home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / w / wmail230.zip / WNODE220.ZIP / WNODELST.PAS < prev   
Pascal/Delphi Source File  |  1992-12-28  |  21KB  |  675 lines

  1. Unit WNodelst;
  2. {$O+;$R-}
  3.  
  4. {-----------------------------------------------------------------}
  5. { Window nodelist handler for editors,mailers and mail processors }
  6. { Copyright 1991,92 by Silvan Calarco (2:334/100.2@fidonet.org)   }
  7. {-----------------------------------------------------------------}
  8.  
  9. {============================================================================}
  10. { This unit may be used in your programs and is distributed to favour the    }
  11. { diffusion of an unique nodelist format. The nodelist compiler program is   }
  12. { called WNODE.EXE and is availaible either in the packed that contains      }
  13. { this unit and in SDS network.                                              }
  14. { The structures of W-Nodelist are in file WNSTRUCT.DOC.                     }
  15. {                                                                            }
  16. { HOW TO USE THIS UNIT:                                                      }
  17. { Using W-Nodelist two sort of shearches can be made:                        }
  18. { 1) By Sysop's name with FindFirstSysop and FindNextSysop                   }
  19. { 2) By Node number with FindFirstNode and FindNextNode                      }
  20. {                                                                            }
  21. { Before performing any sort of search, you have to declare a variable       }
  22. { of type FindNodeRec. The filosophy of this method is very similar to       }
  23. { the one used by TP's FindFirst/FindNext procedures, so FindNodeRec has     }
  24. { the same purpose of SearchRec in unit DOS of TP.                           }
  25. { Inquire results will be returned in FindNodeRec.BBSRecord, a record        }
  26. { which contains these informations:                                         }
  27. {                                                                            }
  28. { BBSRecord=Record                                                           }
  29. {              NodeType:Byte;                                                }
  30. {              Zone,Net,Node,Point:Integer;                                  }
  31. {              BBSName:String[30];                                           }
  32. {              SysopName:String[30];                                         }
  33. {              Location:String[30];                                          }
  34. {              Phone:String[18];                                             }
  35. {              BaudRate:Word;                                                }
  36. {              Flags:String[30];                                             }
  37. {           end;                                                             }
  38. {                                                                            }
  39. { NODETYPE contains one of the following values:                             }
  40. {                                                                            }
  41. {  ZC=1; REGION=2; HOST=4; HUB=8; PVT=16; INHOLD=32; DOWN=64; BOSS=128       }
  42. {                                                                            }
  43. { Other fields contents are the image of what appears in nodelist.           }
  44. {                                                                            }
  45. {----------------------------------------------------------------------------}
  46. {                                                                            }
  47. { 1) FindFirstSysop/FindNextSysop                                            }
  48. {                                                                            }
  49. { To look for one or more entries knowing sysop's name call first time:      }
  50. {                                                                            }
  51. { Procedure FindFirstSysop(SubStr:String;Var Find:FindNodeRec);              }
  52. {                                                                            }
  53. { Where SubStr is the case unsensitive match string for sysop's name.        }
  54. { Note that a name like "John Mc Gregor" is converted in "GREGOR MC JOHN"    }
  55. { for search. This means that match string "MC GREGOR" wouldn't return       }
  56. { the desired entry.                                                         }
  57. {                                                                            }
  58. { To continue search use:                                                    }
  59. {                                                                            }
  60. { Procedure FindNextSysop(Var Find:FindNodeRec);                             }
  61. {                                                                            }
  62. { If Find.BBSRecord.SysopName='' it means that there are no more entries.    }
  63. {                                                                            }
  64. {----------------------------------------------------------------------------}
  65. {                                                                            }
  66. { 2) FindFirstNode/FindNextNode                                              }
  67. {                                                                            }
  68. { To look for one or more entries knowing address call first time:           }
  69. {                                                                            }
  70. { Procedure FindFirstNode(Zone,Net,Node,Point:Integer;Var Find:FindNodeRec); }
  71. {                                                                            }
  72. { Where Zone,Net,Node,Point contain the address of the node to look for.     }
  73. { If you want to look for more than one entry, you can assign one of address }
  74. { fields the value of "ALL" constant. E.g.:                                  }
  75. {                                                                            }
  76. { Zone:=ALL                      looks for every node in database            }
  77. { Zone:=2; Net:=334; Node:=ALL   looks for every node in zone 2, net 334     }
  78. {                                                                            }
  79. { To continue search use:                                                    }
  80. {                                                                            }
  81. { Procedure FindNextSysop(Var Find:FindNodeRec);                             }
  82. {                                                                            }
  83. { If Find.BBSRecord.SysopName='' it means that there are no more entries.    }
  84. {                                                                            }
  85. {============================================================================}
  86.  
  87.  
  88. Interface
  89. Const
  90.    { List of kinds of entries specified in BBSRecord.NodeType }
  91.    ZC=1;
  92.    REGION=2;
  93.    HOST=4;
  94.    HUB=8;
  95.    PVT=16;
  96.    INHOLD=32;
  97.    DOWN=64;
  98.    BOSS=128;
  99.    ALL=-1; { Used to select global nodes with FindFirstNode }
  100.    CompileMode:Boolean=False; { Set to TRUE by WNode when compiling }
  101.  
  102. Type
  103.    BBSRec=Record                 { Record containing nodelist informations }
  104.              NodeType:Byte;
  105.              Zone,Net,Node,Point:Integer;
  106.              BBSName:String[30];
  107.              SysopName:String[30];
  108.              Location:String[30];
  109.              Phone:String[18];
  110.              BaudRate:Word;
  111.              Flags:String[30];
  112.           end;
  113.  
  114.    NodeLocRec=Record             { Record of NODELOC.WNL }
  115.                  NodeType:Byte;
  116.                  Zone,Net,Node,Point:Integer;
  117.                  FileNum:Byte;
  118.                  FilePos:Longint;
  119.               end;
  120.    SysopRec=Record               { Record of SYSLIST.WNL }
  121.                Name:String[20];
  122.                BBSRecord:Longint;
  123.             end;
  124.    NodeRec=Record                { Record di NodeIdx.WNL }
  125.               NodeType:Byte;
  126.               Number:Integer;
  127.               BBSRecord:Longint;
  128.               Match:Array[1..4] of Char;
  129.               SysopRecord:Longint;
  130.            end;
  131.  
  132.    FindNodeRec=Record            { Record usato in FindFirstNode/FindFirstSysop }
  133.                   BBSRecord:BBSRec;
  134.                   SZone,SNet,SNode,SPoint:Integer;
  135.                   SysStr:String[30];
  136.                   FPos,FPos1:Longint;
  137.                end;
  138.  
  139. Var
  140.    NodeLocFile:File of NodeLocRec;
  141.    SysopListFile:File of SysopRec;
  142.    NodeIdxFile:File of NodeRec;
  143.    Nodelist1,NodeList2:File;
  144.    NodeTime:Longint;
  145.  
  146. Function RicavaRecord(Var St:String;Var BBSRecord:BBSRec;CurrZone,CurrNet,CurrNode:Integer):Byte;
  147. Function InitNodeList(NomeDir:String):Boolean; { True=Ok }
  148. Procedure CloseNodeListFiles;
  149. Procedure FindFirstSysop(SubStr:String;Var Find:FindNodeRec);
  150. Procedure FindNextSysop(Var Find:FindNodeRec);
  151. Procedure FindFirstNode(Zone,Net,Node,Point:Integer;Var Find:FindNodeRec);
  152. Procedure FindNextNode(Var Find:FindNodeRec);
  153.  
  154. { The following are internal procedures used also by WNLDEMO.PAS }
  155.  
  156. Function FileExists(Nome_Del_File:String):Boolean;
  157. Function Val2(St:String):Longint;
  158. Function Word_Upcase(Frase:String):String;
  159. Function CmpSort(Stringa1,Stringa2:String):Byte;
  160.  
  161. Implementation
  162. Uses
  163.    Dos;
  164.  
  165. Function FileExists(Nome_Del_File:String):Boolean;
  166. Var
  167.    TestFile:File;
  168.  
  169. Begin
  170.    Assign(TestFile,Nome_Del_File);
  171.    {$I-}
  172.    Reset(TestFile);
  173.    {$I+}
  174.    If IOResult=0 then
  175.    Begin
  176.       FileExists:=True;
  177.       Close(TestFile);
  178.    end
  179.    else
  180.       FileExists:=False;
  181. end;
  182.  
  183. Function Val2(St:String):Longint;
  184. Var
  185.    Res:Longint;
  186.    Err:Integer;
  187.  
  188. Begin
  189.    Val(St,Res,Err);
  190.    Val2:=Res;
  191. end;
  192.  
  193. Function Word_Upcase(Frase:String):String;
  194. Var
  195.    Kunta:Integer;
  196.  
  197. Begin
  198.    For Kunta:=1 to Length(Frase) do
  199.       Frase[Kunta]:=UpCase(Frase[Kunta]);
  200.    Word_UpCase:=Frase;
  201. end;
  202.  
  203. Function CmpSort(Stringa1,Stringa2:String):Byte;
  204. Var
  205.    Pos:Byte;
  206.    Exit:Byte;
  207.  
  208. Begin
  209.    Pos:=1;
  210.    Exit:=0;
  211.    While (Pos<=Length(Stringa1)) and (Pos<=Length(Stringa2))
  212.          and (Exit=0) do
  213.    Begin
  214.       If Stringa1[Pos]<Stringa2[Pos] then
  215.          Exit:=1
  216.       else
  217.       If Stringa1[Pos]>Stringa2[Pos] then
  218.          Exit:=2;
  219.       Inc(Pos);
  220.    end;
  221.    If Exit=0 then
  222.    Begin
  223.       If Length(Stringa1)<Length(Stringa2) then
  224.          Exit:=1
  225.       else
  226.       If Length(Stringa1)>Length(Stringa2) then
  227.          Exit:=2
  228.       else
  229.          Exit:=3;
  230.    end;
  231.    CmpSort:=Exit;
  232. end;
  233.  
  234. Function Convert_Name(FromStr:String):String;
  235. Var
  236.    ResStr:String;
  237.    Cont:Byte;
  238.  
  239. Begin
  240.    ResStr:='';
  241.    FromStr:=Word_UpCase(FromStr)+' ';
  242.    While Length(FromStr)>0 do
  243.    Begin
  244.       Insert(Copy(FromStr,1,Pos(' ',FromStr)),ResStr,1);
  245.       Delete(FromStr,1,Pos(' ',FromStr));
  246.    end;
  247.    ResStr[0]:=Chr(Length(ResStr)-1);
  248.    If not(CompileMode) then
  249.       For Cont:=2 to Length(ResStr) do
  250.          If (ResStr[Cont] in ['A'..'Z']) and (ResStr[Cont-1]<>#32) then
  251.              ResStr[Cont]:=Chr(Ord(ResStr[Cont])+32);
  252.    Convert_Name:=ResStr;
  253. end;
  254.  
  255. Function ReadVar(Var Linea:String):String;
  256. Var
  257.    C:Byte;
  258.  
  259. Begin
  260.    C:=1;
  261.    While (Linea[C]<>',') and (C<=Length(Linea)) do
  262.    Begin
  263.       If Linea[C]='_' then
  264.          Linea[C]:=' ';
  265.       Inc(C);
  266.    end;
  267.    If Pos(',',Linea)=0 then
  268.    Begin
  269.       ReadVar:=Copy(Linea,1,Pos(#13,Linea)-1);
  270.       Linea:='';
  271.    end
  272.    else
  273.    Begin
  274.       ReadVar:=Copy(Linea,1,Pos(',',Linea)-1);
  275.       Delete(Linea,1,Pos(',',Linea));
  276.    end;
  277. end;
  278.  
  279. Procedure Split_Address(Address:String;Var Zona,Net,Nodo,Point:Integer);
  280. Var
  281.    MomStr:String[5];
  282.  
  283. Begin
  284.    Address:=Word_UpCase(Address);
  285.    If Copy(Address,1,3)='ALL' then
  286.    Begin
  287.       Zona:=-1;Net:=-1;Nodo:=-1;Point:=-1;
  288.    end
  289.    else
  290.    Begin
  291.       Address:=Address+' ';
  292.       Zona:=Val2(Copy(Address,1,Pos(':',Address)-1));
  293.       If Zona=0 then
  294.          Zona:=2;
  295.       Delete(Address,1,Pos(':',Address));
  296.       If copy(Address,1,3)='ALL' then
  297.       Begin
  298.          Net:=-1;
  299.          Nodo:=-1;
  300.          Point:=-1;
  301.       end
  302.       else
  303.       Begin
  304.          If Pos('/',Address)<>0 then
  305.             Net:=Val2(Copy(Address,1,Pos('/',Address)-1));
  306.          Delete(Address,1,Pos('/',Address));
  307.          If Pos('.',Address)<>0 then
  308.          Begin
  309.             Nodo:=Val2(Copy(Address,1,Pos('.',Address)-1));
  310.             If Address[1]='.' then
  311.             Begin
  312.                Net:=0;
  313.                Nodo:=0;
  314.             end;
  315.             Delete(Address,1,Pos('.',Address));
  316.             Point:=Val2(Copy(Address,1,Pos(' ',Address)-1));
  317.          end
  318.          else
  319.          Begin
  320.             MomStr:=Copy(Address,1,Pos(' ',Address)-1);
  321.             If MomStr='ALL' then
  322.                Nodo:=-1
  323.             else
  324.                Nodo:=Val2(MomStr);
  325.             Point:=0;
  326.          end
  327.       end
  328.    end
  329. end;
  330.  
  331. Function TrovaTipo(Sub:String):Byte;
  332. Begin
  333.    If Sub='' then
  334.       TrovaTipo:=0
  335.    else
  336.    If Sub='ZONE' then
  337.       TrovaTipo:=ZC
  338.    else
  339.    If Sub='REGION' then
  340.       TrovaTipo:=Region
  341.    else
  342.    If Sub='HOST' then
  343.       TrovaTipo:=Host
  344.    else
  345.    If Sub='HUB' then
  346.       TrovaTipo:=Hub
  347.    else
  348.    If Sub='PVT' then
  349.       TrovaTipo:=Pvt
  350.    else
  351.    If Sub='HOLD' then
  352.       TrovaTipo:=InHold
  353.    else
  354.    If Sub='DOWN' then
  355.       TrovaTipo:=Down
  356.    else
  357.    If Sub='BOSS' then
  358.       TrovaTipo:=Boss;
  359. end;
  360.  
  361. Function RicavaRecord(Var St:String;Var BBSRecord:BBSRec;CurrZone,CurrNet,CurrNode:Integer):Byte;
  362. Var
  363.    Sub:String;
  364.    Err:Integer;
  365.    Virg:Byte;
  366.  
  367. Begin
  368.    FillChar(BBSRecord,SizeOf(BBSRecord),#0);
  369.    With BBSRecord do
  370.    Begin
  371.       Virg:=0;
  372.       For Err:=1 to Length(St) do
  373.          If St[Err]=',' then
  374.             Inc(Virg);
  375.       Sub:=Word_UpCase(ReadVar(St));
  376.       NodeType:=TrovaTipo(Sub);
  377.       Sub:=ReadVar(St);
  378.       If NodeType=ZC then
  379.       Begin
  380.          CurrZone:=Val2(Sub);
  381.          CurrNet:=0;
  382.          CurrNode:=-1;
  383.       end
  384.       else
  385.       If NodeType in [Region,Host] then
  386.       Begin
  387.          CurrNet:=Val2(Sub);
  388.          CurrNode:=-1;
  389.       end
  390.       else
  391.       If NodeType=Boss then
  392.       Begin
  393.          Delete(Sub,Pos(#13,Sub),1);
  394.          Split_Address(Sub,CurrZone,CurrNet,CurrNode,Err)
  395.       end
  396.       else
  397.       Begin
  398.          If CurrNode=-1 then
  399.             Node:=Val2(Sub)
  400.          else
  401.          Begin
  402.             Node:=CurrNode;
  403.             Point:=Val2(Sub);
  404.          end;
  405.       end;
  406.       Zone:=CurrZone;
  407.       Net:=CurrNet;
  408.       If NodeType<>Boss then
  409.       Begin
  410.          BBSName:=ReadVar(St);
  411.          Location:=ReadVar(St);
  412.          SysopName:=ReadVar(St);
  413.          If not(CompileMode) then
  414.          Begin
  415.             Phone:=ReadVar(St);
  416.             BaudRate:=Val2(ReadVar(St));
  417.             Flags:=Copy(St,1,Pos(#13,St)-1);
  418.          end
  419.       end
  420.       else
  421.          Node:=CurrNode;
  422.    end;
  423.    If (Virg<6) and (BBSRecord.NodeType<>Boss) then
  424.       RicavaRecord:=1
  425.    else
  426.       RicavaRecord:=0;
  427. end;
  428.  
  429. Procedure FindRecord(NodoRec:NodeLocRec;Var ToRec:BBSRec);
  430. Var
  431.    Letti:Word;
  432.    Linea:String;
  433.    Res:Byte;
  434.  
  435. Begin
  436.    Case NodoRec.FileNum of
  437.       1:If FileRec(Nodelist1).Mode=FMClosed then
  438.            Reset(Nodelist1,1);
  439.       2:If FileRec(Nodelist2).Mode=FMClosed then
  440.            Reset(Nodelist2,1);
  441.    end;
  442.    Case NodoRec.FileNum of
  443.       1:Begin
  444.            Seek(Nodelist1,NodoRec.FilePos);
  445.            BlockRead(Nodelist1,Linea[1],255,Letti);
  446.            Linea[0]:=Chr(Letti);
  447.         end;
  448.       2:Begin
  449.            Seek(Nodelist2,NodoRec.FilePos);
  450.            BlockRead(Nodelist2,Linea[1],255,Letti);
  451.            Linea[0]:=Chr(Letti);
  452.         end;
  453.    end;
  454.    Res:=RicavaRecord(Linea,ToRec,0,0,-1);
  455.    ToRec.Zone:=NodoRec.Zone;
  456.    ToRec.Net:=NodoRec.Net;
  457.    ToRec.Node:=NodoRec.Node;
  458.    ToRec.Point:=NodoRec.Point;
  459. end;
  460.  
  461. Function ConfrNode(Zona1,Net1,Nodo1,Point1,Zona2,Net2,Nodo2,Point2:Integer):Boolean;
  462. Begin
  463.    If (Zona1=ALL) or
  464.       ((Zona1=Zona2) and (Net1=ALL)) or
  465.       ((Zona1=Zona2) and (Net1=Net2) and (Nodo1=ALL)) or
  466.       ((Zona1=Zona2) and (Net1=Net2) and (Nodo1=Nodo2) and (Point1=ALL)) or
  467.       ((Zona1=Zona2) and (Net1=Net2) and (Nodo1=Nodo2) and (Point1=Point2)) then
  468.          ConfrNode:=True
  469.       else
  470.          ConfrNode:=False;
  471. end;
  472.  
  473. Procedure FindNextNodeIndex(Var Find:FindNodeRec);
  474. Const
  475.    ActZone:Integer=-1;
  476.    ActNet:Integer=-1;
  477.  
  478. Var
  479.    Nodelist:NodeRec;
  480.    ActPos:Longint;
  481.    Esci:Boolean;
  482.  
  483. Begin
  484.    Seek(NodeIdxFile,Find.FPos1);
  485.    Repeat
  486.       Read(NodeIdxFile,Nodelist);
  487.       ActPos:=Nodelist.BBSRecord;
  488.       If Nodelist.NodeType=ZC then
  489.       Begin
  490.          ActZone:=Nodelist.Number;
  491.          ActNet:=0;
  492.       end
  493.       else
  494.       If Nodelist.NodeType in [Region,Host,Boss] then
  495.          ActNet:=Nodelist.Number;
  496.       Esci:=(ConfrNode(Find.SZone,Find.SNet,0,0,ActZone,ActNet,0,0));
  497.    Until Esci or Eof(NodeIdxFile);
  498.    Find.FPos1:=FilePos(NodeIdxFile);
  499.    If not(Esci) then
  500.       ActPos:=-1;
  501.    Find.FPos:=ActPos;
  502. end;
  503.  
  504. Procedure FindNextSysop(Var Find:FindNodeRec);
  505. Var
  506.    SysopList:SysopRec;
  507.    NodeLoc:NodeLocRec;
  508.  
  509. Begin
  510.    Seek(SysopListFile,Find.FPos);
  511.    SysopList.Name:='';
  512.    While not(Eof(SysopListFile)) and
  513.          (CmpSort(Find.SysStr,SysopList.Name) in [2,3]) do
  514.    Begin
  515.       Read(SysopListFile,SysopList);
  516.       If (Pos(Find.SysStr,SysopList.Name)=1) then
  517.       Begin
  518.          Seek(NodeLocFile,SysopList.BBSRecord);
  519.          Read(NodeLocFile,NodeLoc);
  520.          FindRecord(NodeLoc,Find.BBSRecord);
  521.          Find.FPos:=FilePos(SysopListFile);
  522.          Exit;
  523.       end
  524.    end;
  525.    Find.BBSRecord.SysopName:='';
  526. end;
  527.  
  528. Procedure FindNextNode(Var Find:FindNodeRec);
  529. Var
  530.    BBSList:NodeLocRec;
  531.  
  532. Begin
  533.    Seek(NodeLocFile,Find.FPos);
  534.    While not(Eof(NodeLocFile)) and (Find.FPos<>-1) do
  535.    Begin
  536.       Read(NodeLocFile,BBSList);
  537.       If ConfrNode(Find.SZone,Find.SNet,Find.SNode,Find.SPoint,
  538.                    BBSList.Zone,BBSList.Net,BBSList.Node,BBSList.Point) and
  539.          (BBSList.NodeType<>Boss) then
  540.       Begin
  541.          FindRecord(BBSList,Find.BBSRecord);
  542.          Find.FPos:=FilePos(NodeLocFile);
  543.          Exit;
  544.       end;
  545.       If not(ConfrNode(Find.SZone,Find.SNet,0,0,BBSList.Zone,BBSList.Net,0,0)) then
  546.       Begin
  547.          FindNextNodeIndex(Find);
  548.          If Find.FPos<>-1 then
  549.             Seek(NodeLocFile,Find.Fpos);
  550.       end;
  551.    end;
  552.    Find.BBSRecord.SysopName:='';
  553. end;
  554.  
  555. Procedure FindFirstSysop(SubStr:String;Var Find:FindNodeRec);
  556. Var
  557.    NodeIdx:NodeRec;
  558.    ActRec:Longint;
  559.    ExtrStr:String[4];
  560.  
  561. Begin
  562.    Find.SysStr:=Word_UpCase(Convert_Name(SubStr));
  563.    ExtrStr:=Copy(Find.SysStr,1,4);
  564.    Find.BBSRecord.SysopName:='';
  565.    Find.FPos:=0;
  566.    If FileRec(NodeLocFile).Mode=FMClosed then
  567.       Reset(NodeLocFile);
  568.    If FileRec(SysopListFile).Mode=FMClosed then
  569.       Reset(SysopListFile);
  570.    If FileRec(NodeIdxFile).Mode=FMClosed then
  571.       Reset(NodeIdxFile);
  572.    Seek(NodeIdxFile,0);
  573.    NodeIdx.SysopRecord:=0;
  574.    Repeat
  575.       ActRec:=NodeIdx.SysopRecord;
  576.       Read(NodeIdxFile,NodeIdx);
  577.    Until (CmpSort(ExtrStr,NodeIdx.Match) in [1,3]) or
  578.          Eof(NodeIdxFile);
  579.    Find.FPos:=ActRec;
  580.    FindNextSysop(Find);
  581. end;
  582.  
  583. Procedure FindFirstNode(Zone,Net,Node,Point:Integer;Var Find:FindNodeRec);
  584. Begin
  585.    Find.SZone:=Zone;
  586.    Find.SNet:=Net;
  587.    Find.SNode:=Node;
  588.    Find.SPoint:=Point;
  589.    Find.BBSRecord.SysopName:='';
  590.    If FileRec(NodeLocFile).Mode=FMClosed then
  591.       Reset(NodeLocFile);
  592.    If FileRec(SysopListFile).Mode=FMClosed then
  593.       Reset(SysopListFile);
  594.    If FileRec(NodeIdxFile).Mode=FMClosed then
  595.       Reset(NodeIdxFile);
  596.    Find.FPos1:=0;
  597.    FindNextNodeIndex(Find);
  598.    FindNextNode(Find);
  599. end;
  600.  
  601. Function Find_Newest_File(Dir:String;Var Check:Boolean):String;
  602. Var
  603.    S:SearchRec;
  604.    ActTime:Longint;
  605.    ActFile:String[12];
  606.    Num,Err:Word;
  607.  
  608. Begin
  609.    ActTime:=0;
  610.    ActFile:='';
  611.    S.Name:='';
  612.    FindFirst(Dir,Archive,S);
  613.    While S.Name<>'' do
  614.    Begin
  615.       Err:=0;
  616.       If Check then
  617.          Val(Copy(S.Name,Pos('.',S.Name)+1,3),Num,Err);
  618.       If (S.Time>ActTime) and (Err=0) then
  619.       Begin
  620.          ActTime:=S.Time;
  621.          ActFile:=S.Name;
  622.       end;
  623.       S.Name:='';
  624.       FindNext(S);
  625.    end;
  626.    Check:=(ActTime=NodeTime) and (NodeTime*ActTime<>0);
  627.    If ActFile='' then
  628.       Dir:=''
  629.    else
  630.    While (Dir[Length(Dir)]<>'\') and (Length(Dir)>0) do
  631.       Delete(Dir,Length(Dir),1);
  632.    Find_Newest_File:=Dir+ActFile;
  633. end;
  634.  
  635. Function InitNodeList(NomeDir:String):Boolean;
  636. Var
  637.    C:Boolean;
  638.    S:SearchRec;
  639.  
  640. Begin
  641.    If (NomeDir[Length(NomeDir)]<>'\') and (Length(NomeDir)>0) then
  642.       NomeDir:=NomeDir+'\';
  643.    NomeDir:=FExpand(NomeDir);
  644.    Assign(NodeLocFile,NomeDir+'nodeloc.wnl');
  645.    Assign(SysopListFile,NomeDir+'syslist.wnl');
  646.    Assign(NodeIdxFile,NomeDir+'nodeidx.wnl');
  647.    C:=True;
  648.    FindFirst(NomeDir+'NODELOC.WNL',Archive,S);
  649.    If DosError=0 then
  650.       NodeTime:=S.Time
  651.    else
  652.       NodeTime:=0;
  653.    Assign(Nodelist1,Find_Newest_File(NomeDir+'NODELIST.*',C));
  654.    Assign(Nodelist2,NomeDir+'ALTNODE.WNL');
  655.    InitNodeList:=FileExists(NomeDir+'syslist.wnl') and
  656.                  FileExists(NomeDir+'nodeidx.wnl') and
  657.                  FileExists(NomeDir+'nodeloc.wnl') and C;
  658. end;
  659.  
  660. Procedure CloseNodeListFiles;
  661. Begin
  662.    If FileRec(NodeLocFile).Mode=FMInOut then
  663.       Close(NodeLocFile);
  664.    If FileRec(SysopListFile).Mode=FMInOut then
  665.       Close(SysopListFile);
  666.    If FileRec(NodeIdxFile).Mode=FMInOut then
  667.       Close(NodeIdxFile);
  668.    If FileRec(NodeList1).Mode=FMInOut then
  669.       Close(NodeList1);
  670.    If FileRec(NodeList2).Mode=FMInOut then
  671.       Close(NodeList2);
  672. end;
  673.  
  674. Begin
  675. end.