Example: Using SNA/Management Services Transport APIs

This example shows a source and target application in ILE C that use the Systems Network Architecture (SNA) Management Services Transport APIs to send and receive management services data.

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.

Source application program

This source application program sends management services transport requests to a target application program.

/*********************************************************************/
/*********************************************************************/
/*                                                                   */
/* FUNCTION:                                                         */
/*  This is a source application that uses the management services   */
/*  transport APIs.  It does the following:                          */
/*   1.  Prompts for the network ID and CP name of the remote system */
/*       where target application MSTTARG has been started.          */
/*   2.  Prompts for data to be sent to MSTTARG.                     */
/*   3.  Prompts for whether or not a reply is required.             */
/*   4.  Sends a management services transport request to MSTTARG.   */
/*   5.  Repeats steps 2-4 until QUIT is entered.                    */
/*                                                                   */
/* Note: MSTTARG may be ended by this application by sending it the  */
/*        string "ENDRMTAPP".                                        */
/*                                                                   */
/* LANGUAGE:  ILE C                                                  */
/*                                                                   */
/* APIs USED: QNMSTRAP, QNMENDAP, QNMRCVDT,                          */
/*            QNMSNDRQ, QNMCHGMN, QNMENDAP                           */
/*                                                                   */
/*********************************************************************/
/*********************************************************************/
/* Includes                                                          */
/*********************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NOERROR "NOERROR"
#define RQSONLY "*RQS      "
#define RQSRPY "*RQSRPY   "

/*-------------------------------------------------------------------*/
/* Type definitions                                                  */
/*-------------------------------------------------------------------*/
typedef int HANDLE;                 /* typedef for handle            */
typedef char APPLNAME[8];           /* typedef for application name  */
typedef char NETID[8];              /* typedef for network ID        */
typedef char CPNAME[8];             /* typedef for control point name*/
typedef char MODENAME[8];           /* typedef for mode name         */
typedef char SENSECODE[8];          /* typedef for SNA sense code (in
                                       character format)             */
typedef char LIBNAME[10];           /* typedef for library name      */
typedef char QNAME[10];             /* typedef for data queue name   */
typedef char MSGID[7];              /* typedef for message ID        */
typedef char EXCPDATA[48];          /* typedef for exception data    */
typedef char CATEGORY[8];           /* typedef for category          */
typedef char APPLTYPE[10];          /* typedef for application type  */
typedef char REPLREG[10];           /* typedef for replace
                                       registration                  */
typedef char DATARCVD[10];          /* typedef for data received     */
typedef char REQTYPE[10];           /* typedef for request type      */
typedef char POSTRPL[10];           /* typedef for post reply        */
typedef char REQUESTID[53];         /* typedef for request ID        */
typedef char SRBUFFER[500];         /* typedef for send/receive
                                       buffer.  This program limits
                                       the amount of data to be sent
                                       or received to 500 bytes.  The
                                       maximum size of a management
                                       services transport buffer is
                                       31739.                        */

typedef struct {                    /* Library-qualified data queue
                                       name                          */
   QNAME data_queue_name;           /* data queue name               */
   LIBNAME library_name;            /* library name                  */
  } QUALQNAME;

typedef struct {                    /* Error code structure          */
   int bytes_provided;              /* number of bytes provided      */
   int bytes_available;             /* number of bytes available     */
   MSGID exception_ID;              /* exception ID                  */
   char reserved_area;              /* reserved                      */
   EXCPDATA exception_data;         /* exception data                */
  } ERRORCODE;

typedef struct {                    /* Notification record structure */
   char record_type[10];            /* Record type                   */
   char function[2];                /* Function                      */
   HANDLE handle;                   /* Handle                        */
   REQUESTID req_id;                /* Request ID                    */
   char reserved[11];               /* Reserved area                 */
  } NOTIFRCD;

typedef struct {                    /* Receiver variable structure   */
   int bytes_provided;              /* number of bytes provided      */
   int bytes_available;             /* number of bytes available     */
   SRBUFFER received_data;          /* received data                 */
  } RECEIVERVAR;

typedef struct {                    /* Qualified application name    */
   NETID network_id;                /* Network ID                    */
   CPNAME cp_name;                  /* Control point name            */
   APPLNAME app_name;               /* Application name              */
  } QUALAPPL;

/*-------------------------------------------------------------------*/
/* External program declarations                                     */
/*-------------------------------------------------------------------*/
#pragma linkage(QNMSTRAP, OS)       /* Start application API         */
extern void QNMSTRAP (HANDLE *handle, /* pointer to handle           */
                      APPLNAME *applname, /* pointer to appl name    */
                      QUALQNAME *qualqname, /* pointer to data queue
                                       name                          */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

#pragma linkage(QNMENDAP, OS)       /* End application API           */
extern void QNMENDAP (HANDLE *handle, /* pointer to handle           */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

#pragma linkage(QNMRCVDT, OS)       /* Receive data API              */
extern void QNMRCVDT (HANDLE *handle, /* pointer to handle           */
                      RECEIVERVAR *rcvvar, /* pointer to receiver
                                       variable                      */
                      int *rcvvarln, /* pointer to receiver variable
                                       length                        */
                      REQUESTID *reqid, /* pointer to request ID     */
                      QUALAPPL *qualappl, /* pointer to remote
                                       application name              */
                      DATARCVD *datarcvd, /* pointer to type of data
                                       received                      */
                      int *waittim, /* pointer to wait time          */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

#pragma linkage(QNMSNDRQ, OS)       /* Send request API              */
extern void QNMSNDRQ (HANDLE *handle, /* pointer to handle           */
                      QUALAPPL *qualappl, /* pointer to remote
                                       application name              */
                      REQUESTID *reqid, /* pointer to request ID     */
                      SRBUFFER *sndbuf, /* pointer to send buffer    */
                      int *sndbufln, /* pointer to send buffer length*/
                      REQTYPE *reqtype, /* pointer to request type   */
                      POSTRPL *postrpl, /* pointer to post reply     */
                      int *waittim, /* pointer to wait time          */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

#pragma linkage(QNMCHGMN, OS)       /* Change mode name API          */
extern void QNMCHGMN (HANDLE *handle, /* pointer to handle           */
                      MODENAME *modename, /* pointer to mode name    */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

void check_error_code (char func_name[8]); /* Used to check error code
                                                                     */
void get_network_id (void);         /* Get network ID of destination
                                       node                          */
void get_cp_name (void);            /* Get CP name of destination
                                       node                          */
void process_replies(void);         /* Process replies received from
                                       destination application       */

/*-------------------------------------------------------------------*/
/* Global declarations                                               */
/*-------------------------------------------------------------------*/
 HANDLE appl_handle;                /* Handle of application         */
 ERRORCODE error_code_struc =       /* Error code parameter          */
           {sizeof(error_code_struc),  /* Initialize bytes provided  */
            0,                      /* initialize bytes available    */
            NOERROR};               /* initialize error code         */
 char input_line[80];               /* Input data                    */
 QUALAPPL qual_appl =               /* Qualified application name    */
        {"        ","        ","        "};
 REQUESTID req_id;                  /* Returned request ID           */
 int wait_time = -1;                /* Wait time = wait forever      */

/*-------------------------------------------------------------------*/
/* Start of main.                                                    */
/*-------------------------------------------------------------------*/
int main ()
{
 APPLNAME appl_name = "MSTSOURC";   /* Application name to be used   */
 QUALQNAME data_queue_parm =        /* Data queue name to be used    */
           {"*NONE     ", "          "}; /* Initialize structure     */
 NOTIFRCD notif_record;             /* Area to contain notification
                                       record                        */
 CATEGORY category = "*NONE   ";    /* SNA/Management Services function
                                       set group                     */
 APPLTYPE appl_type = "*FPAPP    "; /* Application type              */
 REPLREG replace_reg = "*YES      "; /* Replace registration = *YES  */
 int sys_result;                    /* Result of system function     */
 char end_msg[] = "ENDRMTAPPL";     /* If this data is received then
                                       the application will end      */
 char incoming_data[] = "01";       /* Incoming data constant        */
 SRBUFFER send_buffer;              /* Send buffer                   */
 int data_length;                   /* Length of send data           */
 char input_char;                   /* Input character               */
 REQTYPE req_type;                  /* Request type                  */
 POSTRPL post_reply = "*NO       "; /* Don't post any received replies
                                                                     */
 MODENAME mode_name = "#INTER  ";   /* Mode name = #INTER            */

/*-------------------------------------------------------------------*/
/* Start of code                                                     */
/*-------------------------------------------------------------------*/
 QNMSTRAP (&appl_handle,
           &appl_name,
           &data_queue_parm,
           &error_code_struc);      /* Start application             */
 check_error_code("QNMSTRAP");      /* Check error code              */
 QNMCHGMN (&appl_handle,
           &mode_name,
           &error_code_struc);      /* Change mode name              */
 check_error_code("QNMCHGMN");      /* Check error code              */
 get_network_id();                  /* Get network ID                */
 get_cp_name();                     /* Get CP name                   */
 memcpy(qual_appl.app_name,
        "MSTTARG ",
        sizeof(qual_appl.app_name)); /* Copy application name        */
 printf ("Enter message to send to remote application or "
         "QUIT to end\n");
 gets(input_line);
 while (memcmp(input_line,
               "QUIT",
               sizeof("QUIT")) != 0) /* While an ending string
                                       has not been entered          */
   {
     data_length = strlen(input_line); /* Get length of message      */
     memcpy(send_buffer,
            input_line,
            data_length);           /* Put message in send buffer    */
     printf("Reply necessary? (Y or N)\n"); /* Prompt for reply
                                       indicator                     */
     gets(input_line);              /* Get reply character           */
     input_char = toupper(input_line[0]); /* Convert character to
                                       uppercase                     */
     while (strlen(input_line) != 1 ||
            (input_char != 'Y' &&
            input_char != 'N'))
       {
         printf("Please type Y or N\n");
         gets(input_line);          /* Get reply character           */
         input_char = toupper(input_line[0]); /* Convert character to
                                       uppercase                     */
       }
     if (input_char == 'Y')
       {
         memcpy(req_type,
                RQSRPY,
                sizeof(req_type));  /* Indicate request should have
                                       a reply                       */
       }
     else
       {
         memcpy(req_type,
                RQSONLY,
                sizeof(req_type));  /* Indicate request should not have
                                       a reply                       */
       }
     QNMSNDRQ (&appl_handle,
               &qual_appl,
               &req_id,
               &send_buffer,
               &data_length,
               &req_type,
               &post_reply,
               &wait_time,
               &error_code_struc);  /* Send request to remote
                                       application                   */
     check_error_code("QNMSNDRQ");  /* Check error code              */
     if (input_char == 'Y')
       {
         process_replies();         /* Process one or more received
                                       replies                       */
       }
     printf ("Enter message to send to remote application or "
             "QUIT to end\n");
     gets(input_line);
   }
 QNMENDAP (&appl_handle,
           &error_code_struc);      /* End the application           */

 return 0;
}

/*-------------------------------------------------------------------*/
/* process_replies function                                          */
/*-------------------------------------------------------------------*/
void process_replies ()
{
 RECEIVERVAR receiver_var =         /* Receiver variable             */
           {sizeof(receiver_var)};  /* Initialize bytes provided     */
 int rcv_var_len = sizeof(receiver_var); /* Length of receiver
                                       variable                      */
 DATARCVD data_rcvd = "*NODATA   "; /* Type of data received         */
 QUALAPPL qual_appl;                /* Sender of reply               */

 printf ("Received reply(s):\n");
 while (memcmp(data_rcvd,
               "*RPYCPL   ",
               sizeof(data_rcvd)) != 0) /* While final reply has not
                                       been received                 */
   {
     strncpy(receiver_var.received_data,
             "\0",
             sizeof(receiver_var.received_data)); /* Null out
                                       data buffer                   */
     QNMRCVDT (&appl_handle,
               &receiver_var,
               &rcv_var_len,
               &req_id,
               &qual_appl,
               &data_rcvd,
               &wait_time,
               &error_code_struc);  /* Receive reply                 */
     check_error_code("QNMRCVDT");  /* Check error code              */
     printf("%1.500s\n",receiver_var.received_data); /* Print out
                                                        reply        */
   }
}

/*-------------------------------------------------------------------*/
/* get_network_id function.                                          */
/*-------------------------------------------------------------------*/
void get_network_id ()
{
 int count;
 printf("Enter network ID of remote system where MSTTARG "
        "application has been started\n"); /* Prompt for network
                                       ID                            */
 gets(input_line);                  /* Get network ID                */
 while (strlen(input_line) <= 0 ||
        strlen(input_line) > 8)     /* While network ID is not valid */
   {
     printf("Network ID is too long or too short - try again\n");
     gets(input_line);              /* Get network ID                */
   }
 memcpy(qual_appl.network_id,
        input_line,
        strlen(input_line));        /* Copy network ID               */
 for (count=0; count < strlen(input_line); count++)
   qual_appl.network_id[count] =
                  toupper(qual_appl.network_id[count]); /* Convert
                                       input to uppercase            */
}

/*-------------------------------------------------------------------*/
/* get_cp_name function.                                             */
/*-------------------------------------------------------------------*/
void get_cp_name ()
{
 int count;
 printf("Enter CP name of remote system where MSTTARG application "
        "has been started\n");      /* Prompt for CP name            */
 gets(input_line);                  /* Get CP name                   */
 while (strlen(input_line) <= 0 ||
        strlen(input_line) > 8)     /* While CP name is not valid    */
   {
     printf("CP name is too long or too short - try again\n");
     gets(input_line);              /* Get CP name                   */
   }
 memcpy(qual_appl.cp_name,
        input_line,
        strlen(input_line));        /* Copy CP name                  */
 for (count=0; count < strlen(input_line); count++)
   qual_appl.cp_name[count] =
                     toupper(qual_appl.cp_name[count]); /* Convert
                                       input to uppercase            */
}

/*-------------------------------------------------------------------*/
/* check_error_code -                                                */
/*-------------------------------------------------------------------*/
void check_error_code (char func_name[8])
{
 char *sense_ptr = error_code_struc.exception_data + 36; /*
                                       Pointer to sense code in
                                       exception data                */
 SENSECODE sense_code;              /* SNA sense code                */
 if (error_code_struc.bytes_available != 0) /* Error occurred?       */
   {
     printf("\n\nError occurred calling %1.8s.\n",func_name);
     memcpy(sense_code,
            sense_ptr,
            sizeof(sense_code));    /* Copy sense code from exception
                                       data                          */
     printf("Error code is %1.7s, SNA sense code is %1.8s.\n",
                   error_code_struc.exception_ID,
                   sense_code);
     if (memcmp(func_name,
            "QNMSTRAP",
            sizeof(func_name)) != 0)  /* Error did not occur on
                                       start application?            */
       {
         QNMENDAP (&appl_handle,
                   &error_code_struc); /* End the application        */

       }
     exit(EXIT_FAILURE);            /* Exit this program             */
   }
}

Target application program

This target application program receives management services transport requests from the source application program. The target application program returns replies if requests specify that replies are needed.

/*********************************************************************/
/*********************************************************************/
/*                                                                   */
/* FUNCTION:                                                         */
/* This is a target application that uses the management services    */
/* transport APIs.  It receives management services transport        */
/* requests from source application MSTSOURC and displays the data   */
/* contained in the request.  If the request specifies that a        */
/* reply needs to be sent, this program accepts input from the       */
/* keyboard and sends one or more replies to the source application. */
/*                                                                   */
/* LANGUAGE:  ILE C                                                  */
/*                                                                   */
/* APIs USED: QNMSTRAP, QNMENDAP, QNMREGAP, QNMDRGAP,                */
/*            QNMRCVDT, QNMSNDRP, QNMRCVOC, QRCVDTAQ,                */
/*            QNMENDAP                                               */
/*                                                                   */
/*********************************************************************/
/*********************************************************************/
/* Includes                                                          */
/*********************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NOERROR "NOERROR"
#define REQUEST "*RQS      "
#define REQREPLY "*RQSRPY   "
#define REPLYINC "*RPYINCPL "
#define REPLYCMP "*RPYCPL   "

/*-------------------------------------------------------------------*/
/* Type definitions                                                  */
/*-------------------------------------------------------------------*/
typedef int HANDLE;                 /* typedef for handle            */
typedef char APPLNAME[8];           /* typedef for application name  */
typedef char NETID[8];              /* typedef for network ID        */
typedef char CPNAME[8];             /* typedef for control point name*/
typedef char SENSECODE[8];          /* typedef for SNA sense code
                                       (in character format)         */
typedef char LIBNAME[10];           /* typedef for library name      */
typedef char QNAME[10];             /* typedef for data queue name   */
typedef char MSGID[7];              /* typedef for message ID        */
typedef char EXCPDATA[48];          /* typedef for exception data    */
typedef char CATEGORY[8];           /* typedef for category          */
typedef char APPLTYPE[10];          /* typedef for application type  */
typedef char REPLREG[10];           /* typedef for replace
                                       registration                  */
typedef char DATARCVD[10];          /* typedef for data received     */
typedef char REPLYTYPE[10];         /* typedef for reply type        */
typedef char REQUESTID[53];         /* typedef for request ID        */
typedef char PACKED5[3];            /* typedef for PACKED(5,0) field */
typedef char SRBUFFER[500];         /* typedef for send/receive
                                       buffer.  This program limits
                                       the amount of data to be sent
                                       or received to 500 bytes.  The
                                       maximum size of a management
                                       services transport buffer is
                                       31739.                        */

typedef struct {                    /* Library-qualified data queue
                                       name                          */
   QNAME data_queue_name;           /* data queue name               */
   LIBNAME library_name;            /* library name                  */
  } QUALQNAME;

typedef struct {                    /* Error code structure          */
   int bytes_provided;              /* number of bytes provided      */
   int bytes_available;             /* number of bytes available     */
   MSGID exception_ID;              /* exception ID                  */
   char reserved_area;              /* reserved                      */
   EXCPDATA exception_data;         /* exception data                */
  } ERRORCODE;

typedef struct {                    /* Notification record structure */
   char record_type[10];            /* Record type                   */
   char function[2];                /* Function                      */
   HANDLE handle;                   /* Handle                        */
   REQUESTID req_id;                /* Request ID                    */
   char reserved[11];               /* Reserved area                 */
  } NOTIFRCD;

typedef struct {                    /* Receiver variable structure   */
   int bytes_provided;              /* number of bytes provided      */
   int bytes_available;             /* number of bytes available     */
   SRBUFFER received_data;          /* received data                 */
  } RECEIVERVAR;

typedef struct {                    /* Qualified application name    */
   NETID network_id;                /* Network ID                    */
   CPNAME cp_name;                  /* Control point name            */
   APPLNAME app_name;               /* Application name              */
  } QUALAPPL;

/*-------------------------------------------------------------------*/
/* External program declarations                                     */
/*-------------------------------------------------------------------*/
#pragma linkage(QNMSTRAP, OS)       /* Start application API         */
extern void QNMSTRAP (HANDLE *handle, /* pointer to handle           */
                      APPLNAME *applname,  /* pointer to application
                                       name                          */
                      QUALQNAME *qualqname,/* pointer to data queue
                                       name                          */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

#pragma linkage(QNMENDAP, OS)       /* End application API           */
extern void QNMENDAP (HANDLE *handle, /* pointer to handle           */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

#pragma linkage(QNMREGAP, OS)       /* Register application API      */
extern void QNMREGAP (HANDLE *handle, /* pointer to handle           */
                      CATEGORY *category, /* pointer to category     */
                      APPLTYPE *appltype, /* pointer to application
                                       type                          */
                      REPLREG *replreg, /* pointer to replace
                                       registration parameter        */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

#pragma linkage(QNMDRGAP, OS)       /* Deregister application API    */
extern void QNMDRGAP (HANDLE *handle, /* pointer to handle           */
                      ERRORCODE *errorcode); /* pointer to error code
                                        set group                    */

#pragma linkage(QNMRCVDT, OS)       /* Receive data API              */
extern void QNMRCVDT (HANDLE *handle, /* pointer to handle           */
                      RECEIVERVAR *rcvvar, /* pointer to receiver
                                       variable                      */
                      int *rcvvarln, /* pointer to receiver variable
                                       length                        */
                      REQUESTID *reqid, /* pointer to request ID     */
                      QUALAPPL *qualappl, /* pointer to remote
                                       application name              */
                      DATARCVD *datarcvd, /* pointer to type of data
                                       received                      */
                      int *waittim, /* pointer to wait time          */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

#pragma linkage(QNMSNDRP, OS)       /* Send reply API                */
extern void QNMSNDRP (HANDLE *handle, /* pointer to handle           */
                      REQUESTID *reqid, /* pointer to request ID     */
                      SRBUFFER *sndbuf, /* pointer to send buffer    */
                      int *sndbufln, /* pointer to send buffer length*/
                      REPLYTYPE *rpltype, /* pointer to reply type   */
                      int *waittim, /* pointer to wait time          */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

#pragma linkage(QNMRCVOC, OS)       /* Receive operation completion API
                                                                     */
extern void QNMRCVOC (HANDLE *handle, /* pointer to handle           */
                      REQUESTID *reqid, /* pointer to request ID     */
                      QUALAPPL *qualappl, /* pointer to remote
                                       application name              */
                      ERRORCODE *errorcode); /* pointer to error code
                                       parameter                     */

#pragma linkage(QRCVDTAQ, OS)       /* Receive data queue            */
extern void QRCVDTAQ (QNAME *queue_name, /* pointer to queue name    */
                      LIBNAME *lib_name, /* pointer to library name  */
                      PACKED5 *rcd_len, /* pointer to record length  */
                      NOTIFRCD *notifrcd, /* pointer to notification
                                      record                         */
                      PACKED5 *waittime); /* pointer to wait time    */

void check_error_code (char func_name[8]); /* Used to check error
                                       code                          */

/*-------------------------------------------------------------------*/
/* Global declarations                                               */
/*-------------------------------------------------------------------*/
 HANDLE appl_handle;                /* Handle of application         */
 ERRORCODE error_code_struc =       /* Error code parameter          */
           {sizeof(error_code_struc),  /* Initialize bytes provided  */
            0,                      /* initialize bytes available    */
            NOERROR};               /* initialize error code         */
/*-------------------------------------------------------------------*/
/* Start of main function                                            */
/*-------------------------------------------------------------------*/
int main ()
{
/*-------------------------------------------------------------------*/
/* Local declarations                                                */
/*-------------------------------------------------------------------*/
 APPLNAME appl_name = "MSTTARG ";   /* Application name to be used   */
 QUALQNAME data_queue_parm =        /* Data queue name to be used    */
           {"MSTDTAQ   ", "QTEMP     "}; /* Initialize structure     */
 NOTIFRCD notif_record;             /* Area to contain notification
                                       record                        */
 RECEIVERVAR receiver_var =         /* Receiver variable             */
           {sizeof(receiver_var)};  /* Initialize bytes provided     */
 QUALAPPL qual_appl;                /* Qualified application name    */
 DATARCVD data_rcvd;                /* Type of data received         */
 CATEGORY category = "*NONE   ";    /* SNA/Management Services function
                                        set group                    */
 APPLTYPE appl_type = "*FPAPP    "; /* Application type              */
 REPLREG replace_reg = "*YES      "; /* Replace registration = *NO   */
 REPLYTYPE reply_cmp = REPLYCMP;    /* Complete reply                */
 REPLYTYPE reply_inc = REPLYINC;    /* Incomplete reply              */
 int sys_result;                    /* Result of system function     */
 int rcv_var_len = sizeof(receiver_var); /* Length of receiver
                                       variable                      */
 PACKED5 wait_time_p = "\x00\x00\x1D"; /* Packed value for wait time
                                       = -1, that is, wait forever   */
 PACKED5 record_len;                /* Length of received data queue
                                       record                        */
 int wait_forever = -1;             /* Integer value for wait time =
                                       -1, that is, wait forever     */
 int no_wait = 0;                   /* Do not wait for I/O to
                                       complete                      */
 char end_msg[] = "ENDRMTAPPL";     /* If this data is received then
                                       the application will end      */
 char incoming_data[] = "01";       /* Incoming data constant        */
 char inbuf[85];                    /* Input buffer                  */
 SRBUFFER send_buffer;              /* Send buffer for sending
                                       replies                       */
 int reply_len;                     /* Length of reply data          */

/*-------------------------------------------------------------------*/
/* Start of executable code                                          */
/*-------------------------------------------------------------------*/
 sys_result = system("DLTDTAQ DTAQ(QTEMP/MSTDTAQ)"); /* Delete
                                       previous data queue (if any)  */
 sys_result = system("CRTDTAQ DTAQ(QTEMP/MSTDTAQ) MAXLEN(80)"); /*
                                       Create data queue             */
 QNMSTRAP (&appl_handle,
           &appl_name,
           &data_queue_parm,
           &error_code_struc);      /* Start application             */
 check_error_code("QNMSTRAP");      /* Check error code              */
 QNMREGAP (&appl_handle,
           &category,
           &appl_type,
           &replace_reg,
           &error_code_struc);      /* Register the application      */
 check_error_code("QNMREGAP");      /* Check error code              */
 while (memcmp(receiver_var.received_data,
               end_msg,
               sizeof(end_msg)) != 0)
   {                                /* Loop until an ending string
                                       has been sent by the requesting
                                       application                   */
     QRCVDTAQ (&data_queue_parm.data_queue_name,
               &data_queue_parm.library_name,
               &record_len,
               &notif_record,
               &wait_time_p);       /* Receive indication from data
                                       queue                         */
     if (memcmp(notif_record.function,
                incoming_data,
                sizeof(incoming_data)) == 0) /* Incoming data was
                                       received?                     */
       {
         strncpy(receiver_var.received_data,
                 "\0",
                 sizeof(receiver_var.received_data)); /* Null out the
                                       receive buffer                */
         QNMRCVDT (&appl_handle,
                   &receiver_var,
                   &rcv_var_len,
                   &notif_record.req_id,
                   &qual_appl,
                   &data_rcvd,
                   &wait_forever,
                   &error_code_struc); /* Receive data using the
                                       request ID in the notification*/
         check_error_code("QNMRCVDT"); /* Check error code           */
         printf("%1.500s\n",receiver_var.received_data); /* Display
                                       the received data             */
         if (memcmp(data_rcvd,
                    REQREPLY,
                    sizeof(data_rcvd)) == 0) /* Request requires
                                       a reply?                      */
           {
             printf("Please enter your replies (a null line "
                    "indicates that you are finished)\n"); /* Display
                                       a prompt message              */
             gets(inbuf);           /* Get the reply data            */
             reply_len = strlen(inbuf); /* Get length of reply       */
             while (reply_len != 0)  /* While no null string was input
                                                                     */
               {
                 memcpy(send_buffer,inbuf,strlen(inbuf)); /* Copy
                                       data to send buffer           */
                 QNMSNDRP (&appl_handle,
                           &notif_record.req_id,
                           &send_buffer,
                           &reply_len,
                           &reply_inc,
                           &no_wait,
                           &error_code_struc); /* Send a reply to the
                                       source application (specify
                                       "not last" reply).  The results
                                       of this operation will be
                                       obtained later using the
                                       receive operation completion
                                       API.                          */
                 gets(inbuf);       /* Get the next reply            */
                 reply_len = strlen(inbuf); /* Get length of reply   */
               }
             QNMSNDRP (&appl_handle,
                       &notif_record.req_id,
                       &send_buffer,
                       &reply_len,
                       &reply_cmp,
                       &no_wait,
                       &error_code_struc); /* Send final reply (this
                                       contains no data).  The results
                                       of this operation will be
                                       obtained later using the
                                       receive operation completion
                                       API.                          */
           }
         else
           {                       /* A reply is not required        */
             if (memcmp(data_rcvd,
                 REQUEST,
                 sizeof(data_rcvd)) != 0) /* Something other than a
                                       request was received?         */
               {
                 printf("Incorrect data was received, "
                        "data_rcvd = %1.10s\n", data_rcvd); /* Print
                                       value of data_rcvd            */
               }
           }

       }
     else
       {                            /* A send completion was received
                                       for a previous send reply
                                       operation                     */
         QNMRCVOC (&appl_handle,
                   &notif_record.req_id,
                   &qual_appl,
                   &error_code_struc);/* Receive operation completion*/
         check_error_code("QNMRCVOC"); /* Check error code           */
         printf("Reply was sent successfully.\n"); /* Error code was
                                       OK                            */
       }
   }
 QNMDRGAP (&appl_handle,
           &error_code_struc);      /* Deregister the application    */
 QNMENDAP (&appl_handle,
           &error_code_struc);      /* End the application           */

 return 0;
}

/*-------------------------------------------------------------------*/
/* check_error_code -                                                */
/*                                                                   */
/*   This function validates the error code parameter returned on    */
/*   the call to a management services transport API program.  If    */
/*   an error occurred, it displays the error that occurred and      */
/*   ends this program.                                              */
/*-------------------------------------------------------------------*/
void check_error_code (char func_name[8])
{
 char *sense_ptr = error_code_struc.exception_data + 36; /*
                                       Pointer to sense code in
                                       exception data                */
 SENSECODE sense_code;              /* SNA sense code                */
 if (error_code_struc.bytes_available != 0) /* Error occurred?       */
   {
     printf("\nError occurred calling %1.8s.\n",func_name);
     memcpy(sense_code,
            sense_ptr,
            sizeof(sense_code));    /* Copy sense code from exception
                                       data                          */
     printf("Error code is %1.7s, SNA sense code is %1.8s.\n",
                   error_code_struc.exception_ID,
                   sense_code);
     if (memcmp(func_name,
            "QNMSTRAP",
            sizeof("QNMSTRAP")) != 0)  /* Error did not occur on
                                       start application?            */
       {
         QNMENDAP (&appl_handle,
                   &error_code_struc); /* End the application        */

       }
     exit(EXIT_FAILURE);            /* Exit this program             */
   }
}