tldm-universe/Ardent/UV/sample/tapetest.c

876 lines
20 KiB
C
Raw Permalink Normal View History

2024-09-09 21:51:08 +00:00
/******************************************************************************
*
* tapetest - To determine parameters in &DEVICE& file for generic tape
*
* Module %M% Version %I% Date %H%
*
* (c) Copyright 1998 Ardent Software Inc. - All Rights Reserved
* This is unpublished proprietary source code of Ardent Software Inc.
* The copyright notice above does not evidence any actual or intended
* publication of such source code.
*
*******************************************************************************
*
* Maintenence log - insert most recent change descriptions at top
*
* Date.... GTAR# WHO Description.........................................
* 10/22/98 23801 SAP Change company name to Ardent
* 10/14/98 23801 SAP Change copyrights.
* 09/26/96 19334 AGM Clear up 'duplicate symbol' error when linking
* 09/02/96 19165 JJV Always call tape setup on NOREWOpen and retry get of
* tape MEDIA settings.
* 08/12/96 19031 JJV Added MIPS tape support and tape setup for NT.
* 05/21/96 18456 JJV Removed check for rewdev == norewdev on NT as not
* relevant. Also fixed writeT() for carts.
* 05/06/96 18242 DTM Code Cleanup, Phase I
* 02/02/96 17720 JJV Support for WINNT.
* 08/10/92 10004 TMC define __ISMAIN__
* 10/30/90 7207 JSM Added GENMSG logic
* 08/14/90 7207 JSM Message text changes
* 11/21/89 6207 FAI Port to Bull NCL.
* 04/27/89 5971 TJR fixed open
* 03/23/89 5503 GPS Source creation for ease of generic tape use
*
******************************************************************************/
#define __ISMAIN__
#define __MODULE__ "%M%"
#define __SCCSID__ "%I%"
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include "uv.h"
#ifdef MSWIN
#include "MTU.h"
#endif
#define GENMSG(xxxx) ( ( (xxxx) > tptmax ) ?\
( sprintf(defmsg,"Message[TPT%04d]\n",(xxxx)), defmsg ) :\
( tptmsg[(xxxx-1)] != 0 ?\
tptmsg[(xxxx-1)] :\
( sprintf(defmsg,"Message[TPT%04d]\n",(xxxx)),\
defmsg )))
#ifndef MSWIN
extern char *mktemp();
extern int atoi(), strncmp(), close();
extern unsigned int sleep();
#endif
extern void initmsg();
static int tptmax = 0;
static char **tptmsg = 0;
static char defmsg[17];
#ifdef MSWIN
static HANDLE tapefd;
static DWORD nread = 0;
static DWORD wrtn = 0;
static int status,recchar,recnotok,recno,F13,F14,F15,tryopen;
static char *iobuf1,*iobuf2;
static DWORD bufsiz;
static char *rewdev = 0 ; /* rewind device name */
static char *norewdev = 0 ; /* no rewind device name */
int access_mode = GENERIC_READ;
#endif
#ifndef ARDENT
#define DMAX 28
static char *dmsgs[DMAX] = {
"INVALID ARG:tapetest rewdevice norewdevice blocksize\n",
"Abort :Rewind device name must be different from norewind device. \n",
"Wrote two files each having two records. Trying to read them back.\n",
"Read first file contents correctly.\n",
"3rd record does not match;abort\n",
"Error reading 3rd record\n",
"Read second file contents correctly.\n",
"End of pass 1\n",
"Error in pass 2 on record comparison\n",
"Error reading after close in pass 2\n",
"End of pass 2\n",
"Do not rewind at load point\n",
"End of pass 3\n",
"Value of field 13^L^13\n",
"Value of field 13^E^13\n",
"Value of field 13^A^13\n",
"Value of field 14^Y^14\n",
"Value of field 14^N^14\n",
"Value of field 15^Y^15\n",
"Value of field 15^N^15\n",
"SUCCESSFUL RUN \n",
"Could not open rewind device",
"Could not write to tape",
"Error on reading record=%d\n",
"Error on tape read",
"Record # %d not written correctly\n",
"Error on reading EOF\n",
"Error could not write tapemark = %ld\n"
};
#endif
#ifdef MSWIN
extern void nt_perror();
#else
extern void perror();
#endif
#define NO 0
#define YES 1
#define L 2
#define E 3
#define A 4
#ifdef MSWIN
#define CONFIG_RETRY_LIM 10
#endif
#ifdef MSWIN
int tape_setup( HANDLE hDev, DWORD blocksize )
{
DWORD val, size, dBytes = 0, dwError = NO_ERROR;
TAPE_GET_MEDIA_PARAMETERS mparams;
TAPE_SET_MEDIA_PARAMETERS set_mparams;
TAPE_GET_DRIVE_PARAMETERS dparams;
int exit_code = 1;
int count = 0; /* Used to count up to retry limit */
size = sizeof(dparams);
val = GetTapeParameters(hDev, GET_TAPE_DRIVE_INFORMATION, &size, &dparams);
if( val != NO_ERROR )
{
/* Retry as we may have experienced a non-fatal error */
for( count = 0; count < CONFIG_RETRY_LIM; count++ )
{
if( val != NO_ERROR )
val = GetTapeParameters(hDev,
GET_TAPE_DRIVE_INFORMATION, &size, &dparams);
else
break;
}
}
if( val != NO_ERROR )
{
fprintf( stderr,"Failed to get tape device configuration (%ld)\n", val );
exit_code = 0;
goto exit;
}
else
{
/* Now set or check the blocksize */
if( dparams.FeaturesHigh & TAPE_DRIVE_SET_BLOCK_SIZE )
{
set_mparams.BlockSize = blocksize;
/* Try to set the blocksize */
val = SetTapeParameters( hDev, SET_TAPE_MEDIA_INFORMATION, &set_mparams );
if( val != NO_ERROR )
{
/* Failed, so use the default value reported by the tape */
if( dparams.DefaultBlockSize != 0 )
set_mparams.BlockSize = dparams.DefaultBlockSize;
else
set_mparams.BlockSize = 512; /* Got to try it.. */
val = SetTapeParameters( hDev, SET_TAPE_MEDIA_INFORMATION, &set_mparams );
if( val != NO_ERROR )
{
/* We can't do much about this so fail */
fprintf( stderr,
"Failed set tape blocksize (%ld)\n", val );
exit_code = 0;
goto exit;
}
}
}
else
{
if( dparams.DefaultBlockSize != 0 )
{
if( blocksize % dparams.DefaultBlockSize )
{
/*
* Our blocksize isn't a multiple of that
* supported by the device.
*/
fprintf( stderr,
"Blocksize (%ld) not supported by device.\n", blocksize );
exit_code = 0;
goto exit;
}
}
}
}
size = sizeof(mparams);
val = GetTapeParameters(hDev, GET_TAPE_MEDIA_INFORMATION, &size, &mparams);
if( val != NO_ERROR )
{
/* Retry as we may have experienced a non-fatal error */
for( count = 0; count < CONFIG_RETRY_LIM; count++ )
{
if( val != NO_ERROR )
val = GetTapeParameters(hDev,
GET_TAPE_MEDIA_INFORMATION, &size, &mparams);
else
break;
}
if( val != NO_ERROR )
{
fprintf( stderr,"Failed to get tape parameters (%ld).\n", val );
exit_code = 0;
goto exit;
}
}
exit:
return(exit_code);
}
#endif
/* REWIND - rewinds tape device */
#ifndef MSWIN
#define REWIND() { tryopen = 100; \
while(((tapefd = open(rewdev,O_RDONLY|O_EXCL,0666)) == -1) && tryopen--)\
{ sleep(2);\
}\
if (tapefd == -1)\
{\
perror(GENMSG(22)); /* nopen rewind dev */\
exit(1);\
}\
close(tapefd);\
}
#else
void REWIND()
{ tapefd = CreateFile(norewdev,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (tapefd == INVALID_HANDLE_VALUE)
{
nt_perror(GENMSG(22)); /* nopen rewind dev */
exit(1);
}
PrepareTape(tapefd, TAPE_LOAD, FALSE );
CloseHandle(tapefd);
}
#endif
void settobyte(s1,c,n)
char *s1,c;
int n;
{ register char *i = s1;
register int len = n;
while(len--) *i++ = c;
}
int cmp2strs(s1,s2,n)
char *s1,*s2;
int n;
{ register char *i = s1, *j = s2;
register int len= n;
while(len--) if(*i++ != *j++) return(*(i-1) - *(j-1));
return(0);
}
#ifdef MSWIN
void NTCloseHandle( HANDLE hDev )
{
int flag;
switch( access_mode )
{
case GENERIC_READ:
break;
case GENERIC_WRITE:
flag = WriteTapemark(hDev, TAPE_FILEMARKS, 1, FALSE);
if( flag != NO_ERROR )
{
/* Try to write a long filemark - it may be a 'T' type */
flag = WriteTapemark(hDev, TAPE_LONG_FILEMARKS, 1, FALSE);
if( flag != NO_ERROR )
printf( GENMSG(28), flag);
}
break;
}
CloseHandle( hDev );
}
#endif
/* NOREWopen - opens norewind tape device in the mode specified */
#ifndef MSWIN
#define NOREWopen(mode) { tryopen = 100; \
while (((tapefd = open(norewdev,mode|O_EXCL,0666)) == -1) && tryopen--)\
{ sleep(2);\
}\
if (tapefd == -1)\
{\
perror(GENMSG(22)); /* nopen rewind dev */\
exit(1);\
}\
}
#else
void NOREWopen(int mode)
{
/* Note: we need read & write to allow polling of config. params */
tapefd = CreateFile(norewdev,(GENERIC_READ | GENERIC_WRITE),0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (tapefd == INVALID_HANDLE_VALUE)
{
nt_perror(GENMSG(22)); /* nopen rewind dev */
exit(1);
}
access_mode = mode;
/* Call the setup program every time */
tape_setup( tapefd, bufsiz );
}
#endif
/* writeT - writes bufsiz number of characters specified on to tape */
#ifndef MSWIN
#define writeT(x) { recchar = 'A' + x;\
(void) settobyte(iobuf1,recchar,bufsiz);\
iobuf1[bufsiz] = 0;\
status=write(tapefd, iobuf1,(unsigned) bufsiz);\
if ( status == -1 )\
{\
perror(GENMSG(23)); /* cant write to tape */\
exit(1);\
}\
}
#else
void writeT(int x)
{ recchar = 'A' + x;
(void) settobyte(iobuf1,recchar,bufsiz);
iobuf1[bufsiz] = 0;
status=WriteFile(tapefd, iobuf1, bufsiz, &wrtn, NULL);
if ( (status == 0 ) && (GetLastError() != ERROR_INVALID_FUNCTION) )
{
nt_perror(GENMSG(23)); /* cant write to tape */
exit(1);
}
}
#endif
/* readT - Reads bufsiz number of characters from tape; compares it with
expected value. Aborts on error*/
#ifndef MSWIN
#define readT(x) { recchar = 'A' + x;\
(void) settobyte(iobuf1,recchar,bufsiz);\
iobuf1[bufsiz] = 0;\
status=read(tapefd, iobuf2,(unsigned) bufsiz);\
if ( status != bufsiz )\
{\
printf(GENMSG(24),x); /* rec read error */\
perror(GENMSG(25)); /* read error */\
exit(1);\
}\
iobuf2[bufsiz] = 0;\
recnotok=cmp2strs(iobuf1,iobuf2,bufsiz);\
if (recnotok)\
{\
printf(GENMSG(26),x); /* rec write error */\
exit(1);\
}\
}
#else
void readT(int x)
{ recchar = 'A' + x;
(void) settobyte(iobuf1,recchar,bufsiz);
iobuf1[bufsiz] = 0;
status=ReadFile(tapefd, iobuf2, bufsiz, &nread, NULL);
if ( nread != bufsiz )
{
printf(GENMSG(24),x); /* rec read error */
nt_perror(GENMSG(25)); /* read error */
exit(1);
}
iobuf2[bufsiz] = 0;
recnotok=cmp2strs(iobuf1,iobuf2,bufsiz);
if (recnotok)
{
printf(GENMSG(26),x); /* rec write error */
exit(1);
}
}
#endif
#ifndef MSWIN
#define readEOF { \
status=read(tapefd, iobuf2,(unsigned) bufsiz);\
if ( status > 0 )\
{\
printf(GENMSG(27)); /* read eof error */\
exit(1);\
}\
}
#else
void readEOF()
{
status=ReadFile(tapefd, iobuf2, bufsiz, &nread, NULL);
if ( nread > 0 )
{
printf(GENMSG(27)); /* read eof error */
exit(1);
}
}
#endif
#ifndef MSWIN
static char *rewdev = 0 ; /* rewind device name */
static char *norewdev = 0 ; /* no rewind device name */
static int bufsiz ; /* size of buffer used for tapeio */
char iobuf1[8196],iobuf2[8196];
#endif
int
main(argc,argv)
int argc;
char *argv[];
{
int i, j;
#ifndef MSWIN
int tapefd,status,recchar,recnotok,F13,F14,F15,tryopen;
#endif
#ifdef ARDENT
(void) initmsg("TPT",&tptmsg,&tptmax);
#else
tptmsg=(char**)malloc(tptmsg,DMAX*sizeof(char*));
for(x=0; x<=DMAX-1; x++)
(tptmsg)[x] = dmsgs[x];
tptmax = DMAX;
#endif
if (argc < 3 || argc > 4)
{
fprintf(stderr,GENMSG(1)); /* invalid arg */
exit(1);
}
#ifdef MSWIN
/* Allocate the tape i/o buffers & align them on MIPS (if needed) */
iobuf1 = (char *)malloc(8196 + TAPE_BUFFALIGN );
iobuf2 = (char *)malloc(8196 + TAPE_BUFFALIGN );
if( TAPE_BUFFALIGN > 8 )
{
iobuf1 = (char *)ALIGNNUM((int)iobuf1, 0, TAPE_BUFFALIGN);
iobuf2 = (char *)ALIGNNUM((int)iobuf2, 0, TAPE_BUFFALIGN);
}
#endif
rewdev = argv[1];
norewdev = argv[2];
if (argc==4)
bufsiz=atoi(argv[3]);
else
bufsiz=512;
i=strlen(rewdev);
j=strlen(norewdev);
#ifndef MSWIN
/* Rewind device should be different from no rewind device */
if (i==j)
{
if(!strncmp(rewdev,norewdev,i))
{
fprintf(stderr,GENMSG(2)); /* rewind diff norewind */
exit(1);
}
}
#endif
/* Rewind the device to ensure we are at load point */
REWIND();
/* Open no rewind device, write out two files with each having two records */
#ifndef MSWIN
NOREWopen(O_WRONLY);
#else
NOREWopen(GENERIC_WRITE);
#endif
writeT(1);
writeT(2);
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
#ifndef MSWIN
NOREWopen(O_WRONLY);
#else
NOREWopen(GENERIC_WRITE);
#endif
writeT(3);
writeT(4);
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
/* rewind tape */
REWIND();
printf(GENMSG(3)); /* wrote two files */
#ifndef MSWIN
NOREWopen(O_RDONLY);
#else
NOREWopen(GENERIC_READ);
#endif
/* read contents of first file */
readT(1);
readT(2);
#ifndef MSWIN
readEOF;
#else
readEOF();
#endif
printf(GENMSG(4)); /* read first file */
/* If this read gives EOF again field 15 is 'Y'.
If this read gives 3 rd record field 15 is 'N'.
otherwise abort */
#ifndef MSWIN
status = read( tapefd,iobuf2,(unsigned int) bufsiz );
if (status==bufsiz)
#else
status = ReadFile( tapefd,iobuf2, bufsiz, &nread, NULL );
if (nread==bufsiz)
#endif
{
recchar = 'A' + 3 ;
(void) settobyte(iobuf1,recchar,bufsiz);
iobuf2[bufsiz]=0;iobuf1[bufsiz]=0;
recnotok = cmp2strs(iobuf1,iobuf2,bufsiz);
if (recnotok)
{
fprintf(stderr,GENMSG(5)); /* 3rd rec mismatch */
exit(1);
}
F15 = NO;
}
else
if (( status==0 || status == -1))
{
F15 = YES;
#ifndef MSWIN
close(tapefd);
NOREWopen(O_RDONLY);
#else
NTCloseHandle(tapefd);
NOREWopen(GENERIC_READ);
#endif
readT(3);
}
else
{
fprintf(stderr,GENMSG(6)); /* 3rd rec read error */
exit(1);
}
/* Read rest of the file and rewind */
readT(4);
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
printf(GENMSG(7)); /* read second file */
REWIND();
printf(GENMSG(8)); /* end of pass1 */
/* End of pass1. At this point we have written two files and we are able to
read them. We also know the value of field 15. Now, we want to find out the
value of field 14. For that we will read first record, close the file and
read agin. If the second read gives us 2nd record than F14 value is N, if
the second read gives us 3rd record than F14 value is Y, otherwise abort */
#ifndef MSWIN
NOREWopen(O_RDONLY);
#else
NOREWopen(GENERIC_READ);
#endif
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
#ifndef MSWIN
NOREWopen(O_RDONLY);
#else
NOREWopen(GENERIC_READ);
#endif
#ifndef MSWIN
status = read( tapefd,iobuf2,(unsigned int) bufsiz );
if (status==bufsiz)
#else
status = ReadFile( tapefd,iobuf2, bufsiz, &nread, NULL );
if (nread==bufsiz)
#endif
{
recchar = 'A' + 1 ;
(void) settobyte(iobuf1,recchar,bufsiz);
iobuf2[bufsiz]=0;iobuf1[bufsiz]=0;
recnotok = cmp2strs(iobuf1,iobuf2,bufsiz);
if (recnotok)
{
recchar = 'A' + 3 ;
(void) settobyte(iobuf1,recchar,bufsiz);
iobuf2[bufsiz]=0;iobuf1[bufsiz]=0;
recnotok = cmp2strs(iobuf1,iobuf2,bufsiz);
if(recnotok)
{
fprintf(stderr,GENMSG(9)); /* record error in pass2 */
exit(1);
}
else
F14 = YES;
}
else
{
F14 = NO;
}
}
else
{
fprintf(stderr,GENMSG(10)); /* error reading after close in pass2 */
exit(1);
}
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
REWIND();
/* Fix for Hp; */
if (F14 == YES)
F15 = YES;
printf(GENMSG(11)); /* end of pass2 */
/* End of test2. Now we know the values of field 14, field 15. We want to know
if we can write at non-load-points.That is we want to find out the value of
field 13. We will try to write two records after 1st file and try to read it.
*/
#ifndef MSWIN
NOREWopen(O_RDONLY);
#else
NOREWopen(GENERIC_READ);
#endif
readT(1);
readT(2);
if (F15 == NO)
#ifndef MSWIN
readEOF;
#else
readEOF();
#endif
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
#ifndef MSWIN
NOREWopen(O_WRONLY);
#else
NOREWopen(GENERIC_WRITE);
#endif
writeT(5);
writeT(6);
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
REWIND();
#ifndef MSWIN
NOREWopen(O_RDONLY);
#else
NOREWopen(GENERIC_READ);
#endif
readT(1);
readT(2);
#ifndef MSWIN
readEOF;
#else
readEOF();
#endif
if (F15 == YES)
{
#ifndef MSWIN
close(tapefd);
NOREWopen(O_RDONLY);
#else
NTCloseHandle(tapefd);
NOREWopen(GENERIC_READ);
#endif
}
F13 = L;
#ifndef MSWIN
status = read( tapefd,iobuf2,(unsigned int) bufsiz );
if (status==bufsiz)
#else
status = ReadFile( tapefd,iobuf2, bufsiz, &nread, NULL );
if (nread==bufsiz)
#endif
{
recchar = 'A' + 5 ;
(void) settobyte(iobuf1,recchar,bufsiz);
iobuf2[bufsiz]=0;iobuf1[bufsiz]=0;
recnotok = cmp2strs(iobuf1,iobuf2,bufsiz);
if (!recnotok)
{
#ifndef MSWIN
status = read( tapefd,iobuf2,(unsigned int) bufsiz );
if (status == bufsiz)
#else
status = ReadFile( tapefd,iobuf2, bufsiz, &nread, NULL );
if (nread == bufsiz)
#endif
{
recchar = 'A' + 6 ;
(void) settobyte(iobuf1,recchar,bufsiz);
iobuf2[bufsiz]=0;iobuf1[bufsiz]=0;
recnotok = cmp2strs(iobuf1,iobuf2,bufsiz);
if(!recnotok)
F13 = E;
}
}
}
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
REWIND();
/* If F13=E and F14=N we will will check if writing in the middle of a file
works or not */
if (F13 == E && F14 == NO)
{
#ifndef MSWIN
NOREWopen(O_RDONLY);
#else
NOREWopen(GENERIC_READ);
#endif
readT(1);
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
#ifndef MSWIN
NOREWopen(O_WRONLY);
#else
NOREWopen(GENERIC_WRITE);
#endif
writeT(7);
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
REWIND();
#ifndef MSWIN
NOREWopen(O_RDONLY);
#else
NOREWopen(GENERIC_READ);
#endif
readT(1);
#ifndef MSWIN
status = read( tapefd,iobuf2,(unsigned int) bufsiz );
if (status==bufsiz)
#else
status = ReadFile( tapefd,iobuf2, bufsiz, &nread, NULL );
if (nread==bufsiz)
#endif
{
recchar = 'A' + 7 ;
(void) settobyte(iobuf1,recchar,bufsiz);
iobuf2[bufsiz]=0;iobuf1[bufsiz]=0;
recnotok = cmp2strs(iobuf1,iobuf2,bufsiz);
if (!recnotok)
F13 = A;
}
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
REWIND();
}
/* Now we want test to whether the tape behaves differently at load point or
not. IBMRT for instance does not move forward on close at load point,
though it does move forward on close at other points */
if (F14 == YES && F13 == E)
{
REWIND();
#ifndef MSWIN
NOREWopen(O_WRONLY);
#else
NOREWopen(GENERIC_WRITE);
#endif
recchar = 'A' + 8;
(void) settobyte(iobuf1,recchar,bufsiz);
iobuf1[bufsiz] = 0;
#ifndef MSWIN
status=write(tapefd, iobuf1,(unsigned) bufsiz);
if ( status == -1 )
#else
status=WriteFile(tapefd, iobuf1,(unsigned) bufsiz, &wrtn, NULL);
if ( status == 0 )
#endif
{
F13=L;
printf(GENMSG(12)); /* dont rewind at load point */
}
#ifndef MSWIN
close(tapefd);
#else
NTCloseHandle(tapefd);
#endif
REWIND();
}
printf(GENMSG(13)); /* end of pass3 */
if (F13 == L)
printf(GENMSG(14)); /* fld13 L */
else
if (F13 == E)
printf(GENMSG(15)); /* fld13 E */
else
printf(GENMSG(16)); /* fld13 A*/
if (F14 == YES)
printf(GENMSG(17)); /* fld14 Y */
else
printf(GENMSG(18)); /* fld14 N */
if (F15 == YES)
printf(GENMSG(19)); /* fld15 Y */
else
printf(GENMSG(20)); /* fld15 N */
printf(GENMSG(21)); /* sucessful run */
return(0);
}