|
|
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.