|
|
1.1 root 1: #include <stdio.h>
2: #include <sys/types.h>
3: #include <sys/stat.h>
4: #include <sys/dir.h>
5: #include <sys/mtio.h>
6: #include <signal.h>
7:
8: char *sprintf();
9: char *strcat();
10: daddr_t bsrch();
11: #define TBLOCK 512
12: #define NBLOCK 40 /* maximum blocksize */
13: #define DBLOCK 20 /* default blocksize */
14: #define NAMSIZ 100
15: union hblock {
16: char dummy[TBLOCK];
17: struct header {
18: char name[NAMSIZ];
19: char mode[8];
20: char uid[8];
21: char gid[8];
22: char size[12];
23: char mtime[12];
24: char chksum[8];
25: char linkflag;
26: char linkname[NAMSIZ];
27: } dbuf;
28: } dblock, tbuf[NBLOCK];
29:
30: struct linkbuf {
31: ino_t inum;
32: dev_t devnum;
33: int count;
34: char pathname[NAMSIZ];
35: struct linkbuf *nextp;
36: } *ihead;
37:
38: struct stat stbuf;
39:
40: int rflag, xflag, vflag, tflag, mt, cflag, mflag, fflag, oflag, pflag;
41: int term, chksum, wflag, recno, first, linkerrok;
42: int freemem = 1;
43: int nblock = DBLOCK;
44:
45: daddr_t low;
46: daddr_t high;
47:
48: FILE *tfile;
49: char tname[] = "/tmp/tarXXXXXX";
50:
51:
52: char *usefile;
53: char magtape[] = "/dev/rmt1";
54:
55: char *malloc();
56:
57: main(argc, argv)
58: int argc;
59: char *argv[];
60: {
61: char *cp;
62: int onintr(), onquit(), onhup(), onterm();
63:
64: if (argc < 2)
65: usage();
66:
67: tfile = NULL;
68: usefile = magtape;
69: argv[argc] = 0;
70: argv++;
71: for (cp = *argv++; *cp; cp++)
72: switch(*cp) {
73: case 'f':
74: usefile = *argv++;
75: fflag++;
76: break;
77: case 'c':
78: cflag++;
79: rflag++;
80: break;
81: case 'o':
82: oflag++;
83: break;
84: case 'p':
85: pflag++;
86: break;
87: case 'u':
88: mktemp(tname);
89: if ((tfile = fopen(tname, "w")) == NULL) {
90: fprintf(stderr, "Tar: cannot create temporary file (%s)\n", tname);
91: done(1);
92: }
93: fprintf(tfile, "!!!!!/!/!/!/!/!/!/! 000\n");
94: /* FALL THROUGH */
95: case 'r':
96: rflag++;
97: break;
98: case 'v':
99: vflag++;
100: break;
101: case 'w':
102: wflag++;
103: break;
104: case 'x':
105: xflag++;
106: break;
107: case 't':
108: tflag++;
109: break;
110: case 'm':
111: mflag++;
112: break;
113: case '-':
114: break;
115: case '0':
116: case '1':
117: case '4':
118: case '5':
119: case '7':
120: case '8':
121: magtape[8] = *cp;
122: usefile = magtape;
123: break;
124: case 'b':
125: nblock = atoi(*argv++);
126: if (nblock > NBLOCK || nblock <= 0) {
127: fprintf(stderr, "Invalid blocksize. (Max %d)\n", NBLOCK);
128: done(1);
129: }
130: break;
131: case 'l':
132: linkerrok++;
133: break;
134: default:
135: fprintf(stderr, "tar: %c: unknown option\n", *cp);
136: usage();
137: }
138:
139: if (rflag) {
140: if (cflag && tfile != NULL) {
141: usage();
142: done(1);
143: }
144: if (signal(SIGINT, SIG_IGN) != SIG_IGN)
145: signal(SIGINT, onintr);
146: if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
147: signal(SIGHUP, onhup);
148: if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
149: signal(SIGQUIT, onquit);
150: /*
151: if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
152: signal(SIGTERM, onterm);
153: */
154: if (strcmp(usefile, "-") == 0) {
155: if (cflag == 0) {
156: fprintf(stderr, "Can only create standard output archives\n");
157: done(1);
158: }
159: mt = dup(1);
160: nblock = 1;
161: }
162: else if ((mt = open(usefile, 2)) < 0) {
163: if (cflag == 0 || (mt = creat(usefile, 0666)) < 0) {
164: fprintf(stderr, "tar: cannot open %s\n", usefile);
165: done(1);
166: }
167: }
168: dorep(argv);
169: }
170: else if (xflag) {
171: if (strcmp(usefile, "-") == 0) {
172: mt = dup(0);
173: nblock = 1;
174: }
175: else if ((mt = open(usefile, 0)) < 0) {
176: fprintf(stderr, "tar: cannot open %s\n", usefile);
177: done(1);
178: }
179: doxtract(argv);
180: }
181: else if (tflag) {
182: if (strcmp(usefile, "-") == 0) {
183: mt = dup(0);
184: nblock = 1;
185: }
186: else if ((mt = open(usefile, 0)) < 0) {
187: fprintf(stderr, "tar: cannot open %s\n", usefile);
188: done(1);
189: }
190: dotable();
191: }
192: else
193: usage();
194: done(0);
195: }
196:
197: usage()
198: {
199: fprintf(stderr, "tar: usage tar -{txru}[cvfblm] [tapefile] [blocksize] file1 file2...\n");
200: done(1);
201: }
202:
203: dorep(argv)
204: char *argv[];
205: {
206: register char *cp, *cp2;
207: char wdir[60];
208:
209: if (!cflag) {
210: getdir();
211: do {
212: passtape();
213: if (term)
214: done(0);
215: getdir();
216: } while (!endtape());
217: if (tfile != NULL) {
218: char buf[200];
219:
220: sprintf(buf, "sort +0 -1 +1nr %s -o %s; awk '$1 != prev {print; prev=$1}' %s >%sX; mv %sX %s",
221: tname, tname, tname, tname, tname, tname);
222: fflush(tfile);
223: system(buf);
224: freopen(tname, "r", tfile);
225: fstat(fileno(tfile), &stbuf);
226: high = stbuf.st_size;
227: }
228: }
229:
230: getwdir(wdir);
231: while (*argv && ! term) {
232: cp2 = *argv;
233: if (!strcmp(cp2, "-C") && argv[1]) {
234: argv++;
235: if (chdir(*argv) < 0)
236: perror(*argv);
237: else
238: getwdir(wdir);
239: argv++;
240: continue;
241: }
242: for (cp = *argv; *cp; cp++)
243: if (*cp == '/')
244: cp2 = cp;
245: if (cp2 != *argv) {
246: *cp2 = '\0';
247: chdir(*argv);
248: *cp2 = '/';
249: cp2++;
250: }
251: putfile(*argv++, cp2);
252: chdir(wdir);
253: }
254: putempty();
255: putempty();
256: flushtape();
257: if (linkerrok == 1)
258: for (; ihead != NULL; ihead = ihead->nextp)
259: if (ihead->count != 0)
260: fprintf(stderr, "Missing links to %s\n", ihead->pathname);
261: }
262:
263: endtape()
264: {
265: if (dblock.dbuf.name[0] == '\0') {
266: backtape();
267: return(1);
268: }
269: else
270: return(0);
271: }
272:
273: getdir()
274: {
275: register struct stat *sp;
276: int i;
277:
278: readtape( (char *) &dblock);
279: if (dblock.dbuf.name[0] == '\0')
280: return;
281: sp = &stbuf;
282: sscanf(dblock.dbuf.mode, "%o", &i);
283: sp->st_mode = i;
284: sscanf(dblock.dbuf.uid, "%o", &i);
285: sp->st_uid = i;
286: sscanf(dblock.dbuf.gid, "%o", &i);
287: sp->st_gid = i;
288: sscanf(dblock.dbuf.size, "%lo", &sp->st_size);
289: sscanf(dblock.dbuf.mtime, "%lo", &sp->st_mtime);
290: sscanf(dblock.dbuf.chksum, "%o", &chksum);
291: if (chksum != checksum()) {
292: fprintf(stderr, "directory checksum error\n");
293: done(2);
294: }
295: if(xflag){
296: fixname(dblock.dbuf.name);
297: fixname(dblock.dbuf.linkname);
298: }
299: if (tfile != NULL)
300: fprintf(tfile, "%s %s\n", dblock.dbuf.name, dblock.dbuf.mtime);
301: }
302:
303: passtape()
304: {
305: long blocks;
306: char buf[TBLOCK];
307:
308: if (dblock.dbuf.linkflag == '1')
309: return;
310: blocks = stbuf.st_size;
311: blocks += TBLOCK-1;
312: blocks /= TBLOCK;
313:
314: while (blocks-- > 0)
315: readtape(buf);
316: }
317:
318: putfile(longname, shortname)
319: char *longname;
320: char *shortname;
321: {
322: int infile;
323: long blocks;
324: char buf[TBLOCK];
325: register char *cp, *cp2;
326: struct direct dbuf;
327: int i, j;
328:
329: infile = open(shortname, 0);
330: if (infile < 0) {
331: fprintf(stderr, "tar: %s: cannot open file\n", longname);
332: return;
333: }
334:
335: fstat(infile, &stbuf);
336:
337: if (tfile != NULL && checkupdate(longname) == 0) {
338: close(infile);
339: return;
340: }
341: if (checkw('r', longname) == 0) {
342: close(infile);
343: return;
344: }
345:
346: if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
347: for (i = 0, cp = buf; *cp++ = longname[i++];);
348: *--cp = '/';
349: *++cp = 0 ;
350: i = 0;
351: if (!oflag) {
352: if( (cp - buf) >= NAMSIZ) {
353: fprintf(stderr, "%s: file name too long\n", longname);
354: close(infile);
355: return;
356: }
357: stbuf.st_size = 0;
358: tomodes(&stbuf);
359: strcpy(dblock.dbuf.name,buf);
360: sprintf(dblock.dbuf.chksum, "%6o", checksum());
361: writetape( (char *) &dblock);
362: }
363: chdir(shortname);
364: while (read(infile, (char *)&dbuf, sizeof(dbuf)) > 0 && !term) {
365: if (dbuf.d_ino == 0) {
366: i++;
367: continue;
368: }
369: if (strcmp(".", dbuf.d_name) == 0 || strcmp("..", dbuf.d_name) == 0) {
370: i++;
371: continue;
372: }
373: cp2 = cp;
374: for (j=0; j < DIRSIZ; j++)
375: *cp2++ = dbuf.d_name[j];
376: *cp2 = '\0';
377: close(infile);
378: putfile(buf, cp);
379: infile = open(".", 0);
380: i++;
381: lseek(infile, (long) (sizeof(dbuf) * i), 0);
382: }
383: close(infile);
384: chdir("..");
385: return;
386: }
387: if ((stbuf.st_mode & S_IFMT) != S_IFREG) {
388: fprintf(stderr, "tar: %s is not a file. Not dumped\n", longname);
389: close(infile);
390: return;
391: }
392:
393: tomodes(&stbuf);
394:
395: cp2 = longname;
396: for (cp = dblock.dbuf.name, i=0; (*cp++ = *cp2++) && i < NAMSIZ; i++);
397: if (i >= NAMSIZ) {
398: fprintf(stderr, "%s: file name too long\n", longname);
399: close(infile);
400: return;
401: }
402:
403: if (stbuf.st_nlink > 1) {
404: struct linkbuf *lp;
405: int found = 0;
406:
407: for (lp = ihead; lp != NULL; lp = lp->nextp) {
408: if (lp->inum == stbuf.st_ino && lp->devnum == stbuf.st_dev) {
409: found++;
410: break;
411: }
412: }
413: if (found) {
414: strcpy(dblock.dbuf.linkname, lp->pathname);
415: dblock.dbuf.linkflag = '1';
416: sprintf(dblock.dbuf.chksum, "%6o", checksum());
417: writetape( (char *) &dblock);
418: if (vflag) {
419: fprintf(stderr, "a %s ", longname);
420: fprintf(stderr, "link to %s\n", lp->pathname);
421: }
422: lp->count--;
423: close(infile);
424: return;
425: }
426: else {
427: lp = (struct linkbuf *) malloc(sizeof(*lp));
428: if (lp == NULL) {
429: if (freemem) {
430: fprintf(stderr, "Out of memory. Link information lost\n");
431: freemem = 0;
432: }
433: }
434: else {
435: lp->nextp = ihead;
436: ihead = lp;
437: lp->inum = stbuf.st_ino;
438: lp->devnum = stbuf.st_dev;
439: lp->count = stbuf.st_nlink - 1;
440: strcpy(lp->pathname, longname);
441: }
442: }
443: }
444:
445: blocks = (stbuf.st_size + (TBLOCK-1)) / TBLOCK;
446: if (vflag) {
447: fprintf(stderr, "a %s ", longname);
448: fprintf(stderr, "%ld blocks\n", blocks);
449: }
450: sprintf(dblock.dbuf.chksum, "%6o", checksum());
451: writetape( (char *) &dblock);
452:
453: while ((i = read(infile, buf, TBLOCK)) > 0 && blocks > 0) {
454: writetape(buf);
455: blocks--;
456: }
457: close(infile);
458: if (blocks != 0 || i != 0)
459: fprintf(stderr, "%s: file changed size\n", longname);
460: while (blocks-- > 0)
461: putempty();
462: }
463:
464:
465:
466: doxtract(argv)
467: char *argv[];
468: {
469: long blocks, bytes;
470: char buf[TBLOCK];
471: char **cp;
472: int ofile;
473:
474: for (;;) {
475: getdir();
476: if (endtape())
477: break;
478:
479: if (*argv == 0)
480: goto gotit;
481:
482: for (cp = argv; *cp; cp++)
483: if (prefix(*cp, dblock.dbuf.name))
484: goto gotit;
485: passtape();
486: continue;
487:
488: gotit:
489: if (checkw('x', dblock.dbuf.name) == 0) {
490: passtape();
491: continue;
492: }
493:
494: if(checkdir(dblock.dbuf.name))
495: continue;
496:
497: if (dblock.dbuf.linkflag == '1') {
498: unlink(dblock.dbuf.name);
499: if (link(dblock.dbuf.linkname, dblock.dbuf.name) < 0) {
500: fprintf(stderr, "%s: cannot link\n", dblock.dbuf.name);
501: continue;
502: }
503: if (vflag)
504: fprintf(stderr, "%s linked to %s\n",
505: dblock.dbuf.name, dblock.dbuf.linkname);
506: continue;
507: }
508: if ((ofile = creat(dblock.dbuf.name, stbuf.st_mode & 07777)) < 0) {
509: fprintf(stderr, "tar: %s - cannot create\n", dblock.dbuf.name);
510: passtape();
511: continue;
512: }
513: chown(dblock.dbuf.name, stbuf.st_uid, stbuf.st_gid);
514:
515: blocks = ((bytes = stbuf.st_size) + TBLOCK-1)/TBLOCK;
516: if (vflag)
517: fprintf(stderr, "x %s, %ld bytes, %ld tape blocks\n",
518: dblock.dbuf.name, bytes, blocks);
519: while (blocks-- > 0) {
520: readtape(buf);
521: if (bytes > TBLOCK) {
522: if (write(ofile, buf, TBLOCK) < 0) {
523: fprintf(stderr, "tar: %s: HELP - extract write error\n", dblock.dbuf.name);
524: done(2);
525: }
526: } else
527: if (write(ofile, buf, (int) bytes) < 0) {
528: fprintf(stderr, "tar: %s: HELP - extract write error\n", dblock.dbuf.name);
529: done(2);
530: }
531: bytes -= TBLOCK;
532: }
533: close(ofile);
534: if (mflag == 0) {
535: time_t timep[2];
536:
537: timep[0] = time(NULL);
538: timep[1] = stbuf.st_mtime;
539: utime(dblock.dbuf.name, timep);
540: }
541: if (pflag)
542: chmod(dblock.dbuf.name, stbuf.st_mode & 07777);
543: }
544: }
545:
546: dotable()
547: {
548: for (;;) {
549: getdir();
550: if (endtape())
551: break;
552: if (vflag)
553: longt(&stbuf);
554: printf("%s", dblock.dbuf.name);
555: if (dblock.dbuf.linkflag == '1')
556: printf(" linked to %s", dblock.dbuf.linkname);
557: printf("\n");
558: passtape();
559: }
560: }
561:
562: putempty()
563: {
564: char buf[TBLOCK];
565: char *cp;
566:
567: for (cp = buf; cp < &buf[TBLOCK]; )
568: *cp++ = '\0';
569: writetape(buf);
570: }
571:
572: longt(st)
573: register struct stat *st;
574: {
575: register char *cp;
576: char *ctime();
577:
578: pmode(st);
579: printf("%3d/%1d", st->st_uid, st->st_gid);
580: printf("%7D", st->st_size);
581: cp = ctime(&st->st_mtime);
582: printf(" %-12.12s %-4.4s ", cp+4, cp+20);
583: }
584:
585: #define SUID 04000
586: #define SGID 02000
587: #define ROWN 0400
588: #define WOWN 0200
589: #define XOWN 0100
590: #define RGRP 040
591: #define WGRP 020
592: #define XGRP 010
593: #define ROTH 04
594: #define WOTH 02
595: #define XOTH 01
596: #define STXT 01000
597: int m1[] = { 1, ROWN, 'r', '-' };
598: int m2[] = { 1, WOWN, 'w', '-' };
599: int m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
600: int m4[] = { 1, RGRP, 'r', '-' };
601: int m5[] = { 1, WGRP, 'w', '-' };
602: int m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
603: int m7[] = { 1, ROTH, 'r', '-' };
604: int m8[] = { 1, WOTH, 'w', '-' };
605: int m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
606:
607: int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
608:
609: pmode(st)
610: register struct stat *st;
611: {
612: register int **mp;
613:
614: for (mp = &m[0]; mp < &m[9];)
615: select(*mp++, st);
616: }
617:
618: select(pairp, st)
619: int *pairp;
620: struct stat *st;
621: {
622: register int n, *ap;
623:
624: ap = pairp;
625: n = *ap++;
626: while (--n>=0 && (st->st_mode&*ap++)==0)
627: ap++;
628: printf("%c", *ap);
629: }
630:
631: checkdir(name)
632: register char *name;
633: {
634: register char *cp;
635: int i;
636: for (cp = name; *cp; cp++) {
637: if (*cp == '/') {
638: *cp = '\0';
639: if (access(name, 01) < 0) {
640: register int pid, rp;
641:
642: if ((pid = fork()) == 0) {
643: execl("/bin/mkdir", "mkdir", name, 0);
644: execl("/usr/bin/mkdir", "mkdir", name, 0);
645: fprintf(stderr, "tar: cannot find mkdir!\n");
646: done(0);
647: }
648: while ((rp = wait(&i)) >= 0 && rp != pid)
649: ;
650: chown(name, stbuf.st_uid, stbuf.st_gid);
651: if (pflag)
652: chmod(dblock.dbuf.name,
653: stbuf.st_mode & 0777);
654: }
655: *cp = '/';
656: }
657: }
658: return(cp[-1]=='/');
659: }
660:
661: onintr()
662: {
663: signal(SIGINT, SIG_IGN);
664: term++;
665: }
666:
667: onquit()
668: {
669: signal(SIGQUIT, SIG_IGN);
670: term++;
671: }
672:
673: onhup()
674: {
675: signal(SIGHUP, SIG_IGN);
676: term++;
677: }
678:
679: onterm()
680: {
681: signal(SIGTERM, SIG_IGN);
682: term++;
683: }
684:
685: tomodes(sp)
686: register struct stat *sp;
687: {
688: register char *cp;
689:
690: for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++)
691: *cp = '\0';
692: sprintf(dblock.dbuf.mode, "%6o ", sp->st_mode & 07777);
693: sprintf(dblock.dbuf.uid, "%6o ", sp->st_uid);
694: sprintf(dblock.dbuf.gid, "%6o ", sp->st_gid);
695: sprintf(dblock.dbuf.size, "%11lo ", sp->st_size);
696: sprintf(dblock.dbuf.mtime, "%11lo ", sp->st_mtime);
697: }
698:
699: checksum()
700: {
701: register i;
702: register char *cp;
703:
704: for (cp = dblock.dbuf.chksum; cp < &dblock.dbuf.chksum[sizeof(dblock.dbuf.chksum)]; cp++)
705: *cp = ' ';
706: i = 0;
707: for (cp = dblock.dummy; cp < &dblock.dummy[TBLOCK]; cp++)
708: i += *cp;
709: return(i);
710: }
711:
712: checkw(c, name)
713: char *name;
714: {
715: if (wflag) {
716: printf("%c ", c);
717: if (vflag)
718: longt(&stbuf);
719: printf("%s: ", name);
720: if (response() == 'y'){
721: return(1);
722: }
723: return(0);
724: }
725: return(1);
726: }
727:
728: response()
729: {
730: char c;
731:
732: c = getchar();
733: if (c != '\n')
734: while (getchar() != '\n');
735: else c = 'n';
736: return(c);
737: }
738:
739: checkupdate(arg)
740: char *arg;
741: {
742: char name[100];
743: long mtime;
744: daddr_t seekp;
745: daddr_t lookup();
746:
747: rewind(tfile);
748: for (;;) {
749: if ((seekp = lookup(arg)) < 0)
750: return(1);
751: fseek(tfile, seekp, 0);
752: fscanf(tfile, "%s %lo", name, &mtime);
753: if (stbuf.st_mtime > mtime)
754: return(1);
755: else
756: return(0);
757: }
758: }
759:
760: done(n)
761: {
762: unlink(tname);
763: exit(n);
764: }
765:
766: prefix(s1, s2)
767: register char *s1, *s2;
768: {
769: while (*s1)
770: if (*s1++ != *s2++)
771: return(0);
772: if (*s2)
773: return(*s2 == '/');
774: return(1);
775: }
776:
777: getwdir(s)
778: char *s;
779: {
780: int i;
781: int pipdes[2];
782:
783: pipe(pipdes);
784: if ((i = fork()) == 0) {
785: close(1);
786: dup(pipdes[1]);
787: execl("/bin/pwd", "pwd", 0);
788: execl("/usr/bin/pwd", "pwd", 0);
789: fprintf(stderr, "pwd failed!\n");
790: printf("/\n");
791: exit(1);
792: }
793: while (wait((int *)NULL) != -1)
794: ;
795: read(pipdes[0], s, 50);
796: while(*s != '\n')
797: s++;
798: *s = '\0';
799: close(pipdes[0]);
800: close(pipdes[1]);
801: }
802:
803: #define N 200
804: int njab;
805: daddr_t
806: lookup(s)
807: char *s;
808: {
809: register i;
810: daddr_t a;
811:
812: for(i=0; s[i]; i++)
813: if(s[i] == ' ')
814: break;
815: a = bsrch(s, i, low, high);
816: return(a);
817: }
818:
819: daddr_t
820: bsrch(s, n, l, h)
821: daddr_t l, h;
822: char *s;
823: {
824: register i, j;
825: char b[N];
826: daddr_t m, m1;
827:
828: njab = 0;
829:
830: loop:
831: if(l >= h)
832: return(-1L);
833: m = l + (h-l)/2 - N/2;
834: if(m < l)
835: m = l;
836: fseek(tfile, m, 0);
837: fread(b, 1, N, tfile);
838: njab++;
839: for(i=0; i<N; i++) {
840: if(b[i] == '\n')
841: break;
842: m++;
843: }
844: if(m >= h)
845: return(-1L);
846: m1 = m;
847: j = i;
848: for(i++; i<N; i++) {
849: m1++;
850: if(b[i] == '\n')
851: break;
852: }
853: i = cmp(b+j, s, n);
854: if(i < 0) {
855: h = m;
856: goto loop;
857: }
858: if(i > 0) {
859: l = m1;
860: goto loop;
861: }
862: return(m);
863: }
864:
865: cmp(b, s, n)
866: char *b, *s;
867: {
868: register i;
869:
870: if(b[0] != '\n')
871: exit(2);
872: for(i=0; i<n; i++) {
873: if(b[i+1] > s[i])
874: return(-1);
875: if(b[i+1] < s[i])
876: return(1);
877: }
878: return(b[i+1] == ' '? 0 : -1);
879: }
880:
881: readtape(buffer)
882: char *buffer;
883: {
884: register int i;
885:
886: if (recno >= nblock || first == 0) {
887: if ((i = read(mt, tbuf, TBLOCK*nblock)) < 0) {
888: fprintf(stderr, "Tar: tape read error\n");
889: done(3);
890: }
891: if (first == 0) {
892: if ((i % TBLOCK) != 0) {
893: fprintf(stderr, "Tar: tape blocksize error\n");
894: done(3);
895: }
896: i /= TBLOCK;
897: if (i != nblock) {
898: fprintf(stderr, "Tar: blocksize = %d\n", i);
899: nblock = i;
900: }
901: }
902: recno = 0;
903: }
904: first = 1;
905: copy(buffer, &tbuf[recno++]);
906: return(TBLOCK);
907: }
908:
909: writetape(buffer)
910: char *buffer;
911: {
912: first = 1;
913: if (recno >= nblock) {
914: if (write(mt, tbuf, TBLOCK*nblock) < 0) {
915: fprintf(stderr, "Tar: tape write error\n");
916: done(2);
917: }
918: recno = 0;
919: }
920: copy(&tbuf[recno++], buffer);
921: if (recno >= nblock) {
922: if (write(mt, tbuf, TBLOCK*nblock) < 0) {
923: fprintf(stderr, "Tar: tape write error\n");
924: done(2);
925: }
926: recno = 0;
927: }
928: return(TBLOCK);
929: }
930:
931: backtape()
932: {
933: static int mtdev = 1;
934: static struct mtop mtop = {MTBSR, 1};
935: struct mtget mtget;
936:
937: if (mtdev == 1)
938: mtdev = ioctl(mt, MTIOCGET, &mtget);
939: if (mtdev == 0) {
940: if (ioctl(mt, MTIOCTOP, &mtop) < 0) {
941: fprintf(stderr, "Tar: tape backspace error\n");
942: done(4);
943: }
944: } else
945: lseek(mt, (long) -TBLOCK*nblock, 1);
946: recno--;
947: }
948:
949: flushtape()
950: {
951: write(mt, tbuf, TBLOCK*nblock);
952: }
953:
954: copy(to, from)
955: register char *to, *from;
956: {
957: register i;
958:
959: i = TBLOCK;
960: do {
961: *to++ = *from++;
962: } while (--i);
963: }
964: #define MAXFILENAME 14
965: FILE *longnamefd;
966:
967: affix(n,ptr)
968: int n;
969: char *ptr;
970: {
971: int i=0,m;
972: char ext[5];
973:
974: while(1) {
975: if((m=n%52)<26) ext[i++] = m + 'a';
976: else ext[i++] = m + 'A' - 26;
977: if(n < 52)break;
978: n = n/52 - 1; /* so we have Z,aa not Z,ba */
979: }
980:
981: while(--i >= 0)*ptr++ = ext[i];
982: *ptr = '\0';
983: }
984:
985: #define MAXOVER 1000
986: struct {
987: char *longname,
988: *shortname;
989: } pairs[MAXOVER];
990: int npairs = 0; /* no. of tabulated pairs */
991:
992: int ntoolong = 0; /* no. of overlong pathnames */
993:
994: char *
995: findname(key)
996: char *key;
997: {
998: int i, nprevious = 0, nprefix;
999: char *longptr, *shortptr, *malloc(), *endbit, *rindex();
1000:
1001: endbit = rindex(key,'/');
1002: if(endbit == 0)endbit = key;
1003: else endbit++;
1004: nprefix = endbit - key;
1005:
1006: for(i=0;i<npairs;i++){
1007: if(strcmp(key,pairs[i].longname) == 0)
1008: return(pairs[i].shortname);
1009: if(strncmp(key,pairs[i].longname,nprefix+MAXFILENAME) == 0)
1010: nprevious++;
1011: }
1012: longptr = pairs[npairs].longname = malloc(strlen(key)+1);
1013: shortptr = pairs[npairs].shortname = malloc(MAXFILENAME+1);
1014: strcpy(longptr,key);
1015: strncpy(shortptr,endbit,MAXFILENAME-4);
1016: sprintf(shortptr+MAXFILENAME-4,"..");
1017: affix(nprevious,shortptr+MAXFILENAME-2);
1018: npairs++;
1019: return(shortptr);
1020: }
1021:
1022: fixname(original)
1023: char *original;
1024: {
1025: int length;
1026: char newname[100];
1027: register char *inend, *outptr=newname, *instart=original,
1028: *outstart;
1029: int changed = 0;
1030:
1031: while(1){
1032: if(*instart == '\0')break;
1033: if(*instart == '/')*outptr++ = *instart++;
1034: outstart = outptr;
1035: for(inend=instart;*inend != '\0' && *inend != '/';)
1036: *outptr++ = *inend++;
1037: *outptr = '\0';
1038: length = strlen(outstart);
1039: if(length > MAXFILENAME){
1040: changed++;
1041: strcpy(outstart,findname(newname));
1042: }
1043: outptr = outstart + strlen(outstart);
1044: instart = inend;
1045: }
1046:
1047: if(changed){
1048: if(ntoolong == 0) {
1049: longnamefd = fopen("longnamelist","w");
1050: if(longnamefd == NULL){
1051: fprintf(stderr,
1052: "can't create longnamelist file\n");
1053: exit(1);
1054: }
1055: fprintf(stderr,"check out file 'longnamelist'\n");
1056: }
1057: printf("%s changed to %s\n",original,newname);
1058: fprintf(longnamefd,"%s\t%s\n",original, newname);
1059: fflush(longnamefd);
1060: strcpy(original,newname);
1061: ntoolong++;
1062: }
1063: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.