/****************************************************************************** * * 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 #include #include #include #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); }