/* t3b.c - son of t2b.c - read a tape FAST for commercial media conversion */ char * documentation [] = { "usage: T2B -fn -ln -e -mn -o -qn -x -zf f ! all arguments are optional", "copy MT0: to stdout, tape block -> disk record, tape mark -> empty record", "quit @ end-of-tape", "n== unsigned decimal long number f== file name", "-fn first record ordinal: don't write disk until this", "-ln last record ordinal: exit after this (records start at # 0)", "-e convert each 8-bit byte from EBCDIC to ASCII", "-mn maximum output record size (bytes) split longer records", " a disk record comes from at most one tape record", "-o repress output to stdout", "-qn each n records a tapemark is faked (start new file after quantum)", "-x give R.FIX file, not R.VAR as normal", "-zf make a file f, each line is the decimal length of a tape block read", "f this is a dotless file name. if present, many files are output", " being f.000 f.001 etc, each empty record (=tape mark) starts new file", "" }; #include #include helpless(s) char *s; /* why we give help to idiot */ BEGIN char *p; char **pp; fprintf(stderr,"T2B:\7error %s\n",s); FOR (pp=documentation; *(p=*pp); pp++) DO fprintf(stderr,"%s\n",p); OD; exit(1); END #include #include #include #define EFN 1 #define LUN 6 #define BUFSIZ 32769 extern int $$ferr; char b[BUFSIZ]; 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<>"" */ /* 0 means repress stdout (ie tape data) */ FILE *fsiz; /* write out each tape block size */ unsigned recspat; /* incremented each record output this file */ int fixlen; /* TRUE if not R.VAR output */ BOOL output; /* TRUE if user wants stdout */ #include "ascii.h" main(argc,argv) int argc; char **argv; BEGIN unsigned u; char c; int i; char *p; int toupper(); int ids; /* directive status word */ int isb[2]; /* qio status block */ unsigned got; 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 */ dsw=alun(LUN,'MT',0); IF (dsw!=IS_SUC) THEN error("\7Can't attach to MT0: dsw=%o",dsw&0xFF); FI; 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 */ strcpy(outfile,""); fsiz = NULL; quantum = 0; output = TRUE; /* assume user wants output */ FOR (argc--,argv++; argc; argc--,argv++) DO p = * argv; IF (*p=='-') THEN c = *++p; p++; /* point after switch letter */ switch (tolower(c)) BEGIN case 'e': e2a = TRUE; break; case 'f': sscanf(p,"%lu",&fro); break; case 'l': sscanf(p,"%lu",&lro); break; case 'm': sscanf(p,"%u",&morz); break; case 'o': output = FALSE; break; case 'q': sscanf(p,"%u",&quantum); break; case 'x': fixlen = TRUE; break; case 'z': fsiz = fopen(p,"w"); /* NULL for fail is ok */ IF (!fsiz) THEN fprintf(stderr,"WARNING\7 can't write record size file %s\n",p); FI; break; default: fprintf(stderr,"bad switch %s\7\n",--p); helpless("don't understand command line"); break; END ELSE strcpy(outfile,p); FI OD IF (output) THEN IF (fixlen) THEN ioptr=fopen(outfile,"wn"); recspat = 0; ELSE IF (*outfile) THEN nextfile(); ELSE ioptr=stdout; recspat=0; FI FI ELSE ioptr = 0; FI /* here with ioptr = 0 or an output channel */ eof1=FALSE; ro=0; WHILE ((got=rmtrec(LUN,BUFSIZ,b,EFN,isb,&ids)) || isb[0]==IE_EOF ) DO IF (fsiz) THEN fprintf(fsiz,"%u\n",got); FI; /* printf("got=%d.\n",got); for (u=0; umorz) THEN u=morz; FI; spew(p,u,ioptr); p+=u; i+=u; OD; ELSE spew(b,got,ioptr); FI; FI; eof1=FALSE; FI; ro++; /* advance record counter */ IF (ro > lro) THEN quit(); FI; OD; error("\7Can't read record isb[0]=%oo isb[1]=%oo ids=%oo\n",isb[0],isb[1],ids); END last() BEGIN IF (ioptr) THEN fflush(ioptr); IF (fclose(ioptr)) THEN error("\7Can't close %s $$ferr=%oo\n",filename,$$ferr); FI FI END nextfile() BEGIN filenum++; sprintf(filename,"%s.%03d",outfile,filenum); IF (ioptr) THEN IF (!(ioptr=fopen(filename,"w"))) THEN error("\7Can't open %s $$ferr=%oo\n",$$ferr); FI FI recspat=0; END quit() BEGIN last(); IF (fsiz) THEN fclose(fsiz); FI; exit(0); END spew(buf,len,ptr) char *buf; /* source of record */ unsigned len; /* length of record */ FILE *ptr; /* destination of record */ BEGIN IF (ioptr) THEN IF (fixlen) THEN recsiz(ptr,len); FI fput(buf,len,ptr); IF (ferror(ptr)) THEN error("\7len=%d. $$ferr=%oo\n",len,$$ferr); FI FI recspat++; IF (quantum && recspat>=quantum) THEN last(); nextfile(); FI; END 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 */ BEGIN 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) THEN got=isb[1]; ELSE got=0; /* some error */ FI; return (got); END /* end: t3b.c */