home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / USENET.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  29KB  |  841 lines

  1.  
  2. // LoraBBS Version 2.99 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include "_ldefs.h"
  20. #include "msgbase.h"
  21.  
  22. static PSZ GROUP = "GROUP %s\r\n";
  23. static PSZ HEAD  = "HEAD\r\n";
  24. static PSZ LAST  = "LAST\r\n";
  25. static PSZ NEXT  = "NEXT\r\n";
  26. static PSZ POST  = "POST\r\n";
  27. static PSZ QUIT  = "QUIT\r\n";
  28. static PSZ STAT  = "STAT %ld\r\n";
  29. static PSZ ARTICLE = "ARTICLE %ld\r\n";
  30. static PSZ MONTHS[] = {
  31.    "January", "February", "March", "April", "Maj", "Juni",
  32.    "July", "August", "September", "October", "November", "December"
  33. };
  34.  
  35. USENET::USENET (void)
  36. {
  37.    Tcp = new TTcpip;
  38.    ulHighest = ulFirst = ulTotal = 0L;
  39.    LastReaded = 0L;
  40.    strcpy (HostName, "unknown.host");
  41.    strcpy (User, "anonymous");
  42.    strcpy (NewsGroup, "");
  43.    strcpy (Organization, "No Organization");
  44.    strcpy (ProgramID, "LoraBBS");
  45. }
  46.  
  47. USENET::USENET (PSZ pszServer, PSZ pszGroup)
  48. {
  49.    Tcp = new TTcpip;
  50.    ulHighest = ulFirst = ulTotal = 0L;
  51.    LastReaded = 0L;
  52.    strcpy (HostName, "unknown.host");
  53.    strcpy (NewsGroup, "");
  54.    strcpy (Organization, "No Organization");
  55.    strcpy (ProgramID, "Macca's NNTP Client/Server");
  56.    Open (pszServer, pszGroup);
  57. }
  58.  
  59. USENET::~USENET (void)
  60. {
  61.    if (Tcp != NULL)
  62.       delete Tcp;
  63. }
  64.  
  65. USHORT USENET::Add (VOID)
  66. {
  67.    return (Add (Text));
  68. }
  69.  
  70. USHORT USENET::Add (class TMsgBase *MsgBase)
  71. {
  72.    New ();
  73.  
  74.    strcpy (From, MsgBase->From);
  75.    strcpy (To, MsgBase->To);
  76.    strcpy (Subject, MsgBase->Subject);
  77.  
  78.    strcpy (FromAddress, MsgBase->FromAddress);
  79.    strcpy (ToAddress, MsgBase->ToAddress);
  80.  
  81.    Written.Day = MsgBase->Written.Day;
  82.    Written.Month = MsgBase->Written.Month;
  83.    Written.Year = MsgBase->Written.Year;
  84.    Written.Hour = MsgBase->Written.Hour;
  85.    Written.Minute = MsgBase->Written.Minute;
  86.    Written.Second = MsgBase->Written.Second;
  87.  
  88.    Arrived.Day = MsgBase->Arrived.Day;
  89.    Arrived.Month = MsgBase->Arrived.Month;
  90.    Arrived.Year = MsgBase->Arrived.Year;
  91.    Arrived.Hour = MsgBase->Arrived.Hour;
  92.    Arrived.Minute = MsgBase->Arrived.Minute;
  93.    Arrived.Second = MsgBase->Arrived.Second;
  94.  
  95.    Crash = MsgBase->Crash;
  96.    Direct = MsgBase->Direct;
  97.    FileAttach = MsgBase->FileAttach;
  98.    FileRequest = MsgBase->FileRequest;
  99.    Hold = MsgBase->Hold;
  100.    Immediate = MsgBase->Immediate;
  101.    Intransit = MsgBase->Intransit;
  102.    KillSent = MsgBase->KillSent;
  103.    Local = MsgBase->Local;
  104.    Private = MsgBase->Private;
  105.    ReceiptRequest = MsgBase->ReceiptRequest;
  106.    Received = MsgBase->Received;
  107.    Sent = MsgBase->Sent;
  108.  
  109.    return (Add (MsgBase->Text));
  110. }
  111.  
  112. USHORT USENET::Add (class TCollection &MsgText)
  113. {
  114.    USHORT retVal = FALSE, Lines;
  115.    USHORT GotPath, GotFrom, GotNews, GotSubject, GotOrg, GotLines;
  116.    USHORT GotXNews;
  117.    CHAR *pszText;
  118.  
  119.    GotPath = GotFrom = GotNews = GotSubject = GotOrg = FALSE;
  120.    GotLines = GotXNews = FALSE;
  121.  
  122.    if (Tcp->Carrier () == TRUE) {
  123.       Tcp->SendBytes ((UCHAR *)POST, (USHORT)strlen (POST));
  124.       if (GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1)) == 340) {
  125.          if ((pszText = (CHAR *)MsgText.First ()) != NULL)
  126.             do {
  127.                if (!strncmp (pszText, "\001Path: ", 7)) {
  128.                   Tcp->BufferBytes ((UCHAR *)&pszText[1], (USHORT)(strlen (pszText) - 1));
  129.                   Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  130.                   GotPath = TRUE;
  131.                }
  132.                else if (!strncmp (pszText, "\001From: ", 7)) {
  133.                   Tcp->BufferBytes ((UCHAR *)&pszText[1], (USHORT)(strlen (pszText) - 1));
  134.                   Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  135.                   GotFrom = TRUE;
  136.                }
  137. //               else if (!strncmp (pszText, "\001Newsgroups: ", 13)) {
  138. //                  Tcp->BufferBytes ((UCHAR *)&pszText[1], (USHORT)(strlen (pszText) - 1));
  139. //                  Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  140. //                  GotNews = TRUE;
  141. //               }
  142.                else if (!strncmp (pszText, "\001Subject: ", 10)) {
  143.                   Tcp->BufferBytes ((UCHAR *)&pszText[1], (USHORT)(strlen (pszText) - 1));
  144.                   Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  145.                   GotSubject = TRUE;
  146.                }
  147.                else if (!strncmp (pszText, "\001Organization: ", 15)) {
  148.                   Tcp->BufferBytes ((UCHAR *)&pszText[1], (USHORT)(strlen (pszText) - 1));
  149.                   Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  150.                   GotOrg = TRUE;
  151.                }
  152.                else if (!strncmp (pszText, "\001X-Newsreader: ", 15)) {
  153.                   Tcp->BufferBytes ((UCHAR *)&pszText[1], (USHORT)(strlen (pszText) - 1));
  154.                   Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  155.                   GotXNews = TRUE;
  156.                }
  157.                else if (!strncmp (pszText, "\001References: ", 13) || !strncmp (pszText, "\001Sender: ", 9) || !strncmp (pszText, "\001X-To: ", 7)) {
  158.                   Tcp->BufferBytes ((UCHAR *)&pszText[1], (USHORT)(strlen (pszText) - 1));
  159.                   Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  160.                }
  161.             } while ((pszText = (CHAR *)MsgText.Next ()) != NULL);
  162.  
  163.          if (GotPath == FALSE) {
  164.             sprintf (szBuffer, "Path: %s\r\n", HostName);
  165.             Tcp->BufferBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  166.          }
  167.          if (GotFrom == FALSE) {
  168.             sprintf (szBuffer, "From: %s <%s@%s>\r\n", From, User, HostName);
  169.             Tcp->BufferBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  170.          }
  171.          if (GotNews == FALSE) {
  172.             sprintf (szBuffer, "Newsgroups: %s\r\n", NewsGroup);
  173.             Tcp->BufferBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  174.          }
  175.          if (GotSubject == FALSE) {
  176.             sprintf (szBuffer, "Subject: %s\r\n", Subject);
  177.             Tcp->BufferBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  178.          }
  179.          if (GotOrg == FALSE) {
  180.             sprintf (szBuffer, "Organization: %s\r\n", Organization);
  181.             Tcp->BufferBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  182.          }
  183.          sprintf (szBuffer, "Date: %d %3.3s %d %02d:%02d:%02d GMT\r\n", Written.Day, MONTHS[Written.Month - 1], Written.Year, Written.Hour, Written.Minute, Written.Second);
  184.          Tcp->BufferBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  185.  
  186.          if (GotLines == FALSE) {
  187.             Lines = 1;
  188.             if ((pszText = (CHAR *)MsgText.First ()) != NULL)
  189.                do {
  190.                   if (*pszText != 0x01 && strncmp (pszText, "SEEN-BY:", 8))
  191.                      Lines++;
  192.                } while ((pszText = (CHAR *)MsgText.Next ()) != NULL);
  193.             sprintf (szBuffer, "Lines: %d\r\n", Lines);
  194.             Tcp->BufferBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  195.          }
  196.  
  197. //         sprintf (szBuffer, "NNTP-Posting-Host: %s\r\n", HostName);
  198. //         Tcp->BufferBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  199.          if (GotXNews == FALSE) {
  200.             sprintf (szBuffer, "X-Newsreader: %s\r\n", ProgramID);
  201.             Tcp->BufferBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  202.          }
  203.          Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  204.  
  205.          if ((pszText = (CHAR *)MsgText.First ()) != NULL)
  206.             do {
  207.                if (*pszText != 0x01 && strncmp (pszText, "SEEN-BY:", 8)) {
  208.                   if (!strcmp (pszText, "."))
  209.                      Tcp->BufferBytes ((UCHAR *)"..", 2);
  210.                   else
  211.                      Tcp->BufferBytes ((UCHAR *)pszText, (USHORT)strlen (pszText));
  212.                   Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  213.                }
  214.             } while ((pszText = (CHAR *)MsgText.Next ()) != NULL);
  215.          Tcp->BufferBytes ((UCHAR *)".\r\n", 3);
  216.          Tcp->UnbufferBytes ();
  217.          if (GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1)) == 240)
  218.             retVal = TRUE;
  219.       }
  220.       strcpy (Error, szBuffer);
  221.    }
  222.  
  223.    return (retVal);
  224. }
  225.  
  226. VOID USENET::Close (VOID)
  227. {
  228.    CHAR String[50];
  229.  
  230.    Tcp->SendBytes ((UCHAR *)QUIT, (USHORT)strlen (QUIT));
  231.    GetResponse (String, (USHORT)(sizeof (String) - 1));
  232.    ulHighest = ulFirst = ulTotal = 0L;
  233. }
  234.  
  235. USHORT USENET::Delete (ULONG ulMsg)
  236. {
  237.    ulMsg = ulMsg;
  238.    return (FALSE);
  239. }
  240.  
  241. USHORT USENET::GetHWM (ULONG &ulMsg)
  242. {
  243.    ulMsg = 0L;
  244.  
  245.    return (FALSE);
  246. }
  247.  
  248. USHORT USENET::GetResponse (PSZ pszResponse, USHORT usMaxLen)
  249. {
  250.    USHORT retVal = FALSE, len = 0;
  251.    CHAR c, *pszResp = pszResponse;
  252.    LONG timeout;
  253.  
  254.    timeout = time (NULL) + 60L;
  255.  
  256.    do {
  257.       c = '\0';
  258.       if (Tcp->BytesReady () == TRUE) {
  259.          if ((c = (CHAR)Tcp->ReadByte ()) != '\r') {
  260.             if (c != '\n') {
  261.                *pszResp++ = c;
  262.                if (++len >= usMaxLen)
  263.                   c = '\r';
  264.             }
  265.          }
  266.       }
  267.    } while (c != '\r' && Tcp->Carrier () == TRUE && time (NULL) < timeout);
  268.  
  269.    *pszResp = '\0';
  270.    if (pszResponse[3] == ' ')
  271.       retVal = (USHORT)atoi (pszResponse);
  272.  
  273.    return (retVal);
  274. }
  275.  
  276. ULONG USENET::Highest (VOID)
  277. {
  278.    return (ulHighest);
  279. }
  280.  
  281. USHORT USENET::Lock (ULONG ulTimeout)
  282. {
  283.    ulTimeout = ulTimeout;
  284.    return (TRUE);
  285. }
  286.  
  287. ULONG USENET::Lowest (VOID)
  288. {
  289.    return (ulFirst);
  290. }
  291.  
  292. ULONG USENET::MsgnToUid (ULONG ulMsg)
  293. {
  294.    if (ulMsg >= 1 && ulMsg <= Number ())
  295.       ulMsg = ulMsg + Lowest () - 1L;
  296.  
  297.    return (ulMsg);
  298. }
  299.  
  300. VOID USENET::New (VOID)
  301. {
  302.    LastReaded = 0L;
  303.    From[0] = To[0] = Subject[0] = '\0';
  304.    Crash = Direct = FileAttach = FileRequest = Hold = Immediate = FALSE;
  305.    Intransit = KillSent = Local = Private = ReceiptRequest = Received = FALSE;
  306.    Sent = 0;
  307.    memset (&Written, 0, sizeof (Written));
  308.    memset (&Arrived, 0, sizeof (Arrived));
  309.    Original = Reply = 0L;
  310.    Text.Clear ();
  311. }
  312.  
  313. USHORT USENET::Next (ULONG &ulMsg)
  314. {
  315.    USHORT RetVal = FALSE;
  316.    PSZ p;
  317.  
  318.    if (Tcp->Carrier () == TRUE) {
  319.       if (LastReaded != ulMsg) {
  320.          sprintf (szBuffer, STAT, ulMsg);
  321.          Tcp->SendBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  322.          GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1));
  323.       }
  324.       Tcp->SendBytes ((UCHAR *)NEXT, (USHORT)strlen (NEXT));
  325.       if (GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1)) == 223) {
  326.          if ((p = strtok (szBuffer, " ")) != NULL) {
  327.             if ((p = strtok (NULL, " ")) != NULL) {
  328.                LastReaded = ulMsg = atol (p);
  329.                RetVal = TRUE;
  330.             }
  331.          }
  332.       }
  333.    }
  334.  
  335.    return (RetVal);
  336. }
  337.  
  338. ULONG USENET::Number (VOID)
  339. {
  340.    return (ulTotal);
  341. }
  342.  
  343. USHORT USENET::Open (PSZ pszServer, PSZ pszGroup)
  344. {
  345.    USHORT retVal = FALSE, i;
  346.    CHAR String[128], *p;
  347.  
  348.    if (Tcp->ConnectServer (pszServer, 119) == TRUE) {
  349.       i = GetResponse (String, (USHORT)(sizeof (String) - 1));
  350.       if (i == 200 || i == 201) {
  351.          sprintf (String, GROUP, pszGroup);
  352.          Tcp->SendBytes ((UCHAR *)String, (USHORT)strlen (String));
  353.          if (GetResponse (String, (USHORT)(sizeof (String) - 1)) == 211) {
  354.             p = strtok (String, " ");
  355.             if ((p = strtok (NULL, " ")) != NULL)
  356.                ulTotal = atoi (p);
  357.             if ((p = strtok (NULL, " ")) != NULL)
  358.                ulFirst = atoi (p);
  359.             if ((p = strtok (NULL, " ")) != NULL)
  360.                ulHighest = atoi (p);
  361.             strcpy (NewsGroup, pszGroup);
  362.             LastReaded = 0L;
  363.             retVal = TRUE;
  364.          }
  365.       }
  366.    }
  367.  
  368.    return (retVal);
  369. }
  370.  
  371. VOID USENET::Pack (VOID)
  372. {
  373. }
  374.  
  375. USHORT USENET::Previous (ULONG &ulMsg)
  376. {
  377.    USHORT RetVal = FALSE;
  378.    PSZ p;
  379.  
  380.    if (Tcp->Carrier () == TRUE) {
  381.       if (LastReaded != ulMsg) {
  382.          sprintf (szBuffer, STAT, ulMsg);
  383.          Tcp->SendBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  384.          GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1));
  385.       }
  386.       Tcp->SendBytes ((UCHAR *)LAST, (USHORT)strlen (LAST));
  387.       if (GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1)) == 223) {
  388.          if ((p = strtok (szBuffer, " ")) != NULL) {
  389.             if ((p = strtok (NULL, " ")) != NULL) {
  390.                LastReaded = ulMsg = atol (p);
  391.                RetVal = TRUE;
  392.             }
  393.          }
  394.       }
  395.  
  396.       if (RetVal == FALSE) {
  397.          ulMsg--;
  398.          sprintf (szBuffer, STAT, ulMsg);
  399.          Tcp->SendBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  400.          if (GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1)) == 223) {
  401.             LastReaded = ulMsg;
  402.             RetVal = TRUE;
  403.          }
  404.       }
  405.    }
  406.  
  407.    return (RetVal);
  408. }
  409.  
  410. USHORT USENET::ReadHeader (ULONG ulMsg)
  411. {
  412.    USHORT retVal = FALSE, i;
  413.    UCHAR gotFrom, gotSubject;
  414.    CHAR Temp[128], *p, *a;
  415.    struct dosdate_t date;
  416.    struct dostime_t time;
  417.  
  418.    if (Tcp->Carrier () == TRUE) {
  419.       New ();
  420.       gotFrom = gotSubject = FALSE;
  421.       Text.Clear ();
  422.  
  423.       sprintf (szBuffer, STAT, ulMsg);
  424.       Tcp->SendBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  425.       if (GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1)) == 223) {
  426.          Tcp->SendBytes ((UCHAR *)HEAD, (USHORT)strlen (HEAD));
  427.          if (GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1)) == 221) {
  428.             retVal = TRUE;
  429.             _dos_getdate (&date);
  430.             _dos_gettime (&time);
  431.             Arrived.Day = Written.Day = date.day;
  432.             Arrived.Month = Written.Month = date.month;
  433.             Arrived.Year = Written.Year = (USHORT)date.year;
  434.             Arrived.Hour = Written.Hour = time.hour;
  435.             Arrived.Minute = Written.Minute = time.minute;
  436.             Arrived.Second = Written.Second = time.second;
  437.             do {
  438.                szBuffer[0] = 1;
  439.                GetResponse (&szBuffer[1], (USHORT)(sizeof (szBuffer) - 2));
  440.                if (strcmp (szBuffer, "\001.")) {
  441.                   if (!strncmp (szBuffer, "\001From: ", 7) || !strncmp (szBuffer, "\001To: ", 5))
  442.                      Text.Add (szBuffer);
  443.                   else if (!strncmp (szBuffer, "\001Message-ID: ", 13) || !strncmp (szBuffer, "\001References: ", 13))
  444.                      Text.Add (szBuffer);
  445.                }
  446.  
  447.                if (!strncmp (&szBuffer[1], "From: ", 6)) {
  448.                   strcpy (Temp, &szBuffer[7]);
  449.                   if (strchr (Temp, '(') != NULL) {
  450.                      if ((p = strtok (Temp, " ")) != NULL) {
  451.                         p = strtok (NULL, "");
  452.                         while (*p == ' ')
  453.                            p++;
  454.                         if (*p == '(') {
  455.                            strcpy (Temp, ++p);
  456.                            p = strchr (Temp, '\0');
  457.                            while (--p > Temp) {
  458.                               if (*p == ')') {
  459.                                  *p = '\0';
  460.                                  break;
  461.                               }
  462.                            }
  463.                            strcpy (From, Temp);
  464.                            strcpy (Temp, &szBuffer[7]);
  465.                            if ((p = strtok (Temp, " ")) != NULL)
  466.                               strcpy (FromAddress, p);
  467.                         }
  468.                         else {
  469.                            strcpy (Temp, &szBuffer[7]);
  470.                            if ((p = strtok (Temp, " ")) != NULL)
  471.                               strcpy (From, p);
  472.                         }
  473.                      }
  474.                   }
  475.                   else if ((p = strchr (Temp, '<')) != NULL) {
  476.                      *p++ = '\0';
  477.                      if ((a = strchr (p, '>')) != NULL)
  478.                         *a = '\0';
  479.                      strcpy (FromAddress, p);
  480.                      p = Temp;
  481.                      if (*p == '"')
  482.                         strcpy (Temp, ++p);
  483.                      p = strchr (Temp, '\0');
  484.                      while (--p > Temp) {
  485.                         if (*p != ' ' && *p != '"')
  486.                            break;
  487.                         *p = '\0';
  488.                      }
  489.                      strcpy (From, Temp);
  490.                   }
  491.  
  492.                   gotFrom = TRUE;
  493.                }
  494.                else if (!strncmp (&szBuffer[1], "To: ", 4)) {
  495.                   strcpy (Temp, &szBuffer[5]);
  496.                   if (strchr (Temp, '(') != NULL) {
  497.                      if ((p = strtok (Temp, " ")) != NULL) {
  498.                         p = strtok (NULL, "");
  499.                         while (*p == ' ')
  500.                            p++;
  501.                         if (*p == '(') {
  502.                            strcpy (Temp, ++p);
  503.                            p = strchr (Temp, '\0');
  504.                            while (--p > Temp) {
  505.                               if (*p == ')') {
  506.                                  *p = '\0';
  507.                                  break;
  508.                               }
  509.                            }
  510.                            strcpy (To, Temp);
  511.                            strcpy (Temp, &szBuffer[5]);
  512.                            if ((p = strtok (Temp, " ")) != NULL)
  513.                               strcpy (ToAddress, p);
  514.                         }
  515.                         else {
  516.                            strcpy (Temp, &szBuffer[5]);
  517.                            if ((p = strtok (Temp, " ")) != NULL)
  518.                               strcpy (To, p);
  519.                         }
  520.                      }
  521.                   }
  522.                   else if ((p = strchr (Temp, '<')) != NULL) {
  523.                      *p++ = '\0';
  524.                      if ((a = strchr (p, '>')) != NULL)
  525.                         *a = '\0';
  526.                      strcpy (ToAddress, p);
  527.                      p = Temp;
  528.                      if (*p == '"')
  529.                         strcpy (Temp, ++p);
  530.                      p = strchr (Temp, '\0');
  531.                      while (--p > Temp) {
  532.                         if (*p != ' ' && *p != '"')
  533.                            break;
  534.                         *p = '\0';
  535.                      }
  536.                      strcpy (To, Temp);
  537.                   }
  538.                }
  539.                else if (!strncmp (&szBuffer[1], "Subject: ", 9)) {
  540.                   if (strlen (&szBuffer[10]) >= sizeof (Subject))
  541.                      szBuffer[10 + sizeof (Subject)] = '\0';
  542.                   strcpy (Subject, &szBuffer[10]);
  543.                   gotSubject = TRUE;
  544.                }
  545.                else if (!strncmp (&szBuffer[1], "Date: ", 6)) {
  546.                   p = strtok (&szBuffer[7], " ");
  547.                   if (p != NULL && !isdigit (p[0]))
  548.                      p = strtok (NULL, " ");
  549.                   if (p != NULL) {
  550.                      Written.Day = (UCHAR)atoi (p);
  551.                      if ((p = strtok (NULL, " ")) != NULL) {
  552.                         for (i = 0; i < 12; i++)
  553.                            if (strnicmp (MONTHS[i], p, 3) == 0) {
  554.                               Written.Month = (UCHAR)(i + 1);
  555.                               i = 12;
  556.                            }
  557.                      }
  558.                      if ((p = strtok (NULL, " ")) != NULL) {
  559.                         Written.Year = (USHORT)atoi (p);
  560.                         if (Written.Year >= 80 && Written.Year < 100)
  561.                            Written.Year += 1900;
  562.                         else if (Written.Year < 80)
  563.                            Written.Year += 2000;
  564.                      }
  565.                      if ((p = strtok (NULL, " ")) != NULL) {
  566.                         Written.Hour = (UCHAR)((p[0] - '0') * 10 + (p[1] - '0'));
  567.                         p += 2;
  568.                         if (p[0] == ':')
  569.                            p++;
  570.                         Written.Minute = (UCHAR)((p[0] - '0') * 10 + (p[1] - '0'));
  571.                         p += 2;
  572.                         if (p[0] != '\0') {
  573.                            if (p[0] == ':')
  574.                               p++;
  575.                            if (p[0] != '\0')
  576.                               Written.Second = (UCHAR)((p[0] - '0') * 10 + (p[1] - '0'));
  577.                         }
  578.                      }
  579.                   }
  580.                }
  581.             } while (strcmp (szBuffer, "\001."));
  582.             Id = LastReaded = ulMsg;
  583.          }
  584.       }
  585.       if (gotFrom == FALSE || gotSubject == FALSE)
  586.          retVal = FALSE;
  587.    }
  588.  
  589.    return (retVal);
  590. }
  591.  
  592. USHORT USENET::Read (ULONG ulMsg, SHORT nWidth)
  593. {
  594.    return (Read (ulMsg, Text, nWidth));
  595. }
  596.  
  597. USHORT USENET::Read (ULONG ulMsg, class TCollection &MsgText, SHORT nWidth)
  598. {
  599.    USHORT retVal = FALSE, SkipNext;
  600.    SHORT i, nReaded, nCol;
  601.    PSZ p;
  602.    struct dosdate_t date;
  603.    struct dostime_t time;
  604.  
  605.    MsgText.Clear ();
  606.  
  607.    if (Tcp != NULL) {
  608.       New ();
  609.       sprintf (szBuffer, ARTICLE, ulMsg);
  610.       Tcp->SendBytes ((UCHAR *)szBuffer, (USHORT)strlen (szBuffer));
  611.  
  612.       if (GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1)) == 220) {
  613.          retVal = TRUE;
  614.  
  615.          _dos_getdate (&date);
  616.          _dos_gettime (&time);
  617.          Arrived.Day = Written.Day = date.day;
  618.          Arrived.Month = Written.Month = date.month;
  619.          Arrived.Year = Written.Year = (USHORT)date.year;
  620.          Arrived.Hour = Written.Hour = time.hour;
  621.          Arrived.Minute = Written.Minute = time.minute;
  622.          Arrived.Second = Written.Second = time.second;
  623.  
  624.          do {
  625.             szBuffer[0] = 1;
  626.             GetResponse (&szBuffer[1], (USHORT)(sizeof (szBuffer) - 2));
  627.             if (szBuffer[1] != '\0' && strcmp (szBuffer, "."))
  628.                MsgText.Add (szBuffer);
  629.  
  630.             if (!strncmp (&szBuffer[1], "From: ", 6)) {
  631.                if (strlen (&szBuffer[7]) >= sizeof (From))
  632.                   szBuffer[7 + sizeof (From)] = '\0';
  633.                strcpy (From, &szBuffer[7]);
  634.             }
  635.             else if (!strncmp (&szBuffer[1], "Subject: ", 9)) {
  636.                if (strlen (&szBuffer[10]) >= sizeof (Subject))
  637.                   szBuffer[10 + sizeof (Subject)] = '\0';
  638.                strcpy (Subject, &szBuffer[10]);
  639.             }
  640.             else if (!strncmp (&szBuffer[1], "Date: ", 6)) {
  641.                p = strtok (&szBuffer[7], " ");
  642.                if (p != NULL && !isdigit (p[0]))
  643.                   p = strtok (NULL, " ");
  644.                if (p != NULL) {
  645.                   Written.Day = (UCHAR)atoi (p);
  646.                   if ((p = strtok (NULL, " ")) != NULL) {
  647.                      for (i = 0; i < 12; i++)
  648.                         if (strnicmp (MONTHS[i], p, 3) == 0) {
  649.                            Written.Month = (UCHAR)(i + 1);
  650.                            i = 12;
  651.                         }
  652.                   }
  653.                   if ((p = strtok (NULL, " ")) != NULL) {
  654.                      Written.Year = (USHORT)atoi (p);
  655.                      if (Written.Year >= 80 && Written.Year < 100)
  656.                         Written.Year += 1900;
  657.                      else if (Written.Year < 80)
  658.                         Written.Year += 2000;
  659.                   }
  660.                   if ((p = strtok (NULL, " ")) != NULL) {
  661.                      Written.Hour = (UCHAR)((p[0] - '0') * 10 + (p[1] - '0'));
  662.                      p += 2;
  663.                      if (p[0] == ':')
  664.                         p++;
  665.                      Written.Minute = (UCHAR)((p[0] - '0') * 10 + (p[1] - '0'));
  666.                      p += 2;
  667.                      if (p[0] != '\0') {
  668.                         if (p[0] == ':')
  669.                            p++;
  670.                         if (p[0] != '\0')
  671.                            Written.Second = (UCHAR)((p[0] - '0') * 10 + (p[1] - '0'));
  672.                      }
  673.                   }
  674.                }
  675.             }
  676.          } while (szBuffer[1] != '\0' && strcmp (szBuffer, "."));
  677.  
  678.          Id = LastReaded = ulMsg;
  679.          pLine = szLine;
  680.          nCol = 0;
  681.          SkipNext = FALSE;
  682.  
  683.          do {
  684.             GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1));
  685.             nReaded = (USHORT)strlen (szBuffer);
  686.  
  687.             for (i = 0, pBuff = szBuffer; i < nReaded; i++, pBuff++) {
  688.                if (*pBuff != '\n') {
  689.                   *pLine++ = *pBuff;
  690.                   nCol++;
  691.                   if (nCol >= nWidth) {
  692.                      *pLine = '\0';
  693.                      if (strchr (szLine, ' ') != NULL) {
  694.                         while (nCol > 1 && *pLine != ' ') {
  695.                            nCol--;
  696.                            pLine--;
  697.                         }
  698.                         if (nCol > 0) {
  699.                            while (*pLine == ' ')
  700.                               pLine++;
  701.                            strcpy (szWrp, pLine);
  702.                         }
  703.                         *pLine = '\0';
  704.                      }
  705.                      else
  706.                         szWrp[0] = '\0';
  707.                      MsgText.Add (szLine);
  708.                      strcpy (szLine, szWrp);
  709.                      pLine = strchr (szLine, '\0');
  710.                      nCol = (SHORT)strlen (szLine);
  711.                      SkipNext = TRUE;
  712.                   }
  713.                }
  714.             }
  715.             *pLine = '\0';
  716.             if (pLine > szLine && SkipNext == TRUE) {
  717.                pLine--;
  718.                while (pLine > szLine && *pLine == ' ')
  719.                   *pLine-- = '\0';
  720.                if (pLine > szLine && strcmp (szLine, "."))
  721.                   MsgText.Add (szLine);
  722.             }
  723.             else if (SkipNext == FALSE) {
  724.                if (strcmp (szLine, "."))
  725.                   MsgText.Add (szLine);
  726.             }
  727.             SkipNext = FALSE;
  728.             pLine = szLine;
  729.             nCol = 0;
  730.          } while (strcmp (szBuffer, "."));
  731.       }
  732.    }
  733.  
  734.    return (retVal);
  735. }
  736.  
  737. /*
  738. USHORT USENET::Read (ULONG ulMsg, class TCollection &MsgText, SHORT nWidth)
  739. {
  740.    USHORT retVal = FALSE, SkipNext;
  741.    SHORT i, nReaded, nCol;
  742.  
  743.    MsgText.Clear ();
  744.  
  745.    if (Tcp != NULL) {
  746.       if (ulMsg != Id) {
  747.          if (ReadHeader (ulMsg) == TRUE) {
  748.             Id = LastReaded = ulMsg;
  749.             retVal = TRUE;
  750.          }
  751.       }
  752.       else
  753.          retVal = TRUE;
  754.  
  755.       if (retVal == TRUE) {
  756.          pLine = szLine;
  757.          nCol = 0;
  758.          retVal = FALSE;
  759.          SkipNext = FALSE;
  760.  
  761.          Tcp->SendBytes ((UCHAR *)BODY, (USHORT)strlen (BODY));
  762.          if (GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1)) == 222) {
  763.             retVal = TRUE;
  764.             do {
  765.                GetResponse (szBuffer, (USHORT)(sizeof (szBuffer) - 1));
  766.                nReaded = (USHORT)strlen (szBuffer);
  767.  
  768.                for (i = 0, pBuff = szBuffer; i < nReaded; i++, pBuff++) {
  769.                   if (*pBuff != '\n') {
  770.                      *pLine++ = *pBuff;
  771.                      nCol++;
  772.                      if (nCol >= nWidth) {
  773.                         *pLine = '\0';
  774.                         while (nCol > 1 && *pLine != ' ') {
  775.                            nCol--;
  776.                            pLine--;
  777.                         }
  778.                         if (nCol > 0) {
  779.                            while (*pLine == ' ')
  780.                               pLine++;
  781.                            strcpy (szWrp, pLine);
  782.                         }
  783.                         *pLine = '\0';
  784.                         MsgText.Add (szLine, (USHORT)(strlen (szLine) + 1));
  785.                         strcpy (szLine, szWrp);
  786.                         pLine = strchr (szLine, '\0');
  787.                         nCol = (SHORT)strlen (szLine);
  788.                         SkipNext = TRUE;
  789.                      }
  790.                   }
  791.                }
  792.                *pLine = '\0';
  793.                if (pLine > szLine && SkipNext == TRUE) {
  794.                   pLine--;
  795.                   while (pLine > szLine && *pLine == ' ')
  796.                      *pLine-- = '\0';
  797.                   if (pLine > szLine && strcmp (szLine, "."))
  798.                      MsgText.Add (szLine, (USHORT)(strlen (szLine) + 1));
  799.                }
  800.                else if (SkipNext == FALSE) {
  801.                   if (strcmp (szLine, "."))
  802.                      MsgText.Add (szLine, (USHORT)(strlen (szLine) + 1));
  803.                }
  804.                SkipNext = FALSE;
  805.                pLine = szLine;
  806.                nCol = 0;
  807.             } while (strcmp (szBuffer, "."));
  808.          }
  809.       }
  810.    }
  811.  
  812.    return (retVal);
  813. }
  814. */
  815.  
  816. VOID USENET::SetHWM (ULONG ulMsg)
  817. {
  818.    ulMsg = ulMsg;
  819. }
  820.  
  821. ULONG USENET::UidToMsgn (ULONG ulMsg)
  822. {
  823.    if (ulMsg >= Lowest () && ulMsg <= Highest ())
  824.       ulMsg = ulMsg - Lowest () + 1L;
  825.  
  826.    return (ulMsg);
  827. }
  828.  
  829. VOID USENET::UnLock (VOID)
  830. {
  831. }
  832.  
  833. USHORT USENET::WriteHeader (ULONG ulMsg)
  834. {
  835.    ulMsg = ulMsg;
  836.    return (FALSE);
  837. }
  838.  
  839.  
  840.  
  841.