home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / NNTP.CPP < prev    next >
C/C++ Source or Header  |  1996-08-23  |  14KB  |  385 lines

  1.  
  2. // ----------------------------------------------------------------------
  3. // LoraBBS Professional Edition - Version 3.00.6
  4. // Copyright (c) 1996 by Marco Maccaferri. All rights reserved.
  5. //
  6. // History:
  7. //    03/07/96 - Initial coding.
  8. // ----------------------------------------------------------------------
  9.  
  10. #include "_ldefs.h"
  11. #include "lserver.h"
  12.  
  13. //static CHAR *WeekDays[] = {
  14. //   "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  15. //};
  16.  
  17. static CHAR *Months[] = {
  18.    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  19.    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  20. };
  21.  
  22. TNNTP::TNNTP (void)
  23. {
  24.    Tcp = NULL;
  25.    Msg = NULL;
  26.    Log = NULL;
  27. }
  28.  
  29. TNNTP::~TNNTP (void)
  30. {
  31.    if (Tcp != NULL)
  32.       delete Tcp;
  33.    if (Msg != NULL)
  34.       delete Msg;
  35. }
  36.  
  37. VOID TNNTP::GetCommand (VOID)
  38. {
  39.    USHORT len = 0, MaxLen = sizeof (Response);
  40.    CHAR c, *pszResp = Response;
  41.  
  42.    do {
  43.       if (Tcp->BytesReady () == TRUE) {
  44.          do {
  45.             if ((c = (CHAR)Tcp->ReadByte ()) != '\r') {
  46.                if (c != '\n') {
  47.                   *pszResp++ = c;
  48.                   if (++len >= MaxLen)
  49.                      c = '\r';
  50.                }
  51.             }
  52.          } while (Tcp->RxBytes > 0 && c != '\r');
  53.       }
  54. #if defined(__OS2__)
  55.       DosSleep (1L);
  56. #elif defined(__NT__)
  57.       Sleep (1L);
  58. #endif
  59.    } while (c != '\r' && Tcp->Carrier () == TRUE);
  60.    *pszResp = '\0';
  61. }
  62.  
  63. VOID TNNTP::DisplayXOver (ULONG XFrom, ULONG XTo)
  64. {
  65.    int lines;
  66.    PSZ p;
  67.    ULONG size;
  68.    time_t mtime;
  69.    struct tm ftm;
  70.  
  71.    if (XFrom == 0L)
  72.       XFrom = Msg->Lowest ();
  73.  
  74.    sprintf (Temp, "224 data follows\r\n");
  75.    Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  76.  
  77.    do {
  78.       if (Msg->Read (XFrom) == TRUE) {
  79.          sprintf (Temp, "%lu\t%s\t%s\t", Msg->Current, Msg->Subject, Msg->From);
  80.          Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  81.  
  82.          memset (&ftm, 0, sizeof (ftm));
  83.          ftm.tm_mday = Msg->Written.Day;
  84.          ftm.tm_mon = Msg->Written.Month - 1;
  85.          ftm.tm_year = Msg->Written.Year - 1900;
  86.          ftm.tm_hour = Msg->Written.Hour;
  87.          ftm.tm_min = Msg->Written.Minute;
  88.          ftm.tm_sec = Msg->Written.Second;
  89.          mtime = mktime (&ftm);
  90.          memcpy (&ftm, gmtime (&mtime), sizeof (ftm));
  91.          sprintf (Temp, "%d %s %d %d:%02d:%02d GMT\t", ftm.tm_mday, Months[ftm.tm_mon], ftm.tm_year, ftm.tm_hour, ftm.tm_min, ftm.tm_sec);
  92.          Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  93.  
  94.          sprintf (Temp, "<%lu@lorabbs.server>\t", Msg->Current);
  95.          Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  96.  
  97.          lines = 0;
  98.          size = 0L;
  99.          if ((p = (PSZ)Msg->Text.First ()) != NULL)
  100.             do {
  101.                lines++;
  102.                size += strlen (p) + 1;
  103.             } while ((p = (PSZ)Msg->Text.Next ()) != NULL);
  104.  
  105.          sprintf (Temp, "\t%lu\t%d\r\n", size, lines);
  106.          Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  107.       }
  108.       if (XFrom >= XTo)
  109.          break;
  110.    } while (Msg->Next (XFrom) == TRUE);
  111.  
  112.    sprintf (Temp, ".\r\n");
  113.    Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  114.    Tcp->UnbufferBytes ();
  115. }
  116.  
  117. VOID TNNTP::SendHeader (USHORT Termination)
  118. {
  119.    int lines;
  120.    time_t mtime;
  121.    struct tm ftm;
  122.  
  123.    sprintf (Temp, "From: (%s)\r\n", Msg->From);
  124.    Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  125.    sprintf (Temp, "Subject: %s\r\n", Msg->Subject);
  126.    Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  127.    memset (&ftm, 0, sizeof (ftm));
  128.    ftm.tm_mday = Msg->Written.Day;
  129.    ftm.tm_mon = Msg->Written.Month - 1;
  130.    ftm.tm_year = Msg->Written.Year - 1900;
  131.    ftm.tm_hour = Msg->Written.Hour;
  132.    ftm.tm_min = Msg->Written.Minute;
  133.    ftm.tm_sec = Msg->Written.Second;
  134.    mtime = mktime (&ftm);
  135.    memcpy (&ftm, gmtime (&mtime), sizeof (ftm));
  136.    sprintf (Temp, "Date: %d %s %d %d:%02d:%02d GMT\r\n", ftm.tm_mday, Months[ftm.tm_mon], ftm.tm_year, ftm.tm_hour, ftm.tm_min, ftm.tm_sec);
  137.    Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  138.  
  139.    lines = 0;
  140.    if (Msg->Text.First () != NULL)
  141.       do {
  142.          lines++;
  143.       } while (Msg->Text.Next () != NULL);
  144.    sprintf (Temp, "Lines: %d\r\n", lines);
  145.    Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  146.  
  147.    if (Termination == TRUE) {
  148.       sprintf (Temp, ".\r\n");
  149.       Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  150.       Tcp->UnbufferBytes ();
  151.    }
  152.    else
  153.       Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  154. }
  155.  
  156. VOID TNNTP::SendBody (VOID)
  157. {
  158.    CHAR *p;
  159.  
  160.    if ((p = (CHAR *)Msg->Text.First ()) != NULL)
  161.       do {
  162.          if (*p != 0x01 && strncmp (p, "SEEN-BY: ", 9)) {
  163.             if (!strcmp (p, "."))
  164.                Tcp->BufferBytes ((UCHAR *)"..", 2);
  165.             else
  166.                Tcp->BufferBytes ((UCHAR *)p, (USHORT)strlen (p));
  167.             Tcp->BufferBytes ((UCHAR *)"\r\n", 2);
  168.          }
  169.       } while ((p = (CHAR *)Msg->Text.Next ()) != NULL);
  170.  
  171.    sprintf (Temp, ".\r\n");
  172.    Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  173.    Tcp->UnbufferBytes ();
  174. }
  175.  
  176. VOID TNNTP::Run (VOID)
  177. {
  178.    USHORT EndRun = FALSE, Found;
  179.    CHAR *p;
  180.    ULONG Number, XFrom, XTo;
  181.    class TMsgData *Data;
  182.  
  183.    sprintf (Temp, "200 LoraBBS NNTP server ready (posting ok)\r\n");
  184.    Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  185.  
  186.    while (Tcp->Carrier () == TRUE && EndRun == FALSE) {
  187.       GetCommand ();
  188.       if (Log != NULL)
  189.          Log->Write (":NNTP: %s", Response);
  190.  
  191.       if ((p = strtok (Response, " ")) != NULL) {
  192.          if (!stricmp (p, "QUIT")) {
  193.             sprintf (Temp, "205 goodbye\r\n");
  194.             Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  195.             EndRun = TRUE;
  196.          }
  197.          else if (!stricmp (p, "LIST")) {
  198.             if ((p = strtok (NULL, " ")) == NULL) {
  199.                sprintf (Temp, "215 list of newsgroups follows\r\n");
  200.                Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  201.                if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  202.                   if (Data->First () == TRUE)
  203.                      do {
  204.                         if (Data->NewsGroup[0] != '\0' && Data->Storage != ST_USENET) {
  205.                            sprintf (Temp, "%s %05lu %05lu y\r\n", Data->NewsGroup, Data->LastMessage, Data->FirstMessage);
  206.                            Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  207.                         }
  208.                      } while (Data->Next () == TRUE);
  209.                   delete Data;
  210.                }
  211.                sprintf (Temp, ".\r\n");
  212.                Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  213.                Tcp->UnbufferBytes ();
  214.             }
  215.             else if (!stricmp (p, "overview.fmt")) {
  216.                sprintf (Temp, "215 Order of fields in overview database.\r\n");
  217.                Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  218.                sprintf (Temp, "Subject:\r\nFrom:\r\nDate:\r\nMessage-ID:\r\nReferences:\r\nBytes:\r\nLines:\r\nXref:full\r\n.\r\n");
  219.                Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  220.                Tcp->UnbufferBytes ();
  221.             }
  222.             else {
  223.                sprintf (Temp, "500 command not recognized.\r\n");
  224.                Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  225.             }
  226.          }
  227.          else if (!stricmp (p, "GROUP")) {
  228.             Found = FALSE;
  229.             Number = 0L;
  230.             if ((p = strtok (NULL, " ")) != NULL) {
  231.                if ((Data = new TMsgData (Cfg->SystemPath)) != NULL) {
  232.                   if (Data->First () == TRUE)
  233.                      do {
  234.                         if (Data->NewsGroup[0] != '\0' && Data->Storage != ST_USENET) {
  235.                            if (!stricmp (p, Data->NewsGroup)) {
  236.                               if (Msg != NULL)
  237.                                  delete Msg;
  238.                               Msg = NULL;
  239.                               if (Data->Storage == ST_JAM)
  240.                                  Msg = new JAM (Data->Path);
  241.                               else if (Data->Storage == ST_SQUISH)
  242.                                  Msg = new SQUISH (Data->Path);
  243.                               else if (Data->Storage == ST_FIDO)
  244.                                  Msg = new FIDOSDM (Data->Path);
  245.                               else if (Data->Storage == ST_ADEPT)
  246.                                  Msg = new ADEPT (Data->Path);
  247.                               if (Msg != NULL) {
  248.                                  sprintf (Temp, "211 %lu %lu %lu %s group selected\r\n", Msg->Number (), Msg->Lowest (), Msg->Highest (), Data->NewsGroup);
  249.                                  Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  250.                                  Found = TRUE;
  251.                               }
  252.                               break;
  253.                            }
  254.                         }
  255.                      } while (Data->Next () == TRUE);
  256.                   delete Data;
  257.                }
  258.             }
  259.             if (Found == FALSE) {
  260.                sprintf (Temp, "411 no such news group\r\n");
  261.                Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  262.             }
  263.          }
  264.          else if (!stricmp (p, "XOVER")) {
  265.             if (Msg == NULL) {
  266.                sprintf (Temp, "412 Not in a newsgroup\r\n");
  267.                Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  268.             }
  269.             else if ((p = strtok (NULL, "")) != NULL) {
  270.                XTo = 0L;
  271.                if ((p = strtok (p, " -")) != NULL)
  272.                   XFrom = atol (p);
  273.                if ((p = strtok (NULL, " -")) != NULL)
  274.                   XTo = atol (p);
  275.                else
  276.                   XTo = Msg->Highest ();
  277.                DisplayXOver (XFrom, XTo);
  278.             }
  279.             else
  280.                DisplayXOver (Number, Number);
  281.          }
  282.          else if (!stricmp (p, "STAT")) {
  283.             if ((p = strtok (NULL, " ")) != NULL && Msg != NULL) {
  284.                if (Msg->Read (atol (p)) == TRUE)
  285.                   sprintf (Temp, "223 %lu <%lu@lorabbs.server> article retrived - statistics only\r\n", Msg->Current, Msg->Current);
  286.                else
  287.                   sprintf (Temp, "423 no such article number in this group\r\n");
  288.             }
  289.             else {
  290.                if (Msg == NULL)
  291.                   sprintf (Temp, "412 no newsgroup has been selected\r\n");
  292.                else
  293.                   sprintf (Temp, "423 no such article number in this group\r\n");
  294.             }
  295.             Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  296.          }
  297.          else if (!stricmp (p, "ARTICLE")) {
  298.             if ((p = strtok (NULL, " ")) != NULL && Msg != NULL) {
  299.                if (Msg->Read (atol (p)) == TRUE) {
  300.                   sprintf (Temp, "220 %lu <%lu@lorabbs.server> article retrived - text follows\r\n", Msg->Current, Msg->Current);
  301.                   Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  302.  
  303.                   SendHeader (FALSE);
  304.                   SendBody ();
  305.                }
  306.                else {
  307.                   sprintf (Temp, "420 no such article number in this group\r\n");
  308.                   Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  309.                }
  310.             }
  311.             else {
  312.                if (Msg == NULL)
  313.                   sprintf (Temp, "412 no newsgroup has been selected\r\n");
  314.                else
  315.                   sprintf (Temp, "420 no such article number in this group\r\n");
  316.                Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  317.             }
  318.          }
  319.          else if (!stricmp (p, "NEXT")) {
  320.             if (Msg != NULL) {
  321.                Number = Msg->Current;
  322.                if (Msg->Next (Number) == TRUE) {
  323.                   Msg->Read (Number);
  324.                   sprintf (Temp, "223 %lu <%lu@lorabbs.server> article retrived - statistics only\r\n", Msg->Current, Msg->Current);
  325.                }
  326.                else
  327.                   sprintf (Temp, "423 no such article number in this group\r\n");
  328.                Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  329.             }
  330.          }
  331.          else if (!stricmp (p, "HEAD")) {
  332.             if (Msg != NULL) {
  333.                Found = TRUE;
  334.                if ((p = strtok (NULL, " ")) != NULL) {
  335.                   if (atoi (p) != Msg->Current)
  336.                      Found = Msg->Read ((USHORT)atoi (p));
  337.                }
  338.                if (Found == TRUE) {
  339.                   sprintf (Temp, "221 %lu <%lu@lorabbs.server> article retrived - head follows\r\n", Msg->Current, Msg->Current);
  340.                   Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  341.                   SendHeader (TRUE);
  342.                }
  343.                else {
  344.                   sprintf (Temp, "421 no such article number in this group\r\n");
  345.                   Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  346.                }
  347.             }
  348.          }
  349.          else if (!stricmp (p, "BODY")) {
  350.             if (Msg != NULL) {
  351.                if ((p = strtok (NULL, " ")) != NULL) {
  352.                   if (atoi (p) != Msg->Current)
  353.                      Msg->Read ((USHORT)atoi (p));
  354.                }
  355.                sprintf (Temp, "222 %lu <%lu@lorabbs.server> article retrived - body follows\r\n", Msg->Current, Msg->Current);
  356.                Tcp->BufferBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  357.                SendBody ();
  358.             }
  359.          }
  360.          else if (!stricmp (p, "NEWGROUPS")) {
  361.             sprintf (Temp, "231 list of new newsgroups follows\r\n.\r\n");
  362.             Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  363.          }
  364.          else if (!stricmp (p, "NEWNEWS")) {
  365.             sprintf (Temp, "230 list of new articles by message-id follows\r\n.\r\n");
  366.             Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  367.          }
  368. //         else if (!stricmp (p, "POST")) {
  369. //         }
  370.          else {
  371.             sprintf (Temp, "500 command not recognized.\r\n");
  372.             Tcp->SendBytes ((UCHAR *)Temp, (USHORT)strlen (Temp));
  373.          }
  374.       }
  375.  
  376. #if defined(__OS2__)
  377.       DosSleep (1L);
  378. #elif defined(__NT__)
  379.       Sleep (1L);
  380. #endif
  381.    }
  382. }
  383.  
  384.  
  385.