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