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

  1.  
  2. // LoraBBS Version 2.99 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include "_ldefs.h"
  20. #include "msgbase.h"
  21. #include "lorawin.h"
  22.  
  23. PSZ CheckExts[] = { ".su", ".mo", ".tu", ".we", ".th", ".fr", ".sa", NULL };
  24.  
  25. VOID TMailProcessor::Import (VOID)
  26. {
  27.    int fd;
  28.    USHORT SkipPacket, Empty;
  29.    CHAR *Line, *Base;
  30.    ULONG Number, DestNumber;
  31.    class TUser *User;
  32.    class TMsgBase *Extra;
  33.  
  34.    if (Inbound[0] != '\0') {
  35.       if (Inbound[strlen (Inbound) - 1] == '\\' || Inbound[strlen (Inbound) - 1] == '/')
  36.          Inbound[strlen (Inbound) - 1] = '\0';
  37. #if defined(__LINUX__)
  38.       strcat (Inbound, "/");
  39. #else
  40.       strcat (Inbound, "\\");
  41. #endif
  42.    }
  43.  
  44.    strcpy (Outbound, Cfg->Outbound);
  45.    if (Outbound[strlen (Outbound) - 1] == '\\' || Outbound[strlen (Outbound) - 1] == '/')
  46.       Outbound[strlen (Outbound) - 1] = '\0';
  47.  
  48.    if (Log != NULL)
  49.       Log->Write ("+Import From %s", Inbound);
  50.  
  51.    Nodes = new TNodes (Cfg->NodelistPath);
  52.    Data = new TMsgData (Cfg->SystemPath);
  53.    Forward = new TEchoLink (Cfg->SystemPath);
  54.    Dupes = new TDupes (Cfg->SystemPath);
  55.    if ((Echo = new TEchotoss (Cfg->SystemPath)) != NULL)
  56.       Echo->Load ();
  57.  
  58.    SeenBy = new TKludges;
  59.    Path = new TKludges;
  60.  
  61.    Msg = NULL;
  62.    TossedArea = 0L;
  63.    Packet = NULL;
  64.    BadArea = FALSE;
  65.    Started = time (NULL);
  66.    BytesProcessed = 0L;
  67.  
  68.    while (OpenNextPacket () == TRUE) {
  69.       LastTag[0] = '\0';
  70.       Packets++;
  71.  
  72.       if (Output != NULL)
  73.          Output->Clear ();
  74.  
  75.       if (Log != NULL) {
  76.          Log->Write ("+%s, %02d/%02d/%d, %02d:%02d", strupr (PktName), Packet->Date.Month, Packet->Date.Day, Packet->Date.Year, Packet->Date.Hour, Packet->Date.Minute);
  77.          Log->Write (":Orig: %s, Dest: %s", Packet->FromAddress, Packet->ToAddress);
  78.       }
  79.  
  80.       SkipPacket = FALSE;
  81.       if (Nodes != NULL && Cfg->Secure == TRUE) {
  82.          if (Nodes->Read (Packet->FromAddress) == TRUE) {
  83.             if (Nodes->InPktPwd[0] != '\0' && strcmp (Nodes->InPktPwd, Packet->Password)) {
  84.                SkipPacket = TRUE;
  85.                if (Log != NULL)
  86.                   Log->Write ("!Invalid Packet Password, His: %s, Ours: %s", Packet->Password, Nodes->InPktPwd);
  87.             }
  88.          }
  89.       }
  90.  
  91.       Number = Packet->Lowest ();
  92.  
  93.       do {
  94.          if (SkipPacket == TRUE)
  95.             break;
  96.  
  97.          if (Packet->Read (Number, MAX_LINE_LENGTH) == TRUE) {
  98.             // Vengono resettati i flags che non devono essere mantenuti durante il
  99.             // passaggio da un nodo all'altro
  100.             Packet->Sent = Packet->Received = FALSE;
  101.             Packet->Crash = Packet->Direct = Packet->Hold = FALSE;
  102.  
  103.             if ((Line = (PSZ)Packet->Text.First ()) != NULL) {
  104.                if (!strncmp (Line, "AREA:", 5)) {
  105.                   ImportEchoMail (&Line[5]);
  106.                   TossedArea++;
  107.                }
  108.                else {
  109.                   if (Msg != NULL) {
  110.                      if (TossedArea != 0L) {
  111.                         if (Data != NULL && IsAreasBBS == FALSE) {
  112.                            Data->ActiveMsgs = Msg->Number ();
  113.                            Data->Update ();
  114.                         }
  115.                         if (Dupes != NULL)
  116.                            Dupes->Save ();
  117.                         if (Log != NULL)
  118.                            Log->Write (":   %-20.20s (Toss=%04d)", LastTag, TossedArea);
  119.                         if (Echo != NULL)
  120.                            Echo->Add (LastTag);
  121.                      }
  122.                      TossedArea = 0L;
  123.                      Msg->UnLock ();
  124.                      delete Msg;
  125.                   }
  126.                   strcpy (LastTag, "NetMail");
  127.  
  128.                   Empty = TRUE;
  129.                   if ((Line = (PSZ)Packet->Text.First ()) != NULL)
  130.                      do {
  131.                         if (*Line != '\001' && *Line != '\0') {
  132.                            Empty = FALSE;
  133.                            break;
  134.                         }
  135.                      } while ((Line = (PSZ)Packet->Text.Next ()) != NULL);
  136.  
  137.                   if (Log != NULL) {
  138.                      if (Empty == TRUE)
  139.                         Log->Write ("*Netmail: %s -> %s (Empty)", Packet->From, Packet->To);
  140.                      else
  141.                         Log->Write ("*Netmail: %s -> %s", Packet->From, Packet->To);
  142.                      Log->Write ("*         %s -> %s", Packet->FromAddress, Packet->ToAddress);
  143.                   }
  144.  
  145.                   if (Empty == FALSE || Cfg->ImportEmpty == TRUE) {
  146.                      Msg = NULL;
  147.                      if (Cfg->NetMailStorage == ST_JAM)
  148.                         Msg = new JAM (Cfg->NetMailPath);
  149.                      else if (Cfg->NetMailStorage == ST_SQUISH)
  150.                         Msg = new SQUISH (Cfg->NetMailPath);
  151.                      else if (Cfg->NetMailStorage == ST_FIDO)
  152.                         Msg = new FIDOSDM (Cfg->NetMailPath);
  153.                      else if (Cfg->NetMailStorage == ST_ADEPT)
  154.                         Msg = new ADEPT (Cfg->NetMailPath);
  155.                      else if (Cfg->NetMailStorage == ST_HUDSON)
  156.                         Msg = new HUDSON (Cfg->HudsonPath, (UCHAR)Cfg->NetMailBoard);
  157.  
  158.                      if (Msg != NULL) {
  159.                         Msg->New ();
  160.                         Msg->Add (Packet);
  161.                         DestNumber = Msg->Highest ();
  162.  
  163.                         if (Output != NULL) {
  164.                            Base = "";
  165.                            if (Cfg->NetMailStorage == ST_SQUISH)
  166.                               Base = "Squish<tm>";
  167.                            else if (Cfg->NetMailStorage == ST_JAM)
  168.                               Base = "JAM";
  169.                            else if (Cfg->NetMailStorage == ST_FIDO)
  170.                               Base = "Fido *.MSG";
  171.                            else if (Cfg->NetMailStorage == ST_ADEPT)
  172.                               Base = "AdeptXBBS";
  173.                            else if (Cfg->NetMailStorage == ST_HUDSON)
  174.                               Base = "Hudson";
  175.                            sprintf (Display, "%6lu %-32.32s %-12.12s %6lu", Number + 1L, LastTag, Base, Msg->UidToMsgn (DestNumber));
  176.                            Output->Add (Display);
  177.                         }
  178.  
  179.                         delete Msg;
  180.                         Msg = NULL;
  181.                      }
  182.                      NetMail++;
  183.  
  184.                      if ((User = new TUser (Cfg->UserFile)) != NULL) {
  185.                         if (User->GetData (Packet->To) == TRUE) {
  186.                            Extra = NULL;
  187.                            if (Cfg->MailStorage == ST_JAM)
  188.                               Extra = new JAM (Cfg->MailPath);
  189.                            else if (Cfg->MailStorage == ST_SQUISH)
  190.                               Extra = new SQUISH (Cfg->MailPath);
  191.                            else if (Cfg->MailStorage == ST_FIDO)
  192.                               Extra = new FIDOSDM (Cfg->MailPath);
  193.                            else if (Cfg->MailStorage == ST_ADEPT)
  194.                               Extra = new ADEPT (Cfg->MailPath);
  195.                            else if (Cfg->MailStorage == ST_HUDSON)
  196.                               Extra = new HUDSON (Cfg->HudsonPath, (UCHAR)Cfg->MailBoard);
  197.                            if (Extra != NULL) {
  198.                               Extra->Add (Packet);
  199.                               delete Extra;
  200.                            }
  201.                         }
  202.                         delete User;
  203.                      }
  204.                   }
  205.                   else if (Output != NULL) {
  206.                      sprintf (Display, "%6lu %-32.32s %-12.12s Empty, skipped", Number + 1L, LastTag, "");
  207.                      Output->Add (Display);
  208.                   }
  209.                }
  210.             }
  211.  
  212.             MsgTossed++;
  213.          }
  214.       } while (Packet->Next (Number) == TRUE);
  215.  
  216.       if (Msg != NULL) {
  217.          if (TossedArea != 0L) {
  218.             if (Data != NULL && IsAreasBBS == FALSE) {
  219.                Data->ActiveMsgs = Msg->Number ();
  220.                Data->Update ();
  221.             }
  222.             if (Dupes != NULL)
  223.                Dupes->Save ();
  224.             if (Log != NULL)
  225.                Log->Write (":   %-20.20s (Toss=%04d)", LastTag, TossedArea);
  226.             if (Echo != NULL)
  227.                Echo->Add (LastTag);
  228.          }
  229.          TossedArea = 0L;
  230.          Msg->UnLock ();
  231.          delete Msg;
  232.       }
  233.       Msg = NULL;
  234.  
  235.       if (Packet != NULL) {
  236.          Packet->Kill ();
  237.          delete Packet;
  238.          Packet = NULL;
  239.       }
  240.    }
  241.  
  242.    if (MsgTossed > 0L) {
  243.       sprintf (Temp, "%sarealist.rsn", Cfg->SystemPath);
  244.       if ((fd = open (Temp, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE)) != -1)
  245.          close (fd);
  246.    }
  247.  
  248.    if ((Started = time (NULL) - Started) == 0L)
  249.       Started = 1L;
  250.    if (Log != NULL)
  251.       Log->Write (" Throughput: %lu kB/sec, %lu mail/sec", (BytesProcessed / 1024L) / Started, MsgTossed / Started);
  252.  
  253.    if (Path != NULL)
  254.       delete Path;
  255.    if (SeenBy != NULL)
  256.       delete SeenBy;
  257.  
  258.    if (Echo != NULL) {
  259.       Echo->Save ();
  260.       delete Echo;
  261.    }
  262.    if (Dupes != NULL)
  263.       delete Dupes;
  264.    if (Nodes != NULL)
  265.       delete Nodes;
  266.    if (Forward != NULL)
  267.       delete Forward;
  268.    if (Data != NULL)
  269.       delete Data;
  270. }
  271.  
  272. VOID TMailProcessor::ImportBad (VOID)
  273. {
  274.    int fd;
  275.    CHAR *Line;
  276.    ULONG Number;
  277.    class TMsgBase *Packet;
  278.  
  279.    if (Log != NULL)
  280.       Log->Write ("+Import From %s", Cfg->BadPath);
  281.  
  282.    Nodes = NULL;
  283.    Data = new TMsgData (Cfg->SystemPath);
  284.    Forward = NULL;
  285.    Dupes = NULL;
  286.    if ((Echo = new TEchotoss (Cfg->SystemPath)) != NULL)
  287.       Echo->Load ();
  288.  
  289.    Msg = NULL;
  290.    TossedArea = 0L;
  291.    BadArea = FALSE;
  292.  
  293.    Packet = NULL;
  294.    if (Cfg->BadStorage == ST_JAM)
  295.       Packet = new JAM (Cfg->BadPath);
  296.    else if (Cfg->BadStorage == ST_SQUISH)
  297.       Packet = new SQUISH (Cfg->BadPath);
  298.    else if (Cfg->BadStorage == ST_FIDO)
  299.       Packet = new FIDOSDM (Cfg->BadPath);
  300.    else if (Cfg->BadStorage == ST_ADEPT)
  301.       Packet = new ADEPT (Cfg->BadPath);
  302.    else if (Cfg->BadStorage == ST_HUDSON)
  303.       Packet = new HUDSON (Cfg->HudsonPath, (UCHAR)Cfg->BadBoard);
  304.  
  305.    LastTag[0] = '\0';
  306.  
  307.    if (Output != NULL)
  308.       Output->Clear ();
  309.  
  310.    Number = Packet->Lowest ();
  311.  
  312.    do {
  313.       if (Packet->Read (Number, MAX_LINE_LENGTH) == TRUE) {
  314.          // Vengono resettati i flags che non devono essere mantenuti durante il
  315.          // passaggio da un nodo all'altro
  316.          Packet->Sent = Packet->Received = FALSE;
  317.          Packet->Crash = Packet->Direct = Packet->Hold = FALSE;
  318.  
  319.          if ((Line = (PSZ)Packet->Text.First ()) != NULL) {
  320.             if (!strncmp (Line, "AREA:", 5)) {
  321.                ImportEchoMail (&Line[5], Packet);
  322.                TossedArea++;
  323.                Packet->Delete (Number);
  324.             }
  325.          }
  326.  
  327.          MsgTossed++;
  328.       }
  329.    } while (Packet->Next (Number) == TRUE);
  330.  
  331.    if (Msg != NULL) {
  332.       if (TossedArea != 0L) {
  333.          if (Data != NULL && IsAreasBBS == FALSE) {
  334.             Data->ActiveMsgs = Msg->Number ();
  335.             Data->Update ();
  336.          }
  337.          if (Log != NULL)
  338.             Log->Write (":   %-20.20s (Toss=%04d)", LastTag, TossedArea);
  339.          if (Echo != NULL)
  340.             Echo->Add (LastTag);
  341.       }
  342.       TossedArea = 0L;
  343.       Msg->UnLock ();
  344.       delete Msg;
  345.    }
  346.    Msg = NULL;
  347.  
  348.    if (Packet != NULL) {
  349.       delete Packet;
  350.       Packet = NULL;
  351.    }
  352.  
  353.    if (MsgTossed > 0L) {
  354.       sprintf (Temp, "%sarealist.rsn", Cfg->SystemPath);
  355.       if ((fd = open (Temp, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE)) != -1)
  356.          close (fd);
  357.    }
  358.  
  359.    if (Echo != NULL) {
  360.       Echo->Save ();
  361.       delete Echo;
  362.    }
  363.    if (Data != NULL)
  364.       delete Data;
  365. }
  366.  
  367. ULONG TMailProcessor::ImportEchoMail (PSZ EchoTag, class TMsgBase *InBase)
  368. {
  369.    USHORT BadMessage = FALSE, DupeMessage = FALSE;
  370.    CHAR *Text, *Base;
  371.    ULONG RetVal = 0L;
  372.    class TMsgBase *Extra = NULL;
  373.    class TCollection *MsgText;
  374.  
  375.    Base = "";
  376.    if (InBase == NULL)
  377.       InBase = Packet;
  378.    MsgText = &InBase->Text;
  379.  
  380.    if (stricmp (EchoTag, LastTag)) {
  381.       if (TossedArea != 0L) {
  382.          if (Log != NULL)
  383.             Log->Write (":   %-20.20s (Toss=%04d)", LastTag, TossedArea);
  384.          if (Echo != NULL)
  385.             Echo->Add (LastTag);
  386.       }
  387.  
  388.       TossedArea = 0L;
  389.       strcpy (LastTag, strupr (EchoTag));
  390.       BadArea = FALSE;
  391.  
  392.       if (OpenArea (LastTag) == FALSE) {
  393.          BadArea = TRUE;
  394.          BadMessage = TRUE;
  395.       }
  396.    }
  397.  
  398.    if (BadArea == TRUE) {
  399.       Extra = NULL;
  400.       Bad++;
  401.       Base = "(Bad area)";
  402.       BadMessage = TRUE;
  403.    }
  404.  
  405.    if (BadMessage == FALSE && Forward != NULL) {
  406.       if (Forward->Check (InBase->FromAddress) == FALSE) {
  407.          if (Cfg->Secure == TRUE) {
  408.             BadMessage = TRUE;
  409.             Extra = Msg;
  410.             Bad++;
  411.             Base = "(Bad origin)";
  412.  
  413.             if (Cfg->BadStorage == ST_JAM)
  414.                Msg = new JAM (Cfg->BadPath);
  415.             else if (Cfg->BadStorage == ST_SQUISH)
  416.                Msg = new SQUISH (Cfg->BadPath);
  417.             else if (Cfg->BadStorage == ST_FIDO)
  418.                Msg = new FIDOSDM (Cfg->BadPath);
  419.             else if (Cfg->BadStorage == ST_ADEPT)
  420.                Msg = new ADEPT (Cfg->BadPath);
  421.             else if (Cfg->BadStorage == ST_HUDSON)
  422.                Msg = new HUDSON (Cfg->HudsonPath, (UCHAR)Cfg->BadBoard);
  423.          }
  424.       }
  425.       else {
  426.          if (Forward->ReceiveOnly == TRUE) {
  427.             BadMessage = TRUE;
  428.             Extra = Msg;
  429.             Bad++;
  430.             Base = "(Receive only)";
  431.  
  432.             if (Cfg->BadStorage == ST_JAM)
  433.                Msg = new JAM (Cfg->BadPath);
  434.             else if (Cfg->BadStorage == ST_SQUISH)
  435.                Msg = new SQUISH (Cfg->BadPath);
  436.             else if (Cfg->BadStorage == ST_FIDO)
  437.                Msg = new FIDOSDM (Cfg->BadPath);
  438.             else if (Cfg->BadStorage == ST_ADEPT)
  439.                Msg = new ADEPT (Cfg->BadPath);
  440.             else if (Cfg->BadStorage == ST_HUDSON)
  441.                Msg = new HUDSON (Cfg->HudsonPath, (UCHAR)Cfg->BadBoard);
  442.          }
  443.       }
  444.    }
  445.  
  446.    if (BadMessage == FALSE && Dupes != NULL) {
  447.       if (Dupes->Check (Data->EchoTag, InBase) == TRUE) {
  448.          DupeMessage = TRUE;
  449.          Extra = Msg;
  450.          Duplicate++;
  451.          Base = "(Duplicate)";
  452.  
  453.          if (Cfg->DupeStorage == ST_JAM)
  454.             Msg = new JAM (Cfg->DupePath);
  455.          else if (Cfg->DupeStorage == ST_SQUISH)
  456.             Msg = new SQUISH (Cfg->DupePath);
  457.          else if (Cfg->DupeStorage == ST_FIDO)
  458.             Msg = new FIDOSDM (Cfg->DupePath);
  459.          else if (Cfg->DupeStorage == ST_ADEPT)
  460.             Msg = new ADEPT (Cfg->DupePath);
  461.          else if (Cfg->BadStorage == ST_HUDSON)
  462.             Msg = new HUDSON (Cfg->HudsonPath, (UCHAR)Cfg->BadBoard);
  463.       }
  464.       else
  465.          Dupes->Add (Data->EchoTag, InBase);
  466.    }
  467.  
  468.    if (Msg != NULL) {
  469.       if (BadMessage == FALSE && DupeMessage == FALSE) {
  470.          InBase->Text.First ();
  471.          InBase->Text.Remove ();
  472.       }
  473.  
  474.       Msg->New ();
  475.  
  476.       if (SeenBy != NULL && Path != NULL) {
  477.          SeenBy->Clear ();
  478.          Path->Clear ();
  479.  
  480.          Path->Sort = FALSE;
  481.          SeenBy->Sort = FALSE;
  482.  
  483.          if ((Text = (PSZ)MsgText->Last ()) != NULL)
  484.             do {
  485.                if (strncmp (Text, "SEEN-BY: ", 9) && strncmp (Text, "\001PATH: ", 7) && *Text != '\0')
  486.                   break;
  487.                if (!strncmp (Text, "SEEN-BY: ", 9) && SeenBy != NULL) {
  488.                   SeenBy->AddString (&Text[9]);
  489.                   MsgText->Remove ();
  490.                   Text = (PSZ)MsgText->Value ();
  491.                }
  492.                else if (!strncmp (Text, "\001PATH: ", 7) && Path != NULL) {
  493.                   Path->AddString (&Text[7]);
  494.                   MsgText->Remove ();
  495.                   Text = (PSZ)MsgText->Value ();
  496.                }
  497.                else
  498.                   Text = (PSZ)MsgText->Previous ();
  499.             } while (Text != NULL);
  500.  
  501.          SeenBy->Sort = TRUE;
  502.          SeenBy->AddString (InBase->FromAddress);
  503.          Path->AddString (InBase->FromAddress);
  504.  
  505.          if (Data->Address[0] != '\0') {
  506.             SeenBy->AddString (Data->Address);
  507.             Path->AddString (Data->Address);
  508.          }
  509.          else if (Cfg->MailAddress.First () == TRUE) {
  510.             SeenBy->AddString (Cfg->MailAddress.String);
  511.             Path->AddString (Cfg->MailAddress.String);
  512.          }
  513.  
  514.          if (SeenBy->First () == TRUE) {
  515.             strcpy (Temp, "SEEN-BY:");
  516.             do {
  517.                if (strlen (Temp) + strlen (SeenBy->ShortAddress) + 1 > 70) {
  518.                   MsgText->Add (Temp);
  519.                   strcpy (Temp, "SEEN-BY:");
  520.                   strcpy (SeenBy->ShortAddress, SeenBy->Address);
  521.                }
  522.                strcat (Temp, " ");
  523.                strcat (Temp, SeenBy->ShortAddress);
  524.             } while (SeenBy->Next () == TRUE);
  525.             if (strlen (Temp) > 9)
  526.                MsgText->Add (Temp);
  527.          }
  528.  
  529.          if (Path->First () == TRUE) {
  530.             strcpy (Temp, "\001PATH:");
  531.             do {
  532.                if (strlen (Temp) + strlen (Path->ShortAddress) + 1 > 70) {
  533.                   MsgText->Add (Temp);
  534.                   strcpy (Temp, "\001PATH:");
  535.                   strcpy (Path->ShortAddress, Path->Address);
  536.                }
  537.                strcat (Temp, " ");
  538.                strcat (Temp, Path->ShortAddress);
  539.             } while (Path->Next () == TRUE);
  540.             if (strlen (Temp) > 7)
  541.                MsgText->Add (Temp);
  542.          }
  543.       }
  544.  
  545.       Msg->Add (InBase);
  546.       RetVal = Msg->Highest ();
  547.  
  548. #if defined(__OS2__)
  549.       DosSleep (1L);
  550. #elif defined(__NT__)
  551.       Sleep (1L);
  552. #endif
  553.  
  554.       if (Data->Storage == ST_PASSTHROUGH && BadMessage == FALSE && DupeMessage == FALSE)
  555.          ExportEchoMail (InBase->Current + 1L, Data->EchoTag);
  556.    }
  557.  
  558.    if (Output != NULL && Data->Storage != ST_PASSTHROUGH) {
  559.       if (BadMessage == FALSE && DupeMessage == FALSE) {
  560.          Base = "???";
  561.          if (Data->Storage == ST_SQUISH)
  562.             Base = "Squish<tm>";
  563.          else if (Data->Storage == ST_JAM)
  564.             Base = "JAM";
  565.          else if (Data->Storage == ST_FIDO)
  566.             Base = "Fido *.MSG";
  567.          else if (Data->Storage == ST_ADEPT)
  568.             Base = "AdeptXBBS";
  569.          else if (Data->Storage == ST_USENET)
  570.             Base = "Newsgroup";
  571.          else if (Data->Storage == ST_HUDSON)
  572.             Base = "Hudson";
  573.       }
  574.       sprintf (Display, "%6lu %-32.32s %-12.12s %6lu", InBase->Current + 1L, LastTag, Base, Msg->UidToMsgn (RetVal));
  575.       Output->Add (Display);
  576.    }
  577.  
  578.    if (BadMessage == TRUE || DupeMessage == TRUE) {
  579.       if (Extra != NULL) {
  580.          if (Msg != NULL)
  581.             delete Msg;
  582.          Msg = Extra;
  583.       }
  584.    }
  585.  
  586.    return (RetVal);
  587. }
  588.  
  589. USHORT TMailProcessor::IsArcmail (VOID)
  590. {
  591.    DIR *dir;
  592.    USHORT RetVal = FALSE, i;
  593.    CHAR Filename[128];
  594.    struct dirent *ent;
  595.  
  596.    strcpy (Filename, Inbound);
  597.    if (Filename[strlen (Filename) - 1] == '\\' || Filename[strlen (Filename) - 1] == '/')
  598.       Filename[strlen (Filename) - 1] = '\0';
  599.  
  600.    if ((dir = opendir (Filename)) != NULL) {
  601.       while ((ent = readdir (dir)) != NULL && RetVal == FALSE) {
  602. #if !defined(__LINUX__)
  603.          strlwr (ent->d_name);
  604. #endif
  605.          i = 0;
  606.          while (CheckExts[i] != NULL && RetVal == FALSE) {
  607.             if (strstr (ent->d_name, CheckExts[i]) != NULL)
  608.                RetVal = TRUE;
  609.             i++;
  610.          }
  611.       }
  612.       closedir (dir);
  613.    }
  614.  
  615.    return (RetVal);
  616. }
  617.  
  618. USHORT TMailProcessor::CheckEchoList (PSZ pszFile, PSZ pszEchoTag)
  619. {
  620.    #define MAX_LINECHAR 2048
  621.    FILE *fp;
  622.    USHORT RetVal = FALSE;
  623.    CHAR *lpTemp = (CHAR *)malloc (MAX_LINECHAR + 1);
  624.    CHAR *lpTag;
  625.  
  626.    if (*pszFile == '@')
  627.       pszFile++;
  628.    fp = fopen (pszFile, "rt");
  629.  
  630.    if (fp != NULL && lpTemp != NULL) {
  631.       while (fgets (lpTemp, MAX_LINECHAR, fp) != NULL) {
  632.          lpTemp[strlen (lpTemp) - 1] = '\0';
  633.          if (lpTemp[0] == ';' || lpTemp[0] == '\0')
  634.             continue;
  635.          if ((lpTag = strtok (lpTemp, " ")) != NULL) {
  636.             if (!stricmp (lpTag, pszEchoTag)) {
  637.                RetVal = TRUE;
  638.                break;
  639.             }
  640.          }
  641.       }
  642.    }
  643.  
  644.    if (lpTemp != NULL)
  645.       free (lpTemp);
  646.    if (fp != NULL)
  647.       fclose (fp);
  648.  
  649.    return (RetVal);
  650. }
  651.  
  652. USHORT TMailProcessor::OpenArea (PSZ pszEchoTag)
  653. {
  654.    FILE *fp;
  655.    USHORT Found = FALSE, Create;
  656.    CHAR *p, *path, *tag, *links;
  657.  
  658.    if (Msg != NULL) {
  659.       if (Data != NULL && IsAreasBBS == FALSE) {
  660.          Data->ActiveMsgs = Msg->Number ();
  661.          Data->Update ();
  662.       }
  663.       if (Dupes != NULL)
  664.          Dupes->Save ();
  665.       Msg->UnLock ();
  666.       delete Msg;
  667.    }
  668.  
  669.    Msg = NULL;
  670.    strcpy (LastTag, strupr (pszEchoTag));
  671.    IsAreasBBS = FALSE;
  672.  
  673.    if (Data != NULL) {
  674.       Found = Data->ReadEcho (pszEchoTag);
  675.       if (Found == TRUE) {
  676.          if (Forward != NULL)
  677.             Forward->Load (pszEchoTag);
  678.  
  679.          if (Data->Storage == ST_JAM)
  680.             Msg = new JAM (Data->Path);
  681.          else if (Data->Storage == ST_SQUISH)
  682.             Msg = new SQUISH (Data->Path);
  683.          else if (Data->Storage == ST_FIDO)
  684.             Msg = new FIDOSDM (Data->Path);
  685.          else if (Data->Storage == ST_ADEPT)
  686.             Msg = new ADEPT (Data->Path);
  687.          else if (Data->Storage == ST_HUDSON)
  688.             Msg = new HUDSON (Data->Path, (UCHAR)Data->Board);
  689. #if !defined(__POINT__)
  690.          else if (Data->Storage == ST_USENET)
  691.             Msg = new USENET (Cfg->NewsServer, Data->NewsGroup);
  692.          else if (Data->Storage == ST_PASSTHROUGH)
  693.             Msg = new PASSTHR;
  694. #endif
  695.       }
  696.    }
  697.  
  698.    if (Found == FALSE && Cfg->UseAreasBBS == TRUE && Cfg->AreasBBS[0] != '\0') {
  699.       if ((fp = fopen (Cfg->AreasBBS, "rt")) != NULL) {
  700.          fgets (Temp, sizeof (Temp) - 1, fp);
  701.          while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  702.             if (Temp[0] == ';')
  703.                continue;
  704.             Temp[strlen (Temp) - 1] = '\0';
  705.             if ((path = strtok (Temp, " ")) != NULL) {
  706.                tag = strtok (NULL, " ");
  707.                if ((links = strtok (NULL, "")) != NULL) {
  708.                   while (*links == ' ')
  709.                      links++;
  710.                }
  711.                if (!stricmp (pszEchoTag, tag)) {
  712.                   Found = TRUE;
  713.                   IsAreasBBS = TRUE;
  714.                   if (*path == '$')
  715.                      Msg = new SQUISH (Cfg->AdjustPath (++path));
  716.                   else if (*path == '!')
  717.                      Msg = new JAM (Cfg->AdjustPath (++path));
  718.                   else if (*path == '=')
  719.                      Msg = new ADEPT (Cfg->AdjustPath (++path));
  720.                   else if (isdigit (*path))
  721.                      Msg = new HUDSON (Cfg->HudsonPath, (UCHAR)atoi (path));
  722.                   else
  723.                      Msg = new FIDOSDM (Cfg->FixPath (path));
  724.                   if (Forward != NULL) {
  725.                      Forward->Clear ();
  726.                      Forward->AddString (links);
  727.                   }
  728.                }
  729.             }
  730.          }
  731.          fclose (fp);
  732.       }
  733.    }
  734.  
  735.    if (Found == FALSE && Data != NULL) {
  736.       Create = FALSE;
  737.  
  738.       if (Nodes != NULL) {
  739.          if (Nodes->Read (Packet->FromAddress, FALSE) == TRUE) {
  740.             if (Nodes->CreateNewAreas == TRUE) {
  741.                Create = TRUE;
  742.                if ((p = strtok (Nodes->NewAreasFilter, " ")) != NULL) {
  743.                   Create = FALSE;
  744.                   do {
  745.                      if (*p == '@') {
  746.                         if (CheckEchoList (p, pszEchoTag) == FALSE)
  747.                            Create = FALSE;
  748.                      }
  749.                      else if (strstr (pszEchoTag, strupr (p)) != NULL) {
  750.                         Create = TRUE;
  751.                         break;
  752.                      }
  753.                   } while ((p = strtok (NULL, " ")) != NULL);
  754.                }
  755.             }
  756.          }
  757.  
  758.          if (Create == FALSE && Log != NULL)
  759.             Log->Write ("!Node %s can't create new area %s", Packet->FromAddress, pszEchoTag);
  760.       }
  761.  
  762.       if (Create == TRUE) {
  763.          strcpy (Temp, pszEchoTag);
  764.          Temp[sizeof (Data->Key) - 1] = '\0';
  765.          while (Data->Read (Temp) == TRUE) {
  766.             if (isdigit (Temp[strlen (Temp) - 1]))
  767.                Temp[strlen (Temp) - 1]++;
  768.             else
  769.                Temp[strlen (Temp) - 1] = '0';
  770.          }
  771.  
  772.          Data->New ();
  773.          strcpy (Data->Key, Temp);
  774.          sprintf (Data->Display, "New area %s", pszEchoTag);
  775.          Data->Storage = Cfg->NewAreasStorage;
  776.          strcpy (Temp, pszEchoTag);
  777.          Temp[8] = '\0';
  778.          while ((p = strchr (Temp, '.')) != NULL)
  779.             *p = '_';
  780.          if (Temp[strlen (Temp) - 1] == '_')
  781.             Temp[strlen (Temp) - 1] = '\0';
  782.          sprintf (Data->Path, "%s%s", Cfg->NewAreasPath, Temp);
  783.          strlwr (Data->Path);
  784.          if (Data->Storage == ST_FIDO)
  785. #if defined(__LINUX__)
  786.             mkdir (Data->Path, 0666);
  787. #else
  788.             mkdir (Data->Path);
  789. #endif
  790.          Data->Level = Cfg->NewAreasLevel;
  791.          Data->AccessFlags = Cfg->NewAreasFlags;
  792.          Data->DenyFlags = Cfg->NewAreasDenyFlags;
  793.          Data->WriteLevel = Cfg->NewAreasWriteLevel;
  794.          Data->WriteFlags = Cfg->NewAreasWriteFlags;
  795.          Data->DenyWriteFlags = Cfg->NewAreasDenyWriteFlags;
  796.          strcpy (Data->EchoTag, pszEchoTag);
  797.          Data->EchoMail = TRUE;
  798.          Data->DaysOld = 14;
  799.          Data->MaxMessages = 200;
  800.          Data->Add ();
  801.          Data->ReadEcho (pszEchoTag);
  802.  
  803.          Found = TRUE;
  804.          if (Log != NULL)
  805.             Log->Write ("*Created area [%s] %s from %s", Data->Key, Data->EchoTag, Packet->FromAddress);
  806.  
  807.          if (Forward != NULL) {
  808.             Forward->Load (pszEchoTag);
  809.             Forward->AddString (Packet->FromAddress);
  810.  
  811.             if (Nodes != NULL) {
  812.                strcpy (Temp, Packet->FromAddress);
  813.                if (Nodes->First () == TRUE)
  814.                   do {
  815.                      if (Nodes->LinkNewEcho == TRUE && stricmp (Nodes->Address, Packet->FromAddress)) {
  816.                         Forward->AddString (Nodes->Address);
  817.                         if (Log != NULL)
  818.                            Log->Write ("-Area %s auto-linked to %s", Data->EchoTag, Nodes->Address);
  819.                      }
  820.                   } while (Nodes->Next () == TRUE);
  821.             }
  822.  
  823.             Forward->Save ();
  824.          }
  825.  
  826.          if (Data->Storage == ST_JAM)
  827.             Msg = new JAM (Data->Path);
  828.          else if (Data->Storage == ST_SQUISH)
  829.             Msg = new SQUISH (Data->Path);
  830.          else if (Data->Storage == ST_FIDO)
  831.             Msg = new FIDOSDM (Data->Path);
  832.          else if (Data->Storage == ST_ADEPT)
  833.             Msg = new ADEPT (Data->Path);
  834.          else if (Data->Storage == ST_HUDSON)
  835.             Msg = new HUDSON (Data->Path, (UCHAR)Data->Board);
  836. #if !defined(__POINT__)
  837.          else if (Data->Storage == ST_USENET)
  838.             Msg = new USENET (Cfg->NewsServer, Data->NewsGroup);
  839.          else if (Data->Storage == ST_PASSTHROUGH)
  840.             Msg = new PASSTHR;
  841. #endif
  842.       }
  843.    }
  844.  
  845.    if (Found == FALSE) {
  846.       if (Forward != NULL)
  847.          Forward->Load ("");
  848.  
  849.       if (Cfg->BadStorage == ST_JAM)
  850.          Msg = new JAM (Cfg->BadPath);
  851.       else if (Cfg->BadStorage == ST_SQUISH)
  852.          Msg = new SQUISH (Cfg->BadPath);
  853.       else if (Cfg->BadStorage == ST_FIDO)
  854.          Msg = new FIDOSDM (Cfg->BadPath);
  855.       else if (Cfg->BadStorage == ST_ADEPT)
  856.          Msg = new ADEPT (Cfg->BadPath);
  857.       else if (Cfg->BadStorage == ST_HUDSON)
  858.          Msg = new HUDSON (Cfg->HudsonPath, (UCHAR)Cfg->BadBoard);
  859.    }
  860.  
  861.    if (Msg != NULL)
  862.       Msg->Lock (0L);
  863.    if (Dupes != NULL)
  864.       Dupes->Load (pszEchoTag);
  865.  
  866.    return (Found);
  867. }
  868.  
  869. USHORT TMailProcessor::OpenNextPacket (VOID)
  870. {
  871.    DIR *dir;
  872.    USHORT RetVal = FALSE, MaxBad;
  873.    CHAR Filename[128], OpenFileName[128];
  874.    PSZ p;
  875.    ULONG PktDate;
  876.    struct dirent *ent;
  877.    struct stat statbuf;
  878.  
  879.    strcpy (Filename, Inbound);
  880.    if (Filename[strlen (Filename) - 1] == '\\' || Filename[strlen (Filename) - 1] == '/')
  881.       Filename[strlen (Filename) - 1] = '\0';
  882.  
  883.    if ((dir = opendir (Filename)) != NULL) {
  884.       while ((ent = readdir (dir)) != NULL) {
  885.          strlwr (ent->d_name);
  886.          if (strstr (ent->d_name, ".pk") != NULL) {
  887.             sprintf (Filename, "%s%s", Inbound, ent->d_name);
  888.             stat (Filename, &statbuf);
  889.             strcpy (PktName, ent->d_name);
  890.             PktDate = statbuf.st_mtime;
  891.             RetVal = TRUE;
  892.             break;
  893.          }
  894.       }
  895.  
  896.       if (RetVal == TRUE) {
  897.          while ((ent = readdir (dir)) != NULL) {
  898.             strlwr (ent->d_name);
  899.             if (strstr (ent->d_name, ".pk") != NULL) {
  900.                sprintf (Filename, "%s%s", Inbound, ent->d_name);
  901.                stat (Filename, &statbuf);
  902.                if (PktDate > statbuf.st_mtime) {
  903.                   strcpy (PktName, ent->d_name);
  904.                   PktDate = statbuf.st_mtime;
  905.                }
  906.             }
  907.          }
  908.       }
  909.  
  910.       closedir (dir);
  911.    }
  912.  
  913.    if (RetVal == TRUE) {
  914.       MaxBad = 0;
  915.  
  916.       strcpy (Filename, Inbound);
  917.       if (Filename[strlen (Filename) - 1] == '\\' || Filename[strlen (Filename) - 1] == '/')
  918.          Filename[strlen (Filename) - 1] = '\0';
  919.  
  920.       if ((dir = opendir (Filename)) != NULL) {
  921.          while ((ent = readdir (dir)) != NULL) {
  922.             strlwr (ent->d_name);
  923.             if (strstr (ent->d_name, "bad_pkt.") != NULL) {
  924.                if ((p = strchr (ent->d_name, '.')) != NULL) {
  925.                   p++;
  926.                   if (atoi (p) > MaxBad)
  927.                      MaxBad = (USHORT)atoi (p);
  928.                }
  929.             }
  930.          }
  931.          closedir (dir);
  932.       }
  933.  
  934.       sprintf (Filename, "%s%s", Inbound, PktName);
  935.       sprintf (OpenFileName, "%sbad_pkt.%03d", Inbound, ++MaxBad);
  936.       rename (Filename, OpenFileName);
  937.       stat (OpenFileName, &statbuf);
  938.  
  939.       if (Packet != NULL)
  940.          delete Packet;
  941.  
  942.       if ((Packet = new PACKET) != NULL) {
  943.          if (Packet->Open (OpenFileName, FALSE) == FALSE) {
  944.             delete Packet;
  945.             Packet = NULL;
  946.             RetVal = FALSE;
  947.          }
  948.          else
  949.             BytesProcessed += statbuf.st_size;
  950.       }
  951.    }
  952.  
  953.    return (RetVal);
  954. }
  955.  
  956. USHORT TMailProcessor::UnpackArcmail (VOID)
  957. {
  958.    DIR *dir;
  959.    USHORT RetVal = FALSE, i, counter;
  960.    CHAR Filename[128], BadArc[128];
  961.    struct dirent *ent;
  962.    class TPacker *Packer;
  963.  
  964.    strcpy (Filename, Inbound);
  965.    if (Filename[strlen (Filename) - 1] == '\\' || Filename[strlen (Filename) - 1] == '/')
  966.       Filename[strlen (Filename) - 1] = '\0';
  967.  
  968.    if ((dir = opendir (Filename)) != NULL) {
  969.       while ((ent = readdir (dir)) != NULL && RetVal == FALSE) {
  970.          i = 0;
  971.          while (CheckExts[i] != NULL && RetVal == FALSE) {
  972. #if !defined(__LINUX__)
  973.             strlwr (ent->d_name);
  974. #endif
  975.             if (strstr (ent->d_name, CheckExts[i]) != NULL && isdigit (ent->d_name[strlen (ent->d_name) - 1])) {
  976.                sprintf (Filename, "%s%s", Inbound, ent->d_name);
  977.                if ((Packer = new TPacker (Cfg->SystemPath)) != NULL) {
  978.                   if (Packer->CheckArc (Filename) == TRUE) {
  979.                      Log->Write ("#Unpacking %s (%s)", Filename, Packer->Display);
  980.                      if (Packer->DoUnpack (Filename, Inbound, "*.pk?") == FALSE) {
  981.                         Log->Write ("!Return error: %s", Packer->Error);
  982.                         counter = 1;
  983.                         do {
  984.                            sprintf (BadArc, "%sbad_arc.%03d", Inbound, counter++);
  985.                         } while (rename (Filename, BadArc) == -1);
  986.                         Log->Write (":Renamed %s in %s", Filename, BadArc);
  987.                      }
  988.                      else {
  989.                         unlink (Filename);
  990.                         RetVal = TRUE;
  991.                      }
  992.                   }
  993.                   else {
  994.                      Log->Write ("!Unrecognized method for %s", ent->d_name);
  995.                      counter = 1;
  996.                      do {
  997.                         sprintf (BadArc, "%sbad_arc.%03d", Inbound, counter++);
  998.                      } while (rename (Filename, BadArc) == -1);
  999.                      Log->Write (":Renamed %s in %s", Filename, BadArc);
  1000.                   }
  1001.                   delete Packer;
  1002.                }
  1003.             }
  1004.             i++;
  1005.          }
  1006.       }
  1007.       closedir (dir);
  1008.    }
  1009.  
  1010.    return (RetVal);
  1011. }
  1012.  
  1013.