home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / EXPORT.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  87KB  |  2,188 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. VOID TMailProcessor::Export (VOID)
  24. {
  25.    USHORT i, UseEchotoss;
  26.    ULONG Number, SentArea, Highest;
  27.    class TEchotoss *Echo;
  28.  
  29.    UseEchotoss = FALSE;
  30.    Data = new TMsgData (Cfg->SystemPath);
  31.    Forward = new TEchoLink (Cfg->SystemPath);
  32.    Dupes = new TDupes (Cfg->SystemPath);
  33.  
  34.    SeenBy = new TKludges;
  35.    Path = new TKludges;
  36.  
  37.    strcpy (Outbound, Cfg->Outbound);
  38.    if (Outbound[strlen (Outbound) - 1] == '\\' || Outbound[strlen (Outbound) - 1] == '/')
  39.       Outbound[strlen (Outbound) - 1] = '\0';
  40.  
  41.    if (Output != NULL)
  42.       Output->Clear ();
  43.    if (Status != NULL)
  44.       Status->Clear ();
  45.  
  46.    if (Log != NULL)
  47.       Log->Write ("#Scanning messages");
  48.  
  49.    SentArea = MsgSent = 0L;
  50.  
  51.    if (Data != NULL && Forward != NULL) {
  52.       if ((Echo = new TEchotoss (Cfg->SystemPath)) != NULL) {
  53.          Echo->Load ();
  54.          Echo->Delete ();
  55.          if (Echo->First () == TRUE) {
  56.             UseEchotoss = TRUE;
  57.  
  58.             do {
  59.                Data->ReadEcho (Echo->Tag);
  60.  
  61.                if (Status != NULL)
  62.                   Status->SetLine (0, "Scanning %s", Data->EchoTag);
  63.  
  64.                Msg = NULL;
  65.                if (Data->Storage == ST_JAM)
  66.                   Msg = new JAM (Data->Path);
  67.                else if (Data->Storage == ST_SQUISH)
  68.                   Msg = new SQUISH (Data->Path);
  69.                else if (Data->Storage == ST_FIDO)
  70.                   Msg = new FIDOSDM (Data->Path);
  71.                else if (Data->Storage == ST_ADEPT)
  72.                   Msg = new ADEPT (Data->Path);
  73.                else if (Data->Storage == ST_HUDSON)
  74.                   Msg = new HUDSON (Data->Path, (UCHAR)Data->Board);
  75. #if !defined(__POINT__)
  76.                else if (Data->Storage == ST_USENET)
  77.                   Msg = new USENET (Cfg->NewsServer, Data->NewsGroup);
  78. #endif
  79.  
  80.                if (Msg != NULL) {
  81.                   Msg->Lock (0L);
  82.                   Highest = Msg->Highest ();
  83.  
  84.                   if (Msg->GetHWM (Number) == FALSE)
  85.                      Number = Data->HighWaterMark;
  86.                   if (Number > Highest) {
  87.                      if (Log != NULL)
  88.                         Log->Write ("!Found HWM error: %lu / %lu (%s)", Number, Msg->Highest (), Data->Path);
  89.                      Number = Highest;
  90.                   }
  91.  
  92.                   if (Status != NULL)
  93.                      Status->SetLine (1, "   %lu / %lu", Msg->UidToMsgn (Number), Msg->Number ());
  94.  
  95.                   if (Msg->Next (Number) == TRUE) {
  96.                      Forward->Load (Data->EchoTag);
  97.                      if (Forward->First () == TRUE) {
  98.                         SentArea = 0L;
  99.                         Dupes->Load (Data->EchoTag);
  100.  
  101.                         do {
  102.                            if (Status != NULL)
  103.                               Status->SetLine (1, "   %lu / %lu", Msg->UidToMsgn (Number), Msg->Number ());
  104.                            i = ExportEchoMail (Number, Data->EchoTag);
  105.                            SentArea += i;
  106.                            MsgSent += i;
  107.                         } while (Msg->Next (Number) == TRUE);
  108.  
  109.                         Dupes->Save ();
  110.  
  111.                         if (Log != NULL && SentArea != 0L)
  112.                            Log->Write (":   %-20.20s (Sent=%04lu)", Data->EchoTag, SentArea);
  113.                      }
  114.                      else
  115.                         Number = Msg->Highest ();
  116.                   }
  117.  
  118.                   Msg->SetHWM (Number);
  119.                   Data->HighWaterMark = Number;
  120.                   Data->Update ();
  121.  
  122.                   Msg->UnLock ();
  123.                   delete Msg;
  124.                }
  125.             } while (Echo->Next () == TRUE);
  126.          }
  127.          delete Echo;
  128.       }
  129.  
  130.       if (UseEchotoss == FALSE && Data->First () == TRUE)
  131.          do {
  132.             if (Data->EchoMail == TRUE && Data->EchoTag[0] != '\0' && Data->Storage != ST_PASSTHROUGH) {
  133.                if (Status != NULL)
  134.                   Status->SetLine (0, "Scanning %s", Data->EchoTag);
  135.  
  136.                Msg = NULL;
  137.                if (Data->Storage == ST_JAM)
  138.                   Msg = new JAM (Data->Path);
  139.                else if (Data->Storage == ST_SQUISH)
  140.                   Msg = new SQUISH (Data->Path);
  141.                else if (Data->Storage == ST_FIDO)
  142.                   Msg = new FIDOSDM (Data->Path);
  143.                else if (Data->Storage == ST_ADEPT)
  144.                   Msg = new ADEPT (Data->Path);
  145.                else if (Data->Storage == ST_HUDSON)
  146.                   Msg = new HUDSON (Data->Path, (UCHAR)Data->Board);
  147. #if !defined(__POINT__)
  148.                else if (Data->Storage == ST_USENET)
  149.                   Msg = new USENET (Cfg->NewsServer, Data->NewsGroup);
  150. #endif
  151.  
  152.                if (Msg != NULL) {
  153.                   Msg->Lock (0L);
  154.                   Highest = Msg->Highest ();
  155.  
  156.                   if (Msg->GetHWM (Number) == FALSE)
  157.                      Number = Data->HighWaterMark;
  158.                   if (Number > Highest) {
  159.                      if (Log != NULL)
  160.                         Log->Write ("!Found HWM error: %lu / %lu (%s)", Number, Msg->Highest (), Data->Path);
  161.                      Number = Highest;
  162.                   }
  163.  
  164.                   if (Status != NULL)
  165.                      Status->SetLine (1, "   %lu / %lu", Number, Highest);
  166.  
  167.                   if (Msg->Next (Number) == TRUE) {
  168.                      Forward->Load (Data->EchoTag);
  169.                      if (Forward->First () == TRUE) {
  170.                         SentArea = 0L;
  171.                         Dupes->Load (Data->EchoTag);
  172.  
  173.                         do {
  174.                            if (Status != NULL)
  175.                               Status->SetLine (1, "   %lu / %lu", Msg->UidToMsgn (Number), Msg->Number ());
  176.                            i = ExportEchoMail (Number, Data->EchoTag);
  177.                            SentArea += i;
  178.                            MsgSent += i;
  179.                         } while (Msg->Next (Number) == TRUE);
  180.  
  181.                         Dupes->Save ();
  182.  
  183.                         if (Log != NULL && SentArea != 0L)
  184.                            Log->Write (":   %-20.20s (Sent=%04lu)", Data->EchoTag, SentArea);
  185.                      }
  186.                      else
  187.                         Number = Msg->Highest ();
  188.                   }
  189.  
  190.                   Msg->SetHWM (Number);
  191.                   Data->HighWaterMark = Number;
  192.                   Data->Update ();
  193.  
  194.                   Msg->UnLock ();
  195.                   delete Msg;
  196.                }
  197.             }
  198.          } while (Data->Next () == TRUE);
  199.    }
  200.  
  201.    if (Log != NULL) {
  202.       if (MsgSent == 0L)
  203.          Log->Write ("+No ECHOmail messages forwarded");
  204.       else
  205.          Log->Write ("+%lu ECHOmail message(s) forwarded", MsgSent);
  206.    }
  207.  
  208.    Msg = NULL;
  209.    Packet = NULL;
  210.  
  211.    if (Status != NULL)
  212.       Status->Clear ();
  213.  
  214.    if (Path != NULL)
  215.       delete Path;
  216.    if (SeenBy != NULL)
  217.       delete SeenBy;
  218.  
  219.    if (Dupes != NULL)
  220.       delete Dupes;
  221.    if (Forward != NULL)
  222.       delete Forward;
  223.    if (Data != NULL)
  224.       delete Data;
  225. }
  226.  
  227. USHORT TMailProcessor::ExportEchoMail (ULONG Number, PSZ pszEchoTag)
  228. {
  229.    USHORT SentArea = 0, First = TRUE, DoExport;
  230.    CHAR *Text, *Base;
  231.    ULONG Msgn;
  232.    struct stat statbuf;
  233.    class TAddress ToAddr;
  234.    class PACKET *Packet;
  235.    class TCollection *MsgText;
  236.  
  237.    Base = "???";
  238.    if (Data->Storage == ST_SQUISH)
  239.       Base = "Squish<tm>";
  240.    else if (Data->Storage == ST_JAM)
  241.       Base = "JAM";
  242.    else if (Data->Storage == ST_FIDO)
  243.       Base = "Fido *.MSG";
  244.    else if (Data->Storage == ST_ADEPT)
  245.       Base = "AdeptXBBS";
  246.    else if (Data->Storage == ST_HUDSON)
  247.       Base = "Hudson";
  248. #if !defined(__POINT__)
  249.    else if (Data->Storage == ST_PASSTHROUGH)
  250.       Base = "Passthrough";
  251.    else if (Data->Storage == ST_USENET)
  252.       Base = "Newsgroup";
  253. #endif
  254.  
  255.    if (Msg != NULL && (Data->Storage != ST_FIDO || Number != 1L)) {
  256.       if (Msg->Read (Number, MAX_LINE_LENGTH) == TRUE) {
  257.          DoExport = FALSE;
  258.  
  259.          if (SeenBy != NULL && Path != NULL) {
  260.             SeenBy->Clear ();
  261.             Path->Clear ();
  262.  
  263.             Path->Sort = FALSE;
  264.             SeenBy->Sort = FALSE;
  265.  
  266.             //////////////////////////////////////////////////////////////////
  267.             // Analizza il testo e crea la lista di seen-by e path          //
  268.             //////////////////////////////////////////////////////////////////
  269.             MsgText = &Msg->Text;
  270.             if ((Text = (PSZ)MsgText->Last ()) != NULL)
  271.                do {
  272.                   if (strncmp (Text, "SEEN-BY: ", 9) && strncmp (Text, "\001PATH: ", 7) && *Text != '\0')
  273.                      break;
  274.                   if (!strncmp (Text, "SEEN-BY: ", 9) && SeenBy != NULL) {
  275.                      SeenBy->AddString (&Text[9]);
  276.                      MsgText->Remove ();
  277.                      Text = (PSZ)MsgText->Value ();
  278.                   }
  279.                   else if (!strncmp (Text, "\001PATH: ", 7) && Path != NULL) {
  280.                      Path->AddString (&Text[7]);
  281.                      MsgText->Remove ();
  282.                      Text = (PSZ)MsgText->Value ();
  283.                   }
  284.                   else
  285.                      Text = (PSZ)MsgText->Previous ();
  286.                } while (Text != NULL);
  287.  
  288.             //////////////////////////////////////////////////////////////////
  289.             // Controlla che il messaggio sia da esportare                  //
  290.             //////////////////////////////////////////////////////////////////
  291.             if (Forward->First () == TRUE)
  292.                do {
  293.                   if (SeenBy->Check (Forward->Address) == FALSE && Forward->SendOnly == FALSE) {
  294.                      DoExport = TRUE;
  295.                      break;
  296.                   }
  297.                } while (Forward->Next () == TRUE);
  298.  
  299.             //////////////////////////////////////////////////////////////////
  300.             // Se il messaggio e' locale rimpiazza la tearline              //
  301.             //////////////////////////////////////////////////////////////////
  302.             if (DoExport == TRUE && Msg->Local == TRUE && Cfg->ReplaceTear == TRUE) {
  303.                if ((Text = (PSZ)MsgText->Last ()) != NULL)
  304.                   do {
  305.                      if (!strncmp (Text, "---", 3)) {
  306.                         sprintf (Temp, "--- %s", Cfg->TearLine);
  307.                         strsrep (Temp, "%1", VERSION);
  308.                         MsgText->Replace (Temp);
  309.                         break;
  310.                      }
  311.                   } while ((Text = (PSZ)MsgText->Previous ()) != NULL);
  312.             }
  313.  
  314. #if defined(__OS2__)
  315.             DosSleep (1L);
  316. #elif defined(__NT__)
  317.             Sleep (1L);
  318. #endif
  319.  
  320.             if (DoExport == TRUE) {
  321.                if (Forward->First () == TRUE)
  322.                   do {
  323.                      Forward->Skip = FALSE;
  324.                      Forward->Update ();
  325.                   } while (Forward->Next () == TRUE);
  326.  
  327.                //////////////////////////////////////////////////////////////////
  328.                // Verifica per quali nodi deve essere esportato                //
  329.                //////////////////////////////////////////////////////////////////
  330.                SeenBy->Sort = TRUE;
  331.                if (Forward->First () == TRUE)
  332.                   do {
  333.                      if (SeenBy->Check (Forward->Address) == TRUE) {
  334.                         Forward->Skip = TRUE;
  335.                         Forward->Update ();
  336.                      }
  337.                      else
  338.                         SeenBy->AddString (Forward->Address);
  339.                   } while (Forward->Next () == TRUE);
  340.  
  341.                //////////////////////////////////////////////////////////////////
  342.                // Aggiunge il proprio indirizzo ai seen-by e path              //
  343.                //////////////////////////////////////////////////////////////////
  344.                if (Data->Address[0] != '\0') {
  345.                   SeenBy->AddString (Data->Address);
  346.                   Path->AddString (Data->Address);
  347.                }
  348.                else if (Cfg->MailAddress.First () == TRUE) {
  349.                   SeenBy->AddString (Cfg->MailAddress.String);
  350.                   Path->AddString (Cfg->MailAddress.String);
  351.                }
  352.  
  353.                //////////////////////////////////////////////////////////////////
  354.                // Ricostruisce le linee seen-by                                //
  355.                //////////////////////////////////////////////////////////////////
  356.                if (SeenBy->First () == TRUE) {
  357.                   strcpy (Temp, "SEEN-BY:");
  358.                   do {
  359.                      if (strlen (Temp) + strlen (SeenBy->ShortAddress) + 1 > 70) {
  360.                         MsgText->Add (Temp);
  361.                         strcpy (Temp, "SEEN-BY:");
  362.                         strcpy (SeenBy->ShortAddress, SeenBy->Address);
  363.                      }
  364.                      if (SeenBy->Net != Cfg->FakeNet && SeenBy->Point == 0) {
  365.                         strcat (Temp, " ");
  366.                         strcat (Temp, SeenBy->ShortAddress);
  367.                      }
  368.                   } while (SeenBy->Next () == TRUE);
  369.                   if (strlen (Temp) > 8)
  370.                      MsgText->Add (Temp);
  371.                }
  372.  
  373.                //////////////////////////////////////////////////////////////////
  374.                // Ricostruisce le linee path                                   //
  375.                //////////////////////////////////////////////////////////////////
  376.                if (Path->First () == TRUE) {
  377.                   strcpy (Temp, "\001PATH:");
  378.                   do {
  379.                      if (strlen (Temp) + strlen (Path->ShortAddress) + 1 > 70) {
  380.                         MsgText->Add (Temp);
  381.                         strcpy (Temp, "\001PATH:");
  382.                         strcpy (Path->ShortAddress, SeenBy->Address);
  383.                      }
  384.                      if (Path->Point == 0) {
  385.                         strcat (Temp, " ");
  386.                         strcat (Temp, Path->ShortAddress);
  387.                      }
  388.                   } while (Path->Next () == TRUE);
  389.                   if (strlen (Temp) > 6)
  390.                      MsgText->Add (Temp);
  391.                }
  392.             }
  393.          }
  394.  
  395.          if (DoExport == TRUE) {
  396.             //////////////////////////////////////////////////////////////////
  397.             // Aggiunge la linea AREA: in testa al messaggio                //
  398.             //////////////////////////////////////////////////////////////////
  399.             sprintf (Temp, "AREA:%s", pszEchoTag);
  400.             if ((Text = (PSZ)Msg->Text.First ()) != NULL) {
  401.                Msg->Text.Insert (Temp, (USHORT)(strlen (Temp) + 1));
  402.                if (*Text != '\0')
  403.                   Msg->Text.Insert (Text, (USHORT)(strlen (Text) + 1));
  404.                Msg->Text.First ();
  405.                Msg->Text.Remove ();
  406.             }
  407.             else
  408.                Msg->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  409.  
  410.             //////////////////////////////////////////////////////////////////
  411.             // Esporta il messaggio verso i destinatari                     //
  412.             //////////////////////////////////////////////////////////////////
  413.             if (Forward->First () == TRUE)
  414.                do {
  415.                   if (Forward->SendOnly == TRUE)
  416.                      Forward->Skip = TRUE;
  417.                   if (Forward->PersonalOnly == TRUE || Forward->Passive == TRUE) {
  418.                      if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  419.                         if (Nodes->Read (Forward->Address) == TRUE) {
  420.                            if (stricmp (Nodes->SysopName, Msg->To))
  421.                               Forward->Skip = TRUE;
  422.                         }
  423.                         delete Nodes;
  424.                         Nodes = NULL;
  425.                      }
  426.                   }
  427.  
  428.                   if (Forward->Skip == FALSE) {
  429.                      Msgn = Msg->UidToMsgn (Number);
  430.                      if (Status != NULL && (Msgn % 10L) != 0L)
  431.                         Status->SetLine (1, "   %lu / %lu", Msgn, Msg->Number ());
  432.  
  433.                      if (Output != NULL) {
  434.                         if (First == TRUE) {
  435.                            sprintf (Display, "%6lu %-22.22s %-12.12s %s", Msg->UidToMsgn (Number), pszEchoTag, Base, Forward->Address);
  436.                            Output->Add (Display);
  437.                            First = FALSE;
  438.                         }
  439.                         else {
  440.                            if ((strlen (Display) + strlen (Forward->ShortAddress)) > 68) {
  441.                               sprintf (Display, "       %-22.22s %-12.12s %s", "", "", Forward->Address);
  442.                               Output->Add (Display);
  443.                            }
  444.                            else {
  445.                               strcat (Display, " ");
  446.                               strcat (Display, Forward->ShortAddress);
  447.                               Output->Update (Display);
  448.                            }
  449.                         }
  450.                      }
  451.                      if ((Packet = new PACKET) != NULL) {
  452.                         strcpy (Packet->ToAddress, Forward->Address);
  453.  
  454.                         if (Data->Address[0] != '\0')
  455.                            strcpy (Packet->FromAddress, Data->Address);
  456.                         else {
  457.                            ToAddr.Parse (Packet->ToAddress);
  458.                            if (Cfg->MailAddress.First () == TRUE) {
  459.                               strcpy (Packet->FromAddress, Cfg->MailAddress.String);
  460.                               do {
  461.                                  if (Cfg->MailAddress.Zone == ToAddr.Zone) {
  462.                                     strcpy (Packet->FromAddress, Cfg->MailAddress.String);
  463.                                     break;
  464.                                  }
  465.                               } while (Cfg->MailAddress.Next () == TRUE);
  466.                            }
  467.                         }
  468.  
  469.                         strcpy (Msg->FromAddress, Packet->FromAddress);
  470.                         strcpy (Msg->ToAddress, Packet->ToAddress);
  471.  
  472.                         Cfg->MailAddress.First ();
  473.                         if (Cfg->MailAddress.Zone == Forward->Zone) {
  474.                            if (Forward->Point != 0) {
  475. #if defined(__LINUX__)
  476.                               sprintf (Temp, "%s/%04x%04x.pnt", Outbound, Forward->Net, Forward->Node);
  477.                               mkdir (Temp, 0666);
  478.                               sprintf (Temp, "%s/%04x%04x.pnt/%08x.xpr", Outbound, Forward->Net, Forward->Node, Forward->Point);
  479. #else
  480.                               sprintf (Temp, "%s\\%04x%04x.pnt", Outbound, Forward->Net, Forward->Node);
  481.                               mkdir (Temp);
  482.                               sprintf (Temp, "%s\\%04x%04x.pnt\\%08x.xpr", Outbound, Forward->Net, Forward->Node, Forward->Point);
  483. #endif
  484.                            }
  485.                            else
  486. #if defined(__LINUX__)
  487.                               sprintf (Temp, "%s/%04x%04x.xpr", Outbound, Forward->Net, Forward->Node);
  488. #else
  489.                               sprintf (Temp, "%s\\%04x%04x.xpr", Outbound, Forward->Net, Forward->Node);
  490. #endif
  491.                         }
  492.                         else {
  493.                            sprintf (Temp, "%s.%03x", Outbound, Forward->Zone);
  494. #if defined(__LINUX__)
  495.                            mkdir (Temp, 0666);
  496. #else
  497.                            mkdir (Temp);
  498. #endif
  499.                            if (Forward->Point != 0) {
  500. #if defined(__LINUX__)
  501.                               sprintf (Temp, "%s.%03x/%04x%04x.pnt", Outbound, Forward->Zone, Forward->Net, Forward->Node);
  502.                               mkdir (Temp, 0666);
  503.                               sprintf (Temp, "%s.%03x/%04x%04x.pnt/%08x.xpr", Outbound, Forward->Zone, Forward->Net, Forward->Node, Forward->Point);
  504. #else
  505.                               sprintf (Temp, "%s.%03x\\%04x%04x.pnt", Outbound, Forward->Zone, Forward->Net, Forward->Node);
  506.                               mkdir (Temp);
  507.                               sprintf (Temp, "%s.%03x\\%04x%04x.pnt\\%08x.xpr", Outbound, Forward->Zone, Forward->Net, Forward->Node, Forward->Point);
  508. #endif
  509.                            }
  510.                            else
  511. #if defined(__LINUX__)
  512.                               sprintf (Temp, "%s.%03x/%04x%04x.xpr", Outbound, Forward->Zone, Forward->Net, Forward->Node);
  513. #else
  514.                               sprintf (Temp, "%s.%03x\\%04x%04x.xpr", Outbound, Forward->Zone, Forward->Net, Forward->Node);
  515. #endif
  516.                         }
  517.                         if (stat (Temp, &statbuf) != 0) {
  518.                            if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  519.                               if (Nodes->Read (Forward->Address) == TRUE)
  520.                                  strcpy (Packet->Password, Nodes->OutPktPwd);
  521.                               delete Nodes;
  522.                               Nodes = NULL;
  523.                            }
  524.                         }
  525.                         if (Packet->Open (Temp, FALSE) == TRUE)
  526.                            Packet->Add (Msg);
  527.                         delete Packet;
  528.  
  529. #if defined(__OS2__)
  530.                         DosSleep (1L);
  531. #elif defined(__NT__)
  532.                         Sleep (1L);
  533. #endif
  534.  
  535.                         SentArea++;
  536.                      }
  537.                   }
  538.                } while (Forward->Next () == TRUE);
  539.          }
  540.  
  541.          //////////////////////////////////////////////////////////////////
  542.          // Se il messaggio e' locale aggiorna il database dei duplicati //
  543.          //////////////////////////////////////////////////////////////////
  544.          if (Dupes != NULL && Msg->Local == TRUE) {
  545.             if (Dupes->Check (Data->EchoTag, Msg) == FALSE)
  546.                Dupes->Add (Data->EchoTag, Msg);
  547.          }
  548.       }
  549.    }
  550.  
  551.    return (SentArea);
  552. }
  553.  
  554. VOID TMailProcessor::ExportNetMail (VOID)
  555. {
  556.    FILE *fp;
  557.    USHORT Process;
  558.    CHAR *Base, Found, PktFile[128], Attach[128], *p;
  559.    ULONG Number, Sent, Msgn;
  560.    struct stat statbuf;
  561.    class TNodes *Nodes;
  562.    class TAddress Address, ToAddress, PktAddress;
  563. #if !defined(__POINT__)
  564.    class TAreaManager *AreaMgr;
  565. #endif
  566.  
  567.    if (Output != NULL)
  568.       Output->Clear ();
  569.  
  570.    strcpy (Outbound, Cfg->Outbound);
  571.    if (Outbound[strlen (Outbound) - 1] == '\\' || Outbound[strlen (Outbound) - 1] == '/')
  572.       Outbound[strlen (Outbound) - 1] = '\0';
  573.  
  574.    switch (Cfg->NetMailStorage) {
  575.       case ST_JAM:
  576.          Msg = new JAM (Cfg->NetMailPath);
  577.          Base = "JAM";
  578.          break;
  579.       case ST_SQUISH:
  580.          Msg = new SQUISH (Cfg->NetMailPath);
  581.          Base = "Squish<tm>";
  582.          break;
  583.       case ST_FIDO:
  584.          Msg = new FIDOSDM (Cfg->NetMailPath);
  585.          Base = "Fido *.MSG";
  586.          break;
  587.       case ST_ADEPT:
  588.          Msg = new ADEPT (Cfg->NetMailPath);
  589.          Base = "AdeptXBBS";
  590.          break;
  591.       case ST_HUDSON:
  592.          Msg = new HUDSON (Cfg->HudsonPath, (UCHAR)Cfg->NetMailBoard);
  593.          Base = "Hudson";
  594.          break;
  595.       default:
  596.          Msg = NULL;
  597.          Base = "???";
  598.          break;
  599.    }
  600.  
  601. #if !defined(__POINT__)
  602.    if ((AreaMgr = new TAreaManager) != NULL) {
  603.       AreaMgr->Cfg = Cfg;
  604.       AreaMgr->Log = Log;
  605.    }
  606. #endif
  607.  
  608.    if (Msg != NULL) {
  609.       Msg->Lock (0L);
  610.       Sent = 0L;
  611.  
  612.       if (Log != NULL)
  613.          Log->Write ("#Packing from %s (%lu msgs)", Cfg->NetMailPath, Msg->Number ());
  614.  
  615.       if (Status != NULL) {
  616.          Status->Clear ();
  617.          Status->SetLine (0, "Exporting from %s", Cfg->NetMailPath);
  618.       }
  619.  
  620.       Number = Msg->Lowest ();
  621.       do {
  622.          if (Msg->Read (Number, MAX_LINE_LENGTH) == TRUE) {
  623.             Msgn = Msg->UidToMsgn (Number);
  624.             if (Status != NULL && (Msgn % 10L) == 0L)
  625.                Status->SetLine (1, "   %lu / %lu", Msgn, Msg->Number ());
  626.  
  627.             // Effettua il parsing dell'indirizzo di destinazione in una classe
  628.             // piu' maneggevole.
  629.             Address.Parse (Msg->ToAddress);
  630.             Cfg->MailAddress.First ();
  631.             if (Address.Zone == 0)
  632.                Address.Zone = Cfg->MailAddress.Zone;
  633.  
  634.             // Verifica se il messaggio e' indirizzato ad uno dei nostri aka.
  635.             Found = FALSE;
  636.             if (Cfg->MailAddress.First () == TRUE)
  637.                do {
  638.                   if (Cfg->MailAddress.Zone == Address.Zone && Cfg->MailAddress.Net == Address.Net && Cfg->MailAddress.Node == Address.Node && Cfg->MailAddress.Point == Address.Point) {
  639.                      // Se il messaggio e' per noi, flagga il messaggio come gia'
  640.                      // inviato. Il flag non viene salvato.
  641.                      Found = TRUE;
  642.                      break;
  643.                   }
  644.                } while (Cfg->MailAddress.Next () == TRUE);
  645.  
  646.             // Se si tratta di un messaggio indirizzato a noi (Found == TRUE) verifica
  647.             // se e' gia' stato ricevuto, in caso contrario verifica se il destinatario
  648.             // e' uno dei robot di manutenzione automatica.
  649.             if (Found == TRUE && Msg->Received == FALSE) {
  650.                if (Cfg->AreafixActive == TRUE) {
  651.                   Process = FALSE;
  652.                   if (!stricmp (Msg->To, "Areafix") || !stricmp (Msg->To, "AreaMgr"))
  653.                      Process = TRUE;
  654.                   strcpy (Attach, Cfg->AreafixNames);
  655.                   if ((p = strtok (Attach, " ")) != NULL)
  656.                      do {
  657.                         if (!stricmp (Msg->To, p)) {
  658.                            Process = TRUE;
  659.                            break;
  660.                         }
  661.                      } while ((p = strtok (NULL, " ")) != NULL);
  662.  
  663.                   if (AreaMgr != NULL && Process == TRUE) {
  664.                      Msg->Received = TRUE;
  665.                      Msg->WriteHeader (Number);
  666.                      AreaMgr->Msg = Msg;
  667.                      AreaMgr->ProcessAreafix ();
  668.                      Msg->Sent = TRUE;
  669.                   }
  670.                }
  671.                if (Cfg->RaidActive == TRUE) {
  672.                   Process = FALSE;
  673.                   if (!stricmp (Msg->To, "Raid"))
  674.                      Process = TRUE;
  675.                   strcpy (Attach, Cfg->RaidNames);
  676.                   if ((p = strtok (Attach, " ")) != NULL)
  677.                      do {
  678.                         if (!stricmp (Msg->To, p)) {
  679.                            Process = TRUE;
  680.                            break;
  681.                         }
  682.                      } while ((p = strtok (NULL, " ")) != NULL);
  683.  
  684.                   if (AreaMgr != NULL && Process == TRUE) {
  685.                      Msg->Received = TRUE;
  686.                      Msg->WriteHeader (Number);
  687.                      AreaMgr->Msg = Msg;
  688.                      AreaMgr->ProcessRaid ();
  689.                      Msg->Sent = TRUE;
  690.                   }
  691.                }
  692.             }
  693.  
  694.             if (Found == TRUE && Msg->Sent == FALSE) {
  695.                Msg->Sent = TRUE;
  696.                if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  697.                   if (Nodes->First () == TRUE)
  698.                      do {
  699.                         if (!stricmp (Nodes->SysopName, Msg->To) && Nodes->RemapMail == TRUE) {
  700.                            if (Log != NULL)
  701.                               Log->Write ("+Remapping #%lu from %s to %s", Msg->UidToMsgn (Number), Msg->ToAddress, Nodes->Address);
  702.                            strcpy (Msg->ToAddress, Nodes->Address);
  703.                            Msg->Sent = FALSE;
  704.                            break;
  705.                         }
  706.                      } while (Nodes->Next () == TRUE);
  707.                   delete Nodes;
  708.                }
  709.             }
  710.  
  711.             if (Msg->Sent == FALSE) {
  712.                // Se necessario facciamo prima un po' di output a video per far sapere
  713.                // che siamo ancora vivi.
  714.                if (Output != NULL) {
  715.                   sprintf (Display, "%6lu %-22.22s %-12.12s ", Msgn, "Netmail", Base);
  716.                   strcat (Display, Msg->ToAddress);
  717.                   Output->Add (Display);
  718.                }
  719.  
  720.                // Analizza l'indirizzo di destinazione per l'adattamento degli indirizzi.
  721.                Found = FALSE;
  722.                if (Cfg->MailAddress.First () == TRUE) {
  723.                   // Al primo passaggio cerca di trovare la corrispondenza con zona
  724.                   // net e nodo (nel caso di un point su un sistema multilinea).
  725.                   do {
  726.                      if (Cfg->MailAddress.Zone == Address.Zone && Cfg->MailAddress.Net == Address.Net && Cfg->MailAddress.Node == Address.Node) {
  727.                         PktAddress.Parse (Cfg->MailAddress.String);
  728.                         Found = TRUE;
  729.                         break;
  730.                      }
  731.                   } while (Cfg->MailAddress.Next () == TRUE);
  732.  
  733.                   // Al secondo passaggio cerca la corrispondenza semplicemente con
  734.                   // il numero di zona.
  735.                   if (Found == FALSE) {
  736.                      Cfg->MailAddress.First ();
  737.                      do {
  738.                         if (Cfg->MailAddress.Zone == Address.Zone) {
  739.                            PktAddress.Parse (Cfg->MailAddress.String);
  740.                            Found = TRUE;
  741.                            break;
  742.                         }
  743.                      } while (Cfg->MailAddress.Next () == TRUE);
  744.                   }
  745.  
  746.                   if (Found == FALSE) {
  747.                      // Nessuna corrispondenza, usiamo l'indirizzo di default (il primo
  748.                      // che compare nell'elenco).
  749.                      Cfg->MailAddress.First ();
  750.                      PktAddress.Parse (Cfg->MailAddress.String);
  751.                   }
  752.  
  753.                   if ((Packet = new PACKET) != NULL) {
  754.                      strcpy (Packet->FromAddress, PktAddress.String);
  755.                      strcpy (Packet->ToAddress, Msg->ToAddress);
  756.  
  757.                      // Rende piu' maneggevole l'indirizzo di destinazione e inserisce
  758.                      // la zona di default se l'indirizzo ne e' sprovvisto.
  759.                      Cfg->MailAddress.First ();
  760.                      ToAddress.Parse (Msg->ToAddress);
  761.                      if (ToAddress.Zone == 0)
  762.                         ToAddress.Zone = Cfg->MailAddress.Zone;
  763.  
  764.                      // Verifica se il messaggio e' indirizzato ad uno dei nostri point
  765.                      // verificando la presenza del numero di point e la presenza dello
  766.                      // stesso numero di zona, net e nodo di un nostro aka.
  767.                      if (Cfg->MailAddress.First () == TRUE && ToAddress.Point != 0) {
  768.                         Found = FALSE;
  769.                         do {
  770.                            if (Cfg->MailAddress.Zone == ToAddress.Zone && Cfg->MailAddress.Net == ToAddress.Net && Cfg->MailAddress.Node == ToAddress.Node) {
  771.                               Found = TRUE;
  772.                               break;
  773.                            }
  774.                         } while (Cfg->MailAddress.Next () == TRUE);
  775.  
  776.                         // Se non e' un nostro point (Found == FALSE) azzera il numero
  777.                         // di point per inviare il messaggio direttamente al boss.
  778.                         if (Found == FALSE)
  779.                            ToAddress.Point = 0;
  780.                      }
  781.  
  782.                      // Bisogna sempre avere l'indirizzo primario prima di creare
  783.                      // qualsiasi cosa nell'outbound.
  784.                      Cfg->MailAddress.First ();
  785. #if defined(__LINUX__)
  786. #else
  787.                      // Costruisce il nome file .xpr da creare nell'outbound opportuna.
  788.                      if (ToAddress.Zone == 0 || Cfg->MailAddress.Zone == ToAddress.Zone) {
  789.                         if (ToAddress.Point != 0) {
  790.                            sprintf (PktFile, "%s\\%04x%04x.pnt", Outbound, ToAddress.Net, ToAddress.Node);
  791.                            mkdir (PktFile);
  792.                            sprintf (PktFile, "%s\\%04x%04x.pnt\\%08x.xpr", Outbound, ToAddress.Net, ToAddress.Node, ToAddress.Point);
  793.                         }
  794.                         else
  795.                            sprintf (PktFile, "%s\\%04x%04x.xpr", Outbound, ToAddress.Net, ToAddress.Node);
  796.                      }
  797.                      else {
  798.                         sprintf (PktFile, "%s.%03x", Outbound, ToAddress.Zone);
  799.                         mkdir (PktFile);
  800.                         if (ToAddress.Point != 0) {
  801.                            sprintf (PktFile, "%s.%03x\\%04x%04x.pnt", Outbound, ToAddress.Zone, ToAddress.Net, ToAddress.Node);
  802.                            mkdir (PktFile);
  803.                            sprintf (PktFile, "%s.%03x\\%04x%04x.pnt\\%08x.xpr", Outbound, ToAddress.Zone, ToAddress.Net, ToAddress.Node, ToAddress.Point);
  804.                         }
  805.                         else
  806.                            sprintf (PktFile, "%s.%03x\\%04x%04x.xpr", Outbound, ToAddress.Zone, ToAddress.Net, ToAddress.Node);
  807.                      }
  808. #endif
  809.                      strcpy (Attach, PktFile);
  810.  
  811.                      if (Msg->Crash == TRUE) {
  812.                         strcpy (&PktFile[strlen (PktFile) - 3], "cut");
  813.                         strcpy (&Attach[strlen (Attach) - 3], "clo");
  814.                      }
  815.                      else if (Msg->Direct == TRUE) {
  816.                         strcpy (&PktFile[strlen (PktFile) - 3], "dut");
  817.                         strcpy (&Attach[strlen (Attach) - 3], "dlo");
  818.                      }
  819.                      else if (Msg->Hold == TRUE) {
  820.                         strcpy (&PktFile[strlen (PktFile) - 3], "hut");
  821.                         strcpy (&Attach[strlen (Attach) - 3], "hlo");
  822.                      }
  823.                      else
  824.                         strcpy (&Attach[strlen (Attach) - 3], "flo");
  825.  
  826.                      // Se il file non esiste, allora cerca la password di pacchetto
  827.                      // definita per il nodo di destinazione
  828.                      if (stat (Temp, &statbuf) != 0) {
  829.                         if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  830.                            if (Nodes->Read (Packet->ToAddress) == TRUE)
  831.                               strcpy (Packet->Password, Nodes->OutPktPwd);
  832.                            delete Nodes;
  833.                            Nodes = NULL;
  834.                         }
  835.                      }
  836.  
  837.                      // Apre il pacchetto .xpr senza effettuare lo scan dei messaggi
  838.                      // e aggiunge il messaggio in coda.
  839.                      if (Packet->Open (PktFile, FALSE) == TRUE) {
  840.                         Packet->Add (Msg);
  841.                         Sent++;
  842.                      }
  843.  
  844.                      if (Msg->FileAttach == TRUE) {
  845.                         if ((fp = fopen (AdjustPath (Attach), "at")) != NULL) {
  846.                            strcpy (PktFile, Msg->Subject);
  847.                            if ((p = strtok (PktFile, " ,;")) != NULL)
  848.                               do {
  849.                                  fprintf (fp, "%s\n", p);
  850.                                  if (Log != NULL)
  851.                                     Log->Write ("+  Sending attach %s to %s", p, Packet->ToAddress);
  852.                               } while ((p = strtok (NULL, " ,;")) != NULL);
  853.                            fclose (fp);
  854.                         }
  855.                      }
  856.  
  857.                      delete Packet;
  858.                   }
  859.                }
  860.  
  861.                if (Msg->KillSent == TRUE)
  862.                   Msg->Delete (Number);
  863.                else {
  864.                   Msg->Sent = TRUE;
  865.                   Msg->WriteHeader (Number);
  866.                }
  867.             }
  868.          }
  869.       } while (Msg->Next (Number) == TRUE);
  870.  
  871.       if (Log != NULL)
  872.          Log->Write (":  Packed=%lu", Sent);
  873.  
  874.       if (Status != NULL)
  875.          Status->Clear ();
  876.  
  877.       Msg->UnLock ();
  878.       delete Msg;
  879.       Msg = NULL;
  880.    }
  881.  
  882. #if !defined(__POINT__)
  883.    if (AreaMgr != NULL)
  884.       delete AreaMgr;
  885. #endif
  886. }
  887.  
  888. /*
  889. VOID TMailProcessor::ExportNetMail (VOID)
  890. {
  891.    FILE *fp;
  892.    USHORT OurPoint, FoundIntl;
  893.    CHAR *Text, *Base, PktFile[128], Attach[128], *p;
  894.    ULONG Number, Sent, Msgn;
  895.    struct stat statbuf;
  896.    class TAddress Address, FromAddr, ToAddr;
  897. #if !defined(__POINT__)
  898.    class TAreaManager *AreaMgr;
  899. #endif
  900.  
  901.    if (Output != NULL)
  902.       Output->Clear ();
  903.  
  904.    strcpy (Outbound, Cfg->Outbound);
  905.    if (Outbound[strlen (Outbound) - 1] == '\\' || Outbound[strlen (Outbound) - 1] == '/')
  906.       Outbound[strlen (Outbound) - 1] = '\0';
  907.  
  908.    Msg = NULL;
  909.    Base = "???";
  910.    if (Cfg->NetMailStorage == ST_JAM) {
  911.       Msg = new JAM (Cfg->NetMailPath);
  912.       Base = "JAM";
  913.    }
  914.    else if (Cfg->NetMailStorage == ST_SQUISH) {
  915.       Msg = new SQUISH (Cfg->NetMailPath);
  916.       Base = "Squish<tm>";
  917.    }
  918.    else if (Cfg->NetMailStorage == ST_FIDO) {
  919.       Msg = new FIDOSDM (Cfg->NetMailPath);
  920.       Base = "Fido *.MSG";
  921.    }
  922.    else if (Cfg->NetMailStorage == ST_ADEPT) {
  923.       Msg = new ADEPT (Cfg->NetMailPath);
  924.       Base = "AdeptXBBS";
  925.    }
  926.    else if (Cfg->NetMailStorage == ST_HUDSON) {
  927.       Msg = new HUDSON (Cfg->HudsonPath, (UCHAR)Cfg->NetMailBoard);
  928.       Base = "Hudson";
  929.    }
  930.  
  931. #if !defined(__POINT__)
  932.    if ((AreaMgr = new TAreaManager) != NULL) {
  933.       AreaMgr->Cfg = Cfg;
  934.       AreaMgr->Log = Log;
  935.    }
  936. #endif
  937.  
  938.    if (Msg != NULL) {
  939.       Msg->Lock (0L);
  940.       Sent = 0L;
  941.  
  942.       if (Log != NULL)
  943.          Log->Write ("#Packing from %s (%lu msgs)", Cfg->NetMailPath, Msg->Number ());
  944.  
  945.       if (Status != NULL) {
  946.          Status->Clear ();
  947.          Status->SetLine (0, "Exporting from %s", Cfg->NetMailPath);
  948.       }
  949.  
  950.       Number = Msg->Lowest ();
  951.       do {
  952.          if (Msg->Read (Number, MAX_LINE_LENGTH) == TRUE) {
  953.             Msgn = Msg->UidToMsgn (Number);
  954.             if (Status != NULL && (Msgn % 10L) == 0L)
  955.                Status->SetLine (1, "   %lu / %lu", Msgn, Msg->Number ());
  956.  
  957.             Address.Clear ();
  958.             Address.Parse (Msg->ToAddress);
  959.             if (Cfg->MailAddress.First () == TRUE && Address.Zone == 0)
  960.                Address.Zone = Cfg->MailAddress.Zone;
  961.  
  962.             FoundIntl = FALSE;
  963.             if ((Text = (PSZ)Msg->Text.First ()) != NULL)
  964.                do {
  965.                   if (Text[0] == '\0')
  966.                      continue;
  967.                   if (!strncmp (Text, "\001INTL ", 6)) {
  968.                      FoundIntl = TRUE;
  969.                      if (Msg->Local == FALSE || Cfg->ReplaceTear == FALSE)
  970.                         break;
  971.                   }
  972.                   if (Msg->Local == TRUE && Cfg->ReplaceTear == TRUE) {
  973.                      if (!strncmp (Text, "---", 3)) {
  974.                         sprintf (Temp, "--- %s", Cfg->TearLine);
  975.                         strsrep (Temp, "%1", VERSION);
  976.                         Msg->Text.Replace (Temp, (USHORT)(strlen (Temp) + 1));
  977.                      }
  978.                   }
  979.                   else if (Text[0] != 0x01)
  980.                      break;
  981.                } while ((Text = (PSZ)Msg->Text.Next ()) != NULL);
  982.  
  983.             // Controlla che non si tratti di un messaggio indirizzato ad uno dei
  984.             // nostri aka e nel contempo se e' indirizzato ad un nostro point
  985.             OurPoint = FALSE;
  986.             if (Msg->Sent == FALSE && Cfg->MailAddress.First () == TRUE)
  987.                do {
  988.                   if (Cfg->MailAddress.Zone == Address.Zone || Address.Zone == 0) {
  989.                      if (Cfg->MailAddress.Net == Address.Net && Cfg->MailAddress.Node == Address.Node) {
  990.                         // Ormai e' sicuro che si tratta di un nostro point
  991.                         OurPoint = TRUE;
  992.                         if (Cfg->MailAddress.Point != 0 && Cfg->MailAddress.Point == Address.Point)
  993.                            Msg->Sent = TRUE;
  994.                      }
  995.                   }
  996.                } while (Cfg->MailAddress.Next () == TRUE);
  997.  
  998.             if (Msg->Sent == FALSE && OurPoint == TRUE) {
  999.                if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  1000.                   if (Nodes->First () == TRUE)
  1001.                      do {
  1002.                         if (Nodes->Zone == Address.Zone && !stricmp (Msg->To, Nodes->SysopName) && Nodes->RemapMail == TRUE) {
  1003.                            if (Log != NULL)
  1004.                               Log->Write ("#  Remap %s => %s", Address.String, Nodes->Address);
  1005.                            sprintf (Temp, "\001PointMap %s => %s", Address.String, Nodes->Address);
  1006.                            Msg->Text.Add (Temp);
  1007.                            Address.Parse (Nodes->Address);
  1008.                            break;
  1009.                         }
  1010.                      } while (Nodes->Next () == TRUE);
  1011.                   delete Nodes;
  1012.                   Nodes = NULL;
  1013.                }
  1014.  
  1015.                if (Cfg->MailAddress.First () == TRUE)
  1016.                   do {
  1017.                      if (Cfg->MailAddress.Zone == Address.Zone || Address.Zone == 0) {
  1018.                         if (Cfg->MailAddress.Net == Address.Net && Cfg->MailAddress.Node == Address.Node && Cfg->MailAddress.Point == Address.Point)
  1019.                            Msg->Sent = TRUE;
  1020.                      }
  1021.                   } while (Cfg->MailAddress.Next () == TRUE);
  1022.             }
  1023.  
  1024.             if (Msg->Sent == FALSE) {
  1025.                // Se non si tratta di un nostro point, il messaggio viene indirizzato
  1026.                // sempre al boss, cioe' all'indirizzo con point = 0
  1027.                if (OurPoint == FALSE) {
  1028.                   Address.Point = 0;
  1029.                   Address.Add ();
  1030.                   Address.First ();
  1031.                }
  1032.  
  1033.                if (Status != NULL && (Msgn % 10L) != 0L)
  1034.                   Status->SetLine (1, "   %lu / %lu", Msgn, Msg->Number ());
  1035.  
  1036.                if (Output != NULL) {
  1037.                   sprintf (Display, "%6lu %-22.22s %-12.12s ", Msg->UidToMsgn (Number), "Netmail", Base);
  1038.                   if (OurPoint == TRUE)
  1039.                      strcat (Display, Msg->ToAddress);
  1040.                   else
  1041.                      strcat (Display, Address.String);
  1042.                   Output->Add (Display);
  1043.                }
  1044.  
  1045.                Cfg->MailAddress.First ();
  1046.                if (Address.Zone == 0 || Cfg->MailAddress.Zone == Address.Zone) {
  1047.                   if (Address.Point != 0) {
  1048. #if defined(__LINUX__)
  1049.                      sprintf (PktFile, "%s/%04x%04x.pnt", Outbound, Address.Net, Address.Node);
  1050.                      mkdir (PktFile, 0666);
  1051.                      sprintf (PktFile, "%s/%04x%04x.pnt/%08x.xpr", Outbound, Address.Net, Address.Node, Address.Point);
  1052. #else
  1053.                      sprintf (PktFile, "%s\\%04x%04x.pnt", Outbound, Address.Net, Address.Node);
  1054.                      mkdir (PktFile);
  1055.                      sprintf (PktFile, "%s\\%04x%04x.pnt\\%08x.xpr", Outbound, Address.Net, Address.Node, Address.Point);
  1056. #endif
  1057.                   }
  1058.                   else
  1059. #if defined(__LINUX__)
  1060.                      sprintf (PktFile, "%s/%04x%04x.xpr", Outbound, Address.Net, Address.Node);
  1061. #else
  1062.                      sprintf (PktFile, "%s\\%04x%04x.xpr", Outbound, Address.Net, Address.Node);
  1063. #endif
  1064.                }
  1065.                else {
  1066.                   sprintf (PktFile, "%s.%03x", Outbound, Address.Zone);
  1067. #if defined(__LINUX__)
  1068.                   mkdir (PktFile, 0666);
  1069. #else
  1070.                   mkdir (PktFile);
  1071. #endif
  1072.                   if (Address.Point != 0) {
  1073. #if defined(__LINUX__)
  1074.                      sprintf (PktFile, "%s.%03x/%04x%04x.pnt", Outbound, Address.Zone, Address.Net, Address.Node);
  1075.                      mkdir (PktFile, 0666);
  1076.                      sprintf (PktFile, "%s.%03x/%04x%04x.pnt/%08x.xpr", Outbound, Address.Zone, Address.Net, Address.Node, Address.Point);
  1077. #else
  1078.                      sprintf (PktFile, "%s.%03x\\%04x%04x.pnt", Outbound, Address.Zone, Address.Net, Address.Node);
  1079.                      mkdir (PktFile);
  1080.                      sprintf (PktFile, "%s.%03x\\%04x%04x.pnt\\%08x.xpr", Outbound, Address.Zone, Address.Net, Address.Node, Address.Point);
  1081. #endif
  1082.                   }
  1083.                   else
  1084. #if defined(__LINUX__)
  1085.                      sprintf (PktFile, "%s.%03x/%04x%04x.xpr", Outbound, Address.Zone, Address.Net, Address.Node);
  1086. #else
  1087.                      sprintf (PktFile, "%s.%03x\\%04x%04x.xpr", Outbound, Address.Zone, Address.Net, Address.Node);
  1088. #endif
  1089.                }
  1090.  
  1091.                if (Msg->Crash == TRUE)
  1092.                   strcpy (&PktFile[strlen (PktFile) - 3], "cut");
  1093.                else if (Msg->Direct == TRUE)
  1094.                   strcpy (&PktFile[strlen (PktFile) - 3], "dut");
  1095.                else if (Msg->Hold == TRUE)
  1096.                   strcpy (&PktFile[strlen (PktFile) - 3], "hut");
  1097.  
  1098.                if ((Packet = new PACKET) != NULL) {
  1099.                   strcpy (Packet->ToAddress, Address.String);
  1100.                   ToAddr.Parse (Packet->ToAddress);
  1101.                   if (ToAddr.Zone == 0) {
  1102.                      ToAddr.Zone = Cfg->MailAddress.Zone;
  1103.                      ToAddr.Add ();
  1104.                      ToAddr.First ();
  1105.                   }
  1106.  
  1107.                   if (Msg->FileAttach == TRUE) {
  1108.                      if (Address.Zone == 0 || Cfg->MailAddress.Zone == Address.Zone) {
  1109.                         if (Address.Point != 0) {
  1110.                            sprintf (Attach, "%s\\%04x%04x.pnt", Outbound, Address.Net, Address.Node);
  1111. #if defined(__LINUX__)
  1112.                            mkdir (AdjustPath (Attach), 0666);
  1113. #else
  1114.                            mkdir (AdjustPath (Attach));
  1115. #endif
  1116.                            sprintf (Attach, "%s\\%04x%04x.pnt\\%08x.flo", Outbound, Address.Net, Address.Node, Address.Point);
  1117.                         }
  1118.                         else
  1119.                            sprintf (Attach, "%s\\%04x%04x.flo", Outbound, Address.Net, Address.Node);
  1120.                      }
  1121.                      else {
  1122.                         sprintf (Attach, "%s.%03x", Outbound, Address.Zone);
  1123. #if defined(__LINUX__)
  1124.                         mkdir (AdjustPath (Attach), 0666);
  1125. #else
  1126.                         mkdir (AdjustPath (Attach));
  1127. #endif
  1128.                         if (Address.Point != 0) {
  1129.                            sprintf (Attach, "%s.%03x\\%04x%04x.flo", Outbound, Address.Zone, Address.Net, Address.Node);
  1130. #if defined(__LINUX__)
  1131.                            mkdir (AdjustPath (Attach), 0666);
  1132. #else
  1133.                            mkdir (AdjustPath (Attach));
  1134. #endif
  1135.                            sprintf (Attach, "%s.%03x\\%04x%04x.pnt\\%08x.flo", Outbound, Address.Zone, Address.Net, Address.Node, Address.Point);
  1136.                         }
  1137.                         else
  1138.                            sprintf (Attach, "%s.%03x\\%04x%04x.flo", Outbound, Address.Zone, Address.Net, Address.Node);
  1139.                      }
  1140.  
  1141.                      if (Msg->Crash == TRUE)
  1142.                         strcpy (&Attach[strlen (Attach) - 3], "clo");
  1143.                      else if (Msg->Direct == TRUE)
  1144.                         strcpy (&Attach[strlen (Attach) - 3], "dlo");
  1145.                      else if (Msg->Hold == TRUE)
  1146.                         strcpy (&Attach[strlen (Attach) - 3], "hlo");
  1147.  
  1148.                      if ((fp = fopen (AdjustPath (Attach), "at")) != NULL) {
  1149.                         strcpy (Attach, Msg->Subject);
  1150.                         if ((p = strtok (Attach, " ,;")) != NULL)
  1151.                            do {
  1152.                               fprintf (fp, "%s\n", p);
  1153.                               if (Log != NULL)
  1154.                                  Log->Write ("+  Sending attach %s to %s", p, Address.String);
  1155.                            } while ((p = strtok (NULL, " ,;")) != NULL);
  1156.                         fclose (fp);
  1157.                      }
  1158.                   }
  1159.  
  1160.                   strcpy (Packet->FromAddress, Msg->FromAddress);
  1161.                   FromAddr.Parse (Packet->FromAddress);
  1162.                   if (FromAddr.Zone == 0) {
  1163.                      FromAddr.Zone = Cfg->MailAddress.Zone;
  1164.                      FromAddr.Add ();
  1165.                      FromAddr.First ();
  1166.                   }
  1167.  
  1168.                   if ((Cfg->ForceIntl == TRUE || FromAddr.Zone != ToAddr.Zone) && FoundIntl == FALSE) {
  1169.                      sprintf (Temp, "\001INTL %u:%u/%u %u:%u/%u", ToAddr.Zone, ToAddr.Net, ToAddr.Node, FromAddr.Zone, FromAddr.Net, FromAddr.Node);
  1170.                      if ((Text = (PSZ)Msg->Text.First ()) != NULL) {
  1171.                         Msg->Text.Insert (Temp, (USHORT)(strlen (Temp) + 1));
  1172.                         Msg->Text.Insert (Text, (USHORT)(strlen (Text) + 1));
  1173.                         Msg->Text.First ();
  1174.                         Msg->Text.Remove ();
  1175.                      }
  1176.                      else
  1177.                         Msg->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1178.                   }
  1179.  
  1180.                   // Se il file non esiste, allora cerca la password di pacchetto
  1181.                   // definita per il nodo di destinazione
  1182.                   if (stat (Temp, &statbuf) != 0) {
  1183.                      if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  1184.                         if (Nodes->Read (Packet->ToAddress) == TRUE)
  1185.                            strcpy (Packet->Password, Nodes->OutPktPwd);
  1186.                         delete Nodes;
  1187.                         Nodes = NULL;
  1188.                      }
  1189.                   }
  1190.  
  1191.                   // Apre il pacchetto .xpr senza effettuare lo scan dei messaggi
  1192.                   if (Packet->Open (PktFile, FALSE) == TRUE) {
  1193.                      Packet->Add (Msg);
  1194.                      Sent++;
  1195.                   }
  1196.  
  1197.                   if (Cfg->KeepNetMail == FALSE)
  1198.                      Msg->Delete (Number);
  1199.  
  1200.                   delete Packet;
  1201.                   Packet = NULL;
  1202.                }
  1203.  
  1204.                Msg->Sent = TRUE;
  1205.                Msg->WriteHeader (Number);
  1206.             }
  1207. #if !defined(__POINT__)
  1208.             else if (Msg->Received == FALSE) {
  1209.                if (!stricmp (Msg->To, "Areafix") || !stricmp (Msg->To, "AreaMgr")) {
  1210.                   if (AreaMgr != NULL) {
  1211.                      Msg->Received = TRUE;
  1212.                      Msg->WriteHeader (Number);
  1213.  
  1214.                      AreaMgr->Msg = Msg;
  1215.                      AreaMgr->ProcessAreafix ();
  1216.                   }
  1217.                }
  1218.                else if (!stricmp (Msg->To, "Raid")) {
  1219.                   if (AreaMgr != NULL) {
  1220.                      Msg->Received = TRUE;
  1221.                      Msg->WriteHeader (Number);
  1222.  
  1223.                      AreaMgr->Msg = Msg;
  1224.                      AreaMgr->ProcessRaid ();
  1225.                   }
  1226.                }
  1227.             }
  1228. #endif
  1229.          }
  1230.       } while (Msg->Next (Number) == TRUE);
  1231.  
  1232.       if (Log != NULL)
  1233.          Log->Write (":  Packed=%lu", Sent);
  1234.  
  1235.       if (Status != NULL)
  1236.          Status->Clear ();
  1237.  
  1238.       Msg->UnLock ();
  1239.       delete Msg;
  1240.       Msg = NULL;
  1241.    }
  1242.  
  1243. #if !defined(__POINT__)
  1244.    if (AreaMgr != NULL)
  1245.       delete AreaMgr;
  1246. #endif
  1247. }
  1248. */
  1249.  
  1250. VOID TMailProcessor::Change (VOID)
  1251. {
  1252.    FILE *fp;
  1253.    DIR *dir;
  1254.    USHORT Zone, Net, Node, Point, CheckNet;
  1255.    CHAR *p, FromFlag, ToFlag, Lookup[32], *Text;
  1256.    CHAR FromStr[16], ToStr[16];
  1257.    class TAddress Addr;
  1258.    class TCollection Attach;
  1259.    struct dirent *ent;
  1260.  
  1261.    Cfg->MailAddress.First ();
  1262.    Zone = Cfg->MailAddress.Zone;
  1263.    Net = Cfg->MailAddress.Net;
  1264.    Node = Cfg->MailAddress.Node;
  1265.    Point = 0;
  1266.  
  1267.    FromFlag = 'h';
  1268.    if ((p = strtok (NULL, " ")) != NULL) {
  1269.       if (!stricmp (p, "hold") || !stricmp (p, "crash") || !stricmp (p, "direct") || !stricmp (p, "normal")) {
  1270.          if ((FromFlag = (CHAR)tolower (*p)) == 'n')
  1271.             FromFlag = 'f';
  1272.       }
  1273.       strcpy (FromStr, strupr (p));
  1274.    }
  1275.  
  1276.    ToFlag = 'h';
  1277.    if ((p = strtok (NULL, " ")) != NULL) {
  1278.       if (!stricmp (p, "hold") || !stricmp (p, "crash") || !stricmp (p, "direct") || !stricmp (p, "normal")) {
  1279.          if ((ToFlag = (CHAR)tolower (*p)) == 'n')
  1280.             ToFlag = 'f';
  1281.       }
  1282.       strcpy (ToStr, strupr (p));
  1283.    }
  1284.  
  1285.    if ((p = strtok (NULL, "")) != NULL)
  1286.       strcpy (Line, p);
  1287.  
  1288.    while ((p = strtok (Line, " ")) != NULL) {
  1289.       Addr.Clear ();
  1290.       Addr.Parse (p);
  1291.  
  1292.       if ((p = strtok (NULL, "")) != NULL)
  1293.          strcpy (Line, p);
  1294.       else
  1295.          Line[0] = '\0';
  1296.  
  1297.       if (Addr.Zone != 0)
  1298.          Zone = Addr.Zone;
  1299.       if (Addr.Net != 0)
  1300.          Net = Addr.Net;
  1301.       if (Addr.Node != 0)
  1302.          Node = Addr.Node;
  1303.       Point = Addr.Point;
  1304.  
  1305.       // Cambio dei flags per tutti i point
  1306.       if (Point == 65535U && Net != 65535U && Node != 65535U) {
  1307.          if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1308.             sprintf (Temp, "%s\\%04x%04x.pnt", Outbound, Net, Node);
  1309.          else
  1310.             sprintf (Temp, "%s.%03x\\%04x%04x.pnt", Outbound, Zone, Net, Node);
  1311.          if ((dir = opendir (Temp)) != NULL) {
  1312.             while ((ent = readdir (dir)) != NULL) {
  1313.                strlwr (ent->d_name);
  1314.                sprintf (Name, ".%clo", FromFlag);
  1315.                if (strstr (ent->d_name, Name) != NULL) {
  1316.                   sscanf (ent->d_name, "%08hx", &Point);
  1317.  
  1318.                   Addr.Zone = Zone;
  1319.                   Addr.Net = Net;
  1320.                   Addr.Node = Node;
  1321.                   Addr.Point = Point;
  1322.                   Addr.Add ();
  1323.                   Addr.First ();
  1324.                   if (Log != NULL)
  1325.                      Log->Write (":Changing %s from %s to %s", Addr.String, FromStr, ToStr);
  1326.  
  1327.                   // Legge i file attach da cambiare di stato.
  1328.                   Attach.Clear ();
  1329.                   if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1330.                      sprintf (Name, "%s\\%04x%04x.pnt\\%08x.%clo", Outbound, Net, Node, Point, FromFlag);
  1331.                   else
  1332.                      sprintf (Name, "%s.%03x\\%04x%04x.pnt\\%08x.%clo", Outbound, Zone, Net, Node, Point, FromFlag);
  1333.                   if ((fp = fopen (Name, "rt")) != NULL) {
  1334.                      while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL)
  1335.                         Attach.Add (Temp);
  1336.                      fclose (fp);
  1337.                      unlink (Name);
  1338.                   }
  1339.  
  1340.                   // Legge il file attach che ricevera' gli attachment da cambiare
  1341.                   // di stato controllando i duplicati.
  1342.                   if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1343.                      sprintf (Name, "%s\\%04x%04x.pnt\\%08x.%clo", Outbound, Net, Node, Point, ToFlag);
  1344.                   else
  1345.                      sprintf (Name, "%s.%03x\\%04x%04x.pnt\\%08x.%clo", Outbound, Zone, Net, Node, Point, ToFlag);
  1346.                   if ((fp = fopen (Name, "rt")) != NULL) {
  1347.                      while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  1348.                         if ((Text = (CHAR *)Attach.First ()) != NULL)
  1349.                            do {
  1350.                               if (!stricmp (Text, Temp))
  1351.                                  break;
  1352.                            } while ((Text = (CHAR *)Attach.Next ()) != NULL);
  1353.                         if (Text == NULL)
  1354.                            Attach.Add (Temp);
  1355.                      }
  1356.                      fclose (fp);
  1357.                      unlink (Name);
  1358.                   }
  1359.  
  1360.                   // Scrive il nuovo file attach.
  1361.                   if ((fp = fopen (Name, "wt")) != NULL) {
  1362.                      if ((Text = (CHAR *)Attach.First ()) != NULL)
  1363.                         do {
  1364.                            fprintf (fp, "%s", Text);
  1365.                         } while ((Text = (CHAR *)Attach.Next ()) != NULL);
  1366.                      fclose (fp);
  1367.                   }
  1368.                }
  1369.             }
  1370.             closedir (dir);
  1371.          }
  1372.       }
  1373.       else if (Net == 65535U || Node == 65535U) {
  1374.          CheckNet = (Net != 65535U) ? TRUE : FALSE;
  1375.          sprintf (Lookup, "%04x", Net);
  1376.          if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1377.             sprintf (Temp, "%s", Outbound);
  1378.          else
  1379.             sprintf (Temp, "%s.%03x", Outbound, Zone);
  1380.          if ((dir = opendir (Temp)) != NULL) {
  1381.             while ((ent = readdir (dir)) != NULL) {
  1382.                strlwr (ent->d_name);
  1383.                sprintf (Name, ".%clo", FromFlag);
  1384.                if (strstr (ent->d_name, Name) != NULL && (CheckNet == FALSE || !strncmp (ent->d_name, Lookup, strlen (Lookup)))) {
  1385.                   sscanf (ent->d_name, "%04hx%04hx", &Net, &Node);
  1386.  
  1387.                   Addr.Zone = Zone;
  1388.                   Addr.Net = Net;
  1389.                   Addr.Node = Node;
  1390.                   Addr.Point = Point;
  1391.                   Addr.Add ();
  1392.                   Addr.First ();
  1393.                   if (Log != NULL)
  1394.                      Log->Write (":Changing %s from %s to %s", Addr.String, FromStr, ToStr);
  1395.  
  1396.                   // Legge i file attach da cambiare di stato.
  1397.                   Attach.Clear ();
  1398.                   if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1399.                      sprintf (Name, "%s\\%04x%04x.%clo", Outbound, Net, Node, FromFlag);
  1400.                   else
  1401.                      sprintf (Name, "%s.%03x\\%04x%04x.%clo", Outbound, Zone, Net, Node, FromFlag);
  1402.                   if ((fp = fopen (Name, "rt")) != NULL) {
  1403.                      while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL)
  1404.                         Attach.Add (Temp);
  1405.                      fclose (fp);
  1406.                      unlink (Name);
  1407.                   }
  1408.  
  1409.                   // Legge il file attach che ricevera' gli attachment da cambiare
  1410.                   // di stato controllando i duplicati.
  1411.                   if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1412.                      sprintf (Name, "%s\\%04x%04x.%clo", Outbound, Net, Node, ToFlag);
  1413.                   else
  1414.                      sprintf (Name, "%s.%03x\\%04x%04x.%clo", Outbound, Zone, Net, Node, ToFlag);
  1415.                   if ((fp = fopen (Name, "rt")) != NULL) {
  1416.                      while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  1417.                         if ((Text = (CHAR *)Attach.First ()) != NULL)
  1418.                            do {
  1419.                               if (!stricmp (Text, Temp))
  1420.                                  break;
  1421.                            } while ((Text = (CHAR *)Attach.Next ()) != NULL);
  1422.                         if (Text == NULL)
  1423.                            Attach.Add (Temp);
  1424.                      }
  1425.                      fclose (fp);
  1426.                      unlink (Name);
  1427.                   }
  1428.  
  1429.                   // Scrive il nuovo file attach.
  1430.                   if ((fp = fopen (Name, "wt")) != NULL) {
  1431.                      if ((Text = (CHAR *)Attach.First ()) != NULL)
  1432.                         do {
  1433.                            fprintf (fp, "%s", Text);
  1434.                         } while ((Text = (CHAR *)Attach.Next ()) != NULL);
  1435.                      fclose (fp);
  1436.                   }
  1437.                }
  1438.             }
  1439.             closedir (dir);
  1440.          }
  1441.       }
  1442.       else {
  1443.          // Legge i file attach da cambiare di stato.
  1444.          Attach.Clear ();
  1445.          if (Zone == 0 || Cfg->MailAddress.Zone == Zone) {
  1446.             if (Point != 0)
  1447.                sprintf (Name, "%s\\%04x%04x.pnt\\%08x.%clo", Outbound, Net, Node, Point, FromFlag);
  1448.             else
  1449.                sprintf (Name, "%s\\%04x%04x.%clo", Outbound, Net, Node, FromFlag);
  1450.          }
  1451.          else {
  1452.             if (Point != 0)
  1453.                sprintf (Name, "%s.%03x\\%04x%04x.pnt\\%08x.%clo", Outbound, Zone, Net, Node, Point, FromFlag);
  1454.             else
  1455.                sprintf (Name, "%s.%03x\\%04x%04x.%clo", Outbound, Zone, Net, Node, FromFlag);
  1456.          }
  1457.          if ((fp = fopen (Name, "rt")) != NULL) {
  1458.             if (Log != NULL)
  1459.                Log->Write (":Changing %s from %s to %s", Addr.String, FromStr, ToStr);
  1460.  
  1461.             while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL)
  1462.                Attach.Add (Temp);
  1463.             fclose (fp);
  1464.             unlink (Name);
  1465.  
  1466.             // Legge il file attach che ricevera' gli attachment da cambiare
  1467.             // di stato controllando i duplicati.
  1468.             if (Zone == 0 || Cfg->MailAddress.Zone == Zone) {
  1469.                if (Point != 0)
  1470.                   sprintf (Name, "%s\\%04x%04x.pnt\\%08x.%clo", Outbound, Net, Node, Point, ToFlag);
  1471.                else
  1472.                   sprintf (Name, "%s\\%04x%04x.%clo", Outbound, Net, Node, ToFlag);
  1473.             }
  1474.             else {
  1475.                if (Point != 0)
  1476.                   sprintf (Name, "%s.%03x\\%04x%04x.pnt\\%08x.%clo", Outbound, Zone, Net, Node, Point, ToFlag);
  1477.                else
  1478.                   sprintf (Name, "%s.%03x\\%04x%04x.%clo", Outbound, Zone, Net, Node, ToFlag);
  1479.             }
  1480.             if ((fp = fopen (Name, "rt")) != NULL) {
  1481.                while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  1482.                   if ((Text = (CHAR *)Attach.First ()) != NULL)
  1483.                      do {
  1484.                         if (!stricmp (Text, Temp))
  1485.                            break;
  1486.                      } while ((Text = (CHAR *)Attach.Next ()) != NULL);
  1487.                   if (Text == NULL)
  1488.                      Attach.Add (Temp);
  1489.                }
  1490.                fclose (fp);
  1491.                unlink (Name);
  1492.             }
  1493.  
  1494.             // Scrive il nuovo file attach.
  1495.             if ((fp = fopen (Name, "wt")) != NULL) {
  1496.                if ((Text = (CHAR *)Attach.First ()) != NULL)
  1497.                   do {
  1498.                      fprintf (fp, "%s", Text);
  1499.                   } while ((Text = (CHAR *)Attach.Next ()) != NULL);
  1500.                fclose (fp);
  1501.             }
  1502.          }
  1503.       }
  1504.    }
  1505. }
  1506.  
  1507. VOID TMailProcessor::RouteTo (VOID)
  1508. {
  1509.    DIR *dir;
  1510.    int fd;
  1511.    USHORT Zone, Net, Node, Point, DoPack, CheckNet, MakeArc = TRUE;
  1512.    CHAR *p, Flag, Lookup[32], DestPath[128], FlagStr[32];
  1513.    ULONG TotalSize;
  1514.    PKT2HDR pktHdr;
  1515.    class TAddress Addr, DestAddr;
  1516.    class TPacker *Packer;
  1517.    class TNodes *Nodes;
  1518.    struct dirent *ent;
  1519.    struct stat statbuf;
  1520.  
  1521.    Cfg->MailAddress.First ();
  1522.    Zone = Cfg->MailAddress.Zone;
  1523.    Net = Cfg->MailAddress.Net;
  1524.    Node = Cfg->MailAddress.Node;
  1525.  
  1526.    DoPack = FALSE;
  1527.    DestPath[0] = '\0';
  1528.    TotalSize = 0L;
  1529.  
  1530.    Flag = 'H';
  1531.    if ((p = strtok (NULL, " ")) != NULL) {
  1532.       if (!stricmp (p, "hold") || !stricmp (p, "crash") || !stricmp (p, "direct") || !stricmp (p, "normal")) {
  1533.          if ((Flag = (CHAR)toupper (*p)) == 'N')
  1534.             Flag = 'F';
  1535.       }
  1536.       strcpy (FlagStr, strupr (p));
  1537.    }
  1538.  
  1539.    if ((p = strtok (NULL, "")) != NULL)
  1540.       strcpy (Line, p);
  1541.  
  1542.    if ((p = strtok (Line, " ")) != NULL) {
  1543.       Addr.Parse (p);
  1544.       if ((p = strtok (NULL, "")) != NULL)
  1545.          strcpy (Line, p);
  1546.       else
  1547.          Line[0] = '\0';
  1548.  
  1549.       Point = 0;
  1550.       if (Addr.Zone != 0)
  1551.          Zone = Addr.Zone;
  1552.       if (Addr.Net != 0)
  1553.          Net = Addr.Net;
  1554.       Node = Addr.Node;
  1555.       Point = Addr.Point;
  1556.  
  1557.       if (Zone == 0 || Cfg->MailAddress.Zone == Zone) {
  1558.          if (Point != 0)
  1559.             sprintf (DestPath, "%s\\%04x%04x.pnt\\", Outbound, Net, Node);
  1560.          else
  1561.             sprintf (DestPath, "%s\\", Outbound);
  1562.       }
  1563.       else {
  1564.          if (Point != 0)
  1565.             sprintf (DestPath, "%s.%03x\\%04x%04x.pnt\\", Outbound, Zone, Net, Node);
  1566.          else
  1567.             sprintf (DestPath, "%s.%03x\\", Outbound, Zone);
  1568.       }
  1569.  
  1570.       AdjustPath (DestPath);
  1571.       DestAddr.Add (Zone, Net, Node, Point);
  1572.       DestAddr.First ();
  1573.  
  1574.       if (Point != 0)
  1575.          sprintf (Temp, "%s%08x.xpr", DestPath, Point);
  1576.       else
  1577.          sprintf (Temp, "%s%04x%04x.xpr", DestPath, Net, Node);
  1578.  
  1579.       if ((fd = sopen (Temp, O_RDONLY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1580.          close (fd);
  1581.  
  1582.          if (MakeArc == TRUE) {
  1583.             MakeArcMailName (DestAddr.String, Flag);
  1584.             MakeArc = FALSE;
  1585.          }
  1586.  
  1587.          do {
  1588.             sprintf (Name, "%s%08lx.pkt", DestPath, time (NULL));
  1589.          } while (rename (Temp, Name) != 0);
  1590.  
  1591.          if (stat (Name, &statbuf) == 0)
  1592.             TotalSize += statbuf.st_size;
  1593.          DoPack = TRUE;
  1594.       }
  1595.    }
  1596.  
  1597.    while ((p = strtok (Line, " ")) != NULL) {
  1598.       Addr.Parse (p);
  1599.       if ((p = strtok (NULL, "")) != NULL)
  1600.          strcpy (Line, p);
  1601.       else
  1602.          Line[0] = '\0';
  1603.  
  1604.       if (Addr.Zone != 0)
  1605.          Zone = Addr.Zone;
  1606.       if (Addr.Net != 0)
  1607.          Net = Addr.Net;
  1608.       Node = Addr.Node;
  1609.       Point = Addr.Point;
  1610.  
  1611.       // Controlla se e' stato comando di compattare la posta di
  1612.       // tutti i point (send-to 2:332/402.All).
  1613.       if (Point == 65535U && Net != 65535U && Node != 65535U) {
  1614.          if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1615.             sprintf (Temp, "%s\\%04x%04x.pnt", Outbound, Net, Node);
  1616.          else
  1617.             sprintf (Temp, "%s.%03x\\%04x%04x.pnt", Outbound, Zone, Net, Node);
  1618.          AdjustPath (Temp);
  1619.          if ((dir = opendir (Temp)) != NULL) {
  1620.             while ((ent = readdir (dir)) != NULL) {
  1621.                strlwr (ent->d_name);
  1622.                if (strstr (ent->d_name, ".xpr") != NULL) {
  1623.                   sscanf (ent->d_name, "%08hx", &Point);
  1624.  
  1625.                   if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1626.                      sprintf (Temp, "%s\\%04x%04x.pnt\\%08lx.xpr", Outbound, Net, Node, Point);
  1627.                   else
  1628.                      sprintf (Temp, "%s.%03x\\%04x%04x.pnt\\%08lx.xpr", Outbound, Zone, Net, Node, Point);
  1629.  
  1630.                   AdjustPath (Temp);
  1631.                   if ((fd = sopen (Temp, O_RDWR|O_BINARY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1632.                      if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  1633.                         // Azzera il campo password per evitare di propagare verso un altro
  1634.                         // nodo una password errata.
  1635.                         memset (pktHdr.Password, 0, sizeof (pktHdr.Password));
  1636.                         if (Nodes->Read (DestAddr.Zone, DestAddr.Net, DestAddr.Node, DestAddr.Point) == TRUE) {
  1637.                            read (fd, &pktHdr, sizeof (pktHdr));
  1638.                            pktHdr.DestZone = pktHdr.DestZone2 = DestAddr.Zone;
  1639.                            pktHdr.DestNet = DestAddr.Net;
  1640.                            pktHdr.DestNode = DestAddr.Node;
  1641.                            pktHdr.DestPoint = DestAddr.Point;
  1642.                            // Copia la password nuova con un memcpy per evitare di copiare anche
  1643.                            // il terminatore che non e' ammesso. La verifica sulla lunghezza viene
  1644.                            // fatta perche' e' probabile che un memcpy di 0 bytes copi in realta' 64k
  1645.                            // di dati con certi compilatori.
  1646.                            if (strlen (Nodes->OutPktPwd) > 0)
  1647.                               memcpy (pktHdr.Password, Nodes->OutPktPwd, strlen (Nodes->OutPktPwd));
  1648.                            lseek (fd, 0L, SEEK_SET);
  1649.                            write (fd, &pktHdr, sizeof (pktHdr));
  1650.                         }
  1651.                         delete Nodes;
  1652.                         Nodes = NULL;
  1653.                      }
  1654.                      close (fd);
  1655.                      if (MakeArc == TRUE) {
  1656.                         MakeArcMailName (DestAddr.String, Flag);
  1657.                         MakeArc = FALSE;
  1658.                      }
  1659.                      do {
  1660.                         sprintf (Name, "%s%08lx.pkt", DestPath, time (NULL));
  1661.                      } while (rename (Temp, Name) != 0);
  1662.  
  1663.                      if (stat (Name, &statbuf) == 0)
  1664.                         TotalSize += statbuf.st_size;
  1665.                      DoPack = TRUE;
  1666.                   }
  1667.                }
  1668.             }
  1669.             closedir (dir);
  1670.          }
  1671.       }
  1672.       // Controlla se e' stato comando di compattare la posta di
  1673.       // tutta una zona (send-to all 2:All) o di un solo net (send-to 2:332/All).
  1674.       else if (Net == 65535U || Node == 65535U) {
  1675.          CheckNet = (Net != 65535U) ? TRUE : FALSE;
  1676.          sprintf (Lookup, "%04x", Net);
  1677.          if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1678.             sprintf (Temp, "%s", Outbound);
  1679.          else
  1680.             sprintf (Temp, "%s.%03x", Outbound, Zone);
  1681.          AdjustPath (Temp);
  1682.          if ((dir = opendir (Temp)) != NULL) {
  1683.             while ((ent = readdir (dir)) != NULL) {
  1684.                strlwr (ent->d_name);
  1685.                if (strstr (ent->d_name, ".xpr") != NULL) {
  1686.                   DoPack = FALSE;
  1687.                   if (CheckNet == FALSE) {
  1688.                      sscanf (ent->d_name, "%04hx%04hx", &Net, &Node);
  1689.                      DoPack = TRUE;
  1690.                   }
  1691.                   else if (!strncmp (ent->d_name, Lookup, strlen (Lookup))) {
  1692.                      sscanf (ent->d_name, "%04hx%04hx", &Net, &Node);
  1693.                      DoPack = TRUE;
  1694.                   }
  1695.  
  1696.                   if (DoPack == TRUE) {
  1697.                      if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1698.                         sprintf (Temp, "%s\\%04x%04x.xpr", Outbound, Net, Node);
  1699.                      else
  1700.                         sprintf (Temp, "%s.%03x\\%04x%04x.xpr", Outbound, Zone, Net, Node);
  1701.  
  1702.                      AdjustPath (Temp);
  1703.                      if ((fd = sopen (Temp, O_RDWR|O_BINARY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1704.                         if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  1705.                            memset (pktHdr.Password, 0, sizeof (pktHdr.Password));
  1706.                            if (Nodes->Read (DestAddr.Zone, DestAddr.Net, DestAddr.Node, DestAddr.Point) == TRUE) {
  1707.                               read (fd, &pktHdr, sizeof (pktHdr));
  1708.                               pktHdr.DestZone = pktHdr.DestZone2 = DestAddr.Zone;
  1709.                               pktHdr.DestNet = DestAddr.Net;
  1710.                               pktHdr.DestNode = DestAddr.Node;
  1711.                               pktHdr.DestPoint = DestAddr.Point;
  1712.                               if (strlen (Nodes->OutPktPwd) > 0)
  1713.                                  memcpy (pktHdr.Password, Nodes->OutPktPwd, strlen (Nodes->OutPktPwd));
  1714.                               lseek (fd, 0L, SEEK_SET);
  1715.                               write (fd, &pktHdr, sizeof (pktHdr));
  1716.                            }
  1717.                            delete Nodes;
  1718.                            Nodes = NULL;
  1719.                         }
  1720.                         close (fd);
  1721.                         if (MakeArc == TRUE) {
  1722.                            MakeArcMailName (DestAddr.String, Flag);
  1723.                            MakeArc = FALSE;
  1724.                         }
  1725.                         do {
  1726.                            sprintf (Name, "%s%08lx.pkt", DestPath, time (NULL));
  1727.                         } while (rename (Temp, Name) != 0);
  1728.  
  1729.                         if (stat (Name, &statbuf) == 0)
  1730.                            TotalSize += statbuf.st_size;
  1731.                      }
  1732.                   }
  1733.                }
  1734.             }
  1735.             closedir (dir);
  1736.          }
  1737.       }
  1738.       else {
  1739.          if (Zone == 0 || Cfg->MailAddress.Zone == Zone) {
  1740.             if (Point != 0)
  1741.                sprintf (Temp, "%s\\%04x%04x.pnt\\%08x.xpr", Outbound, Net, Node, Point);
  1742.             else
  1743.                sprintf (Temp, "%s\\%04x%04x.xpr", Outbound, Net, Node);
  1744.          }
  1745.          else {
  1746.             if (Point != 0)
  1747.                sprintf (Temp, "%s.%03x\\%04x%04x.pnt\\%08x.xpr", Outbound, Zone, Net, Node, Point);
  1748.             else
  1749.                sprintf (Temp, "%s.%03x\\%04x%04x.xpr", Outbound, Zone, Net, Node);
  1750.          }
  1751.  
  1752.          AdjustPath (Temp);
  1753.          if ((fd = sopen (Temp, O_RDWR|O_BINARY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1754.             if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  1755.                memset (pktHdr.Password, 0, sizeof (pktHdr.Password));
  1756.                if (Nodes->Read (DestAddr.Zone, DestAddr.Net, DestAddr.Node, DestAddr.Point) == TRUE) {
  1757.                   read (fd, &pktHdr, sizeof (pktHdr));
  1758.                   pktHdr.DestZone = pktHdr.DestZone2 = DestAddr.Zone;
  1759.                   pktHdr.DestNet = DestAddr.Net;
  1760.                   pktHdr.DestNode = DestAddr.Node;
  1761.                   pktHdr.DestPoint = DestAddr.Point;
  1762.                   if (strlen (Nodes->OutPktPwd) > 0)
  1763.                      memcpy (pktHdr.Password, Nodes->OutPktPwd, strlen (Nodes->OutPktPwd));
  1764.                   lseek (fd, 0L, SEEK_SET);
  1765.                   write (fd, &pktHdr, sizeof (pktHdr));
  1766.                }
  1767.                delete Nodes;
  1768.                Nodes = NULL;
  1769.             }
  1770.             close (fd);
  1771.             if (MakeArc == TRUE) {
  1772.                MakeArcMailName (DestAddr.String, Flag);
  1773.                MakeArc = FALSE;
  1774.             }
  1775.             do {
  1776.                sprintf (Name, "%s%08lx.pkt", DestPath, time (NULL));
  1777.             } while (rename (Temp, Name) != 0);
  1778.  
  1779.             if (stat (Name, &statbuf) == 0)
  1780.                TotalSize += statbuf.st_size;
  1781.             DoPack = TRUE;
  1782.          }
  1783.       }
  1784.    }
  1785.  
  1786.    if (DoPack == TRUE) {
  1787.       MakeArcMailName (DestAddr.String, Flag);
  1788.       sprintf (Name, "%s*.pkt", DestPath);
  1789.  
  1790.       if ((Packer = new TPacker (Cfg->SystemPath)) != NULL) {
  1791.          Packer->First ();
  1792.          if (Packer->CheckArc (ArcMailName) == FALSE) {
  1793.             if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  1794.                if (Nodes->Read (DestAddr.String) == TRUE)
  1795.                   Packer->Read (Nodes->Packer);
  1796.                delete Nodes;
  1797.             }
  1798.          }
  1799.          if (Log != NULL)
  1800.             Log->Write ("#Packing mail for %s (%lu bytes)", DestAddr.String, TotalSize);
  1801.          Packer->DoPack (ArcMailName, Name);
  1802.          delete Packer;
  1803.       }
  1804.    }
  1805. }
  1806.  
  1807. VOID TMailProcessor::SendTo (VOID)
  1808. {
  1809.    DIR *dir;
  1810.    int fd;
  1811.    USHORT Zone, Net, Node, Point, DoPack, CheckNet;
  1812.    CHAR *p, Flag, Lookup[32], FlagStr[16];
  1813.    class TAddress Addr;
  1814.    class TPacker *Packer;
  1815.    class TNodes *Nodes;
  1816.    struct dirent *ent;
  1817.    struct stat statbuf;
  1818.  
  1819.    Cfg->MailAddress.First ();
  1820.    Zone = Cfg->MailAddress.Zone;
  1821.    Net = Cfg->MailAddress.Net;
  1822.    Node = Cfg->MailAddress.Node;
  1823.    Point = 0;
  1824.  
  1825.    Flag = 'H';
  1826.    if ((p = strtok (NULL, " ")) != NULL) {
  1827.       if (!stricmp (p, "hold") || !stricmp (p, "crash") || !stricmp (p, "direct") || !stricmp (p, "normal")) {
  1828.          if ((Flag = (CHAR)toupper (*p)) == 'N')
  1829.             Flag = 'F';
  1830.       }
  1831.       strcpy (FlagStr, strupr (p));
  1832.    }
  1833.  
  1834.    if ((p = strtok (NULL, "")) != NULL)
  1835.       strcpy (Line, p);
  1836.  
  1837.    while ((p = strtok (Line, " ")) != NULL) {
  1838.       Addr.Parse (p);
  1839.       if ((p = strtok (NULL, "")) != NULL)
  1840.          strcpy (Line, p);
  1841.       else
  1842.          Line[0] = '\0';
  1843.  
  1844.       if (Addr.Zone != 0)
  1845.          Zone = Addr.Zone;
  1846.       if (Addr.Net != 0)
  1847.          Net = Addr.Net;
  1848.       if (Addr.Node != 0)
  1849.          Node = Addr.Node;
  1850.       Point = Addr.Point;
  1851.  
  1852.       // Controlla se e' stato comando di compattare la posta di
  1853.       // tutti i point (send-to 2:332/402.All).
  1854.       if (Point == 65535U && Net != 65535U && Node != 65535U) {
  1855.          if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1856.             sprintf (Temp, "%s\\%04x%04x.pnt", Outbound, Net, Node);
  1857.          else
  1858.             sprintf (Temp, "%s.%03x\\%04x%04x.pnt", Outbound, Zone, Net, Node);
  1859.          if ((dir = opendir (AdjustPath (Temp))) != NULL) {
  1860.             while ((ent = readdir (dir)) != NULL) {
  1861.                strlwr (ent->d_name);
  1862.                if (strstr (ent->d_name, ".xpr") != NULL) {
  1863.                   sscanf (ent->d_name, "%08hx", &Point);
  1864.  
  1865.                   if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1866.                      sprintf (Temp, "%s\\%04x%04x.pnt\\%08x.xpr", Outbound, Net, Node, Point);
  1867.                   else
  1868.                      sprintf (Temp, "%s.%03x\\%04x%04x.pnt\\%08x.xpr", Outbound, Zone, Net, Node, Point);
  1869.  
  1870.                   if ((fd = sopen (AdjustPath (Temp), O_RDONLY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1871.                      close (fd);
  1872.                      do {
  1873.                         if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1874.                            sprintf (Name, "%s\\%04x%04x.pnt\\%08lx.pkt", Outbound, Net, Node, time (NULL));
  1875.                         else
  1876.                            sprintf (Name, "%s.%03x\\%04x%04x.pnt\\%08lx.pkt", Outbound, Zone, Net, Node, time (NULL));
  1877.                      } while (rename (Temp, AdjustPath (Name)) != 0);
  1878.  
  1879.                      sprintf (Addr.String, "%u:%u/%u.%u", Zone, Net, Node, Point);
  1880.                      MakeArcMailName (Addr.String, Flag);
  1881.  
  1882.                      if ((Packer = new TPacker (Cfg->SystemPath)) != NULL) {
  1883.                         Packer->First ();
  1884.                         if (Packer->CheckArc (ArcMailName) == FALSE) {
  1885.                            if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  1886.                               if (Nodes->Read (Addr.String) == TRUE)
  1887.                                  Packer->Read (Nodes->Packer);
  1888.                               delete Nodes;
  1889.                            }
  1890.                         }
  1891.                         stat (Name, &statbuf);
  1892.                         if (Log != NULL)
  1893.                            Log->Write ("#Packing mail for %s (%lu bytes)", Addr.String, statbuf.st_size);
  1894.                         Packer->DoPack (ArcMailName, Name);
  1895.                         delete Packer;
  1896.                      }
  1897.                   }
  1898.                }
  1899.             }
  1900.             closedir (dir);
  1901.          }
  1902.       }
  1903.       // Controlla se e' stato comando di compattare la posta di
  1904.       // tutta una zona (send-to all 2:All) o di un solo net (send-to 2:332/All).
  1905.       else if (Net == 65535U || Node == 65535U) {
  1906.          CheckNet = (Net != 65535U) ? TRUE : FALSE;
  1907.          sprintf (Lookup, "%04x", Net);
  1908.          if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1909.             sprintf (Temp, "%s", Outbound);
  1910.          else
  1911.             sprintf (Temp, "%s.%03x", Outbound, Zone);
  1912.          if ((dir = opendir (AdjustPath (Temp))) != NULL) {
  1913.             while ((ent = readdir (dir)) != NULL) {
  1914.                strlwr (ent->d_name);
  1915.                if (strstr (ent->d_name, ".xpr") != NULL) {
  1916.                   DoPack = FALSE;
  1917.                   if (CheckNet == FALSE) {
  1918.                      sscanf (ent->d_name, "%04hx%04hx", &Net, &Node);
  1919.                      DoPack = TRUE;
  1920.                   }
  1921.                   else if (!strncmp (ent->d_name, Lookup, strlen (Lookup))) {
  1922.                      sscanf (ent->d_name, "%04hx%04hx", &Net, &Node);
  1923.                      DoPack = TRUE;
  1924.                   }
  1925.  
  1926.                   if (DoPack == TRUE) {
  1927.                      if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1928.                         sprintf (Temp, "%s\\%04x%04x.xpr", Outbound, Net, Node);
  1929.                      else
  1930.                         sprintf (Temp, "%s.%03x\\%04x%04x.xpr", Outbound, Zone, Net, Node);
  1931.  
  1932.                      if ((fd = sopen (AdjustPath (Temp), O_RDONLY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1933.                         close (fd);
  1934.                         do {
  1935.                            if (Zone == 0 || Cfg->MailAddress.Zone == Zone)
  1936.                               sprintf (Name, "%s\\%08lx.pkt", Outbound, time (NULL));
  1937.                            else
  1938.                               sprintf (Name, "%s.%03x\\%08lx.pkt", Outbound, Zone, time (NULL));
  1939.                         } while (rename (Temp, AdjustPath (Name)) != 0);
  1940.  
  1941.                         sprintf (Addr.String, "%u:%u/%u.%u", Zone, Net, Node, Point);
  1942.                         MakeArcMailName (Addr.String, Flag);
  1943.  
  1944.                         if ((Packer = new TPacker (Cfg->SystemPath)) != NULL) {
  1945.                            Packer->First ();
  1946.                            if (Packer->CheckArc (ArcMailName) == FALSE) {
  1947.                               if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  1948.                                  if (Nodes->Read (Addr.String) == TRUE)
  1949.                                     Packer->Read (Nodes->Packer);
  1950.                                  delete Nodes;
  1951.                               }
  1952.                            }
  1953.                            stat (Name, &statbuf);
  1954.                            if (Log != NULL)
  1955.                               Log->Write ("#Packing mail for %s (%lu bytes)", Addr.String, statbuf.st_size);
  1956.                            Packer->DoPack (ArcMailName, Name);
  1957.                            delete Packer;
  1958.                         }
  1959.                      }
  1960.                   }
  1961.                }
  1962.             }
  1963.             closedir (dir);
  1964.          }
  1965.       }
  1966.       else {
  1967.          if (Zone == 0 || Cfg->MailAddress.Zone == Zone) {
  1968.             if (Point != 0)
  1969.                sprintf (Temp, "%s\\%04x%04x.pnt\\%08x.xpr", Outbound, Net, Node, Point);
  1970.             else
  1971.                sprintf (Temp, "%s\\%04x%04x.xpr", Outbound, Net, Node);
  1972.          }
  1973.          else {
  1974.             if (Point != 0)
  1975.                sprintf (Temp, "%s.%03x\\%04x%04x.pnt\\%08x.xpr", Outbound, Zone, Net, Node, Point);
  1976.             else
  1977.                sprintf (Temp, "%s.%03x\\%04x%04x.xpr", Outbound, Zone, Net, Node);
  1978.          }
  1979.  
  1980.          if ((fd = sopen (AdjustPath (Temp), O_RDONLY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1981.             close (fd);
  1982.             do {
  1983.                if (Zone == 0 || Cfg->MailAddress.Zone == Zone) {
  1984.                   if (Point != 0)
  1985.                      sprintf (Name, "%s\\%04x%04x.pnt\\%08lx.pkt", Outbound, Net, Node, time (NULL));
  1986.                   else
  1987.                      sprintf (Name, "%s\\%08lx.pkt", Outbound, time (NULL));
  1988.                }
  1989.                else {
  1990.                   if (Point != 0)
  1991.                      sprintf (Name, "%s.%03x\\%04x%04x.pnt\\%08lx.pkt", Outbound, Zone, Net, Node, time (NULL));
  1992.                   else
  1993.                      sprintf (Name, "%s.%03x\\%08lx.pkt", Outbound, Zone, time (NULL));
  1994.                }
  1995.             } while (rename (Temp, AdjustPath (Name)) != 0);
  1996.  
  1997.             sprintf (Addr.String, "%u:%u/%u.%u", Zone, Net, Node, Point);
  1998.             MakeArcMailName (Addr.String, Flag);
  1999.  
  2000.             if ((Packer = new TPacker (Cfg->SystemPath)) != NULL) {
  2001.                Packer->First ();
  2002.                if (Packer->CheckArc (ArcMailName) == FALSE) {
  2003.                   if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  2004.                      if (Nodes->Read (Addr.String) == TRUE)
  2005.                         Packer->Read (Nodes->Packer);
  2006.                      delete Nodes;
  2007.                   }
  2008.                }
  2009.                stat (Name, &statbuf);
  2010.                if (Log != NULL)
  2011.                   Log->Write ("#Packing mail for %s (%lu bytes)", Addr.String, statbuf.st_size);
  2012.                Packer->DoPack (ArcMailName, Name);
  2013.                delete Packer;
  2014.             }
  2015.          }
  2016.       }
  2017.    }
  2018. }
  2019.  
  2020. VOID TMailProcessor::Poll (VOID)
  2021. {
  2022.    int fd;
  2023.    USHORT Zone, Net, Node, Point;
  2024.    CHAR *p, Flag;
  2025.    class TAddress Addr;
  2026.  
  2027.    Cfg->MailAddress.First ();
  2028.    Zone = Cfg->MailAddress.Zone;
  2029.    Net = Cfg->MailAddress.Net;
  2030.    Node = Cfg->MailAddress.Node;
  2031.    Point = 0;
  2032.  
  2033.    Flag = 'H';
  2034.    if ((p = strtok (NULL, " ")) != NULL) {
  2035.       if (!stricmp (p, "hold") || !stricmp (p, "crash") || !stricmp (p, "direct") || !stricmp (p, "normal")) {
  2036.          if ((Flag = (CHAR)toupper (*p)) == 'N')
  2037.             Flag = 'F';
  2038.       }
  2039.    }
  2040.  
  2041.    if ((p = strtok (NULL, "")) != NULL)
  2042.       strcpy (Line, p);
  2043.  
  2044.    while ((p = strtok (Line, " ")) != NULL) {
  2045.       Addr.Parse (p);
  2046.       if ((p = strtok (NULL, "")) != NULL)
  2047.          strcpy (Line, p);
  2048.       else
  2049.          Line[0] = '\0';
  2050.  
  2051.       if (Addr.Zone != 0)
  2052.          Zone = Addr.Zone;
  2053.       if (Addr.Net != 0)
  2054.          Net = Addr.Net;
  2055.       if (Addr.Node != 0)
  2056.          Node = Addr.Node;
  2057.       Point = Addr.Point;
  2058.  
  2059.       if (Zone == 0 || Cfg->MailAddress.Zone == Zone) {
  2060.          if (Point != 0)
  2061.             sprintf (Temp, "%s\\%04x%04x.pnt\\%08x.%clo", Outbound, Net, Node, Point, tolower (Flag));
  2062.          else
  2063.             sprintf (Temp, "%s\\%04x%04x.%clo", Outbound, Net, Node, tolower (Flag));
  2064.       }
  2065.       else {
  2066.          if (Point != 0)
  2067.             sprintf (Temp, "%s.%03x\\%04x%04x.pnt\\%08x.%clo", Outbound, Zone, Net, Node, Point, tolower (Flag));
  2068.          else
  2069.             sprintf (Temp, "%s.%03x\\%04x%04x.%clo", Outbound, Zone, Net, Node, tolower (Flag));
  2070.       }
  2071.  
  2072.       if ((fd = sopen (AdjustPath (Temp), O_RDONLY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE)) != -1)
  2073.          close (fd);
  2074.    }
  2075. }
  2076.  
  2077. VOID TMailProcessor::Pack (PSZ pszFile, PSZ pszTag /* = NULL*/)
  2078. {
  2079.    FILE *fp;
  2080.    USHORT LineNum, DoRoute, Process;
  2081.    CHAR Tag[64], *p;
  2082.    class TPacker *Packer;
  2083.  
  2084.    Process = TRUE;
  2085.    DoRoute = FALSE;
  2086.    Tag[0] = '\0';
  2087.  
  2088.    strcpy (Outbound, Cfg->Outbound);
  2089.    if (Outbound[strlen (Outbound) - 1] == '\\' || Outbound[strlen (Outbound) - 1] == '/')
  2090.       Outbound[strlen (Outbound) - 1] = '\0';
  2091.  
  2092.    if (Log != NULL) {
  2093.       Log->Write (":Pack outbound mail (%s)", pszFile);
  2094.       if (pszTag != NULL) {
  2095.          if (pszTag[0] != '\0')
  2096.             Log->Write (":Processing tag %s", pszTag);
  2097.          strcpy (Tag, pszTag);
  2098.       }
  2099.    }
  2100.  
  2101.    if ((Packer = new TPacker (Cfg->SystemPath)) != NULL) {
  2102.       if (Packer->First () == TRUE)
  2103.          DoRoute = TRUE;
  2104.       delete Packer;
  2105.    }
  2106.  
  2107.    if (DoRoute == TRUE) {
  2108.       if ((fp = _fsopen (pszFile, "rt", SH_DENYNO)) != NULL) {
  2109.          LineNum = 1;
  2110.          while (fgets (Line, sizeof (Line) - 1, fp) != NULL) {
  2111.             if ((p = strchr (Line, '\n')) != NULL)
  2112.                *p = '\0';
  2113.             if ((p = strtok (Line, " ")) != NULL) {
  2114.                if (!stricmp (p, "send-to") || !stricmp (p, "send")) {
  2115.                   if (Process == TRUE)
  2116.                      SendTo ();
  2117.                }
  2118.                else if (!stricmp (p, "route-to") || !stricmp (p, "route")) {
  2119.                   if (Process == TRUE)
  2120.                      RouteTo ();
  2121.                }
  2122.                else if (!stricmp (p, "change")) {
  2123.                   if (Process == TRUE)
  2124.                      Change ();
  2125.                }
  2126.                else if (!stricmp (p, "poll")) {
  2127.                   if (Process == TRUE)
  2128.                      Poll ();
  2129.                }
  2130.                else if (!stricmp (p, "tag")) {
  2131.                   if ((p = strtok (NULL, " ")) != NULL) {
  2132.                      if (!stricmp (p, Tag))
  2133.                         Process = TRUE;
  2134.                      else
  2135.                         Process = FALSE;
  2136.                   }
  2137.                }
  2138.                else if (*p != '\0' && *p != ';' && *p != '%')
  2139.                   Log->Write ("!Unknown keyword '%s' on line #%d", p, LineNum);
  2140.             }
  2141.  
  2142.             LineNum++;
  2143.          }
  2144.          fclose (fp);
  2145.       }
  2146.    }
  2147.    else {
  2148.       if (Log != NULL)
  2149.          Log->Write ("!No compressor(s) defined");
  2150.    }
  2151. }
  2152.  
  2153. USHORT TMailProcessor::DoRescan (VOID)
  2154. {
  2155.    FILE *fp;
  2156.    USHORT RetVal = FALSE;
  2157.    CHAR Temp[128], *tag, *node, *maxmsgs;
  2158.    class TAreaManager *Manager;
  2159.  
  2160.    // Verifica ed esegue la procedura di rescan delle aree echomail richieste
  2161.    // mediante messaggio ad areafix
  2162.    if ((fp = fopen ("rescan.log", "rt")) != NULL) {
  2163.       if ((Manager = new TAreaManager) != NULL) {
  2164.          Manager->Log = Log;
  2165.          Manager->Cfg = Cfg;
  2166.          Manager->Status = Status;
  2167.  
  2168.          while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  2169.             Temp[strlen (Temp) - 1] = '\0';
  2170.             tag = strtok (Temp, " ");
  2171.             node = strtok (NULL, " ");
  2172.             maxmsgs = strtok (NULL, " ");
  2173.             if (tag != NULL && node != NULL && maxmsgs != NULL)
  2174.                Manager->Rescan (tag, node, (USHORT)atoi (maxmsgs));
  2175.          }
  2176.  
  2177.          RetVal = TRUE;
  2178.          delete Manager;
  2179.       }
  2180.  
  2181.       fclose (fp);
  2182.       unlink ("rescan.log");
  2183.    }
  2184.  
  2185.    return (RetVal);
  2186. }
  2187.  
  2188.