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