PROGRAM NLookup1;

USES Database,
     Fido;

TYPE FilenameEntry = RECORD
                           Filename : ARRAY[1..8+1+3] OF CHAR;
                           Length   : LONGINT;
                     END;

TYPE ZoneEntry = RECORD
                       Zone   : WORD;
                       Length : WORD;
                 END;

TYPE NetEntry = RECORD
                      Net       : WORD;
                      ByteNodes : BYTE;
                      WordNodes : BYTE;
                END;

VAR FAddr    : FidoAddrType;
    InFile   : FILE;
    IORes    : BYTE;
    FNameStr : STRING[8+1+3];

    FName    : FilenameEntry;
    Zone     : ZonEEntry;
    Net      : NetEntry;

    BNodes   : ARRAY[1..255] OF BYTE;
    WNodes   : ARRAY[1..255] OF WORD;
    Lp       : BYTE;

    AccessCount : WORD;
    BytesRead   : LONGINT;

LABEL Found,
      NotFound,
      Einde;

BEGIN
     WriteLn ('NODELIST.TDB Lookup Utility');
     WriteLn ('Written by Ramon van der Winkel');
     WriteLn;

     IF (ParamCount = 0) THEN
     BEGIN
          WriteLn ('Usage: NLOOKUP 2:200/111');
          Exit;
     END;

     Assign (InFile,'NODELIST.TDB');
     {$I-} Reset (InFile,1); {$I+} IORes:=IOResult;
     IF (IORes <> 0) THEN
     BEGIN
          WriteLn ('Error opening NODELIST.TDB');
          Exit;
     END;

     FidoSplit (ParamStr (1),FAddr);
     WriteLn ('Searching for ',FAddr.Zone,':',FAddr.Net,'/',FAddr.Node);
     WriteLn;

     AccessCount:=0;
     BytesRead:=0;

     WHILE (FilePos (InFile) < FileSize (InFile)) DO
     BEGIN
          BlockRead (InFile,FName,SizeOf (FilenameEntry));
          Inc (AccessCount);
          Inc (BytesRead,SizeOf (FilenameEntry));

          Move (FName.Filename,FNameStr[1],8+1+3);
          FNameStr[0]:=Char (8+1+3);

          WriteLn ('Checking in ',FNameStr);

          WHILE (FName.Length > 0) DO
          BEGIN
               BlockRead (InFile,Zone,SizeOf (ZoneEntry));
               Inc (AccessCount);
               Inc (BytesRead,SizeOf (ZoneEntry));
               Dec (FName.Length,SizeOf (ZoneEntry)+Zone.Length);

               IF (Zone.Zone <> FAddr.Zone) THEN
               BEGIN
                    Seek (InFile,FilePos (InFile)+Zone.Length);
                    Continue; { next zone }
               END;

               WHILE (Zone.Length > 0) DO
               BEGIN
                    BlockRead (InFile,Net,SizeOf (NetEntry));
                    Inc (AccessCount);
                    Inc (BytesRead,SizeOf (NetEntry));
                    Dec (Zone.Length,SizeOf (NetEntry)+Net.ByteNodes+Net.WordNodes*2);

                    IF (Net.Net <> FAddr.Net) THEN
                    BEGIN
                         Seek (InFile,FilePos (InFile)+Net.ByteNodes+Net.WordNodes*2);
                         Continue; { next net }
                    END;

                    IF (Net.ByteNodes > 0) THEN
                    BEGIN
                         BlockRead (InFile,BNodes,Net.ByteNodes);
                         Inc (AccessCount);
                         Inc (BytesRead,Net.ByteNodes);
                         IF (FAddr.Node < 256) THEN
                            FOR Lp:=1 TO Net.ByteNodes DO
                                IF (BNodes[Lp] = FAddr.Node) THEN
                                   GOTO Found;
                    END;

                    IF (Net.WordNodes > 0) THEN
                    BEGIN
                         BlockRead (InFile,WNodes,Net.WordNodes*2);
                         Inc (AccessCount);
                         Inc (BytesRead,Net.WordNodes);
                         FOR Lp:=1 TO Net.WordNodes DO
                             IF (WNodes[Lp] = FAddr.Node) THEN
                                GOTO Found;
                    END;

                    { cannot stop searching here. there might be another }
                    { net entry with the same net number.                }
               END; { while }

          END; { while }
     END; { while }

NotFound:
     WriteLn;
     WriteLn ('Not found.');
     GOTO Einde;

Found:
     WriteLn;
     WriteLn ('Found!');

Einde:
     WriteLn;
     WriteLn ('(',AccessCount,' reads, totalling ',BytesRead,' bytes)');
     Close (InFile);
END.
