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