home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / LANMAN.ZIP / SIGNALS.C < prev   
C/C++ Source or Header  |  1991-01-01  |  11KB  |  286 lines

  1. /*-------------------------------------------------------------------
  2.   SIGNALS.C -- PBX signal related routines
  3.  
  4.   Description:
  5.  
  6.   This file contains the routines used by PBX to install an OS/2
  7.   signal handler and to process incoming signals.
  8.  
  9.   Author:  Brendan Dixon
  10.            Microsoft, inc.
  11.            LAN Manager Developer Support
  12.  
  13.   This code example is provided for demonstration purposes only.
  14.   Microsoft makes no warranty, either express or implied,
  15.   as to its usability in any given situation.
  16. -------------------------------------------------------------------*/
  17.  
  18. // Includes ---------------------------------------------------------
  19. #define   INCL_DOS
  20. #define   INCL_DOSERRORS
  21. #include  <os2.h>
  22.  
  23. #define   INCL_NETHANDLE
  24. #define   INCL_NETMESSAGE
  25. #define   INCL_NETSERVICE
  26. #define   INCL_NETERRORS
  27. #include  <lan.h>
  28.  
  29. typedef struct handle_info_2 HDLI2;   // NetHandleGetInfo structure
  30.  
  31. #include  <stdio.h>
  32. #include  <string.h>
  33.  
  34. #include  "pbxsrv.h"
  35.  
  36.  
  37. /* ExitHandler ------------------------------------------------------
  38.   Description:  Perform clean-up processing and shut down the PBX
  39.   Input      :  None, Exit codes and text are taken from global
  40.                 variables
  41.   Ouput      :  Control is returned to OS/2
  42. -------------------------------------------------------------------*/
  43. void ExitHandler(void)
  44. {
  45.   CHAR    pszBuf[sizeof(HDLI2)+UNCLEN+1]; // Buffer
  46.   HDLI2   *phdli2 = (HDLI2 *)pszBuf;      // NetHandleGetInfo pointer
  47.   USHORT  usByteCnt;                      // Bytes returned
  48.   USHORT  usCIndex;                       // Routing table index
  49.   CHAR    pszMsg[255];                    // Shutdown message buffer
  50.   USHORT  usWCnt;                         // Uninstall wait counter
  51.   USHORT  usRetCode;                      // Return code
  52.  
  53.   // Inform LAN Manager that this service is being uninstalled
  54.   usWCnt = 0;
  55.   ssStatus.svcs_status = SERVICE_UNINSTALL_PENDING;
  56.   ssStatus.svcs_code   = SERVICE_CCP_CODE(PBXUNINSTALLTIME,
  57.                                           usWCnt++);
  58.   NetServiceStatus((char _far *)&ssStatus, sizeof(ssStatus));
  59.  
  60.   // Inform registered clients that PBX is shutting down
  61.   if (pbPBXMem           != NULL &&       // PBX memory obtained
  62.       pbPBXMem->abRTable != NULL  ) {     // Routing table obtained
  63.     // Build shut down message
  64.     sprintf(pszMsg, PBXSHUTDOWNMSG, pbPBXMem->pszPBXMsg);
  65.  
  66.     for (usCIndex=0; usCIndex < pbPBXMem->usLines; usCIndex++) {
  67.       if (pbPBXMem->abRTable[usCIndex].fState > Open) {
  68.         // Get client computer name
  69.         usRetCode =
  70.             NetHandleGetInfo(
  71.                   pbPBXMem->abRTable[usCIndex].hLine, // Pipe handle
  72.                   2,                                  // Info level
  73.                   pszBuf,                             // Buffer
  74.                   sizeof(pszBuf),                     // Size
  75.                   &usByteCnt);                     // Bytes returned
  76.  
  77.         // If computer name was returned, send client a message
  78.         if (usRetCode == NERR_Success) {
  79.           NetMessageBufferSend(NULL,                   // Local
  80.                                phdli2->hdli2_username, // Target
  81.                                pszMsg,                 // Message
  82.                                strlen(pszMsg)+1);      // Size
  83.         }
  84.  
  85.         // Provide LAN Manager with a status hint
  86.         ssStatus.svcs_status = SERVICE_UNINSTALL_PENDING;
  87.         ssStatus.svcs_code   = SERVICE_CCP_CODE(PBXINSTALLTIME,
  88.                                                 usWCnt++);
  89.         NetServiceStatus((char _far *)&ssStatus, sizeof(ssStatus));
  90.       }
  91.     }
  92.   }
  93.  
  94.   // Inform LAN Manager that this service has been uninstalled
  95.   ssStatus.svcs_status = SERVICE_UNINSTALLED;
  96.   ssStatus.svcs_code   = ulExitCode;
  97.   strcpy(ssStatus.svcs_text, pszExitText);
  98.   NetServiceStatus((char _far *)&ssStatus, sizeof(ssStatus));
  99.  
  100.   // Return control to OS/2
  101.   DosExit(EXIT_PROCESS, 0);
  102.  
  103.   return;
  104. }
  105.  
  106.  
  107. /* SignalHandler ----------------------------------------------------
  108.   Description:  Process system signals
  109.                 Signals should come (primarily) from two sources:
  110.                 LAN Manager and the PBX Service itself (during error
  111.                 handling)
  112.   Input      :  usSigArg --- Signal argument
  113.                 usSigNum --- Signal number
  114.                              (should only be SERVICE_RCV_SIG_FLAG)
  115.   Output     :  None
  116. -------------------------------------------------------------------*/
  117. void _far _pascal SignalHandler(USHORT usSigArg, USHORT usSigNum)
  118. {
  119.   UCHAR        fSigArg;                   // Signal argument
  120.   USHORT       usRetCode;                 // Return code
  121.  
  122.   // Extract signal argument from the first byte
  123.   fSigArg = (UCHAR)(usSigArg & 0x00FF);
  124.  
  125.   // And take the appropriate action
  126.   switch (fSigArg) {
  127.     // Uninstall PBXSRV.EXE
  128.     case SERVICE_CTRL_UNINSTALL:
  129.       DosSemSet(&(pbPBXMem->semExit));
  130.       ExitHandler();
  131.       break;
  132.  
  133.     // Pause all processing
  134.     case SERVICE_CTRL_PAUSE:
  135.       DosSemSet(&(pbPBXMem->semPause));
  136.       ssStatus.svcs_status = SERVICE_INSTALLED     |
  137.                              SERVICE_PAUSED        |
  138.                              SERVICE_UNINSTALLABLE |
  139.                              SERVICE_PAUSABLE;
  140.       ssStatus.svcs_code   = SERVICE_UIC_NORMAL;
  141.       usRetCode = NetServiceStatus((char _far *)&ssStatus,
  142.                                    sizeof(ssStatus));
  143.       if (usRetCode) {
  144.         ERRRPT("NetServiceStatus", usRetCode, Error);
  145.         ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM,
  146.                                       usRetCode);
  147.         ExitHandler();
  148.       }
  149.       break;
  150.  
  151.     // Continue (after a pause) processing
  152.     case SERVICE_CTRL_CONTINUE:
  153.       DosSemClear(&(pbPBXMem->semPause));
  154.       ssStatus.svcs_status = SERVICE_INSTALLED     |
  155.                              SERVICE_ACTIVE        |
  156.                              SERVICE_UNINSTALLABLE |
  157.                              SERVICE_PAUSABLE;
  158.       ssStatus.svcs_code   = SERVICE_UIC_NORMAL;
  159.       usRetCode = NetServiceStatus((char _far *)&ssStatus,
  160.                                    sizeof(ssStatus));
  161.       if (usRetCode) {
  162.         ERRRPT("NetServiceStatus", usRetCode, Error);
  163.         ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM,
  164.                                       usRetCode);
  165.         ExitHandler();
  166.       }
  167.       break;
  168.  
  169.     // Return service information
  170.     case SERVICE_CTRL_INTERROGATE:
  171.     default:
  172.       usRetCode = NetServiceStatus((char _far *)&ssStatus,
  173.                                    sizeof(ssStatus));
  174.       if (usRetCode) {
  175.         ERRRPT("NetServiceStatus", usRetCode, Error);
  176.         ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM,
  177.                                       usRetCode);
  178.         ExitHandler();
  179.       }
  180.       break;
  181.   }
  182.  
  183.   // Reset the signal handler to accept the next signal
  184.   usRetCode = DosSetSigHandler(0,
  185.                                0,
  186.                                0,
  187.                                SIGA_ACKNOWLEDGE,
  188.                                usSigNum);
  189.   if (usRetCode) {
  190.     ERRRPT("DosSetSigHandler", usRetCode, Error);
  191.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM,
  192.                                   usRetCode);
  193.     ExitHandler();
  194.   }
  195.  
  196.   return;
  197. }
  198.  
  199.  
  200. /* InstallSignals ---------------------------------------------------
  201.   Description:  Install signal handler for PBX
  202.   Input      :  None
  203.   Output     :  None
  204. -------------------------------------------------------------------*/
  205. void InstallSignals(void)
  206. {
  207.   // Values associated with the previous signal handler are not
  208.   // needed after this routine and therefore may be held in local
  209.   // variables
  210.   PFNSIGHANDLER fnSigHandler;             // Previous signal handler
  211.   USHORT        fSPrevAction;             // Previous signal action
  212.   USHORT        usRetCode;                // Return Code
  213.  
  214.   // The handler will be called only for SERVICE_RCV_SIG_FLAG
  215.   // signals (which are the same as SIG_PFLG_A).  This implies that
  216.   // LAN Manager will cover all CTRL+C, BREAK, and KILL signals
  217.   usRetCode = DosSetSigHandler(SignalHandler,
  218.                                &fnSigHandler,
  219.                                &fSPrevAction,
  220.                                SIGA_ACCEPT,
  221.                                SERVICE_RCV_SIG_FLAG);
  222.   if (usRetCode) {
  223.     ERRRPT("DosSetSigHandler", usRetCode, Error);
  224.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM, usRetCode);
  225.     ExitHandler();
  226.   }
  227.  
  228.   // Tell OS/2 that CTRL+C, BREAK, and KILL signals will not be
  229.   // processed by PBXSRV.EXEs signal handler
  230.   usRetCode = DosSetSigHandler(NULL,      // Ignore CTRL+C
  231.                                &fnSigHandler,
  232.                                &fSPrevAction,
  233.                                SIGA_IGNORE,
  234.                                SIG_CTRLC);
  235.   if (usRetCode) {
  236.     ERRRPT("DosSetSigHandler", usRetCode, Error);
  237.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM, usRetCode);
  238.     ExitHandler();
  239.   }
  240.   usRetCode = DosSetSigHandler(NULL,      // Ignore BREAK
  241.                                &fnSigHandler,
  242.                                &fSPrevAction,
  243.                                SIGA_IGNORE,
  244.                                SIG_CTRLBREAK);
  245.   if (usRetCode) {
  246.     ERRRPT("DosSetSigHandler", usRetCode, Error);
  247.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM, usRetCode);
  248.     ExitHandler();
  249.   }
  250.   usRetCode = DosSetSigHandler(NULL,      // Ignore KILL
  251.                                &fnSigHandler,
  252.                                &fSPrevAction,
  253.                                SIGA_IGNORE,
  254.                                SIG_KILLPROCESS);
  255.   if (usRetCode) {
  256.     ERRRPT("DosSetSigHandler", usRetCode, Error);
  257.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM, usRetCode);
  258.     ExitHandler();
  259.   }
  260.  
  261.   // However, a SIG_PFLG_B and SIG_PFLG_C signal should cause errors
  262.   // (since they shouldn't occur)
  263.   usRetCode = DosSetSigHandler(NULL,      // SIG_PFLG_B is an error
  264.                                &fnSigHandler,
  265.                                &fSPrevAction,
  266.                                SIGA_ERROR,
  267.                                SIG_PFLG_B);
  268.   if (usRetCode) {
  269.     ERRRPT("DosSetSigHandler", usRetCode, Error);
  270.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM, usRetCode);
  271.     ExitHandler();
  272.   }
  273.   usRetCode = DosSetSigHandler(NULL,      // SIG_PFLG_C is an error
  274.                                &fnSigHandler,
  275.                                &fSPrevAction,
  276.                                SIGA_ERROR,
  277.                                SIG_PFLG_C);
  278.   if (usRetCode) {
  279.     ERRRPT("DosSetSigHandler", usRetCode, Error);
  280.     ulExitCode = SERVICE_UIC_CODE(SERVICE_UIC_SYSTEM, usRetCode);
  281.     ExitHandler();
  282.   }
  283.  
  284.   return;
  285. }
  286.