{$IFDEF WtrGate}{$IFDEF UseOvr}{$O+,F+}{$ENDIF}{$ENDIF}
UNIT UUCP;

{$i platform.inc}

{ This unit contains all code to interface UUCP spool directory and to }
{ process files found therein. Outbound UUCP jobs are handled in the   }
{ MAKEOUT unit.                                                        }


{ search for ## for changes to made because of multi-recipient handling }


INTERFACE

PROCEDURE UucpToss;
PROCEDURE BagToss;


IMPLEMENTATION

USES Ramon,
     Dos,
     Logs,
     Cfg,
     Globals,
     Start,
     Database,
     Userbase,  { PacketUserData }
     FBuffer,
     Address,
     Msgs,
     Cun,
     NewExec,
     Usenet,
     AreaBase,  { AreaCreatorUserBaseRecNr }
     {Stats,}
     NewStats,
     Slice,
     Routing;   { temp, for UUPCMode }

VAR LastDFilenameTry : BYTE;
    DFile            : FBufferType;


{--------------------------------------------------------------------------}
{ FilenameUnix2Waffle                                                      }
{                                                                          }
{ Deze routine doet een filename conversie net als Waffle. Het algoritme   }
{ is als volgt: Zet de extensie die nu vooraan staat achteraan, haal de    }
{ systeem naam weg en neem het restant. Geef alle lowercase chrs een 1 en  }
{ alle uppercase en nummers een 0. Doet dit alleen met de laatste 5 tekens }
{ en maak hiervan een bitmap. De waarde van de bitmap is geeft een teken   }
{ dat ervoor moet worden gezet. Na 0..9 komt A..Z.                         }
{ Voorbeeld: D.ozoneBC0312 -> \SPOOL\OZONE\0BC0312.D                       }
{            X.ozoneXC0312 -> \SPOOL\OZONE\0XC0312.X                       }
{            D.ozoneB7n72  -> \SPOOL\OZONE\4S7N72.D                        }
{            X.ozoneX7pt0  -> \SPOOL\OZONE\6X7PT0.X                        }
{ Dit wordt ook wel Filename Munging genoemd.                              }
{                                                                          }
{ RvdW 16-05-93 Foutje verbeterd. Aan het einde wordt gekeken of door de   }
{               bepaalde bitmask een cijfer of een letter voor de naam     }
{               gezet moet worden. 0..8 werden slechts gebruikt, 9 niet.   }
{               Door de vergelijking van "< 9" in "< 10" te veranderen was }
{               de fout verholpen. Door de fout kwamen .D filenamen voor   }
{               die begonnen met een @...                                  }
{                                                                          }
FUNCTION FilenameUnix2Waffle (OrgUnixFilename : STRING;
                              UUCPName : UUCPNameString) : FilenameString;

VAR NewName      : STRING;
    UnixFilename : STRING[79];
    Lp,
    BitMask      : BYTE;

BEGIN
     UnixFilename:=OrgUnixFilename;

     IF (Pos ('.',UnixFilename) > 0) THEN
     BEGIN
          NewName:='.'+Copy (UnixFilename,1,Pos ('.',UnixFilename)-1);
          Delete (UnixFilename,1,Pos ('.',UnixFilename));
     END ELSE
     BEGIN
          NewName:='';
          {LogMessage ('[FilenameUnix2Waffle] Period (.) not in unix style name: '+OrgUnixFilename);}
     END;

     { UUCPnames worden door Waffle afgekort tot de 7 tekens }
     IF (Length (UUCPName) > 7) THEN
        IF (UpCaseString (Copy (UnixFilename,1,7)) = Copy (UUCPName,1,7)) THEN
           Delete (UnixFilename,1,7)
        ELSE BEGIN
             { Ander formaat, nodes die een verkorte UUCP name in een file }
             { name gebruiken werden niet correct geparsed... hopelijk     }
             { werkt die wel we strippen nu het gedeelte dat overeenkomt   }
             { met de UUCP name van de filename af.                        }
             FOR Lp:=1 TO Length (UUCPName) DO
                 IF (UpCase (UnixFileName[1]) = UpCase (UUCPName[Lp])) THEN
                    Delete (UnixFileName,1,1)
                 ELSE
                     Break; { uit de for }
        END ELSE
            {LogMessage ('[FilenameUnix2Waffle] UUCPName ('+UUCPName+') not in unix style name: '+OrgUnixFilename)}
            IF (UpCaseString (Copy (UnixFilename,1,Length (UUCPName))) = UUCPName) THEN
               Delete (UnixFilename,1,Length (UUCPName))
            ELSE
                FOR Lp:=1 TO Length (UUCPName) DO
                    IF Upcase(UnixFileName[1]) = Upcase(UUCPName[Lp]) THEN
                       Delete (UnixFileName,1,1)
                    ELSE
                        Break; { uit de for }

     {LogMessage ('[FilenameUnix2Waffle] UUCPName ('+UUCPName+') not in unix style name: '+OrgUnixFilename); }

     BitMask:=0;

     { Bugfix: De teller liep van (X) tot (X-5), ofwel 6            }
     { verschillende waardes terwijl er maar 5 geteld mogen worden. }
     FOR Lp:=Length (UnixFileName) DOWNTO Length (UnixFilename)-4 DO
     BEGIN
          IF (UnixFilename[Lp] IN ['a'..'z']) THEN
             BitMask:=BitMask OR (1 SHL (Length (UnixFilename)-Lp));
     END;

     { Is dit de oplossing ???????                                   }
     { Er zijn maximaal 36 mogenlijke tekens, maar 255 verschillende }
     { waardes.                                                      }

     { BitMask := BitMask MOD 36; }

     IF (BitMask < 10) THEN UnixFilename:=Chr (48+BitMask)+UnixFilename
                       ELSE UnixFilename:=Chr (55+BitMask)+UnixFilename;

     FilenameUnix2Waffle:=UpCaseString (Copy (UnixFilename,1,8))+NewName;
END;


{--------------------------------------------------------------------------}
{ Uucp_FindAndOpenDFile                                                    }
{                                                                          }
{ Deze routine gaat op zoek naar de juiste D filename en de methode om die }
{ te bepalen. Na de eerste keer onthoudt ie welke methode gebruikt is en   }
{ die wordt bij de volgende doorgang weer gebruikt, zodat het geheel       }
{ sneller doorlopen wordt. Als de file geopend kon worden, dan wordt TRUE  }
{ terug gegeven en in DFilename de uiteindelijke naam, anders FALSE.       }
{                                                                          }
FUNCTION Uucp_FindAndOpenDFile (Path : PathString;           { spool dir path, incl. \ }
                                UUCPName,                    { uit user record }
                                Filename,                    { .X I-regel }
                                OtherUUCPName : STRING;      { UUCPname uit .X U-regel }
                                VAR DFilename : STRING) : BOOLEAN;

VAR Tried    : ARRAY[1..4] OF BOOLEAN;
    TryNames : STRING;
    Lp       : BYTE;
    CurrTry  : BYTE;
    BitMask  : BYTE;

BEGIN
     FOR Lp:=1 TO 4 DO
         Tried[Lp]:=FALSE;

     CurrTry:=LastDFilenameTry;
     TryNames:='';

     WHILE TRUE DO
     BEGIN
          { stel de DFilename samen op deze manier }

          CASE CurrTry OF

                   { met de UUCPname uit het user record }
               1 : DFilename:=FileNameUnix2Waffle (FileName,UUCPName);

                   { met de UUCPname uit de U-regel van de .X file }
               2 : DFilename:=FileNameUnix2Waffle (FileName,OtherUUCPName);

                   { met onze systeem UUCPname }
               3 : DFilename:=FileNameUnix2Waffle (FileName,Config.UUCPName);

                   { met een speciale conversie: munged laatste 7 tekens uit I regel }
               4 : BEGIN
                        { deze actie kan ook een deel van de UUCPname }
                        { meenemen. Bijvoorbeeld:                     }
                        { D.chard4bc2  -> ard4bc2  -> MARD4BC2        }

                        DFilename:=Copy (Filename,Length (Filename)-6,7);

                        { nu nog mungen }
                        BitMask:=0;

                        FOR Lp:=Length (DFileName) DOWNTO Length (DFilename)-4 DO
                        BEGIN
                             IF (DFilename[Lp] IN ['a'..'z']) THEN
                                BitMask:=BitMask OR (1 SHL (Length (DFilename)-Lp));
                        END;

                        IF (BitMask < 10) THEN DFilename:=Chr (48+BitMask)+DFilename
                                          ELSE DFilename:=Chr (55+BitMask)+DFilename;

                        IF (Pos ('.',Filename) > 0) THEN
                           DFilename:=DFilename+'.'+Copy (Filename,1,Pos ('.',Filename)-1)
                        ELSE
                            DFilename:=DFilename+'.';

                        DFilename:=UpCaseString (DFilename);
                   END;
          END; { case }

          { filename is nu samengesteld. Kijk of deze ook voorkomt in het }
          { rijtje met namen die we al geprobeerd hebben, want dan slaan  }
          { we deze gewoon over.                                          }

          IF (TryNames = '') OR (Pos (DFilename,TryNames) = 0) THEN
          BEGIN
               { nog niet geprobeerd met deze naam }
               IF FBufferOpen (DFile,Path+DFilename,10000,0) THEN
               BEGIN
                    { gelukt! }

                    { onthoud welke methode succesvol was }
                    LastDFilenameTry:=CurrTry;

                    Uucp_FindAndOpenDFile:=TRUE;
                    Exit;
               END;

               { mislukt. Vergeet nu niet te sluiten }
               FBufferClose (DFile);

               IF (TryNames <> '') THEN
                  TryNames:=TryNames+', ';

               TryNames:=TryNames+DFilename;

          END; { filename niet al geprobeerd }

          { niet gelukt op deze manier }
          Tried[CurrTry]:=TRUE;

          CurrTry:=0;
          FOR Lp:=1 TO 4 DO
              IF (NOT Tried[Lp]) THEN
              BEGIN
                   CurrTry:=Lp;
                   Break; { uit de for }
              END;

          IF (CurrTry = 0) THEN
          BEGIN
               { allemaal gehad. Keer terug met FALSE }
               LogMessage (liFatal,'Failed to find .D file!');
               LogExtraMessage ('Tried: '+TryNames);
               DFilename:=''; { prevent problems }
               Uucp_FindAndOpenDFile:=FALSE;
               Exit;
          END;
     END; { while }
END;


{--------------------------------------------------------------------------}
{ FilenameUnix2Uupc                                                        }
{                                                                          }
{ Examples:                                                                }
{ In: Unix="D.inruhrd0N38", UUCPName="INRUHR" -> ""                        }
{                                                                          }
FUNCTION FilenameUnix2Uupc (UnixFilename : STRING;
                            UUCPName : UUCPNameString) : FilenameString;

CONST DosChars : STRING[52] = '!#$%&''()-0123456789@^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{}~';

VAR NewName   : STRING[20];
    Lp        : BYTE;
    Hulp      : BYTE;

    Number    : ARRAY[1..20] OF BYTE;

    PROCEDURE _Add (A : WORD);

    VAR L     : BYTE;
        Carry : WORD;
        Value : WORD;

    BEGIN
         Carry:=A;
         FOR L:=20 DOWNTO 1 DO
             IF (A > 0) THEN
             BEGIN
                  Value:=Number[L]+Carry;
                  Number[L]:=Value MOD 256;
                  Carry:=Value DIV 256;
             END;
    END;

    PROCEDURE _Mult (N : BYTE);

    VAR L     : BYTE;
        Carry : WORD;
        Value : WORD;

    BEGIN
         Carry:=0;
         FOR L:=20 DOWNTO 1 DO
         BEGIN
              Value:=Number[L]*N+Carry;
              Number[L]:=Value MOD 256;
              Carry:=Value DIV 256;
         END;
    END;

    FUNCTION _Div (N : BYTE; VAR A : BYTE) : BOOLEAN;

    VAR L     : BYTE;
        Value : WORD;

    BEGIN
         _Div:=FALSE;
         A:=0;
         FOR L:=1 TO 20 DO
         BEGIN
              Value:=A*256+Number[L];
              IF (Number[L] > 0) THEN
                 _Div:=TRUE;
              A:=Value MOD N;
              Number[L]:=Value DIV N;
         END;
    END;

{FilenameUnix2Uupc}

BEGIN
     IF (UnixFilename[1] IN ['A'..'Z']) AND (UnixFilename[2] = '.') THEN
        Delete (UnixFilename,1,2);

     { remove as many characters of the UUCP name found at the start }
     { of the UnixFilename.                                          }
     Hulp:=0;
     FOR Lp:=1 TO Length (UUCPName) DO
         IF (UpCase (UnixFileName[1]) = UpCase (UUCPName[Lp])) THEN
         BEGIN
              Inc (Hulp);
              Delete (UnixFileName,1,1);
         END ELSE
             Break; { uit de for }

     { the "magic" part }
     FOR Lp:=1 TO 20 DO
         Number[Lp]:=0;

     { multiply and add }
     _Add (Hulp*8);

     FOR Lp:=1 TO Length (UnixFilename) DO
     BEGIN
          Hulp:=Ord (UnixFilename[Lp])-Ord ('#');
          _Mult (88);  { 88 is range from # to z }
          _Add (Hulp);
     END;

     { divide again }
     NewName:='';
     WHILE _Div (52,Hulp) DO
           NewName:=DosChars[1+Hulp]+NewName;

     FilenameUnix2Uupc:='D\'+NewName;
END;


{--------------------------------------------------------------------------}
{ Uupc_FindAndOpenDFile                                                    }
{                                                                          }
{ This routine tries to munge the job name to the filename format used by  }
{ UUPC, find the file and open it. If succesful, it returns TRUE,          }
{ otherwise FALSE.                                                         }
{                                                                          }
FUNCTION Uupc_FindAndOpenDFile (Path : PathString;           { spool dir path, incl. \ }
                                UUCPName,                    { uit user record }
                                Filename,                    { .X I-regel }
                                OtherUUCPName : STRING;      { UUCPname uit .X U-regel }
                                VAR DFilename : STRING) : BOOLEAN;

VAR Tried    : ARRAY[1..3] OF BOOLEAN;
    TryNames : STRING;
    Lp       : BYTE;
    CurrTry  : BYTE;
    BitMask  : BYTE;

BEGIN
     FOR Lp:=1 TO 3 DO
         Tried[Lp]:=FALSE;

     CurrTry:=LastDFilenameTry;
     TryNames:='';

     WHILE TRUE DO
     BEGIN
          { stel de DFilename samen op deze manier }

          CASE CurrTry OF
                   { met de UUCPname uit het user record }
               1 : DFilename:=FileNameUnix2Uupc (FileName,UUCPName);

                   { met de UUCPname uit de U-regel van de .X file }
               2 : DFilename:=FileNameUnix2Uupc (FileName,OtherUUCPName);

                   { met onze systeem UUCPname }
               3 : DFilename:=FileNameUnix2Uupc (FileName,Config.UUCPName);

          END; { case }

          { filename is nu samengesteld. Kijk of deze ook voorkomt in het }
          { rijtje met namen die we al geprobeerd hebben, want dan slaan  }
          { we deze gewoon over.                                          }

          IF (TryNames = '') OR (Pos (DFilename,TryNames) = 0) THEN
          BEGIN
               { nog niet geprobeerd met deze naam }
               IF FBufferOpen (DFile,Path+DFilename,10000,0) THEN
               BEGIN
                    { gelukt! }

                    { onthoud welke methode succesvol was }
                    LastDFilenameTry:=CurrTry;

                    Uupc_FindAndOpenDFile:=TRUE;
                    Exit;
               END;

               { mislukt. Vergeet nu niet te sluiten }
               FBufferClose (DFile);

               IF (TryNames <> '') THEN
                  TryNames:=TryNames+', ';

               TryNames:=TryNames+DFilename;

          END; { filename niet al geprobeerd }

          { niet gelukt op deze manier }
          Tried[CurrTry]:=TRUE;

          CurrTry:=0;
          FOR Lp:=1 TO 3 DO
              IF (NOT Tried[Lp]) THEN
              BEGIN
                   CurrTry:=Lp;
                   Break; { uit de for }
              END;

          IF (CurrTry = 0) THEN
          BEGIN
               { allemaal gehad. Keer terug met FALSE }
               LogMessage (liFatal,'Failed to find .D file!');
               LogExtraMessage ('Tried: '+TryNames);
               DFilename:=''; { prevent problems }
               Uupc_FindAndOpenDFile:=FALSE;
               Exit;
          END;
     END; { while }
END;


{--------------------------------------------------------------------------}
{ Uucp_TossNewsDFile                                                       }
{                                                                          }
{ Deze routine leest een .D file met Usenet NEWS in. Deze file             }
{ heeft als EOF teken een #22. Mocht deze er niet staan, dan wordt het     }
{ fysieke einde van de file ook als EOF gezien.                            }
{ Deze routine geeft sinds RWI950322 een byte terug ipv een boolean. De    }
{ volgende return waarden zijn mogelijk:                                   }
{                                                                          }
{ 0 - .D file is verwerkt en verwijderd -> .X file mag nu ook weg.         }
{ 1 - .D file kon niet gevonden worden  -> .X file moet nog even blijven.  }
{ 2 - Problem bij het verwerken van de                                     }
{     .D en is hernoemd naar .DRR       -> .X ook hernoemen (naar .XRR)    }
{                                                                          }
FUNCTION Uucp_TossNewsDFile (Path : PathString;
                             UUCPName,Filename,OtherUUCPName : STRING;
                             VAR DFilename : STRING) : BYTE;

CONST ErrFnc : STRING[16] = '[TossNewsDFile] ';

VAR Regel      : STRING;
    CunBatch,
    DeGZip,
    DeCompress : BOOLEAN;
    AFile      : FILE;
    IORes      : BYTE;
    PrevHad13  : BOOLEAN;  { RWI 960601 }
    Decomp     : CompUUCPType;

BEGIN
     Uucp_TossNewsDFile:=1; { assume .D file could not be found }

     IF Config.UUPCMode THEN
     BEGIN
          IF (NOT Uupc_FindAndOpenDFile (Path,UUCPName,Filename,OtherUUCPName,DFilename)) THEN
             Exit; { met exit code 1 }
     END ELSE
     BEGIN
          IF (NOT Uucp_FindAndOpenDFile (Path,UUCPName,Filename,OtherUUCPName,DFilename)) THEN
             Exit; { met exit code 1 }
     END;

     IF Config.LogSpoolTossed THEN
        LogMessage (liTrivial,'  Processing (news) '+DFilename);

     UpdateReadFile ('(news) '+Path+DFilename,FileSize (DFile.Bestand));

     Uucp_TossNewsDFile:=2; { assume problems (case "rename em") }

     { kijken of er nog gepreprocessed moet worden }
     IF (NOT FBBlockPeek (DFile,Regel[1],13)) THEN
     BEGIN
          FBufferClose (DFile);
          LogMessage (liFatal,ErrFnc+'Peek error 1 with '+Path+DFilename+', skipping file');
          Exit;
     END;

     Regel[0]:=#11; { lengte van de string invullen }

     IF (Regel = '#! cunbatch') OR (Regel = '#! gunbatch') OR (Regel = '#! zunbatch') THEN
     BEGIN
          CunBatch:=TRUE;
          FBBlockRead (DFile,Regel[1],12); { lees de CunBatch+#13/#10 weg }

          { RWI 961029: Now allowing CR,LF }
          IF (Regel[12] = #13) THEN
             FBBlockRead (DFile,Regel[13],1);

          { read the two next bytes for compressor detection }
          IF (NOT FBBlockPeek (DFile,Regel[1],2)) THEN
          BEGIN
               FBufferClose (DFile);
               LogMessage (liFatal,ErrFnc+'Peek error 2 with '+Path+DFilename+', skipping file');
               Exit;
          END;
     END ELSE
         CunBatch:=FALSE;

     DeCompress:=((Regel[1] = #31) AND (Regel[2] = #157));
     DeGZip:=((Regel[1] = #31) AND (Regel[2] = #139));

     FBufferClose (DFile);

     { CunBatch verwijderen met check of het gelukt is }
     IF CunBatch THEN
        IF NOT DelCun (Path+DFilename) THEN
        BEGIN
             LogMessage (liFatal,'Execution of DeCunBatch failed, skipping file: '+Path+DFilename);
             Exit;
        END;

     { decompress de file, met check of het gelukt is }
     IF DeCompress OR DeGZip THEN
     BEGIN
          { if there is no dot, then the filename can be too long (>8)  }
          { so we have to cut it down to eight and then add a dummy dot }
          IF (Pos ('.',DFilename) = 0) THEN
             Regel:=Copy (DFilename,1,8)+'.DZ'
          ELSE
              Regel:=Copy (DFilename,1,Pos ('.',DFilename))+'DZ';

          Assign (AFile,Path+DFilename);
          {$I-} Rename (AFile,Path+Regel); {$I+} IORes:=IOResult;
          IF (IORes <> 0) THEN
          BEGIN
               LogDiskIOError (IORes,ErrFnc+'Renaming to .DZ failed, skipping file: '+Path+DFilename);
               Exit;
          END;

          IF DeGZip THEN
             Decomp:=GZip
          ELSE
              Decomp:=Compress;

          GoExec (Config.ComprPrg_U[Decomp,DeCompr],Path+Regel,'Decompressing news archive');

          IF (ExecRes <> 0) THEN
          BEGIN
               LogMessage (liFatal,ErrFnc+'Execution of decompressor failed, skipping file: '+Path+DFilename);
               Exit;
          END;

          { remove the Z }
          Delete (Regel,Length (Regel),1);

          IF (Regel <> DFilename) THEN
          BEGIN
               { UUPC case }
               Assign (AFile,Path+Regel);
               {$I-} Rename (AFile,Path+DFilename); {$I+} IORes:=IOResult;
               IF (IORes <> 0) THEN
               BEGIN
                    LogDiskIOError (IORes,ErrFnc+'Error renaming '+Path+Regel+' to '+Path+DFilename);
                    Exit;
               END;
          END;

          IF (NOT FBufferOpen (DFile,Path+DFilename,10000,0)) THEN
          BEGIN
               FBufferClose (DFile);
               LogMessage (liFatal,ErrFnc+'Cannot open file (after decompressing): '+Path+Regel);
               Exit;
          END;

          { RWI 960322: lege files worden nu verwijderd en ignored }
          IF (FileSize (DFile.Bestand) = 0) THEN
          BEGIN
               LogMessage (liGeneral,'Skipping empty news batch');

               FBufferClose (DFile);

               {$I-} Erase (DFile.Bestand); {$I+} IORes:=IOResult;
               IF (IORes <> 0) THEN
                  LogDiskIOError (IORes,ErrFnc+'Error deleting empty news batch');

               Uucp_TossNewsDFile:=0; { verwerkt -> verwijder .X file }
               Exit;
          END;

          IF (NOT FBBlockPeek (DFile,Regel[1],2)) THEN
          BEGIN
               FBufferClose (DFile);
               LogMessage (liFatal,ErrFnc+'Peek error 2 with '+Path+DFilename+' (after decompressing), skipping file');
               Exit;
          END;

          FBufferClose (DFile);

          IF (Regel[1] = #31) AND (Regel[2] IN [#157{Compress},#139{GZip}]) THEN
          BEGIN
               LogMessage (liFatal,ErrFnc+'Decompression failed, skipping file: '+Path+DFilename);
               Exit;
          END;
     END; { DeCompress }

     { verwerk de nu gedecunbatchte en gedecompressde file }
     IF (NOT FBufferOpen (DFile,Path+DFilename,10000,0)) THEN
     BEGIN
          FBufferClose (DFile);
          LogMessage (liFatal,'[UsenetTossNewsDFile] Cannot open just decompressed file '+Path+DFilename);
          Exit;
     END;

     UpdateInfoNr (INFO_UucpIn_Jobs,1);

     MsgsEmptyKeepDeliveringUser;

     RFC_AddWhereTo:=Header_U; { gebeurd anders bij "#! rnews" detectie }
     PrevHad13:=FALSE;

     WHILE FBReadLnLF (DFile,Regel) DO
           RFC_AddTossedRegel (Regel,PrevHad13);

     Msg.Ready_U:=News;    { should be set already! .. not for test jobs }
     RFC_GoProcess;

     { geheugen van laatste msg weer vrij geven }
     MsgsEmptyKeepDeliveringUser;

     UpdateInfoNr (INFO_UucpIn_Bytes,FileSize (DFile.Bestand));

     FBufferClose (DFile);

     { .D file laten wissen }
     {$I-} Erase (DFile.Bestand); {$I+} IORes:=IOResult;
     IF (IORes <> 0) THEN
        LogDiskIOError (IORes,'[UsenetTossNewsDFile] Cannot delete .D file: '+Path+DFilename);

     Uucp_TossNewsDFile:=0; { verwerkt -> verwijder .X file }
END;


{--------------------------------------------------------------------------}
{ Uucp_TossMailDFile                                                       }
{                                                                          }
{ Deze routine leest een .D file met mail in en haalt relevante gegevens   }
{ uit de header. Als TRUE terug gegeven wordt dan is de .D gevonden en     }
{ verwerkt en kan de .X verwijderd worden.                                 }
{                                                                          }
FUNCTION Uucp_TossMailDFile (Path : PathString;
                             UUCPName,Filename,OtherUUCPName : STRING;
                             DFilename : STRING) : BOOLEAN;

VAR Regel     : STRING;
    DeleteEm  : BOOLEAN;
    IORes     : BYTE;
    PrevHad13 : BOOLEAN;
    P         : BYTE;
    OldNews,
    OldMail   : LONGINT;

BEGIN
     Uucp_TossMailDFile:=FALSE; { .X laten staan, .D was er (nog) niet }

     IF Config.UUPCMode THEN
     BEGIN
          IF (NOT Uupc_FindAndOpenDFile (Path,UUCPName,Filename,OtherUUCPName,DFilename)) THEN
             Exit; { met exit code 1 }
     END ELSE
     BEGIN
          IF (NOT Uucp_FindAndOpenDFile (Path,UUCPName,Filename,OtherUUCPName,DFilename)) THEN
             Exit; { met exit code 1 }
     END;

     IF Config.LogSpoolTossed THEN
        LogMessage (liTrivial,'  Processing (mail) '+DFilename);

     UpdateReadFile ('(mail) '+Path+DFilename,FileSize (DFile.Bestand));

     UpdateInfoNr (INFO_UucpIn_Jobs,1);

     { initialiseer envelope }
     RFC_AddWhereTo:=Header_U; { gebeurt bij news anders bij "#! rnews" detectie }
     PrevHad13:=FALSE;

     Msg.Ready_U:=Mail;

     { read the first line from disk }
     FBReadLnLF (DFile,Regel);

     IF (NOT CaselessStartMatch (Regel,'From ')) THEN
     BEGIN
          LogMessage (liGeneral,'UUCP job does not start with From_ header!');
          RFC_AddTossedRegel (Regel,PrevHad13);
     END ELSE
     BEGIN
          { From_ line updating removed }
          {## could put From_ updating back in, but only when the mail }
          {## comes from a downlink; never when coming from an uplink. }

          { store the line }
          { UUCP outbound will add it again }

          Msg.UUCP_From_:=Regel;
     END;

     { Received: by dijkline.wlink.nl (0.01 beta/WaterGate) }
     {           via UUCP; Sat, 10 Jul 93 00:06:50 +0100    }
     {           for martijnd@htsa.aha.nl                   }

     Regel:='Received: by '+UseGetSystemFromName+' ('+ProgramShortName+' '+MainRevisionNr+')'+#13;
     RFC_AddTossedRegel (Regel,PrevHad13);

     Regel:='          via UUCP; '+UsenetArpaNetDate+#13;
     RFC_AddTossedRegel (Regel,PrevHad13);

     { ID toevoegen? }

     {##}
     (* now multiple addresses..
     Regel:='          for '+Msg.XqtTo_U+#13;
     RFC_AddTossedRegel (Regel,PrevHad13);
     *)

     WHILE FBReadLnLF (DFile,Regel) DO
           RFC_AddTossedRegel (Regel,PrevHad13);

     UpdateInfoNr (INFO_UucpIn_Bytes,FileSize (DFile.Bestand));

     {### stats}
     {
     UpdateUserStats (Msg.DeliveringUserRecNr,MailFrom,Msg.MsgSize);
     }

     {Msg.ToSystem_U:=PacketUserData.UUCPName;     { ivm ForceFileFull }

     { check for existance of Msg.FromUser_U removed }

     { For statistics: save old UUCP News/mail count, so that we can count }
     { the number of messages in this job.                                 }
     OldMail := RetrieveInfoNr (INFO_UucpIn_Mail);
     OldNews := RetrieveInfoNr (INFO_UucpIn_News);

     { nu aan alle mogelijke adresses afleveren }
     RFC_GoProcess;

     StatEntry_UUCPJob (stdInbound, PacketUserData.UUCPName, 'LOCAL',
                              FileSize (DFile.Bestand),
                              RetrieveInfoNr (INFO_UucpIn_News) - OldNews,
                              RetrieveInfoNr (INFO_UucpIn_Mail) - OldMail);

     FBufferClose (DFile);

     { .D file wissen als er geen fouten waren }
     {$I-} Erase (DFile.Bestand); {$I+} IORes:=IOResult;
     IF (IORes <> 0) THEN
        LogDiskIOError (IORes,'[Uucp_TossMailDFile] Error deleting '+DFilename);

     Uucp_TossMailDFile:=TRUE; { delete X }
END;


{--------------------------------------------------------------------------}
{ Uucp_TossXFile                                                           }
{                                                                          }
{ This routine processes a found .X files. PacketUserData must contain the }
{ record of the sending user. The pairing .D file is searched for and both }
{ are processed.                                                           }
{                                                                          }
PROCEDURE Uucp_TossXFile (XDPath : STRING; XFileName : FilenameString; UUCPName : UUCPNameString);

VAR XFile  : FBufferType;
    Regel  : STRING;
    EMail  : STRING;
    CmdCh  : CHAR;
    AFile  : FILE;
    Search : SearchRec;
    IORes  : BYTE;
    Error  : BYTE;

    Data_F        : STRING; { strings later op lengte maken }
    Data_I        : STRING;
    Data_C        : STRING;
    Data_R        : STRING;
    Data_U_Login  : STRING;
    Data_U_System : STRING[MaxLenUUCPName];
    DFilename     : STRING[79];

    {----------------------------------------------------------------------}
    { RenameXFile .D -> .BAD en .X->.BAX                                   }
    {                                                                      }
    PROCEDURE RenameXFileAndDFile;

    VAR NewName : STRING[15];
        AddedZ  : BOOLEAN;

    BEGIN
         IF Config.UUPCMode THEN
         BEGIN
              LogMessage (liDebug,'Cannot rename to .BAX/.BAD in UUPC mode yet');
              Exit;
         END;

         AddedZ:=TRUE;

         { zowel .X file renamen naar *.BAX }
         LogExtraMessage ('  Renaming '+XFilename+' to .BAX');
         NewName:=Copy (XFilename,1,Pos ('.',XFilename))+'BAX';

         Assign (AFile,XDPath+XFileName);
         {$I-} Rename (AFile,XDPath+NewName); {$I+} IORes:=IOResult;
         IF (IORes <> 0) THEN
            LogDiskIOError (IORes,'[DeleteXFile] Error renaming file '+
                                  XDPath+XFileName+' to '+XDPath+NewName);

         IF (DFilename = '') THEN
            Exit; { not effective yet }

         LogExtraMessage ('  Renaming '+DFilename+' to .BAD');
         NewName:=Copy (DFilename,1,Pos ('.',DFilename))+'BAD';

         Assign (AFile,XDPath+DFilename);
         {$I-} Rename (AFile,XDPath+NewName); {$I+} IORes:=IOResult;
         IF (IORes = 2) THEN
         BEGIN
              { probeer het nog eens, maar nu met .DZ }
              DFilename:=DFilename+'Z';
              AddedZ:=TRUE;
              Assign (AFile,XDPath+DFilename);
              {$I-} Rename (AFile,XDPath+NewName); {$I+} IORes:=IOResult;
         END;

         IF (IORes <> 0) THEN
            LogDiskIOError (IORes,'[DeleteDFile] Error renaming file '+
                                  XDPath+DFilename+' to '+XDPath+NewName);

         { restore DFilename file is modified }
         IF AddedZ THEN
            Delete (DFilename,Length (DFilename),1);
    END;


    {----------------------------------------------------------------------}
    { DeleteXFile                                                          }
    {                                                                      }
    { Beide files zijn gebruikt voor verwerking en kunnen nu fietsen.      }
    {                                                                      }
    PROCEDURE DeleteXFile;

    VAR AFile : FILE;
        IORes : BYTE;

    BEGIN
         Assign (AFile,XDPath+XFilename);
         {$I-} Erase (AFile); {$I+} IORes:=IOResult;
         IF (IORes <> 0) THEN
            LogDiskIOError (IORes,'[DeleteXFile] Error deleting '+XDPath+XFilename);
    END;

{ Uucp_TossXFile }

VAR P     : BYTE;
    HadCR : BOOLEAN;

BEGIN
     IF (NOT CheckMinDiskFree) THEN
        Exit;

     IF Config.UUPCMode THEN
     BEGIN
          IF (NOT FBufferOpen (XFile,XDPath+XFilename,256,0)) THEN
          BEGIN
               FBufferClose (XFile);
               LogMessage (liFatal,'Could not open just found .X file: '+XDPath+XFileName);
               Exit;
          END;
     END ELSE
     BEGIN
          IF (NOT FBufferOpen (XFile,XDPath+XFilename,256,0)) THEN
          BEGIN
               FBufferClose (XFile);
               LogMessage (liFatal,'Could not open just found .X file: '+XDPath+XFileName);
               Exit;
          END;
     END;

     { clears dest list as well }
     MsgsEmptyKeepDeliveringUser;

     IF Config.LogSpoolTossed THEN
        LogMessage (liTrivial,'  Processing '+XFilename);

     Data_C:='';
     Data_I:='';        { invoer file, voor inlezen .D file }
     Data_F:='';
     Data_R:='';
     Data_U_Login:='';
     Data_U_System:=''; { UUCPName van het sturende systeem }
     DFilename:='';

     WHILE FBReadLnLF (XFile,Regel) DO
     BEGIN
          IF (Regel[Length (Regel)] = #13) THEN
          BEGIN
               HadCR:=TRUE;
               Delete (Regel,Length (Regel),1);
          END ELSE
              HadCR:=FALSE;

          Regel:=DeleteBackSpaces (Regel);

          IF (Regel = '') THEN
             Continue;

          CmdCh:=Regel[1];

          Delete (Regel,1,1);
          Regel:=DeleteFrontSpaces (Regel);

          CASE CmdCh OF
               'C' :
                   BEGIN { Command line }
                        P:=Pos (' ',Regel);

                        IF (P = 0) THEN
                           Data_C:=UpCaseString (Regel)
                        ELSE BEGIN
                             Data_C:=UpCaseString (Copy (Regel,1,P-1));
                             Delete (Regel,1,P);
                             Regel:=DeleteFrontSpaces (Regel);

                             IF (Data_C = 'RMAIL') THEN
                             BEGIN
                                  { RWI961230 ivm GIGOT jobs.. :( }
                                  { Remove "C rmail 0 ramon@wsd.wline.se" }
                                  {    and "C rmail U ramon@wsd.wline.se" }
                                  IF (Length (Regel) > 2) AND (Regel[2] = ' ') AND (Regel[3] <> ' ') THEN
                                     Delete (Regel,1,2);

                                  { process each and every recipient name }
                                  IF HadCR THEN
                                     Regel:=Regel+#13;

                                  REPEAT
                                        Regel:=DeleteFrontSpaces (Regel);

                                        P:=Pos (' ',Regel);

                                        IF (P > 0) THEN
                                        BEGIN
                                             EMail:=Copy (Regel,1,P-1);
                                             Delete (Regel,1,P);
                                        END ELSE
                                        BEGIN
                                             { check if last on line }
                                             P:=Pos (#13,Regel);

                                             IF (P > 0) THEN
                                             BEGIN
                                                  EMail:=Copy (Regel,1,P-1);
                                                  Regel:=#13; { should be last }
                                             END ELSE
                                             BEGIN
                                                  { read next line }
                                                  EMail:=Regel;

                                                  IF FBReadLnLF (XFile,Regel) THEN
                                                  BEGIN
                                                       { read a new line }
                                                       { complete address in Email }
                                                       P:=Pos (' ',Regel);
                                                       IF (P > 0) THEN
                                                       BEGIN
                                                            EMail:=Email+Copy (Regel,1,P-1);
                                                            Delete (Regel,1,P);
                                                       END ELSE
                                                       BEGIN
                                                            { last part of last address? }
                                                            P:=Pos (#13,Regel);
                                                            IF (P > 0) THEN
                                                            BEGIN
                                                                 EMail:=EMail+Copy (Regel,1,P-1);
                                                                 Regel:=#13;
                                                            END ELSE
                                                            BEGIN
                                                                 { unexpected end }
                                                                 EMail:=EMail+Regel;
                                                                 LogMessage (liFatal,'Unexpected on C line (2): "'+Regel+'"');
                                                                 Regel:=#13;
                                                            END;
                                                       END;
                                                  END ELSE
                                                  BEGIN
                                                       { nothing more to read }
                                                       { if something is left on }
                                                       { Regel and it is not #13 }
                                                       { then just process it }
                                                       LogMessage (liFatal,'Unexpected on C line (1): "'+Regel+'"');
                                                       Regel:=#13;
                                                  END;
                                             END;
                                        END;

                                        Address_AddRFCRaw (Email,destTo,FALSE,FALSE);

                                  UNTIL (Regel = #13);

                             END; { if "C rmail" }
                        END; { if spatie in "C" regel }
                   END; { C }

               'I' :
                   Data_I:=Regel; { Standard Input }

               'F' :
                   BEGIN { Required file filename-to-use }
                        { kan twee argumenten hebben, neem altijd de 1e }
                        IF (Pos (' ',Regel) = 0) THEN
                           Regel:=Regel+' ';
                        Data_F:=Copy (Regel,1,Pos (' ',Regel));
                   END;

               'R' :
                   Data_R:=Regel; { requestor address } { voor terugsturen mail? }

               'U' :
                   BEGIN { user system }
                        IF (Pos (' ',Regel) = 0) THEN
                           Regel:=Regel+' ';
                        Data_U_Login:=Copy (Regel,1,Pos (' ',Regel)-1);
                        Delete (Regel,1,Pos (' ',Regel));

                        IF (Pos (' ',Regel) = 0) THEN
                           Regel:=Regel+' ';
                        Data_U_System:=Copy (Regel,1,Pos (' ',Regel)-1);
                        Delete (Regel,1,Pos (' ',Regel));
                   END;

               'N' :; { no acknowledge on failure }

               'Z','O','n','B',
               'e','E','M'     :; {('[UsenetTossXFile] Cannot process .X-file code ('+CmdCh+') yet, skipping');}

               '#' :; { remark, skip this line }

             {  ELSE
                   LogMessage ('[UsenetTossXFile] Unknown cmdcode ('+CmdCh+') in '+
                               Config.SpoolBaseDir+UUCPName+'\'+XFileName);         }
          END; { case }
     END; { while }

     FBufferClose (XFile);

     Data_U_System:=UpCaseString (DeleteBackSpaces (Data_U_System));

     IF (Data_C = 'RNEWS') THEN
     BEGIN
          { RWI 951231: geen news tossen als -NONEWSTOSS opgegeven is }
          IF (NOT ForceNoNewsToss) THEN
          BEGIN
               RFC_TossWhat:=twNews; { .X with with rnews }

               { RWI 950212: als pad wordt nu altijd het pad van de .X file }
               {             genomen. Het maakt dan dus niet meer uit       }
               {             welke naam in het U veld stond. Die wordt nu   }
               {             wel gebruikt voor het decoderen van de naam.   }
               CASE Uucp_TossNewsDFile (XDPath,
                                        UUCPName,
                                        Data_I,
                                        Data_U_System,
                                        DFilename)
               OF
                    0 : DeleteXFile; { delete de .X file als de .D nu ook weg is }
                    1 : {niks mee doen, gewoon laten staan};
                    2 : RenameXFileAndDFile;

               END; { case }

          END ELSE
              IF Config.LogSpoolTossed THEN
                 LogMessage (liTrivial,'  Skipping news');

     END ELSE
         IF (Data_C = 'RMAIL') THEN
         BEGIN
              RFC_TossWhat:=twMail; { .X file with email }

              IF Uucp_TossMailDFile (XDPath,UUCPName,
                                     Data_I,Data_U_System,
                                     DFilename)
              THEN
                  DeleteXFile;
         END ELSE
         BEGIN
              LogMessage (liFatal,'Unknown C command in .X file '+XDPath+XFilename);
              RenameXFileAndDFile;
         END;

     { clean up after toss }
     MsgsEmptyKeepDeliveringUser;
END;


{--------------------------------------------------------------------------}
{ Uucp_SearchXFiles                                                        }
{                                                                          }
{ This routine searches the given Path - pointing to a sub-directory of    }
{ the spool directory - for inbound UUCP jobs: .X files. Each are read and }
{ processed.                                                               }
{ PacketUserData should contain the user record of the sending user.       }
{                                                                          }
PROCEDURE Uucp_SearchXFiles (Path : STRING);

VAR Search : SearchRec;
    IORes  : BYTE;
    Stop   : BOOLEAN;

BEGIN
     Stop:=FALSE;

     IF Config.UUPCMode THEN
     BEGIN
          { alle .X files in de X\ subdirectory aflopen }
          FindFirst (Path+'X\*.*',saJustFiles,Search);
          IF (DosError <> 0) AND (DosError <> 18{no more files}) THEN
          BEGIN
               LogDiskIOError (DosError,'Cannot find spool path '+Path+'X\');
               Stop:=TRUE;
          END;
     END ELSE
     BEGIN
          { alle .X files aflopen }
          FindFirst (Path+'*.X',saJustFiles,Search);
          IF (DosError <> 0) AND (DosError <> 18{no more files}) THEN
          BEGIN
               LogDiskIOError (DosError,'Cannot find spool path '+Path);
               Stop:=TRUE;
          END;
     END;

     IF (NOT Stop) THEN
     BEGIN
          IF (DosError = 0) THEN
             LogMessage (liTrivial,'Tossing for '+PacketUserData.UUCPName);

          WHILE (DosError = 0) AND (NOT KeyPressed) DO
          BEGIN
               PeekMem;
               IF Config.UUPCMode THEN
               BEGIN
                    UpdateReadFile (Path+'X\'+Search.Name,Search.Size);
                    Uucp_TossXFile (Path,'X\'+Search.Name,PacketUserData.UUCPName);
               END ELSE
               BEGIN
                    UpdateReadFile (Path+Search.Name,Search.Size);
                    Uucp_TossXFile (Path,Search.Name,PacketUserData.UUCPName);
               END;

               FindNext (Search);
          END; { while more files }
     END;

     FindClose (Search);
END;


{--------------------------------------------------------------------------}
{ UucpToss                                                                 }
{                                                                          }
{ Deze routine zoekt in de spool directories van alle nodes naar .X files  }
{ waarin de namen van de .D files waarin de mail zit. Deze wordt doorgege- }
{ ven aan TossDATFile.                                                     }
{                                                                          }
PROCEDURE UucpToss;

VAR Lp : UserBaseRecordNrType;

BEGIN
     LogMessage (liTrivial,'UUCP toss started on '+DateStamp);

     FOR Lp:=1 TO UserBaseRecCount DO
         IF (NOT KeyPressed) THEN
         BEGIN
              Msg.DeliveringUserRecNr:=Lp;
              ReadUserBaseRecord (Lp,PacketUserData);

              IF (NOT PacketUserData.Deleted) AND (PacketUserData.System = _U) THEN
              BEGIN
                   UserDataRecNr:=Lp; { voor MsgsExport }
                   AreaCreatorUserBaseRecNr:=Lp;
                   PacketUserData.UUCPName:=UpCaseString (PacketUserData.UUCPName);

                   UpdateAction ('Search spool directory for "'+PacketUserData.UUCPName+'"');

                   Uucp_SearchXFiles (Config.SpoolBaseDir+PacketUserData.UUCPName+'\');
              END; { if }
         END; { if, for }

     LogMessage (liTrivial,'UUCP toss finished');
END;


{--------------------------------------------------------------------------}
{ TossBagFile                                                              }
{                                                                          }
{ Verwerkt een binnen gekomen NEWS0000.BAG file, en tossed 'm bijna net    }
{ zoals een gewone Usenet bundle.                                          }
{                                                                          }
{ RWI 950322: geeft nu ook 0=ok;del,1=keep,2=rename terug.                 }
{                                                                          }
PROCEDURE TossBagFile (Path : PathString);

VAR BagFile   : FBufferType;
    Regel     : STRING;
    IORes     : BYTE;
    PrevHad13 : BOOLEAN; { RWI 960601 }
    OldMail,
    OldNews   : LONGINT;

BEGIN
     IF (NOT CheckMinDiskFree) THEN
        Exit;

     IF (NOT FBufferOpen (BagFile,Path,10000,0)) THEN
     BEGIN
          FBufferClose (BagFile);
          LogDiskIOError (LastFBufferError,'Failed to open BAG file: '+Path);
          Exit;
     END;

     MsgsEmptyKeepDeliveringUser; { empties address list as well }

     IF Config.LogSpoolTossed THEN
        LogMessage (liTrivial,'  Processing (bag) '+Path);

     RFC_AddWhereTo:=Header_U; { just in case this is an invalid message }
     PrevHad13:=FALSE;

     FBReadLnLF (BagFile,Regel);
     IF (UpCaseString (Copy (Regel,1,4)) <> '#! R') THEN
     BEGIN
          LogMessage (liFatal,'BAG file misses "#! rmail" or "#! rnews" at begin');
          FBufferClose (BagFile);

          Regel:=Path;
          WHILE (Regel <> '') AND (Regel[Length (Regel)] <> '.') DO
                Delete (Regel,Length (Regel),1);
          Regel:=Regel+'ERR';

          LogMessage (liGeneral,'Renaming '+Path+' to .ERR');

          {$I-} Rename (BagFile.Bestand,Path); {$I+} IORes:=IOResult;
          IF (IORes <> 0) THEN
             LogDiskIOError (IORes,'Rename failed');

          Exit;
     END;

     { RWI961102: deze regel met #rmail of #rnews nog wel verwerken!! }
     RFC_AddTossedRegel (Regel,PrevHad13);

     WHILE FBReadLnLF (BagFile,Regel) DO
           { add GlobalAbort handling here }
           RFC_AddTossedRegel (Regel,PrevHad13);

     { process the last message }
     { For statistics: save old BAG News/mail count, so that we can count  }
     { the number of messages in this job.                                 }
     OldMail:=RetrieveInfoNr (INFO_BagIn_Mail);
     OldNews:=RetrieveInfoNr (INFO_BagIn_News);

     { nu aan alle mogelijke adresses afleveren }
     RFC_GoProcess;

     StatEntry_BAGJob (stdInbound, PacketUserData.UUCPName, 'LOCAL',
                       FileSize (BagFile.Bestand),
                       RetrieveInfoNr (INFO_UucpIn_News) - OldNews,
                       RetrieveInfoNr (INFO_UucpIn_Mail) - OldMail);

     { geheugen van laatste msg weer vrij geven }
     MsgsEmptyKeepDeliveringUser;

     UpdateInfoNr (INFO_BagIn_Bytes,FileSize (BagFile.Bestand));

     FBufferClose (BagFile);

     { .D file laten wissen }
     {$I-} Erase (BagFile.Bestand); {$I+} IORes:=IOResult;
     IF (IORes <> 0) THEN
        LogDiskIOError (IORes,'Cannot delete .BAG file: '+Path);
END;


{--------------------------------------------------------------------------}
{ BagToss                                                                  }
{                                                                          }
{ This routine searches the user base for BAG style links and searches the }
{ given search path for each. If a file is found, it is processed.         }
{                                                                          }
PROCEDURE BagToss;

VAR Lp     : UserBaseRecordNrType;
    Search : SearchRec;
    IORes  : BYTE;
    Path   : STRING;
    Dir    : DirStr;
    Name   : NameStr;
    Ext    : ExtStr;

BEGIN
     LogMessage (liTrivial,'BAG toss started on '+DateStamp);

     FOR Lp:=1 TO UserBaseRecCount DO
         IF (NOT GlobalAbort) THEN
         BEGIN
              Msg.DeliveringUserRecNr:=Lp;
              ReadUserBaseRecord (Lp,PacketUserData);

              IF (NOT PacketUserData.Deleted) AND (PacketUserData.System = _B) THEN
              BEGIN
                   UserDataRecNr:=Lp; { voor MsgsExport }
                   AreaCreatorUserBaseRecNr:=Lp;
                   PacketUserData.UUCPName:=UpCaseString (PacketUserData.UUCPName);

                   UpdateAction ('BAG search for '+PacketUserData.UUCPName);

                   Path:=UNC_FExpand (PacketUserData.BagPath);
                   FSplit (Path,Dir,Name,Ext);

                   { Handling exeption: "C:\NEWS" -> "C:\NEWS\*.BAG" }
                   IF (Ext = '') AND (Name <> '') AND (Pos ('*',Name) = 0) AND (Pos ('?',Name) = 0) THEN
                      Path:=Path+'\*.BAG'
                   ELSE BEGIN
                        IF (Name = '') AND (Ext = '') THEN
                           Path:=Path+'*.BAG';
                   END;

                   { split again to get the directory }
                   FSplit (Path,Dir,Name,Ext);

                   { alle .BAG files aflopen }
                   FindFirst (Path,saJustFiles,Search);

                   IF (DosError <> 0) AND (DosError <> 18{no more files}) THEN
                   BEGIN
                        LogDiskIOError (DosError,'Cannot find BAG path '+Dir);
                        FindClose (Search);
                        Continue; { for }
                   END;

                   IF (DosError = 0) THEN
                      LogMessage (liTrivial,'Searching BAG files for '+PacketUserData.UUCPName);

                   WHILE (DosError = 0) AND (NOT GlobalAbort) DO
                   BEGIN
                        IF KeyPressed THEN
                        BEGIN
                             GlobalAbort:=TRUE;
                             ReadKey; { weglezen }
                        END ELSE
                        BEGIN
                             UpdateInfoNr (INFO_BagIn_Jobs,1);
                             UpdateReadFile (Dir+Search.Name,Search.Size);

                             RFC_TossWhat:=twBag; { BAG files }
                             TossBagFile (Dir+Search.Name);
                             Slice_Now;

                             FindNext (Search);
                        END; { if, while }
                   END;

                   FindClose (Search);

              END; { if not deleted *and* _B }

              IF KeyPressed THEN
              BEGIN
                   GlobalAbort:=TRUE;
                   ReadKey; { weglezen }
              END;

         END; { if, for }

     LogMessage (liTrivial,'BAG toss finished');
END;


{--------------------------------------------------------------------------}
{ unit initialization                                                      }
{                                                                          }
BEGIN
     LastDFilenameTry:=1;
END.
