/* t2b.c: read a R.VAR file from tape */ /* format of output file is 1 record :: 1 tape block */ /* a 0-length output record means a tape-mark was read */ /* now with featuritus: you can get R.FIX files output! */ #include #include #include #include #define EFN 1 #define LUN 6 #define BUFSIZ 32769 extern int $$ferr; char b[BUFSIZ]; char ascii[256]; /* ebcdic->ascii table */ char outfile[40]; /* output file name basis if any */ char filename[50]; /* build output file name here */ unsigned quantum; /* non-zero: quantum to fake tapemark after */ unsigned filenum; /* last file number used when outfile<>"" */ FILE *ioptr; /* the output file when outfile<>"" */ unsigned recspat; /* incremented each record output this file */ int fixlen; /* TRUE if not R.VAR output */ helpless() {puts("usage: T2B MTn [first-record-ordinal] [last-record-ordinal] [-e] [maxoutrecsiz] [outfile] [quantum] [-f]"); puts("copies MTn: to stdout or nominated file(s)"); puts("each record of stdout maps to one tape record"); puts("a tape mark is written as an empty output record"); puts("reading stops at EOT"); puts("each record read is numbered, starting at zero"); puts("a tape mark counts as one record"); puts("first-record-ordinal defaults to zero"); puts("last-record-read defaults to a VERY large number"); puts("if the record read has a number outside f-r-o to l-r-o inclusive"); puts(" then that record is NOT output: tape reading stops after the l-r-o record"); puts("record ordinals should be typed in as unsigned decimal integers"); puts("a 4th command argument of \"-e\" means convert each byte from EBCDIC to ASCII"); puts("a 4th argument of \"-a\" means leave bytes alone - they are in ASCII already"); puts("a 5th argument is a decimal number: the maximum output record size"); puts("if the 5th argument is used, long output records are fractured into parts"); puts("all but the last part of a record will be bytes long"); puts("using arg5>0 means that B2T will not restore the tape correctly!"); puts("a 6th argument is a filename. If present, many files are output."); puts("Each time a file-mark is seen, a new file is started."); puts("also, no empty record is output like normal."); puts("Each file has a name {filename}n where n is counted from 1."); puts("use \"\" as a place-holder for 6th argument."); puts("a 7th argument is a decimal number: each 'quantum' records a tapemark is faked."); puts("an absent or zero 7th argument means don't fake file marks."); puts("for example quantum of 1000 means fake tapemark after each 1000. records."); puts("a 8th argument of \"-f\" means LOOSE the record lengths from"); puts("the front of each record: means B2T can't use the output file"); puts("this is mainly used for dense image copies of tapes"); exit(); } main(argc,argv) char **argv; {unsigned u; char c; int i; char *p; int toupper(); int ids; /* directive status word */ int isb[2]; /* qio status block */ unsigned got; char dnam[3]; /* magtape device name (ASCII) */ int dnum; /* magtape unit number */ int dev; /* word-aligned device name */ int dsw; /* directive status word */ int eof1; /* TRUE if just seen eof */ unsigned rmtrec(); /* read a magtape record (or tape mark) */ int morz; /* maximum output record size */ long int fro; /* first record ordinal */ long int lro; /* last record ordinal */ long int ro; /* current record ordinal */ int e2a; /* TRUE if ebcdic to ascii conversion */ #include "cascii.h" /* above is a gross patch until I figure out how to initialise arrays in C */ if (argc==0) {helpless(); } ; if (strlen(argv[1])!=3 || !isdigit(argv[1][2])) {puts("\7First Argument must be EXACTLY ddn"); helpless(); } ; copy(dnam,argv[1],2); dnum=argv[1][2]-'0'; dev = toupper(dnam[1])<<8 | toupper(dnam[0]); dsw=alun(LUN,dev,dnum); if (dsw!=IS_SUC) {error("\7Can't attach to %s dsw=%o",argv[1],dsw&0xFF); } ; fro=0; lro=1000000000L; e2a=FALSE; /* assume no ebcdic to ascii conversion */ morz=0; /* assume no maximum output record size */ fixlen = FALSE;/* assume no fixed-length output */ if (argc>2) {sscanf(argv[2],"%ld",&fro); if (argc>3) {sscanf(argv[3],"%ld",&lro); if (argc>4) {c=toupper(argv[4][1]); if (argv[4][0]!='-' ||strlen(argv[4])!=2 ||c!='A'&&c!='E' ) {puts("\74th argument may only be \"-e\" or \"-a\"!"); helpless(); } ; e2a = c=='E'; if (argc>5) {sscanf(argv[5],"%d",&morz); if (morz<0) {puts("\7negative maximum output record size"); helpless(); } ; if (argc>6) {strcpy(outfile,argv[6]); filenum=0; if (argc>7) {sscanf(argv[7],"%d",&quantum); if (argc>8) {fixlen = (argv[8][0]=='-') && (tolower(argv[8][1])=='f'); } ; } else {quantum=0; } ; } else {strcpy(outfile,""); quantum=0; } ; } ; } ; } ; } ; if (fixlen) {ioptr=fopen(outfile,"wn"); recspat = 0; } else {if (*outfile) {nextfile(); } else {ioptr=stdout; recspat=0; } ; } eof1=FALSE; ro=0; while ((got=rmtrec(LUN,BUFSIZ,b,EFN,isb,&ids)) || isb[0]==IE_EOF ) { /* printf("got=%d.\n",got); for (u=0; umorz) u=morz; spew(p,u,ioptr); p+=u; i+=u; } ; } else {spew(b,got,ioptr); } ; } ; eof1=FALSE; } ; ro++; /* advance record counter */ if (ro > lro) {quit(); } ; } error("\7Can't read record isb[0]=%oo isb[1]=%oo ids=%oo\n",isb[0],isb[1],ids); } last() { fflush(ioptr); if (fclose(ioptr)) error("\7Can't close %s $$ferr=%oo\n",filename,$$ferr); } nextfile() { filenum++; sprintf(filename,"%s%d",outfile,filenum); if (!(ioptr=fopen(filename,"w"))) error("\7Can't open %s $$ferr=%oo\n",$$ferr); recspat=0; } quit() {last(); exit(); } spew(buf,len,ptr) char *buf; /* source of record */ unsigned len; /* length of record */ FILE *ptr; /* destination of record */ { if (fixlen) {recsiz(ptr,len); } ; fput(buf,len,ptr); if (ferror(ptr)) error("\7len=%d. $$ferr=%oo\n",len,$$ferr); recspat++; if (quantum && recspat>=quantum) {last(); nextfile(); } ; } unsigned rmtrec(lun,bufsiz,buf,efn,isb,ids) /* read a magtape record */ int lun; /* lun MT: lives on */ int bufsiz; /* buffer size for QIO */ char *buf; /* buffer to read data into */ int efn; /* event flag number to use */ int isb[2]; /* i/o status block for qiow$ */ int *ids; /* directive status word returned */ { int got; /* return 0 or number of bytes read from record */ int prl[6]; /* parameter block for qiow$ */ int noast; /* */ int qiow(); noast=0; prl[0]=buf; prl[1]=bufsiz; *ids=qiow(IO_RLB,lun,efn,isb,noast,prl); if (isb[0]==IS_SUC) {got=isb[1]; } else {got=0; /* some error */ } ; return (got); }