/*********************************************************************** read_tape.c ********************************************************************** Description: Handles reading of data files from tape for the AAPM Patient Data Exchange format and subsequently writing the files to disk. ************************ Revision History: $Log: read_tape.c,v $ * Revision 1.1 2000/01/17 14:22:39 jwm * Remove comments originating in other development trees; Clean up some * compiler gripes found on castor * * Revision 1.0 2000/01/17 14:17:23 jwm * Initial revision ====================================================================*/ /* Include Files */ #include #include #include #include #include #include #include #include #include #include #include "exchkeys.h" #include "sitedata.h" #include "patexchange.h" /* GLOBAL FILE STREAM POINTER FOR LOG FILE */ FILE *aapm_log_file=NULL; char aapm_log_string[180]; /*********************************************************************** main() ********************************************************************** Functional Description: Handles the reading of fixed block length records from magnetic tape being used for patient data exchange. It reads all records of all files up to a double file mark. The files are automatically named "aapmXXXX" where the XXXX is the same as the file number (with 0000 being the directory file). The command line is as follows: read_tape where: read_tape is the name of the executable is the identifier of the device. On our SGI machines, for instance, for our DAT tape we use /dev/tps0d3nrnsv for the no-rewind, no byte swap, variable record length device (variable as the tape drive will use its own size if you don's specify variable). is the number of bytes in a tape block (2048 per protocol, but may be otherwise). is the path to the directory into which to place the tape files for later processing. We read the files onto disk before doing ANY processing on them with a different program than this. I only claim to know UNIX (System V, in particular). Your mileage may vary with conditions. *********************************************************************/ void main ( int argc, char *argv[] ) { int block_size; /* TAPE RECORD SIZE IN BYTES */ int files_done; /* FLAG FOR DOUBLE FILE MARK FOUND */ int records_done; /* FLAG FOR SINGLE FILE MARK FOUND */ int block_number; /* NUMBER OF BLOCK BEING PROCESSED */ int num_written; /* NUMBER OF BYTES WRITTEN TO DISK */ int file_number; /* FILE NUMBER BEING PROCESSED */ int max_files; /* MAX # OF FILES ON TAPE */ char *device; /* TAPE DEVICE STRING */ char *path; /* DESTINATION PATH FOR FILES */ char filename[PATH_MAX]; /* OUTPUT DISK FILE NAME */ char *data_block; /* BUFFER FOR DATA TO BE READ INTO */ int filedes; /* FILE DESCRIPTOR FOR TAPE DRIVE */ int num_read; /* NUMBER OF BYTES READ FROM TAPE */ FILE *fp; /* FILE POINTER FOR OUTPUT FILE */ int retry; /* TRY TO READ PAST OPENING FILE MARK */ int my_error; /* GUESS */ /* CHECK THE ARGUMENTS PASSED IN */ if ( argc != 5 ) { /* LET USER KNOW THE ACTUAL USAGE */ fprintf( stderr, "\nUsage: \n" ); fprintf( stderr, " read_tape \n" ); fprintf( stderr, " Device should be a no swap or rewind, variable block size device\n"); fprintf( stdout, "=FAILED=\n" ); exit( 1 ); } block_size = atoi( argv[2] ); device = dup_string( argv[1] ); max_files = atoi( argv[3] ); path = dup_string( argv[4] ); /* OPEN THE DEVICE */ if ( (filedes = open( device, O_RDONLY )) < 0 ) { /* LET USER KNOW HE HAS A PROBLEM */ fprintf( stderr, "\nError opening device: %s (%s)\n", device, strerror(errno) ); fprintf( stdout, "=FAILED=\n" ); exit( 1 ); } /* ALLOCATE THE DATA BLOCK */ if ( (data_block = (char *)malloc( block_size )) == NULL ) { fprintf( stderr, "\nError allocating block data memory\n" ); close( filedes ); fprintf( stdout, "=FAILED=\n" ); exit( 1 ); } files_done = file_number = retry = 0; while( files_done == 0 ) { records_done = 0; block_number = 0; while( records_done == 0 ) { /* READ IN A BLOCK AT A TIME UNTIL A FILE MARK IS FOUND */ num_read = read( filedes, (void *)data_block, (unsigned)block_size ); my_error = errno; /* REPORT IF NUMBER OF BYTES IF READ DIFFERS FROM GOAL */ if ( num_read != block_size && num_read > 0 ) fprintf( stdout, "\nnum_read (%d) different than block size (%d)\n", num_read, block_size ); if ( num_read <= 0 ) { /* SEE IF THIS IS A LEADING FILE MARK */ if ( block_number == 0 && file_number == 0 && retry == 0 ) { fprintf( stderr, "\nTape began with a file mark. Trying to read past it...\n" ); fprintf( stderr, "\n %s\n", strerror( my_error ) ); retry++; continue; } /* END OF FILE ENCOUNTERED */ records_done = 1; file_number++; if ( block_number == 0 || file_number == max_files ) { if ( num_read < 0 ) { fprintf( stderr, "\nDone with tape due to: %s\n", strerror( my_error ) ); files_done = 1; } else { fprintf( stdout, "\nDone reading tape\n" ); files_done = 1; } } /* CLOSE THE OUTPUT FILE */ fclose( fp ); } else { /* IF THIS IS THE FIRST BLOCK READ. OPEN THE OUTPUT FILE */ if ( block_number == 0 ) { /* OPEN THE OUTPUT DISK FILE */ sprintf( filename, "%s/aapm%04d", path, file_number ); if ( (fp = fopen( filename, "w" )) == NULL ) { /* LET USER KNOW HE HAS A PROBLEM */ fprintf( stderr, "\nError opening file: %s\n %s\n", filename, strerror( my_error ) ); close( filedes ); fprintf( stdout, "=FAILED=\n" ); exit( 1 ); } if ( (file_number % 6) == 0 ) fprintf( stdout, "\nReading file: aapm%04d", file_number ); else fprintf( stdout, " aapm%04d", file_number ); fflush( stdout ); } /* WRITE THE DATA BLOCK TO DISK */ if ( (num_written = fwrite( (void *)data_block, (size_t)1, (size_t)block_size, fp )) != block_size ) { fprintf( stderr, "\nError writing block #%d to disk\n %s\n", block_number, strerror( errno ) ); fprintf( stderr, "\nShould have been %d bytes, was %d bytes\n", block_size, num_written ); fclose( fp ); close( filedes ); fprintf( stdout, "=FAILED=\n" ); exit( 1 ); } block_number++; } /* CLOSE OF ELSE */ } } /* CLOSE THE TAPE DRIVE */ close( filedes ); fprintf( stdout, "=SUCCEEDED=\n" ); } /************************** End of main() *****************************/ /********************** End of read_tape.c ****************************/