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