home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / OFFLINE.CPP < prev    next >
Text File  |  1998-05-12  |  79KB  |  2,238 lines

  1.  
  2. // LoraBBS Version 2.99 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include "_ldefs.h"
  20. #include "lora.h"
  21.  
  22. class TMsgAreaSelect : public TListings
  23. {
  24. public:
  25.    class  TConfig *Cfg;
  26.    class  TLanguage *Language;
  27.  
  28.    VOID   Begin (VOID);
  29.    VOID   PrintCursor (USHORT y);
  30.    VOID   PrintLine (VOID);
  31.    VOID   PrintTitles (VOID);
  32.    VOID   RemoveCursor (USHORT y);
  33.    VOID   Select (VOID);
  34.    VOID   Tag (VOID);
  35.  
  36. private:
  37. };
  38.  
  39. // ----------------------------------------------------------------------
  40.  
  41. TOffline::TOffline (void)
  42. {
  43.    Cfg = NULL;
  44.    Log = NULL;
  45.    Embedded = NULL;
  46.    User = NULL;
  47.    Language = NULL;
  48.    Progress = NULL;
  49.  
  50.    CarrierSpeed = 19200L;
  51.  
  52.    Total = TotalPersonal = 0L;
  53.    Limit = 0L;
  54.    strcpy (Id, "offline");
  55.    Msg = NULL;
  56. }
  57.  
  58. TOffline::~TOffline (void)
  59. {
  60.    if (User != NULL) {
  61.       sprintf (Work, "%s%s", Cfg->TempPath, User->MailBox);
  62.       rmdir (AdjustPath (Work));
  63.    }
  64.    if (Cfg != NULL && User != NULL) {
  65.       sprintf (Path, "%s%s", Cfg->UsersHomePath, User->MailBox);
  66.       rmdir (AdjustPath (Path));
  67.    }
  68. }
  69.  
  70. VOID TOffline::AddKludges (class TCollection &Text, class TMsgData *Data)
  71. {
  72.    FILE *fp;
  73.    int i, max;
  74.    CHAR Temp[128], Origin[128], *p;
  75.  
  76.    strcpy (Origin, Cfg->SystemName);
  77.    if (Data->Origin[0] != '\0')
  78.       strcpy (Origin, Data->Origin);
  79.    else if (Data->OriginIndex == OIDX_DEFAULT)
  80.       strcpy (Origin, Cfg->SystemName);
  81.    else if (Data->OriginIndex == OIDX_RANDOM) {
  82.       srand ((unsigned int)time (NULL));
  83.       sprintf (Temp, "%sorigin.txt", Cfg->SystemPath);
  84.       if ((fp = fopen (Temp, "rt")) != NULL) {
  85.          max = 0;
  86.          while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL)
  87.             max++;
  88.          while ((i = rand ()) > max)
  89.             ;
  90.          fseek (fp, 0L, SEEK_SET);
  91.          while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  92.             if (i == 0) {
  93.                if (Temp[strlen (Temp) - 1] == '\n')
  94.                   Temp[strlen (Temp) - 1] = '\0';
  95.                strcpy (Origin, Temp);
  96.                break;
  97.             }
  98.             i--;
  99.          }
  100.          fclose (fp);
  101.       }
  102.    }
  103.    else {
  104.       i = 1;
  105.       sprintf (Temp, "%sorigin.txt", Cfg->SystemPath);
  106.       if ((fp = fopen (Temp, "rt")) != NULL) {
  107.          while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  108.             if (i == Data->OriginIndex) {
  109.                if (Temp[strlen (Temp) - 1] == '\n')
  110.                   Temp[strlen (Temp) - 1] = '\0';
  111.                strcpy (Origin, Temp);
  112.                break;
  113.             }
  114.          }
  115.          fclose (fp);
  116.       }
  117.    }
  118.  
  119.    if (Data->EchoMail == TRUE) {
  120.       if (Data->Address[0] == '\0') {
  121.          Cfg->MailAddress.First ();
  122.          sprintf (Temp, "\001MSGID: %s %08lx", Cfg->MailAddress.String, time (NULL));
  123.       }
  124.       else
  125.          sprintf (Temp, "\001MSGID: %s %08lx", Data->Address, time (NULL));
  126.       p = (PSZ)Text.First ();
  127.       Text.Insert (Temp);
  128.       if (p != NULL) {
  129.          Text.Insert (p, (USHORT)(strlen (p) + 1));
  130.          Text.First ();
  131.          Text.Remove ();
  132.       }
  133.  
  134.       sprintf (Temp, "\001PID: %s", NAME_OS);
  135.       Text.Insert (Temp);
  136.  
  137.       Text.Add ("");
  138.       sprintf (Temp, "--- %s v%s", NAME, VERSION);
  139.       Text.Add (Temp);
  140.       if (Data->Address[0] == '\0')
  141.          sprintf (Temp, " * Origin: %s (%s)", Origin, Cfg->MailAddress.String);
  142.       else
  143.          sprintf (Temp, " * Origin: %s (%s)", Origin, Data->Address);
  144.       Text.Add (Temp);
  145.    }
  146. }
  147.  
  148. VOID TOffline::ManageTagged (VOID)
  149. {
  150.    USHORT Line, Tagged;
  151.    CHAR Areas[32], *p;
  152.    class TMsgData *Data;
  153.    class TMsgTag *MsgTag = User->MsgTag;
  154.    class TMsgAreaSelect *List;
  155.  
  156.    Embedded->BufferedPrintf ("\n\026\001\017Please enter the area numbers to tag/untag.\n");
  157.  
  158.    while (Embedded->AbortSession () == FALSE) {
  159.       Embedded->BufferedPrintf ("\026\001\013[Enter area(s) to tag, \"?\"=list areas, \"-\"=delete all, <enter>=Quit]\n");
  160.       Embedded->BufferedPrintf ("\026\001\017Tag area: ");
  161.       Embedded->Input (Areas, (USHORT)(sizeof (Areas) - 1), 0);
  162.  
  163.       if (Areas[0] == '-') {
  164.          if (MsgTag->First () == TRUE)
  165.             do {
  166.                MsgTag->Tagged = FALSE;
  167.                MsgTag->Update ();
  168.             } while (MsgTag->Next () == TRUE);
  169.          Embedded->Printf ("\026\001\017Done!\n");
  170.       }
  171.       else if (Areas[0] == '?') {
  172.          if (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE) {
  173.             if ((List = new TMsgAreaSelect) != NULL) {
  174.                List->Cfg = Cfg;
  175.                List->Embedded = Embedded;
  176.                List->Log = Log;
  177.                List->User = User;
  178.                List->Language = Language;
  179.                List->Run ();
  180.                delete List;
  181.             }
  182.          }
  183.          else {
  184.             if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  185.                if (Data->First () == TRUE) {
  186.                   Embedded->BufferedPrintf ("\x0C");
  187.                   Embedded->BufferedPrintf ("\n\026\001\017 Area             Msgs   Description\n \031─\017  \031─\005  \031─\066\n");
  188.                   Line = 4;
  189.  
  190.                   do {
  191.                      Tagged = FALSE;
  192.                      if (User->MsgTag->Read (Data->Key) == TRUE)
  193.                         Tagged = User->MsgTag->Tagged;
  194.  
  195.                      if (Tagged == FALSE)
  196.                         Embedded->BufferedPrintf ("\026\001\015 %-15.15s  \026\001\002%5ld  \026\001\003%.54s\n", Data->Key, Data->ActiveMsgs, Data->Display);
  197.                      else
  198.                         Embedded->BufferedPrintf ("\026\001\016*\026\001\015%-15.15s\026\001\016* \026\001\002%5ld  \026\001\003%.54s\n", Data->Key, Data->ActiveMsgs, Data->Display);
  199.                      if ((Line = Embedded->MoreQuestion (Line)) == 1) {
  200.                         Embedded->BufferedPrintf ("\x0C");
  201.                         Embedded->BufferedPrintf ("\n\026\001\017 Area             Msgs   Description\n \031─\017  \031─\005  \031─\066\n");
  202.                         Line = 4;
  203.                      }
  204.                   } while (Data->Next () == TRUE && Line != 0);
  205.  
  206.                   if (Line > 4)
  207.                      Embedded->MoreQuestion (99);
  208.                }
  209.                delete Data;
  210.             }
  211.             Embedded->Printf ("\n\026\001\016Areas marked with an \"*\" are currently tagged.\n");
  212.          }
  213.       }
  214.       else if (Areas[0] == '\0')
  215.          break;
  216.       else if ((p = strtok (Areas, " ")) != NULL)
  217.          do {
  218.             if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  219.                if (Data->Read (p) == TRUE) {
  220.                   if (User->Level >= Data->Level) {
  221.                      if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  222.                         if (MsgTag->Read (Data->Key) == FALSE) {
  223.                            MsgTag->New ();
  224.                            strcpy (MsgTag->Area, Data->Key);
  225.                            MsgTag->Tagged = TRUE;
  226.                            MsgTag->Add ();
  227.                            Embedded->Printf ("\026\001\016Area \026\001\012%s \026\001\016tagged.\n", MsgTag->Area);
  228.                         }
  229.                         else {
  230.                            MsgTag->Tagged = (MsgTag->Tagged == TRUE) ? FALSE : TRUE;
  231.                            MsgTag->Update ();
  232.                            if (MsgTag->Tagged == FALSE)
  233.                               Embedded->Printf ("\026\001\016Area \026\001\012%s \026\001\016untagged.\n", MsgTag->Area);
  234.                            else
  235.                               Embedded->Printf ("\026\001\016Area \026\001\012%s \026\001\016tagged.\n", MsgTag->Area);
  236.                         }
  237.                      }
  238.                   }
  239.                }
  240.                else
  241.                   Embedded->Printf ("\026\001\014That area doesn't exist!.\n");
  242.                delete Data;
  243.             }
  244.          } while ((p = strtok (NULL, " ")) != NULL);
  245.    }
  246. }
  247.  
  248. VOID TOffline::AddConference (VOID)
  249. {
  250.    USHORT Found = FALSE, Line;
  251.    CHAR Area[16];
  252.    class TMsgData *Data;
  253.    class TMsgAreaSelect *List;
  254.  
  255.    if (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE) {
  256.       if ((List = new TMsgAreaSelect) != NULL) {
  257.          List->Cfg = Cfg;
  258.          List->Embedded = Embedded;
  259.          List->Log = Log;
  260.          List->User = User;
  261.          List->Language = Language;
  262.          List->Run ();
  263.          delete List;
  264.       }
  265.    }
  266.    else {
  267.       if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  268.          do {
  269.             Embedded->Printf ("\n\026\001\013Enter the name of the Conference, or ? for a list: \026\001\x1E");
  270.             Embedded->Input (Area, (USHORT)(sizeof (Area) - 1), INP_FIELD);
  271.  
  272.             if (!stricmp (Area, "?")) {
  273.                if (Data->First () == TRUE) {
  274.                   Embedded->Printf ("\n\026\001\012Conference       Msgs   Description\n\026\001\017\031─\017  \031─\005  \031─\067\n");
  275.                   Line = 3;
  276.                   do {
  277.                      if (Data->Offline == TRUE && User->Level >= Data->Level) {
  278.                         if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  279.                            Embedded->Printf ("\026\001\013%-15.15s  \026\001\016%5ld  %.55s\n", Data->Key, Data->ActiveMsgs, Data->Display);
  280.                            Line = Embedded->MoreQuestion (Line);
  281.                         }
  282.                      }
  283.                   } while (Embedded->AbortSession () == FALSE && Data->Next () == TRUE && Line != 0);
  284.                }
  285.             }
  286.             else if (Area[0] != '\0') {
  287.                if (Data->Read (Area) == TRUE) {
  288.                   if (User->Level >= Data->Level) {
  289.                      if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  290.                         if (User->MsgTag->Read (Area) == FALSE) {
  291.                            User->MsgTag->New ();
  292.                            strcpy (User->MsgTag->Area, Area);
  293.                            User->MsgTag->Tagged = TRUE;
  294.                            User->MsgTag->Add ();
  295.                         }
  296.                         else {
  297.                            User->MsgTag->Tagged = TRUE;
  298.                            User->MsgTag->Update ();
  299.                         }
  300.                         Found = TRUE;
  301.                      }
  302.                   }
  303.                }
  304.  
  305.                if (Found == FALSE)
  306.                   Embedded->Printf ("\n\x16\x01\x0DSorry, no such Conference is accessible to you.\n");
  307.             }
  308.          } while (Area[0] != '\0' && Found == FALSE && Embedded->AbortSession () == FALSE);
  309.  
  310.          delete Data;
  311.       }
  312.    }
  313. }
  314.  
  315. USHORT TOffline::Compress (PSZ pszPacket)
  316. {
  317.    USHORT RetVal = FALSE;
  318.    CHAR Cmd[16], Temp[128];
  319.    class TPacker *Packer;
  320.  
  321.    Embedded->Printf ("\n\n");
  322.  
  323.    if ((Packer = new TPacker (Cfg->SystemPath)) != NULL) {
  324.       if (Packer->First () == TRUE)
  325.          do {
  326. #if defined(__OS2__)
  327.             if (Packer->OS2 == TRUE)
  328. #elif defined(__NT__)
  329.             if (Packer->Windows == TRUE)
  330. #elif defined(__LINUX__)
  331.             if (Packer->Linux == TRUE)
  332. #else
  333.             if (Packer->Dos == TRUE)
  334. #endif
  335.                Embedded->Printf ("  \x16\x01\013%s ... \x16\x01\016%s\n", Packer->Key, Packer->Display);
  336.          } while (Packer->Next () == TRUE);
  337.  
  338.       do {
  339.          Embedded->Printf ("\n\x16\x01\013Choose a compression option (or RETURN to exit): ");
  340.          Embedded->Input (Cmd, (USHORT)(sizeof (Cmd) - 1), 0);
  341.       } while (Cmd[0] != '\0' && Embedded->AbortSession () == FALSE && Packer->Read (Cmd) == FALSE);
  342.  
  343.       if (Cmd[0] != '\0' && Packer->Read (Cmd) == TRUE) {
  344.          Embedded->Printf ("\n\x16\x01\016Please wait while compressing your mail packet.\n");
  345.          strcpy (Temp, Work);
  346.          strcat (Temp, "*.*");
  347.          if (Log != NULL)
  348.             Log->Write ("#Executing %s", Packer->PackCmd);
  349.          if (Packer->DoPack (pszPacket, Temp) == TRUE)
  350.             RetVal = TRUE;
  351.       }
  352.  
  353.       delete Packer;
  354.    }
  355.  
  356.    if (RetVal == TRUE) {
  357.       MsgTag = User->MsgTag;
  358.       if (NewMsgTag.First () == TRUE)
  359.          do {
  360.             if (MsgTag->Read (NewMsgTag.Area) == TRUE) {
  361.                MsgTag->LastRead = NewMsgTag.LastRead;
  362.                MsgTag->Update ();
  363.             }
  364.          } while (NewMsgTag.Next () == TRUE);
  365.  
  366.       MsgTag->Save ();
  367.    }
  368.  
  369.    return (RetVal);
  370. }
  371.  
  372. USHORT TOffline::Create (VOID)
  373. {
  374.    return (FALSE);
  375. }
  376.  
  377. VOID TOffline::Display (VOID)
  378. {
  379.    class TMsgData *Data;
  380.  
  381.    if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  382.       Embedded->Printf ("\n\x16\x01\012You have selected the following Conference(s):\n\x16\x01\x0E");
  383.  
  384.       if (User->MsgTag->First () == TRUE) {
  385.          Embedded->Printf ("\n\026\001\012Conference       Msgs   Description\n\026\001\017\031─\017  \031─\005  \031─\067\n");
  386.          do {
  387.             if (User->MsgTag->Tagged == TRUE) {
  388.                if (Data->Read (User->MsgTag->Area) == TRUE)
  389.                   Embedded->Printf ("\026\001\013%-15.15s  \026\001\016%5ld  %.55s\n", Data->Key, Data->ActiveMsgs, Data->Display);
  390.             }
  391.          } while (User->MsgTag->Next () == TRUE);
  392.       }
  393.  
  394.       Embedded->Printf ("\n");
  395.       delete Data;
  396.    }
  397. }
  398.  
  399. VOID TOffline::Download (PSZ pszFile, PSZ pszName)
  400. {
  401.    USHORT RetVal = FALSE, SelectOK, Loop;
  402.    USHORT WasTagged = FALSE;
  403.    CHAR Cmd[10];
  404.    ULONG DlTime;
  405.    struct stat statbuf;
  406.    class TTransfer *Transfer;
  407.  
  408.    if (stat (pszFile, &statbuf) == 0) {
  409.       DlTime = (statbuf.st_size / (CarrierSpeed / 10L) + 30L) / 60L;
  410.       if (DlTime < 1)
  411.          Embedded->Printf ("\n\x16\x01\012Approximate download time: < 1 minute.\n\n");
  412.       else
  413.          Embedded->Printf ("\n\x16\x01\012Approximate download time: %ld minutes.\n\n", DlTime);
  414.  
  415.       if (DlTime < Embedded->TimeRemain ()) {
  416.          Embedded->Printf ("  \x16\x01\013M ... \x16\x01\016XMODEM (Checksum/CRC)\n");
  417.          Embedded->Printf ("  \x16\x01\0131 ... \x16\x01\016XMODEM-1K\n");
  418.          Embedded->Printf ("  \x16\x01\013Z ... \x16\x01\016ZMODEM\n");
  419.       }
  420.       Embedded->Printf ("  \x16\x01\013T ... \x16\x01\016Tag file(s) for later download\n");
  421.  
  422.       SelectOK = FALSE;
  423.  
  424.       do {
  425.          Embedded->Printf ("\n\x16\x01\013Choose a download option (or RETURN to exit): ");
  426.          if (Embedded->HotKey == TRUE)
  427.             Embedded->Input (Cmd, 1, INP_HOTKEY);
  428.          else
  429.             Embedded->Input (Cmd, (USHORT)(sizeof (Cmd) - 1), 0);
  430.          Cmd[0] = (CHAR)toupper (Cmd[0]);
  431.          if (Cmd[0] == 'M' || Cmd[0] == '1')
  432.             SelectOK = TRUE;
  433.          else if (Cmd[0] == '\0' || Cmd[0] == 'Z' || Cmd[0] == 'T')
  434.             SelectOK = TRUE;
  435.       } while (Embedded->AbortSession () == FALSE && SelectOK == FALSE);
  436.  
  437.       if (Cmd[0] != '\0' && (Transfer = new TTransfer) != NULL) {
  438.          Transfer->Com = Embedded->Com;
  439.          Transfer->Log = Log;
  440.          Transfer->Speed = CarrierSpeed;
  441.          Transfer->Progress = Progress;
  442.          Transfer->Telnet = Cfg->ZModemTelnet;
  443.  
  444.          Loop = TRUE;
  445.          while (Loop == TRUE && RetVal == FALSE && Embedded->AbortSession () == FALSE) {
  446.             if (DlTime < Embedded->TimeRemain ()) {
  447.                if (Cmd[0] != 'T')
  448.                   Embedded->Printf ("\n\x16\x01\012(Hit \x16\x01\013CTRL-X \x16\x01\012a few times to abort)\n");
  449.  
  450.                if (Cmd[0] == '1') {
  451.                   Embedded->Printf ("\x16\x01\012Beginning %s download of the file %s\n", "XMODEM-1K", pszName);
  452.                   RetVal = Transfer->Send1kXModem (pszFile);
  453.                }
  454.                else if (Cmd[0] == 'M') {
  455.                   Embedded->Printf ("\x16\x01\012Beginning %s download of the file %s\n", "XMODEM", pszName);
  456.                   RetVal = Transfer->SendXModem (pszFile);
  457.                }
  458.                else if (Cmd[0] == 'Z') {
  459.                   Embedded->Printf ("\x16\x01\012Beginning %s download of the file %s\n", "ZMODEM", pszName);
  460.                   if ((RetVal = Transfer->SendZModem (pszFile)) == TRUE)
  461.                      Transfer->SendZModem (NULL);
  462.                }
  463.             }
  464.  
  465.             if (Cmd[0] == 'T') {
  466.                Embedded->Printf ("\n\x16\x01\012You have just tagged:\n\n");
  467.                User->FileTag->New ();
  468.                strcpy (User->FileTag->Name, pszName);
  469.                strcpy (User->FileTag->Area, "Offline-Reader");
  470.                strcpy (User->FileTag->Complete, pszFile);
  471.                User->FileTag->Size = statbuf.st_size;
  472.                User->FileTag->DeleteAfter = TRUE;
  473.                User->FileTag->Add ();
  474.                Embedded->Printf ("\x16\x01\x0A%5d. The file %s in the %s Library\n", User->FileTag->Index, pszName, User->FileTag->Area);
  475.                if (Log != NULL)
  476.                   Log->Write (":Tagged file %s, library %s", pszName, User->FileTag->Area);
  477.                RetVal = TRUE;
  478.                WasTagged = TRUE;
  479.             }
  480.  
  481.             if (Cmd[0] != 'T' && Embedded->AbortSession () == FALSE) {
  482.                if (RetVal == FALSE) {
  483.                   Embedded->Printf ("\n\n\x16\x01\015*** NO FILES DOWNLOADED ***\n\006\007\006\007");
  484.                   Embedded->Printf ("\n\x16\x01\013Do you want to try to download the file again");
  485.                   if (Embedded->GetAnswer (ASK_DEFYES) == ANSWER_NO)
  486.                      Loop = FALSE;
  487.                }
  488.                else
  489.                   Embedded->Printf ("\n\n\x16\x01\016*** DOWNLOAD COMPLETE ***\n\006\007\006\007");
  490.             }
  491.          }
  492.  
  493.          delete Transfer;
  494.       }
  495.  
  496.       if (WasTagged == FALSE)
  497.          unlink (pszFile);
  498.    }
  499. }
  500.  
  501. USHORT TOffline::FetchReply (VOID)
  502. {
  503.    return (FALSE);
  504. }
  505.  
  506. VOID TOffline::PackArea (ULONG &ulLast)
  507. {
  508.    ulLast = ulLast;
  509. }
  510.  
  511. VOID TOffline::PackEMail (ULONG &ulLast)
  512. {
  513.    ulLast = ulLast;
  514. }
  515.  
  516. USHORT TOffline::Prescan (VOID)
  517. {
  518.    USHORT RetVal = FALSE, Areas;
  519.    ULONG Number;
  520.    class TMsgTag *MsgTag;
  521.  
  522.    sprintf (Work, "%s%s\\", Cfg->TempPath, User->MailBox);
  523.    BuildPath (Work);
  524.    sprintf (Path, "%s%s\\", Cfg->UsersHomePath, User->MailBox);
  525.    BuildPath (Path);
  526.  
  527.    Areas = 0;
  528.    MsgTag = User->MsgTag;
  529.  
  530.    if (MsgTag->First () == TRUE) {
  531.       Embedded->Printf ("\n\x16\x01\012Forum \x0A Description & Msgs. Pers.\n\x16\x01\x0F─ ─1 ─ ─\n");
  532.  
  533.       MsgTag->First ();
  534.       do {
  535.          if (MsgTag->Tagged == TRUE) {
  536.             if ((MsgArea = new TMsgData (Cfg->SystemPath)) != NULL) {
  537.                if (MsgArea->Read (MsgTag->Area) == TRUE) {
  538.                   Msg = NULL;
  539.                   if (MsgArea->Storage == ST_JAM)
  540.                      Msg = new JAM (MsgArea->Path);
  541.                   else if (MsgArea->Storage == ST_SQUISH)
  542.                      Msg = new SQUISH (MsgArea->Path);
  543.                   else if (MsgArea->Storage == ST_FIDO)
  544.                      Msg = new FIDOSDM (MsgArea->Path);
  545.                   else if (MsgArea->Storage == ST_ADEPT)
  546.                      Msg = new ADEPT (MsgArea->Path);
  547.                   else if (MsgArea->Storage == ST_HUDSON)
  548.                      Msg = new HUDSON (MsgArea->Path, (UCHAR)MsgArea->Board);
  549.  
  550.                   Areas++;
  551.                   Current = Personal = 0L;
  552.                   Embedded->Printf ("\x16\x01\x0B%-15.15s \x16\x01\x0E%-49.49s ", MsgArea->Key, MsgArea->Display);
  553.  
  554.                   if (Msg != NULL) {
  555.                      Number = MsgTag->LastRead;
  556.                      if (Msg->Next (Number) == TRUE) {
  557.                         do {
  558.                            Msg->ReadHeader (Number);
  559.                            if (TooOld (MsgTag->OlderMsg, Msg) == FALSE) {
  560.                               Current++;
  561.                               Total++;
  562.                               if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  563.                                  Personal++;
  564.                                  TotalPersonal++;
  565.                               }
  566.                            }
  567.                            else if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  568.                               Current++;
  569.                               Total++;
  570.                               Personal++;
  571.                               TotalPersonal++;
  572.                            }
  573. #if defined(__OS2__)
  574.                            if ((Total % 16L) == 0L)
  575.                               DosSleep (1L);
  576. #elif defined(__NT__)
  577.                            if ((Total % 16L) == 0L)
  578.                               Sleep (1L);
  579. #endif
  580.                         } while (Msg->Next (Number) == TRUE);
  581.                      }
  582.                   }
  583.  
  584.                   Embedded->Printf ("%5lu %5lu\n", Current, Personal);
  585.  
  586.                   if (Msg != NULL) {
  587.                      Msg->Close ();
  588.                      delete Msg;
  589.                   }
  590.                }
  591.                delete MsgArea;
  592.             }
  593.          }
  594.       } while (MsgTag->Next () == TRUE);
  595.    }
  596.  
  597.    if (Log != NULL)
  598.       Log->Write (":OLR Prescan: %u Areas, %lu Messages", Areas, Total);
  599.  
  600.    Embedded->Printf ("\n\x16\x01\x0ATotal messages found: %lu\n\n", Total);
  601.  
  602.    if (Total == 0L)
  603.       Embedded->Printf ("\x16\x01\015No messages found to download!\n\006\007\006\007");
  604.    else {
  605.       if (Limit != 0 && Total > Limit) {
  606.          Embedded->Printf ("\x16\x01\015Too much messages. Only the first %lu will be packed!\n\n\006\007\006\007", Limit);
  607.          Total = Limit;
  608.       }
  609.  
  610.       Embedded->Printf ("\x16\x01\013Do you want to download these messages");
  611.       if (Embedded->GetAnswer (ASK_DEFYES) == ANSWER_YES) {
  612.          RetVal = TRUE;
  613.          TotalPack = Total;
  614.          BarWidth = 0;
  615.       }
  616.    }
  617.  
  618.    return (RetVal);
  619. }
  620.  
  621. VOID TOffline::RemoveArea (VOID)
  622. {
  623.    CHAR Area[16];
  624.  
  625.    Embedded->Printf ("\n\026\001\013Enter the name of the Conference, or ? for a list: \026\001\x1E");
  626.    Embedded->Input (Area, (USHORT)(sizeof (Area) - 1), INP_FIELD);
  627.  
  628.    if (Embedded->AbortSession () == FALSE) {
  629.       if (User->MsgTag->Read (Area) == TRUE) {
  630.          User->MsgTag->Tagged = FALSE;
  631.          User->MsgTag->Update ();
  632.       }
  633.       else
  634.          Embedded->Printf ("\n\x16\x01\x0DThere is no such Conference in your offline reader configuration.\n");
  635.    }
  636. }
  637.  
  638. VOID TOffline::RestrictDate (VOID)
  639. {
  640.    int dd, mm, yy;
  641.    CHAR Temp[32];
  642.    ULONG Restrict;
  643.    struct tm ltm;
  644.    class TMsgTag *MsgTag = User->MsgTag;
  645.  
  646.    memcpy (<m, localtime ((time_t *)&User->LastCall), sizeof (struct tm));
  647.    Embedded->Printf ("\n\026\001\017Enter date of oldest message to pack, or press <enter> for %d-%02d-%d: ", ltm.tm_mday, ltm.tm_mon + 1, ltm.tm_year % 100);
  648.    Embedded->Input (Temp, 10);
  649.  
  650.    if (Embedded->AbortSession () == FALSE) {
  651.       Restrict = User->LastCall;
  652.       if (Temp[0] != '\0') {
  653.          sscanf (Temp, "%d-%d-%d", &dd, &mm, &yy);
  654.          if (yy < 90)
  655.             yy += 100;
  656.          memset (<m, 0, sizeof (struct tm));
  657.          ltm.tm_mday = dd;
  658.          ltm.tm_mon = mm - 1;
  659.          ltm.tm_year = yy;
  660.          Restrict = mktime (<m);
  661.       }
  662.  
  663.       if (MsgTag->First () == TRUE)
  664.          do {
  665.             if (MsgTag->Tagged == TRUE) {
  666.                MsgTag->LastRead = 0L;
  667.                MsgTag->OlderMsg = Restrict;
  668.                MsgTag->Update ();
  669.             }
  670.          } while (MsgTag->Next () == TRUE);
  671.    }
  672. }
  673.  
  674. USHORT TOffline::TooOld (ULONG Restrict, class TMsgBase *Msg)
  675. {
  676.    USHORT RetVal = FALSE;
  677.    struct tm ltm;
  678.  
  679.    memset (<m, 0, sizeof (struct tm));
  680.    ltm.tm_mday = Msg->Written.Day;
  681.    ltm.tm_mon = Msg->Written.Month - 1;
  682.    ltm.tm_year = Msg->Written.Year - 1900;
  683.    if (mktime (<m) < Restrict)
  684.       RetVal = TRUE;
  685.  
  686.    return (RetVal);
  687. }
  688.  
  689. VOID TOffline::Scan (PSZ pszKey, ULONG ulLast)
  690. {
  691.    class TMsgData *MsgArea;
  692.    class TMsgBase *Msg = NULL;
  693.  
  694.    Current = Personal = 0L;
  695.  
  696.    if ((Limit == 0 || Total < Limit) && (MsgArea = new TMsgData (Cfg->SystemPath)) != NULL) {
  697.       if (MsgArea->Read (pszKey) == TRUE) {
  698.          if (MsgArea->Storage == ST_JAM)
  699.             Msg = new JAM (MsgArea->Path);
  700.          else if (MsgArea->Storage == ST_SQUISH)
  701.             Msg = new SQUISH (MsgArea->Path);
  702.          else if (MsgArea->Storage == ST_FIDO)
  703.             Msg = new FIDOSDM (MsgArea->Path);
  704.          else if (MsgArea->Storage == ST_ADEPT)
  705.             Msg = new ADEPT (MsgArea->Path);
  706.          else if (MsgArea->Storage == ST_HUDSON)
  707.             Msg = new HUDSON (MsgArea->Path, (UCHAR)MsgArea->Board);
  708.  
  709.          if (Msg != NULL) {
  710.             if (Msg->Next (ulLast) == TRUE) {
  711.                do {
  712.                   Msg->ReadHeader (ulLast);
  713.  
  714.                   Current++;
  715.                   Total++;
  716.                   if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  717. // ----------------------------------------------------------------------
  718. // If the message is directed to the user, then writes the message
  719. // number and area number in the personal index file too.
  720. // ----------------------------------------------------------------------
  721.                      Personal++;
  722.                      TotalPersonal++;
  723.                   }
  724.                } while (Msg->Next (ulLast) == TRUE);
  725.             }
  726.             Msg->Close ();
  727.             delete Msg;
  728.          }
  729.       }
  730.       delete MsgArea;
  731.    }
  732. }
  733.  
  734. VOID TOffline::Upload (VOID)
  735. {
  736.    DIR *dir;
  737.    USHORT RetVal = FALSE, i;
  738.    CHAR Protocol[10], File[128], *p;
  739.    PSZ Extensions[] = { ".su", ".mo", ".tu", ".we", ".th", ".fr", ".sa" };
  740.    class TTransfer *Transfer;
  741.    class TPacker *Packer;
  742.    struct dirent *ent;
  743.    struct stat statbuf;
  744.  
  745.    sprintf (Work, "%s%s\\", Cfg->TempPath, User->MailBox);
  746.    BuildPath (Work);
  747.    sprintf (Path, "%s%s\\", Cfg->UsersHomePath, User->MailBox);
  748.    BuildPath (Path);
  749.  
  750.    if (RetVal == FALSE) {
  751.       sprintf (File, "%s%s.rep", Path, Id);
  752.       if (stat (File, &statbuf) == 0)
  753.          RetVal = TRUE;
  754.    }
  755.    if (RetVal == FALSE) {
  756.       sprintf (File, "%s%s.new", Path, Id);
  757.       if (stat (File, &statbuf) == 0)
  758.          RetVal = TRUE;
  759.    }
  760.  
  761.    if (RetVal == FALSE) {
  762.       Embedded->Printf ("\n\x16\x01\012To start uploading %s.REP, type:\n\n", Id);
  763.  
  764.       Embedded->Printf ("  \x16\x01\013A ... \x16\x01\016ASCII\n");
  765.       Embedded->Printf ("  \x16\x01\013M ... \x16\x01\016XMODEM (Checksum/CRC)\n");
  766.       Embedded->Printf ("  \x16\x01\0131 ... \x16\x01\016XMODEM-1K\n");
  767.       Embedded->Printf ("  \x16\x01\013Z ... \x16\x01\016ZMODEM\n");
  768. //      Embedded->Printf ("  \x16\x01\013F ... \x16\x01\016File Import (existing file)\n");
  769.  
  770.       Embedded->Printf ("\n\x16\x01\013Choose an upload option, or RETURN to exit: ");
  771.       Embedded->Input (Protocol, 1, INP_HOTKEY);
  772.  
  773.       if ((Transfer = new TTransfer) != NULL) {
  774.          Transfer->Com = Embedded->Com;
  775.          Transfer->Log = Log;
  776.          Transfer->Speed = CarrierSpeed;
  777.          Transfer->Progress = Progress;
  778.          Transfer->Telnet = Cfg->ZModemTelnet;
  779.  
  780.          sprintf (File, "%s%s.REP", Path, Id);
  781.  
  782.          switch (toupper (Protocol[0])) {
  783.             case '1':
  784.                if (Transfer->Receive1kXModem (File) != NULL)
  785.                   RetVal = TRUE;
  786.                break;
  787.  
  788.             case 'M':
  789.                if (Transfer->ReceiveXModem (File) != NULL)
  790.                   RetVal = TRUE;
  791.                break;
  792.  
  793.             case 'Z':
  794.                if ((p = Transfer->ReceiveZModem (Path)) != NULL) {
  795.                   RetVal = TRUE;
  796.                   while ((p = Transfer->ReceiveZModem (Path)) != NULL)
  797.                      ;
  798.                }
  799.                break;
  800.          }
  801.  
  802.          delete Transfer;
  803.       }
  804.    }
  805.  
  806.    Embedded->Printf ("\n\006\007");
  807.  
  808.    if (RetVal == TRUE) {
  809.       if ((Packer = new TPacker (Cfg->SystemPath)) != NULL) {
  810.          sprintf (File, "%s%s.rep", Path, Id);
  811.          if (Packer->CheckArc (File) == TRUE) {
  812.             if (Log != NULL)
  813.                Log->Write ("+Unpacking %s", File);
  814.             if (Packer->DoUnpack (File, Work, "*.*") == FALSE)
  815.                Log->Write ("!  Command returned error: %s", Packer->Error);
  816.             unlink (File);
  817.          }
  818.          sprintf (File, "%s%s.new", Path, Id);
  819.          if (Packer->CheckArc (File) == TRUE) {
  820.             if (Log != NULL)
  821.                Log->Write ("+Unpacking %s", File);
  822.             if (Packer->DoUnpack (File, Work, "*.*") == FALSE)
  823.                Log->Write ("!  Command returned error: %s", Packer->Error);
  824.             unlink (File);
  825.          }
  826.          if ((dir = opendir (Path)) != NULL) {
  827.             while ((ent = readdir (dir)) != NULL) {
  828.                for (i = 0; i < 7; i++) {
  829.                   if (strstr (strlwr (ent->d_name), Extensions[i]) != NULL) {
  830.                      sprintf (File, "%s%s", Path, ent->d_name);
  831.                      if (Packer->CheckArc (File) == TRUE) {
  832.                         if (Log != NULL)
  833.                            Log->Write ("+Unpacking %s", File);
  834.                         if (Packer->DoUnpack (File, Work, "*.*") == FALSE)
  835.                            Log->Write ("!  Command returned error: %s", Packer->Error);
  836.                         unlink (File);
  837.                      }
  838.                      break;
  839.                   }
  840.                }
  841.             }
  842.             closedir (dir);
  843.          }
  844.          delete Packer;
  845.       }
  846.    }
  847. }
  848.  
  849. // ----------------------------------------------------------------------
  850.  
  851. VOID TMsgAreaSelect::Begin (VOID)
  852. {
  853.    USHORT i;
  854.    LISTDATA ld;
  855.    class TMsgData *MsgData;
  856.  
  857.    i = 0;
  858.    y = 4;
  859.    Found = FALSE;
  860.    List.Clear ();
  861.    Data.Clear ();
  862.  
  863.    if ((MsgData = new TMsgData (Cfg->SystemPath)) != NULL) {
  864.       if (MsgData->First () == TRUE)
  865.          do {
  866.             if (User->Level >= MsgData->Level) {
  867.                if ((MsgData->AccessFlags & User->AccessFlags) == MsgData->AccessFlags) {
  868.                   strcpy (ld.Key, MsgData->Key);
  869.                   ld.ActiveMsgs = MsgData->ActiveMsgs;
  870.                   strcpy (ld.Display, MsgData->Display);
  871.                   Data.Add (&ld, sizeof (LISTDATA));
  872.                }
  873.             }
  874.          } while (MsgData->Next () == TRUE);
  875.  
  876.       delete MsgData;
  877.    }
  878.  
  879.    if ((pld = (LISTDATA *)Data.First ()) != NULL) {
  880.       do {
  881.          List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  882.          i++;
  883.          if (i >= (User->ScreenHeight - 6))
  884.             break;
  885.       } while ((pld = (LISTDATA *)Data.Next ()) != NULL);
  886.    }
  887. }
  888.  
  889. VOID TMsgAreaSelect::PrintTitles (VOID)
  890. {
  891.    Embedded->Printf ("\x0C");
  892.    Embedded->Printf ("\n\026\001\017 Area             Msgs   Description\n \031─\017  \031─\005  \031─\066\n");
  893.  
  894.    Embedded->PrintfAt ((USHORT)(User->ScreenHeight - 2), 1, " \031─\017  \031─\005  \031─\066\n");
  895.  
  896.    Embedded->Printf (Language->Text (LNG_FILEAREADESCRIPTION1));
  897.    Embedded->Printf (Language->Text (LNG_FILEAREADESCRIPTION2));
  898.  
  899.    Embedded->PrintfAt (4, 1, "");
  900. }
  901.  
  902. VOID TMsgAreaSelect::PrintLine (VOID)
  903. {
  904.    USHORT Tagged = FALSE;
  905.  
  906.    if (User->MsgTag->Read (pld->Key) == TRUE)
  907.       Tagged = User->MsgTag->Tagged;
  908.  
  909.    if (Tagged == FALSE)
  910.       Embedded->Printf ("\026\001\015 %-15.15s  \026\001\002%5ld  \026\001\003%.54s\n", pld->Key, pld->ActiveMsgs, pld->Display);
  911.    else
  912.       Embedded->Printf ("\026\001\016*\026\001\015%-15.15s\026\001\016* \026\001\002%5ld  \026\001\003%.54s\n", pld->Key, pld->ActiveMsgs, pld->Display);
  913. }
  914.  
  915. VOID TMsgAreaSelect::PrintCursor (USHORT y)
  916. {
  917.    Embedded->PrintfAt (y, 2, Language->Text (LNG_MESSAGEAREACURSOR), (PSZ)List.Value ());
  918. }
  919.  
  920. VOID TMsgAreaSelect::RemoveCursor (USHORT y)
  921. {
  922.    Embedded->PrintfAt (y, 2, Language->Text (LNG_MESSAGEAREAKEY), (PSZ)List.Value ());
  923. }
  924.  
  925. VOID TMsgAreaSelect::Select (VOID)
  926. {
  927.    RetVal = End = TRUE;
  928. }
  929.  
  930. VOID TMsgAreaSelect::Tag (VOID)
  931. {
  932.    if (User->MsgTag->Read ((PSZ)List.Value ()) == FALSE) {
  933.       User->MsgTag->New ();
  934.       strcpy (User->MsgTag->Area, (PSZ)List.Value ());
  935.       User->MsgTag->Tagged = TRUE;
  936.       User->MsgTag->Add ();
  937.    }
  938.    else {
  939.       if (User->MsgTag->Tagged == TRUE)
  940.          User->MsgTag->Tagged = FALSE;
  941.       else
  942.          User->MsgTag->Tagged = TRUE;
  943.       User->MsgTag->Update ();
  944.    }
  945.  
  946.    if (User->MsgTag->Tagged == TRUE)
  947.       Embedded->PrintfAt (y, 1, "\026\001\016*\x16\x01\x70%-15.15s\x16\x01\x0E*", (PSZ)List.Value ());
  948.    else
  949.       Embedded->PrintfAt (y, 1, "\026\001\016 \x16\x01\x70%-15.15s\x16\x01\x0E ", (PSZ)List.Value ());
  950. }
  951.  
  952. // ----------------------------------------------------------------------
  953.  
  954. PSZ Extensions[] = {
  955.    ".su0", ".mo0", ".tu0", ".we0", ".th0", ".fr0", ".sa0"
  956. };
  957.  
  958. TBlueWave::TBlueWave (void)
  959. {
  960. }
  961.  
  962. TBlueWave::~TBlueWave (void)
  963. {
  964. }
  965.  
  966. USHORT TBlueWave::Create (VOID)
  967. {
  968.    int fd;
  969.    USHORT RetVal = FALSE;
  970.    CHAR Temp[128], PktName[32];
  971.    struct dosdate_t date;
  972.  
  973.    Log->Write ("+Preparing BlueWave packet");
  974.    MsgTag = User->MsgTag;
  975.    _dos_getdate (&date);
  976.    sprintf (PktName, "%s%s", Id, Extensions[date.dayofweek]);
  977.  
  978.    Total = 0L;
  979.    TotalPersonal = 0L;
  980.  
  981.    sprintf (Work, "%s%s\\", Cfg->TempPath, User->MailBox);
  982.    sprintf (Path, "%s%s\\", Cfg->UsersHomePath, User->MailBox);
  983.  
  984.    NewMsgTag.Clear ();
  985.  
  986.    if (BuildPath (Work) == TRUE) {
  987.       sprintf (Temp, "%s%s.INF", Work, Id);
  988.       if ((fd = sopen (Temp, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  989.          memset (&Inf, 0, sizeof (Inf));
  990.          Inf.ver = PACKET_LEVEL;
  991.          strcpy ((PSZ)Inf.loginname, User->Name);
  992.          strcpy ((PSZ)Inf.aliasname, User->RealName);
  993.          if (Cfg->MailAddress.First () == TRUE) {
  994.             Inf.zone = Cfg->MailAddress.Zone;
  995.             Inf.net = Cfg->MailAddress.Net;
  996.             Inf.node = Cfg->MailAddress.Node;
  997.             Inf.point = Cfg->MailAddress.Point;
  998.          }
  999.          strcpy ((PSZ)Inf.sysop, Cfg->SysopName);
  1000.          strcpy ((PSZ)Inf.systemname, Cfg->SystemName);
  1001.          Inf.inf_header_len = sizeof (INF_HEADER);
  1002.          Inf.inf_areainfo_len = sizeof (INF_AREA_INFO);
  1003.          Inf.mix_structlen = sizeof (MIX_REC);
  1004.          Inf.fti_structlen = sizeof (FTI_REC);
  1005.          Inf.uses_upl_file = TRUE;
  1006.          Inf.can_forward = TRUE;
  1007.          strcpy ((PSZ)Inf.packet_id, Id);
  1008.          write (fd, &Inf, sizeof (INF_HEADER));
  1009.  
  1010.          memset (&AreaInf, 0, sizeof (INF_AREA_INFO));
  1011.  
  1012.          if ((MsgArea = new TMsgData (Cfg->SystemPath)) != NULL) {
  1013.             Area = 1;
  1014.             if (MsgArea->First () == TRUE)
  1015.                do {
  1016.                   memset (&AreaInf, 0, sizeof (AreaInf));
  1017.                   sprintf ((PSZ)AreaInf.areanum, "%u", Area++);
  1018.                   if (strlen (MsgArea->Key) > sizeof (AreaInf.echotag))
  1019.                      MsgArea->Key[sizeof (AreaInf.echotag) - 1] = '\0';
  1020.                   strcpy ((PSZ)AreaInf.echotag, MsgArea->Key);
  1021.                   MsgArea->Display[sizeof (AreaInf.title) - 1] = '\0';
  1022.                   strcpy ((PSZ)AreaInf.title, MsgArea->Display);
  1023.                   AreaInf.area_flags |= INF_POST|INF_NO_PRIVATE;
  1024.                   if (MsgTag->Read (MsgArea->Key) == TRUE)
  1025.                      AreaInf.area_flags |= INF_SCANNING;
  1026.                   write (fd, &AreaInf, sizeof (AreaInf));
  1027.                } while (MsgArea->Next () == TRUE);
  1028.             delete MsgArea;
  1029.          }
  1030.  
  1031.          close (fd);
  1032.       }
  1033.  
  1034.       if (MsgTag->First () == TRUE)
  1035.          do {
  1036.             if (MsgTag->Tagged == TRUE)
  1037.                RetVal = TRUE;
  1038.          } while (RetVal == FALSE && MsgTag->Next () == TRUE);
  1039.  
  1040.       if (RetVal == TRUE) {
  1041.          Embedded->Printf ("\n\x16\x01\012Preparing %s packet...\n\n", PktName);
  1042.  
  1043.          Embedded->Printf ("\x16\x01\0170%%    10%%  20%%   30%%   40%%   50%%   60%%   70%%   80%%   90%%   100%%\n|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|\r");
  1044.  
  1045.          if ((MsgArea = new TMsgData (Cfg->SystemPath)) != NULL) {
  1046.             Area = 1;
  1047.             if (MsgArea->First () == TRUE)
  1048.                do {
  1049.                   if (MsgTag->First () == TRUE)
  1050.                      do {
  1051.                         if (!stricmp (MsgArea->Key, MsgTag->Area) && MsgTag->Tagged == TRUE) {
  1052.                            NewMsgTag.New ();
  1053.                            strcpy (NewMsgTag.Area, MsgTag->Area);
  1054.                            NewMsgTag.LastRead = MsgTag->LastRead;
  1055.                            NewMsgTag.Add ();
  1056.  
  1057.                            PackArea (NewMsgTag.LastRead);
  1058.                            if (Log != NULL)
  1059.                               Log->Write (":  Area %s, %ld msgs. (%ld personal)", NewMsgTag.Area, Current, Personal);
  1060.  
  1061.                            NewMsgTag.Update ();
  1062.                         }
  1063.                      } while (MsgTag->Next () == TRUE);
  1064.                   Area++;
  1065.                } while (MsgArea->Next () == TRUE);
  1066.             delete MsgArea;
  1067.          }
  1068.  
  1069.          if (Log != NULL)
  1070.             Log->Write ("*Packed %ld messages (%ld personal)", Total, TotalPersonal);
  1071.  
  1072.          if (Total > 0L) {
  1073.             if (BuildPath (Path) == TRUE) {
  1074.                sprintf (Temp, "%s%s", Path, PktName);
  1075.                if (Compress (Temp) == TRUE)
  1076.                   Download (Temp, PktName);
  1077.             }
  1078.          }
  1079.       }
  1080.    }
  1081.    else
  1082.       Log->Write ("!Path Error: %s", Work);
  1083.  
  1084.    return (RetVal);
  1085. }
  1086.  
  1087. USHORT TBlueWave::FetchReply (VOID)
  1088. {
  1089.    FILE *fp;
  1090.    int fdh;
  1091.    USHORT RetVal = FALSE;
  1092.    CHAR Temp[128], *p;
  1093.    ULONG t, Number;
  1094.    struct tm *ltm;
  1095.  
  1096.    sprintf (Work, "%s%s\\", Cfg->TempPath, User->MailBox);
  1097.    BuildPath (Work);
  1098.  
  1099.    MsgArea = new TMsgData (Cfg->SystemPath);
  1100.  
  1101.    sprintf (Temp, "%s%s.UPL", Work, Id);
  1102.    if ((fdh = sopen (Temp, O_RDONLY|O_BINARY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1103.       read (fdh, &Uplh, sizeof (UPL_HEADER));
  1104.       while (read (fdh, &Uplr, sizeof (UPL_REC)) == sizeof (UPL_REC)) {
  1105.          if (MsgArea->Read ((PSZ)Uplr.echotag) == TRUE) {
  1106.             if (Log != NULL)
  1107.                Log->Write (":Message Area: %s - %s", MsgArea->Key, MsgArea->Display);
  1108.  
  1109.             Msg = NULL;
  1110.             if (MsgArea->Storage == ST_JAM)
  1111.                Msg = new JAM (MsgArea->Path);
  1112.             else if (MsgArea->Storage == ST_SQUISH)
  1113.                Msg = new SQUISH (MsgArea->Path);
  1114.             else if (MsgArea->Storage == ST_FIDO)
  1115.                Msg = new FIDOSDM (MsgArea->Path);
  1116.             else if (MsgArea->Storage == ST_ADEPT)
  1117.                Msg = new ADEPT (MsgArea->Path);
  1118.             else if (MsgArea->Storage == ST_HUDSON)
  1119.                Msg = new HUDSON (MsgArea->Path, (UCHAR)MsgArea->Board);
  1120.  
  1121.             if (Msg != NULL) {
  1122.                Msg->New ();
  1123.                if (!stricmp ((PSZ)Uplr.from, User->Name) || !stricmp ((PSZ)Uplr.from, User->RealName))
  1124.                   strcpy (Msg->From, (PSZ)Uplr.from);
  1125.                else
  1126.                   strcpy (Msg->From, User->Name);
  1127.                strcpy (Msg->To, (PSZ)Uplr.to);
  1128.                strcpy (Msg->Subject, (PSZ)Uplr.subj);
  1129.                ltm = localtime ((time_t *)&Uplr.unix_date);
  1130.                Msg->Written.Day = (UCHAR)ltm->tm_mday;
  1131.                Msg->Written.Month = (UCHAR)(ltm->tm_mon + 1);
  1132.                Msg->Written.Year = (USHORT)(ltm->tm_year + 1900);
  1133.                Msg->Written.Hour = (UCHAR)ltm->tm_hour;
  1134.                Msg->Written.Minute = (UCHAR)ltm->tm_min;
  1135.                Msg->Written.Second = (UCHAR)ltm->tm_sec;
  1136.                t = time (NULL);
  1137.                ltm = localtime ((time_t *)&t);
  1138.                Msg->Arrived.Day = (UCHAR)ltm->tm_mday;
  1139.                Msg->Arrived.Month = (UCHAR)(ltm->tm_mon + 1);
  1140.                Msg->Arrived.Year = (USHORT)(ltm->tm_year + 1900);
  1141.                Msg->Arrived.Hour = (UCHAR)ltm->tm_hour;
  1142.                Msg->Arrived.Minute = (UCHAR)ltm->tm_min;
  1143.                Msg->Arrived.Second = (UCHAR)ltm->tm_sec;
  1144.  
  1145.                sprintf (Temp, "%s%s", Work, Uplr.filename);
  1146.                if ((fp = _fsopen (Temp, "rt", SH_DENYNO)) != NULL) {
  1147.                   while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  1148.                      while ((p = strchr (Temp, '\n')) != NULL)
  1149.                         *p = '\0';
  1150.                      while ((p = strchr (Temp, '\r')) != NULL)
  1151.                         *p = '\0';
  1152.                      Msg->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  1153.                   }
  1154.                   fclose (fp);
  1155.  
  1156.                   if (MsgArea->EchoMail == TRUE)
  1157.                      AddKludges (Msg->Text, MsgArea);
  1158.  
  1159.                   Msg->Add ();
  1160.                   MsgArea->ActiveMsgs++;
  1161.                   MsgArea->Update ();
  1162.  
  1163.                   Number = Msg->Highest ();
  1164.                   Log->Write (":Written message #%lu (%lu)", Msg->UidToMsgn (Number), Number);
  1165.                   Embedded->Printf ("\n\x16\x01\x0E<<< CONFIRMED: MESSAGE #%lu WRITTEN TO DISK >>>\n\006\007", Msg->UidToMsgn (Number));
  1166.                }
  1167.  
  1168.                Msg->Close ();
  1169.                delete Msg;
  1170.  
  1171.                sprintf (Temp, "%s%s", Work, Uplr.filename);
  1172.                unlink (Temp);
  1173.             }
  1174.          }
  1175.       }
  1176.       close (fdh);
  1177.    }
  1178.  
  1179.    if (MsgArea != NULL)
  1180.       delete MsgArea;
  1181.  
  1182.    sprintf (Temp, "%s%s.UPL", Work, Id);
  1183.    unlink (Temp);
  1184.  
  1185.    return (RetVal);
  1186. }
  1187.  
  1188. VOID TBlueWave::PackArea (ULONG &ulLast)
  1189. {
  1190.    int fdm, fdfti, fdmix;
  1191.    CHAR Temp[128], *Text;
  1192.    ULONG Number;
  1193.  
  1194.    Number = ulLast;
  1195.    Current = Personal = 0L;
  1196.  
  1197.    if (Limit == 0 || Total < Limit) {
  1198.       if (MsgArea->Storage == ST_JAM)
  1199.          Msg = new JAM (MsgArea->Path);
  1200.       else if (MsgArea->Storage == ST_SQUISH)
  1201.          Msg = new SQUISH (MsgArea->Path);
  1202.       else if (MsgArea->Storage == ST_FIDO)
  1203.          Msg = new FIDOSDM (MsgArea->Path);
  1204.       else if (MsgArea->Storage == ST_ADEPT)
  1205.          Msg = new ADEPT (MsgArea->Path);
  1206.       else if (MsgArea->Storage == ST_HUDSON)
  1207.          Msg = new HUDSON (MsgArea->Path, (UCHAR)MsgArea->Board);
  1208.  
  1209.       sprintf (Temp, "%s%s.fti", Work, Id);
  1210.       fdfti = sopen (Temp, O_WRONLY|O_BINARY|O_CREAT|O_APPEND, SH_DENYNO, S_IREAD|S_IWRITE);
  1211.       lseek (fdfti, 0L, SEEK_END);
  1212.  
  1213.       sprintf (Temp, "%s%s.mix", Work, Id);
  1214.       fdmix = sopen (Temp, O_WRONLY|O_BINARY|O_CREAT|O_APPEND, SH_DENYNO, S_IREAD|S_IWRITE);
  1215.       lseek (fdmix, 0L, SEEK_END);
  1216.  
  1217.       sprintf (Temp, "%s%s.dat", Work, Id);
  1218.       fdm = sopen (Temp, O_WRONLY|O_BINARY|O_CREAT|O_APPEND, SH_DENYNO, S_IREAD|S_IWRITE);
  1219.       lseek (fdm, 0L, SEEK_END);
  1220.  
  1221.       memset (&Mix, 0, sizeof (MIX_REC));
  1222.       sprintf ((PSZ)Mix.areanum, "%u", Area);
  1223.       Mix.msghptr = tell (fdfti);
  1224.  
  1225.       if (Msg != NULL && fdfti != -1 && fdmix != -1 && fdm != -1) {
  1226.          Msg->Lock (0L);
  1227.          if (Msg->Next (Number) == TRUE) {
  1228.             do {
  1229.                Msg->ReadHeader (Number);
  1230.                if (TooOld (MsgTag->OlderMsg, Msg) == FALSE || !stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  1231.                   Msg->Read (Number);
  1232.  
  1233.                   Current++;
  1234.                   Total++;
  1235.                   if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  1236.                      Personal++;
  1237.                      TotalPersonal++;
  1238.                   }
  1239.  
  1240.                   memset (&Fti, 0, sizeof (FTI_REC));
  1241.  
  1242.                   Msg->From[sizeof (Fti.from) - 1] = '\0';
  1243.                   strcpy ((PSZ)Fti.from, Msg->From);
  1244.                   Msg->To[sizeof (Fti.to) - 1] = '\0';
  1245.                   strcpy ((PSZ)Fti.to, Msg->To);
  1246.                   Msg->Subject[sizeof (Fti.subject) - 1] = '\0';
  1247.                   strcpy ((PSZ)Fti.subject, Msg->Subject);
  1248.                   sprintf ((PSZ)Fti.date, "%2d %.3s %2d %2d:%02d:%02d", Msg->Written.Day, Language->Months[Msg->Written.Month - 1], Msg->Written.Year, Msg->Written.Hour, Msg->Written.Minute, Msg->Written.Second);
  1249.                   Fti.msgnum = (tWORD)Msg->UidToMsgn (Number);
  1250.                   Fti.msgptr = tell (fdm);
  1251.                   if (Cfg->MailAddress.First () == TRUE) {
  1252.                      Fti.orig_zone = Cfg->MailAddress.Zone;
  1253.                      Fti.orig_net = Cfg->MailAddress.Net;
  1254.                      Fti.orig_node = Cfg->MailAddress.Node;
  1255.                   }
  1256.  
  1257.                   Fti.msglength += write (fdm, " ", 1);
  1258.  
  1259.                   if ((Text = (PSZ)Msg->Text.First ()) != NULL)
  1260.                      do {
  1261.                         if (Text[0] != 0x01 && strnicmp (Text, "SEEN-BY: ", 9)) {
  1262.                            Fti.msglength += write (fdm, Text, strlen (Text));
  1263.                            Fti.msglength += write (fdm, "\r\n", 2);
  1264.                         }
  1265.                      } while ((Text = (PSZ)Msg->Text.Next ()) != NULL);
  1266.  
  1267.                   write (fdfti, &Fti, sizeof (Fti));
  1268. #if defined(__OS2__)
  1269.                   if ((Total % 16L) == 0L)
  1270.                      DosSleep (1L);
  1271. #elif defined(__NT__)
  1272.                   if ((Total % 16L) == 0L)
  1273.                      Sleep (1L);
  1274. #endif
  1275.                   if (BarWidth != (USHORT)((Total * 61L) / TotalPack)) {
  1276.                      BarWidth = (USHORT)((Total * 61L) / TotalPack);
  1277.                      Embedded->Printf ("\r%.*s", BarWidth, "█████████████████████████████████████████████████████████████");
  1278.                   }
  1279.                }
  1280.             } while ((Limit == 0 || Total < Limit) && Msg->Next (Number) == TRUE);
  1281.          }
  1282.          Msg->UnLock ();
  1283.       }
  1284.  
  1285.       Mix.totmsgs = (tWORD)Current;
  1286.       Mix.numpers = (tWORD)Personal;
  1287.       write (fdmix, &Mix, sizeof (Mix));
  1288.  
  1289.       if (Msg != NULL) {
  1290.          Msg->Close ();
  1291.          delete Msg;
  1292.       }
  1293.       if (fdfti != -1)
  1294.          close (fdfti);
  1295.       if (fdmix != -1)
  1296.          close (fdmix);
  1297.       if (fdm != -1)
  1298.          close (fdm);
  1299.    }
  1300.  
  1301.    ulLast = Number;
  1302. }
  1303.  
  1304. // ----------------------------------------------------------------------
  1305.  
  1306. TQWK::TQWK (void)
  1307. {
  1308. }
  1309.  
  1310. TQWK::~TQWK (void)
  1311. {
  1312. }
  1313.  
  1314. USHORT TQWK::Create (VOID)
  1315. {
  1316.    int i;
  1317.    FILE *fp;
  1318.    USHORT RetVal = FALSE;
  1319.    CHAR Temp[128], PktName[32];
  1320.    struct dosdate_t date;
  1321.    struct dostime_t dtime;
  1322.  
  1323.    if (Log != NULL)
  1324.       Log->Write ("+Preparing QWK packet");
  1325.    MsgTag = User->MsgTag;
  1326.    sprintf (PktName, "%s.QWK", Id);
  1327.  
  1328.    Total = 0L;
  1329.    TotalPersonal = 0L;
  1330.  
  1331.    sprintf (Work, "%s%s\\", Cfg->TempPath, User->MailBox);
  1332.    sprintf (Path, "%s%s\\", Cfg->UsersHomePath, User->MailBox);
  1333.  
  1334.    if (BuildPath (Work) == TRUE) {
  1335.       if (MsgTag->First () == TRUE)
  1336.          do {
  1337.             if (MsgTag->Tagged == TRUE)
  1338.                RetVal = TRUE;
  1339.          } while (RetVal == FALSE && MsgTag->Next () == TRUE);
  1340.  
  1341.       if (RetVal == TRUE) {
  1342.          Embedded->Printf ("\n\x16\x01\012Preparing %s packet...\n\n", PktName);
  1343.  
  1344.          Embedded->Printf ("\x16\x01\0170%%    10%%  20%%   30%%   40%%   50%%   60%%   70%%   80%%   90%%   100%%\n|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|\r");
  1345.          Area = 1;
  1346.          NewMsgTag.Clear ();
  1347.          Blocks = 2L;
  1348.  
  1349.          if ((MsgArea = new TMsgData (Cfg->SystemPath)) != NULL) {
  1350.             if (MsgTag->First () == TRUE)
  1351.                do {
  1352.                   if (MsgTag->Tagged == TRUE) {
  1353.                      if (MsgArea->Read (MsgTag->Area) == TRUE) {
  1354.                         strcpy (NewMsgTag.Area, MsgTag->Area);
  1355.                         NewMsgTag.LastRead = MsgTag->LastRead;
  1356.                         NewMsgTag.Add ();
  1357.  
  1358.                         PackArea (NewMsgTag.LastRead);
  1359.                         if (Log != NULL)
  1360.                            Log->Write (":  Area %s, %ld msgs. (%ld personal)", NewMsgTag.Area, Current, Personal);
  1361.  
  1362.                         NewMsgTag.Update ();
  1363.                      }
  1364.                      Area++;
  1365.                   }
  1366.                } while (MsgTag->Next () == TRUE);
  1367.  
  1368.             delete MsgArea;
  1369.          }
  1370.  
  1371.          sprintf (Temp, "%sCONTROL.DAT", Work);
  1372.          if ((fp = _fsopen (Temp, "wt", SH_DENYNO)) != NULL) {
  1373.             fprintf (fp, "%s\n", Cfg->SystemName);
  1374.             fprintf (fp, " \n");
  1375.             fprintf (fp, " \n");
  1376.             fprintf (fp, "%s\n", Cfg->SysopName);
  1377.             fprintf (fp, "00000,%s\n", Id);
  1378.             _dos_getdate (&date);
  1379.             _dos_gettime (&dtime);
  1380.             fprintf (fp, "%02d-%02d-%04d,%02d:%02d:%02d\n", date.month, date.day, date.year, dtime.hour, dtime.minute, dtime.second);
  1381.             strcpy (Temp, User->Name);
  1382.             fprintf (fp, "%s\n", strupr (Temp));
  1383.             fprintf (fp, " \n");
  1384.             fprintf (fp, "0\n");
  1385.             fprintf (fp, "%lu\n", Total);
  1386.  
  1387.             i = 0;
  1388.             if (MsgTag->First () == TRUE)
  1389.                do {
  1390.                   if (MsgTag->Tagged == TRUE)
  1391.                      i++;
  1392.                } while (MsgTag->Next () == TRUE);
  1393.             fprintf (fp, "%d\n", i - 1);
  1394.  
  1395.             i = 1;
  1396.             if (MsgTag->First () == TRUE)
  1397.                do {
  1398.                   if (MsgTag->Tagged == TRUE)
  1399.                      fprintf (fp, "%d\n%s\n", i++, MsgTag->Area);
  1400.                } while (MsgTag->Next () == TRUE);
  1401.  
  1402.             fprintf (fp, "WELCOME\n");
  1403.             fprintf (fp, "NEWS\n");
  1404.             fprintf (fp, "GOODBYE\n");
  1405.  
  1406.             fclose (fp);
  1407.          }
  1408.  
  1409.          sprintf (Temp, "%sDOOR.ID", Work);
  1410.          if ((fp = _fsopen (Temp, "wt", SH_DENYNO)) != NULL) {
  1411.             fprintf (fp, "DOOR = %s\n", NAME);
  1412.             fprintf (fp, "VERSION = %s\n", VERSION);
  1413.             fprintf (fp, "SYSTEM = %s\n", NAME);
  1414.             fprintf (fp, "CONTROLNAME = LoraQWK\n");
  1415.             fprintf (fp, "CONTROLTYPE = ADD\n");
  1416.             fprintf (fp, "CONTROLTYPE = DROP\n");
  1417.             fclose (fp);
  1418.          }
  1419.  
  1420.          Log->Write ("*Packed %ld messages (%ld personal)", Total, TotalPersonal);
  1421.  
  1422.          if (Total > 0L) {
  1423.             if (BuildPath (Path) == TRUE) {
  1424.                sprintf (Temp, "%s%s", Path, PktName);
  1425.                if (Compress (Temp) == TRUE)
  1426.                   Download (Temp, PktName);
  1427.             }
  1428.          }
  1429.       }
  1430.    }
  1431.    else
  1432.       Log->Write ("!Path Error: %s", Work);
  1433.  
  1434.    return (RetVal);
  1435. }
  1436.  
  1437. USHORT TQWK::FetchReply (VOID)
  1438. {
  1439.    int fdh;
  1440.    USHORT RetVal = FALSE, i, r, x, nCol, nWidth, nReaded, nRec;
  1441.    CHAR Temp[128], szLine[132], szWrp[132], *pLine, *pBuff;
  1442.    ULONG t, Number;
  1443.    struct tm *ltm;
  1444.    class TMsgTag *MsgTag = User->MsgTag;
  1445.    class TCollection MsgText;
  1446.  
  1447.    sprintf (Work, "%s%s\\", Cfg->TempPath, User->MailBox);
  1448.    BuildPath (Work);
  1449.  
  1450.    nWidth = (USHORT)(sizeof (szLine) - 1);
  1451.    MsgArea = new TMsgData (Cfg->SystemPath);
  1452.  
  1453.    sprintf (Temp, "%s%s.msg", Work, Id);
  1454.    if ((fdh = sopen (Temp, O_RDONLY|O_BINARY, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1455.       read (fdh, Temp, 128);
  1456.       Temp[8] = '\0';
  1457.  
  1458.       while (read (fdh, &Qwk, sizeof (Qwk)) == sizeof (Qwk)) {
  1459.          Msg = NULL;
  1460.  
  1461.          Area = 1;
  1462.          strcpy (Temp, StripSpaces ((PSZ)Qwk.Msgnum, (USHORT)sizeof (Qwk.Msgnum)));
  1463.  
  1464.          if (MsgTag->First () == TRUE)
  1465.             do {
  1466.                if (MsgTag->Tagged == TRUE && Area == (USHORT)atoi (Temp)) {
  1467.                   if (MsgArea->Read (MsgTag->Area) == TRUE) {
  1468.                      if (Log != NULL)
  1469.                         Log->Write (":Message Area: %s - %s", MsgArea->Key, MsgArea->Display);
  1470.  
  1471.                      Msg = NULL;
  1472.                      if (MsgArea->Storage == ST_JAM)
  1473.                         Msg = new JAM (MsgArea->Path);
  1474.                      else if (MsgArea->Storage == ST_SQUISH)
  1475.                         Msg = new SQUISH (MsgArea->Path);
  1476.                      else if (MsgArea->Storage == ST_FIDO)
  1477.                         Msg = new FIDOSDM (MsgArea->Path);
  1478.                      else if (MsgArea->Storage == ST_ADEPT)
  1479.                         Msg = new ADEPT (MsgArea->Path);
  1480.                      else if (MsgArea->Storage == ST_HUDSON)
  1481.                         Msg = new HUDSON (MsgArea->Path, (UCHAR)MsgArea->Board);
  1482.                   }
  1483.                   break;
  1484.                }
  1485.                if (MsgTag->Tagged == TRUE)
  1486.                   Area++;
  1487.             } while (MsgTag->Next () == TRUE);
  1488.  
  1489.          if (Msg == NULL && Log != NULL)
  1490.             Log->Write ("!Unknown Forum %s, Skipping", Temp);
  1491.  
  1492.          MsgText.Clear ();
  1493.          nRec = (USHORT)atoi (StripSpaces ((PSZ)Qwk.Msgrecs, (USHORT)sizeof (Qwk.Msgrecs)));
  1494.          pLine = szLine;
  1495.          nCol = 0;
  1496.  
  1497.          for (r = 1; r < nRec; r++) {
  1498.             nReaded = (USHORT)read (fdh, Temp, 128);
  1499.             if (r == (USHORT)(nRec - 1)) {
  1500.                x = 127;
  1501.                while (x > 0 && Temp[x] == ' ') {
  1502.                   nReaded--;
  1503.                   x--;
  1504.                }
  1505.             }
  1506.  
  1507.             for (i = 0, pBuff = Temp; i < nReaded; i++, pBuff++) {
  1508.                if (*pBuff == '\r' || *pBuff == (CHAR)0xE3) {
  1509.                   *pLine = '\0';
  1510.                   MsgText.Add (szLine);
  1511.                   pLine = szLine;
  1512.                   nCol = 0;
  1513.                }
  1514.                else if (*pBuff != '\n') {
  1515.                   *pLine++ = *pBuff;
  1516.                   nCol++;
  1517.                   if (nCol >= nWidth) {
  1518.                      *pLine = '\0';
  1519.                      while (nCol > 1 && *pLine != ' ') {
  1520.                         nCol--;
  1521.                         pLine--;
  1522.                      }
  1523.                      if (nCol > 0) {
  1524.                         while (*pLine == ' ')
  1525.                            pLine++;
  1526.                         strcpy (szWrp, pLine);
  1527.                      }
  1528.                      *pLine = '\0';
  1529.                      MsgText.Add (szLine);
  1530.                      strcpy (szLine, szWrp);
  1531.                      pLine = strchr (szLine, '\0');
  1532.                      nCol = (SHORT)strlen (szLine);
  1533.                   }
  1534.                }
  1535.             }
  1536.          }
  1537.  
  1538.          if (nCol > 0) {
  1539.             *pLine = '\0';
  1540.             MsgText.Add (szLine);
  1541.          }
  1542.  
  1543.          if (MsgArea->EchoMail == TRUE)
  1544.             AddKludges (MsgText, MsgArea);
  1545.  
  1546.          if (Msg != NULL) {
  1547.             Msg->New ();
  1548.  
  1549.             strcpy (Msg->From, StripSpaces ((PSZ)Qwk.MsgFrom, (USHORT)sizeof (Qwk.MsgFrom)));
  1550.             if (stricmp (Msg->From, User->Name) && stricmp (Msg->From, User->RealName))
  1551.                strcpy (Msg->From, User->Name);
  1552.             strcpy (Msg->To, StripSpaces ((PSZ)Qwk.MsgTo, (USHORT)sizeof (Qwk.MsgTo)));
  1553.             strcpy (Msg->Subject, StripSpaces ((PSZ)Qwk.MsgSubj, (USHORT)sizeof (Qwk.MsgSubj)));
  1554.  
  1555.             strcpy (Temp, StripSpaces ((PSZ)Qwk.Msgdate, (USHORT)sizeof (Qwk.Msgdate)));
  1556.             Msg->Written.Day = (UCHAR)(atoi (&Temp[3]));
  1557.             Msg->Written.Month = (UCHAR)(atoi (Temp));
  1558.             Msg->Written.Year = (USHORT)(atoi (&Temp[6]));
  1559.             if (Msg->Written.Year < 96)
  1560.                Msg->Written.Year += 2000;
  1561.             else
  1562.                Msg->Written.Year += 1900;
  1563.  
  1564.             strcpy (Temp, StripSpaces ((PSZ)Qwk.Msgtime, (USHORT)sizeof (Qwk.Msgtime)));
  1565.             Msg->Written.Hour = (UCHAR)(atoi (Temp));
  1566.             Msg->Written.Minute = (UCHAR)(atoi (&Temp[3]));
  1567.             Msg->Written.Second = 0;
  1568.  
  1569.             t = time (NULL);
  1570.             ltm = localtime ((time_t *)&t);
  1571.             Msg->Arrived.Day = (UCHAR)ltm->tm_mday;
  1572.             Msg->Arrived.Month = (UCHAR)(ltm->tm_mon + 1);
  1573.             Msg->Arrived.Year = (USHORT)(ltm->tm_year + 1900);
  1574.             Msg->Arrived.Hour = (UCHAR)ltm->tm_hour;
  1575.             Msg->Arrived.Minute = (UCHAR)ltm->tm_min;
  1576.             Msg->Arrived.Second = (UCHAR)ltm->tm_sec;
  1577.  
  1578.             Msg->Add (MsgText);
  1579.             MsgArea->ActiveMsgs++;
  1580.             MsgArea->Update ();
  1581.  
  1582.             Number = Msg->Highest ();
  1583.             Log->Write (":Written message #%lu (%lu)", Msg->UidToMsgn (Number), Number);
  1584.             Embedded->Printf ("\n\x16\x01\x0E<<< CONFIRMED: MESSAGE #%lu WRITTEN TO DISK >>>\n\006\007", Msg->UidToMsgn (Number));
  1585.  
  1586.             Msg->Close ();
  1587.             delete Msg;
  1588.          }
  1589.  
  1590.          MsgText.Clear ();
  1591.       }
  1592.  
  1593.       RetVal = TRUE;
  1594.       close (fdh);
  1595.    }
  1596.  
  1597.    if (MsgArea != NULL)
  1598.       delete MsgArea;
  1599.  
  1600.    sprintf (Temp, "%s%s.msg", Work, Id);
  1601.    unlink (Temp);
  1602.  
  1603.    return (RetVal);
  1604. }
  1605.  
  1606. float TQWK::IEEToMSBIN (float f)
  1607. {
  1608.    short sign, exp;
  1609.    QWKCONV t;
  1610.  
  1611.    t.f[0] = f;
  1612.    sign = (short)(t.uc[3] / 0x80);
  1613.    exp = (short)(((t.ui[1] >> 7) - 0x7F + 0x81) & 0xFF);
  1614.    t.ui[1] = (USHORT)((t.ui[1] & 0x7F) | (sign << 7) | (exp << 8));
  1615.  
  1616.    return (t.f[0]);
  1617. }
  1618.  
  1619. VOID TQWK::PackArea (ULONG &ulLast)
  1620. {
  1621.    int fdm, fdi, fdp;
  1622.    float out, in;
  1623.    CHAR Temp[128], *Text;
  1624.    ULONG Number, Pos, Size;
  1625.  
  1626.    Number = ulLast;
  1627.    Current = Personal = 0L;
  1628.  
  1629.    if (Limit == 0 || Total < Limit) {
  1630.       Msg = NULL;
  1631.       if (MsgArea->Storage == ST_JAM)
  1632.          Msg = new JAM (MsgArea->Path);
  1633.       else if (MsgArea->Storage == ST_SQUISH)
  1634.          Msg = new SQUISH (MsgArea->Path);
  1635.       else if (MsgArea->Storage == ST_FIDO)
  1636.          Msg = new FIDOSDM (MsgArea->Path);
  1637.       else if (MsgArea->Storage == ST_ADEPT)
  1638.          Msg = new ADEPT (MsgArea->Path);
  1639.       else if (MsgArea->Storage == ST_HUDSON)
  1640.          Msg = new HUDSON (MsgArea->Path, (UCHAR)MsgArea->Board);
  1641.  
  1642.       sprintf (Temp, "%s%03d.NDX", Work, Area);
  1643.       fdi = sopen (Temp, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE);
  1644.       lseek (fdi, 0L, SEEK_END);
  1645.  
  1646.       sprintf (Temp, "%sPERSONAL.NDX", Work);
  1647.       fdp = sopen (Temp, O_WRONLY|O_BINARY|O_CREAT|O_APPEND, SH_DENYNO, S_IREAD|S_IWRITE);
  1648.       lseek (fdp, 0L, SEEK_END);
  1649.  
  1650.       sprintf (Temp, "%sMESSAGES.DAT", Work);
  1651.       if ((fdm = sopen (Temp, O_WRONLY|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  1652.          lseek (fdm, 0L, SEEK_END);
  1653.          if (tell (fdm) == 0L) {
  1654. // ----------------------------------------------------------------------
  1655. // The first record of the MESSAGE.DAT file must be the Sparkware id
  1656. // block, otherwise some applications may complain.
  1657. // ----------------------------------------------------------------------
  1658.             write (fdm, "Produced by Qmail...", 20);
  1659.             write (fdm, "Copywright (c) 1987 by Sparkware.  ", 35);
  1660.             write (fdm, "All Rights Reserved", 19);
  1661.             memset (Temp, ' ', 54);
  1662.             write (fdm, Temp, 54);
  1663.          }
  1664.       }
  1665.  
  1666.       if (Msg != NULL && fdi != -1 && fdp != -1 && fdm != -1) {
  1667.          Msg->Lock (0L);
  1668.          if (Msg->Next (Number) == TRUE) {
  1669.             do {
  1670.                Msg->ReadHeader (Number);
  1671.                if (TooOld (MsgTag->OlderMsg, Msg) == FALSE || !stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  1672.                   Msg->Read (Number);
  1673.  
  1674.                   Current++;
  1675.                   Total++;
  1676.                   sprintf (Temp, "%lu", Blocks);
  1677.                   in = atof (Temp);
  1678.                   out = IEEToMSBIN (in);
  1679.                   write (fdi, &out, sizeof (float));
  1680.                   write (fdi, "", 1);
  1681.                   if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  1682.                      Personal++;
  1683.                      TotalPersonal++;
  1684.                      write (fdp, &out, sizeof (float));
  1685.                      write (fdp, "", 1);
  1686.                   }
  1687.  
  1688.                   memset (&Qwk, ' ', sizeof (Qwk));
  1689.                   sprintf (Temp, "%-*lu", sizeof (Qwk.Msgnum), Msg->UidToMsgn (Number));
  1690.                   memcpy (Qwk.Msgnum, Temp, sizeof (Qwk.Msgnum));
  1691.                   sprintf (Temp, "%02d-%02d-%02d", Msg->Written.Month, Msg->Written.Day, Msg->Written.Year % 100);
  1692.                   memcpy (Qwk.Msgdate, Temp, sizeof (Qwk.Msgdate));
  1693.                   sprintf (Temp, "%02d:%02d", Msg->Written.Hour, Msg->Written.Minute);
  1694.                   memcpy (Qwk.Msgtime, Temp, sizeof (Qwk.Msgtime));
  1695.                   Msg->From[sizeof (Qwk.MsgFrom) - 1] = '\0';
  1696.                   memcpy (Qwk.MsgFrom, Msg->From, strlen (Msg->From));
  1697.                   Msg->To[sizeof (Qwk.MsgTo) - 1] = '\0';
  1698.                   memcpy (Qwk.MsgTo, Msg->To, strlen (Msg->To));
  1699.                   Msg->Subject[sizeof (Qwk.MsgSubj) - 1] = '\0';
  1700.                   memcpy (Qwk.MsgSubj, Msg->Subject, strlen (Msg->Subject));
  1701.                   Qwk.Msglive = 0xE1;
  1702.                   Qwk.Msgarealo = (UCHAR)(Area & 0xFF);
  1703.                   Qwk.Msgareahi = (UCHAR)((Area & 0xFF00) >> 8);
  1704.  
  1705.                   Pos = tell (fdm);
  1706.                   write (fdm, &Qwk, sizeof (Qwk));
  1707.  
  1708.                   Size = 128L;
  1709.                   if ((Text = (PSZ)Msg->Text.First ()) != NULL)
  1710.                      do {
  1711.                         if (Text[0] != 0x01 && strnicmp (Text, "SEEN-BY: ", 9)) {
  1712.                            Size += (ULONG)write (fdm, Text, strlen (Text));
  1713.                            Size += (ULONG)write (fdm, "\xE3", 1);
  1714.                         }
  1715.                      } while ((Text = (PSZ)Msg->Text.Next ()) != NULL);
  1716.  
  1717.                   if ((Size % 128L) != 0) {
  1718.                      memset (Temp, ' ', 128);
  1719.                      Size += (ULONG)write (fdm, Temp, (int)(128L - (Size % 128L)));
  1720.                   }
  1721.  
  1722.                   Blocks += (Size / 128L);
  1723.                   sprintf (Temp, "%-*lu", sizeof (Qwk.Msgrecs), Size / 128L);
  1724.                   memcpy (Qwk.Msgrecs, Temp, sizeof (Qwk.Msgrecs));
  1725.                   lseek (fdm, Pos, SEEK_SET);
  1726.                   write (fdm, &Qwk, sizeof (Qwk));
  1727.                   lseek (fdm, 0L, SEEK_END);
  1728. #if defined(__OS2__)
  1729.                   if ((Total % 16L) == 0L)
  1730.                      DosSleep (1L);
  1731. #elif defined(__NT__)
  1732.                   if ((Total % 16L) == 0L)
  1733.                      Sleep (1L);
  1734. #endif
  1735.                   if (BarWidth != (USHORT)((Total * 61L) / TotalPack)) {
  1736.                      BarWidth = (USHORT)((Total * 61L) / TotalPack);
  1737.                      Embedded->Printf ("\r%.*s", BarWidth, "█████████████████████████████████████████████████████████████");
  1738.                   }
  1739.                }
  1740.             } while ((Limit == 0 || Total < Limit) && Msg->Next (Number) == TRUE);
  1741.          }
  1742.          Msg->UnLock ();
  1743.       }
  1744.  
  1745.       if (Msg != NULL) {
  1746.          Msg->Close ();
  1747.          delete Msg;
  1748.       }
  1749.       if (fdm != -1)
  1750.          close (fdm);
  1751.       if (fdi != -1)
  1752.          close (fdi);
  1753.       if (fdp != -1)
  1754.          close (fdp);
  1755.    }
  1756.  
  1757.    ulLast = Number;
  1758. }
  1759.  
  1760. PSZ TQWK::StripSpaces (PSZ pszString, USHORT usSize)
  1761. {
  1762.    USHORT x;
  1763.  
  1764.    memcpy (TempStr, pszString, usSize);
  1765.    TempStr[usSize] = '\0';
  1766.    if ((x = (USHORT)(usSize - 1)) > 0) {
  1767.       while (x > 0 && TempStr[x] == ' ')
  1768.          TempStr[x--] = '\0';
  1769.    }
  1770.  
  1771.    return (TempStr);
  1772. }
  1773.  
  1774. // ----------------------------------------------------------------------
  1775.  
  1776. TAscii::TAscii (void)
  1777. {
  1778. }
  1779.  
  1780. TAscii::~TAscii (void)
  1781. {
  1782. }
  1783.  
  1784. USHORT TAscii::Create (VOID)
  1785. {
  1786.    USHORT RetVal = FALSE;
  1787.    CHAR Temp[128], PktName[32];
  1788.  
  1789.    if (Log != NULL)
  1790.       Log->Write ("+Preparing Ascii packet");
  1791.    MsgTag = User->MsgTag;
  1792.    sprintf (PktName, "%s.MSG", Id);
  1793.  
  1794.    Total = 0L;
  1795.    TotalPersonal = 0L;
  1796.  
  1797.    sprintf (Work, "%s%s\\", Cfg->TempPath, User->MailBox);
  1798.    sprintf (Path, "%s%s\\", Cfg->UsersHomePath, User->MailBox);
  1799.  
  1800.    if (BuildPath (Work) == TRUE) {
  1801.       if (MsgTag->First () == TRUE)
  1802.          do {
  1803.             if (MsgTag->Tagged == TRUE)
  1804.                RetVal = TRUE;
  1805.          } while (RetVal == FALSE && MsgTag->Next () == TRUE);
  1806.  
  1807.       if (RetVal == TRUE) {
  1808.          Embedded->Printf ("\n\x16\x01\012Preparing %s packet...\n\n", PktName);
  1809.  
  1810.          Embedded->Printf ("\x16\x01\0170%%    10%%  20%%   30%%   40%%   50%%   60%%   70%%   80%%   90%%   100%%\n|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|\r");
  1811.          Area = 1;
  1812.          NewMsgTag.Clear ();
  1813.  
  1814.          if ((MsgArea = new TMsgData (Cfg->SystemPath)) != NULL) {
  1815.             if (MsgTag->First () == TRUE)
  1816.                do {
  1817.                   if (MsgTag->Tagged == TRUE) {
  1818.                      if (MsgArea->Read (MsgTag->Area) == TRUE) {
  1819.                         strcpy (NewMsgTag.Area, MsgTag->Area);
  1820.                         NewMsgTag.LastRead = MsgTag->LastRead;
  1821.                         NewMsgTag.Add ();
  1822.  
  1823.                         PackArea (NewMsgTag.LastRead);
  1824.                         if (Log != NULL)
  1825.                            Log->Write (":  Area %s, %ld msgs. (%ld personal)", NewMsgTag.Area, Current, Personal);
  1826.  
  1827.                         NewMsgTag.Update ();
  1828.                         Area++;
  1829.                      }
  1830.                   }
  1831.                } while (MsgTag->Next () == TRUE);
  1832.  
  1833.             delete MsgArea;
  1834.          }
  1835.  
  1836.          if (Log != NULL)
  1837.             Log->Write ("*Packed %ld messages (%ld personal)", Total, TotalPersonal);
  1838.  
  1839.          if (Total > 0L) {
  1840.             if (BuildPath (Path) == TRUE) {
  1841.                sprintf (Temp, "%s%s", Path, PktName);
  1842.                if (Compress (Temp) == TRUE)
  1843.                   Download (Temp, PktName);
  1844.             }
  1845.          }
  1846.       }
  1847.    }
  1848.    else if (Log != NULL)
  1849.       Log->Write ("!Path Error: %s", Work);
  1850.  
  1851.    return (RetVal);
  1852. }
  1853.  
  1854. VOID TAscii::PackArea (ULONG &ulLast)
  1855. {
  1856.    FILE *fp;
  1857.    CHAR Temp[128], *Text;
  1858.    ULONG Number;
  1859.  
  1860.    Number = ulLast;
  1861.    Current = Personal = 0L;
  1862.  
  1863.    if (Limit == 0 || Total < Limit) {
  1864.       if (MsgArea->Storage == ST_JAM)
  1865.          Msg = new JAM (MsgArea->Path);
  1866.       else if (MsgArea->Storage == ST_SQUISH)
  1867.          Msg = new SQUISH (MsgArea->Path);
  1868.       else if (MsgArea->Storage == ST_FIDO)
  1869.          Msg = new FIDOSDM (MsgArea->Path);
  1870.       else if (MsgArea->Storage == ST_ADEPT)
  1871.          Msg = new ADEPT (MsgArea->Path);
  1872.       else if (MsgArea->Storage == ST_HUDSON)
  1873.          Msg = new HUDSON (MsgArea->Path, (UCHAR)MsgArea->Board);
  1874.  
  1875.       sprintf (Temp, "%s%03d.TXT", Work, Area);
  1876.       fp = _fsopen (Temp, "wt", SH_DENYNO);
  1877.  
  1878.       if (Msg != NULL && fp != NULL) {
  1879.          Msg->Lock (0L);
  1880.          if (Msg->Next (Number) == TRUE) {
  1881.             do {
  1882.                Msg->ReadHeader (Number);
  1883.                if (TooOld (MsgTag->OlderMsg, Msg) == FALSE || !stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  1884.                   Msg->Read (Number);
  1885.  
  1886.                   fprintf (fp, "\n==============================================\n    Msg. #%ld of %ld (%s)\n", Msg->UidToMsgn (Number), Msg->Number (), MsgArea->Display);
  1887.                   fprintf (fp, "   Date: %d %s %d %2d:%02d\n", Msg->Written.Day, Language->Months[Msg->Written.Month - 1], Msg->Written.Year, Msg->Written.Hour, Msg->Written.Minute);
  1888.                   fprintf (fp, "   From: %s\n", Msg->From);
  1889.                   if (Msg->To[0])
  1890.                      fprintf (fp, "     To: %s\n", Msg->To);
  1891.                   fprintf (fp, "Subject: %s\n----------------------------------------------\n", Msg->Subject);
  1892.  
  1893.                   Current++;
  1894.                   Total++;
  1895.                   if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  1896.                      Personal++;
  1897.                      TotalPersonal++;
  1898.                   }
  1899.  
  1900.                   if ((Text = (PSZ)Msg->Text.First ()) != NULL)
  1901.                      do {
  1902.                         if (Text[0] != 0x01 && strnicmp (Text, "SEEN-BY: ", 9))
  1903.                            fprintf (fp, "%s\n", Text);
  1904.                      } while ((Text = (PSZ)Msg->Text.Next ()) != NULL);
  1905. #if defined(__OS2__)
  1906.                   if ((Total % 16L) == 0L)
  1907.                      DosSleep (1L);
  1908. #elif defined(__NT__)
  1909.                   if ((Total % 16L) == 0L)
  1910.                      Sleep (1L);
  1911. #endif
  1912.                   if (BarWidth != (USHORT)((Total * 61L) / TotalPack)) {
  1913.                      BarWidth = (USHORT)((Total * 61L) / TotalPack);
  1914.                      Embedded->Printf ("\r%.*s", BarWidth, "█████████████████████████████████████████████████████████████");
  1915.                   }
  1916.                }
  1917.             } while ((Limit == 0 || Total < Limit) && Msg->Next (Number) == TRUE);
  1918.          }
  1919.          Msg->UnLock ();
  1920.       }
  1921.  
  1922.       if (Msg != NULL) {
  1923.          Msg->Close ();
  1924.          delete Msg;
  1925.       }
  1926.       if (fp != NULL)
  1927.          fclose (fp);
  1928.    }
  1929.  
  1930.    ulLast = Number;
  1931. }
  1932.  
  1933. // ----------------------------------------------------------------------
  1934.  
  1935. TPoint::TPoint (void)
  1936. {
  1937. }
  1938.  
  1939. TPoint::~TPoint (void)
  1940. {
  1941. }
  1942.  
  1943. USHORT TPoint::Create (VOID)
  1944. {
  1945.    USHORT RetVal = FALSE;
  1946.    CHAR Temp[128], PktName[32];
  1947.    struct dosdate_t date;
  1948.  
  1949.    if (Log != NULL)
  1950.       Log->Write ("+Preparing PointMail packet");
  1951.    MsgTag = User->MsgTag;
  1952.    _dos_getdate (&date);
  1953.    sprintf (PktName, "%08lX%s", StringCrc32 (Id, 0xFFFFFFFFL), Extensions[date.dayofweek]);
  1954.  
  1955.    Total = 0L;
  1956.    TotalPersonal = 0L;
  1957.  
  1958.    sprintf (Work, "%s%s\\", Cfg->TempPath, User->MailBox);
  1959.    sprintf (Path, "%s%s\\", Cfg->UsersHomePath, User->MailBox);
  1960.  
  1961.    if (BuildPath (Work) == TRUE) {
  1962.       if (MsgTag->First () == TRUE)
  1963.          do {
  1964.             if (MsgTag->Tagged == TRUE)
  1965.                RetVal = TRUE;
  1966.          } while (RetVal == FALSE && MsgTag->Next () == TRUE);
  1967.  
  1968.       if (RetVal == TRUE) {
  1969.          Embedded->Printf ("\n\x16\x01\012Preparing %s packet...\n\n", PktName);
  1970.  
  1971.          Embedded->Printf ("\x16\x01\0170%%    10%%  20%%   30%%   40%%   50%%   60%%   70%%   80%%   90%%   100%%\n|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|\r");
  1972.          Area = 1;
  1973.          NewMsgTag.Clear ();
  1974.  
  1975.          if ((MsgArea = new TMsgData (Cfg->SystemPath)) != NULL) {
  1976.             if (MsgTag->First () == TRUE)
  1977.                do {
  1978.                   if (MsgTag->Tagged == TRUE) {
  1979.                      if (MsgArea->Read (MsgTag->Area) == TRUE) {
  1980.                         strcpy (NewMsgTag.Area, MsgTag->Area);
  1981.                         NewMsgTag.LastRead = MsgTag->LastRead;
  1982.                         NewMsgTag.Add ();
  1983.  
  1984.                         PackArea (NewMsgTag.LastRead);
  1985.                         if (Log != NULL)
  1986.                            Log->Write (":  Area %s, %ld msgs. (%ld personal)", NewMsgTag.Area, Current, Personal);
  1987.  
  1988.                         NewMsgTag.Update ();
  1989.                         Area++;
  1990.                      }
  1991.                   }
  1992.                } while (MsgTag->Next () == TRUE);
  1993.  
  1994.             delete MsgArea;
  1995.          }
  1996.  
  1997.          if (Log != NULL)
  1998.             Log->Write ("*Packed %ld messages (%ld personal)", Total, TotalPersonal);
  1999.  
  2000.          if (Total > 0L) {
  2001.             if (BuildPath (Path) == TRUE) {
  2002.                sprintf (Temp, "%s%s", Path, PktName);
  2003.                if (Compress (Temp) == TRUE)
  2004.                   Download (Temp, PktName);
  2005.             }
  2006.          }
  2007.       }
  2008.    }
  2009.    else if (Log != NULL)
  2010.       Log->Write ("!Path Error: %s", Work);
  2011.  
  2012.    return (RetVal);
  2013. }
  2014.  
  2015. VOID TPoint::PackArea (ULONG &ulLast)
  2016. {
  2017.    CHAR Temp[128], *Text;
  2018.    ULONG Number;
  2019.    class PACKET *Packet;
  2020.  
  2021.    Number = ulLast;
  2022.    Current = Personal = 0L;
  2023.  
  2024.    if (Limit == 0 || Total < Limit) {
  2025.       if (MsgArea->Storage == ST_JAM)
  2026.          Msg = new JAM (MsgArea->Path);
  2027.       else if (MsgArea->Storage == ST_SQUISH)
  2028.          Msg = new SQUISH (MsgArea->Path);
  2029.       else if (MsgArea->Storage == ST_FIDO)
  2030.          Msg = new FIDOSDM (MsgArea->Path);
  2031.       else if (MsgArea->Storage == ST_ADEPT)
  2032.          Msg = new ADEPT (MsgArea->Path);
  2033.       else if (MsgArea->Storage == ST_HUDSON)
  2034.          Msg = new HUDSON (MsgArea->Path, (UCHAR)MsgArea->Board);
  2035.  
  2036.       if ((Packet = new PACKET) != NULL) {
  2037.          if (Cfg->MailAddress.First () == TRUE) {
  2038.             strcpy (Packet->FromAddress, Cfg->MailAddress.String);
  2039.             strcpy (Packet->ToAddress, Cfg->MailAddress.String);
  2040.          }
  2041.          sprintf (Temp, "%s%08lX.PKT", Work, time (NULL));
  2042.          Packet->Open (Temp);
  2043.       }
  2044.  
  2045.       if (Msg != NULL && Packet != NULL) {
  2046.          Msg->Lock (0L);
  2047.          if (Msg->Next (Number) == TRUE) {
  2048.             do {
  2049.                Msg->ReadHeader (Number);
  2050.                if (TooOld (MsgTag->OlderMsg, Msg) == FALSE || !stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  2051.                   Msg->Read (Number);
  2052.  
  2053.                   Current++;
  2054.                   Total++;
  2055.                   if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  2056.                      Personal++;
  2057.                      TotalPersonal++;
  2058.                   }
  2059.  
  2060.                   if ((Text = (CHAR *)Msg->Text.First ()) != NULL)
  2061.                      do {
  2062.                         if (!strncmp (Text, "SEEN-BY: ", 9) || !strncmp (Text, "\001PATH: ", 7)) {
  2063.                            Msg->Text.Remove ();
  2064.                            Text = (CHAR *)Msg->Text.Value ();
  2065.                         }
  2066.                         else
  2067.                            Text = (CHAR *)Msg->Text.Next ();
  2068.                      } while (Text != NULL);
  2069.  
  2070.                   if (Cfg->MailAddress.First () == TRUE) {
  2071.                      sprintf (Temp, "SEEN-BY: %u/%u", Cfg->MailAddress.Net, Cfg->MailAddress.Node);
  2072.                      Msg->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  2073.                      sprintf (Temp, "\001PATH: %u/%u", Cfg->MailAddress.Net, Cfg->MailAddress.Node);
  2074.                      Msg->Text.Add (Temp, (USHORT)(strlen (Temp) + 1));
  2075.                   }
  2076.  
  2077.                   if ((Text = (CHAR *)Msg->Text.First ()) != NULL) {
  2078.                      if (MsgArea->EchoTag[0] != '\0')
  2079.                         sprintf (Temp, "AREA:%s", MsgArea->EchoTag);
  2080.                      else
  2081.                         sprintf (Temp, "AREA:%s", MsgArea->Key);
  2082.                      Msg->Text.Insert (Temp, (USHORT)(strlen (Temp) + 1));
  2083.                      Msg->Text.Insert (Text, (USHORT)(strlen (Text) + 1));
  2084.                      Msg->Text.First ();
  2085.                      Msg->Text.Remove ();
  2086.                   }
  2087.  
  2088.                   Packet->Add (Msg);
  2089. #if defined(__OS2__)
  2090.                   if ((Total % 16L) == 0L)
  2091.                      DosSleep (1L);
  2092. #elif defined(__NT__)
  2093.                   if ((Total % 16L) == 0L)
  2094.                      Sleep (1L);
  2095. #endif
  2096.                   if (BarWidth != (USHORT)((Total * 61L) / TotalPack)) {
  2097.                      BarWidth = (USHORT)((Total * 61L) / TotalPack);
  2098.                      Embedded->Printf ("\r%.*s", BarWidth, "█████████████████████████████████████████████████████████████");
  2099.                   }
  2100.                }
  2101.             } while ((Limit == 0 || Total < Limit) && Msg->Next (Number) == TRUE);
  2102.          }
  2103.          Msg->UnLock ();
  2104.       }
  2105.  
  2106.       if (Msg != NULL) {
  2107.          Msg->Close ();
  2108.          delete Msg;
  2109.       }
  2110.       if (Packet != NULL) {
  2111.          Packet->Close ();
  2112.          delete Packet;
  2113.       }
  2114.    }
  2115.  
  2116.    ulLast = Number;
  2117. }
  2118.  
  2119. USHORT TPoint::FetchReply (VOID)
  2120. {
  2121.    DIR *dir;
  2122.    USHORT RetVal = FALSE, Found;
  2123.    CHAR Temp[128], LastTag[64], *Text;
  2124.    ULONG Number, Written;
  2125.    class PACKET *Packet;
  2126.    class dirent *ent;
  2127.  
  2128.    sprintf (Work, "%s%s\\", Cfg->TempPath, User->MailBox);
  2129.    BuildPath (Work);
  2130.  
  2131.    MsgArea = new TMsgData (Cfg->SystemPath);
  2132.    LastTag[0] = '\0';
  2133.    Msg = NULL;
  2134.  
  2135.    if ((dir = opendir (Work)) != NULL) {
  2136.       while ((ent = readdir (dir)) != NULL) {
  2137.          if (strstr (ent->d_name, ".pk") != NULL || strstr (ent->d_name, ".PK") != NULL) {
  2138.             sprintf (Temp, "%s%s", Work, ent->d_name);
  2139.             if ((Packet = new PACKET) != NULL) {
  2140.                if (Packet->Open (Temp) == TRUE) {
  2141.                   Number = Packet->Lowest ();
  2142.                   do {
  2143.                      if (Packet->Read (Number) == TRUE) {
  2144.                         if ((Text = (CHAR *)Packet->Text.First ()) != NULL) {
  2145.                            if (!strncmp (Text, "AREA:", 5)) {
  2146.                               if (stricmp (&Text[5], LastTag)) {
  2147.                                  if (Msg != NULL) {
  2148.                                     Msg->Close ();
  2149.                                     delete Msg;
  2150.                                     Msg = NULL;
  2151.                                  }
  2152.                                  strcpy (LastTag, &Text[5]);
  2153.                                  Found = FALSE;
  2154.                                  if (MsgArea->First () == TRUE)
  2155.                                     do {
  2156.                                        if (MsgArea->EchoTag[0] != '\0' && !stricmp (MsgArea->EchoTag, LastTag)) {
  2157.                                           Found = TRUE;
  2158.                                           break;
  2159.                                        }
  2160.                                        else if (MsgArea->EchoTag[0] == '\0' && !stricmp (MsgArea->Key, LastTag)) {
  2161.                                           Found = TRUE;
  2162.                                           break;
  2163.                                        }
  2164.                                     } while (MsgArea->Next () == TRUE);
  2165.                                  if (Found == TRUE) {
  2166.                                     if (Log != NULL)
  2167.                                        Log->Write (":Message Area: %s - %s", MsgArea->Key, MsgArea->Display);
  2168.  
  2169.                                     Msg = NULL;
  2170.                                     if (MsgArea->Storage == ST_JAM)
  2171.                                        Msg = new JAM (MsgArea->Path);
  2172.                                     else if (MsgArea->Storage == ST_SQUISH)
  2173.                                        Msg = new SQUISH (MsgArea->Path);
  2174.                                     else if (MsgArea->Storage == ST_FIDO)
  2175.                                        Msg = new FIDOSDM (MsgArea->Path);
  2176.                                     else if (MsgArea->Storage == ST_ADEPT)
  2177.                                        Msg = new ADEPT (MsgArea->Path);
  2178.                                     else if (MsgArea->Storage == ST_HUDSON)
  2179.                                        Msg = new HUDSON (MsgArea->Path, (UCHAR)MsgArea->Board);
  2180.                                  }
  2181.                               }
  2182.  
  2183.                               // Toglie la prima linea che contiene il kludge AREA:
  2184.                               Packet->Text.Remove ();
  2185.  
  2186.                               // Nel caso di un'area echomail, aggiunge tutti i kludges
  2187.                               // Necessari.
  2188.                               if (MsgArea->EchoMail == TRUE)
  2189.                                  AddKludges (Packet->Text, MsgArea);
  2190.  
  2191.                               if (Msg != NULL) {
  2192.                                  if (stricmp (Packet->From, User->Name) && stricmp (Packet->From, User->RealName))
  2193.                                     strcpy (Packet->From, User->Name);
  2194.                                  if ((Text = (CHAR *)Packet->Text.First ()) != NULL)
  2195.                                     do {
  2196.                                        if (!strncmp (Text, "SEEN-BY: ", 9) || !strncmp (Text, "\001PATH: ", 7)) {
  2197.                                           Packet->Text.Remove ();
  2198.                                           Text = (CHAR *)Packet->Text.Value ();
  2199.                                        }
  2200.                                        else
  2201.                                           Text = (CHAR *)Packet->Text.Next ();
  2202.                                     } while (Text != NULL);
  2203.  
  2204.                                  Msg->Add (Packet);
  2205.                                  MsgArea->ActiveMsgs++;
  2206.                                  MsgArea->Update ();
  2207.  
  2208.                                  Written = Msg->Highest ();
  2209.                                  Log->Write (":Written message #%lu (%lu)", Msg->UidToMsgn (Number), Number);
  2210.                                  Embedded->Printf ("\n\x16\x01\x0E<<< CONFIRMED: MESSAGE #%lu WRITTEN TO DISK >>>\n\006\007", Msg->UidToMsgn (Number));
  2211.                               }
  2212.                            }
  2213.                         }
  2214.                      }
  2215.                   } while (Packet->Next (Number) == TRUE);
  2216.                }
  2217.                Packet->Close ();
  2218.                delete Packet;
  2219.             }
  2220.             sprintf (Temp, "%s%s", Work, ent->d_name);
  2221.             unlink (Temp);
  2222.          }
  2223.       }
  2224.       closedir (dir);
  2225.    }
  2226.  
  2227.    if (Msg != NULL) {
  2228.       Msg->Close ();
  2229.       delete Msg;
  2230.    }
  2231.    if (MsgArea != NULL)
  2232.       delete MsgArea;
  2233.  
  2234.    return (RetVal);
  2235. }
  2236.  
  2237.  
  2238.