|
|
1.1 ! root 1: /* @(#)cpio.c 1.17 */ ! 2: /* cpio COMPILE: cc -O cpio.c -s -i -o cpio ! 3: cpio -- copy file collections ! 4: ! 5: */ ! 6: #include <stdio.h> ! 7: #include <signal.h> ! 8: #ifdef RT ! 9: #include <rt/macro.h> ! 10: #include <rt/types.h> ! 11: #include <rt/stat.h> ! 12: #else ! 13: #include <sys/types.h> ! 14: #include <sys/stat.h> ! 15: #include <errno.h> ! 16: #endif ! 17: #define EQ(x,y) (strcmp(x,y)==0) ! 18: /* for VAX, Interdata, ... */ ! 19: #define MKSHORT(v,lv) {U.l=1L;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,v[0]=U.s[0],v[1]=U.s[1];} ! 20: #define MAGIC 070707 /* cpio magic number */ ! 21: #define IN 1 /* copy in */ ! 22: #define OUT 2 /* copy out */ ! 23: #define PASS 3 /* direct copy */ ! 24: #define HDRSIZE (Hdr.h_name - (char *)&Hdr) /* header size minus filename field */ ! 25: #define LINKS 1000 /* max no. of links allowed */ ! 26: #define CHARS 76 /* ASCII header size minus filename field */ ! 27: #undef BUFSIZE ! 28: #define BUFSIZE 512 /* In u370, can't use BUFSIZ nor BSIZE */ ! 29: #define CPIOBSZ 4096 /* file read/write */ ! 30: #define MAXFILENAME 14 ! 31: #ifdef RT ! 32: extern long filespace; ! 33: #endif ! 34: ! 35: struct stat Statb, Xstatb; ! 36: ! 37: /* Cpio header format */ ! 38: struct header { ! 39: short h_magic, ! 40: h_dev; ! 41: unsigned ! 42: short h_ino, ! 43: h_mode, ! 44: h_uid, ! 45: h_gid; ! 46: short h_nlink, ! 47: h_rdev, ! 48: h_mtime[2], ! 49: h_namesize, ! 50: h_filesize[2]; ! 51: char h_name[256]; ! 52: } Hdr; ! 53: ! 54: unsigned Bufsize = BUFSIZE; /* default record size */ ! 55: short Buf[CPIOBSZ/2], *Dbuf; ! 56: char BBuf[CPIOBSZ], *Cbuf; ! 57: int Wct, Wc; ! 58: short *Wp; ! 59: char *Cp; ! 60: ! 61: #ifdef RT ! 62: short Actual_size[2]; ! 63: #endif ! 64: ! 65: short Option, ! 66: Dir, ! 67: Uncond, ! 68: Link, ! 69: Rename, ! 70: Toc, ! 71: Verbose, ! 72: Select, ! 73: Mod_time, ! 74: Acc_time, ! 75: Cflag, ! 76: fflag, ! 77: #ifdef RT ! 78: Extent, ! 79: #endif ! 80: Swap, ! 81: byteswap, ! 82: bothswap, ! 83: halfswap; ! 84: ! 85: int Ifile, ! 86: Ofile, ! 87: Input = 0, ! 88: Output = 1; ! 89: long Blocks, ! 90: Longfile, ! 91: Longtime; ! 92: ! 93: char Fullname[256], ! 94: Name[256]; ! 95: int Pathend; ! 96: int usrmask; ! 97: ! 98: FILE *Rtty, ! 99: *Wtty; ! 100: ! 101: char *Pattern[100]; ! 102: char Strhdr[500]; ! 103: char *Chdr = Strhdr; ! 104: short Dev, ! 105: Uid, ! 106: A_directory, ! 107: A_special, ! 108: #ifdef RT ! 109: One_extent, ! 110: Multi_extent, ! 111: #endif ! 112: Filetype = S_IFMT; ! 113: ! 114: extern errno; ! 115: char *malloc(); ! 116: char *cd(); ! 117: /* char *Cd_name; */ ! 118: FILE *popen(); ! 119: ! 120: union { long l; short s[2]; char c[4]; } U; ! 121: ! 122: /* for VAX, Interdata, ... */ ! 123: long mklong(v) ! 124: short v[]; ! 125: { ! 126: U.l = 1; ! 127: if(U.c[0]) ! 128: U.s[0] = v[1], U.s[1] = v[0]; ! 129: else ! 130: U.s[0] = v[0], U.s[1] = v[1]; ! 131: return U.l; ! 132: } ! 133: ! 134: main(argc, argv) ! 135: char **argv; ! 136: { ! 137: register ct; ! 138: long filesz; ! 139: register char *fullp; ! 140: register i; ! 141: int ans; ! 142: ! 143: signal(SIGSYS, 1); ! 144: if(*argv[1] != '-') ! 145: usage(); ! 146: Uid = geteuid(); ! 147: usrmask = umask(0); ! 148: umask(usrmask); ! 149: Pattern[0] = "*"; ! 150: ! 151: while(*++argv[1]) { ! 152: switch(*argv[1]) { ! 153: case 'a': /* reset access time */ ! 154: Acc_time++; ! 155: break; ! 156: case 'B': /* change record size to 5120 bytes */ ! 157: Bufsize = 5120; ! 158: break; ! 159: case 'i': ! 160: Option = IN; ! 161: if(argc > 2 ) { /* save patterns, if any */ ! 162: for(i = 0; (i+2) < argc; ++i) ! 163: Pattern[i] = argv[i+2]; ! 164: } ! 165: break; ! 166: case 'f': /* do not consider patterns in cmd line */ ! 167: fflag++; ! 168: break; ! 169: case 'o': ! 170: if(argc != 2) ! 171: usage(); ! 172: Option = OUT; ! 173: break; ! 174: case 'p': ! 175: if(argc != 3) ! 176: usage(); ! 177: if(access(argv[2], 2) == -1) { ! 178: accerr: ! 179: fprintf(stderr,"cannot write in <%s>\n", argv[2]); ! 180: exit(2); ! 181: } ! 182: strcpy(Fullname, argv[2]); /* destination directory */ ! 183: strcat(Fullname, "/"); ! 184: stat(Fullname, &Xstatb); ! 185: if((Xstatb.st_mode&S_IFMT) != S_IFDIR) ! 186: goto accerr; ! 187: Option = PASS; ! 188: Dev = Xstatb.st_dev; ! 189: break; ! 190: case 'c': /* ASCII header */ ! 191: Cflag++; ! 192: break; ! 193: case 'd': /* create directories when needed */ ! 194: Dir++; ! 195: break; ! 196: case 'l': /* link files, when necessary */ ! 197: Link++; ! 198: break; ! 199: case 'm': /* retain mod time */ ! 200: Mod_time++; ! 201: break; ! 202: case 'r': /* rename files interactively */ ! 203: Rename++; ! 204: Rtty = fopen("/dev/tty", "r"); ! 205: Wtty = fopen("/dev/tty", "w"); ! 206: if(Rtty==NULL || Wtty==NULL) { ! 207: fprintf(stderr, ! 208: "Cannot rename (/dev/tty missing)\n"); ! 209: exit(2); ! 210: } ! 211: break; ! 212: case 'S': /* swap halfwords */ ! 213: halfswap++; ! 214: Swap++; ! 215: break; ! 216: case 's': /* swap bytes */ ! 217: byteswap++; ! 218: Swap++; ! 219: break; ! 220: case 'b': ! 221: bothswap++; ! 222: Swap++; ! 223: break; ! 224: case 't': /* table of contents */ ! 225: Toc++; ! 226: break; ! 227: case 'u': /* copy unconditionally */ ! 228: Uncond++; ! 229: break; ! 230: case 'v': /* verbose table of contents */ ! 231: Verbose++; ! 232: break; ! 233: case '6': /* for old, sixth-edition files */ ! 234: Filetype = 060000; ! 235: break; ! 236: #ifdef RT ! 237: case 'e': ! 238: Extent++; ! 239: break; ! 240: #endif ! 241: default: ! 242: usage(); ! 243: } ! 244: } ! 245: if(!Option) { ! 246: fprintf(stderr,"Options must include o|i|p\n"); ! 247: exit(2); ! 248: } ! 249: #ifdef RT ! 250: setio(-1,1); /* turn on physio */ ! 251: #endif ! 252: ! 253: if(Option == PASS) { ! 254: if(Rename) { ! 255: fprintf(stderr,"Pass and Rename cannot be used together\n"); ! 256: exit(2); ! 257: } ! 258: if(Bufsize == 5120) { ! 259: printf("`B' option is irrelevant with the '-p' option\n"); ! 260: Bufsize = BUFSIZE; ! 261: } ! 262: ! 263: }else { ! 264: if(Cflag) ! 265: Cp = Cbuf = (char *)malloc(Bufsize); ! 266: else ! 267: Wp = Dbuf = (short *)malloc(Bufsize); ! 268: } ! 269: Wct = Bufsize >> 1; ! 270: Wc = Bufsize; ! 271: ! 272: switch(Option) { ! 273: ! 274: case OUT: /* get filename, copy header and file out */ ! 275: while(getname()) { ! 276: if( mklong(Hdr.h_filesize) == 0L) { ! 277: if( Cflag ) ! 278: writehdr(Chdr,CHARS+Hdr.h_namesize); ! 279: else ! 280: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize); ! 281: #ifdef RT ! 282: if (One_extent || Multi_extent) { ! 283: actsize(0); ! 284: if( Cflag ) ! 285: writehdr(Chdr,CHARS+Hdr.h_namesize); ! 286: else ! 287: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize); ! 288: } ! 289: #endif ! 290: continue; ! 291: } ! 292: if((Ifile = open(Hdr.h_name, 0)) < 0) { ! 293: fprintf(stderr,"<%s> ?\n", Hdr.h_name); ! 294: continue; ! 295: } ! 296: if ( Cflag ) ! 297: writehdr(Chdr,CHARS+Hdr.h_namesize); ! 298: else ! 299: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize); ! 300: #ifdef RT ! 301: if (One_extent || Multi_extent) { ! 302: actsize(Ifile); ! 303: if(Cflag) ! 304: writehdr(Chdr,CHARS+Hdr.h_namesize); ! 305: else ! 306: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize); ! 307: Hdr.h_filesize[0] = Actual_size[0]; ! 308: Hdr.h_filesize[1] = Actual_size[1]; ! 309: } ! 310: #endif ! 311: for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){ ! 312: ct = filesz>CPIOBSZ? CPIOBSZ: filesz; ! 313: if(read(Ifile, Cflag? BBuf: (char *)Buf, ct) < 0) { ! 314: fprintf(stderr,"Cannot read %s\n", Hdr.h_name); ! 315: continue; ! 316: } ! 317: Cflag? writehdr(BBuf,ct): bwrite(Buf,ct); ! 318: } ! 319: close(Ifile); ! 320: if(Acc_time) ! 321: utime(Hdr.h_name, &Statb.st_atime); ! 322: if(Verbose) ! 323: fprintf(stderr,"%s\n", Hdr.h_name); ! 324: } ! 325: ! 326: /* copy trailer, after all files have been copied */ ! 327: strcpy(Hdr.h_name, "TRAILER!!!"); ! 328: Hdr.h_magic = MAGIC; ! 329: MKSHORT(Hdr.h_filesize, 0L); ! 330: Hdr.h_namesize = strlen("TRAILER!!!") + 1; ! 331: if ( Cflag ) { ! 332: bintochar(0L); ! 333: writehdr(Chdr,CHARS+Hdr.h_namesize); ! 334: } ! 335: else ! 336: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize); ! 337: Cflag? writehdr(Cbuf, Bufsize): bwrite(Dbuf, Bufsize); ! 338: break; ! 339: ! 340: case IN: ! 341: pwd(); ! 342: while(gethdr()) { ! 343: Ofile = ckname(Hdr.h_name)? openout(Hdr.h_name): 0; ! 344: for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){ ! 345: ct = filesz>CPIOBSZ? CPIOBSZ: filesz; ! 346: Cflag? readhdr(BBuf,ct): bread(Buf, ct); ! 347: if(Ofile) { ! 348: if(Swap) ! 349: Cflag? swap(BBuf,ct): swap(Buf,ct); ! 350: if(write(Ofile, Cflag? BBuf: (char *)Buf, ct) < 0) { ! 351: fprintf(stderr,"Cannot write %s\n", Hdr.h_name); ! 352: continue; ! 353: } ! 354: } ! 355: } ! 356: if(Ofile) { ! 357: close(Ofile); ! 358: if(chmod(Hdr.h_name, Hdr.h_mode) < 0) { ! 359: fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Hdr.h_name, errno); ! 360: } ! 361: set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); ! 362: } ! 363: if(!Select) ! 364: continue; ! 365: if(Verbose) ! 366: if(Toc) ! 367: pentry(Hdr.h_name); ! 368: else ! 369: puts(Hdr.h_name); ! 370: else if(Toc) ! 371: puts(Hdr.h_name); ! 372: } ! 373: break; ! 374: ! 375: case PASS: /* move files around */ ! 376: fullp = Fullname + strlen(Fullname); ! 377: ! 378: while(getname()) { ! 379: if (A_directory && !Dir) ! 380: fprintf(stderr,"Use `-d' option to copy <%s>\n",Hdr.h_name); ! 381: if(!ckname(Hdr.h_name)) ! 382: continue; ! 383: i = 0; ! 384: while(Hdr.h_name[i] == '/') ! 385: i++; ! 386: strcpy(fullp, &(Hdr.h_name[i])); ! 387: ! 388: if(Link ! 389: && !A_directory ! 390: && Dev == Statb.st_dev) { ! 391: /* ??? && (Uid == Statb.st_uid || !Uid)) {*/ ! 392: if(link(Hdr.h_name, Fullname) < 0) { /* missing dir.? */ ! 393: if(errno == EEXIST) ! 394: fprintf(stderr, "Cannot link <%s> & <%s> (errno:%d)\n", ! 395: Hdr.h_name, Fullname, errno); ! 396: else { ! 397: unlink(Fullname); ! 398: missdir(Fullname); ! 399: if(link(Hdr.h_name, Fullname) < 0) { ! 400: fprintf(stderr, "Cannot link <%s> & <%s> (errno:%d)\n", Hdr.h_name, Fullname, errno); ! 401: continue; ! 402: } ! 403: } ! 404: } ! 405: ! 406: /* try creating (only twice) */ ! 407: ans = 0; ! 408: do { ! 409: if(link(Hdr.h_name, Fullname) < 0) { /* missing dir.? */ ! 410: if(errno == EEXIST) { ! 411: ans = 3; ! 412: break; ! 413: } ! 414: else ! 415: unlink(Fullname); ! 416: ans += 1; ! 417: }else { ! 418: ans = 0; ! 419: break; ! 420: } ! 421: }while(ans < 2 && missdir(Fullname) == 0); ! 422: if(ans == 1) { ! 423: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", Fullname, errno); ! 424: exit(0); ! 425: }else if(ans == 2) { ! 426: fprintf(stderr,"Cannot link <%s> & <%s> (errno:%d)\n", Hdr.h_name, Fullname, errno); ! 427: exit(0); ! 428: } ! 429: ! 430: if(!Link) ! 431: if(chmod(Hdr.h_name, Hdr.h_mode) < 0) { ! 432: fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Hdr.h_name, errno); ! 433: } ! 434: set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); ! 435: goto ckverbose; ! 436: } ! 437: #ifdef RT ! 438: if (One_extent || Multi_extent) ! 439: actsize(0); ! 440: #endif ! 441: if(!(Ofile = openout(Fullname))) ! 442: continue; ! 443: if((Ifile = open(Hdr.h_name, 0)) < 0) { ! 444: fprintf(stderr,"<%s> ?\n", Hdr.h_name); ! 445: close(Ofile); ! 446: continue; ! 447: } ! 448: filesz = Statb.st_size; ! 449: for(; filesz > 0; filesz -= CPIOBSZ) { ! 450: ct = filesz>CPIOBSZ? CPIOBSZ: filesz; ! 451: if(read(Ifile, Buf, ct) < 0) { ! 452: fprintf(stderr,"Cannot read %s\n", Hdr.h_name); ! 453: break; ! 454: } ! 455: if(Ofile) ! 456: if(write(Ofile, Buf, ct) < 0) { ! 457: fprintf(stderr,"Cannot write %s\n", Hdr.h_name); ! 458: break; ! 459: } ! 460: #ifndef u370 ! 461: Blocks += ((ct + (BUFSIZE - 1)) / BUFSIZE); ! 462: #else ! 463: ++Blocks; ! 464: #endif ! 465: } ! 466: close(Ifile); ! 467: if(Acc_time) ! 468: utime(Hdr.h_name, &Statb.st_atime); ! 469: if(Ofile) { ! 470: close(Ofile); ! 471: if(chmod(Fullname, Hdr.h_mode) < 0) { ! 472: fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Fullname, errno); ! 473: } ! 474: set_time(Fullname, Statb.st_atime, mklong(Hdr.h_mtime)); ! 475: ckverbose: ! 476: if(Verbose) ! 477: puts(Fullname); ! 478: } ! 479: } ! 480: } ! 481: /* print number of blocks actually copied */ ! 482: fprintf(stderr,"%ld blocks\n", Blocks * (Bufsize>>9)); ! 483: exit(0); ! 484: } ! 485: usage() ! 486: { ! 487: fprintf(stderr,"Usage: cpio -o[acvB] <name-list >collection\n%s\n%s\n", ! 488: " cpio -i[cdmrstuvfB6] [pattern ...] <collection", ! 489: " cpio -p[adlmruv] directory <name-list"); ! 490: exit(2); ! 491: } ! 492: ! 493: getname() /* get file name, get info for header */ ! 494: { ! 495: register char *namep = Name; ! 496: register unsigned short ftype; ! 497: long tlong; ! 498: ! 499: for(;;) { ! 500: if(gets(namep) == NULL) ! 501: return 0; ! 502: if(*namep == '.' && namep[1] == '/') { ! 503: namep++; ! 504: while(*namep == '/') namep++; ! 505: } ! 506: strcpy(Hdr.h_name, namep); ! 507: if(stat(namep, &Statb) < 0) { ! 508: fprintf(stderr,"< %s > ?\n", Hdr.h_name); ! 509: continue; ! 510: } ! 511: ftype = Statb.st_mode & Filetype; ! 512: A_directory = (ftype == S_IFDIR); ! 513: A_special = (ftype == S_IFBLK) ! 514: || (ftype == S_IFCHR) ! 515: #ifdef UX3 ! 516: || (ftype == S_IFIFO) ! 517: #endif ! 518: ; ! 519: #ifdef RT ! 520: A_special |= (ftype == S_IFREC); ! 521: One_extent = (ftype == S_IF1EXT); ! 522: Multi_extent = (ftype == S_IFEXT); ! 523: #endif ! 524: Hdr.h_magic = MAGIC; ! 525: Hdr.h_namesize = strlen(Hdr.h_name) + 1; ! 526: Hdr.h_uid = Statb.st_uid; ! 527: Hdr.h_gid = Statb.st_gid; ! 528: Hdr.h_dev = Statb.st_dev; ! 529: Hdr.h_ino = Statb.st_ino; ! 530: Hdr.h_mode = Statb.st_mode; ! 531: MKSHORT(Hdr.h_mtime, Statb.st_mtime); ! 532: Hdr.h_nlink = Statb.st_nlink; ! 533: tlong = (Hdr.h_mode&S_IFMT) == S_IFREG? Statb.st_size: 0L; ! 534: #ifdef RT ! 535: if (One_extent || Multi_extent) tlong = Statb.st_size; ! 536: #endif ! 537: MKSHORT(Hdr.h_filesize, tlong); ! 538: Hdr.h_rdev = Statb.st_rdev; ! 539: if( Cflag ) ! 540: bintochar(tlong); ! 541: return 1; ! 542: } ! 543: } ! 544: ! 545: bintochar(t) /* ASCII header write */ ! 546: long t; ! 547: { ! 548: sprintf(Chdr,"%.6o%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.11lo%.6ho%.11lo%s", ! 549: MAGIC,Statb.st_dev,Statb.st_ino,Statb.st_mode, ! 550: Statb.st_uid & 00000177777, Statb.st_gid & 00000177777, ! 551: Statb.st_nlink,Statb.st_rdev & 00000177777, ! 552: Statb.st_mtime,(short)strlen(Hdr.h_name)+1,t,Hdr.h_name); ! 553: } ! 554: ! 555: chartobin() /* ASCII header read */ ! 556: { ! 557: sscanf(Chdr,"%6ho%6ho%6ho%6ho%6ho%6ho%6ho%6ho%11lo%6ho%11lo", ! 558: &Hdr.h_magic,&Hdr.h_dev,&Hdr.h_ino,&Hdr.h_mode,&Hdr.h_uid, ! 559: &Hdr.h_gid,&Hdr.h_nlink,&Hdr.h_rdev,&Longtime,&Hdr.h_namesize, ! 560: &Longfile); ! 561: MKSHORT(Hdr.h_filesize, Longfile); ! 562: MKSHORT(Hdr.h_mtime, Longtime); ! 563: } ! 564: ! 565: gethdr() /* get file headers */ ! 566: { ! 567: register unsigned short ftype; ! 568: ! 569: if (Cflag) { ! 570: readhdr(Chdr,CHARS); ! 571: chartobin(); ! 572: } ! 573: else ! 574: bread(&Hdr, HDRSIZE); ! 575: ! 576: if(Hdr.h_magic != MAGIC) { ! 577: fprintf(stderr,"Out of phase--get help\n"); ! 578: fprintf(stderr,"Perhaps the \"-c\" option should be used\n"); ! 579: exit(2); ! 580: } ! 581: if(Cflag) ! 582: readhdr(Hdr.h_name, Hdr.h_namesize); ! 583: else ! 584: bread(Hdr.h_name, Hdr.h_namesize); ! 585: if(EQ(Hdr.h_name, "TRAILER!!!")) ! 586: return 0; ! 587: ftype = Hdr.h_mode & Filetype; ! 588: A_directory = (ftype == S_IFDIR); ! 589: A_special =(ftype == S_IFBLK) ! 590: || (ftype == S_IFCHR) ! 591: #ifdef UX3 ! 592: || (ftype == S_IFIFO) ! 593: #endif ! 594: ; ! 595: #ifdef RT ! 596: A_special |= (ftype == S_IFREC); ! 597: One_extent = (ftype == S_IF1EXT); ! 598: Multi_extent = (ftype == S_IFEXT); ! 599: if (One_extent || Multi_extent) { ! 600: Actual_size[0] = Hdr.h_filesize[0]; ! 601: Actual_size[1] = Hdr.h_filesize[1]; ! 602: if (Cflag) { ! 603: readhdr(Chdr,CHARS); ! 604: chartobin(); ! 605: } ! 606: else ! 607: bread(&Hdr, HDRSIZE); ! 608: ! 609: if(Hdr.h_magic != MAGIC) { ! 610: fprintf(stderr,"Out of phase--get RT help\n"); ! 611: fprintf(stderr,"Perhaps the \"-c\" option should be used\n"); ! 612: exit(2); ! 613: } ! 614: if(Cflag) ! 615: readhdr(Hdr.h_name, Hdr.h_namesize); ! 616: else ! 617: bread(Hdr.h_name, Hdr.h_namesize); ! 618: } ! 619: #endif ! 620: return 1; ! 621: } ! 622: ! 623: ckname(namep) /* check filenames with patterns given on cmd line */ ! 624: register char *namep; ! 625: { ! 626: ++Select; ! 627: if(fflag ^ !nmatch(namep, Pattern)) { ! 628: Select = 0; ! 629: return 0; ! 630: } ! 631: if(Rename && !A_directory) { /* rename interactively */ ! 632: fprintf(Wtty, "Rename <%s>\n", namep); ! 633: fflush(Wtty); ! 634: fgets(namep, 128, Rtty); ! 635: if(feof(Rtty)) ! 636: exit(2); ! 637: namep[strlen(namep) - 1] = '\0'; ! 638: if(EQ(namep, "")) { ! 639: printf("Skipped\n"); ! 640: return 0; ! 641: } ! 642: } ! 643: return !Toc; ! 644: } ! 645: ! 646: openout(namep) /* open files for writing, set all necessary info */ ! 647: register char *namep; ! 648: { ! 649: register f; ! 650: register char *np; ! 651: int ans; ! 652: ! 653: if(!strncmp(namep, "./", 2)) ! 654: namep += 2; ! 655: fixname(namep); ! 656: np = namep; ! 657: /* ! 658: if(Option == IN) ! 659: Cd_name = namep = cd(namep); ! 660: */ ! 661: if(A_directory) { ! 662: if(!Dir ! 663: || Rename ! 664: || EQ(namep, ".") ! 665: || EQ(namep, "..")) /* do not consider . or .. files */ ! 666: return 0; ! 667: if(stat(namep, &Xstatb) == -1) { ! 668: ! 669: /* try creating (only twice) */ ! 670: ans = 0; ! 671: do { ! 672: if(makdir(namep) != 0) { ! 673: ans += 1; ! 674: }else { ! 675: ans = 0; ! 676: break; ! 677: } ! 678: }while(ans < 2 && missdir(namep) == 0); ! 679: if(ans == 1) { ! 680: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno); ! 681: return(0); ! 682: }else if(ans == 2) { ! 683: fprintf(stderr,"Cannot create directory <%s> (errno:%d)\n", namep, errno); ! 684: return(0); ! 685: } ! 686: } ! 687: ! 688: ret: ! 689: if(chmod(namep, Hdr.h_mode) < 0) { ! 690: fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", namep, errno); ! 691: } ! 692: if(Uid == 0) ! 693: if(chown(namep, Hdr.h_uid, Hdr.h_gid) < 0) { ! 694: fprintf(stderr,"Cannot chown <%s> (errno:%d)\n", namep, errno); ! 695: } ! 696: set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); ! 697: return 0; ! 698: } ! 699: if(Hdr.h_nlink > 1) ! 700: if(!postml(namep, np)) ! 701: return 0; ! 702: if(stat(namep, &Xstatb) == 0) { ! 703: if(Uncond && !((!(Xstatb.st_mode & S_IWRITE) || A_special) && (Uid != 0))) { ! 704: if(unlink(namep) < 0) { ! 705: fprintf(stderr,"cannot unlink current <%s> (errno:%d)\n", namep, errno); ! 706: } ! 707: } ! 708: if(!Uncond && (mklong(Hdr.h_mtime) <= Xstatb.st_mtime)) { ! 709: /* There's a newer version of file on destination */ ! 710: if(mklong(Hdr.h_mtime) < Xstatb.st_mtime) ! 711: fprintf(stderr,"current <%s> newer\n", np); ! 712: return 0; ! 713: } ! 714: } ! 715: if(Option == PASS ! 716: && Hdr.h_ino == Xstatb.st_ino ! 717: && Hdr.h_dev == Xstatb.st_dev) { ! 718: fprintf(stderr,"Attempt to pass file to self!\n"); ! 719: exit(2); ! 720: } ! 721: if(A_special) { ! 722: #ifdef UX3 ! 723: if((Hdr.h_mode & Filetype) == S_IFIFO) ! 724: Hdr.h_rdev = 0; ! 725: #endif ! 726: ! 727: /* try creating (only twice) */ ! 728: ans = 0; ! 729: do { ! 730: if(mknod(namep, Hdr.h_mode, Hdr.h_rdev) < 0) { ! 731: ans += 1; ! 732: }else { ! 733: ans = 0; ! 734: break; ! 735: } ! 736: }while(ans < 2 && missdir(np) == 0); ! 737: if(ans == 1) { ! 738: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno); ! 739: return(0); ! 740: }else if(ans == 2) { ! 741: fprintf(stderr,"Cannot mknod <%s> (errno:%d)\n", namep, errno); ! 742: return(0); ! 743: } ! 744: ! 745: goto ret; ! 746: } ! 747: #ifdef RT ! 748: if(One_extent || Multi_extent) { ! 749: ! 750: /* try creating (only twice) */ ! 751: ans = 0; ! 752: do { ! 753: if((f = falloc(namep, Hdr.h_mode, longword(Hdr.h_filesize[0]))) < 0) { ! 754: ans += 1; ! 755: }else { ! 756: ans = 0; ! 757: break; ! 758: } ! 759: }while(ans < 2 && missdir(np) == 0); ! 760: if(ans == 1) { ! 761: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno); ! 762: return(0); ! 763: }else if(ans == 2) { ! 764: fprintf(stderr,"Cannot create <%s> (errno:%d)\n", namep, errno); ! 765: return(0); ! 766: } ! 767: ! 768: if(filespace < longword(Hdr.h_filesize[0])){ ! 769: fprintf(stderr,"Cannot create contiguous file <%s> proper size\n", namep); ! 770: fprintf(stderr," <%s> will be created as a regular file\n", namep); ! 771: if(unlink(Fullname) != 0) ! 772: fprintf(stderr,"<%s> not removed\n", namep); ! 773: Hdr.h_mode = (Hdr.h_mode & !S_IFMT) | S_IFREG; ! 774: One_extent = Multi_extent = 0; ! 775: } ! 776: Hdr.h_filesize[0] = Actual_size[0]; ! 777: Hdr.h_filesize[1] = Actual_size[1]; ! 778: } ! 779: if (!(One_extent || Multi_extent)) { ! 780: #endif ! 781: ! 782: /* try creating (only twice) */ ! 783: ans = 0; ! 784: do { ! 785: if((f = creat(namep, ~usrmask)) < 0) { ! 786: ans += 1; ! 787: }else { ! 788: ans = 0; ! 789: break; ! 790: } ! 791: }while(ans < 2 && missdir(np) == 0); ! 792: if(ans == 1) { ! 793: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno); ! 794: return(0); ! 795: }else if(ans == 2) { ! 796: fprintf(stderr,"Cannot create <%s> (errno:%d)\n", namep, errno); ! 797: return(0); ! 798: } ! 799: ! 800: #ifdef RT ! 801: } ! 802: #endif ! 803: if(Uid == 0) ! 804: chown(namep, Hdr.h_uid, Hdr.h_gid); ! 805: return f; ! 806: } ! 807: ! 808: bread(b, c) ! 809: register c; ! 810: register short *b; ! 811: { ! 812: static nleft = 0; ! 813: static short *ip; ! 814: register int rv; ! 815: register short *p = ip; ! 816: register int in; ! 817: ! 818: c = (c+1)>>1; ! 819: while(c--) { ! 820: if(nleft == 0) { ! 821: in = 0; ! 822: while((rv=read(Input, &(((char *)Dbuf)[in]), Bufsize - in)) != Bufsize - in) { ! 823: if(rv <= 0) { ! 824: Input = chgreel(0, Input); ! 825: continue; ! 826: } ! 827: in += rv; ! 828: nleft += (rv >> 1); ! 829: } ! 830: nleft += (rv >> 1); ! 831: p = Dbuf; ! 832: ++Blocks; ! 833: } ! 834: *b++ = *p++; ! 835: --nleft; ! 836: } ! 837: ip = p; ! 838: } ! 839: ! 840: readhdr(b, c) ! 841: register c; ! 842: register char *b; ! 843: { ! 844: static nleft = 0; ! 845: static char *ip; ! 846: register int rv; ! 847: register char *p = ip; ! 848: register int in; ! 849: ! 850: while(c--) { ! 851: if(nleft == 0) { ! 852: in = 0; ! 853: while((rv=read(Input, &(((char *)Cbuf)[in]), Bufsize - in)) != Bufsize - in) { ! 854: if(rv <= 0) { ! 855: Input = chgreel(0, Input); ! 856: continue; ! 857: } ! 858: in += rv; ! 859: nleft += rv; ! 860: } ! 861: nleft += rv; ! 862: p = Cbuf; ! 863: ++Blocks; ! 864: } ! 865: *b++ = *p++; ! 866: --nleft; ! 867: } ! 868: ip = p; ! 869: } ! 870: ! 871: bwrite(rp, c) ! 872: register short *rp; ! 873: register c; ! 874: { ! 875: register short *wp = Wp; ! 876: ! 877: c = (c+1) >> 1; ! 878: while(c--) { ! 879: if(!Wct) { ! 880: again: ! 881: if(write(Output, Dbuf, Bufsize)<0) { ! 882: Output = chgreel(1, Output); ! 883: goto again; ! 884: } ! 885: Wct = Bufsize >> 1; ! 886: wp = Dbuf; ! 887: ++Blocks; ! 888: } ! 889: *wp++ = *rp++; ! 890: --Wct; ! 891: } ! 892: Wp = wp; ! 893: } ! 894: ! 895: writehdr(rp, c) ! 896: register char *rp; ! 897: register c; ! 898: { ! 899: register char *cp = Cp; ! 900: ! 901: while(c--) { ! 902: if(!Wc) { ! 903: again: ! 904: if(write(Output,Cbuf,Bufsize)<0) { ! 905: Output = chgreel(1,Output); ! 906: goto again; ! 907: } ! 908: Wc = Bufsize; ! 909: cp = Cbuf; ! 910: ++Blocks; ! 911: } ! 912: *cp++ = *rp++; ! 913: --Wc; ! 914: } ! 915: Cp = cp; ! 916: } ! 917: ! 918: postml(namep, np) /* linking funtion */ ! 919: register char *namep, *np; ! 920: { ! 921: register i; ! 922: static struct ml { ! 923: short m_dev, ! 924: m_ino; ! 925: char m_name[2]; ! 926: } *ml[LINKS]; ! 927: static mlinks = 0; ! 928: char *mlp; ! 929: int ans; ! 930: ! 931: for(i = 0; i < mlinks; ++i) { ! 932: if(mlinks == LINKS) break; ! 933: if(ml[i]->m_ino==Hdr.h_ino && ! 934: ml[i]->m_dev==Hdr.h_dev) { ! 935: if(Verbose) ! 936: printf("%s linked to %s\n", ml[i]->m_name, ! 937: np); ! 938: unlink(namep); ! 939: if(Option == IN && *ml[i]->m_name != '/') { ! 940: Fullname[Pathend] = '\0'; ! 941: strcat(Fullname, ml[i]->m_name); ! 942: mlp = Fullname; ! 943: } ! 944: mlp = ml[i]->m_name; ! 945: ! 946: /* try linking (only twice) */ ! 947: ans = 0; ! 948: do { ! 949: if(link(mlp, namep) < 0) { ! 950: ans += 1; ! 951: }else { ! 952: ans = 0; ! 953: break; ! 954: } ! 955: }while(ans < 2 && missdir(np) == 0); ! 956: if(ans == 1) { ! 957: fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", np, errno); ! 958: return(0); ! 959: }else if(ans == 2) { ! 960: fprintf(stderr,"Cannot link <%s> & <%s> (errno:%d)\n", ml[i]->m_name, np, errno); ! 961: return(0); ! 962: } ! 963: ! 964: set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); ! 965: return 0; ! 966: } ! 967: } ! 968: if(mlinks == LINKS ! 969: || !(ml[mlinks] = (struct ml *)malloc(strlen(np) + 2 + sizeof(struct ml)))) { ! 970: static int first=1; ! 971: ! 972: if(first) ! 973: if(mlinks == LINKS) ! 974: fprintf(stderr,"Too many links\n"); ! 975: else ! 976: fprintf(stderr,"No memory for links\n"); ! 977: mlinks = LINKS; ! 978: first = 0; ! 979: return 1; ! 980: } ! 981: ml[mlinks]->m_dev = Hdr.h_dev; ! 982: ml[mlinks]->m_ino = Hdr.h_ino; ! 983: strcpy(ml[mlinks]->m_name, np); ! 984: ++mlinks; ! 985: return 1; ! 986: } ! 987: ! 988: pentry(namep) /* print verbose table of contents */ ! 989: register char *namep; ! 990: { ! 991: ! 992: static short lastid = -1; ! 993: #include <pwd.h> ! 994: static struct passwd *pw; ! 995: struct passwd *getpwuid(); ! 996: static char tbuf[32]; ! 997: char *ctime(); ! 998: ! 999: printf("%-7o", Hdr.h_mode & 0177777); ! 1000: if(lastid == Hdr.h_uid) ! 1001: printf("%-6s", pw->pw_name); ! 1002: else { ! 1003: setpwent(); ! 1004: if(pw = getpwuid((int)Hdr.h_uid)) { ! 1005: printf("%-6s", pw->pw_name); ! 1006: lastid = Hdr.h_uid; ! 1007: } else { ! 1008: printf("%-6d", Hdr.h_uid); ! 1009: lastid = -1; ! 1010: } ! 1011: } ! 1012: printf("%7ld ", mklong(Hdr.h_filesize)); ! 1013: U.l = mklong(Hdr.h_mtime); ! 1014: strcpy(tbuf, ctime((long *)&U.l)); ! 1015: tbuf[24] = '\0'; ! 1016: printf(" %s %s\n", &tbuf[4], namep); ! 1017: } ! 1018: ! 1019: /* pattern matching functions */ ! 1020: nmatch(s, pat) ! 1021: char *s, **pat; ! 1022: { ! 1023: if(EQ(*pat, "*")) ! 1024: return 1; ! 1025: while(*pat) { ! 1026: if((**pat == '!' && !gmatch(s, *pat+1)) ! 1027: || gmatch(s, *pat)) ! 1028: return 1; ! 1029: ++pat; ! 1030: } ! 1031: return 0; ! 1032: } ! 1033: gmatch(s, p) ! 1034: register char *s, *p; ! 1035: { ! 1036: register int c; ! 1037: register cc, ok, lc, scc; ! 1038: ! 1039: scc = *s; ! 1040: lc = 077777; ! 1041: switch (c = *p) { ! 1042: ! 1043: case '[': ! 1044: ok = 0; ! 1045: while (cc = *++p) { ! 1046: switch (cc) { ! 1047: ! 1048: case ']': ! 1049: if (ok) ! 1050: return(gmatch(++s, ++p)); ! 1051: else ! 1052: return(0); ! 1053: ! 1054: case '-': ! 1055: ok |= ((lc <= scc) && (scc <= (cc=p[1]))); ! 1056: } ! 1057: if (scc==(lc=cc)) ok++; ! 1058: } ! 1059: return(0); ! 1060: ! 1061: case '?': ! 1062: caseq: ! 1063: if(scc) return(gmatch(++s, ++p)); ! 1064: return(0); ! 1065: case '*': ! 1066: return(umatch(s, ++p)); ! 1067: case 0: ! 1068: return(!scc); ! 1069: } ! 1070: if (c==scc) goto caseq; ! 1071: return(0); ! 1072: } ! 1073: ! 1074: umatch(s, p) ! 1075: register char *s, *p; ! 1076: { ! 1077: if(*p==0) return(1); ! 1078: while(*s) ! 1079: if (gmatch(s++,p)) return(1); ! 1080: return(0); ! 1081: } ! 1082: ! 1083: makdir(namep) /* make needed directories */ ! 1084: register char *namep; ! 1085: { ! 1086: static status; ! 1087: register pid; ! 1088: ! 1089: if(pid = fork()) ! 1090: while(wait(&status) != pid); ! 1091: else if(pid == -1) { ! 1092: fprintf(stderr,"Cannot fork, try again\n"); ! 1093: exit(2); ! 1094: } ! 1095: else { ! 1096: close(2); ! 1097: execl("/bin/mkdir", "mkdir", namep, 0); ! 1098: exit(2); ! 1099: } ! 1100: return ((status>>8) & 0377)? 1: 0; ! 1101: } ! 1102: ! 1103: swap(buf, ct) /* swap halfwords, bytes or both */ ! 1104: register ct; ! 1105: register char *buf; ! 1106: { ! 1107: register char c; ! 1108: register union swp { long longw; short shortv[2]; char charv[4]; } *pbuf; ! 1109: int savect, n, i; ! 1110: char *savebuf; ! 1111: short cc; ! 1112: ! 1113: savect = ct; savebuf = buf; ! 1114: if(byteswap || bothswap) { ! 1115: if (ct % 2) buf[ct] = 0; ! 1116: ct = (ct + 1) / 2; ! 1117: while (ct--) { ! 1118: c = *buf; ! 1119: *buf = *(buf + 1); ! 1120: *(buf + 1) = c; ! 1121: buf += 2; ! 1122: } ! 1123: if (bothswap) { ! 1124: ct = savect; ! 1125: pbuf = (union swp *)savebuf; ! 1126: if (n = ct % sizeof(union swp)) { ! 1127: if(n % 2) ! 1128: for(i = ct + 1; i <= ct + (sizeof(union swp) - n); i++) pbuf->charv[i] = 0; ! 1129: else ! 1130: for (i = ct; i < ct + (sizeof(union swp) - n); i++) pbuf->charv[i] = 0; ! 1131: } ! 1132: ct = (ct + (sizeof(union swp) -1)) / sizeof(union swp); ! 1133: while(ct--) { ! 1134: cc = pbuf->shortv[0]; ! 1135: pbuf->shortv[0] = pbuf->shortv[1]; ! 1136: pbuf->shortv[1] = cc; ! 1137: ++pbuf; ! 1138: } ! 1139: } ! 1140: } ! 1141: else if (halfswap) { ! 1142: pbuf = (union swp *)buf; ! 1143: if (n = ct % sizeof(union swp)) ! 1144: for (i = ct; i < ct + (sizeof(union swp) - n); i++) pbuf->charv[i] = 0; ! 1145: ct = (ct + (sizeof(union swp) -1)) / sizeof(union swp); ! 1146: while (ct--) { ! 1147: cc = pbuf->shortv[0]; ! 1148: pbuf->shortv[0] = pbuf->shortv[1]; ! 1149: pbuf->shortv[1] = cc; ! 1150: ++pbuf; ! 1151: } ! 1152: } ! 1153: } ! 1154: set_time(namep, atime, mtime) /* set access and modification times */ ! 1155: register *namep; ! 1156: long atime, mtime; ! 1157: { ! 1158: static long timevec[2]; ! 1159: ! 1160: if(!Mod_time) ! 1161: return; ! 1162: timevec[0] = atime; ! 1163: timevec[1] = mtime; ! 1164: utime(namep, timevec); ! 1165: } ! 1166: chgreel(x, fl) ! 1167: { ! 1168: register f; ! 1169: char str[22]; ! 1170: FILE *devtty; ! 1171: struct stat statb; ! 1172: ! 1173: fprintf(stderr,"errno: %d, ", errno); ! 1174: fprintf(stderr,"Can't %s\n", x? "write output": "read input"); ! 1175: fstat(fl, &statb); ! 1176: #ifndef RT ! 1177: if((statb.st_mode&S_IFMT) != S_IFCHR) ! 1178: exit(2); ! 1179: #else ! 1180: if((statb.st_mode & (S_IFBLK|S_IFREC))==0) ! 1181: exit(2); ! 1182: #endif ! 1183: again: ! 1184: fprintf(stderr,"If you want to go on, type device/file name when ready\n"); ! 1185: devtty = fopen("/dev/tty", "r"); ! 1186: fgets(str, 20, devtty); ! 1187: str[strlen(str) - 1] = '\0'; ! 1188: if(!*str) ! 1189: exit(2); ! 1190: close(fl); ! 1191: if((f = open(str, x? 1: 0)) < 0) { ! 1192: fprintf(stderr,"That didn't work"); ! 1193: fclose(devtty); ! 1194: goto again; ! 1195: } ! 1196: fclose(devtty); ! 1197: return f; ! 1198: } ! 1199: missdir(namep) ! 1200: register char *namep; ! 1201: { ! 1202: register char *np; ! 1203: register ct = 2; ! 1204: ! 1205: for(np = namep; *np; ++np) ! 1206: if(*np == '/') { ! 1207: if(np == namep) continue; /* skip over 'root slash' */ ! 1208: *np = '\0'; ! 1209: if(stat(namep, &Xstatb) == -1) { ! 1210: if(Dir) { ! 1211: if((ct = makdir(namep)) != 0) { ! 1212: *np = '/'; ! 1213: return(ct); ! 1214: } ! 1215: }else { ! 1216: fprintf(stderr,"missing 'd' option\n"); ! 1217: return(-1); ! 1218: } ! 1219: } ! 1220: *np = '/'; ! 1221: } ! 1222: if (ct == 2) ct = 0; /* the file already exists */ ! 1223: return ct; ! 1224: } ! 1225: ! 1226: pwd() /* get working directory */ ! 1227: { ! 1228: FILE *dir; ! 1229: ! 1230: dir = popen("pwd", "r"); ! 1231: fgets(Fullname, 256, dir); ! 1232: if(pclose(dir)) ! 1233: exit(2); ! 1234: Pathend = strlen(Fullname); ! 1235: Fullname[Pathend - 1] = '/'; ! 1236: } ! 1237: char * cd(n) /* change directories */ ! 1238: register char *n; ! 1239: { ! 1240: char *p_save = Name, *n_save = n, *p_end = 0; ! 1241: register char *p = Name; ! 1242: static char dotdot[]="../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../"; ! 1243: int slashes, ans; ! 1244: ! 1245: if(*n == '/') /* don't try to chdir on full pathnames */ ! 1246: return n; ! 1247: for(; *p && *n == *p; ++p, ++n) { /* whatever part of strings == */ ! 1248: if(*p == '/') ! 1249: p_save = p+1, n_save = n+1; ! 1250: } ! 1251: ! 1252: p = p_save; ! 1253: *p++ = '\0'; ! 1254: for(slashes = 0; *p; ++p) { /* if prev is longer, chdir("..") */ ! 1255: if(*p == '/') ! 1256: ++slashes; ! 1257: } ! 1258: p = p_save; ! 1259: if(slashes) { ! 1260: slashes = slashes * 3 - 1; ! 1261: dotdot[slashes] = '\0'; ! 1262: chdir(dotdot); ! 1263: dotdot[slashes] = '/'; ! 1264: } ! 1265: ! 1266: n = n_save; ! 1267: for(; *n; ++n, ++p) { ! 1268: *p = *n; ! 1269: if(*n == '/') ! 1270: p_end = p+1, n_save = n+1; ! 1271: } ! 1272: *p = '\0'; ! 1273: ! 1274: if(p_end) { ! 1275: *p_end = '\0'; ! 1276: if(chdir(p_save) == -1) { ! 1277: if((ans = missdir(p_save)) == -1) { ! 1278: fprintf(stderr,"Cannot chdir (no `d' option)\n"); ! 1279: exit(2); ! 1280: } else if (ans > 0) { ! 1281: fprintf(stderr,"Cannot chdir - no write permission\n"); ! 1282: exit(2); ! 1283: } else if(chdir(p_save) == -1) { ! 1284: fprintf(stderr,"Cannot chdir\n"); ! 1285: exit(2); ! 1286: } ! 1287: } ! 1288: } else ! 1289: *p_save = '\0'; ! 1290: return n_save; ! 1291: } ! 1292: #ifdef RT ! 1293: actsize(file) ! 1294: register int file; ! 1295: { ! 1296: long tlong; ! 1297: long fsize(); ! 1298: register int tfile; ! 1299: ! 1300: Actual_size[0] = Hdr.h_filesize[0]; ! 1301: Actual_size[1] = Hdr.h_filesize[1]; ! 1302: if (!Extent) ! 1303: return; ! 1304: if (file) ! 1305: tfile = file; ! 1306: else if ((tfile = open(Hdr.h_name,0)) < 0) ! 1307: return; ! 1308: tlong = fsize(tfile); ! 1309: MKSHORT(Hdr.h_filesize,tlong); ! 1310: if (Cflag) ! 1311: bintochar(tlong); ! 1312: if (!file) ! 1313: close(tfile); ! 1314: } ! 1315: #endif ! 1316: ! 1317: #ifdef MAXFILENAME ! 1318: FILE *longnamefd; ! 1319: ! 1320: affix(n,ptr) ! 1321: int n; ! 1322: char *ptr; ! 1323: { ! 1324: int i=0,m; ! 1325: char ext[5]; ! 1326: ! 1327: while(1) { ! 1328: if((m=n%52)<26) ext[i++] = m + 'a'; ! 1329: else ext[i++] = m + 'A' - 26; ! 1330: if(n < 52)break; ! 1331: n = n/52 - 1; /* so we have Z,aa not Z,ba */ ! 1332: } ! 1333: ! 1334: while(--i >= 0)*ptr++ = ext[i]; ! 1335: *ptr = '\0'; ! 1336: } ! 1337: ! 1338: #define MAXOVER 1000 ! 1339: struct { ! 1340: char *longname, ! 1341: *shortname; ! 1342: } pairs[MAXOVER]; ! 1343: int npairs = 0; /* no. of tabulated pairs */ ! 1344: ! 1345: int ntoolong = 0; /* no. of overlong pathnames */ ! 1346: ! 1347: char * ! 1348: findname(key) ! 1349: char *key; ! 1350: { ! 1351: int i, nprevious = 0, nprefix; ! 1352: char *longptr, *shortptr, *malloc(), *endbit, *strrchr(); ! 1353: ! 1354: endbit = strrchr(key,'/'); ! 1355: if(endbit == 0)endbit = key; ! 1356: else endbit++; ! 1357: nprefix = endbit - key; ! 1358: ! 1359: for(i=0;i<npairs;i++){ ! 1360: if(strcmp(key,pairs[i].longname) == 0) ! 1361: return(pairs[i].shortname); ! 1362: if(strncmp(key,pairs[i].longname,nprefix+MAXFILENAME-4) == 0) ! 1363: nprevious++; ! 1364: } ! 1365: longptr = pairs[npairs].longname = malloc(strlen(key)+1); ! 1366: shortptr = pairs[npairs].shortname = malloc(MAXFILENAME+1); ! 1367: strcpy(longptr,key); ! 1368: strncpy(shortptr,endbit,MAXFILENAME-4); ! 1369: sprintf(shortptr+MAXFILENAME-4,".."); ! 1370: affix(nprevious,shortptr+MAXFILENAME-2); ! 1371: npairs++; ! 1372: return(shortptr); ! 1373: } ! 1374: ! 1375: fixname(original) ! 1376: char *original; ! 1377: { ! 1378: int length; ! 1379: char newname[100]; ! 1380: register char *inend, *outptr=newname, *instart=original, ! 1381: *outstart; ! 1382: int changed = 0; ! 1383: ! 1384: while(1){ ! 1385: if(*instart == '\0')break; ! 1386: if(*instart == '/')*outptr++ = *instart++; ! 1387: outstart = outptr; ! 1388: for(inend=instart;*inend != '\0' && *inend != '/';) ! 1389: *outptr++ = *inend++; ! 1390: *outptr = '\0'; ! 1391: length = strlen(outstart); ! 1392: if(length > MAXFILENAME){ ! 1393: changed++; ! 1394: strcpy(outstart,findname(newname)); ! 1395: } ! 1396: outptr = outstart + strlen(outstart); ! 1397: instart = inend; ! 1398: } ! 1399: ! 1400: if(changed){ ! 1401: if(ntoolong == 0) { ! 1402: longnamefd = fopen("longnamelist","w"); ! 1403: if(longnamefd == NULL){ ! 1404: fprintf(stderr, ! 1405: "can't create longnamelist file\n"); ! 1406: exit(1); ! 1407: } ! 1408: fprintf(stderr,"check out file 'longnamelist'\n"); ! 1409: } ! 1410: printf("%s changed to %s\n",original,newname); ! 1411: fprintf(longnamefd,"%s\t%s\n",original, newname); ! 1412: fflush(longnamefd); ! 1413: strcpy(original,newname); ! 1414: ntoolong++; ! 1415: } ! 1416: } ! 1417: #else /* MAXFILESIZE */ ! 1418: fixname(){} ! 1419: #else /* MAXFILESIZE */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.