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