home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / wnode230.zip / WNODELST.PAS < prev    next >
Pascal/Delphi Source File  |  1993-03-14  |  20KB  |  599 lines

  1. Unit WNodeLst;
  2. {$O+;$R-}
  3.  
  4. {-----------------------------------------------------------------}
  5. { Window nodelist handler for editors,mailers and mail processors }
  6. { Copyright 1991-93 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(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. Function Convert_Name(FromStr:String):String;
  154. Function Trova_File_Recente(Dir:String;Var Check:Boolean):String;
  155.  
  156. Implementation
  157. Uses
  158.    Utils,Dos;
  159.  
  160. Function Convert_Name(FromStr:String):String;
  161. Var
  162.    ResStr:String;
  163.    Cont:Byte;
  164.  
  165. Begin
  166.    ResStr:='';
  167.    FromStr:=Word_UpCase(FromStr)+' ';
  168.    While Length(FromStr)>0 do
  169.    Begin
  170.       Insert(Copy(FromStr,1,Pos(' ',FromStr)),ResStr,1);
  171.       Delete(FromStr,1,Pos(' ',FromStr));
  172.    end;
  173.    ResStr[0]:=Chr(Length(ResStr)-1);
  174.    If not(CompileMode) then
  175.       For Cont:=2 to Length(ResStr) do
  176.          If (ResStr[Cont] in ['A'..'Z']) and (ResStr[Cont-1]<>#32) then
  177.              ResStr[Cont]:=Chr(Ord(ResStr[Cont])+32);
  178.    Convert_Name:=ResStr;
  179. end;
  180.  
  181. Function ReadVar(Var Linea:String):String;
  182. Var
  183.    C:Byte;
  184.  
  185. Begin
  186.    C:=1;
  187.    While (Linea[C]<>',') and (C<=Length(Linea)) do
  188.    Begin
  189.       If Linea[C]='_' then
  190.          Linea[C]:=' ';
  191.       Inc(C);
  192.    end;
  193.    If Pos(',',Linea)=0 then
  194.    Begin
  195.       ReadVar:=Linea;
  196.       Linea:='';
  197.    end
  198.    else
  199.    Begin
  200.       ReadVar:=Copy(Linea,1,Pos(',',Linea)-1);
  201.       Delete(Linea,1,Pos(',',Linea));
  202.    end;
  203. end;
  204.  
  205. Procedure Split_Address(Address:String;Var Zona,Net,Nodo,Point:Integer);
  206. Var
  207.    MomStr:String[5];
  208.  
  209. Begin
  210.    Address:=Word_UpCase(Address);
  211.    If Copy(Address,1,3)='ALL' then
  212.    Begin
  213.       Zona:=-1;Net:=-1;Nodo:=-1;Point:=-1;
  214.    end
  215.    else
  216.    Begin
  217.       Address:=Address+' ';
  218.       Zona:=Val2(Copy(Address,1,Pos(':',Address)-1));
  219.       If Zona=0 then
  220.          Zona:=2;
  221.       Delete(Address,1,Pos(':',Address));
  222.       If copy(Address,1,3)='ALL' then
  223.       Begin
  224.          Net:=-1;
  225.          Nodo:=-1;
  226.          Point:=-1;
  227.       end
  228.       else
  229.       Begin
  230.          If Pos('/',Address)<>0 then
  231.             Net:=Val2(Copy(Address,1,Pos('/',Address)-1));
  232.          Delete(Address,1,Pos('/',Address));
  233.          If Pos('.',Address)<>0 then
  234.          Begin
  235.             Nodo:=Val2(Copy(Address,1,Pos('.',Address)-1));
  236.             If Address[1]='.' then
  237.             Begin
  238.                Net:=0;
  239.                Nodo:=0;
  240.             end;
  241.             Delete(Address,1,Pos('.',Address));
  242.             Point:=Val2(Copy(Address,1,Pos(' ',Address)-1));
  243.          end
  244.          else
  245.          Begin
  246.             MomStr:=Copy(Address,1,Pos(' ',Address)-1);
  247.             If MomStr='ALL' then
  248.                Nodo:=-1
  249.             else
  250.                Nodo:=Val2(MomStr);
  251.             Point:=0;
  252.          end
  253.       end
  254.    end
  255. end;
  256.  
  257. Function TrovaTipo(Sub:String):Byte;
  258. Begin
  259.    If Sub='' then
  260.       TrovaTipo:=0
  261.    else
  262.    If Sub='ZONE' then
  263.       TrovaTipo:=ZC
  264.    else
  265.    If Sub='REGION' then
  266.       TrovaTipo:=Region
  267.    else
  268.    If Sub='HOST' then
  269.       TrovaTipo:=Host
  270.    else
  271.    If Sub='HUB' then
  272.       TrovaTipo:=Hub
  273.    else
  274.    If Sub='PVT' then
  275.       TrovaTipo:=Pvt
  276.    else
  277.    If Sub='HOLD' then
  278.       TrovaTipo:=InHold
  279.    else
  280.    If Sub='DOWN' then
  281.       TrovaTipo:=Down
  282.    else
  283.    If Sub='BOSS' then
  284.       TrovaTipo:=Boss;
  285. end;
  286.  
  287. Function RicavaRecord(St:String;Var BBSRecord:BBSRec;CurrZone,CurrNet,CurrNode:Integer):Byte;
  288. Var
  289.    Sub:String;
  290.    Err:Integer;
  291.    Virg:Byte;
  292.  
  293. Begin
  294.    FillChar(BBSRecord,SizeOf(BBSRecord),#0);
  295.    With BBSRecord do
  296.    Begin
  297.       Virg:=0;
  298.       For Err:=1 to Length(St) do
  299.          If St[Err]=',' then
  300.             Inc(Virg);
  301.       Sub:=Word_UpCase(ReadVar(St));
  302.       NodeType:=TrovaTipo(Sub);
  303.       Sub:=ReadVar(St);
  304.       If NodeType=ZC then
  305.       Begin
  306.          CurrZone:=Val2(Sub);
  307.          CurrNet:=0;
  308.          CurrNode:=-1;
  309.       end
  310.       else
  311.       If NodeType in [Region,Host] then
  312.       Begin
  313.          CurrNet:=Val2(Sub);
  314.          CurrNode:=-1;
  315.       end
  316.       else
  317.       If NodeType=Boss then
  318.          Split_Address(Sub,CurrZone,CurrNet,CurrNode,Err)
  319.       else
  320.       Begin
  321.          If CurrNode=-1 then
  322.             Node:=Val2(Sub)
  323.          else
  324.          Begin
  325.             Node:=CurrNode;
  326.             Point:=Val2(Sub);
  327.          end;
  328.       end;
  329.       Zone:=CurrZone;
  330.       Net:=CurrNet;
  331.       If NodeType<>Boss then
  332.       Begin
  333.          BBSName:=ReadVar(St);
  334.          Location:=ReadVar(St);
  335.          SysopName:=ReadVar(St);
  336.          If not(CompileMode) then
  337.          Begin
  338.             Phone:=ReadVar(St);
  339.             BaudRate:=Val2(ReadVar(St));
  340.             Flags:=St;
  341.          end
  342.       end
  343.       else
  344.          Node:=CurrNode;
  345.    end;
  346.    If (Virg<6) and (BBSRecord.NodeType<>Boss) then
  347.       RicavaRecord:=1
  348.    else
  349.       RicavaRecord:=0;
  350. end;
  351.  
  352. Procedure FindRecord(NodoRec:NodeLocRec;Var ToRec:BBSRec);
  353. Var
  354.    Letti:Word;
  355.    Linea:String;
  356.    Res:Byte;
  357.  
  358. Begin
  359.    Case NodoRec.FileNum of
  360.       1:If FileRec(Nodelist1).Mode=FMClosed then
  361.            Reset(Nodelist1,1);
  362.       2:If FileRec(Nodelist2).Mode=FMClosed then
  363.            Reset(Nodelist2,1);
  364.    end;
  365.    Case NodoRec.FileNum of
  366.       1:Begin
  367.            Seek(Nodelist1,NodoRec.FilePos);
  368.            BlockRead(Nodelist1,Linea[1],255,Letti);
  369.            Linea[0]:=Chr(Letti);
  370.         end;
  371.       2:Begin
  372.            Seek(Nodelist2,NodoRec.FilePos);
  373.            BlockRead(Nodelist2,Linea[1],255,Letti);
  374.            Linea[0]:=Chr(Letti);
  375.         end;
  376.    end;
  377.    Res:=RicavaRecord(Linea,ToRec,0,0,-1);
  378.    ToRec.Zone:=NodoRec.Zone;
  379.    ToRec.Net:=NodoRec.Net;
  380.    ToRec.Node:=NodoRec.Node;
  381.    ToRec.Point:=NodoRec.Point;
  382. end;
  383.  
  384. Function ConfrNode(Zona1,Net1,Nodo1,Point1,Zona2,Net2,Nodo2,Point2:Integer):Boolean;
  385. Begin
  386.    If (Zona1=ALL) or
  387.       ((Zona1=Zona2) and (Net1=ALL)) or
  388.       ((Zona1=Zona2) and (Net1=Net2) and (Nodo1=ALL)) or
  389.       ((Zona1=Zona2) and (Net1=Net2) and (Nodo1=Nodo2) and (Point1=ALL)) or
  390.       ((Zona1=Zona2) and (Net1=Net2) and (Nodo1=Nodo2) and (Point1=Point2)) then
  391.          ConfrNode:=True
  392.       else
  393.          ConfrNode:=False;
  394. end;
  395.  
  396. Procedure FindNextNodeIndex(Var Find:FindNodeRec);
  397. Const
  398.    ActZone:Integer=-1;
  399.    ActNet:Integer=-1;
  400.  
  401. Var
  402.    Nodelist:NodeRec;
  403.    ActPos:Longint;
  404.    Esci:Boolean;
  405.  
  406. Begin
  407.    Seek(NodeIdxFile,Find.FPos1);
  408.    Repeat
  409.       Read(NodeIdxFile,Nodelist);
  410.       ActPos:=Nodelist.BBSRecord;
  411.       If Nodelist.NodeType=ZC then
  412.       Begin
  413.          ActZone:=Nodelist.Number;
  414.          ActNet:=0;
  415.       end
  416.       else
  417.       If Nodelist.NodeType in [Region,Host,Boss] then
  418.          ActNet:=Nodelist.Number;
  419.       Esci:=(ConfrNode(Find.SZone,Find.SNet,0,0,ActZone,ActNet,0,0));
  420.    Until Esci or Eof(NodeIdxFile);
  421.    Find.FPos1:=FilePos(NodeIdxFile);
  422.    If not(Esci) then
  423.       ActPos:=-1;
  424.    Find.FPos:=ActPos;
  425. end;
  426.  
  427. Procedure FindNextSysop(Var Find:FindNodeRec);
  428. Var
  429.    SysopList:SysopRec;
  430.    NodeLoc:NodeLocRec;
  431.  
  432. Begin
  433.    Seek(SysopListFile,Find.FPos);
  434.    SysopList.Name:='';
  435.    While not(Eof(SysopListFile)) and
  436.          (CmpSort(Find.SysStr,SysopList.Name) in [2,3]) do
  437.    Begin
  438.       Read(SysopListFile,SysopList);
  439.       If (Pos(Find.SysStr,SysopList.Name)=1) then
  440.       Begin
  441.          Seek(NodeLocFile,SysopList.BBSRecord);
  442.          Read(NodeLocFile,NodeLoc);
  443.          FindRecord(NodeLoc,Find.BBSRecord);
  444.          Find.FPos:=FilePos(SysopListFile);
  445.          Exit;
  446.       end
  447.    end;
  448.    Find.BBSRecord.SysopName:='';
  449. end;
  450.  
  451. Procedure FindNextNode(Var Find:FindNodeRec);
  452. Var
  453.    BBSList:NodeLocRec;
  454.  
  455. Begin
  456.    Seek(NodeLocFile,Find.FPos);
  457.    While not(Eof(NodeLocFile)) and (Find.FPos<>-1) do
  458.    Begin
  459.       Read(NodeLocFile,BBSList);
  460.       If ConfrNode(Find.SZone,Find.SNet,Find.SNode,Find.SPoint,
  461.                    BBSList.Zone,BBSList.Net,BBSList.Node,BBSList.Point) and
  462.          (BBSList.NodeType<>Boss) then
  463.       Begin
  464.          FindRecord(BBSList,Find.BBSRecord);
  465.          Find.FPos:=FilePos(NodeLocFile);
  466.          Exit;
  467.       end;
  468.       If not(ConfrNode(Find.SZone,Find.SNet,0,0,BBSList.Zone,BBSList.Net,0,0)) then
  469.       Begin
  470.          FindNextNodeIndex(Find);
  471.          If Find.FPos<>-1 then
  472.             Seek(NodeLocFile,Find.Fpos);
  473.       end;
  474.    end;
  475.    Find.BBSRecord.SysopName:='';
  476. end;
  477.  
  478. Procedure FindFirstSysop(SubStr:String;Var Find:FindNodeRec);
  479. Var
  480.    NodeIdx:NodeRec;
  481.    ActRec:Longint;
  482.    ExtrStr:String[4];
  483.  
  484. Begin
  485.    Find.SysStr:=Word_UpCase(Convert_Name(SubStr));
  486.    ExtrStr:=Copy(Find.SysStr,1,4);
  487.    Find.BBSRecord.SysopName:='';
  488.    Find.FPos:=0;
  489.    If FileRec(NodeLocFile).Mode=FMClosed then
  490.       Reset(NodeLocFile);
  491.    If FileRec(SysopListFile).Mode=FMClosed then
  492.       Reset(SysopListFile);
  493.    If FileRec(NodeIdxFile).Mode=FMClosed then
  494.       Reset(NodeIdxFile);
  495.    Seek(NodeIdxFile,0);
  496.    NodeIdx.SysopRecord:=0;
  497.    Repeat
  498.       ActRec:=NodeIdx.SysopRecord;
  499.       Read(NodeIdxFile,NodeIdx);
  500.    Until (CmpSort(ExtrStr,NodeIdx.Match) in [1,3]) or
  501.          Eof(NodeIdxFile);
  502.    Find.FPos:=ActRec;
  503.    FindNextSysop(Find);
  504. end;
  505.  
  506. Procedure FindFirstNode(Zone,Net,Node,Point:Integer;Var Find:FindNodeRec);
  507. Begin
  508.    Find.SZone:=Zone;
  509.    Find.SNet:=Net;
  510.    Find.SNode:=Node;
  511.    Find.SPoint:=Point;
  512.    Find.BBSRecord.SysopName:='';
  513.    If FileRec(NodeLocFile).Mode=FMClosed then
  514.       Reset(NodeLocFile);
  515.    If FileRec(SysopListFile).Mode=FMClosed then
  516.       Reset(SysopListFile);
  517.    If FileRec(NodeIdxFile).Mode=FMClosed then
  518.       Reset(NodeIdxFile);
  519.    Find.FPos1:=0;
  520.    FindNextNodeIndex(Find);
  521.    FindNextNode(Find);
  522. end;
  523.  
  524. Function Trova_File_Recente(Dir:String;Var Check:Boolean):String;
  525. Var
  526.    S:SearchRec;
  527.    ActTime:Longint;
  528.    ActFile:String[12];
  529.    Num,Err:Word;
  530.  
  531. Begin
  532.    ActTime:=0;
  533.    ActFile:='';
  534.    S.Name:='';
  535.    FindFirst(Dir,Archive,S);
  536.    While S.Name<>'' do
  537.    Begin
  538.       Err:=0;
  539.       If Check then
  540.          Val(Copy(S.Name,Pos('.',S.Name)+1,3),Num,Err);
  541.       If (S.Time>ActTime) and (Err=0) then
  542.       Begin
  543.          ActTime:=S.Time;
  544.          ActFile:=S.Name;
  545.       end;
  546.       S.Name:='';
  547.       FindNext(S);
  548.    end;
  549.    Check:=(ActTime=NodeTime) and (NodeTime*ActTime<>0);
  550.    If ActFile='' then
  551.       Dir:=''
  552.    else
  553.    While (Dir[Length(Dir)]<>'\') and (Length(Dir)>0) do
  554.       Delete(Dir,Length(Dir),1);
  555.    Trova_File_Recente:=Dir+ActFile;
  556. end;
  557.  
  558. Function InitNodeList(NomeDir:String):Boolean;
  559. Var
  560.    C:Boolean;
  561.    S:SearchRec;
  562.  
  563. Begin
  564.    If (NomeDir[Length(NomeDir)]<>'\') and (Length(NomeDir)>0) then
  565.       NomeDir:=NomeDir+'\';
  566.    NomeDir:=FExpand(NomeDir);
  567.    Assign(NodeLocFile,NomeDir+'nodeloc.wnl');
  568.    Assign(SysopListFile,NomeDir+'syslist.wnl');
  569.    Assign(NodeIdxFile,NomeDir+'nodeidx.wnl');
  570.    C:=True;
  571.    FindFirst(NomeDir+'NODELOC.WNL',Archive,S);
  572.    If DosError=0 then
  573.       NodeTime:=S.Time
  574.    else
  575.       NodeTime:=0;
  576.    Assign(Nodelist1,Trova_File_Recente(NomeDir+'NODELIST.*',C));
  577.    Assign(Nodelist2,NomeDir+'ALTNODE.WNL');
  578.    InitNodeList:=FileExists(NomeDir+'syslist.wnl') and
  579.                  FileExists(NomeDir+'nodeidx.wnl') and
  580.                  FileExists(NomeDir+'nodeloc.wnl') and C;
  581. end;
  582.  
  583. Procedure CloseNodeListFiles;
  584. Begin
  585.    If FileRec(NodeLocFile).Mode=FMInOut then
  586.       Close(NodeLocFile);
  587.    If FileRec(SysopListFile).Mode=FMInOut then
  588.       Close(SysopListFile);
  589.    If FileRec(NodeIdxFile).Mode=FMInOut then
  590.       Close(NodeIdxFile);
  591.    If FileRec(NodeList1).Mode=FMInOut then
  592.       Close(NodeList1);
  593.    If FileRec(NodeList2).Mode=FMInOut then
  594.       Close(NodeList2);
  595. end;
  596.  
  597. Begin
  598. end.
  599.