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