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