130880Sbostic #include <sys/types.h> 230880Sbostic #include <sys/time.h> 330880Sbostic #include <sys/mtio.h> 430880Sbostic #include <sys/ioctl.h> 530880Sbostic #include <sys/file.h> 630880Sbostic #include <sys/stat.h> 730880Sbostic #include <a.out.h> 830880Sbostic #include <stdio.h> 930880Sbostic #include <ctype.h> 1030880Sbostic 1130880Sbostic char *malloc(); 1232599Sbostic static void rewind(); 1332599Sbostic long lseek(); 1430880Sbostic int wflag; 1530880Sbostic int xflag; 1630880Sbostic int tflag; 1730880Sbostic int cflag; 1830880Sbostic int vflag; 1930880Sbostic int dflag; 2031972Sbostic int fflag; 2130880Sbostic int totalreadfiles = 0 ; 2230880Sbostic int totalreadblocks = 0 ; 2330880Sbostic int totalreadlines = 0 ; 2430880Sbostic int totalreadchars = 0 ; 2530880Sbostic int totalwritefiles = 0 ; 2630880Sbostic int totalwriteblocks = 0 ; 2730880Sbostic int totalwritelines = 0 ; 2830880Sbostic int totalwritechars = 0 ; 2930880Sbostic 3030880Sbostic main(argc,argv) 3130880Sbostic int argc; 3230880Sbostic char *argv[]; 3330880Sbostic { 3430880Sbostic struct tm *tm; 3532599Sbostic long timetemp,time(); 3630880Sbostic int year; 3730880Sbostic int day; 3830880Sbostic char *tapename; 3930880Sbostic char *filename; 4030880Sbostic char *namelist=NULL; 4130880Sbostic char *device = "/dev/rmt12"; 4230880Sbostic int tape; 4330880Sbostic int file; 4430880Sbostic int filenum; 4530880Sbostic int argnum; 4630880Sbostic char line[1001]; 4730880Sbostic char vmsname[1000]; 4830880Sbostic char unixname[1000]; 4930880Sbostic FILE *names; 5030880Sbostic int count; 5130880Sbostic int tmp; 5230880Sbostic char blockchar; 5330880Sbostic int blocksize=2048; 5431972Sbostic int recordsize=1; 5530880Sbostic 5630880Sbostic char *key; 5730880Sbostic 5832599Sbostic timetemp = time((long *)NULL); 5930880Sbostic tm = localtime(&timetemp); 6030880Sbostic year = tm->tm_year; 6130880Sbostic day = tm->tm_yday; 6230880Sbostic tapename = malloc(10); 6330880Sbostic gethostname(tapename,6); 6430880Sbostic tapename[7]='\0'; 6530880Sbostic 6630880Sbostic /* parse command line */ 6730880Sbostic if (argc < 2) 6830880Sbostic usage(); 6930880Sbostic 7030880Sbostic argv++; 7130880Sbostic argc--; 7230880Sbostic /* loop through first argument (key) */ 7330880Sbostic argc--; 7430880Sbostic for (key = *argv++; *key; key++) 7530880Sbostic switch(*key) { 7630880Sbostic 7730880Sbostic case 'f': 7830880Sbostic if (*argv == NULL || argc <1) { 7930880Sbostic fprintf(stderr, 8030880Sbostic "ansitape: 'f' option requires tape name \n"); 8130880Sbostic usage(); 8230880Sbostic } 8330880Sbostic device = *argv++; 8430880Sbostic argc--; 8530880Sbostic break; 8630880Sbostic 8730880Sbostic case 'n': 8830880Sbostic if (*argv == NULL || argc <1) { 8930880Sbostic fprintf(stderr, 9030880Sbostic "ansitape: 'n' option requires file name\n"); 9130880Sbostic usage(); 9230880Sbostic } 9330880Sbostic namelist = *argv++; 9430880Sbostic argc--; 9530880Sbostic break; 9630880Sbostic 9730880Sbostic case 'l': 9830880Sbostic if (*argv == NULL || argc<1) { 9930880Sbostic fprintf(stderr, 10030880Sbostic "ansitape: 'l' option requires label\n"); 10130880Sbostic usage(); 10230880Sbostic } 10330880Sbostic tapename = *argv++; 10430880Sbostic argc--; 10530880Sbostic break; 10630880Sbostic 10731972Sbostic case 'F': 10831972Sbostic if(*argv == NULL) { 10931972Sbostic fprintf(stderr, 11031972Sbostic "ansitape: 'F' options requires recordsize and blocksize specifiers.\n" 11131972Sbostic ); 11231972Sbostic usage(); 11331972Sbostic } 11431972Sbostic tmp = sscanf(*argv++," %d%c ",&recordsize,&blockchar); 11531972Sbostic argc--; 11631972Sbostic if(tmp<1) { 11731972Sbostic fprintf(stderr,"illegal recordsize: recordsize set to 80\n"); 11831972Sbostic recordsize=80; 11931972Sbostic } else if(tmp>1) { 12031972Sbostic if(blockchar == 'b') recordsize *= 512; 12131972Sbostic if(blockchar == 'k') recordsize *= 1024; 12231972Sbostic } 12331972Sbostic 12431972Sbostic if (*argv == NULL) { 12531972Sbostic fprintf(stderr, 12631972Sbostic "ansitape: 'F' option requires blocksize specifier \n"); 12731972Sbostic usage(); 12831972Sbostic } 12931972Sbostic tmp = sscanf(*argv++," %d%c ",&blocksize,&blockchar); 13031972Sbostic argc--; 13131972Sbostic if(tmp<1) { 13231972Sbostic fprintf(stderr,"illegal blocksize: blocksize set to 2048\n"); 13331972Sbostic blocksize=2048; 13431972Sbostic } else if(tmp>1) { 13531972Sbostic if(blockchar == 'b') blocksize *= 512; 13631972Sbostic if(blockchar == 'k') blocksize *= 1024; 13731972Sbostic } 13831972Sbostic if(blocksize <18) blocksize=18; 13931972Sbostic if(blocksize >62*1024) blocksize=62*1024; 14031972Sbostic fflag++; 14131972Sbostic break; 14231972Sbostic 14330880Sbostic case 'b': 14430880Sbostic if (*argv == NULL) { 14530880Sbostic fprintf(stderr, 14630880Sbostic "ansitape: 'b' option requires blocksize specifier \n"); 14730880Sbostic usage(); 14830880Sbostic } 14930880Sbostic tmp = sscanf(*argv++," %d%c ",&blocksize,&blockchar); 15030880Sbostic argc--; 15130880Sbostic if(tmp<1) { 15230880Sbostic fprintf(stderr,"illegal blocksize: blocksize set to 2048\n"); 15330880Sbostic blocksize=2048; 15430880Sbostic } else if(tmp>1) { 15530880Sbostic if(blockchar == 'b') blocksize *= 512; 15630880Sbostic if(blockchar == 'k') blocksize *= 1024; 15730880Sbostic } 15830880Sbostic if(blocksize <18) blocksize=18; 15930880Sbostic if(blocksize >62*1024) blocksize=62*1024; 16030880Sbostic break; 16130880Sbostic 16230880Sbostic case 'c': 16330880Sbostic cflag++; 16430880Sbostic wflag++; 16530880Sbostic break; 16630880Sbostic 16730880Sbostic case 'r': 16830880Sbostic /*I know, this should be rflag, but I just don't like r for write*/ 16930880Sbostic wflag++; 17030880Sbostic break; 17130880Sbostic 17230880Sbostic case 'v': 17330880Sbostic vflag++; 17430880Sbostic break; 17530880Sbostic 17630880Sbostic case 'x': 17730880Sbostic xflag++; 17830880Sbostic break; 17930880Sbostic 18030880Sbostic case 't': 18130880Sbostic tflag++; 18230880Sbostic break; 18330880Sbostic 18430880Sbostic case '-': 18530880Sbostic break; 18630880Sbostic 18730880Sbostic default: 18830880Sbostic fprintf(stderr, "ansitape: %c: unknown option\n", *key); 18930880Sbostic usage(); 19030880Sbostic } 19130880Sbostic 19230880Sbostic if (!wflag && !xflag && !tflag) 19330880Sbostic usage(); 19430880Sbostic 19530880Sbostic tape = open(device,wflag?O_RDWR:O_RDONLY,NULL); 19630880Sbostic if(tape<0) { 19730880Sbostic perror(device); 19832599Sbostic fprintf(stderr,"tape not accessable - check if drive online and write ring present\n"); 19930880Sbostic exit(1); 20030880Sbostic } 20130880Sbostic rewind(tape); 20230880Sbostic filenum=1; 20330880Sbostic casefix(tapename); 20430880Sbostic 20530880Sbostic if(cflag) { 20630880Sbostic writevol(tapename,tape); 20730880Sbostic } else { 20830880Sbostic getvol(tapename,tape); 20930880Sbostic while(1) { 21030880Sbostic /* read files */ 21130880Sbostic if( readfile(tape,argc,argv) ) break; 21230880Sbostic filenum++; 21330880Sbostic } 21430880Sbostic backspace(tape); 21530880Sbostic } 21630880Sbostic 21730880Sbostic if(wflag) { 21830880Sbostic if(namelist) { 21930880Sbostic if(*namelist == '-') { 22030880Sbostic names = stdin; 22130880Sbostic } else { 22230880Sbostic names=fopen(namelist,"r"); 22330880Sbostic if(names == NULL) { 22430880Sbostic fprintf(stderr,"unable to open namelist file - no files added to tape\n"); 22530880Sbostic } 22630880Sbostic } 22730880Sbostic while(1) { 22830880Sbostic fgets(line,1000,names); 22930880Sbostic if(feof(names)) break; 23030880Sbostic count = sscanf(line,"%s %s",unixname,vmsname); 23130880Sbostic if(count<1) continue; /* blank line */ 23230880Sbostic if(count==1) strcpy(vmsname,unixname); 23330880Sbostic casefix(vmsname); 23430880Sbostic if(filecheck(&file,unixname)) continue; 23531972Sbostic writefile(tape,file,vmsname,tapename,filenum,year,day,blocksize, 23631972Sbostic recordsize); 23730880Sbostic filenum++; 23830880Sbostic close(file); 23930880Sbostic } 24030880Sbostic } else { 24130880Sbostic for(argnum=0;argnum<argc;argnum++) { 24230880Sbostic filename = argv[argnum]; 24330880Sbostic if(filecheck(&file,filename)) continue; 24430880Sbostic casefix(filename); 24531972Sbostic writefile(tape,file,filename,tapename,filenum,year,day, 24631972Sbostic blocksize,recordsize); 24730880Sbostic filenum++; 24830880Sbostic close(file); 24930880Sbostic } 25030880Sbostic } 25130880Sbostic writetm(tape); 25230880Sbostic writetm(tape); 25330880Sbostic writetm(tape); 25430880Sbostic writetm(tape); 25530880Sbostic } 25630880Sbostic rewind(tape); 25730880Sbostic close(tape); 25830880Sbostic if(vflag && (tflag || xflag)) { 25930880Sbostic fprintf(stdout," read %d files in %d blocks (%d lines, %d chars)\n", 26030880Sbostic totalreadfiles,totalreadblocks,totalreadlines,totalreadchars); 26130880Sbostic } 26230880Sbostic if(vflag && wflag) { 26330880Sbostic fprintf(stdout," wrote %d files in %d blocks (%d lines, %d chars)\n", 26430880Sbostic totalwritefiles,totalwriteblocks,totalwritelines,totalwritechars); 26530880Sbostic } 26632594Sbostic return(0); 26730880Sbostic } 26830880Sbostic usage() { 26930880Sbostic fprintf(stderr, 27030880Sbostic "ansitape: usage: ansitape -{rxtc}[flnvb] [filename] [label] [filename] [blocksize] [files]\n"); 27132594Sbostic exit(1); 27230880Sbostic } 27330880Sbostic 27431972Sbostic writefile(tape,file,filename,tapename,filenum,year,day,blocksize,recordsize) 27530880Sbostic int tape; 27630880Sbostic int file; 27730880Sbostic char *filename; 27830880Sbostic char *tapename; 27930880Sbostic int filenum; 28030880Sbostic int year; 28130880Sbostic int day; 28230880Sbostic int blocksize; 28331972Sbostic int recordsize; 28430880Sbostic 28530880Sbostic { 28630880Sbostic int blocks; 28730880Sbostic writehdr1(tape,filename,tapename,filenum,year,day); 28831972Sbostic writehdr2(tape,blocksize,recordsize); 28930880Sbostic writehdr3(tape); 29030880Sbostic writetm(tape); 29131972Sbostic writedata(tape,file,filename,&blocks,blocksize,recordsize); 29230880Sbostic writetm(tape); 29330880Sbostic writeeof1(tape,filename,tapename,filenum,year,day,blocks); 29431972Sbostic writeeof2(tape,blocksize,recordsize); 29530880Sbostic writeeof3(tape); 29630880Sbostic writetm(tape); 29730880Sbostic totalwritefiles++; 29830880Sbostic } 29930880Sbostic 30031972Sbostic writedata(tape,file,filename,blocks,blocksize,recsize) 30130880Sbostic int tape; 30230880Sbostic int file; 30330880Sbostic char *filename; 30430880Sbostic int *blocks; 30530880Sbostic int blocksize; 30631972Sbostic int recsize; 30730880Sbostic { 30830880Sbostic char *ibuf; 30930880Sbostic char *ibufstart; 31030880Sbostic char *obuf; 31130880Sbostic char *obufstart; 31230880Sbostic char *endibuf; 31330880Sbostic char *endobuf; 31430880Sbostic int got; 31530880Sbostic int i; 31630880Sbostic char *j; 31730880Sbostic int numchar = 0 ; 31830880Sbostic int numline = 0 ; 31930880Sbostic int numblock = 0; 32030880Sbostic int success; 32130880Sbostic 32232599Sbostic ibufstart = ibuf = malloc((unsigned)(blocksize<4096?8200:(2*blocksize+10))); 32332599Sbostic obufstart = obuf = malloc((unsigned)(blocksize+10)); 32430880Sbostic endobuf = obuf + blocksize; 32530880Sbostic endibuf = ibuf; 32630880Sbostic 32730880Sbostic 32830880Sbostic i=0; 32931972Sbostic if (!fflag) { 33031972Sbostic while(1) { 33131972Sbostic if(ibuf+i>=endibuf) { /* end of input buffer */ 33231972Sbostic strncpy(ibufstart,ibuf,endibuf-ibuf); /* copy leftover to start */ 33331972Sbostic ibuf = ibufstart+(endibuf-ibuf); /* point to end of valid data */ 33431972Sbostic got = read(file,ibuf,blocksize<4096?4096:2*blocksize); /* read in a chunk */ 33531972Sbostic endibuf = ibuf + got; 33631972Sbostic ibuf = ibufstart; /* point to beginning of data */ 33731972Sbostic if(got == 0) { /* end of input */ 33831972Sbostic if(ibuf==ibufstart){ /* no leftovers */ 33931972Sbostic break; /* done */ 34031972Sbostic } else { 34131972Sbostic ibuf[i]='\n'; /* fake extra newline */ 34231972Sbostic } 34330880Sbostic } 34430880Sbostic } 34530880Sbostic 34631972Sbostic if(obuf+i+4 > endobuf) { /* end of output buffer */ 34731972Sbostic if(i>blocksize-4) { 34831972Sbostic printf("record exceeds blocksize - file truncated\n"); 34931972Sbostic break; 35031972Sbostic } 35131972Sbostic /* filled up output record - have to fill,output,restart*/ 35231972Sbostic for(j=obuf;j<endobuf;j++) { 35331972Sbostic *j = '^'; 35431972Sbostic } 35531972Sbostic success = write(tape,obufstart,blocksize); 35631972Sbostic if(success != blocksize) { 35731972Sbostic perror("tape"); 35831972Sbostic fprintf(stderr," hard write error: write aborted\n"); 35931972Sbostic rewind(tape); 36031972Sbostic exit(1); 36131972Sbostic } 36231972Sbostic obuf=obufstart; 36331972Sbostic numchar -= i; 36431972Sbostic i=0; 36531972Sbostic numblock++; 36631972Sbostic continue; 36730880Sbostic } 36831972Sbostic 36931972Sbostic if(ibuf[i] == '\n') { /* end of line */ 37031972Sbostic obuf[0] = ((i+4)/1000) + '0'; 37131972Sbostic obuf[1] = (((i+4)/100)%10) + '0'; 37231972Sbostic obuf[2] = (((i+4)/10)%10) + '0'; 37331972Sbostic obuf[3] = (((i+4)/1)%10) + '0'; 37431972Sbostic obuf += (4+i); /* size + strlen */ 37531972Sbostic ibuf += (1+i); /* newline + strlen */ 37631972Sbostic i=0; 37731972Sbostic numline++; 37831972Sbostic continue; /* back to the top */ 37931972Sbostic } 38031972Sbostic 38131972Sbostic obuf[i+4]=ibuf[i]; 38231972Sbostic numchar++; 38331972Sbostic i++; 38431972Sbostic 38531972Sbostic } 38631972Sbostic /* exited - write last record and go for lunch */ 38731972Sbostic if(obuf != obufstart) { 38830880Sbostic for(j=obuf;j<endobuf;j++) { 38930880Sbostic *j = '^'; 39030880Sbostic } 39130880Sbostic success = write(tape,obufstart,blocksize); 39230880Sbostic if(success != blocksize) { 39330880Sbostic perror("tape"); 39430880Sbostic fprintf(stderr," hard write error: write aborted\n"); 39530880Sbostic rewind(tape); 39630880Sbostic exit(1); 39730880Sbostic } 39830880Sbostic numblock++; 39930880Sbostic } 40031972Sbostic } else { 40131972Sbostic fflush(stdout); 40231972Sbostic while(1) { 40331972Sbostic /* writing an 'F' format tape */ 40431972Sbostic got = read(file,ibuf,recsize+1); 40531972Sbostic if(got == 0) { 40631972Sbostic /* end of input */ 40731972Sbostic if(obuf<=obufstart) { 40831972Sbostic break; /* done */ 40931972Sbostic } else { 41031972Sbostic /* no more data, so force the record out */ 41131972Sbostic recsize = blocksize+1; 41231972Sbostic } 41331972Sbostic } else if(got != recsize+1) { 41431972Sbostic printf("short read: filled\n"); 41531972Sbostic } else if( *(ibuf+recsize) != '\n') { 41631972Sbostic printf("corrupted record - write aborted\b"); 41731972Sbostic rewind(tape); 41831972Sbostic exit(1); 41931972Sbostic } 42031972Sbostic if(obuf+recsize >endobuf) { 42131972Sbostic /*would overflow output buffer, so fill up old buffer */ 42231972Sbostic for(j=obuf;j<endobuf;j++) { 42331972Sbostic *j = '^'; 42431972Sbostic } 42531972Sbostic /* and write it */ 42631972Sbostic success = write(tape,obufstart,blocksize); 42731972Sbostic if(success != blocksize) { 42831972Sbostic perror("tape"); 42931972Sbostic fprintf(stderr," hard write error: write aborted\n"); 43031972Sbostic rewind(tape); 43131972Sbostic exit(1); 43231972Sbostic } 43331972Sbostic obuf=obufstart; 43431972Sbostic numblock++; 43531972Sbostic } 43631972Sbostic bcopy(ibuf,obuf,recsize); 43731972Sbostic obuf+=got-1; 43830880Sbostic numline++; 43931972Sbostic numchar += recsize; 44030880Sbostic } 44131972Sbostic numchar -= recsize; 44231972Sbostic numline--; 44330880Sbostic } 44430880Sbostic free(ibufstart); 44530880Sbostic free(obufstart); 44630880Sbostic if(vflag) { 44730880Sbostic fprintf(stdout,"r - %s: %d lines (%d chars) in %d tape blocks\n", 44830880Sbostic filename,numline,numchar,numblock); 44930880Sbostic } 45030880Sbostic totalwritechars += numchar; 45130880Sbostic totalwritelines += numline; 45230880Sbostic totalwriteblocks += numblock; 45330880Sbostic *blocks = numblock; 45430880Sbostic } 45530880Sbostic 45630880Sbostic writetm(tape) 45730880Sbostic int tape; 45830880Sbostic { 45930880Sbostic struct mtop mtop; 46030880Sbostic mtop.mt_op = MTWEOF; 46130880Sbostic mtop.mt_count = 1; 46230880Sbostic ioctl(tape,MTIOCTOP,&mtop); 46330880Sbostic } 46430880Sbostic 46531972Sbostic void 46632599Sbostic static rewind(tape) 46730880Sbostic int tape; 46830880Sbostic { 46930880Sbostic struct mtop mtop; 47030880Sbostic mtop.mt_op = MTREW; 47130880Sbostic mtop.mt_count = 1; 47230880Sbostic ioctl(tape,MTIOCTOP,&mtop); 47330880Sbostic } 47430880Sbostic 47530880Sbostic skipfile(tape) 47630880Sbostic int tape; 47730880Sbostic { 47830880Sbostic struct mtop mtop; 47930880Sbostic mtop.mt_op = MTFSF; 48030880Sbostic mtop.mt_count = 1; 48130880Sbostic ioctl(tape,MTIOCTOP,&mtop); 48230880Sbostic } 48330880Sbostic 48430880Sbostic backspace(tape) 48530880Sbostic int tape; 48630880Sbostic { 48730880Sbostic struct mtop mtop; 48830880Sbostic mtop.mt_op = MTBSF; 48930880Sbostic mtop.mt_count = 1; 49030880Sbostic ioctl(tape,MTIOCTOP,&mtop); 49130880Sbostic } 49230880Sbostic 49330880Sbostic writehdr1(tape,filename,tapename,filenum,year,day) 49430880Sbostic int tape; 49530880Sbostic char *filename; 49630880Sbostic char *tapename; 49730880Sbostic int filenum; 49830880Sbostic int year; 49930880Sbostic int day; 50030880Sbostic { 50130880Sbostic char buf[81]; 50230880Sbostic sprintf(buf, 50330880Sbostic "HDR1%-17.17s%-6.6s0001%4.4d000101 %2.2d%3.3d %2.2d%3.3d 000000DECFILE11A " 50430880Sbostic ,filename,tapename,filenum,year,day,year,day); 50530880Sbostic write(tape,buf,80); 50630880Sbostic } 50730880Sbostic 50830880Sbostic writeeof1(tape,filename,tapename,filenum,year,day,blocks) 50930880Sbostic int tape; 51030880Sbostic char *filename; 51130880Sbostic char *tapename; 51230880Sbostic int filenum; 51330880Sbostic int year; 51430880Sbostic int day; 51530880Sbostic int blocks; 51630880Sbostic { 51730880Sbostic char buf[81]; 51830880Sbostic sprintf(buf, 51930880Sbostic "EOF1%-17.17s%-6.6s0001%4.4d000101 %2.2d%3.3d %2.2d%3.3d %6.6dDECFILE11A " 52030880Sbostic ,filename,tapename,filenum,year,day,year,day,blocks); 52130880Sbostic write(tape,buf,80); 52230880Sbostic } 52330880Sbostic 52431972Sbostic writehdr2(tape,blocksize,recordsize) 52530880Sbostic int tape; 52630880Sbostic int blocksize; 52731972Sbostic int recordsize; 52830880Sbostic { 52930880Sbostic char buf[81]; 53031972Sbostic sprintf(buf,"HDR2%c%5.5d%5.5d%35.35s00%28.28s",fflag?'F':'D', 53131972Sbostic blocksize,recordsize," "," "); 53230880Sbostic write(tape,buf,80); 53330880Sbostic } 53430880Sbostic 53531972Sbostic writeeof2(tape,blocksize,recordsize) 53630880Sbostic int tape; 53730880Sbostic int blocksize; 53831972Sbostic int recordsize; 53930880Sbostic { 54030880Sbostic char buf[81]; 54131972Sbostic sprintf(buf,"EOF2%c%5.5d%5.5d%35.35s00%28.28s",fflag?'F':'D', 54231972Sbostic blocksize,recordsize," "," "); 54330880Sbostic write(tape,buf,80); 54430880Sbostic } 54530880Sbostic 54630880Sbostic writehdr3(tape) 54730880Sbostic int tape; 54830880Sbostic { 54930880Sbostic char buf[81]; 55030880Sbostic sprintf(buf, "HDR3%76.76s"," "); 55130880Sbostic write(tape,buf,80); 55230880Sbostic } 55330880Sbostic 55430880Sbostic writeeof3(tape) 55530880Sbostic int tape; 55630880Sbostic { 55730880Sbostic char buf[81]; 55830880Sbostic sprintf(buf, "EOF3%76.76s"," "); 55930880Sbostic write(tape,buf,80); 56030880Sbostic } 56130880Sbostic 56230880Sbostic writevol(tapename,tape) 56330880Sbostic int tape; 56430880Sbostic char *tapename; 56530880Sbostic { 56630880Sbostic char buf[81]; 567*32862Sbostic sprintf(buf,"VOL1%-6.6s %26.26sD%cC%10.10s1%28.28s3",tapename," ",'%'," "," "); 56830880Sbostic write(tape,buf,80); 56930880Sbostic if(vflag) { 57030880Sbostic fprintf(stdout," tape labeled %-6.6s\n",tapename); 57130880Sbostic } 57230880Sbostic } 57330880Sbostic 57430880Sbostic getvol(tapename,tape) 57530880Sbostic int tape; 57630880Sbostic char *tapename; 57730880Sbostic { 57830880Sbostic char buf[81]; 57930880Sbostic read(tape,buf,80); 58030880Sbostic sscanf(buf,"VOL1%6s",tapename); 58130880Sbostic if(vflag) { 58230880Sbostic fprintf(stdout," tape was labeled %-6.6s\n",tapename); 58330880Sbostic } 58430880Sbostic } 58530880Sbostic 58630880Sbostic casefix(string) 58730880Sbostic register char *string; 58830880Sbostic { 58930880Sbostic while(*string) { 59030880Sbostic if(islower(*string)) { 59130880Sbostic *string = toupper(*string); 59230880Sbostic } 59330880Sbostic string++; 59430880Sbostic } 59530880Sbostic } 59630880Sbostic 59730880Sbostic int 59830880Sbostic readfile(tape,argc,argv) 59930880Sbostic int tape; 60030880Sbostic int argc; 60130880Sbostic char *argv[]; 60230880Sbostic { 60330880Sbostic char buf[80]; 60430880Sbostic char mode; 60530880Sbostic char filename[18]; 60630880Sbostic FILE *file; 60730880Sbostic int extract; 60830880Sbostic char *ibuf; 60930880Sbostic char *ibufstart; 61030880Sbostic char *endibuf; 61131972Sbostic char *fixpoint; 61230880Sbostic int size; 61330880Sbostic int numblock = 0 ; 61430880Sbostic int numchar = 0 ; 61530880Sbostic int numline = 0 ; 61630880Sbostic int argnum; 61730880Sbostic int ok; 61830880Sbostic int blocksize; 61930880Sbostic int recordsize; 62030880Sbostic 62130880Sbostic if(!(read(tape,buf,80))) return(1); /* no hdr record, so second eof */ 62230880Sbostic sscanf(buf,"HDR1%17s",filename); 62330880Sbostic read(tape,buf,80); 62430880Sbostic sscanf(buf,"HDR2%c%5d%5d",&mode,&blocksize,&recordsize); 62530880Sbostic blocksize = blocksize>recordsize?blocksize:recordsize; 62630880Sbostic skipfile(tape); /* throw away rest of header(s) - not interesting */ 62732599Sbostic ibufstart=ibuf=malloc((unsigned)(blocksize+10)); 62830880Sbostic endibuf=ibufstart+blocksize; 62930880Sbostic extract=0; 63030880Sbostic if(tflag || xflag) { 63130880Sbostic ok=0; 63230880Sbostic if(!argc) { 63330880Sbostic ok=1; 63430880Sbostic } else for(argnum=0;argnum<argc;argnum++) { 63530880Sbostic casefix(argv[argnum]); 63630880Sbostic if(!strcmp(filename,argv[argnum])) { 63730880Sbostic ok=1; 63830880Sbostic break; 63930880Sbostic } 64030880Sbostic } 64130880Sbostic if(mode == 'D') { 64230880Sbostic if(xflag && ok) { 64330880Sbostic file = fopen(filename,"w"); 64430880Sbostic if(file == NULL) { 64530880Sbostic perror(filename); 64630880Sbostic } else { 64730880Sbostic extract = 1; 64830880Sbostic } 64930880Sbostic } 65031972Sbostic while(size=read(tape,ibufstart,blocksize)) { 65131972Sbostic if(size != blocksize) { 65231972Sbostic /* 65331972Sbostic * somebody's brain damaged program leaves 65431972Sbostic * short blocks on the tape - fill them up to size 65531972Sbostic * (this is work THEY should have done before writing 65631972Sbostic * their undersized blocks) 65731972Sbostic */ 65831972Sbostic for(fixpoint=ibufstart+size;fixpoint<endibuf;fixpoint++) { 65931972Sbostic *fixpoint='^'; 66031972Sbostic } 66131972Sbostic } 66230880Sbostic numblock++; 66330880Sbostic ibuf = ibufstart; 66430880Sbostic while(strncmp("^^^^",ibuf,4)) { 66531972Sbostic #define getsize(a) ((a[0]-'0')*1000)+((a[1]-'0')*100)+((a[2]-'0')*10)+(a[3]-'0') 66631972Sbostic #define bad(a) (!(isdigit(ibuf[a]))) 66731972Sbostic if(bad(0) || bad(1) || bad(2) || bad(3)) { 66831972Sbostic fprintf(stderr, "error: bad record length field - file may be corrupted, skipping\n"); 66930881Sbostic break; 67030881Sbostic } 67131972Sbostic size = getsize(ibuf); 67230880Sbostic if(extract) { 67330880Sbostic fwrite(ibuf+4,sizeof(char),size-4,file); 67430880Sbostic fwrite("\n",1,1,file); 67530880Sbostic } 67630880Sbostic ibuf += (size); 67730880Sbostic numline++; 67830880Sbostic numchar += (size-4); 67930880Sbostic if(ibuf > endibuf+1) { 68030880Sbostic fprintf(stderr,"error: bad tape records(s) - file may be corrupted\n"); 68130880Sbostic break; 68230880Sbostic } 68330880Sbostic if(ibuf>endibuf-4) break; 68430880Sbostic } 68530880Sbostic } 68630880Sbostic if(extract) { 68730880Sbostic fclose(file); 68830880Sbostic } 68930880Sbostic } else if (mode == 'F') { 69030880Sbostic if(xflag && ok) { 69130880Sbostic file = fopen(filename,"w"); 69230880Sbostic if(file == NULL) { 69330880Sbostic perror(filename); 69430880Sbostic } else { 69530880Sbostic extract = 1; 69630880Sbostic } 69730880Sbostic } 69830880Sbostic while(read(tape,ibufstart,blocksize)) { 69930880Sbostic numblock++; 70030880Sbostic ibuf = ibufstart; 70130880Sbostic while(ibuf+recordsize <= endibuf) { 70230880Sbostic if(extract) { 70330880Sbostic fwrite(ibuf,sizeof(char),recordsize,file); 70430880Sbostic fwrite("\n",1,1,file); 70530880Sbostic } 70630880Sbostic ibuf += recordsize; 70730880Sbostic numline++; 70830880Sbostic numchar += recordsize; 70930880Sbostic } 71030880Sbostic } 71130880Sbostic if(extract) { 71230880Sbostic fclose(file); 71330880Sbostic } 71430880Sbostic } else { 71530880Sbostic fprintf(stderr,"unknown record mode (%c) - file %s skipped\n", 71630880Sbostic mode,filename); 71730880Sbostic skipfile(tape); /* throw away actual file */ 71830880Sbostic } 71930880Sbostic } else { 72030880Sbostic /* not interested in contents of file, so move fast */ 72130880Sbostic skipfile(tape); 72230880Sbostic } 72330880Sbostic skipfile(tape); /* throw away eof stuff - not interesting */ 72430880Sbostic totalreadchars += numchar; 72530880Sbostic totalreadlines += numline; 72630880Sbostic totalreadblocks += numblock; 72730880Sbostic totalreadfiles ++; 72830880Sbostic if(xflag && vflag && ok) { 72930880Sbostic fprintf(stdout,"x - %s: %d lines (%d chars) in %d tape blocks\n", 73030880Sbostic filename,numline,numchar,numblock); 73130880Sbostic } else if(tflag && ok) { 73230880Sbostic fprintf(stdout,"t - %s: %d lines (%d chars) in %d tape blocks\n", 73330880Sbostic filename,numline,numchar,numblock); 73430880Sbostic } 73530880Sbostic free(ibufstart); 73630880Sbostic return(0); 73730880Sbostic } 73830880Sbostic 73930880Sbostic filecheck(file,name) 74030880Sbostic int *file; 74130880Sbostic char *name; 74230880Sbostic 74330880Sbostic { 74430880Sbostic 74530880Sbostic struct stat buf; 74630880Sbostic struct exec sample; 74730880Sbostic 74830880Sbostic stat(name,&buf); 74930880Sbostic if ((buf.st_mode & S_IFDIR)==S_IFDIR) { 75030880Sbostic fprintf(stderr,"%s: directory - skipped\n",name); 75130880Sbostic return(1); 75230880Sbostic } 75330880Sbostic if ((buf.st_mode & S_IFCHR)==S_IFCHR) { 75430880Sbostic fprintf(stderr,"%s: character device - skipped\n",name); 75530880Sbostic return(1); 75630880Sbostic } 75730880Sbostic if ((buf.st_mode & S_IFBLK)==S_IFBLK) { 75830880Sbostic fprintf(stderr,"%s: block device - skipped\n",name); 75930880Sbostic return(1); 76030880Sbostic } 76130880Sbostic if ((buf.st_mode & S_IFLNK)==S_IFLNK) { 76230880Sbostic fprintf(stderr,"%s: symbolic link - skipped\n",name); 76330880Sbostic return(1); 76430880Sbostic } 76530880Sbostic if ((buf.st_mode & S_IFSOCK)==S_IFSOCK) { 76630880Sbostic fprintf(stderr,"%s: socket - skipped\n",name); 76730880Sbostic return(1); 76830880Sbostic } 76930880Sbostic *file = open(name,O_RDONLY,NULL); 77030880Sbostic if(*file <0) { 77130880Sbostic perror(name); 77230880Sbostic return(1); 77330880Sbostic } 77430880Sbostic if(read(*file,&sample,sizeof(struct exec))>= sizeof(struct exec)) { 77530880Sbostic if(!(N_BADMAG(sample))) { 77630880Sbostic /* executable */ 77730880Sbostic /* the format requires either fixed blocked records, 77830880Sbostic * or variable format records with each record remaining 77930880Sbostic * entirely within a tape block - this limits the 78030880Sbostic * distance between \n's to 2044 bytes, something 78130880Sbostic * which is VERY rarely true of executables, so 78230880Sbostic * we don't even try with them.... 78330880Sbostic */ 78430880Sbostic close(*file); 78530880Sbostic fprintf(stderr,"%s: executable - skipped\n",name); 78630880Sbostic return(1); 78730880Sbostic } 78830880Sbostic } 78930880Sbostic /* either couldn't read sizeof(struct exec) or wasn't executable */ 79030880Sbostic /* so we assume it is a reasonable file until proven otherwise */ 79130880Sbostic lseek(*file,0l,0); 79230880Sbostic return(0); 79330880Sbostic } 794