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