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