1 /*- 2 * Copyright (c) 1992 Keith Muller. 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Keith Muller of the University of California, San Diego. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #ifndef lint 39 #if 0 40 static char sccsid[] = "@(#)cpio.c 8.1 (Berkeley) 5/31/93"; 41 #endif 42 static const char rcsid[] = 43 "$FreeBSD$"; 44 #endif /* not lint */ 45 46 #include <sys/types.h> 47 #include <sys/time.h> 48 #include <sys/stat.h> 49 #include <string.h> 50 #include <stdio.h> 51 #include <unistd.h> 52 #include <stdlib.h> 53 #include "pax.h" 54 #include "cpio.h" 55 #include "extern.h" 56 57 static int rd_nm __P((register ARCHD *, int)); 58 static int rd_ln_nm __P((register ARCHD *)); 59 static int com_rd __P((register ARCHD *)); 60 61 /* 62 * Routines which support the different cpio versions 63 */ 64 65 static int swp_head; /* binary cpio header byte swap */ 66 67 /* 68 * Routines common to all versions of cpio 69 */ 70 71 /* 72 * cpio_strd() 73 * Fire up the hard link detection code 74 * Return: 75 * 0 if ok -1 otherwise (the return values of lnk_start()) 76 */ 77 78 #ifdef __STDC__ 79 int 80 cpio_strd(void) 81 #else 82 int 83 cpio_strd() 84 #endif 85 { 86 return(lnk_start()); 87 } 88 89 /* 90 * cpio_trail() 91 * Called to determine if a header block is a valid trailer. We are 92 * passed the block, the in_sync flag (which tells us we are in resync 93 * mode; looking for a valid header), and cnt (which starts at zero) 94 * which is used to count the number of empty blocks we have seen so far. 95 * Return: 96 * 0 if a valid trailer, -1 if not a valid trailer, 97 */ 98 99 #ifdef __STDC__ 100 int 101 cpio_trail(register ARCHD *arcn) 102 #else 103 int 104 cpio_trail(arcn) 105 register ARCHD *arcn; 106 #endif 107 { 108 /* 109 * look for trailer id in file we are about to process 110 */ 111 if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0)) 112 return(0); 113 return(-1); 114 } 115 116 /* 117 * com_rd() 118 * operations common to all cpio read functions. 119 * Return: 120 * 0 121 */ 122 123 #ifdef __STDC__ 124 static int 125 com_rd(register ARCHD *arcn) 126 #else 127 static int 128 com_rd(arcn) 129 register ARCHD *arcn; 130 #endif 131 { 132 arcn->skip = 0; 133 arcn->pat = NULL; 134 arcn->org_name = arcn->name; 135 switch(arcn->sb.st_mode & C_IFMT) { 136 case C_ISFIFO: 137 arcn->type = PAX_FIF; 138 break; 139 case C_ISDIR: 140 arcn->type = PAX_DIR; 141 break; 142 case C_ISBLK: 143 arcn->type = PAX_BLK; 144 break; 145 case C_ISCHR: 146 arcn->type = PAX_CHR; 147 break; 148 case C_ISLNK: 149 arcn->type = PAX_SLK; 150 break; 151 case C_ISOCK: 152 arcn->type = PAX_SCK; 153 break; 154 case C_ISCTG: 155 case C_ISREG: 156 default: 157 /* 158 * we have file data, set up skip (pad is set in the format 159 * specific sections) 160 */ 161 arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG; 162 arcn->type = PAX_REG; 163 arcn->skip = arcn->sb.st_size; 164 break; 165 } 166 if (chk_lnk(arcn) < 0) 167 return(-1); 168 return(0); 169 } 170 171 /* 172 * cpio_end_wr() 173 * write the special file with the name trailer in the proper format 174 * Return: 175 * result of the write of the trailer from the cpio specific write func 176 */ 177 178 #ifdef __STDC__ 179 int 180 cpio_endwr(void) 181 #else 182 int 183 cpio_endwr() 184 #endif 185 { 186 ARCHD last; 187 188 /* 189 * create a trailer request and call the proper format write function 190 */ 191 memset(&last, 0, sizeof(last)); 192 last.nlen = sizeof(TRAILER) - 1; 193 last.type = PAX_REG; 194 last.sb.st_nlink = 1; 195 (void)strcpy(last.name, TRAILER); 196 return((*frmt->wr)(&last)); 197 } 198 199 /* 200 * rd_nam() 201 * read in the file name which follows the cpio header 202 * Return: 203 * 0 if ok, -1 otherwise 204 */ 205 206 #ifdef __STDC__ 207 static int 208 rd_nm(register ARCHD *arcn, int nsz) 209 #else 210 static int 211 rd_nm(arcn, nsz) 212 register ARCHD *arcn; 213 int nsz; 214 #endif 215 { 216 /* 217 * do not even try bogus values 218 */ 219 if ((nsz == 0) || (nsz > sizeof(arcn->name))) { 220 paxwarn(1, "Cpio file name length %d is out of range", nsz); 221 return(-1); 222 } 223 224 /* 225 * read the name and make sure it is not empty and is \0 terminated 226 */ 227 if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') || 228 (arcn->name[0] == '\0')) { 229 paxwarn(1, "Cpio file name in header is corrupted"); 230 return(-1); 231 } 232 return(0); 233 } 234 235 /* 236 * rd_ln_nm() 237 * read in the link name for a file with links. The link name is stored 238 * like file data (and is NOT \0 terminated!) 239 * Return: 240 * 0 if ok, -1 otherwise 241 */ 242 243 #ifdef __STDC__ 244 static int 245 rd_ln_nm(register ARCHD *arcn) 246 #else 247 static int 248 rd_ln_nm(arcn) 249 register ARCHD *arcn; 250 #endif 251 { 252 /* 253 * check the length specified for bogus values 254 */ 255 if ((arcn->sb.st_size == 0) || 256 (arcn->sb.st_size >= sizeof(arcn->ln_name))) { 257 # ifdef NET2_STAT 258 paxwarn(1, "Cpio link name length is invalid: %lu", 259 arcn->sb.st_size); 260 # else 261 paxwarn(1, "Cpio link name length is invalid: %qu", 262 arcn->sb.st_size); 263 # endif 264 return(-1); 265 } 266 267 /* 268 * read in the link name and \0 terminate it 269 */ 270 if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) != 271 (int)arcn->sb.st_size) { 272 paxwarn(1, "Cpio link name read error"); 273 return(-1); 274 } 275 arcn->ln_nlen = arcn->sb.st_size; 276 arcn->ln_name[arcn->ln_nlen] = '\0'; 277 278 /* 279 * watch out for those empty link names 280 */ 281 if (arcn->ln_name[0] == '\0') { 282 paxwarn(1, "Cpio link name is corrupt"); 283 return(-1); 284 } 285 return(0); 286 } 287 288 /* 289 * Routines common to the extended byte oriented cpio format 290 */ 291 292 /* 293 * cpio_id() 294 * determine if a block given to us is a valid extended byte oriented 295 * cpio header 296 * Return: 297 * 0 if a valid header, -1 otherwise 298 */ 299 300 #ifdef __STDC__ 301 int 302 cpio_id(char *blk, int size) 303 #else 304 int 305 cpio_id(blk, size) 306 char *blk; 307 int size; 308 #endif 309 { 310 if ((size < sizeof(HD_CPIO)) || 311 (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0)) 312 return(-1); 313 return(0); 314 } 315 316 /* 317 * cpio_rd() 318 * determine if a buffer is a byte oriented extended cpio archive entry. 319 * convert and store the values in the ARCHD parameter. 320 * Return: 321 * 0 if a valid header, -1 otherwise. 322 */ 323 324 #ifdef __STDC__ 325 int 326 cpio_rd(register ARCHD *arcn, register char *buf) 327 #else 328 int 329 cpio_rd(arcn, buf) 330 register ARCHD *arcn; 331 register char *buf; 332 #endif 333 { 334 register int nsz; 335 register HD_CPIO *hd; 336 337 /* 338 * check that this is a valid header, if not return -1 339 */ 340 if (cpio_id(buf, sizeof(HD_CPIO)) < 0) 341 return(-1); 342 hd = (HD_CPIO *)buf; 343 344 /* 345 * byte oriented cpio (posix) does not have padding! extract the octal 346 * ascii fields from the header 347 */ 348 arcn->pad = 0L; 349 arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT); 350 arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT); 351 arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT); 352 arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT); 353 arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT); 354 arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 355 OCT); 356 arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT); 357 #ifdef NET2_STAT 358 arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime), 359 OCT); 360 #else 361 arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime, sizeof(hd->c_mtime), 362 OCT); 363 #endif 364 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 365 #ifdef NET2_STAT 366 arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize), 367 OCT); 368 #else 369 arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize), 370 OCT); 371 #endif 372 373 /* 374 * check name size and if valid, read in the name of this entry (name 375 * follows header in the archive) 376 */ 377 if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2) 378 return(-1); 379 arcn->nlen = nsz - 1; 380 if (rd_nm(arcn, nsz) < 0) 381 return(-1); 382 383 if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 384 /* 385 * no link name to read for this file 386 */ 387 arcn->ln_nlen = 0; 388 arcn->ln_name[0] = '\0'; 389 return(com_rd(arcn)); 390 } 391 392 /* 393 * check link name size and read in the link name. Link names are 394 * stored like file data. 395 */ 396 if (rd_ln_nm(arcn) < 0) 397 return(-1); 398 399 /* 400 * we have a valid header (with a link) 401 */ 402 return(com_rd(arcn)); 403 } 404 405 /* 406 * cpio_endrd() 407 * no cleanup needed here, just return size of the trailer (for append) 408 * Return: 409 * size of trailer header in this format 410 */ 411 412 #ifdef __STDC__ 413 off_t 414 cpio_endrd(void) 415 #else 416 off_t 417 cpio_endrd() 418 #endif 419 { 420 return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER))); 421 } 422 423 /* 424 * cpio_stwr() 425 * start up the device mapping table 426 * Return: 427 * 0 if ok, -1 otherwise (what dev_start() returns) 428 */ 429 430 #ifdef __STDC__ 431 int 432 cpio_stwr(void) 433 #else 434 int 435 cpio_stwr() 436 #endif 437 { 438 return(dev_start()); 439 } 440 441 /* 442 * cpio_wr() 443 * copy the data in the ARCHD to buffer in extended byte oriented cpio 444 * format. 445 * Return 446 * 0 if file has data to be written after the header, 1 if file has NO 447 * data to write after the header, -1 if archive write failed 448 */ 449 450 #ifdef __STDC__ 451 int 452 cpio_wr(register ARCHD *arcn) 453 #else 454 int 455 cpio_wr(arcn) 456 register ARCHD *arcn; 457 #endif 458 { 459 register HD_CPIO *hd; 460 register int nsz; 461 char hdblk[sizeof(HD_CPIO)]; 462 463 /* 464 * check and repair truncated device and inode fields in the header 465 */ 466 if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0) 467 return(-1); 468 469 arcn->pad = 0L; 470 nsz = arcn->nlen + 1; 471 hd = (HD_CPIO *)hdblk; 472 if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 473 arcn->sb.st_rdev = 0; 474 475 switch(arcn->type) { 476 case PAX_CTG: 477 case PAX_REG: 478 case PAX_HRG: 479 /* 480 * set data size for file data 481 */ 482 # ifdef NET2_STAT 483 if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, 484 sizeof(hd->c_filesize), OCT)) { 485 # else 486 if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, 487 sizeof(hd->c_filesize), OCT)) { 488 # endif 489 paxwarn(1,"File is too large for cpio format %s", 490 arcn->org_name); 491 return(1); 492 } 493 break; 494 case PAX_SLK: 495 /* 496 * set data size to hold link name 497 */ 498 if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 499 sizeof(hd->c_filesize), OCT)) 500 goto out; 501 break; 502 default: 503 /* 504 * all other file types have no file data 505 */ 506 if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize), 507 OCT)) 508 goto out; 509 break; 510 } 511 512 /* 513 * copy the values to the header using octal ascii 514 */ 515 if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || 516 ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev), 517 OCT) || 518 ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 519 OCT) || 520 ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 521 OCT) || 522 ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 523 OCT) || 524 ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 525 OCT) || 526 ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 527 OCT) || 528 ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev), 529 OCT) || 530 ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime), 531 OCT) || 532 ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT)) 533 goto out; 534 535 /* 536 * write the file name to the archive 537 */ 538 if ((wr_rdbuf(hdblk, (int)sizeof(HD_CPIO)) < 0) || 539 (wr_rdbuf(arcn->name, nsz) < 0)) { 540 paxwarn(1, "Unable to write cpio header for %s", arcn->org_name); 541 return(-1); 542 } 543 544 /* 545 * if this file has data, we are done. The caller will write the file 546 * data, if we are link tell caller we are done, go to next file 547 */ 548 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 549 (arcn->type == PAX_HRG)) 550 return(0); 551 if (arcn->type != PAX_SLK) 552 return(1); 553 554 /* 555 * write the link name to the archive, tell the caller to go to the 556 * next file as we are done. 557 */ 558 if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) { 559 paxwarn(1,"Unable to write cpio link name for %s",arcn->org_name); 560 return(-1); 561 } 562 return(1); 563 564 out: 565 /* 566 * header field is out of range 567 */ 568 paxwarn(1, "Cpio header field is too small to store file %s", 569 arcn->org_name); 570 return(1); 571 } 572 573 /* 574 * Routines common to the system VR4 version of cpio (with/without file CRC) 575 */ 576 577 /* 578 * vcpio_id() 579 * determine if a block given to us is a valid system VR4 cpio header 580 * WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header 581 * uses HEX 582 * Return: 583 * 0 if a valid header, -1 otherwise 584 */ 585 586 #ifdef __STDC__ 587 int 588 vcpio_id(char *blk, int size) 589 #else 590 int 591 vcpio_id(blk, size) 592 char *blk; 593 int size; 594 #endif 595 { 596 if ((size < sizeof(HD_VCPIO)) || 597 (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0)) 598 return(-1); 599 return(0); 600 } 601 602 /* 603 * crc_id() 604 * determine if a block given to us is a valid system VR4 cpio header 605 * WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX 606 * Return: 607 * 0 if a valid header, -1 otherwise 608 */ 609 610 #ifdef __STDC__ 611 int 612 crc_id(char *blk, int size) 613 #else 614 int 615 crc_id(blk, size) 616 char *blk; 617 int size; 618 #endif 619 { 620 if ((size < sizeof(HD_VCPIO)) || 621 (strncmp(blk, AVCMAGIC, sizeof(AVCMAGIC) - 1) != 0)) 622 return(-1); 623 return(0); 624 } 625 626 /* 627 * crc_strd() 628 w set file data CRC calculations. Fire up the hard link detection code 629 * Return: 630 * 0 if ok -1 otherwise (the return values of lnk_start()) 631 */ 632 633 #ifdef __STDC__ 634 int 635 crc_strd(void) 636 #else 637 int 638 crc_strd() 639 #endif 640 { 641 docrc = 1; 642 return(lnk_start()); 643 } 644 645 /* 646 * vcpio_rd() 647 * determine if a buffer is a system VR4 archive entry. (with/without CRC) 648 * convert and store the values in the ARCHD parameter. 649 * Return: 650 * 0 if a valid header, -1 otherwise. 651 */ 652 653 #ifdef __STDC__ 654 int 655 vcpio_rd(register ARCHD *arcn, register char *buf) 656 #else 657 int 658 vcpio_rd(arcn, buf) 659 register ARCHD *arcn; 660 register char *buf; 661 #endif 662 { 663 register HD_VCPIO *hd; 664 dev_t devminor; 665 dev_t devmajor; 666 register int nsz; 667 668 /* 669 * during the id phase it was determined if we were using CRC, use the 670 * proper id routine. 671 */ 672 if (docrc) { 673 if (crc_id(buf, sizeof(HD_VCPIO)) < 0) 674 return(-1); 675 } else { 676 if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0) 677 return(-1); 678 } 679 680 hd = (HD_VCPIO *)buf; 681 arcn->pad = 0L; 682 683 /* 684 * extract the hex ascii fields from the header 685 */ 686 arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX); 687 arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX); 688 arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX); 689 arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX); 690 #ifdef NET2_STAT 691 arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX); 692 #else 693 arcn->sb.st_mtime = (time_t)asc_uqd(hd->c_mtime,sizeof(hd->c_mtime),HEX); 694 #endif 695 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 696 #ifdef NET2_STAT 697 arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize, 698 sizeof(hd->c_filesize), HEX); 699 #else 700 arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize, 701 sizeof(hd->c_filesize), HEX); 702 #endif 703 arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 704 HEX); 705 devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX); 706 devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX); 707 arcn->sb.st_dev = TODEV(devmajor, devminor); 708 devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX); 709 devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX); 710 arcn->sb.st_rdev = TODEV(devmajor, devminor); 711 arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX); 712 713 /* 714 * check the length of the file name, if ok read it in, return -1 if 715 * bogus 716 */ 717 if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2) 718 return(-1); 719 arcn->nlen = nsz - 1; 720 if (rd_nm(arcn, nsz) < 0) 721 return(-1); 722 723 /* 724 * skip padding. header + filename is aligned to 4 byte boundries 725 */ 726 if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0) 727 return(-1); 728 729 /* 730 * if not a link (or a file with no data), calculate pad size (for 731 * padding which follows the file data), clear the link name and return 732 */ 733 if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 734 /* 735 * we have a valid header (not a link) 736 */ 737 arcn->ln_nlen = 0; 738 arcn->ln_name[0] = '\0'; 739 arcn->pad = VCPIO_PAD(arcn->sb.st_size); 740 return(com_rd(arcn)); 741 } 742 743 /* 744 * read in the link name and skip over the padding 745 */ 746 if ((rd_ln_nm(arcn) < 0) || 747 (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0)) 748 return(-1); 749 750 /* 751 * we have a valid header (with a link) 752 */ 753 return(com_rd(arcn)); 754 } 755 756 /* 757 * vcpio_endrd() 758 * no cleanup needed here, just return size of the trailer (for append) 759 * Return: 760 * size of trailer header in this format 761 */ 762 763 #ifdef __STDC__ 764 off_t 765 vcpio_endrd(void) 766 #else 767 off_t 768 vcpio_endrd() 769 #endif 770 { 771 return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) + 772 (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER))))); 773 } 774 775 /* 776 * crc_stwr() 777 * start up the device mapping table, enable crc file calculation 778 * Return: 779 * 0 if ok, -1 otherwise (what dev_start() returns) 780 */ 781 782 #ifdef __STDC__ 783 int 784 crc_stwr(void) 785 #else 786 int 787 crc_stwr() 788 #endif 789 { 790 docrc = 1; 791 return(dev_start()); 792 } 793 794 /* 795 * vcpio_wr() 796 * copy the data in the ARCHD to buffer in system VR4 cpio 797 * (with/without crc) format. 798 * Return 799 * 0 if file has data to be written after the header, 1 if file has 800 * NO data to write after the header, -1 if archive write failed 801 */ 802 803 #ifdef __STDC__ 804 int 805 vcpio_wr(register ARCHD *arcn) 806 #else 807 int 808 vcpio_wr(arcn) 809 register ARCHD *arcn; 810 #endif 811 { 812 register HD_VCPIO *hd; 813 unsigned int nsz; 814 char hdblk[sizeof(HD_VCPIO)]; 815 816 /* 817 * check and repair truncated device and inode fields in the cpio 818 * header 819 */ 820 if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0) 821 return(-1); 822 nsz = arcn->nlen + 1; 823 hd = (HD_VCPIO *)hdblk; 824 if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 825 arcn->sb.st_rdev = 0; 826 827 /* 828 * add the proper magic value depending whether we were asked for 829 * file data crc's, and the crc if needed. 830 */ 831 if (docrc) { 832 if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic), 833 OCT) || 834 ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum), 835 HEX)) 836 goto out; 837 } else { 838 if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic), 839 OCT) || 840 ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX)) 841 goto out; 842 } 843 844 switch(arcn->type) { 845 case PAX_CTG: 846 case PAX_REG: 847 case PAX_HRG: 848 /* 849 * caller will copy file data to the archive. tell him how 850 * much to pad. 851 */ 852 arcn->pad = VCPIO_PAD(arcn->sb.st_size); 853 # ifdef NET2_STAT 854 if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, 855 sizeof(hd->c_filesize), HEX)) { 856 # else 857 if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, 858 sizeof(hd->c_filesize), HEX)) { 859 # endif 860 paxwarn(1,"File is too large for sv4cpio format %s", 861 arcn->org_name); 862 return(1); 863 } 864 break; 865 case PAX_SLK: 866 /* 867 * no file data for the caller to process, the file data has 868 * the size of the link 869 */ 870 arcn->pad = 0L; 871 if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 872 sizeof(hd->c_filesize), HEX)) 873 goto out; 874 break; 875 default: 876 /* 877 * no file data for the caller to process 878 */ 879 arcn->pad = 0L; 880 if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize), 881 HEX)) 882 goto out; 883 break; 884 } 885 886 /* 887 * set the other fields in the header 888 */ 889 if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 890 HEX) || 891 ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 892 HEX) || 893 ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 894 HEX) || 895 ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 896 HEX) || 897 ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime), 898 HEX) || 899 ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 900 HEX) || 901 ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj), 902 HEX) || 903 ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min), 904 HEX) || 905 ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj), 906 HEX) || 907 ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min), 908 HEX) || 909 ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX)) 910 goto out; 911 912 /* 913 * write the header, the file name and padding as required. 914 */ 915 if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) || 916 (wr_rdbuf(arcn->name, (int)nsz) < 0) || 917 (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) { 918 paxwarn(1,"Could not write sv4cpio header for %s",arcn->org_name); 919 return(-1); 920 } 921 922 /* 923 * if we have file data, tell the caller we are done, copy the file 924 */ 925 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 926 (arcn->type == PAX_HRG)) 927 return(0); 928 929 /* 930 * if we are not a link, tell the caller we are done, go to next file 931 */ 932 if (arcn->type != PAX_SLK) 933 return(1); 934 935 /* 936 * write the link name, tell the caller we are done. 937 */ 938 if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 939 (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) { 940 paxwarn(1,"Could not write sv4cpio link name for %s", 941 arcn->org_name); 942 return(-1); 943 } 944 return(1); 945 946 out: 947 /* 948 * header field is out of range 949 */ 950 paxwarn(1,"Sv4cpio header field is too small for file %s",arcn->org_name); 951 return(1); 952 } 953 954 /* 955 * Routines common to the old binary header cpio 956 */ 957 958 /* 959 * bcpio_id() 960 * determine if a block given to us is a old binary cpio header 961 * (with/without header byte swapping) 962 * Return: 963 * 0 if a valid header, -1 otherwise 964 */ 965 966 #ifdef __STDC__ 967 int 968 bcpio_id(char *blk, int size) 969 #else 970 int 971 bcpio_id(blk, size) 972 char *blk; 973 int size; 974 #endif 975 { 976 if (size < sizeof(HD_BCPIO)) 977 return(-1); 978 979 /* 980 * check both normal and byte swapped magic cookies 981 */ 982 if (((u_short)SHRT_EXT(blk)) == MAGIC) 983 return(0); 984 if (((u_short)RSHRT_EXT(blk)) == MAGIC) { 985 if (!swp_head) 986 ++swp_head; 987 return(0); 988 } 989 return(-1); 990 } 991 992 /* 993 * bcpio_rd() 994 * determine if a buffer is a old binary archive entry. (it may have byte 995 * swapped header) convert and store the values in the ARCHD parameter. 996 * This is a very old header format and should not really be used. 997 * Return: 998 * 0 if a valid header, -1 otherwise. 999 */ 1000 1001 #ifdef __STDC__ 1002 int 1003 bcpio_rd(register ARCHD *arcn, register char *buf) 1004 #else 1005 int 1006 bcpio_rd(arcn, buf) 1007 register ARCHD *arcn; 1008 register char *buf; 1009 #endif 1010 { 1011 register HD_BCPIO *hd; 1012 register int nsz; 1013 1014 /* 1015 * check the header 1016 */ 1017 if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0) 1018 return(-1); 1019 1020 arcn->pad = 0L; 1021 hd = (HD_BCPIO *)buf; 1022 if (swp_head) { 1023 /* 1024 * header has swapped bytes on 16 bit boundaries 1025 */ 1026 arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev)); 1027 arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino)); 1028 arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode)); 1029 arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid)); 1030 arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid)); 1031 arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink)); 1032 arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev)); 1033 arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1)); 1034 arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 1035 ((time_t)(RSHRT_EXT(hd->h_mtime_2))); 1036 arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1)); 1037 arcn->sb.st_size = (arcn->sb.st_size << 16) | 1038 ((off_t)(RSHRT_EXT(hd->h_filesize_2))); 1039 nsz = (int)(RSHRT_EXT(hd->h_namesize)); 1040 } else { 1041 arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev)); 1042 arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino)); 1043 arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode)); 1044 arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid)); 1045 arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid)); 1046 arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink)); 1047 arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev)); 1048 arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1)); 1049 arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 1050 ((time_t)(SHRT_EXT(hd->h_mtime_2))); 1051 arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1)); 1052 arcn->sb.st_size = (arcn->sb.st_size << 16) | 1053 ((off_t)(SHRT_EXT(hd->h_filesize_2))); 1054 nsz = (int)(SHRT_EXT(hd->h_namesize)); 1055 } 1056 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 1057 1058 /* 1059 * check the file name size, if bogus give up. otherwise read the file 1060 * name 1061 */ 1062 if (nsz < 2) 1063 return(-1); 1064 arcn->nlen = nsz - 1; 1065 if (rd_nm(arcn, nsz) < 0) 1066 return(-1); 1067 1068 /* 1069 * header + file name are aligned to 2 byte boundries, skip if needed 1070 */ 1071 if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0) 1072 return(-1); 1073 1074 /* 1075 * if not a link (or a file with no data), calculate pad size (for 1076 * padding which follows the file data), clear the link name and return 1077 */ 1078 if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){ 1079 /* 1080 * we have a valid header (not a link) 1081 */ 1082 arcn->ln_nlen = 0; 1083 arcn->ln_name[0] = '\0'; 1084 arcn->pad = BCPIO_PAD(arcn->sb.st_size); 1085 return(com_rd(arcn)); 1086 } 1087 1088 if ((rd_ln_nm(arcn) < 0) || 1089 (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0)) 1090 return(-1); 1091 1092 /* 1093 * we have a valid header (with a link) 1094 */ 1095 return(com_rd(arcn)); 1096 } 1097 1098 /* 1099 * bcpio_endrd() 1100 * no cleanup needed here, just return size of the trailer (for append) 1101 * Return: 1102 * size of trailer header in this format 1103 */ 1104 1105 #ifdef __STDC__ 1106 off_t 1107 bcpio_endrd(void) 1108 #else 1109 off_t 1110 bcpio_endrd() 1111 #endif 1112 { 1113 return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) + 1114 (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER))))); 1115 } 1116 1117 /* 1118 * bcpio_wr() 1119 * copy the data in the ARCHD to buffer in old binary cpio format 1120 * There is a real chance of field overflow with this critter. So we 1121 * always check the conversion is ok. nobody in his their right mind 1122 * should write an achive in this format... 1123 * Return 1124 * 0 if file has data to be written after the header, 1 if file has NO 1125 * data to write after the header, -1 if archive write failed 1126 */ 1127 1128 #ifdef __STDC__ 1129 int 1130 bcpio_wr(register ARCHD *arcn) 1131 #else 1132 int 1133 bcpio_wr(arcn) 1134 register ARCHD *arcn; 1135 #endif 1136 { 1137 register HD_BCPIO *hd; 1138 register int nsz; 1139 char hdblk[sizeof(HD_BCPIO)]; 1140 off_t t_offt; 1141 int t_int; 1142 time_t t_timet; 1143 1144 /* 1145 * check and repair truncated device and inode fields in the cpio 1146 * header 1147 */ 1148 if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0) 1149 return(-1); 1150 1151 if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 1152 arcn->sb.st_rdev = 0; 1153 hd = (HD_BCPIO *)hdblk; 1154 1155 switch(arcn->type) { 1156 case PAX_CTG: 1157 case PAX_REG: 1158 case PAX_HRG: 1159 /* 1160 * caller will copy file data to the archive. tell him how 1161 * much to pad. 1162 */ 1163 arcn->pad = BCPIO_PAD(arcn->sb.st_size); 1164 hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size); 1165 hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size); 1166 hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size); 1167 hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size); 1168 t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1)); 1169 t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2))); 1170 if (arcn->sb.st_size != t_offt) { 1171 paxwarn(1,"File is too large for bcpio format %s", 1172 arcn->org_name); 1173 return(1); 1174 } 1175 break; 1176 case PAX_SLK: 1177 /* 1178 * no file data for the caller to process, the file data has 1179 * the size of the link 1180 */ 1181 arcn->pad = 0L; 1182 hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen); 1183 hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen); 1184 hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen); 1185 hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen); 1186 t_int = (int)(SHRT_EXT(hd->h_filesize_1)); 1187 t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2))); 1188 if (arcn->ln_nlen != t_int) 1189 goto out; 1190 break; 1191 default: 1192 /* 1193 * no file data for the caller to process 1194 */ 1195 arcn->pad = 0L; 1196 hd->h_filesize_1[0] = (char)0; 1197 hd->h_filesize_1[1] = (char)0; 1198 hd->h_filesize_2[0] = (char)0; 1199 hd->h_filesize_2[1] = (char)0; 1200 break; 1201 } 1202 1203 /* 1204 * build up the rest of the fields 1205 */ 1206 hd->h_magic[0] = CHR_WR_2(MAGIC); 1207 hd->h_magic[1] = CHR_WR_3(MAGIC); 1208 hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev); 1209 hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev); 1210 if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev))) 1211 goto out; 1212 hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino); 1213 hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino); 1214 if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino))) 1215 goto out; 1216 hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode); 1217 hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode); 1218 if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode))) 1219 goto out; 1220 hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid); 1221 hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid); 1222 if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid))) 1223 goto out; 1224 hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid); 1225 hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid); 1226 if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid))) 1227 goto out; 1228 hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink); 1229 hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink); 1230 if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink))) 1231 goto out; 1232 hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev); 1233 hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev); 1234 if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev))) 1235 goto out; 1236 hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime); 1237 hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime); 1238 hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime); 1239 hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime); 1240 t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1)); 1241 t_timet = (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2))); 1242 if (arcn->sb.st_mtime != t_timet) 1243 goto out; 1244 nsz = arcn->nlen + 1; 1245 hd->h_namesize[0] = CHR_WR_2(nsz); 1246 hd->h_namesize[1] = CHR_WR_3(nsz); 1247 if (nsz != (int)(SHRT_EXT(hd->h_namesize))) 1248 goto out; 1249 1250 /* 1251 * write the header, the file name and padding as required. 1252 */ 1253 if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) || 1254 (wr_rdbuf(arcn->name, nsz) < 0) || 1255 (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) { 1256 paxwarn(1, "Could not write bcpio header for %s", arcn->org_name); 1257 return(-1); 1258 } 1259 1260 /* 1261 * if we have file data, tell the caller we are done 1262 */ 1263 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 1264 (arcn->type == PAX_HRG)) 1265 return(0); 1266 1267 /* 1268 * if we are not a link, tell the caller we are done, go to next file 1269 */ 1270 if (arcn->type != PAX_SLK) 1271 return(1); 1272 1273 /* 1274 * write the link name, tell the caller we are done. 1275 */ 1276 if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 1277 (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) { 1278 paxwarn(1,"Could not write bcpio link name for %s",arcn->org_name); 1279 return(-1); 1280 } 1281 return(1); 1282 1283 out: 1284 /* 1285 * header field is out of range 1286 */ 1287 paxwarn(1,"Bcpio header field is too small for file %s", arcn->org_name); 1288 return(1); 1289 } 1290