/*-------------------------------------------------------------------*/ 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 */
/*-------------------------------------------------------------------*/ 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 */
/*-------------------------------------------------------------------*/ 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 */
/*-------------------------------------------------------------------*/ 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) { logmsg (_("HHCTA420E %4.4X: Error forward spacing to next file " "at block %8.8X in file %s: %s(%s)\n"), dev->devnum, dev->hetb->cblk, dev->filename, het_error(rc), strerror(errno)); 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 */
/*-------------------------------------------------------------------*/ 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) { logmsg (_("HHCTA421E %4.4X: Error back spacing to previous file " "at block %8.8X in file %s:\n %s(%s)\n"), dev->devnum, dev->hetb->cblk, dev->filename, het_error(rc), strerror(errno)); 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 */
/*-------------------------------------------------------------------*/ int write_het (DEVBLK *dev, BYTE *buf, U16 blklen, BYTE *unitstat,BYTE code) { int rc; /* Return code */ off_t cursize; /* Current size for size chk */ /* Check if we have already violated the size limit */ if(dev->tdparms.maxsize>0) { cursize=het_tell(dev->hetb); if(cursize>=dev->tdparms.maxsize) { build_senseX(TAPE_BSENSE_ENDOFTAPE,dev,unitstat,code); return -1; } } /* Write the data block */ rc = het_write (dev->hetb, buf, blklen); if (rc < 0) { /* Handle write error condition */ logmsg (_("HHCTA416E %4.4X: Error writing data block " "at block %8.8X in file %s: %s(%s)\n"), dev->devnum, dev->hetb->cblk, dev->filename, het_error(rc), strerror(errno)); /* Set unit check with equipment check */ build_senseX(TAPE_BSENSE_WRITEFAIL,dev,unitstat,code); return -1; } /* Check if we have violated the maxsize limit */ /* Also check if we are passed EOT marker */ if(dev->tdparms.maxsize>0) { cursize=het_tell(dev->hetb); if(cursize>dev->tdparms.maxsize) { logmsg (_("HHCTA430I %4.4X: max tape capacity exceeded\n"), dev->devnum); if(dev->tdparms.strictsize) { logmsg (_("HHCTA431I %4.4X: max tape capacity enforced\n"), dev->devnum); het_bsb(dev->hetb); cursize=het_tell(dev->hetb); ftruncate( fileno(dev->hetb->fd),cursize); dev->hetb->truncated=TRUE; /* SHOULD BE IN HETLIB */ } build_senseX(TAPE_BSENSE_ENDOFTAPE,dev,unitstat,code); return -1; } } /* Return normal status */ dev->blockid++; return 0; } /* end function write_het */
/*-------------------------------------------------------------------*/ 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 */ logmsg (_("HHCTA258E %4.4X: Error seeking to offset "I32_FMTX" " "in file %s: %s\n"), dev->devnum, blkpos, omadesc->filename, 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) { logmsg (_("HHCTA259E %4.4X: Error reading data block " "at offset "I32_FMTX" in file %s: %s\n"), dev->devnum, blkpos, omadesc->filename, 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 */
/*-------------------------------------------------------------------*/ 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 */
/*-------------------------------------------------------------------*/ 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 */
/*-------------------------------------------------------------------*/ 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 */
/*-------------------------------------------------------------------*/ int bsf_awstape (DEVBLK *dev, BYTE *unitstat,BYTE code) { int rc; /* Return code */ while (1) { /* Exit if now at start of tape */ if (dev->nxtblkpos == 0) { build_senseX(TAPE_BSENSE_LOADPTERR,dev,unitstat,code); return -1; } /* Backspace to previous block position */ rc = bsb_awstape (dev, unitstat,code); if (rc < 0) return -1; /* Exit loop if backspaced over a tapemark */ if (rc == 0) break; } /* end while */ /* Return normal status */ return 0; } /* end function bsf_awstape */
/*-------------------------------------------------------------------*/ int write_hetmark (DEVBLK *dev, BYTE *unitstat,BYTE code) { int rc; /* Return code */ /* Write the tape mark */ rc = het_tapemark (dev->hetb); if (rc < 0) { /* Handle error condition */ logmsg (_("HHCTA417E %4.4X: Error writing tape mark " "at block %8.8X in file %s: %s(%s)\n"), dev->devnum, dev->hetb->cblk, dev->filename, het_error(rc), strerror(errno)); /* 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 */
/*-------------------------------------------------------------------*/ int open_awstape (DEVBLK *dev, BYTE *unitstat,BYTE code) { int rc = -1; /* Return code */ char pathname[MAX_PATH]; /* file path in host format */ /* Check for no tape in drive */ if (!strcmp (dev->filename, TAPE_UNLOADED)) { build_senseX(TAPE_BSENSE_TAPEUNLOADED,dev,unitstat,code); return -1; } /* Open the AWSTAPE file */ hostpath(pathname, dev->filename, sizeof(pathname)); if(!dev->tdparms.logical_readonly) { rc = hopen(pathname, O_RDWR | O_BINARY); } /* If file is read-only, attempt to open again */ if (dev->tdparms.logical_readonly || (rc < 0 && (EROFS == errno || EACCES == errno))) { dev->readonly = 1; rc = hopen(pathname, O_RDONLY | O_BINARY); } /* Check for successful open */ if (rc < 0) { logmsg (_("HHCTA102E %4.4X: Error opening %s: %s\n"), dev->devnum, dev->filename, strerror(errno)); strcpy(dev->filename, TAPE_UNLOADED); build_senseX(TAPE_BSENSE_TAPELOADFAIL,dev,unitstat,code); return -1; } /* Store the file descriptor in the device block */ dev->fd = rc; rc=rewind_awstape(dev,unitstat,code); return rc; } /* end function open_awstape */
/*-------------------------------------------------------------------*/ 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; logmsg (_("HHCTA264E %4.4X: Error seeking to end of file %s: %s\n"), dev->devnum, omadesc->filename, 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 */
/*-------------------------------------------------------------------*/ 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) { logmsg (_("HHCTA414E %4.4X: End of file (end of tape) " "at block %8.8X in file %s\n"), dev->devnum, dev->hetb->cblk, dev->filename); /* Set unit exception with tape indicate (end of tape) */ build_senseX(TAPE_BSENSE_ENDOFTAPE,dev,unitstat,code); return -1; } logmsg (_("HHCTA415E %4.4X: Error reading data block " "at block %8.8X in file %s: %s(%s)\n"), dev->devnum, dev->hetb->cblk, dev->filename, het_error(rc), strerror(errno)); /* 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 */
/*-------------------------------------------------------------------*/ int fsb_het (DEVBLK *dev, BYTE *unitstat,BYTE code) { int rc; /* Return code */ /* Forward space one block */ rc = het_fsb (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; } logmsg (_("HHCTA418E %4.4X: Error forward spacing " "at block %8.8X in file %s: %s(%s)\n"), dev->devnum, dev->hetb->cblk, dev->filename, het_error(rc), strerror(errno)); /* Set unit check with equipment check */ if(rc==HETE_EOT) { build_senseX(TAPE_BSENSE_ENDOFTAPE,dev,unitstat,code); } else { build_senseX(TAPE_BSENSE_READFAIL,dev,unitstat,code); } return -1; } dev->blockid++; /* Return +1 to indicate forward space successful */ return +1; } /* end function fsb_het */
/*-------------------------------------------------------------------*/ 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 */
/*-------------------------------------------------------------------*/ 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; } logmsg (_("HHCTA419E %4.4X: Error reading data block " "at block %8.8X in file %s: %s(%s)\n"), dev->devnum, dev->hetb->cblk, dev->filename, het_error(rc), strerror(errno)); /* 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 */
/*-------------------------------------------------------------------*/ 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 */
/*-------------------------------------------------------------------*/ 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 */
/*-------------------------------------------------------------------*/ 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 */
/*-------------------------------------------------------------------*/ 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 { logmsg (_("HHCTA488E %4.4X: Sync error on file %s: %s\n"), dev->devnum, dev->filename, strerror(errno)); build_senseX(TAPE_BSENSE_WRITEFAIL,dev,unitstat,code); } return -1; } /* Return normal status */ return 0; } /* end function sync_het */
/*-------------------------------------------------------------------*/ 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 */ logmsg (_("HHCTA120E %4.4X: Sync error on file %s: %s\n"), dev->devnum, dev->filename, 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 */
/*-------------------------------------------------------------------*/ int rewind_awstape (DEVBLK *dev,BYTE *unitstat,BYTE code) { off_t rcoff; rcoff=lseek(dev->fd,0,SEEK_SET); if(rcoff<0) { 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; }
/*-------------------------------------------------------------------*/ int bsb_awstape (DEVBLK *dev, BYTE *unitstat,BYTE code) { int rc; /* Return code */ AWSTAPE_BLKHDR awshdr; /* AWSTAPE block header */ U16 curblkl; /* Length of current block */ U16 prvblkl; /* Length of previous block */ off_t blkpos; /* Offset of block header */ /* Unit check if already at start of tape */ if (dev->nxtblkpos == 0) { build_senseX(TAPE_BSENSE_LOADPTERR,dev,unitstat,code); return -1; } /* Backspace to previous block position */ blkpos = dev->prvblkpos; /* Read the 6-byte block header */ rc = readhdr_awstape (dev, blkpos, &awshdr, unitstat,code); if (rc < 0) return -1; /* Extract the block lengths from the block header */ curblkl = ((U16)(awshdr.curblkl[1]) << 8) | awshdr.curblkl[0]; prvblkl = ((U16)(awshdr.prvblkl[1]) << 8) | awshdr.prvblkl[0]; /* Calculate the offset of the previous block */ dev->prvblkpos = blkpos - sizeof(awshdr) - prvblkl; dev->nxtblkpos = blkpos; /* Decrement current file number if backspaced over tapemark */ if (curblkl == 0) dev->curfilen--; dev->blockid--; /* Return block length or zero if tapemark */ return curblkl; } /* end function bsb_awstape */
/*-------------------------------------------------------------------*/ int rewind_het(DEVBLK *dev,BYTE *unitstat,BYTE code) { int rc; rc = het_rewind (dev->hetb); if (rc < 0) { /* Handle seek error condition */ logmsg (_("HHCTA402E %4.4X: Error seeking to start of %s: %s(%s)\n"), dev->devnum, dev->filename, het_error(rc), strerror(errno)); 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; }
/*-------------------------------------------------------------------*/ 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; }
/*-------------------------------------------------------------------*/ int open_het (DEVBLK *dev, BYTE *unitstat,BYTE code) { int rc; /* Return code */ /* Check for no tape in drive */ if (!strcmp (dev->filename, TAPE_UNLOADED)) { build_senseX(TAPE_BSENSE_TAPEUNLOADED,dev,unitstat,code); return -1; } /* Open the HET file */ rc = het_open (&dev->hetb, dev->filename, dev->tdparms.logical_readonly ? HETOPEN_READONLY : HETOPEN_CREATE ); if (rc >= 0) { if(dev->hetb->writeprotect) { dev->readonly=1; } rc = het_cntl (dev->hetb, HETCNTL_SET | HETCNTL_COMPRESS, dev->tdparms.compress); if (rc >= 0) { rc = het_cntl (dev->hetb, HETCNTL_SET | HETCNTL_METHOD, dev->tdparms.method); if (rc >= 0) { rc = het_cntl (dev->hetb, HETCNTL_SET | HETCNTL_LEVEL, dev->tdparms.level); if (rc >= 0) { rc = het_cntl (dev->hetb, HETCNTL_SET | HETCNTL_CHUNKSIZE, dev->tdparms.chksize); } } } } /* Check for successful open */ if (rc < 0) { int save_errno = errno; het_close (&dev->hetb); errno = save_errno; logmsg (_("HHCTA401E %4.4X: Error opening %s: %s(%s)\n"), dev->devnum, dev->filename, het_error(rc), strerror(errno)); strcpy(dev->filename, TAPE_UNLOADED); build_senseX(TAPE_BSENSE_TAPELOADFAIL,dev,unitstat,code); return -1; } /* Indicate file opened */ dev->fd = 1; return 0; } /* end function open_het */
/*-------------------------------------------------------------------*/ int write_awsmark (DEVBLK *dev, BYTE *unitstat,BYTE code) { int rc; /* Return code */ off_t rcoff; /* Return code from lseek() */ AWSTAPE_BLKHDR awshdr; /* AWSTAPE block header */ off_t blkpos; /* Offset of block header */ U16 prvblkl; /* Length of previous block */ /* Initialize current block position and previous block length */ blkpos = dev->nxtblkpos; prvblkl = 0; /* Determine previous block length if not at start of tape */ if (dev->nxtblkpos > 0) { /* Reread the previous block header */ rc = readhdr_awstape (dev, dev->prvblkpos, &awshdr, unitstat,code); if (rc < 0) return -1; /* Extract the block length from the block header */ prvblkl = ((U16)(awshdr.curblkl[1]) << 8) | awshdr.curblkl[0]; /* Recalculate the offset of the next block */ blkpos = dev->prvblkpos + sizeof(awshdr) + prvblkl; } /* Reposition file to the new block header */ rcoff = lseek (dev->fd, blkpos, SEEK_SET); if (rcoff < 0) { /* Handle seek error condition */ logmsg (_("HHCTA117E %4.4X: Error seeking to offset "I64_FMTX" " "in file %s: %s\n"), dev->devnum, blkpos, dev->filename, strerror(errno)); build_senseX(TAPE_BSENSE_LOCATEERR,dev,unitstat,code); return -1; } /* ISW: Determine if we are passed maxsize */ if(dev->tdparms.maxsize>0) { if((off_t)(dev->nxtblkpos+sizeof(awshdr)) > dev->tdparms.maxsize) { build_senseX(TAPE_BSENSE_ENDOFTAPE,dev,unitstat,code); return -1; } } /* ISW: End of virtual physical EOT determination */ /* Build the 6-byte block header */ awshdr.curblkl[0] = 0; awshdr.curblkl[1] = 0; awshdr.prvblkl[0] = prvblkl & 0xFF; awshdr.prvblkl[1] = (prvblkl >>8) & 0xFF; awshdr.flags1 = AWSTAPE_FLAG1_TAPEMARK; awshdr.flags2 = 0; /* Write the block header */ rc = write (dev->fd, &awshdr, sizeof(awshdr)); if (rc < (int)sizeof(awshdr)) { /* Handle write error condition */ logmsg (_("HHCTA118E %4.4X: Error writing block header " "at offset "I64_FMTX" in file %s: %s\n"), dev->devnum, blkpos, dev->filename, strerror(errno)); build_senseX(TAPE_BSENSE_WRITEFAIL,dev,unitstat,code); return -1; } dev->blockid++; /* Calculate the offsets of the next and previous blocks */ dev->nxtblkpos = blkpos + sizeof(awshdr); dev->prvblkpos = blkpos; /* Set new physical EOF */ do rc = ftruncate( dev->fd, dev->nxtblkpos ); while (EINTR == rc); if (rc != 0) { /* Handle write error condition */ logmsg (_("HHCTA119E Error writing tape mark " "at offset "I64_FMTX" in file %s: %s\n"), blkpos, dev->filename, 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 write_awsmark */
/*-------------------------------------------------------------------*/ int read_awstape (DEVBLK *dev, BYTE *buf, BYTE *unitstat,BYTE code) { int rc; /* Return code */ AWSTAPE_BLKHDR awshdr; /* AWSTAPE block header */ off_t blkpos; /* Offset of block header */ int blklen = 0; /* Total length of block */ U16 seglen; /* Data length of segment */ /* Initialize current block position */ blkpos = dev->nxtblkpos; /* Read block segments until end of block */ do { /* Read the 6-byte block header */ rc = readhdr_awstape (dev, blkpos, &awshdr, unitstat,code); if (rc < 0) return -1; /* Extract the segment length from the block header */ seglen = ((U16)(awshdr.curblkl[1]) << 8) | awshdr.curblkl[0]; /* Calculate the offset of the next block segment */ blkpos += sizeof(awshdr) + seglen; /* Check that block length will not exceed buffer size */ if (blklen + seglen > MAX_BLKLEN) { logmsg (_("HHCTA107E %4.4X: Block length exceeds %d " "at offset "I64_FMTX" in file %s\n"), dev->devnum, (int)MAX_BLKLEN, blkpos, dev->filename); /* Set unit check with data check */ build_senseX(TAPE_BSENSE_READFAIL,dev,unitstat,code); return -1; } /* Check that tapemark blocksize is zero */ if ((awshdr.flags1 & AWSTAPE_FLAG1_TAPEMARK) && blklen + seglen > 0) { logmsg (_("HHCTA108E %4.4X: Invalid tapemark " "at offset "I64_FMTX" in file %s\n"), dev->devnum, blkpos, dev->filename); /* Set unit check with data check */ build_senseX(TAPE_BSENSE_READFAIL,dev,unitstat,code); return -1; } /* Exit loop if this is a tapemark */ if (awshdr.flags1 & AWSTAPE_FLAG1_TAPEMARK) break; /* Read data block segment from tape file */ rc = read (dev->fd, buf+blklen, seglen); /* Handle read error condition */ if (rc < 0) { logmsg (_("HHCTA109E %4.4X: Error reading data block " "at offset "I64_FMTX" in file %s: %s\n"), dev->devnum, blkpos, dev->filename, 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 < seglen) { logmsg (_("HHCTA110E %4.4X: Unexpected end of file in data block " "at offset "I64_FMTX" in file %s\n"), dev->devnum, blkpos, dev->filename); /* Set unit check with data check and partial record */ build_senseX(TAPE_BSENSE_BLOCKSHORT,dev,unitstat,code); return -1; } /* Accumulate the total block length */ blklen += seglen; } while ((awshdr.flags1 & AWSTAPE_FLAG1_ENDREC) == 0); /* Calculate the offsets of the next and previous blocks */ dev->prvblkpos = dev->nxtblkpos; dev->nxtblkpos = blkpos; /* Increment the block number */ dev->blockid++; /* Increment file number and return zero if tapemark was read */ if (blklen == 0) { dev->curfilen++; return 0; /* UX will be set by caller */ } /* Return block length */ return blklen; } /* end function read_awstape */