home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / PACKET.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  22KB  |  798 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. #define MAX_TEXT     2048
  23.  
  24. PSZ pktMonths[] = {
  25.    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  26.    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  27. };
  28.  
  29. typedef struct {
  30.    ULONG Number;
  31.    ULONG Position;
  32. } PKTINDEX;
  33.  
  34. PACKET::PACKET (void)
  35. {
  36.    Current = Id = 0L;
  37.    TotalMsgs = 0L;
  38.    Index.Clear ();
  39.    fp = NULL;
  40.    memset (Password, 0, sizeof (Password));
  41. }
  42.  
  43. PACKET::PACKET (PSZ pszName)
  44. {
  45.    Id = 0L;
  46.    TotalMsgs = 0L;
  47.    Index.Clear ();
  48.    fp = NULL;
  49.    memset (Password, 0, sizeof (Password));
  50.  
  51.    Open (pszName);
  52. }
  53.  
  54. PACKET::~PACKET (void)
  55. {
  56.    Close ();
  57. }
  58.  
  59. USHORT PACKET::Add (VOID)
  60. {
  61.    return (Add (Text));
  62. }
  63.  
  64. USHORT PACKET::Add (class TMsgBase *MsgBase)
  65. {
  66.    New ();
  67.  
  68.    strcpy (From, MsgBase->From);
  69.    strcpy (To, MsgBase->To);
  70.    strcpy (Subject, MsgBase->Subject);
  71.    strcpy (FromAddress, MsgBase->FromAddress);
  72.    strcpy (ToAddress, MsgBase->ToAddress);
  73.  
  74.    Written.Day = MsgBase->Written.Day;
  75.    Written.Month = MsgBase->Written.Month;
  76.    Written.Year = MsgBase->Written.Year;
  77.    Written.Hour = MsgBase->Written.Hour;
  78.    Written.Minute = MsgBase->Written.Minute;
  79.    Written.Second = MsgBase->Written.Second;
  80.  
  81.    Arrived.Day = MsgBase->Arrived.Day;
  82.    Arrived.Month = MsgBase->Arrived.Month;
  83.    Arrived.Year = MsgBase->Arrived.Year;
  84.    Arrived.Hour = MsgBase->Arrived.Hour;
  85.    Arrived.Minute = MsgBase->Arrived.Minute;
  86.    Arrived.Second = MsgBase->Arrived.Second;
  87.  
  88.    Crash = MsgBase->Crash;
  89.    Direct = MsgBase->Direct;
  90.    FileAttach = MsgBase->FileAttach;
  91.    FileRequest = MsgBase->FileRequest;
  92.    Hold = MsgBase->Hold;
  93.    Immediate = MsgBase->Immediate;
  94.    Intransit = MsgBase->Intransit;
  95.    KillSent = MsgBase->KillSent;
  96.    Local = MsgBase->Local;
  97.    Private = MsgBase->Private;
  98.    ReceiptRequest = MsgBase->ReceiptRequest;
  99.    Received = MsgBase->Received;
  100.    Sent = MsgBase->Sent;
  101.  
  102.    return (Add (MsgBase->Text));
  103. }
  104.  
  105. USHORT PACKET::Add (class TCollection &MsgText)
  106. {
  107.    int f1, f2, f3, f4, t1, t2, t3, t4;
  108.    USHORT RetVal = TRUE, AddedIntl = FALSE, IsEchomail = FALSE;
  109.    CHAR Temp[64], *pszText, *pszAddress, *p;
  110.    PKTINDEX pktIndex;
  111.    struct dosdate_t d_date;
  112.    struct dostime_t d_time;
  113.  
  114.    memset (&pktIndex, 0, sizeof (PKTINDEX));
  115.    fflush (fp);
  116.    fseek (fp, filelength (fileno (fp)) - 2L, SEEK_SET);
  117.  
  118.    pktIndex.Number = TotalMsgs + 1;
  119.    pktIndex.Position = ftell (fp);
  120.  
  121.    memset (&msgHdr, 0, sizeof (msgHdr));
  122.    msgHdr.Version = 2;
  123.  
  124.    f1 = f2 = f3 = f4 = 0;
  125.    pszAddress = FromAddress;
  126.    if (strchr (pszAddress, ':') != NULL) {
  127.       f1 = atoi (pszAddress);
  128.       pszAddress = strchr (pszAddress, ':') + 1;
  129.    }
  130.    if (strchr (pszAddress, '/') != NULL) {
  131.       f2 = (USHORT)atoi (pszAddress);
  132.       pszAddress = strchr (pszAddress, '/') + 1;
  133.    }
  134.    f3 = (USHORT)atoi (pszAddress);
  135.    if ((p = strchr (pszAddress, '@')) != NULL)
  136.       *p++ = '\0';
  137.    if (strchr (pszAddress, '.') != NULL) {
  138.       pszAddress = strchr (pszAddress, '.') + 1;
  139.       f4 = (USHORT)atoi (pszAddress);
  140.    }
  141.  
  142.    msgHdr.OrigNet = (USHORT)f2;
  143.    msgHdr.OrigNode = (USHORT)f3;
  144.  
  145.    t1 = t2 = t3 = t4 = 0;
  146.    pszAddress = ToAddress;
  147.    if (strchr (pszAddress, ':') != NULL) {
  148.       t1 = atoi (pszAddress);
  149.       pszAddress = strchr (pszAddress, ':') + 1;
  150.    }
  151.    if (strchr (pszAddress, '/') != NULL) {
  152.       t2 = (USHORT)atoi (pszAddress);
  153.       pszAddress = strchr (pszAddress, '/') + 1;
  154.    }
  155.    t3 = (USHORT)atoi (pszAddress);
  156.    if ((p = strchr (pszAddress, '@')) != NULL)
  157.       *p++ = '\0';
  158.    if (strchr (pszAddress, '.') != NULL) {
  159.       pszAddress = strchr (pszAddress, '.') + 1;
  160.       t4 = (USHORT)atoi (pszAddress);
  161.    }
  162.  
  163.    msgHdr.DestNet = (USHORT)t2;
  164.    msgHdr.DestNode = (USHORT)t3;
  165.  
  166.    if (Crash == TRUE)
  167.       msgHdr.Attrib |= MSGCRASH;
  168.    if (FileAttach == TRUE)
  169.       msgHdr.Attrib |= MSGFILE;
  170.    if (FileRequest == TRUE)
  171.       msgHdr.Attrib |= MSGFRQ;
  172.    if (Hold == TRUE)
  173.       msgHdr.Attrib |= MSGHOLD;
  174.    if (KillSent == TRUE)
  175.       msgHdr.Attrib |= MSGKILL;
  176.    if (Local == TRUE)
  177.       msgHdr.Attrib |= MSGLOCAL;
  178.    if (Private == TRUE)
  179.       msgHdr.Attrib |= MSGPRIVATE;
  180.    if (ReceiptRequest == TRUE)
  181.       msgHdr.Attrib |= MSGRRQ;
  182.    if (Received == TRUE)
  183.       msgHdr.Attrib |= MSGREAD;
  184.    if (Sent == TRUE)
  185.       msgHdr.Attrib |= MSGSENT;
  186.  
  187.    fwrite (&msgHdr, sizeof (MSGHDR), 1, fp);
  188.  
  189.    _dos_getdate (&d_date);
  190.    _dos_gettime (&d_time);
  191.  
  192.    if (Written.Day == 0)
  193.       Written.Day = d_date.day;
  194.    if (Written.Month == 0)
  195.       Written.Month = d_date.month;
  196.    if (Written.Year == 0)
  197.       Written.Year = (USHORT)d_date.year;
  198.    if (Written.Hour == 0)
  199.       Written.Hour = d_time.hour;
  200.    if (Written.Minute == 0)
  201.       Written.Minute = d_time.minute;
  202.    if (Written.Second == 0)
  203.       Written.Second = d_time.second;
  204.  
  205.    sprintf (Line, "%2d %3.3s %02d  %02d:%02d:%02d", Written.Day, pktMonths[Written.Month - 1], Written.Year % 100, Written.Hour, Written.Minute, 0);
  206.    fwrite (Line, strlen (Line) + 1, 1, fp);
  207.  
  208.    fwrite (To, strlen (To) + 1, 1, fp);
  209.    fwrite (From, strlen (From) + 1, 1, fp);
  210.    fwrite (Subject, strlen (Subject) + 1, 1, fp);
  211.  
  212.    if ((pszText = (PSZ)MsgText.First ()) != NULL) {
  213.       if (!strncmp (pszText, "AREA:", 5))
  214.          IsEchomail = TRUE;
  215.    }
  216.  
  217.    if (IsEchomail == FALSE) {
  218.       if (f1 != t1) {
  219.          sprintf (Temp, "\001INTL %d:%d/%d %d:%d/%d\r", t1, t2, t3, f1, f2, f3);
  220.          fwrite (Temp, strlen (Temp), 1, fp);
  221.          AddedIntl = TRUE;
  222.       }
  223.       if (f4 != 0) {
  224.          sprintf (Temp, "\001FMPT %u\r", f4);
  225.          fwrite (Temp, strlen (Temp), 1, fp);
  226.       }
  227.       if (t4 != 0) {
  228.          sprintf (Temp, "\001TOPT %u\r", t4);
  229.          fwrite (Temp, strlen (Temp), 1, fp);
  230.       }
  231.    }
  232.  
  233.    if ((pszText = (PSZ)MsgText.First ()) != NULL)
  234.       do {
  235.          if (IsEchomail == FALSE) {
  236.             if (!strncmp (pszText, "\001FMPT ", 6))
  237.                continue;
  238.             else if (!strncmp (pszText, "\001TOPT ", 6))
  239.                continue;
  240.             else if (!strncmp (pszText, "\001INTL ", 6) && AddedIntl == TRUE)
  241.                continue;
  242.          }
  243.          fwrite (pszText, strlen (pszText), 1, fp);
  244.          fwrite ("\r", 1, 1, fp);
  245.       } while ((pszText = (PSZ)MsgText.Next ()) != NULL);
  246.  
  247.    fwrite ("\000\000\000", 3, 1, fp);
  248.  
  249.    Index.Add (&pktIndex, sizeof (PKTINDEX));
  250.  
  251.    return (RetVal);
  252. }
  253.  
  254. VOID PACKET::Close (VOID)
  255. {
  256.    Id = 0L;
  257.    if (fp != NULL) {
  258.       fclose (fp);
  259.       fp = NULL;
  260.    }
  261.    Index.Clear ();
  262. }
  263.  
  264. USHORT PACKET::Delete (ULONG ulMsg)
  265. {
  266.    USHORT RetVal = FALSE;
  267.    PKTINDEX *pktIndex;
  268.  
  269.    if ((pktIndex = (PKTINDEX *)Index.First ()) != NULL)
  270.       do {
  271.          if (pktIndex->Number == ulMsg) {
  272.             Index.Remove ();
  273.             RetVal = TRUE;
  274.          }
  275.       } while ((pktIndex = (PKTINDEX *)Index.Next ()) != NULL);
  276.  
  277.    return (RetVal);
  278. }
  279.  
  280. USHORT PACKET::GetHWM (ULONG &ulMsg)
  281. {
  282.    ulMsg = 0L;
  283.  
  284.    return (FALSE);
  285. }
  286.  
  287. USHORT PACKET::GetLine (VOID)
  288. {
  289.    int c;
  290.    USHORT Readed = 0, MaybeEOM = FALSE;
  291.    PSZ Ptr = Line;
  292.  
  293.    if (LastRead == 13) {
  294.       MaybeEOM = TRUE;
  295.       if ((c = fgetc (fp)) >= ' ' || c == 0x01) {
  296.         *Ptr++ = (CHAR)c;
  297.         Readed++;
  298.       }
  299.       else if (c != 10)
  300.          ungetc (c, fp);
  301.    }
  302.  
  303.    do {
  304.       if (Readed < sizeof (Line) - 1) {
  305. //         if ((c = fgetc (fp)) >= ' ' || c == 0x01) {
  306.          if ((c = fgetc (fp)) != '\0') {
  307.             *Ptr++ = (CHAR)c;
  308.             Readed++;
  309.          }
  310.       }
  311.    } while (Readed < sizeof (Line) - 1 && c != '\0' && c != EOF);
  312. //   } while (Readed < sizeof (Line) - 1 && (c == 1 || c >= ' ') && c != EOF);
  313.  
  314.    *Ptr = '\0';
  315.    LastRead = (CHAR)c;
  316.  
  317.    if (MaybeEOM == TRUE && c == 0)
  318.       ungetc (c, fp);
  319.  
  320.    return ((Readed == 0 && c == EOF) ? FALSE : TRUE);
  321. }
  322.  
  323. ULONG PACKET::Highest (VOID)
  324. {
  325.    ULONG RetVal = 0L;
  326.    PKTINDEX *pktIndex;
  327.  
  328.    if ((pktIndex = (PKTINDEX *)Index.Last ()) != NULL)
  329.       RetVal = pktIndex->Number;
  330.  
  331.    return (RetVal);
  332. }
  333.  
  334. VOID PACKET::Kill (VOID)
  335. {
  336.    if (fp != NULL) {
  337.       fclose (fp);
  338.       fp = NULL;
  339.    }
  340.    unlink (FileName);
  341.    Index.Clear ();
  342. }
  343.  
  344. USHORT PACKET::Lock (ULONG ulTimeout)
  345. {
  346.    ulTimeout = ulTimeout;
  347.    return (TRUE);
  348. }
  349.  
  350. ULONG PACKET::Lowest (VOID)
  351. {
  352.    ULONG RetVal = 0L;
  353.    PKTINDEX *pktIndex;
  354.  
  355.    if ((pktIndex = (PKTINDEX *)Index.First ()) != NULL)
  356.       RetVal = pktIndex->Number;
  357.  
  358.    return (RetVal);
  359. }
  360.  
  361. ULONG PACKET::MsgnToUid (ULONG ulMsg)
  362. {
  363.    return (ulMsg);
  364. }
  365.  
  366. VOID PACKET::New (VOID)
  367. {
  368.    From[0] = To[0] = Subject[0] = '\0';
  369.    Crash = Direct = FileAttach = FileRequest = Hold = Immediate = FALSE;
  370.    Intransit = KillSent = Local = Private = ReceiptRequest = Received = FALSE;
  371.    Sent = 0;
  372.    memset (&Written, 0, sizeof (Written));
  373.    Written.Month = 1;
  374.    memset (&Arrived, 0, sizeof (Arrived));
  375.    Arrived.Month = 1;
  376.    Original = Reply = 0L;
  377.    Text.Clear ();
  378. }
  379.  
  380. USHORT PACKET::Next (ULONG &ulMsg)
  381. {
  382.    int c;
  383.    USHORT RetVal = FALSE;
  384.    PKTINDEX *pktIndex;
  385.  
  386.    if ((pktIndex = (PKTINDEX *)Index.Next ()) != NULL) {
  387.       ulMsg = pktIndex->Number;
  388.       if (ftell (fp) != pktIndex->Position)
  389.          fseek (fp, pktIndex->Position, SEEK_SET);
  390.       RetVal = TRUE;
  391.    }
  392.    else if (Index.Elements == 0) {
  393.       if ((c = fgetc (fp)) != EOF) {
  394.          if (c == 2) {
  395.             Current = ++ulMsg;
  396.             RetVal = TRUE;
  397.          }
  398.          ungetc (c, fp);
  399.       }
  400. /*
  401.       memset (&msgHdr, 0, sizeof (MSGHDR));
  402.       position = ftell (fp);
  403.       fread (&msgHdr, sizeof (MSGHDR), 1, fp);
  404.       fseek (fp, position, SEEK_SET);
  405.       if (msgHdr.Version == 2) {
  406.          Current = ++ulMsg;
  407.          RetVal = TRUE;
  408.       }
  409. */
  410.    }
  411.  
  412.    return (RetVal);
  413. }
  414.  
  415. ULONG PACKET::Number (VOID)
  416. {
  417.    return (TotalMsgs);
  418. }
  419.  
  420. USHORT PACKET::Open (PSZ pszName, USHORT doScan)
  421. {
  422.    int c;
  423.    USHORT RetVal = FALSE, i;
  424.    PSZ pszAddress;
  425.    ULONG Position;
  426.    PKTINDEX pktIndex;
  427.    struct dosdate_t date;
  428.    struct dostime_t time;
  429.  
  430.    TotalMsgs = 0L;
  431.    Index.Clear ();
  432.  
  433.    if (fp != NULL)
  434.       fclose (fp);
  435.  
  436.    if ((fp = fopen (pszName, "r+b")) == NULL)
  437.       fp = fopen (pszName, "w+b");
  438.    strcpy (FileName, pszName);
  439.  
  440.    if (fp != NULL) {
  441.       setvbuf (fp, NULL, _IOFBF, 4096L);
  442.       if (filelength (fileno (fp)) == 0L) {
  443.          memset (&pkt2Hdr, 0, sizeof (PKT2HDR));
  444.  
  445.          _dos_getdate (&date);
  446.          _dos_gettime (&time);
  447.  
  448.          pkt2Hdr.Version = 2;
  449.          pkt2Hdr.CWValidation = 0x100;
  450.          pkt2Hdr.Capability = 0x0001;
  451.          pkt2Hdr.ProductL = 0x4E;
  452.  
  453.          pkt2Hdr.Day = date.day;
  454.          pkt2Hdr.Month = (UCHAR)(date.month - 1);
  455.          pkt2Hdr.Year = (USHORT)date.year;
  456.          pkt2Hdr.Hour = time.hour;
  457.          pkt2Hdr.Minute = time.minute;
  458.          pkt2Hdr.Second = time.second;
  459.  
  460.          pszAddress = ToAddress;
  461.          if (strchr (pszAddress, ':') != NULL) {
  462.             pkt2Hdr.DestZone2 = pkt2Hdr.DestZone = (USHORT)atoi (pszAddress);
  463.             pszAddress = strchr (pszAddress, ':') + 1;
  464.          }
  465.          if (strchr (pszAddress, '/') != NULL) {
  466.             pkt2Hdr.DestNet = (USHORT)atoi (pszAddress);
  467.             pszAddress = strchr (pszAddress, '/') + 1;
  468.          }
  469.          pkt2Hdr.DestNode = (USHORT)atoi (pszAddress);
  470.          if (strchr (pszAddress, '.') != NULL) {
  471.             pszAddress = strchr (pszAddress, '.') + 1;
  472.             pkt2Hdr.DestPoint = (USHORT)atoi (pszAddress);
  473.          }
  474.  
  475.          pszAddress = FromAddress;
  476.          if (strchr (pszAddress, ':') != NULL) {
  477.             pkt2Hdr.OrigZone2 = pkt2Hdr.OrigZone = (USHORT)atoi (pszAddress);
  478.             pszAddress = strchr (pszAddress, ':') + 1;
  479.          }
  480.          if (strchr (pszAddress, '/') != NULL) {
  481.             pkt2Hdr.OrigNet = (USHORT)atoi (pszAddress);
  482.             pszAddress = strchr (pszAddress, '/') + 1;
  483.          }
  484.          pkt2Hdr.OrigNode = (USHORT)atoi (pszAddress);
  485.          if (strchr (pszAddress, '.') != NULL) {
  486.             pszAddress = strchr (pszAddress, '.') + 1;
  487.             pkt2Hdr.OrigPoint = (USHORT)atoi (pszAddress);
  488.          }
  489.  
  490.          memcpy (pkt2Hdr.Password, Password, 8);
  491.          fwrite (&pkt2Hdr, sizeof (PKT2HDR), 1, fp);
  492.  
  493.          memset (&msgHdr, 0, sizeof (MSGHDR));
  494.          fwrite (&msgHdr, 2, 1, fp);
  495.  
  496.          sprintf (FromAddress, "%d:%d/%d.%d", pkt2Hdr.OrigZone, pkt2Hdr.OrigNet, pkt2Hdr.OrigNode, pkt2Hdr.OrigPoint);
  497.          sprintf (ToAddress, "%d:%d/%d.%d", pkt2Hdr.DestZone, pkt2Hdr.DestNet, pkt2Hdr.DestNode, pkt2Hdr.DestPoint);
  498.  
  499.          fflush (fp);
  500.          fseek (fp, filelength (fileno (fp)) - sizeof (MSGHDR), SEEK_SET);
  501.          RetVal = TRUE;
  502.       }
  503.       else {
  504.          fread (&pkt2Hdr, sizeof (PKT2HDR), 1, fp);
  505.          if (pkt2Hdr.Version == 2) {
  506.             if (pkt2Hdr.Rate == 2) {
  507.                memcpy (&pkt22Hdr, &pkt2Hdr, sizeof (PKT22HDR));
  508.                sprintf (FromAddress, "%d:%d/%d.%d", pkt22Hdr.OrigZone, pkt22Hdr.OrigNet, pkt22Hdr.OrigNode, pkt22Hdr.OrigPoint);
  509.                if (pkt22Hdr.OrigDomain[0] != '\0') {
  510.                   strcat (FromAddress, "@");
  511.                   strcat (FromAddress, pkt22Hdr.OrigDomain);
  512.                }
  513.                sprintf (ToAddress, "%d:%d/%d.%d", pkt22Hdr.DestZone, pkt22Hdr.DestNet, pkt22Hdr.DestNode, pkt22Hdr.DestPoint);
  514.                if (pkt22Hdr.DestDomain[0] != '\0') {
  515.                   strcat (ToAddress, "@");
  516.                   strcat (ToAddress, pkt22Hdr.DestDomain);
  517.                }
  518.                RetVal = TRUE;
  519.             }
  520.             else {
  521.                swab ((char *)&pkt2Hdr.CWValidation, (char *)&i, 2);
  522.                pkt2Hdr.CWValidation = i;
  523.                if (pkt2Hdr.Capability != pkt2Hdr.CWValidation || !(pkt2Hdr.Capability & 0x0001)) {
  524.                   sprintf (FromAddress, "%d:%d/%d.%d", pkt2Hdr.OrigZone, pkt2Hdr.OrigNet, pkt2Hdr.OrigNode, 0);
  525.                   sprintf (ToAddress, "%d:%d/%d.%d", pkt2Hdr.DestZone, pkt2Hdr.DestNet, pkt2Hdr.DestNode, 0);
  526.                }
  527.                else {
  528.                   sprintf (FromAddress, "%d:%d/%d.%d", pkt2Hdr.OrigZone, pkt2Hdr.OrigNet, pkt2Hdr.OrigNode, pkt2Hdr.OrigPoint);
  529.                   sprintf (ToAddress, "%d:%d/%d.%d", pkt2Hdr.DestZone, pkt2Hdr.DestNet, pkt2Hdr.DestNode, pkt2Hdr.DestPoint);
  530.                }
  531.                memcpy (Password, pkt2Hdr.Password, sizeof (pkt2Hdr.Password));
  532.                Password[sizeof (pkt2Hdr.Password)] = '\0';
  533.                RetVal = TRUE;
  534.             }
  535.          }
  536.       }
  537.    }
  538.  
  539.    if (RetVal == TRUE) {
  540.       Date.Day = (UCHAR)pkt2Hdr.Day;
  541.       Date.Month = (UCHAR)(pkt2Hdr.Month + 1);
  542.       Date.Year = (USHORT)pkt2Hdr.Year;
  543.       Date.Hour = (UCHAR)pkt2Hdr.Hour;
  544.       Date.Minute = (UCHAR)pkt2Hdr.Minute;
  545.       Date.Second = (UCHAR)pkt2Hdr.Second;
  546.    }
  547.  
  548.    if (RetVal == TRUE && fp != NULL && doScan == TRUE) {
  549.       do {
  550.          memset (&pktIndex, 0, sizeof (PKTINDEX));
  551.          pktIndex.Position = ftell (fp);
  552.  
  553.          memset (&msgHdr, 0, sizeof (MSGHDR));
  554.          fread (&msgHdr, sizeof (MSGHDR), 1, fp);
  555.  
  556.          if (msgHdr.Version == 2) {
  557.             // Date and time
  558.             while ((c = fgetc (fp)) != '\0' && c != EOF)
  559.                ;
  560.             // To
  561.             while ((c = fgetc (fp)) != '\0' && c != EOF)
  562.                ;
  563.             // From
  564.             while ((c = fgetc (fp)) != '\0' && c != EOF)
  565.                ;
  566.             // Subject
  567.             while ((c = fgetc (fp)) != '\0' && c != EOF)
  568.                ;
  569.             // Text body
  570.             while ((c = fgetc (fp)) != '\0' && c != EOF)
  571.                ;
  572.  
  573.             TotalMsgs++;
  574.             pktIndex.Number = TotalMsgs;
  575.             Index.Add (&pktIndex, sizeof (PKTINDEX));
  576.          }
  577.          else if (msgHdr.Version != 0) {
  578.             while ((c = fgetc (fp)) != EOF && c != 0)
  579.                ;
  580.             if (c == 0) {
  581.                Position = ftell (fp);
  582.                memset (&msgHdr, 0, sizeof (MSGHDR));
  583.                fread (&msgHdr, sizeof (MSGHDR), 1, fp);
  584.                fseek (fp, Position, SEEK_SET);
  585.             }
  586.             else
  587.                msgHdr.Version = 0;
  588.          }
  589.       } while (msgHdr.Version != 0);
  590.    }
  591.  
  592.    return (RetVal);
  593. }
  594.  
  595. VOID PACKET::Pack (VOID)
  596. {
  597. }
  598.  
  599. USHORT PACKET::Previous (ULONG &ulMsg)
  600. {
  601.    USHORT RetVal = FALSE;
  602.    PKTINDEX *pktIndex;
  603.  
  604.    if ((pktIndex = (PKTINDEX *)Index.Previous ()) != NULL) {
  605.       ulMsg = pktIndex->Number;
  606.       if (ftell (fp) != pktIndex->Position)
  607.          fseek (fp, pktIndex->Position, SEEK_SET);
  608.       RetVal = TRUE;
  609.    }
  610.  
  611.    return (RetVal);
  612. }
  613.  
  614. USHORT PACKET::ReadHeader (ULONG ulMsg)
  615. {
  616.    int dd, yy, hr, mn, sc;
  617.    USHORT RetVal = FALSE, i;
  618.    CHAR mm[4];
  619.    PKTINDEX *pktIndex;
  620.    struct dosdate_t date;
  621.    struct dostime_t time;
  622.  
  623.    New ();
  624.  
  625.    if ((pktIndex = (PKTINDEX *)Index.First ()) != NULL) {
  626.       do {
  627.          if (pktIndex->Number == ulMsg) {
  628.             fseek (fp, pktIndex->Position, SEEK_SET);
  629.             break;
  630.          }
  631.       } while ((pktIndex = (PKTINDEX *)Index.Next ()) != NULL);
  632.    }
  633.  
  634.    memset (&msgHdr, 0, sizeof (MSGHDR));
  635.    fread (&msgHdr, sizeof (MSGHDR), 1, fp);
  636.  
  637.    if (msgHdr.Version == 2) {
  638.       RetVal = TRUE;
  639.  
  640.       if (pkt2Hdr.Capability != pkt2Hdr.CWValidation || !(pkt2Hdr.Capability & 0x0001)) {
  641.          sprintf (FromAddress, "%d:%d/%d.%d", pkt2Hdr.OrigZone, msgHdr.OrigNet, msgHdr.OrigNode, 0);
  642.          sprintf (ToAddress, "%d:%d/%d.%d", pkt2Hdr.DestZone, msgHdr.DestNet, msgHdr.DestNode, 0);
  643.       }
  644.       else {
  645.          sprintf (FromAddress, "%d:%d/%d.%d", pkt2Hdr.OrigZone, msgHdr.OrigNet, msgHdr.OrigNode, pkt2Hdr.OrigPoint);
  646.          sprintf (ToAddress, "%d:%d/%d.%d", pkt2Hdr.DestZone, msgHdr.DestNet, msgHdr.DestNode, pkt2Hdr.DestPoint);
  647.       }
  648.  
  649.       GetLine ();
  650.       sscanf (Line, "%2d %3s %2d  %2d:%2d:%02d", &dd, mm, &yy, &hr, &mn, &sc);
  651.  
  652.       Written.Day = (UCHAR)dd;
  653.       for (i = 0; i < 12; i++) {
  654.          if (!stricmp (pktMonths[i], mm)) {
  655.             Written.Month = (UCHAR)(i + 1);
  656.             break;
  657.          }
  658.       }
  659.       if (Written.Month < 1 || Written.Month > 12)
  660.          Written.Month = 1;
  661.       if ((Written.Year = (USHORT)(yy + 1900)) < 1990)
  662.          Written.Year += 100;
  663.       Written.Hour = (UCHAR)hr;
  664.       Written.Minute = (UCHAR)mn;
  665.       Written.Second = (UCHAR)sc;
  666.  
  667.       _dos_getdate (&date);
  668.       _dos_gettime (&time);
  669.  
  670.       Arrived.Day = date.day;
  671.       Arrived.Month = date.month;
  672.       Arrived.Year = (USHORT)date.year;
  673.       Arrived.Hour = time.hour;
  674.       Arrived.Minute = time.minute;
  675.       Arrived.Second = time.second;
  676.  
  677.       GetLine ();
  678.       strcpy (To, Line);
  679.       GetLine ();
  680.       strcpy (From, Line);
  681.       GetLine ();
  682.       strcpy (Subject, Line);
  683.    }
  684.  
  685.    return (RetVal);
  686. }
  687.  
  688. USHORT PACKET::Read (ULONG ulMsg, SHORT nWidth)
  689. {
  690.    return (Read (ulMsg, Text, nWidth));
  691. }
  692.  
  693. USHORT PACKET::Read (ULONG ulMsg, class TCollection &MsgText, SHORT nWidth)
  694. {
  695.    int c, f1, f2, f3, f4, t1, t2, t3, t4;
  696.    USHORT RetVal = FALSE;
  697.    SHORT nCol;
  698.  
  699.    MsgText.Clear ();
  700.  
  701.    if ((RetVal = ReadHeader (ulMsg)) == TRUE) {
  702.       Current = ulMsg;
  703.       pLine = szLine;
  704.       nCol = 0;
  705.  
  706.       f1 = pkt2Hdr.OrigZone;
  707.       f2 = msgHdr.OrigNet;
  708.       f3 = msgHdr.OrigNode;
  709.       f4 = pkt2Hdr.OrigPoint;
  710.  
  711.       t1 = pkt2Hdr.DestZone;
  712.       t2 = msgHdr.DestNet;
  713.       t3 = msgHdr.DestNode;
  714.       t4 = pkt2Hdr.DestPoint;
  715.  
  716.       sprintf (FromAddress, "%d:%d/%d.%d", f1, f2, f3, f4);
  717.       sprintf (ToAddress, "%d:%d/%d.%d", t1, t2, t3, t4);
  718.  
  719.       while ((c = fgetc (fp)) != 0 && c != EOF) {
  720.          if (c == '\r') {
  721.             *pLine = '\0';
  722.             if (!strncmp (szLine, "\001FMPT ", 6)) {
  723.                f4 = atoi (&szLine[6]);
  724.                sprintf (FromAddress, "%d:%d/%d.%d", f1, f2, f3, f4);
  725.             }
  726.             else if (!strncmp (szLine, "\001TOPT ", 6)) {
  727.                t4 = atoi (&szLine[6]);
  728.                sprintf (ToAddress, "%d:%d/%d.%d", t1, t2, t3, t4);
  729.             }
  730.             else if (!strncmp (szLine, "\001INTL ", 6)) {
  731.                sscanf (&szLine[6], "%d:%d/%d %d:%d/%d", &t1, &t2, &t3, &f1, &f2, &f3);
  732.                if (t2 != msgHdr.DestNet || t3 != msgHdr.DestNode) {
  733.                   sprintf (szLine, "\001INTL %d:%d/%d %d:%d/%d", t1, t2, t3, f1, f2, f3);
  734.                   MsgText.Add (szLine);
  735.                   t2 = msgHdr.DestNet;
  736.                   t3 = msgHdr.DestNode;
  737.                }
  738.                else {
  739.                   sprintf (FromAddress, "%d:%d/%d.%d", f1, f2, f3, f4);
  740.                   sprintf (ToAddress, "%d:%d/%d.%d", t1, t2, t3, t4);
  741.                }
  742.             }
  743.             else
  744.                MsgText.Add (szLine, (USHORT)(strlen (szLine) + 1));
  745.             pLine = szLine;
  746.             nCol = 0;
  747.          }
  748.          else if (c != '\n') {
  749.             *pLine++ = (CHAR)c;
  750.             nCol++;
  751.             if (nCol >= nWidth) {
  752.                *pLine = '\0';
  753.                while (nCol > 1 && *pLine != ' ') {
  754.                   nCol--;
  755.                   pLine--;
  756.                }
  757.                if (nCol > 0) {
  758.                   while (*pLine == ' ')
  759.                      pLine++;
  760.                   strcpy (szWrp, pLine);
  761.                }
  762.                *pLine = '\0';
  763.                MsgText.Add (szLine, (USHORT)(strlen (szLine) + 1));
  764.                strcpy (szLine, szWrp);
  765.                pLine = strchr (szLine, '\0');
  766.                nCol = (SHORT)strlen (szLine);
  767.             }
  768.          }
  769.       }
  770.    }
  771.  
  772.    return (RetVal);
  773. }
  774.  
  775. VOID PACKET::SetHWM (ULONG ulMsg)
  776. {
  777.    ulMsg = ulMsg;
  778. }
  779.  
  780. ULONG PACKET::UidToMsgn (ULONG ulMsg)
  781. {
  782.    return (ulMsg);
  783. }
  784.  
  785. VOID PACKET::UnLock (VOID)
  786. {
  787. }
  788.  
  789. USHORT PACKET::WriteHeader (ULONG ulMsg)
  790. {
  791.    USHORT RetVal = FALSE;
  792.  
  793.    ulMsg = ulMsg;
  794.  
  795.    return (RetVal);
  796. }
  797.  
  798.