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