Add FAKETAPE support to tape utilities. ftlib.c and ftlib.h added. Faketape is detected by using file extension of ".fkt".

git-svn-id: file:///home/jj/hercules.svn/trunk@6158 956126f8-22a0-4046-8f4a-272fa8102e63
This commit is contained in:
Paul Gorlinsky
2010-07-07 01:44:02 +00:00
parent 432a2b29a4
commit dbc83ca0b5
12 changed files with 1101 additions and 69 deletions
+2
View File
@@ -1,3 +1,5 @@
06 Jul 2010 Add FTLIB.C FakeTape library; add support in hetmap and hetinit for
FAKETAPE.
22 Jun 2010 CAPPING feature. Capping can be set in hercules.cnf with the keyword
CAPPING and a number, representing the maximum MIPS for CPs. Capping
does not apply to specialty engines.
+8
View File
@@ -729,6 +729,10 @@
RelativePath=".\hetlib.h"
>
</File>
<File
RelativePath=".\ftlib.h"
>
</File>
<File
RelativePath=".\scsitape.h"
>
@@ -765,6 +769,10 @@
RelativePath=".\hetlib.c"
>
</File>
<File
RelativePath=".\ftlib.c"
>
</File>
<File
RelativePath=".\hettape.c"
>
+3
View File
@@ -143,6 +143,7 @@ dyndev_SRC = commadpt.c \
tapeccws.c \
sllib.c \
hetlib.c \
ftlib.c \
awstape.c \
faketape.c \
hettape.c \
@@ -335,6 +336,7 @@ endif
#
libherct_la_SOURCES = sllib.c \
ftlib.c \
hetlib.c
libherct_la_LDFLAGS = $(LIB_LD_FLAGS)
@@ -719,6 +721,7 @@ noinst_HEADERS = fishhang.h \
hbyteswp.h \
dasdblks.h \
hetlib.h \
ftlib.h \
version.h \
parser.h \
dasdtab.h \
+792
View File
@@ -0,0 +1,792 @@
/* FTLIB.C (c) Copyright TurboHercules, SAS 2010 */
/* Hercules Tape Function Lib for FAKETAPE */
/* */
/* Released under "The Q Public License Version 1" */
/* (http://www.hercules-390.org/herclic.html) as modifications to */
/* Hercules. */
// $Id: ftlib.c 6000 2010-05-18 14:30:48Z pgorlinsky $
/*-------------------------------------------------------------------*/
/* This module contains the FAKETAPE emulated tape format library. */
/* Note: this library was built from the original FAKETAPE.C source. */
/*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/* Reference information: */
/* FSIMS100 Faketape manual */
/*-------------------------------------------------------------------*/
#include "hstdinc.h"
#define _FTLIB_C_
#define _HTAPE_DLL_
#include "hercules.h" /* need Hercules control blocks */
#include "ftlib.h" /* Main faketape header file */
// Local constant data NOTE: Keep in sync with hetlib.c
static const char *fet_errstr[] =
{
"No error", // FETE_OK
"File error", // FETE_ERROR
"Tapemark read", // FETE_TAPEMARK
"Beginning of tape", // FETE_BOT
"End of tape", // FETE_EOT
"BOR not found", // FETE_BADBOR
"EOR not found", // FETE_BADEOR
"Unexpected tapemark", // FETE_BADMARK
"Buffer not big enough", // FETE_OVERFLOW
"Premature EOF", // FETE_PREMEOF
"Decompression error",
"Unknown compression method",
"Compression error",
"Specified length to big", // FETE_BADLEN
"Write protected", // FETE_PROTECTED
"Bad function code passed", // FETE_BADFUNC
"Bad compression method",
"Bad compression level",
"Bad write chunk size",
"Invalid direction specified", // FETE_BADDIR
"Insufficient memory", // FETE_NOMEM
"Couldn't read block header", // FETE_BADHDR
"Inconsistent compression flags",
"Block is short", // FETE_BADBLOCK
"Location error", // FETE_BADLOC
"Invalid error code", // unknown error
};
#define FET_ERRSTR_MAX ( sizeof( fet_errstr) / sizeof( fet_errstr[ 0 ] ) )
/*-------------------------------------------------------------------*/
/* Open a FAKETAPE format file */
/* */
/* If successful, the file descriptor is stored in the device block */
/* and the return value is zero. Otherwise the return value is < 0. */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_open ( FETB **fetb, char *filename, int flags )
{
int rc = -1; /* Return code */
int fd = -1;
char pathname[MAX_PATH]; /* file path in host format */
FETB *tfetb;
char *omode;
int oflags;
/* Open the FAKETAPE file */
*fetb = NULL;
hostpath(pathname, filename, sizeof(pathname));
/*
|| Allocate a new FETB
*/
tfetb = calloc( 1, sizeof( FETB ) );
if( tfetb == NULL )
{
return( FETE_NOMEM );
}
/*
|| clear FETOPEN_CREATE if FETOPEN_READONLY is specified
*/
if(flags & FETOPEN_READONLY)
{
flags&=~FETOPEN_CREATE;
}
/*
|| Translate HET create flag to filesystem flag
*/
oflags = ( ( flags & FETOPEN_CREATE ) ? O_CREAT : 0 );
omode = "r+b";
if( !( flags & FETOPEN_READONLY ) )
{
fd = open( pathname, O_RDWR | O_BINARY | oflags, S_IRUSR | S_IWUSR | S_IRGRP );
}
/* If file is read-only, attempt to open again */
if ( ( flags & FETOPEN_READONLY ) || (fd < 0 && (EROFS == errno || EACCES == errno)))
{
omode = "rb";
tfetb->writeprotect = TRUE;
fd = open( pathname, O_RDONLY | O_BINARY, S_IRUSR | S_IRGRP );
}
/*
|| Error out if both opens failed
*/
if( fd == -1 )
{
free( tfetb );
return( FETE_ERROR );
}
/*
|| Associate stream with file descriptor
*/
tfetb->fd = fdopen( fd, omode );
if( tfetb->fd == NULL )
{
rc = errno;
close( fd );
errno = rc;
free( tfetb );
return( FETE_ERROR );
}
/*
|| If uninitialized tape, write 2 tapemarks to make it a valid NL tape
*/
rc = fet_read_header( tfetb, 0L, NULL, NULL );
if( rc < 0 && rc != FETE_TAPEMARK )
{
if( rc != FETE_EOT )
{
return( rc );
}
rc = fet_tapemark( tfetb );
if( rc < 0 )
{
return( rc );
}
rc = fet_tapemark( tfetb );
if( rc < 0 )
{
return( rc );
}
}
/*
|| Reposition tape to load point
*/
rc = fet_rewind( tfetb );
if( rc < 0 )
{
return( rc );
}
/*
|| Give the caller the new FETB
*/
*fetb = tfetb;
return( 0 );
} /* end function fet_open */
/*-------------------------------------------------------------------*/
/* Close a FAKETAPE format file */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_close ( FETB **fetb )
{
if( *(fetb) != NULL )
{
if( (*fetb)->fd != NULL )
{
fclose( (*fetb)->fd );
}
free( *(fetb) );
}
*fetb = NULL;
return( 0 );
}
/*-------------------------------------------------------------------*/
/* Read a FAKETAPE block header */
/* */
/* If successful, return value is zero, and prvblkl and curblkl are */
/* set to the previous and current block lengths respectively. */
/* If error, return value is -1 and unitstat is set to CE+DE+UC */
/* and prvblkl and curblkl are undefined. Either or both of prvblkl */
/* and/or curblkl may be NULL. */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_read_header( FETB *fetb, off_t blkpos,
U16* pprvblkl, U16* pcurblkl )
{
int rc; /* Return code */
off_t rcoff; /* Return code from lseek() */
FAKETAPE_BLKHDR fakehdr; /* FakeTape block header */
char sblklen[5]; /* work for converting hdr */
int prvblkl; /* Previous block length */
int curblkl; /* Current block length */
int xorblkl; /* XOR check of block lens */
/* Reposition file to the requested block header */
rc = fseek( fetb->fd, blkpos, SEEK_SET );
if (rc < 0)
{
return FETE_ERROR;
}
else
rcoff = ftell( fetb->fd );
/* Read the 12-ASCII-hex-character block header */
rc = (int)fread( &fakehdr, 1, sizeof(FAKETAPE_BLKHDR), fetb->fd );
/* Handle read error condition */
if (rc < 0)
{
return FETE_ERROR;
}
/* Handle end of file (uninitialized tape) condition */
if (rc == 0)
{
return FETE_EOT;
}
/* Handle end of file within block header */
if (rc < (int)sizeof(FAKETAPE_BLKHDR))
{
return FETE_BADHDR;
}
/* Convert the ASCII-hex-character block lengths to binary */
strncpy( sblklen, fakehdr.sprvblkl, 4 ); sblklen[4] = 0; sscanf( sblklen, "%x", &prvblkl );
strncpy( sblklen, fakehdr.scurblkl, 4 ); sblklen[4] = 0; sscanf( sblklen, "%x", &curblkl );
strncpy( sblklen, fakehdr.sxorblkl, 4 ); sblklen[4] = 0; sscanf( sblklen, "%x", &xorblkl );
/* Verify header integrity using the XOR header field */
if ( (prvblkl ^ curblkl) != xorblkl )
{
return FETE_ERROR;
}
/* Return the converted value(s) to the caller */
if (pprvblkl) *pprvblkl = prvblkl;
if (pcurblkl) *pcurblkl = curblkl;
/* Successful return */
return FETE_OK;
} /* end function fet_read_header */
/*-------------------------------------------------------------------*/
/* Read a block from a FAKETAPE format file */
/* */
/* If successful, return value is block length read. */
/* If a tapemark was read, the return value is zero, and the */
/* current file number in the device block is incremented. */
/* If error, return value is < 0 */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_read ( FETB *fetb, BYTE *buf )
{
int rc; /* Return code */
off_t blkpos; /* Offset of block header */
U16 curblkl; /* Current block length */
/* Initialize current block position */
blkpos = fetb->nxtblkpos;
/* Read the block header to obtain the current block length */
rc = fet_read_header( fetb, blkpos, NULL, &curblkl );
if ( rc == FETE_EOT ) return FETE_EOT;
if (rc < 0)
return FETE_BADHDR; /* (error message already issued) */
ASSERT( curblkl >= 0 );
/* Calculate the offset of the next block header */
blkpos += sizeof(FAKETAPE_BLKHDR) + curblkl;
/* If not a tapemark, read the data block */
if (curblkl > 0)
{
rc = (int)fread( buf, 1, curblkl, fetb->fd );
/* Handle read error condition */
if (rc < 0)
{
return FETE_ERROR;
}
/* Handle end of file within data block */
if (rc < curblkl)
{
return FETE_BADBLOCK;
}
}
/* Calculate the offsets of the next and previous blocks */
fetb->prvblkpos = fetb->nxtblkpos;
fetb->nxtblkpos = blkpos;
/* Increment the block number */
fetb->blockid++;
/* Increment file number and return zero if tapemark was read */
if (curblkl == 0)
{
fetb->curfilen++;
return FETE_TAPEMARK; /* UX will be set by caller */
}
/* Return block length */
return curblkl;
} /* end function fet_read */
/*-------------------------------------------------------------------*/
/* Write a FAKETAPE block header */
/* */
/* If successful, return value is zero. */
/* If error, return value is < 0 */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_write_header ( FETB *fetb, off_t blkpos,
U16 prvblkl, U16 curblkl )
{
int rc; /* Return code */
off_t rcoff; /* Return code from lseek() */
FAKETAPE_BLKHDR fakehdr; /* FAKETAPE block header */
char sblklen[5]; /* work buffer */
/* Position file to where block header is to go */
rc = fseek( fetb->fd, blkpos, SEEK_SET );
if (rc < 0)
{
return FETE_BADLOC;
}
else
rcoff = ftell( fetb->fd );
/* Build the 12-ASCII-hex-character block header */
snprintf( sblklen, sizeof(sblklen), "%4.4X", prvblkl );
strncpy( fakehdr.sprvblkl, sblklen, sizeof(fakehdr.sprvblkl) );
snprintf( sblklen, sizeof(sblklen), "%4.4X", curblkl );
strncpy( fakehdr.scurblkl, sblklen, sizeof(fakehdr.scurblkl) );
snprintf( sblklen, sizeof(sblklen), "%4.4X", prvblkl ^ curblkl );
strncpy( fakehdr.sxorblkl, sblklen, sizeof(fakehdr.sxorblkl) );
/* Write the block header */
rc = (int)fwrite( &fakehdr, 1, sizeof(FAKETAPE_BLKHDR), fetb->fd );
if (rc < (int)sizeof(FAKETAPE_BLKHDR))
{
if(errno==ENOSPC)
{
/* Disk FULL */
return FETE_EOT;
}
return FETE_ERROR;
}
return 0;
} /* end function fet_write_header */
/*-------------------------------------------------------------------*/
/* Write a block to a FAKETAPE format file */
/* */
/* If successful, return value is zero. */
/* If error, return value is < 0 */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_write( FETB *fetb, BYTE *buf, U16 blklen )
{
int rc; /* Return code */
off_t rcoff; /* Return code from lseek() */
off_t blkpos; /* Offset of block header */
U16 prvblkl; /* Length of previous block */
/* Initialize current block position and previous block length */
blkpos = fetb->nxtblkpos;
prvblkl = 0;
/* Determine previous block length if not at start of tape */
if (fetb->nxtblkpos > 0)
{
/* Retrieve the previous block length */
rc = fet_read_header( fetb, fetb->prvblkpos, NULL, &prvblkl );
if (rc < 0) return FETE_ERROR;
/* Recalculate the offset of the next block */
blkpos = fetb->prvblkpos + sizeof(FAKETAPE_BLKHDR) + prvblkl;
}
/* Reposition file to the new block header */
rc = fseek( fetb->fd, blkpos, SEEK_SET );
if (rc < 0)
{
return FETE_BADLOC;
}
else
rcoff = ftell( fetb->fd );
if(fetb->maxsize>0)
{
if((off_t)(fetb->nxtblkpos+blklen+sizeof(FAKETAPE_BLKHDR)) > fetb->maxsize )
{
return FETE_EOT;
}
}
/* Write the block header */
rc = fet_write_header( fetb, rcoff, prvblkl, blklen );
if (rc < 0)
return FETE_EOT; /* (error message already issued) */
/* Calculate the offsets of the next and previous blocks */
fetb->nxtblkpos = blkpos + sizeof(FAKETAPE_BLKHDR) + blklen;
fetb->prvblkpos = blkpos;
/* Write the data block */
rc = (int)fwrite( buf, 1, blklen, fetb->fd);
if (rc < blklen)
{
if(errno==ENOSPC)
{
/* Disk FULL */
return FETE_ERROR;
}
return FETE_EOT;
}
/* Increment the block number */
fetb->blockid++;
/* Set new physical EOF */
do rc = ftruncate( fileno( fetb->fd ), fetb->nxtblkpos );
while (EINTR == rc);
if (rc != 0)
{
return FETE_EOT;
}
/* Return normal status */
return 0;
} /* end function fet_write */
/*-------------------------------------------------------------------*/
/* Write a tapemark to a FAKETAPE format file */
/* */
/* If successful, return value is zero. */
/* If error, return value is < 0 */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_tapemark( FETB *fetb )
{
int rc; /* Return code */
off_t rcoff; /* Return code from lseek() */
off_t blkpos; /* Offset of block header */
U16 prvblkl; /* Length of previous block */
/* Initialize current block position and previous block length */
blkpos = fetb->nxtblkpos;
prvblkl = 0;
/* Determine previous block length if not at start of tape */
if (fetb->nxtblkpos > 0)
{
/* Retrieve the previous block length */
rc = fet_read_header( fetb, fetb->prvblkpos, NULL, &prvblkl );
if (rc < 0)
return rc;
/* Recalculate the offset of the next block */
blkpos = fetb->prvblkpos + sizeof(FAKETAPE_BLKHDR) + prvblkl;
}
/* Reposition file to the new block header */
rc = fseek( fetb->fd, blkpos, SEEK_SET );
if (rc < 0)
{
return FETE_BADLOC;
}
else
rcoff = ftell( fetb->fd );
if(fetb->maxsize>0)
{
if((off_t)(fetb->nxtblkpos+sizeof(FAKETAPE_BLKHDR)) > fetb->maxsize)
{
return FETE_EOT;
}
}
/* Write the block header */
rc = fet_write_header( fetb, rcoff, prvblkl, 0 );
if (rc < 0)
return rc; /* (error message already issued) */
/* Increment the block number */
fetb->blockid++;
/* Calculate the offsets of the next and previous blocks */
fetb->nxtblkpos = blkpos + sizeof(FAKETAPE_BLKHDR);
fetb->prvblkpos = blkpos;
/* Set new physical EOF */
rc = ftell( fetb->fd );
do rc = ftruncate( fileno( fetb->fd ), fetb->nxtblkpos );
while (EINTR == rc);
if (rc != 0)
{
return FETE_PROTECTED;
}
/* Return normal status */
return 0;
} /* end function fet_tapemark */
/*-------------------------------------------------------------------*/
/* Synchronize a FAKETAPE format file (i.e. flush buffers to disk) */
/* */
/* If successful, return value is zero. */
/* If error, return value is < 0 */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_sync( FETB *fetb )
{
/* Unit check if tape is write-protected */
if (fetb->writeprotect)
{
return FETE_PROTECTED;
}
/* Perform sync. Return error on failure. */
if (fdatasync( fileno( fetb->fd ) ) < 0)
{
return FETE_ERROR;
}
/* Return normal status */
return 0;
} /* end function fet_sync */
/*-------------------------------------------------------------------*/
/* Forward space over next block of a FAKETAPE format file */
/* */
/* If successful, return value is the length of the block skipped. */
/* If the block skipped was a tapemark, the return value is zero, */
/* and the current file number in the device block is incremented. */
/* If error, return value is < 0. */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_fsb( FETB *fetb )
{
int rc; /* Return code */
off_t blkpos; /* Offset of block header */
U16 blklen; /* Block length */
/* Initialize current block position */
blkpos = fetb->nxtblkpos;
/* Read the block header to obtain the current block length */
rc = fet_read_header( fetb, blkpos, NULL, &blklen );
if (rc < 0)
return rc; /* (error message already issued) */
/* Calculate the offset of the next block */
blkpos += sizeof(FAKETAPE_BLKHDR) + blklen;
/* Calculate the offsets of the next and previous blocks */
fetb->prvblkpos = fetb->nxtblkpos;
fetb->nxtblkpos = blkpos;
/* Increment current file number if tapemark was skipped */
if (blklen == 0)
fetb->curfilen++;
/* Increment the block number */
fetb->blockid++;
/* Return block length or zero if tapemark */
return blklen;
} /* end function fet_fsb */
/*-------------------------------------------------------------------*/
/* Backspace to previous block of a FAKETAPE format file */
/* */
/* If successful, return value is the length of the block. */
/* If the block is a tapemark, the return value is zero, */
/* and the current file number in the device block is decremented. */
/* If error, return value is < 0 */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_bsb( FETB *fetb )
{
int rc; /* Return code */
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 (fetb->nxtblkpos == 0)
{
return FETE_BOT;
}
/* Backspace to previous block position */
blkpos = fetb->prvblkpos;
/* Read the block header to obtain the block lengths */
rc = fet_read_header( fetb, blkpos, &prvblkl, &curblkl );
if (rc < 0)
return rc; /* (error message already issued) */
/* Calculate the offset of the previous block */
fetb->prvblkpos = blkpos - sizeof(FAKETAPE_BLKHDR) - prvblkl;
fetb->nxtblkpos = blkpos;
/* Decrement current file number if backspaced over tapemark */
if (curblkl == 0)
fetb->curfilen--;
/* Decrement the block number */
fetb->blockid--;
/* Return block length or zero if tapemark */
return curblkl;
} /* end function fet_bsb */
/*-------------------------------------------------------------------*/
/* Forward space to next logical file of a FAKETAPE format file */
/* */
/* For FAKETAPE files, the forward space file operation is achieved */
/* by forward spacing blocks until positioned just after a tapemark. */
/* */
/* If successful, return value is zero, and the current file number */
/* in the device block is incremented by fet_fsb. */
/* If error, return value is < 0 */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_fsf( FETB *fetb )
{
int rc; /* Return code */
while (1)
{
/* Forward space over next block */
rc = fet_fsb( fetb );
if (rc < 0)
return rc; /* (error message already issued) */
/* Exit loop if spaced over a tapemark */
if (rc == 0)
break;
} /* end while */
/* Return normal status */
return 0;
} /* end function fet_fsf */
/*-------------------------------------------------------------------*/
/* Backspace to previous logical file of a FAKETAPE format file */
/* */
/* For FAKETAPE files, the backspace file operation is achieved */
/* by backspacing blocks until positioned just before a tapemark */
/* or until positioned at start of tape. */
/* */
/* If successful, return value is zero, and the current file number */
/* in the device block is decremented by fet_bsb. */
/* If error, return value is < 0 */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_bsf( FETB *fetb )
{
int rc; /* Return code */
while (1)
{
/* Exit if now at start of tape */
if (fetb->nxtblkpos == 0)
{
return FETE_BOT;
}
/* Backspace to previous block position */
rc = fet_bsb( fetb );
if (rc < 0)
return rc; /* (error message already issued) */
/* Exit loop if backspaced over a tapemark */
if (rc == 0)
break;
} /* end while */
/* Return normal status */
return 0;
} /* end function fet_bsf */
/*-------------------------------------------------------------------*/
/* Rewinds a FAKETAPE format file */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_rewind ( FETB *fetb )
{
int rc;
off_t rcoff;
rc = fseek( fetb->fd, 0L, SEEK_SET );
if ( rc < 0 )
{
return FETE_ERROR;
}
else
rcoff = ftell( fetb->fd );
fetb->nxtblkpos=0;
fetb->prvblkpos=-1;
fetb->curfilen=1;
fetb->blockid=0;
return 0;
}
/*-------------------------------------------------------------------*/
/* Determines if a FAKETAPE has passed a virtual EOT marker */
/*-------------------------------------------------------------------*/
DLL_EXPORT int
fet_passedeot ( FETB *fetb )
{
if(fetb->nxtblkpos==0)
fetb->eotwarning = FALSE;
else
if(fetb->maxsize==0)
fetb->eotwarning = TRUE;
else
if(fetb->nxtblkpos+fetb->eotmargin > fetb->maxsize)
fetb->eotwarning = TRUE;
else
fetb->eotwarning = FALSE;
return fetb->eotwarning;
}
DLL_EXPORT const char *
fet_error( int rc )
{
// no error, return OK
if( rc > -1 )
rc = 0;
rc *= -1; // make positive for indexing
if( rc >= (int)FET_ERRSTR_MAX ) // detect mismatch errors vs error strings
rc = FET_ERRSTR_MAX - 1;
return( fet_errstr[ rc ] );
}
+134
View File
@@ -0,0 +1,134 @@
/* FTLIB.H (c) Copyright TurboHercules, SAS 2010 */
/* Header files for FAKETAPE. */
/* */
/* Released under "The Q Public License Version 1" */
/* (http://www.hercules-390.org/herclic.html) as modifications to */
/* Hercules. */
// $Id: ftlib.h 6033 2010-05-25 03:55:37Z pgorlinsky $
#if !defined( _FTLIB_H_ )
#define _FTLIB_H_
#include "hercules.h"
#ifndef _FTLIB_C_
#ifndef _HTAPE_DLL_
#define FET_DLL_IMPORT DLL_IMPORT
#else /* _HTAPE_DLL_ */
#define FET_DLL_IMPORT extern
#endif /* _HTAPE_DLL_ */
#else
#define FET_DLL_IMPORT DLL_EXPORT
#endif
/*-------------------------------------------------------------------*/
/* Structure definition for Flex FakeTape block headers */
/*-------------------------------------------------------------------*/
/*
* The character length fields in a Flex FakeTape header are in BIG
* endian ASCII hex. That is to say, when the length field is ASCII
* "0123" (i.e. 0x30, 0x31, 0x32, 0x33), the length of the block is
* decimal 291 bytes (0x0123 == 291).
*
* The two block length fields are followed by an XOR "check" field
* calculated as the XOR of the two preceding length fields and is
* used to verify the integrity of the header.
*
* The Flex FakeTape tape format does not support any flag fields
* in its header and thus does not support any type of compression.
*/
typedef struct _FAKETAPE_BLKHDR
{ /*
* PROGRAMMING NOTE: note that for Flex FakeTapes, the "previous
* chunk size" comes FIRST, followed by the "current chunk size"
* second. This is the complete opposite from the way it is for
* AWS tape files. Also note that for Flex FakeTape the size fields
* are in BIG endian ASCII hex-string whereas for AWS tapes
* they're LITTLE endian binary.
*/
char sprvblkl[4]; /* length of previous block */
char scurblkl[4]; /* length of this block */
char sxorblkl[4]; /* XOR both lengths together */
}
FAKETAPE_BLKHDR;
/*
|| Control block for FakeTape Emulated Tape files
*/
typedef struct _fetb
{
FILE *fd; /* Tape file descriptor */
char filename[MAX_PATH]; /* filename */
off_t nxtblkpos; /* Offset from start of file
to next block */
off_t prvblkpos; /* Offset from start of file
to previous block */
off_t eotmargin; /* Amount of space left before
reporting EOT (in bytes) */
off_t maxsize; /* Maximum allowed TAPE file
size */
U16 curfilen; /* Current file number */
U32 blockid; /* Current device block ID */
FAKETAPE_BLKHDR chdr; /* Current block header */
u_int writeprotect:1; /* TRUE=write protected */
u_int readlast:1; /* TRUE=last i/o was read */
u_int truncated:1; /* TRUE=file truncated */
u_int eotwarning:1; /* TRUE=EOT warning area reached */
} FETB;
/*
|| Flags for fet_open()
*/
#define FETOPEN_CREATE 0x01 /* Create NL tape, if file missing */
#define FETOPEN_READONLY 0x02 /* Force the open read-only */
/*
|| Error definitions NOTE: Keep these in sync with hetlib.h
*/
#define FETE_OK 0 /* No error */
#define FETE_ERROR -1 /* File error (check errno) */
#define FETE_TAPEMARK -2 /* Tapemark read */
#define FETE_BOT -3 /* Beginning of tape */
#define FETE_EOT -4 /* End of tape */
#define FETE_BADBOR -5 /* BOR not found */
#define FETE_BADEOR -6 /* EOR not found */
#define FETE_BADMARK -7 /* Unexpected tapemark */
#define FETE_OVERFLOW -8 /* Buffer not big enough */
#define FETE_PREMEOF -9 /* Premature EOF */
#define FETE_DECERR -10 // unused
#define FETE_UNKMETH -11 // unused
#define FETE_COMPERR -12 // unused
#define FETE_BADLEN -13 /* Specified length to big */
#define FETE_PROTECTED -14 /* Write protected */
#define FETE_BADFUNC -15 /* Bad function code passed */
#define FETE_BADMETHOD -16 // unused
#define FETE_BADLEVEL -17 // unused
#define FETE_BADMSIZE -18 // unused
#define FETE_BADDIR -19 /* Invalid direction specified */
#define FETE_NOMEM -20 /* Insufficient memory */
#define FETE_BADHDR -21 /* Couldn't read block header */
#define FETE_BADCOMPRESS -22 // unused
#define FETE_BADBLOCK -23 /* Block is short */
#define FETE_BADLOC -24 /* Location error */
// Function Prototypes
FET_DLL_IMPORT int fet_open( FETB **fetb, char *filename, int flags );
FET_DLL_IMPORT int fet_close( FETB **fetb );
FET_DLL_IMPORT int fet_read_header( FETB *fetb, off_t blkpos, U16* pprvblkl, U16* pcurblkl );
FET_DLL_IMPORT int fet_read( FETB *fetb, void *sbuf );
FET_DLL_IMPORT int fet_write_header( FETB *fetb, off_t blkpos, U16 prvblkl, U16 curblkl );
FET_DLL_IMPORT int fet_write( FETB *fetb, void *sbuf, U16 slen );
FET_DLL_IMPORT int fet_tapemark( FETB *fetb );
FET_DLL_IMPORT int fet_sync( FETB *fetb );
FET_DLL_IMPORT int fet_bsb( FETB *fetb );
FET_DLL_IMPORT int fet_fsb( FETB *fetb );
FET_DLL_IMPORT int fet_bsf( FETB *fetb );
FET_DLL_IMPORT int fet_fsf( FETB *fetb );
FET_DLL_IMPORT int fet_rewind( FETB *fetb );
FET_DLL_IMPORT int fet_passedeot( FETB *fetb );
FET_DLL_IMPORT const char *fet_error( int rc );
#endif /* defined( _FTLIB_H_ ) */
+71 -20
View File
@@ -1,4 +1,5 @@
/* HETINIT.C (c) Copyright Leland Lucius, 2000-2009 */
/* (c) Copyright TurboHercules, SAS 2010 */
/* Creates IEHINITT or NL format Hercules Emulated Tapes */
/* */
/* Released under "The Q Public License Version 1" */
@@ -22,6 +23,7 @@
#include "hercules.h"
#include "hetlib.h"
#include "ftlib.h"
#include "sllib.h"
#include "herc_getopt.h"
@@ -59,10 +61,12 @@ main( int argc, char *argv[] )
char msgbuf[512]; /* message build work area */
int rc;
SLLABEL lab;
HETB *hetb;
HETB *hetb; /* used for aws and het tapes*/
FETB *fetb; /* used for faketapes */
int o_iehinitt;
int o_nl;
int o_compress;
int o_faketape;
char *o_filename;
char *o_owner;
char *o_volser;
@@ -105,7 +109,9 @@ main( int argc, char *argv[] )
display_version (stderr, msgbuf+10, FALSE);
hetb = NULL;
fetb = NULL;
o_filename = NULL;
o_faketape = FALSE;
o_iehinitt = TRUE;
o_nl = FALSE;
o_compress = TRUE;
@@ -158,6 +164,11 @@ main( int argc, char *argv[] )
o_filename = argv[ optind ];
if ( ( rc = (int)strlen( o_filename ) ) > 4 && ( rc = strcasecmp( &o_filename[rc-4], ".fkt" ) ) == 0 )
{
o_faketape = TRUE;
}
if( o_iehinitt )
{
if( argc == 2 )
@@ -191,18 +202,31 @@ main( int argc, char *argv[] )
if( o_owner )
het_string_to_upper( o_owner );
rc = het_open( &hetb, o_filename, HETOPEN_CREATE );
if( rc < 0 )
if ( o_faketape )
{
printf( MSG( HHC00075, "E", "het_open()", het_error( rc ) ) );
goto exit;
}
rc = fet_open( &fetb, o_filename, FETOPEN_CREATE );
if ( rc < 0 )
{
printf( MSG( HHC00075, "E", "fet_open()", fet_error( rc ) ) );
goto exit;
}
rc = het_cntl( hetb, HETCNTL_SET | HETCNTL_COMPRESS, o_compress );
if( rc < 0 )
}
else
{
printf( MSG( HHC00075, "E", "het_cntl()", het_error( rc ) ) );
goto exit;
rc = het_open( &hetb, o_filename, HETOPEN_CREATE );
if( rc < 0 )
{
printf( MSG( HHC00075, "E", "het_open()", het_error( rc ) ) );
goto exit;
}
rc = het_cntl( hetb, HETCNTL_SET | HETCNTL_COMPRESS, o_compress );
if( rc < 0 )
{
printf( MSG( HHC00075, "E", "het_cntl()", het_error( rc ) ) );
goto exit;
}
}
if( o_iehinitt )
@@ -214,10 +238,16 @@ main( int argc, char *argv[] )
goto exit;
}
rc = het_write( hetb, &lab, sizeof( lab ) );
if ( o_faketape )
rc = fet_write( fetb, &lab, (U16)sizeof( lab ) );
else
rc = het_write( hetb, &lab, sizeof( lab ) );
if( rc < 0 )
{
printf( MSG( HHC00075, "E", "het_write() for VOL1", het_error( rc ) ) );
if ( o_faketape )
printf( MSG( HHC00075, "E", "fet_write() for VOL1", fet_error( rc ) ) );
else
printf( MSG( HHC00075, "E", "het_write() for VOL1", het_error( rc ) ) );
goto exit;
}
@@ -227,34 +257,55 @@ main( int argc, char *argv[] )
printf( MSG( HHC00075, "E", "sl_hdr1()", sl_error( rc ) ) );
goto exit;
}
rc = het_write( hetb, &lab, sizeof( lab ) );
if ( o_faketape )
rc = fet_write( fetb, &lab, (U16)sizeof(lab) );
else
rc = het_write( hetb, &lab, sizeof( lab ) );
if( rc < 0 )
{
printf( MSG( HHC00075, "E", "het_write() for HDR1", het_error( rc ) ) );
if ( o_faketape )
printf( MSG( HHC00075, "E", "fet_write() for HDR1", fet_error( rc ) ) );
else
printf( MSG( HHC00075, "E", "het_write() for HDR1", het_error( rc ) ) );
goto exit;
}
}
else if( o_nl )
{
rc = het_tapemark( hetb );
if ( o_faketape )
rc = fet_tapemark( fetb );
else
rc = het_tapemark( hetb );
if( rc < 0 )
{
printf( MSG( HHC00075, "E", "het_tapemark()", het_error( rc ) ) );
if ( o_faketape )
printf( MSG( HHC00075, "E", "fet_tapemark()", fet_error( rc ) ) );
else
printf( MSG( HHC00075, "E", "het_tapemark()", het_error( rc ) ) );
goto exit;
}
}
rc = het_tapemark( hetb );
if ( o_faketape )
rc = fet_tapemark( fetb );
else
rc = het_tapemark( hetb );
if( rc < 0 )
{
printf( MSG( HHC00075, "E", "het_tapemark()", het_error( rc ) ) );
if ( o_faketape )
printf( MSG( HHC00075, "E", "fet_tapemark()", fet_error( rc ) ) );
else
printf( MSG( HHC00075, "E", "het_tapemark()", het_error( rc ) ) );
goto exit;
}
exit:
het_close( &hetb );
if ( o_faketape)
fet_close( &fetb );
else
het_close( &hetb );
return( rc < 0 );
}
+3 -1
View File
@@ -30,7 +30,7 @@
#undef HETDEBUGW
/*
|| Local constant data
|| Local constant data NOTE: Keep in sync with ftlib.c
*/
static const char *het_errstr[] =
{
@@ -57,6 +57,8 @@ static const char *het_errstr[] =
"Insufficient memory",
"Couldn't read block header",
"Inconsistent compression flags",
"Block is short",
"Location error",
"Invalid error code",
};
#define HET_ERRSTR_MAX ( sizeof( het_errstr) / sizeof( het_errstr[ 0 ] ) )
+2
View File
@@ -173,6 +173,8 @@ typedef struct _hetb
#define HETE_NOMEM -20 /* Insufficient memory */
#define HETE_BADHDR -21 /* Couldn't read block header */
#define HETE_BADCOMPRESS -22 /* Inconsistent compression flags */
#define HETE_BADBLOCK -23 // unused
#define HETE_BADLOC -24 // unused
/*
|| Public functions
+79 -42
View File
@@ -24,6 +24,7 @@
#include "hercules.h"
#include "hetlib.h"
#include "ftlib.h"
#include "sllib.h"
#include "herc_getopt.h"
@@ -189,7 +190,7 @@ static SInt32 Print_Block_Data ( SInt32 );
*/
static const char sep[] = "---------------------\n";
static const char help_hetmap[] =
"%s - Print a map of an HET or AWS tape file\n\n"
"%s - Print a map of an AWS, HET or FakeTape tape file\n\n"
"Usage: %s [options] filename\n\n"
"Options:\n"
" -a print all label and file information (default: on)\n"
@@ -200,7 +201,7 @@ static const char help_hetmap[] =
" -s print dump of each data file (SLANAL format) (default: off)\n"
" -t print TAPEMAP-compatible format output (default: off)\n";
static const char help_tapemap[] =
"%s - Print a map of an HET or AWS tape file\n\n"
"%s - Print a map of an AWS, HET or FakeTape tape file\n\n"
"Usage: %s filename\n\n";
#ifdef EXTERNALGUI
@@ -228,6 +229,9 @@ main( int argc, char *argv[] )
{
Boolean lProcStdLbl = FALSE;
HETB *hetb;
FETB *fetb;
char *i_filename;
int i_faketape = FALSE;
SInt32 rc;
SInt32 fileno;
SInt32 i;
@@ -240,7 +244,7 @@ main( int argc, char *argv[] )
U32 totblocks;
U32 totubytes;
U32 totcbytes;
U32 opts;
U32 opts = 0;
SInt32 lResidue = max_bytes_dsply; /* amount of space left to print */
char pgmpath[MAX_PATH];
char *pgm;
@@ -284,7 +288,7 @@ main( int argc, char *argv[] )
INITIALIZE_UTILITY(pgm);
/* Display the program identification message */
display_version (stderr, "Hercules HET and AWS tape map program", FALSE);
display_version (stderr, "Hercules AWS, HET and FakeTape tape map program", FALSE);
if (! (opts & O_TAPEMAP_INVOKED) )
{
@@ -295,45 +299,36 @@ main( int argc, char *argv[] )
{
rc = getopt( argc, argv, "adfhlst" );
if( rc == -1 )
{
break;
}
switch( rc )
{
case 'a':
opts = O_ALL;
break;
break;
case 'd':
opts = O_DATASETS;
break;
break;
case 'f':
opts = O_FILES;
break;
break;
case 'h':
Print_Usage( pgm );
exit( 1 );
break;
break;
case 'l':
opts = O_LABELS;
break;
break;
case 's':
opts = O_SLANAL_OUT;
break;
case 't':
opts = O_TAPEMAP_OUTPUT;
break;
break;
default:
Print_Usage( pgm );
exit( 1 );
break;
break;
}
}
@@ -352,11 +347,29 @@ main( int argc, char *argv[] )
printf( "%-20.20s: %s\n", "Filename", argv[ optind ] );
}
rc = het_open( &hetb, argv[ optind ], 0 );
i_filename = argv[ optind ];
if ( ( rc = (int)strlen( i_filename ) ) > 4 && ( rc = strcasecmp( &i_filename[rc-4], ".fkt" ) ) == 0 )
{
i_faketape = TRUE;
}
if ( i_faketape )
rc = fet_open( &fetb, i_filename, FETOPEN_READONLY );
else
rc = het_open( &hetb, i_filename, HETOPEN_READONLY );
if( rc < 0 )
{
printf( "het_open() returned %d\n", rc );
het_close( &hetb );
if ( i_faketape )
{
printf( "fet_open() returned %d\n", rc );
fet_close( &fetb );
}
else
{
printf( "het_open() returned %d\n", rc );
het_close( &hetb );
}
exit( 1 );
}
@@ -381,8 +394,12 @@ main( int argc, char *argv[] )
#ifdef EXTERNALGUI
if( extgui )
{
off_t curpos;
/* Report progress every nnnK */
off_t curpos = ftell( hetb->fd );
if ( i_faketape )
curpos = ftell( fetb->fd );
else
curpos = ftell( hetb->fd );
if( ( curpos & PROGRESS_MASK ) != ( prevpos & PROGRESS_MASK ) )
{
prevpos = curpos;
@@ -391,8 +408,13 @@ main( int argc, char *argv[] )
}
#endif /*EXTERNALGUI*/
rc = het_read( hetb, gBuffer );
if( rc == HETE_EOT )
if ( i_faketape)
{
rc = fet_read( fetb, gBuffer );
}
else
rc = het_read( hetb, gBuffer );
if( rc == HETE_EOT ) // FETE and HETE enums are the same
{
if( opts & O_TAPEMAP_OUTPUT )
{
@@ -400,7 +422,7 @@ main( int argc, char *argv[] )
}
break;
}
if( rc == HETE_TAPEMARK )
{
fileno += 1;
@@ -420,10 +442,13 @@ main( int argc, char *argv[] )
printf( "%-20.20s: %d\n", "Blocks", gBlkCount );
printf( "%-20.20s: %d\n", "Min Blocksize", uminsz );
printf( "%-20.20s: %d\n", "Max Blocksize", umaxsz );
printf( "%-20.20s: %d\n", "Uncompressed bytes", ubytes );
printf( "%-20.20s: %d\n", "Min Blocksize-Comp", cminsz );
printf( "%-20.20s: %d\n", "Max Blocksize-Comp", cmaxsz );
printf( "%-20.20s: %d\n", "Compressed bytes", cbytes );
if ( !i_faketape )
{
printf( "%-20.20s: %d\n", "Uncompressed bytes", ubytes );
printf( "%-20.20s: %d\n", "Min Blocksize-Comp", cminsz );
printf( "%-20.20s: %d\n", "Max Blocksize-Comp", cmaxsz );
printf( "%-20.20s: %d\n", "Compressed bytes", cbytes );
}
}
totblocks += gBlkCount;
@@ -445,18 +470,24 @@ main( int argc, char *argv[] )
if( rc < 0 )
{
printf( "het_read() returned %d\n", rc );
if ( i_faketape )
printf( "fet_read() returned %d\n", rc );
else
printf( "het_read() returned %d\n", rc );
break;
}
gBlkCount += 1;
ubytes += hetb->ublksize;
cbytes += hetb->cblksize;
if ( !i_faketape )
{
ubytes += hetb->ublksize;
cbytes += hetb->cblksize;
if( uminsz == 0 || hetb->ublksize < uminsz ) uminsz = hetb->ublksize;
if( hetb->ublksize > umaxsz ) umaxsz = hetb->ublksize;
if( cminsz == 0 || hetb->cblksize < cminsz ) cminsz = hetb->cblksize;
if( hetb->cblksize > cmaxsz ) cmaxsz = hetb->cblksize;
if( uminsz == 0 || hetb->ublksize < uminsz ) uminsz = hetb->ublksize;
if( hetb->ublksize > umaxsz ) umaxsz = hetb->ublksize;
if( cminsz == 0 || hetb->cblksize < cminsz ) cminsz = hetb->cblksize;
if( hetb->cblksize > cmaxsz ) cmaxsz = hetb->cblksize;
}
if ( rc >= 80 )
{
@@ -541,12 +572,18 @@ main( int argc, char *argv[] )
printf( "%-20.20s:\n", "Summary" );
printf( "%-20.20s: %d\n", "Files", fileno );
printf( "%-20.20s: %d\n", "Blocks", totblocks );
printf( "%-20.20s: %d\n", "Uncompressed bytes", totubytes );
printf( "%-20.20s: %d\n", "Compressed bytes", totcbytes );
printf( "%-20.20s: %d\n", "Reduction", totubytes - totcbytes );
if ( !i_faketape )
{
printf( "%-20.20s: %d\n", "Uncompressed bytes", totubytes );
printf( "%-20.20s: %d\n", "Compressed bytes", totcbytes );
printf( "%-20.20s: %d\n", "Reduction", totubytes - totcbytes );
}
}
het_close( &hetb );
if ( i_faketape )
fet_close( &fetb );
else
fet_close( &fetb );
return 0;
}
+3 -3
View File
@@ -183,10 +183,10 @@ dasdcopy_OBJ = dasdcopy.o dasdutil.o codepage.o hostinfo.o version.o \
hetget_OBJ = hetget.o hetlib.o sllib.o hostinfo.o version.o logmsg.o \
codepage.o pttrace.o hsys.o
hetinit_OBJ = hetinit.o hetlib.o sllib.o hostinfo.o version.o logmsg.o \
hetinit_OBJ = hetinit.o hetlib.o ftlib.o sllib.o hostinfo.o version.o logmsg.o \
codepage.o pttrace.o hsys.o
hetmap_OBJ = hetmap.o hetlib.o sllib.o hostinfo.o version.o logmsg.o \
hetmap_OBJ = hetmap.o hetlib.o ftlib.o sllib.o hostinfo.o version.o logmsg.o \
codepage.o pttrace.o hsys.o
hetupd_OBJ = hetupd.o hetlib.o sllib.o codepage.o hostinfo.o version.o logmsg.o pttrace.o hsys.o
@@ -199,7 +199,7 @@ HEADERS = codepage.h commadpt.h cpuint.h ctcadpt.h dasdblks.h \
dasdtab.h dat.h devtype.h esa390.h feat370.h feat390.h \
feat900.h featall.h featchk.h feature.h fishhang.h \
fthreads.h wthreads.h hbyteswp.h hercifc.h hercnls.h hercules.h \
hetlib.h hostinfo.h httpmisc.h htypes.h ieee-w32.h \
hetlib.h ftlib.h hostinfo.h httpmisc.h htypes.h ieee-w32.h \
inline.h linklist.h logger.h machdep.h opcode.h chsc.h \
parser.h sllib.h tapedev.h tt32api.h tuntap.h version.h \
vstore.h w32chan.h w32ctca.h shared.h hdl.h crypto.h \
+3 -3
View File
@@ -194,10 +194,10 @@ dasdcopy_OBJ = dasdcopy.o dasdutil.o codepage.o hostinfo.o version.o \
hetget_OBJ = hetget.o hetlib.o sllib.o hostinfo.o version.o logmsg.o \
codepage.o hsys.o pttrace.o
hetinit_OBJ = hetinit.o hetlib.o sllib.o hostinfo.o version.o logmsg.o \
hetinit_OBJ = hetinit.o hetlib.o ftlib.o sllib.o hostinfo.o version.o logmsg.o \
codepage.o hsys.o pttrace.o
hetmap_OBJ = hetmap.o hetlib.o sllib.o hostinfo.o version.o logmsg.o \
hetmap_OBJ = hetmap.o hetlib.o ftlib.o sllib.o hostinfo.o version.o logmsg.o \
codepage.o hsys.o pttrace.o
hetupd_OBJ = hetupd.o hetlib.o sllib.o codepage.o hostinfo.o version.o \
@@ -211,7 +211,7 @@ dyngui_OBJ = dyngui.o
HEADERS = codepage.h commadpt.h cpuint.h ctcadpt.h dasdblks.h \
dasdtab.h dat.h devtype.h esa390.h feat370.h feat390.h \
feat900.h featall.h featchk.h feature.h fishhang.h \
feat900.h featall.h featchk.h feature.h fishhang.h ftlib.h \
fthreads.h wthreads.h hbyteswp.h hercifc.h hercnls.h hercules.h \
hetlib.h hostinfo.h httpmisc.h htypes.h ieee-w32.h \
inline.h linklist.h logger.h machdep.h opcode.h chsc.h \
+1
View File
@@ -52,6 +52,7 @@ hdasd_OBJ = \
htape_OBJ = \
$(O)hetlib.obj \
$(O)ftlib.obj \
$(O)sllib.obj \
$(O)w32stape.obj