home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / MAIL.CPP < prev    next >
C/C++ Source or Header  |  1996-09-11  |  67KB  |  1,924 lines

  1.  
  2. // ----------------------------------------------------------------------
  3. // LoraBBS Professional Edition - Version 3.00.11
  4. // Copyright (c) 1996 by Marco Maccaferri. All rights reserved.
  5. //
  6. // History:
  7. //    07/17/95 - Initial coding.
  8. // ----------------------------------------------------------------------
  9.  
  10. #include "_ldefs.h"
  11. #include "mail.h"
  12.  
  13. PSZ CheckExts[] = { ".su", ".mo", ".tu", ".we", ".th", ".fr", ".sa", NULL };
  14.  
  15. TKludges::TKludges (void)
  16. {
  17.    Data.Clear ();
  18.    Sort = TRUE;
  19. }
  20.  
  21. TKludges::~TKludges (void)
  22. {
  23.    Data.Clear ();
  24. }
  25.  
  26. USHORT TKludges::Add (VOID)
  27. {
  28.    USHORT Insert = FALSE;
  29.    CHAR Temp[64];
  30.    KLUDGES Buffer, *Current;
  31.  
  32.    sprintf (Temp, "%u:%u/%u.%u", Zone, Net, Node, Point);
  33.  
  34.    if (Check (Temp) == FALSE) {
  35.       memset (&Buffer, 0, sizeof (KLUDGES));
  36.  
  37.       Buffer.Zone = Zone;
  38.       Buffer.Net = Net;
  39.       Buffer.Node = Node;
  40.       Buffer.Point = Point;
  41.  
  42.       if (Sort == TRUE) {
  43.          if ((Current = (KLUDGES *)Data.First ()) != NULL) {
  44.             if (Current->Net > Net)
  45.                Insert = TRUE;
  46.             else if (Current->Net == Net && Current->Node > Node)
  47.                Insert = TRUE;
  48.             else if (Current->Net == Net && Current->Node == Node && Current->Point > Point)
  49.                Insert = TRUE;
  50.  
  51.             if (Insert == TRUE) {
  52.                Data.Insert (&Buffer, sizeof (KLUDGES));
  53.                Data.Insert (Current, sizeof (KLUDGES));
  54.                Data.First ();
  55.                Data.Remove ();
  56.                Data.First ();
  57.             }
  58.             else {
  59.                while ((Current = (KLUDGES *)Data.Next ()) != NULL) {
  60.                   if (Current->Net > Net)
  61.                      Insert = TRUE;
  62.                   else if (Current->Net == Net && Current->Node > Node)
  63.                      Insert = TRUE;
  64.                   else if (Current->Net == Net && Current->Node == Node && Current->Point > Point)
  65.                      Insert = TRUE;
  66.  
  67.                   if (Insert == TRUE) {
  68.                      Data.Previous ();
  69.                      Data.Insert (&Buffer, sizeof (KLUDGES));
  70.                      break;
  71.                   }
  72.                }
  73.                if (Insert == FALSE) {
  74.                   Data.Add (&Buffer, sizeof (KLUDGES));
  75.                   Insert = TRUE;
  76.                }
  77.             }
  78.          }
  79.          else {
  80.             if (Insert == FALSE) {
  81.                Data.Add (&Buffer, sizeof (KLUDGES));
  82.                Insert = TRUE;
  83.             }
  84.          }
  85.       }
  86.       else
  87.          Data.Add (&Buffer, sizeof (KLUDGES));
  88.    }
  89.  
  90.    return (Insert);
  91. }
  92.  
  93. USHORT TKludges::AddString (PSZ pszString)
  94. {
  95.    USHORT RetVal = FALSE;
  96.    CHAR Temp[128], *p;
  97.    class TAddress Address;
  98.  
  99.    strcpy (Temp, pszString);
  100.    if ((p = strtok (Temp, " ")) != NULL)
  101.       do {
  102.          if (Check (p) == FALSE) {
  103.             Address.Parse (p);
  104.             Zone = Address.Zone;
  105.             if (Address.Net != 0)
  106.                Net = Address.Net;
  107.             if (Address.Node != 0)
  108.                Node = Address.Node;
  109.             Point = Address.Point;
  110.             RetVal = Add ();
  111.          }
  112.       } while ((p = strtok (NULL, " ")) != NULL);
  113.  
  114.    return (RetVal);
  115. }
  116.  
  117. USHORT TKludges::Check (PSZ pszAddress)
  118. {
  119.    USHORT RetVal = FALSE;
  120.    KLUDGES *El;
  121.    class TAddress Addr;
  122.  
  123.    Addr.Parse (pszAddress);
  124.  
  125.    if ((El = (KLUDGES *)Data.First ()) != NULL)
  126.       do {
  127.          if (El->Net == Addr.Net && El->Node == Addr.Node && El->Point == Addr.Point) {
  128.             Zone = El->Zone;
  129.             Net = El->Net;
  130.             Node = El->Node;
  131.             Point = El->Point;
  132.             sprintf (Address, "%u/%u", Net, Node);
  133.             RetVal = TRUE;
  134.             break;
  135.          }
  136.       } while ((El = (KLUDGES *)Data.Next ()) != NULL);
  137.  
  138.    return (RetVal);
  139. }
  140.  
  141. VOID TKludges::Clear (VOID)
  142. {
  143.    Data.Clear ();
  144.    New ();
  145. }
  146.  
  147. VOID TKludges::Delete (VOID)
  148. {
  149.    if (Data.Value () != NULL)
  150.       Data.Remove ();
  151. }
  152.  
  153. USHORT TKludges::First (VOID)
  154. {
  155.    USHORT RetVal = FALSE;
  156.    KLUDGES *El;
  157.  
  158.    if ((El = (KLUDGES *)Data.First ()) != NULL) {
  159.       Zone = El->Zone;
  160.       Net = El->Net;
  161.       Node = El->Node;
  162.       Point = El->Point;
  163.       if (Point != 0)
  164.          sprintf (Address, "%u/%u.%u", Net, Node, Point);
  165.       else
  166.          sprintf (Address, "%u/%u", Net, Node);
  167.       strcpy (ShortAddress, Address);
  168.       RetVal = TRUE;
  169.    }
  170.  
  171.    return (RetVal);
  172. }
  173.  
  174. VOID TKludges::New (VOID)
  175. {
  176.    Zone = 0;
  177.    Net = 0;
  178.    Node = 0;
  179.    Point = 0;
  180. }
  181.  
  182. USHORT TKludges::Next (VOID)
  183. {
  184.    USHORT RetVal = FALSE;
  185.    KLUDGES *El;
  186.  
  187.    if ((El = (KLUDGES *)Data.Next ()) != NULL) {
  188.       if (Net != El->Net) {
  189.          if (El->Point != 0)
  190.             sprintf (ShortAddress, "%u/%u.%u", El->Net, El->Node, El->Point);
  191.          else
  192.             sprintf (ShortAddress, "%u/%u", El->Net, El->Node);
  193.       }
  194.       else {
  195.          if (Node == El->Node && El->Point != 0)
  196.             sprintf (ShortAddress, ".%u", El->Point);
  197.          else {
  198.             if (El->Point != 0)
  199.                sprintf (ShortAddress, "%u.%u", El->Point);
  200.             else
  201.                sprintf (ShortAddress, "%u", El->Node);
  202.          }
  203.       }
  204.  
  205.       Zone = El->Zone;
  206.       Net = El->Net;
  207.       Node = El->Node;
  208.       Point = El->Point;
  209.       if (Point != 0)
  210.          sprintf (Address, "%u/%u.%u", Net, Node, Point);
  211.       else
  212.          sprintf (Address, "%u/%u", Net, Node);
  213.       RetVal = TRUE;
  214.    }
  215.  
  216.    return (RetVal);
  217. }
  218.  
  219. // ----------------------------------------------------------------------
  220.  
  221. TMail::TMail (void)
  222. {
  223. #if defined(__LINUX__)
  224.    strcpy (Inbound, "./");
  225. #else
  226.    strcpy (Inbound, ".\\");
  227. #endif
  228.    Log = NULL;
  229.  
  230.    Msg = NULL;
  231.    Packet = NULL;
  232.    PktName[0] = LastTag[0] = '\0';
  233.    MsgTossed = Duplicate = Bad = NetMail = 0L;
  234.    Packets = 0;
  235. }
  236.  
  237. TMail::~TMail (void)
  238. {
  239.    if (Msg != NULL) {
  240.       Msg->UnLock ();
  241.       delete Msg;
  242.       Msg = NULL;
  243.    }
  244.    if (Packet != NULL) {
  245.       delete Packet;
  246.       Packet = NULL;
  247.    }
  248. }
  249.  
  250. USHORT TMail::OpenNextPacket (VOID)
  251. {
  252.    DIR *dir;
  253.    USHORT RetVal = FALSE, MaxBad;
  254.    CHAR Filename[128], OpenFileName[128];
  255.    PSZ p;
  256.    ULONG PktDate;
  257.    struct dirent *ent;
  258.    struct stat statbuf;
  259.  
  260.    strcpy (Filename, Inbound);
  261.    if (Filename[strlen (Filename) - 1] == '\\' || Filename[strlen (Filename) - 1] == '/')
  262.       Filename[strlen (Filename) - 1] = '\0';
  263.  
  264.    if ((dir = opendir (Filename)) != NULL) {
  265.       while ((ent = readdir (dir)) != NULL) {
  266.          strlwr (ent->d_name);
  267.          if (strstr (ent->d_name, ".pk") != NULL) {
  268.             sprintf (Filename, "%s%s", Inbound, ent->d_name);
  269.             stat (Filename, &statbuf);
  270.             strcpy (PktName, ent->d_name);
  271.             PktDate = statbuf.st_mtime;
  272.             RetVal = TRUE;
  273.             break;
  274.          }
  275.       }
  276.  
  277.       if (RetVal == TRUE) {
  278.          while ((ent = readdir (dir)) != NULL) {
  279.             strlwr (ent->d_name);
  280.             if (strstr (ent->d_name, ".pk") != NULL) {
  281.                sprintf (Filename, "%s%s", Inbound, ent->d_name);
  282.                stat (Filename, &statbuf);
  283.                if (PktDate > statbuf.st_mtime) {
  284.                   strcpy (PktName, ent->d_name);
  285.                   PktDate = statbuf.st_mtime;
  286.                }
  287.             }
  288.          }
  289.       }
  290.  
  291.       closedir (dir);
  292.    }
  293.  
  294.    if (RetVal == TRUE) {
  295.       MaxBad = 0;
  296.  
  297.       strcpy (Filename, Inbound);
  298.       if (Filename[strlen (Filename) - 1] == '\\' || Filename[strlen (Filename) - 1] == '/')
  299.          Filename[strlen (Filename) - 1] = '\0';
  300.  
  301.       if ((dir = opendir (Filename)) != NULL) {
  302.          while ((ent = readdir (dir)) != NULL) {
  303.             strlwr (ent->d_name);
  304.             if (strstr (ent->d_name, "bad_pkt.") != NULL) {
  305.                if ((p = strchr (ent->d_name, '.')) != NULL) {
  306.                   p++;
  307.                   if (atoi (p) > MaxBad)
  308.                      MaxBad = (USHORT)atoi (p);
  309.                }
  310.             }
  311.          }
  312.          closedir (dir);
  313.       }
  314.  
  315. // We have found a valid packet. To avoid system lockups due to an invalid
  316. // packet file we now rename the file to something that prevents the same
  317. // file to be read two times.
  318.       sprintf (Filename, "%s%s", Inbound, PktName);
  319.       sprintf (OpenFileName, "%sbad_pkt.%03d", Inbound, ++MaxBad);
  320.       rename (Filename, OpenFileName);
  321.  
  322.       if (Packet != NULL)
  323.          delete Packet;
  324.  
  325.       if ((Packet = new PACKET) != NULL) {
  326.          if (Packet->Open (OpenFileName, FALSE) == FALSE) {
  327.             delete Packet;
  328.             Packet = NULL;
  329.             RetVal = FALSE;
  330.          }
  331.       }
  332.    }
  333.  
  334.    return (RetVal);
  335. }
  336.  
  337. USHORT TMail::ExportEchoMail (ULONG Number, PSZ pszEchoTag)
  338. {
  339.    USHORT SentArea = 0;
  340.    CHAR *Text;
  341.    class TAddress ToAddr;
  342.  
  343.    if (Msg != NULL) {
  344.       if (Msg->Read (Number, MAX_LINE_LENGTH) == TRUE) {
  345.          sprintf (Temp, "AREA:%s", pszEchoTag);
  346.          if ((Text = (PSZ)Msg->Text.First ()) != NULL) {
  347.             Msg->Text.Insert (Temp, (USHORT)(strlen (Temp) + 1));
  348.             if (*Text != '\0')
  349.                Msg->Text.Insert (Text, (USHORT)(strlen (Text) + 1));
  350.             Msg->Text.First ();
  351.             Msg->Text.Remove ();
  352.          }
  353.          else
  354.             Msg->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  355.  
  356.          SeenBy = new TKludges;
  357.          Path = new TKludges;
  358.  
  359.          if (SeenBy != NULL && Path != NULL) {
  360.             Path->Sort = FALSE;
  361.             if ((Text = (PSZ)Msg->Text.First ()) != NULL)
  362.                do {
  363.                   if (!strncmp (Text, "SEEN-BY: ", 9) && SeenBy != NULL) {
  364.                      SeenBy->AddString (&Text[9]);
  365.                      Msg->Text.Remove ();
  366.                      Text = (PSZ)Msg->Text.Value ();
  367.                   }
  368.                   else if (!strncmp (Text, "\001PATH: ", 7) && Path != NULL) {
  369.                      Path->AddString (&Text[7]);
  370.                      Msg->Text.Remove ();
  371.                      Text = (PSZ)Msg->Text.Value ();
  372.                   }
  373.                   else {
  374.                      if (Msg->Local == TRUE && Cfg->ReplaceTear == TRUE) {
  375.                         if (!strncmp (Text, "---", 3)) {
  376.                            sprintf (Temp, "--- %s", Cfg->TearLine);
  377.                            strsrep (Temp, "%1", VERSION);
  378.                            Msg->Text.Replace (Temp, (USHORT)(strlen (Temp) + 1));
  379.                         }
  380.                      }
  381.                      Text = (PSZ)Msg->Text.Next ();
  382.                   }
  383.                } while (Text != NULL);
  384.  
  385.             if (Forward->First () == TRUE)
  386.                do {
  387.                   Forward->Skip = FALSE;
  388.                   Forward->Update ();
  389.                } while (Forward->Next () == TRUE);
  390.  
  391.             if (Forward->First () == TRUE)
  392.                do {
  393.                   if (SeenBy->Check (Forward->Address) == TRUE) {
  394.                      Forward->Skip = TRUE;
  395.                      Forward->Update ();
  396.                   }
  397.                   else
  398.                      SeenBy->AddString (Forward->Address);
  399.                } while (Forward->Next () == TRUE);
  400.  
  401.             if (Data->Address[0] != '\0') {
  402.                SeenBy->AddString (Data->Address);
  403.                Path->AddString (Data->Address);
  404.             }
  405.             else if (Cfg->MailAddress.First () == TRUE) {
  406.                SeenBy->AddString (Cfg->MailAddress.String);
  407.                Path->AddString (Cfg->MailAddress.String);
  408.             }
  409.  
  410.             if (SeenBy->First () == TRUE) {
  411.                strcpy (Temp, "SEEN-BY:");
  412.                do {
  413.                   if (strlen (Temp) + strlen (SeenBy->ShortAddress) + 1 > 70) {
  414.                      Msg->Text.Add (Temp);
  415.                      strcpy (Temp, "SEEN-BY:");
  416.                      strcpy (SeenBy->ShortAddress, SeenBy->Address);
  417.                   }
  418.                   if (SeenBy->Net != Cfg->FakeNet && SeenBy->Point == 0) {
  419.                      strcat (Temp, " ");
  420.                      strcat (Temp, SeenBy->ShortAddress);
  421.                   }
  422.                } while (SeenBy->Next () == TRUE);
  423.                if (strlen (Temp) > 8)
  424.                   Msg->Text.Add (Temp);
  425.             }
  426.  
  427.             if (Path->First () == TRUE) {
  428.                strcpy (Temp, "\001PATH:");
  429.                do {
  430.                   if (strlen (Temp) + strlen (Path->ShortAddress) + 1 > 70) {
  431.                      Msg->Text.Add (Temp);
  432.                      strcpy (Temp, "\001PATH:");
  433.                      strcpy (Path->ShortAddress, SeenBy->Address);
  434.                   }
  435.                   if (Path->Point == 0) {
  436.                      strcat (Temp, " ");
  437.                      strcat (Temp, Path->ShortAddress);
  438.                   }
  439.                } while (Path->Next () == TRUE);
  440.                if (strlen (Temp) > 6)
  441.                   Msg->Text.Add (Temp);
  442.             }
  443.          }
  444.  
  445.          if (Path != NULL)
  446.             delete Path;
  447.          if (SeenBy != NULL)
  448.             delete SeenBy;
  449.  
  450.          if (Forward->First () == TRUE)
  451.             do {
  452.                if (Forward->Skip == FALSE) {
  453.                   if ((Packet = new PACKET) != NULL) {
  454.                      strcpy (Packet->ToAddress, Forward->Address);
  455.  
  456.                      if (Data->Address[0] != '\0')
  457.                         strcpy (Packet->FromAddress, Data->Address);
  458.                      else {
  459.                         ToAddr.Parse (Packet->ToAddress);
  460.                         if (Cfg->MailAddress.First () == TRUE) {
  461.                            strcpy (Packet->FromAddress, Cfg->MailAddress.String);
  462.                            do {
  463.                               if (Cfg->MailAddress.Zone == ToAddr.Zone) {
  464.                                  strcpy (Packet->FromAddress, Cfg->MailAddress.String);
  465.                                  break;
  466.                               }
  467.                            } while (Cfg->MailAddress.Next () == TRUE);
  468.                         }
  469.                      }
  470.  
  471.                      Cfg->MailAddress.First ();
  472.                      if (Cfg->MailAddress.Zone == Forward->Zone) {
  473.                         if (Forward->Point != 0) {
  474. #if defined(__LINUX__)
  475.                            sprintf (Temp, "%s/%04x%04x.pnt", Outbound, Forward->Net, Forward->Node);
  476.                            mkdir (Temp, 0666);
  477.                            sprintf (Temp, "%s/%04x%04x.pnt/%08x.xpr", Outbound, Forward->Net, Forward->Node, Forward->Point);
  478. #else
  479.                            sprintf (Temp, "%s\\%04x%04x.pnt", Outbound, Forward->Net, Forward->Node);
  480.                            mkdir (Temp);
  481.                            sprintf (Temp, "%s\\%04x%04x.pnt\\%08x.xpr", Outbound, Forward->Net, Forward->Node, Forward->Point);
  482. #endif
  483.                         }
  484.                         else
  485. #if defined(__LINUX__)
  486.                            sprintf (Temp, "%s/%04x%04x.xpr", Outbound, Forward->Net, Forward->Node);
  487. #else
  488.                            sprintf (Temp, "%s\\%04x%04x.xpr", Outbound, Forward->Net, Forward->Node);
  489. #endif
  490.                      }
  491.                      else {
  492.                         sprintf (Temp, "%s.%03x", Outbound, Forward->Zone);
  493. #if defined(__LINUX__)
  494.                         mkdir (Temp, 0666);
  495. #else
  496.                         mkdir (Temp);
  497. #endif
  498.                         if (Forward->Point != 0) {
  499. #if defined(__LINUX__)
  500.                            sprintf (Temp, "%s.%03x/%04x%04x.pnt", Outbound, Forward->Zone, Forward->Net, Forward->Node);
  501.                            mkdir (Temp, 0666);
  502.                            sprintf (Temp, "%s.%03x/%04x%04x.pnt/%08x.xpr", Outbound, Forward->Zone, Forward->Net, Forward->Node, Forward->Point);
  503. #else
  504.                            sprintf (Temp, "%s.%03x\\%04x%04x.pnt", Outbound, Forward->Zone, Forward->Net, Forward->Node);
  505.                            mkdir (Temp);
  506.                            sprintf (Temp, "%s.%03x\\%04x%04x.pnt\\%08x.xpr", Outbound, Forward->Zone, Forward->Net, Forward->Node, Forward->Point);
  507. #endif
  508.                         }
  509.                         else
  510. #if defined(__LINUX__)
  511.                            sprintf (Temp, "%s.%03x/%04x%04x.xpr", Outbound, Forward->Zone, Forward->Net, Forward->Node);
  512. #else
  513.                            sprintf (Temp, "%s.%03x\\%04x%04x.xpr", Outbound, Forward->Zone, Forward->Net, Forward->Node);
  514. #endif
  515.                      }
  516.                      if (stat (Temp, &statbuf) != 0) {
  517.                         if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  518.                            if (Nodes->Read (Forward->Address) == TRUE)
  519.                               strcpy (Packet->Password, Nodes->OutPktPwd);
  520.                            delete Nodes;
  521.                            Nodes = NULL;
  522.                         }
  523.                      }
  524.                      if (Packet->Open (Temp, FALSE) == TRUE)
  525.                         Packet->Add (Msg);
  526.                      delete Packet;
  527.  
  528.                      SentArea++;
  529.                   }
  530.                }
  531.             } while (Forward->Next () == TRUE);
  532.  
  533.          if (Dupes->Check (Data->EchoTag, Msg) == FALSE)
  534.             Dupes->Add (Data->EchoTag, Msg);
  535.       }
  536.    }
  537.  
  538.    return (SentArea);
  539. }
  540.  
  541. VOID TMail::Export (VOID)
  542. {
  543.    USHORT i;
  544.    ULONG Number, SentArea;
  545.  
  546.    Data = new TMsgData (Cfg->SystemPath);
  547.    Forward = new TEchoLink (Cfg->SystemPath);
  548.    Dupes = new TDupes (Cfg->SystemPath);
  549.  
  550.    strcpy (Outbound, Cfg->Outbound);
  551.    if (Outbound[strlen (Outbound) - 1] == '\\' || Outbound[strlen (Outbound) - 1] == '/')
  552.       Outbound[strlen (Outbound) - 1] = '\0';
  553.  
  554.    if (Log != NULL)
  555.       Log->Write ("#Scanning messages");
  556.  
  557.    SentArea = MsgSent = 0L;
  558.  
  559.    if (Data != NULL && Forward != NULL) {
  560.       if (Data->First () == TRUE)
  561.          do {
  562.             if (Data->EchoMail == TRUE && Data->EchoTag[0] != '\0') {
  563.                Dupes->Load (Data->EchoTag);
  564.  
  565.                Msg = NULL;
  566.                if (Data->Storage == ST_JAM)
  567.                   Msg = new JAM (Data->Path);
  568.                else if (Data->Storage == ST_SQUISH)
  569.                   Msg = new SQUISH (Data->Path);
  570.                else if (Data->Storage == ST_FIDO)
  571.                   Msg = new FIDOSDM (Data->Path);
  572.                else if (Data->Storage == ST_ADEPT)
  573.                   Msg = new ADEPT (Data->Path);
  574.  
  575.                if (Msg != NULL) {
  576.                   Msg->Lock (0L);
  577.                   memset (Temp, '.', sizeof (Temp));
  578.                   memcpy (Temp, Data->EchoTag, strlen (Data->EchoTag));
  579.                   Temp[strlen (Data->EchoTag)] = ' ';
  580.                   cprintf ("Scanning %-40.40s ", Temp);
  581.  
  582.                   Forward->Load (Data->EchoTag);
  583.                   if (Forward->First () == TRUE) {
  584.                      if (Msg->GetHWM (Number) == FALSE)
  585.                         Number = Data->HighWaterMark;
  586.  
  587.                      cprintf ("#%06lu to #%06lu ", Number, Msg->Highest ());
  588.  
  589.                      SentArea = 0L;
  590.                      if (Msg->Next (Number) == TRUE) {
  591.                         do {
  592.                            cprintf ("<#%06lu>\b\b\b\b\b\b\b\b\b", Number);
  593.                            i = ExportEchoMail (Number, Data->EchoTag);
  594.                            SentArea += i;
  595.                            MsgSent += i;
  596.                         } while (Msg->Next (Number) == TRUE);
  597.  
  598.                         Msg->SetHWM (Number);
  599.                         Data->HighWaterMark = Number;
  600.                         Data->Update ();
  601.  
  602.                         if (Log != NULL && SentArea != 0L)
  603.                            Log->Write (":   %-30.30s (Sent=%04lu)", Data->EchoTag, SentArea);
  604.                      }
  605.                   }
  606.                   else {
  607.                      Number = Msg->Highest ();
  608.                      Msg->SetHWM (Number);
  609.                      Data->HighWaterMark = Number;
  610.                      Data->Update ();
  611.                   }
  612.  
  613.                   Msg->UnLock ();
  614.                   delete Msg;
  615.                   cprintf ("\r\n");
  616.                }
  617.  
  618.                Dupes->Save ();
  619.             }
  620.          } while (Data->Next () == TRUE);
  621.    }
  622.  
  623.    Msg = NULL;
  624.    Packet = NULL;
  625.  
  626.    if (Dupes != NULL)
  627.       delete Dupes;
  628.    if (Forward != NULL)
  629.       delete Forward;
  630.    if (Data != NULL)
  631.       delete Data;
  632.  
  633.    cprintf ("\r\n");
  634. }
  635.  
  636. VOID TMail::ExportNetMail (VOID)
  637. {
  638.    USHORT OurPoint, FoundIntl;
  639.    CHAR *Flag, *Text;
  640.    ULONG Number, Sent;
  641.    class TAddress Address, FromAddr, ToAddr;
  642.    class TAreaMgr *AreaMgr;
  643.  
  644.    strcpy (Outbound, Cfg->Outbound);
  645.    if (Outbound[strlen (Outbound) - 1] == '\\' || Outbound[strlen (Outbound) - 1] == '/')
  646.       Outbound[strlen (Outbound) - 1] = '\0';
  647.  
  648.    cprintf ("Searching path '%s'...\r\n", Cfg->NetMailPath);
  649.  
  650.    Msg = NULL;
  651.    if (Cfg->NetMailStorage == ST_JAM)
  652.       Msg = new JAM (Cfg->NetMailPath);
  653.    else if (Cfg->NetMailStorage == ST_SQUISH)
  654.       Msg = new SQUISH (Cfg->NetMailPath);
  655.    else if (Cfg->NetMailStorage == ST_FIDO)
  656.       Msg = new FIDOSDM (Cfg->NetMailPath);
  657.    else if (Cfg->NetMailStorage == ST_ADEPT)
  658.       Msg = new ADEPT (Cfg->NetMailPath);
  659.  
  660.    if ((AreaMgr = new TAreaMgr) != NULL) {
  661.       AreaMgr->Cfg = Cfg;
  662.       AreaMgr->Log = Log;
  663.    }
  664.  
  665.    if (Msg != NULL) {
  666.       Msg->Lock (0L);
  667.       Sent = 0L;
  668.       if (Log != NULL)
  669.          Log->Write ("#Packing from %s (%lu msgs)", Cfg->NetMailPath, Msg->Number ());
  670.       Number = Msg->Lowest ();
  671.       do {
  672.          if (Msg->Read (Number, MAX_LINE_LENGTH) == TRUE) {
  673.             Address.Clear ();
  674.             Address.Parse (Msg->ToAddress);
  675.  
  676.             FoundIntl = FALSE;
  677.             if ((Text = (PSZ)Msg->Text.First ()) != NULL)
  678.                do {
  679.                   if (!strncmp (Text, "\001INTL ", 6)) {
  680.                      FoundIntl = TRUE;
  681.                      break;
  682.                   }
  683.                } while ((Text = (PSZ)Msg->Text.Next ()) != NULL);
  684.  
  685.             // Controlla che non si tratti di un messaggio indirizzato ad uno dei
  686.             // nostri aka e nel contempo se e' indirizzato ad un nostro point
  687.             OurPoint = FALSE;
  688.             if (Msg->Sent == FALSE && Cfg->MailAddress.First () == TRUE)
  689.                do {
  690.                   if (Cfg->MailAddress.Zone == Address.Zone || Address.Zone == 0) {
  691.                      if (Cfg->MailAddress.Net == Address.Net && Cfg->MailAddress.Node == Address.Node) {
  692.                         // Ormai e' sicuro che si tratta di un nostro point
  693.                         OurPoint = TRUE;
  694.                         if (Cfg->MailAddress.Point == Address.Point)
  695.                            Msg->Sent = TRUE;
  696.                      }
  697.                   }
  698.                } while (Cfg->MailAddress.Next () == TRUE);
  699.  
  700.             if (Msg->Sent == FALSE) {
  701.                // Se non si tratta di un nostro point, il messaggio viene indirizzato
  702.                // sempre al boss, cioe' all'indirizzo con point = 0
  703.                if (OurPoint == FALSE) {
  704.                   Address.Point = 0;
  705.                   Address.Add ();
  706.                   Address.First ();
  707.                }
  708.                else {
  709.                   if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  710.                      if (Nodes->First () == TRUE)
  711.                         do {
  712.                            if (Nodes->Zone == Address.Zone && !stricmp (Msg->To, Nodes->SysopName) && Nodes->RemapMail == TRUE) {
  713.                               if (Log != NULL)
  714.                                  Log->Write ("#  Remap %s => %s", Address.String, Nodes->Address);
  715.                               sprintf (Temp, "\001PointMap %s => %s", Address.String, Nodes->Address);
  716.                               Msg->Text.Add (Temp);
  717.                               Address.Parse (Nodes->Address);
  718.                               OurPoint = FALSE;
  719.                               break;
  720.                            }
  721.                         } while (Nodes->Next () == TRUE);
  722.                      delete Nodes;
  723.                      Nodes = NULL;
  724.                   }
  725.                }
  726.  
  727.                Flag = "NORMAL";
  728.                if (Msg->Crash == TRUE)
  729.                   Flag = "CRASH";
  730.                else if (Msg->Direct == TRUE)
  731.                   Flag = "DIRECT";
  732.                else if (Msg->Hold == TRUE)
  733.                   Flag = "HOLD";
  734. //               sprintf (Temp, "Sending: #%06lu to %s (%s)", Number, Address.String, Flag);
  735. //               cprintf ("%-52.52s\r", Temp);
  736.                cprintf ("Sending: #%06lu to %s (%s)\r\n", Number, Msg->ToAddress, Flag);
  737.  
  738.                Cfg->MailAddress.First ();
  739.                if (Address.Zone == 0 || Cfg->MailAddress.Zone == Address.Zone) {
  740.                   if (Address.Point != 0) {
  741. #if defined(__LINUX__)
  742.                      sprintf (Temp, "%s/%04x%04x.pnt", Outbound, Address.Net, Address.Node);
  743.                      mkdir (Temp, 0666);
  744.                      sprintf (Temp, "%s/%04x%04x.pnt/%08x.xpr", Outbound, Address.Net, Address.Node, Address.Point);
  745. #else
  746.                      sprintf (Temp, "%s\\%04x%04x.pnt", Outbound, Address.Net, Address.Node);
  747.                      mkdir (Temp);
  748.                      sprintf (Temp, "%s\\%04x%04x.pnt\\%08x.xpr", Outbound, Address.Net, Address.Node, Address.Point);
  749. #endif
  750.                   }
  751.                   else
  752. #if defined(__LINUX__)
  753.                      sprintf (Temp, "%s/%04x%04x.xpr", Outbound, Address.Net, Address.Node);
  754. #else
  755.                      sprintf (Temp, "%s\\%04x%04x.xpr", Outbound, Address.Net, Address.Node);
  756. #endif
  757.                }
  758.                else {
  759.                   sprintf (Temp, "%s.%03x", Outbound, Address.Zone);
  760. #if defined(__LINUX__)
  761.                   mkdir (Temp, 0666);
  762. #else
  763.                   mkdir (Temp);
  764. #endif
  765.                   if (Address.Point != 0) {
  766. #if defined(__LINUX__)
  767.                      sprintf (Temp, "%s.%03x/%04x%04x.pnt", Outbound, Address.Zone, Address.Net, Address.Node);
  768.                      mkdir (Temp, 0666);
  769.                      sprintf (Temp, "%s.%03x/%04x%04x.pnt/%08x.xpr", Outbound, Address.Zone, Address.Net, Address.Node, Address.Point);
  770. #else
  771.                      sprintf (Temp, "%s.%03x\\%04x%04x.pnt", Outbound, Address.Zone, Address.Net, Address.Node);
  772.                      mkdir (Temp);
  773.                      sprintf (Temp, "%s.%03x\\%04x%04x.pnt\\%08x.xpr", Outbound, Address.Zone, Address.Net, Address.Node, Address.Point);
  774. #endif
  775.                   }
  776.                   else
  777. #if defined(__LINUX__)
  778.                      sprintf (Temp, "%s.%03x/%04x%04x.xpr", Outbound, Address.Zone, Address.Net, Address.Node);
  779. #else
  780.                      sprintf (Temp, "%s.%03x\\%04x%04x.xpr", Outbound, Address.Zone, Address.Net, Address.Node);
  781. #endif
  782.                }
  783.  
  784.                if (Msg->Crash == TRUE)
  785.                   strcpy (&Temp[strlen (Temp) - 3], "cut");
  786.                else if (Msg->Direct == TRUE)
  787.                   strcpy (&Temp[strlen (Temp) - 3], "dut");
  788.                else if (Msg->Hold == TRUE)
  789.                   strcpy (&Temp[strlen (Temp) - 3], "hut");
  790.  
  791.                if ((Packet = new PACKET) != NULL) {
  792.                   if (OurPoint == TRUE)
  793.                      strcpy (Packet->ToAddress, Msg->ToAddress);
  794.                   else
  795.                      strcpy (Packet->ToAddress, Address.String);
  796.                   ToAddr.Parse (Packet->ToAddress);
  797.  
  798.                   if (Cfg->MailAddress.First () == TRUE) {
  799.                      strcpy (Packet->FromAddress, Cfg->MailAddress.String);
  800.                      do {
  801.                         if (Cfg->MailAddress.Zone == ToAddr.Zone) {
  802.                            strcpy (Packet->FromAddress, Cfg->MailAddress.String);
  803.                            break;
  804.                         }
  805.                      } while (Cfg->MailAddress.Next () == TRUE);
  806.                   }
  807.                   else
  808.                      strcpy (Packet->FromAddress, Msg->FromAddress);
  809.                   FromAddr.Parse (Packet->FromAddress);
  810.  
  811.                   if ((Cfg->ForceIntl == TRUE || FromAddr.Zone != ToAddr.Zone) && FoundIntl == FALSE) {
  812.                      sprintf (Temp, "\001INTL %u:%u/%u %u:%u/%u", ToAddr.Zone, ToAddr.Net, ToAddr.Node, FromAddr.Zone, FromAddr.Net, FromAddr.Node);
  813.                      if ((Text = (PSZ)Msg->Text.First ()) != NULL) {
  814.                         Msg->Text.Insert (Temp, (USHORT)(strlen (Temp) + 1));
  815.                         Msg->Text.Insert (Text, (USHORT)(strlen (Text) + 1));
  816.                         Msg->Text.First ();
  817.                         Msg->Text.Remove ();
  818.                      }
  819.                      else
  820.                         Msg->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  821.                   }
  822.  
  823.                   // Se il file non esiste, allora cerca la password di pacchetto
  824.                   // definita per il nodo di destinazione
  825.                   if (stat (Temp, &statbuf) != 0) {
  826.                      if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  827.                         if (Nodes->Read (Msg->ToAddress) == TRUE)
  828.                            strcpy (Packet->Password, Nodes->OutPktPwd);
  829.                         delete Nodes;
  830.                         Nodes = NULL;
  831.                      }
  832.                   }
  833.  
  834.                   // Apre il pacchetto .xpr senza effettuare lo scan dei messaggi
  835.                   if (Packet->Open (Temp, FALSE) == TRUE) {
  836.                      Packet->Add (Msg);
  837.                      Sent++;
  838.                   }
  839.  
  840.                   if (Cfg->KeepNetMail == FALSE)
  841.                      Msg->Delete (Number);
  842.  
  843.                   delete Packet;
  844.                   Packet = NULL;
  845.                }
  846.  
  847.                Msg->Sent = TRUE;
  848.                Msg->WriteHeader (Number);
  849.             }
  850.             else if (Msg->Received == FALSE) {
  851.                if (!stricmp (Msg->To, "Areafix") || !stricmp (Msg->To, "AreaMgr")) {
  852.                   if (AreaMgr != NULL) {
  853.                      Msg->Received = TRUE;
  854.                      Msg->WriteHeader (Number);
  855.  
  856.                      AreaMgr->Msg = Msg;
  857.                      cprintf ("Processing: #%06lu from %s\r\n", Number, Msg->FromAddress);
  858.                      AreaMgr->Process ();
  859.                   }
  860.                }
  861.             }
  862.          }
  863.       } while (Msg->Next (Number) == TRUE);
  864.  
  865.       if (Log != NULL)
  866.          Log->Write (":  Packed=%lu", Sent);
  867.  
  868.       Msg->UnLock ();
  869.       delete Msg;
  870.       Msg = NULL;
  871.    }
  872.  
  873.    if (AreaMgr != NULL)
  874.       delete AreaMgr;
  875.  
  876.    cprintf ("\r\n");
  877. }
  878.  
  879. USHORT TMail::OpenArea (PSZ pszEchoTag)
  880. {
  881.    FILE *fp;
  882.    USHORT Found = FALSE, Create;
  883.    CHAR Temp[64], *p, *path, *tag, *links;
  884.  
  885.    if (Msg != NULL) {
  886.       if (Data != NULL && IsAreasBBS == FALSE) {
  887.          Data->ActiveMsgs = Msg->Number ();
  888.          Data->Update ();
  889.       }
  890.       if (Dupes != NULL)
  891.          Dupes->Save ();
  892.       Msg->UnLock ();
  893.       delete Msg;
  894.    }
  895.  
  896.    Msg = NULL;
  897.    strcpy (LastTag, strupr (pszEchoTag));
  898.    IsAreasBBS = FALSE;
  899.  
  900.    if (Data != NULL) {
  901.       Found = Data->ReadEcho (pszEchoTag);
  902.       if (Found == TRUE) {
  903.          if (Forward != NULL)
  904.             Forward->Load (pszEchoTag);
  905.  
  906.          if (Data->Storage == ST_JAM)
  907.             Msg = new JAM (Data->Path);
  908.          else if (Data->Storage == ST_SQUISH)
  909.             Msg = new SQUISH (Data->Path);
  910.          else if (Data->Storage == ST_FIDO)
  911.             Msg = new FIDOSDM (Data->Path);
  912.          else if (Data->Storage == ST_ADEPT)
  913.             Msg = new ADEPT (Data->Path);
  914.       }
  915.    }
  916.  
  917.    if (Found == FALSE && Cfg->UseAreasBBS == TRUE && Cfg->AreasBBS[0] != '\0') {
  918.       if ((fp = fopen (Cfg->AreasBBS, "rt")) != NULL) {
  919.          fgets (Temp, sizeof (Temp) - 1, fp);
  920.          while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  921.             if (Temp[0] == ';')
  922.                continue;
  923.             Temp[strlen (Temp) - 1] = '\0';
  924.             if ((path = strtok (Temp, " ")) != NULL) {
  925.                tag = strtok (NULL, " ");
  926.                if ((links = strtok (NULL, "")) != NULL) {
  927.                   while (*links == ' ')
  928.                      links++;
  929.                }
  930.                if (!stricmp (pszEchoTag, tag)) {
  931.                   Found = TRUE;
  932.                   IsAreasBBS = TRUE;
  933.                   if (*path == '$')
  934.                      Msg = new SQUISH (++path);
  935.                   else if (*path == '&')
  936.                      Msg = new JAM (++path);
  937.                   else if (*path == '=')
  938.                      Msg = new ADEPT (++path);
  939.                   else
  940.                      Msg = new FIDOSDM (path);
  941.                   if (Forward != NULL) {
  942.                      Forward->Clear ();
  943.                      Forward->AddString (links);
  944.                   }
  945.                }
  946.             }
  947.          }
  948.          fclose (fp);
  949.       }
  950.    }
  951.  
  952.    if (Found == FALSE && Data != NULL) {
  953.       Create = FALSE;
  954.  
  955.       if (Nodes != NULL) {
  956.          if (Nodes->Read (Packet->FromAddress, FALSE) == TRUE) {
  957.             if (Nodes->CreateNewAreas == TRUE) {
  958.                Create = TRUE;
  959.                if ((p = strtok (Nodes->NewAreasFilter, " ")) != NULL) {
  960.                   Create = FALSE;
  961.                   do {
  962.                      if (strstr (pszEchoTag, strupr (p)) != NULL) {
  963.                         Create = TRUE;
  964.                         break;
  965.                      }
  966.                   } while ((p = strtok (NULL, " ")) != NULL);
  967.                }
  968.             }
  969.          }
  970.       }
  971.  
  972.       if (Create == TRUE) {
  973.          strcpy (Temp, pszEchoTag);
  974.          Temp[sizeof (Data->Key) - 1] = '\0';
  975.          while (Data->Read (Temp) == TRUE) {
  976.             if (isdigit (Temp[strlen (Temp) - 1]))
  977.                Temp[strlen (Temp) - 1]++;
  978.             else
  979.                Temp[strlen (Temp) - 1] = '0';
  980.          }
  981.  
  982.          Data->New ();
  983.          strcpy (Data->Key, Temp);
  984.          sprintf (Data->Display, "New area %s", pszEchoTag);
  985.          Data->Storage = Cfg->NewAreasStorage;
  986.          strcpy (Temp, pszEchoTag);
  987.          Temp[8] = '\0';
  988.          while ((p = strchr (Temp, '.')) != NULL)
  989.             *p = '_';
  990.          if (Temp[strlen (Temp) - 1] == '_')
  991.             Temp[strlen (Temp) - 1] = '\0';
  992.          sprintf (Data->Path, "%s%s", Cfg->NewAreasPath, Temp);
  993.          strlwr (Data->Path);
  994.          Data->Level = Cfg->NewAreasLevel;
  995.          Data->AccessFlags = Cfg->NewAreasFlags;
  996.          Data->DenyFlags = Cfg->NewAreasDenyFlags;
  997.          Data->WriteLevel = Cfg->NewAreasWriteLevel;
  998.          Data->WriteFlags = Cfg->NewAreasWriteFlags;
  999.          Data->DenyWriteFlags = Cfg->NewAreasDenyWriteFlags;
  1000.          strcpy (Data->EchoTag, pszEchoTag);
  1001.          Data->EchoMail = TRUE;
  1002.          Data->DaysOld = 14;
  1003.          Data->MaxMessages = 200;
  1004.          Data->Add ();
  1005.  
  1006.          Found = TRUE;
  1007.  
  1008.          if (Forward != NULL) {
  1009.             Forward->Load (pszEchoTag);
  1010.             Forward->AddString (Packet->FromAddress);
  1011.             Forward->Save ();
  1012.          }
  1013.  
  1014.          if (Data->Storage == ST_JAM)
  1015.             Msg = new JAM (Data->Path);
  1016.          else if (Data->Storage == ST_SQUISH)
  1017.             Msg = new SQUISH (Data->Path);
  1018.          else if (Data->Storage == ST_FIDO)
  1019.             Msg = new FIDOSDM (Data->Path);
  1020.          else if (Data->Storage == ST_ADEPT)
  1021.             Msg = new ADEPT (Data->Path);
  1022.       }
  1023.    }
  1024.  
  1025.    if (Found == FALSE) {
  1026.       if (Forward != NULL)
  1027.          Forward->Load ("");
  1028.  
  1029.       if (Cfg->BadStorage == ST_JAM)
  1030.          Msg = new JAM (Cfg->BadPath);
  1031.       else if (Cfg->BadStorage == ST_SQUISH)
  1032.          Msg = new SQUISH (Cfg->BadPath);
  1033.       else if (Cfg->BadStorage == ST_FIDO)
  1034.          Msg = new FIDOSDM (Cfg->BadPath);
  1035.       else if (Cfg->BadStorage == ST_ADEPT)
  1036.          Msg = new ADEPT (Cfg->BadPath);
  1037.    }
  1038.  
  1039.    if (Msg != NULL)
  1040.       Msg->Lock (0L);
  1041.    if (Dupes != NULL)
  1042.       Dupes->Load (pszEchoTag);
  1043.  
  1044.    return (Found);
  1045. }
  1046.  
  1047. ULONG TMail::ImportEchoMail (VOID)
  1048. {
  1049.    USHORT BadMessage = FALSE;
  1050.    CHAR *Text;
  1051.    ULONG RetVal = 0L;
  1052.    class TMsgBase *Extra;
  1053.  
  1054.    if (Forward != NULL) {
  1055.       if (Forward->Check (Packet->FromAddress) == FALSE && Cfg->Secure == TRUE) {
  1056.          BadMessage = TRUE;
  1057.          Extra = Msg;
  1058.  
  1059.          if (Cfg->BadStorage == ST_JAM)
  1060.             Msg = new JAM (Cfg->BadPath);
  1061.          else if (Cfg->BadStorage == ST_SQUISH)
  1062.             Msg = new SQUISH (Cfg->BadPath);
  1063.          else if (Cfg->BadStorage == ST_FIDO)
  1064.             Msg = new FIDOSDM (Cfg->BadPath);
  1065.          else if (Cfg->BadStorage == ST_ADEPT)
  1066.             Msg = new ADEPT (Cfg->BadPath);
  1067.       }
  1068.    }
  1069.  
  1070.    if (Dupes != NULL) {
  1071.       if (Dupes->Check (Data->EchoTag, Packet) == TRUE) {
  1072.          BadMessage = TRUE;
  1073.          Extra = Msg;
  1074.  
  1075.          if (Cfg->DupeStorage == ST_JAM)
  1076.             Msg = new JAM (Cfg->DupePath);
  1077.          else if (Cfg->DupeStorage == ST_SQUISH)
  1078.             Msg = new SQUISH (Cfg->DupePath);
  1079.          else if (Cfg->DupeStorage == ST_FIDO)
  1080.             Msg = new FIDOSDM (Cfg->DupePath);
  1081.          else if (Cfg->DupeStorage == ST_ADEPT)
  1082.             Msg = new ADEPT (Cfg->DupePath);
  1083.       }
  1084.       else
  1085.          Dupes->Add (Data->EchoTag, Packet);
  1086.    }
  1087.  
  1088.    if (Msg != NULL) {
  1089.       if (BadMessage == FALSE) {
  1090.          Packet->Text.First ();
  1091.          Packet->Text.Remove ();
  1092.       }
  1093.  
  1094.       Msg->New ();
  1095.  
  1096.       SeenBy = new TKludges;
  1097.       Path = new TKludges;
  1098.  
  1099.       if (SeenBy != NULL && Path != NULL) {
  1100.          Path->Sort = FALSE;
  1101.          if ((Text = (PSZ)Packet->Text.First ()) != NULL)
  1102.             do {
  1103.                if (!strncmp (Text, "SEEN-BY: ", 9) && SeenBy != NULL) {
  1104.                   SeenBy->AddString (&Text[9]);
  1105.                   Packet->Text.Remove ();
  1106.                   Text = (PSZ)Packet->Text.Value ();
  1107.                }
  1108.                else if (!strncmp (Text, "\001PATH: ", 7) && Path != NULL) {
  1109.                   Path->AddString (&Text[7]);
  1110.                   Packet->Text.Remove ();
  1111.                   Text = (PSZ)Packet->Text.Value ();
  1112.                }
  1113.                else
  1114.                   Text = (PSZ)Packet->Text.Next ();
  1115.             } while (Text != NULL);
  1116.  
  1117.          SeenBy->AddString (Packet->FromAddress);
  1118.          Path->AddString (Packet->FromAddress);
  1119.  
  1120.          if (Data->Address[0] != '\0') {
  1121.             SeenBy->AddString (Data->Address);
  1122.             Path->AddString (Data->Address);
  1123.          }
  1124.          else if (Cfg->MailAddress.First () == TRUE) {
  1125.             SeenBy->AddString (Cfg->MailAddress.String);
  1126.             Path->AddString (Cfg->MailAddress.String);
  1127.          }
  1128.  
  1129.          if (SeenBy->First () == TRUE) {
  1130.             strcpy (Temp, "SEEN-BY:");
  1131.             do {
  1132.                if (strlen (Temp) + strlen (SeenBy->ShortAddress) + 1 > 70) {
  1133.                   Packet->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1134.                   strcpy (Temp, "SEEN-BY:");
  1135.                   strcpy (SeenBy->ShortAddress, SeenBy->Address);
  1136.                }
  1137.                strcat (Temp, " ");
  1138.                strcat (Temp, SeenBy->ShortAddress);
  1139.             } while (SeenBy->Next () == TRUE);
  1140.             if (strlen (Temp) > 9)
  1141.                Packet->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1142.          }
  1143.  
  1144.          if (Path->First () == TRUE) {
  1145.             strcpy (Temp, "\001PATH:");
  1146.             do {
  1147.                if (strlen (Temp) + strlen (Path->ShortAddress) + 1 > 70) {
  1148.                   Packet->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1149.                   strcpy (Temp, "\001PATH:");
  1150.                   strcpy (Path->ShortAddress, Path->Address);
  1151.                }
  1152.                strcat (Temp, " ");
  1153.                strcat (Temp, Path->ShortAddress);
  1154.             } while (Path->Next () == TRUE);
  1155.             if (strlen (Temp) > 7)
  1156.                Packet->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1157.          }
  1158.       }
  1159.  
  1160.       if (Path != NULL)
  1161.          delete Path;
  1162.       if (SeenBy != NULL)
  1163.          delete SeenBy;
  1164.  
  1165.       Msg->Add (Packet);
  1166.       RetVal = Msg->Highest ();
  1167.    }
  1168.  
  1169.    if (BadMessage == TRUE) {
  1170.       if (Msg != NULL)
  1171.          delete Msg;
  1172.       Msg = Extra;
  1173.    }
  1174.  
  1175.    return (RetVal);
  1176. }
  1177.  
  1178. VOID TMail::Import (VOID)
  1179. {
  1180.    USHORT Found, SkipPacket, Empty;
  1181.    CHAR *Line;
  1182.    ULONG Number, TossedArea;
  1183.    class TUser *User;
  1184.    class TMsgBase *Extra;
  1185.  
  1186.    if (Inbound[0] != '\0') {
  1187.       if (Inbound[strlen (Inbound) - 1] == '\\' || Inbound[strlen (Inbound) - 1] == '/')
  1188.          Inbound[strlen (Inbound) - 1] = '\0';
  1189. #if defined(__LINUX__)
  1190.       strcat (Inbound, "/");
  1191. #else
  1192.       strcat (Inbound, "\\");
  1193. #endif
  1194.    }
  1195.  
  1196.    if (Log != NULL)
  1197.       Log->Write ("+Import From %s", Inbound);
  1198.  
  1199.    Nodes = new TNodes (Cfg->NodelistPath);
  1200.    Data = new TMsgData (Cfg->SystemPath);
  1201.    Forward = new TEchoLink (Cfg->SystemPath);
  1202.    Dupes = new TDupes (Cfg->SystemPath);
  1203.  
  1204.    TossedArea = 0L;
  1205.  
  1206.    while (OpenNextPacket () == TRUE) {
  1207.       LastTag[0] = '\0';
  1208.       Packets++;
  1209.  
  1210.       cprintf ("Tossing mail bundle %s from %s (%lu msgs.)\r\n", strupr (PktName), Packet->FromAddress, Packet->Number ());
  1211.  
  1212.       if (Log != NULL) {
  1213.          Log->Write ("+%s, %02d/%02d/%d, %02d:%02d (%lu Msgs.)", strupr (PktName), Packet->Date.Month, Packet->Date.Day, Packet->Date.Year, Packet->Date.Hour, Packet->Date.Minute, Packet->Number ());
  1214.          Log->Write (":Orig: %s, Dest: %s", Packet->FromAddress, Packet->ToAddress);
  1215.       }
  1216.  
  1217.       SkipPacket = FALSE;
  1218.       if (Nodes != NULL && Cfg->Secure == TRUE) {
  1219.          if (Nodes->Read (Packet->FromAddress) == TRUE) {
  1220.             if (Nodes->InPktPwd[0] != '\0' && strcmp (Nodes->InPktPwd, Packet->Password)) {
  1221.                SkipPacket = TRUE;
  1222.                if (Log != NULL)
  1223.                   Log->Write ("!Invalid Packet Password, His: %s, Ours: %s", Packet->Password, Nodes->InPktPwd);
  1224.             }
  1225.          }
  1226.       }
  1227.  
  1228.       Number = Packet->Lowest ();
  1229.       Found = FALSE;
  1230.  
  1231.       do {
  1232.          if (SkipPacket == TRUE)
  1233.             break;
  1234.          cprintf ("%s #%06lu: ", PktName, Number);
  1235.          if (Packet->Read (Number, MAX_LINE_LENGTH) == TRUE) {
  1236.             // Vengono resettati i flags che non devono essere mantenuti durante il
  1237.             // passaggio da un nodo all'altro
  1238.             Packet->Sent = Packet->Received = FALSE;
  1239.             Packet->Crash = Packet->Direct = Packet->Hold = FALSE;
  1240.  
  1241.             if ((Line = (PSZ)Packet->Text.First ()) != NULL) {
  1242.                if (!strncmp (Line, "AREA:", 5)) {
  1243.                   cprintf ("%s ", strupr (&Line[5]));
  1244.                   if (stricmp (&Line[5], LastTag)) {
  1245.                      if (Log != NULL && TossedArea != 0L)
  1246.                         Log->Write (":   %-30.30s (Toss=%04d)", LastTag, TossedArea);
  1247.                      TossedArea = 0L;
  1248.                      strcpy (LastTag, strupr (&Line[5]));
  1249.                      Found = OpenArea (LastTag);
  1250.                   }
  1251.                   if (Found == TRUE) {
  1252.                      if (Forward->Check (Packet->FromAddress) == TRUE) {
  1253.                         if (Dupes->Check (Data->EchoTag, Packet) == FALSE)
  1254.                            cprintf ("=> #%06lu", ImportEchoMail ());
  1255.                         else {
  1256.                            cprintf ("=> Duplicate #%06lu", ImportEchoMail ());
  1257.                            Duplicate++;
  1258.                         }
  1259.                      }
  1260.                      else {
  1261.                         cprintf ("=> Bad_Msgs #%06lu", ImportEchoMail ());
  1262.                         Bad++;
  1263.                      }
  1264.                   }
  1265.                   else {
  1266.                      cprintf ("=> Bad_Msgs #%06lu", ImportEchoMail ());
  1267.                      Bad++;
  1268.                   }
  1269.                   TossedArea++;
  1270.                }
  1271.                else {
  1272.                   if (Msg != NULL) {
  1273.                      if (TossedArea != 0L) {
  1274.                         if (Data != NULL && IsAreasBBS == FALSE) {
  1275.                            Data->ActiveMsgs = Msg->Number ();
  1276.                            Data->Update ();
  1277.                         }
  1278.                         if (Dupes != NULL)
  1279.                            Dupes->Save ();
  1280.                         if (Log != NULL)
  1281.                            Log->Write (":   %-30.30s (Toss=%04d)", LastTag, TossedArea);
  1282.                      }
  1283.                      TossedArea = 0L;
  1284.                      Msg->UnLock ();
  1285.                      delete Msg;
  1286.                   }
  1287.                   strcpy (LastTag, "NetMail");
  1288.  
  1289.                   cprintf ("NetMail from %s ", Packet->FromAddress);
  1290.  
  1291.                   Empty = TRUE;
  1292.                   if ((Line = (PSZ)Packet->Text.First ()) != NULL)
  1293.                      do {
  1294.                         if (*Line != '\001' && *Line != '\0') {
  1295.                            Empty = FALSE;
  1296.                            break;
  1297.                         }
  1298.                      } while ((Line = (PSZ)Packet->Text.Next ()) != NULL);
  1299.  
  1300.                   if (Log != NULL) {
  1301.                      if (Empty == TRUE)
  1302.                         Log->Write ("*Netmail: %s -> %s (Empty)", Packet->From, Packet->To);
  1303.                      else
  1304.                         Log->Write ("*Netmail: %s -> %s", Packet->From, Packet->To);
  1305.                      Log->Write ("*         %s -> %s", Packet->FromAddress, Packet->ToAddress);
  1306.                   }
  1307.  
  1308.                   if (Empty == FALSE || Cfg->ImportEmpty == TRUE) {
  1309.                      Msg = NULL;
  1310.                      if (Cfg->NetMailStorage == ST_JAM)
  1311.                         Msg = new JAM (Cfg->NetMailPath);
  1312.                      else if (Cfg->NetMailStorage == ST_SQUISH)
  1313.                         Msg = new SQUISH (Cfg->NetMailPath);
  1314.                      else if (Cfg->NetMailStorage == ST_FIDO)
  1315.                         Msg = new FIDOSDM (Cfg->NetMailPath);
  1316.                      else if (Cfg->NetMailStorage == ST_ADEPT)
  1317.                         Msg = new ADEPT (Cfg->NetMailPath);
  1318.  
  1319.                      if (Msg != NULL) {
  1320.                         Msg->New ();
  1321.                         Msg->Add (Packet);
  1322.                         cprintf ("=> #%06lu", Msg->Highest ());
  1323.                         delete Msg;
  1324.                         Msg = NULL;
  1325.                      }
  1326.                      NetMail++;
  1327.  
  1328.                      if ((User = new TUser (Cfg->UserFile)) != NULL) {
  1329.                         if (User->GetData (Packet->To) == TRUE) {
  1330.                            Extra = NULL;
  1331.                            if (Cfg->MailStorage == ST_JAM)
  1332.                               Extra = new JAM (Cfg->MailPath);
  1333.                            else if (Cfg->MailStorage == ST_SQUISH)
  1334.                               Extra = new SQUISH (Cfg->MailPath);
  1335.                            else if (Cfg->MailStorage == ST_FIDO)
  1336.                               Extra = new FIDOSDM (Cfg->MailPath);
  1337.                            else if (Cfg->MailStorage == ST_ADEPT)
  1338.                               Extra = new ADEPT (Cfg->MailPath);
  1339.                            if (Extra != NULL) {
  1340.                               Extra->Add (Packet);
  1341.                               delete Extra;
  1342.                            }
  1343.                         }
  1344.                         delete User;
  1345.                      }
  1346.                   }
  1347.                   else
  1348.                      cprintf ("Empty message, skipped");
  1349.                }
  1350.             }
  1351.  
  1352.             MsgTossed++;
  1353.          }
  1354.          cprintf ("\r\n");
  1355.       } while (Packet->Next (Number) == TRUE);
  1356.  
  1357.       if (Msg != NULL) {
  1358.          if (TossedArea != 0L) {
  1359.             if (Data != NULL && IsAreasBBS == FALSE) {
  1360.                Data->ActiveMsgs = Msg->Number ();
  1361.                Data->Update ();
  1362.             }
  1363.             if (Dupes != NULL)
  1364.                Dupes->Save ();
  1365.             if (Log != NULL)
  1366.                Log->Write (":   %-30.30s (Toss=%04d)", LastTag, TossedArea);
  1367.          }
  1368.          TossedArea = 0L;
  1369.          Msg->UnLock ();
  1370.          delete Msg;
  1371.       }
  1372.       Msg = NULL;
  1373.  
  1374.       cprintf ("Toss of bundle %s successful, deleting\r\n\r\n", PktName);
  1375.       if (Packet != NULL) {
  1376.          Packet->Kill ();
  1377.          delete Packet;
  1378.          Packet = NULL;
  1379.       }
  1380.    }
  1381.  
  1382.    if (Dupes != NULL)
  1383.       delete Dupes;
  1384.    if (Nodes != NULL)
  1385.       delete Nodes;
  1386.    if (Forward != NULL)
  1387.       delete Forward;
  1388.    if (Data != NULL)
  1389.       delete Data;
  1390. }
  1391.  
  1392. USHORT TMail::IsArcmail (VOID)
  1393. {
  1394.    DIR *dir;
  1395.    USHORT RetVal = FALSE, i;
  1396.    CHAR Filename[128];
  1397.    struct dirent *ent;
  1398.  
  1399.    strcpy (Filename, Inbound);
  1400.    if (Filename[strlen (Filename) - 1] == '\\' || Filename[strlen (Filename) - 1] == '/')
  1401.       Filename[strlen (Filename) - 1] = '\0';
  1402.  
  1403.    if ((dir = opendir (Filename)) != NULL) {
  1404.       while ((ent = readdir (dir)) != NULL && RetVal == FALSE) {
  1405. #if !defined(__LINUX__)
  1406.          strlwr (ent->d_name);
  1407. #endif
  1408.          i = 0;
  1409.          while (CheckExts[i] != NULL && RetVal == FALSE) {
  1410.             if (strstr (ent->d_name, CheckExts[i]) != NULL)
  1411.                RetVal = TRUE;
  1412.             i++;
  1413.          }
  1414.       }
  1415.       closedir (dir);
  1416.    }
  1417.  
  1418.    return (RetVal);
  1419. }
  1420.  
  1421. USHORT TMail::IsMail (VOID)
  1422. {
  1423.    DIR *dir;
  1424.    USHORT RetVal = FALSE;
  1425.    CHAR Filename[128];
  1426.    struct dirent *ent;
  1427.  
  1428.    strcpy (Filename, Inbound);
  1429.    if (Filename[strlen (Filename) - 1] == '\\' || Filename[strlen (Filename) - 1] == '/')
  1430.       Filename[strlen (Filename) - 1] = '\0';
  1431.  
  1432.    if ((dir = opendir (Filename)) != NULL) {
  1433.       while ((ent = readdir (dir)) != NULL && RetVal == FALSE) {
  1434. #if !defined(__LINUX__)
  1435.          strlwr (ent->d_name);
  1436. #endif
  1437.          if (strstr (ent->d_name, ".pk") != NULL)
  1438.             RetVal = TRUE;
  1439.       }
  1440.       closedir (dir);
  1441.    }
  1442.  
  1443.    return (RetVal);
  1444. }
  1445.  
  1446. USHORT TMail::UnpackArcmail (VOID)
  1447. {
  1448.    DIR *dir;
  1449.    USHORT RetVal = FALSE, i, counter;
  1450.    CHAR Filename[128], BadArc[128];
  1451.    struct dirent *ent;
  1452.    class TPacker *Packer;
  1453.  
  1454.    strcpy (Filename, Inbound);
  1455.    if (Filename[strlen (Filename) - 1] == '\\' || Filename[strlen (Filename) - 1] == '/')
  1456.       Filename[strlen (Filename) - 1] = '\0';
  1457.  
  1458.    if ((dir = opendir (Filename)) != NULL) {
  1459.       while ((ent = readdir (dir)) != NULL && RetVal == FALSE) {
  1460.          i = 0;
  1461.          while (CheckExts[i] != NULL && RetVal == FALSE) {
  1462. #if !defined(__LINUX__)
  1463.             strlwr (ent->d_name);
  1464. #endif
  1465.             if (strstr (ent->d_name, CheckExts[i]) != NULL && isdigit (ent->d_name[strlen (ent->d_name) - 1])) {
  1466.                sprintf (Filename, "%s%s", Inbound, ent->d_name);
  1467.                if (Log != NULL)
  1468.                   Log->Write ("+Unpacking %s", Filename);
  1469.                if ((Packer = new TPacker (Cfg->SystemPath)) != NULL) {
  1470.                   if (Packer->CheckArc (Filename) == TRUE) {
  1471.                      cprintf ("Unpacking %s", Filename);
  1472.                      if (Packer->DoUnpack (Filename, Inbound, "*.pk?") == FALSE) {
  1473.                         if (Log != NULL)
  1474.                            Log->Write ("!  Command returned error: %s", Packer->Error);
  1475.                      }
  1476.                      unlink (Filename);
  1477.                      cprintf ("\r\n");
  1478.                      RetVal = TRUE;
  1479.                   }
  1480.                   else {
  1481.                      counter = 1;
  1482.                      do {
  1483.                         sprintf (BadArc, "%sbad_arc.%03d", Inbound, counter++);
  1484.                      } while (rename (Filename, BadArc) == -1);
  1485.                   }
  1486.                   delete Packer;
  1487.                }
  1488.             }
  1489.             i++;
  1490.          }
  1491.       }
  1492.       closedir (dir);
  1493.    }
  1494.  
  1495.    return (RetVal);
  1496. }
  1497.  
  1498. // ----------------------------------------------------------------------
  1499. class TConfig *Cfg = NULL;
  1500. class TLog *Log = NULL;
  1501.  
  1502. VOID ImportFromBadMsgs (VOID)
  1503. {
  1504.    CHAR *p, Found;
  1505.    ULONG Number;
  1506.    class TMsgBase *Msg, *Bad;
  1507.    class TMsgData *Data;
  1508.  
  1509.    if (Cfg != NULL) {
  1510.       Bad = NULL;
  1511.       if (Cfg->BadStorage == ST_JAM)
  1512.          Bad = new JAM (Cfg->BadPath);
  1513.       else if (Cfg->BadStorage == ST_SQUISH)
  1514.          Bad = new SQUISH (Cfg->BadPath);
  1515.       else if (Cfg->BadStorage == ST_FIDO)
  1516.          Bad = new FIDOSDM (Cfg->BadPath);
  1517.       else if (Cfg->BadStorage == ST_ADEPT)
  1518.          Bad = new ADEPT (Cfg->BadPath);
  1519.  
  1520.       cprintf ("Sarching path '%s'...\r\n", Cfg->BadPath);
  1521.  
  1522.       if (Bad != NULL) {
  1523.          Bad->Lock (0L);
  1524.          Number = Bad->Lowest ();
  1525.          do {
  1526.             if (Bad->Read (Number) == TRUE) {
  1527.                if ((p = (CHAR *)Bad->Text.First ()) != NULL)
  1528.                   do {
  1529.                      if (*p != 0x01)
  1530.                         break;
  1531.                      else
  1532.                         Bad->Text.Remove ();
  1533.                   } while ((p = (CHAR *)Bad->Text.First ()) != NULL);
  1534.  
  1535.                if (p != NULL) {
  1536.                   if (!strncmp (p, "AREA:", 5)) {
  1537.                      Found = FALSE;
  1538.                      cprintf ("Tossing %s #%06lu: %s ", Cfg->BadPath, Number, &p[5]);
  1539.  
  1540.                      if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  1541.                         if (Data->First () == TRUE)
  1542.                            do {
  1543.                               if (!stricmp (&p[5], Data->EchoTag)) {
  1544.                                  Msg = NULL;
  1545.                                  if (Data->Storage == ST_JAM)
  1546.                                     Msg = new JAM (Data->Path);
  1547.                                  else if (Data->Storage == ST_SQUISH)
  1548.                                     Msg = new SQUISH (Data->Path);
  1549.                                  else if (Data->Storage == ST_FIDO)
  1550.                                     Msg = new FIDOSDM (Data->Path);
  1551.                                  else if (Data->Storage == ST_ADEPT)
  1552.                                     Msg = new ADEPT (Data->Path);
  1553.                                  if (Msg != NULL) {
  1554.                                     Bad->Text.Remove ();
  1555.                                     Msg->Add (Bad);
  1556.                                     cprintf ("=> #%06lu\r\n", Msg->Highest ());
  1557.                                     Bad->Delete (Number);
  1558.                                     delete Msg;
  1559.                                  }
  1560.                                  Found = TRUE;
  1561.                                  break;
  1562.                               }
  1563.                            } while (Data->Next () == TRUE);
  1564.                         delete Data;
  1565.                      }
  1566.  
  1567.                      if (Found == FALSE)
  1568.                         cprintf ("(Unknown area)\r\n");
  1569.                   }
  1570.                }
  1571.             }
  1572.          } while (Bad->Next (Number) == TRUE);
  1573.  
  1574.          Bad->UnLock ();
  1575.  
  1576.          cprintf ("Packing '%s'...\r\n", Cfg->BadPath);
  1577.          Bad->Pack ();
  1578.  
  1579.          delete Bad;
  1580.       }
  1581.  
  1582.       cprintf ("\r\n");
  1583.    }
  1584. }
  1585.  
  1586. VOID ImportTic (VOID)
  1587. {
  1588. #if !defined(__LINUX__)
  1589.    class TTic *Tic;
  1590.  
  1591.    if ((Tic = new TTic) != NULL) {
  1592.       strcpy (Tic->Inbound, Cfg->ProtectedInbound);
  1593.       while (Tic->OpenNext () == TRUE) {
  1594.          if (Tic->Import () == TRUE)
  1595.             Tic->Delete ();
  1596.       }
  1597.       strcpy (Tic->Inbound, Cfg->KnownInbound);
  1598.       while (Tic->OpenNext () == TRUE) {
  1599.          if (Tic->Import () == TRUE)
  1600.             Tic->Delete ();
  1601.       }
  1602.       strcpy (Tic->Inbound, Cfg->NormalInbound);
  1603.       while (Tic->OpenNext () == TRUE) {
  1604.          if (Tic->Import () == TRUE)
  1605.             Tic->Delete ();
  1606.       }
  1607.       delete Tic;
  1608.    }
  1609. #endif
  1610. }
  1611.  
  1612. VOID ProcessNewsgroups (VOID)
  1613. {
  1614.    ULONG Number, Tossed, SentArea;
  1615.    class TMsgData *Data;
  1616.    class USENET *Usenet;
  1617.    class TMsgBase *Msg;
  1618.    class TUser *User;
  1619.  
  1620.    if (Log != NULL)
  1621.       Log->Write ("+Processing NEWSgroups");
  1622.  
  1623.    if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  1624.       if (Data->First () == TRUE)
  1625.          do {
  1626.             if (Data->Storage != ST_USENET && Data->NewsGroup[0] != '\0' && Data->UpdateNews == TRUE) {
  1627.                if (Data->Storage == ST_JAM)
  1628.                   Msg = new JAM (Data->Path);
  1629.                else if (Data->Storage == ST_SQUISH)
  1630.                   Msg = new SQUISH (Data->Path);
  1631.                else if (Data->Storage == ST_FIDO)
  1632.                   Msg = new FIDOSDM (Data->Path);
  1633.                else if (Data->Storage == ST_ADEPT)
  1634.                   Msg = new ADEPT (Data->Path);
  1635.  
  1636.                if (Msg != NULL) {
  1637.                   cprintf ("Processing %s ", Data->NewsGroup);
  1638.                   if ((Usenet = new USENET (Cfg->NewsServer, Data->NewsGroup)) != NULL) {
  1639.                      strcpy (Usenet->HostName, Cfg->HostName);
  1640.                      strcpy (Usenet->Organization, Cfg->SystemName);
  1641.                      sprintf (Usenet->ProgramID, "%s Version %s", NAME, VERSION);
  1642.  
  1643.                      cprintf ("(%lu msgs)\r\n", Usenet->Number ());
  1644.  
  1645.                      cprintf ("Scanning %-40.40s ", Data->NewsGroup);
  1646.                      Number = Msg->Lowest ();
  1647.                      cprintf ("#%06lu to #%06lu ", Number, Msg->Highest ());
  1648.                      SentArea = 0L;
  1649.  
  1650.                      Msg->Lock (0L);
  1651.  
  1652.                      do {
  1653.                         if (Msg->Read (Number) == TRUE) {
  1654.                            cprintf ("<#%06lu>\b\b\b\b\b\b\b\b\b", Number);
  1655.                            if (Msg->Sent == FALSE) {
  1656.                               strcpy (Usenet->User, "anonymous");
  1657.                               if (Msg->Local == TRUE) {
  1658.                                  if ((User = new TUser (Cfg->UserFile)) != NULL) {
  1659.                                     if (User->GetData (Msg->From) == TRUE)
  1660.                                        strcpy (Usenet->User, User->MailBox);
  1661.                                     delete User;
  1662.                                  }
  1663.                               }
  1664.                               if (Usenet->Add (Msg) == TRUE) {
  1665.                                  Msg->Delete (Number);
  1666.                                  SentArea++;
  1667.                               }
  1668.                               else if (Log != NULL) {
  1669.                                  Log->Write (":Sending msg# %lu in %s", Number, Data->NewsGroup);
  1670.                                  Log->Write ("!Server error: %s", Usenet->Error);
  1671.                               }
  1672.                            }
  1673.                         }
  1674.                      } while (Msg->Next (Number) == TRUE);
  1675.  
  1676.                      Msg->UnLock ();
  1677.  
  1678.                      cprintf ("\r\n");
  1679.                      Tossed = 0L;
  1680.                      Number = Data->Highest;
  1681.  
  1682.                      while (Usenet->Next (Number) == TRUE) {
  1683.                         if (Usenet->Read (Number, MAX_LINE_LENGTH) == TRUE) {
  1684.                            cprintf ("%s #%06lu: ", Data->NewsGroup, Number);
  1685.                            Usenet->Sent = TRUE;
  1686.                            Msg->Add (Usenet);
  1687.                            cprintf ("=> #%06lu\r\n", Msg->Highest ());
  1688.                            Tossed++;
  1689.                         }
  1690.                      }
  1691.  
  1692.                      Data->Highest = Number;
  1693.  
  1694.                      if (Log != NULL && (Tossed != 0L || SentArea != 0L))
  1695.                         Log->Write (":   %-30.30s (Toss=%04d,Sent=%04lu)", Data->NewsGroup, Tossed, SentArea);
  1696.  
  1697.                      delete Usenet;
  1698.  
  1699.                      Data->ActiveMsgs = Msg->Number ();
  1700.                      Data->Update ();
  1701.                   }
  1702.                   delete Msg;
  1703.                   Msg = NULL;
  1704.                   cprintf ("\r\n");
  1705.                }
  1706.             }
  1707.          } while (Data->Next () == TRUE);
  1708.  
  1709.       cprintf ("\r\n");
  1710.       delete Data;
  1711.    }
  1712. }
  1713.  
  1714. int main (int argc, char *argv[])
  1715. {
  1716.    int fd, i;
  1717.    USHORT Import, Export, Pack, DoNetmail, NoArcMail;
  1718.    USHORT DoBad, Tic, News;
  1719.    CHAR Temp[128], *Config = NULL, *Channel = NULL, *Inbound = NULL;
  1720.    ULONG Running, Messages = 0L;
  1721.    struct stat statbuf;
  1722.    class TMail *Mail;
  1723.    class TRoute *Route;
  1724.  
  1725.    Import = Export = Pack = FALSE;
  1726.    DoNetmail = TRUE, DoBad = TRUE;
  1727.    Tic = News = NoArcMail = FALSE;
  1728.  
  1729.    printf ("\nMAIL; %s Mail Processor - Version %s\n", NAME, VERSION);
  1730.    printf ("      Copyright (c) 1991-96 by Marco Maccaferri. All Rights Reserved.\n\n");
  1731.  
  1732.    if (ValidateKey ("bbs") == KEY_UNREGISTERED) {
  1733.       printf ("* * *     WARNING: No license key found    * * *\n");
  1734.       if ((i = CheckExpiration ()) == 0) {
  1735.          printf ("* * *   This evaluation copy has expired   * * *\n\a\n");
  1736.           exit (0);
  1737.       }
  1738.       else
  1739.          printf ("* * * You have %2d days left for evaluation * * * \n\a\n", i);
  1740.    }
  1741.  
  1742.    if (argc <= 1) {
  1743.       printf (" * Command-line parameters:\n\n");
  1744.  
  1745.       printf ("        IMPORT    Import (toss) messages from packets\n");
  1746.       printf ("        EXPORT    Export (scan) messages to packets\n");
  1747.       printf ("        PACK      Export netmail and route outgoing packets\n\n");
  1748. //#if !defined(__LINUX__)
  1749. //      printf ("        TIC       Process TIC files\n\n");
  1750. //#endif
  1751.       printf ("        NEWS      Process newsgroups\n\n");
  1752.       printf ("        -o        Only route packets when PACKing\n");
  1753.       printf ("        -b        Only toss .PKT files, never ARCmail bundles\n");
  1754.       printf ("        -i        Do no import from bad messages\n");
  1755.       printf ("        -f<dir>   Use <dir> as inbound directory\n");
  1756.  
  1757.       printf ("\n * Please refer to the documentation for a more complete command summary\n\n");
  1758.    }
  1759.    else {
  1760.       for (i = 1; i < argc; i++) {
  1761.          if (!stricmp (argv[i], "import") || !stricmp (argv[i], "toss") || !stricmp (argv[i], "in"))
  1762.             Import = TRUE;
  1763.          else if (!stricmp (argv[i], "export") || !stricmp (argv[i], "scan") || !stricmp (argv[i], "out"))
  1764.             Export = TRUE;
  1765.          else if (!stricmp (argv[i], "pack") || !stricmp (argv[i], "squash"))
  1766.             Pack = TRUE;
  1767. //         else if (!stricmp (argv[i], "tic"))
  1768. //            Tic = TRUE;
  1769.          else if (!stricmp (argv[i], "news"))
  1770.             News = TRUE;
  1771.          else if (!stricmp (argv[i], "-o"))
  1772.             DoNetmail = FALSE;
  1773.          else if (!stricmp (argv[i], "-b"))
  1774.             NoArcMail = TRUE;
  1775.          else if (!stricmp (argv[i], "-i"))
  1776.             DoBad = FALSE;
  1777.          else if (!stricmp (argv[i], "-f")) {
  1778.             if (argv[i][2] != '\0')
  1779.                Inbound = &argv[i][2];
  1780.          }
  1781.          else if (Config == NULL)
  1782.             Config = argv[i];
  1783.          else if (Channel == NULL)
  1784.             Channel = argv[i];
  1785.       }
  1786.  
  1787.       if ((Cfg = new TConfig) != NULL) {
  1788.          if (Cfg->Load (Config, Channel) == FALSE)
  1789.             Cfg->Default ();
  1790.       }
  1791.  
  1792.       Running = time (NULL);
  1793.  
  1794.       sprintf (Temp, "%smailproc.flg", Cfg->SystemPath);
  1795.       if (stat (Temp, &statbuf) != 0) {
  1796.          if ((fd = sopen (Temp, O_WRONLY|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE)) != -1)
  1797.             close (fd);
  1798.  
  1799.          if ((Log = new TLog) != NULL) {
  1800.             Log->Open ("mail.log");
  1801. #if defined(__OS2__)
  1802.             Log->Write ("+Begin, v%s (OS/2)", VERSION);
  1803. #elif defined(__NT__)
  1804.             Log->Write ("+Begin, v%s (Win32)", VERSION);
  1805. #endif
  1806.             Log->Write ("+Message-base sharing is enabled");
  1807.          }
  1808.  
  1809.          if ((Mail = new TMail) != NULL) {
  1810.             Mail->Cfg = Cfg;
  1811.             Mail->Log = Log;
  1812.  
  1813.             if (Import == TRUE) {
  1814.                if (DoBad == TRUE)
  1815.                   ImportFromBadMsgs ();
  1816.  
  1817.                if (Inbound == NULL) {
  1818.                   strcpy (Mail->Inbound, Cfg->ProtectedInbound);
  1819.                   if (NoArcMail == FALSE) {
  1820.                      while (Mail->IsArcmail () == TRUE)
  1821.                         Mail->UnpackArcmail ();
  1822.                   }
  1823.                   if (Mail->IsMail () == TRUE)
  1824.                      Mail->Import ();
  1825.                   strcpy (Mail->Inbound, Cfg->KnownInbound);
  1826.                   if (NoArcMail == FALSE) {
  1827.                      while (Mail->IsArcmail () == TRUE)
  1828.                         Mail->UnpackArcmail ();
  1829.                   }
  1830.                   if (Mail->IsMail () == TRUE)
  1831.                      Mail->Import ();
  1832.                   strcpy (Mail->Inbound, Cfg->NormalInbound);
  1833.                   if (NoArcMail == FALSE) {
  1834.                      while (Mail->IsArcmail () == TRUE)
  1835.                         Mail->UnpackArcmail ();
  1836.                   }
  1837.                   if (Mail->IsMail () == TRUE)
  1838.                      Mail->Import ();
  1839.                }
  1840.                else {
  1841.                   strcpy (Mail->Inbound, Inbound);
  1842.                   if (NoArcMail == FALSE) {
  1843.                      while (Mail->IsArcmail () == TRUE)
  1844.                         Mail->UnpackArcmail ();
  1845.                   }
  1846.                   if (Mail->IsMail () == TRUE)
  1847.                      Mail->Import ();
  1848.                }
  1849.  
  1850.                strcpy (Mail->Inbound, ".\\");
  1851.                if (NoArcMail == FALSE) {
  1852.                   while (Mail->IsArcmail () == TRUE)
  1853.                      Mail->UnpackArcmail ();
  1854.                }
  1855.                if (Mail->IsMail () == TRUE)
  1856.                   Mail->Import ();
  1857.  
  1858.                if (Log != NULL) {
  1859.                   if (Mail->Packets == 0)
  1860.                      Log->Write ("+No ECHOmail processed at this time");
  1861.                   else {
  1862.                      Messages = Mail->MsgTossed;
  1863.                      Log->Write ("+%d packet(s): %lu NETmail, %lu ECHOmail, %lu Dupes, %lu Bad", Mail->Packets, Mail->NetMail, Mail->MsgTossed - Mail->NetMail, Mail->Duplicate, Mail->Bad);
  1864.                   }
  1865.                }
  1866.             }
  1867.  
  1868.             if (Tic == TRUE)
  1869.                ImportTic ();
  1870.  
  1871.             if (News == TRUE)
  1872.                ProcessNewsgroups ();
  1873.  
  1874.             if (Export == TRUE) {
  1875.                Mail->Export ();
  1876.  
  1877.                if (Log != NULL) {
  1878.                   if (Mail->MsgSent != 0L)
  1879.                      Log->Write ("+%lu ECHOmail message(s) forwarded", Mail->MsgSent);
  1880.                   else
  1881.                      Log->Write ("+No ECHOmail messages forwarded");
  1882.                }
  1883.             }
  1884.  
  1885.             if (Pack == TRUE && DoNetmail == TRUE)
  1886.                Mail->ExportNetMail ();
  1887.  
  1888.             delete Mail;
  1889.          }
  1890.  
  1891.          if (Pack == TRUE) {
  1892.             if ((Route = new TRoute) != NULL) {
  1893.                Route->Cfg = Cfg;
  1894.                Route->Log = Log;
  1895.                Route->Run ();
  1896.                delete Route;
  1897.             }
  1898.          }
  1899.  
  1900.          if (Log != NULL) {
  1901.             Log->Write (":End");
  1902.             delete Log;
  1903.          }
  1904.  
  1905.          sprintf (Temp, "%smailproc.flg", Cfg->SystemPath);
  1906.          unlink (Temp);
  1907.  
  1908.          if ((Running = time (NULL) - Running) == 0L)
  1909.             Running = 1L;
  1910.          if (Messages != 0L)
  1911.             printf ("Run time %lu second(s), %lu msgs/sec, exit\n\n", Running, Messages / Running);
  1912.          else
  1913.             printf ("Run time %lu second(s), exit\n\n", Running);
  1914.       }
  1915.  
  1916.       if (Cfg != NULL)
  1917.          delete Cfg;
  1918.    }
  1919.  
  1920.    return (0);
  1921. }
  1922.  
  1923.  
  1924.