home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / lora299s.zip / HUDSON.CPP < prev    next >
C/C++ Source or Header  |  1998-05-12  |  32KB  |  1,014 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. HUDSON::HUDSON (void)
  23. {
  24.    fdTxt = fdHdr = -1;
  25.    Current = Id = 0L;
  26.    msgIdx = NULL;
  27.    Locked = FALSE;
  28. }
  29.  
  30. HUDSON::HUDSON (PSZ pszName, UCHAR board)
  31. {
  32.    fdTxt = fdHdr = -1;
  33.    Id = 0L;
  34.    msgIdx = NULL;
  35.    Locked = FALSE;
  36.  
  37.    Open (pszName, board);
  38. }
  39.  
  40. HUDSON::~HUDSON (void)
  41. {
  42.    Close ();
  43. }
  44.  
  45. VOID HUDSON::Pascal2C (PSZ strp, PSZ strc)
  46. {
  47.    memcpy (strc, &strp[1], strp[0]);
  48.    strc[strp[0]] = '\0';
  49. }
  50.  
  51. VOID HUDSON::C2Pascal (PSZ strp, PSZ strc)
  52. {
  53.    memcpy (&strp[1], strc, strlen (strc));
  54.    strp[0] = (CHAR)strlen (strc);
  55. }
  56.  
  57. USHORT HUDSON::Add (VOID)
  58. {
  59.    return (Add (Text));
  60. }
  61.  
  62. USHORT HUDSON::Add (class TMsgBase *MsgBase)
  63. {
  64.    New ();
  65.  
  66.    strcpy (From, MsgBase->From);
  67.    strcpy (To, MsgBase->To);
  68.    strcpy (Subject, MsgBase->Subject);
  69.  
  70.    strcpy (FromAddress, MsgBase->FromAddress);
  71.    strcpy (ToAddress, MsgBase->ToAddress);
  72.  
  73.    Written.Day = MsgBase->Written.Day;
  74.    Written.Month = MsgBase->Written.Month;
  75.    Written.Year = MsgBase->Written.Year;
  76.    Written.Hour = MsgBase->Written.Hour;
  77.    Written.Minute = MsgBase->Written.Minute;
  78.    Written.Second = MsgBase->Written.Second;
  79.  
  80.    Arrived.Day = MsgBase->Arrived.Day;
  81.    Arrived.Month = MsgBase->Arrived.Month;
  82.    Arrived.Year = MsgBase->Arrived.Year;
  83.    Arrived.Hour = MsgBase->Arrived.Hour;
  84.    Arrived.Minute = MsgBase->Arrived.Minute;
  85.    Arrived.Second = MsgBase->Arrived.Second;
  86.  
  87.    Crash = MsgBase->Crash;
  88.    Direct = MsgBase->Direct;
  89.    FileAttach = MsgBase->FileAttach;
  90.    FileRequest = MsgBase->FileRequest;
  91.    Hold = MsgBase->Hold;
  92.    Immediate = MsgBase->Immediate;
  93.    Intransit = MsgBase->Intransit;
  94.    KillSent = MsgBase->KillSent;
  95.    Local = MsgBase->Local;
  96.    Private = MsgBase->Private;
  97.    ReceiptRequest = MsgBase->ReceiptRequest;
  98.    Received = MsgBase->Received;
  99.    Sent = MsgBase->Sent;
  100.  
  101.    return (Add (MsgBase->Text));
  102. }
  103.  
  104. USHORT HUDSON::Add (class TCollection &MsgText)
  105. {
  106.    int fd;
  107.    USHORT RetVal = FALSE, inblock, len;
  108.    CHAR Temp[32], File[128], *pszAddress, *pszText;
  109.    HMSGTOIDX msgToIdx;
  110.    HMSGIDX hmsgIdx;
  111.  
  112.    //////////////////////////////////////////////////////////////////////////////
  113.    // Se la base non e' lockata, rilegge il msginfo.bbs                        //
  114.    //////////////////////////////////////////////////////////////////////////////
  115.    if (Locked == FALSE) {
  116.       memset (&msgInfo, 0, sizeof (HMSGINFO));
  117.       sprintf (File, "%smsginfo.bbs", BaseName);
  118.       if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  119.          read (fd, &msgInfo, sizeof (HMSGINFO));
  120.          close (fd);
  121.       }
  122.    }
  123.  
  124.    //////////////////////////////////////////////////////////////////////////////
  125.    // Costruisce la struttura MSGHDR                                           //
  126.    //////////////////////////////////////////////////////////////////////////////
  127.    memset (&msgHdr, 0, sizeof (HMSGHDR));
  128.    msgHdr.MsgNum = ++msgInfo.HighMsg;
  129.    msgHdr.PrevReply = (USHORT)Original;
  130.    msgHdr.NextReply = (USHORT)Reply;
  131.  
  132.    if (msgInfo.LowMsg == 0)
  133.       msgInfo.LowMsg = msgInfo.HighMsg;
  134.    msgInfo.TotalMsgs++;
  135.    msgInfo.TotalOnBoard[BoardNum - 1]++;
  136.    TotalMsgs = msgInfo.TotalOnBoard[BoardNum - 1];
  137.  
  138.    pszAddress = FromAddress;
  139.    if (strchr (pszAddress, ':') != NULL) {
  140.       msgHdr.OrigZone = (UCHAR)atoi (pszAddress);
  141.       pszAddress = strchr (pszAddress, ':') + 1;
  142.    }
  143.    if (strchr (pszAddress, '/') != NULL) {
  144.       msgHdr.OrigNet = (USHORT)atoi (pszAddress);
  145.       pszAddress = strchr (pszAddress, '/') + 1;
  146.    }
  147.    msgHdr.OrigNode = (USHORT)atoi (pszAddress);
  148.  
  149.    pszAddress = ToAddress;
  150.    if (strchr (pszAddress, ':') != NULL) {
  151.       msgHdr.DestZone = (UCHAR)atoi (pszAddress);
  152.       pszAddress = strchr (pszAddress, ':') + 1;
  153.    }
  154.    if (strchr (pszAddress, '/') != NULL) {
  155.       msgHdr.DestNet = (USHORT)atoi (pszAddress);
  156.       pszAddress = strchr (pszAddress, '/') + 1;
  157.    }
  158.    msgHdr.DestNode = (USHORT)atoi (pszAddress);
  159.  
  160.    msgHdr.Board = BoardNum;
  161.    sprintf (Temp, "%02d:%02d", Written.Hour, Written.Minute);
  162.    C2Pascal (msgHdr.Time, Temp);
  163.    sprintf (Temp, "%02d-%02d-%02d", Written.Month, Written.Day, Written.Year % 100);
  164.    C2Pascal (msgHdr.Date, Temp);
  165.    C2Pascal (msgHdr.WhoFrom, From);
  166.    C2Pascal (msgHdr.WhoTo, To);
  167.    C2Pascal (msgHdr.Subject, Subject);
  168.  
  169.    if (Local == TRUE)
  170.       msgHdr.MsgAttr |= HUD_LOCAL;
  171.    if (Private == TRUE)
  172.       msgHdr.MsgAttr |= HUD_PRIVATE;
  173.    if (Received == TRUE)
  174.       msgHdr.MsgAttr |= HUD_RECEIVED;
  175.    if (Crash == TRUE)
  176.       msgHdr.NetAttr |= HUD_CRASH;
  177.    if (KillSent == TRUE)
  178.       msgHdr.NetAttr |= HUD_KILL;
  179.    if (Sent == TRUE)
  180.       msgHdr.NetAttr |= HUD_SENT;
  181.    if (FileAttach == TRUE)
  182.       msgHdr.NetAttr |= HUD_FILE;
  183.    if (FileRequest == TRUE)
  184.       msgHdr.NetAttr |= HUD_FRQ;
  185.  
  186.    //////////////////////////////////////////////////////////////////////////////
  187.    // Inserisce il destinatario del file msgtoidx.bbs                          //
  188.    //////////////////////////////////////////////////////////////////////////////
  189.    memset (&msgToIdx, 0, sizeof (HMSGTOIDX));
  190.    C2Pascal (msgToIdx.String, To);
  191.    if (Locked == FALSE) {
  192.       sprintf (File, "%smsgtoidx.bbs", BaseName);
  193.       fdToIdx = open (File, O_RDWR|O_BINARY|O_CREAT|O_APPEND, S_IREAD|S_IWRITE);
  194.    }
  195.    if (fdToIdx != -1) {
  196.       lseek (fdToIdx, 0L, SEEK_END);
  197.       write (fdToIdx, &msgToIdx, sizeof (HMSGTOIDX));
  198.    }
  199.    if (Locked == FALSE)
  200.       close (fdToIdx);
  201.  
  202.    //////////////////////////////////////////////////////////////////////////////
  203.    // Inserisce l'entry nuova nel msgidx.bbs                                   //
  204.    //////////////////////////////////////////////////////////////////////////////
  205.    memset (&hmsgIdx, 0, sizeof (HMSGIDX));
  206.    hmsgIdx.MsgNum = msgHdr.MsgNum;
  207.    hmsgIdx.Board = msgHdr.Board;
  208.    if (Locked == FALSE) {
  209.       sprintf (File, "%smsgidx.bbs", BaseName);
  210.       if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT|O_APPEND, S_IREAD|S_IWRITE)) != -1) {
  211.          lseek (fd, 0L, SEEK_END);
  212.          write (fd, &hmsgIdx, sizeof (HMSGIDX));
  213.          close (fd);
  214.       }
  215.    }
  216.    else {
  217.       msgIdx[msgInfo.TotalMsgs - 1].MsgNum = hmsgIdx.MsgNum;
  218.       msgIdx[msgInfo.TotalMsgs - 1].Board = hmsgIdx.Board;
  219.    }
  220.  
  221.    //////////////////////////////////////////////////////////////////////////////
  222.    // Inserisce il testo del messaggio nel file msgtxt.bbs                     //
  223.    //////////////////////////////////////////////////////////////////////////////
  224.    if (Locked == FALSE) {
  225.       sprintf (File, "%smsgtxt.bbs", BaseName);
  226.       fdTxt = open (File, O_RDWR|O_BINARY|O_CREAT|O_APPEND, S_IREAD|S_IWRITE);
  227.    }
  228.    if (fdTxt != -1) {
  229.       lseek (fdTxt, 0L, SEEK_END);
  230.       msgHdr.StartBlock = (USHORT)(tell (fdTxt) / 256L);
  231.       inblock = 0;
  232.       if ((pszText = (PSZ)MsgText.First ()) != NULL)
  233.          do {
  234.             len = (USHORT)strlen (pszText);
  235.             while (len > 0) {
  236.                if (inblock + len <= 255) {
  237.                   memcpy (&szBuff[1 + inblock], pszText, len);
  238.                   inblock += len;
  239.                   len = 0;
  240.                }
  241.                else {
  242.                   memcpy (&szBuff[1 + inblock], pszText, 255 - inblock);
  243.                   szBuff[0] = 255;
  244.                   write (fdTxt, szBuff, 256);
  245.                   msgHdr.NumBlocks++;
  246.                   pszText += (255 - inblock);
  247.                   len -= (255 - inblock);
  248.                   inblock = 0;
  249.                }
  250.             }
  251.  
  252.             if (inblock >= 255) {
  253.                szBuff[0] = 255;
  254.                write (fdTxt, szBuff, 256);
  255.                msgHdr.NumBlocks++;
  256.                inblock = 0;
  257.             }
  258.             szBuff[1 + inblock] = '\r';
  259.             inblock++;
  260.  
  261.             if (inblock >= 255) {
  262.                szBuff[0] = 255;
  263.                write (fdTxt, szBuff, 256);
  264.                msgHdr.NumBlocks++;
  265.                inblock = 0;
  266.             }
  267.             szBuff[1 + inblock] = '\n';
  268.             inblock++;
  269.          } while ((pszText = (PSZ)MsgText.Next ()) != NULL);
  270.  
  271.       if (inblock > 0) {
  272.          szBuff[0] = (CHAR)inblock;
  273.          write (fdTxt, szBuff, 256);
  274.          msgHdr.NumBlocks++;
  275.       }
  276.    }
  277.    if (Locked == FALSE)
  278.       close (fdTxt);
  279.  
  280.    //////////////////////////////////////////////////////////////////////////////
  281.    // Aggiunge l'header del messaggio al file msghdr.bbs                       //
  282.    //////////////////////////////////////////////////////////////////////////////
  283.    if (Locked == FALSE) {
  284.       sprintf (File, "%smsghdr.bbs", BaseName);
  285.       fdHdr = open (File, O_RDWR|O_BINARY|O_CREAT|O_APPEND, S_IREAD|S_IWRITE);
  286.    }
  287.    if (fdHdr != -1) {
  288.       lseek (fdHdr, 0L, SEEK_END);
  289.       write (fdHdr, &msgHdr, sizeof (HMSGHDR));
  290.    }
  291.    if (Locked == FALSE)
  292.       close (fdHdr);
  293.  
  294.    //////////////////////////////////////////////////////////////////////////////
  295.    // Se la base non e' lockata aggiorna gli indici e il msginfo.bbs           //
  296.    //////////////////////////////////////////////////////////////////////////////
  297.    if (Locked == FALSE) {
  298.       if (msgIdx != NULL) {
  299.          free (msgIdx);
  300.          msgIdx = NULL;
  301.       }
  302.  
  303.       sprintf (File, "%smsgidx.bbs", BaseName);
  304.       if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  305.          if ((msgIdx = (HMSGIDX *)malloc ((size_t)filelength (fd))) != NULL)
  306.             read (fd, msgIdx, (unsigned)filelength (fd));
  307.          close (fd);
  308.       }
  309.  
  310.       sprintf (File, "%smsginfo.bbs", BaseName);
  311.       if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  312.          write (fd, &msgInfo, sizeof (HMSGINFO));
  313.          close (fd);
  314.       }
  315.    }
  316.  
  317.    return (TRUE);
  318. }
  319.  
  320. VOID HUDSON::Close (VOID)
  321. {
  322.    UnLock ();
  323.  
  324.    if (msgIdx != NULL)
  325.       free (msgIdx);
  326.  
  327.    fdTxt = fdHdr = -1;
  328.    Id = 0L;
  329.    msgIdx = NULL;
  330. }
  331.  
  332. USHORT HUDSON::Delete (ULONG ulMsg)
  333. {
  334.    int fd, i;
  335.    USHORT RetVal = FALSE;
  336.    CHAR File[128];
  337.  
  338.    if (Locked == FALSE) {
  339.       sprintf (File, "%smsginfo.bbs", BaseName);
  340.       if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  341.          read (fd, &msgInfo, sizeof (HMSGINFO));
  342.          close (fd);
  343.       }
  344.       TotalMsgs = msgInfo.TotalOnBoard[BoardNum - 1];
  345.    }
  346.  
  347.    if (Locked == FALSE) {
  348.       if (TotalMsgs != 0) {
  349.          sprintf (File, "%smsgidx.bbs", BaseName);
  350.          if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  351.             if ((msgIdx = (HMSGIDX *)malloc ((size_t)filelength (fd))) != NULL) {
  352.                read (fd, msgIdx, (unsigned)filelength (fd));
  353.                for (i = 0; i < msgInfo.TotalMsgs; i++) {
  354.                   if (msgIdx[i].Board == BoardNum && msgIdx[i].MsgNum == ulMsg) {
  355.                      msgIdx[i].MsgNum = 0xFFFFU;
  356.                      lseek (fd, 0L, SEEK_SET);
  357.                      write (fd, msgIdx, (unsigned)filelength (fd));
  358.                      RetVal = TRUE;
  359.                      break;
  360.                   }
  361.                }
  362.             }
  363.             close (fd);
  364.          }
  365.       }
  366.    }
  367.    else {
  368.       for (i = 0; i < msgInfo.TotalMsgs; i++) {
  369.          if (msgIdx[i].Board == BoardNum && msgIdx[i].MsgNum == ulMsg) {
  370.             msgIdx[i].MsgNum = 0xFFFFU;
  371.             RetVal = TRUE;
  372.             break;
  373.          }
  374.       }
  375.    }
  376.  
  377.    if (RetVal == TRUE) {
  378.       msgInfo.TotalMsgs--;
  379.       msgInfo.TotalOnBoard[BoardNum - 1]--;
  380.       TotalMsgs = msgInfo.TotalOnBoard[BoardNum - 1];
  381.  
  382.       if (Locked == FALSE) {
  383.          sprintf (File, "%smsginfo.bbs", BaseName);
  384.          if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  385.             write (fd, &msgInfo, sizeof (HMSGINFO));
  386.             close (fd);
  387.          }
  388.       }
  389.    }
  390.  
  391.    return (RetVal);
  392. }
  393.  
  394. USHORT HUDSON::GetHWM (ULONG &ulMsg)
  395. {
  396.    ulMsg = 0L;
  397.  
  398.    return (FALSE);
  399. }
  400.  
  401. ULONG HUDSON::Highest (VOID)
  402. {
  403.    int i;
  404.    ULONG RetVal = 0L;
  405.  
  406.    if (msgIdx != NULL && TotalMsgs != 0L) {
  407.       for (i = msgInfo.TotalMsgs - 1; i >= 0; i--) {
  408.          if (msgIdx[i].Board == BoardNum && msgIdx[i].MsgNum != 0xFFFFU) {
  409.             RetVal = msgIdx[i].MsgNum;
  410.             break;
  411.          }
  412.       }
  413.    }
  414.  
  415.    return (RetVal);
  416. }
  417.  
  418. USHORT HUDSON::Lock (ULONG ulTimeout)
  419. {
  420.    int fd;
  421.    CHAR File[128];
  422.  
  423.    ulTimeout = ulTimeout;
  424.  
  425.    if (Locked == FALSE) {
  426.       sprintf (File, "%smsginfo.bbs", BaseName);
  427.       if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  428.          read (fd, &msgInfo, sizeof (HMSGINFO));
  429.          close (fd);
  430.  
  431.          TotalMsgs = msgInfo.TotalOnBoard[BoardNum - 1];
  432.  
  433.          sprintf (File, "%smsgidx.bbs", BaseName);
  434.          if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  435.             if ((msgIdx = (HMSGIDX *)malloc ((size_t)filelength (fd) + 5000 * sizeof (HMSGIDX))) != NULL)
  436.                read (fd, msgIdx, (unsigned)filelength (fd));
  437.             close (fd);
  438.          }
  439.  
  440.          sprintf (File, "%smsgtxt.bbs", BaseName);
  441.          fdHdr = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  442.          sprintf (File, "%smsghdr.bbs", BaseName);
  443.          fdTxt = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  444.          sprintf (File, "%smsgtoidx.bbs", BaseName);
  445.          fdToIdx = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  446.       }
  447.    }
  448.  
  449.    return (TRUE);
  450. }
  451.  
  452. ULONG HUDSON::Lowest (VOID)
  453. {
  454.    int i;
  455.    ULONG RetVal = 0L;
  456.  
  457.    if (msgIdx != NULL && TotalMsgs != 0L) {
  458.       for (i = 0; i < msgInfo.TotalMsgs; i++) {
  459.          if (msgIdx[i].Board == BoardNum && msgIdx[i].MsgNum != 0xFFFFU) {
  460.             RetVal = msgIdx[i].MsgNum;
  461.             break;
  462.          }
  463.       }
  464.    }
  465.  
  466.    return (RetVal);
  467. }
  468.  
  469. ULONG HUDSON::MsgnToUid (ULONG ulMsg)
  470. {
  471.    int i;
  472.    ULONG Num = 1L;
  473.  
  474.    if (msgIdx != NULL && TotalMsgs != 0L) {
  475.       for (i = 0; i < msgInfo.TotalMsgs; i++) {
  476.          if (msgIdx[i].Board == BoardNum && msgIdx[i].MsgNum != 0xFFFFU) {
  477.             if (Num == ulMsg) {
  478.                ulMsg = msgIdx[i].MsgNum;
  479.                break;
  480.             }
  481.             Num++;
  482.          }
  483.       }
  484.    }
  485.  
  486.    return (ulMsg);
  487. }
  488.  
  489. VOID HUDSON::New (VOID)
  490. {
  491.    From[0] = To[0] = Subject[0] = '\0';
  492.    Crash = Direct = FileAttach = FileRequest = Hold = Immediate = FALSE;
  493.    Intransit = KillSent = Local = Private = ReceiptRequest = Received = FALSE;
  494.    Sent = 0;
  495.    memset (&Written, 0, sizeof (Written));
  496.    memset (&Arrived, 0, sizeof (Arrived));
  497.    FromAddress[0] = ToAddress[0] = '\0';
  498.    Original = Reply = 0L;
  499.    Text.Clear ();
  500. }
  501.  
  502. USHORT HUDSON::Next (ULONG &ulMsg)
  503. {
  504.    int i;
  505.    USHORT RetVal = FALSE;
  506.  
  507.    if (msgIdx != NULL && TotalMsgs != 0L) {
  508.       for (i = 0; i < msgInfo.TotalMsgs; i++) {
  509.          if (msgIdx[i].Board == BoardNum && msgIdx[i].MsgNum > ulMsg && msgIdx[i].MsgNum != 0xFFFFU) {
  510.             ulMsg = msgIdx[i].MsgNum;
  511.             RetVal = TRUE;
  512.             break;
  513.          }
  514.       }
  515.    }
  516.  
  517.    return (RetVal);
  518. }
  519.  
  520. ULONG HUDSON::Number (VOID)
  521. {
  522.    return (TotalMsgs);
  523. }
  524.  
  525. USHORT HUDSON::Open (PSZ pszName, UCHAR board)
  526. {
  527.    int fd;
  528.    USHORT RetVal = FALSE;
  529.    CHAR File[128];
  530.  
  531.    Close ();
  532.  
  533.    strcpy (BaseName, pszName);
  534.    BoardNum = board;
  535.  
  536.    //////////////////////////////////////////////////////////////////////////////
  537.    // Legge il msginfo.bbs per sapere quanti messaggi ci sono nella board      //
  538.    //////////////////////////////////////////////////////////////////////////////
  539.    sprintf (File, "%smsginfo.bbs", BaseName);
  540.    if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  541.       read (fd, &msgInfo, sizeof (HMSGINFO));
  542.       close (fd);
  543.  
  544.       TotalMsgs = msgInfo.TotalOnBoard[BoardNum - 1];
  545.  
  546.       //////////////////////////////////////////////////////////////////////////////
  547.       // Legge tutto l'indice in memoria                                          //
  548.       //////////////////////////////////////////////////////////////////////////////
  549.       sprintf (File, "%smsgidx.bbs", BaseName);
  550.       if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  551.          if ((msgIdx = (HMSGIDX *)malloc ((size_t)filelength (fd))) != NULL)
  552.             read (fd, msgIdx, (unsigned)filelength (fd));
  553.          close (fd);
  554.       }
  555.  
  556.       RetVal = TRUE;
  557.    }
  558.  
  559.    return (RetVal);
  560. }
  561.  
  562. VOID HUDSON::Pack (VOID)
  563. {
  564.    int i, fd, fdo[4], fdn[4];
  565.    USHORT Number, DoRename = FALSE;
  566.    CHAR File[128], NewName[128];
  567.    HMSGIDX hmsgIdx;
  568.  
  569.    UnLock ();
  570.  
  571.    sprintf (File, "%smsgidx.bbs", BaseName);
  572.    fdo[0] = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  573.    sprintf (File, "%smsgidx.new", BaseName);
  574.    fdn[0] = open (File, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
  575.  
  576.    sprintf (File, "%smsghdr.bbs", BaseName);
  577.    fdo[1] = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  578.    sprintf (File, "%smsghdr.new", BaseName);
  579.    fdn[1] = open (File, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
  580.  
  581.    sprintf (File, "%smsgtoidx.bbs", BaseName);
  582.    fdo[2] = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  583.    sprintf (File, "%smsgtoidx.new", BaseName);
  584.    fdn[2] = open (File, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
  585.  
  586.    sprintf (File, "%smsgtxt.bbs", BaseName);
  587.    fdo[3] = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  588.    sprintf (File, "%smsgtxt.new", BaseName);
  589.    fdn[3] = open (File, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
  590.  
  591.    if (fdo[0] != -1 && fdo[1] != -1 && fdo[2] != -1 && fdo[3] != -1 && fdn[0] != -1 && fdn[1] != -1 && fdn[2] != -1 && fdn[3] != -1) {
  592.       Number = 1;
  593.       memset (&msgInfo, 0, sizeof (HMSGINFO));
  594.       while (read (fdo[0], &hmsgIdx, sizeof (HMSGIDX)) == sizeof (HMSGIDX)) {
  595.          if (hmsgIdx.MsgNum != 0xFFFFU) {
  596.             hmsgIdx.MsgNum = Number;
  597.             write (fdn[0], &hmsgIdx, sizeof (HMSGIDX));
  598.  
  599.             lseek (fdo[3], (long)msgHdr.StartBlock * 256L, SEEK_SET);
  600.             msgHdr.StartBlock = (USHORT)(tell (fdn[3]) / 256L);
  601.             for (i = 0; i < msgHdr.NumBlocks; i++) {
  602.                read (fdo[3], szBuff, 256);
  603.                write (fdn[3], szBuff, 256);
  604.             }
  605.  
  606.             read (fdo[1], &msgHdr, sizeof (HMSGHDR));
  607.             msgHdr.MsgNum = Number;
  608.             write (fdn[1], &msgHdr, sizeof (HMSGHDR));
  609.  
  610.             read (fdo[2], szBuff, sizeof (HMSGTOIDX));
  611.             write (fdn[2], szBuff, sizeof (HMSGTOIDX));
  612.  
  613.             msgInfo.TotalMsgs++;
  614.             msgInfo.TotalOnBoard[hmsgIdx.Board - 1]++;
  615.             if (msgInfo.LowMsg == 0)
  616.                msgInfo.LowMsg = Number;
  617.             Number++;
  618.          }
  619.       }
  620.  
  621.       sprintf (File, "%smsginfo.bbs", BaseName);
  622.       if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE)) != -1) {
  623.          write (fd, &msgInfo, sizeof (HMSGINFO));
  624.          close (fd);
  625.       }
  626.  
  627.       DoRename = TRUE;
  628.    }
  629.  
  630.    if (fdo[0] != -1)
  631.       close (fdo[0]);
  632.    if (fdo[1] != -1)
  633.       close (fdo[1]);
  634.    if (fdo[2] != -1)
  635.       close (fdo[2]);
  636.    if (fdo[3] != -1)
  637.       close (fdo[3]);
  638.  
  639.    if (fdn[0] != -1)
  640.       close (fdn[0]);
  641.    if (fdn[1] != -1)
  642.       close (fdn[1]);
  643.    if (fdn[2] != -1)
  644.       close (fdn[2]);
  645.    if (fdn[3] != -1)
  646.       close (fdn[3]);
  647.  
  648.    sprintf (NewName, "%smsgidx.bbs", BaseName);
  649.    unlink (NewName);
  650.    sprintf (File, "%smsgidx.new", BaseName);
  651.    rename (File, NewName);
  652.  
  653.    sprintf (NewName, "%smsghdr.bbs", BaseName);
  654.    unlink (NewName);
  655.    sprintf (File, "%smsghdr.new", BaseName);
  656.    rename (File, NewName);
  657.  
  658.    sprintf (NewName, "%smsgtoidx.bbs", BaseName);
  659.    unlink (NewName);
  660.    sprintf (File, "%smsgtoidx.new", BaseName);
  661.    rename (File, NewName);
  662.  
  663.    sprintf (NewName, "%smsgtxt.bbs", BaseName);
  664.    unlink (NewName);
  665.    sprintf (File, "%smsgtxt.new", BaseName);
  666.    rename (File, NewName);
  667. }
  668.  
  669. USHORT HUDSON::Previous (ULONG &ulMsg)
  670. {
  671.    int i;
  672.    USHORT RetVal = FALSE;
  673.  
  674.    if (msgIdx != NULL && TotalMsgs != 0L) {
  675.       for (i = msgInfo.TotalMsgs - 1; i >= 0; i--) {
  676.          if (msgIdx[i].Board == BoardNum && msgIdx[i].MsgNum < ulMsg && msgIdx[i].MsgNum != 0xFFFFU) {
  677.             ulMsg = msgIdx[i].MsgNum;
  678.             RetVal = TRUE;
  679.             break;
  680.          }
  681.       }
  682.    }
  683.  
  684.    return (RetVal);
  685. }
  686.  
  687. USHORT HUDSON::ReadHeader (ULONG ulMsg)
  688. {
  689.    int fz, fn, fo, tz, tn, to;
  690.    USHORT RetVal = FALSE, FromPoint, ToPoint, FromZone, ToZone;
  691.    SHORT i, nReaded, nCol;
  692.    CHAR File[128];
  693.  
  694.    ToPoint = ToZone = FromPoint = FromZone = 0;
  695.  
  696.    if (msgIdx != NULL && TotalMsgs != 0L) {
  697.       for (i = 0; i < msgInfo.TotalMsgs; i++) {
  698.          if (msgIdx[i].Board == BoardNum && msgIdx[i].MsgNum == ulMsg && msgIdx[i].MsgNum != 0xFFFFU) {
  699.             RetVal = TRUE;
  700.             break;
  701.          }
  702.       }
  703.    }
  704.  
  705.    if (RetVal == TRUE) {
  706.       Current = Id = ulMsg;
  707.  
  708.       if (Locked == FALSE) {
  709.          sprintf (File, "%smsghdr.bbs", BaseName);
  710.          fdHdr = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  711.       }
  712.       if (fdHdr != -1) {
  713.          lseek (fdHdr, (long)i * (long)sizeof (HMSGHDR), SEEK_SET);
  714.          read (fdHdr, &msgHdr, sizeof (HMSGHDR));
  715.          if (Locked == FALSE)
  716.             close (fdHdr);
  717.  
  718.          Pascal2C (msgHdr.WhoFrom, From);
  719.          Pascal2C (msgHdr.WhoTo, To);
  720.          Pascal2C (msgHdr.Subject, Subject);
  721.  
  722.          sprintf (FromAddress, "%d:%d/%d", msgHdr.OrigZone, msgHdr.OrigNet, msgHdr.OrigNode);
  723.          sprintf (ToAddress, "%d:%d/%d", msgHdr.DestZone, msgHdr.DestNet, msgHdr.DestNode);
  724.  
  725.          Original = msgHdr.PrevReply;
  726.          Reply = msgHdr.NextReply;
  727.  
  728.          Arrived.Day = Written.Day = (UCHAR)((msgHdr.Date[4] - '0') * 10 + (msgHdr.Date[5] - '0'));
  729.          Arrived.Month = Written.Month = (UCHAR)((msgHdr.Date[1] - '0') * 10 + (msgHdr.Date[2] - '0'));
  730.          Written.Year = (USHORT)((msgHdr.Date[7] - '0') * 10 + (msgHdr.Date[8] - '0'));
  731.          if (Written.Year < 90)
  732.             Written.Year += 2000;
  733.          else
  734.             Written.Year += 1900;
  735.          Arrived.Year = Written.Year;
  736.          Arrived.Hour = Written.Hour = (UCHAR)((msgHdr.Time[1] - '0') * 10 + (msgHdr.Time[2] - '0'));
  737.          Arrived.Minute = Written.Minute = (UCHAR)((msgHdr.Time[4] - '0') * 10 + (msgHdr.Time[5] - '0'));
  738.          Arrived.Second = Written.Second = 0;
  739.  
  740.          Local = ((msgHdr.MsgAttr & HUD_LOCAL) == HUD_LOCAL) ? TRUE : FALSE;
  741.          Private = (msgHdr.MsgAttr & HUD_PRIVATE) ? TRUE : FALSE;
  742.          Received = (msgHdr.MsgAttr & HUD_RECEIVED) ? TRUE : FALSE;
  743.          Crash = (msgHdr.NetAttr & HUD_CRASH) ? TRUE : FALSE;
  744.          KillSent = (msgHdr.NetAttr & HUD_KILL) ? TRUE : FALSE;
  745.          Sent = (msgHdr.NetAttr & HUD_SENT) ? TRUE : FALSE;
  746.          FileAttach = (msgHdr.NetAttr & HUD_FILE) ? TRUE : FALSE;
  747.          FileRequest = (msgHdr.NetAttr & HUD_FRQ) ? TRUE : FALSE;
  748.  
  749.          if (Locked == FALSE) {
  750.             sprintf (File, "%smsgtxt.bbs", BaseName);
  751.             fdTxt = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  752.          }
  753.          if (fdTxt != -1) {
  754.             lseek (fdTxt, (long)msgHdr.StartBlock * 256L, SEEK_SET);
  755.             read (fdTxt, szBuff, 256);
  756.             nReaded = szBuff[0];
  757.  
  758.             pLine = szLine;
  759.             nCol = 0;
  760.             FromZone = msgHdr.OrigZone;
  761.             ToZone = msgHdr.DestZone;
  762.  
  763.             for (i = 0, pBuff = &szBuff[1]; i < nReaded; i++, pBuff++) {
  764.                if (*pBuff == '\r') {
  765.                   *pLine = '\0';
  766.                   if (!strncmp (szLine, "\001FMPT ", 6))
  767.                      FromPoint = (USHORT)atoi (&szLine[6]);
  768.                   else if (!strncmp (szLine, "\001TOPT ", 6))
  769.                      ToPoint = (USHORT)atoi (&szLine[6]);
  770.                   else if (!strncmp (szLine, "\001INTL ", 6)) {
  771.                      sscanf (&szLine[6], "%d:%d/%d %d:%d/%d", &tz, &tn, &to, &fz, &fn, &fo);
  772.                      if (tn == msgHdr.DestNet && to == msgHdr.DestNode)
  773.                         ToZone = (USHORT)tz;
  774.                      if (fn == msgHdr.OrigNet && fo == msgHdr.OrigNode)
  775.                         FromZone = (USHORT)fz;
  776.                   }
  777.                   else if (!strncmp (szLine, "\001FLAGS ", 7)) {
  778.                      if (strstr (szLine, "DIR"))
  779.                         Direct = TRUE;
  780.                   }
  781.                   pLine = szLine;
  782.                   nCol = 0;
  783.                }
  784.                else if (*pBuff != '\n') {
  785.                   *pLine++ = *pBuff;
  786.                   nCol++;
  787.                   if (nCol >= 80) {
  788.                      *pLine = '\0';
  789.                      pLine = szLine;
  790.                      nCol = 0;
  791.                   }
  792.                }
  793.             }
  794.  
  795.             sprintf (FromAddress, "%u:%u/%u.%u", FromZone, msgHdr.OrigNet, msgHdr.OrigNode, FromPoint);
  796.             sprintf (ToAddress, "%u:%u/%u.%u", ToZone, msgHdr.DestNet, msgHdr.DestNode, ToPoint);
  797.  
  798.             if (Locked == FALSE)
  799.                close (fdTxt);
  800.          }
  801.       }
  802.    }
  803.  
  804.    return (RetVal);
  805. }
  806.  
  807. USHORT HUDSON::Read (ULONG ulMsg, SHORT nWidth)
  808. {
  809.    return (Read (ulMsg, Text, nWidth));
  810. }
  811.  
  812. USHORT HUDSON::Read (ULONG ulMsg, class TCollection &MsgText, SHORT nWidth)
  813. {
  814.    int fz, fn, fo, tz, tn, to;
  815.    USHORT RetVal = FALSE, SkipNext = FALSE, FromPoint, ToPoint, FromZone, ToZone;
  816.    SHORT i, m, nReaded, nCol;
  817.    CHAR File[128];
  818.  
  819.    MsgText.Clear ();
  820.    ToPoint = ToZone = FromPoint = FromZone = 0;
  821.  
  822.    if ((RetVal = ReadHeader (ulMsg)) == TRUE) {
  823.       if (Locked == FALSE) {
  824.          sprintf (File, "%smsgtxt.bbs", BaseName);
  825.          fdTxt = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  826.       }
  827.       if (fdTxt != -1) {
  828.          lseek (fdTxt, (long)msgHdr.StartBlock * 256L, SEEK_SET);
  829.  
  830.          pLine = szLine;
  831.          nCol = 0;
  832.  
  833.          for (m = 0; m < msgHdr.NumBlocks; m++) {
  834.             read (fdTxt, szBuff, 256);
  835.             nReaded = szBuff[0];
  836.  
  837.             for (i = 0, pBuff = &szBuff[1]; i < nReaded; i++, pBuff++) {
  838.                if (*pBuff == '\r') {
  839.                   *pLine = '\0';
  840.                   if (!strncmp (szLine, "\001FMPT ", 6))
  841.                      FromPoint = (USHORT)atoi (&szLine[6]);
  842.                   else if (!strncmp (szLine, "\001TOPT ", 6))
  843.                      ToPoint = (USHORT)atoi (&szLine[6]);
  844.                   else if (!strncmp (szLine, "\001INTL ", 6)) {
  845.                      sscanf (&szLine[6], "%d:%d/%d %d:%d/%d", &tz, &tn, &to, &fz, &fn, &fo);
  846.                      if (tn == msgHdr.DestNet && to == msgHdr.DestNode)
  847.                         ToZone = (USHORT)tz;
  848.                      if (fn == msgHdr.OrigNet && fo == msgHdr.OrigNode)
  849.                         FromZone = (USHORT)fz;
  850.                   }
  851.                   else if (!strncmp (szLine, "\001FLAGS ", 7)) {
  852.                      if (strstr (szLine, "DIR"))
  853.                         Direct = TRUE;
  854.                   }
  855.                   if (pLine > szLine && SkipNext == TRUE) {
  856.                      pLine--;
  857.                      while (pLine > szLine && *pLine == ' ')
  858.                         *pLine-- = '\0';
  859.                      if (pLine > szLine)
  860.                         MsgText.Add (szLine, (USHORT)(strlen (szLine) + 1));
  861.                   }
  862.                   else if (SkipNext == FALSE)
  863.                      MsgText.Add (szLine, (USHORT)(strlen (szLine) + 1));
  864.                   SkipNext = FALSE;
  865.                   pLine = szLine;
  866.                   nCol = 0;
  867.                }
  868.                else if (*pBuff != '\n') {
  869.                   *pLine++ = *pBuff;
  870.                   nCol++;
  871.                   if (nCol >= nWidth) {
  872.                      *pLine = '\0';
  873.                      if (strchr (szLine, ' ') != NULL) {
  874.                         while (nCol > 1 && *pLine != ' ') {
  875.                            nCol--;
  876.                            pLine--;
  877.                         }
  878.                         if (nCol > 0) {
  879.                            while (*pLine == ' ')
  880.                               pLine++;
  881.                            strcpy (szWrp, pLine);
  882.                         }
  883.                         *pLine = '\0';
  884.                      }
  885.                      else
  886.                         szWrp[0] = '\0';
  887.                      MsgText.Add (szLine, (USHORT)(strlen (szLine) + 1));
  888.                      strcpy (szLine, szWrp);
  889.                      pLine = strchr (szLine, '\0');
  890.                      nCol = (SHORT)strlen (szLine);
  891.                      SkipNext = TRUE;
  892.                   }
  893.                }
  894.             }
  895.          }
  896.  
  897.          sprintf (FromAddress, "%u:%u/%u.%u", FromZone, msgHdr.OrigNet, msgHdr.OrigNode, FromPoint);
  898.          sprintf (ToAddress, "%u:%u/%u.%u", ToZone, msgHdr.DestNet, msgHdr.DestNode, ToPoint);
  899.  
  900.          if (Locked == FALSE)
  901.             close (fdTxt);
  902.       }
  903.    }
  904.  
  905.    return (RetVal);
  906. }
  907.  
  908. VOID HUDSON::SetHWM (ULONG ulMsg)
  909. {
  910.    ulMsg = ulMsg;
  911. }
  912.  
  913. ULONG HUDSON::UidToMsgn (ULONG ulMsg)
  914. {
  915.    int i;
  916.    ULONG Num = 1L;
  917.  
  918.    if (msgIdx != NULL && TotalMsgs != 0L) {
  919.       for (i = 0; i < msgInfo.TotalMsgs; i++) {
  920.          if (msgIdx[i].Board == BoardNum && msgIdx[i].MsgNum != 0xFFFFU) {
  921.             if (msgIdx[i].MsgNum == ulMsg) {
  922.                ulMsg = Num;
  923.                break;
  924.             }
  925.             Num++;
  926.          }
  927.       }
  928.    }
  929.  
  930.    return (ulMsg);
  931. }
  932.  
  933. VOID HUDSON::UnLock (VOID)
  934. {
  935.    int fd;
  936.    CHAR File[128];
  937.  
  938.    if (Locked == TRUE) {
  939.       sprintf (File, "%smsginfo.bbs", BaseName);
  940.       if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  941.          write (fd, &msgInfo, sizeof (HMSGINFO));
  942.          close (fd);
  943.  
  944.          sprintf (File, "%smsgidx.bbs", BaseName);
  945.          if ((fd = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE)) != -1) {
  946.             write (fd, msgIdx, msgInfo.TotalMsgs * sizeof (HMSGIDX));
  947.             close (fd);
  948.          }
  949.  
  950.          if (fdHdr != -1)
  951.             close (fdHdr);
  952.          if (fdTxt != -1)
  953.             close (fdTxt);
  954.          if (fdToIdx != -1)
  955.             close (fdToIdx);
  956.       }
  957.    }
  958. }
  959.  
  960. USHORT HUDSON::WriteHeader (ULONG ulMsg)
  961. {
  962.    int i;
  963.    USHORT RetVal = FALSE;
  964.    CHAR File[128];
  965.  
  966.    if (msgIdx != NULL && TotalMsgs != 0L) {
  967.       for (i = 0; i < msgInfo.TotalMsgs; i++) {
  968.          if (msgIdx[i].Board == BoardNum && msgIdx[i].MsgNum == ulMsg && msgIdx[i].MsgNum != 0xFFFFU) {
  969.             RetVal = TRUE;
  970.             break;
  971.          }
  972.       }
  973.    }
  974.  
  975.    if (RetVal == TRUE) {
  976.       if (Locked == FALSE) {
  977.          sprintf (File, "%smsghdr.bbs", BaseName);
  978.          fdHdr = open (File, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  979.       }
  980.       if (fdHdr != -1) {
  981.          lseek (fdHdr, (long)i * (long)sizeof (HMSGHDR), SEEK_SET);
  982.          read (fdHdr, &msgHdr, sizeof (HMSGHDR));
  983.  
  984.          msgHdr.MsgAttr = msgHdr.NetAttr = 0;
  985.          if (Local == TRUE)
  986.             msgHdr.MsgAttr |= HUD_LOCAL;
  987.          if (Private == TRUE)
  988.             msgHdr.MsgAttr |= HUD_PRIVATE;
  989.          if (Received == TRUE)
  990.             msgHdr.MsgAttr |= HUD_RECEIVED;
  991.          if (Crash == TRUE)
  992.             msgHdr.NetAttr |= HUD_CRASH;
  993.          if (KillSent == TRUE)
  994.             msgHdr.NetAttr |= HUD_KILL;
  995.          if (Sent == TRUE)
  996.             msgHdr.NetAttr |= HUD_SENT;
  997.          if (FileAttach == TRUE)
  998.             msgHdr.NetAttr |= HUD_FILE;
  999.          if (FileRequest == TRUE)
  1000.             msgHdr.NetAttr |= HUD_FRQ;
  1001.  
  1002.          lseek (fdHdr, (long)i * (long)sizeof (HMSGHDR), SEEK_SET);
  1003.          write (fdHdr, &msgHdr, sizeof (HMSGHDR));
  1004.  
  1005.          if (Locked == FALSE)
  1006.             close (fdHdr);
  1007.       }
  1008.    }
  1009.  
  1010.    return (RetVal);
  1011. }
  1012.  
  1013.  
  1014.