home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / top2src.zip / MESSAGES.C < prev    next >
C/C++ Source or Header  |  2000-07-13  |  9KB  |  236 lines

  1. /******************************************************************************
  2. MESSAGES.C   Message writing functions.
  3.  
  4.     Copyright 1993 - 2000 Paul J. Sidorsky
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License, version 2, as
  8.     published by the Free Software Foundation.
  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19. This module contains the functions that handle the writing of messages.  The
  20. reading and processing is done in PROCMSGS.C.
  21. ******************************************************************************/
  22.  
  23. #include "top.h"
  24.  
  25. /* dispatch_message() - Sends a message to one or more TOP node.
  26.    Parameters:  type - Type of message to send (MSG_ constant).
  27.                 string - Text of message to send.
  28.                 tonode - Node the message is "done to", or -1 for none.
  29.                 priv - Whether or not to send the message privately (i.e.
  30.                        only to the node specified in tonode).
  31.                 echo - Whether or not to echo the message to this node.
  32.    Returns:  Nothing.
  33.    Notes:  The contents of some parameters depend on the type of message
  34.            being sent.  See MESSAGES.TXT for a complete message-by-message
  35.            guide.  All messages are sent to all nodes unless the priv flag
  36.            is TRUE, excluding the sender if the echo flag is FALSE.  There
  37.            are globals that handle some additional data that this function
  38.            uses.  See GLOBAL.C.  This function does not return because
  39.            errors are treated as fatal and TOP will be aborted.
  40. */
  41. void dispatch_message(XINT type, unsigned char *string, XINT tonode,
  42.                       XINT priv, XINT echo)
  43. {
  44. XINT d, low, high; /* Counter, low node to send to, high node to send to. */
  45. msg_typ msgout; /* Message data buffer. */
  46.  
  47. /* See which nodes are active. */
  48. check_nodes_used(TRUE);
  49.  
  50. if (tonode < 0 || !priv)
  51.     {
  52.     /* If tonode is -1 or the message isn't private, send to all nodes. */
  53.     low = 0;
  54.     high = MAXNODES - 1;
  55.     }
  56. else
  57.     {
  58.     /* The message is private so only send to one node by making the low
  59.        and high nodes the same. */
  60.     low = high = tonode;
  61.     }
  62.  
  63. /* Loop for the predetermined node range. */
  64. for (d = low; d <= high; d++)
  65.     {
  66.     /* The message is not sent if the node is active, if the message is
  67.        private and this isn't the right node (although this shouldn't happen
  68.        because the range limits the sending to the one node; the test was
  69.        leftover from a previous version of the function that didn't use a
  70.        range), or if we're sending to this node and echoing is not on. */
  71.     /* I think this test should have parentheses around the priv & node, and
  72.        the echo & node tests, but it still seems to work without them. */
  73.     if (activenodes[d] && (priv || d != od_control.od_node ||
  74.         echo || tonode == od_control.od_node))
  75.         {
  76.         /* All of the message data is either copied from the user data,
  77.            door kit, function parameters, or global variables that were
  78.            created to maintain function calling compatibility. */
  79.         msgout.type = type;
  80.         msgout.from = od_control.od_node;
  81.         msgout.doneto = tonode;
  82.         msgout.gender = user.gender;
  83.         fixname(msgout.handle, user.handle);
  84.         strcpy(msgout.string, string);
  85.         /* The global override causes the message to be sent on channel 0
  86.            (the global channel) instead of the current one. */
  87.         msgout.channel = (msgsendglobal ? 0UL : curchannel);
  88.         msgout.minsec = msgminsec;
  89.         msgout.maxsec = msgmaxsec;
  90.         msgout.data1 = msgextradata;
  91.         /* Write the message to disk. */
  92.         write_message(d, &msgout);
  93.         }
  94.     }
  95.  
  96. /* Clear the global send flag.  The other global variables generally must
  97.    be set if they are used, so they do not need to be cleared. */
  98. msgsendglobal = 0;
  99.  
  100. return;
  101. }
  102.  
  103. /* write_message() - Writes message data to disk.
  104.    Parameters:  outnode - Node number to write the message to.
  105.                 msgbuf - Pointer to message data buffer.
  106.    Returns:  Nothing.
  107.    Notes:  As with dispatch_message(), all errors are treated as fatal so
  108.            there is no need to return anything.  For a full explanation of
  109.            how the messaging system works on a technical level, see
  110.            MESSAGES.TXT.
  111. */
  112. void write_message(XINT outnode, msg_typ *msgbuf)
  113. {
  114. char filnam[256], tstbit[2]; /* File name buffer, byte test buffer. */
  115. XINT res, d; /* Result code, counter. */
  116. XINT mrecnum = -1; /* Message record number to use. */
  117.  
  118. /* The structlength is not used but may be one day to allow for backward
  119.    compatibility. */
  120. msgbuf->structlength = sizeof(msg_typ);
  121.  
  122. /* Open the message index file for the receiving node. */
  123. sprintf(filnam, "%sMIX%05i.TCH", cfg.topworkpath, outnode);
  124. midxoutfil = sh_open(filnam, O_RDWR | O_CREAT | O_BINARY , SH_DENYNONE,
  125.                      S_IREAD | S_IWRITE);
  126. if (midxoutfil == -1)
  127.     {
  128.     errorabort(ERR_CANTOPEN, filnam);
  129.     }
  130.  
  131. /* Loop through the message index looking for a free record. */
  132. for (d = 0; d < filelength(midxoutfil) && mrecnum == -1; d++)
  133.     {
  134.     /* Read in the byte for this record index. */
  135.     res = lseek(midxoutfil, (long) d, SEEK_SET);
  136.     if (res == -1)
  137.         {
  138.         continue;
  139.         }
  140.     rec_locking(REC_LOCK, midxoutfil, d, 1L);
  141.     res = read(midxoutfil, tstbit, 1L);
  142.     if (!tstbit[0] && res != -1)
  143.         {
  144.         /* If the test byte was false and there were no errors, the
  145.            record is available for us to use. */
  146.         mrecnum = d;
  147.         res = lseek(midxoutfil, (long) d, SEEK_SET);
  148.         }
  149.     else
  150.         {
  151.         rec_locking(REC_UNLOCK, midxoutfil, d, 1L);
  152.         }
  153.     }
  154.  
  155. if (mrecnum == -1)
  156.     {
  157.     /* If no free record was found, a new one is created. */
  158.     mrecnum = filelength(midxoutfil);
  159.     res = lseek(midxoutfil, (long) mrecnum, SEEK_SET);
  160.     rec_locking(REC_LOCK, midxoutfil, mrecnum, 1L);
  161.     }
  162.  
  163. /* Write TRUE to the index for the record being used to show we are using
  164.    it. */
  165. tstbit[0] = 1;
  166. res = write(midxoutfil, tstbit, 1L);
  167. if (res == -1)
  168.     {
  169.     rec_locking(REC_UNLOCK, midxoutfil, mrecnum, 1L);
  170.     close(midxoutfil);
  171.     errorabort(ERR_CANTWRITE, filnam);
  172.     }
  173.  
  174. /* Open the message data file for the receiving node. */
  175. sprintf(filnam, "%sMSG%05i.TCH", cfg.topworkpath, outnode);
  176. msgoutfil = sh_open(filnam, O_RDWR | O_CREAT | O_BINARY, SH_DENYNONE,
  177.                   S_IREAD | S_IWRITE);
  178. if (msgoutfil == -1)
  179.     {
  180.     rec_locking(REC_UNLOCK, midxoutfil, mrecnum, 1L);
  181.     close(midxoutfil);
  182.     errorabort(ERR_CANTOPEN, filnam);
  183.     }
  184.  
  185. /* Seek to the predetermined record number and write the message data. */
  186. res = lseek(msgoutfil, (long) mrecnum * (long) sizeof(msg_typ), SEEK_SET);
  187. if (res == -1)
  188.     {
  189.     rec_locking(REC_UNLOCK, midxoutfil, mrecnum, 1L);
  190.     close(msgoutfil);
  191.     close(midxoutfil);
  192.     errorabort(ERR_CANTACCESS, filnam);
  193.     }
  194. rec_locking(REC_LOCK, msgoutfil, (long) mrecnum * (long) sizeof(msg_typ),
  195.             (long) sizeof(msg_typ));
  196. res = write(msgoutfil, msgbuf, sizeof(msg_typ));
  197. rec_locking(REC_UNLOCK, msgoutfil, (long) mrecnum * (long) sizeof(msg_typ),
  198.             (long) sizeof(msg_typ));
  199. if (res == -1)
  200.     {
  201.     rec_locking(REC_UNLOCK, midxoutfil, mrecnum, 1L);
  202.     close(msgoutfil);
  203.     close(midxoutfil);
  204.     errorabort(ERR_CANTWRITE, filnam);
  205.     }
  206.  
  207. /* Close the files. */
  208. res = close(msgoutfil);
  209. if (res == -1)
  210.     {
  211.     rec_locking(REC_UNLOCK, midxoutfil, mrecnum, 1L);
  212.     close(msgoutfil);
  213.     close(midxoutfil);
  214.     errorabort(ERR_CANTCLOSE, filnam);
  215.     }
  216. rec_locking(REC_UNLOCK, midxoutfil, mrecnum, 1L);
  217. res = close(midxoutfil);
  218. if (res == -1)
  219.     {
  220.     close(midxoutfil);
  221.     errorabort(ERR_CANTCLOSE, filnam);
  222.     }
  223.  
  224. /* Write TRUE to the change index for this node so it knows there is a new
  225.    message. */
  226. tstbit[0] = 1;
  227. // Not sure if these need errorchecking...
  228. lseek(chgfil, outnode, SEEK_SET);
  229. rec_locking(REC_LOCK, chgfil, outnode, 1L);
  230. write(chgfil, tstbit, 1L);
  231. rec_locking(REC_UNLOCK, chgfil, outnode, 1L);
  232.  
  233. return;
  234. }
  235.  
  236.