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