|
|
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.