home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / MESSAGE.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  119KB  |  3,197 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 TMsgAreaListing : public TListings
  23. {
  24. public:
  25.    TMsgAreaListing (void);
  26.  
  27.    CHAR   Area[16];
  28.    CHAR   Command[16];
  29.    class  TConfig *Cfg;
  30.    class  TMsgData *Current;
  31.  
  32.    VOID   Begin (VOID);
  33.    USHORT DrawScreen (VOID);
  34.    VOID   PrintCursor (USHORT y);
  35.    VOID   PrintLine (VOID);
  36.    VOID   PrintTitles (VOID);
  37.    VOID   RemoveCursor (USHORT y);
  38.    VOID   Select (VOID);
  39. };
  40.  
  41. class TMsgNewAreaListing : public TListings
  42. {
  43. public:
  44.    class  TConfig *Cfg;
  45.    class  TMsgData *Current;
  46.  
  47.    CHAR   Area[16];
  48.  
  49.    VOID   Begin (VOID);
  50.    USHORT DrawScreen (VOID);
  51.    VOID   PrintCursor (USHORT y);
  52.    VOID   PrintLine (VOID);
  53.    VOID   PrintTitles (VOID);
  54.    VOID   RemoveCursor (USHORT y);
  55.    VOID   Select (VOID);
  56. };
  57.  
  58. class TMessageList : public TListings
  59. {
  60. public:
  61.    USHORT ShowKludges;
  62.    CHAR   LastRead[16];
  63.    ULONG  Number;
  64.    class  TConfig *Cfg;
  65.    class  TMsgBase *Msg;
  66.    class  TMsgData *Current;
  67.    class  TMessage *Parent;
  68.  
  69.    VOID   Begin (VOID);
  70.    USHORT DrawScreen (VOID);
  71.    VOID   PrintCursor (USHORT y);
  72.    VOID   PrintLine (VOID);
  73.    VOID   PrintTitles (VOID);
  74.    VOID   RemoveCursor (USHORT y);
  75.    VOID   Select (VOID);
  76. };
  77.  
  78. // ----------------------------------------------------------------------
  79.  
  80. VOID TMessageList::Begin (VOID)
  81. {
  82.    USHORT i, Total = 0;
  83.    ULONG Msgn;
  84.    LISTDATA ld;
  85.  
  86.    i = 0;
  87.    y = 4;
  88.    Found = FALSE;
  89.    List.Clear ();
  90.    Data.Clear ();
  91.  
  92.    if (Msg  != NULL) {
  93.       Msg->Lock (0L);
  94.  
  95.       do {
  96.          if (Msg->ReadHeader (Number) == TRUE) {
  97.             if (Msg->Private == FALSE || !stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To) || !stricmp (User->Name, Msg->From) || !stricmp (User->RealName, Msg->From)) {
  98.                Msgn = Msg->UidToMsgn (Number);
  99.                sprintf (ld.Key, "%5lu", Msgn);
  100.                if (!stricmp (Msg->From, User->Name))
  101.                   sprintf (ld.Display, "\026\001\007%5lu  \026\001\014%-20.20s  \026\001\012%-20.20s  \026\001\013%-.28s", Msgn, Msg->From, Msg->To, Msg->Subject);
  102.                else if (!stricmp (Msg->To, User->Name))
  103.                   sprintf (ld.Display, "\026\001\007%5lu  \026\001\016%-20.20s  \026\001\014%-20.20s  \026\001\013%-.28s", Msgn, Msg->From, Msg->To, Msg->Subject);
  104.                else
  105.                   sprintf (ld.Display, "\026\001\007%5lu  \026\001\016%-20.20s  \026\001\012%-20.20s  \026\001\013%-.28s", Msgn, Msg->From, Msg->To, Msg->Subject);
  106.                Data.Add (&ld, sizeof (LISTDATA));
  107.             }
  108.          }
  109.          Total++;
  110. #if defined(__OS2__)
  111.          if ((Total % 16) == 0L)
  112.             DosSleep (1L);
  113. #elif defined(__NT__)
  114.          if ((Total % 16) == 0L)
  115.             Sleep (1L);
  116. #endif
  117.       } while (Embedded->AbortSession () == FALSE && Msg->Next (Number) == TRUE);
  118.  
  119.       Msg->UnLock ();
  120.    }
  121.  
  122.    if ((pld = (LISTDATA *)Data.First ()) != NULL) {
  123.       do {
  124.          List.Add (pld->Key);
  125.          i++;
  126.          if (i >= (User->ScreenHeight - 6))
  127.             break;
  128.       } while ((pld = (LISTDATA *)Data.Next ()) != NULL);
  129.    }
  130.  
  131. /*
  132.    if ((pld = (LISTDATA *)Data.First ()) != NULL) {
  133.       do {
  134.          if (!strcmp (pld->Key, LastRead))
  135.             Found = TRUE;
  136.          List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  137.          i++;
  138.          if (i >= (User->ScreenHeight - 6)) {
  139.             if (Found == TRUE)
  140.                break;
  141.             List.Clear ();
  142.             i = 0;
  143.          }
  144.       } while ((pld = (LISTDATA *)Data.Next ()) != NULL);
  145.    }
  146.  
  147.    if (Found == FALSE) {
  148.       List.Clear ();
  149.       if ((pld = (LISTDATA *)Data.First ()) != NULL) {
  150.          do {
  151.             List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  152.             i++;
  153.             if (i >= (User->ScreenHeight - 6))
  154.                break;
  155.          } while ((pld = (LISTDATA *)Data.Next ()) != NULL);
  156.       }
  157.    }
  158. */
  159. }
  160.  
  161. USHORT TMessageList::DrawScreen (VOID)
  162. {
  163.    USHORT i;
  164.  
  165.    i = 0;
  166.    do {
  167.       List.Next ();
  168.       pld = (LISTDATA *)Data.Value ();
  169. //      if (Found == TRUE && !strcmp (pld->Key, LastRead)) {
  170. //         y = (USHORT)(i + 4);
  171. //         Found = FALSE;
  172. //      }
  173.       PrintLine ();
  174.       i++;
  175.    } while (Data.Next () != NULL && i < (User->ScreenHeight - 6));
  176.  
  177.    return (i);
  178. }
  179.  
  180. VOID TMessageList::PrintTitles (VOID)
  181. {
  182.    Embedded->Printf ("\x0C\x16\x01\x0B%s \x16\x01\x0A- \x16\x01\x0B%s\026\007\n", Current->Key, Current->Display);
  183.    Embedded->Printf ("\026\001\017    #  From                  To                    Subject\n\031─\005  \031─\024  \031─\024  \031─\034\n");
  184.  
  185.    Embedded->PrintfAt ((USHORT)(User->ScreenHeight - 2), 1, "\026\001\017\031─\005  \031─\024  \031─\024  \031─\034\n");
  186.  
  187.    Embedded->Printf ("\026\001\016Use your arrow keys or CTRL-X / CTRL-E to hilight an area, RETURN selects it.\n");
  188.    Embedded->Printf ("\026\001\016Hit CTRL-V for next page, CTRL-Y for previous page, or X to exit.");
  189.  
  190.    Embedded->PrintfAt (4, 1, "");
  191. }
  192.  
  193. VOID TMessageList::PrintLine (VOID)
  194. {
  195.    Embedded->Printf ("%s\n", pld->Display);
  196. }
  197.  
  198. VOID TMessageList::PrintCursor (USHORT y)
  199. {
  200.    Embedded->PrintfAt (y, 1, "\x16\x01\x70%-5.5s\x16\x01\x07", (PSZ)List.Value ());
  201. }
  202.  
  203. VOID TMessageList::RemoveCursor (USHORT y)
  204. {
  205.    Embedded->PrintfAt (y, 1, "\x16\x01\x07%-5.5s\x16\x01\x07", (PSZ)List.Value ());
  206. }
  207.  
  208. VOID TMessageList::Select (VOID)
  209. {
  210.    USHORT Line, MaxLine, gotFrom = FALSE, gotTo = FALSE;
  211.    CHAR *Text, Temp[96], *p, Flags[96];
  212.    ULONG Msgn;
  213.  
  214.    if (Msg != NULL) {
  215.       Msgn = atol ((PSZ)List.Value ());
  216.       Msg->Read (Msg->MsgnToUid (Msgn));
  217.  
  218.       if (Log != NULL)
  219.          Log->Write (":Display Msg. #%lu, area %s (%lu)", Msgn, Current->Key, Msg->Current);
  220.  
  221.       if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  222.          do {
  223.             if (!strncmp (p, " * Origin: ", 11)) {
  224.                Msg->ToAddress[0] = '\0';
  225.  
  226.                strcpy (Temp, &p[11]);
  227.                p = strchr (Temp, '\0');
  228.                while (--p > Temp) {
  229.                   if (*p != ' ' && *p != ')')
  230.                      break;
  231.                   *p = '\0';
  232.                }
  233.                if (p > Temp) {
  234.                   while (--p > Temp) {
  235.                      if (*p == '(' || *p == ' ')
  236.                         break;
  237.                   }
  238.                }
  239.                if (*p == '(' || *p == ' ')
  240.                   *p++;
  241.                strcpy (Msg->FromAddress, p);
  242.                break;
  243.             }
  244.             else if (!strncmp (p, "\001From: ", 7)) {
  245.                Msg->FromAddress[0] = '\0';
  246.                if (gotTo == FALSE)
  247.                   Msg->ToAddress[0] = '\0';
  248.                ParseAddress (&p[7], Msg->From, Msg->FromAddress);
  249.                gotFrom = TRUE;
  250.             }
  251.             else if (!strncmp (p, "\001To: ", 5)) {
  252.                if (gotFrom == FALSE)
  253.                   Msg->FromAddress[0] = '\0';
  254.                Msg->ToAddress[0] = '\0';
  255.                ParseAddress (&p[5], Msg->To, Msg->ToAddress);
  256.                gotTo = TRUE;
  257.             }
  258.             if (gotFrom == TRUE && gotTo == TRUE)
  259.                break;
  260.          } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  261.  
  262.       Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEHDR), Current->Display, (CHAR)(80 - strlen (Current->Display) - 3));
  263.       if (Msg->Original != 0L && Msg->Reply == 0L)
  264.          sprintf (Temp, Language->Text (LNG_MESSAGENUMBER1), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Original));
  265.       else if (Msg->Original == 0L && Msg->Reply != 0L)
  266.          sprintf (Temp, Language->Text (LNG_MESSAGENUMBER2), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Reply));
  267.       else if (Msg->Original != 0L && Msg->Reply != 0L)
  268.          sprintf (Temp, Language->Text (LNG_MESSAGENUMBER3), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Original), Msg->UidToMsgn (Msg->Reply));
  269.       else
  270.          sprintf (Temp, Language->Text (LNG_MESSAGENUMBER), Msgn, Msg->Number ());
  271.       Flags[0] = '\0';
  272.       if (Msg->Received == TRUE)
  273.          strcat (Flags, Language->Text (LNG_MSGFLAG_RCV));
  274.       if (Msg->Sent == TRUE)
  275.          strcat (Flags, Language->Text (LNG_MSGFLAG_SNT));
  276.       if (Msg->Private == TRUE)
  277.          strcat (Flags, Language->Text (LNG_MSGFLAG_PVT));
  278.       if (Msg->Crash == TRUE)
  279.          strcat (Flags, Language->Text (LNG_MSGFLAG_CRA));
  280.       if (Msg->KillSent == TRUE)
  281.          strcat (Flags, Language->Text (LNG_MSGFLAG_KS));
  282.       if (Msg->Local == TRUE)
  283.          strcat (Flags, Language->Text (LNG_MSGFLAG_LOC));
  284.       if (Msg->Hold == TRUE)
  285.          strcat (Flags, Language->Text (LNG_MSGFLAG_HLD));
  286.       if (Msg->FileAttach == TRUE)
  287.          strcat (Flags, Language->Text (LNG_MSGFLAG_ATT));
  288.       if (Msg->FileRequest == TRUE)
  289.          strcat (Flags, Language->Text (LNG_MSGFLAG_FRQ));
  290.       if (Msg->Intransit == TRUE)
  291.          strcat (Flags, Language->Text (LNG_MSGFLAG_TRS));
  292.       Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFLAGS), Temp, Flags);
  293.  
  294.       Parent->BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Written);
  295.       Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFROM), Msg->From, Msg->FromAddress, Temp);
  296.       Parent->BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Arrived);
  297.       Embedded->BufferedPrintf (Language->Text (LNG_MESSAGETO), Msg->To, Msg->ToAddress, Temp);
  298.       if (Msg->FileAttach == TRUE || Msg->FileRequest == TRUE)
  299.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFILE), Msg->Subject);
  300.       else
  301.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGESUBJECT), Msg->Subject);
  302.       Embedded->BufferedPrintf ("\x16\x01\x13\031─\120");
  303.  
  304.       Line = 6;
  305.  
  306.       if ((Text = (CHAR *)Msg->Text.First ()) != NULL)
  307.          do {
  308.             if (ShowKludges == TRUE || (strncmp (Text, "SEEN-BY: ", 9) && Text[0] != 1)) {
  309.                if (!strncmp (Text, "SEEN-BY: ", 9) || Text[0] == 1) {
  310.                   if (Text[0] == 1)
  311.                      Text++;
  312.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEKLUDGE), Text);
  313.                }
  314.                else if (!strncmp (Text, " * Origin", 9) || !strncmp (Text, "---", 3))
  315.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEORIGIN), Text);
  316.                else if (strchr (Text, '>') != NULL)
  317.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEQUOTE), Text);
  318.                else
  319.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGETEXT), Text);
  320.  
  321.                MaxLine = Line;
  322.                if ((Line = Embedded->MoreQuestion (Line)) == 1) {
  323.                   MaxLine++;
  324.                   while (MaxLine > 6)
  325.                      Embedded->BufferedPrintfAt (MaxLine--, 1, "\026\007");
  326.                   Line = 6;
  327.                }
  328.             }
  329.          } while ((Text = (CHAR *)Msg->Text.Next ()) != NULL && Embedded->AbortSession () == FALSE && Line != 0);
  330.  
  331.       Embedded->UnbufferBytes ();
  332.  
  333.       if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  334.          Msg->Received = TRUE;
  335.          Msg->WriteHeader (Msg->Current);
  336.       }
  337.  
  338.       if (Line > 6)
  339.          Embedded->MoreQuestion (99);
  340.  
  341.       Redraw = Titles = TRUE;
  342.    }
  343. }
  344.  
  345. // ----------------------------------------------------------------------
  346.  
  347. TMessage::TMessage (PSZ pszDataPath)
  348. {
  349.    Log = NULL;
  350.    Language = NULL;
  351.    Embedded = NULL;
  352.    Msg = NULL;
  353.  
  354.    strcpy (DataPath, pszDataPath);
  355.    Current = new TMsgData (DataPath);
  356.  
  357.    ShowKludges = FALSE;
  358.    Width = 79;
  359.    Height = 24;
  360.    DoCls = More = TRUE;
  361. }
  362.  
  363. TMessage::~TMessage (void)
  364. {
  365.    if (Msg != NULL) {
  366.       Msg->Close ();
  367.       delete Msg;
  368.    }
  369.    if (Current != NULL)
  370.       delete Current;
  371. }
  372.  
  373. VOID TMessage::BriefList (VOID)
  374. {
  375.    CHAR Temp[16];
  376.    SHORT Line, Continue;
  377.    ULONG Number;
  378.    class TMessageList *List;
  379.  
  380.    if (Msg != NULL) {
  381.       Number = 0L;
  382.       if (User != NULL) {
  383.          if (User->MsgTag->Read (Current->Key) == TRUE)
  384.             Number = User->MsgTag->LastRead;
  385.       }
  386.  
  387.       if (Msg->Number () != 0L) {
  388.          Embedded->Printf ("\n\026\001\017Start displaying at which msg# (\"=\" for current): ");
  389.          Embedded->Input (Temp, (USHORT)(sizeof (Temp) - 1), 0);
  390.  
  391.          if (Temp[0] != '\0') {
  392.             if (Temp[0] != '=')
  393.                Number = Msg->MsgnToUid (atol (Temp));
  394.  
  395.             if ((Embedded->Ansi == TRUE || Embedded->Avatar == TRUE) && User->FullScreen == TRUE) {
  396.                if ((List = new TMessageList) != NULL) {
  397.                   List->Cfg = Cfg;
  398.                   List->Embedded = Embedded;
  399.                   List->Log = Log;
  400.                   List->User = User;
  401.                   List->Language = Language;
  402.                   List->Current = Current;
  403.                   List->Msg = Msg;
  404.                   List->Number = Number;
  405.                   List->ShowKludges = ShowKludges;
  406.                   List->Parent = this;
  407.                   sprintf (List->LastRead, "%5lu", atol (Temp));
  408.                   List->Run ();
  409.                   delete List;
  410.                }
  411.             }
  412.             else {
  413.                Line = 1;
  414.                Embedded->Printf ("\x0C");
  415.                Embedded->Printf ("\026\001\017    #  From                    To                     Subject\n\031─\005  \031─\026  \031─\025  \031─\027\n");
  416.  
  417.                Continue = Msg->Next (Number);
  418.                while (Embedded->AbortSession () == FALSE && Line != 0 && Continue == TRUE) {
  419.                   if (Msg->ReadHeader (Number) == TRUE) {
  420.                      if (Msg->Private == FALSE || !stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To) || !stricmp (User->Name, Msg->From) || !stricmp (User->RealName, Msg->From)) {
  421.                         if ((Line = Embedded->MoreQuestion (Line)) == 1) {
  422.                            Embedded->Printf ("\x0C");
  423.                            Embedded->Printf ("\026\001\017    #  From                    To                     Subject\n\031─\005  \031─\026  \031─\025  \031─\027\n");
  424.                            Line = 2;
  425.                         }
  426.                         Embedded->Printf ("\026\001\007%5lu  \026\001\016%-22.22s  \026\001\012%-21.21s  \026\001\013%-.23s\n", Msg->UidToMsgn (Msg->Current), Msg->From, Msg->To, Msg->Subject);
  427.                      }
  428.                   }
  429.                   Continue = Msg->Next (Number);
  430.                }
  431.  
  432.                if (Line > 2)
  433.                   Embedded->PressEnter ();
  434.             }
  435.          }
  436.       }
  437.    }
  438. }
  439.  
  440. VOID TMessage::Delete (VOID)
  441. {
  442.    CHAR szTemp[20];
  443.    ULONG ulMsg, ulNumber, First;
  444.  
  445.    if (Msg != NULL) {
  446.       ulNumber = Msg->Highest ();
  447.       First = Msg->Lowest ();
  448.  
  449.       do {
  450.          Embedded->Printf ("\n\x16\x01\013Enter the message number to be erased (%lu-%lu): ", First, ulNumber);
  451.          Embedded->Input (szTemp, (USHORT)(sizeof (szTemp) - 1), 0);
  452.          ulMsg = atol (szTemp);
  453.          if (ulMsg < First || ulMsg > ulNumber)
  454.             Embedded->Printf ("\n\x16\x01\x0DThe message #%ld is out of range.\n\006\007\006\007", ulMsg);
  455.       } while (ulMsg > ulNumber && ulMsg != 0 && Embedded->AbortSession () == FALSE);
  456.  
  457.       if (ulMsg > 0) {
  458.          if (Msg->ReadHeader (ulMsg) == TRUE) {
  459.             if (!stricmp (Msg->From, User->Name) || !stricmp (Msg->To, User->Name)) {
  460.                if (Msg->Delete (ulMsg) == TRUE)
  461.                   Embedded->Printf ("\n\x16\x01\x0E<<< CONFIRMED: MESSAGE #%ld ERASED >>>\n", ulMsg);
  462.             }
  463.             else
  464.                Embedded->Printf ("\n\x16\x01\x0DSorry, message number %ld is neither FROM you,\nnor a PRIVATE message TO you, so you can't erase it.\n\006\007\006\007", ulMsg);
  465.          }
  466.          else
  467.             Embedded->Printf ("\n\x16\x01\x0DSorry, message number %ld is neither FROM you,\nnor a PRIVATE message TO you, so you can't erase it.\n\006\007\006\007", ulMsg);
  468.  
  469.          Current->LastMessage = Msg->Highest ();
  470.          Current->FirstMessage = Msg->Lowest ();
  471.          Current->ActiveMsgs = Msg->Number ();
  472.       }
  473.    }
  474. }
  475.  
  476. VOID TMessage::BuildDate (PSZ format, PSZ dest, MDATE *date)
  477. {
  478.    CHAR Temp[16];
  479.  
  480.    while (*format != '\0') {
  481.       if (*format == '%') {
  482.          format++;
  483.          switch (*format) {
  484.             case 'A':
  485.                if (date->Hour >= 12)
  486.                   strcpy (dest, "pm");
  487.                else
  488.                   strcpy (dest, "am");
  489.                dest += 2;
  490.                format++;
  491.                break;
  492.             case 'B':
  493.                sprintf (Temp, "%2d", date->Month);
  494.                strcpy (dest, Temp);
  495.                dest += strlen (Temp);
  496.                format++;
  497.                break;
  498.             case 'C':
  499.                sprintf (Temp, "%-3.3s", Language->Months[date->Month - 1]);
  500.                strcpy (dest, Temp);
  501.                dest += strlen (Temp);
  502.                format++;
  503.                break;
  504.             case 'D':
  505.                sprintf (Temp, "%2d", date->Day);
  506.                strcpy (dest, Temp);
  507.                dest += strlen (Temp);
  508.                format++;
  509.                break;
  510.             case 'E':
  511.                if (date->Hour > 12)
  512.                   sprintf (Temp, "%2d", date->Hour - 12);
  513.                else
  514.                   sprintf (Temp, "%2d", date->Hour);
  515.                strcpy (dest, Temp);
  516.                dest += strlen (Temp);
  517.                format++;
  518.                break;
  519.             case 'H':
  520.                sprintf (Temp, "%2d", date->Hour);
  521.                strcpy (dest, Temp);
  522.                dest += strlen (Temp);
  523.                format++;
  524.                break;
  525.             case 'M':
  526.                sprintf (Temp, "%02d", date->Minute);
  527.                strcpy (dest, Temp);
  528.                dest += strlen (Temp);
  529.                format++;
  530.                break;
  531.             case 'S':
  532.                sprintf (Temp, "%02d", date->Second);
  533.                strcpy (dest, Temp);
  534.                dest += strlen (Temp);
  535.                format++;
  536.                break;
  537.             case 'Y':
  538.                sprintf (Temp, "%2d", date->Year % 100);
  539.                strcpy (dest, Temp);
  540.                dest += strlen (Temp);
  541.                format++;
  542.                break;
  543.             case 'Z':
  544.                sprintf (Temp, "%4d", date->Year);
  545.                strcpy (dest, Temp);
  546.                dest += strlen (Temp);
  547.                format++;
  548.                break;
  549.             default:
  550.                *dest++ = *format++;
  551.                break;
  552.          }
  553.       }
  554.       else
  555.          *dest++ = *format++;
  556.    }
  557.    *dest = '\0';
  558. }
  559.  
  560. VOID TMessage::DisplayCurrent (VOID)
  561. {
  562.    USHORT InitialLine;
  563.    USHORT Line, MaxLine, gotFrom = FALSE, gotTo = FALSE;
  564.    CHAR *Text, Temp[96], *p, Flags[96];
  565.    ULONG Msgn;
  566.  
  567.    if (Msg != NULL) {
  568.       if (Msg->Current == 0L)
  569.          Msg->Read (Msg->MsgnToUid (Current->LastReaded));
  570.       Msgn = Msg->UidToMsgn (Msg->Current);
  571.       Current->LastReaded = Msgn;
  572.       if (Log != NULL && Pause == FALSE)
  573.          Log->Write (":Display Msg. #%lu, area %s (%lu)", Msgn, Current->Key, Msg->Current);
  574.  
  575.       if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  576.          do {
  577.             if (!strncmp (p, " * Origin: ", 11)) {
  578.                Msg->ToAddress[0] = '\0';
  579.  
  580.                strcpy (Temp, &p[11]);
  581.                p = strchr (Temp, '\0');
  582.                while (--p > Temp) {
  583.                   if (*p != ' ' && *p != ')')
  584.                      break;
  585.                   *p = '\0';
  586.                }
  587.                if (p > Temp) {
  588.                   while (--p > Temp) {
  589.                      if (*p == '(' || *p == ' ')
  590.                         break;
  591.                   }
  592.                }
  593.                if (*p == '(' || *p == ' ')
  594.                   *p++;
  595.                strcpy (Msg->FromAddress, p);
  596.                break;
  597.             }
  598.             else if (!strncmp (p, "\001From: ", 7)) {
  599.                Msg->FromAddress[0] = '\0';
  600.                if (gotTo == FALSE)
  601.                   Msg->ToAddress[0] = '\0';
  602.                ParseAddress (&p[7], Msg->From, Msg->FromAddress);
  603.                gotFrom = TRUE;
  604.             }
  605.             else if (!strncmp (p, "\001To: ", 5)) {
  606.                if (gotFrom == FALSE)
  607.                   Msg->FromAddress[0] = '\0';
  608.                Msg->ToAddress[0] = '\0';
  609.                ParseAddress (&p[5], Msg->To, Msg->ToAddress);
  610.                gotTo = TRUE;
  611.             }
  612.             if (gotFrom == TRUE && gotTo == TRUE)
  613.                break;
  614.          } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  615.  
  616.       Flags[0] = '\0';
  617.       if (Msg->Received == TRUE)
  618.          strcat (Flags, Language->Text (LNG_MSGFLAG_RCV));
  619.       if (Msg->Sent == TRUE)
  620.          strcat (Flags, Language->Text (LNG_MSGFLAG_SNT));
  621.       if (Msg->Private == TRUE)
  622.          strcat (Flags, Language->Text (LNG_MSGFLAG_PVT));
  623.       if (Msg->Crash == TRUE)
  624.          strcat (Flags, Language->Text (LNG_MSGFLAG_CRA));
  625.       if (Msg->KillSent == TRUE)
  626.          strcat (Flags, Language->Text (LNG_MSGFLAG_KS));
  627.       if (Msg->Local == TRUE)
  628.          strcat (Flags, Language->Text (LNG_MSGFLAG_LOC));
  629.       if (Msg->Hold == TRUE)
  630.          strcat (Flags, Language->Text (LNG_MSGFLAG_HLD));
  631.       if (Msg->FileAttach == TRUE)
  632.          strcat (Flags, Language->Text (LNG_MSGFLAG_ATT));
  633.       if (Msg->FileRequest == TRUE)
  634.          strcat (Flags, Language->Text (LNG_MSGFLAG_FRQ));
  635.       if (Msg->Intransit == TRUE)
  636.          strcat (Flags, Language->Text (LNG_MSGFLAG_TRS));
  637.  
  638.       if (User->FullReader == TRUE && (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE)) {
  639.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEHDR), Current->Display, (CHAR)(80 - strlen (Current->Display) - 3));
  640.          if (Msg->Original != 0L && Msg->Reply == 0L)
  641.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER1), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Original));
  642.          else if (Msg->Original == 0L && Msg->Reply != 0L)
  643.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER2), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Reply));
  644.          else if (Msg->Original != 0L && Msg->Reply != 0L)
  645.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER3), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Original), Msg->UidToMsgn (Msg->Reply));
  646.          else
  647.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER), Msgn, Msg->Number ());
  648.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFLAGS), Temp, Flags);
  649.  
  650.          BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Written);
  651.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFROM), Msg->From, Msg->FromAddress, Temp);
  652.          BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Arrived);
  653.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGETO), Msg->To, Msg->ToAddress, Temp);
  654.          if (Msg->FileAttach == TRUE || Msg->FileRequest == TRUE)
  655.             Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFILE), Msg->Subject);
  656.          else
  657.             Embedded->BufferedPrintf (Language->Text (LNG_MESSAGESUBJECT), Msg->Subject);
  658.          Embedded->BufferedPrintf ("\x16\x01\x13\031─\120");
  659.  
  660.          InitialLine = Line = 6;
  661.       }
  662.       else {
  663.          Embedded->BufferedPrintf ("\x0C");
  664.          Embedded->BufferedPrintf ("\026\001\003From:    \026\001\016%-36.36s \026\001\017%-.33s\n", Msg->From, Flags);
  665.  
  666.          BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Written);
  667.          Embedded->BufferedPrintf ("\026\001\003To:      \026\001\016%-36.36s \026\001\012Msg #%lu, %-.23s\n", Msg->To, Msgn, Temp);
  668.  
  669.          if (Msg->FileAttach == TRUE || Msg->FileRequest == TRUE)
  670.             Embedded->BufferedPrintf ("\026\001\003File(s): \026\001\016%-.70s\n", Msg->Subject);
  671.          else
  672.             Embedded->BufferedPrintf ("\026\001\003Subject: \026\001\016%-.70s\n\n", Msg->Subject);
  673.  
  674.          InitialLine = Line = 4;
  675.       }
  676.  
  677.       if ((Text = (CHAR *)Msg->Text.First ()) != NULL)
  678.          do {
  679.             if (ShowKludges == TRUE || (strncmp (Text, "SEEN-BY: ", 9) && Text[0] != 1)) {
  680.                if (!strncmp (Text, "SEEN-BY: ", 9) || Text[0] == 1) {
  681.                   if (Text[0] == 1)
  682.                      Text++;
  683.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEKLUDGE), Text);
  684.                }
  685.                else if (!strncmp (Text, " * Origin", 9) || !strncmp (Text, "---", 3))
  686.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEORIGIN), Text);
  687.                else if (strchr (Text, '>') != NULL)
  688.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEQUOTE), Text);
  689.                else
  690.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGETEXT), Text);
  691.  
  692.                MaxLine = Line;
  693.                if ((Line = Embedded->MoreQuestion (Line)) == 1) {
  694.                   MaxLine++;
  695.                   while (MaxLine > InitialLine)
  696.                      Embedded->BufferedPrintfAt (MaxLine--, 1, "\026\007");
  697.                   Line = InitialLine;
  698.                }
  699.             }
  700.          } while ((Text = (CHAR *)Msg->Text.Next ()) != NULL && Embedded->AbortSession () == FALSE && Line != 0);
  701.  
  702.       if (User->FullReader == FALSE || (Embedded->Ansi == FALSE && Embedded->Avatar == FALSE)) {
  703.          if (Msg->Original != 0L && Msg->Reply == 0L)
  704.             Embedded->BufferedPrintf ("\n\026\001\017*** This is a reply to #%lu.\n", Msg->UidToMsgn (Msg->Original));
  705.          else if (Msg->Original == 0L && Msg->Reply != 0L)
  706.             Embedded->BufferedPrintf ("\n\026\001\017*** See also #%lu.\n", Msg->UidToMsgn (Msg->Reply));
  707.          else if (Msg->Original != 0L && Msg->Reply != 0L)
  708.             Embedded->BufferedPrintf ("\n\026\001\017*** This is a reply to #%lu.  *** See also #%lu.\n", Msg->UidToMsgn (Msg->Original), Msg->UidToMsgn (Msg->Reply));
  709.          Line += 2;
  710.       }
  711.  
  712.       Embedded->UnbufferBytes ();
  713.  
  714.       if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  715.          Msg->Received = TRUE;
  716.          Msg->WriteHeader (Msg->Current);
  717.       }
  718.  
  719.       if (Line > InitialLine) {
  720.          MaxLine = Line;
  721.          Embedded->MoreQuestion (99);
  722.          MaxLine++;
  723.          while (MaxLine > InitialLine)
  724.             Embedded->BufferedPrintfAt (MaxLine--, 1, "\026\007");
  725.       }
  726.    }
  727. }
  728.  
  729. VOID TMessage::DisplayText (VOID)
  730. {
  731.    USHORT gotFrom = FALSE, gotTo = FALSE;
  732.    CHAR *Text, Temp[96], Flags[96];
  733.    ULONG Msgn;
  734.  
  735.    if (Msg != NULL) {
  736.       Msgn = Msg->UidToMsgn (Msg->Current);
  737.       Current->LastReaded = Msgn;
  738.  
  739.       Flags[0] = '\0';
  740.       if (Msg->Received == TRUE)
  741.          strcat (Flags, Language->Text (LNG_MSGFLAG_RCV));
  742.       if (Msg->Sent == TRUE)
  743.          strcat (Flags, Language->Text (LNG_MSGFLAG_SNT));
  744.       if (Msg->Private == TRUE)
  745.          strcat (Flags, Language->Text (LNG_MSGFLAG_PVT));
  746.       if (Msg->Crash == TRUE)
  747.          strcat (Flags, Language->Text (LNG_MSGFLAG_CRA));
  748.       if (Msg->KillSent == TRUE)
  749.          strcat (Flags, Language->Text (LNG_MSGFLAG_KS));
  750.       if (Msg->Local == TRUE)
  751.          strcat (Flags, Language->Text (LNG_MSGFLAG_LOC));
  752.       if (Msg->Hold == TRUE)
  753.          strcat (Flags, Language->Text (LNG_MSGFLAG_HLD));
  754.       if (Msg->FileAttach == TRUE)
  755.          strcat (Flags, Language->Text (LNG_MSGFLAG_ATT));
  756.       if (Msg->FileRequest == TRUE)
  757.          strcat (Flags, Language->Text (LNG_MSGFLAG_FRQ));
  758.       if (Msg->Intransit == TRUE)
  759.          strcat (Flags, Language->Text (LNG_MSGFLAG_TRS));
  760.       Embedded->BufferedPrintf ("\n");
  761.       Embedded->BufferedPrintf ("\026\001\003From:    \026\001\016%-36.36s \026\001\017%-.33s\n", Msg->From, Flags);
  762.  
  763.       BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Written);
  764.       Embedded->BufferedPrintf ("\026\001\003To:      \026\001\016%-36.36s \026\001\012Msg #%lu, %-.23s\n", Msg->To, Msgn, Temp);
  765.  
  766.       if (Msg->FileAttach == TRUE || Msg->FileRequest == TRUE)
  767.          Embedded->BufferedPrintf ("\026\001\003File(s): \026\001\016%-.70s\n", Msg->Subject);
  768.       else
  769.          Embedded->BufferedPrintf ("\026\001\003Subject: \026\001\016%-.70s\n\n", Msg->Subject);
  770.  
  771.       if ((Text = (CHAR *)Msg->Text.First ()) != NULL)
  772.          do {
  773.             if (ShowKludges == TRUE || (strncmp (Text, "SEEN-BY: ", 9) && Text[0] != 1)) {
  774.                if (!strncmp (Text, "SEEN-BY: ", 9) || Text[0] == 1) {
  775.                   if (Text[0] == 1)
  776.                      Text++;
  777.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEKLUDGE), Text);
  778.                }
  779.                else if (!strncmp (Text, " * Origin", 9) || !strncmp (Text, "---", 3))
  780.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEORIGIN), Text);
  781.                else if (strchr (Text, '>') != NULL)
  782.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEQUOTE), Text);
  783.                else
  784.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGETEXT), Text);
  785.             }
  786.          } while ((Text = (CHAR *)Msg->Text.Next ()) != NULL && Embedded->AbortSession () == FALSE);
  787.  
  788.       Embedded->UnbufferBytes ();
  789.    }
  790. }
  791.  
  792. VOID TMessage::GetOrigin (class TMsgData *Data, PSZ Origin)
  793. {
  794.    FILE *fp;
  795.    int i, max;
  796.    CHAR Temp[128];
  797.  
  798.    strcpy (Origin, Cfg->SystemName);
  799.    if (Data->Origin[0] != '\0')
  800.       strcpy (Origin, Data->Origin);
  801.    else if (Data->OriginIndex == OIDX_DEFAULT)
  802.       strcpy (Origin, Cfg->SystemName);
  803.    else if (Data->OriginIndex == OIDX_RANDOM) {
  804.       srand ((unsigned int)time (NULL));
  805.       sprintf (Temp, "%sorigin.txt", Cfg->SystemPath);
  806.       if ((fp = fopen (Temp, "rt")) != NULL) {
  807.          max = 0;
  808.          while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL)
  809.             max++;
  810.          while ((i = rand ()) > max)
  811.             ;
  812.          fseek (fp, 0L, SEEK_SET);
  813.          while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  814.             if (i == 0) {
  815.                if (Temp[strlen (Temp) - 1] == '\n')
  816.                   Temp[strlen (Temp) - 1] = '\0';
  817.                strcpy (Origin, Temp);
  818.                break;
  819.             }
  820.             i--;
  821.          }
  822.          fclose (fp);
  823.       }
  824.    }
  825.    else {
  826.       i = 1;
  827.       sprintf (Temp, "%sorigin.txt", Cfg->SystemPath);
  828.       if ((fp = fopen (Temp, "rt")) != NULL) {
  829.          while (fgets (Temp, sizeof (Temp) - 1, fp) != NULL) {
  830.             if (i == Data->OriginIndex) {
  831.                if (Temp[strlen (Temp) - 1] == '\n')
  832.                   Temp[strlen (Temp) - 1] = '\0';
  833.                strcpy (Origin, Temp);
  834.                break;
  835.             }
  836.          }
  837.          fclose (fp);
  838.       }
  839.    }
  840. }
  841.  
  842. VOID TMessage::Reply (VOID)
  843. {
  844.    ULONG Number;
  845.    class TMsgEditor *Editor;
  846.  
  847.    Number = Msg->Current;
  848.  
  849.    if (User->Level >= Current->WriteLevel) {
  850.       if ((User->AccessFlags & Current->WriteFlags) == Current->WriteFlags) {
  851.          if (Log != NULL)
  852.             Log->Write (":Reply to Msg. #%lu, area %s", Msg->UidToMsgn (Number), Current->Key);
  853.  
  854.          if ((Editor = new TMsgEditor) != NULL) {
  855.             Editor->Cfg = Cfg;
  856.             Editor->Embedded = Embedded;
  857.             Editor->Log = Log;
  858.             Editor->Msg = Msg;
  859.             Editor->Language = Language;
  860.             Editor->Width = User->ScreenWidth;
  861.             Editor->Height = User->ScreenHeight;
  862.             strcpy (Editor->UserName, User->Name);
  863.             strcpy (Editor->AreaKey, Current->Key);
  864.             strcpy (Editor->AreaTitle, Current->Display);
  865.             if (Current->EchoMail == TRUE) {
  866.                Editor->EchoMail = TRUE;
  867.                GetOrigin (Current, Editor->Origin);
  868.                if (Cfg->MailAddress.First () == TRUE)
  869.                   strcpy (Editor->Address, Cfg->MailAddress.String);
  870.                if (Current->Address[0] != '\0')
  871.                   strcpy (Editor->Address, Current->Address);
  872.             }
  873.             if (User->FullEd == TRUE && (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE))
  874.                Editor->UseFullScreen = TRUE;
  875.             if (Editor->Reply () == TRUE)
  876.                Editor->Menu ();
  877.             delete Editor;
  878.          }
  879.  
  880.          Msg->Read (Number);
  881.          Current->ActiveMsgs = Msg->Number ();
  882.          Current->FirstMessage = Msg->Lowest ();
  883.          Current->LastMessage = Msg->Highest ();
  884.          Current->LastReaded = Msg->UidToMsgn (Number);
  885.          Current->Update ();
  886.       }
  887.       else {
  888.          Embedded->Printf ("\026\001\015Sorry, you can't write messages in this Conference.\n\006\007\006\007");
  889.          if (Log != NULL)
  890.             Log->Write ("!User can't write messages (flags)");
  891.       }
  892.    }
  893.    else {
  894.       Embedded->Printf ("\026\001\015Sorry, you can't write messages in this Conference.\n\006\007\006\007");
  895.       if (Log != NULL)
  896.          Log->Write ("!User can't write messages (level)");
  897.    }
  898. }
  899.  
  900. VOID TMessage::Write (VOID)
  901. {
  902.    class TMsgEditor *Editor;
  903.  
  904.    if (User->Level >= Current->WriteLevel) {
  905.       if ((User->AccessFlags & Current->WriteFlags) == Current->WriteFlags) {
  906.          if (Log != NULL)
  907.             Log->Write (":Writing Msg. in area %s", Current->Key);
  908.  
  909.          if ((Editor = new TMsgEditor) != NULL) {
  910.             Editor->Cfg = Cfg;
  911.             Editor->Embedded = Embedded;
  912.             Editor->Log = Log;
  913.             Editor->Msg = Msg;
  914.             Editor->Language = Language;
  915.             Editor->Width = User->ScreenWidth;
  916.             Editor->Height = User->ScreenHeight;
  917.             strcpy (Editor->UserName, User->Name);
  918.             strcpy (Editor->AreaKey, Current->Key);
  919.             strcpy (Editor->AreaTitle, Current->Display);
  920.             if (Current->EchoMail == TRUE) {
  921.                Editor->EchoMail = TRUE;
  922.                GetOrigin (Current, Editor->Origin);
  923.                if (Cfg->MailAddress.First () == TRUE)
  924.                   strcpy (Editor->Address, Cfg->MailAddress.String);
  925.                if (Current->Address[0] != '\0')
  926.                   strcpy (Editor->Address, Current->Address);
  927.             }
  928.             if (User->FullEd == TRUE && (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE))
  929.                Editor->UseFullScreen = TRUE;
  930.             if (Editor->Write () == TRUE)
  931.                Editor->Menu ();
  932.             delete Editor;
  933.          }
  934.  
  935.          Current->ActiveMsgs = Msg->Number ();
  936.          Current->FirstMessage = Msg->Lowest ();
  937.          Current->LastMessage = Msg->Highest ();
  938.          Current->Update ();
  939.       }
  940.       else {
  941.          Embedded->Printf ("\026\001\015Sorry, you can't write messages in this Conference.\n\006\007\006\007");
  942.          if (Log != NULL)
  943.             Log->Write ("!User can't write messages (flags)");
  944.       }
  945.    }
  946.    else {
  947.       Embedded->Printf ("\026\001\015Sorry, you can't write messages in this Conference.\n\006\007\006\007");
  948.       if (Log != NULL)
  949.          Log->Write ("!User can't write messages (level)");
  950.    }
  951. }
  952.  
  953. VOID TMessage::Read (ULONG Number)
  954. {
  955.    ULONG Last;
  956.  
  957.    if (Msg != NULL) {
  958.       Last = Msg->Current;
  959.       if (Msg->Read (Number) == TRUE) {
  960.          if (Msg->Private == TRUE && stricmp (User->Name, Msg->To) && stricmp (User->RealName, Msg->To) && stricmp (User->Name, Msg->From) && stricmp (User->RealName, Msg->From))
  961.             Embedded->Printf ("\026\001\015Sorry, you can't read that message.\n\006\007\006\007");
  962.          else {
  963.             DisplayCurrent ();
  964.             Last = Msg->Current;
  965.          }
  966.       }
  967.       else
  968.          Embedded->Printf ("\026\001\015Sorry, you can't read that message.\n\006\007\006\007");
  969.  
  970.       if (Last != Msg->Current)
  971.          Msg->Read (Last);
  972.  
  973.       if (User != NULL && Msg->Current != 0L) {
  974.          if (User->MsgTag->Read (Current->Key) == TRUE) {
  975.             User->MsgTag->LastRead = Msg->Current;
  976.             User->MsgTag->Update ();
  977.          }
  978.          else {
  979.             User->MsgTag->New ();
  980.             strcpy (User->MsgTag->Area, Current->Key);
  981.             User->MsgTag->Tagged = FALSE;
  982.             User->MsgTag->LastRead = Msg->Current;
  983.             User->MsgTag->Add ();
  984.          }
  985.       }
  986.    }
  987. }
  988.  
  989. VOID TMessage::ReadReply (VOID)
  990. {
  991.    if (Msg != NULL) {
  992.       if (Msg->Current == 0L || Msg->Reply == 0L)
  993.          Embedded->Printf ("\n\026\001\017That message isn't available.\n");
  994.       else
  995.          Read (Msg->Reply);
  996.    }
  997. }
  998.  
  999. VOID TMessage::ReadOriginal (VOID)
  1000. {
  1001.    if (Msg != NULL) {
  1002.       if (Msg->Current == 0L || Msg->Original == 0L)
  1003.          Embedded->Printf ("\n\026\001\017That message isn't available.\n");
  1004.       else
  1005.          Read (Msg->Original);
  1006.    }
  1007. }
  1008.  
  1009. VOID TMessage::ReadMessages (VOID)
  1010. {
  1011.    USHORT Forward;
  1012.    CHAR Cmd, NewMessages, End, DoRead, Temp[40];
  1013.    ULONG First, Last, Number, LastReaded;
  1014.    class TMailEditor *MailEditor;
  1015.  
  1016.    if (Msg != NULL) {
  1017.       First = Msg->Lowest ();
  1018.       Last = Msg->Highest ();
  1019.  
  1020.       Number = 0L;
  1021.       Cmd = '\0';
  1022.  
  1023.       NewMessages = TRUE;
  1024.       if (User != NULL) {
  1025.          if (User->MsgTag->Read (Current->Key) == TRUE) {
  1026.             Number = User->MsgTag->LastRead;
  1027.             if (Number >= Last)
  1028.                NewMessages = FALSE;
  1029.          }
  1030.       }
  1031.  
  1032.       if (Msg->Number () != 0L) {
  1033.          StartMessageQuestion (First, Last, NewMessages, Number, Forward);
  1034.          LastReaded = Number;
  1035.  
  1036.          if (Embedded->AbortSession () == FALSE) {
  1037.             DoRead = FALSE;
  1038.             do {
  1039.                End = TRUE;
  1040.                if (Forward == TRUE) {
  1041.                   if (Msg->Next (Number) == TRUE) {
  1042.                      End = FALSE;
  1043.                      Msg->ReadHeader (Number);
  1044.                      if (Msg->Private == TRUE && stricmp (User->Name, Msg->To) && stricmp (User->RealName, Msg->To) && stricmp (User->Name, Msg->From) && stricmp (User->RealName, Msg->From))
  1045.                         continue;
  1046.                      DoRead = TRUE;
  1047.                   }
  1048.                }
  1049.                else {
  1050.                   if (Msg->Previous (Number) == TRUE) {
  1051.                      End = FALSE;
  1052.                      Msg->ReadHeader (Number);
  1053.                      if (Msg->Private == TRUE && stricmp (User->Name, Msg->To) && stricmp (User->RealName, Msg->To) && stricmp (User->Name, Msg->From) && stricmp (User->RealName, Msg->From))
  1054.                         continue;
  1055.                      DoRead = TRUE;
  1056.                   }
  1057.                }
  1058.             } while (End == FALSE && DoRead == FALSE);
  1059.  
  1060.             if (End == TRUE) {
  1061.                Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  1062.                Cmd = Language->Text(LNG_EXITREADMESSAGE)[0];
  1063.             }
  1064.          }
  1065.  
  1066.          while (Embedded->AbortSession () == FALSE && Cmd != Language->Text(LNG_EXITREADMESSAGE)[0]) {
  1067.             if (End == FALSE && DoRead == TRUE) {
  1068.                LastReaded = Number;
  1069.                if (Msg->Read (Number) == TRUE)
  1070.                   DisplayCurrent ();
  1071.                DoRead = FALSE;
  1072.             }
  1073.  
  1074.             if (End == FALSE)
  1075.                Embedded->Printf (Language->Text(LNG_READMENU));
  1076.             else
  1077.                Embedded->Printf (Language->Text(LNG_ENDREADMENU));
  1078.             Embedded->GetString (Temp, 10, INP_HOTKEY|INP_NUMERIC);
  1079.             if ((Cmd = (CHAR)toupper (Temp[0])) == '\0')
  1080.                Cmd = Language->Text(LNG_NEXTMESSAGE)[0];
  1081.  
  1082.             if (isdigit (Cmd)) {
  1083.                if (Msg->ReadHeader (atol (Temp)) == TRUE) {
  1084.                   Number = atol (Temp);
  1085.                   DoRead = TRUE;
  1086.                   End = FALSE;
  1087.                }
  1088.             }
  1089.             else if (Cmd == Language->Text(LNG_NEXTMESSAGE)[0]) {
  1090.                do {
  1091.                   End = TRUE;
  1092.                   if (Forward == TRUE) {
  1093.                      if (Msg->Next (Number) == TRUE) {
  1094.                         End = FALSE;
  1095.                         Msg->ReadHeader (Number);
  1096.                         if (Msg->Private == TRUE && stricmp (User->Name, Msg->To) && stricmp (User->RealName, Msg->To) && stricmp (User->Name, Msg->From) && stricmp (User->RealName, Msg->From))
  1097.                            continue;
  1098.                         DoRead = TRUE;
  1099.                      }
  1100.                   }
  1101.                   else {
  1102.                      if (Msg->Previous (Number) == TRUE) {
  1103.                         End = FALSE;
  1104.                         Msg->ReadHeader (Number);
  1105.                         if (Msg->Private == TRUE && stricmp (User->Name, Msg->To) && stricmp (User->RealName, Msg->To) && stricmp (User->Name, Msg->From) && stricmp (User->RealName, Msg->From))
  1106.                            continue;
  1107.                         DoRead = TRUE;
  1108.                      }
  1109.                   }
  1110.                } while (End == FALSE && DoRead == FALSE);
  1111.  
  1112.                if (End == TRUE) {
  1113.                   Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  1114.                   Number = LastReaded;
  1115.                }
  1116.             }
  1117.             else if (Cmd == Language->Text(LNG_REREADMESSAGE)[0] && End == TRUE) {
  1118.                DoRead = TRUE;
  1119.                End = FALSE;
  1120.             }
  1121.             else if (Cmd == Language->Text(LNG_PREVIOUSMESSAGE)[0]) {
  1122.                do {
  1123.                   End = TRUE;
  1124.                   if (Forward == TRUE) {
  1125.                      if (Msg->Previous (Number) == TRUE) {
  1126.                         End = FALSE;
  1127.                         Msg->ReadHeader (Number);
  1128.                         if (Msg->Private == TRUE && stricmp (User->Name, Msg->To) && stricmp (User->RealName, Msg->To) && stricmp (User->Name, Msg->From) && stricmp (User->RealName, Msg->From))
  1129.                            continue;
  1130.                         DoRead = TRUE;
  1131.                      }
  1132.                   }
  1133.                   else {
  1134.                      if (Msg->Next (Number) == TRUE) {
  1135.                         End = FALSE;
  1136.                         Msg->ReadHeader (Number);
  1137.                         if (Msg->Private == TRUE && stricmp (User->Name, Msg->To) && stricmp (User->RealName, Msg->To) && stricmp (User->Name, Msg->From) && stricmp (User->RealName, Msg->From))
  1138.                            continue;
  1139.                         DoRead = TRUE;
  1140.                      }
  1141.                   }
  1142.                } while (End == FALSE && DoRead == FALSE);
  1143.  
  1144.                if (End == TRUE) {
  1145.                   Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  1146.                   Number = LastReaded;
  1147.                }
  1148.             }
  1149.             else if (Cmd == Language->Text(LNG_REPLYMESSAGE)[0]) {
  1150.                if (User->Level >= Current->WriteLevel) {
  1151.                   if ((User->AccessFlags & Current->WriteFlags) == Current->WriteFlags) {
  1152.                      Reply ();
  1153.                      Msg->Read (Number);
  1154.                      Current->ActiveMsgs = Msg->Number ();
  1155.                      Current->FirstMessage = Msg->Lowest ();
  1156.                      Current->LastMessage = Msg->Highest ();
  1157.                      Current->LastReaded = Msg->UidToMsgn (Number);
  1158.                      Current->Update ();
  1159.                      Last = Msg->Highest ();
  1160.                   }
  1161.                   else
  1162.                      Embedded->Printf ("\026\001\015Sorry, you can't write messages in this Conference.\n\006\007\006\007");
  1163.                }
  1164.                else
  1165.                   Embedded->Printf ("\026\001\015Sorry, you can't write messages in this Conference.\n\006\007\006\007");
  1166.             }
  1167.             else if (Cmd == Language->Text(LNG_EMAILREPLYMESSAGE)[0] && End == FALSE) {
  1168.                if ((MailEditor = new TMailEditor) != NULL) {
  1169.                   MailEditor->Cfg = Cfg;
  1170.                   MailEditor->Embedded = Embedded;
  1171.                   MailEditor->Log = Log;
  1172.                   MailEditor->Msg = Msg;
  1173.                   MailEditor->Language = Language;
  1174.                   MailEditor->Width = User->ScreenWidth;
  1175.                   strcpy (MailEditor->UserName, User->Name);
  1176.                   if (Cfg->MailAddress.First () == TRUE)
  1177.                      strcpy (MailEditor->Address, Cfg->MailAddress.String);
  1178.                   if (MailEditor->Reply () == TRUE)
  1179.                      MailEditor->Menu ();
  1180.                   delete MailEditor;
  1181.                }
  1182.                Last = Msg->Highest ();
  1183.             }
  1184.          }
  1185.       }
  1186.  
  1187.       if (User != NULL) {
  1188.          if (User->MsgTag->Read (Current->Key) == TRUE) {
  1189.             User->MsgTag->LastRead = Number;
  1190.             User->MsgTag->Update ();
  1191.          }
  1192.          else {
  1193.             User->MsgTag->New ();
  1194.             strcpy (User->MsgTag->Area, Current->Key);
  1195.             User->MsgTag->Tagged = FALSE;
  1196.             User->MsgTag->LastRead = Number;
  1197.             User->MsgTag->Add ();
  1198.          }
  1199.       }
  1200.    }
  1201. }
  1202.  
  1203. VOID TMessage::ReadNext (VOID)
  1204. {
  1205.    USHORT DoRead = FALSE;
  1206.    ULONG Number = 0L;
  1207.  
  1208.    if (User != NULL) {
  1209.       if (User->MsgTag->Read (Current->Key) == TRUE)
  1210.          Number = User->MsgTag->LastRead;
  1211.    }
  1212.  
  1213.    if (Msg != NULL) {
  1214.       if (Msg->Next (Number) == TRUE)
  1215.          do {
  1216.             Msg->ReadHeader (Number);
  1217.             if (Msg->Private == FALSE || !stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To) || !stricmp (User->Name, Msg->From) || !stricmp (User->RealName, Msg->From)) {
  1218.                DoRead = TRUE;
  1219.                break;
  1220.             }
  1221.          } while (Msg->Next (Number) == TRUE);
  1222.  
  1223.       if (DoRead == TRUE) {
  1224.          Msg->Read (Number);
  1225.          DisplayCurrent ();
  1226.  
  1227.          if (User != NULL) {
  1228.             if (User->MsgTag->Read (Current->Key) == TRUE) {
  1229.                User->MsgTag->LastRead = Msg->Current;
  1230.                User->MsgTag->Update ();
  1231.             }
  1232.             else {
  1233.                User->MsgTag->New ();
  1234.                strcpy (User->MsgTag->Area, Current->Key);
  1235.                User->MsgTag->Tagged = FALSE;
  1236.                User->MsgTag->LastRead = Msg->Current;
  1237.                User->MsgTag->Add ();
  1238.             }
  1239.          }
  1240.       }
  1241.       else
  1242.          Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  1243.    }
  1244. }
  1245.  
  1246. VOID TMessage::ReadPrevious (VOID)
  1247. {
  1248.    USHORT DoRead = FALSE;
  1249.    ULONG Number = 0L;
  1250.  
  1251.    if (User != NULL) {
  1252.       if (User->MsgTag->Read (Current->Key) == TRUE)
  1253.          Number = User->MsgTag->LastRead;
  1254.    }
  1255.  
  1256.    if (Msg != NULL) {
  1257.       if (Msg->Previous (Number) == TRUE)
  1258.          do {
  1259.             Msg->ReadHeader (Number);
  1260.             if (Msg->Private == FALSE || !stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To) || !stricmp (User->Name, Msg->From) || !stricmp (User->RealName, Msg->From)) {
  1261.                DoRead = TRUE;
  1262.                break;
  1263.             }
  1264.          } while (Msg->Previous (Number) == TRUE);
  1265.  
  1266.       if (DoRead == TRUE) {
  1267.          Msg->Read (Number);
  1268.          DisplayCurrent ();
  1269.  
  1270.          if (User != NULL) {
  1271.             if (User->MsgTag->Read (Current->Key) == TRUE) {
  1272.                User->MsgTag->LastRead = Msg->Current;
  1273.                User->MsgTag->Update ();
  1274.             }
  1275.             else {
  1276.                User->MsgTag->New ();
  1277.                strcpy (User->MsgTag->Area, Current->Key);
  1278.                User->MsgTag->Tagged = FALSE;
  1279.                User->MsgTag->LastRead = Msg->Current;
  1280.                User->MsgTag->Add ();
  1281.             }
  1282.          }
  1283.       }
  1284.       else
  1285.          Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  1286.    }
  1287. }
  1288.  
  1289. VOID TMessage::OpenArea (PSZ area)
  1290. {
  1291.    USHORT DoOpen = TRUE;
  1292.  
  1293.    if (Current->Read (area) == FALSE) {
  1294.       DoOpen = FALSE;
  1295.       if (Current->First () == TRUE)
  1296.          do {
  1297.             if (User->Level >= Current->Level) {
  1298.                if ((Current->AccessFlags & User->AccessFlags) == Current->AccessFlags) {
  1299.                   DoOpen = TRUE;
  1300.                   break;
  1301.                }
  1302.             }
  1303.          } while (Current->Next () == TRUE);
  1304.    }
  1305.  
  1306.    if (DoOpen == TRUE) {
  1307.       if (Msg != NULL) {
  1308.          Msg->Close ();
  1309.          delete Msg;
  1310.       }
  1311.  
  1312.       Msg = NULL;
  1313.       if (Current->Storage == ST_JAM)
  1314.          Msg = new JAM (Current->Path);
  1315.       else if (Current->Storage == ST_SQUISH)
  1316.          Msg = new SQUISH (Current->Path);
  1317.       else if (Current->Storage == ST_USENET)
  1318.          Msg = new USENET (Cfg->NewsServer, Current->NewsGroup);
  1319.       else if (Current->Storage == ST_FIDO)
  1320.          Msg = new FIDOSDM (Current->Path);
  1321.       else if (Current->Storage == ST_ADEPT)
  1322.          Msg = new ADEPT (Current->Path);
  1323.       else if (Current->Storage == ST_HUDSON)
  1324.          Msg = new HUDSON (Current->Path, (UCHAR)Current->Board);
  1325.  
  1326.       if (Log != NULL)
  1327.          Log->Write (":Message Area: %s - %s", Current->Key, Current->Display);
  1328.       if (Msg != NULL) {
  1329.          Current->LastReaded = 0L;
  1330.          if (User->MsgTag->Read (Current->Key) == TRUE)
  1331.             Current->LastReaded = Msg->UidToMsgn (User->MsgTag->LastRead);
  1332.          Current->ActiveMsgs = Msg->Number ();
  1333.          Current->FirstMessage = Msg->Lowest ();
  1334.          Current->LastMessage = Msg->Highest ();
  1335.       }
  1336.       Current->Update ();
  1337.  
  1338.       if (User != NULL) {
  1339.          strcpy (User->LastMsgArea, Current->Key);
  1340.          User->Update ();
  1341.       }
  1342.    }
  1343. }
  1344.  
  1345. USHORT TMessage::SelectArea (PSZ pszArea)
  1346. {
  1347.    USHORT RetVal = FALSE, FirstHit, DoList;
  1348.    SHORT Line;
  1349.    CHAR Command[16], Temp[128];
  1350.    class TMsgData *Data;
  1351.    class TMsgAreaListing *List;
  1352.  
  1353.    DoList = FALSE;
  1354.    if (pszArea != NULL && *pszArea != '\0') {
  1355.       strcpy (Command, pszArea);
  1356.       DoList = TRUE;
  1357.    }
  1358.  
  1359.    if ((Data = new TMsgData (DataPath)) != NULL) {
  1360.       do {
  1361.          if (DoList == FALSE) {
  1362.             Embedded->Printf (Language->Text(LNG_MESSAGEAREAREQUEST));
  1363.             Embedded->Input (Command, (USHORT)(sizeof (Command) - 1), INP_FIELD);
  1364.          }
  1365.          else
  1366.             DoList = FALSE;
  1367.  
  1368.          if (toupper (Command[0]) == Language->Help) {
  1369.             if (User->FullScreen == TRUE && (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE)) {
  1370.                if ((List = new TMsgAreaListing) != NULL) {
  1371.                   List->Cfg = Cfg;
  1372.                   List->Embedded = Embedded;
  1373.                   List->Log = Log;
  1374.                   List->Current = Current;
  1375.                   List->User = User;
  1376.                   List->Language = Language;
  1377.                   if ((RetVal = List->Run ()) == TRUE)
  1378.                      OpenArea (List->Area);
  1379.                   delete List;
  1380.                }
  1381.             }
  1382.             else {
  1383.                if (Data->First () == TRUE) {
  1384.                   Embedded->Printf ("\x0C");
  1385.                   Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1386.                   Line = 3;
  1387.                   do {
  1388.                      if (User->Level >= Data->Level) {
  1389.                         if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  1390.                            Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), Data->Key, Data->ActiveMsgs, Data->Display);
  1391.                            if ((Line = Embedded->MoreQuestion (Line)) == 1) {
  1392.                               Embedded->Printf ("\x0C");
  1393.                               Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1394.                               Line = 3;
  1395.                            }
  1396.                         }
  1397.                      }
  1398.                   } while (Line != 0 && Embedded->AbortSession () == FALSE && Data->Next () == TRUE);
  1399.                }
  1400.             }
  1401.          }
  1402.          else if (!stricmp (Command, "[")) {
  1403.             Data->Read (Current->Key, FALSE);
  1404.             if (Data->Previous () == TRUE)
  1405.                do {
  1406.                   if (User->Level >= Data->Level) {
  1407.                      if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  1408.                         OpenArea (Data->Key);
  1409.                         RetVal = TRUE;
  1410.                         break;
  1411.                      }
  1412.                   }
  1413.                } while (Data->Previous () == TRUE);
  1414.          }
  1415.          else if (!stricmp (Command, "]")) {
  1416.             Data->Read (Current->Key, FALSE);
  1417.             if (Data->Next () == TRUE)
  1418.                do {
  1419.                   if (User->Level >= Data->Level) {
  1420.                      if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  1421.                         OpenArea (Data->Key);
  1422.                         RetVal = TRUE;
  1423.                         break;
  1424.                      }
  1425.                   }
  1426.                } while (Data->Next () == TRUE);
  1427.          }
  1428.          else if (Command[0] != '\0') {
  1429.             if (Data->Read (Command) == TRUE) {
  1430.                if (User->Level >= Data->Level) {
  1431.                   if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  1432.                      OpenArea (Data->Key);
  1433.                      RetVal = TRUE;
  1434.                   }
  1435.                }
  1436.             }
  1437.  
  1438.             if (RetVal == FALSE) {
  1439.                if (User->FullScreen == TRUE && (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE)) {
  1440.                   if ((List = new TMsgAreaListing) != NULL) {
  1441.                      List->Cfg = Cfg;
  1442.                      List->Embedded = Embedded;
  1443.                      List->Log = Log;
  1444.                      List->Current = Current;
  1445.                      List->User = User;
  1446.                      List->Language = Language;
  1447.                      strcpy (List->Command, Command);
  1448.                      if ((RetVal = List->Run ()) == TRUE)
  1449.                         OpenArea (Current->Key);
  1450.                      delete List;
  1451.                   }
  1452.                }
  1453.                else {
  1454.                   FirstHit = TRUE;
  1455.                   strupr (Command);
  1456.                   Line = 3;
  1457.  
  1458.                   if (Data->First () == TRUE) {
  1459.                      do {
  1460.                         if (User->Level >= Data->Level) {
  1461.                            if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  1462.                               strcpy (Temp, Data->Key);
  1463.                               if (strstr (strupr (Temp), Command) != NULL) {
  1464.                                  if (FirstHit == TRUE)
  1465.                                     Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1466.                                  Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), Data->Key, Data->ActiveMsgs, Data->Display);
  1467.                                  Line = Embedded->MoreQuestion (Line);
  1468.                                  FirstHit = FALSE;
  1469.                               }
  1470.                               else {
  1471.                                  strcpy (Temp, Data->Display);
  1472.                                  if (strstr (strupr (Temp), Command) != NULL) {
  1473.                                     if (FirstHit == TRUE)
  1474.                                        Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1475.                                     Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), Data->Key, Data->ActiveMsgs, Data->Display);
  1476.                                     Line = Embedded->MoreQuestion (Line);
  1477.                                     FirstHit = FALSE;
  1478.                                  }
  1479.                                  else {
  1480.                                     strcpy (Temp, Data->EchoTag);
  1481.                                     if (strstr (strupr (Temp), Command) != NULL) {
  1482.                                        if (FirstHit == TRUE)
  1483.                                           Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1484.                                        Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), Data->Key, Data->ActiveMsgs, Data->Display);
  1485.                                        Line = Embedded->MoreQuestion (Line);
  1486.                                        FirstHit = FALSE;
  1487.                                     }
  1488.                                     else {
  1489.                                        strcpy (Temp, Data->NewsGroup);
  1490.                                        if (strstr (strupr (Temp), Command) != NULL) {
  1491.                                           if (FirstHit == TRUE)
  1492.                                              Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1493.                                           Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), Data->Key, Data->ActiveMsgs, Data->Display);
  1494.                                           Line = Embedded->MoreQuestion (Line);
  1495.                                           FirstHit = FALSE;
  1496.                                        }
  1497.                                     }
  1498.                                  }
  1499.                               }
  1500.                            }
  1501.                         }
  1502.                      } while (Line != 0 && Embedded->AbortSession () == FALSE && Data->Next () == TRUE);
  1503.                   }
  1504.  
  1505.                   if (FirstHit == TRUE)
  1506.                      Embedded->Printf (Language->Text(LNG_CONFERENCENOTAVAILABLE));
  1507.                }
  1508.                if (pszArea != NULL && *pszArea != '\0')
  1509.                   Command[0] = '\0';
  1510.             }
  1511.          }
  1512.       } while (Command[0] != '\0' && RetVal == FALSE && Embedded->AbortSession () == FALSE);
  1513.  
  1514.       if (Data != NULL)
  1515.          delete Data;
  1516.    }
  1517.  
  1518.    return (RetVal);
  1519. }
  1520.  
  1521. USHORT TMessage::SelectNewArea (PSZ pszArea)
  1522. {
  1523.    USHORT RetVal = FALSE, FirstHit, DoList;
  1524.    SHORT Line;
  1525.    CHAR Command[16], Temp[128];
  1526.    class TMsgData *Data;
  1527.    class TMsgNewAreaListing *List;
  1528.  
  1529.    DoList = FALSE;
  1530.    if (pszArea != NULL && *pszArea != '\0') {
  1531.       strcpy (Command, pszArea);
  1532.       DoList = TRUE;
  1533.    }
  1534.  
  1535.    if ((Data = new TMsgData (DataPath)) != NULL) {
  1536.       do {
  1537.          if (DoList == FALSE) {
  1538.             Embedded->Printf (Language->Text(LNG_MESSAGEAREAREQUEST));
  1539.             Embedded->Input (Command, (USHORT)(sizeof (Command) - 1), INP_FIELD);
  1540.          }
  1541.          else
  1542.             DoList = FALSE;
  1543.  
  1544.          if (toupper (Command[0]) == Language->Help) {
  1545.             if (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE) {
  1546.                if ((List = new TMsgNewAreaListing) != NULL) {
  1547.                   List->Cfg = Cfg;
  1548.                   List->Embedded = Embedded;
  1549.                   List->Log = Log;
  1550.                   List->Current = Current;
  1551.                   List->User = User;
  1552.                   List->Language = Language;
  1553.                   if ((RetVal = List->Run ()) == TRUE) {
  1554.                      if (Msg != NULL) {
  1555.                         Msg->Close ();
  1556.                         delete Msg;
  1557.                      }
  1558.  
  1559.                      Msg = NULL;
  1560.                      if (Current->Storage == ST_JAM)
  1561.                         Msg = new JAM (Current->Path);
  1562.                      else if (Current->Storage == ST_SQUISH)
  1563.                         Msg = new SQUISH (Current->Path);
  1564.                      else if (Current->Storage == ST_USENET)
  1565.                         Msg = new USENET (Cfg->NewsServer, Current->NewsGroup);
  1566.                      else if (Current->Storage == ST_FIDO)
  1567.                         Msg = new FIDOSDM (Current->Path);
  1568.                      else if (Current->Storage == ST_ADEPT)
  1569.                         Msg = new ADEPT (Current->Path);
  1570.                      else if (Current->Storage == ST_HUDSON)
  1571.                         Msg = new HUDSON (Current->Path, (UCHAR)Current->Board);
  1572.  
  1573.                      if (Msg != NULL) {
  1574.                         Current->ActiveMsgs = Msg->Number ();
  1575.                         Current->FirstMessage = Msg->Lowest ();
  1576.                         Current->LastMessage = Msg->Highest ();
  1577.                      }
  1578.                      Current->Update ();
  1579.                   }
  1580.                   delete List;
  1581.                }
  1582.             }
  1583.             else {
  1584.                if (Data->First () == TRUE) {
  1585.                   Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1586.                   Line = 3;
  1587.                   do {
  1588.                      if (User->Level >= Data->Level) {
  1589.                         if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  1590.                            if (User->MsgTag->Read (Data->Key) == TRUE) {
  1591.                               if (User->MsgTag->LastRead < Data->LastMessage) {
  1592.                                  Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), Data->Key, Data->ActiveMsgs, Data->Display);
  1593.                                  Line = Embedded->MoreQuestion (Line);
  1594.                               }
  1595.                            }
  1596.                         }
  1597.                      }
  1598.                   } while (Line != 0 && Embedded->AbortSession () == FALSE && Data->Next () == TRUE);
  1599.                }
  1600.             }
  1601.          }
  1602.          else if (Command[0] != '\0') {
  1603.             if (Data->Read (Command) == TRUE) {
  1604.                if (User->Level >= Data->Level) {
  1605.                   if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  1606.                      delete Data;
  1607.                      Data = NULL;
  1608.                      if (Msg != NULL) {
  1609.                         Msg->Close ();
  1610.                         delete Msg;
  1611.                      }
  1612.  
  1613.                      Current->Read (Command);
  1614.                      if (User != NULL) {
  1615.                         strcpy (User->LastMsgArea, Current->Key);
  1616.                         User->Update ();
  1617.                      }
  1618.  
  1619.                      Msg = NULL;
  1620.                      if (Current->Storage == ST_JAM)
  1621.                         Msg = new JAM (Current->Path);
  1622.                      else if (Current->Storage == ST_SQUISH)
  1623.                         Msg = new SQUISH (Current->Path);
  1624.                      else if (Current->Storage == ST_USENET)
  1625.                         Msg = new USENET (Cfg->NewsServer, Current->NewsGroup);
  1626.                      else if (Current->Storage == ST_FIDO)
  1627.                         Msg = new FIDOSDM (Current->Path);
  1628.                      else if (Current->Storage == ST_ADEPT)
  1629.                         Msg = new ADEPT (Current->Path);
  1630.                      else if (Current->Storage == ST_HUDSON)
  1631.                         Msg = new HUDSON (Current->Path, (UCHAR)Current->Board);
  1632.  
  1633.                      Log->Write (":Message Area: %s - %s", Current->Key, Current->Display);
  1634.                      if (Msg != NULL) {
  1635.                         Current->ActiveMsgs = Msg->Number ();
  1636.                         Current->FirstMessage = Msg->Lowest ();
  1637.                         Current->LastMessage = Msg->Highest ();
  1638.                      }
  1639.                      Current->Update ();
  1640.                      RetVal = TRUE;
  1641.                   }
  1642.                }
  1643.             }
  1644.  
  1645.             if (RetVal == FALSE) {
  1646.                FirstHit = TRUE;
  1647.                strupr (Command);
  1648.                Line = 3;
  1649.  
  1650.                if (Data->First () == TRUE) {
  1651.                   do {
  1652.                      if (User->Level >= Data->Level) {
  1653.                         if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  1654.                            if (User->MsgTag->Read (Data->Key) == TRUE) {
  1655.                               if (User->MsgTag->LastRead < Data->LastMessage) {
  1656.                                  strcpy (Temp, Data->Key);
  1657.                                  if (strstr (strupr (Temp), Command) != NULL) {
  1658.                                     if (FirstHit == TRUE)
  1659.                                        Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1660.                                     Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), Data->Key, Data->ActiveMsgs, Data->Display);
  1661.                                     Line = Embedded->MoreQuestion (Line);
  1662.                                     FirstHit = FALSE;
  1663.                                  }
  1664.                                  else {
  1665.                                     strcpy (Temp, Data->Display);
  1666.                                     if (strstr (strupr (Temp), Command) != NULL) {
  1667.                                        if (FirstHit == TRUE)
  1668.                                           Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1669.                                        Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), Data->Key, Data->ActiveMsgs, Data->Display);
  1670.                                        Line = Embedded->MoreQuestion (Line);
  1671.                                        FirstHit = FALSE;
  1672.                                     }
  1673.                                     else {
  1674.                                        strcpy (Temp, Data->EchoTag);
  1675.                                        if (strstr (strupr (Temp), Command) != NULL) {
  1676.                                           if (FirstHit == TRUE)
  1677.                                              Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1678.                                           Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), Data->Key, Data->ActiveMsgs, Data->Display);
  1679.                                           Line = Embedded->MoreQuestion (Line);
  1680.                                           FirstHit = FALSE;
  1681.                                        }
  1682.                                        else {
  1683.                                           strcpy (Temp, Data->NewsGroup);
  1684.                                           if (strstr (strupr (Temp), Command) != NULL) {
  1685.                                              if (FirstHit == TRUE)
  1686.                                                 Embedded->Printf (Language->Text(LNG_MESSAGEAREAHEADER));
  1687.                                              Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), Data->Key, Data->ActiveMsgs, Data->Display);
  1688.                                              Line = Embedded->MoreQuestion (Line);
  1689.                                              FirstHit = FALSE;
  1690.                                           }
  1691.                                        }
  1692.                                     }
  1693.                                  }
  1694.                               }
  1695.                            }
  1696.                         }
  1697.                      }
  1698.                   } while (Line != 0 && Embedded->AbortSession () == FALSE && Data->Next () == TRUE);
  1699.                }
  1700.  
  1701.                if (FirstHit == TRUE)
  1702.                   Embedded->Printf (Language->Text(LNG_CONFERENCENOTAVAILABLE));
  1703.             }
  1704.          }
  1705.       } while (Command[0] != '\0' && RetVal == FALSE && Embedded->AbortSession () == FALSE);
  1706.  
  1707.       if (Data != NULL)
  1708.          delete Data;
  1709.    }
  1710.  
  1711.    return (RetVal);
  1712. }
  1713.  
  1714. VOID TMessage::StartMessageQuestion (ULONG ulFirst, ULONG ulLast, USHORT fNewMessages, ULONG &ulMsg, USHORT &fForward)
  1715. {
  1716.    CHAR Cmd, Temp[20];
  1717.  
  1718.    do {
  1719.       Embedded->Printf (Language->Text(LNG_STARTWITHMESSAGE));
  1720.       if (fNewMessages == TRUE)
  1721.          Embedded->Printf (Language->Text(LNG_NEWMESSAGES));
  1722.       Embedded->Printf (": ");
  1723.       Embedded->Input (Temp, (USHORT)(sizeof (Temp) - 1), INP_HOTKEY|INP_NUMERIC);
  1724.       Cmd = (CHAR)toupper (Temp[0]);
  1725.       if (Cmd == Language->Help)
  1726.          Embedded->DisplayFile ("MAILSTRT");
  1727.    } while (Embedded->AbortSession () == FALSE && Cmd != 'F' && Cmd != 'L' && Cmd != '\0' && !isdigit (Cmd));
  1728.  
  1729.    fForward = TRUE;
  1730.    if (Cmd == 'F') {
  1731.       if ((ulMsg = ulFirst) > 0L)
  1732.          ulMsg--;
  1733.    }
  1734.    else if (Cmd == 'L') {
  1735.       ulMsg = ulLast + 1L;
  1736.       fForward = FALSE;
  1737.    }
  1738.    else if (isdigit (Cmd)) {
  1739.       if ((ulMsg = atol (Temp)) > 0L)
  1740.          ulMsg--;
  1741.    }
  1742. }
  1743.  
  1744. VOID TMessage::ReadNonStop (VOID)
  1745. {
  1746.    USHORT Forward, Continue;
  1747.    ULONG Number;
  1748.  
  1749.    if (Msg != NULL) {
  1750.       Number = 0L;
  1751.       if (User != NULL) {
  1752.          if (User->MsgTag->Read (Current->Key) == TRUE)
  1753.             Number = User->MsgTag->LastRead;
  1754.       }
  1755.  
  1756.       Forward = TRUE;
  1757.       Embedded->BufferedPrintf ("\x0C");
  1758.  
  1759.       if (Msg->Number () > 0L && Number < Msg->Highest ()) {
  1760.          if (Forward == TRUE)
  1761.             Continue = Msg->Next (Number);
  1762.          else
  1763.             Continue = Msg->Previous (Number);
  1764.  
  1765.          while (Embedded->AbortSession () == FALSE && Continue == TRUE) {
  1766.             if (Msg->Read (Number) == TRUE) {
  1767.                if (Msg->Private == FALSE || !stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To) || !stricmp (User->Name, Msg->From) || !stricmp (User->RealName, Msg->From)) {
  1768.                   DisplayText ();
  1769.                   if (User != NULL) {
  1770.                      if (User->MsgTag->Read (Current->Key) == TRUE) {
  1771.                         User->MsgTag->LastRead = Msg->Current;
  1772.                         User->MsgTag->Update ();
  1773.                      }
  1774.                      else {
  1775.                         User->MsgTag->New ();
  1776.                         strcpy (User->MsgTag->Area, Current->Key);
  1777.                         User->MsgTag->Tagged = FALSE;
  1778.                         User->MsgTag->LastRead = Msg->Current;
  1779.                         User->MsgTag->Add ();
  1780.                      }
  1781.                   }
  1782.                }
  1783.             }
  1784.             if (Forward == TRUE)
  1785.                Continue = Msg->Next (Number);
  1786.             else
  1787.                Continue = Msg->Previous (Number);
  1788.          }
  1789.       }
  1790.    }
  1791. }
  1792.  
  1793. VOID TMessage::TitleList (VOID)
  1794. {
  1795.    USHORT NewMessages, Forward, Continue;
  1796.    SHORT Line;
  1797.    CHAR Temp[64];
  1798.    ULONG Number, First, Last;
  1799.  
  1800.    if (Msg != NULL) {
  1801.       First = Msg->Lowest ();
  1802.       Last = Msg->Highest ();
  1803.  
  1804.       Number = 0L;
  1805.       NewMessages = TRUE;
  1806.       if (User != NULL) {
  1807.          if (User->MsgTag->Read (Current->Key) == TRUE) {
  1808.             Number = User->MsgTag->LastRead;
  1809.             if (Number >= Last)
  1810.                NewMessages = FALSE;
  1811.          }
  1812.       }
  1813.  
  1814.       if (Msg->Number () > 0L) {
  1815.          StartMessageQuestion (First, Last, NewMessages, Number, Forward);
  1816.  
  1817.          Line = 3;
  1818.          Embedded->Printf ("\026\001\012FORUM: %s\n", Current->Key);
  1819.          if (Current->Moderator[0] != '\0') {
  1820.             Embedded->Printf ("\026\001\012Forum-Op: %s\n", Current->Moderator);
  1821.             Line++;
  1822.          }
  1823.          Embedded->Printf ("\026\001\012Forum Topic: %s\n\n", Current->Display);
  1824.  
  1825.          if (Forward == TRUE)
  1826.             Continue = Msg->Next (Number);
  1827.          else
  1828.             Continue = Msg->Previous (Number);
  1829.  
  1830.          while (Embedded->AbortSession () == FALSE && Line != 0 && Continue == TRUE) {
  1831.             if (Msg->ReadHeader (Number) == TRUE) {
  1832.                sprintf (Temp, "%d %s %d %2d:%02d", Msg->Written.Day, Language->Months[Msg->Written.Month - 1], Msg->Written.Year, Msg->Written.Hour, Msg->Written.Minute);
  1833.                Embedded->Printf ("\026\001\012   Date: %-30.30s %30s\n", Temp, Current->Display);
  1834.  
  1835.                if ((Line = Embedded->MoreQuestion (Line)) != 0) {
  1836.                   sprintf (Temp, "Msg#: %lu", Msg->Current);
  1837.                   Embedded->Printf ("   From: %-40.40s %20s\n", Msg->From, Temp);
  1838.  
  1839.                   if ((Line = Embedded->MoreQuestion (Line)) != 0) {
  1840.                      Embedded->Printf ("     To: %.70s\n", Msg->To);
  1841.                      if ((Line = Embedded->MoreQuestion (Line)) != 0) {
  1842.                         Embedded->Printf ("Subject: %.70s\n", Msg->Subject);
  1843.                         Line = Embedded->MoreQuestion (Line);
  1844.                      }
  1845.                   }
  1846.                }
  1847.                Embedded->Printf ("\n");
  1848.                Line = Embedded->MoreQuestion (Line);
  1849.             }
  1850.  
  1851.             if (Forward == TRUE)
  1852.                Continue = Msg->Next (Number);
  1853.             else
  1854.                Continue = Msg->Previous (Number);
  1855.          }
  1856.  
  1857.          Embedded->Printf ("\n\026\001\016End of list!\n");
  1858.          if (Line > 1)
  1859.             Embedded->PressEnter ();
  1860.       }
  1861.    }
  1862. }
  1863.  
  1864. VOID TMessage::Unreceive (VOID)
  1865. {
  1866.    if (Msg != NULL) {
  1867.       if (Msg->Current == 0L)
  1868.          Msg->Read (Msg->MsgnToUid (Current->LastReaded));
  1869.       if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  1870.          Msg->Received = FALSE;
  1871.          Msg->WriteHeader (Msg->Current);
  1872.       }
  1873.    }
  1874. }
  1875.  
  1876. // ----------------------------------------------------------------------
  1877.  
  1878. TMsgAreaListing::TMsgAreaListing (void)
  1879. {
  1880.    Command[0] = '\0';
  1881. }
  1882.  
  1883. VOID TMsgAreaListing::Begin (VOID)
  1884. {
  1885.    USHORT i, Add;
  1886.    CHAR Temp[128];
  1887.    LISTDATA ld;
  1888.    class TMsgData *MsgData;
  1889.  
  1890.    i = 0;
  1891.    y = 4;
  1892.    Found = FALSE;
  1893.    List.Clear ();
  1894.    Data.Clear ();
  1895.    strupr (Command);
  1896.  
  1897.    if ((MsgData = new TMsgData (Cfg->SystemPath)) != NULL) {
  1898.       if (MsgData->First () == TRUE)
  1899.          do {
  1900.             if (User->Level >= MsgData->Level) {
  1901.                if ((MsgData->AccessFlags & User->AccessFlags) == MsgData->AccessFlags) {
  1902.                   if (Command[0] != '\0') {
  1903.                      Add = FALSE;
  1904.                      strcpy (Temp, MsgData->Key);
  1905.                      if (strstr (strupr (Temp), Command) != NULL)
  1906.                         Add = TRUE;
  1907.                      else {
  1908.                         strcpy (Temp, MsgData->Display);
  1909.                         if (strstr (strupr (Temp), Command) != NULL)
  1910.                            Add = TRUE;
  1911.                         else {
  1912.                            strcpy (Temp, MsgData->EchoTag);
  1913.                            if (strstr (strupr (Temp), Command) != NULL)
  1914.                               Add = TRUE;
  1915.                            else {
  1916.                               strcpy (Temp, MsgData->NewsGroup);
  1917.                               if (strstr (strupr (Temp), Command) != NULL)
  1918.                                  Add = TRUE;
  1919.                            }
  1920.                         }
  1921.                      }
  1922.                   }
  1923.  
  1924.                   if (Command[0] == '\0' || Add == TRUE) {
  1925.                      strcpy (ld.Key, MsgData->Key);
  1926.                      ld.ActiveMsgs = MsgData->ActiveMsgs;
  1927.                      strcpy (ld.Display, MsgData->Display);
  1928.                      Data.Add (&ld, sizeof (LISTDATA));
  1929.                   }
  1930.                }
  1931.             }
  1932.          } while (MsgData->Next () == TRUE);
  1933.  
  1934.       delete MsgData;
  1935.    }
  1936.  
  1937.    if ((pld = (LISTDATA *)Data.First ()) != NULL) {
  1938.       do {
  1939.          if (!strcmp (pld->Key, Current->Key))
  1940.             Found = TRUE;
  1941.          List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  1942.          i++;
  1943.          if (i >= (User->ScreenHeight - 6)) {
  1944.             if (Found == TRUE)
  1945.                break;
  1946.             List.Clear ();
  1947.             i = 0;
  1948.          }
  1949.       } while ((pld = (LISTDATA *)Data.Next ()) != NULL);
  1950.    }
  1951.  
  1952.    if (Found == FALSE) {
  1953.       List.Clear ();
  1954.       if ((pld = (LISTDATA *)Data.First ()) != NULL) {
  1955.          do {
  1956.             List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  1957.             i++;
  1958.             if (i >= (User->ScreenHeight - 6))
  1959.                break;
  1960.          } while ((pld = (LISTDATA *)Data.Next ()) != NULL);
  1961.       }
  1962.    }
  1963. }
  1964.  
  1965. USHORT TMsgAreaListing::DrawScreen (VOID)
  1966. {
  1967.    USHORT i;
  1968.  
  1969.    i = 0;
  1970.    do {
  1971.       List.Next ();
  1972.       pld = (LISTDATA *)Data.Value ();
  1973.       if (Found == TRUE && !strcmp (pld->Key, Current->Key)) {
  1974.          y = (USHORT)(i + 4);
  1975.          Found = FALSE;
  1976.       }
  1977.       PrintLine ();
  1978.       i++;
  1979.    } while (Data.Next () != NULL && i < (User->ScreenHeight - 6));
  1980.  
  1981.    return (i);
  1982. }
  1983.  
  1984. VOID TMsgAreaListing::PrintTitles (VOID)
  1985. {
  1986.    Embedded->Printf ("\x0C");
  1987.    Embedded->Printf (Language->Text (LNG_MESSAGEAREAHEADER));
  1988.  
  1989.    Embedded->PrintfAt ((USHORT)(User->ScreenHeight - 2), 1, Language->Text (LNG_MESSAGEAREASEPARATOR));
  1990.  
  1991.    Embedded->Printf (Language->Text (LNG_MESSAGEAREADESCRIPTION1));
  1992.    Embedded->Printf (Language->Text (LNG_MESSAGEAREADESCRIPTION2));
  1993.  
  1994.    Embedded->PrintfAt (4, 1, "");
  1995. }
  1996.  
  1997. VOID TMsgAreaListing::PrintLine (VOID)
  1998. {
  1999.    Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), pld->Key, pld->ActiveMsgs, pld->Display);
  2000. }
  2001.  
  2002. VOID TMsgAreaListing::PrintCursor (USHORT y)
  2003. {
  2004.    Embedded->PrintfAt (y, 1, Language->Text (LNG_MESSAGEAREACURSOR), (PSZ)List.Value ());
  2005. }
  2006.  
  2007. VOID TMsgAreaListing::RemoveCursor (USHORT y)
  2008. {
  2009.    Embedded->PrintfAt (y, 1, Language->Text (LNG_MESSAGEAREAKEY), (PSZ)List.Value ());
  2010. }
  2011.  
  2012. VOID TMsgAreaListing::Select (VOID)
  2013. {
  2014.    strcpy (Area, (PSZ)List.Value ());
  2015.    RetVal = End = TRUE;
  2016. }
  2017.  
  2018. // ----------------------------------------------------------------------
  2019.  
  2020. VOID TMsgNewAreaListing::Begin (VOID)
  2021. {
  2022.    USHORT i;
  2023.    LISTDATA ld;
  2024.    class TMsgData *MsgData;
  2025.  
  2026.    i = 0;
  2027.    y = 4;
  2028.    Found = FALSE;
  2029.    List.Clear ();
  2030.    Data.Clear ();
  2031.  
  2032.    if ((MsgData = new TMsgData (Cfg->SystemPath)) != NULL) {
  2033.       if (MsgData->First () == TRUE)
  2034.          do {
  2035.             if (User->Level >= MsgData->Level) {
  2036.                if ((MsgData->AccessFlags & User->AccessFlags) == MsgData->AccessFlags) {
  2037.                   if (User->MsgTag->Read (MsgData->Key) == TRUE) {
  2038.                      if (User->MsgTag->LastRead < MsgData->LastMessage) {
  2039.                         strcpy (ld.Key, MsgData->Key);
  2040.                         ld.ActiveMsgs = MsgData->ActiveMsgs;
  2041.                         strcpy (ld.Display, MsgData->Display);
  2042.                         Data.Add (&ld, sizeof (LISTDATA));
  2043.                      }
  2044.                   }
  2045.                }
  2046.             }
  2047.          } while (MsgData->Next () == TRUE);
  2048.  
  2049.       delete MsgData;
  2050.    }
  2051.  
  2052.    if ((pld = (LISTDATA *)Data.First ()) != NULL) {
  2053.       do {
  2054.          if (!strcmp (pld->Key, Current->Key))
  2055.             Found = TRUE;
  2056.          List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  2057.          i++;
  2058.          if (i >= (User->ScreenHeight - 6)) {
  2059.             if (Found == TRUE)
  2060.                break;
  2061.             List.Clear ();
  2062.             i = 0;
  2063.          }
  2064.       } while ((pld = (LISTDATA *)Data.Next ()) != NULL);
  2065.    }
  2066. }
  2067.  
  2068. USHORT TMsgNewAreaListing::DrawScreen (VOID)
  2069. {
  2070.    USHORT i;
  2071.  
  2072.    i = 0;
  2073.    do {
  2074.       pld = (LISTDATA *)Data.Value ();
  2075.       if (Found == TRUE && !strcmp (pld->Key, Current->Key)) {
  2076.          y = (USHORT)(i + 4);
  2077.          Found = FALSE;
  2078.       }
  2079.       PrintLine ();
  2080.       i++;
  2081.    } while (Data.Next () != NULL && i < (User->ScreenHeight - 6));
  2082.  
  2083.    return (i);
  2084. }
  2085.  
  2086. VOID TMsgNewAreaListing::PrintTitles (VOID)
  2087. {
  2088.    Embedded->Printf ("\x0C\n");
  2089.    Embedded->Printf ("\026\001\012Conference       Msgs   Description\n\026\001\017\031=\017  \031=\005  \031=\067\n");
  2090.  
  2091.    Embedded->PrintfAt ((USHORT)(User->ScreenHeight - 2), 1, "\026\001\017\031=\017  \031=\005  \031=\067\n");
  2092.  
  2093.    Embedded->Printf ("\026\001\012Hit \026\001\013CTRL-V \026\001\012for next page, \026\001\013CTRL-Y \026\001\012for previous page, \026\001\013? \026\001\012for help, or \026\001\013X \026\001\012to exit.\n");
  2094.    Embedded->Printf ("\026\001\012To highlight an area, use your \026\001\013arrow keys\026\001\012, \026\001\013RETURN \026\001\012selects it.");
  2095.  
  2096.    Embedded->PrintfAt (4, 1, "");
  2097. }
  2098.  
  2099. VOID TMsgNewAreaListing::PrintLine (VOID)
  2100. {
  2101.    Embedded->Printf (Language->Text(LNG_MESSAGEAREALIST), pld->Key, pld->ActiveMsgs, pld->Display);
  2102. }
  2103.  
  2104. VOID TMsgNewAreaListing::PrintCursor (USHORT y)
  2105. {
  2106.    Embedded->PrintfAt (y, 1, "\x16\x01\x70%-15.15s\x16\x01\x0E", (PSZ)List.Value ());
  2107. }
  2108.  
  2109. VOID TMsgNewAreaListing::RemoveCursor (USHORT y)
  2110. {
  2111.    Embedded->PrintfAt (y, 1, "\x16\x01\x0B%-15.15s\x16\x01\x0E", (PSZ)List.Value ());
  2112. }
  2113.  
  2114. VOID TMsgNewAreaListing::Select (VOID)
  2115. {
  2116.    strcpy (Area, (PSZ)List.Value ());
  2117.    RetVal = End = TRUE;
  2118. }
  2119.  
  2120. // ---------------------------------------------------------------------------
  2121.  
  2122. TInquire::TInquire (void)
  2123. {
  2124.    Type = TYPE_ALL;
  2125.    Action = ACTION_UNDEFINED;
  2126.    Range = RANGE_UNDEFINED;
  2127.    User = NULL;
  2128.    Embedded = NULL;
  2129.    Language = NULL;
  2130.    ShowKludges = FALSE;
  2131.    Current = Data = NULL;
  2132.    Log = NULL;
  2133.    Stop = FALSE;
  2134. }
  2135.  
  2136. TInquire::~TInquire (void)
  2137. {
  2138. }
  2139.  
  2140. VOID TInquire::DeleteCurrent (VOID)
  2141. {
  2142.    if (Msg != NULL && Number > 0) {
  2143.       if (Msg->ReadHeader (Number) == TRUE) {
  2144.          if (!stricmp (Msg->From, User->Name) || !stricmp (Msg->To, User->Name)) {
  2145.             if (Msg->Delete (Number) == TRUE)
  2146.                Embedded->Printf ("\n\x16\x01\x0E<<< CONFIRMED: MESSAGE #%ld ERASED >>>\n", Number);
  2147.          }
  2148.          else
  2149.             Embedded->Printf ("\n\x16\x01\x0DSorry, message number %ld is neither FROM you,\nnor a PRIVATE message TO you, so you can't erase it.\n\006\007\006\007", Number);
  2150.       }
  2151.       else
  2152.          Embedded->Printf ("\n\x16\x01\x0DSorry, message number %ld is neither FROM you,\nnor a PRIVATE message TO you, so you can't erase it.\n\006\007\006\007", Number);
  2153.    }
  2154. }
  2155.  
  2156. VOID TInquire::DisplayCurrent (VOID)
  2157. {
  2158.    USHORT InitialLine;
  2159.    USHORT Line, MaxLine, gotFrom = FALSE, gotTo = FALSE;
  2160.    CHAR *Text, Temp[96], *p, Flags[96];
  2161.    ULONG Msgn;
  2162.  
  2163.    if (Msg != NULL) {
  2164.       if (Msg->Current == 0L)
  2165.          Msg->Read (Msg->MsgnToUid (Current->LastReaded));
  2166.       Msgn = Msg->UidToMsgn (Msg->Current);
  2167.       Current->LastReaded = Msgn;
  2168.       if (Log != NULL && Pause == FALSE)
  2169.          Log->Write (":Display Msg. #%lu, area %s (%lu)", Msgn, Current->Key, Msg->Current);
  2170.  
  2171.       if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  2172.          do {
  2173.             if (!strncmp (p, " * Origin: ", 11)) {
  2174.                Msg->ToAddress[0] = '\0';
  2175.  
  2176.                strcpy (Temp, &p[11]);
  2177.                p = strchr (Temp, '\0');
  2178.                while (--p > Temp) {
  2179.                   if (*p != ' ' && *p != ')')
  2180.                      break;
  2181.                   *p = '\0';
  2182.                }
  2183.                if (p > Temp) {
  2184.                   while (--p > Temp) {
  2185.                      if (*p == '(' || *p == ' ')
  2186.                         break;
  2187.                   }
  2188.                }
  2189.                if (*p == '(' || *p == ' ')
  2190.                   *p++;
  2191.                strcpy (Msg->FromAddress, p);
  2192.                break;
  2193.             }
  2194.             else if (!strncmp (p, "\001From: ", 7)) {
  2195.                Msg->FromAddress[0] = '\0';
  2196.                if (gotTo == FALSE)
  2197.                   Msg->ToAddress[0] = '\0';
  2198.                ParseAddress (&p[7], Msg->From, Msg->FromAddress);
  2199.                gotFrom = TRUE;
  2200.             }
  2201.             else if (!strncmp (p, "\001To: ", 5)) {
  2202.                if (gotFrom == FALSE)
  2203.                   Msg->FromAddress[0] = '\0';
  2204.                Msg->ToAddress[0] = '\0';
  2205.                ParseAddress (&p[5], Msg->To, Msg->ToAddress);
  2206.                gotTo = TRUE;
  2207.             }
  2208.             if (gotFrom == TRUE && gotTo == TRUE)
  2209.                break;
  2210.          } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  2211.  
  2212.       Flags[0] = '\0';
  2213.       if (Msg->Received == TRUE)
  2214.          strcat (Flags, Language->Text (LNG_MSGFLAG_RCV));
  2215.       if (Msg->Sent == TRUE)
  2216.          strcat (Flags, Language->Text (LNG_MSGFLAG_SNT));
  2217.       if (Msg->Private == TRUE)
  2218.          strcat (Flags, Language->Text (LNG_MSGFLAG_PVT));
  2219.       if (Msg->Crash == TRUE)
  2220.          strcat (Flags, Language->Text (LNG_MSGFLAG_CRA));
  2221.       if (Msg->KillSent == TRUE)
  2222.          strcat (Flags, Language->Text (LNG_MSGFLAG_KS));
  2223.       if (Msg->Local == TRUE)
  2224.          strcat (Flags, Language->Text (LNG_MSGFLAG_LOC));
  2225.       if (Msg->Hold == TRUE)
  2226.          strcat (Flags, Language->Text (LNG_MSGFLAG_HLD));
  2227.       if (Msg->FileAttach == TRUE)
  2228.          strcat (Flags, Language->Text (LNG_MSGFLAG_ATT));
  2229.       if (Msg->FileRequest == TRUE)
  2230.          strcat (Flags, Language->Text (LNG_MSGFLAG_FRQ));
  2231.       if (Msg->Intransit == TRUE)
  2232.          strcat (Flags, Language->Text (LNG_MSGFLAG_TRS));
  2233.  
  2234.       if (User->FullReader == TRUE && (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE)) {
  2235.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEHDR), Current->Display, (CHAR)(80 - strlen (Current->Display) - 3));
  2236.          if (Msg->Original != 0L && Msg->Reply == 0L)
  2237.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER1), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Original));
  2238.          else if (Msg->Original == 0L && Msg->Reply != 0L)
  2239.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER2), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Reply));
  2240.          else if (Msg->Original != 0L && Msg->Reply != 0L)
  2241.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER3), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Original), Msg->UidToMsgn (Msg->Reply));
  2242.          else
  2243.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER), Msgn, Msg->Number ());
  2244.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFLAGS), Temp, Flags);
  2245.  
  2246.          BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Written);
  2247.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFROM), Msg->From, Msg->FromAddress, Temp);
  2248.          BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Arrived);
  2249.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGETO), Msg->To, Msg->ToAddress, Temp);
  2250.          if (Msg->FileAttach == TRUE || Msg->FileRequest == TRUE)
  2251.             Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFILE), Msg->Subject);
  2252.          else
  2253.             Embedded->BufferedPrintf (Language->Text (LNG_MESSAGESUBJECT), Msg->Subject);
  2254.          Embedded->BufferedPrintf ("\x16\x01\x13\031─\120");
  2255.  
  2256.          InitialLine = Line = 6;
  2257.       }
  2258.       else {
  2259.          Embedded->BufferedPrintf ("\x0C");
  2260.          Embedded->BufferedPrintf (Language->Text (LNG_READERFROM), Msg->From, Flags);
  2261.  
  2262.          BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Written);
  2263.          Embedded->BufferedPrintf (Language->Text (LNG_READERTO), Msg->To, Msgn, Temp);
  2264.  
  2265.          if (Msg->FileAttach == TRUE || Msg->FileRequest == TRUE)
  2266.             Embedded->BufferedPrintf (Language->Text (LNG_READERFILE), Msg->Subject);
  2267.          else
  2268.             Embedded->BufferedPrintf (Language->Text (LNG_READERSUBJECT), Msg->Subject);
  2269.  
  2270.          InitialLine = Line = 4;
  2271.       }
  2272.  
  2273.       if ((Text = (CHAR *)Msg->Text.First ()) != NULL)
  2274.          do {
  2275.             if (ShowKludges == TRUE || (strncmp (Text, "SEEN-BY: ", 9) && Text[0] != 1)) {
  2276.                if (!strncmp (Text, "SEEN-BY: ", 9) || Text[0] == 1) {
  2277.                   if (Text[0] == 1)
  2278.                      Text++;
  2279.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEKLUDGE), Text);
  2280.                }
  2281.                else if (!strncmp (Text, " * Origin", 9) || !strncmp (Text, "---", 3))
  2282.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEORIGIN), Text);
  2283.                else if (strchr (Text, '>') != NULL)
  2284.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEQUOTE), Text);
  2285.                else
  2286.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGETEXT), Text);
  2287.  
  2288.                MaxLine = Line;
  2289.                if ((Line = Embedded->MoreQuestion (Line)) == 1) {
  2290.                   MaxLine++;
  2291.                   while (MaxLine > InitialLine)
  2292.                      Embedded->BufferedPrintfAt (MaxLine--, 1, "\026\007");
  2293.                   Line = InitialLine;
  2294.                }
  2295.             }
  2296.          } while ((Text = (CHAR *)Msg->Text.Next ()) != NULL && Embedded->AbortSession () == FALSE && Line != 0);
  2297.  
  2298.       if (User->FullReader == FALSE || (Embedded->Ansi == FALSE && Embedded->Avatar == FALSE)) {
  2299.          if (Msg->Original != 0L && Msg->Reply == 0L)
  2300.             Embedded->BufferedPrintf ("\n\026\001\017*** This is a reply to #%lu.\n", Msg->UidToMsgn (Msg->Original));
  2301.          else if (Msg->Original == 0L && Msg->Reply != 0L)
  2302.             Embedded->BufferedPrintf ("\n\026\001\017*** See also #%lu.\n", Msg->UidToMsgn (Msg->Reply));
  2303.          else if (Msg->Original != 0L && Msg->Reply != 0L)
  2304.             Embedded->BufferedPrintf ("\n\026\001\017*** This is a reply to #%lu.  *** See also #%lu.\n", Msg->UidToMsgn (Msg->Original), Msg->UidToMsgn (Msg->Reply));
  2305.          Line += 2;
  2306.       }
  2307.  
  2308.       Embedded->UnbufferBytes ();
  2309.  
  2310.       if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  2311.          Msg->Received = TRUE;
  2312.          Msg->WriteHeader (Msg->Current);
  2313.       }
  2314.  
  2315.       if (Line > InitialLine) {
  2316.          MaxLine = Line;
  2317.          Embedded->MoreQuestion (99);
  2318.          MaxLine++;
  2319.          while (MaxLine > InitialLine)
  2320.             Embedded->BufferedPrintfAt (MaxLine--, 1, "\026\007");
  2321.       }
  2322.    }
  2323. }
  2324.  
  2325. USHORT TInquire::FirstMessage (VOID)
  2326. {
  2327.    USHORT RetVal = FALSE, Total = 0;
  2328.    CHAR Temp[128], *p;
  2329.  
  2330.    if (Msg != NULL) {
  2331.       Msg->Lock (0L);
  2332.       do {
  2333.          if ((++Total % 16) == 0) {
  2334.             if (Embedded->KBHit () == TRUE) {
  2335.                switch (Embedded->Getch ()) {
  2336.                   case 0x03:
  2337.                   case 'c':
  2338.                   case 'C':
  2339.                   case 's':
  2340.                   case 'S':
  2341.                      Stop = TRUE;
  2342.                      break;
  2343.                }
  2344.             }
  2345.          }
  2346.          if (Type == TYPE_KEYWORD) {
  2347.             if (Msg->Read (Number) == TRUE) {
  2348.                strcpy (Temp, Msg->From);
  2349.                if (strstr (strlwr (Temp), Keyword) != NULL)
  2350.                   RetVal = TRUE;
  2351.                if (RetVal == FALSE) {
  2352.                   strcpy (Temp, Msg->To);
  2353.                   if (strstr (strlwr (Temp), Keyword) != NULL)
  2354.                      RetVal = TRUE;
  2355.                }
  2356.                if (RetVal == FALSE) {
  2357.                   strcpy (Temp, Msg->Subject);
  2358.                   if (strstr (strlwr (Temp), Keyword) != NULL)
  2359.                      RetVal = TRUE;
  2360.                }
  2361.                if (RetVal == FALSE) {
  2362.                   if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  2363.                      do {
  2364.                         strcpy (Temp, p);
  2365.                         if (strstr (strlwr (Temp), Keyword) != NULL) {
  2366.                            RetVal = TRUE;
  2367.                            break;
  2368.                         }
  2369.                      } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  2370.                }
  2371.                if (RetVal == TRUE)
  2372.                   break;
  2373.             }
  2374.          }
  2375.          else {
  2376.             if (Msg->ReadHeader (Number) == TRUE) {
  2377.                if (Type == TYPE_PERSONAL || Type == TYPE_PERSONALNEW) {
  2378.                   if (!stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To)) {
  2379.                      if (Type == TYPE_PERSONAL || (Type == TYPE_PERSONALNEW && Msg->Received == FALSE)) {
  2380.                         RetVal = TRUE;
  2381.                         break;
  2382.                      }
  2383.                   }
  2384.                }
  2385.                else if (Type == TYPE_ALL) {
  2386.                   RetVal = TRUE;
  2387.                   break;
  2388.                }
  2389.             }
  2390.          }
  2391.       } while (Stop == FALSE && Msg->Next (Number) == TRUE && Embedded->AbortSession () == FALSE);
  2392.       Msg->UnLock ();
  2393.    }
  2394.  
  2395.    return (RetVal);
  2396. }
  2397.  
  2398. USHORT TInquire::NextMessage (VOID)
  2399. {
  2400.    USHORT RetVal = FALSE, Total = 0;
  2401.    CHAR Temp[128], *p;
  2402.  
  2403.    if (Msg != NULL) {
  2404.       Msg->Lock (0L);
  2405.       while (Stop == FALSE && Msg->Next (Number) == TRUE && Embedded->AbortSession () == FALSE) {
  2406.          if ((++Total % 16) == 0) {
  2407.             if (Embedded->KBHit () == TRUE) {
  2408.                switch (Embedded->Getch ()) {
  2409.                   case 0x03:
  2410.                   case 'c':
  2411.                   case 'C':
  2412.                   case 's':
  2413.                   case 'S':
  2414.                      Stop = TRUE;
  2415.                      break;
  2416.                }
  2417.             }
  2418.          }
  2419.          if (Type == TYPE_KEYWORD) {
  2420.             if (Msg->Read (Number) == TRUE) {
  2421.                strcpy (Temp, Msg->From);
  2422.                if (strstr (strlwr (Temp), Keyword) != NULL)
  2423.                   RetVal = TRUE;
  2424.                if (RetVal == FALSE) {
  2425.                   strcpy (Temp, Msg->To);
  2426.                   if (strstr (strlwr (Temp), Keyword) != NULL)
  2427.                      RetVal = TRUE;
  2428.                }
  2429.                if (RetVal == FALSE) {
  2430.                   strcpy (Temp, Msg->Subject);
  2431.                   if (strstr (strlwr (Temp), Keyword) != NULL)
  2432.                      RetVal = TRUE;
  2433.                }
  2434.                if (RetVal == FALSE) {
  2435.                   if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  2436.                      do {
  2437.                         strcpy (Temp, p);
  2438.                         if (strstr (strlwr (Temp), Keyword) != NULL) {
  2439.                            RetVal = TRUE;
  2440.                            break;
  2441.                         }
  2442.                      } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  2443.                }
  2444.                if (RetVal == TRUE)
  2445.                   break;
  2446.             }
  2447.          }
  2448.          else {
  2449.             if (Msg->ReadHeader (Number) == TRUE) {
  2450.                if (Type == TYPE_PERSONAL || Type == TYPE_PERSONALNEW) {
  2451.                   if (!stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To)) {
  2452.                      if (Type == TYPE_PERSONAL || (Type == TYPE_PERSONALNEW && Msg->Received == FALSE)) {
  2453.                         RetVal = TRUE;
  2454.                         break;
  2455.                      }
  2456.                   }
  2457.                }
  2458.                else if (Type == TYPE_ALL) {
  2459.                   RetVal = TRUE;
  2460.                   break;
  2461.                }
  2462.             }
  2463.          }
  2464.       }
  2465.       Msg->UnLock ();
  2466.    }
  2467.  
  2468.    return (RetVal);
  2469. }
  2470.  
  2471. USHORT TInquire::PreviousMessage (VOID)
  2472. {
  2473.    USHORT RetVal = FALSE, Total = 0;
  2474.    CHAR Temp[128], *p;
  2475.  
  2476.    if (Msg != NULL) {
  2477.       Msg->Lock (0L);
  2478.       while (Stop == FALSE && Msg->Previous (Number) == TRUE && Embedded->AbortSession () == FALSE) {
  2479.          if ((++Total % 16) == 0) {
  2480.             if (Embedded->KBHit () == TRUE) {
  2481.                switch (Embedded->Getch ()) {
  2482.                   case 0x03:
  2483.                   case 'c':
  2484.                   case 'C':
  2485.                   case 's':
  2486.                   case 'S':
  2487.                      Stop = TRUE;
  2488.                      break;
  2489.                }
  2490.             }
  2491.          }
  2492.          if (Type == TYPE_KEYWORD) {
  2493.             if (Msg->Read (Number) == TRUE) {
  2494.                strcpy (Temp, Msg->From);
  2495.                if (strstr (strlwr (Temp), Keyword) != NULL)
  2496.                   RetVal = TRUE;
  2497.                if (RetVal == FALSE) {
  2498.                   strcpy (Temp, Msg->To);
  2499.                   if (strstr (strlwr (Temp), Keyword) != NULL)
  2500.                      RetVal = TRUE;
  2501.                }
  2502.                if (RetVal == FALSE) {
  2503.                   strcpy (Temp, Msg->Subject);
  2504.                   if (strstr (strlwr (Temp), Keyword) != NULL)
  2505.                      RetVal = TRUE;
  2506.                }
  2507.                if (RetVal == FALSE) {
  2508.                   if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  2509.                      do {
  2510.                         strcpy (Temp, p);
  2511.                         if (strstr (strlwr (Temp), Keyword) != NULL) {
  2512.                            RetVal = TRUE;
  2513.                            break;
  2514.                         }
  2515.                      } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  2516.                }
  2517.                if (RetVal == TRUE)
  2518.                   break;
  2519.             }
  2520.          }
  2521.          else {
  2522.             if (Msg->ReadHeader (Number) == TRUE) {
  2523.                if (Type == TYPE_PERSONAL || Type == TYPE_PERSONALNEW) {
  2524.                   if (!stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To)) {
  2525.                      if (Type == TYPE_PERSONAL || (Type == TYPE_PERSONALNEW && Msg->Received == FALSE)) {
  2526.                         RetVal = TRUE;
  2527.                         break;
  2528.                      }
  2529.                   }
  2530.                }
  2531.                else if (Type == TYPE_ALL) {
  2532.                   RetVal = TRUE;
  2533.                   break;
  2534.                }
  2535.             }
  2536.          }
  2537.       }
  2538.       Msg->UnLock ();
  2539.    }
  2540.  
  2541.    return (RetVal);
  2542. }
  2543.  
  2544. USHORT TInquire::First (VOID)
  2545. {
  2546.    USHORT RetVal = FALSE, NewLine = TRUE;
  2547.  
  2548.    Msg = NULL;
  2549.  
  2550.    if (Range == RANGE_ALL) {
  2551.       if (Data->First () == TRUE)
  2552.          do {
  2553.             if (User->Level >= Data->Level) {
  2554.                if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  2555.                   if (NewLine == TRUE) {
  2556.                      Embedded->Printf ("\n\026\001\012Searching area %s ...                ", Data->Key);
  2557.                      NewLine = FALSE;
  2558.                   }
  2559.                   else
  2560.                      Embedded->Printf ("\r\026\001\012Searching area %s ...                ", Data->Key);
  2561.                   Current = Data;
  2562.                   if (Msg != NULL) {
  2563.                      Msg->Close ();
  2564.                      delete Msg;
  2565.                   }
  2566.                   Msg = NULL;
  2567.                   if (Current->Storage == ST_JAM)
  2568.                      Msg = new JAM (Current->Path);
  2569.                   else if (Current->Storage == ST_SQUISH)
  2570.                      Msg = new SQUISH (Current->Path);
  2571.                   else if (Current->Storage == ST_USENET)
  2572.                      Msg = new USENET (Cfg->NewsServer, Current->NewsGroup);
  2573.                   else if (Current->Storage == ST_FIDO)
  2574.                      Msg = new FIDOSDM (Current->Path);
  2575.                   else if (Current->Storage == ST_ADEPT)
  2576.                      Msg = new ADEPT (Current->Path);
  2577.                   else if (Current->Storage == ST_HUDSON)
  2578.                      Msg = new HUDSON (Current->Path, (UCHAR)Current->Board);
  2579.  
  2580.                   if (Msg != NULL) {
  2581.                      Number = Msg->Lowest ();
  2582.  
  2583.                      if (FirstMessage () == TRUE) {
  2584.                         RetVal = TRUE;
  2585.                         break;
  2586.                      }
  2587.  
  2588.                      Msg->Close ();
  2589.                      delete Msg;
  2590.                      Msg = NULL;
  2591.                   }
  2592.                }
  2593.             }
  2594.          } while (Stop == FALSE && Data->Next () == TRUE && Embedded->AbortSession () == FALSE);
  2595.    }
  2596.    else if (Range == RANGE_TAGGED) {
  2597.       if (User->MsgTag->First () == TRUE)
  2598.          do {
  2599.             if (User->MsgTag->Tagged == TRUE && Data->Read (User->MsgTag->Area) == TRUE) {
  2600.                if (User->Level >= Data->Level) {
  2601.                   if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  2602.                      if (NewLine == TRUE) {
  2603.                         Embedded->Printf ("\n\026\001\012Searching area %s ...                ", Data->Key);
  2604.                         NewLine = FALSE;
  2605.                      }
  2606.                      else
  2607.                         Embedded->Printf ("\r\026\001\012Searching area %s ...                ", Data->Key);
  2608.                      Current = Data;
  2609.                      if (Msg != NULL) {
  2610.                         Msg->Close ();
  2611.                         delete Msg;
  2612.                      }
  2613.                      Msg = NULL;
  2614.                      if (Current->Storage == ST_JAM)
  2615.                         Msg = new JAM (Current->Path);
  2616.                      else if (Current->Storage == ST_SQUISH)
  2617.                         Msg = new SQUISH (Current->Path);
  2618.                      else if (Current->Storage == ST_USENET)
  2619.                         Msg = new USENET (Cfg->NewsServer, Current->NewsGroup);
  2620.                      else if (Current->Storage == ST_FIDO)
  2621.                         Msg = new FIDOSDM (Current->Path);
  2622.                      else if (Current->Storage == ST_ADEPT)
  2623.                         Msg = new ADEPT (Current->Path);
  2624.                      else if (Current->Storage == ST_HUDSON)
  2625.                         Msg = new HUDSON (Current->Path, (UCHAR)Current->Board);
  2626.  
  2627.                      if (Msg != NULL) {
  2628.                         Number = Msg->Lowest ();
  2629.  
  2630.                         if (FirstMessage () == TRUE) {
  2631.                            RetVal = TRUE;
  2632.                            break;
  2633.                         }
  2634.  
  2635.                         Msg->Close ();
  2636.                         delete Msg;
  2637.                         Msg = NULL;
  2638.                      }
  2639.                   }
  2640.                }
  2641.             }
  2642.          } while (Stop == FALSE && User->MsgTag->Next () == TRUE && Embedded->AbortSession () == FALSE);
  2643.    }
  2644.    else if (Range == RANGE_CURRENT) {
  2645.       if (Msg != NULL) {
  2646.          Msg->Close ();
  2647.          delete Msg;
  2648.       }
  2649.       Msg = NULL;
  2650.       if (Current->Storage == ST_JAM)
  2651.          Msg = new JAM (Current->Path);
  2652.       else if (Current->Storage == ST_SQUISH)
  2653.          Msg = new SQUISH (Current->Path);
  2654.       else if (Current->Storage == ST_USENET)
  2655.          Msg = new USENET (Cfg->NewsServer, Current->NewsGroup);
  2656.       else if (Current->Storage == ST_FIDO)
  2657.          Msg = new FIDOSDM (Current->Path);
  2658.       else if (Current->Storage == ST_ADEPT)
  2659.          Msg = new ADEPT (Current->Path);
  2660.       else if (Current->Storage == ST_HUDSON)
  2661.          Msg = new HUDSON (Current->Path, (UCHAR)Current->Board);
  2662.  
  2663.       if (Msg != NULL) {
  2664.          Number = Msg->Lowest ();
  2665.  
  2666.          if (FirstMessage () == TRUE)
  2667.             RetVal = TRUE;
  2668.          else {
  2669.             Msg->Close ();
  2670.             delete Msg;
  2671.             Msg = NULL;
  2672.          }
  2673.       }
  2674.    }
  2675.  
  2676.    return (RetVal);
  2677. }
  2678.  
  2679. USHORT TInquire::Next (VOID)
  2680. {
  2681.    USHORT RetVal = FALSE;
  2682.  
  2683.    if (Action == ACTION_LIST)
  2684.       Embedded->Printf ("\r\026\001\012Searching area %s ...                ", Data->Key);
  2685.    else
  2686.       Embedded->Printf ("\n\026\001\012Searching area %s ...                ", Data->Key);
  2687.    if (Msg != NULL && NextMessage () == TRUE)
  2688.       RetVal = TRUE;
  2689.  
  2690.    if (RetVal == FALSE) {
  2691.       if (Range == RANGE_ALL) {
  2692.          if (Data->Next () == TRUE)
  2693.             do {
  2694.                if (User->Level >= Data->Level) {
  2695.                   if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  2696.                      Embedded->Printf ("\r\026\001\012Searching area %s ...                ", Data->Key);
  2697.                      Current = Data;
  2698.                      if (Msg != NULL) {
  2699.                         Msg->Close ();
  2700.                         delete Msg;
  2701.                      }
  2702.                      Msg = NULL;
  2703.                      if (Current->Storage == ST_JAM)
  2704.                         Msg = new JAM (Current->Path);
  2705.                      else if (Current->Storage == ST_SQUISH)
  2706.                         Msg = new SQUISH (Current->Path);
  2707.                      else if (Current->Storage == ST_USENET)
  2708.                         Msg = new USENET (Cfg->NewsServer, Current->NewsGroup);
  2709.                      else if (Current->Storage == ST_FIDO)
  2710.                         Msg = new FIDOSDM (Current->Path);
  2711.                      else if (Current->Storage == ST_ADEPT)
  2712.                         Msg = new ADEPT (Current->Path);
  2713.                      else if (Current->Storage == ST_HUDSON)
  2714.                         Msg = new HUDSON (Current->Path, (UCHAR)Current->Board);
  2715.  
  2716.                      if (Msg != NULL) {
  2717.                         Number = Msg->Lowest ();
  2718.  
  2719.                         if (FirstMessage () == TRUE) {
  2720.                            RetVal = TRUE;
  2721.                            break;
  2722.                         }
  2723.  
  2724.                         Msg->Close ();
  2725.                         delete Msg;
  2726.                         Msg = NULL;
  2727.                      }
  2728.                   }
  2729.                }
  2730.             } while (Stop == FALSE && Data->Next () == TRUE && Embedded->AbortSession () == FALSE);
  2731.       }
  2732.       else if (Range == RANGE_TAGGED) {
  2733.          if (User->MsgTag->Next () == TRUE)
  2734.             do {
  2735.                if (User->MsgTag->Tagged == TRUE && Data->Read (User->MsgTag->Area) == TRUE) {
  2736.                   if (User->Level >= Data->Level) {
  2737.                      if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  2738.                         Embedded->Printf ("\r\026\001\012Searching area %s ...                ", Data->Key);
  2739.                         Current = Data;
  2740.                         if (Msg != NULL) {
  2741.                            Msg->Close ();
  2742.                            delete Msg;
  2743.                         }
  2744.                         Msg = NULL;
  2745.                         if (Current->Storage == ST_JAM)
  2746.                            Msg = new JAM (Current->Path);
  2747.                         else if (Current->Storage == ST_SQUISH)
  2748.                            Msg = new SQUISH (Current->Path);
  2749.                         else if (Current->Storage == ST_USENET)
  2750.                            Msg = new USENET (Cfg->NewsServer, Current->NewsGroup);
  2751.                         else if (Current->Storage == ST_FIDO)
  2752.                            Msg = new FIDOSDM (Current->Path);
  2753.                         else if (Current->Storage == ST_ADEPT)
  2754.                            Msg = new ADEPT (Current->Path);
  2755.                         else if (Current->Storage == ST_HUDSON)
  2756.                            Msg = new HUDSON (Current->Path, (UCHAR)Current->Board);
  2757.  
  2758.                         if (Msg != NULL) {
  2759.                            Number = Msg->Lowest ();
  2760.  
  2761.                            if (FirstMessage () == TRUE) {
  2762.                               RetVal = TRUE;
  2763.                               break;
  2764.                            }
  2765.  
  2766.                            Msg->Close ();
  2767.                            delete Msg;
  2768.                            Msg = NULL;
  2769.                         }
  2770.                      }
  2771.                   }
  2772.                }
  2773.             } while (Stop == FALSE && User->MsgTag->Next () == TRUE && Embedded->AbortSession () == FALSE);
  2774.       }
  2775.    }
  2776.  
  2777.    return (RetVal);
  2778. }
  2779.  
  2780. USHORT TInquire::Previous (VOID)
  2781. {
  2782.    USHORT RetVal = FALSE;
  2783.  
  2784.    Embedded->Printf ("\r\026\001\012Searching area %s ...                \r", Data->Key);
  2785.    if (Msg != NULL && PreviousMessage () == TRUE)
  2786.       RetVal = TRUE;
  2787.  
  2788.    if (RetVal == FALSE) {
  2789.       if (Range == RANGE_ALL) {
  2790.          if (Data->Previous () == TRUE)
  2791.             do {
  2792.                if (User->Level >= Data->Level) {
  2793.                   if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  2794.                      Embedded->Printf ("\r\026\001\012Searching area %s ...                ", Data->Key);
  2795.                      Current = Data;
  2796.                      if (Msg != NULL) {
  2797.                         Msg->Close ();
  2798.                         delete Msg;
  2799.                      }
  2800.                      Msg = NULL;
  2801.                      if (Current->Storage == ST_JAM)
  2802.                         Msg = new JAM (Current->Path);
  2803.                      else if (Current->Storage == ST_SQUISH)
  2804.                         Msg = new SQUISH (Current->Path);
  2805.                      else if (Current->Storage == ST_USENET)
  2806.                         Msg = new USENET (Cfg->NewsServer, Current->NewsGroup);
  2807.                      else if (Current->Storage == ST_FIDO)
  2808.                         Msg = new FIDOSDM (Current->Path);
  2809.                      else if (Current->Storage == ST_ADEPT)
  2810.                         Msg = new ADEPT (Current->Path);
  2811.                      else if (Current->Storage == ST_HUDSON)
  2812.                         Msg = new HUDSON (Current->Path, (UCHAR)Current->Board);
  2813.  
  2814.                      if (Msg != NULL) {
  2815.                         Number = Msg->Highest () + 1L;
  2816.  
  2817.                         if (PreviousMessage () == TRUE) {
  2818.                            RetVal = TRUE;
  2819.                            break;
  2820.                         }
  2821.  
  2822.                         Msg->Close ();
  2823.                         delete Msg;
  2824.                         Msg = NULL;
  2825.                      }
  2826.                   }
  2827.                }
  2828.             } while (Stop == FALSE && Data->Previous () == TRUE && Embedded->AbortSession () == FALSE);
  2829.       }
  2830.       else if (Range == RANGE_TAGGED) {
  2831.          if (User->MsgTag->Previous () == TRUE)
  2832.             do {
  2833.                if (User->MsgTag->Tagged == TRUE && Data->Read (User->MsgTag->Area) == TRUE) {
  2834.                   if (User->Level >= Data->Level) {
  2835.                      if ((Data->AccessFlags & User->AccessFlags) == Data->AccessFlags) {
  2836.                         Embedded->Printf ("\r\026\001\012Searching area %s ...                ", Data->Key);
  2837.                         Current = Data;
  2838.                         if (Msg != NULL) {
  2839.                            Msg->Close ();
  2840.                            delete Msg;
  2841.                         }
  2842.                         Msg = NULL;
  2843.                         if (Current->Storage == ST_JAM)
  2844.                            Msg = new JAM (Current->Path);
  2845.                         else if (Current->Storage == ST_SQUISH)
  2846.                            Msg = new SQUISH (Current->Path);
  2847.                         else if (Current->Storage == ST_USENET)
  2848.                            Msg = new USENET (Cfg->NewsServer, Current->NewsGroup);
  2849.                         else if (Current->Storage == ST_FIDO)
  2850.                            Msg = new FIDOSDM (Current->Path);
  2851.                         else if (Current->Storage == ST_ADEPT)
  2852.                            Msg = new ADEPT (Current->Path);
  2853.                         else if (Current->Storage == ST_HUDSON)
  2854.                            Msg = new HUDSON (Current->Path, (UCHAR)Current->Board);
  2855.  
  2856.                         if (Msg != NULL) {
  2857.                            Number = Msg->Highest ();
  2858.  
  2859.                            if (PreviousMessage () == TRUE) {
  2860.                               RetVal = TRUE;
  2861.                               break;
  2862.                            }
  2863.  
  2864.                            Msg->Close ();
  2865.                            delete Msg;
  2866.                            Msg = NULL;
  2867.                         }
  2868.                      }
  2869.                   }
  2870.                }
  2871.             } while (Stop == FALSE && User->MsgTag->Previous () == TRUE && Embedded->AbortSession () == FALSE);
  2872.       }
  2873.    }
  2874.  
  2875.    return (RetVal);
  2876. }
  2877.  
  2878. VOID TInquire::Query (VOID)
  2879. {
  2880.    USHORT End, DoRead;
  2881.    SHORT Line, Continue;
  2882.    CHAR Temp[16], LastKey[16], Cmd;
  2883.    class TMsgEditor *Editor;
  2884.    class TMailEditor *MailEditor;
  2885.  
  2886.    Number = 0L;
  2887.  
  2888.    Data = new TMsgData (Cfg->SystemPath);
  2889.    Msg = NULL;
  2890.    LastKey[0] = '\0';
  2891.  
  2892.    if (Range == RANGE_UNDEFINED) {
  2893.       if (SearchRange () == FALSE)
  2894.          return;
  2895.    }
  2896.    if (Action == ACTION_UNDEFINED) {
  2897.       if (SearchAction () == FALSE)
  2898.          return;
  2899.    }
  2900.  
  2901.    if (Type == TYPE_KEYWORD) {
  2902.       Embedded->Printf ("\n\x16\x01\013Enter the text to search, ? for help, or RETURN to exit.\n: ");
  2903.       Embedded->Input (Keyword, (USHORT)(sizeof (Keyword) - 1), 0);
  2904.       if (Keyword[0] == '\0' || Embedded->AbortSession () == TRUE)
  2905.          return;
  2906.       strlwr (Keyword);
  2907.    }
  2908.  
  2909.    if (First () == TRUE) {
  2910.       End = FALSE;
  2911.       DoRead = TRUE;
  2912.  
  2913.       if (Action == ACTION_READ) {
  2914.          Cmd = '\0';
  2915.          while (Embedded->AbortSession () == FALSE && Cmd != Language->Text(LNG_EXITREADMESSAGE)[0]) {
  2916.             if (End == FALSE && DoRead == TRUE) {
  2917.                if (Msg->Read (Number) == TRUE) {
  2918.                   DisplayCurrent ();
  2919.                   if (Msg->Received == FALSE) {
  2920.                      Msg->Received = TRUE;
  2921.                      Msg->WriteHeader (Number);
  2922.                   }
  2923.                }
  2924.                DoRead = FALSE;
  2925.             }
  2926.  
  2927.             if (End == FALSE)
  2928.                Embedded->Printf (Language->Text(LNG_READMENU));
  2929.             else
  2930.                Embedded->Printf (Language->Text(LNG_ENDREADMENU));
  2931.             Embedded->GetString (Temp, 10, INP_HOTKEY|INP_NUMERIC);
  2932.             if ((Cmd = (CHAR)toupper (Temp[0])) == '\0')
  2933.                Cmd = Language->Text(LNG_NEXTMESSAGE)[0];
  2934.  
  2935.             if (Cmd == Language->Text(LNG_NEXTMESSAGE)[0]) {
  2936.                End = FALSE;
  2937.                if (Next () == FALSE) {
  2938.                   Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  2939.                   End = TRUE;
  2940.                }
  2941.                else
  2942.                   DoRead = TRUE;
  2943.             }
  2944.             else if (Cmd == Language->Text(LNG_PREVIOUSMESSAGE)[0]) {
  2945.                End = FALSE;
  2946.                if (Previous () == FALSE) {
  2947.                   Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  2948.                   End = TRUE;
  2949.                }
  2950.                else
  2951.                   DoRead = TRUE;
  2952.             }
  2953.             else if (Cmd == Language->Text(LNG_REPLYMESSAGE)[0]) {
  2954.                if (User->Level >= Current->WriteLevel) {
  2955.                   if ((User->AccessFlags & Current->WriteFlags) == Current->WriteFlags) {
  2956.                      if ((Editor = new TMsgEditor) != NULL) {
  2957.                         Editor->Cfg = Cfg;
  2958.                         Editor->Embedded = Embedded;
  2959.                         Editor->Log = Log;
  2960.                         Editor->Msg = Msg;
  2961.                         Editor->Language = Language;
  2962.                         Editor->Width = User->ScreenWidth;
  2963.                         strcpy (Editor->UserName, User->Name);
  2964.                         if (Current->EchoMail == TRUE) {
  2965.                            Editor->EchoMail = TRUE;
  2966.                            strcpy (Editor->Origin, Cfg->SystemName);
  2967.                            if (Cfg->MailAddress.First () == TRUE)
  2968.                               strcpy (Editor->Address, Cfg->MailAddress.String);
  2969.                         }
  2970.                         if (Editor->Reply () == TRUE)
  2971.                            Editor->Menu ();
  2972.                         delete Editor;
  2973.  
  2974.                         Current->ActiveMsgs = Msg->Number ();
  2975.                         Current->FirstMessage = Msg->Lowest ();
  2976.                         Current->LastMessage = Msg->Highest ();
  2977.                         Current->Update ();
  2978.                         Msg->Read (Number);
  2979.                      }
  2980.                   }
  2981.                   else
  2982.                      Embedded->Printf ("\026\001\015Sorry, you can't write messages in this Conference.\n\006\007\006\007");
  2983.                }
  2984.                else
  2985.                   Embedded->Printf ("\026\001\015Sorry, you can't write messages in this Conference.\n\006\007\006\007");
  2986.             }
  2987.             else if (Cmd == Language->Text(LNG_EMAILREPLYMESSAGE)[0] && End == FALSE) {
  2988.                if ((MailEditor = new TMailEditor) != NULL) {
  2989.                   Editor->Cfg = Cfg;
  2990.                   MailEditor->Embedded = Embedded;
  2991.                   MailEditor->Log = Log;
  2992.                   MailEditor->Msg = Msg;
  2993.                   MailEditor->Language = Language;
  2994.                   MailEditor->Width = User->ScreenWidth;
  2995.                   strcpy (MailEditor->UserName, User->Name);
  2996.                   if (Cfg->MailAddress.First () == TRUE)
  2997.                      strcpy (MailEditor->Address, Cfg->MailAddress.String);
  2998.                   if (MailEditor->Reply () == TRUE)
  2999.                      MailEditor->Menu ();
  3000.                }
  3001.             }
  3002.          }
  3003.       }
  3004.       else if (Action == ACTION_LIST) {
  3005.          Line = 2;
  3006.          Embedded->Printf ("\x0C\026\001\012    #  From                    To                     Subject\n");
  3007.          Embedded->Printf ("-----  ----------------------  ---------------------  -----------------------\n");
  3008.          Continue = TRUE;
  3009.  
  3010.          while (Embedded->AbortSession () == FALSE && Line != 0 && Continue == TRUE) {
  3011.             if (Msg->ReadHeader (Number) == TRUE) {
  3012.                Embedded->Printf ("\r");
  3013.                if ((Line = Embedded->MoreQuestion (Line)) == 1) {
  3014.                   Embedded->Printf ("\x0C    #  From                    To                     Subject\n");
  3015.                   Embedded->Printf ("-----  ----------------------  ---------------------  -----------------------\n");
  3016.                   Line = 2;
  3017.                }
  3018.                if (strcmp (LastKey, Current->Key)) {
  3019.                   Embedded->Printf ("Area %s - %s\n", Current->Key, Current->Display);
  3020.                   strcpy (LastKey, Current->Key);
  3021.                   Line++;
  3022.                }
  3023.                Embedded->Printf ("\026\001\016%5ld  \026\001\012%-22.22s  %-21.21s  %-.23s\n", Msg->UidToMsgn (Msg->Current), Msg->From, Msg->To, Msg->Subject);
  3024.             }
  3025.             if (Line != 0)
  3026.                Continue = Next ();
  3027.          }
  3028.  
  3029.          if (Line != 2) {
  3030.             Embedded->Printf ("\r");
  3031.             Embedded->PressEnter ();
  3032.          }
  3033.       }
  3034.    }
  3035.    else
  3036.       Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  3037.  
  3038.    if (Msg != NULL) {
  3039.       Msg->Close ();
  3040.       delete Msg;
  3041.    }
  3042.    if (Data != NULL)
  3043.       delete Data;
  3044. }
  3045.  
  3046. USHORT TInquire::SearchRange (VOID)
  3047. {
  3048.    USHORT RetVal = FALSE;
  3049.    CHAR Temp[4];
  3050.  
  3051.    while (Embedded->AbortSession () == FALSE) {
  3052.       Embedded->Printf ("\n\x16\x01\012Which Conferences would you like included in the list of search?\n\n");
  3053.       Embedded->Printf ("  \x16\x01\013C \x16\x01\016... Current Conference (%s)\n", Current->Key);
  3054.       Embedded->Printf ("  \x16\x01\013T \x16\x01\016... Tagged Conferences\n");
  3055.       Embedded->Printf ("  \x16\x01\013A \x16\x01\016... All Conferences\n\n");
  3056.       Embedded->Printf ("\x16\x01\013Select an option, X to exit, or RETURN for the current Conference: ");
  3057.       Embedded->Input (Temp, 1, INP_HOTKEY);
  3058.       Temp[0] = (CHAR)toupper (Temp[0]);
  3059.       if (Temp[0] == 'A' || Temp[0] == 'T' || Temp[0] == 'C' || Temp[0] == 'X' || Temp[0] == '\0')
  3060.          break;
  3061.    }
  3062.  
  3063.    switch (Temp[0]) {
  3064.       case 'C':
  3065.       case '\0':
  3066.          Range = RANGE_CURRENT;
  3067.          RetVal = TRUE;
  3068.          break;
  3069.       case 'A':
  3070.          Range = RANGE_ALL;
  3071.          RetVal = TRUE;
  3072.          break;
  3073.       case 'T':
  3074.          Range = RANGE_TAGGED;
  3075.          RetVal = TRUE;
  3076.          break;
  3077.    }
  3078.  
  3079.    return (RetVal);
  3080. }
  3081.  
  3082. USHORT TInquire::SearchAction (VOID)
  3083. {
  3084.    USHORT RetVal = FALSE;
  3085.    CHAR Temp[4];
  3086.  
  3087.    while (Embedded->AbortSession () == FALSE) {
  3088.       Embedded->Printf ("\n\x16\x01\012How do you like to display the messages?\n\n");
  3089.       Embedded->Printf ("  \x16\x01\013R \x16\x01\016... Read (show entire message)\n");
  3090.       Embedded->Printf ("  \x16\x01\013L \x16\x01\016... List (one per line)\n\n");
  3091.       Embedded->Printf ("\x16\x01\013Select an option, X to exit, or RETURN for read: ");
  3092.       Embedded->Input (Temp, 1, INP_HOTKEY);
  3093.       Temp[0] = (CHAR)toupper (Temp[0]);
  3094.       if (Temp[0] == 'R' || Temp[0] == 'L' || Temp[0] == 'X' || Temp[0] == '\0')
  3095.          break;
  3096.    }
  3097.  
  3098.    switch (Temp[0]) {
  3099.       case 'R':
  3100.       case '\0':
  3101.          Action = ACTION_READ;
  3102.          RetVal = TRUE;
  3103.          break;
  3104.       case 'L':
  3105.          Action = ACTION_LIST;
  3106.          RetVal = TRUE;
  3107.          break;
  3108.    }
  3109.  
  3110.    return (RetVal);
  3111. }
  3112.  
  3113. VOID TInquire::BuildDate (PSZ format, PSZ dest, MDATE *date)
  3114. {
  3115.    CHAR Temp[16];
  3116.  
  3117.    while (*format != '\0') {
  3118.       if (*format == '%') {
  3119.          format++;
  3120.          switch (*format) {
  3121.             case 'A':
  3122.                if (date->Hour >= 12)
  3123.                   strcpy (dest, "pm");
  3124.                else
  3125.                   strcpy (dest, "am");
  3126.                dest += 2;
  3127.                format++;
  3128.                break;
  3129.             case 'B':
  3130.                sprintf (Temp, "%2d", date->Month);
  3131.                strcpy (dest, Temp);
  3132.                dest += strlen (Temp);
  3133.                format++;
  3134.                break;
  3135.             case 'C':
  3136.                sprintf (Temp, "%-3.3s", Language->Months[date->Month - 1]);
  3137.                strcpy (dest, Temp);
  3138.                dest += strlen (Temp);
  3139.                format++;
  3140.                break;
  3141.             case 'D':
  3142.                sprintf (Temp, "%2d", date->Day);
  3143.                strcpy (dest, Temp);
  3144.                dest += strlen (Temp);
  3145.                format++;
  3146.                break;
  3147.             case 'E':
  3148.                if (date->Hour > 12)
  3149.                   sprintf (Temp, "%2d", date->Hour - 12);
  3150.                else
  3151.                   sprintf (Temp, "%2d", date->Hour);
  3152.                strcpy (dest, Temp);
  3153.                dest += strlen (Temp);
  3154.                format++;
  3155.                break;
  3156.             case 'H':
  3157.                sprintf (Temp, "%2d", date->Hour);
  3158.                strcpy (dest, Temp);
  3159.                dest += strlen (Temp);
  3160.                format++;
  3161.                break;
  3162.             case 'M':
  3163.                sprintf (Temp, "%02d", date->Minute);
  3164.                strcpy (dest, Temp);
  3165.                dest += strlen (Temp);
  3166.                format++;
  3167.                break;
  3168.             case 'S':
  3169.                sprintf (Temp, "%02d", date->Second);
  3170.                strcpy (dest, Temp);
  3171.                dest += strlen (Temp);
  3172.                format++;
  3173.                break;
  3174.             case 'Y':
  3175.                sprintf (Temp, "%2d", date->Year % 100);
  3176.                strcpy (dest, Temp);
  3177.                dest += strlen (Temp);
  3178.                format++;
  3179.                break;
  3180.             case 'Z':
  3181.                sprintf (Temp, "%4d", date->Year);
  3182.                strcpy (dest, Temp);
  3183.                dest += strlen (Temp);
  3184.                format++;
  3185.                break;
  3186.             default:
  3187.                *dest++ = *format++;
  3188.                break;
  3189.          }
  3190.       }
  3191.       else
  3192.          *dest++ = *format++;
  3193.    }
  3194.    *dest = '\0';
  3195. }
  3196.  
  3197.