/*---------------------------------------------------------------------+
| Copyright (c) 1995, SAS Institute Inc. |
| Unpublished - All Rights Reserved |
| S A S / C S A M P L E |
| |
| NAME: SENDER |
| LANGUAGE: C |
| PURPOSE: This application demonstrates IUCV communications in |
| CMS environments. SENDER works in conjunction with |
| the SAS/C RECEIVER 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 SENDER |
| LINK: CLINK SENDER (genmod |
| EXECUTE: SENDER |
| NOTES: The target virtual machine, in this case the machine |
| running the RECEIVER module, must be identified. |
| Modify the: #define TARGET statement below. The default|
| value is: "SASCUSER". The value *is* case sensitive, |
| if less then eight characters, padded with blanks. |
| |
+---------------------------------------------------------------------*/
#include <lcsignal.h>
#include <lcstring.h>
#include <cmsiucv.h>
#include <lcio.h>
/*----------------------------------------------------------------+
| TARGET must customized to identify the virtual machine |
| running the RECEIVER module. The value should be the virtual |
| machine name. If the name is not correct or the RECEIVER is NOT |
| running, expect IUCV connect errors with non-zero IPRCODE's. |
+----------------------------------------------------------------*/
#define TARGET "SASCUSER"
void iucvtrap(void); /* Declare SIGIUCV handler. */
/* Set up stdin amparms. */
char *_stdiamp = "prompt=What message do I send?\n,eof=";
int rep_len = 0;
short pathid = 0;
void main()
{
struct iucv_path_plist path; /* IUCV plist for CONNECT, SEVER. */
struct iucv_msg_plist msg; /* IUCV plist for SEND. */
int maxconns, /* Maximum number of IUCV connec- */
/* tions for this virtual machine*/
rc; /* Return code from IUCV functions*/
char message(|120|), /* Message buffer. */
reply(|120|); /* Reply buffer. */
/*----------------------------------------------------------------+
| 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 SENDER. |
+----------------------------------------------------------------*/
if ((rc = iucvset("SENDER",&maxconns)) != 0) {
printf("Return code from iucvset was %d\n",rc);
exit(4);
}
printf("Maximum IUCV connections: %d\n",maxconns);
/*----------------------------------------------------------------+
| Fill in the IUCV "path" parameter list with the target userid |
| and the name of the target program. All of the other parameters|
| are superflous in this program. |
| |
| Note that the userid copied to path.vmid must be eight bytes |
| long, padded on the right with blanks if necessary. |
+----------------------------------------------------------------*/
memset((char *) &path,0,sizeof(path));
memcpy(path.vmid,TARGET,8);
memcpy(path.pgm,"RECEIVER",8);
/*----------------------------------------------------------------+
| Request an IUCV CONNECT to the userid/program pair named in the |
| parameter list. Check for an IUCV error (return code of 1) and |
| print the IUCV error code. |
+----------------------------------------------------------------*/
rc = iucvconn("SENDER",&path);
if (rc != 0) {
printf("Return code from iucvconn was %d\n",rc);
if (rc == 1)
printf("IPRCODE = %d\n",path.ip.rcode);
exit(8);
}
/*----------------------------------------------------------------+
| Now we're ready. The first interrupt we will receive is the |
| CONNECTION COMPLETE interrupt that occurs when RECEIVER |
| issues an IUCV ACCEPT. |
+----------------------------------------------------------------*/
sigpause(0);
/*----------------------------------------------------------------+
| Initialize the SEND parameter list with the pathid and buffer |
| addresses, and the length of the reply buffer. |
+----------------------------------------------------------------*/
memset((char *) &msg,'\0',sizeof(msg));
path.pathid = msg.pathid = pathid;
msg.msg.bf1.adr = message;
msg.bf2.adr = reply;
msg.bf2.ln = sizeof(reply);
/*----------------------------------------------------------------+
| Prompt for input messages and send until EOF. |
+----------------------------------------------------------------*/
fgets(message,sizeof(message),stdin);
while (!feof(stdin))
{
/*-------------------------------------------------------------+
| Put message length in the SEND parameter list. |
+-------------------------------------------------------------*/
msg.msg.bf1.ln = strlen(message) - 1;
/*-------------------------------------------------------------+
| Send message. Wait (via sigpause) for reply. Upon receipt |
| of reply, 'rep_len' contains the number of unused bytes in |
| the reply buffer. Print the reply and prompt for a new |
| message. |
+-------------------------------------------------------------*/
iucvsend(&msg);
sigpause(0);
rep_len = sizeof(reply) - rep_len;
printf("RECEIVER replies \"%.*s\"\n",rep_len,reply);
fgets(message,sizeof(message),stdin);
}
/*----------------------------------------------------------------+
| We're ready to quit. SEVER the IUCV path. Check for IUCV |
| errors as before. |
+----------------------------------------------------------------*/
if ((rc = iucvsevr("SENDER",&path,"ONE")) != 0) {
printf("Return code from iucvsever = %d\n",rc);
if (rc == 1)
printf("IPRCODE = %d\n",path.ip.rcode);
exit(10);
}
/*----------------------------------------------------------------+
| Terminate IUCV communications for SENDER. |
+----------------------------------------------------------------*/
iucvclr("SENDER");
exit(0);
}
#eject
/*-------------------------------------------------------------------+
| The 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 arbitrary since it */
/* can point to any of the */
/* IUCV structures. */
/*----------------------------------------------------------------+
| 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_COMPLETE: /* Save the pathid for SEND. */
pathid = XID->pathid;
break;
case INCOMING_REPLY: /* Extract the number of unused */
/* characters in the buffer. */
rep_len = ((iucv_msg_data *)XID)->bf2.ln;
break;
case PATH_SEVERED: /* Handle unexpected termination */
/* of RECEIVER. */
puts("Unexpected SEVER!");
exit(20);
default: /* Handle unexpected type of */
/* IUCV signal. */
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;
}
|