home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / TIC.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  22KB  |  677 lines

  1.  
  2. // LoraBBS Version 2.99 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include "_ldefs.h"
  20. #include "msgbase.h"
  21. #include "lorawin.h"
  22.  
  23. TTicProcessor::TTicProcessor (void)
  24. {
  25.    Output = NULL;
  26.    Log = NULL;
  27. }
  28.  
  29. TTicProcessor::~TTicProcessor (void)
  30. {
  31. }
  32.  
  33. USHORT TTicProcessor::Check (VOID)
  34. {
  35.    USHORT RetVal = FALSE;
  36.    class TNodes *Nodes;
  37.  
  38.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  39.       if (Nodes->Read (From) == TRUE) {
  40.          if (!stricmp (Nodes->TicPwd, Password))
  41.             RetVal = TRUE;
  42.       }
  43.       delete Nodes;
  44.    }
  45.  
  46.    return (RetVal);
  47. }
  48.  
  49. VOID TTicProcessor::Delete (VOID)
  50. {
  51.    if (Log != NULL)
  52.    Log->Write ("+Deleting %s", CurrentFile);
  53.    unlink (CurrentFile);
  54.    sprintf (Temp, "%s%s", Inbound, Name);
  55.    unlink (Temp);
  56. }
  57.  
  58. VOID TTicProcessor::Hatch (class TAddress *Dest)
  59. {
  60.    class TAddress Addr;
  61.  
  62.    Addr.Parse (Dest->String);
  63.    Hatch (Addr);
  64. }
  65.  
  66. VOID TTicProcessor::Hatch (PSZ address)
  67. {
  68.    class TAddress Addr;
  69.  
  70.    Addr.Parse (address);
  71.    Hatch (Addr);
  72. }
  73.  
  74. VOID TTicProcessor::Hatch (class TAddress &Dest)
  75. {
  76.    FILE *fp;
  77.    CHAR TicName[32], TicFile[128], *p;
  78.    struct dostime_t dtime;
  79.    struct stat statbuf;
  80.    class TOutbound *Out;
  81.    class TNodes *Nodes;
  82.  
  83.    Password[0] = '\0';
  84.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  85.       if (Nodes->Read (Dest.String) == TRUE)
  86.          strcpy (Password, Nodes->TicPwd);
  87.       delete Nodes;
  88.    }
  89.  
  90.    Cfg->MailAddress.First ();
  91.  
  92.    do {
  93.       _dos_gettime (&dtime);
  94.       sprintf (TicName, "lb%02d%02d%02d.tic", dtime.minute, dtime.second, dtime.hsecond);
  95.       strcpy (TicFile, Cfg->Outbound);
  96.       if (Dest.Zone != Cfg->MailAddress.Zone) {
  97.          TicFile[strlen (TicFile) - 1] = '\0';
  98.          sprintf (Temp, ".%03x", Dest.Zone);
  99.          strcat (TicFile, Temp);
  100. #if defined(__LINUX__)
  101.          mkdir (TicFile, 0666);
  102.          strcat (TicFile, "/");
  103. #else
  104.          mkdir (TicFile);
  105.          strcat (TicFile, "\\");
  106. #endif
  107.       }
  108.       if (Dest.Point != 0) {
  109.          sprintf (Temp, "%s%04x%04x.pnt", TicFile, Dest.Net, Dest.Node);
  110. #if defined(__LINUX__)
  111.          mkdir (Temp, 0666);
  112.          strcat (Temp, "/");
  113. #else
  114.          mkdir (Temp);
  115.          strcat (Temp, "\\");
  116. #endif
  117.          strcpy (TicFile, Temp);
  118.       }
  119.       strcat (TicFile, TicName);
  120.    } while (stat (TicFile, &statbuf) == 0);
  121.  
  122.    if ((fp = fopen (TicFile, "wt")) != NULL) {
  123.       fprintf (fp, "Area %s\n", strupr (Area));
  124.       fprintf (fp, "Origin %s\n", Origin.String);
  125.       if (Cfg->MailAddress.First () == TRUE)
  126.          fprintf (fp, "From %s\n", Cfg->MailAddress.String);
  127.       fprintf (fp, "File %s\n", Name);
  128.       if (Replace[0] != '\0')
  129.          fprintf (fp, "Replaces %s\n", Replace);
  130.       if ((p = (PSZ)Description->First ()) == NULL)
  131.          p = "";
  132.       fprintf (fp, "Desc %s\n", p);
  133.       fprintf (fp, "CRC %08lX\n", Crc);
  134.       fprintf (fp, "Created by %s v%s\n", NAME, VERSION);
  135.       if (Size != 0L)
  136.          fprintf (fp, "Size %lu\n", Size);
  137.       while ((p = (PSZ)Description->Next ()) != NULL)
  138.          fprintf (fp, "Ldesc %s\n", p);
  139.  
  140.       if ((p = (PSZ)Path->First ()) != NULL)
  141.          do {
  142.             fprintf (fp, "Path %s\n", p);
  143.          } while ((p = (PSZ)Path->Next ()) != NULL);
  144.  
  145.       if (SeenBy->First () == TRUE)
  146.          do {
  147.             fprintf (fp, "Seenby %s\n", SeenBy->Address);
  148.          } while (SeenBy->Next () == TRUE);
  149.  
  150.       fprintf (fp, "Pw %s\n", Password);
  151.       fclose (fp);
  152.    }
  153.  
  154.    if ((Out = new TOutbound (Cfg->Outbound)) != NULL) {
  155.       Cfg->MailAddress.First ();
  156.       Out->DefaultZone = Cfg->MailAddress.Zone;
  157.       Out->Add (Dest.Zone, Dest.Net, Dest.Node, Dest.Point, Dest.Domain);
  158.  
  159.       Out->New ();
  160.       Out->Zone = Dest.Zone;
  161.       Out->Net = Dest.Net;
  162.       Out->Node = Dest.Node;
  163.       Out->Point = Dest.Point;
  164.       strcpy (Out->Domain, Dest.Domain);
  165.       strcpy (Out->Name, TicName);
  166.       strcpy (Out->Complete, TicFile);
  167.       Out->Status = 'F';
  168.       Out->DeleteAfter = TRUE;
  169.       Out->Add ();
  170.  
  171.       Out->New ();
  172.       Out->Zone = Dest.Zone;
  173.       Out->Net = Dest.Net;
  174.       Out->Node = Dest.Node;
  175.       Out->Point = Dest.Point;
  176.       strcpy (Out->Domain, Dest.Domain);
  177.       strcpy (Out->Name, Name);
  178.       strcpy (Out->Complete, Complete);
  179.       Out->Status = 'F';
  180.       Out->Add ();
  181.  
  182.       Out->Update ();
  183.       delete Out;
  184.    }
  185. }
  186.  
  187. VOID TTicProcessor::Import (VOID)
  188. {
  189.    Description = new TCollection;
  190.    SeenBy = new TKludges;
  191.    Path = new TCollection;
  192.  
  193.    while (OpenNext () == TRUE) {
  194.       if (ImportTic () == TRUE)
  195.          Delete ();
  196.    }
  197.  
  198.    if (Path != NULL)
  199.       delete Path;
  200.    if (SeenBy != NULL)
  201.       delete SeenBy;
  202.    if (Description != NULL)
  203.       delete Description;
  204. }
  205.  
  206. USHORT TTicProcessor::CheckEchoList (PSZ pszFile, PSZ pszEchoTag)
  207. {
  208.    #define MAX_LINECHAR 2048
  209.    FILE *fp;
  210.    USHORT RetVal = FALSE;
  211.    CHAR *lpTemp = (CHAR *)malloc (MAX_LINECHAR + 1);
  212.    CHAR *lpTag;
  213.  
  214.    if (*pszFile == '@')
  215.       pszFile++;
  216.    fp = fopen (pszFile, "rt");
  217.  
  218.    if (fp != NULL && lpTemp != NULL) {
  219.       while (fgets (lpTemp, MAX_LINECHAR, fp) != NULL) {
  220.          lpTemp[strlen (lpTemp) - 1] = '\0';
  221.          if (lpTemp[0] == ';' || lpTemp[0] == '\0')
  222.             continue;
  223.          if ((lpTag = strtok (lpTemp, " ")) != NULL) {
  224.             if (!stricmp (lpTag, pszEchoTag)) {
  225.                RetVal = TRUE;
  226.                break;
  227.             }
  228.          }
  229.       }
  230.    }
  231.  
  232.    if (lpTemp != NULL)
  233.       free (lpTemp);
  234.    if (fp != NULL)
  235.       fclose (fp);
  236.  
  237.    return (RetVal);
  238. }
  239.  
  240. USHORT TTicProcessor::ImportTic (VOID)
  241. {
  242.    int i, a, fds, fdd;
  243.    USHORT RetVal = FALSE, Found = FALSE, Bad = FALSE, Create;
  244.    CHAR Temp[32], *Buffer, *p;
  245.    ULONG FileCrc;
  246.    class TFilechoLink *Link;
  247.    class TNodes *Nodes;
  248.    struct stat statbuf;
  249.    struct dosdate_t datet;
  250.    struct dostime_t timet;
  251.    time_t t;
  252.    struct tm *timep;
  253.  
  254.    if (Output != NULL) {
  255.       sprintf (Display, " %-12.12s  %7ld  %-19.19s  %-24.24s", Name, Size, Area, From.String);
  256.       Output->Add (Display);
  257.    }
  258.  
  259.    if ((Data = new TFileData (Cfg->SystemPath)) != NULL) {
  260.       if ((Found = Data->ReadEcho (Area)) == FALSE) {
  261.          if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  262.             if (Nodes->Read (From.String, FALSE) == TRUE) {
  263.                if (Nodes->CreateNewTic == TRUE) {
  264.                   Create = TRUE;
  265.                   if ((p = strtok (Nodes->NewTicFilter, " ")) != NULL) {
  266.                      Create = FALSE;
  267.                      do {
  268.                         if (*p == '@') {
  269.                            if (CheckEchoList (p, Area) == FALSE)
  270.                               Create = FALSE;
  271.                         }
  272.                         else if (strstr (Area, strupr (p)) != NULL) {
  273.                            Create = TRUE;
  274.                            break;
  275.                         }
  276.                      } while ((p = strtok (NULL, " ")) != NULL);
  277.                   }
  278.                }
  279.             }
  280.  
  281.             delete Nodes;
  282.          }
  283.  
  284.          if (Create == TRUE) {
  285.             strcpy (Temp, Area);
  286.             Temp[sizeof (Data->Key) - 1] = '\0';
  287.             while (Data->Read (Temp) == TRUE) {
  288.                if (isdigit (Temp[strlen (Temp) - 1]))
  289.                   Temp[strlen (Temp) - 1]++;
  290.                else
  291.                   Temp[strlen (Temp) - 1] = '0';
  292.             }
  293.  
  294.             Data->New ();
  295.             strcpy (Data->Key, Temp);
  296.             sprintf (Data->Display, "New area %s", Area);
  297.             sprintf (Data->Download, "%s%s", Cfg->NewTicPath, Area);
  298.             mkdir (Data->Download);
  299.             strcat (Data->Download, "\\");
  300.             strcpy (Data->Upload, Data->Download);
  301.             Data->DownloadLevel = Data->Level = Cfg->NewAreasLevel;
  302.             Data->DownloadFlags = Data->AccessFlags = Cfg->NewAreasFlags;
  303.             Data->DownloadDenyFlags = Data->DenyFlags = Cfg->NewAreasDenyFlags;
  304.             strcpy (Data->EchoTag, Area);
  305.             Data->Add ();
  306.  
  307.             Found = Data->Read (Temp);
  308.             if (Found == TRUE && Log != NULL)
  309.                Log->Write ("*Created area [%s] %s from %s", Data->Key, Data->EchoTag, From.String);
  310.  
  311.             if ((Link = new TFilechoLink (Cfg->SystemPath)) != NULL) {
  312.                Link->Load (Area);
  313.                Link->AddString (From.String);
  314.  
  315.                if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  316.                   if (Nodes->First () == TRUE)
  317.                      do {
  318.                         if (Nodes->LinkNewTic == TRUE && stricmp (Nodes->Address, From.String)) {
  319.                            Link->AddString (Nodes->Address);
  320.                            if (Log != NULL)
  321.                               Log->Write ("-Area %s auto-linked to %s", Area, Nodes->Address);
  322.                         }
  323.                      } while (Nodes->Next () == TRUE);
  324.                   delete Nodes;
  325.                }
  326.  
  327.                Link->Save ();
  328.                delete Link;
  329.             }
  330.          }
  331.  
  332.          if (Create == FALSE && Log != NULL)
  333.             Log->Write ("!Node %s can't create new TIC area %s", From.String, Area);
  334.       }
  335.  
  336.       if (Found == TRUE) {
  337.          if ((Link = new TFilechoLink (Cfg->SystemPath)) != NULL) {
  338.             Link->Load (Area);
  339.             if (Link->Check (From.String) == FALSE && Cfg->Secure == TRUE) {
  340.                if (Log != NULL)
  341.                   Log->Write ("!Bad origin node %s", From.String);
  342.                if (Output != NULL) {
  343.                   strcat (Display, " Bad origin");
  344.                   Output->Update (Display);
  345.                }
  346.                Bad = TRUE;
  347.             }
  348.             delete Link;
  349.          }
  350.          if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  351.             if (Nodes->Read (From) == TRUE) {
  352.                if (Nodes->TicPwd[0] != '\0' && stricmp (Nodes->TicPwd, Password)) {
  353.                   if (Log != NULL)
  354.                      Log->Write ("!Bad password %s from %s", Password, From.String);
  355.                   if (Output != NULL) {
  356.                      strcat (Display, " Bad password");
  357.                      Output->Update (Display);
  358.                   }
  359.                   Bad = TRUE;
  360.                }
  361.             }
  362.             delete Nodes;
  363.          }
  364.          if (Bad == FALSE) {
  365.             if ((fds = open (Complete, O_RDONLY|O_BINARY)) != -1) {
  366.                if ((Buffer = (PSZ)malloc (8192)) != NULL) {
  367.                   FileCrc = 0xFFFFFFFFL;
  368.                   do {
  369.                      i = read (fds, Buffer, 8192);
  370.                      for (a = 0; a < i; a++)
  371.                         FileCrc = Crc32 (Buffer[a], FileCrc);
  372.                   } while (i == 8192);
  373.                   FileCrc = ~FileCrc;
  374.                   if (FileCrc == Crc) {
  375.                      sprintf (Temp, "%s%s", Data->Download, Name);
  376.                      if ((fdd = open (Temp, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE)) != -1) {
  377.                         if (Log != NULL)
  378.                            Log->Write (" Moving %s to %s", Complete, Temp);
  379.                         lseek (fds, 0L, SEEK_SET);
  380.                         do {
  381.                            i = read (fds, Buffer, 8192);
  382.                            write (fdd, Buffer, i);
  383.                         } while (i == 8192);
  384.                         close (fdd);
  385.                         RetVal = TRUE;
  386.                      }
  387.                   }
  388.                   else if (Log != NULL)
  389.                      Log->Write ("!%s bad CRC! (%08lX / %08lX)", Name, Crc, FileCrc);
  390.                   free (Buffer);
  391.                }
  392.                close (fds);
  393.             }
  394.          }
  395.          if (RetVal == TRUE && Bad == FALSE) {
  396.             if (Replace[0] != '\0') {
  397.                sprintf (Temp, "%s%s", Data->Download, Replace);
  398.                if (unlink (Temp) == -1) {
  399.                   if (Log != NULL)
  400.                      Log->Write ("*%s doesn't exist", Temp);
  401.                }
  402.                else {
  403.                   if (Log != NULL)
  404.                      Log->Write ("*Replaces: %s", Temp);
  405.                }
  406.             }
  407.             if ((File = new TFileBase (Cfg->SystemPath, Data->Key)) != NULL) {
  408.                if (Replace[0] != '\0') {
  409.                   if (File->Read (Replace) == TRUE)
  410.                      File->Delete ();
  411.                }
  412.                if (File->Read (Name) == TRUE)
  413.                   File->Delete ();
  414.                File->Clear ();
  415.                strcpy (File->Area, Data->Key);
  416.                strcpy (File->Name, Name);
  417. #if !defined(__LINUX__)
  418.                strupr (File->Name);
  419. #endif
  420.                sprintf (File->Complete, "%s%s", Data->Download, Name);
  421.                if ((p = (PSZ)Description->First ()) != NULL)
  422.                   do {
  423.                      File->Description->Add (p, (USHORT)(strlen (p) + 1));
  424.                   } while ((p = (PSZ)Description->Next ()) != NULL);
  425.  
  426.                _dos_getdate (&datet);
  427.                _dos_gettime (&timet);
  428.                File->UplDate.Day = datet.day;
  429.                File->UplDate.Month = datet.month;
  430.                File->UplDate.Year = datet.year;
  431.                File->UplDate.Hour = timet.hour;
  432.                File->UplDate.Minute = timet.minute;
  433.  
  434.                stat (Complete, &statbuf);
  435.                File->Size = statbuf.st_size;
  436.  
  437.                timep = localtime (&statbuf.st_mtime);
  438.                File->Date.Day = (UCHAR)timep->tm_mday;
  439.                File->Date.Month = (UCHAR)(timep->tm_mon + 1);
  440.                File->Date.Year = (USHORT)(timep->tm_year + 1900);
  441.                File->Date.Hour = (UCHAR)timep->tm_hour;
  442.                File->Date.Minute = (UCHAR)timep->tm_min;
  443.  
  444.                File->Uploader = "TIC Processor";
  445.  
  446.                File->Add ();
  447.                delete File;
  448.  
  449.                Data->ActiveFiles++;
  450.                Data->Update ();
  451.             }
  452.  
  453.             sprintf (Complete, "%s%s", Data->Download, Name);
  454.             if ((Link = new TFilechoLink (Cfg->SystemPath)) != NULL) {
  455.                Link->Load (Area);
  456.                if (Link->First () == TRUE)
  457.                   do {
  458.                      if (SeenBy->Check (Link->Address) == TRUE) {
  459.                         Link->Skip = TRUE;
  460.                         Link->Update ();
  461.                      }
  462.                      else if (strcmp (Link->Address, From.String))
  463.                         SeenBy->AddString (Link->Address);
  464.                   } while (Link->Next () == TRUE);
  465.  
  466.                t = time (NULL);
  467.                timep = gmtime (&t);
  468.                sprintf (Temp, "%s %lu %s", Cfg->MailAddress.String, t, asctime (timep));
  469.                Temp[strlen (Temp) - 1] = '\0';
  470.                strcat (Temp, " GMT");
  471.                Path->Add (Temp);
  472.  
  473.                if (Link->First () == TRUE)
  474.                   do {
  475.                      if (strcmp (Link->Address, From.String) && Link->Skip == FALSE) {
  476.                         if (Log != NULL)
  477.                            Log->Write ("+Sending %s to %s", Name, Link->Address);
  478.                         Password[0] = '\0';
  479.                         if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  480.                            if (Nodes->Read (From) == TRUE)
  481.                               strcpy (Password, Nodes->TicPwd);
  482.                            delete Nodes;
  483.                         }
  484.                         Hatch (Link->Address);
  485.                      }
  486.                   } while (Link->Next () == TRUE);
  487.                delete Link;
  488.             }
  489.          }
  490.       }
  491.  
  492.       if (Found == FALSE || Bad == TRUE) {
  493.          if (Log != NULL && Bad == FALSE) {
  494.             Log->Write ("!Unknown area \"%s\" in %s", Area, CurrentFile);
  495.             if (Output != NULL) {
  496.                strcat (Display, " Bad area");
  497.                Output->Update (Display);
  498.             }
  499.          }
  500.  
  501.          strcpy (Temp, CurrentFile);
  502.          strcpy (&Temp[strlen (Temp) - 4], ".bad");
  503.          if (Log != NULL)
  504.             Log->Write (":Renaming %s in %s", CurrentFile, Temp);
  505.          rename (CurrentFile, Temp);
  506.       }
  507.  
  508.       delete Data;
  509.    }
  510.  
  511.    return (RetVal);
  512. }
  513.  
  514. USHORT TTicProcessor::Open (PSZ pszFile)
  515. {
  516.    FILE *fp;
  517.    USHORT RetVal = FALSE, Count;
  518.    CHAR *Temp, *p;
  519.  
  520.    if (Inbound[strlen (Inbound) - 1] == '\\' || Inbound[strlen (Inbound) - 1] == '/')
  521.       Inbound[strlen (Inbound) - 1] = '\0';
  522. #if defined(__LINUX__)
  523.    if (Inbound[0] != '\0')
  524.       strcat (Inbound, "/");
  525. #else
  526.    if (Inbound[0] != '\0')
  527.       strcat (Inbound, "\\");
  528. #endif
  529.  
  530.    Count = 0;
  531.    Description->Clear ();
  532.    SeenBy->Clear ();
  533.    SeenBy->Sort = TRUE;
  534.    Path->Clear ();
  535.    Replace[0] = '\0';
  536.  
  537.    if ((fp = fopen (pszFile, "rt")) != NULL) {
  538.       strcpy (CurrentFile, pszFile);
  539.       if ((Temp = (CHAR *)malloc (2048)) != NULL) {
  540.          while (fgets (Temp, 2048 - 1, fp) != NULL) {
  541.             Temp[strlen (Temp) - 1] = '\0';
  542.             if ((p = strtok (Temp, " ")) != NULL) {
  543.                if (!stricmp (p, "Area")) {
  544.                   if ((p = strtok (NULL, " ")) != NULL) {
  545.                      strcpy (Area, strupr (p));
  546.                      if (++Count >= 2)
  547.                         RetVal = TRUE;
  548.                   }
  549.                }
  550.                else if (!stricmp (p, "File")) {
  551.                   if ((p = strtok (NULL, " ")) != NULL) {
  552.                      strcpy (Name, strlwr (p));
  553.                      strcpy (Complete, Inbound);
  554.                      strcat (Complete, Name);
  555.                      if (++Count >= 2)
  556.                         RetVal = TRUE;
  557.                   }
  558.                }
  559.                else if (!stricmp (p, "Size")) {
  560.                   if ((p = strtok (NULL, " ")) != NULL)
  561.                      Size = atol (p);
  562.                }
  563.                else if (!stricmp (p, "CRC")) {
  564.                   if ((p = strtok (NULL, " ")) != NULL)
  565.                      sscanf (p, "%08lx", &Crc);
  566.                }
  567.                else if (!stricmp (p, "Desc")) {
  568.                   if ((p = strtok (NULL, "")) != NULL) {
  569.                      while (*p == ' ')
  570.                         p++;
  571.                      Description->Add (p, (USHORT)(strlen (p) + 1));
  572.                   }
  573.                }
  574.                else if (!stricmp (p, "Ldesc")) {
  575.                   if ((p = strtok (NULL, "")) != NULL) {
  576.                      while (*p == ' ')
  577.                         p++;
  578.                      Description->Add (p, (USHORT)(strlen (p) + 1));
  579.                   }
  580.                }
  581.                else if (!stricmp (p, "Pw")) {
  582.                   if ((p = strtok (NULL, " ")) != NULL)
  583.                      strcpy (Password, strupr (p));
  584.                }
  585.                else if (!stricmp (p, "SeenBy")) {
  586.                   if ((p = strtok (NULL, " ")) != NULL)
  587.                      SeenBy->AddString (p);
  588.                }
  589.                else if (!stricmp (p, "Path")) {
  590.                   if ((p = strtok (NULL, "")) != NULL) {
  591.                      while (*p == ' ')
  592.                         p++;
  593.                      Path->Add (p);
  594.                   }
  595.                }
  596.                else if (!stricmp (p, "From")) {
  597.                   if ((p = strtok (NULL, " ")) != NULL)
  598.                      From.Parse (p);
  599.                }
  600.                else if (!stricmp (p, "Origin")) {
  601.                   if ((p = strtok (NULL, " ")) != NULL)
  602.                      Origin.Parse (p);
  603.                }
  604.                else if (!stricmp (p, "Replace") || !stricmp (p, "Replaces")) {
  605.                   if ((p = strtok (NULL, " ")) != NULL)
  606.                      strcpy (Replace, p);
  607.                }
  608.             }
  609.          }
  610.          free (Temp);
  611.       }
  612.       fclose (fp);
  613.    }
  614.  
  615.    if (RetVal == TRUE && Log != NULL) {
  616.       Log->Write (":AREA: %s", Area);
  617.       if ((p = (PSZ)Description->First ()) == NULL)
  618.          p = "";
  619.       Log->Write (":%s - %s", Name, p);
  620.       Log->Write (":Originated by %s", Origin.String);
  621.    }
  622.  
  623.    return (RetVal);
  624. }
  625.  
  626. USHORT TTicProcessor::OpenNext (VOID)
  627. {
  628.    DIR *dir;
  629.    USHORT RetVal = FALSE;
  630.    CHAR Filename[128], OpenFileName[128];
  631.    ULONG PktDate;
  632.    struct dirent *ent;
  633.    struct stat statbuf;
  634.  
  635.    strcpy (Filename, Inbound);
  636.    if (Filename[strlen (Filename) - 1] == '\\' || Filename[strlen (Filename) - 1] == '/')
  637.       Filename[strlen (Filename) - 1] = '\0';
  638.  
  639.    if ((dir = opendir (Filename)) != NULL) {
  640.       while ((ent = readdir (dir)) != NULL) {
  641.          strlwr (ent->d_name);
  642.          if (strstr (ent->d_name, ".tic") != NULL) {
  643.             sprintf (Filename, "%s%s", Inbound, ent->d_name);
  644.             stat (Filename, &statbuf);
  645.             strcpy (PktName, ent->d_name);
  646.             PktDate = statbuf.st_mtime;
  647.             RetVal = TRUE;
  648.             break;
  649.          }
  650.       }
  651.  
  652.       if (RetVal == TRUE) {
  653.          while ((ent = readdir (dir)) != NULL) {
  654.             strlwr (ent->d_name);
  655.             if (strstr (ent->d_name, ".tic") != NULL) {
  656.                sprintf (Filename, "%s%s", Inbound, ent->d_name);
  657.                stat (Filename, &statbuf);
  658.                if (PktDate > statbuf.st_mtime) {
  659.                   strcpy (PktName, ent->d_name);
  660.                   PktDate = statbuf.st_mtime;
  661.                }
  662.             }
  663.          }
  664.       }
  665.  
  666.       closedir (dir);
  667.    }
  668.  
  669.    if (RetVal == TRUE) {
  670.       sprintf (OpenFileName, "%s%s", Inbound, PktName);
  671.       Open (OpenFileName);
  672.    }
  673.  
  674.    return (RetVal);
  675. }
  676.  
  677.