/*---------------------------------------------------------------------+ | Copyright (c) 1995, SAS Institute Inc. | | Unpublished - All Rights Reserved | | S A S / C S A M P L E | | | | NAME: RECEIVER | | LANGUAGE: C | | PURPOSE: This application demonstrates IUCV communications in | | CMS environments. RECEIVER works in conjunction with | | the SAS/C SENDER sample. Refer to the SAS/C Library | | Reference, Volume 2, Third Edition, Version 6.00 for | | additional information. | | MVS - N/A - SAS/C IUCV functions are only supported in CMS. | | CMS - | | COMPILE: LC370 RECEIVER | | LINK: CLINK RECEIVER (genmod | | EXECUTE: RECEIVER | | MISC NOTES: RECEIVER must be started prior to SENDER, or SENDER | | will terminate with an IUCV error. | +---------------------------------------------------------------------*/ #include #include #include #include void iucvtrap(void); /* Declare SIGIUCV signal handler.*/ /* Establish stdin prompt string. */ char *_stdiamp = "prompt=What do I reply to SENDER?\n"; int connects = 0; /* Number of connections made. */ /*-------------------------------------------------------------------+ | Declare internal functions. | +-------------------------------------------------------------------*/ static void rcvrply(iucv_msg_data *); void main() { int maxconns, /* Number of IUCV connections */ /* allowed. */ rc; /* Return code from IUCV functions*/ /*----------------------------------------------------------------+ | Initialize IUCV signal processing and establish a handler. | | Block IUCV signals until we're ready to handle them. | +----------------------------------------------------------------*/ signal(SIGIUCV,(_HANDLER) &iucvtrap); sigblock(1 << (SIGIUCV-1)); /*----------------------------------------------------------------+ | Identify this program as RECEIVER. | +----------------------------------------------------------------*/ if ((rc = iucvset("RECEIVER",&maxconns)) != 0) { printf("Return code from iucvset was %d\n",rc); exit(4); } printf("Maximum IUCV connections: %d\n",maxconns); /*----------------------------------------------------------------+ | This call waits for the initial CONNECTION PENDING interrupt. | +----------------------------------------------------------------*/ sigpause(0); /*----------------------------------------------------------------+ | As long as some SENDER is connected, wait for incoming messages.| +----------------------------------------------------------------*/ while (connects > 0) sigpause(0); /*----------------------------------------------------------------+ | All paths have been terminated. Terminate IUCV processing. | +----------------------------------------------------------------*/ iucvclr("RECEIVER"); exit(0); } #eject /*-------------------------------------------------------------------+ | SIGIUCV signal handler. Signals are blocked until return. | +-------------------------------------------------------------------*/ void iucvtrap() { iucv_path_data *XID; /* Pointer to external interrupt */ /* data returned by siginfo. The */ /* type is arbitrarily chosen */ /* since it can point to any of */ /* the IUCV structures. */ int rc; /* Return code from iucvacc. */ /*----------------------------------------------------------------+ | Get a pointer to the external interrupt data. Use the interrupt| | type to determine what to do. | +----------------------------------------------------------------*/ XID = (iucv_path_data *) siginfo(); switch (XID->ip.type) { case CONNECTION_PENDING: /* Issue ACCEPT. */ XID->ip.type = 0; if ((rc = iucvacc("RECEIVER",XID)) != 0) { printf("Return code from iucvacc = %d\n",rc); if (rc == 1) printf("IPRCODE = %d\n",XID->ip.rcode); exit(8); } connects++; /* Keep track of the number of */ break; /* connections made. */ case INCOMING_MSG: /* Call function to get message */ /* and send reply. */ rcvrply((iucv_msg_data *)XID); break; case PATH_SEVERED: /* SENDER decided to stop. */ if ((rc = iucvsevr("RECEIVER",XID,"ONE")) != 0) { printf("Return code from iucvsevr = %d\n",rc); exit(8); } connects--; /* Update number of connections. */ break; default: /* Handle other interrupt types. */ printf("Unexpected interrupt type %d\n",XID->ip.type); fflush(stdout); abort(); } /*----------------------------------------------------------------+ | Re-establish this function as the SIGIUCV signal handler. | +----------------------------------------------------------------*/ signal(SIGIUCV,(_HANDLER) &iucvtrap); return; } #eject /*-------------------------------------------------------------------+ | Function to issue IUCV RECIEVE and print the message. | +-------------------------------------------------------------------*/ static void rcvrply(m_data) iucv_msg_data *m_data; { int msg_len; /* Incoming message length. */ char msg_buffer(|120|); /* Message buffer. */ /*----------------------------------------------------------------+ | Create IUCV RECEIVE parameter list using the external | | interrupt data area. Issue the IUCV RECEIVE. | +----------------------------------------------------------------*/ m_data->msg.bf1.adr = msg_buffer; m_data->msg.bf1.ln = sizeof(msg_buffer); iucvrecv(m_data); /*----------------------------------------------------------------+ | Upon return, m_data->msg.bf1.ln contains the number of unused | | bytes in the message buffer. Print the message. | +----------------------------------------------------------------*/ msg_len = sizeof(msg_buffer) - m_data->msg.bf1.ln; printf("SENDER says \"%.*s\"\n",msg_len,msg_buffer); /*----------------------------------------------------------------+ | Prompt for a reply message. If EOF, quit. | +----------------------------------------------------------------*/ fgets(msg_buffer,sizeof(msg_buffer),stdin); if (feof(stdin)) { puts("Terminating due to end-of-file."); exit(12); } /*----------------------------------------------------------------+ | Fill in IUCV REPLY parameter list with buffer address/length. | | Send REPLY. | +----------------------------------------------------------------*/ m_data->bf2.adr = msg_buffer; m_data->bf2.ln = strlen(msg_buffer) - 1; iucvrply(m_data); }