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