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