static void* con1052_panel_command (char *cmd) { DEVBLK *dev; char *input; int i; void* (*next_panel_command_handler)(char *cmd); for(dev = sysblk.firstdev; dev; dev = dev->nextdev) { if(dev->allocated && dev->hnd == &con1052_device_hndinfo && !strncasecmp(cmd,dev->filename,strlen(dev->filename)) ) { input = cmd + strlen(dev->filename); WRCMSG ("<pnl,color(lightyellow,black)>", HHC00008, "I", dev->filename, cmd+strlen(dev->filename) ); for(i = 0; i < dev->bufsize && input[i] != '\0'; i++) dev->buf[i] = isprint(input[i]) ? host_to_guest(input[i]) : SPACE; dev->keybdrem = dev->buflen = i; obtain_lock(&dev->lock); if(dev->iowaiters) { signal_condition(&dev->iocond); release_lock(&dev->lock); } else { release_lock(&dev->lock); device_attention (dev, CSW_ATTN); } return NULL; } } next_panel_command_handler = HDL_FINDNXT(con1052_panel_command); if (!next_panel_command_handler) return NULL; return next_panel_command_handler(cmd); }
/*-------------------------------------------------------------------*/ static int printer_init_handler (DEVBLK *dev, int argc, char *argv[]) { int iarg,i,j; /* some Array subscripts */ char *ptr; char *nxt; int sockdev = 0; /* 1 == is socket device */ /* For re-initialisation, close the existing file, if any, and raise attention */ if (dev->fd >= 0) { (dev->hnd->close)(dev); release_lock (&dev->lock); device_attention (dev, CSW_DE); obtain_lock (&dev->lock); } dev->excps = 0; /* Forcibly disconnect anyone already currently connected */ if (dev->bs && !unbind_device_ex(dev,1)) return -1; // (error msg already issued) /* The first argument is the file name */ if (argc == 0 || strlen(argv[0]) >= sizeof(dev->filename)) { WRMSG (HHC01101, "E", SSID_TO_LCSS(dev->ssid), dev->devnum); return -1; } /* Save the file name in the device block */ hostpath(dev->filename, argv[0], sizeof(dev->filename)); if(!sscanf(dev->typname,"%hx",&(dev->devtype))) dev->devtype = 0x3211; /* Initialize device dependent fields */ dev->fd = -1; dev->diaggate = 0; dev->fold = 0; dev->crlf = 0; dev->stopdev = FALSE; dev->notrunc = 0; dev->ispiped = (dev->filename[0] == '|'); /* initialize the new fields for FCB+ support */ dev->fcbsupp = 1; dev->cc = 0; dev->rawcc = 0; dev->fcbcheck = 1; dev->nofcbcheck = 0; dev->ccpend = 0; dev->chskip = 0; dev->prevline = 1; dev->currline = 1; dev->destline = 1; dev->print = 1; dev->browse = 0; dev->lpi = 6; dev->index = 0; dev->ffchan = 1; for (i = 0; i < FCBSIZE; i++) dev->fcb[i] = 0; for (i = 1; i <= 12; i++ ) { if ( FCBMASK[i] != 0 ) dev->fcb[FCBMASK[i]] = i; } dev->lpp = FCBMASK[0]; dev->fcbisdef = 0; /* Process the driver arguments */ for (iarg = 1; iarg < argc; iarg++) { if (strcasecmp(argv[iarg], "crlf") == 0) { dev->crlf = 1; continue; } /* sockdev means the device file is actually a connected socket instead of a disk file. The file name is the socket_spec (host:port) to listen for connections on. */ if (!dev->ispiped && strcasecmp(argv[iarg], "sockdev") == 0) { sockdev = 1; continue; } if (strcasecmp(argv[iarg], "noclear") == 0) { dev->notrunc = 1; continue; } if (strcasecmp(argv[iarg], "cc") == 0) { dev->cc = 1; dev->rawcc = 0; continue; } if (strcasecmp(argv[iarg], "rawcc") == 0) { dev->cc = 0; dev->rawcc = 1; continue; } if (strcasecmp(argv[iarg], "nofcbcheck") == 0) { dev->fcbcheck = 0; dev->nofcbcheck = 1; continue; } if (strcasecmp(argv[iarg], "fcbcheck") == 0) { dev->fcbcheck = 1; dev->nofcbcheck = 0; continue; } if ( (strcasecmp(argv[iarg], "browse") == 0) || (strcasecmp(argv[iarg], "optbrowse") == 0 ) ) { dev->print = 0; dev->browse = 1; continue; } if ( (strcasecmp(argv[iarg], "print") == 0 ) || (strcasecmp(argv[iarg], "optprint") == 0) ) { dev->print = 1; dev->browse = 0; continue; } if (strncasecmp("lpi=", argv[iarg], 4) == 0) { ptr = argv[iarg]+4; errno = 0; dev->lpi = (int) strtoul(ptr,&nxt,10); if (errno != 0 || nxt == ptr || *nxt != 0 || ( dev->lpi != 6 && dev->lpi != 8 ) ) { j = ptr - argv[iarg]; WRMSG (HHC01103, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg], j); return -1; } continue; } if (strncasecmp("index=", argv[iarg], 6) == 0) { if (dev->devtype != 0x3211 ) { WRMSG (HHC01103, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg], 1); return -1; } ptr = argv[iarg]+6; errno = 0; dev->index = (int) strtoul(ptr,&nxt,10); if (errno != 0 || nxt == ptr || *nxt != 0 || ( dev->index < 0 || dev->index > 15) ) { j = ptr - argv[iarg]; WRMSG (HHC01103, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg], j); return -1; } continue; } if (strncasecmp("lpp=", argv[iarg], 4) == 0) { ptr = argv[iarg]+4; errno = 0; dev->lpp = (int) strtoul(ptr,&nxt,10); if (errno != 0 || nxt == ptr || *nxt != 0 ||dev->lpp > FCBSIZE) { j = ptr - argv[iarg]; WRMSG (HHC01103, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg], j); return -1; } continue; } #if 0 if (strncasecmp("ffchan=", argv[iarg], 7) == 0) { ptr = argv[iarg]+7; errno = 0; dev->ffchan = (int) strtoul(ptr,&nxt,10); if (errno != 0 || nxt == ptr || *nxt != 0 || dev->ffchan < 1 || dev->ffchan > 12) { j = ptr - argv[iarg]; WRMSG (HHC01103, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg], j); return -1; } continue; } #endif if (strncasecmp("fcb=", argv[iarg], 4) == 0) { for (line = 0; line <= FCBSIZE; line++) dev->fcb[line] = 0; /* check for simple mode */ if ( strstr(argv[iarg],":") ) { /* ':" found ==> new mode */ ptr = argv[iarg]+4; while (*ptr) { errno = 0; line = (int) strtoul(ptr,&nxt,10); if (errno != 0 || *nxt != ':' || nxt == ptr || line > dev->lpp || dev->fcb[line] != 0 ) { j = ptr - argv[iarg]; WRMSG (HHC01103, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg], j); return -1; } ptr = nxt + 1; errno = 0; chan = (int) strtoul(ptr,&nxt,10); if (errno != 0 || (*nxt != ',' && *nxt != 0) || nxt == ptr || chan < 1 || chan > 12 ) { j = ptr - argv[iarg]; WRMSG (HHC01103, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg], j); return -1; } dev->fcb[line] = chan; if ( *nxt == 0 ) break; ptr = nxt + 1; } } else { /* ':" NOT found ==> old mode */ ptr = argv[iarg]+4; chan = 0; while (*ptr) { errno = 0; line = (int) strtoul(ptr,&nxt,10); if (errno != 0 || (*nxt != ',' && *nxt != 0) || nxt == ptr || line > dev->lpp || dev->fcb[line] != 0 ) { j = ptr - argv[iarg]; WRMSG (HHC01103, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg], j); return -1; } chan += 1; if ( chan > 12 ) { j = ptr - argv[iarg]; WRMSG (HHC01103, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg], j); return -1; } dev->fcb[line] = chan; if ( *nxt == 0 ) break; ptr = nxt + 1; } if ( chan != 12 ) { j = 5; WRMSG (HHC01103, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg], j); return -1; } } continue; } WRMSG (HHC01102, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, iarg + 1, argv[iarg]); return -1; } /* Check for incompatible options */ if (dev->rawcc && dev->browse) { WRMSG (HHC01104, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "rawcc/browse"); return -1; } if (sockdev && dev->crlf) { WRMSG (HHC01104, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "sockdev/crlf"); return -1; } if (sockdev && dev->notrunc) { WRMSG (HHC01104, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "sockdev/noclear"); return -1; } /* If socket device, create a listening socket to accept connections on. */ if (sockdev && !bind_device_ex( dev, dev->filename, onconnect_callback, dev )) { return -1; // (error msg already issued) } /* Set length of print buffer */ // dev->bufsize = LINE_LENGTH + 8; dev->bufsize = BUFF_SIZE + BUFF_OVFL; dev->bufres = BUFF_SIZE; dev->bufoff = 0; /* Set number of sense bytes */ dev->numsense = 1; /* Initialize the device identifier bytes */ dev->devid[0] = 0xFF; dev->devid[1] = 0x28; /* Control unit type is 2821-1 */ dev->devid[2] = 0x21; dev->devid[3] = 0x01; dev->devid[4] = dev->devtype >> 8; dev->devid[5] = dev->devtype & 0xFF; dev->devid[6] = 0x01; dev->numdevid = 7; /* Activate I/O tracing */ // dev->ccwtrace = 1; return 0; } /* end function printer_init_handler */
/*-------------------------------------------------------------------*/ static int cardrdr_init_handler ( DEVBLK *dev, int argc, char *argv[] ) { int i; /* Array subscript */ int fc; /* File counter */ char pathname[MAX_PATH]; /* file path in host format */ int sockdev = 0; int attn = 0; /* Raise attention for re-init */ if(dev->devtype) attn = 1; /* For re-initialisarion close the existing file */ if (dev->fd >= 0) (dev->hnd->close)(dev); if (dev->bs) { if (!unbind_device(dev)) { // (error message already issued) return -1; } } /* Initialize device dependent fields */ dev->fd = -1; dev->fh = NULL; dev->multifile = 0; dev->ebcdic = 0; dev->ascii = 0; dev->trunc = 0; dev->cardpos = 0; dev->cardrem = 0; dev->autopad = 0; dev->excps = 0; if(!sscanf(dev->typname,"%hx",&(dev->devtype))) dev->devtype = 0x2501; fc = 0; if (dev->more_files) free (dev->more_files); dev->more_files = malloc(sizeof(char*) * (fc + 1)); if (!dev->more_files) { char buf[40]; MSGBUF(buf, "malloc(%d)", (int)(sizeof(char) * (fc + 1)) ); WRMSG (HHC01200, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, buf, strerror(errno)); return -1; } dev->more_files[fc] = NULL; /* Process the driver arguments starting with the SECOND argument. (The FIRST argument is the filename and is checked later further below.) */ for (i = 1; i < argc; i++) { /* sockdev means the device file is actually a connected socket instead of a disk file. The file name is the socket_spec (host:port) to listen for connections on. */ if (strcasecmp(argv[i], "sockdev") == 0) { sockdev = 1; continue; } /* multifile means to automatically open the next i/p file if multiple i/p files are defined. */ if (strcasecmp(argv[i], "multifile") == 0) { dev->multifile = 1; continue; } /* eof means that unit exception will be returned at end of file, instead of intervention required */ if (strcasecmp(argv[i], "eof") == 0) { dev->rdreof = 1; continue; } /* intrq means that intervention required will be returned at end of file, instead of unit exception */ if (strcasecmp(argv[i], "intrq") == 0) { dev->rdreof = 0; continue; } /* ebcdic means that the card image file consists of fixed length 80-byte EBCDIC card images with no line-end delimiters */ if (strcasecmp(argv[i], "ebcdic") == 0) { dev->ebcdic = 1; continue; } /* ascii means that the card image file consists of variable length ASCII records delimited by either line-feed or carriage-return line-feed sequences */ if (strcasecmp(argv[i], "ascii") == 0) { dev->ascii = 1; continue; } /* trunc means that records longer than 80 bytes will be silently truncated to 80 bytes when processing a variable length ASCII file. The default behaviour is to present a data check if an overlength record is encountered. The trunc option is ignored except when processing an ASCII card image file. */ if (strcasecmp(argv[i], "trunc") == 0) { dev->trunc = 1; continue; } /* autopad means that if reading fixed sized records * (ebcdic) and end of file is reached in the middle of * a record, the record is automatically padded to 80 bytes. */ if (strcasecmp(argv[i], "autopad") == 0) { dev->autopad = 1; continue; } // add additional file arguments if (strlen(argv[i]) >= sizeof(dev->filename)) { WRMSG (HHC01201, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, argv[i], (unsigned int)sizeof(dev->filename)-1); return -1; } if (access(argv[i], R_OK | F_OK) != 0) { WRMSG (HHC01200, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "access()", strerror(errno)); return -1; } hostpath(pathname, argv[i], sizeof(pathname)); dev->more_files[fc++] = strdup(pathname); dev->more_files = realloc(dev->more_files, sizeof(char*) * (fc + 1)); if (!dev->more_files) { WRMSG (HHC01200, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "strdup()", strerror(errno)); return -1; } dev->more_files[fc] = NULL; } dev->current_file = dev->more_files; /* Check for conflicting arguments */ if (dev->ebcdic && dev->ascii) { WRMSG (HHC01202, "E", SSID_TO_LCSS(dev->ssid), dev->devnum); return -1; } if (sockdev) { if (fc) { WRMSG (HHC01203, "E", SSID_TO_LCSS(dev->ssid), dev->devnum); return -1; } // If neither ascii nor ebcdic is specified, default to ascii. // This is required for socket devices because the open logic, // if neither is specified, attempts to determine whether the data // is actually ascii or ebcdic by reading the 1st 160 bytes of // data and then rewinding to the beginning of the file afterwards. // Since you can't "rewind" a socket, we must therefore default // to one of them. if (!dev->ebcdic && !dev->ascii) { WRMSG (HHC01204, "I", SSID_TO_LCSS(dev->ssid), dev->devnum); dev->ascii = 1; } } if (dev->multifile && !fc) { WRMSG (HHC01205, "W", SSID_TO_LCSS(dev->ssid), dev->devnum); dev->multifile = 0; } /* The first argument is the file name */ if (argc > 0) { /* Check for valid file name */ if (strlen(argv[0]) >= sizeof(dev->filename)) { WRMSG (HHC01201, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, argv[0], (unsigned int)sizeof(dev->filename)-1); return -1; } if (!sockdev) { /* Check for specification of no file mounted on reader */ if (argv[0][0] == '*') { dev->filename[0] = '\0'; } else if (access(argv[0], R_OK | F_OK) != 0) { WRMSG (HHC01200, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "access()", strerror(errno)); return -1; } } /* Save the file name in the device block */ hostpath(dev->filename, argv[0], sizeof(dev->filename)); } else { dev->filename[0] = '\0'; } /* Set size of i/o buffer */ dev->bufsize = CARD_SIZE; /* Set number of sense bytes */ /* ISW 20030307 : Empirical knowledge : DOS/VS R34 Erep */ /* indicates 4 bytes in 3505 sense */ dev->numsense = 4; /* Initialize the device identifier bytes */ dev->devid[0] = 0xFF; dev->devid[1] = 0x28; /* Control unit type is 2821-1 */ dev->devid[2] = 0x21; dev->devid[3] = 0x01; dev->devid[4] = dev->devtype >> 8; dev->devid[5] = dev->devtype & 0xFF; dev->devid[6] = 0x01; dev->numdevid = 7; // If socket device, create a listening socket // to accept connections on. if(attn) { release_lock (&dev->lock); device_attention (dev, CSW_DE); obtain_lock (&dev->lock); } if (sockdev && !bind_device(dev,dev->filename)) { // (error message already issued) return -1; } return 0; } /* end function cardrdr_init_handler */
/*-------------------------------------------------------------------*/ void socket_device_connection_handler (bind_struct* bs) { struct sockaddr_in client; /* Client address structure */ struct hostent* pHE; /* Addr of hostent structure */ socklen_t namelen; /* Length of client structure*/ char* clientip; /* Addr of client ip address */ char* clientname; /* Addr of client hostname */ DEVBLK* dev; /* Device Block pointer */ int csock; /* Client socket */ dev = bs->dev; logdebug("socket_device_connection_handler(dev=%4.4X)\n", dev->devnum); /* Accept the connection... */ csock = accept(bs->sd, 0, 0); if (csock == -1) { logmsg (_("HHCSD017E Connect to device %4.4X (%s) failed: %s\n"), dev->devnum, bs->spec, strerror(HSO_errno)); return; } /* Determine the connected client's IP address and hostname */ namelen = sizeof(client); clientip = NULL; clientname = "<unknown>"; if (1 && getpeername(csock, (struct sockaddr*) &client, &namelen) == 0 && (clientip = inet_ntoa(client.sin_addr)) != NULL && (pHE = gethostbyaddr((unsigned char*)(&client.sin_addr), sizeof(client.sin_addr), AF_INET)) != NULL && pHE->h_name && *pHE->h_name ) { clientname = (char*) pHE->h_name; } if (!clientip) clientip = "<unknown>"; /* Obtain the device lock */ obtain_lock (&dev->lock); /* Reject if device is busy or interrupt pending */ if (dev->busy || IOPENDING(dev) || (dev->scsw.flag3 & SCSW3_SC_PEND)) { close_socket( csock ); logmsg (_("HHCSD015E Client %s (%s) connection to device %4.4X " "(%s) rejected: device busy or interrupt pending\n"), clientname, clientip, dev->devnum, bs->spec); release_lock (&dev->lock); return; } /* Reject new client if previous client still connected */ if (dev->fd != -1) { close_socket( csock ); logmsg (_("HHCSD016E Client %s (%s) connection to device %4.4X " "(%s) rejected: client %s (%s) still connected\n"), clientname, clientip, dev->devnum, bs->spec, bs->clientname, bs->clientip); release_lock (&dev->lock); return; } /* Indicate that a client is now connected to this device */ dev->fd = csock; if (bs->clientip) free(bs->clientip); if (bs->clientname) free(bs->clientname); bs->clientip = strdup(clientip); bs->clientname = strdup(clientname); /* Call the boolean onconnect callback */ if (bs->fn && !bs->fn( bs->arg )) { /* Callback says it can't accept it */ close_socket( dev->fd ); dev->fd = -1; logmsg (_("HHCSD026E Client %s (%s) connection to device %4.4X " "(%s) rejected: by onconnect callback\n"), clientname, clientip, dev->devnum, bs->spec); release_lock (&dev->lock); return; } logmsg (_("HHCSD018I Client %s (%s) connected to device %4.4X (%s)\n"), clientname, clientip, dev->devnum, bs->spec); release_lock (&dev->lock); device_attention (dev, CSW_DE); }