home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / ADEPT.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  20KB  |  711 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. PSZ adeptMonths[] = {
  23.    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  24.    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  25. };
  26.  
  27. ADEPT::ADEPT (void)
  28. {
  29.    fdTxt = fdHdr = fdIdx = -1;
  30.    Current = Id = 0L;
  31. }
  32.  
  33. ADEPT::ADEPT (PSZ pszName)
  34. {
  35.    fdTxt = fdHdr = fdIdx = -1;
  36.    Id = 0L;
  37.  
  38.    Open (pszName);
  39. }
  40.  
  41. ADEPT::~ADEPT (void)
  42. {
  43.    Close ();
  44. }
  45.  
  46. USHORT ADEPT::Add (VOID)
  47. {
  48.    return (Add (Text));
  49. }
  50.  
  51. USHORT ADEPT::Add (class TMsgBase *MsgBase)
  52. {
  53.    New ();
  54.  
  55.    strcpy (From, MsgBase->From);
  56.    strcpy (To, MsgBase->To);
  57.    strcpy (Subject, MsgBase->Subject);
  58.    strcpy (FromAddress, MsgBase->FromAddress);
  59.    strcpy (ToAddress, MsgBase->ToAddress);
  60.  
  61.    Written.Day = MsgBase->Written.Day;
  62.    Written.Month = MsgBase->Written.Month;
  63.    Written.Year = MsgBase->Written.Year;
  64.    Written.Hour = MsgBase->Written.Hour;
  65.    Written.Minute = MsgBase->Written.Minute;
  66.    Written.Second = MsgBase->Written.Second;
  67.  
  68.    Arrived.Day = MsgBase->Arrived.Day;
  69.    Arrived.Month = MsgBase->Arrived.Month;
  70.    Arrived.Year = MsgBase->Arrived.Year;
  71.    Arrived.Hour = MsgBase->Arrived.Hour;
  72.    Arrived.Minute = MsgBase->Arrived.Minute;
  73.    Arrived.Second = MsgBase->Arrived.Second;
  74.  
  75.    Crash = MsgBase->Crash;
  76.    Direct = MsgBase->Direct;
  77.    FileAttach = MsgBase->FileAttach;
  78.    FileRequest = MsgBase->FileRequest;
  79.    Hold = MsgBase->Hold;
  80.    Immediate = MsgBase->Immediate;
  81.    Intransit = MsgBase->Intransit;
  82.    KillSent = MsgBase->KillSent;
  83.    Local = MsgBase->Local;
  84.    Private = MsgBase->Private;
  85.    ReceiptRequest = MsgBase->ReceiptRequest;
  86.    Received = MsgBase->Received;
  87.    Sent = MsgBase->Sent;
  88.  
  89.    return (Add (MsgBase->Text));
  90. }
  91.  
  92. USHORT ADEPT::Add (class TCollection &MsgText)
  93. {
  94.    USHORT RetVal = FALSE;
  95.    CHAR *Text, *p, *pszAddress;
  96.    ADEPTINDEXES Index;
  97.  
  98.    if (fdHdr != -1 && fdIdx != -1 && fdTxt != -1) {
  99.       RetVal = TRUE;
  100.  
  101.       memset (&Index, 0, sizeof (Index));
  102.       Text = To;
  103.       while (*Text)
  104.          Index.to += (UCHAR)*Text++;
  105.       Text = From;
  106.       while (*Text)
  107.          Index.from += (UCHAR)*Text++;
  108.       Text = Subject;
  109.       while (*Text)
  110.          Index.subj += (UCHAR)*Text++;
  111.  
  112.       Index.msgidserialno = Highest () + 1L;
  113.       lseek (fdIdx, 0L, SEEK_END);
  114.       write (fdIdx, &Index, sizeof (Index));
  115.  
  116.       memset (&Data, 0, sizeof (Data));
  117.       Data.StructLen = sizeof (Data);
  118.       strcpy (Data.from, From);
  119.       strcpy (Data.to, To);
  120.       strcpy (Data.subj, Subject);
  121.       Data.msgnum = Index.msgidserialno;
  122.  
  123.       pszAddress = FromAddress;
  124.       if (strchr (pszAddress, ':') != NULL) {
  125.          Data.o_zone = (USHORT)atoi (pszAddress);
  126.          pszAddress = strchr (pszAddress, ':') + 1;
  127.       }
  128.       if (strchr (pszAddress, '/') != NULL) {
  129.          Data.o_net = (USHORT)atoi (pszAddress);
  130.          pszAddress = strchr (pszAddress, '/') + 1;
  131.       }
  132.       Data.o_node = (USHORT)atoi (pszAddress);
  133.       if ((p = strchr (pszAddress, '@')) != NULL)
  134.          *p++ = '\0';
  135.       if (strchr (pszAddress, '.') != NULL) {
  136.          pszAddress = strchr (pszAddress, '.') + 1;
  137.          Data.o_point = (USHORT)atoi (pszAddress);
  138.       }
  139.  
  140.       pszAddress = ToAddress;
  141.       if (strchr (pszAddress, ':') != NULL) {
  142.          Data.d_zone = (USHORT)atoi (pszAddress);
  143.          pszAddress = strchr (pszAddress, ':') + 1;
  144.       }
  145.       if (strchr (pszAddress, '/') != NULL) {
  146.          Data.d_net = (USHORT)atoi (pszAddress);
  147.          pszAddress = strchr (pszAddress, '/') + 1;
  148.       }
  149.       Data.d_node = (USHORT)atoi (pszAddress);
  150.       if ((p = strchr (pszAddress, '@')) != NULL)
  151.          *p++ = '\0';
  152.       if (strchr (pszAddress, '.') != NULL) {
  153.          pszAddress = strchr (pszAddress, '.') + 1;
  154.          Data.d_point = (USHORT)atoi (pszAddress);
  155.       }
  156.  
  157.       if (Written.Month == 0)
  158.          Written.Month = 1;
  159.       sprintf (Data.date, "%2d %3.3s %02d  %02d:%02d:%02d", Written.Day, adeptMonths[Written.Month - 1], Written.Year % 100, Written.Hour, Written.Minute, Written.Second);
  160.  
  161.       Data.fflags |= (Sent == TRUE) ? MSGSENT : 0;
  162.       Data.fflags |= (Crash == TRUE) ? MSGCRASH : 0;
  163.       Data.fflags |= (Received == TRUE) ? MSGREAD : 0;
  164.       Data.fflags |= (Private == TRUE) ? MSGPRIVATE : 0;
  165.       Data.fflags |= (KillSent == TRUE) ? MSGKILL : 0;
  166.       Data.fflags |= (Local == TRUE) ? MSGLOCAL : 0;
  167.       Data.fflags |= (FileRequest == TRUE) ? MSGFRQ : 0;
  168.  
  169.       lseek (fdTxt, 0L, SEEK_END);
  170.       Data.start = tell (fdTxt);
  171.  
  172.       if ((Text = (PSZ)MsgText.First ()) != NULL)
  173.          do {
  174.             Data.length += strlen (Text) + 1;
  175.             write (fdTxt, Text, strlen (Text));
  176.             write (fdTxt, "\r", 1);
  177.          } while ((Text = (PSZ)MsgText.Next ()) != NULL);
  178.  
  179.       lseek (fdHdr, 0L, SEEK_END);
  180.       write (fdHdr, &Data, sizeof (Data));
  181.  
  182.       TotalMsgs++;
  183.    }
  184.  
  185.    return (RetVal);
  186. }
  187.  
  188. VOID ADEPT::Close (VOID)
  189. {
  190.    if (fdIdx != -1)
  191.       close (fdIdx);
  192.    if (fdHdr != -1)
  193.       close (fdHdr);
  194.    if (fdTxt != -1)
  195.       close (fdTxt);
  196.  
  197.    fdTxt = fdHdr = fdIdx = -1;
  198.    Id = 0L;
  199. }
  200.  
  201. USHORT ADEPT::Delete (ULONG ulMsg)
  202. {
  203.    USHORT RetVal = FALSE;
  204.  
  205.    if (ReadHeader (ulMsg) == TRUE) {
  206.       Data.xflags |= MSGDELETED;
  207.       lseek (fdHdr, tell (fdHdr) - sizeof (Data), SEEK_SET);
  208.       write (fdHdr, &Data, sizeof (Data));
  209.       TotalMsgs--;
  210.       RetVal = TRUE;
  211.    }
  212.  
  213.    return (RetVal);
  214. }
  215.  
  216. USHORT ADEPT::GetHWM (ULONG &ulMsg)
  217. {
  218.    ulMsg = 0L;
  219.  
  220.    return (FALSE);
  221. }
  222.  
  223. ULONG ADEPT::Highest (VOID)
  224. {
  225.    ULONG RetVal = 0L, Position;
  226.    LONG Current;
  227.  
  228.    if (filelength (fdHdr) >= sizeof (ADEPTDATA)) {
  229.       Position = tell (fdHdr);
  230.       Current = filelength (fdHdr) - sizeof (ADEPTDATA);
  231.       do {
  232.          lseek (fdHdr, Current, SEEK_SET);
  233.          if (read (fdHdr, &Data, sizeof (Data)) == sizeof (Data)) {
  234.             if (!(Data.xflags & MSGDELETED))
  235.                RetVal = Data.msgnum;
  236.          }
  237.          Current -= sizeof (ADEPTDATA);
  238.       } while (RetVal == 0L && Current > 0L);
  239.       lseek (fdHdr, Position, SEEK_SET);
  240.    }
  241.  
  242.    return (RetVal);
  243. }
  244.  
  245. USHORT ADEPT::Lock (ULONG ulTimeout)
  246. {
  247.    ulTimeout = ulTimeout;
  248.    return (TRUE);
  249. }
  250.  
  251. ULONG ADEPT::Lowest (VOID)
  252. {
  253.    ULONG RetVal = 0L, Position;
  254.  
  255.    Position = tell (fdHdr);
  256.    lseek (fdHdr, 0L, SEEK_SET);
  257.    while (read (fdHdr, &Data, sizeof (Data)) == sizeof (Data)) {
  258.       if (!(Data.xflags & MSGDELETED)) {
  259.          RetVal = Data.msgnum;
  260.          break;
  261.       }
  262.    }
  263.    lseek (fdHdr, Position, SEEK_SET);
  264.  
  265.    return (RetVal);
  266. }
  267.  
  268. ULONG ADEPT::MsgnToUid (ULONG ulMsg)
  269. {
  270.    return (ulMsg);
  271. }
  272.  
  273. VOID ADEPT::New (VOID)
  274. {
  275.    From[0] = To[0] = Subject[0] = '\0';
  276.    Crash = Direct = FileAttach = FileRequest = Hold = Immediate = FALSE;
  277.    Intransit = KillSent = Local = Private = ReceiptRequest = Received = FALSE;
  278.    Sent = 0;
  279.    memset (&Written, 0, sizeof (Written));
  280.    memset (&Arrived, 0, sizeof (Arrived));
  281.    FromAddress[0] = ToAddress[0] = '\0';
  282.    Original = Reply = 0L;
  283.    Text.Clear ();
  284. }
  285.  
  286. USHORT ADEPT::Next (ULONG &ulMsg)
  287. {
  288.    USHORT RetVal = FALSE, MayBeNext;
  289.  
  290.    if (tell (fdHdr) >= sizeof (Data)) {
  291.       lseek (fdHdr, tell (fdHdr) - sizeof (Data), SEEK_SET);
  292.       read (fdHdr, &Data, sizeof (Data));
  293.       if (Data.msgnum == ulMsg) {
  294.          while (read (fdHdr, &Data, sizeof (Data)) == sizeof (Data)) {
  295.             if (!(Data.xflags & MSGDELETED)) {
  296.                RetVal = TRUE;
  297.                ulMsg = Data.msgnum;
  298.                break;
  299.             }
  300.          }
  301.       }
  302.    }
  303.  
  304.    if (RetVal == FALSE) {
  305.       lseek (fdHdr, 0L, SEEK_SET);
  306.       MayBeNext = FALSE;
  307.       while (read (fdHdr, &Data, sizeof (Data)) == sizeof (Data)) {
  308.          if (!(Data.xflags & MSGDELETED)) {
  309.             if (MayBeNext == TRUE) {
  310.                RetVal = TRUE;
  311.                ulMsg = Data.msgnum;
  312.                break;
  313.             }
  314.             else if (ulMsg == Data.msgnum)
  315.                MayBeNext = TRUE;
  316.             else if (ulMsg < Data.msgnum) {
  317.                RetVal = TRUE;
  318.                ulMsg = Data.msgnum;
  319.                break;
  320.             }
  321.          }
  322.       }
  323.    }
  324.  
  325.    Id = ulMsg;
  326.  
  327.    return (RetVal);
  328. }
  329.  
  330. ULONG ADEPT::Number (VOID)
  331. {
  332.    return (TotalMsgs);
  333. }
  334.  
  335. USHORT ADEPT::Open (PSZ pszName)
  336. {
  337.    USHORT RetVal = FALSE;
  338.    CHAR File[128];
  339.  
  340.    TotalMsgs = 0L;
  341.  
  342.    sprintf (File, "%s.Data", pszName);
  343.    if ((fdHdr = sopen (File, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE)) != -1) {
  344.       sprintf (File, "%s.Index", pszName);
  345.       fdIdx = sopen (File, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  346.       sprintf (File, "%s.Text", pszName);
  347.       fdTxt = sopen (File, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  348.  
  349.       while (read (fdHdr, &Data, sizeof (Data)) == sizeof (Data)) {
  350.          if (!(Data.xflags & MSGDELETED))
  351.             TotalMsgs++;
  352.       }
  353.  
  354.       strcpy (BaseName, pszName);
  355.       RetVal = TRUE;
  356.    }
  357.  
  358.    Current = Id = 0L;
  359.  
  360.    return (RetVal);
  361. }
  362.  
  363. VOID ADEPT::Pack (VOID)
  364. {
  365.    int fdHdrNew, fdTxtNew, fdIdxNew;
  366.    USHORT Max;
  367.    CHAR OldName[128], NewName[128], *Text;
  368.    ADEPTINDEXES Index;
  369.  
  370.    sprintf (NewName, "%s.NewData", BaseName);
  371.    fdHdrNew = sopen (NewName, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE);
  372.    sprintf (NewName, "%s.NewIndex", BaseName);
  373.    fdIdxNew = sopen (NewName, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE);
  374.    sprintf (NewName, "%s.NewText", BaseName);
  375.    fdTxtNew = sopen (NewName, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, SH_DENYNO, S_IREAD|S_IWRITE);
  376.    Text = (CHAR *)malloc (2048);
  377.  
  378.    if (fdIdxNew != -1 && fdHdrNew != -1 && fdTxtNew != -1 && Text != NULL) {
  379.       lseek (fdHdr, 0L, SEEK_SET);
  380.       lseek (fdIdx, 0L, SEEK_SET);
  381.       while (read (fdHdr, &Data, sizeof (Data)) == sizeof (Data)) {
  382.          read (fdIdx, &Index, sizeof (Index));
  383.          if (!(Data.xflags & MSGDELETED)) {
  384.             lseek (fdTxt, Data.start, SEEK_SET);
  385.             Data.start = tell (fdTxtNew);
  386.             write (fdHdrNew, &Data, sizeof (Data));
  387.             while (Data.length > 0) {
  388.                if ((Max = 2048) > Data.length)
  389.                   Max = (USHORT)Data.length;
  390.                read (fdTxt, Text, Max);
  391.                write (fdTxtNew, Text, Max);
  392.                Data.length -= Max;
  393.             }
  394.             write (fdIdxNew, &Index, sizeof (Index));
  395.          }
  396.       }
  397.  
  398.       free (Text);
  399.       Text = NULL;
  400.       close (fdHdrNew);
  401.       close (fdTxtNew);
  402.       close (fdIdxNew);
  403.       fdHdrNew = fdIdxNew = fdTxtNew = -1;
  404.  
  405.       close (fdHdr);
  406.       close (fdTxt);
  407.       close (fdIdx);
  408.  
  409.       sprintf (NewName, "%s.NewData", BaseName);
  410.       sprintf (OldName, "%s.Data", BaseName);
  411.       unlink (OldName);
  412.       rename (NewName, OldName);
  413.       fdHdr = sopen (OldName, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  414.  
  415.       sprintf (NewName, "%s.NewIndex", BaseName);
  416.       sprintf (OldName, "%s.Index", BaseName);
  417.       unlink (OldName);
  418.       rename (NewName, OldName);
  419.       fdIdx = sopen (OldName, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  420.  
  421.       sprintf (NewName, "%s.NewText", BaseName);
  422.       sprintf (OldName, "%s.Text", BaseName);
  423.       unlink (OldName);
  424.       rename (NewName, OldName);
  425.       fdTxt = sopen (OldName, O_RDWR|O_BINARY|O_CREAT, SH_DENYNO, S_IREAD|S_IWRITE);
  426.    }
  427.  
  428.    if (Text != NULL)
  429.       free (Text);
  430.    if (fdHdrNew != -1)
  431.       close (fdHdrNew);
  432.    if (fdTxtNew != -1)
  433.       close (fdTxtNew);
  434.    if (fdIdxNew != -1)
  435.       close (fdIdxNew);
  436.  
  437.    sprintf (NewName, "%s.NewData", BaseName);
  438.    unlink (NewName);
  439.    sprintf (NewName, "%s.NewText", BaseName);
  440.    unlink (NewName);
  441.    sprintf (NewName, "%s.NewIndex", BaseName);
  442.    unlink (NewName);
  443. }
  444.  
  445. USHORT ADEPT::Previous (ULONG &ulMsg)
  446. {
  447.    USHORT RetVal = FALSE, MayBeNext;
  448.  
  449.    if (tell (fdHdr) >= sizeof (Data) * 2) {
  450.       lseek (fdHdr, tell (fdHdr) - sizeof (Data), SEEK_SET);
  451.       read (fdHdr, &Data, sizeof (Data));
  452.       if (Data.msgnum == ulMsg) {
  453.          while (tell (fdHdr) >= sizeof (Data) * 2) {
  454.             lseek (fdHdr, tell (fdHdr) - sizeof (Data) * 2, SEEK_SET);
  455.             read (fdHdr, &Data, sizeof (Data));
  456.             if (!(Data.xflags & MSGDELETED)) {
  457.                RetVal = TRUE;
  458.                ulMsg = Data.msgnum;
  459.                break;
  460.             }
  461.          }
  462.       }
  463.  
  464.       if (RetVal == FALSE) {
  465.          lseek (fdHdr, filelength (fdHdr) - sizeof (Data), SEEK_SET);
  466.          MayBeNext = FALSE;
  467.  
  468.          read (fdHdr, &Data, sizeof (Data));
  469.          if (!(Data.xflags & MSGDELETED)) {
  470.             if (ulMsg == Data.msgnum)
  471.                MayBeNext = TRUE;
  472.             else if (ulMsg > Data.msgnum) {
  473.                RetVal = TRUE;
  474.                ulMsg = Data.msgnum;
  475.             }
  476.          }
  477.  
  478.          while (tell (fdHdr) >= sizeof (Data) * 2) {
  479.             lseek (fdHdr, tell (fdHdr) - sizeof (Data) * 2, SEEK_SET);
  480.             read (fdHdr, &Data, sizeof (Data));
  481.             if (!(Data.xflags & MSGDELETED)) {
  482.                if (MayBeNext == TRUE) {
  483.                   RetVal = TRUE;
  484.                   ulMsg = Data.msgnum;
  485.                   break;
  486.                }
  487.                else if (ulMsg == Data.msgnum)
  488.                   MayBeNext = TRUE;
  489.                else if (ulMsg > Data.msgnum) {
  490.                   RetVal = TRUE;
  491.                   ulMsg = Data.msgnum;
  492.                   break;
  493.                }
  494.             }
  495.          }
  496.       }
  497.    }
  498.  
  499.    Id = ulMsg;
  500.  
  501.    return (RetVal);
  502. }
  503.  
  504. USHORT ADEPT::ReadHeader (ULONG ulMsg)
  505. {
  506.    int dd, yy, hr, mn, sc;
  507.    USHORT RetVal = FALSE, i;
  508.    CHAR mm[8];
  509.  
  510.    New ();
  511.  
  512.    if (Id == ulMsg) {
  513.       lseek (fdHdr, tell (fdHdr) - sizeof (ADEPTDATA), SEEK_SET);
  514.       if (read (fdHdr, &Data, sizeof (Data)) == sizeof (Data)) {
  515.          if (Data.msgnum == ulMsg)
  516.             RetVal = TRUE;
  517.       }
  518.    }
  519.  
  520.    if (RetVal == FALSE) {
  521.       lseek (fdHdr, 0L, SEEK_SET);
  522.       while (read (fdHdr, &Data, sizeof (Data)) == sizeof (Data)) {
  523.          if (!(Data.xflags & MSGDELETED)) {
  524.             if (ulMsg == Data.msgnum) {
  525.                RetVal = TRUE;
  526.                break;
  527.             }
  528.          }
  529.       }
  530.    }
  531.  
  532.    if (RetVal == TRUE) {
  533.       Current = Id = ulMsg;
  534.       strcpy (From, Data.from);
  535.       strcpy (To, Data.to);
  536.       strcpy (Subject, Data.subj);
  537.  
  538.       sprintf (FromAddress, "%u:%u/%u.%u", Data.o_zone, Data.o_net, Data.o_node, Data.o_point);
  539.       sprintf (ToAddress, "%u:%u/%u.%u", Data.d_zone, Data.d_net, Data.d_node, Data.d_point);
  540.  
  541.       sscanf (Data.date, "%2d %3s %2d  %2d:%2d:%02d", &dd, mm, &yy, &hr, &mn, &sc);
  542.  
  543.       Arrived.Day = Written.Day = (UCHAR)dd;
  544.       for (i = 0; i < 12; i++) {
  545.          if (!stricmp (adeptMonths[i], mm)) {
  546.             Written.Month = (UCHAR)(i + 1);
  547.             break;
  548.          }
  549.       }
  550.       if (Written.Month < 1 || Written.Month > 12)
  551.          Written.Month = 1;
  552.       Arrived.Month = Written.Month;
  553.       if ((Written.Year = (USHORT)(yy + 1900)) < 1980)
  554.          Written.Year += 100;
  555.       Arrived.Year = Written.Year;
  556.       Arrived.Hour = Written.Hour = (UCHAR)hr;
  557.       Arrived.Minute = Written.Minute = (UCHAR)mn;
  558.       Arrived.Second = Written.Second = (UCHAR)sc;
  559.  
  560.       Sent = (UCHAR)((Data.fflags & MSGSENT) ? TRUE : FALSE);
  561.       Crash = (UCHAR)((Data.fflags & MSGCRASH) ? TRUE : FALSE);
  562.       Received = (UCHAR)((Data.fflags & MSGREAD) ? TRUE : FALSE);
  563.       Private = (UCHAR)((Data.fflags & MSGPRIVATE) ? TRUE : FALSE);
  564.       KillSent = (UCHAR)((Data.fflags & MSGKILL) ? TRUE : FALSE);
  565.       Local = (UCHAR)((Data.fflags & MSGLOCAL) ? TRUE : FALSE);
  566.       FileRequest = (UCHAR)((Data.fflags & MSGFRQ) ? TRUE : FALSE);
  567.    }
  568.  
  569.    return (RetVal);
  570. }
  571.  
  572. USHORT ADEPT::Read (ULONG ulMsg, SHORT nWidth)
  573. {
  574.    return (Read (ulMsg, Text, nWidth));
  575. }
  576.  
  577. USHORT ADEPT::Read (ULONG ulMsg, class TCollection &MsgText, SHORT nWidth)
  578. {
  579.    USHORT RetVal = FALSE, SkipNext;
  580.    SHORT i, nReaded, nCol, nRead;
  581.    LONG TxtLen;
  582.  
  583.    MsgText.Clear ();
  584.  
  585.    if (ReadHeader (ulMsg) == TRUE) {
  586.       lseek (fdTxt, Data.start, SEEK_SET);
  587.  
  588.       TxtLen = Data.length;
  589.       pLine = szLine;
  590.       nCol = 0;
  591.       SkipNext = FALSE;
  592.  
  593.       if (TxtLen > 0L)
  594.          do {
  595.             if ((nRead = sizeof (szBuff)) > TxtLen)
  596.                nRead = (SHORT)TxtLen;
  597.  
  598.             nReaded = (SHORT)read (fdTxt, szBuff, nRead);
  599.  
  600.             for (i = 0, pBuff = szBuff; i < nReaded; i++, pBuff++) {
  601.                if (*pBuff == '\r') {
  602.                   *pLine = '\0';
  603.                   if (pLine > szLine && SkipNext == TRUE) {
  604.                      pLine--;
  605.                      while (pLine > szLine && *pLine == ' ')
  606.                         *pLine-- = '\0';
  607.                      if (pLine > szLine)
  608.                         MsgText.Add (szLine);
  609.                   }
  610.                   else if (SkipNext == FALSE)
  611.                      MsgText.Add (szLine);
  612.                   SkipNext = FALSE;
  613.                   pLine = szLine;
  614.                   nCol = 0;
  615.                }
  616.                else if (*pBuff != '\n') {
  617.                   *pLine++ = *pBuff;
  618.                   nCol++;
  619.                   if (nCol >= nWidth) {
  620.                      *pLine = '\0';
  621.                      if (strchr (szLine, ' ') != NULL) {
  622.                         while (nCol > 1 && *pLine != ' ') {
  623.                            nCol--;
  624.                            pLine--;
  625.                         }
  626.                         if (nCol > 0) {
  627.                            while (*pLine == ' ')
  628.                               pLine++;
  629.                            strcpy (szWrp, pLine);
  630.                         }
  631.                         *pLine = '\0';
  632.                      }
  633.                      else
  634.                         szWrp[0] = '\0';
  635.                      MsgText.Add (szLine);
  636.                      strcpy (szLine, szWrp);
  637.                      pLine = strchr (szLine, '\0');
  638.                      nCol = (SHORT)strlen (szLine);
  639.                      SkipNext = TRUE;
  640.                   }
  641.                }
  642.             }
  643.  
  644.             TxtLen -= nReaded;
  645.          } while (TxtLen > 0);
  646.  
  647.       RetVal = TRUE;
  648.    }
  649.  
  650.    return (RetVal);
  651. }
  652.  
  653. VOID ADEPT::SetHWM (ULONG ulMsg)
  654. {
  655.    ulMsg = ulMsg;
  656. }
  657.  
  658. ULONG ADEPT::UidToMsgn (ULONG ulMsg)
  659. {
  660.    return (ulMsg);
  661. }
  662.  
  663. VOID ADEPT::UnLock (VOID)
  664. {
  665. }
  666.  
  667. USHORT ADEPT::WriteHeader (ULONG ulMsg)
  668. {
  669.    USHORT RetVal = FALSE;
  670.  
  671.    if (Id == ulMsg) {
  672.       lseek (fdHdr, tell (fdHdr) - sizeof (ADEPTDATA), SEEK_SET);
  673.       if (read (fdHdr, &Data, sizeof (Data)) == sizeof (Data)) {
  674.          if (Data.msgnum == ulMsg)
  675.             RetVal = TRUE;
  676.       }
  677.    }
  678.  
  679.    if (RetVal == FALSE) {
  680.       lseek (fdHdr, 0L, SEEK_SET);
  681.       while (read (fdHdr, &Data, sizeof (Data)) == sizeof (Data)) {
  682.          if (!(Data.xflags & MSGDELETED)) {
  683.             if (ulMsg == Data.msgnum) {
  684.                RetVal = TRUE;
  685.                break;
  686.             }
  687.          }
  688.       }
  689.    }
  690.  
  691.    if (RetVal == TRUE) {
  692.       RetVal = TRUE;
  693.  
  694.       Data.fflags = 0;
  695.       Data.fflags |= (Sent == TRUE) ? MSGSENT : 0;
  696.       Data.fflags |= (Crash == TRUE) ? MSGCRASH : 0;
  697.       Data.fflags |= (Received == TRUE) ? MSGREAD : 0;
  698.       Data.fflags |= (Private == TRUE) ? MSGPRIVATE : 0;
  699.       Data.fflags |= (KillSent == TRUE) ? MSGKILL : 0;
  700.       Data.fflags |= (Local == TRUE) ? MSGLOCAL : 0;
  701.       Data.fflags |= (FileRequest == TRUE) ? MSGFRQ : 0;
  702.  
  703.       lseek (fdHdr, tell (fdHdr) - sizeof (Data), SEEK_SET);
  704.       write (fdHdr, &Data, sizeof (Data));
  705.    }
  706.  
  707.    return (RetVal);
  708. }
  709.  
  710.  
  711.