home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / top2src.zip / OS2.ZIP / BBSMAXMC.C next >
C/C++ Source or Header  |  1998-01-14  |  11KB  |  327 lines

  1. /******************************************************************************
  2. BBSMAXMC.C   Implements Maximus for OS/2 v3.xx BBS functions.
  3. Copyright 1993 - 1998 Paul Sidorsky, All Rights Reserved
  4. Based on Scott Dudley's example code in MAX_CHAT.C and MCP.H.
  5.  
  6. The module contains all of the functions for interfacing with Maximus for OS/2
  7. v3.xx.  Two calls are used from BBSMAX.C.
  8.  
  9. NOTE:  This module contains OS/2 specific code and should not be included in a
  10. DOS or Win32 build.
  11. ******************************************************************************/
  12. #include "top.h"
  13.  
  14. /* The last MCP page is stored to compensate for Maximus thinking there
  15.    are two "copies" of each node.  See TOP/2's MAXOS2V3.DOC for details. */
  16. char *lastmcppage;
  17.  
  18. /* max_mcpinit() - Initialize pointers to Maximus MCP interface functions.
  19.    Paremeters:  None.
  20.    Returns:  Nothing.
  21. */
  22. void max_mcpinit(void)
  23.     {
  24.  
  25.     bbs_call_loaduseron = max_loadmcpstatus;
  26.     bbs_call_saveuseron = max_savemcpstatus;
  27.     bbs_call_processmsgs = max_processmcpmsgs;
  28.     bbs_call_page = max_mcppage;
  29.     bbs_call_setexistbits = max_setexistbits;
  30.     bbs_call_login = max_mcplogin;
  31.     bbs_call_logout = max_mcplogout;
  32.     bbs_call_openfiles = max_mcpopenpipe;
  33.     bbs_call_updateopenfiles = max_mcpopenpipe;
  34.     bbs_call_pageedit = max_shortpageeditor;
  35.  
  36.     lastmcppage = malloc(4096);
  37.     lastmcppage[0] = '\0';
  38.  
  39.     }
  40.  
  41. /* max_loadmcpstatus() - Retrieves a node's status from the MCP.
  42.    Parameters:  nodenum - Node number to load the data for.
  43.                 userdata - Pointer to generic BBS data structure to fill.
  44.    Returns:  TRUE if an error occurred, FALSE if successful.
  45. */
  46. char max_loadmcpstatus(XINT nodenum, bbsnodedata_typ *userdata)
  47.     {
  48.     struct _mcpcstat cs; /* Maximus MCP node status buffer. */
  49.     USHORT si; /* Size of the message.  Not used. */
  50.  
  51.     /* Maximus doesn't support Node 0. */
  52.     if (nodenum == 0)
  53.         {
  54.         return 1;
  55.         }
  56.  
  57.     /* Retreive the status from the MCP. */
  58.     McpSendMsg(hpMCP, PMSG_QUERY_ACTIVE, (BYTE *) &nodenum, 2);
  59.     McpGetMsg(hpMCP, (BYTE *) &cs, &si, sizeof(struct _mcpcstat));
  60.  
  61.     /* Abort if nobody's online (blank name). */
  62.     if (!cs.username[0])
  63.         {
  64.         return 1;
  65.         }
  66.  
  67.     /* Copy the information to the generic BBS structure. */
  68.     strcpy(userdata->handle, cs.username);
  69.     strcpy(userdata->realname, cs.username);
  70.     userdata->node = nodenum;
  71.     strcpy(userdata->statdesc, cs.status);
  72.     userdata->quiet = !cs.avail;
  73.  
  74.     return 0;
  75.     }
  76.  
  77. /* max_savemcpstatus() - Saves a node status to the MCP.
  78.    Parameters:  nodenum - Node number to save the data for.
  79.                 userdata - Pointer to generic BBS data structure to use.
  80.    Returns:  TRUE if an error occurred, FALSE if successful.
  81. */
  82. char max_savemcpstatus(XINT nodenum, bbsnodedata_typ *userdata)
  83.     {
  84.     struct _mcpcstat cs; /* Maximus MCP node status buffer. */
  85.  
  86.     /* The node number is not used because the MCP will know which node is
  87.        sending the message. */
  88.     (void) nodenum;
  89.  
  90.     /* Initialize the node status data. */
  91.     memset(&cs, 0, sizeof(struct _mcpcstat));
  92.     strcpy(cs.username,
  93.            cfg.usehandles ? userdata->handle : userdata->realname);
  94.     strcpy(cs.status, userdata->statdesc);
  95.     cs.avail = 1;
  96.  
  97.     /* Set the status using the MCP. */
  98.     McpSendMsg(hpMCP, PMSG_SET_STATUS, (BYTE *) &cs,
  99.                sizeof(struct _mcpcstat));
  100.  
  101.     return 0;
  102.     }
  103.  
  104. /* max_processmpcmsgs() - Reads and displays messages from the MCP.
  105.    Parameters:  None.
  106.    Returns:  Number of messages processed.  (0 on error.)
  107. */
  108. XINT max_processmcpmsgs(void)
  109.     {
  110.     ULONG bytes, status; /* Size and status holders. */
  111.     AVAILDATA ad; /* OS/2 pipe availability data. */
  112.     char tbuf[11], *msgbuf; /* Temporary buffer, message buffer. */
  113.     struct _mcpcdat cd; /* Maximus MCP message information buffer. */
  114.  
  115.     /* Check the pipe to see if there's something to get. */
  116.     if (DosPeekNPipe(hpMCP, tbuf, 1, &bytes, &ad, &status))
  117.         {
  118.         return 0;
  119.         }
  120.     if (!bytes)
  121.         {
  122.         return 0;
  123.         }
  124.  
  125.     /* Allocate the buffer for the incoming message. */
  126.     msgbuf = malloc(ad.cbmessage);
  127.     if (msgbuf == NULL)
  128.         {
  129.         return 0;
  130.         }
  131.  
  132.     if (!DosRead(hpMCP, msgbuf, ad.cbmessage, &bytes))
  133.         {
  134.         if (* (USHORT *) msgbuf == RPMSG_GOT_MSG)
  135.             {
  136.             /* Retrieve the incoming message. */
  137.             memcpy(&cd, msgbuf + sizeof(USHORT), sizeof(struct _mcpcdat));
  138.             memmove(msgbuf,
  139.                     msgbuf + sizeof(USHORT) + sizeof(struct _mcpcdat),
  140.                     min(ad.cbmessage, cd.len));
  141.             /* Don't display this message if it's the same as the last one.
  142.                See beginning of this file for explanation. */
  143.             if (!strcmp(lastmcppage, msgbuf))
  144.                 {
  145.                 lastmcppage[0] = '\0';
  146.                 dofree(msgbuf);
  147.                 return 0;
  148.                 }
  149.             /* Save this message for duplicate detection. */
  150.             strcpy(lastmcppage, msgbuf);
  151.             if (cd.type == CMSG_HEY_DUDE)
  152.                 {
  153.                 /* Display the message to the user. */
  154.                 max_showmeccastring(msgbuf);
  155.                 dofree(msgbuf);
  156.                 return 1;
  157.                 }
  158.             else
  159.                 {
  160.                 /* All other message types are ignored. */
  161.                 dofree(msgbuf);
  162.                 return 0;
  163.                 }
  164.             }
  165.         }
  166.  
  167.     dofree(msgbuf);
  168.  
  169.     return 0;
  170.     }
  171.  
  172. /* max_mcppage() - Sends a page to a Maximus MCP node.
  173.    Parameters:  nodenum - Node number to page.
  174.                 pagebuf - Text to send.
  175.    Returns:  TRUE if successful, FALSE if an error occurred.
  176.    Notes:  pagebuf should contain the text to send, and it must also be big
  177.            enough to have the page header and footer appended.
  178. */
  179. char max_mcppage(XINT nodenum, unsigned char *pagebuf)
  180.     {
  181.     XINT len, slen, slenf; /* Length, header length, footer length. */
  182.     char *buf; /* Output buffer. */
  183.     struct _mcpcdat *pcd; /* Maximus MCP node information buffer. */
  184.     ULONG bytes; /* Size holder. */
  185.  
  186.  
  187.     /* Get the header and footer lengths. */
  188.     itoa(od_control.od_node, outnum[0], 10);
  189.     slen = strlen(top_output(OUT_STRINGNF, getlang("MaxPageHeader"),
  190.                              cfg.usehandles ? user.handle : user.realname,
  191.                              outnum[0]));
  192.     slenf = strlen(top_output(OUT_STRINGNF, getlang("MaxPageFooter")));
  193.     len = strlen(pagebuf) + 1 + slen + slenf;
  194.     /* Allocate the memory to store the entire message. */
  195.     buf = malloc(len + sizeof(USHORT) + sizeof(struct _mcpcdat));
  196.     if (buf == NULL)
  197.         {
  198.         od_log_write(top_output(OUT_STRING, getlang("LogOutOfMemory")));
  199.         return -1;
  200.         }
  201.  
  202.     /* Prepare the message information. */
  203.     * (USHORT *) buf = PMSG_MAX_SEND_MSG;
  204.     pcd = (struct _mcpcdat *) (buf + sizeof(USHORT));
  205.     pcd->tid = od_control.od_node;
  206.     pcd->dest_tid = nodenum;
  207.     pcd->type = CMSG_HEY_DUDE;
  208.     pcd->len = len;
  209.  
  210.     /* Copy the page header, then the page itself, then the footer. */
  211.     itoa(od_control.od_node, outnum[0], 10);
  212.     memcpy(buf + sizeof(USHORT) + sizeof(struct _mcpcdat),
  213.            top_output(OUT_STRINGNF, getlang("MaxPageHeader"),
  214.                       cfg.usehandles ? user.handle : user.realname,
  215.                       outnum[0]), slen);
  216.     memmove(buf + sizeof(USHORT) + sizeof(struct _mcpcdat) + slen, pagebuf,
  217.             strlen(pagebuf));
  218.     memmove(buf + sizeof(USHORT) + sizeof(struct _mcpcdat) + slen +
  219.             strlen(pagebuf),
  220.             top_output(OUT_STRINGNF, getlang("MaxPageFooter")), slenf);
  221.  
  222.     /* Write the page to the pipe. */
  223.     itoa(nodenum, outnum[0], 10);
  224.     if (DosWrite(hpMCP, buf, len + sizeof(USHORT) + sizeof(struct _mcpcdat),
  225.                  &bytes) != 0)
  226.         {
  227.         top_output(OUT_SCREEN, getlang("CantPage"), outnum[0]);
  228.         return -1;
  229.         }
  230.  
  231.     free(buf);
  232.  
  233.     top_output(OUT_SCREEN, getlang("Paged"), outnum[0]);
  234.     return 0;
  235.     }
  236.  
  237. /* max_mcplogin() - Maximus MCP initialization when TOP is started.
  238.    Parameters:  None.
  239.    Returns:  Nothing.
  240. */
  241. void max_mcplogin(void)
  242.     {
  243.      /* Generic BBS data buffer, login check BBS data buffer.*/
  244.     bbsnodedata_typ bd, logintmp;
  245.     int res;
  246.  
  247.     /* Check if the node is already logged in RA/SBBS. */
  248.     res = max_loadmcpstatus(od_control.od_node, &logintmp);
  249.     if (!res)
  250.         {
  251.         /* Set the do not disturb flag. */
  252.         node->quiet = bd.quiet = logintmp.quiet;
  253.         save_node_data(od_control.od_node, node);
  254.         }
  255.  
  256.     /* Copy the user information into the generic BBS data buffer. */
  257.     strcpy(bd.realname, user.realname);
  258.     strcpy(bd.handle, user.handle);
  259.     bd.node = od_control.od_node;
  260.     strcpy(bd.statdesc,
  261.            top_output(OUT_STRING, getlang("NodeStatus")));
  262.  
  263.     /* Send the status information to the MCP. */
  264.     max_savemcpstatus(od_control.od_node, &bd);
  265.  
  266.     }
  267.  
  268. /* max_mcplogout() - Maximus deinitialization when TOP is exited.
  269.    Parameters:  None.
  270.    Returns:  Nothing.
  271. */
  272. void max_mcplogout(void)
  273.     {
  274.  
  275.     /* Tell the MCP we're leaving. */
  276.     if (hpMCP)
  277.         {
  278.         McpSendMsg(hpMCP, PMSG_EOT, NULL, 0);
  279.         DosClose(hpMCP);
  280.         hpMCP = 0;
  281.         }
  282.  
  283.     dofree(lastmcppage);
  284.  
  285.     }
  286.  
  287. /* max_mcpopenpipe() - Establishes connection to the Maximus MCP. */
  288.    Parameters:  None.
  289.    Returns:  Number of errors that occurred, or 0 on success.
  290. */
  291. XINT max_mcpopenpipe(void)
  292.     {
  293.     ULONG rc, action; /* Result code, action buffer (unused). */
  294.     unsigned char tid; /* Task ID (node number). */
  295.  
  296.     /* Don't open the MCP if it's already open.  This can happen in LAN
  297.        mode when the node number is changed. */
  298.     if (hpMCP)
  299.         {
  300.         return 0;
  301.         }
  302.  
  303.     /* Setup the pipe name. */
  304.     strcpy(outbuf, cfg.bbsmultipath);
  305.     strcat(outbuf, "maximus");
  306.     tid = od_control.od_node;
  307.  
  308.     /* Open the pipe. */
  309.     rc = DosOpen(outbuf, &hpMCP, &action, 0L, FILE_NORMAL,
  310.                  OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
  311.                  OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE |
  312.                  OPEN_FLAGS_NOINHERIT, NULL);
  313.     if (rc == 0)
  314.         {
  315.         /* Tell the MCP we're here. */
  316.         McpSendMsg(hpMCP, PMSG_HELLO, &tid, 1);
  317.         }
  318.     else
  319.         {
  320.         hpMCP = 0;
  321.         return 1;
  322.         }
  323.  
  324.     return 0;
  325.     }
  326.  
  327.