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