home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / OUTBOUND.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  46KB  |  1,223 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 "lora_api.h"
  21.  
  22. PSZ ArcFlags[] = { ".mo", ".tu", ".we", ".th", ".fr", ".sa", ".su" };
  23.  
  24. TOutbound::TOutbound (PSZ pszPath)
  25. {
  26.    DefaultZone = 2;
  27.    Files.Clear ();
  28.    TotalNodes = TotalFiles = 0;
  29.    TotalSize = 0L;
  30.  
  31.    if (pszPath != NULL) {
  32.       strcpy (Path, pszPath);
  33.       if (Path[strlen (Path) - 1] != '\\' && Path[strlen (Path) - 1] != '/')
  34.          strcat (Path, "\\");
  35.    }
  36. }
  37.  
  38. TOutbound::TOutbound (PSZ pszPath, USHORT usZone, USHORT usNet, USHORT usNode, USHORT usPoint, PSZ pszDomain)
  39. {
  40.    DefaultZone = 2;
  41.    Files.Clear ();
  42.    TotalFiles = 0;
  43.    TotalSize = 0L;
  44.  
  45.    if (pszPath != NULL) {
  46.       strcpy (Path, pszPath);
  47.       if (Path[strlen (Path) - 1] != '\\' && Path[strlen (Path) - 1] != '/')
  48.          strcat (Path, "\\");
  49.    }
  50.  
  51.    Add (usZone, usNet, usNode, usPoint, pszDomain);
  52. }
  53.  
  54. TOutbound::~TOutbound (void)
  55. {
  56.    Files.Clear ();
  57.    Nodes.Clear ();
  58. }
  59.  
  60. VOID TOutbound::Clear (VOID)
  61. {
  62.    Files.Clear ();
  63.    Nodes.Clear ();
  64.    TotalFiles = 0;
  65.    TotalSize = 0L;
  66.    New ();
  67. }
  68.  
  69. USHORT TOutbound::Add (VOID)
  70. {
  71.    USHORT RetVal = FALSE;
  72.    PSZ p;
  73.    OUTFILE Out;
  74.  
  75.    memset (&Out, 0, sizeof (Out));
  76.    Out.Zone = Zone;
  77.    Out.Net = Net;
  78.    Out.Node = Node;
  79.    Out.Point = Point;
  80.    strcpy (Out.Domain, Domain);
  81.    if (Name[0] == '\0') {
  82.       if ((p = strchr (Complete, '\0')) != NULL) {
  83.          while (p > Complete && *p != '\\' && *p != ':' && *p != '/')
  84.             p--;
  85.          strcpy (Out.Name, ++p);
  86.       }
  87.    }
  88.    else
  89.       strcpy (Out.Name, Name);
  90.    strcpy (Out.Complete, Complete);
  91.    Out.Size = Size;
  92.    Out.ArcMail = ArcMail;
  93.    Out.MailPKT = MailPKT;
  94.    Out.Request = Request;
  95.    Out.Poll = Poll;
  96.    Out.DeleteAfter = DeleteAfter;
  97.    Out.TruncateAfter = TruncateAfter;
  98.    if (Poll == TRUE) {
  99.       if (Crash == TRUE)
  100.          Status = 'C';
  101.       else if (Direct == TRUE)
  102.          Status = 'D';
  103.       else if (Normal == TRUE)
  104.          Status = 'F';
  105.       else if (Immediate == TRUE)
  106.          Status = 'I';
  107.    }
  108.    Out.Status = Status;
  109.    if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  110.       if (AddQueue (Out) == TRUE) {
  111.          TotalSize += Out.Size;
  112.          TotalFiles++;
  113.          RetVal = TRUE;
  114.       }
  115.    }
  116.  
  117.    return (RetVal);
  118. }
  119.  
  120. USHORT TOutbound::Add (USHORT usZone, USHORT usNet, USHORT usNode, USHORT usPoint, PSZ pszDomain)
  121. {
  122.    FILE *fp;
  123.    USHORT i, x, RetVal = FALSE, Readed;
  124.    CHAR FileName[128], String[128], *pFile, *p;
  125.    CHAR Flags[] = { 'h', 'c', 'd', 'f', 'o', 'i' };
  126.    OUTFILE Out;
  127.    struct stat statbuf;
  128.  
  129.    pszDomain = pszDomain;
  130.  
  131. // ----------------------------------------------------------------------
  132. // The first thing to do is create an outbound path that is conforming
  133. // with the Bink/Opus outbound directory specifications.
  134. // ----------------------------------------------------------------------
  135.    strcpy (Outbound, Path);
  136.    if (usZone != DefaultZone) {
  137.       Outbound[strlen (Outbound) - 1] = '\0';
  138.       sprintf (String, ".%03x\\", usZone);
  139.       strcat (Outbound, String);
  140.    }
  141.  
  142. // ----------------------------------------------------------------------
  143. // Check for the mail files for the node address being added
  144. // ----------------------------------------------------------------------
  145.    if (usPoint != 0)
  146.       sprintf (FileName, "%s%04x%04x.pnt\\%08x.hut", Outbound, usNet, usNode, usPoint);
  147.    else
  148.       sprintf (FileName, "%s%04x%04x.hut", Outbound, usNet, usNode);
  149.  
  150.    for (i = 0; i < 6; i++) {
  151.       FileName[strlen (FileName) - 3] = Flags[i];
  152.       if (stat (AdjustPath (FileName), &statbuf) == 0) {
  153.          memset (&Out, 0, sizeof (Out));
  154.          Out.Zone = usZone;
  155.          Out.Net = usNet;
  156.          Out.Node = usNode;
  157.          Out.Point = usPoint;
  158.          if (pszDomain != NULL)
  159.             strcpy (Out.Domain, pszDomain);
  160.          if (usPoint != 0)
  161.             sprintf (Out.Name, "%08x.hut", usPoint);
  162.          else
  163.             sprintf (Out.Name, "%04x%04x.hut", usNet, usNode);
  164.          Out.Name[strlen (Out.Name) - 3] = Flags[i];
  165.          strcpy (Out.Complete, FileName);
  166.          Out.Size = statbuf.st_size;
  167.          Out.MailPKT = TRUE;
  168.          Out.DeleteAfter = TRUE;
  169.          Out.Status = Flags[i];
  170.          if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  171.             if (AddQueue (Out) == TRUE) {
  172.                TotalSize += Out.Size;
  173.                TotalFiles++;
  174.                RetVal = TRUE;
  175.             }
  176.          }
  177.       }
  178.    }
  179.  
  180. // ----------------------------------------------------------------------
  181. // Check for the file attachments for the node address being added
  182. // ----------------------------------------------------------------------
  183.    if (usPoint != 0)
  184.       sprintf (FileName, "%s%04x%04x.pnt\\%08x.hlo", Outbound, usNet, usNode, usPoint);
  185.    else
  186.       sprintf (FileName, "%s%04x%04x.hlo", Outbound, usNet, usNode);
  187.  
  188.    for (i = 0; i < 6; i++) {
  189.       FileName[strlen (FileName) - 3] = Flags[i];
  190.       if ((fp = _fsopen (AdjustPath (FileName), "rt", SH_DENYNO)) != NULL) {
  191.          Readed = FALSE;
  192.          while (fgets (String, sizeof (String) - 1, fp) != NULL) {
  193.             if (String[strlen (String) - 1] == '\n')
  194.                String[strlen (String) - 1] = '\0';
  195.             pFile = String;
  196.             if (String[0] == '^' || String[0] == '#')
  197.                pFile++;
  198.             if (pFile[0] != '~' && stat (AdjustPath (pFile), &statbuf) == 0) {
  199.                memset (&Out, 0, sizeof (Out));
  200.                Out.Zone = usZone;
  201.                Out.Net = usNet;
  202.                Out.Node = usNode;
  203.                Out.Point = usPoint;
  204.                if (pszDomain != NULL)
  205.                   strcpy (Out.Domain, pszDomain);
  206.                if ((p = strchr (pFile, '!')) != NULL) {
  207.                   *p++ = '\0';
  208.                   strcpy (Out.Name, p);
  209.                }
  210.                else if ((p = strchr (pFile, '\0')) != NULL) {
  211.                   while (p > pFile && *p != '\\' && *p != ':' && *p != '/')
  212.                      p--;
  213.                   strcpy (Out.Name, ++p);
  214.                }
  215.                strcpy (Out.Complete, pFile);
  216.                Out.Size = statbuf.st_size;
  217.                if (strstr (Out.Name, ".pk") != NULL)
  218.                   Out.MailPKT = TRUE;
  219.                else {
  220.                   for (x = 0; x < 7 && Out.ArcMail == FALSE; x++) {
  221.                      if (strstr (Out.Name, ArcFlags[x]) != NULL)
  222.                         Out.ArcMail = TRUE;
  223.                   }
  224.                }
  225.                if (String[0] == '^')
  226.                   Out.DeleteAfter = TRUE;
  227.                else if (String[0] == '#')
  228.                   Out.TruncateAfter = TRUE;
  229.                Out.Status = Flags[i];
  230.                if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  231.                   if (AddQueue (Out) == TRUE) {
  232.                      TotalSize += Out.Size;
  233.                      TotalFiles++;
  234.                      RetVal = TRUE;
  235.                      Readed = TRUE;
  236.                   }
  237.                }
  238.             }
  239.          }
  240.          fclose (fp);
  241.  
  242.          if (Readed == FALSE) {
  243.             memset (&Out, 0, sizeof (Out));
  244.             Out.Zone = usZone;
  245.             Out.Net = usNet;
  246.             Out.Node = usNode;
  247.             Out.Point = usPoint;
  248.             if (pszDomain != NULL)
  249.                strcpy (Out.Domain, pszDomain);
  250.             Out.Status = Flags[i];
  251.             Out.Poll = TRUE;
  252.             if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  253.                if (AddQueue (Out) == TRUE) {
  254.                   TotalSize += Out.Size;
  255.                   TotalFiles++;
  256.                   RetVal = TRUE;
  257.                }
  258.             }
  259.          }
  260.       }
  261.    }
  262.  
  263. // ----------------------------------------------------------------------
  264. // Check for file requests directed to the node being added
  265. // ----------------------------------------------------------------------
  266.    if (usPoint != 0)
  267.       sprintf (FileName, "%s%04x%04x.pnt\\%08x.req", Outbound, usNet, usNode, usPoint);
  268.    else
  269.       sprintf (FileName, "%s%04x%04x.req", Outbound, usNet, usNode);
  270.  
  271.    if (stat (AdjustPath (FileName), &statbuf) == 0) {
  272.       memset (&Out, 0, sizeof (Out));
  273.       Out.Zone = usZone;
  274.       Out.Net = usNet;
  275.       Out.Node = usNode;
  276.       Out.Point = usPoint;
  277.       if (pszDomain != NULL)
  278.          strcpy (Out.Domain, pszDomain);
  279.       if (usPoint != 0)
  280.          sprintf (Out.Name, "%08x.req", usPoint);
  281.       else
  282.          sprintf (Out.Name, "%04x%04x.req", usNet, usNode);
  283.       strcpy (Out.Complete, FileName);
  284.       Out.Size = statbuf.st_size;
  285.       Out.Request = TRUE;
  286.       Out.DeleteAfter = TRUE;
  287.       if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  288.          if (AddQueue (Out) == TRUE) {
  289.             TotalSize += Out.Size;
  290.             TotalFiles++;
  291.             RetVal = TRUE;
  292.          }
  293.       }
  294.    }
  295.  
  296.    return (RetVal);
  297. }
  298.  
  299. USHORT TOutbound::AddQueue (OUTFILE &Out)
  300. {
  301.    USHORT RetVal = FALSE, Insert;
  302.    QUEUE Queue, *Temp;
  303.  
  304.    if ((Temp = (QUEUE *)Nodes.First ()) != NULL)
  305.       do {
  306.          if (Temp->Zone == Out.Zone && Temp->Net == Out.Net && Temp->Node == Out.Node && Temp->Point == Out.Point && !stricmp (Temp->Domain, Out.Domain)) {
  307.             Temp->Files++;
  308.             Temp->Size += Out.Size;
  309.             if (Out.Status == 'C')
  310.                Temp->Crash = TRUE;
  311.             else if (Out.Status == 'D')
  312.                Temp->Direct = TRUE;
  313.             else if (Out.Status == 'H')
  314.                Temp->Hold = TRUE;
  315.             else if (Out.Status == 'I')
  316.                Temp->Immediate = TRUE;
  317.             else if (Out.Status == 'O' || Out.Status == 'F')
  318.                Temp->Normal = TRUE;
  319.             RetVal = TRUE;
  320.             break;
  321.          }
  322.       } while ((Temp = (QUEUE *)Nodes.Next ()) != NULL && RetVal == FALSE);
  323.  
  324.    if (RetVal == FALSE) {
  325.       memset (&Queue, 0, sizeof (Queue));
  326.       Queue.Zone = Out.Zone;
  327.       Queue.Net = Out.Net;
  328.       Queue.Node = Out.Node;
  329.       Queue.Point = Out.Point;
  330.       strcpy (Queue.Domain, Out.Domain);
  331.       Queue.Files++;
  332.       Queue.Size += Out.Size;
  333.       if (Out.Status == 'C')
  334.          Queue.Crash = TRUE;
  335.       else if (Out.Status == 'D')
  336.          Queue.Direct = TRUE;
  337.       else if (Out.Status == 'H')
  338.          Queue.Hold = TRUE;
  339.       else if (Out.Status == 'I')
  340.          Queue.Immediate = TRUE;
  341.       else if (Out.Status == 'N')
  342.          Queue.Normal = TRUE;
  343.  
  344.       Insert = FALSE;
  345.       if ((Temp = (QUEUE *)Nodes.First ()) != NULL) {
  346.          if (Temp->Zone > Queue.Zone)
  347.             Insert = TRUE;
  348.          else if (Temp->Zone == Queue.Zone && Temp->Net > Queue.Net)
  349.             Insert = TRUE;
  350.          else if (Temp->Zone == Queue.Zone && Temp->Net == Queue.Net && Temp->Node > Queue.Node)
  351.             Insert = TRUE;
  352.          else if (Temp->Zone == Queue.Zone && Temp->Net == Queue.Net && Temp->Node == Queue.Node && Temp->Point > Queue.Point)
  353.             Insert = TRUE;
  354.  
  355.          if (Insert == TRUE) {
  356.             Nodes.Insert (&Queue, sizeof (QUEUE));
  357.             Nodes.Insert (Temp, sizeof (QUEUE));
  358.             Nodes.First ();
  359.             Nodes.Remove ();
  360.             Nodes.First ();
  361.             TotalNodes++;
  362.          }
  363.          else {
  364.             while ((Temp = (QUEUE *)Nodes.Next ()) != NULL) {
  365.                if (Temp->Zone > Queue.Zone)
  366.                   Insert = TRUE;
  367.                else if (Temp->Zone == Queue.Zone && Temp->Net > Queue.Net)
  368.                   Insert = TRUE;
  369.                else if (Temp->Zone == Queue.Zone && Temp->Net == Queue.Net && Temp->Node > Queue.Node)
  370.                   Insert = TRUE;
  371.                else if (Temp->Zone == Queue.Zone && Temp->Net == Queue.Net && Temp->Node == Queue.Node && Temp->Point > Queue.Point)
  372.                   Insert = TRUE;
  373.  
  374.                if (Insert == TRUE) {
  375.                   Nodes.Previous ();
  376.                   Nodes.Insert (&Queue, sizeof (QUEUE));
  377.                   TotalNodes++;
  378.                   break;
  379.                }
  380.             }
  381.             if (Insert == FALSE) {
  382.                Nodes.Add (&Queue, sizeof (QUEUE));
  383.                TotalNodes++;
  384.                Insert = TRUE;
  385.             }
  386.          }
  387.       }
  388.       if (Insert == FALSE) {
  389.          Nodes.Add (&Queue, sizeof (QUEUE));
  390.          TotalNodes++;
  391.       }
  392.  
  393.       RetVal = TRUE;
  394.    }
  395.  
  396.    return (RetVal);
  397. }
  398.  
  399. VOID TOutbound::BuildQueue (PSZ pszPath)
  400. {
  401.    FILE *fp;
  402.    int i;
  403.    USHORT x, Added;
  404.    CHAR BasePath[128], Temp[128], *p, BaseOut[32];
  405.    DIR *dir, *dir1;
  406.    OUTFILE Out;
  407.    QUEUE *Queue;
  408.    struct dirent *ent;
  409.    struct stat statbuf;
  410.  
  411.    Files.Clear ();
  412.    Nodes.Clear ();
  413.    TotalNodes = TotalFiles = 0;
  414.    TotalSize = 0L;
  415.    Number = 0;
  416.    TotalNodes = 0;
  417.  
  418.    strcpy (BasePath, pszPath);
  419.    if (BasePath[strlen (BasePath) - 1] == '\\' || BasePath[strlen (BasePath) - 1] == '/')
  420.       BasePath[strlen (BasePath) - 1] = '\0';
  421.  
  422.    strcpy (Temp, BasePath);
  423.    if ((p = strchr (Temp, '\0')) != NULL) {
  424.       while (p > Temp && *p != '\\' && *p != ':' && *p != '/')
  425.          *p-- = '\0';
  426.    }
  427.    *p-- = '\0';
  428.    if (*p == ':')
  429.       strcat (p, "\\");
  430.  
  431.    // Il primo loop cerca le directory di outbound aventi come
  432.    // nome del file la directory di base passata come argomento e, se di zone diversa
  433.    // da quella di default, una estensione di tre caratteri esadecimali rappresentanti
  434.    // il numero di zona.
  435.    if ((dir = opendir (AdjustPath (Temp))) != NULL) {
  436.       if ((p = strchr (BasePath, '\0')) != NULL) {
  437.          while (p > BasePath && *p != '\\' && *p != ':' && *p != '/')
  438.             p--;
  439.          strcpy (BaseOut, ++p);
  440.       }
  441.  
  442.       while ((ent = readdir (dir)) != NULL) {
  443.          if (strnicmp (strupr (ent->d_name), BaseOut, strlen (BaseOut)) == 0) {
  444.             memset (&Out, 0, sizeof (Out));
  445.             p = strchr (ent->d_name, '.');
  446.             if (p != NULL) {
  447.                sscanf (p, ".%03hx", &Out.Zone);
  448.                if (Out.Zone != 0)
  449.                   sprintf (Temp, "%s.%03x", BasePath, Out.Zone);
  450.                else {
  451.                   Out.Zone = DefaultZone;
  452.                   sprintf (Temp, "%s", BasePath);
  453.                }
  454.             }
  455.             else {
  456.                Out.Zone = DefaultZone;
  457.                sprintf (Temp, "%s", BasePath);
  458.             }
  459.  
  460.             if ((dir1 = opendir (AdjustPath (Temp))) != NULL) {
  461.                while ((ent = readdir (dir1)) != NULL) {
  462.                   if ((p = strchr (ent->d_name, '.')) != NULL) {
  463.                      if (toupper (p[2]) == 'L' && toupper (p[3]) == 'O') {
  464.                         // Trovato un file attach. La prima lettera rappresenta il tipo
  465.                         // di priorita'.
  466.                         Out.Point = 0;
  467.                         sscanf (ent->d_name, "%04hx%04hx", &Out.Net, &Out.Node);
  468.                         Out.Status = (CHAR)toupper (p[1]);
  469.                         if (Out.Zone != DefaultZone)
  470.                            sprintf (Temp, "%s.%03x\\%s", BasePath, Out.Zone, ent->d_name);
  471.                         else
  472.                            sprintf (Temp, "%s\\%s", BasePath, ent->d_name);
  473.                         Out.Size = 0L;
  474.                         if ((fp = _fsopen (AdjustPath (Temp), "rt", SH_DENYNO)) != NULL) {
  475.                            Added = FALSE;
  476.                            while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  477.                               if (Temp[strlen (Temp) - 1] == '\n')
  478.                                  Temp[strlen (Temp) - 1] = '\0';
  479.                               p = Temp;
  480.                               if (Temp[0] == '^' || Temp[0] == '#')
  481.                                  p++;
  482.                               if (p[0] != '~' && stat (AdjustPath (p), &statbuf) == 0) {
  483.                                  strcpy (Out.Complete, p);
  484.                                  if ((p = strchr (Temp, '\0')) != NULL) {
  485.                                     while (p > Temp && *p != '\\' && *p != ':' && *p != '/')
  486.                                        p--;
  487.                                     if (*p == '\\' || *p == ':' || *p == '/' || *p == '^' || *p == '#')
  488.                                        p++;
  489.                                     strcpy (Out.Name, p);
  490.                                  }
  491.                                  Out.Size = statbuf.st_size;
  492.                                  if (strstr (Out.Name, ".pk") != NULL)
  493.                                     Out.MailPKT = TRUE;
  494.                                  else {
  495.                                     for (x = 0; x < 7 && Out.ArcMail == FALSE; x++) {
  496.                                        if (strstr (Out.Name, ArcFlags[x]) != NULL)
  497.                                           Out.ArcMail = TRUE;
  498.                                     }
  499.                                  }
  500.                                  if (Temp[0] == '^')
  501.                                     Out.DeleteAfter = TRUE;
  502.                                  else if (Temp[0] == '#')
  503.                                     Out.TruncateAfter = TRUE;
  504.                                  if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  505.                                     if (AddQueue (Out) == TRUE) {
  506.                                        TotalSize += Out.Size;
  507.                                        TotalFiles++;
  508.                                     }
  509.                                     Added = TRUE;
  510.                                  }
  511.  
  512.                                  // Azzera i flags pericolosi nel caso in cui il file
  513.                                  // seguente non li abbia settati nello stesso modo.
  514.                                  Out.DeleteAfter = Out.TruncateAfter = Out.ArcMail = FALSE;
  515.                                  Out.MailPKT = FALSE;
  516.                               }
  517.                            }
  518.                            fclose (fp);
  519.  
  520.                            if (Added == FALSE) {
  521.                               Out.Poll = TRUE;
  522.                               if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  523.                                  if (AddQueue (Out) == TRUE) {
  524.                                     TotalSize += Out.Size;
  525.                                     TotalFiles++;
  526.                                  }
  527.                                  Added = TRUE;
  528.                               }
  529.                            }
  530.                         }
  531.                      }
  532.                      else if (toupper (p[2]) == 'U' && toupper (p[3]) == 'T') {
  533.                         // Trovato un pacchetto di posta. La prima lettera rappresenta
  534.                         // il tipo di priorita'. Il file va aggiunto cosi' come si trova.
  535.                         Out.Point = 0;
  536.                         sscanf (ent->d_name, "%04hx%04hx", &Out.Net, &Out.Node);
  537.                         Out.Status = (CHAR)toupper (p[1]);
  538.                         if (Out.Zone != DefaultZone)
  539.                            sprintf (Out.Complete, "%s.%03x\\%s", BasePath, Out.Zone, ent->d_name);
  540.                         else
  541.                            sprintf (Out.Complete, "%s\\%s", BasePath, ent->d_name);
  542.                         stat (AdjustPath (Out.Complete), &statbuf);
  543.                         strcpy (Out.Name, ent->d_name);
  544.                         Out.Size = statbuf.st_size;
  545.                         Out.DeleteAfter = TRUE;
  546.                         Out.MailPKT = TRUE;
  547.                         if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  548.                            if (AddQueue (Out) == TRUE) {
  549.                               TotalSize += Out.Size;
  550.                               TotalFiles++;
  551.                            }
  552.                         }
  553.                      }
  554.                      else if (toupper (p[1]) == 'R' && toupper (p[2]) == 'E' && toupper (p[3]) == 'Q') {
  555.                         // Trovato un file request diretto al nodo.
  556.                         Out.Point = 0;
  557.                         sscanf (ent->d_name, "%04hx%04hx", &Out.Net, &Out.Node);
  558.                         Out.Status = (CHAR)toupper (p[1]);
  559.                         if (Out.Zone != DefaultZone)
  560.                            sprintf (Out.Complete, "%s.%03x\\%s", BasePath, Out.Zone, ent->d_name);
  561.                         else
  562.                            sprintf (Out.Complete, "%s\\%s", BasePath, ent->d_name);
  563.                         stat (AdjustPath (Out.Complete), &statbuf);
  564.                         strcpy (Out.Name, ent->d_name);
  565.                         Out.Size = statbuf.st_size;
  566.                         Out.DeleteAfter = TRUE;
  567.                         Out.Request = TRUE;
  568.                         if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  569.                            if (AddQueue (Out) == TRUE) {
  570.                               TotalSize += Out.Size;
  571.                               TotalFiles++;
  572.                            }
  573.                         }
  574.                      }
  575.                      else if (toupper (p[1]) == '$' && toupper (p[2]) == '$') {
  576.                         // Trovato il contatore dei tentativi di chiamata
  577.                         Out.Point = 0;
  578.                         sscanf (ent->d_name, "%04hx%04hx", &Out.Net, &Out.Node);
  579.                         if (AddQueue (Out) == TRUE) {
  580.                            if ((Queue = (QUEUE *)Nodes.Value ()) != NULL) {
  581.                               Queue->Failed = (USHORT)(p[3] - '0');
  582.                               if (Out.Zone != DefaultZone)
  583.                                  sprintf (Out.Complete, "%s.%03x\\%s", BasePath, Out.Zone, ent->d_name);
  584.                               else
  585.                                  sprintf (Out.Complete, "%s\\%s", BasePath, ent->d_name);
  586.                               if ((i = open (AdjustPath (Out.Complete), O_RDONLY|O_BINARY)) != -1) {
  587.                                  read (i, &Queue->Attempts, 2);
  588.                                  read (i, Queue->LastCall, sizeof (LastCall));
  589.                                  close (i);
  590.                               }
  591.                            }
  592.                         }
  593.                      }
  594.                      else if (toupper (p[1]) == 'P' && toupper (p[2]) == 'N' && toupper (p[3]) == 'T') {
  595.                         USHORT pZone, pNet, pNode;
  596.                         DIR *dir3;
  597.  
  598.                         // Point subdirectory
  599.                         pZone = Out.Zone;
  600.                         sscanf (ent->d_name, "%04hx%04hx", &pNet, &pNode);
  601.  
  602.                         sprintf (Temp, "%s\\%s", BasePath, ent->d_name);
  603.                         if ((dir3 = opendir (Temp)) != NULL) {
  604.                            while ((ent = readdir (dir3)) != NULL) {
  605.                               if ((p = strchr (ent->d_name, '.')) != NULL) {
  606.                                  memset (&Out, 0, sizeof (Out));
  607.                                  Out.Zone = pZone;
  608.                                  Out.Net = pNet;
  609.                                  Out.Node = pNode;
  610.                                  if (toupper (p[2]) == 'L' && toupper (p[3]) == 'O') {
  611.                                     // Trovato un file attach. La prima lettera rappresenta il tipo
  612.                                     // di priorita'.
  613.                                     Added = FALSE;
  614.                                     sscanf (ent->d_name, "%08hx", &Out.Point);
  615.                                     Out.Status = (CHAR)toupper (p[1]);
  616.                                     sprintf (Temp, "%s\\%04x%04x.pnt\\%s", BasePath, Out.Net, Out.Node, ent->d_name);
  617.                                     Out.Size = 0L;
  618.                                     if ((fp = _fsopen (AdjustPath (Temp), "rt", SH_DENYNO)) != NULL) {
  619.                                        while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  620.                                           if (Temp[strlen (Temp) - 1] == '\n')
  621.                                              Temp[strlen (Temp) - 1] = '\0';
  622.                                           p = Temp;
  623.                                           if (Temp[0] == '^' || Temp[0] == '#')
  624.                                              p++;
  625.                                           if (p[0] != '~' && stat (AdjustPath (p), &statbuf) == 0) {
  626.                                              strcpy (Out.Complete, p);
  627.                                              if ((p = strchr (Temp, '\0')) != NULL) {
  628.                                                 while (p > Temp && *p != '\\' && *p != ':' && *p != '/')
  629.                                                    p--;
  630.                                                 if (*p == '\\' || *p == ':' || *p == '/' || *p == '^' || *p == '#')
  631.                                                    p++;
  632.                                                 strcpy (Out.Name, p);
  633.                                              }
  634.                                              Out.Size = statbuf.st_size;
  635.                                              if (strstr (Out.Name, ".pk") != NULL)
  636.                                                 Out.MailPKT = TRUE;
  637.                                              else {
  638.                                                 for (x = 0; x < 7 && Out.ArcMail == FALSE; x++) {
  639.                                                    if (strstr (Out.Name, ArcFlags[x]) != NULL)
  640.                                                       Out.ArcMail = TRUE;
  641.                                                 }
  642.                                              }
  643.                                              if (Temp[0] == '^')
  644.                                                 Out.DeleteAfter = TRUE;
  645.                                              else if (Temp[0] == '#')
  646.                                                 Out.TruncateAfter = TRUE;
  647.                                              if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  648.                                                 if (AddQueue (Out) == TRUE) {
  649.                                                    TotalSize += Out.Size;
  650.                                                    TotalFiles++;
  651.                                                 }
  652.                                              }
  653.  
  654.                                              // Azzera i flags pericolosi nel caso in cui il file
  655.                                              // seguente non li abbia settati nello stesso modo.
  656.                                              Out.DeleteAfter = Out.TruncateAfter = Out.ArcMail = FALSE;
  657.                                              Out.MailPKT = FALSE;
  658.                                           }
  659.                                        }
  660.                                        fclose (fp);
  661.                                     }
  662.  
  663.                                     if (Added == FALSE) {
  664.                                        Out.Poll = TRUE;
  665.                                        if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  666.                                           if (AddQueue (Out) == TRUE) {
  667.                                              TotalSize += Out.Size;
  668.                                              TotalFiles++;
  669.                                           }
  670.                                           Added = TRUE;
  671.                                        }
  672.                                     }
  673.                                  }
  674.                                  else if (toupper (p[2]) == 'U' && toupper (p[3]) == 'T') {
  675.                                     // Trovato un pacchetto di posta. La prima lettera rappresenta
  676.                                     // il tipo di priorita'. Il file va aggiunto cosi' come si trova.
  677.                                     sscanf (ent->d_name, "%08hx", &Out.Point);
  678.                                     Out.Status = (CHAR)toupper (p[1]);
  679.                                     sprintf (Out.Complete, "%s\\%04x%04x.pnt\\%s", BasePath, Out.Net, Out.Node, ent->d_name);
  680.                                     stat (AdjustPath (Out.Complete), &statbuf);
  681.                                     strcpy (Out.Name, ent->d_name);
  682.                                     Out.Size = statbuf.st_size;
  683.                                     Out.DeleteAfter = TRUE;
  684.                                     Out.MailPKT = TRUE;
  685.                                     if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  686.                                        if (AddQueue (Out) == TRUE) {
  687.                                           TotalSize += Out.Size;
  688.                                           TotalFiles++;
  689.                                        }
  690.                                     }
  691.                                  }
  692.                                  else if (toupper (p[1]) == 'R' && toupper (p[2]) == 'E' && toupper (p[3]) == 'Q') {
  693.                                     // Trovato un file request diretto al nodo.
  694.                                     sscanf (ent->d_name, "%08hx", &Out.Point);
  695.                                     Out.Status = (CHAR)toupper (p[1]);
  696.                                     sprintf (Out.Complete, "%s\\%04x%04x.pnt\\%s", BasePath, Out.Net, Out.Node, ent->d_name);
  697.                                     stat (AdjustPath (Out.Complete), &statbuf);
  698.                                     strcpy (Out.Name, ent->d_name);
  699.                                     Out.Size = statbuf.st_size;
  700.                                     Out.DeleteAfter = TRUE;
  701.                                     Out.Request = TRUE;
  702.                                     if (Files.Add (&Out, sizeof (Out)) == TRUE) {
  703.                                        if (AddQueue (Out) == TRUE) {
  704.                                           TotalSize += Out.Size;
  705.                                           TotalFiles++;
  706.                                        }
  707.                                     }
  708.                                  }
  709.                               }
  710.                            }
  711.                            closedir (dir3);
  712.                         }
  713.                      }
  714.                   }
  715.                }
  716.                closedir (dir1);
  717.             }
  718.          }
  719.       }
  720.       closedir (dir);
  721.    }
  722. }
  723.  
  724. VOID TOutbound::PollNode (PSZ address, CHAR flag)
  725. {
  726.    FILE *fp;
  727.    CHAR PollFile[128], Outb[128];
  728.    class TAddress Addr;
  729.  
  730.    Addr.Parse (address);
  731.  
  732.    strcpy (Outb, Path);
  733.    if (Outb[strlen (Outb) - 1] == '\\' || Outb[strlen (Outb) - 1] == '/')
  734.       Outb[strlen (Outb) - 1] = '\0';
  735.  
  736.    if (Addr.Zone == 0 || DefaultZone == Addr.Zone) {
  737.       if (Addr.Point != 0) {
  738. #if defined(__LINUX__)
  739.          sprintf (PollFile, "%s/%04x%04x.pnt", Outb, Addr.Net, Addr.Node);
  740.          mkdir (PollFile, 0666);
  741.          sprintf (PollFile, "%s/%04x%04x.pnt/%08x.%clo", Outbound, Addr.Net, Addr.Node, Addr.Point, flag);
  742. #else
  743.          sprintf (PollFile, "%s\\%04x%04x.pnt", Outb, Addr.Net, Addr.Node);
  744.          mkdir (PollFile);
  745.          sprintf (PollFile, "%s\\%04x%04x.pnt\\%08x.%clo", Outb, Addr.Net, Addr.Node, Addr.Point, flag);
  746. #endif
  747.       }
  748.       else
  749. #if defined(__LINUX__)
  750.          sprintf (PollFile, "%s/%04x%04x.%clo", Outb, Addr.Net, Addr.Node, flag);
  751. #else
  752.          sprintf (PollFile, "%s\\%04x%04x.%clo", Outb, Addr.Net, Addr.Node, flag);
  753. #endif
  754.    }
  755.    else {
  756.       sprintf (PollFile, "%s.%03x", Outb, Addr.Zone);
  757. #if defined(__LINUX__)
  758.       mkdir (PollFile, 0666);
  759. #else
  760.       mkdir (PollFile);
  761. #endif
  762.       if (Addr.Point != 0) {
  763. #if defined(__LINUX__)
  764.          sprintf (PollFile, "%s.%03x/%04x%04x.pnt", Outb, Addr.Zone, Addr.Net, Addr.Node);
  765.          mkdir (PollFile, 0666);
  766.          sprintf (PollFile, "%s.%03x/%04x%04x.pnt/%08x.%clo", Outb, Addr.Zone, Addr.Net, Addr.Node, Addr.Point, flag);
  767. #else
  768.          sprintf (PollFile, "%s.%03x\\%04x%04x.pnt", Outb, Addr.Zone, Addr.Net, Addr.Node);
  769.          mkdir (PollFile);
  770.          sprintf (PollFile, "%s.%03x\\%04x%04x.pnt\\%08x.%clo", Outb, Addr.Zone, Addr.Net, Addr.Node, Addr.Point, flag);
  771. #endif
  772.       }
  773.       else
  774. #if defined(__LINUX__)
  775.          sprintf (PollFile, "%s.%03x/%04x%04x.%clo", Outb, Addr.Zone, Addr.Net, Addr.Node, flag);
  776. #else
  777.          sprintf (PollFile, "%s.%03x\\%04x%04x.%clo", Outb, Addr.Zone, Addr.Net, Addr.Node, flag);
  778. #endif
  779.    }
  780.  
  781.    if ((fp = fopen (PollFile, "at")) != NULL)
  782.       fclose (fp);
  783. }
  784.  
  785. USHORT TOutbound::First (VOID)
  786. {
  787.    USHORT RetVal = FALSE;
  788.    OUTFILE *Out;
  789.  
  790.    if ((Out = (OUTFILE *)Files.First ()) != NULL) {
  791.       Zone = Out->Zone;
  792.       Net = Out->Net;
  793.       Node = Out->Node;
  794.       Point = Out->Point;
  795.       strcpy (Domain, Out->Domain);
  796.       if (Point)
  797.          sprintf (Address, "%u:%u/%u.%u", Zone, Net, Node, Point);
  798.       else
  799.          sprintf (Address, "%u:%u/%u", Zone, Net, Node);
  800.       if (Domain[0]) {
  801.          strcat (Address, "@");
  802.          strcat (Address, Domain);
  803.       }
  804.       strcpy (Name, Out->Name);
  805.       strcpy (Complete, Out->Complete);
  806.       Size = Out->Size;
  807.       ArcMail = Out->ArcMail;
  808.       MailPKT = Out->MailPKT;
  809.       Request = Out->Request;
  810.       Poll = Out->Poll;
  811.       DeleteAfter = Out->DeleteAfter;
  812.       TruncateAfter = Out->TruncateAfter;
  813.       Status = Out->Status;
  814.       RetVal = TRUE;
  815.    }
  816.  
  817.    return (RetVal);
  818. }
  819.  
  820. USHORT TOutbound::FirstNode (VOID)
  821. {
  822.    USHORT RetVal = FALSE;
  823.    QUEUE *Queue;
  824.  
  825.    if ((Queue = (QUEUE *)Nodes.First ()) != NULL) {
  826.       Zone = Queue->Zone;
  827.       Net = Queue->Net;
  828.       Node = Queue->Node;
  829.       Point = Queue->Point;
  830.       strcpy (Domain, Queue->Domain);
  831.       if (Point)
  832.          sprintf (Address, "%u:%u/%u.%u", Zone, Net, Node, Point);
  833.       else
  834.          sprintf (Address, "%u:%u/%u", Zone, Net, Node);
  835.       if (Domain[0]) {
  836.          strcat (Address, "@");
  837.          strcat (Address, Domain);
  838.       }
  839.       Number = Queue->Files;
  840.       Size = Queue->Size;
  841.       Crash = Queue->Crash;
  842.       Direct = Queue->Direct;
  843.       Hold = Queue->Hold;
  844.       Immediate = Queue->Immediate;
  845.       Normal = Queue->Normal;
  846.       Attempts = Queue->Attempts;
  847.       Failed = Queue->Failed;
  848.       strcpy (LastCall, Queue->LastCall);
  849.       RetVal = TRUE;
  850.    }
  851.  
  852.    return (RetVal);
  853. }
  854.  
  855. VOID TOutbound::New (VOID)
  856. {
  857.    Zone = Net = Node = Point = 0;
  858.    memset (Domain, 0, sizeof (Domain));
  859.    memset (Name, 0, sizeof (Name));
  860.    memset (Complete, 0, sizeof (Complete));
  861.    Size = 0L;
  862.    ArcMail = MailPKT = Request = DeleteAfter = TruncateAfter = FALSE;
  863.    Poll = FALSE;
  864.    Status = '\0';
  865. }
  866.  
  867. USHORT TOutbound::Next (VOID)
  868. {
  869.    USHORT RetVal = FALSE;
  870.    OUTFILE *Out;
  871.  
  872.    if ((Out = (OUTFILE *)Files.Next ()) != NULL) {
  873.       Zone = Out->Zone;
  874.       Net = Out->Net;
  875.       Node = Out->Node;
  876.       Point = Out->Point;
  877.       strcpy (Domain, Out->Domain);
  878.       if (Point)
  879.          sprintf (Address, "%u:%u/%u.%u", Zone, Net, Node, Point);
  880.       else
  881.          sprintf (Address, "%u:%u/%u", Zone, Net, Node);
  882.       if (Domain[0]) {
  883.          strcat (Address, "@");
  884.          strcat (Address, Domain);
  885.       }
  886.       strcpy (Name, Out->Name);
  887.       strcpy (Complete, Out->Complete);
  888.       Size = Out->Size;
  889.       ArcMail = Out->ArcMail;
  890.       MailPKT = Out->MailPKT;
  891.       Request = Out->Request;
  892.       Poll = Out->Poll;
  893.       DeleteAfter = Out->DeleteAfter;
  894.       TruncateAfter = Out->TruncateAfter;
  895.       Status = Out->Status;
  896.       RetVal = TRUE;
  897.    }
  898.  
  899.    return (RetVal);
  900. }
  901.  
  902. USHORT TOutbound::NextNode (VOID)
  903. {
  904.    USHORT RetVal = FALSE;
  905.    QUEUE *Queue;
  906.  
  907.    if ((Queue = (QUEUE *)Nodes.Next ()) != NULL) {
  908.       Zone = Queue->Zone;
  909.       Net = Queue->Net;
  910.       Node = Queue->Node;
  911.       Point = Queue->Point;
  912.       strcpy (Domain, Queue->Domain);
  913.       if (Point)
  914.          sprintf (Address, "%u:%u/%u.%u", Zone, Net, Node, Point);
  915.       else
  916.          sprintf (Address, "%u:%u/%u", Zone, Net, Node);
  917.       if (Domain[0]) {
  918.          strcat (Address, "@");
  919.          strcat (Address, Domain);
  920.       }
  921.       Number = Queue->Files;
  922.       Size = Queue->Size;
  923.       Crash = Queue->Crash;
  924.       Direct = Queue->Direct;
  925.       Hold = Queue->Hold;
  926.       Immediate = Queue->Immediate;
  927.       Normal = Queue->Normal;
  928.       Attempts = Queue->Attempts;
  929.       Failed = Queue->Failed;
  930.       strcpy (LastCall, Queue->LastCall);
  931.       RetVal = TRUE;
  932.    }
  933.  
  934.    return (RetVal);
  935. }
  936.  
  937. VOID TOutbound::Remove (VOID)
  938. {
  939.    int fd;
  940.    USHORT More = FALSE, Stop = FALSE;
  941.    CHAR FileName[128], i;
  942.    OUTFILE *Out;
  943.    QUEUE *Temp;
  944.  
  945.    if ((Out = (OUTFILE *)Files.Value ()) != NULL) {
  946.       AdjustPath (Out->Complete);
  947.       if (Out->DeleteAfter == TRUE)
  948.          unlink (Out->Complete);
  949.       else if (Out->TruncateAfter == TRUE) {
  950.          if ((fd = sopen (Out->Complete, O_WRONLY|O_BINARY|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE)) != -1)
  951.             close (fd);
  952.       }
  953.  
  954.       TotalFiles--;
  955.       TotalSize -= Out->Size;
  956.  
  957.       if ((Temp = (QUEUE *)Nodes.First ()) != NULL)
  958.          do {
  959.             if (Temp->Zone == Zone && Temp->Net == Net && Temp->Node == Node && Temp->Point == Point && !stricmp (Temp->Domain, Domain)) {
  960.                Temp->Files--;
  961.                Temp->Size -= Out->Size;
  962.                if (Temp->Files == 0) {
  963.                   Nodes.Remove ();
  964.                   TotalNodes--;
  965.                }
  966.                Stop = TRUE;
  967.             }
  968.          } while (Stop == FALSE && (Temp = (QUEUE *)Nodes.Next ()) != NULL);
  969.  
  970.       Files.Remove ();
  971.  
  972.       if (MailPKT == FALSE && Request == FALSE) {
  973.          if ((Out = (OUTFILE *)Files.First ()) != NULL)
  974.             do {
  975.                if (Out->MailPKT == FALSE && Out->Request == FALSE && Out->Status == Status) {
  976.                   if (Out->Zone == Zone && Out->Net == Net && Out->Node == Node && Out->Point == Point) {
  977.                      if (!stricmp (Out->Domain, Domain))
  978.                         More = TRUE;
  979.                   }
  980.                }
  981.             } while (More == FALSE && (Out = (OUTFILE *)Files.Next ()) != NULL);
  982.  
  983.          if (More == FALSE) {
  984.             strcpy (Outbound, Path);
  985.             if (Zone != DefaultZone) {
  986.                Outbound[strlen (Outbound) - 1] = '\0';
  987.                sprintf (FileName, ".%03x\\", Zone);
  988.                strcat (Outbound, FileName);
  989.             }
  990.             if (Point != 0)
  991.                sprintf (FileName, "%s%04x%04x.PNT\\%08x.%cLO", Outbound, Net, Node, Point, Status);
  992.             else
  993.                sprintf (FileName, "%s%04x%04x.%cLO", Outbound, Net, Node, Status);
  994.             unlink (FileName);
  995.  
  996.             for (i = '0'; i <= '9'; i++) {
  997.                if (Point != 0)
  998.                   sprintf (FileName, "%s%04x%04x.PNT\\%08x.$$%c", Outbound, Net, Node, Point, i);
  999.                else
  1000.                   sprintf (FileName, "%s%04x%04x.$$%c", Outbound, Net, Node, i);
  1001.                unlink (FileName);
  1002.             }
  1003.          }
  1004.       }
  1005.    }
  1006. }
  1007.  
  1008. VOID TOutbound::AddAttempt (PSZ address, USHORT failed, PSZ status)
  1009. {
  1010.    int fd;
  1011.    USHORT attempts = 0;
  1012.    CHAR i, FileName[128], Status[32];
  1013.    QUEUE *Queue, *Current;
  1014.    class TAddress Addr;
  1015.  
  1016.    Addr.Parse (address);
  1017.  
  1018.    strcpy (Outbound, Path);
  1019.    if (Addr.Zone != DefaultZone) {
  1020.       Outbound[strlen (Outbound) - 1] = '\0';
  1021.       sprintf (FileName, ".%03x/", Addr.Zone);
  1022.       strcat (Outbound, FileName);
  1023.    }
  1024.  
  1025.    for (i = '0'; i <= '9'; i++) {
  1026.       if (Addr.Point != 0)
  1027.          sprintf (FileName, "%s%04x%04x.pnt/%08x.$$%c", Outbound, Addr.Net, Addr.Node, Addr.Point, i);
  1028.       else
  1029.          sprintf (FileName, "%s%04x%04x.$$%c", Outbound, Addr.Net, Addr.Node, i);
  1030.       if ((fd = open (FileName, O_RDWR|O_BINARY)) != -1) {
  1031.          read (fd, &attempts, sizeof (attempts));
  1032.          read (fd, Status, sizeof (Status));
  1033.          close (fd);
  1034.          break;
  1035.       }
  1036.    }
  1037.  
  1038.    if (i > '9')
  1039.       i = '0';
  1040.  
  1041.    if (failed == TRUE && i < '9') {
  1042.       unlink (FileName);
  1043.       i++;
  1044.    }
  1045.  
  1046.    if (Addr.Point != 0)
  1047.       sprintf (FileName, "%s%04x%04x.pnt/%08x.$$%c", Outbound, Addr.Net, Addr.Node, Addr.Point, i);
  1048.    else
  1049.       sprintf (FileName, "%s%04x%04x.$$%c", Outbound, Addr.Net, Addr.Node, i);
  1050.  
  1051.    memset (Status, 0, sizeof (Status));
  1052.    strcpy (Status, status);
  1053.    attempts++;
  1054.  
  1055.    if ((fd = open (FileName, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE)) != -1) {
  1056.       write (fd, &attempts, sizeof (attempts));
  1057.       write (fd, Status, sizeof (Status));
  1058.       close (fd);
  1059.    }
  1060.  
  1061.    Current = (QUEUE *)Nodes.Value ();
  1062.    if ((Queue = (QUEUE *)Nodes.First ()) != NULL)
  1063.       do {
  1064.          if (Addr.Zone == Queue->Zone && Addr.Net == Queue->Net && Addr.Node == Queue->Node && Addr.Point == Queue->Point) {
  1065.             Queue->Attempts = attempts;
  1066.             Queue->Failed = (USHORT)(i - '0');
  1067.             memcpy (Queue->LastCall, Status, sizeof (Queue->LastCall));
  1068.             break;
  1069.          }
  1070.       } while ((Queue = (QUEUE *)Nodes.Next ()) != NULL);
  1071.  
  1072.    if ((Queue = (QUEUE *)Nodes.First ()) != NULL)
  1073.       do {
  1074.          if (Queue == Current)
  1075.             break;
  1076.       } while ((Queue = (QUEUE *)Nodes.Next ()) != NULL);
  1077. }
  1078.  
  1079. VOID TOutbound::ClearAttempt (PSZ address)
  1080. {
  1081.    CHAR i, FileName[128];
  1082.    QUEUE *Queue, *Current;
  1083.    class TAddress Addr;
  1084.  
  1085.    Addr.Parse (address);
  1086.  
  1087.    strcpy (Outbound, Path);
  1088.    if (Addr.Zone != DefaultZone) {
  1089.       Outbound[strlen (Outbound) - 1] = '\0';
  1090.       sprintf (FileName, ".%03x/", Addr.Zone);
  1091.       strcat (Outbound, FileName);
  1092.    }
  1093.  
  1094.    for (i = '0'; i <= '9'; i++) {
  1095.       if (Addr.Point != 0)
  1096.          sprintf (FileName, "%s%04x%04x.pnt/%08x.$$%c", Outbound, Addr.Net, Addr.Node, Addr.Point, i);
  1097.       else
  1098.          sprintf (FileName, "%s%04x%04x.$$%c", Outbound, Addr.Net, Addr.Node, i);
  1099.       unlink (FileName);
  1100.    }
  1101.  
  1102.    Current = (QUEUE *)Nodes.Value ();
  1103.    if ((Queue = (QUEUE *)Nodes.First ()) != NULL)
  1104.       do {
  1105.          if (Addr.Zone == Queue->Zone && Addr.Net == Queue->Net && Addr.Node == Queue->Node && Addr.Point == Queue->Point) {
  1106.             Queue->Attempts = 0;
  1107.             Queue->Failed = 0;
  1108.             memset (Queue->LastCall, 0, sizeof (Queue->LastCall));
  1109.             break;
  1110.          }
  1111.       } while ((Queue = (QUEUE *)Nodes.Next ()) != NULL);
  1112.  
  1113.    if ((Queue = (QUEUE *)Nodes.First ()) != NULL)
  1114.       do {
  1115.          if (Queue == Current)
  1116.             break;
  1117.       } while ((Queue = (QUEUE *)Nodes.Next ()) != NULL);
  1118. }
  1119.  
  1120. VOID TOutbound::Update (VOID)
  1121. {
  1122.    FILE *fp;
  1123.    int fd;
  1124.    CHAR FileName[128], i;
  1125.  
  1126.    if (FirstNode () == TRUE)
  1127.       do {
  1128.          strcpy (Outbound, Path);
  1129.          if (Zone != DefaultZone) {
  1130.             Outbound[strlen (Outbound) - 1] = '\0';
  1131.             sprintf (FileName, ".%03x/", Zone);
  1132.             strcat (Outbound, FileName);
  1133.          }
  1134.          for (i = '0'; i <= '9'; i++) {
  1135.             if (Point != 0)
  1136.                sprintf (FileName, "%s%04x%04x.pnt/%08x.$$%c", Outbound, Net, Node, Point, i);
  1137.             else
  1138.                sprintf (FileName, "%s%04x%04x.$$%c", Outbound, Net, Node, i);
  1139.             unlink (FileName);
  1140.          }
  1141.       } while (NextNode () == TRUE);
  1142.  
  1143.    if (First () == TRUE)
  1144.       do {
  1145.          if (MailPKT == FALSE && Request == FALSE) {
  1146.             strcpy (Outbound, Path);
  1147.             if (Zone != DefaultZone) {
  1148.                Outbound[strlen (Outbound) - 1] = '\0';
  1149.                sprintf (FileName, ".%03x/", Zone);
  1150.                strcat (Outbound, FileName);
  1151.             }
  1152.             if (Point != 0)
  1153.                sprintf (FileName, "%s%04x%04x.pnt/%08x.%clo", Outbound, Net, Node, Point, Status);
  1154.             else
  1155.                sprintf (FileName, "%s%04x%04x.%clo", Outbound, Net, Node, Status);
  1156.             unlink (FileName);
  1157.          }
  1158.       } while (Next () == TRUE);
  1159.  
  1160.    if (FirstNode () == TRUE)
  1161.       do {
  1162.          if (Attempts != 0 || Failed != 0) {
  1163.             strcpy (Outbound, Path);
  1164.             if (Zone != DefaultZone) {
  1165.                Outbound[strlen (Outbound) - 1] = '\0';
  1166.                sprintf (FileName, ".%03x/", Zone);
  1167.                strcat (Outbound, FileName);
  1168.             }
  1169.             if (Point != 0)
  1170.                sprintf (FileName, "%s%04x%04x.pnt/%08x.$$%c", Outbound, Net, Node, Point, Failed + '0');
  1171.             else
  1172.                sprintf (FileName, "%s%04x%04x.$$%c", Outbound, Net, Node, Failed + '0');
  1173.             if ((fd = open (FileName, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE)) != -1) {
  1174.                write (fd, &Attempts, 2);
  1175.                close (fd);
  1176.             }
  1177.          }
  1178.       } while (NextNode () == TRUE);
  1179.  
  1180.    if (First () == TRUE)
  1181.       do {
  1182.          if (MailPKT == FALSE && Request == FALSE) {
  1183.             strcpy (Outbound, Path);
  1184.             if (Zone != DefaultZone) {
  1185.                Outbound[strlen (Outbound) - 1] = '\0';
  1186.                sprintf (FileName, ".%03x", Zone);
  1187.                strcat (Outbound, FileName);
  1188. #if defined(__LINUX__)
  1189.                mkdir (Outbound, 0666);
  1190.                strcat (Outbound, "/");
  1191. #else
  1192.                mkdir (Outbound);
  1193.                strcat (Outbound, "\\");
  1194. #endif
  1195.             }
  1196.  
  1197.             if (Point != 0) {
  1198.                sprintf (FileName, "%s%04x%04x.pnt", Outbound, Net, Node);
  1199. #if defined(__LINUX__)
  1200.                mkdir (FileName, 0666);
  1201. #else
  1202.                mkdir (FileName);
  1203. #endif
  1204.                sprintf (FileName, "%s%04x%04x.pnt/%08x.%clo", Outbound, Net, Node, Point, Status);
  1205.             }
  1206.             else
  1207.                sprintf (FileName, "%s%04x%04x.%clo", Outbound, Net, Node, Status);
  1208.  
  1209.             if ((fp = _fsopen (AdjustPath (FileName), "ab", SH_DENYNO)) != NULL) {
  1210.                if (TruncateAfter == TRUE)
  1211.                   fprintf (fp, "#%s\r\n", Complete);
  1212.                else if (DeleteAfter == TRUE)
  1213.                   fprintf (fp, "^%s\r\n", Complete);
  1214.                else if (Poll == FALSE)
  1215.                   fprintf (fp, "%s\r\n", Complete);
  1216.                fclose (fp);
  1217.             }
  1218.          }
  1219.       } while (Next () == TRUE);
  1220. }
  1221.  
  1222.  
  1223.