home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / TIMEXSRC.ZIP / UA_BAIF.C < prev    next >
C/C++ Source or Header  |  1990-03-29  |  8KB  |  335 lines

  1. /* ua_baif.c -- Generalized interface to background agent, for TIMEXUA.
  2.  
  3.     February 1990    Mark E. Mallett, Personal Workstation Magazine
  4.  
  5. This file contains routines that map to the TIMEXUA requests.  These
  6. routines are:
  7.  
  8.         ba_add          Add an event
  9.         ba_del          Delete an event
  10.         ba_get          Get Event
  11.         ba_getnext      Get Next Event
  12.         ba_modify       Modify an event
  13.  
  14. */
  15.  
  16. #define INCL_BASE
  17.  
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <os2.h>
  21.  
  22. #include "timex.h"
  23. #include "ua_timex.h"
  24. #include "evpack.h"
  25. #include "ua_baif.h"
  26.  
  27. /* Local definitions */
  28.  
  29.  
  30. /* External data referenced */
  31.  
  32.  
  33. /* External routines used */
  34.  
  35.  
  36. /* Local data publicly available */
  37.  
  38.  
  39. /* Local routines and forward declarations */
  40.  
  41. static  EVENT   *ba_evgetname( int fcode, char *evnameP );
  42. static  int     ba_req(void);
  43.  
  44.  
  45. /* Private data */
  46.  
  47. static  USHORT  Rsplen;                 /* Response length */
  48. static  char    Reqbuf[512];            /* Request buffer */
  49. static  char    Rspbuf[512];            /* Response buffer */
  50.  
  51.  
  52. /*
  53.  
  54. *//* ba_add( eventP )
  55.  
  56.         Add a new event to the database
  57.  
  58. Accepts :
  59.  
  60.         eventP          Ptr to new event
  61.  
  62. Returns :
  63.  
  64.         <value>         TRUE if OK
  65.                         FALSE if problem
  66.  
  67. */
  68.  
  69. int
  70. ba_add(
  71.         EVENT           *eventP         /* Ptr to the event */
  72. ) {
  73.         TMXMSG          *reqP;          /* Ptr to request block */
  74.  
  75.     reqP = (TMXMSG *)&Reqbuf[0];
  76.  
  77.     /* Format the request */
  78.     reqP->m_code = REQ_ADD;
  79.     reqP->m_len = sizeof( TMXMSG );
  80.     reqP->m_len += event_pack( eventP, (char *)&reqP[1],
  81.                                  512 - sizeof(TMXMSG) );
  82.  
  83.     /* Send off the request... */
  84.     return( ba_req() );
  85. }
  86. /*
  87.  
  88. *//* ba_del( evnameP )
  89.  
  90.         Delete an event in the database
  91.  
  92. Accepts :
  93.  
  94.         evnameP         Ptr to name of event to delete
  95.  
  96. Returns :
  97.  
  98.         <value>         TRUE if OK
  99.                         FALSE if problem
  100.  
  101. */
  102.  
  103. int
  104. ba_del(
  105.         char            *evnameP        /* Ptr to name */
  106. ) {
  107.  
  108.         TMXREQ_DEL      *reqP;          /* Ptr to request block */
  109.  
  110.     reqP = (TMXREQ_DEL *)&Reqbuf[0];
  111.  
  112.     /* Format the request */
  113.     reqP->d_msghdr.m_code = REQ_DEL;
  114.     strcpy( (char *)&reqP->d_evname[0], evnameP );
  115.     reqP->d_msghdr.m_len = sizeof( TMXREQ_DEL ) + strlen( evnameP );
  116.  
  117.     /* Send off the request... */
  118.     return( ba_req() );
  119. }
  120. /*
  121.  
  122. *//* ba_get( evnameP )
  123.  
  124.         Get an event by name
  125.  
  126. Accepts :
  127.  
  128.         evnameP         The name of the event
  129.  
  130. Returns :
  131.  
  132.         < value >       The EVENT retrieved,
  133.                         NULL if error or not found
  134.  
  135. */
  136.  
  137. EVENT *
  138. ba_get(
  139.         char            *evnameP        /* Name of the event */
  140. ) {
  141.  
  142.     /* Hand off to general event-getter */
  143.     return( ba_evgetname( REQ_GET, evnameP ) );
  144. }
  145. /*
  146.  
  147. *//* ba_getnext( evnameP )
  148.  
  149.         Get next event by name
  150.  
  151. Accepts :
  152.  
  153.         evnameP         The name of the prior event
  154.  
  155. Returns :
  156.  
  157.         < value >       The EVENT retrieved,
  158.                         NULL if error or not found
  159.  
  160. */
  161.  
  162. EVENT *
  163. ba_getnext(
  164.         char            *evnameP        /* Name of the event */
  165. ) {
  166.  
  167.     /* Hand off to general event-getter */
  168.     return( ba_evgetname( REQ_GETNEXT, evnameP ) );
  169. }
  170. /*
  171.  
  172. *//* ba_modify( evnameP, eventP )
  173.  
  174.         Modify an event in the database
  175.  
  176. Accepts :
  177.  
  178.         evnameP         Ptr to name of event to modify
  179.         eventP          Ptr to new info for the event
  180.  
  181. Returns :
  182.  
  183.         <value>         TRUE if OK
  184.                         FALSE if problem
  185.  
  186. */
  187.  
  188. int
  189. ba_modify(
  190.         char            *evnameP,       /* Ptr to name */
  191.         EVENT           *eventP         /* Ptr to the event */
  192. ) {
  193.         int             len;            /* Length */
  194.         char            *bufP;          /* Ptr to buffer */
  195.         TMXMSG          *reqP;          /* Ptr to request block */
  196.  
  197.     reqP = (TMXMSG *)&Reqbuf[0];
  198.  
  199.     /* Format the request */
  200.     reqP->m_code = REQ_MODIFY;
  201.     reqP->m_len = sizeof( TMXMSG );
  202.     bufP = (char *)&reqP[1];
  203.  
  204.     strcpy( bufP, evnameP );
  205.     len = strlen( bufP ) +1;
  206.     reqP->m_len += len;
  207.     bufP += len;
  208.  
  209.     len = event_pack( eventP, bufP, 512 - reqP->m_len );
  210.     reqP->m_len += len;
  211.  
  212.     /* Send off the request... */
  213.     return( ba_req() );
  214. }
  215. /*
  216.  
  217. *//* ba_evgetname( fcode, evnameP )
  218.  
  219.         Issue a name-based event-getting request
  220.  
  221. Accepts :
  222.  
  223.         fcode           Function code
  224.         evnameP         Name of event
  225.  
  226.  
  227. Returns :
  228.  
  229.         < value >       Ptr to EVENT struct if OK,
  230.                         NULL if not.
  231.  
  232. */
  233.  
  234. EVENT *
  235. ba_evgetname(
  236.         int             fcode,          /* Function code */
  237.         char            *evnameP        /* Name for function */
  238. ) {
  239.         TMXREQ_GETNEXT  *reqP;          /* Request ptr */
  240.         TMXMSG          *rspP;          /* Response ptr */
  241.  
  242.     /* Fill in the request block */
  243.     reqP = (TMXREQ_GETNEXT *)&Reqbuf[0];
  244.     reqP->g_msghdr.m_code = fcode;
  245.     reqP->g_msghdr.m_len = sizeof(TMXREQ_GETNEXT) + strlen( evnameP );
  246.  
  247.     strcpy( &reqP->g_evname[0], evnameP );
  248.  
  249.     /* Make the request */
  250.     if ( !ba_req() )
  251.         return( NULL );
  252.  
  253.     /* If no event returned, return NULL */
  254.     rspP = (TMXMSG *)&Rspbuf[0];
  255.     if ( rspP->m_code != RSP_EVENT )
  256.         return( NULL );
  257.  
  258.     /* Return the event */
  259.     return( event_unpack( (char *)&rspP[1], rspP->m_len - sizeof(TMXMSG) ) );
  260. }
  261. /*
  262.  
  263. *//* ba_req()
  264.  
  265.         Make a request of the background agent.
  266.  
  267. Accepts :
  268.  
  269.         Reqbuf          Request data in proper format
  270.  
  271.  
  272. Returns :
  273.  
  274.         < value >       TRUE if request made OK
  275.                         FALSE if problem making request
  276.         Rspbuf          Response data
  277.  
  278. */
  279.  
  280. static int
  281. ba_req( void ) {
  282.  
  283.         int             status;         /* Status code */
  284.         USHORT          action;         /* Response from DosOpen */
  285.         HPIPE           pipeH;          /* Pipe handle */
  286.         TMXMSG          *reqP;          /* Request ptr */
  287.         TMXMSG          *rspP;          /* Response ptr */
  288.         TMXRSP_ERR      *errP;          /* Error block */
  289.  
  290.     /* Open a connection to the background agent */
  291.  
  292.     /* For some reason, OS/2 doesn't mediate pipe-busy's.  Have to
  293.         do it by hand!!! */
  294.  
  295.     for( ; ; ) {
  296.  
  297.         status = DosOpen( REQPIPE, &pipeH, &action, 0L, 0,
  298.                         FILE_OPEN,
  299.                         OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
  300.                         0L );
  301.  
  302.         if ( status == 0 )              /* Opened? */
  303.             break;
  304.  
  305.         if ( status != ERROR_PIPE_BUSY ) {
  306.             warning( EC_NOTOK, "Can't contact background agent." );
  307.             return( FALSE );
  308.         }
  309.  
  310.         DosWaitNmPipe( REQPIPE, (ULONG)60000 );
  311.     }
  312.  
  313.     /* Make the request */
  314.     reqP = (TMXMSG *)&Reqbuf[0];
  315.  
  316.     status = DosTransactNmPipe( pipeH, &Reqbuf[0], reqP->m_len,
  317.                 &Rspbuf[0], 512, &Rsplen );
  318.     DosClose( pipeH );
  319.  
  320.     if ( status != 0 ) {
  321.         warning( EC_NOTOK, "Can't send to background agent." );
  322.         return( FALSE );
  323.     }
  324.  
  325.     rspP = (TMXMSG *)&Rspbuf[0];
  326.     if ( rspP->m_code == RSP_ERROR ) {
  327.         errP = (TMXRSP_ERR *)rspP;
  328.         warning( EC_NOTOK, "Error %d: %s", errP->e_code, &errP->e_msg[0] );
  329.         return( FALSE );
  330.     }
  331.  
  332.     return( TRUE );
  333. }
  334.  
  335.