home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / AREAMGR.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  60KB  |  1,634 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. enum {
  24.    ALREADY_LINKED = 2,
  25.    NOT_FOUND
  26. };
  27.  
  28. TAreaManager::TAreaManager (void)
  29. {
  30.    Log = NULL;
  31.    EchoLink = NULL;
  32.    Status = NULL;
  33. }
  34.  
  35. TAreaManager::~TAreaManager (void)
  36. {
  37. }
  38.  
  39. VOID TAreaManager::MsgFooter (VOID)
  40. {
  41.    CHAR Temp[96];
  42.  
  43.    Text.Add ("");
  44.    sprintf (Temp, "--- %s v%s", NAME, VERSION);
  45.    Text.Add (Temp);
  46. }
  47.  
  48. VOID TAreaManager::MsgHeader (VOID)
  49. {
  50.    CHAR Temp[96];
  51.    class TAddress From, To;
  52.  
  53.    From.Parse (Msg->FromAddress);
  54.    To.Parse (Msg->ToAddress);
  55.  
  56.    if (From.Zone != To.Zone) {
  57.       sprintf (Temp, "\001INTL %u:%u/%u %u:%u/%u", To.Zone, To.Net, To.Node, From.Zone, From.Net, From.Node);
  58.       Text.Add (Temp);
  59.    }
  60.    if (From.Point != 0) {
  61.       sprintf (Temp, "\001FMPT %u", From.Point);
  62.       Text.Add (Temp);
  63.    }
  64.    if (To.Point != 0) {
  65.       sprintf (Temp, "\001TOPT %u", To.Point);
  66.       Text.Add (Temp);
  67.    }
  68.  
  69.    sprintf (Temp, "\001MSGID: %s %08lx", Msg->ToAddress, time (NULL));
  70.    Text.Add (Temp);
  71.    sprintf (Temp, "\001PID: %s", NAME);
  72.    Text.Insert (Temp, (USHORT)(strlen (Temp) + 1));
  73. }
  74.  
  75. USHORT TAreaManager::SetPacker (PSZ Cmd)
  76. {
  77.    USHORT RetVal = FALSE;
  78.    CHAR Temp[128];
  79.    class TPacker *Packer;
  80.    class TNodes *Nodes;
  81.  
  82.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  83.       if (Nodes->Read (Msg->FromAddress) == TRUE) {
  84.          if ((Packer = new TPacker (Cfg->SystemPath)) != NULL) {
  85.             if (Packer->Read (Cmd) == TRUE) {
  86.                strcpy (Nodes->Packer, Cmd);
  87.                Nodes->Update ();
  88.                sprintf (Temp, "Compressor set to %s (%s).", Packer->Display, strupr (Cmd));
  89.                RetVal = TRUE;
  90.             }
  91.             delete Packer;
  92.          }
  93.       }
  94.       delete Nodes;
  95.    }
  96.  
  97.    if (RetVal == FALSE)
  98.       sprintf (Temp, "The compressor %s was not found.", strupr (Cmd));
  99.    Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  100.  
  101.    return (RetVal);
  102. }
  103.  
  104. VOID TAreaManager::ImportAreasBBS (VOID)
  105. {
  106.    #define MAX_LINECHAR 2048
  107.    int i, counter, existing;
  108.    FILE *fp = fopen (Cfg->AreasBBS, "rt");
  109.    CHAR *lpTemp = (CHAR *)malloc (MAX_LINECHAR + 1);
  110.    CHAR *lpPath, *lpTag, *lpLink, Name[16];
  111.    class TMsgData *MsgData = new TMsgData (Cfg->SystemPath);
  112.    class TEchoLink *EchoLink = new TEchoLink (Cfg->SystemPath);
  113.  
  114.    counter = 0;
  115.    existing = 0;
  116.    if (Log != NULL)
  117.       Log->Write ("+Import areas from %s", Cfg->AreasBBS);
  118.  
  119.    if (fp != NULL && lpTemp != NULL && MsgData != NULL && EchoLink != NULL) {
  120.       fgets (lpTemp, MAX_LINECHAR, fp);
  121.       while (fgets (lpTemp, MAX_LINECHAR, fp) != NULL) {
  122.          lpTemp[strlen (lpTemp) - 1] = '\0';
  123.          if (lpTemp[0] == ';' || lpTemp[0] == '\0')
  124.             continue;
  125.          if ((lpPath = strtok (lpTemp, " ")) != NULL) {
  126.             if ((lpTag = strtok (NULL, " ")) != NULL) {
  127.                if (MsgData->ReadEcho (lpTag) == FALSE) {
  128.                   i = 1;
  129.                   do {
  130.                      sprintf (Name, "newarea%d", i++);
  131.                   } while (MsgData->Read (Name) == TRUE);
  132.  
  133.                   MsgData->New ();
  134.                   strcpy (MsgData->Key, Name);
  135.                   sprintf (MsgData->Display, "Imported area %s", lpTag);
  136.                   strcpy (MsgData->EchoTag, lpTag);
  137.                   if (lpPath[0] == '$') {
  138.                      MsgData->Storage = ST_SQUISH;
  139.                      lpPath++;
  140.                   }
  141.                   else if (lpPath[0] == '!') {
  142.                      MsgData->Storage = ST_JAM;
  143.                      lpPath++;
  144.                   }
  145.                   else if (lpPath[0] == '=') {
  146.                      MsgData->Storage = ST_SQUISH;
  147.                      lpPath++;
  148.                   }
  149.                   else if (isdigit (lpPath[0]))
  150.                      MsgData->Storage = ST_HUDSON;
  151.                   else
  152.                      MsgData->Storage = ST_FIDO;
  153.                   MsgData->EchoMail = TRUE;
  154.                   MsgData->Add ();
  155.                }
  156.                else
  157.                   existing++;
  158.  
  159.                EchoLink->Load (lpTag);
  160.                EchoLink->Clear ();
  161.                if ((lpLink = strtok (NULL, "")) != NULL)
  162.                   EchoLink->AddString (lpLink);
  163.                EchoLink->Save ();
  164.  
  165.                counter++;
  166.             }
  167.          }
  168.       }
  169.    }
  170.  
  171.    if (Log != NULL)
  172.       Log->Write (":%d area(s) readed, %d new", counter, counter - existing);
  173.  
  174.    if (EchoLink != NULL)
  175.       delete EchoLink;
  176.    if (MsgData != NULL)
  177.       delete MsgData;
  178.    if (lpTemp != NULL)
  179.       free (lpTemp);
  180.    if (fp != NULL)
  181.       fclose (fp);
  182. }
  183.  
  184. VOID TAreaManager::ImportDescriptions (PSZ pszFile)
  185. {
  186.    #define MAX_LINECHAR 2048
  187.    int counter, existing;
  188.    FILE *fp = fopen (pszFile, "rt");
  189.    CHAR *lpTemp = (CHAR *)malloc (MAX_LINECHAR + 1);
  190.    CHAR *lpTag, *lpDescription;
  191.    class TMsgData *MsgData = new TMsgData (Cfg->SystemPath);
  192.  
  193.    counter = 0;
  194.    existing = 0;
  195.    if (Log != NULL)
  196.       Log->Write ("+Import descriptions from %s", pszFile);
  197.  
  198.    if (fp != NULL && lpTemp != NULL && MsgData != NULL) {
  199.       while (fgets (lpTemp, MAX_LINECHAR, fp) != NULL) {
  200.          lpTemp[strlen (lpTemp) - 1] = '\0';
  201.          if (lpTemp[0] == ';' || lpTemp[0] == '\0')
  202.             continue;
  203.          if ((lpTag = strtok (lpTemp, " ")) != NULL) {
  204.             if ((lpDescription = strtok (NULL, "")) != NULL) {
  205.                while (*lpDescription == ' ' || *lpDescription == 0x09)
  206.                   lpDescription++;
  207.                if (MsgData->ReadEcho (lpTag) == TRUE) {
  208.                   strcpy (MsgData->Display, lpDescription);
  209.                   MsgData->Update ();
  210.                   existing++;
  211.                }
  212.  
  213.                counter++;
  214.             }
  215.          }
  216.       }
  217.    }
  218.  
  219.    if (Log != NULL)
  220.       Log->Write (":%d area(s) readed, %d updated", counter, existing);
  221.  
  222.    if (MsgData != NULL)
  223.       delete MsgData;
  224.    if (lpTemp != NULL)
  225.       free (lpTemp);
  226.    if (fp != NULL)
  227.       fclose (fp);
  228. }
  229.  
  230. VOID TAreaManager::UpdateAreasBBS (VOID)
  231. {
  232.    FILE *fp;
  233.    int counter = 0;
  234.    class TMsgData *MsgData;
  235.    class TEchoLink *EchoLink;
  236.  
  237.    if (Log != NULL)
  238.       Log->Write ("+Updating %s", Cfg->AreasBBS);
  239.  
  240.    if ((fp = fopen (Cfg->AreasBBS, "wt")) != NULL) {
  241.       fprintf (fp, "%s ! %s\n;\n", Cfg->SystemName, Cfg->SysopName);
  242.       if ((EchoLink = new TEchoLink (Cfg->SystemPath)) != NULL) {
  243.          if ((MsgData = new TMsgData (Cfg->SystemPath)) != NULL) {
  244.             if (MsgData->First () == TRUE)
  245.                do {
  246.                   if (MsgData->EchoMail == TRUE && MsgData->EchoTag[0] != '\0') {
  247.                      if (MsgData->Storage == ST_SQUISH)
  248.                         fprintf (fp, "$%-30s", MsgData->Path);
  249.                      else if (MsgData->Storage == ST_JAM)
  250.                         fprintf (fp, "!%-30s", MsgData->Path);
  251.                      else if (MsgData->Storage == ST_ADEPT)
  252.                         fprintf (fp, "=%-30s", MsgData->Path);
  253.                      else if (MsgData->Storage == ST_FIDO)
  254.                         fprintf (fp, "%-30s ", MsgData->Path);
  255.                      else if (MsgData->Storage == ST_HUDSON)
  256.                         fprintf (fp, "%-30d ", MsgData->Board);
  257.                      EchoLink->Load (MsgData->EchoTag);
  258.                      fprintf (fp, " %-30s", MsgData->EchoTag);
  259.                      if (EchoLink->First () == TRUE)
  260.                         do {
  261.                            fprintf (fp, " %s", EchoLink->Address);
  262.                         } while (EchoLink->Next () == TRUE);
  263.                      fprintf (fp, "\n");
  264.                      counter++;
  265.                   }
  266.                } while (MsgData->Next () == TRUE);
  267.             delete MsgData;
  268.          }
  269.          delete EchoLink;
  270.       }
  271.       fprintf (fp, ";\n");
  272.       fclose (fp);
  273.    }
  274.  
  275.    if (Log != NULL)
  276.       Log->Write (":%d area(s) exported", counter);
  277. }
  278.  
  279. VOID TAreaManager::ExportDescriptions (PSZ pszFile)
  280. {
  281.    FILE *fp;
  282.    int counter = 0;
  283.    class TMsgData *MsgData;
  284.  
  285.    if (Log != NULL)
  286.       Log->Write ("+Updating %s", pszFile);
  287.  
  288.    if ((fp = fopen (pszFile, "wt")) != NULL) {
  289.       if ((MsgData = new TMsgData (Cfg->SystemPath)) != NULL) {
  290.          if (MsgData->First () == TRUE)
  291.             do {
  292.                if (MsgData->EchoMail == TRUE && MsgData->EchoTag[0] != '\0') {
  293.                   fprintf (fp, "%-24s %s\n", MsgData->EchoTag, MsgData->Display);
  294.                   counter++;
  295.                }
  296.             } while (MsgData->Next () == TRUE);
  297.          delete MsgData;
  298.       }
  299.       fclose (fp);
  300.    }
  301.  
  302.    if (Log != NULL)
  303.       Log->Write (":%d description(s) exported", counter);
  304. }
  305.  
  306. USHORT TAreaManager::Passive (PSZ address, USHORT flag)
  307. {
  308.    USHORT RetVal = FALSE;
  309.    CHAR Temp[96];
  310.  
  311.    if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  312.       if (Data->First () == TRUE)
  313.          do {
  314.             if (Data->EchoMail == TRUE && Data->EchoTag[0] != '\0') {
  315.                EchoLink->Load (Data->EchoTag);
  316.                if (EchoLink->Check (address) == TRUE) {
  317.                   if (EchoLink->Passive != flag) {
  318.                      EchoLink->Passive = (UCHAR)flag;
  319.                      EchoLink->Update ();
  320.                      EchoLink->Save ();
  321.                      sprintf (Temp, "Area %s is now %s.", strupr (Data->EchoTag), (flag == TRUE) ? "passive" : "active");
  322.                   }
  323.                   else
  324.                      sprintf (Temp, "Area %s already %s.", strupr (Data->EchoTag), (flag == TRUE) ? "passive" : "active");
  325.                   Text.Add (Temp);
  326.                   RetVal = TRUE;
  327.                }
  328.             }
  329.          } while (Data->Next () == TRUE);
  330.       delete Data;
  331.    }
  332.  
  333.    return (RetVal);
  334. }
  335.  
  336. ///////////////////////////////////////////////////////////////////////////////
  337. // Rimuove tutte le aree agganciate ad un nodo                               //
  338. ///////////////////////////////////////////////////////////////////////////////
  339. USHORT TAreaManager::RemoveAll (PSZ address)
  340. {
  341.    USHORT RetVal = FALSE, DoDelete = FALSE;
  342.    CHAR Temp[96];
  343.  
  344.    if (EchoLink == NULL) {
  345.       EchoLink = new TEchoLink (Cfg->SystemPath);
  346.       DoDelete = TRUE;
  347.    }
  348.  
  349.    if (EchoLink != NULL) {
  350.       if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  351.          if (Data->First () == TRUE)
  352.             do {
  353.                if (Data->EchoMail == TRUE && Data->EchoTag[0] != '\0') {
  354.                   EchoLink->Load (Data->EchoTag);
  355.                   if (EchoLink->Check (address) == TRUE) {
  356.                      EchoLink->Delete ();
  357.                      EchoLink->Save ();
  358.                      sprintf (Temp, "Area %s has been removed.", strupr (Data->EchoTag));
  359.                      Text.Add (Temp);
  360.                      RetVal = TRUE;
  361.                   }
  362.                }
  363.             } while (Data->Next () == TRUE);
  364.          delete Data;
  365.       }
  366.    }
  367.  
  368.    if (EchoLink != NULL && DoDelete == TRUE) {
  369.       delete EchoLink;
  370.       EchoLink = NULL;
  371.    }
  372.  
  373.    return (RetVal);
  374. }
  375.  
  376. ///////////////////////////////////////////////////////////////////////////////
  377. // Imposta la password di sessione                                           //
  378. ///////////////////////////////////////////////////////////////////////////////
  379. USHORT TAreaManager::SetSessionPwd (PSZ address, PSZ pwd)
  380. {
  381.    USHORT RetVal = FALSE;
  382.  
  383.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  384.       if (Nodes->Read (address) == TRUE) {
  385.          strcpy (Nodes->SessionPwd, pwd);
  386.          Nodes->Update ();
  387.          RetVal = TRUE;
  388.       }
  389.       delete Nodes;
  390.    }
  391.  
  392.    return (RetVal);
  393. }
  394.  
  395. USHORT TAreaManager::SetPwd (PSZ address, PSZ pwd)
  396. {
  397.    USHORT RetVal = FALSE;
  398.  
  399.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  400.       if (Nodes->Read (address) == TRUE) {
  401.          strcpy (Nodes->AreaMgrPwd, pwd);
  402.          Nodes->Update ();
  403.          RetVal = TRUE;
  404.       }
  405.       delete Nodes;
  406.    }
  407.  
  408.    return (RetVal);
  409. }
  410.  
  411. USHORT TAreaManager::SetPacketPwd (PSZ address, PSZ pwd)
  412. {
  413.    USHORT RetVal = FALSE;
  414.  
  415.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  416.       if (Nodes->Read (address) == TRUE) {
  417.          if (pwd == NULL)
  418.             Nodes->InPktPwd[0] = Nodes->OutPktPwd[0] = '\0';
  419.          else {
  420.             strcpy (Nodes->InPktPwd, pwd);
  421.             strcpy (Nodes->OutPktPwd, pwd);
  422.          }
  423.          Nodes->Update ();
  424.          RetVal = TRUE;
  425.       }
  426.       delete Nodes;
  427.    }
  428.  
  429.    return (RetVal);
  430. }
  431.  
  432. USHORT TAreaManager::SetInPacketPwd (PSZ address, PSZ pwd)
  433. {
  434.    USHORT RetVal = FALSE;
  435.  
  436.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  437.       if (Nodes->Read (address) == TRUE) {
  438.          if (pwd == NULL)
  439.             Nodes->OutPktPwd[0] = '\0';
  440.          else
  441.             strcpy (Nodes->OutPktPwd, pwd);
  442.          Nodes->Update ();
  443.          RetVal = TRUE;
  444.       }
  445.       delete Nodes;
  446.    }
  447.  
  448.    return (RetVal);
  449. }
  450.  
  451. USHORT TAreaManager::SetOutPacketPwd (PSZ address, PSZ pwd)
  452. {
  453.    USHORT RetVal = FALSE;
  454.  
  455.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  456.       if (Nodes->Read (address) == TRUE) {
  457.          if (pwd == NULL)
  458.             Nodes->InPktPwd[0] = '\0';
  459.          else
  460.             strcpy (Nodes->InPktPwd, pwd);
  461.          Nodes->Update ();
  462.          RetVal = TRUE;
  463.       }
  464.       delete Nodes;
  465.    }
  466.  
  467.    return (RetVal);
  468. }
  469.  
  470. ///////////////////////////////////////////////////////////////////////////////
  471. // Aggancia un'area ad un nuodo                                              //
  472. ///////////////////////////////////////////////////////////////////////////////
  473. USHORT TAreaManager::AddArea (PSZ address, PSZ area)
  474. {
  475.    USHORT RetVal = FALSE, DoDelete = FALSE;
  476.    class TNodes *Nodes;
  477.    class TMsgData *Data;
  478.  
  479.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  480.       if (Nodes->Read (Msg->FromAddress) == TRUE) {
  481.          if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  482.             if (Data->ReadEcho (area) == TRUE) {
  483.                if (Nodes->Level < Data->Level)
  484.                   RetVal = NOT_FOUND;
  485.                if ((Nodes->AccessFlags & Data->Flags) != Data->Flags)
  486.                   RetVal = NOT_FOUND;
  487.                if ((Nodes->DenyFlags & Data->DenyFlags) != Data->DenyFlags && Data->DenyFlags != 0L)
  488.                   RetVal = NOT_FOUND;
  489.                if (Log != NULL && RetVal == NOT_FOUND)
  490.                   Log->Write ("!Area %s not accessible to node", area);
  491.             }
  492.             else
  493.                RetVal = NOT_FOUND;
  494.             delete Data;
  495.          }
  496.       }
  497.       delete Nodes;
  498.    }
  499.  
  500.    if (RetVal == NOT_FOUND)
  501.       return (RetVal);
  502.  
  503.    ///////////////////////////////////////////////////////////////////////////////
  504.    // Si assicura che la classe EchoLink sia accessibile                        //
  505.    ///////////////////////////////////////////////////////////////////////////////
  506.    if (EchoLink == NULL) {
  507.       EchoLink = new TEchoLink (Cfg->SystemPath);
  508.       DoDelete = TRUE;
  509.    }
  510.  
  511.    if (EchoLink != NULL) {
  512.       EchoLink->Load (area);
  513.       if (EchoLink->First () == TRUE) {
  514.          if (EchoLink->Check (address) == TRUE)
  515.             RetVal = ALREADY_LINKED;
  516.          else {
  517.             EchoLink->AddString (address);
  518.             EchoLink->Save ();
  519.             RetVal = TRUE;
  520.          }
  521.       }
  522.       else {
  523.          ///////////////////////////////////////////////////////////////////////////////
  524.          // Se non trova l'area negli echolink, ne verifica l'esistenza               //
  525.          ///////////////////////////////////////////////////////////////////////////////
  526.          RetVal = NOT_FOUND;
  527.          if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  528.             if (Data->ReadEcho (area) == TRUE) {
  529.                EchoLink->Load (area);
  530.                EchoLink->AddString (address);
  531.                EchoLink->Save ();
  532.                RetVal = TRUE;
  533.             }
  534.             delete Data;
  535.          }
  536.       }
  537.    }
  538.  
  539.    if (EchoLink != NULL && DoDelete == TRUE) {
  540.       delete EchoLink;
  541.       EchoLink = NULL;
  542.    }
  543.  
  544.    return (RetVal);
  545. }
  546.  
  547. USHORT TAreaManager::RemoveArea (PSZ address, PSZ area)
  548. {
  549.    USHORT RetVal = FALSE, DoDelete = FALSE;
  550.  
  551.    if (EchoLink == NULL) {
  552.       EchoLink = new TEchoLink (Cfg->SystemPath);
  553.       DoDelete = TRUE;
  554.    }
  555.  
  556.    if (EchoLink != NULL) {
  557.       EchoLink->Load (area);
  558.       if (EchoLink->First () == TRUE) {
  559.          if (EchoLink->Check (address) == TRUE) {
  560.             EchoLink->Delete ();
  561.             EchoLink->Save ();
  562.             RetVal = TRUE;
  563.          }
  564.       }
  565.    }
  566.  
  567.    if (EchoLink != NULL && DoDelete == TRUE) {
  568.       delete EchoLink;
  569.       EchoLink = NULL;
  570.    }
  571.  
  572.    return (RetVal);
  573. }
  574.  
  575. VOID TAreaManager::DoAreaListings (PSZ Address, USHORT Type, USHORT Level, ULONG AccessFlags, ULONG DenyFlags)
  576. {
  577.    CHAR Temp[96];
  578.    ULONG Total = 0L;
  579.  
  580.    Text.Clear ();
  581.    MsgHeader ();
  582.  
  583.    if (Type == 1) {
  584.       Total = 0L;
  585.       strcpy (Msg->Subject, "List of available echomail areas");
  586.  
  587.       sprintf (Temp, "Area(s) available to %s:", Address);
  588.       Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  589.       Text.Add ("");
  590.       if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  591.          if (Data->First () == TRUE)
  592.             do {
  593.                if (Level < Data->Level)
  594.                   continue;
  595.                if ((AccessFlags & Data->Flags) != Data->Flags)
  596.                   continue;
  597.                if ((DenyFlags & Data->DenyFlags) != Data->DenyFlags && Data->DenyFlags != 0L)
  598.                   continue;
  599.                if (Data->EchoMail == TRUE && Data->EchoTag[0] != '\0') {
  600.                   sprintf (Temp, "%-30.30s %.48s", Data->EchoTag, Data->Display);
  601.                   Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  602.                   Total++;
  603.                }
  604.             } while (Data->Next () == TRUE);
  605.          delete Data;
  606.       }
  607.       Text.Add ("");
  608.       sprintf (Temp, "%lu available area(s).", Total);
  609.       Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  610.    }
  611.    else if (Type == 2) {
  612.       strcpy (Msg->Subject, "List of linked echomail areas");
  613.  
  614.       sprintf (Temp, "%s is now linked to the following area(s):", Address);
  615.       Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  616.       Text.Add ("");
  617.       Total = 0L;
  618.       if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  619.          EchoLink = new TEchoLink (Cfg->SystemPath);
  620.          if (Data->First () == TRUE)
  621.             do {
  622.                if (Data->EchoMail == TRUE && Data->EchoTag[0] != '\0' && EchoLink != NULL) {
  623.                   EchoLink->Load (Data->EchoTag);
  624.                   if (EchoLink->Check (Address) == TRUE) {
  625.                      if (EchoLink->Passive == TRUE)
  626.                         sprintf (Temp, "%-30.30s (P) %.44s", Data->EchoTag, Data->Display);
  627.                      else
  628.                         sprintf (Temp, "%-30.30s %.48s", Data->EchoTag, Data->Display);
  629.                      Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  630.                      Total++;
  631.                   }
  632.                }
  633.             } while (Data->Next () == TRUE);
  634.          if (EchoLink != NULL)
  635.             delete EchoLink;
  636.          delete Data;
  637.       }
  638.       Text.Add ("");
  639.       sprintf (Temp, "%lu linked area(s).", Total);
  640.       Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  641.    }
  642.    else if (Type == 3) {
  643.       strcpy (Msg->Subject, "List of unlinked echomail areas");
  644.  
  645.       sprintf (Temp, "Area(s) not linked to %s:", Address);
  646.       Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  647.       Text.Add ("");
  648.       Total = 0L;
  649.       if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  650.          EchoLink = new TEchoLink (Cfg->SystemPath);
  651.          if (Data->First () == TRUE)
  652.             do {
  653.                if (Level < Data->Level)
  654.                   continue;
  655.                if ((AccessFlags & Data->Flags) != Data->Flags)
  656.                   continue;
  657.                if ((DenyFlags & Data->DenyFlags) != Data->DenyFlags && Data->DenyFlags != 0L)
  658.                   continue;
  659.                if (Data->EchoMail == TRUE && Data->EchoTag[0] != '\0' && EchoLink != NULL) {
  660.                   EchoLink->Load (Data->EchoTag);
  661.                   if (EchoLink->Check (Address) == FALSE) {
  662.                      sprintf (Temp, "%-30.30s %.48s", Data->EchoTag, Data->Display);
  663.                      Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  664.                      Total++;
  665.                   }
  666.                }
  667.             } while (Data->Next () == TRUE);
  668.          if (EchoLink != NULL)
  669.             delete EchoLink;
  670.          delete Data;
  671.       }
  672.       Text.Add ("");
  673.       sprintf (Temp, "%lu unlinked area(s).", Total);
  674.       Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  675.    }
  676.  
  677.    MsgFooter ();
  678.    Msg->Add (Text);
  679. }
  680.  
  681. VOID TAreaManager::ProcessAreafix (VOID)
  682. {
  683.    FILE *fp;
  684.    USHORT i, Ok, DoList, DoRescan, DoLinked, DoUnlinked, CanMaint;
  685.    USHORT DoListPacker, DoReport, DoHelp, Level, CanRename, MaxMsgs, Changed;
  686.    ULONG AccessFlags, DenyFlags;
  687.    CHAR Address[48], Temp[96], *Password, *p;
  688. //   class TPacker *Packer;
  689.  
  690.    CanMaint = FALSE;
  691.    Changed = FALSE;
  692.  
  693.    strcpy (Address, Msg->FromAddress);
  694.    if (Log != NULL)
  695.       Log->Write ("#  Process AreaMgr requests for %s", Address);
  696.  
  697.    strcpy (Temp, Msg->Subject);
  698.    if ((Password = strtok (Temp, " ")) == NULL)
  699.       Password = "";
  700.  
  701.    Ok = FALSE;
  702.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  703.       if (Nodes->Read (Address) == TRUE) {
  704.          Level = Nodes->Level;
  705.          AccessFlags = Nodes->AccessFlags;
  706.          DenyFlags = Nodes->DenyFlags;
  707.          CanMaint = Nodes->EchoMaint;
  708.          CanRename = Nodes->ChangeEchoTag;
  709.          if (!stricmp (Password, Nodes->AreaMgrPwd))
  710.             Ok = TRUE;
  711.       }
  712.       delete Nodes;
  713.    }
  714.  
  715.    if (Ok == TRUE) {
  716.       DoList = DoRescan = DoLinked = DoUnlinked = FALSE;
  717.       DoHelp = DoListPacker = FALSE;
  718.       DoReport = FALSE;
  719.       MaxMsgs = 0;
  720.  
  721.       strcpy (Temp, Msg->Subject);
  722.       if ((p = strtok (Temp, " ")) != NULL) {
  723.          while ((p = strtok (NULL, " ")) != NULL) {
  724.             if (!stricmp (p, "-l"))
  725.                DoList = TRUE;
  726.             else if (!stricmp (p, "-r"))
  727.                DoRescan = TRUE;
  728.          }
  729.       }
  730.  
  731.       Text.Clear ();
  732.       MsgHeader ();
  733.  
  734.       sprintf (Temp, "Following is a summary from %s of changes in Echomail topology:", Msg->ToAddress);
  735.       Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  736.       Text.Add ("");
  737.  
  738.       strcpy (Temp, Msg->FromAddress);
  739.       strcpy (Msg->FromAddress, Msg->ToAddress);
  740.       strcpy (Msg->ToAddress, Temp);
  741.       strcpy (Msg->To, Msg->From);
  742.       strcpy (Msg->From, "EchoMail Manager");
  743.  
  744.       if ((EchoLink = new TEchoLink (Cfg->SystemPath)) != NULL) {
  745.          if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  746.             do {
  747.                if ((p = strtok (p, " ")) != NULL) {
  748.                   if (*p == '%') {
  749.                      if (!stricmp (p, "%rescan"))
  750.                         DoRescan = TRUE;
  751.                      else if (!stricmp (p, "%msgs")) {
  752.                         if ((p = strtok (NULL, " ")) != NULL)
  753.                            MaxMsgs = (USHORT)atoi (p);
  754.                      }
  755.                      else if (!stricmp (p, "%help"))
  756.                         DoHelp = TRUE;
  757.                      else if (!stricmp (p, "%list"))
  758.                         DoList = TRUE;
  759.                      else if (!stricmp (p, "%unlinked"))
  760.                         DoUnlinked = TRUE;
  761.                      else if (!stricmp (p, "%linked") || !stricmp (p, "%query"))
  762.                         DoLinked = TRUE;
  763.                      else if (!stricmp (p, "%from")) {
  764.                         if (CanMaint == TRUE) {
  765.                            if (Changed == TRUE) {
  766.                               if (DoList == TRUE)
  767.                                  DoAreaListings (Address, 1, Level, AccessFlags, DenyFlags);
  768.                               if (DoLinked == TRUE)
  769.                                  DoAreaListings (Address, 2, Level, AccessFlags, DenyFlags);
  770.                               if (DoUnlinked == TRUE)
  771.                                  DoAreaListings (Address, 3, Level, AccessFlags, DenyFlags);
  772.                            }
  773.                            strcpy (Address, &p[6]);
  774.                            if (Log != NULL)
  775.                               Log->Write ("#Remote maintenance for %s", Address);
  776.                            sprintf (Temp, "Remote maintenance for %s", Address);
  777.                         }
  778.                         else
  779.                            sprintf (Temp, "Remote maintenance not allowed");
  780.                         Text.Add (Temp);
  781.                      }
  782.                      else if (!stricmp (p, "%packer")) {
  783.                         if ((p = strtok (NULL, " ")) != NULL)
  784.                            SetPacker (p);
  785.                         else
  786.                            DoListPacker = TRUE;
  787.                      }
  788.                      else if (!stricmp (p, "%passive")) {
  789.                         if (Passive (Address, TRUE) == TRUE)
  790.                            DoReport = TRUE;
  791.                      }
  792.                      else if (!stricmp (p, "%active")) {
  793.                         if (Passive (Address, FALSE) == TRUE)
  794.                            DoReport = TRUE;
  795.                      }
  796.                      else if (!stricmp (p, "%-all")) {
  797.                         if (RemoveAll (Address) == TRUE)
  798.                            DoReport = TRUE;
  799.                      }
  800.                      else if (!stricmp (p, "%pwd")) {
  801.                         if ((p = strtok (NULL, " ")) != NULL) {
  802.                            if (SetPwd (Address, p) == TRUE)
  803.                               DoReport = TRUE;
  804.                         }
  805.                      }
  806.                      else if (!stricmp (p, "%sessionpwd")) {
  807.                         if ((p = strtok (NULL, " ")) != NULL) {
  808.                            if (SetSessionPwd (Address, p) == TRUE)
  809.                               DoReport = TRUE;
  810.                         }
  811.                      }
  812.                      else if (!stricmp (p, "%pktpwd")) {
  813.                         p = strtok (NULL, " ");
  814.                         if (SetPacketPwd (Address, p) == TRUE)
  815.                            DoReport = TRUE;
  816.                      }
  817.                      else if (!stricmp (p, "%inpktpwd")) {
  818.                         p = strtok (NULL, " ");
  819.                         if (SetInPacketPwd (Address, p) == TRUE)
  820.                            DoReport = TRUE;
  821.                      }
  822.                      else if (!stricmp (p, "%outpktpwd")) {
  823.                         p = strtok (NULL, " ");
  824.                         if (SetOutPacketPwd (Address, p) == TRUE)
  825.                            DoReport = TRUE;
  826.                      }
  827.                   }
  828.                   else if (*p == '#') {
  829.                      if (CanRename == TRUE) {
  830.                         if ((p = strtok (NULL, " :")) != NULL) {
  831.                            if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  832.                               if (Data->ReadEcho (p) == TRUE) {
  833.                                  if ((p = strtok (NULL, " :")) != NULL) {
  834.                                     if (Log != NULL)
  835.                                        Log->Write ("#Area %s changed to %s", Data->EchoTag, p);
  836.                                     sprintf (Temp, "Area %s changed to %s", Data->EchoTag, p);
  837.                                     Text.Add (Temp);
  838.                                     // Cambia il tag nel file dei forward
  839.                                     EchoLink->Change (Data->EchoTag, p);
  840.                                     // Cambia il tag nella configurazione dell'area
  841.                                     strcpy (Data->EchoTag, p);
  842.                                     Data->Update ();
  843.                                  }
  844.                               }
  845.                               delete Data;
  846.                            }
  847.                         }
  848.                      }
  849.                      else
  850.                         Text.Add ("Remote maintenance not allowed");
  851.                   }
  852.                   else if (*p == '-' && strcmp (p, "---")) {
  853.                      p++;
  854.                      if (RemoveArea (Address, p) == FALSE)
  855.                         sprintf (Temp, "Area %s never linked.", strupr (p));
  856.                      else
  857.                         sprintf (Temp, "Area %s has been removed.", strupr (p));
  858.                      Text.Add (Temp);
  859.                      Changed = DoReport = TRUE;
  860.                   }
  861.                   else if (*p != '\0' && strcmp (p, "---") && *p != '\001') {
  862.                      if (*p == '+')
  863.                         p++;
  864.                      if ((i = AddArea (Address, p)) == TRUE)
  865.                         sprintf (Temp, "Area %s has been added%s.\n", strupr (p), (DoRescan == TRUE) ? ", and rescanned" : "");
  866.                      else if (i == NOT_FOUND)
  867.                         sprintf (Temp, "Area %s not found.\n", strupr (p));
  868.                      else if (i == ALREADY_LINKED)
  869.                         sprintf (Temp, "Area %s already linked%s.\n", strupr (p), (DoRescan == TRUE) ? ", rescanned" : "");
  870.                      Text.Add (Temp);
  871.                      Changed = DoReport = TRUE;
  872.  
  873.                      if (i != NOT_FOUND && DoRescan == TRUE) {
  874.                         if ((fp = fopen ("rescan.log", "at")) != NULL) {
  875.                            fprintf (fp, "%s %s %d\n", p, Address, MaxMsgs);
  876.                            fclose (fp);
  877.                         }
  878.                      }
  879.                   }
  880.                }
  881.             } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  882.          delete EchoLink;
  883.       }
  884.  
  885.       if (DoReport == TRUE) {
  886.          MsgFooter ();
  887.          strcpy (Msg->Subject, "EchoMail changes report");
  888.          Msg->Text.Clear ();
  889.          Msg->Local = TRUE;
  890.          Msg->Crash = Msg->Direct = Msg->Hold = FALSE;
  891.          Msg->Sent = FALSE;
  892.          Msg->Add (Text);
  893.  
  894.          // Invia le notifiche dei cambiamenti ai nodi indicati
  895.          if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  896.             strcpy (Temp, Msg->ToAddress);
  897.             if (Nodes->First () == TRUE)
  898.                do {
  899.                   if (Nodes->NotifyAreafix == TRUE && stricmp (Temp, Nodes->Address)) {
  900.                      strcpy (Msg->To, Nodes->SysopName);
  901.                      if (Msg->To[0] == '\0')
  902.                         strcpy (Msg->To, "Sysop");
  903.                      strcpy (Msg->ToAddress, Nodes->Address);
  904.                      Msg->Add (Text);
  905.                      if (Log != NULL)
  906.                         Log->Write ("-Sent notification to %s (%s)", Msg->To, Msg->ToAddress);
  907.                   }
  908.                } while (Nodes->Next () == TRUE);
  909.             delete Nodes;
  910.          }
  911.  
  912.          if (Cfg->UpdateAreasBBS == TRUE)
  913.             UpdateAreasBBS ();
  914.       }
  915.  
  916.       if (DoList == TRUE)
  917.          DoAreaListings (Address, 1, Level, AccessFlags, DenyFlags);
  918.       if (DoLinked == TRUE)
  919.          DoAreaListings (Address, 2, Level, AccessFlags, DenyFlags);
  920.       if (DoUnlinked == TRUE)
  921.          DoAreaListings (Address, 3, Level, AccessFlags, DenyFlags);
  922.  
  923.       if (DoHelp == TRUE) {
  924.          strcpy (Msg->Subject, "Areafix help");
  925.          Text.Clear ();
  926.          MsgHeader ();
  927.  
  928.          if (Cfg->AreafixHelp[0] != '\0')
  929.             strcpy (Temp, Cfg->AreafixHelp);
  930.          else
  931.             sprintf (Temp, "%safxhelp.txt", Cfg->SystemPath);
  932.          if ((fp = fopen (Temp, "rt")) != NULL) {
  933.             while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  934.                Temp[strlen (Temp) - 1] = '\0';
  935.                Text.Add (Temp);
  936.             }
  937.             fclose (fp);
  938.          }
  939.          else {
  940.             Text.Add ("");
  941.             Text.Add ("No help file available. Contact the Sysop.");
  942.             Text.Add ("");
  943.          }
  944.  
  945.          MsgFooter ();
  946.          Msg->Add (Text);
  947.       }
  948.    }
  949.    else {
  950.       Text.Clear ();
  951.       MsgHeader ();
  952.  
  953.       if (Log != NULL)
  954.          Log->Write ("!Node %s is not authorized for echomanager", Msg->FromAddress);
  955.  
  956.       Text.Add ("");
  957.       sprintf (Temp, "Node %s isn't authorized to use areafix at %s", Msg->FromAddress, Msg->ToAddress);
  958.       Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  959.       Text.Add ("");
  960.  
  961.       strcpy (Temp, Msg->FromAddress);
  962.       strcpy (Msg->FromAddress, Msg->ToAddress);
  963.       strcpy (Msg->ToAddress, Temp);
  964.       strcpy (Msg->To, Msg->From);
  965.       strcpy (Msg->From, "Echo Manager");
  966.       strcpy (Msg->Subject, "EchoMail changes report");
  967.       Msg->Text.Clear ();
  968.       Msg->Local = TRUE;
  969.       Msg->Crash = Msg->Direct = Msg->Hold = FALSE;
  970.  
  971.       MsgFooter ();
  972.       Msg->Add (Text);
  973.  
  974.       // Invia le notifiche dei cambiamenti ai nodi indicati
  975.       if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  976.          strcpy (Temp, Msg->ToAddress);
  977.          if (Nodes->First () == TRUE)
  978.             do {
  979.                if (Nodes->NotifyAreafix == TRUE && stricmp (Temp, Nodes->Address)) {
  980.                   strcpy (Msg->To, Nodes->SysopName);
  981.                   if (Msg->To[0] == '\0')
  982.                      strcpy (Msg->To, "Sysop");
  983.                   strcpy (Msg->ToAddress, Nodes->Address);
  984.                   Msg->Add (Text);
  985.                   if (Log != NULL)
  986.                      Log->Write ("-Sent notification to %s (%s)", Msg->To, Msg->ToAddress);
  987.                }
  988.             } while (Nodes->Next () == TRUE);
  989.          delete Nodes;
  990.       }
  991.    }
  992. }
  993.  
  994. USHORT TAreaManager::FilePassive (PSZ address, USHORT flag)
  995. {
  996.    USHORT RetVal = FALSE;
  997.    CHAR Temp[96];
  998.  
  999.    if ((FileData = new TFileData (Cfg->SystemPath)) != NULL) {
  1000.       if (FileData->First () == TRUE)
  1001.          do {
  1002.             if (FileData->EchoTag[0] != '\0') {
  1003.                FileEchoLink->Load (FileData->EchoTag);
  1004.                if (FileEchoLink->Check (address) == TRUE) {
  1005.                   if (FileEchoLink->Passive != flag) {
  1006.                      FileEchoLink->Passive = (UCHAR)flag;
  1007.                      FileEchoLink->Update ();
  1008.                      FileEchoLink->Save ();
  1009.                      sprintf (Temp, "Area %s is now %s.", strupr (FileData->EchoTag), (flag == TRUE) ? "passive" : "active");
  1010.                   }
  1011.                   else
  1012.                      sprintf (Temp, "Area %s already %s.", strupr (FileData->EchoTag), (flag == TRUE) ? "passive" : "active");
  1013.                   Text.Add (Temp);
  1014.                   RetVal = TRUE;
  1015.                }
  1016.             }
  1017.          } while (FileData->Next () == TRUE);
  1018.       delete FileData;
  1019.    }
  1020.  
  1021.    return (RetVal);
  1022. }
  1023.  
  1024. USHORT TAreaManager::FileRemoveAll (PSZ address)
  1025. {
  1026.    USHORT RetVal = FALSE;
  1027.    CHAR Temp[96];
  1028.  
  1029.    if ((FileData = new TFileData (Cfg->SystemPath)) != NULL) {
  1030.       if (FileData->First () == TRUE)
  1031.          do {
  1032.             if (FileData->EchoTag[0] != '\0') {
  1033.                FileEchoLink->Load (FileData->EchoTag);
  1034.                if (FileEchoLink->Check (address) == TRUE) {
  1035.                   FileEchoLink->Delete ();
  1036.                   FileEchoLink->Save ();
  1037.                   sprintf (Temp, "Area %s has been removed.", strupr (FileData->EchoTag));
  1038.                   Text.Add (Temp);
  1039.                   RetVal = TRUE;
  1040.                }
  1041.             }
  1042.          } while (FileData->Next () == TRUE);
  1043.       delete FileData;
  1044.    }
  1045.  
  1046.    return (RetVal);
  1047. }
  1048.  
  1049. VOID TAreaManager::ProcessRaid (VOID)
  1050. {
  1051.    FILE *fp;
  1052.    USHORT Ok, DoList, DoLinked, DoUnlinked, Found;
  1053.    USHORT DoReport, DoHelp, CanMaint, CanRename;
  1054.    CHAR Address[48], Temp[96], *Password, *p;
  1055.    ULONG Total;
  1056.  
  1057.    if (Log != NULL)
  1058.       Log->Write ("#Process Raid requests for %s", Msg->FromAddress);
  1059.    strcpy (Address, Msg->FromAddress);
  1060.  
  1061.    strcpy (Temp, Msg->Subject);
  1062.    if ((Password = strtok (Temp, " ")) == NULL)
  1063.       Password = "";
  1064.  
  1065.    CanMaint = FALSE;
  1066.    CanRename = FALSE;
  1067.  
  1068.    Ok = FALSE;
  1069.    if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  1070.       if (Nodes->Read (Address) == TRUE) {
  1071.          CanMaint = Nodes->TicMaint;
  1072.          CanRename = Nodes->ChangeTicTag;
  1073.          if (!stricmp (Password, Nodes->AreaMgrPwd))
  1074.             Ok = TRUE;
  1075.       }
  1076.       delete Nodes;
  1077.    }
  1078.  
  1079.    if (Ok == TRUE) {
  1080.       DoHelp = DoList = DoLinked = DoUnlinked = FALSE;
  1081.       DoReport = FALSE;
  1082.  
  1083.       strcpy (Temp, Msg->Subject);
  1084.       if ((p = strtok (Temp, " ")) != NULL) {
  1085.          while ((p = strtok (NULL, " ")) != NULL) {
  1086.             if (!stricmp (p, "-l"))
  1087.                DoList = TRUE;
  1088.          }
  1089.       }
  1090.  
  1091.       Text.Clear ();
  1092.       MsgHeader ();
  1093.  
  1094.       sprintf (Temp, "Following is a summary from %s of changes in Fileecho topology:", Msg->ToAddress);
  1095.       Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1096.       Text.Add ("");
  1097.  
  1098.       strcpy (Temp, Msg->FromAddress);
  1099.       strcpy (Msg->FromAddress, Msg->ToAddress);
  1100.       strcpy (Msg->ToAddress, Temp);
  1101.       strcpy (Msg->To, Msg->From);
  1102.       strcpy (Msg->From, "Tic Manager");
  1103.  
  1104.       if ((FileEchoLink = new TFilechoLink (Cfg->SystemPath)) != NULL) {
  1105.          if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  1106.             do {
  1107.                if ((p = strtok (p, " ")) != NULL) {
  1108.                   if (*p == '%') {
  1109.                      if (!stricmp (p, "%list"))
  1110.                         DoList = TRUE;
  1111.                      else if (!stricmp (p, "%unlinked"))
  1112.                         DoUnlinked = TRUE;
  1113.                      else if (!stricmp (p, "%linked"))
  1114.                         DoLinked = TRUE;
  1115.                      else if (!stricmp (p, "%help"))
  1116.                         DoHelp = TRUE;
  1117.                      else if (!stricmp (p, "%from")) {
  1118.                         if (CanMaint == TRUE) {
  1119.                            strcpy (Address, &p[6]);
  1120.                            if (Log != NULL)
  1121.                               Log->Write ("#Remote maintenance for %s", Address);
  1122.                            sprintf (Temp, "Remote maintenance for %s", Address);
  1123.                         }
  1124.                         else
  1125.                            sprintf (Temp, "Remote maintenance not allowed");
  1126.                         Text.Add (Temp);
  1127.                      }
  1128.                      else if (!stricmp (p, "%passive")) {
  1129.                         if (FilePassive (Address, TRUE) == TRUE)
  1130.                            DoReport = TRUE;
  1131.                      }
  1132.                      else if (!stricmp (p, "%active")) {
  1133.                         if (FilePassive (Address, FALSE) == TRUE)
  1134.                            DoReport = TRUE;
  1135.                      }
  1136.                      else if (!stricmp (p, "%-all")) {
  1137.                         if (FileRemoveAll (Address) == TRUE)
  1138.                            DoReport = TRUE;
  1139.                      }
  1140.                      else if (!stricmp (p, "%pwd")) {
  1141.                         if ((p = strtok (NULL, " ")) != NULL) {
  1142.                            if (SetPwd (Address, p) == TRUE)
  1143.                               DoReport = TRUE;
  1144.                         }
  1145.                      }
  1146.                      else if (!stricmp (p, "%sessionpwd")) {
  1147.                         if ((p = strtok (NULL, " ")) != NULL) {
  1148.                            if (SetSessionPwd (Address, p) == TRUE)
  1149.                               DoReport = TRUE;
  1150.                         }
  1151.                      }
  1152.                      else if (!stricmp (p, "%pktpwd")) {
  1153.                         p = strtok (NULL, " ");
  1154.                         if (SetPacketPwd (Address, p) == TRUE)
  1155.                            DoReport = TRUE;
  1156.                      }
  1157.                      else if (!stricmp (p, "%inpktpwd")) {
  1158.                         p = strtok (NULL, " ");
  1159.                         if (SetInPacketPwd (Address, p) == TRUE)
  1160.                            DoReport = TRUE;
  1161.                      }
  1162.                      else if (!stricmp (p, "%outpktpwd")) {
  1163.                         p = strtok (NULL, " ");
  1164.                         if (SetOutPacketPwd (Address, p) == TRUE)
  1165.                            DoReport = TRUE;
  1166.                      }
  1167.                   }
  1168.                   else if (*p == '#') {
  1169.                      if (CanRename == TRUE) {
  1170.                         if ((p = strtok (NULL, " :")) != NULL) {
  1171.                            if ((FileData = new TFileData (Cfg->SystemPath)) != NULL) {
  1172.                               if (FileData->ReadEcho (p) == TRUE) {
  1173.                                  if ((p = strtok (NULL, " :")) != NULL) {
  1174.                                     if (Log != NULL)
  1175.                                        Log->Write ("#Area %s changed to %s", FileData->EchoTag, p);
  1176.                                     sprintf (Temp, "Area %s changed to %s", FileData->EchoTag, p);
  1177.                                     Text.Add (Temp);
  1178.                                     // Cambia il tag nel file dei forward
  1179.                                     FileEchoLink->Change (FileData->EchoTag, p);
  1180.                                     // Cambia il tag nella configurazione dell'area
  1181.                                     strcpy (FileData->EchoTag, p);
  1182.                                     FileData->Update ();
  1183.                                  }
  1184.                               }
  1185.                               delete FileData;
  1186.                            }
  1187.                         }
  1188.                      }
  1189.                      else
  1190.                         Text.Add ("Remote maintenance not allowed");
  1191.                   }
  1192.                   else if (*p == '-' && strcmp (p, "---")) {
  1193.                      p++;
  1194.                      FileEchoLink->Load (p);
  1195.                      if (FileEchoLink->First () == TRUE) {
  1196.                         if (FileEchoLink->Check (Address) == TRUE) {
  1197.                            FileEchoLink->Delete ();
  1198.                            FileEchoLink->Save ();
  1199.                            sprintf (Temp, "Area %s has been removed.", strupr (p));
  1200.                         }
  1201.                         else
  1202.                            sprintf (Temp, "Area %s never linked.", strupr (p));
  1203.                      }
  1204.                      else
  1205.                         sprintf (Temp, "Area %s never linked.", strupr (p));
  1206.                      Text.Add (Temp);
  1207.                      DoReport = TRUE;
  1208.                   }
  1209.                   else if (*p != '\0' && strcmp (p, "---") && *p != '\001') {
  1210.                      if (*p == '+')
  1211.                         p++;
  1212.                      FileEchoLink->Load (p);
  1213.                      if (FileEchoLink->First () == TRUE) {
  1214.                         if (FileEchoLink->Check (Address) == TRUE)
  1215.                            sprintf (Temp, "Area %s already linked.\n", strupr (p));
  1216.                         else {
  1217.                            FileEchoLink->AddString (Address);
  1218.                            FileEchoLink->Save ();
  1219.                            sprintf (Temp, "Area %s has been added.\n", strupr (p));
  1220.                         }
  1221.                      }
  1222.                      else {
  1223.                         Found = FALSE;
  1224.                         if ((FileData = new TFileData (Cfg->SystemPath)) != NULL) {
  1225.                            if (FileData->ReadEcho (p) == TRUE) {
  1226.                               FileEchoLink->Load (FileData->EchoTag);
  1227.                               FileEchoLink->AddString (Address);
  1228.                               FileEchoLink->Save ();
  1229.                               sprintf (Temp, "Area %s has been added.\n", strupr (p));
  1230.                               Found = TRUE;
  1231.                            }
  1232.                            delete Data;
  1233.                         }
  1234.                         if (Found == FALSE)
  1235.                            sprintf (Temp, "Area %s not found.\n", strupr (p));
  1236.                      }
  1237.                      Text.Add (Temp);
  1238.                      DoReport = TRUE;
  1239.                   }
  1240.                }
  1241.             } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  1242.          delete FileEchoLink;
  1243.       }
  1244.  
  1245.       if (DoReport == TRUE) {
  1246.          MsgFooter ();
  1247.          strcpy (Msg->Subject, "Tic changes report");
  1248.          Msg->Text.Clear ();
  1249.          Msg->Local = TRUE;
  1250.          Msg->Crash = Msg->Direct = Msg->Hold = FALSE;
  1251.          Msg->Sent = FALSE;
  1252.          Msg->Add (Text);
  1253.       }
  1254.  
  1255.       if (DoList == TRUE) {
  1256.          Total = 0L;
  1257.          strcpy (Msg->Subject, "List of available Tic areas");
  1258.          Text.Clear ();
  1259.          MsgHeader ();
  1260.  
  1261.          sprintf (Temp, "Area(s) available to %s:", Msg->ToAddress);
  1262.          Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1263.          Text.Add ("");
  1264.          if ((FileData = new TFileData (Cfg->SystemPath)) != NULL) {
  1265.             if (FileData->First () == TRUE)
  1266.                do {
  1267.                   if (FileData->EchoTag[0] != '\0') {
  1268.                      sprintf (Temp, "%-30.30s %.48s", FileData->EchoTag, FileData->Display);
  1269.                      Text.Add (Temp);
  1270.                      Total++;
  1271.                   }
  1272.                } while (FileData->Next () == TRUE);
  1273.             delete FileData;
  1274.          }
  1275.          Text.Add ("");
  1276.          sprintf (Temp, "%lu available area(s).", Total);
  1277.          Text.Add (Temp);
  1278.  
  1279.          MsgFooter ();
  1280.          Msg->Add (Text);
  1281.       }
  1282.  
  1283.       if (DoLinked == TRUE) {
  1284.          strcpy (Msg->Subject, "List of linked Tic areas");
  1285.          Text.Clear ();
  1286.          MsgHeader ();
  1287.  
  1288.          sprintf (Temp, "%s is now linked to the following area(s):", Msg->ToAddress);
  1289.          Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1290.          Text.Add ("");
  1291.          Total = 0L;
  1292.          if ((FileData = new TFileData (Cfg->SystemPath)) != NULL) {
  1293.             FileEchoLink = new TFilechoLink (Cfg->SystemPath);
  1294.             if (FileData->First () == TRUE)
  1295.                do {
  1296.                   if (FileData->EchoTag[0] != '\0' && FileEchoLink != NULL) {
  1297.                      FileEchoLink->Load (FileData->EchoTag);
  1298.                      if (FileEchoLink->Check (Msg->ToAddress) == TRUE) {
  1299.                         sprintf (Temp, "%-30.30s %.48s", FileData->EchoTag, FileData->Display);
  1300.                         Text.Add (Temp);
  1301.                         Total++;
  1302.                      }
  1303.                   }
  1304.                } while (FileData->Next () == TRUE);
  1305.             if (FileEchoLink != NULL)
  1306.                delete FileEchoLink;
  1307.             delete FileData;
  1308.          }
  1309.          Text.Add ("");
  1310.          sprintf (Temp, "%lu linked area(s).", Total);
  1311.          Text.Add (Temp);
  1312.  
  1313.          MsgFooter ();
  1314.          Msg->Add (Text);
  1315.       }
  1316.  
  1317.       if (DoUnlinked == TRUE) {
  1318.          strcpy (Msg->Subject, "List of unlinked Tic areas");
  1319.          Text.Clear ();
  1320.          MsgHeader ();
  1321.  
  1322.          sprintf (Temp, "Area(s) not linked to %s:", Msg->ToAddress);
  1323.          Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1324.          Text.Add ("");
  1325.          Total = 0L;
  1326.          if ((FileData = new TFileData (Cfg->SystemPath)) != NULL) {
  1327.             FileEchoLink = new TFilechoLink (Cfg->SystemPath);
  1328.             if (FileData->First () == TRUE)
  1329.                do {
  1330.                   if (FileData->EchoTag[0] != '\0' && FileEchoLink != NULL) {
  1331.                      FileEchoLink->Load (FileData->EchoTag);
  1332.                      if (FileEchoLink->Check (Msg->ToAddress) == FALSE) {
  1333.                         sprintf (Temp, "%-30.30s %.48s", FileData->EchoTag, FileData->Display);
  1334.                         Text.Add (Temp);
  1335.                         Total++;
  1336.                      }
  1337.                   }
  1338.                } while (FileData->Next () == TRUE);
  1339.             if (FileEchoLink != NULL)
  1340.                delete FileEchoLink;
  1341.             delete FileData;
  1342.          }
  1343.          Text.Add ("");
  1344.          sprintf (Temp, "%lu unlinked area(s).", Total);
  1345.          Text.Add (Temp);
  1346.          MsgFooter ();
  1347.  
  1348.          Msg->Add (Text);
  1349.       }
  1350.  
  1351.       if (DoHelp == TRUE) {
  1352.          strcpy (Msg->Subject, "TIC Manager help");
  1353.          Text.Clear ();
  1354.          MsgHeader ();
  1355.  
  1356.          if (Cfg->RaidHelp[0] != '\0')
  1357.             strcpy (Temp, Cfg->RaidHelp);
  1358.          else
  1359.             sprintf (Temp, "%sraidhelp.txt", Cfg->SystemPath);
  1360.          if ((fp = fopen (Temp, "rt")) != NULL) {
  1361.             while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  1362.                Temp[strlen (Temp) - 1] = '\0';
  1363.                Text.Add (Temp);
  1364.             }
  1365.             fclose (fp);
  1366.          }
  1367.          else {
  1368.             Text.Add ("");
  1369.             Text.Add ("No help file available. Contact the Sysop.");
  1370.             Text.Add ("");
  1371.          }
  1372.  
  1373.          MsgFooter ();
  1374.          Msg->Add (Text);
  1375.       }
  1376.    }
  1377.    else {
  1378.       Text.Clear ();
  1379.       MsgHeader ();
  1380.  
  1381.       Text.Add ("");
  1382.       sprintf (Temp, "Node %s isn't authorized to use raid at %s", Address, Msg->ToAddress);
  1383.       Text.Add (Temp);
  1384.       Text.Add ("");
  1385.  
  1386.       strcpy (Temp, Msg->FromAddress);
  1387.       strcpy (Msg->FromAddress, Msg->ToAddress);
  1388.       strcpy (Msg->ToAddress, Temp);
  1389.       strcpy (Msg->To, Msg->From);
  1390.       strcpy (Msg->From, "Tic Manager");
  1391.       strcpy (Msg->Subject, "Tic changes report");
  1392.       Msg->Text.Clear ();
  1393.       Msg->Local = TRUE;
  1394.       Msg->Crash = Msg->Direct = Msg->Hold = FALSE;
  1395.  
  1396.       MsgFooter ();
  1397.       Msg->Add (Text);
  1398.    }
  1399. }
  1400.  
  1401. VOID TAreaManager::Rescan (PSZ pszEchoTag, PSZ pszAddress, USHORT MaxMsgs)
  1402. {
  1403.    CHAR Temp[128], Outbound[64], *Text;
  1404.    ULONG Number;
  1405.    struct stat statbuf;
  1406.    class TMsgData *Data;
  1407.    class TMsgBase *Msg;
  1408.    class TAddress Forward;
  1409.    class PACKET *Packet;
  1410.    class TKludges *SeenBy, *Path;
  1411.  
  1412.    if (Status != NULL)
  1413.       Status->SetLine (0, "Scanning %s", pszEchoTag);
  1414.  
  1415.    strcpy (Outbound, Cfg->Outbound);
  1416.    Outbound[strlen (Outbound) - 1] = '\0';
  1417.  
  1418.    Forward.Parse (pszAddress);
  1419.  
  1420.    if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  1421.       if (Data->ReadEcho (pszEchoTag) == TRUE) {
  1422.          Msg = NULL;
  1423.          if (Data->Storage == ST_JAM)
  1424.             Msg = new JAM (Data->Path);
  1425.          else if (Data->Storage == ST_SQUISH)
  1426.             Msg = new SQUISH (Data->Path);
  1427.          else if (Data->Storage == ST_FIDO)
  1428.             Msg = new FIDOSDM (Data->Path);
  1429.          else if (Data->Storage == ST_ADEPT)
  1430.             Msg = new ADEPT (Data->Path);
  1431.          else if (Data->Storage == ST_HUDSON)
  1432.             Msg = new HUDSON (Data->Path, (UCHAR)Data->Board);
  1433.  
  1434.          if (Msg != NULL) {
  1435.             if ((Packet = new PACKET) != NULL) {
  1436.                strcpy (Packet->ToAddress, Forward.String);
  1437.  
  1438.                if (Data->Address[0] != '\0')
  1439.                   strcpy (Packet->FromAddress, Data->Address);
  1440.                else {
  1441.                   if (Cfg->MailAddress.First () == TRUE) {
  1442.                      strcpy (Packet->FromAddress, Cfg->MailAddress.String);
  1443.                      do {
  1444.                         if (Cfg->MailAddress.Zone == Forward.Zone) {
  1445.                            strcpy (Packet->FromAddress, Cfg->MailAddress.String);
  1446.                            break;
  1447.                         }
  1448.                      } while (Cfg->MailAddress.Next () == TRUE);
  1449.                   }
  1450.                }
  1451.  
  1452.                Cfg->MailAddress.First ();
  1453.                if (Cfg->MailAddress.Zone == Forward.Zone) {
  1454.                   if (Forward.Point != 0) {
  1455. #if defined(__LINUX__)
  1456.                      sprintf (Temp, "%s/%04x%04x.pnt", Outbound, Forward.Net, Forward.Node);
  1457.                      mkdir (Temp, 0666);
  1458.                      sprintf (Temp, "%s/%04x%04x.pnt/%08x.xpr", Outbound, Forward.Net, Forward.Node, Forward.Point);
  1459. #else
  1460.                      sprintf (Temp, "%s\\%04x%04x.pnt", Outbound, Forward.Net, Forward.Node);
  1461.                      mkdir (Temp);
  1462.                      sprintf (Temp, "%s\\%04x%04x.pnt\\%08x.xpr", Outbound, Forward.Net, Forward.Node, Forward.Point);
  1463. #endif
  1464.                   }
  1465.                   else
  1466. #if defined(__LINUX__)
  1467.                      sprintf (Temp, "%s/%04x%04x.xpr", Outbound, Forward.Net, Forward.Node);
  1468. #else
  1469.                      sprintf (Temp, "%s\\%04x%04x.xpr", Outbound, Forward.Net, Forward.Node);
  1470. #endif
  1471.                }
  1472.                else {
  1473.                   sprintf (Temp, "%s.%03x", Outbound, Forward.Zone);
  1474. #if defined(__LINUX__)
  1475.                   mkdir (Temp, 0666);
  1476. #else
  1477.                   mkdir (Temp);
  1478. #endif
  1479.                   if (Forward.Point != 0) {
  1480. #if defined(__LINUX__)
  1481.                      sprintf (Temp, "%s.%03x/%04x%04x.pnt", Outbound, Forward.Zone, Forward.Net, Forward.Node);
  1482.                      mkdir (Temp, 0666);
  1483.                      sprintf (Temp, "%s.%03x/%04x%04x.pnt/%08x.xpr", Outbound, Forward.Zone, Forward.Net, Forward.Node, Forward.Point);
  1484. #else
  1485.                      sprintf (Temp, "%s.%03x\\%04x%04x.pnt", Outbound, Forward.Zone, Forward.Net, Forward.Node);
  1486.                      mkdir (Temp);
  1487.                      sprintf (Temp, "%s.%03x\\%04x%04x.pnt\\%08x.xpr", Outbound, Forward.Zone, Forward.Net, Forward.Node, Forward.Point);
  1488. #endif
  1489.                   }
  1490.                   else
  1491. #if defined(__LINUX__)
  1492.                      sprintf (Temp, "%s.%03x/%04x%04x.xpr", Outbound, Forward.Zone, Forward.Net, Forward.Node);
  1493. #else
  1494.                      sprintf (Temp, "%s.%03x\\%04x%04x.xpr", Outbound, Forward.Zone, Forward.Net, Forward.Node);
  1495. #endif
  1496.                }
  1497.  
  1498.                if (stat (Temp, &statbuf) != 0) {
  1499.                   if ((Nodes = new TNodes (Cfg->NodelistPath)) != NULL) {
  1500.                      if (Nodes->Read (Forward.String) == TRUE)
  1501.                         strcpy (Packet->Password, Nodes->OutPktPwd);
  1502.                      delete Nodes;
  1503.                      Nodes = NULL;
  1504.                   }
  1505.                }
  1506.  
  1507.                if (Log != NULL)
  1508.                   Log->Write ("#Rescan area %s for %s (%lu messages)", pszEchoTag, pszAddress, Msg->Number ());
  1509.  
  1510.                if (Packet->Open (Temp, FALSE) == TRUE) {
  1511.                   Number = Msg->Lowest ();
  1512.                   // Se e' stato specificato un numero massimo di messaggi per il
  1513.                   // rescan, limita il rescan agli ultimi MaxMsgs messaggi.
  1514.                   if (Msg->Number () > MaxMsgs && MaxMsgs != 0)
  1515.                      Number = Msg->MsgnToUid (Msg->Number () - MaxMsgs);
  1516.                   // Evita di esportare il messaggio #1 delle basi Fido (l'high water mark)
  1517.                   if (Number == 1L && Data->Storage == ST_FIDO) {
  1518.                      if (Msg->Next (Number) == FALSE)
  1519.                         Number = 0L;
  1520.                   }
  1521.                   do {
  1522.                      if (Status != NULL)
  1523.                         Status->SetLine (1, "   %lu / %lu", Msg->UidToMsgn (Number), Msg->Number ());
  1524.                      if (Msg->Read (Number) == TRUE) {
  1525.                         sprintf (Temp, "AREA:%s", Data->EchoTag);
  1526.                         if ((Text = (PSZ)Msg->Text.First ()) != NULL) {
  1527.                            Msg->Text.Insert (Temp, (USHORT)(strlen (Temp) + 1));
  1528.                            if (*Text != '\0')
  1529.                               Msg->Text.Insert (Text, (USHORT)(strlen (Text) + 1));
  1530.                            Msg->Text.First ();
  1531.                            Msg->Text.Remove ();
  1532.                         }
  1533.                         else
  1534.                            Msg->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1535.  
  1536.                         SeenBy = new TKludges;
  1537.                         Path = new TKludges;
  1538.  
  1539.                         if (SeenBy != NULL && Path != NULL) {
  1540.                            Path->Sort = FALSE;
  1541.                            if ((Text = (PSZ)Msg->Text.First ()) != NULL)
  1542.                               do {
  1543.                                  if (!strncmp (Text, "SEEN-BY: ", 9) && SeenBy != NULL) {
  1544.                                     SeenBy->AddString (&Text[9]);
  1545.                                     Msg->Text.Remove ();
  1546.                                     Text = (PSZ)Msg->Text.Value ();
  1547.                                  }
  1548.                                  else if (!strncmp (Text, "\001PATH: ", 7) && Path != NULL) {
  1549.                                     Path->AddString (&Text[7]);
  1550.                                     Msg->Text.Remove ();
  1551.                                     Text = (PSZ)Msg->Text.Value ();
  1552.                                  }
  1553.                                  else {
  1554.                                     if (Msg->Local == TRUE && Cfg->ReplaceTear == TRUE) {
  1555.                                        if (!strncmp (Text, "---", 3)) {
  1556.                                           sprintf (Temp, "--- %s", Cfg->TearLine);
  1557.                                           strsrep (Temp, "%1", VERSION);
  1558.                                           Msg->Text.Replace (Temp, (USHORT)(strlen (Temp) + 1));
  1559.                                        }
  1560.                                     }
  1561.                                     Text = (PSZ)Msg->Text.Next ();
  1562.                                  }
  1563.                               } while (Text != NULL);
  1564.  
  1565.                            SeenBy->AddString (Forward.String);
  1566.  
  1567.                            if (Data->Address[0] != '\0') {
  1568.                               SeenBy->AddString (Data->Address);
  1569.                               Path->AddString (Data->Address);
  1570.                            }
  1571.                            else if (Cfg->MailAddress.First () == TRUE) {
  1572.                               SeenBy->AddString (Cfg->MailAddress.String);
  1573.                               Path->AddString (Cfg->MailAddress.String);
  1574.                            }
  1575.  
  1576.                            if (SeenBy->First () == TRUE) {
  1577.                               strcpy (Temp, "SEEN-BY:");
  1578.                               do {
  1579.                                  if (strlen (Temp) + strlen (SeenBy->ShortAddress) + 1 > 70) {
  1580.                                     Msg->Text.Add (Temp);
  1581.                                     strcpy (Temp, "SEEN-BY:");
  1582.                                     strcpy (SeenBy->ShortAddress, SeenBy->Address);
  1583.                                  }
  1584.                                  if (SeenBy->Net != Cfg->FakeNet && SeenBy->Point == 0) {
  1585.                                     strcat (Temp, " ");
  1586.                                     strcat (Temp, SeenBy->ShortAddress);
  1587.                                  }
  1588.                               } while (SeenBy->Next () == TRUE);
  1589.                               if (strlen (Temp) > 8)
  1590.                                  Msg->Text.Add (Temp);
  1591.                            }
  1592.  
  1593.                            if (Path->First () == TRUE) {
  1594.                               strcpy (Temp, "\001PATH:");
  1595.                               do {
  1596.                                  if (strlen (Temp) + strlen (Path->ShortAddress) + 1 > 70) {
  1597.                                     Msg->Text.Add (Temp);
  1598.                                     strcpy (Temp, "\001PATH:");
  1599.                                     strcpy (Path->ShortAddress, SeenBy->Address);
  1600.                                  }
  1601.                                  if (Path->Point == 0) {
  1602.                                     strcat (Temp, " ");
  1603.                                     strcat (Temp, Path->ShortAddress);
  1604.                                  }
  1605.                               } while (Path->Next () == TRUE);
  1606.                               if (strlen (Temp) > 6)
  1607.                                  Msg->Text.Add (Temp);
  1608.                            }
  1609.                         }
  1610.  
  1611.                         if (Path != NULL)
  1612.                            delete Path;
  1613.                         if (SeenBy != NULL)
  1614.                            delete SeenBy;
  1615.  
  1616.                         strcpy (Msg->ToAddress, Forward.String);
  1617.                         Packet->Add (Msg);
  1618.                      }
  1619.                   } while (Msg->Next (Number) == TRUE);
  1620.                }
  1621.  
  1622.                delete Packet;
  1623.             }
  1624.  
  1625.             delete Msg;
  1626.          }
  1627.       }
  1628.  
  1629.       delete Data;
  1630.    }
  1631. }
  1632.  
  1633.  
  1634.