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