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