> > Now it starts to look interesting :)
> > Where is source of that example program ?
> Re: AF_IUCV. Yes, it would also work, but the programming is more
> complex. There's something to the ability to just use plain old 'cat'
> or any language that understands file I/O to deal with IUCV that I like
> about Neale's driver.

In fact, it's so small, here's the whole sample program. This code takes 
anything delivered to the guest via *MSG (the classes you specify) and copies 
it to syslog and a terminal. Works for CPCONIO, MSG, SMSG, etc, etc -- anything 
you can SET <foo> IUCV.

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <iconv.h>
#include <syslog.h>

#define FSIUCV_IOC_MAGIC  'u'

#define IUCV_IOCRESET   _IO(FSIUCV_IOC_MAGIC, 0)
#define IUCVTCS         _IOW(FSIUCV_IOC_MAGIC, 1, int)
#define IUCVTCG         _IOR(FSIUCV_IOC_MAGIC, 1, int)
#define IUCVONE         _IOW(FSIUCV_IOC_MAGIC, 1, char)

/* 
 * This sample assumes we're playing with the *MSG service but it should be
 * able to drive any connection
 */

typedef struct iucvMsg {
        char userid[8];
        char msgText[1016];
} iucvMsg;

static char *class[] = { "MSG ", "WNG ", "CPIO", "SMSG",
        "VMIO", "EMSG", "IMSG", "SCIF"
};

int
main(int argc, char **argv)
{
        iconv_t cd;
        int fd, i_buf, trgcls;
        size_t count, outCount;
        char buffer[1024], output[1024];
        char *pBuffer, *pOutput, userName[9];
        size_t *pCount = (size_t *) & count, *pOutCount =
            (size_t *) & outCount, iconvSz;
        iucvMsg *msgData = (iucvMsg *) & output[0];

        printf("User ID  Class\tMessage\n"
               "-------  -----\t--------------------------------\n");
        userName[8] = 0;
        cd = iconv_open("ASCII", "EBCDIC-US");
        fd = open("/dev/iucv0", O_RDONLY);
        count = read(fd, &buffer, sizeof (buffer));
        while (count > 0) {
                pBuffer = (char *) &buffer;
                pOutput = (char *) &output;
                ioctl(fd, IUCVTCG, (char *) &trgcls);
                outCount = sizeof (output);
                iconvSz = iconv(cd, &pBuffer, pCount, &pOutput, pOutCount);
                output[sizeof (output) - outCount] = 0;
                memcpy(userName, msgData->userid, sizeof (msgData->userid));
                printf("%s [%s]\t%s\n", userName, class[trgcls-1], 
msgData->msgText);
                syslog(LOG_INFO, "[%s] %s %s\n",
                       class[trgcls - 1], userName, msgData->msgText);
                if (strcmp("STOP", msgData->msgText) == 0)
                        break;
                count = read(fd, &buffer, sizeof (buffer));
        }
        close(fd);
        iconv_close(cd);
}

Note that the guts of it are simply opening /dev/iucv0 as a sequential file and 
doing sequential blocking reads. Even Fortran can do that. 8-)
It also correctly processes distributed IUCV, so if you have ISFC or TSAF 
active, it will work cross-system. Might also work with IPGATE; haven't tested 
it. 

----------------------------------------------------------------------
For LINUX-390 subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO LINUX-390 or visit
http://www.marist.edu/htbin/wlvindex?LINUX-390
----------------------------------------------------------------------
For more information on Linux on System z, visit
http://wiki.linuxvm.org/

Reply via email to