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