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