|
|
1.1 ! root 1: /* Copyright (c) 1988 AT&T */ ! 2: /* All Rights Reserved */ ! 3: ! 4: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ ! 5: /* The copyright notice above does not evidence any */ ! 6: /* actual or intended publication of such source code. */ ! 7: ! 8: #ident "@(#)cpio:cpio.c 1.30.1.11" ! 9: /* /sccs/src/cmd/s.cpio.c ! 10: cpio.c 1.30.1.11 1/11/86 13:46:48 ! 11: Reworked cpio which uses getopt(3) to interpret flag arguments and ! 12: changes reels to the save file name. ! 13: Performance and size improvements. ! 14: */ ! 15: ! 16: /* cpio COMPILE: cc -O cpio.c -s -i -o cpio -lgen -lerr ! 17: cpio -- copy file collections ! 18: ! 19: */ ! 20: #include <errno.h> ! 21: #include <fcntl.h> ! 22: #include <memory.h> ! 23: #include <stdio.h> ! 24: #include <string.h> ! 25: #include <signal.h> ! 26: #include <varargs.h> ! 27: #include <sys/param.h> ! 28: #include <sys/types.h> ! 29: #include <sys/stat.h> ! 30: ! 31: struct utimbuf { ! 32: time_t actime; ! 33: time_t modtime; ! 34: }; ! 35: #ifndef S_IFIFO ! 36: #define S_IFIFO 010000 ! 37: #endif ! 38: ! 39: #define EQ(x,y) (strcmp(x,y)==0) ! 40: ! 41: /* MKSHORT: for VAX, Interdata, ... */ ! 42: /* Take a 4-byte long, lv, and turn it */ ! 43: /* into an array of two 2-byte shorts, v*/ ! 44: #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];} ! 45: ! 46: #define MAGIC 070707 /* cpio magic number */ ! 47: #define BSMAGIC 0143561 /* byte-swapped cpio magic number */ ! 48: #define IN 'i' /* copy in */ ! 49: #define OUT 'o' /* copy out */ ! 50: #define PASS 'p' /* direct copy */ ! 51: #define HDRSIZE (Hdr.h_name - (char *)&Hdr) /* header size minus filename field */ ! 52: #define LINKS 500 /* no. of links allocated per bunch */ ! 53: #define CHARS 76 /* ASCII header size minus filename field */ ! 54: #define BUFSIZE 512 /* In u370, can't use BUFSIZ or BSIZE */ ! 55: #define CPIOBSZ 4096 /* file read/write */ ! 56: #define MK_USHORT(a) (a & 00000177777) /* Make unsigned shorts for portable */ ! 57: /* header. Hardware may only know */ ! 58: /* integer operations and sign extend */ ! 59: /* the large unsigned short resulting */ ! 60: /* in 8 rather than 6 octal char in */ ! 61: /* the header. */ ! 62: ! 63: static struct stat Statb, Xstatb; ! 64: ! 65: /* Cpio header format */ ! 66: static struct header { ! 67: short h_magic; ! 68: short h_dev; ! 69: ushort h_ino; ! 70: ushort h_mode, ! 71: h_uid, ! 72: h_gid; ! 73: short h_nlink; ! 74: short h_rdev; ! 75: short h_mtime[2], ! 76: h_namesize, ! 77: h_filesize[2]; ! 78: char h_name[256]; ! 79: } Hdr; ! 80: ! 81: char Symlbuf[MAXPATHLEN + 1]; /* target of symbolic link */ ! 82: static unsigned Bufsize = BUFSIZE; /* default record size */ ! 83: static char Buf[CPIOBSZ], *Cbuf; ! 84: static char *Cp; ! 85: ! 86: ! 87: static ! 88: short Option, ! 89: Dir, ! 90: Uncond, ! 91: PassLink, ! 92: Rename, ! 93: Toc, ! 94: Verbose, ! 95: Mod_time, ! 96: Acc_time, ! 97: Cflag, ! 98: fflag, ! 99: Swap, ! 100: byteswap, ! 101: halfswap; ! 102: ! 103: static ! 104: int Ifile, ! 105: Ofile, ! 106: Input = 0, ! 107: Output = 1; ! 108: /* sBlocks: short Blocks. Cumulative character */ ! 109: /* count for short reads in bread(). Encountered */ ! 110: /* with communication lines and pipes as in: */ ! 111: /* split -100 cpio_archive; cat xa* | cpio -icd */ ! 112: static ! 113: long sBlocks, ! 114: Blocks, ! 115: Longfile, ! 116: Longtime; ! 117: ! 118: static ! 119: char Fullname[256], ! 120: Name[256]; ! 121: static ! 122: int Pathend; ! 123: static ! 124: char *swfile; ! 125: static ! 126: char *eommsg = "Change to part %d and press RETURN key. [q] "; ! 127: ! 128: static ! 129: FILE *Rtty, ! 130: *Wtty; ! 131: static ! 132: char ttyname[] = "/dev/tty"; ! 133: ! 134: static ! 135: char **Pattern = 0; ! 136: static ! 137: char Chdr[500]; ! 138: static ! 139: short Dev; ! 140: ushort Uid, ! 141: A_directory, ! 142: A_special, ! 143: A_symlink, ! 144: Filetype = S_IFMT; ! 145: ! 146: extern errno; ! 147: extern void exit(); ! 148: char *malloc(); ! 149: FILE *popen(); ! 150: ! 151: static char *smemcpy(); ! 152: ! 153: static ! 154: union { ! 155: long l; ! 156: short s[2]; ! 157: char c[4]; ! 158: } U; ! 159: ! 160: /* for VAX, Interdata, ... */ ! 161: static ! 162: long mklong(v) ! 163: short v[]; ! 164: { ! 165: U.l = 1; ! 166: if(U.c[0]) ! 167: U.s[0] = v[1], U.s[1] = v[0]; ! 168: else ! 169: U.s[0] = v[0], U.s[1] = v[1]; ! 170: return U.l; ! 171: } ! 172: ! 173: main(argc, argv) ! 174: char **argv; ! 175: { ! 176: register ct; ! 177: long filesz; ! 178: int symlsz; ! 179: register char *fullp; ! 180: register i; ! 181: int ans; ! 182: register char *symlinkp; ! 183: short select; /* set when files are selected */ ! 184: extern char *optarg; ! 185: extern int optind; ! 186: ! 187: signal(SIGSYS, SIG_IGN); ! 188: if(argc <= 1 || *argv[1] != '-') ! 189: usage(); ! 190: Uid = getuid(); ! 191: ! 192: while( (ans = getopt( argc, argv, "aBC:ifopcdlmrSsbtuvM:6eI:O:")) != EOF ) { ! 193: ! 194: switch( ans ) { ! 195: case 'a': /* reset access time */ ! 196: Acc_time++; ! 197: break; ! 198: case 'B': /* change record size to 5120 bytes */ ! 199: Bufsize = 5120; ! 200: break; ! 201: case 'C': /* reset buffer size to arbitrary valu ! 202: */ ! 203: Bufsize = atoi( optarg ); ! 204: if( Bufsize == 0 ) { ! 205: fperr("Illegal argument to -%c, '%s'", ! 206: ans, optarg ); ! 207: exit(2); ! 208: } ! 209: break; ! 210: case 'i': ! 211: Option = IN; ! 212: break; ! 213: case 'f': /* copy files not matched by patterns */ ! 214: fflag++; ! 215: break; ! 216: case 'o': ! 217: Option = OUT; ! 218: break; ! 219: case 'p': ! 220: Option = PASS; ! 221: break; ! 222: case 'c': /* ASCII header */ ! 223: Cflag++; ! 224: break; ! 225: case 'd': /* create directories when needed */ ! 226: Dir++; ! 227: break; ! 228: case 'l': /* link files, when necessary */ ! 229: PassLink++; ! 230: break; ! 231: case 'm': /* retain mod time */ ! 232: Mod_time++; ! 233: break; ! 234: case 'r': /* rename files interactively */ ! 235: Rename++; ! 236: Rtty = fopen(ttyname, "r"); ! 237: Wtty = fopen(ttyname, "w"); ! 238: if(Rtty==NULL || Wtty==NULL) { ! 239: fperrno("Cannot rename (%s missing)", ! 240: ttyname ); ! 241: exit(2); ! 242: } ! 243: break; ! 244: case 'S': /* swap halfwords */ ! 245: halfswap++; ! 246: Swap++; ! 247: break; ! 248: case 's': /* swap bytes */ ! 249: byteswap++; ! 250: Swap++; ! 251: break; ! 252: case 'b': /* swap both bytes and halfwords */ ! 253: halfswap++; ! 254: byteswap++; ! 255: Swap++; ! 256: break; ! 257: case 't': /* table of contents */ ! 258: Toc++; ! 259: break; ! 260: case 'u': /* copy unconditionally */ ! 261: Uncond++; ! 262: break; ! 263: case 'v': /* verbose - print out file names */ ! 264: Verbose++; ! 265: break; ! 266: case 'M': /* alternate message for end-of-media */ ! 267: eommsg = optarg; ! 268: break; ! 269: case '6': /* for old, sixth-edition files */ ! 270: Filetype = 060000; ! 271: break; ! 272: case 'I': ! 273: chkswfile( swfile, ans, Option ); ! 274: if( (i = open( optarg, O_RDONLY ) ) < 0) { ! 275: fperrno("Cannot open <%s> for input", optarg); ! 276: exit(2); ! 277: } ! 278: if( dup2(i, Input ) < 0 ) { ! 279: fperrno("Cannot dup to standard input"); ! 280: exit(2); ! 281: } ! 282: swfile = optarg; ! 283: break; ! 284: case 'O': ! 285: chkswfile( swfile, ans, Option ); ! 286: if( (i = open( optarg, O_WRONLY | O_CREAT | O_TRUNC, ! 287: 0666 ) ) < 0) { ! 288: fperrno("Cannot open <%s> for output", optarg); ! 289: exit(2); ! 290: } ! 291: if( dup2(i, Output ) < 0 ) { ! 292: fperrno("Cannot dup to standard output"); ! 293: exit(2); ! 294: } ! 295: swfile = optarg; ! 296: break; ! 297: default: ! 298: usage(); ! 299: } ! 300: } ! 301: if(!Option) { ! 302: (void) fprintf(stderr, ! 303: "Options must include one of -o, -i, or -p\n"); ! 304: exit(2); ! 305: } ! 306: ! 307: if(Option == PASS) { ! 308: if(Rename) { ! 309: (void) fprintf(stderr, ! 310: "Pass and Rename cannot be used together\n"); ! 311: exit(2); ! 312: } ! 313: if( Bufsize != BUFSIZE ) { ! 314: fprintf( stderr, "`B' or `C' option is irrelevant with the '-p' option\n"); ! 315: Bufsize = BUFSIZE; ! 316: } ! 317: ! 318: }else { ! 319: Cp = Cbuf = (char *)malloc(Bufsize); ! 320: if(Cp == NULL) { ! 321: perror("cpio"); ! 322: exit(2); ! 323: } ! 324: } ! 325: argc -= optind; ! 326: argv += optind; ! 327: ! 328: switch(Option) { ! 329: case OUT: ! 330: if(argc != 0) ! 331: usage(); ! 332: /* get filename, copy header and file out */ ! 333: while(getname()) { ! 334: if( mklong(Hdr.h_filesize) == 0L) { ! 335: if( Cflag ) ! 336: bwrite(Chdr,CHARS+Hdr.h_namesize); ! 337: else ! 338: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize); ! 339: if(Verbose) ! 340: (void) fprintf(stderr, "%s\n", ! 341: Hdr.h_name); ! 342: continue; ! 343: } else if( A_symlink ) { ! 344: symlsz = (int) mklong(Hdr.h_filesize); ! 345: if (readlink(Hdr.h_name, Symlbuf, symlsz) < 0) { ! 346: fperrno("Cannot read symbolic link <%s>", ! 347: Hdr.h_name); ! 348: continue; ! 349: } ! 350: Symlbuf[symlsz] = '\0'; ! 351: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize); ! 352: bwrite(Symlbuf, symlsz); ! 353: if(Verbose) ! 354: (void) fprintf(stderr, "%s\n", ! 355: Hdr.h_name); ! 356: continue; ! 357: } ! 358: if((Ifile = open(Hdr.h_name, 0)) < 0) { ! 359: fperrno("Cannot open <%s>", Hdr.h_name); ! 360: continue; ! 361: } ! 362: if ( Cflag ) ! 363: bwrite(Chdr,CHARS+Hdr.h_namesize); ! 364: else ! 365: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize); ! 366: for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){ ! 367: ct = filesz>CPIOBSZ? CPIOBSZ: filesz; ! 368: if(read(Ifile, Buf, ct) < 0) { ! 369: fperrno("Cannot read %s", Hdr.h_name); ! 370: continue; ! 371: } ! 372: bwrite(Buf,ct); ! 373: } ! 374: close(Ifile); ! 375: if(Acc_time) { ! 376: struct utimbuf utb; ! 377: ! 378: utb.actime = Statb.st_atime; ! 379: utb.modtime = Statb.st_mtime; ! 380: (void)utime(Hdr.h_name, &utb); ! 381: } ! 382: if(Verbose) ! 383: (void) fprintf(stderr, "%s\n", Hdr.h_name); ! 384: } ! 385: ! 386: /* copy trailer, after all files have been copied */ ! 387: strcpy(Hdr.h_name, "TRAILER!!!"); ! 388: Hdr.h_magic = MAGIC; ! 389: MKSHORT(Hdr.h_filesize, 0L); ! 390: Hdr.h_namesize = strlen("TRAILER!!!") + 1; ! 391: if ( Cflag ) { ! 392: bintochar(0L); ! 393: bwrite(Chdr, CHARS+Hdr.h_namesize); ! 394: } ! 395: else ! 396: bwrite(&Hdr, HDRSIZE+Hdr.h_namesize); ! 397: bwrite(Cbuf, Bufsize); ! 398: break; ! 399: ! 400: case IN: ! 401: if(argc > 0 ) { /* save patterns, if any */ ! 402: Pattern = argv; ! 403: } ! 404: pwd(); ! 405: chkhdr(); ! 406: while(gethdr()) { ! 407: if (A_symlink) { ! 408: symlsz = (int) mklong(Hdr.h_filesize); ! 409: bread(Symlbuf, symlsz); ! 410: Symlbuf[symlsz] = '\0'; ! 411: if( ckname(Hdr.h_name) && !Toc) ! 412: (void)openout(Hdr.h_name, Symlbuf); ! 413: } else { ! 414: if( (select = ckname(Hdr.h_name)) && !Toc ) ! 415: Ofile = openout(Hdr.h_name, (char *)0); ! 416: else ! 417: Ofile = 0; ! 418: for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){ ! 419: ct = filesz>CPIOBSZ? CPIOBSZ: filesz; ! 420: bread(Buf, ct); ! 421: if(Ofile) { ! 422: if(Swap) ! 423: swap(Buf,ct,byteswap,halfswap); ! 424: if(write(Ofile, Buf, ct) < 0) { ! 425: fperrno("Cannot write %s", Hdr.h_name); ! 426: continue; ! 427: } ! 428: } ! 429: } ! 430: if( Ofile ) { ! 431: (void) close(Ofile); ! 432: if(chmod(Hdr.h_name, Hdr.h_mode) < 0) ! 433: fperrno("Cannot change mode of <%s>", ! 434: Hdr.h_name); ! 435: set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); ! 436: } ! 437: } ! 438: if(select) { ! 439: if(Verbose) ! 440: if(Toc) ! 441: pentry(Hdr.h_name); ! 442: else ! 443: puts(Hdr.h_name); ! 444: else if(Toc) ! 445: puts(Hdr.h_name); ! 446: } ! 447: } ! 448: break; ! 449: ! 450: case PASS: /* move files around */ ! 451: if(argc != 1) ! 452: usage(); ! 453: if(access(argv[0], 2) == -1) { ! 454: (void) fperrno("Cannot write in <%s>", argv[0]); ! 455: exit(2); ! 456: } ! 457: strcpy(Fullname, argv[0]); /* destination directory */ ! 458: if(stat(Fullname, &Xstatb) < 0) { ! 459: fperrno("Cannot stat <%s>", Fullname); ! 460: exit(2); ! 461: } ! 462: if((Xstatb.st_mode&S_IFMT) != S_IFDIR) { ! 463: (void) fprintf(stderr, "<%s> is not a directory", ! 464: Fullname); ! 465: exit(2); ! 466: } ! 467: Dev = Xstatb.st_dev; ! 468: if( Fullname[ strlen(Fullname) - 1 ] != '/' ) ! 469: strcat(Fullname, "/"); ! 470: fullp = Fullname + strlen(Fullname); ! 471: ! 472: while(getname()) { ! 473: if (A_directory && !Dir) ! 474: fperr("Use `-d' option to copy <%s>", ! 475: Hdr.h_name); ! 476: if(!ckname(Hdr.h_name)) ! 477: continue; ! 478: i = 0; ! 479: while(Hdr.h_name[i] == '/') ! 480: i++; ! 481: strcpy(fullp, &(Hdr.h_name[i])); ! 482: ! 483: if( PassLink && !A_directory && Dev == Statb.st_dev ) { ! 484: if(link(Hdr.h_name, Fullname) < 0) { ! 485: switch(errno) { ! 486: case ENOENT: ! 487: if(missdir(Fullname) != 0) { ! 488: fperrno("Cannot create directory for <%s>", ! 489: Fullname); ! 490: continue; ! 491: } ! 492: break; ! 493: case EEXIST: ! 494: if(unlink(Fullname) < 0) { ! 495: fperrno("Cannot unlink <%s>", ! 496: Fullname); ! 497: continue; ! 498: } ! 499: break; ! 500: default: ! 501: fperrno("Cannot link <%s> to <%s>", ! 502: Hdr.h_name, Fullname); ! 503: continue; ! 504: } ! 505: if(link(Hdr.h_name, Fullname) < 0) { ! 506: fperrno("Cannot link <%s> to <%s>", ! 507: Hdr.h_name, Fullname); ! 508: continue; ! 509: } ! 510: } ! 511: ! 512: goto ckverbose; ! 513: } ! 514: if( A_symlink ) { ! 515: symlsz = (int) mklong(Hdr.h_filesize); ! 516: if (readlink(Hdr.h_name, Symlbuf, symlsz) < 0) { ! 517: fperrno("Cannot read symbolic link <%s>", ! 518: Hdr.h_name); ! 519: continue; ! 520: } ! 521: Symlbuf[symlsz] = '\0'; ! 522: if(!openout(Fullname, Symlbuf)) ! 523: continue; ! 524: Blocks += ((symlsz + (BUFSIZE - 1)) / BUFSIZE); ! 525: if(Verbose) ! 526: puts(Fullname); ! 527: continue; ! 528: } ! 529: if(!(Ofile = openout(Fullname, (char *)0))) ! 530: continue; ! 531: if((Ifile = open(Hdr.h_name, 0)) < 0) { ! 532: fperrno("Cannot open <%s>", Hdr.h_name); ! 533: close(Ofile); ! 534: continue; ! 535: } ! 536: filesz = Statb.st_size; ! 537: for(; filesz > 0; filesz -= CPIOBSZ) { ! 538: ct = filesz>CPIOBSZ? CPIOBSZ: filesz; ! 539: if(read(Ifile, Buf, ct) < 0) { ! 540: fperrno("Cannot read %s", Hdr.h_name); ! 541: break; ! 542: } ! 543: if(write(Ofile, Buf, ct) < 0) { ! 544: fperrno("Cannot write %s", Hdr.h_name); ! 545: break; ! 546: } ! 547: /* Removed u370 ifdef which caused cpio */ ! 548: /* to report blocks in terms of 4096 bytes. */ ! 549: ! 550: Blocks += ((ct + (BUFSIZE - 1)) / BUFSIZE); ! 551: } ! 552: close(Ifile); ! 553: if(Acc_time) { ! 554: struct utimbuf utb; ! 555: ! 556: utb.actime = Statb.st_atime; ! 557: utb.modtime = Statb.st_mtime; ! 558: (void)utime(Hdr.h_name, &utb); ! 559: } ! 560: if(Ofile) { ! 561: close(Ofile); ! 562: if(chmod(Fullname, Hdr.h_mode) < 0) ! 563: fperrno("Cannot change mode of <%s>", ! 564: Fullname); ! 565: set_time(Fullname, Statb.st_atime, mklong(Hdr.h_mtime)); ! 566: ckverbose: ! 567: if(Verbose) ! 568: puts(Fullname); ! 569: } ! 570: } ! 571: } ! 572: /* print number of blocks actually copied */ ! 573: Blocks += ((sBlocks + (BUFSIZE - 1)) / BUFSIZE); ! 574: (void) fprintf(stderr, "%ld blocks\n", Blocks * (Bufsize>>9)); ! 575: exit(0); ! 576: } ! 577: ! 578: static ! 579: usage() ! 580: { ! 581: (void) fprintf("Usage: %s\n %s\n %s\n %s\n %s\n", ! 582: "cpio -o[acvB] <name-list >collection", ! 583: "cpio -o[acvB] -Ocollection <name-list", ! 584: "cpio -i[cdmrstuvfB6] [ pattern ... ] <collection", ! 585: "cpio -i[cdmrstuvfB6] -Icollection [ pattern ... ]", ! 586: "cpio -p[adlmruv] directory <name-list"); ! 587: } ! 588: ! 589: static ! 590: chkswfile( sp, c, option ) ! 591: char *sp; ! 592: char c; ! 593: short option; ! 594: { ! 595: if( !option ) { ! 596: fperr( "-%c must be specified before -%c option", ! 597: c == 'I' ? 'i' : 'o', c ); ! 598: exit(2); ! 599: } ! 600: if( (c == 'I' && option != IN) || (c == 'O' && option != OUT) ) { ! 601: fperr( "-%c option not permitted with -%c option", c, ! 602: option ); ! 603: exit(2); ! 604: } ! 605: if( !sp ) ! 606: return; ! 607: fperr("No more than one -I or -O flag permitted"); ! 608: exit(2); ! 609: } ! 610: ! 611: static ! 612: getname() /* get file name, get info for header */ ! 613: { ! 614: register char *namep = Name; ! 615: register ushort ftype; ! 616: struct stat Lstatb; ! 617: long tlong; ! 618: ! 619: for(;;) { ! 620: if(gets(namep) == NULL) ! 621: return 0; ! 622: while(*namep == '.' && namep[1] == '/') { ! 623: namep++; ! 624: while(*namep == '/') namep++; ! 625: } ! 626: strcpy(Hdr.h_name, namep); ! 627: if(lstat(namep, &Statb) < 0) { ! 628: fperrno("Cannot stat <%s>", Hdr.h_name); ! 629: continue; ! 630: } ! 631: ftype = Statb.st_mode & Filetype; ! 632: A_directory = (ftype == S_IFDIR); ! 633: A_special = (ftype == S_IFBLK) ! 634: || (ftype == S_IFCHR) ! 635: || (ftype == S_IFIFO); ! 636: A_symlink = (ftype == S_IFLNK); ! 637: Hdr.h_magic = MAGIC; ! 638: Hdr.h_namesize = strlen(Hdr.h_name) + 1; ! 639: Hdr.h_uid = Statb.st_uid; ! 640: Hdr.h_gid = Statb.st_gid; ! 641: Hdr.h_dev = Statb.st_dev; ! 642: Hdr.h_ino = Statb.st_ino; ! 643: Hdr.h_mode = Statb.st_mode; ! 644: MKSHORT(Hdr.h_mtime, Statb.st_mtime); ! 645: Hdr.h_nlink = Statb.st_nlink; ! 646: tlong = ((Hdr.h_mode&S_IFMT) == S_IFREG || ! 647: (Hdr.h_mode&S_IFMT) == S_IFLNK)? Statb.st_size: 0L; ! 648: MKSHORT(Hdr.h_filesize, tlong); ! 649: Hdr.h_rdev = Statb.st_rdev; ! 650: if( Cflag ) ! 651: bintochar(tlong); ! 652: return 1; ! 653: } ! 654: } ! 655: ! 656: static ! 657: bintochar(t) /* ASCII header write */ ! 658: long t; ! 659: { ! 660: sprintf(Chdr,"%.6o%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.11lo%.6ho%.11lo%s", ! 661: MAGIC, MK_USHORT(Statb.st_dev), MK_USHORT(Statb.st_ino), Statb.st_mode, Statb.st_uid, ! 662: Statb.st_gid, Statb.st_nlink, MK_USHORT(Statb.st_rdev), ! 663: Statb.st_mtime, (short)strlen(Hdr.h_name)+1, t, Hdr.h_name); ! 664: } ! 665: ! 666: static ! 667: chartobin() /* ASCII header read */ ! 668: { ! 669: sscanf(Chdr, "%6ho%6ho%6ho%6ho%6ho%6ho%6ho%6ho%11lo%6ho%11lo", ! 670: &Hdr.h_magic, &Hdr.h_dev, &Hdr.h_ino, &Hdr.h_mode, &Hdr.h_uid, ! 671: &Hdr.h_gid, &Hdr.h_nlink, &Hdr.h_rdev, &Longtime, ! 672: &Hdr.h_namesize, &Longfile); ! 673: MKSHORT(Hdr.h_filesize, Longfile); ! 674: MKSHORT(Hdr.h_mtime, Longtime); ! 675: } ! 676: ! 677: ! 678: /* Check the header for the magic number. Switch modes automatically to ! 679: match the type of header found. ! 680: */ ! 681: static ! 682: chkhdr() ! 683: { ! 684: bread(Chdr, CHARS); ! 685: chartobin(); ! 686: if( Hdr.h_magic == MAGIC ) ! 687: Cflag = 1; ! 688: else { ! 689: breread(&Hdr.h_magic, sizeof Hdr.h_magic); ! 690: if( Hdr.h_magic == MAGIC || Hdr.h_magic == (short)BSMAGIC ) ! 691: Cflag = 0; ! 692: else { ! 693: fperr("This is not a cpio file. Bad magic number."); ! 694: exit(2); ! 695: } ! 696: } ! 697: breread(Chdr, 0); ! 698: } ! 699: ! 700: ! 701: static ! 702: gethdr() /* get file headers */ ! 703: { ! 704: register ushort ftype; ! 705: ! 706: if (Cflag) { ! 707: bread(Chdr, CHARS); ! 708: chartobin(); ! 709: } ! 710: else ! 711: bread(&Hdr, HDRSIZE); ! 712: ! 713: if(Hdr.h_magic == (short)BSMAGIC) ! 714: swap((char *)&Hdr, HDRSIZE, 1, 0); ! 715: else if( Hdr.h_magic != MAGIC ) { ! 716: fperr("Out of phase--get help"); ! 717: exit(2); ! 718: } ! 719: bread(Hdr.h_name, Hdr.h_namesize); ! 720: if(EQ(Hdr.h_name, "TRAILER!!!")) ! 721: return 0; ! 722: ftype = Hdr.h_mode & Filetype; ! 723: A_directory = (ftype == S_IFDIR); ! 724: A_special = (ftype == S_IFBLK) ! 725: || (ftype == S_IFCHR) ! 726: || (ftype == S_IFIFO); ! 727: A_symlink = (ftype == S_IFLNK); ! 728: return 1; ! 729: } ! 730: ! 731: static ! 732: ckname(namep) /* check filenames with patterns given on cmd line */ ! 733: register char *namep; ! 734: { ! 735: char buf[sizeof Hdr.h_name]; ! 736: ! 737: if(fflag ^ !nmatch(namep, Pattern)) { ! 738: return 0; ! 739: } ! 740: if(Rename && !A_directory) { /* rename interactively */ ! 741: fprintf(Wtty, "Rename <%s>\n", namep); ! 742: fflush(Wtty); ! 743: fgets(buf, sizeof buf, Rtty); ! 744: if(feof(Rtty)) ! 745: exit(2); ! 746: buf[strlen(buf) - 1] = '\0'; ! 747: if(EQ(buf, "")) { ! 748: strcpy(namep,buf); ! 749: printf("Skipped\n"); ! 750: return 0; ! 751: } ! 752: else if(EQ(buf, ".")) ! 753: printf("Same name\n"); ! 754: else ! 755: strcpy(namep,buf); ! 756: } ! 757: return 1; ! 758: } ! 759: ! 760: static ! 761: openout(namep, symlname) /* open files for writing, set all necessary info */ ! 762: register char *namep; ! 763: char *symlname; ! 764: { ! 765: register f; ! 766: register char *np; ! 767: int ans; ! 768: ! 769: if(!strncmp(namep, "./", 2)) ! 770: namep += 2; ! 771: np = namep; ! 772: if(A_directory) { ! 773: if( !Dir || Rename || EQ(namep, ".") || EQ(namep, "..") ) ! 774: /* do not consider . or .. files */ ! 775: return 0; ! 776: if(stat(namep, &Xstatb) == -1) { ! 777: ! 778: /* try creating (only twice) */ ! 779: ans = 0; ! 780: do { ! 781: if(mkdir(namep, Hdr.h_mode) != 0) { ! 782: ans += 1; ! 783: }else { ! 784: ans = 0; ! 785: break; ! 786: } ! 787: }while(ans < 2 && missdir(namep) == 0); ! 788: if(ans == 1) { ! 789: fperrno("Cannot create directory for <%s>", ! 790: namep); ! 791: return(0); ! 792: }else if(ans == 2) { ! 793: fperrno("Cannot create directory <%s>", namep); ! 794: return(0); ! 795: } ! 796: } ! 797: ! 798: ret: ! 799: if(chmod(namep, Hdr.h_mode) < 0) ! 800: fperrno("Cannot change mode of <%s>", namep); ! 801: if(Uid == 0) ! 802: if(chown(namep, Hdr.h_uid, Hdr.h_gid) < 0) ! 803: fperrno("Cannot change ownership of <%s>", ! 804: namep); ! 805: set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); ! 806: return 0; ! 807: } ! 808: if(Hdr.h_nlink > 1) ! 809: if(!postml(namep, np)) ! 810: return 0; ! 811: if(lstat(namep, &Xstatb) == 0) { ! 812: if(Uncond && !((!(Xstatb.st_mode & S_IWRITE) || A_special) && (Uid != 0))) { ! 813: if(unlink(namep) < 0) { ! 814: fperrno("cannot unlink current <%s>", namep); ! 815: } ! 816: } ! 817: if(!Uncond && (mklong(Hdr.h_mtime) <= Xstatb.st_mtime)) { ! 818: /* There's a newer or same aged version of file on destination */ ! 819: fperr("current <%s> newer or same age", np); ! 820: return 0; ! 821: } ! 822: } ! 823: if( Option == PASS ! 824: && Hdr.h_ino == Xstatb.st_ino ! 825: && Hdr.h_dev == Xstatb.st_dev) { ! 826: fperr("Attempt to pass file to self!"); ! 827: exit(2); ! 828: } ! 829: if(A_symlink) { ! 830: /* try symlinking (only twice) */ ! 831: ans = 0; ! 832: do { ! 833: if(symlink( ! 834: symlname, namep) < 0) { ! 835: ans += 1; ! 836: }else { ! 837: ans = 0; ! 838: break; ! 839: } ! 840: }while(ans < 2 && missdir(np) == 0); ! 841: if(ans == 1) { ! 842: fperrno("Cannot create directory for <%s>", namep); ! 843: return(0); ! 844: }else if(ans == 2) { ! 845: fperrno("Cannot symlink <%s> and <%s>", namep, symlname); ! 846: return(0); ! 847: } ! 848: ! 849: return 0; ! 850: } ! 851: if(A_special) { ! 852: if((Hdr.h_mode & Filetype) == S_IFIFO) ! 853: Hdr.h_rdev = 0; ! 854: ! 855: /* try creating (only twice) */ ! 856: ans = 0; ! 857: do { ! 858: if(mknod(namep, Hdr.h_mode, Hdr.h_rdev) < 0) { ! 859: ans += 1; ! 860: }else { ! 861: ans = 0; ! 862: break; ! 863: } ! 864: }while(ans < 2 && missdir(np) == 0); ! 865: if(ans == 1) { ! 866: fperrno("Cannot create directory for <%s>", namep); ! 867: return(0); ! 868: }else if(ans == 2) { ! 869: fperrno("Cannot mknod <%s>", namep); ! 870: return(0); ! 871: } ! 872: ! 873: goto ret; ! 874: } ! 875: ! 876: /* try creating (only twice) */ ! 877: ans = 0; ! 878: do { ! 879: if((f = creat(namep, Hdr.h_mode)) < 0) { ! 880: ans += 1; ! 881: }else { ! 882: ans = 0; ! 883: break; ! 884: } ! 885: }while(ans < 2 && missdir(np) == 0); ! 886: if(ans == 1) { ! 887: fperrno("Cannot create directory for <%s>", namep); ! 888: return(0); ! 889: }else if(ans == 2) { ! 890: fperrno("Cannot create <%s>", namep); ! 891: return(0); ! 892: } ! 893: ! 894: if(Uid == 0) ! 895: if(chown(namep, Hdr.h_uid, Hdr.h_gid) < 0) ! 896: fperrno("Cannot change ownership of <%s>", namep); ! 897: return f; ! 898: } ! 899: ! 900: ! 901: /* Shared by bread() and breread() ! 902: */ ! 903: static int nleft = 0; /* unread chars left in Cbuf */ ! 904: static char *ip; /* pointer to next char to be read from Cbuf */ ! 905: ! 906: /* Reread the current buffer Cbuf. ! 907: A character count, c, of 0 simply resets the pointer so next bread gets ! 908: the same data again. ! 909: */ ! 910: static ! 911: breread(b, c) ! 912: char *b; ! 913: int c; ! 914: { ! 915: ip = Cbuf; ! 916: if( nleft ) ! 917: nleft = Bufsize; ! 918: if( !c ) ! 919: return; ! 920: bread(b, c); ! 921: } ! 922: ! 923: static ! 924: bread(b, c) ! 925: register char *b; ! 926: register int c; ! 927: { ! 928: register int rv; ! 929: register char *p = ip; ! 930: ! 931: if( !Cflag ) { ! 932: /* round c up to an even number */ ! 933: c = (c+1)/2; ! 934: c *= 2; ! 935: } ! 936: while( c ) { ! 937: if( nleft == 0 ) { ! 938: while( (rv = read(Input, Cbuf, Bufsize)) == 0 ) { ! 939: Input = chgreel(0, Input, rv); ! 940: } ! 941: if( rv == Bufsize ) { ! 942: nleft = Bufsize; ! 943: p = Cbuf; ! 944: ++Blocks; ! 945: } ! 946: else if( rv == -1 ) { ! 947: fperrno("Read error on archive"); ! 948: exit(2); ! 949: } ! 950: else if( rv < Bufsize ) { /* short read */ ! 951: smemcpy( &Cbuf[ Bufsize - rv ], Cbuf, rv ); ! 952: nleft = rv; ! 953: p = &Cbuf[ Bufsize - rv ]; ! 954: sBlocks += rv; ! 955: } ! 956: } ! 957: if( nleft <= c ) { ! 958: memcpy( b, p, nleft ); ! 959: c -= nleft; ! 960: b += nleft; ! 961: p += nleft; ! 962: nleft = 0; ! 963: } ! 964: else { ! 965: memcpy( b, p, c ); ! 966: nleft -= c; ! 967: b += c; ! 968: p += c; ! 969: c = 0; ! 970: } ! 971: } ! 972: ip = p; ! 973: } ! 974: ! 975: ! 976: static ! 977: bwrite(rp, c) ! 978: register char *rp; ! 979: register c; ! 980: { ! 981: register char *cp = Cp; ! 982: static unsigned Ccnt = 0; ! 983: register unsigned Cleft; ! 984: register int rv; ! 985: ! 986: if( !Cflag ) { ! 987: /* round c up to an even number */ ! 988: c = (c+1)/2; ! 989: c *= 2; ! 990: } ! 991: while( c ) { ! 992: if( (Cleft = Bufsize - Ccnt) <= c ) { ! 993: memcpy( cp, rp, Cleft ); ! 994: rv = write(Output, Cbuf, Bufsize); ! 995: if( rv == 0 || ( rv == -1 && errno == ENXIO ) ) { ! 996: rv = eomchgreel(); ! 997: } ! 998: if( rv == Bufsize ) { ! 999: Ccnt = 0; ! 1000: cp = Cbuf; ! 1001: } ! 1002: else if( rv == -1 ) { ! 1003: fperrno("Write error on archive"); ! 1004: exit(2); ! 1005: } ! 1006: else if( rv < Bufsize ) { ! 1007: Output = chgreel(1, Output, 0); ! 1008: smemcpy( Cbuf, &Cbuf[ Bufsize - rv ], rv ); ! 1009: Ccnt = Bufsize - rv; ! 1010: cp = &Cbuf[ rv ]; ! 1011: } ! 1012: ++Blocks; ! 1013: rp += Cleft; ! 1014: c -= Cleft; ! 1015: } ! 1016: else { ! 1017: memcpy( cp, rp, c ); ! 1018: Ccnt += c; ! 1019: cp += c; ! 1020: rp += c; ! 1021: c = 0; ! 1022: } ! 1023: } ! 1024: Cp = cp; ! 1025: } ! 1026: ! 1027: ! 1028: static int reelcount = 1; /* used below and in chgreel() */ ! 1029: ! 1030: /* Change reel due to reaching end-of-media. ! 1031: Keep trying to get a successful write before considering the ! 1032: change-of-reel as successful. ! 1033: */ ! 1034: static ! 1035: int ! 1036: eomchgreel() ! 1037: { ! 1038: int rv; ! 1039: ! 1040: while( 1 ) { ! 1041: Output = chgreel(1, Output, 0); ! 1042: rv = write(Output, Cbuf, Bufsize); ! 1043: if( rv == Bufsize ) ! 1044: return rv; ! 1045: if( rv == -1 ) ! 1046: fperrno( "Unable to write this medium" ); ! 1047: else ! 1048: fperr( "Unable to write this medium: Premature EOF" ); ! 1049: (void) fprintf(stderr, "Try again.\n"); ! 1050: reelcount--; ! 1051: } ! 1052: /*NOTREACHED*/ ! 1053: } ! 1054: ! 1055: ! 1056: static ! 1057: postml(namep, np) /* linking funtion: Postml() is called after */ ! 1058: register char *namep, *np; /* namep is created. Postml() checks to see */ ! 1059: { /* if namep should be linked to np. If so, */ ! 1060: /* postml() removes the independent instance */ ! 1061: register i; /* of namep and links namep to np. */ ! 1062: static struct ml { ! 1063: short m_dev; ! 1064: ushort m_ino; ! 1065: char m_name[2]; ! 1066: } **ml = 0; ! 1067: register struct ml *mlp; ! 1068: static unsigned mlsize = 0; ! 1069: static unsigned mlinks = 0; ! 1070: char *lnamep; ! 1071: int ans; ! 1072: ! 1073: if( !ml ) { ! 1074: mlsize = LINKS; ! 1075: ml = (struct ml **) malloc(mlsize * sizeof(struct ml)); ! 1076: } ! 1077: else if( mlinks == mlsize ) { ! 1078: mlsize += LINKS; ! 1079: ml = (struct ml **) realloc((char *) ml, ! 1080: mlsize * sizeof(struct ml)); ! 1081: } ! 1082: if (ml == NULL) { ! 1083: fperr("Out of memory for links"); ! 1084: exit(2); ! 1085: } ! 1086: for(i = 0; i < mlinks; ++i) { ! 1087: mlp = ml[i]; ! 1088: if(mlp->m_ino==Hdr.h_ino && mlp->m_dev==Hdr.h_dev) { ! 1089: if(Verbose) ! 1090: printf("%s linked to %s\n", ml[i]->m_name, ! 1091: np); ! 1092: unlink(namep); ! 1093: if(Option == IN && *(mlp->m_name) != '/') { ! 1094: Fullname[Pathend] = '\0'; ! 1095: strcat(Fullname, mlp->m_name); ! 1096: lnamep = Fullname; ! 1097: } ! 1098: lnamep = mlp->m_name; ! 1099: ! 1100: /* try linking (only twice) */ ! 1101: ans = 0; ! 1102: do { ! 1103: if(link(lnamep, namep) < 0) { ! 1104: ans += 1; ! 1105: }else { ! 1106: ans = 0; ! 1107: break; ! 1108: } ! 1109: }while(ans < 2 && missdir(np) == 0); ! 1110: if(ans == 1) { ! 1111: fperrno("Cannot create directory for <%s>", np); ! 1112: return(0); ! 1113: }else if(ans == 2) { ! 1114: fperrno("Cannot link <%s> & <%s>", lnamep, np); ! 1115: return(0); ! 1116: } ! 1117: ! 1118: set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); ! 1119: return 0; ! 1120: } ! 1121: } ! 1122: if( !(ml[mlinks] = (struct ml *)malloc(strlen(np) + 2 + sizeof(struct ml)))) { ! 1123: static int first=1; ! 1124: ! 1125: if(first) ! 1126: fperr("Out of memory for links"); ! 1127: first = 0; ! 1128: return 1; ! 1129: } ! 1130: ml[mlinks]->m_dev = Hdr.h_dev; ! 1131: ml[mlinks]->m_ino = Hdr.h_ino; ! 1132: strcpy(ml[mlinks]->m_name, np); ! 1133: ++mlinks; ! 1134: return 1; ! 1135: } ! 1136: ! 1137: static ! 1138: pentry(namep) /* print verbose table of contents */ ! 1139: register char *namep; ! 1140: { ! 1141: ! 1142: static short lastid = -1; ! 1143: #include <pwd.h> ! 1144: static struct passwd *pw; ! 1145: struct passwd *getpwuid(); ! 1146: static char tbuf[32]; ! 1147: char *ctime(); ! 1148: ! 1149: printf("%-7o", MK_USHORT(Hdr.h_mode)); ! 1150: if(lastid == Hdr.h_uid) ! 1151: printf("%-6s", pw->pw_name); ! 1152: else { ! 1153: setpwent(); ! 1154: if(pw = getpwuid((int)Hdr.h_uid)) { ! 1155: printf("%-6s", pw->pw_name); ! 1156: lastid = Hdr.h_uid; ! 1157: } else { ! 1158: printf("%-6d", Hdr.h_uid); ! 1159: lastid = -1; ! 1160: } ! 1161: } ! 1162: printf("%7ld ", mklong(Hdr.h_filesize)); ! 1163: U.l = mklong(Hdr.h_mtime); ! 1164: strcpy(tbuf, ctime((long *)&U.l)); ! 1165: tbuf[24] = '\0'; ! 1166: printf(" %s %s", &tbuf[4], namep); ! 1167: if (A_symlink) ! 1168: printf(" -> %s", Symlbuf); ! 1169: putchar('\n'); ! 1170: } ! 1171: ! 1172: /* pattern matching functions */ ! 1173: static ! 1174: nmatch(s, pat) ! 1175: char *s, **pat; ! 1176: { ! 1177: if( !pat ) ! 1178: return 1; ! 1179: while(*pat) { ! 1180: if((**pat == '!' && !gmatch(s, *pat+1)) ! 1181: || gmatch(s, *pat)) ! 1182: return 1; ! 1183: ++pat; ! 1184: } ! 1185: return 0; ! 1186: } ! 1187: ! 1188: ! 1189: static ! 1190: gmatch(s, p) ! 1191: register char *s, *p; ! 1192: { ! 1193: register int c; ! 1194: register cc, ok, lc, scc; ! 1195: ! 1196: scc = *s; ! 1197: lc = 077777; ! 1198: switch (c = *p) { ! 1199: ! 1200: case '[': ! 1201: ok = 0; ! 1202: while (cc = *++p) { ! 1203: switch (cc) { ! 1204: ! 1205: case ']': ! 1206: if (ok) ! 1207: return(gmatch(++s, ++p)); ! 1208: else ! 1209: return(0); ! 1210: ! 1211: case '-': ! 1212: ok |= ((lc <= scc) && (scc <= (cc=p[1]))); ! 1213: } ! 1214: if (scc==(lc=cc)) ok++; ! 1215: } ! 1216: return(0); ! 1217: ! 1218: case '?': ! 1219: caseq: ! 1220: if(scc) return(gmatch(++s, ++p)); ! 1221: return(0); ! 1222: case '*': ! 1223: return(umatch(s, ++p)); ! 1224: case 0: ! 1225: return(!scc); ! 1226: } ! 1227: if (c==scc) goto caseq; ! 1228: return(0); ! 1229: } ! 1230: ! 1231: ! 1232: ! 1233: static ! 1234: umatch(s, p) ! 1235: register char *s, *p; ! 1236: { ! 1237: if(*p==0) return(1); ! 1238: while(*s) ! 1239: if (gmatch(s++,p)) return(1); ! 1240: return(0); ! 1241: } ! 1242: ! 1243: swap(buf, bytecount, bytes, halfwords) /* swap halfwords, bytes or both */ ! 1244: char *buf; ! 1245: int bytecount; ! 1246: int bytes, halfwords; ! 1247: { ! 1248: register int count; ! 1249: int n, i; ! 1250: ! 1251: if(bytes) { ! 1252: register union swpbytes { ! 1253: short shortw; ! 1254: char charv[2]; ! 1255: } *pbuf; ! 1256: register char c; ! 1257: ! 1258: count = bytecount; ! 1259: pbuf = (union swpbytes *)buf; ! 1260: if (count % sizeof(union swpbytes)) ! 1261: pbuf->charv[count] = 0; ! 1262: count = (count + (sizeof(union swpbytes) - 1)) / sizeof(union swpbytes); ! 1263: while (count--) { ! 1264: c = pbuf->charv[0]; ! 1265: pbuf->charv[0] = pbuf->charv[1]; ! 1266: pbuf->charv[1] = c; ! 1267: ++pbuf; ! 1268: } ! 1269: } ! 1270: if (halfwords) { ! 1271: register union swphalf { ! 1272: long longw; ! 1273: short shortv[2]; ! 1274: char charv[4]; ! 1275: } *pbuf; ! 1276: register short cc; ! 1277: ! 1278: count = bytecount; ! 1279: pbuf = (union swphalf *)buf; ! 1280: if (n = count % sizeof(union swphalf)) ! 1281: if(bytes && n % 2) ! 1282: for(i = count + 1; i <= count + (sizeof(union swphalf) - n); i++) ! 1283: pbuf->charv[i] = 0; ! 1284: else ! 1285: for (i = count; i < count + (sizeof(union swphalf) - n); i++) ! 1286: pbuf->charv[i] = 0; ! 1287: count = (count + (sizeof(union swphalf) - 1)) / sizeof(union swphalf); ! 1288: while (count--) { ! 1289: cc = pbuf->shortv[0]; ! 1290: pbuf->shortv[0] = pbuf->shortv[1]; ! 1291: pbuf->shortv[1] = cc; ! 1292: ++pbuf; ! 1293: } ! 1294: } ! 1295: } ! 1296: ! 1297: ! 1298: static ! 1299: set_time(namep, atime, mtime) /* set access and modification times */ ! 1300: register char *namep; ! 1301: time_t atime, mtime; ! 1302: { ! 1303: static struct utimbuf timevec; ! 1304: ! 1305: if(!Mod_time) ! 1306: return; ! 1307: timevec.actime = atime; ! 1308: timevec.modtime = mtime; ! 1309: (void)utime(namep, &timevec); ! 1310: } ! 1311: ! 1312: ! 1313: ! 1314: static ! 1315: chgreel(x, fl, rv) ! 1316: { ! 1317: register f; ! 1318: char str[BUFSIZ]; ! 1319: struct stat statb; ! 1320: ! 1321: fstat(fl, &statb); ! 1322: if((statb.st_mode&S_IFMT) != S_IFCHR) { ! 1323: fperrno("Can't %s: ", x? "write output": "read input"); ! 1324: exit(2); ! 1325: } ! 1326: if( rv == 0 || ! 1327: ( rv == -1 && ( errno == ENOSPC || errno == ENXIO ) ) ) ! 1328: fperr( "\007Reached end of medium on %s", ! 1329: x? "output":"input" ); ! 1330: else { ! 1331: fperrno( "\007Encountered an error on %s", ! 1332: x? "output":"input" ); ! 1333: exit(2); ! 1334: } ! 1335: if( Rtty == NULL ) { ! 1336: Rtty = fopen(ttyname, "r"); ! 1337: if( Rtty == NULL ) { ! 1338: fperrno("Cannot prompt (can't open %s)", ttyname); ! 1339: exit(2); ! 1340: } ! 1341: } ! 1342: close(fl); ! 1343: reelcount++; ! 1344: again: ! 1345: if( swfile ) { ! 1346: askagain: ! 1347: fperr( eommsg, reelcount ); ! 1348: fgets(str, sizeof str, Rtty); ! 1349: switch( *str ) { ! 1350: case '\n': ! 1351: strcpy( str, swfile ); ! 1352: break; ! 1353: case 'q': ! 1354: exit(2); ! 1355: default: ! 1356: goto askagain; ! 1357: } ! 1358: } ! 1359: else { ! 1360: fperr("If you want to go on, type device/file name when ready."); ! 1361: fgets(str, sizeof str, Rtty); ! 1362: str[strlen(str) - 1] = '\0'; ! 1363: if(!*str) ! 1364: exit(2); ! 1365: } ! 1366: if((f = open(str, x? 1: 0)) < 0) { ! 1367: fperrno("Can't open <%s>", str); ! 1368: goto again; ! 1369: } ! 1370: return f; ! 1371: } ! 1372: ! 1373: ! 1374: ! 1375: static ! 1376: missdir(namep) ! 1377: register char *namep; ! 1378: { ! 1379: register char *np; ! 1380: register ct = 2; ! 1381: ! 1382: for(np = namep; *np; ++np) ! 1383: if(*np == '/') { ! 1384: if(np == namep) continue; /* skip over 'root slash' */ ! 1385: *np = '\0'; ! 1386: if(stat(namep, &Xstatb) == -1) { ! 1387: if(Dir) { ! 1388: if((ct = mkdir(namep, 0777)) != 0) { ! 1389: *np = '/'; ! 1390: return(ct); ! 1391: } ! 1392: }else { ! 1393: fperr("missing 'd' option"); ! 1394: return(-1); ! 1395: } ! 1396: } ! 1397: *np = '/'; ! 1398: } ! 1399: if (ct == 2) ct = 0; /* the file already exists */ ! 1400: return ct; ! 1401: } ! 1402: ! 1403: ! 1404: ! 1405: static ! 1406: pwd() /* get working directory */ ! 1407: { ! 1408: if (getwd(Fullname) == 0) { ! 1409: (void)fprintf(stderr, "cpio: %s\n", ! 1410: Fullname); ! 1411: exit(2); ! 1412: } ! 1413: Pathend = strlen(Fullname); ! 1414: Fullname[Pathend++] = '/'; ! 1415: Fullname[Pathend] = '\0'; ! 1416: } ! 1417: ! 1418: ! 1419: /* ! 1420: print message on the stderr ! 1421: */ ! 1422: static ! 1423: fperr( va_alist ) ! 1424: va_dcl ! 1425: { ! 1426: va_list args; ! 1427: char *fmt; ! 1428: ! 1429: va_start( args ); ! 1430: fprintf( stderr, "cpio: "); ! 1431: fmt = va_arg( args, char * ); ! 1432: vfprintf( stderr, fmt, args ); ! 1433: putc( '\n', stderr); ! 1434: fflush( stderr ); ! 1435: } ! 1436: ! 1437: /* ! 1438: print message on the stderr followed by error number and meaning. ! 1439: */ ! 1440: static ! 1441: fperrno( va_alist ) ! 1442: va_dcl ! 1443: { ! 1444: va_list args; ! 1445: char *fmt; ! 1446: ! 1447: va_start( args ); ! 1448: fprintf( stderr, "cpio: "); ! 1449: fmt = va_arg( args, char * ); ! 1450: vfprintf( stderr, fmt, args ); ! 1451: fprintf( stderr, ": " ); ! 1452: fflush( stderr ); ! 1453: perror(""); ! 1454: } ! 1455: ! 1456: ! 1457: /* Safe memory copy. ! 1458: Fast if the to and from strings do not overlap, ! 1459: slower but safe if they do. ! 1460: */ ! 1461: ! 1462: static char * ! 1463: smemcpy( to, from, count ) ! 1464: register char *to, *from; ! 1465: register unsigned count; ! 1466: { ! 1467: char *savedto; ! 1468: ! 1469: if( &to[ count ] <= from || &from[ count ] <= to ) ! 1470: return memcpy( to, from, count ); ! 1471: ! 1472: if( to == from ) ! 1473: return to; ! 1474: ! 1475: savedto = to; ! 1476: if( to < from ) ! 1477: while( count-- ) ! 1478: *(to++) = *(from++); ! 1479: else { ! 1480: to += count; ! 1481: from += count; ! 1482: while( count-- ) ! 1483: *(--to) = *(--from); ! 1484: } ! 1485: ! 1486: return savedto; ! 1487: } ! 1488: ! 1489: extern int _doprnt(); ! 1490: ! 1491: /*VARARGS2*/ ! 1492: int ! 1493: vfprintf(iop, format, ap) ! 1494: FILE *iop; ! 1495: char *format; ! 1496: va_list ap; ! 1497: { ! 1498: register int count; ! 1499: ! 1500: if (!(iop->_flag | _IOWRT)) { ! 1501: /* if no write flag */ ! 1502: if (iop->_flag | _IORW) { ! 1503: /* if ok, cause read-write */ ! 1504: iop->_flag |= _IOWRT; ! 1505: } else { ! 1506: /* else error */ ! 1507: return EOF; ! 1508: } ! 1509: } ! 1510: count = _doprnt(format, ap, iop); ! 1511: return(ferror(iop)? EOF: count); ! 1512: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.