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