home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LORA299S.ZIP / EMAIL.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  44KB  |  1,265 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 TMailList : public TListings
  23. {
  24. public:
  25.    USHORT Forward, ShowKludges, ToYou, Unread;
  26.    ULONG  Number;
  27.    class  TConfig *Cfg;
  28.    class  TMsgBase *Msg;
  29.  
  30.    VOID   Begin (VOID);
  31.    USHORT DrawScreen (VOID);
  32.    VOID   PrintCursor (USHORT y);
  33.    VOID   PrintLine (VOID);
  34.    VOID   PrintTitles (VOID);
  35.    VOID   RemoveCursor (USHORT y);
  36.    VOID   Select (VOID);
  37. };
  38.  
  39. VOID TMailList::Begin (VOID)
  40. {
  41.    USHORT i, Continue;
  42.    LISTDATA ld;
  43.  
  44.    i = 0;
  45.    y = 4;
  46.    Found = FALSE;
  47.    List.Clear ();
  48.    Data.Clear ();
  49.  
  50.    if (Msg  != NULL) {
  51.       if (Forward == TRUE)
  52.          Continue = Msg->Next (Number);
  53.       else
  54.          Continue = Msg->Previous (Number);
  55.  
  56.       while (Embedded->AbortSession () == FALSE && Continue == TRUE) {
  57.          if (Msg->ReadHeader (Number) == TRUE) {
  58.             if (Unread == TRUE) {
  59.                if (Msg->Received == FALSE && !stricmp (Msg->To, User->Name)) {
  60.                   sprintf (ld.Key, "%lu", Number);
  61.                   sprintf (ld.Display, "%-26.26s  %-42.42s", Msg->From, Msg->Subject);
  62.                   Data.Add (&ld, sizeof (LISTDATA));
  63.                }
  64.             }
  65.             else if ((ToYou == TRUE && !stricmp (Msg->To, User->Name)) || (ToYou == FALSE && !stricmp (Msg->From, User->Name))) {
  66.                sprintf (ld.Key, "%lu", Number);
  67.                if (ToYou == TRUE)
  68.                   sprintf (ld.Display, "%-26.26s  %-42.42s", Msg->From, Msg->Subject);
  69.                else
  70.                   sprintf (ld.Display, "%-26.26s  %-42.42s", Msg->To, Msg->Subject);
  71.                Data.Add (&ld, sizeof (LISTDATA));
  72.             }
  73.             if (Forward == TRUE)
  74.                Continue = Msg->Next (Number);
  75.             else
  76.                Continue = Msg->Previous (Number);
  77.          }
  78.       }
  79.    }
  80.  
  81.    Found = TRUE;
  82.    if ((pld = (LISTDATA *)Data.First ()) != NULL) {
  83.       do {
  84.          List.Add (pld->Key, (USHORT)(strlen (pld->Key) + 1));
  85.          i++;
  86.          if (i >= (User->ScreenHeight - 6)) {
  87.             if (Found == TRUE)
  88.                break;
  89.             List.Clear ();
  90.             i = 0;
  91.          }
  92.       } while ((pld = (LISTDATA *)Data.Next ()) != NULL);
  93.    }
  94. }
  95.  
  96. USHORT TMailList::DrawScreen (VOID)
  97. {
  98.    USHORT i;
  99.  
  100.    i = 0;
  101.    do {
  102.       pld = (LISTDATA *)Data.Value ();
  103.       PrintLine ();
  104.       i++;
  105.    } while (Data.Next () != NULL && i < (User->ScreenHeight - 6));
  106.  
  107.    return (i);
  108. }
  109.  
  110. VOID TMailList::PrintTitles (VOID)
  111. {
  112.    Embedded->Printf ("\x0C\x16\x01\x0B%s \x16\x01\x0A- \x16\x01\x0B%s\026\007\n", "E-Mail", "Electronic Mail");
  113.    if (ToYou == TRUE)
  114.       Embedded->Printf ("\026\001\012    #  From                        Subject\n");
  115.    else
  116.       Embedded->Printf ("\026\001\012    #  To                          Subject\n");
  117.    Embedded->Printf ("=====  ==========================  ==========================================\n");
  118.  
  119.    Embedded->PrintfAt ((USHORT)(User->ScreenHeight - 2), 1, "=====  ==========================  ==========================================\n");
  120.  
  121.    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");
  122.    Embedded->Printf ("\026\001\012To highlight a message, use your \026\001\013arrow keys\026\001\012, \026\001\013RETURN \026\001\012reads it.");
  123.  
  124.    Embedded->PrintfAt (4, 1, "");
  125. }
  126.  
  127. VOID TMailList::PrintLine (VOID)
  128. {
  129.    Embedded->Printf ("\026\001\013%-5.5s  \026\001\016%s\n", pld->Key, pld->Display);
  130. }
  131.  
  132. VOID TMailList::PrintCursor (USHORT y)
  133. {
  134.    Embedded->PrintfAt (y, 1, "\x16\x01\x70%-5.5s\x16\x01\x0E", (PSZ)List.Value ());
  135. }
  136.  
  137. VOID TMailList::RemoveCursor (USHORT y)
  138. {
  139.    Embedded->PrintfAt (y, 1, "\x16\x01\x0B%-5.5s\x16\x01\x0E", (PSZ)List.Value ());
  140. }
  141.  
  142. VOID TMailList::Select (VOID)
  143. {
  144.    USHORT Line, MaxLine, gotFrom = FALSE, gotTo = FALSE;
  145.    CHAR *Text, Temp[96], *p, Display[32];
  146.    ULONG Msgn;
  147.  
  148.    if (Msg != NULL) {
  149.       Msg->Read (atoi ((PSZ)List.Value ()));
  150.       Msgn = Msg->Current;
  151.  
  152.       if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  153.          do {
  154.             if (!strncmp (p, "\001From: ", 7)) {
  155.                Msg->FromAddress[0] = '\0';
  156.                if (gotTo == FALSE)
  157.                   Msg->ToAddress[0] = '\0';
  158.                ParseAddress (&p[7], Msg->From, Msg->FromAddress);
  159.                gotFrom = TRUE;
  160.             }
  161.             else if (!strncmp (p, "\001To: ", 5)) {
  162.                if (gotFrom == FALSE)
  163.                   Msg->FromAddress[0] = '\0';
  164.                Msg->ToAddress[0] = '\0';
  165.                ParseAddress (&p[5], Msg->To, Msg->ToAddress);
  166.                gotTo = TRUE;
  167.             }
  168.             if (gotFrom == TRUE && gotTo == TRUE)
  169.                break;
  170.          } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  171.  
  172.       strcpy (Temp, "===============================================================================");
  173.       strcpy (Display, "Electronic Mail");
  174.       Temp[79 - strlen (Display) - 3] = '\0';
  175.       Embedded->BufferedPrintf ("\x0C\x16\x01\x09= \x16\x01\x0E%s \x16\x01\x09%s\n", Display, Temp);
  176.  
  177.       Embedded->BufferedPrintf ("\x16\x01\x0A    Msg: \x16\x01\x0E%lu\n", Msgn);
  178.       sprintf (Temp, "%02d %3.3s %d %2d:%02d", Msg->Written.Day, Language->Months[Msg->Written.Month - 1], Msg->Written.Year, Msg->Written.Hour, Msg->Written.Minute);
  179.       Embedded->BufferedPrintf ("\x16\x01\x0A   From: \x16\x01\x0E%-35.35s \x16\x01\x0F%-16.16s \x16\x01\x07%s\n", Msg->From, Msg->FromAddress, Temp);
  180.       sprintf (Temp, "%02d %3.3s %d %2d:%02d", Msg->Arrived.Day, Language->Months[Msg->Arrived.Month - 1], Msg->Arrived.Year, Msg->Arrived.Hour, Msg->Arrived.Minute);
  181.       Embedded->BufferedPrintf ("\x16\x01\x0A     To: \x16\x01\x0E%-35.35s \x16\x01\x0F%-16.16s \x16\x01\x07%s\n", Msg->To, Msg->ToAddress, Temp);
  182.       Embedded->BufferedPrintf ("\x16\x01\x0ASubject: \x16\x01\x0E%s\n", Msg->Subject);
  183.       Embedded->BufferedPrintf ("\x16\x01\x09===============================================================================\n");
  184.       Line = 6;
  185.  
  186.       if ((Text = (CHAR *)Msg->Text.First ()) != NULL)
  187.          do {
  188.             if (ShowKludges == TRUE || (strncmp (Text, "SEEN-BY: ", 9) && Text[0] != 1)) {
  189.                if (strchr (Text, '>') != NULL)
  190.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEQUOTE), Text);
  191.                else if (!strncmp (Text, "SEEN-BY: ", 9) || Text[0] == 1)
  192.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEKLUDGE), Text);
  193.                else if (!strncmp (Text, " * Origin", 9) || !strncmp (Text, "---", 3))
  194.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEORIGIN), Text);
  195.                else
  196.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGETEXT), Text);
  197.  
  198.                MaxLine = Line;
  199.                if ((Line = Embedded->MoreQuestion (Line)) == 1) {
  200.                   MaxLine++;
  201.                   while (MaxLine > 6)
  202.                      Embedded->BufferedPrintfAt (MaxLine--, 1, "\026\007");
  203.                   Line = 6;
  204.                }
  205.             }
  206.          } while ((Text = (CHAR *)Msg->Text.Next ()) != NULL && Embedded->AbortSession () == FALSE && Line != 0);
  207.  
  208.       Embedded->UnbufferBytes ();
  209.  
  210.       if (Line > 6) {
  211.          Embedded->Printf ("\n\026\001\013");
  212.          if (Embedded->MoreQuestion (Line) != 1)
  213.             Embedded->PressEnter ();
  214.       }
  215.  
  216.       Redraw = Titles = TRUE;
  217.    }
  218. }
  219.  
  220. // ----------------------------------------------------------------------
  221.  
  222. TEMail::TEMail (void)
  223. {
  224.    Log = NULL;
  225.    Language = NULL;
  226.    Embedded = NULL;
  227.    Msg = NULL;
  228.  
  229.    ShowKludges = FALSE;
  230.    Width = 79;
  231.    Height = 24;
  232.    DoCls = More = TRUE;
  233.  
  234.    Storage = ST_SQUISH;
  235.    strcpy (BasePath, "email");
  236. }
  237.  
  238. TEMail::~TEMail (void)
  239. {
  240.    if (Msg != NULL)
  241.       delete Msg;
  242. }
  243.  
  244. VOID TEMail::BriefList (VOID)
  245. {
  246.    USHORT Found, Continue, Line;
  247.    CHAR Which, Start, Temp[40];
  248.    ULONG First, Last, Number;
  249.    class TMailList *List;
  250.  
  251.    Msg = NULL;
  252.    if (Storage == ST_JAM)
  253.       Msg = new JAM (BasePath);
  254.    else if (Storage == ST_SQUISH)
  255.       Msg = new SQUISH (BasePath);
  256.    else if (Storage == ST_FIDO)
  257.       Msg = new FIDOSDM (BasePath);
  258.    else if (Storage == ST_ADEPT)
  259.       Msg = new ADEPT (BasePath);
  260.    else
  261.       Log->Write ("!Invalid e-mail storage type");
  262.  
  263.    if (Msg != NULL) {
  264.       First = Msg->Lowest ();
  265.       Last = Msg->Highest ();
  266.  
  267.       if (Msg->Number () != 0L) {
  268.          do {
  269.             Embedded->Printf ("\n\026\001\013Read messages (F)rom you or (T)o you (? for help)? \026\001\007");
  270.             Embedded->Input (Temp, 10, INP_HOTKEY|INP_NUMERIC);
  271.             if ((Which = (CHAR)toupper (Temp[0])) == '\0')
  272.                Which = Language->Text(LNG_NEXTMESSAGE)[0];
  273.          } while (Which != 'T' && Which != 'F' && Which != '\0' && Embedded->AbortSession () == FALSE);
  274.  
  275.          if ((Which == 'T' || Which == 'F') && Embedded->AbortSession () == FALSE) {
  276.             Found = FALSE;
  277.             Number = Msg->Lowest ();
  278.             do {
  279.                if (Msg->ReadHeader (Number) == TRUE) {
  280.                   if (Which == 'T' && (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName))) {
  281.                      Found = TRUE;
  282.                      break;
  283.                   }
  284.                   else if (Which == 'F' && (!stricmp (Msg->From, User->Name) || !stricmp (Msg->From, User->RealName))) {
  285.                      Found = TRUE;
  286.                      break;
  287.                   }
  288.                }
  289.             } while (Msg->Next (Number) == TRUE);
  290.  
  291.             if (Found == TRUE) {
  292.                Number = 0L;
  293.  
  294.                do {
  295.                   Embedded->Printf (Language->Text(LNG_STARTWITHMESSAGE));
  296.                   Embedded->Printf (Language->Text(LNG_NEWMESSAGES));
  297.                   Embedded->Printf (": ");
  298.                   Embedded->Input (Temp, 10, INP_HOTKEY|INP_NUMERIC);
  299.                   if ((Start = (CHAR)toupper (Temp[0])) == Language->Help)
  300.                      Embedded->DisplayFile ("MAILSTRT");
  301.                } while (Embedded->AbortSession () == FALSE && Start != 'F' && Start != 'L' && Start != '\0' && !isdigit (Start));
  302.  
  303.                if (isdigit (Start)) {
  304.                   Start = 'F';
  305.                   Number = atol (Temp);
  306.                }
  307.                else if (Start == 'F' || Start == '\0')
  308.                   Number = First - 1L;
  309.                else if (Start == 'L')
  310.                   Number = Last + 1L;
  311.  
  312.                if (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE) {
  313.                   if ((List = new TMailList) != NULL) {
  314.                      List->Cfg = Cfg;
  315.                      List->Embedded = Embedded;
  316.                      List->Log = Log;
  317.                      List->User = User;
  318.                      List->Language = Language;
  319.                      List->Msg = Msg;
  320.                      List->Forward = TRUE;
  321.                      if (Start == 'L')
  322.                         List->Forward = FALSE;
  323.                      List->ToYou = TRUE;
  324.                      List->Unread = (USHORT)(Start == '\0' ? TRUE : FALSE);
  325.                      if (Which == 'F')
  326.                         List->ToYou = FALSE;
  327.                      List->Number = Number;
  328.                      List->ShowKludges = FALSE;
  329.                      List->Run ();
  330.                      delete List;
  331.                   }
  332.                }
  333.                else {
  334.                   Line = 2;
  335.                   Embedded->Printf ("\x0C\026\001\012    #  From                    To                     Subject\n");
  336.                   Embedded->Printf ("-----  ----------------------  ---------------------  -----------------------\n");
  337.  
  338.                   if (Start == 'F' || Start == '\0')
  339.                      Continue = Msg->Next (Number);
  340.                   else
  341.                      Continue = Msg->Previous (Number);
  342.  
  343.                   while (Embedded->AbortSession () == FALSE && Line != 0 && Continue == TRUE) {
  344.                      if (Msg->ReadHeader (Number) == TRUE) {
  345.                         if ((Which == 'T' && !stricmp (Msg->To, User->Name)) || (Which == 'F' && !stricmp (Msg->From, User->Name))) {
  346.                            if ((Line = Embedded->MoreQuestion (Line)) == 1) {
  347.                               Embedded->Printf ("\x0C    #  From                    To                     Subject\n");
  348.                               Embedded->Printf ("-----  ----------------------  ---------------------  -----------------------\n");
  349.                               Line = 2;
  350.                            }
  351.                            Embedded->Printf ("\026\001\016%5d  \026\001\012%-22.22s  %-21.21s  %-.23s\n", Msg->Current, Msg->From, Msg->To, Msg->Subject);
  352.                         }
  353.                      }
  354.                      if (Start == 'F' || Start == '\0')
  355.                         Continue = Msg->Next (Number);
  356.                      else
  357.                         Continue = Msg->Previous (Number);
  358.                   }
  359.  
  360.                   Embedded->Printf ("\n\026\001\016End of list! \001\001");
  361.                }
  362.             }
  363.             else {
  364.                if (Which == 'T')
  365.                   Embedded->Printf ("\n\026\001\015Sorry, there are no messages in your mailbox.\n\006\007\006\007");
  366.                else
  367.                   Embedded->Printf ("\n\026\001\015Sorry, there are no messages from you in the database.\n\006\007\006\007");
  368.             }
  369.          }
  370.       }
  371.  
  372.       delete Msg;
  373.       Msg = NULL;
  374.    }
  375. }
  376.  
  377. VOID TEMail::CheckUnread (VOID)
  378. {
  379.    USHORT i, Unread = 0;
  380.    CHAR *Rotating = "-\\|/";
  381.    ULONG Number;
  382.  
  383.    Msg = NULL;
  384.    if (Storage == ST_JAM)
  385.       Msg = new JAM (BasePath);
  386.    else if (Storage == ST_SQUISH)
  387.       Msg = new SQUISH (BasePath);
  388.    else if (Storage == ST_FIDO)
  389.       Msg = new FIDOSDM (BasePath);
  390.    else if (Storage == ST_ADEPT)
  391.       Msg = new ADEPT (BasePath);
  392.    else
  393.       Log->Write ("!Invalid e-mail storage type");
  394.  
  395.    Embedded->Printf ("\n\026\001\012Checking your mailbox ...  ");
  396.    if (Msg != NULL) {
  397.       Msg->Lock (0L);
  398.       Number = Msg->Lowest ();
  399.       i = 0;
  400.  
  401.       do {
  402.          if (Number > 0L && (Number % 10L) == 0L) {
  403.             Embedded->Printf ("\x08%c", Rotating[i++]);
  404.             if (Rotating[i] == '\0')
  405.                i = 0;
  406.          }
  407.          if (Msg->ReadHeader (Number) == TRUE) {
  408.             if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  409.                if (Msg->Received == FALSE)
  410.                   Unread++;
  411.             }
  412.          }
  413.       } while (Msg->Next (Number) == TRUE);
  414.  
  415.       Embedded->Printf (" \010\n");
  416.  
  417.       Msg->UnLock ();
  418.       delete Msg;
  419.       Msg = NULL;
  420.    }
  421.  
  422.    if (Unread > 0)
  423.       ReadMessages ();
  424.    else
  425.       Embedded->Printf ("\n\026\001\007Sorry, but you have no mail waiting.\n\006\007\006\007");
  426. }
  427.  
  428. VOID TEMail::Delete (VOID)
  429. {
  430.    CHAR szTemp[20];
  431.    ULONG ulMsg, ulNumber, First;
  432.  
  433.    Msg = NULL;
  434.    if (Storage == ST_JAM)
  435.       Msg = new JAM (BasePath);
  436.    else if (Storage == ST_SQUISH)
  437.       Msg = new SQUISH (BasePath);
  438.    else if (Storage == ST_FIDO)
  439.       Msg = new FIDOSDM (BasePath);
  440.    else if (Storage == ST_ADEPT)
  441.       Msg = new ADEPT (BasePath);
  442.    else
  443.       Log->Write ("!Invalid e-mail storage type");
  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", 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\006\007\006\007", ulMsg);
  462.             }
  463.             else
  464.                Embedded->Printf ("\n\x16\x01\x0DSorry, message number %ld is neither FROM you nor 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 nor a PRIVATE message TO you, so you can't erase it.\n\006\007\006\007", ulMsg);
  468.       }
  469.  
  470.       delete Msg;
  471.       Msg = NULL;
  472.    }
  473. }
  474.  
  475. /*
  476.    "\026\001\013Do you want to send a copy of this message to anyone (Y/N)? "
  477.  
  478.    "\026\001\013Who do you whish to send a copy f this message (cc:) to?\nYou may also type ? for help: "
  479. */
  480.  
  481. VOID TEMail::BuildDate (PSZ format, PSZ dest, MDATE *date)
  482. {
  483.    CHAR Temp[16];
  484.  
  485.    while (*format != '\0') {
  486.       if (*format == '%') {
  487.          format++;
  488.          switch (*format) {
  489.             case 'A':
  490.                if (date->Hour >= 12)
  491.                   strcpy (dest, "pm");
  492.                else
  493.                   strcpy (dest, "am");
  494.                dest += 2;
  495.                format++;
  496.                break;
  497.             case 'B':
  498.                sprintf (Temp, "%2d", date->Month);
  499.                strcpy (dest, Temp);
  500.                dest += strlen (Temp);
  501.                format++;
  502.                break;
  503.             case 'C':
  504.                sprintf (Temp, "%-3.3s", Language->Months[date->Month - 1]);
  505.                strcpy (dest, Temp);
  506.                dest += strlen (Temp);
  507.                format++;
  508.                break;
  509.             case 'D':
  510.                sprintf (Temp, "%2d", date->Day);
  511.                strcpy (dest, Temp);
  512.                dest += strlen (Temp);
  513.                format++;
  514.                break;
  515.             case 'E':
  516.                if (date->Hour > 12)
  517.                   sprintf (Temp, "%2d", date->Hour - 12);
  518.                else
  519.                   sprintf (Temp, "%2d", date->Hour);
  520.                strcpy (dest, Temp);
  521.                dest += strlen (Temp);
  522.                format++;
  523.                break;
  524.             case 'H':
  525.                sprintf (Temp, "%2d", date->Hour);
  526.                strcpy (dest, Temp);
  527.                dest += strlen (Temp);
  528.                format++;
  529.                break;
  530.             case 'M':
  531.                sprintf (Temp, "%02d", date->Minute);
  532.                strcpy (dest, Temp);
  533.                dest += strlen (Temp);
  534.                format++;
  535.                break;
  536.             case 'S':
  537.                sprintf (Temp, "%02d", date->Second);
  538.                strcpy (dest, Temp);
  539.                dest += strlen (Temp);
  540.                format++;
  541.                break;
  542.             case 'Y':
  543.                sprintf (Temp, "%2d", date->Year % 100);
  544.                strcpy (dest, Temp);
  545.                dest += strlen (Temp);
  546.                format++;
  547.                break;
  548.             case 'Z':
  549.                sprintf (Temp, "%4d", date->Year);
  550.                strcpy (dest, Temp);
  551.                dest += strlen (Temp);
  552.                format++;
  553.                break;
  554.             default:
  555.                *dest++ = *format++;
  556.                break;
  557.          }
  558.       }
  559.       else
  560.          *dest++ = *format++;
  561.    }
  562.    *dest = '\0';
  563. }
  564.  
  565. VOID TEMail::DisplayCurrent (VOID)
  566. {
  567.    USHORT InitialLine;
  568.    USHORT Line, MaxLine, gotFrom = FALSE, gotTo = FALSE;
  569.    CHAR *Text, Temp[96], *p, Flags[96];
  570.    ULONG Msgn;
  571.  
  572.    if (Msg != NULL) {
  573.       Msgn = Msg->UidToMsgn (Msg->Current);
  574.  
  575.       if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  576.          do {
  577.             if (!strncmp (p, "\001From: ", 7)) {
  578.                Msg->FromAddress[0] = '\0';
  579.                if (gotTo == FALSE)
  580.                   Msg->ToAddress[0] = '\0';
  581.                ParseAddress (&p[7], Msg->From, Msg->FromAddress);
  582.                gotFrom = TRUE;
  583.             }
  584.             else if (!strncmp (p, "\001To: ", 5)) {
  585.                if (gotFrom == FALSE)
  586.                   Msg->FromAddress[0] = '\0';
  587.                Msg->ToAddress[0] = '\0';
  588.                ParseAddress (&p[5], Msg->To, Msg->ToAddress);
  589.                gotTo = TRUE;
  590.             }
  591.             if (gotFrom == TRUE && gotTo == TRUE)
  592.                break;
  593.          } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  594.  
  595.       Flags[0] = '\0';
  596.       if (Msg->Received == TRUE)
  597.          strcat (Flags, Language->Text (LNG_MSGFLAG_RCV));
  598.       if (Msg->Sent == TRUE)
  599.          strcat (Flags, Language->Text (LNG_MSGFLAG_SNT));
  600.       if (Msg->Private == TRUE)
  601.          strcat (Flags, Language->Text (LNG_MSGFLAG_PVT));
  602.       if (Msg->Crash == TRUE)
  603.          strcat (Flags, Language->Text (LNG_MSGFLAG_CRA));
  604.       if (Msg->KillSent == TRUE)
  605.          strcat (Flags, Language->Text (LNG_MSGFLAG_KS));
  606.       if (Msg->Local == TRUE)
  607.          strcat (Flags, Language->Text (LNG_MSGFLAG_LOC));
  608.       if (Msg->Hold == TRUE)
  609.          strcat (Flags, Language->Text (LNG_MSGFLAG_HLD));
  610.       if (Msg->FileAttach == TRUE)
  611.          strcat (Flags, Language->Text (LNG_MSGFLAG_ATT));
  612.       if (Msg->FileRequest == TRUE)
  613.          strcat (Flags, Language->Text (LNG_MSGFLAG_FRQ));
  614.       if (Msg->Intransit == TRUE)
  615.          strcat (Flags, Language->Text (LNG_MSGFLAG_TRS));
  616.  
  617.       if (User->FullReader == TRUE && (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE)) {
  618.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEHDR), "E-Mail", (CHAR)(80 - 6 - 3));
  619.          if (Msg->Original != 0L && Msg->Reply == 0L)
  620.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER1), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Original));
  621.          else if (Msg->Original == 0L && Msg->Reply != 0L)
  622.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER2), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Reply));
  623.          else if (Msg->Original != 0L && Msg->Reply != 0L)
  624.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER3), Msgn, Msg->Number (), Msg->UidToMsgn (Msg->Original), Msg->UidToMsgn (Msg->Reply));
  625.          else
  626.             sprintf (Temp, Language->Text (LNG_MESSAGENUMBER), Msgn, Msg->Number ());
  627.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFLAGS), Temp, Flags);
  628.  
  629.          BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Written);
  630.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFROM), Msg->From, Msg->FromAddress, Temp);
  631.          BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Arrived);
  632.          Embedded->BufferedPrintf (Language->Text (LNG_MESSAGETO), Msg->To, Msg->ToAddress, Temp);
  633.          if (Msg->FileAttach == TRUE || Msg->FileRequest == TRUE)
  634.             Embedded->BufferedPrintf (Language->Text (LNG_MESSAGEFILE), Msg->Subject);
  635.          else
  636.             Embedded->BufferedPrintf (Language->Text (LNG_MESSAGESUBJECT), Msg->Subject);
  637.          Embedded->BufferedPrintf ("\x16\x01\x13\031─\120");
  638.  
  639.          InitialLine = Line = 6;
  640.       }
  641.       else {
  642.          Embedded->BufferedPrintf ("\x0C");
  643.          Embedded->BufferedPrintf ("\026\001\003From:    \026\001\016%-36.36s \026\001\017%-.33s\n", Msg->From, Flags);
  644.  
  645.          BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Written);
  646.          Embedded->BufferedPrintf ("\026\001\003To:      \026\001\016%-36.36s \026\001\012Msg #%lu, %-.23s\n", Msg->To, Msgn, Temp);
  647.  
  648.          if (Msg->FileAttach == TRUE || Msg->FileRequest == TRUE)
  649.             Embedded->BufferedPrintf ("\026\001\003File(s): \026\001\016%-.70s\n", Msg->Subject);
  650.          else
  651.             Embedded->BufferedPrintf ("\026\001\003Subject: \026\001\016%-.70s\n\n", Msg->Subject);
  652.  
  653.          InitialLine = Line = 4;
  654.       }
  655.  
  656.       if ((Text = (CHAR *)Msg->Text.First ()) != NULL)
  657.          do {
  658.             if (ShowKludges == TRUE || (strncmp (Text, "SEEN-BY: ", 9) && Text[0] != 1)) {
  659.                if (!strncmp (Text, "SEEN-BY: ", 9) || Text[0] == 1) {
  660.                   if (Text[0] == 1)
  661.                      Text++;
  662.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEKLUDGE), Text);
  663.                }
  664.                else if (!strncmp (Text, " * Origin", 9) || !strncmp (Text, "---", 3))
  665.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEORIGIN), Text);
  666.                else if (strchr (Text, '>') != NULL)
  667.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEQUOTE), Text);
  668.                else
  669.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGETEXT), Text);
  670.  
  671.                MaxLine = Line;
  672.                if ((Line = Embedded->MoreQuestion (Line)) == 1) {
  673.                   MaxLine++;
  674.                   while (MaxLine > InitialLine)
  675.                      Embedded->BufferedPrintfAt (MaxLine--, 1, "\026\007");
  676.                   Line = InitialLine;
  677.                }
  678.             }
  679.          } while ((Text = (CHAR *)Msg->Text.Next ()) != NULL && Embedded->AbortSession () == FALSE && Line != 0);
  680.  
  681.       if (User->FullReader == FALSE || (Embedded->Ansi == FALSE && Embedded->Avatar == FALSE)) {
  682.          if (Msg->Original != 0L && Msg->Reply == 0L)
  683.             Embedded->BufferedPrintf ("\n\026\001\017*** This is a reply to #%lu.\n", Msg->UidToMsgn (Msg->Original));
  684.          else if (Msg->Original == 0L && Msg->Reply != 0L)
  685.             Embedded->BufferedPrintf ("\n\026\001\017*** See also #%lu.\n", Msg->UidToMsgn (Msg->Reply));
  686.          else if (Msg->Original != 0L && Msg->Reply != 0L)
  687.             Embedded->BufferedPrintf ("\n\026\001\017*** This is a reply to #%lu.  *** See also #%lu.\n", Msg->UidToMsgn (Msg->Original), Msg->UidToMsgn (Msg->Reply));
  688.          Line += 2;
  689.       }
  690.  
  691.       Embedded->UnbufferBytes ();
  692.  
  693.       if (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName)) {
  694.          Msg->Received = TRUE;
  695.          Msg->WriteHeader (Msg->Current);
  696.       }
  697.  
  698.       if (Line > InitialLine) {
  699.          MaxLine = Line;
  700.          Embedded->MoreQuestion (99);
  701.          MaxLine++;
  702.          while (MaxLine > InitialLine)
  703.             Embedded->BufferedPrintfAt (MaxLine--, 1, "\026\007");
  704.       }
  705.    }
  706. }
  707.  
  708. VOID TEMail::Write (USHORT Type, PSZ Argument)
  709. {
  710.    char *v, *p;
  711.    class TMailEditor *Editor;
  712.  
  713.    if ((Editor = new TMailEditor) != NULL) {
  714.       if (Argument != NULL) {
  715.          while ((p = strchr (Argument, '/')) != NULL) {
  716.             if (!strnicmp (p, "/T=\"", 4)) {
  717.                if ((v = strchr (&p[4], '"')) != NULL)
  718.                   *v = '\0';
  719.                strcpy (Editor->To, (char *)&p[4]);
  720.                if (v != NULL)
  721.                   *v = '"';
  722.             }
  723.             else if (!strnicmp (p, "/S=\"", 4)) {
  724.                if ((v = strchr (&p[4], '"')) != NULL)
  725.                   *v = '\0';
  726.                strcpy (Editor->Subject, (char *)&p[4]);
  727.                if (v != NULL)
  728.                   *v = '"';
  729.             }
  730.  
  731.             Argument = p + 1;
  732.          }
  733.       }
  734.  
  735.       Editor->Type = Type;
  736.       Editor->Cfg = Cfg;
  737.       Editor->Embedded = Embedded;
  738.       Editor->Log = Log;
  739.       Editor->Language = Language;
  740.       Editor->Width = User->ScreenWidth;
  741.       Editor->Height = User->ScreenHeight;
  742.       strcpy (Editor->UserName, User->Name);
  743.       if (Cfg->MailAddress.First () == TRUE)
  744.          strcpy (Editor->Address, Cfg->MailAddress.String);
  745.       if (User->FullEd == TRUE && (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE))
  746.          Editor->UseFullScreen = TRUE;
  747.       if (Editor->Write () == TRUE)
  748.          Editor->Menu ();
  749.       delete Editor;
  750.    }
  751. }
  752.  
  753. VOID TEMail::Reply (USHORT ToCurrent /* = FALSE*/)
  754. {
  755.    USHORT gotFrom = FALSE, gotTo = FALSE;
  756.    CHAR *p;
  757.    ULONG Number;
  758.    class TMailEditor *Editor;
  759.  
  760.    if (ToCurrent == FALSE) {
  761.       Msg = NULL;
  762.       if (Storage == ST_JAM)
  763.          Msg = new JAM (BasePath);
  764.       else if (Storage == ST_SQUISH)
  765.          Msg = new SQUISH (BasePath);
  766.       else if (Storage == ST_FIDO)
  767.          Msg = new FIDOSDM (BasePath);
  768.       else if (Storage == ST_ADEPT)
  769.          Msg = new ADEPT (BasePath);
  770.       else
  771.          Log->Write ("!Invalid e-mail storage type");
  772.  
  773.       if (User != NULL) {
  774.          if (User->MsgTag->Read ("EMail") == TRUE)
  775.             Number = User->MsgTag->LastRead;
  776.       }
  777.    }
  778.    else
  779.       Number = Msg->Current;
  780.  
  781.    if (Msg != NULL) {
  782.       if (Msg->Read (Number) == TRUE) {
  783.          if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  784.             do {
  785.                if (!strncmp (p, "\001From: ", 7)) {
  786.                   Msg->FromAddress[0] = '\0';
  787.                   if (gotTo == FALSE)
  788.                      Msg->ToAddress[0] = '\0';
  789.                   ParseAddress (&p[7], Msg->From, Msg->FromAddress);
  790.                   gotFrom = TRUE;
  791.                }
  792.                else if (!strncmp (p, "\001To: ", 5)) {
  793.                   if (gotFrom == FALSE)
  794.                      Msg->FromAddress[0] = '\0';
  795.                   Msg->ToAddress[0] = '\0';
  796.                   ParseAddress (&p[5], Msg->To, Msg->ToAddress);
  797.                   gotTo = TRUE;
  798.                }
  799.                if (gotFrom == TRUE && gotTo == TRUE)
  800.                   break;
  801.             } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  802.  
  803.          if ((Editor = new TMailEditor) != NULL) {
  804.             Editor->Cfg = Cfg;
  805.             Editor->Embedded = Embedded;
  806.             Editor->Log = Log;
  807.             Editor->Language = Language;
  808.             Editor->Width = User->ScreenWidth;
  809.             Editor->Height = User->ScreenHeight;
  810.             strcpy (Editor->UserName, User->Name);
  811.             Editor->Msg = Msg;
  812.             if (Cfg->MailAddress.First () == TRUE)
  813.                strcpy (Editor->Address, Cfg->MailAddress.String);
  814.             if (User->FullEd == TRUE && (Embedded->Ansi == TRUE || Embedded->Avatar == TRUE))
  815.                Editor->UseFullScreen = TRUE;
  816.             if (Editor->Reply () == TRUE)
  817.                Editor->Menu ();
  818.             delete Editor;
  819.          }
  820.       }
  821.  
  822.       if (ToCurrent == FALSE) {
  823.          delete Msg;
  824.          Msg = NULL;
  825.       }
  826.    }
  827. }
  828.  
  829. VOID TEMail::ReadMessages (USHORT fUnreaded)
  830. {
  831.    USHORT Found;
  832.    CHAR Cmd, DoRead, Temp[40];
  833.    ULONG Number;
  834.  
  835.    Msg = NULL;
  836.    if (Storage == ST_JAM)
  837.       Msg = new JAM (BasePath);
  838.    else if (Storage == ST_SQUISH)
  839.       Msg = new SQUISH (BasePath);
  840.    else if (Storage == ST_FIDO)
  841.       Msg = new FIDOSDM (BasePath);
  842.    else if (Storage == ST_ADEPT)
  843.       Msg = new ADEPT (BasePath);
  844.    else
  845.       Log->Write ("!Invalid e-mail storage type");
  846.  
  847.    if (Msg != NULL) {
  848.       Found = FALSE;
  849.       Number = Msg->Lowest ();
  850.       do {
  851.          if (Msg->ReadHeader (Number) == TRUE) {
  852.             if (Msg->Received == FALSE || fUnreaded == TRUE) {
  853.                if ((!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName))) {
  854.                   Found = TRUE;
  855.                   break;
  856.                }
  857.             }
  858.          }
  859.          if (Msg->Next (Number) == FALSE)
  860.             break;
  861.       } while (Found == FALSE);
  862.  
  863.       if (Found == TRUE) {
  864.          DoRead = TRUE;
  865.          while (Embedded->AbortSession () == FALSE) {
  866.             if (DoRead == TRUE) {
  867.                if (Msg->Read (Number) == TRUE) {
  868.                   DisplayCurrent ();
  869.                   if (Msg->Received == FALSE) {
  870.                      Msg->Received = TRUE;
  871.                      Msg->WriteHeader (Number);
  872.                   }
  873.                }
  874.                DoRead = FALSE;
  875.             }
  876.             Embedded->Printf ("\n\026\001\017Next Msg [Y)es, N)o, A)gain, R)eply, K)ill, U)nreceive, !)Kludges]: ");
  877.             Embedded->Input (Temp, 10, INP_HOTKEY|INP_NUMERIC);
  878.             Cmd = (CHAR)toupper (Temp[0]);
  879.  
  880.             if (Cmd == 'Y' || Cmd == '\0') {
  881.                Found = FALSE;
  882.                if (Msg->Next (Number) == TRUE)
  883.                   do {
  884.                      if (Msg->ReadHeader (Number) == TRUE) {
  885.                         if (Msg->Received == FALSE || fUnreaded == TRUE) {
  886.                            if ((!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName))) {
  887.                               Found = TRUE;
  888.                               DoRead = TRUE;
  889.                               break;
  890.                            }
  891.                         }
  892.                      }
  893.                      if (Msg->Next (Number) == FALSE)
  894.                         break;
  895.                   } while (Found == FALSE);
  896.  
  897.                if (Found == FALSE) {
  898.                   Embedded->Printf ("\n\026\001\014No more mail waiting.\n");
  899.                   break;
  900.                }
  901.             }
  902.             else if (Cmd == 'A')
  903.                DoRead = TRUE;
  904.             else if (Cmd == 'U') {
  905.                if (Msg->Received == TRUE) {
  906.                   Msg->Received = FALSE;
  907.                   Msg->WriteHeader (Number);
  908.                   Embedded->Printf ("\n\026\001\017Done!\n");
  909.                }
  910.             }
  911.             else if (Cmd == 'R')
  912.                Reply (TRUE);
  913.             else if (Cmd == '!') {
  914.                ShowKludges = (ShowKludges == TRUE) ? FALSE : TRUE;
  915.                DoRead = TRUE;
  916.             }
  917.             else if (Cmd == 'K') {
  918.                Embedded->Printf ("\n\026\001\014Message #%lu deleted.\n", Msg->UidToMsgn (Number));
  919.                Msg->Delete (Number);
  920.  
  921.                Found = FALSE;
  922.                if (Msg->Next (Number) == TRUE)
  923.                   do {
  924.                      if (Msg->ReadHeader (Number) == TRUE) {
  925.                         if (Msg->Received == FALSE && (!stricmp (Msg->To, User->Name) || !stricmp (Msg->To, User->RealName))) {
  926.                            Found = TRUE;
  927.                            DoRead = TRUE;
  928.                            break;
  929.                         }
  930.                      }
  931.                      if (Msg->Next (Number) == FALSE)
  932.                         break;
  933.                   } while (Found == FALSE);
  934.  
  935.                if (Found == FALSE) {
  936.                   Embedded->Printf ("\n\026\001\014No more mail waiting.\n");
  937.                   break;
  938.                }
  939.             }
  940.             else if (Cmd == 'N')
  941.                break;
  942.          }
  943.       }
  944.       else
  945.          Embedded->Printf ("\n\026\001\014Sorry, you have no mail waiting.\n\006\007\006\007");
  946.  
  947.       delete Msg;
  948.       Msg = NULL;
  949.    }
  950. }
  951.  
  952. VOID TEMail::StartMessageQuestion (ULONG ulFirst, ULONG ulLast, ULONG &ulMsg, USHORT &fForward)
  953. {
  954.    CHAR Cmd, Temp[20];
  955.  
  956.    do {
  957.       Embedded->Printf (Language->Text(LNG_STARTWITHMESSAGE));
  958.       Embedded->Printf (Language->Text(LNG_NEWMESSAGES));
  959.       Embedded->Printf (": ");
  960.       Embedded->Input (Temp, (USHORT)(sizeof (Temp) - 1), INP_HOTKEY|INP_NUMERIC);
  961.       Cmd = (CHAR)toupper (Temp[0]);
  962.       if (Cmd == Language->Help)
  963.          Embedded->DisplayFile ("MAILSTRT");
  964.    } while (Embedded->AbortSession () == FALSE && Cmd != 'F' && Cmd != 'L' && Cmd != '\0' && !isdigit (Cmd));
  965.  
  966.    fForward = TRUE;
  967.    if (Cmd == 'F') {
  968.       if ((ulMsg = ulFirst) > 0L)
  969.          ulMsg--;
  970.    }
  971.    else if (Cmd == 'L') {
  972.       ulMsg = ulLast + 1L;
  973.       fForward = FALSE;
  974.    }
  975.    else if (isdigit (Cmd)) {
  976.       if ((ulMsg = atol (Temp)) > 0L)
  977.          ulMsg--;
  978.    }
  979. }
  980.  
  981. VOID TEMail::ReadNext (VOID)
  982. {
  983.    USHORT DoRead = FALSE;
  984.    ULONG Number = 0L;
  985.  
  986.    Msg = NULL;
  987.    if (Storage == ST_JAM)
  988.       Msg = new JAM (BasePath);
  989.    else if (Storage == ST_SQUISH)
  990.       Msg = new SQUISH (BasePath);
  991.    else if (Storage == ST_FIDO)
  992.       Msg = new FIDOSDM (BasePath);
  993.    else if (Storage == ST_ADEPT)
  994.       Msg = new ADEPT (BasePath);
  995.    else
  996.       Log->Write ("!Invalid e-mail storage type");
  997.  
  998.    if (User != NULL) {
  999.       if (User->MsgTag->Read ("EMail") == TRUE)
  1000.          Number = User->MsgTag->LastRead;
  1001.    }
  1002.  
  1003.    if (Msg != NULL) {
  1004.       if (Msg->Next (Number) == TRUE)
  1005.          do {
  1006.             Msg->ReadHeader (Number);
  1007.             if (!stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To) || !stricmp (User->Name, Msg->From) || !stricmp (User->RealName, Msg->From)) {
  1008.                DoRead = TRUE;
  1009.                break;
  1010.             }
  1011.          } while (Msg->Next (Number) == TRUE);
  1012.  
  1013.       if (DoRead == TRUE) {
  1014.          Msg->Read (Number);
  1015.          DisplayCurrent ();
  1016.  
  1017.          if (User != NULL) {
  1018.             if (User->MsgTag->Read ("EMail") == TRUE) {
  1019.                User->MsgTag->LastRead = Msg->Current;
  1020.                User->MsgTag->Update ();
  1021.             }
  1022.             else {
  1023.                User->MsgTag->New ();
  1024.                strcpy (User->MsgTag->Area, "EMail");
  1025.                User->MsgTag->Tagged = FALSE;
  1026.                User->MsgTag->LastRead = Msg->Current;
  1027.                User->MsgTag->Add ();
  1028.             }
  1029.          }
  1030.       }
  1031.       else
  1032.          Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  1033.  
  1034.       delete Msg;
  1035.       Msg = NULL;
  1036.    }
  1037. }
  1038.  
  1039. VOID TEMail::ReadPrevious (VOID)
  1040. {
  1041.    USHORT DoRead = FALSE;
  1042.    ULONG Number = 0L;
  1043.  
  1044.    Msg = NULL;
  1045.    if (Storage == ST_JAM)
  1046.       Msg = new JAM (BasePath);
  1047.    else if (Storage == ST_SQUISH)
  1048.       Msg = new SQUISH (BasePath);
  1049.    else if (Storage == ST_FIDO)
  1050.       Msg = new FIDOSDM (BasePath);
  1051.    else if (Storage == ST_ADEPT)
  1052.       Msg = new ADEPT (BasePath);
  1053.    else
  1054.       Log->Write ("!Invalid e-mail storage type");
  1055.  
  1056.    if (User != NULL) {
  1057.       if (User->MsgTag->Read ("EMail") == TRUE)
  1058.          Number = User->MsgTag->LastRead;
  1059.    }
  1060.  
  1061.    if (Msg != NULL) {
  1062.       if (Msg->Previous (Number) == TRUE)
  1063.          do {
  1064.             Msg->ReadHeader (Number);
  1065.             if (!stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To) || !stricmp (User->Name, Msg->From) || !stricmp (User->RealName, Msg->From)) {
  1066.                DoRead = TRUE;
  1067.                break;
  1068.             }
  1069.          } while (Msg->Previous (Number) == TRUE);
  1070.  
  1071.       if (DoRead == TRUE) {
  1072.          Msg->Read (Number);
  1073.          DisplayCurrent ();
  1074.  
  1075.          if (User != NULL) {
  1076.             if (User->MsgTag->Read ("EMail") == TRUE) {
  1077.                User->MsgTag->LastRead = Msg->Current;
  1078.                User->MsgTag->Update ();
  1079.             }
  1080.             else {
  1081.                User->MsgTag->New ();
  1082.                strcpy (User->MsgTag->Area, "EMail");
  1083.                User->MsgTag->Tagged = FALSE;
  1084.                User->MsgTag->LastRead = Msg->Current;
  1085.                User->MsgTag->Add ();
  1086.             }
  1087.          }
  1088.       }
  1089.       else
  1090.          Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  1091.  
  1092.       delete Msg;
  1093.       Msg = NULL;
  1094.    }
  1095. }
  1096.  
  1097. VOID TEMail::Read (ULONG Number)
  1098. {
  1099.    USHORT DoRead = FALSE;
  1100.  
  1101.    Msg = NULL;
  1102.    if (Storage == ST_JAM)
  1103.       Msg = new JAM (BasePath);
  1104.    else if (Storage == ST_SQUISH)
  1105.       Msg = new SQUISH (BasePath);
  1106.    else if (Storage == ST_FIDO)
  1107.       Msg = new FIDOSDM (BasePath);
  1108.    else if (Storage == ST_ADEPT)
  1109.       Msg = new ADEPT (BasePath);
  1110.    else
  1111.       Log->Write ("!Invalid e-mail storage type");
  1112.  
  1113.    if (Msg != NULL) {
  1114.       Number = Msg->MsgnToUid (Number);
  1115.  
  1116.       do {
  1117.          Msg->ReadHeader (Number);
  1118.          if (!stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To) || !stricmp (User->Name, Msg->From) || !stricmp (User->RealName, Msg->From)) {
  1119.             DoRead = TRUE;
  1120.             break;
  1121.          }
  1122.       } while (Msg->Next (Number) == TRUE);
  1123.  
  1124.       if (DoRead == TRUE) {
  1125.          Msg->Read (Number);
  1126.          DisplayCurrent ();
  1127.  
  1128.          if (User != NULL) {
  1129.             if (User->MsgTag->Read ("EMail") == TRUE) {
  1130.                User->MsgTag->LastRead = Msg->Current;
  1131.                User->MsgTag->Update ();
  1132.             }
  1133.             else {
  1134.                User->MsgTag->New ();
  1135.                strcpy (User->MsgTag->Area, "EMail");
  1136.                User->MsgTag->Tagged = FALSE;
  1137.                User->MsgTag->LastRead = Msg->Current;
  1138.                User->MsgTag->Add ();
  1139.             }
  1140.          }
  1141.       }
  1142.       else
  1143.          Embedded->Printf (Language->Text(LNG_ENDOFMESSAGES));
  1144.  
  1145.       delete Msg;
  1146.       Msg = NULL;
  1147.    }
  1148. }
  1149.  
  1150. VOID TEMail::DisplayText (VOID)
  1151. {
  1152.    USHORT gotFrom = FALSE, gotTo = FALSE;
  1153.    CHAR *Text, Temp[96], Flags[96];
  1154.    ULONG Msgn;
  1155.  
  1156.    if (Msg != NULL) {
  1157.       Msgn = Msg->UidToMsgn (Msg->Current);
  1158.  
  1159.       Flags[0] = '\0';
  1160.       if (Msg->Received == TRUE)
  1161.          strcat (Flags, Language->Text (LNG_MSGFLAG_RCV));
  1162.       if (Msg->Sent == TRUE)
  1163.          strcat (Flags, Language->Text (LNG_MSGFLAG_SNT));
  1164.       if (Msg->Private == TRUE)
  1165.          strcat (Flags, Language->Text (LNG_MSGFLAG_PVT));
  1166.       if (Msg->Crash == TRUE)
  1167.          strcat (Flags, Language->Text (LNG_MSGFLAG_CRA));
  1168.       if (Msg->KillSent == TRUE)
  1169.          strcat (Flags, Language->Text (LNG_MSGFLAG_KS));
  1170.       if (Msg->Local == TRUE)
  1171.          strcat (Flags, Language->Text (LNG_MSGFLAG_LOC));
  1172.       if (Msg->Hold == TRUE)
  1173.          strcat (Flags, Language->Text (LNG_MSGFLAG_HLD));
  1174.       if (Msg->FileAttach == TRUE)
  1175.          strcat (Flags, Language->Text (LNG_MSGFLAG_ATT));
  1176.       if (Msg->FileRequest == TRUE)
  1177.          strcat (Flags, Language->Text (LNG_MSGFLAG_FRQ));
  1178.       if (Msg->Intransit == TRUE)
  1179.          strcat (Flags, Language->Text (LNG_MSGFLAG_TRS));
  1180.       Embedded->BufferedPrintf ("\n");
  1181.       Embedded->BufferedPrintf ("\026\001\003From:    \026\001\016%-36.36s \026\001\017%-.33s\n", Msg->From, Flags);
  1182.  
  1183.       BuildDate (Language->Text (LNG_MESSAGEDATE), Temp, &Msg->Written);
  1184.       Embedded->BufferedPrintf ("\026\001\003To:      \026\001\016%-36.36s \026\001\012Msg #%lu, %-.23s\n", Msg->To, Msgn, Temp);
  1185.  
  1186.       if (Msg->FileAttach == TRUE || Msg->FileRequest == TRUE)
  1187.          Embedded->BufferedPrintf ("\026\001\003File(s): \026\001\016%-.70s\n", Msg->Subject);
  1188.       else
  1189.          Embedded->BufferedPrintf ("\026\001\003Subject: \026\001\016%-.70s\n\n", Msg->Subject);
  1190.  
  1191.       if ((Text = (CHAR *)Msg->Text.First ()) != NULL)
  1192.          do {
  1193.             if (ShowKludges == TRUE || (strncmp (Text, "SEEN-BY: ", 9) && Text[0] != 1)) {
  1194.                if (!strncmp (Text, "SEEN-BY: ", 9) || Text[0] == 1) {
  1195.                   if (Text[0] == 1)
  1196.                      Text++;
  1197.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEKLUDGE), Text);
  1198.                }
  1199.                else if (!strncmp (Text, " * Origin", 9) || !strncmp (Text, "---", 3))
  1200.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEORIGIN), Text);
  1201.                else if (strchr (Text, '>') != NULL)
  1202.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGEQUOTE), Text);
  1203.                else
  1204.                   Embedded->BufferedPrintf (Language->Text(LNG_MESSAGETEXT), Text);
  1205.             }
  1206.          } while ((Text = (CHAR *)Msg->Text.Next ()) != NULL && Embedded->AbortSession () == FALSE);
  1207.  
  1208.       Embedded->UnbufferBytes ();
  1209.    }
  1210. }
  1211.  
  1212. VOID TEMail::ReadNonStop (VOID)
  1213. {
  1214.    ULONG Number;
  1215.  
  1216.    Msg = NULL;
  1217.    if (Storage == ST_JAM)
  1218.       Msg = new JAM (BasePath);
  1219.    else if (Storage == ST_SQUISH)
  1220.       Msg = new SQUISH (BasePath);
  1221.    else if (Storage == ST_FIDO)
  1222.       Msg = new FIDOSDM (BasePath);
  1223.    else if (Storage == ST_ADEPT)
  1224.       Msg = new ADEPT (BasePath);
  1225.    else
  1226.       Log->Write ("!Invalid e-mail storage type");
  1227.  
  1228.    if (Msg != NULL) {
  1229.       Number = 0L;
  1230.       if (User != NULL) {
  1231.          if (User->MsgTag->Read ("EMail") == TRUE)
  1232.             Number = User->MsgTag->LastRead;
  1233.       }
  1234.  
  1235.       Embedded->BufferedPrintf ("\x0C");
  1236.  
  1237.       if (Msg->Number () > 0L && Number < Msg->Highest ()) {
  1238.          while (Embedded->AbortSession () == FALSE && Msg->Next (Number) == TRUE) {
  1239.             if (Msg->Read (Number) == TRUE) {
  1240.                if (!stricmp (User->Name, Msg->To) || !stricmp (User->RealName, Msg->To) || !stricmp (User->Name, Msg->From) || !stricmp (User->RealName, Msg->From)) {
  1241.                   DisplayText ();
  1242.                   if (User != NULL) {
  1243.                      if (User->MsgTag->Read ("EMail") == TRUE) {
  1244.                         User->MsgTag->LastRead = Msg->Current;
  1245.                         User->MsgTag->Update ();
  1246.                      }
  1247.                      else {
  1248.                         User->MsgTag->New ();
  1249.                         strcpy (User->MsgTag->Area, "EMail");
  1250.                         User->MsgTag->Tagged = FALSE;
  1251.                         User->MsgTag->LastRead = Msg->Current;
  1252.                         User->MsgTag->Add ();
  1253.                      }
  1254.                   }
  1255.                }
  1256.             }
  1257.          }
  1258.       }
  1259.  
  1260.       delete Msg;
  1261.       Msg = NULL;
  1262.    }
  1263. }
  1264.  
  1265.