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