Exemplo n.º 1
0
/*-------------------------------------------------------------------*/
static int cardrdr_close_device ( DEVBLK *dev )
{
    /* Close the device file */

    if (0
        || (  dev->bs && dev->fd >=  0   && close_socket( dev->fd ) <  0 )
        || ( !dev->bs && dev->fh != NULL &&    fclose(    dev->fh ) != 0 )
    )
    {
        int errnum = dev->bs ? get_HSO_errno() : errno;
        WRMSG (HHC01200, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "close_socket() or fclose()", strerror(errnum));
        dev->fd = -1;
        dev->fh = NULL;
        return -1;
    }

    if (dev->bs && (dev->bs->clientip || dev->bs->clientname))
    {
        WRMSG (HHC01206, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->clientname, dev->bs->clientip, dev->bs->spec);
    }

    dev->fd = -1;
    dev->fh = NULL;

    return 0;
} /* end function cardrdr_close_device */
Exemplo n.º 2
0
static int bufgetc(DEVBLK *dev, int blocking)
{
BYTE *bufp = dev->buf + dev->ctcpos, *bufend = bufp + dev->ctcrem;
int n;

    if (bufp >= bufend) {
        if (blocking == 0) return -1;
        do {
            n = read(dev->fd, dev->buf, dev->bufsize);
            if (n <= 0) {
                if (n == 0) {
                    /* VMnet died on us. */
                    WRMSG (HHC00976, "E", SSID_TO_LCSS(dev->ssid), dev->devnum);
                    /* -2 will cause an error status to be set */
                    return -2;
                }
                if( n == EINTR )
                    return -3;
                WRMSG (HHC00900, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "read()", strerror(errno));
                SLEEP(2);
            }
        } while (n <= 0);
        dev->ctcrem = n;
        bufend = &dev->buf[n];
        dev->ctclastpos = dev->ctclastrem = dev->ctcpos = 0;
        bufp = dev->buf;
    }

    dev->ctcpos++;
    dev->ctcrem--;

    return *bufp;
}
Exemplo n.º 3
0
/*-------------------------------------------------------------------*/
int read_omaheaders (DEVBLK *dev, OMATAPE_DESC *omadesc,
                        BYTE *buf, BYTE *unitstat,BYTE code)
{
int             rc;                     /* Return code               */
long            blkpos;                 /* Offset to block header    */
S32             curblkl;                /* Length of current block   */
S32             prvhdro;                /* Offset of previous header */
S32             nxthdro;                /* Offset of next header     */

    /* Read the 16-byte block header */
    blkpos = dev->nxtblkpos;
    rc = readhdr_omaheaders (dev, omadesc, blkpos, &curblkl,
                            &prvhdro, &nxthdro, unitstat,code);
    if (rc < 0) return -1;

    /* Update the offsets of the next and previous blocks */
    dev->nxtblkpos = nxthdro;
    dev->prvblkpos = blkpos;

    /* Increment file number and return zero if tapemark */
    if (curblkl == -1)
    {
        close (dev->fd);
        dev->fd = -1;
        dev->curfilen++;
        dev->nxtblkpos = 0;
        dev->prvblkpos = -1;
        return 0;
    }

    /* Read data block from tape file */
    rc = read (dev->fd, buf, curblkl);

    /* Handle read error condition */
    if (rc < 0)
    {
        WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, omadesc->filename, "oma", "read()", (off_t)blkpos,
                strerror(errno));

        /* Set unit check with equipment check */
        build_senseX(TAPE_BSENSE_READFAIL,dev,unitstat,code);
        return -1;
    }

    /* Handle end of file within data block */
    if (rc < curblkl)
    {
        WRMSG(HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, omadesc->filename, "oma", "read_omaheaders()", (off_t)blkpos, "unexpected end of file");

        /* Set unit check with data check and partial record */
        build_senseX(TAPE_BSENSE_BLOCKSHORT,dev,unitstat,code);
        return -1;
    }

    /* Return block length */
    return curblkl;

} /* end function read_omaheaders */
Exemplo n.º 4
0
/*-------------------------------------------------------------------*/
int read_omafixed (DEVBLK *dev, OMATAPE_DESC *omadesc,
                        BYTE *buf, BYTE *unitstat,BYTE code)
{
off_t           rcoff;                  /* Return code from lseek()  */
int             blklen;                 /* Block length              */
long            blkpos;                 /* Offset of block in file   */

    /* Initialize current block position */
    blkpos = dev->nxtblkpos;

    /* Seek to new current block position */
    rcoff = lseek (dev->fd, blkpos, SEEK_SET);
    if (rcoff < 0)
    {
        /* Handle seek error condition */
        WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, omadesc->filename, "oma", "lseek()", (off_t)blkpos, strerror(errno));

        /* Set unit check with equipment check */
        build_senseX(TAPE_BSENSE_LOCATEERR,dev,unitstat,code);
        return -1;
    }

    /* Read fixed length block or short final block */
    blklen = read (dev->fd, buf, omadesc->blklen);

    /* Handle read error condition */
    if (blklen < 0)
    {
        WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, omadesc->filename, "oma", "read()", (off_t)blkpos,
                strerror(errno));

        build_senseX(TAPE_BSENSE_READFAIL,dev,unitstat,code);
        return -1;
    }

    /* At end of file return zero to indicate tapemark */
    if (blklen == 0)
    {
        close (dev->fd);
        dev->fd = -1;
        dev->curfilen++;
        dev->nxtblkpos = 0;
        dev->prvblkpos = -1;
        return 0;
    }

    /* Calculate the offsets of the next and previous blocks */
    dev->nxtblkpos = blkpos + blklen;
    dev->prvblkpos = blkpos;

    /* Return block length, or zero to indicate tapemark */
    return blklen;

} /* end function read_omafixed */
Exemplo n.º 5
0
/*-------------------------------------------------------------------*/
int readhdr_awstape (DEVBLK *dev, off_t blkpos,
                     AWSTAPE_BLKHDR *buf, BYTE *unitstat,BYTE code)
{
int             rc;                     /* Return code               */
off_t           rcoff;                  /* Return code from lseek()  */

    /* Reposition file to the requested block header */
    rcoff = lseek (dev->fd, blkpos, SEEK_SET);
    if (rcoff < 0)
    {
        /* Handle seek error condition */
        WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "aws", "lseek()", blkpos, strerror(errno));

        /* Set unit check with equipment check */
        build_senseX(TAPE_BSENSE_LOCATEERR,dev,unitstat,code);
        return -1;
    }

    /* Read the 6-byte block header */
    rc = read (dev->fd, buf, sizeof(AWSTAPE_BLKHDR));

    /* Handle read error condition */
    if (rc < 0)
    {
        WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "aws", "read()", blkpos, strerror(errno));

        /* Set unit check with equipment check */
        build_senseX(TAPE_BSENSE_READFAIL,dev,unitstat,code);
        return -1;
    }

    /* Handle end of file (uninitialized tape) condition */
    if (rc == 0)
    {
        WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "aws", "readhdr_awstape()", blkpos, "end of file (uninitialized tape)");

        /* Set unit exception with tape indicate (end of tape) */
        build_senseX(TAPE_BSENSE_EMPTYTAPE,dev,unitstat,code);
        return -1;
    }

    /* Handle end of file within block header */
    if (rc < (int)sizeof(AWSTAPE_BLKHDR))
    {
        WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "aws", "readhdr_awstape()", blkpos, "unexpected end of file");

        build_senseX(TAPE_BSENSE_BLOCKSHORT,dev,unitstat,code);
        return -1;
    }

    /* Successful return */
    return 0;

} /* end function readhdr_awstape */
Exemplo n.º 6
0
/*-------------------------------------------------------------------*/
static int start_vmnet(DEVBLK *dev, DEVBLK *xdev, int argc, char *argv[])
{
int sockfd[2];
int r, i;
char *ipaddress;

    if (argc < 2) {
        WRMSG (HHC00915, "E", SSID_TO_LCSS(dev->ssid), dev->devnum);
        return -1;
    }

    ipaddress = argv[0];
    argc--;
    argv++;

    if (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) {
        WRMSG (HHC00900, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "socketpair()", strerror(errno));
        return -1;
    }

    r = fork ();

    if (r < 0) {
        WRMSG (HHC00900, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "fork()", strerror(errno));
        return -1;
    } else if (r == 0) {
        /* child */
        close (0);
        close (1);
        dup (sockfd[1]);
        dup (sockfd[1]);
        r = (sockfd[0] > sockfd[1]) ? sockfd[0] : sockfd[1];
        for (i = 3; i <= r; i++) {
            close (i);
        }

        /* the ugly cast is to silence a compiler warning due to const */
        execv (argv[0], (EXECV_ARG2_ARGV_T)argv);

        exit (1);
    }

    close (sockfd[1]);
    dev->fd = sockfd[0];
    xdev->fd = sockfd[0];

    /* We just blindly copy these out in the hope vmnet will pick them
     * up correctly.  I don't feel like implementing a complete login
     * scripting facility here...
     */
    write(dev->fd, ipaddress, (u_int)strlen(ipaddress));
    write(dev->fd, "\n", 1);
    return 0;
}
Exemplo n.º 7
0
static int VMNET_Write(DEVBLK *dev, BYTE *iobuf, U32 count, BYTE *unitstat)
{
U32 blklen = (iobuf[0]<<8) | iobuf[1];
U32 pktlen;
BYTE *p = iobuf + 2;
BYTE *buffer = dev->buf;
U32 len = 0, rem;

    if (count < blklen) {
        WRMSG (HHC00975, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "block", count, blklen);
        blklen = count;
    }
    while (p < iobuf + blklen) {
        pktlen = (p[0]<<8) | p[1];

        rem = iobuf + blklen - p;

        if (rem < pktlen) {
            WRMSG (HHC00975, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "packet", rem, pktlen);
            pktlen = rem;
        }
        if (pktlen < 6) {
        WRMSG (HHC00975, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "packet", pktlen, 6);
            pktlen = 6;
        }

        pktlen -= 6;
        p += 6;

        while (pktlen--) {
            switch (*p) {
            case SLIP_END:
                buffer[len++] = SLIP_ESC;
                buffer[len++] = SLIP_ESC_END;
                break;
            case SLIP_ESC:
                buffer[len++] = SLIP_ESC;
                buffer[len++] = SLIP_ESC_ESC;
                break;
            default:
                buffer[len++] = *p;
                break;
            }
            p++;
        }
        buffer[len++] = SLIP_END;
        write(dev->fd, buffer, len);   /* should check error conditions? */
        len = 0;
    }

    *unitstat = CSW_CE | CSW_DE;

    return count;
}
Exemplo n.º 8
0
static int VMNET_Init(DEVBLK *dev, int argc, char *argv[])
{
U16             xdevnum;                /* Pair device devnum        */
DEVBLK          *xdev;                  /* Pair device               */
int rc;
U16 lcss;

    dev->devtype = 0x3088;

    dev->excps = 0;

    /* parameters for network CTC are:
     *    devnum of the other CTC device of the pair
     *    ipaddress
     *    vmnet command line
     *
     * CTC adapters are used in pairs, one for READ, one for WRITE.
     * The vmnet is only initialised when both are initialised.
     */
    if (argc < 3) {
        WRMSG(HHC00915, "E", SSID_TO_LCSS(dev->ssid), dev->devnum);
        return -1;
    }
    rc=parse_single_devnum(argv[0],&lcss,&xdevnum);
    if (rc<0)
    {
        WRMSG(HHC00916, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "device number", argv[0]);
        return -1;
    }
    xdev = find_device_by_devnum(lcss,xdevnum);
    if (xdev != NULL) {
        if (start_vmnet(dev, xdev, argc - 1, &argv[1]))
            return -1;
    }
    strlcpy(dev->filename, "vmnet", sizeof(dev->filename) );

    /* Set the control unit type */
    /* Linux/390 currently only supports 3088 model 2 CTCA and ESCON */
    dev->ctctype = CTC_VMNET;

    SetSIDInfo( dev, 0x3088, 0x08, 0x3088, 0x01 );

    /* Initialize the device dependent fields */
    dev->ctcpos = 0;
    dev->ctcrem = 0;

    /* Set length of buffer */
    /* This size guarantees we can write a full iobuf of 65536
     * as a SLIP packet in a single write.  Probably overkill... */
    dev->bufsize = 65536 * 2 + 1;
    return 0;
}
Exemplo n.º 9
0
/*-------------------------------------------------------------------*/
int bsf_het (DEVBLK *dev, BYTE *unitstat,BYTE code)
{
int             rc;                     /* Return code               */

    /* Exit if already at BOT */
    if (dev->curfilen==1 && dev->nxtblkpos == 0)
    {
        build_senseX(TAPE_BSENSE_LOADPTERR,dev,unitstat,code);
        return -1;
    }

    rc = het_bsf (dev->hetb);
    if (rc < 0)
    {
        char msgbuf[128];
        MSGBUF( msgbuf, "Het error '%s': '%s'", het_error(rc), strerror(errno));
        WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "het", "het_bsf()", (off_t)dev->hetb->cblk, msgbuf);

        build_senseX(TAPE_BSENSE_LOCATEERR,dev,unitstat,code);
        return -1;
    }

    /* Maintain position */
    dev->blockid = rc;
    dev->curfilen--;

    /* Return success */
    return 0;

} /* end function bsf_het */
Exemplo n.º 10
0
/*-------------------------------------------------------------------*/
int fsf_het (DEVBLK *dev, BYTE *unitstat,BYTE code)
{
int             rc;                     /* Return code               */

    /* Forward space to start of next file */
    rc = het_fsf (dev->hetb);
    if (rc < 0)
    {
        char msgbuf[128];
        MSGBUF( msgbuf, "Het error '%s': '%s'", het_error(rc), strerror(errno));
        WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "het", "het_fsf()", (off_t)dev->hetb->cblk, msgbuf);

        if(rc==HETE_EOT)
        {
            build_senseX(TAPE_BSENSE_ENDOFTAPE,dev,unitstat,code);
        }
        else
        {
            build_senseX(TAPE_BSENSE_READFAIL,dev,unitstat,code);
        }
        return -1;
    }

    /* Maintain position */
    dev->blockid = rc;
    dev->curfilen++;

    /* Return success */
    return 0;

} /* end function fsf_het */
Exemplo n.º 11
0
/*-------------------------------------------------------------------*/
int write_hetmark( DEVBLK *dev, BYTE *unitstat, BYTE code )
{
int             rc;                     /* Return code               */

    if ( dev->hetb->writeprotect )
    {
        build_senseX(TAPE_BSENSE_WRITEPROTECT,dev,unitstat,code);
        return -1;
    }

    /* Write the tape mark */
    rc = het_tapemark (dev->hetb);
    if (rc < 0)
    {
        /* Handle error condition */
        char msgbuf[128];
        MSGBUF( msgbuf, "Het error '%s': '%s'", het_error(rc), strerror(errno));
        WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "het", "het_tapemark()", (off_t)dev->hetb->cblk, msgbuf);

        /* Set unit check with equipment check */
        build_senseX(TAPE_BSENSE_WRITEFAIL,dev,unitstat,code);
        return -1;
    }

    /* Return normal status */
    dev->blockid++;

    return 0;

} /* end function write_hetmark */
Exemplo n.º 12
0
/*-------------------------------------------------------------------*/
static void
write_buffer (DEVBLK *dev, char *buf, int len, BYTE *unitstat)
{
int             rc;                     /* Return code               */

    /* Write data to the printer file */
    if (dev->bs)
    {
        /* (socket printer) */
        rc = write_socket (dev->fd, buf, len);

        /* Check for socket error */
        if (rc < len)
        {
            /* Close the connection */
            if (dev->fd != -1)
            {
                int fd = dev->fd;
                dev->fd = -1;
                close_socket( fd );
                WRMSG (HHC01100, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->clientname, dev->bs->clientip, dev->bs->spec);
            }

            /* Set unit check with intervention required */
            dev->sense[0] = SENSE_IR;
            *unitstat = CSW_CE | CSW_DE | CSW_UC;
        }
    }
    else
    {
        /* Write data to the printer file */
        rc = write (dev->fd, buf, len);

        /* Equipment check if error writing to printer file */
        if (rc < len)
        {
            WRMSG (HHC01105, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "write()",
                   rc < 0 ? strerror(errno) : "incomplete record written");
            dev->sense[0] = SENSE_EC;
            *unitstat = CSW_CE | CSW_DE | CSW_UC;
        }
    }

} /* end function write_buffer */
Exemplo n.º 13
0
/*-------------------------------------------------------------------*/
int fsb_omafixed (DEVBLK *dev, OMATAPE_DESC *omadesc,
                        BYTE *unitstat,BYTE code)
{
off_t           eofpos;                 /* Offset of end of file     */
off_t           blkpos;                 /* Offset of current block   */
int             curblkl;                /* Length of current block   */

    /* Initialize current block position */
    blkpos = dev->nxtblkpos;

    /* Seek to end of file to determine file size */
    eofpos = lseek (dev->fd, 0, SEEK_END);
    if (eofpos < 0 || eofpos >= LONG_MAX)
    {
        /* Handle seek error condition */
        if ( eofpos >= LONG_MAX) errno = EOVERFLOW;
        WRMSG (HHC00205, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, omadesc->filename, "oma", "lseek()", strerror(errno));

        /* Set unit check with equipment check */
        build_senseX(TAPE_BSENSE_LOCATEERR,dev,unitstat,code);
        return -1;
    }

    /* Check if already at end of file */
    if (blkpos >= eofpos)
    {
        /* Close the current OMA file */
        if (dev->fd >= 0)
            close (dev->fd);
        dev->fd = -1;
        dev->nxtblkpos = 0;
        dev->prvblkpos = -1;

        /* Increment the file number */
        dev->curfilen++;

        /* Return zero to indicate tapemark */
        return 0;
    }

    /* Calculate current block length */
    curblkl = (int)(eofpos - blkpos);
    if (curblkl > omadesc->blklen)
        curblkl = omadesc->blklen;

    /* Update the offsets of the next and previous blocks */
    dev->nxtblkpos = (long)(blkpos + curblkl);
    dev->prvblkpos = (long)(blkpos);

    /* Return block length */
    return curblkl;

} /* end function fsb_omafixed */
Exemplo n.º 14
0
/*-------------------------------------------------------------------*/
void close_awstape (DEVBLK *dev)
{
    if( dev->fd >= 0 )
    {
        WRMSG (HHC00201, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "aws");
        close(dev->fd);
    }
    strlcpy(dev->filename, TAPE_UNLOADED, sizeof(dev->filename));
    dev->fd=-1;
    dev->blockid = 0;
    dev->fenced = 0;
    return;
}
Exemplo n.º 15
0
/*-------------------------------------------------------------------*/
static int printer_close_device ( DEVBLK *dev )
{
int fd = dev->fd;

    if (fd == -1)
        return 0;

    dev->fd      = -1;
    dev->stopdev =  FALSE;

    /* Close the device file */
    if ( dev->ispiped )
    {
#if !defined( _MSVC_ )
        close_pipe (fd);
#else /* defined( _MSVC_ ) */
        close (fd);
        /* Log end of child process */
        WRMSG (HHC01107, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->ptpcpid);
#endif /* defined( _MSVC_ ) */
        dev->ptpcpid = 0;
    }
    else
    {
        if (dev->bs)
        {
            /* Socket printer */
            close_socket (fd);
            WRMSG (HHC01100, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->bs->clientname, dev->bs->clientip, dev->bs->spec);
        }
        else
        {
            /* Regular printer */
            close (fd);
        }
    }

    return 0;
} /* end function printer_close_device */
Exemplo n.º 16
0
/*-------------------------------------------------------------------*/
int read_het (DEVBLK *dev, BYTE *buf, BYTE *unitstat,BYTE code)
{
int             rc;                     /* Return code               */

    rc = het_read (dev->hetb, buf);
    if (rc < 0)
    {
        /* Increment file number and return zero if tapemark was read */
        if (rc == HETE_TAPEMARK)
        {
            dev->curfilen++;
            dev->blockid++;
            return 0;
        }

        /* Handle end of file (uninitialized tape) condition */
        if (rc == HETE_EOT)
        {
            WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "het", "het_read()", (off_t)dev->hetb->cblk, "end of file (uninitialized tape)");

            /* Set unit exception with tape indicate (end of tape) */
            build_senseX(TAPE_BSENSE_ENDOFTAPE,dev,unitstat,code);
            return -1;
        }
        {
            char msgbuf[128];
            MSGBUF( msgbuf, "Het error '%s': '%s'", het_error(rc), strerror(errno));
            WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "het", "het_read()", (off_t)dev->hetb->cblk, msgbuf);
        }
        /* Set unit check with equipment check */
        build_senseX(TAPE_BSENSE_READFAIL,dev,unitstat,code);
        return -1;
    }
    dev->blockid++;
    /* Return block length */
    return rc;

} /* end function read_het */
Exemplo n.º 17
0
int  CTCX_Init( DEVBLK* pDEVBLK, int argc, char *argv[] )
{
    pDEVBLK->devtype = 0x3088;

    pDEVBLK->excps = 0;

    // The first argument is the device emulation type
    if( argc < 1 )
    {
        WRMSG (HHC00915, "E", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum );
        return -1;
    }

    if((pDEVBLK->hnd = hdl_ghnd(argv[0])))
    {
        if(pDEVBLK->hnd->init == &CTCX_Init)
            return -1;
        free(pDEVBLK->typname);
        pDEVBLK->typname = strdup(argv[0]);
        return (pDEVBLK->hnd->init)( pDEVBLK, --argc, ++argv );
    }
    WRMSG (HHC00970, "E", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum, argv[0]);
    return -1;
}
Exemplo n.º 18
0
static void*  CTCT_ListenThread( void* argp )
{
    int          connfd;
    socklen_t    servlen;
    char         str[80];
    CTCG_PARMBLK parm;

    // set up the parameters passed via create_thread
    parm = *((CTCG_PARMBLK*) argp);
    free( argp );

    for( ; ; )
    {
        servlen = sizeof(parm.addr);

        // await a connection
        connfd = accept( parm.listenfd,
                         (struct sockaddr *)&parm.addr,
                         &servlen );

        MSGBUF( str, "%s:%d",
                 inet_ntoa( parm.addr.sin_addr ),
                 ntohs( parm.addr.sin_port ) );

        if( strcmp( str, parm.dev->filename ) != 0 )
        {
            WRMSG(HHC00974, "E", SSID_TO_LCSS(parm.dev->ssid), parm.dev->devnum,
                    parm.dev->filename, str);
            close_socket( connfd );
        }
        else
        {
            parm.dev->fd = connfd;
        }

        // Ok, so having done that we're going to loop back to the
        // accept().  This was meant to handle the connection failing
        // at the other end; this end will be ready to accept another
        // connection.  Although this will happen, I'm sure you can
        // see the possibility for bad things to occur (eg if another
        // Hercules tries to connect).  This will also be fixed RSN.
    }

    // UNREACHABLE
}
Exemplo n.º 19
0
/*--------------------------------------------------------------------*/
DLL_EXPORT void  mpc_display_description( DEVBLK* pDEVBLK, char* pDesc )
{

    /* Display description, if one has been provided. */
    if( pDesc )
    {
        if( pDEVBLK )
        {
            // HHC03983 "%1d:%04X %s: %s
            WRMSG(HHC03983, "I", SSID_TO_LCSS(pDEVBLK->ssid), pDEVBLK->devnum, pDEVBLK->typname, pDesc );
        }
        else
        {
            // HHC03984 "%s"
            WRMSG(HHC03984, "I", pDesc );
        }
    }

    return;
}   /* End function  mpc_display_description() */
Exemplo n.º 20
0
/*-------------------------------------------------------------------*/
int rewind_het(DEVBLK *dev,BYTE *unitstat,BYTE code)
{
int rc;
    rc = het_rewind (dev->hetb);
    if (rc < 0)
    {
        /* Handle seek error condition */
        char msgbuf[128];
        MSGBUF( msgbuf, "Het error '%s': '%s'", het_error(rc), strerror(errno));
        WRMSG (HHC00205, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "het", "het_rewind()", msgbuf);

        build_senseX(TAPE_BSENSE_REWINDFAILED,dev,unitstat,code);
        return -1;
    }
    dev->nxtblkpos=0;
    dev->prvblkpos=-1;
    dev->curfilen=1;
    dev->blockid=0;
    dev->fenced = 0;
    return 0;
}
Exemplo n.º 21
0
/*-------------------------------------------------------------------*/
void build_attach_chrpt( DEVBLK *dev )
{
U32 ssid, subchan, crwarray[8], crwcount=0;
int devlock_obtained;

    /* Just return if shutting down */
    if (sysblk.shutdown)
        return;

    /* Retrieve Source IDs */
    devlock_obtained = (try_obtain_lock( &dev->lock ) == 0);
    {
        ssid    = ((U32)SSID_TO_LCSS( dev->ssid )) & CRW_RSID_MASK;
        subchan = ((U32)dev->subchan)              & CRW_RSID_MASK;
    }
    if (devlock_obtained)
        release_lock( &dev->lock );

    /* Build Subchannel Alert Channel Report */
    crwarray[crwcount++] =
        0
        | (sysblk.mss ? CRW_CHAIN : 0)
        | CRW_RSC_SUBCH
        | CRW_AR
        | CRW_ERC_ALERT
        | subchan
        ;
    if (sysblk.mss)
        crwarray[crwcount++] =
            0
            | CRW_RSC_SUBCH
            | CRW_AR
            | CRW_ERC_ALERT
            | (ssid << 8)
            ;

    /* Queue the Channel Report(s) */
    VERIFY( queue_channel_report( crwarray, crwcount ) == 0 );
}
Exemplo n.º 22
0
/*-------------------------------------------------------------------*/
int bsb_het (DEVBLK *dev, BYTE *unitstat,BYTE code)
{
int             rc;                     /* Return code               */

    /* Back space one block */
    rc = het_bsb (dev->hetb);
    if (rc < 0)
    {
        /* Increment file number and return zero if tapemark was read */
        if (rc == HETE_TAPEMARK)
        {
            dev->blockid--;
            dev->curfilen--;
            return 0;
        }

        /* Unit check if already at start of tape */
        if (rc == HETE_BOT)
        {
            build_senseX(TAPE_BSENSE_LOADPTERR,dev,unitstat,code);
            return -1;
        }
        {
            char msgbuf[128];
            MSGBUF( msgbuf, "Het error '%s': '%s'", het_error(rc), strerror(errno));
            WRMSG (HHC00204, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename,
                   "het", "het_bsb()", (off_t)dev->hetb->cblk, msgbuf);
        }
        /* Set unit check with equipment check */
        build_senseX(TAPE_BSENSE_READFAIL,dev,unitstat,code);
        return -1;
    }

    dev->blockid--;

    /* Return +1 to indicate back space successful */
    return +1;

} /* end function bsb_het */
Exemplo n.º 23
0
/*-------------------------------------------------------------------*/
void close_het (DEVBLK *dev)
{
    /* BHE 03/04/2010: This was the statement?? */
    /* if(dev->hetb->fd >= 0) */
    /* Caught it after a warning message */
    if(dev->fd >= 0)
    {
        WRMSG (HHC00201, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "het");
    }
    /* Close the HET file */
    het_close (&dev->hetb);

    /* Reinitialize the DEV fields */
    dev->fd = -1;
    dev->fh = NULL;
    strlcpy( dev->filename, TAPE_UNLOADED, sizeof(dev->filename) );
    dev->blockid = 0;
    dev->fenced = 0;

    return;

} /* end function close_het */
Exemplo n.º 24
0
/*-------------------------------------------------------------------*/
int sync_het(DEVBLK *dev, BYTE *unitstat,BYTE code)
{
int             rc;                     /* Return code               */

    /* Perform the flush */
    rc = het_sync (dev->hetb);
    if (rc < 0)
    {
        /* Handle error condition */
        if (HETE_PROTECTED == rc)
            build_senseX(TAPE_BSENSE_WRITEPROTECT,dev,unitstat,code);
        else
        {
            WRMSG (HHC00205, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "het", "het_sync()", strerror(errno));
            build_senseX(TAPE_BSENSE_WRITEFAIL,dev,unitstat,code);
        }
        return -1;
    }

    /* Return normal status */
    return 0;

} /* end function sync_het */
Exemplo n.º 25
0
/*-------------------------------------------------------------------*/
int sync_awstape (DEVBLK *dev, BYTE *unitstat,BYTE code)
{
    /* Unit check if tape is write-protected */
    if (dev->readonly)
    {
        build_senseX(TAPE_BSENSE_WRITEPROTECT,dev,unitstat,code);
        return -1;
    }

    /* Perform sync. Return error on failure. */
    if (fdatasync( dev->fd ) < 0)
    {
        /* Log the error */
        WRMSG (HHC00205, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "aws", "fdatasync()", strerror(errno));
        /* Set unit check with equipment check */
        build_senseX(TAPE_BSENSE_WRITEFAIL,dev,unitstat,code);
        return -1;
    }

    /* Return normal status */
    return 0;

} /* end function sync_awstape */
Exemplo n.º 26
0
/*-------------------------------------------------------------------*/
void close_omatape2(DEVBLK *dev)
{
    if (dev->fd >= 0)
    {
        WRMSG (HHC00201, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename, "oma");
        close (dev->fd);
    }
    dev->fd=-1;
    if (dev->omadesc != NULL)
    {
        free (dev->omadesc);
        dev->omadesc = NULL;
    }

    /* Reset the device dependent fields */
    dev->nxtblkpos=0;
    dev->prvblkpos=-1;
    dev->curfilen=1;
    dev->blockid=0;
    dev->fenced = 0;
    dev->omafiles = 0;
    return;
}
Exemplo n.º 27
0
/*-------------------------------------------------------------------*/
static void printer_execute_ccw (DEVBLK *dev, BYTE code, BYTE flags,
        BYTE chained, U16 count, BYTE prevcode, int ccwseq,
        BYTE *iobuf, BYTE *more, BYTE *unitstat, U16 *residual)
{
int             rc = 0;                 /* Return code               */
int             i;                      /* Loop counter              */
int             num;                    /* Number of bytes to move   */
char           *eor;                    /* -> end of record string   */
char           *nls = "\n\n\n";         /* -> new lines              */
BYTE            c;                      /* Print character           */
char            hex[3];                 /* for hex conversion        */
char            wbuf[150];

    /* Reset flags at start of CCW chain */
    if (chained == 0)
    {
        dev->diaggate = 0;
    }

    /* Open the device file if necessary */
    if (dev->fd < 0 && !IS_CCW_SENSE(code))
        rc = open_printer (dev);
    else
    {
        /* If printer stopped, return intervention required */
        if (dev->stopdev && !IS_CCW_SENSE(code))
            rc = -1;
        else
            rc = 0;
    }

    if (rc < 0)
    {
        /* Set unit check with intervention required */
        dev->sense[0] = SENSE_IR;
        *unitstat = CSW_UC;
        return;
    }

    /* Process depending on CCW opcode */

    switch (code) {

    case 0x01: /* Write     No Space             */
    case 0x09: /* Write and Space 1 Line         */
    case 0x11: /* Write and Space 2 Lines        */
    case 0x19: /* Write and Space 3 Lines        */

    case 0x89: /* Write and Skip to Channel 1    */
    case 0x91: /* Write and Skip to Channel 2    */
    case 0x99: /* Write and Skip to Channel 3    */
    case 0xA1: /* Write and Skip to Channel 4    */
    case 0xA9: /* Write and Skip to Channel 5    */
    case 0xB1: /* Write and Skip to Channel 6    */
    case 0xB9: /* Write and Skip to Channel 7    */
    case 0xC1: /* Write and Skip to Channel 8    */
    case 0xC9: /* Write and Skip to Channel 9    */
    case 0xD1: /* Write and Skip to Channel 10   */
    case 0xD9: /* Write and Skip to Channel 11   */
    case 0xE1: /* Write and Skip to Channel 12   */
        if (dev->rawcc)
        {
            sprintf(hex,"%02x",code);
            write_buffer(dev, hex, 2, unitstat);
            if (*unitstat != 0) return;
            WRITE_LINE();
            write_buffer(dev, "\n", 1, unitstat);
            if (*unitstat == 0)
                *unitstat = CSW_CE | CSW_DE;
            return;
        }

        if ( dev->browse && dev->ccpend && ((chained & CCW_FLAGS_CD) == 0) )
        {
            dev->ccpend = 0;
            /* dev->currline++; */
            write_buffer(dev, "\n", 1, unitstat);
            if (*unitstat != 0) return;
        }
        WRITE_LINE();
        if ((flags & CCW_FLAGS_CD) == 0)
        {
            if    ( code <= 0x80 ) /* line control */
            {
                coun = code / 8;
                if ( coun == 0 )
                {
                    dev->chskip = 1;
                    if ( dev->browse )
                    {
                        dev->ccpend = 1;
                        *unitstat = 0;
                    }
                    else
                        write_buffer(dev, "\r", 1, unitstat);
                    if (*unitstat == 0)
                        *unitstat = CSW_CE | CSW_DE;
                    return;
                }

                dev->ccpend = 0;
                dev->currline += coun;
                write_buffer(dev, nls, coun, unitstat);
                if (*unitstat == 0)
                    *unitstat = CSW_CE | CSW_DE;
                return;
            }
            else  /*code >  0x80*/ /* chan control */
            {
                /*
                if ( dev->browse )
                {
                    dev->currline++;
                    write_buffer(dev, "\n", 1, unitstat);
                    if (*unitstat != 0) return;
                }
                */
                chan = ( code - 128 ) / 8;
                if ( chan == 1 )
                {
                    write_buffer(dev, "\r", 1, unitstat);
                    if (*unitstat != 0)
                        return;
                }
                SKIP_TO_CHAN();
                if (*unitstat == 0)
                    *unitstat = CSW_CE | CSW_DE;
                return;
            }

        }
        *unitstat = CSW_CE | CSW_DE;
        return;

    case 0x03: /* No Operation                   */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0x0B: /*           Space 1 Line         */
    case 0x13: /*           Space 2 Lines        */
    case 0x1B: /*           Space 3 Lines        */

    case 0x8B: /*           Skip to Channel 1    */
    case 0x93: /*           Skip to Channel 2    */
    case 0x9B: /*           Skip to Channel 3    */
    case 0xA3: /*           Skip to Channel 4    */
    case 0xAB: /*           Skip to Channel 5    */
    case 0xB3: /*           Skip to Channel 6    */
    case 0xBB: /*           Skip to Channel 7    */
    case 0xC3: /*           Skip to Channel 8    */
    case 0xCB: /*           Skip to Channel 9    */
    case 0xD3: /*           Skip to Channel 10   */
    case 0xDB: /*           Skip to Channel 11   */
    case 0xE3: /*           Skip to Channel 12   */
        if (dev->rawcc)
        {
            sprintf(hex,"%02x",code);
            write_buffer(dev, hex, 2, unitstat);
            if (*unitstat != 0) return;
            eor = (dev->crlf) ? "\r\n" : "\n";
            write_buffer(dev, eor, (int)strlen(eor), unitstat);
            if (*unitstat == 0)
                *unitstat = CSW_CE | CSW_DE;
            return;
        }

        if    ( code <= 0x80 ) /* line control */
        {
            coun = code / 8;
            dev->ccpend = 0;
            dev->currline += coun;
            write_buffer(dev, nls, coun, unitstat);
            if (*unitstat == 0)
                *unitstat = CSW_CE | CSW_DE;
            return;
        }
        else  /*code >  0x80*/ /* chan control */
        {
            /*
            if ( dev->browse && dev->ccpend)
            {
                coun = 1;
                dev->ccpend = 0;
                dev->currline += coun;
                write_buffer(dev, nls, coun, unitstat);
                if (*unitstat != 0) return;
            }
            */
            chan = ( code - 128 ) / 8;
            SKIP_TO_CHAN();
            if (*unitstat == 0)
                *unitstat = CSW_CE | CSW_DE;
            return;
        }
        break;

    case 0x63:
    /*---------------------------------------------------------------*/
    /* LOAD FORMS CONTROL BUFFER                                     */
    /*---------------------------------------------------------------*/
        if (dev->rawcc)
        {
            sprintf(hex,"%02x",code);
            write_buffer(dev, hex, 2, unitstat);
            if (*unitstat != 0) return;
            for (i = 0; i < count; i++)
            {
                sprintf(hex,"%02x",iobuf[i]);
                dev->buf[i*2] = hex[0];
                dev->buf[i*2+1] = hex[1];
            } /* end for(i) */
            write_buffer(dev, (char *)dev->buf, i*2, unitstat);
            if (*unitstat != 0) return;
            eor = (dev->crlf) ? "\r\n" : "\n";
            write_buffer(dev, eor, (int)strlen(eor), unitstat);
            if (*unitstat != 0) return;
        }
        else
        {
            int i = 0;
            int j = 1;
            int more = 1;
            for (i = 0; i <= FCBSIZE; i++) dev->fcb[i] = 0;

            dev->lpi = 6;
            dev->index = 0;
            if (iobuf[0] & 0xc0)
            {
                /* First byte is a print position index */
                if ((iobuf[0] & 0xc0) == 0x80)
                    /* Indexing right */
                    dev->index = iobuf[0] & 0x1f;
                else
                    /* Indexing left */
                    dev->index = - (iobuf[0] & 0x1f);
                i = 1;
            }

            for (; i < count && j <= FCBSIZE && more; i++, j++)
            {
                dev->fcb[i] = iobuf[i] & 0x0f;
                if (dev->fcb[j] > 12)
                {
                    *residual = count - i;
                    *unitstat = CSW_CE | CSW_DE | CSW_UC;
                    dev->sense[0] = SENSE_CC;
                    return;
                }

                if (iobuf[i] & 0x10)
                {
                    /* Flag bit is on */
                    if (j == 1)
                        /* Flag bit in first byte means eight lines per inch */
                        dev->lpi = 8;
                    else
                        more = 0;
                }
            }
            if (more)
            {
                /* No flag in last byte or too many bytes */
                *residual = count - i;
                *unitstat = CSW_CE | CSW_DE | CSW_UC;
                dev->sense[0] = SENSE_CC;
                return;
            }
            *residual = count - i;
            dev->lpp = j - 1;

            fcb_dump(dev, wbuf, 150);
            WRMSG(HHC02210, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, wbuf );
        }
        /* Return normal status */
        *residual = 0;
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0x06:
    /*---------------------------------------------------------------*/
    /* DIAGNOSTIC CHECK READ                                         */
    /*---------------------------------------------------------------*/
        /* If not 1403, reject if not preceded by DIAGNOSTIC GATE */
        if (dev->devtype != 0x1403 && dev->diaggate == 0)
        {
            dev->sense[0] = SENSE_CR;
            *unitstat = CSW_CE | CSW_DE | CSW_UC;
            break;
        }

        /* Return normal status */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0x07:
    /*---------------------------------------------------------------*/
    /* DIAGNOSTIC GATE                                               */
    /*---------------------------------------------------------------*/
        /* Command reject if 1403, or if chained to another CCW
           except a no-operation at the start of the CCW chain */
        if (dev->devtype == 0x1403 || ccwseq > 1
            || (chained && prevcode != 0x03))
        {
            dev->sense[0] = SENSE_CR;
            *unitstat = CSW_CE | CSW_DE | CSW_UC;
            break;
        }

        /* Set diagnostic gate flag */
        dev->diaggate = 1;

        /* Return normal status */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0x0A:
    /*---------------------------------------------------------------*/
    /* DIAGNOSTIC READ UCS BUFFER                                    */
    /*---------------------------------------------------------------*/
        /* Reject if 1403 or not preceded by DIAGNOSTIC GATE */
        if (dev->devtype == 0x1403 || dev->diaggate == 0)
        {
            dev->sense[0] = SENSE_CR;
            *unitstat = CSW_CE | CSW_DE | CSW_UC;
            break;
        }

        /* Return normal status */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0x12:
    /*---------------------------------------------------------------*/
    /* DIAGNOSTIC READ fcb                                           */
    /*---------------------------------------------------------------*/
        /* Reject if 1403 or not preceded by DIAGNOSTIC GATE */
        if (dev->devtype == 0x1403 || dev->diaggate == 0)
        {
            dev->sense[0] = SENSE_CR;
            *unitstat = CSW_CE | CSW_DE | CSW_UC;
            break;
        }

        /* Return normal status */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0x23:
    /*---------------------------------------------------------------*/
    /* UNFOLD                                                        */
    /*---------------------------------------------------------------*/
        dev->fold = 0;
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0x43:
    /*---------------------------------------------------------------*/
    /* FOLD                                                          */
    /*---------------------------------------------------------------*/
        dev->fold = 1;
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0x73:
    /*---------------------------------------------------------------*/
    /* BLOCK DATA CHECK                                              */
    /*---------------------------------------------------------------*/
    /*
        *residual = 0;
    */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0x7B:
    /*---------------------------------------------------------------*/
    /* ALLOW DATA CHECK                                              */
    /*---------------------------------------------------------------*/
    /*
        *residual = 0;
    */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0xEB:
    /*---------------------------------------------------------------*/
    /* UCS GATE LOAD                                                 */
    /*---------------------------------------------------------------*/
        /* Command reject if not first command in chain */
        if (chained != 0)
        {
            dev->sense[0] = SENSE_CR;
            *unitstat = CSW_CE | CSW_DE | CSW_UC;
            break;
        }

        /* Return normal status */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0xF3:
    /*---------------------------------------------------------------*/
    /* LOAD UCS BUFFER AND FOLD                                      */
    /*---------------------------------------------------------------*/
        /* For 1403, command reject if not chained to UCS GATE */
        /* Also allow ALLOW DATA CHECK to get TSS/370 working  */
        /* -- JRM 11/28/2007 */
        if (dev->devtype == 0x1403 &&
            ((prevcode != 0xEB) && (prevcode != 0x7B)))
        {
            dev->sense[0] = SENSE_CR;
            *unitstat = CSW_CE | CSW_DE | CSW_UC;
            break;
        }

        /* Set fold indicator and return normal status */
        dev->fold = 1;
        dev->chskip = 1;
    /*
        *residual = 0;
    */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0xFB:
    /*---------------------------------------------------------------*/
    /* LOAD UCS BUFFER (NO FOLD)                                     */
    /*---------------------------------------------------------------*/
        /* For 1403, command reject if not chained to UCS GATE */
        if (dev->devtype == 0x1403 && prevcode != 0xEB)
        {
            dev->sense[0] = SENSE_CR;
            *unitstat = CSW_CE | CSW_DE | CSW_UC;
            break;
        }

        /* Reset fold indicator and return normal status */
        dev->fold = 0;
        dev->chskip = 1;

    /*
        *residual = 0;
    */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0x04:
    /*---------------------------------------------------------------*/
    /* SENSE                                                         */
    /*---------------------------------------------------------------*/
        /* Calculate residual byte count */
        num = (count < dev->numsense) ? count : dev->numsense;
        *residual = count - num;
        if (count < dev->numsense) *more = 1;

        /* Copy device sense bytes to channel I/O buffer */
        memcpy (iobuf, dev->sense, num);

        /* Clear the device sense bytes */
        memset (dev->sense, 0, sizeof(dev->sense));

        /* Return unit status */
        *unitstat = CSW_CE | CSW_DE;
        break;

    case 0xE4:
    /*---------------------------------------------------------------*/
    /* SENSE ID                                                      */
    /*---------------------------------------------------------------*/

        /* SENSE ID is only supported if LEGACYSENSEID is ON;
         * otherwise, fall through to invalid operation.
         */
        if (sysblk.legacysenseid)
        {
            /* Calculate residual byte count */
            num = (count < dev->numdevid) ? count : dev->numdevid;
            *residual = count - num;
            if (count < dev->numdevid) *more = 1;

            /* Copy device identifier bytes to channel I/O buffer */
            memcpy (iobuf, dev->devid, num);

            /* Return unit status */
            *unitstat = CSW_CE | CSW_DE;
            break;
        }

    default:
    /*---------------------------------------------------------------*/
    /* INVALID OPERATION                                             */
    /*---------------------------------------------------------------*/
        /* Set command reject sense byte, and unit check status */
        dev->sense[0] = SENSE_CR;
        *unitstat = CSW_UC;

    } /* end switch(code) */

} /* end function printer_execute_ccw */
Exemplo n.º 28
0
/*-------------------------------------------------------------------*/
static int
open_printer (DEVBLK *dev)
{
pid_t           pid;                    /* Child process identifier  */
int             open_flags;             /* File open flags           */
#if !defined( _MSVC_ )
int             pipefd[2];              /* Pipe descriptors          */
int             rc;                     /* Return code               */
#endif

    /* Regular open if 1st char of filename is not vertical bar */
    if (!dev->ispiped)
    {
        int fd;

        /* Socket printer? */
        if (dev->bs)
            return (dev->fd < 0 ? -1 : 0);

        /* Normal printer */
        open_flags = O_BINARY | O_WRONLY | O_CREAT /* | O_SYNC */;
        if (dev->notrunc != 1)
        {
            open_flags |= O_TRUNC;
        }
        fd = HOPEN (dev->filename, open_flags,
                    S_IRUSR | S_IWUSR | S_IRGRP);
        if (fd < 0)
        {
            WRMSG (HHC01105, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "open()", strerror(errno));
            return -1;
        }

        /* Save file descriptor in device block and return */
        dev->fd = fd;
        return 0;
    }

    /* Filename is in format |xxx, set up pipe to program xxx */

#if defined( _MSVC_ )

    /* "Poor man's" fork... */
    pid = w32_poor_mans_fork ( dev->filename+1, &dev->fd );
    if (pid < 0)
    {
        WRMSG (HHC01105, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "fork()", strerror(errno));
        return -1;
    }

    /* Log start of child process */
    WRMSG (HHC01106, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, pid);
    dev->ptpcpid = pid;

#else /* !defined( _MSVC_ ) */

    /* Create a pipe */
    rc = create_pipe (pipefd);
    if (rc < 0)
    {
        WRMSG (HHC01105, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "create_pipe()", strerror(errno));
        return -1;
    }

    /* Fork a child process to receive the pipe data */
    pid = fork();
    if (pid < 0)
    {
        WRMSG (HHC01005, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "fork()", strerror(errno));
        close_pipe ( pipefd[0] );
        close_pipe ( pipefd[1] );
        return -1;
    }

    /* The child process executes the pipe receiver program... */
    if (pid == 0)
    {
        /* Log start of child process */
        WRMSG (HHC01106, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, getpid());

        /* Close the write end of the pipe */
        close_pipe ( pipefd[1] );

        /* Duplicate the read end of the pipe onto STDIN */
        if (pipefd[0] != STDIN_FILENO)
        {
            rc = dup2 (pipefd[0], STDIN_FILENO);
            if (rc != STDIN_FILENO)
            {
                WRMSG (HHC01105, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, "dup2()", strerror(errno));
                close_pipe ( pipefd[0] );
                _exit(127);
            }
        } /* end if(pipefd[0] != STDIN_FILENO) */

        /* Close the original descriptor now duplicated to STDIN */
        close_pipe ( pipefd[0] );

        /* Redirect stderr (screen) to hercules log task */
        dup2(STDOUT_FILENO, STDERR_FILENO);

        /* Relinquish any ROOT authority before calling shell */
        SETMODE(TERM);

        /* Execute the specified pipe receiver program */
        rc = system (dev->filename+1);

        if (rc == 0)
        {
            /* Log end of child process */
            WRMSG (HHC01107, "I", SSID_TO_LCSS(dev->ssid), dev->devnum, getpid());
        }
        else
        {
            /* Log error */
            WRMSG (HHC01108, "E", SSID_TO_LCSS(dev->ssid), dev->devnum, dev->filename+1, strerror(errno));
        }

        /* The child process terminates using _exit instead of exit
           to avoid invoking the panel atexit cleanup routine */
        _exit(rc);

    } /* end if(pid==0) */

    /* The parent process continues as the pipe sender */

    /* Close the read end of the pipe */
    close_pipe ( pipefd[0] );

    /* Save pipe write descriptor in the device block */
    dev->fd = pipefd[1];
    dev->ptpcpid = pid;

#endif /* defined( _MSVC_ ) */

    return 0;

} /* end function open_printer */
Exemplo n.º 29
0
/*-------------------------------------------------------------------*/
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 */
Exemplo n.º 30
0
/*-------------------------------------------------------------------*/
static void* spthread (void* arg)
{
    DEVBLK* dev = (DEVBLK*) arg;
    BYTE byte;
    fd_set readset, errorset;
    struct timeval tv;
    int rc, fd = dev->fd;           // (save original fd)

    /* Fix thread name */
    {
        char thread_name[32];
        thread_name[sizeof(thread_name)-1] = 0;
        snprintf( thread_name, sizeof(thread_name)-1,
            "spthread %1d:%04X", SSID_TO_LCSS(dev->ssid), dev->devnum );
        SET_THREAD_NAME( thread_name );
    }

    // Looooop...  until shutdown or disconnect...

    // PROGRAMMING NOTE: we do our select specifying an immediate
    // timeout to prevent our select from holding up (slowing down)
    // the device thread (which does the actual writing of data to
    // the client). The only purpose for our thread even existing
    // is to detect a severed connection (i.e. to detect when the
    // client disconnects)...

    while ( !sysblk.shutdown && dev->fd == fd )
    {
        if (dev->busy)
        {
            SLEEP(3);
            continue;
        }

        FD_ZERO( &readset );
        FD_ZERO( &errorset );

        FD_SET( fd, &readset );
        FD_SET( fd, &errorset );

        tv.tv_sec = 0;
        tv.tv_usec = 0;

        rc = select( fd+1, &readset, NULL, &errorset, &tv );

        if (rc < 0)
            break;

        if (rc == 0)
        {
            SLEEP(3);
            continue;
        }

        if (FD_ISSET( fd, &errorset ))
            break;

        // Read and ignore any data they send us...
        // Note: recv should complete immediately
        // as we know data is waiting to be read.

        ASSERT( FD_ISSET( fd, &readset ) );

        rc = recv( fd, &byte, sizeof(byte), 0 );

        if (rc <= 0)
            break;
    }

    obtain_lock( &dev->lock );

    // PROGRAMMING NOTE: the following tells us whether we detected
    // the error or if the device thread already did. If the device
    // thread detected it while we were sleeping (and subsequently
    // closed the connection) then we don't need to do anything at
    // all; just exit. If we were the ones that detected the error
    // however, then we need to close the connection so the device
    // thread can learn of it...

    if (dev->fd == fd)
    {
        dev->fd = -1;
        close_socket( fd );
        WRMSG (HHC01100, "I", SSID_TO_LCSS(dev->ssid), dev->devnum,
               dev->bs->clientname, dev->bs->clientip, dev->bs->spec);
    }

    release_lock( &dev->lock );

    return NULL;

} /* end function spthread */