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