1*30880Sbostic #include <sys/types.h> 2*30880Sbostic #include <sys/time.h> 3*30880Sbostic #include <sys/mtio.h> 4*30880Sbostic #include <sys/ioctl.h> 5*30880Sbostic #include <sys/file.h> 6*30880Sbostic #include <sys/stat.h> 7*30880Sbostic #include <a.out.h> 8*30880Sbostic #include <stdio.h> 9*30880Sbostic #include <ctype.h> 10*30880Sbostic 11*30880Sbostic char *malloc(); 12*30880Sbostic int wflag; 13*30880Sbostic int xflag; 14*30880Sbostic int tflag; 15*30880Sbostic int cflag; 16*30880Sbostic int vflag; 17*30880Sbostic int dflag; 18*30880Sbostic int totalreadfiles = 0 ; 19*30880Sbostic int totalreadblocks = 0 ; 20*30880Sbostic int totalreadlines = 0 ; 21*30880Sbostic int totalreadchars = 0 ; 22*30880Sbostic int totalwritefiles = 0 ; 23*30880Sbostic int totalwriteblocks = 0 ; 24*30880Sbostic int totalwritelines = 0 ; 25*30880Sbostic int totalwritechars = 0 ; 26*30880Sbostic 27*30880Sbostic main(argc,argv) 28*30880Sbostic int argc; 29*30880Sbostic char *argv[]; 30*30880Sbostic { 31*30880Sbostic struct tm *tm; 32*30880Sbostic long timetemp; 33*30880Sbostic int year; 34*30880Sbostic int day; 35*30880Sbostic char *tapename; 36*30880Sbostic char *filename; 37*30880Sbostic char *namelist=NULL; 38*30880Sbostic char *device = "/dev/rmt12"; 39*30880Sbostic int tape; 40*30880Sbostic int file; 41*30880Sbostic int filenum; 42*30880Sbostic int argnum; 43*30880Sbostic char line[1001]; 44*30880Sbostic char vmsname[1000]; 45*30880Sbostic char unixname[1000]; 46*30880Sbostic FILE *names; 47*30880Sbostic int count; 48*30880Sbostic int tmp; 49*30880Sbostic char blockchar; 50*30880Sbostic int blocksize=2048; 51*30880Sbostic 52*30880Sbostic char *key; 53*30880Sbostic 54*30880Sbostic timetemp = time(0); 55*30880Sbostic tm = localtime(&timetemp); 56*30880Sbostic year = tm->tm_year; 57*30880Sbostic day = tm->tm_yday; 58*30880Sbostic tapename = malloc(10); 59*30880Sbostic gethostname(tapename,6); 60*30880Sbostic tapename[7]='\0'; 61*30880Sbostic 62*30880Sbostic /* parse command line */ 63*30880Sbostic if (argc < 2) 64*30880Sbostic usage(); 65*30880Sbostic 66*30880Sbostic argv++; 67*30880Sbostic argc--; 68*30880Sbostic /* loop through first argument (key) */ 69*30880Sbostic argc--; 70*30880Sbostic for (key = *argv++; *key; key++) 71*30880Sbostic switch(*key) { 72*30880Sbostic 73*30880Sbostic case 'f': 74*30880Sbostic if (*argv == NULL || argc <1) { 75*30880Sbostic fprintf(stderr, 76*30880Sbostic "ansitape: 'f' option requires tape name \n"); 77*30880Sbostic usage(); 78*30880Sbostic } 79*30880Sbostic device = *argv++; 80*30880Sbostic argc--; 81*30880Sbostic break; 82*30880Sbostic 83*30880Sbostic case 'n': 84*30880Sbostic if (*argv == NULL || argc <1) { 85*30880Sbostic fprintf(stderr, 86*30880Sbostic "ansitape: 'n' option requires file name\n"); 87*30880Sbostic usage(); 88*30880Sbostic } 89*30880Sbostic namelist = *argv++; 90*30880Sbostic argc--; 91*30880Sbostic break; 92*30880Sbostic 93*30880Sbostic case 'l': 94*30880Sbostic if (*argv == NULL || argc<1) { 95*30880Sbostic fprintf(stderr, 96*30880Sbostic "ansitape: 'l' option requires label\n"); 97*30880Sbostic usage(); 98*30880Sbostic } 99*30880Sbostic tapename = *argv++; 100*30880Sbostic argc--; 101*30880Sbostic break; 102*30880Sbostic 103*30880Sbostic case 'b': 104*30880Sbostic if (*argv == NULL) { 105*30880Sbostic fprintf(stderr, 106*30880Sbostic "ansitape: 'b' option requires blocksize specifier \n"); 107*30880Sbostic usage(); 108*30880Sbostic } 109*30880Sbostic tmp = sscanf(*argv++," %d%c ",&blocksize,&blockchar); 110*30880Sbostic argc--; 111*30880Sbostic if(tmp<1) { 112*30880Sbostic fprintf(stderr,"illegal blocksize: blocksize set to 2048\n"); 113*30880Sbostic blocksize=2048; 114*30880Sbostic } else if(tmp>1) { 115*30880Sbostic if(blockchar == 'b') blocksize *= 512; 116*30880Sbostic if(blockchar == 'k') blocksize *= 1024; 117*30880Sbostic } 118*30880Sbostic if(blocksize <18) blocksize=18; 119*30880Sbostic if(blocksize >62*1024) blocksize=62*1024; 120*30880Sbostic break; 121*30880Sbostic 122*30880Sbostic case 'c': 123*30880Sbostic cflag++; 124*30880Sbostic wflag++; 125*30880Sbostic break; 126*30880Sbostic 127*30880Sbostic case 'r': 128*30880Sbostic /*I know, this should be rflag, but I just don't like r for write*/ 129*30880Sbostic wflag++; 130*30880Sbostic break; 131*30880Sbostic 132*30880Sbostic case 'v': 133*30880Sbostic vflag++; 134*30880Sbostic break; 135*30880Sbostic 136*30880Sbostic case 'x': 137*30880Sbostic xflag++; 138*30880Sbostic break; 139*30880Sbostic 140*30880Sbostic case 't': 141*30880Sbostic tflag++; 142*30880Sbostic break; 143*30880Sbostic 144*30880Sbostic case '-': 145*30880Sbostic break; 146*30880Sbostic 147*30880Sbostic default: 148*30880Sbostic fprintf(stderr, "ansitape: %c: unknown option\n", *key); 149*30880Sbostic usage(); 150*30880Sbostic } 151*30880Sbostic 152*30880Sbostic if (!wflag && !xflag && !tflag) 153*30880Sbostic usage(); 154*30880Sbostic 155*30880Sbostic tape = open(device,wflag?O_RDWR:O_RDONLY,NULL); 156*30880Sbostic if(tape<0) { 157*30880Sbostic perror(device); 158*30880Sbostic printf(stderr,"tape not accessable - check if drive online and write ring present\n"); 159*30880Sbostic exit(1); 160*30880Sbostic } 161*30880Sbostic rewind(tape); 162*30880Sbostic filenum=1; 163*30880Sbostic casefix(tapename); 164*30880Sbostic 165*30880Sbostic if(cflag) { 166*30880Sbostic writevol(tapename,tape); 167*30880Sbostic } else { 168*30880Sbostic getvol(tapename,tape); 169*30880Sbostic while(1) { 170*30880Sbostic /* read files */ 171*30880Sbostic if( readfile(tape,argc,argv) ) break; 172*30880Sbostic filenum++; 173*30880Sbostic } 174*30880Sbostic backspace(tape); 175*30880Sbostic } 176*30880Sbostic 177*30880Sbostic if(wflag) { 178*30880Sbostic if(namelist) { 179*30880Sbostic if(*namelist == '-') { 180*30880Sbostic names = stdin; 181*30880Sbostic } else { 182*30880Sbostic names=fopen(namelist,"r"); 183*30880Sbostic if(names == NULL) { 184*30880Sbostic fprintf(stderr,"unable to open namelist file - no files added to tape\n"); 185*30880Sbostic } 186*30880Sbostic } 187*30880Sbostic while(1) { 188*30880Sbostic fgets(line,1000,names); 189*30880Sbostic if(feof(names)) break; 190*30880Sbostic count = sscanf(line,"%s %s",unixname,vmsname); 191*30880Sbostic if(count<1) continue; /* blank line */ 192*30880Sbostic if(count==1) strcpy(vmsname,unixname); 193*30880Sbostic casefix(vmsname); 194*30880Sbostic if(filecheck(&file,unixname)) continue; 195*30880Sbostic writefile(tape,file,vmsname,tapename,filenum,year,day,blocksize); 196*30880Sbostic filenum++; 197*30880Sbostic close(file); 198*30880Sbostic } 199*30880Sbostic } else { 200*30880Sbostic for(argnum=0;argnum<argc;argnum++) { 201*30880Sbostic filename = argv[argnum]; 202*30880Sbostic if(filecheck(&file,filename)) continue; 203*30880Sbostic casefix(filename); 204*30880Sbostic writefile(tape,file,filename,tapename,filenum,year,day,blocksize); 205*30880Sbostic filenum++; 206*30880Sbostic close(file); 207*30880Sbostic } 208*30880Sbostic } 209*30880Sbostic writetm(tape); 210*30880Sbostic writetm(tape); 211*30880Sbostic writetm(tape); 212*30880Sbostic writetm(tape); 213*30880Sbostic } 214*30880Sbostic rewind(tape); 215*30880Sbostic close(tape); 216*30880Sbostic if(vflag && (tflag || xflag)) { 217*30880Sbostic fprintf(stdout," read %d files in %d blocks (%d lines, %d chars)\n", 218*30880Sbostic totalreadfiles,totalreadblocks,totalreadlines,totalreadchars); 219*30880Sbostic } 220*30880Sbostic if(vflag && wflag) { 221*30880Sbostic fprintf(stdout," wrote %d files in %d blocks (%d lines, %d chars)\n", 222*30880Sbostic totalwritefiles,totalwriteblocks,totalwritelines,totalwritechars); 223*30880Sbostic } 224*30880Sbostic } 225*30880Sbostic usage() { 226*30880Sbostic fprintf(stderr, 227*30880Sbostic "ansitape: usage: ansitape -{rxtc}[flnvb] [filename] [label] [filename] [blocksize] [files]\n"); 228*30880Sbostic exit(); 229*30880Sbostic } 230*30880Sbostic 231*30880Sbostic writefile(tape,file,filename,tapename,filenum,year,day,blocksize) 232*30880Sbostic int tape; 233*30880Sbostic int file; 234*30880Sbostic char *filename; 235*30880Sbostic char *tapename; 236*30880Sbostic int filenum; 237*30880Sbostic int year; 238*30880Sbostic int day; 239*30880Sbostic int blocksize; 240*30880Sbostic 241*30880Sbostic { 242*30880Sbostic int blocks; 243*30880Sbostic writehdr1(tape,filename,tapename,filenum,year,day); 244*30880Sbostic writehdr2(tape,blocksize); 245*30880Sbostic writehdr3(tape); 246*30880Sbostic writetm(tape); 247*30880Sbostic writedata(tape,file,filename,&blocks,blocksize); 248*30880Sbostic writetm(tape); 249*30880Sbostic writeeof1(tape,filename,tapename,filenum,year,day,blocks); 250*30880Sbostic writeeof2(tape); 251*30880Sbostic writeeof3(tape); 252*30880Sbostic writetm(tape); 253*30880Sbostic totalwritefiles++; 254*30880Sbostic } 255*30880Sbostic 256*30880Sbostic writedata(tape,file,filename,blocks,blocksize) 257*30880Sbostic int tape; 258*30880Sbostic int file; 259*30880Sbostic char *filename; 260*30880Sbostic int *blocks; 261*30880Sbostic int blocksize; 262*30880Sbostic { 263*30880Sbostic char *ibuf; 264*30880Sbostic char *ibufstart; 265*30880Sbostic char *obuf; 266*30880Sbostic char *obufstart; 267*30880Sbostic char sizebuf[5]; 268*30880Sbostic char *endibuf; 269*30880Sbostic char *endobuf; 270*30880Sbostic int got; 271*30880Sbostic int i; 272*30880Sbostic char *j; 273*30880Sbostic int numchar = 0 ; 274*30880Sbostic int numline = 0 ; 275*30880Sbostic int numblock = 0; 276*30880Sbostic int success; 277*30880Sbostic 278*30880Sbostic ibufstart = ibuf = malloc(blocksize<4096?8200:(2*blocksize+10)); 279*30880Sbostic obufstart = obuf = malloc(blocksize+10); 280*30880Sbostic endobuf = obuf + blocksize; 281*30880Sbostic endibuf = ibuf; 282*30880Sbostic 283*30880Sbostic 284*30880Sbostic i=0; 285*30880Sbostic while(1) { 286*30880Sbostic if(ibuf+i>=endibuf) { /* end of input buffer */ 287*30880Sbostic strncpy(ibufstart,ibuf,endibuf-ibuf); /* copy leftover to start */ 288*30880Sbostic ibuf = ibufstart+(endibuf-ibuf); /* point to end of valid data */ 289*30880Sbostic got = read(file,ibuf,blocksize<4096?4096:2*blocksize); /* read in a chunk */ 290*30880Sbostic endibuf = ibuf + got; 291*30880Sbostic ibuf = ibufstart; /* point to beginning of data */ 292*30880Sbostic if(got == 0) { /* end of input */ 293*30880Sbostic if(ibuf==ibufstart){ /* no leftovers */ 294*30880Sbostic break; /* done */ 295*30880Sbostic } else { 296*30880Sbostic ibuf[i]='\n'; /* fake extra newline */ 297*30880Sbostic } 298*30880Sbostic } 299*30880Sbostic } 300*30880Sbostic 301*30880Sbostic if(obuf+i+4 > endobuf) { /* end of output buffer */ 302*30880Sbostic if(i>blocksize-4) { 303*30880Sbostic printf("record exceeds blocksize - file truncated\n"); 304*30880Sbostic break; 305*30880Sbostic } 306*30880Sbostic /* filled up output record - have to fill,output,restart*/ 307*30880Sbostic for(j=obuf;j<endobuf;j++) { 308*30880Sbostic *j = '^'; 309*30880Sbostic } 310*30880Sbostic success = write(tape,obufstart,blocksize); 311*30880Sbostic if(success != blocksize) { 312*30880Sbostic perror("tape"); 313*30880Sbostic fprintf(stderr," hard write error: write aborted\n"); 314*30880Sbostic rewind(tape); 315*30880Sbostic exit(1); 316*30880Sbostic } 317*30880Sbostic obuf=obufstart; 318*30880Sbostic numchar -= i; 319*30880Sbostic i=0; 320*30880Sbostic numblock++; 321*30880Sbostic continue; 322*30880Sbostic } 323*30880Sbostic 324*30880Sbostic if(ibuf[i] == '\n') { /* end of line */ 325*30880Sbostic /*sprintf(sizebuf,"%4.4d",i+4); /* make length string */ 326*30880Sbostic /*strncpy(obuf,sizebuf,4); /* put in length field */ 327*30880Sbostic obuf[0] = ((i+4)/1000) + '0'; 328*30880Sbostic obuf[1] = (((i+4)/100)%10) + '0'; 329*30880Sbostic obuf[2] = (((i+4)/10)%10) + '0'; 330*30880Sbostic obuf[3] = (((i+4)/1)%10) + '0'; 331*30880Sbostic obuf += (4+i); /* size + strlen */ 332*30880Sbostic ibuf += (1+i); /* newline + strlen */ 333*30880Sbostic i=0; 334*30880Sbostic numline++; 335*30880Sbostic continue; /* back to the top */ 336*30880Sbostic } 337*30880Sbostic 338*30880Sbostic obuf[i+4]=ibuf[i]; 339*30880Sbostic numchar++; 340*30880Sbostic i++; 341*30880Sbostic 342*30880Sbostic } 343*30880Sbostic /* exited - write last record and go for lunch */ 344*30880Sbostic if(obuf != obufstart) { 345*30880Sbostic for(j=obuf;j<endobuf;j++) { 346*30880Sbostic *j = '^'; 347*30880Sbostic } 348*30880Sbostic success = write(tape,obufstart,blocksize); 349*30880Sbostic if(success != blocksize) { 350*30880Sbostic perror("tape"); 351*30880Sbostic fprintf(stderr," hard write error: write aborted\n"); 352*30880Sbostic rewind(tape); 353*30880Sbostic exit(1); 354*30880Sbostic } 355*30880Sbostic numblock++; 356*30880Sbostic } 357*30880Sbostic free(ibufstart); 358*30880Sbostic free(obufstart); 359*30880Sbostic if(vflag) { 360*30880Sbostic fprintf(stdout,"r - %s: %d lines (%d chars) in %d tape blocks\n", 361*30880Sbostic filename,numline,numchar,numblock); 362*30880Sbostic } 363*30880Sbostic totalwritechars += numchar; 364*30880Sbostic totalwritelines += numline; 365*30880Sbostic totalwriteblocks += numblock; 366*30880Sbostic *blocks = numblock; 367*30880Sbostic } 368*30880Sbostic 369*30880Sbostic writetm(tape) 370*30880Sbostic int tape; 371*30880Sbostic { 372*30880Sbostic struct mtop mtop; 373*30880Sbostic mtop.mt_op = MTWEOF; 374*30880Sbostic mtop.mt_count = 1; 375*30880Sbostic ioctl(tape,MTIOCTOP,&mtop); 376*30880Sbostic } 377*30880Sbostic 378*30880Sbostic rewind(tape) 379*30880Sbostic int tape; 380*30880Sbostic { 381*30880Sbostic struct mtop mtop; 382*30880Sbostic mtop.mt_op = MTREW; 383*30880Sbostic mtop.mt_count = 1; 384*30880Sbostic ioctl(tape,MTIOCTOP,&mtop); 385*30880Sbostic } 386*30880Sbostic 387*30880Sbostic skipfile(tape) 388*30880Sbostic int tape; 389*30880Sbostic { 390*30880Sbostic struct mtop mtop; 391*30880Sbostic mtop.mt_op = MTFSF; 392*30880Sbostic mtop.mt_count = 1; 393*30880Sbostic ioctl(tape,MTIOCTOP,&mtop); 394*30880Sbostic } 395*30880Sbostic 396*30880Sbostic backspace(tape) 397*30880Sbostic int tape; 398*30880Sbostic { 399*30880Sbostic struct mtop mtop; 400*30880Sbostic mtop.mt_op = MTBSF; 401*30880Sbostic mtop.mt_count = 1; 402*30880Sbostic ioctl(tape,MTIOCTOP,&mtop); 403*30880Sbostic } 404*30880Sbostic 405*30880Sbostic writehdr1(tape,filename,tapename,filenum,year,day) 406*30880Sbostic int tape; 407*30880Sbostic char *filename; 408*30880Sbostic char *tapename; 409*30880Sbostic int filenum; 410*30880Sbostic int year; 411*30880Sbostic int day; 412*30880Sbostic { 413*30880Sbostic char buf[81]; 414*30880Sbostic sprintf(buf, 415*30880Sbostic "HDR1%-17.17s%-6.6s0001%4.4d000101 %2.2d%3.3d %2.2d%3.3d 000000DECFILE11A " 416*30880Sbostic ,filename,tapename,filenum,year,day,year,day); 417*30880Sbostic write(tape,buf,80); 418*30880Sbostic } 419*30880Sbostic 420*30880Sbostic writeeof1(tape,filename,tapename,filenum,year,day,blocks) 421*30880Sbostic int tape; 422*30880Sbostic char *filename; 423*30880Sbostic char *tapename; 424*30880Sbostic int filenum; 425*30880Sbostic int year; 426*30880Sbostic int day; 427*30880Sbostic int blocks; 428*30880Sbostic { 429*30880Sbostic char buf[81]; 430*30880Sbostic sprintf(buf, 431*30880Sbostic "EOF1%-17.17s%-6.6s0001%4.4d000101 %2.2d%3.3d %2.2d%3.3d %6.6dDECFILE11A " 432*30880Sbostic ,filename,tapename,filenum,year,day,year,day,blocks); 433*30880Sbostic write(tape,buf,80); 434*30880Sbostic } 435*30880Sbostic 436*30880Sbostic writehdr2(tape,blocksize) 437*30880Sbostic int tape; 438*30880Sbostic int blocksize; 439*30880Sbostic { 440*30880Sbostic char buf[81]; 441*30880Sbostic sprintf(buf, "HDR2D%5.5d%5.5d%35.35s00%28.28s",blocksize,blocksize," "," "); 442*30880Sbostic write(tape,buf,80); 443*30880Sbostic } 444*30880Sbostic 445*30880Sbostic writeeof2(tape,blocksize) 446*30880Sbostic int tape; 447*30880Sbostic int blocksize; 448*30880Sbostic { 449*30880Sbostic char buf[81]; 450*30880Sbostic sprintf(buf, "EOF2D%5.5d%5.5d%35.35s00%28.28s",blocksize,blocksize," "," "); 451*30880Sbostic write(tape,buf,80); 452*30880Sbostic } 453*30880Sbostic 454*30880Sbostic writehdr3(tape) 455*30880Sbostic int tape; 456*30880Sbostic { 457*30880Sbostic char buf[81]; 458*30880Sbostic sprintf(buf, "HDR3%76.76s"," "); 459*30880Sbostic write(tape,buf,80); 460*30880Sbostic } 461*30880Sbostic 462*30880Sbostic writeeof3(tape) 463*30880Sbostic int tape; 464*30880Sbostic { 465*30880Sbostic char buf[81]; 466*30880Sbostic sprintf(buf, "EOF3%76.76s"," "); 467*30880Sbostic write(tape,buf,80); 468*30880Sbostic } 469*30880Sbostic 470*30880Sbostic writevol(tapename,tape) 471*30880Sbostic int tape; 472*30880Sbostic char *tapename; 473*30880Sbostic { 474*30880Sbostic char buf[81]; 475*30880Sbostic sprintf(buf,"VOL1%-6.6s %26.26sD%47510.10s1%28.28s3",tapename," "," "," "); 476*30880Sbostic write(tape,buf,80); 477*30880Sbostic if(vflag) { 478*30880Sbostic fprintf(stdout," tape labeled %-6.6s\n",tapename); 479*30880Sbostic } 480*30880Sbostic } 481*30880Sbostic 482*30880Sbostic getvol(tapename,tape) 483*30880Sbostic int tape; 484*30880Sbostic char *tapename; 485*30880Sbostic { 486*30880Sbostic char buf[81]; 487*30880Sbostic read(tape,buf,80); 488*30880Sbostic sscanf(buf,"VOL1%6s",tapename); 489*30880Sbostic if(vflag) { 490*30880Sbostic fprintf(stdout," tape was labeled %-6.6s\n",tapename); 491*30880Sbostic } 492*30880Sbostic } 493*30880Sbostic 494*30880Sbostic casefix(string) 495*30880Sbostic register char *string; 496*30880Sbostic { 497*30880Sbostic while(*string) { 498*30880Sbostic if(islower(*string)) { 499*30880Sbostic *string = toupper(*string); 500*30880Sbostic } 501*30880Sbostic string++; 502*30880Sbostic } 503*30880Sbostic } 504*30880Sbostic 505*30880Sbostic #define getsize(a) ((a[0]-'0')*1000)+((a[1]-'0')*100)+((a[2]-'0')*10)+(a[3]-'0') 506*30880Sbostic int 507*30880Sbostic readfile(tape,argc,argv) 508*30880Sbostic int tape; 509*30880Sbostic int argc; 510*30880Sbostic char *argv[]; 511*30880Sbostic { 512*30880Sbostic char buf[80]; 513*30880Sbostic char mode; 514*30880Sbostic char filename[18]; 515*30880Sbostic FILE *file; 516*30880Sbostic int extract; 517*30880Sbostic char *ibuf; 518*30880Sbostic char *ibufstart; 519*30880Sbostic char *endibuf; 520*30880Sbostic int i; 521*30880Sbostic int size; 522*30880Sbostic int numblock = 0 ; 523*30880Sbostic int numchar = 0 ; 524*30880Sbostic int numline = 0 ; 525*30880Sbostic int argnum; 526*30880Sbostic int ok; 527*30880Sbostic int blocksize; 528*30880Sbostic int recordsize; 529*30880Sbostic int writeblock; 530*30880Sbostic 531*30880Sbostic if(!(read(tape,buf,80))) return(1); /* no hdr record, so second eof */ 532*30880Sbostic sscanf(buf,"HDR1%17s",filename); 533*30880Sbostic read(tape,buf,80); 534*30880Sbostic sscanf(buf,"HDR2%c%5d%5d",&mode,&blocksize,&recordsize); 535*30880Sbostic blocksize = blocksize>recordsize?blocksize:recordsize; 536*30880Sbostic skipfile(tape); /* throw away rest of header(s) - not interesting */ 537*30880Sbostic ibufstart=ibuf=malloc(blocksize+10); 538*30880Sbostic endibuf=ibufstart+blocksize; 539*30880Sbostic extract=0; 540*30880Sbostic if(tflag || xflag) { 541*30880Sbostic ok=0; 542*30880Sbostic if(!argc) { 543*30880Sbostic ok=1; 544*30880Sbostic } else for(argnum=0;argnum<argc;argnum++) { 545*30880Sbostic casefix(argv[argnum]); 546*30880Sbostic if(!strcmp(filename,argv[argnum])) { 547*30880Sbostic ok=1; 548*30880Sbostic break; 549*30880Sbostic } 550*30880Sbostic } 551*30880Sbostic if(mode == 'D') { 552*30880Sbostic if(xflag && ok) { 553*30880Sbostic file = fopen(filename,"w"); 554*30880Sbostic if(file == NULL) { 555*30880Sbostic perror(filename); 556*30880Sbostic } else { 557*30880Sbostic extract = 1; 558*30880Sbostic } 559*30880Sbostic } 560*30880Sbostic while(read(tape,ibufstart,blocksize)) { 561*30880Sbostic numblock++; 562*30880Sbostic ibuf = ibufstart; 563*30880Sbostic while(strncmp("^^^^",ibuf,4)) { 564*30880Sbostic size = getsize(ibuf); 565*30880Sbostic if(extract) { 566*30880Sbostic fwrite(ibuf+4,sizeof(char),size-4,file); 567*30880Sbostic fwrite("\n",1,1,file); 568*30880Sbostic } 569*30880Sbostic ibuf += (size); 570*30880Sbostic numline++; 571*30880Sbostic numchar += (size-4); 572*30880Sbostic if(ibuf > endibuf+1) { 573*30880Sbostic fprintf(stderr,"error: bad tape records(s) - file may be corrupted\n"); 574*30880Sbostic break; 575*30880Sbostic } 576*30880Sbostic if(ibuf>endibuf-4) break; 577*30880Sbostic } 578*30880Sbostic } 579*30880Sbostic if(extract) { 580*30880Sbostic fclose(file); 581*30880Sbostic } 582*30880Sbostic } else if (mode == 'F') { 583*30880Sbostic if(xflag && ok) { 584*30880Sbostic file = fopen(filename,"w"); 585*30880Sbostic if(file == NULL) { 586*30880Sbostic perror(filename); 587*30880Sbostic } else { 588*30880Sbostic extract = 1; 589*30880Sbostic } 590*30880Sbostic } 591*30880Sbostic while(read(tape,ibufstart,blocksize)) { 592*30880Sbostic numblock++; 593*30880Sbostic ibuf = ibufstart; 594*30880Sbostic while(ibuf+recordsize <= endibuf) { 595*30880Sbostic if(extract) { 596*30880Sbostic fwrite(ibuf,sizeof(char),recordsize,file); 597*30880Sbostic fwrite("\n",1,1,file); 598*30880Sbostic } 599*30880Sbostic ibuf += recordsize; 600*30880Sbostic numline++; 601*30880Sbostic numchar += recordsize; 602*30880Sbostic } 603*30880Sbostic } 604*30880Sbostic if(extract) { 605*30880Sbostic fclose(file); 606*30880Sbostic } 607*30880Sbostic } else { 608*30880Sbostic fprintf(stderr,"unknown record mode (%c) - file %s skipped\n", 609*30880Sbostic mode,filename); 610*30880Sbostic skipfile(tape); /* throw away actual file */ 611*30880Sbostic } 612*30880Sbostic } else { 613*30880Sbostic /* not interested in contents of file, so move fast */ 614*30880Sbostic skipfile(tape); 615*30880Sbostic } 616*30880Sbostic skipfile(tape); /* throw away eof stuff - not interesting */ 617*30880Sbostic totalreadchars += numchar; 618*30880Sbostic totalreadlines += numline; 619*30880Sbostic totalreadblocks += numblock; 620*30880Sbostic totalreadfiles ++; 621*30880Sbostic if(xflag && vflag && ok) { 622*30880Sbostic fprintf(stdout,"x - %s: %d lines (%d chars) in %d tape blocks\n", 623*30880Sbostic filename,numline,numchar,numblock); 624*30880Sbostic } else if(tflag && ok) { 625*30880Sbostic fprintf(stdout,"t - %s: %d lines (%d chars) in %d tape blocks\n", 626*30880Sbostic filename,numline,numchar,numblock); 627*30880Sbostic } 628*30880Sbostic free(ibufstart); 629*30880Sbostic return(0); 630*30880Sbostic } 631*30880Sbostic 632*30880Sbostic filecheck(file,name) 633*30880Sbostic int *file; 634*30880Sbostic char *name; 635*30880Sbostic 636*30880Sbostic { 637*30880Sbostic 638*30880Sbostic struct stat buf; 639*30880Sbostic struct exec sample; 640*30880Sbostic 641*30880Sbostic stat(name,&buf); 642*30880Sbostic if ((buf.st_mode & S_IFDIR)==S_IFDIR) { 643*30880Sbostic fprintf(stderr,"%s: directory - skipped\n",name); 644*30880Sbostic return(1); 645*30880Sbostic } 646*30880Sbostic if ((buf.st_mode & S_IFCHR)==S_IFCHR) { 647*30880Sbostic fprintf(stderr,"%s: character device - skipped\n",name); 648*30880Sbostic return(1); 649*30880Sbostic } 650*30880Sbostic if ((buf.st_mode & S_IFBLK)==S_IFBLK) { 651*30880Sbostic fprintf(stderr,"%s: block device - skipped\n",name); 652*30880Sbostic return(1); 653*30880Sbostic } 654*30880Sbostic if ((buf.st_mode & S_IFLNK)==S_IFLNK) { 655*30880Sbostic fprintf(stderr,"%s: symbolic link - skipped\n",name); 656*30880Sbostic return(1); 657*30880Sbostic } 658*30880Sbostic if ((buf.st_mode & S_IFSOCK)==S_IFSOCK) { 659*30880Sbostic fprintf(stderr,"%s: socket - skipped\n",name); 660*30880Sbostic return(1); 661*30880Sbostic } 662*30880Sbostic *file = open(name,O_RDONLY,NULL); 663*30880Sbostic if(*file <0) { 664*30880Sbostic perror(name); 665*30880Sbostic return(1); 666*30880Sbostic } 667*30880Sbostic if(read(*file,&sample,sizeof(struct exec))>= sizeof(struct exec)) { 668*30880Sbostic if(!(N_BADMAG(sample))) { 669*30880Sbostic /* executable */ 670*30880Sbostic /* the format requires either fixed blocked records, 671*30880Sbostic * or variable format records with each record remaining 672*30880Sbostic * entirely within a tape block - this limits the 673*30880Sbostic * distance between \n's to 2044 bytes, something 674*30880Sbostic * which is VERY rarely true of executables, so 675*30880Sbostic * we don't even try with them.... 676*30880Sbostic */ 677*30880Sbostic close(*file); 678*30880Sbostic fprintf(stderr,"%s: executable - skipped\n",name); 679*30880Sbostic return(1); 680*30880Sbostic } 681*30880Sbostic } 682*30880Sbostic /* either couldn't read sizeof(struct exec) or wasn't executable */ 683*30880Sbostic /* so we assume it is a reasonable file until proven otherwise */ 684*30880Sbostic lseek(*file,0l,0); 685*30880Sbostic return(0); 686*30880Sbostic } 687