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