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