1/* $NetBSD: cpio.c,v 1.21 2011/03/26 12:01:06 martin 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. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#if HAVE_NBTOOL_CONFIG_H 37#include "nbtool_config.h" 38#endif 39 40#include <sys/cdefs.h> 41#if !defined(lint) 42#if 0 43static char sccsid[] = "@(#)cpio.c 8.1 (Berkeley) 5/31/93"; 44#else 45__RCSID("$NetBSD: cpio.c,v 1.21 2011/03/26 12:01:06 martin 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 62static int rd_nm(ARCHD *, int); 63static int rd_ln_nm(ARCHD *); 64static int com_rd(ARCHD *); 65 66/* 67 * Routines which support the different cpio versions 68 */ 69 70int 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 83int 84cpio_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 99int 100cpio_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 117static int 118com_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 166int 167cpio_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 189static int 190rd_nm(ARCHD *arcn, int nsz) 191{ 192 /* 193 * do not even try bogus values 194 */ 195 if ((nsz <= 0) || (nsz > (int)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 219static int 220rd_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 >= (off_t)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 265int 266cpio_id(char *blk, int size) 267{ 268 if ((size < (int)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 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 353off_t 354cpio_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 366int 367cpio_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 381int 382cpio_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 return 0; 471 if (arcn->type != PAX_SLK) 472 return 1; 473 474 /* 475 * write the link name to the archive, tell the caller to go to the 476 * next file as we are done. 477 */ 478 if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) { 479 tty_warn(1,"Unable to write cpio link name for %s", 480 arcn->org_name); 481 return -1; 482 } 483 return 1; 484 485 out: 486 /* 487 * header field is out of range 488 */ 489 tty_warn(1, "Cpio header field is too small to store file %s", 490 arcn->org_name); 491 return 1; 492} 493 494/* 495 * Routines common to the system VR4 version of cpio (with/without file CRC) 496 */ 497 498/* 499 * vcpio_id() 500 * determine if a block given to us is a valid system VR4 cpio header 501 * WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header 502 * uses HEX 503 * Return: 504 * 0 if a valid header, -1 otherwise 505 */ 506 507int 508vcpio_id(char *blk, int size) 509{ 510 if ((size < (int)sizeof(HD_VCPIO)) || 511 (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0)) 512 return -1; 513 return 0; 514} 515 516/* 517 * crc_id() 518 * determine if a block given to us is a valid system VR4 cpio header 519 * WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX 520 * Return: 521 * 0 if a valid header, -1 otherwise 522 */ 523 524int 525crc_id(char *blk, int size) 526{ 527 if ((size < (int)sizeof(HD_VCPIO)) || 528 (strncmp(blk, AVCMAGIC, sizeof(AVCMAGIC) - 1) != 0)) 529 return -1; 530 return 0; 531} 532 533/* 534 * crc_strd() 535 * set file data CRC calculations. Fire up the hard link detection code 536 * Return: 537 * 0 if ok -1 otherwise (the return values of lnk_start()) 538 */ 539 540int 541crc_strd(void) 542{ 543 docrc = 1; 544 return lnk_start(); 545} 546 547/* 548 * vcpio_rd() 549 * determine if a buffer is a system VR4 archive entry. (with/without CRC) 550 * convert and store the values in the ARCHD parameter. 551 * Return: 552 * 0 if a valid header, -1 otherwise. 553 */ 554 555int 556vcpio_rd(ARCHD *arcn, char *buf) 557{ 558 HD_VCPIO *hd; 559 dev_t devminor; 560 dev_t devmajor; 561 int nsz; 562 563 /* 564 * during the id phase it was determined if we were using CRC, use the 565 * proper id routine. 566 */ 567 if (docrc) { 568 if (crc_id(buf, sizeof(HD_VCPIO)) < 0) 569 return -1; 570 } else { 571 if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0) 572 return -1; 573 } 574 575 hd = (HD_VCPIO *)buf; 576 arcn->pad = 0L; 577 578 /* 579 * extract the hex ascii fields from the header 580 */ 581 arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX); 582 arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX); 583 arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX); 584 arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX); 585 arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX); 586 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 587 arcn->sb.st_size = (off_t)ASC_OFFT(hd->c_filesize, 588 sizeof(hd->c_filesize), HEX); 589 arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 590 HEX); 591 devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX); 592 devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX); 593 arcn->sb.st_dev = TODEV(devmajor, devminor); 594 devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX); 595 devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX); 596 arcn->sb.st_rdev = TODEV(devmajor, devminor); 597 arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX); 598 599 /* 600 * check the length of the file name, if ok read it in, return -1 if 601 * bogus 602 */ 603 if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2) 604 return -1; 605 arcn->nlen = nsz - 1; 606 if (rd_nm(arcn, nsz) < 0) 607 return -1; 608 609 /* 610 * skip padding. header + filename is aligned to 4 byte boundaries 611 */ 612 if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0) 613 return -1; 614 615 /* 616 * if not a link (or a file with no data), calculate pad size (for 617 * padding which follows the file data), clear the link name and return 618 */ 619 if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 620 /* 621 * we have a valid header (not a link) 622 */ 623 arcn->ln_nlen = 0; 624 arcn->ln_name[0] = '\0'; 625 arcn->pad = VCPIO_PAD(arcn->sb.st_size); 626 return com_rd(arcn); 627 } 628 629 /* 630 * read in the link name and skip over the padding 631 */ 632 if ((rd_ln_nm(arcn) < 0) || 633 (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0)) 634 return -1; 635 636 /* 637 * we have a valid header (with a link) 638 */ 639 return com_rd(arcn); 640} 641 642/* 643 * vcpio_endrd() 644 * no cleanup needed here, just return size of the trailer (for append) 645 * Return: 646 * size of trailer header in this format 647 */ 648 649off_t 650vcpio_endrd(void) 651{ 652 return (off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) + 653 (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER)))); 654} 655 656/* 657 * crc_stwr() 658 * start up the device mapping table, enable crc file calculation 659 * Return: 660 * 0 if ok, -1 otherwise (what dev_start() returns) 661 */ 662 663int 664crc_stwr(void) 665{ 666 docrc = 1; 667 return dev_start(); 668} 669 670/* 671 * vcpio_wr() 672 * copy the data in the ARCHD to buffer in system VR4 cpio 673 * (with/without crc) format. 674 * Return 675 * 0 if file has data to be written after the header, 1 if file has 676 * NO data to write after the header, -1 if archive write failed 677 */ 678 679int 680vcpio_wr(ARCHD *arcn) 681{ 682 HD_VCPIO *hd; 683 unsigned int nsz; 684 char hdblk[sizeof(HD_VCPIO)]; 685 686 /* 687 * check and repair truncated device and inode fields in the cpio 688 * header 689 */ 690 if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0) 691 return -1; 692 nsz = arcn->nlen + 1; 693 hd = (HD_VCPIO *)hdblk; 694 if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 695 arcn->sb.st_rdev = 0; 696 697 /* 698 * add the proper magic value depending whether we were asked for 699 * file data crc's, and the crc if needed. 700 */ 701 if (docrc) { 702 if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic), 703 OCT) || 704 ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum), 705 HEX)) 706 goto out; 707 } else { 708 if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic), 709 OCT) || 710 ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX)) 711 goto out; 712 } 713 714 switch(arcn->type) { 715 case PAX_CTG: 716 case PAX_REG: 717 case PAX_HRG: 718 /* 719 * caller will copy file data to the archive. tell him how 720 * much to pad. 721 */ 722 arcn->pad = VCPIO_PAD(arcn->sb.st_size); 723 if (OFFT_ASC(arcn->sb.st_size, hd->c_filesize, 724 sizeof(hd->c_filesize), HEX)) { 725 tty_warn(1,"File is too large for sv4cpio format %s", 726 arcn->org_name); 727 return 1; 728 } 729 break; 730 case PAX_SLK: 731 /* 732 * no file data for the caller to process, the file data has 733 * the size of the link 734 */ 735 arcn->pad = 0L; 736 if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 737 sizeof(hd->c_filesize), HEX)) 738 goto out; 739 break; 740 default: 741 /* 742 * no file data for the caller to process 743 */ 744 arcn->pad = 0L; 745 if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize), 746 HEX)) 747 goto out; 748 break; 749 } 750 751 /* 752 * set the other fields in the header 753 */ 754 if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 755 HEX) || 756 ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 757 HEX) || 758 ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 759 HEX) || 760 ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 761 HEX) || 762 ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime), 763 HEX) || 764 ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 765 HEX) || 766 ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj), 767 HEX) || 768 ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min), 769 HEX) || 770 ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj), 771 HEX) || 772 ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min), 773 HEX) || 774 ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX)) 775 goto out; 776 777 /* 778 * write the header, the file name and padding as required. 779 */ 780 if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) || 781 (wr_rdbuf(arcn->name, (int)nsz) < 0) || 782 (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) { 783 tty_warn(1,"Could not write sv4cpio header for %s", 784 arcn->org_name); 785 return -1; 786 } 787 788 /* 789 * if we have file data, tell the caller we are done, copy the file 790 */ 791 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 792 (arcn->type == PAX_HRG)) 793 return 0; 794 795 /* 796 * if we are not a link, tell the caller we are done, go to next file 797 */ 798 if (arcn->type != PAX_SLK) 799 return 1; 800 801 /* 802 * write the link name, tell the caller we are done. 803 */ 804 if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 805 (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) { 806 tty_warn(1,"Could not write sv4cpio link name for %s", 807 arcn->org_name); 808 return -1; 809 } 810 return 1; 811 812 out: 813 /* 814 * header field is out of range 815 */ 816 tty_warn(1,"Sv4cpio header field is too small for file %s", 817 arcn->org_name); 818 return 1; 819} 820 821/* 822 * Routines common to the old binary header cpio 823 */ 824 825/* 826 * bcpio_id() 827 * determine if a block given to us is a old binary cpio header 828 * (with/without header byte swapping) 829 * Return: 830 * 0 if a valid header, -1 otherwise 831 */ 832 833int 834bcpio_id(char *blk, int size) 835{ 836 if (size < (int)sizeof(HD_BCPIO)) 837 return -1; 838 839 /* 840 * check both normal and byte swapped magic cookies 841 */ 842 if (((u_short)SHRT_EXT(blk)) == MAGIC) 843 return 0; 844 if (((u_short)RSHRT_EXT(blk)) == MAGIC) { 845 if (!cpio_swp_head) 846 ++cpio_swp_head; 847 return 0; 848 } 849 return -1; 850} 851 852/* 853 * bcpio_rd() 854 * determine if a buffer is a old binary archive entry. (it may have byte 855 * swapped header) convert and store the values in the ARCHD parameter. 856 * This is a very old header format and should not really be used. 857 * Return: 858 * 0 if a valid header, -1 otherwise. 859 */ 860 861int 862bcpio_rd(ARCHD *arcn, char *buf) 863{ 864 HD_BCPIO *hd; 865 int nsz; 866 867 /* 868 * check the header 869 */ 870 if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0) 871 return -1; 872 873 arcn->pad = 0L; 874 hd = (HD_BCPIO *)buf; 875 if (cpio_swp_head) { 876 /* 877 * header has swapped bytes on 16 bit boundaries 878 */ 879 arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev)); 880 arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino)); 881 arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode)); 882 arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid)); 883 arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid)); 884 arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink)); 885 arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev)); 886 arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1)); 887 arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 888 ((time_t)(RSHRT_EXT(hd->h_mtime_2))); 889 arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1)); 890 arcn->sb.st_size = (arcn->sb.st_size << 16) | 891 ((off_t)(RSHRT_EXT(hd->h_filesize_2))); 892 nsz = (int)(RSHRT_EXT(hd->h_namesize)); 893 } else { 894 arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev)); 895 arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino)); 896 arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode)); 897 arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid)); 898 arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid)); 899 arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink)); 900 arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev)); 901 arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1)); 902 arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 903 ((time_t)(SHRT_EXT(hd->h_mtime_2))); 904 arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1)); 905 arcn->sb.st_size = (arcn->sb.st_size << 16) | 906 ((off_t)(SHRT_EXT(hd->h_filesize_2))); 907 nsz = (int)(SHRT_EXT(hd->h_namesize)); 908 } 909 arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; 910 911 /* 912 * check the file name size, if bogus give up. otherwise read the file 913 * name 914 */ 915 if (nsz < 2) 916 return -1; 917 arcn->nlen = nsz - 1; 918 if (rd_nm(arcn, nsz) < 0) 919 return -1; 920 921 /* 922 * header + file name are aligned to 2 byte boundaries, skip if needed 923 */ 924 if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0) 925 return -1; 926 927 /* 928 * if not a link (or a file with no data), calculate pad size (for 929 * padding which follows the file data), clear the link name and return 930 */ 931 if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){ 932 /* 933 * we have a valid header (not a link) 934 */ 935 arcn->ln_nlen = 0; 936 arcn->ln_name[0] = '\0'; 937 arcn->pad = BCPIO_PAD(arcn->sb.st_size); 938 return com_rd(arcn); 939 } 940 941 if ((rd_ln_nm(arcn) < 0) || 942 (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0)) 943 return -1; 944 945 /* 946 * we have a valid header (with a link) 947 */ 948 return com_rd(arcn); 949} 950 951/* 952 * bcpio_endrd() 953 * no cleanup needed here, just return size of the trailer (for append) 954 * Return: 955 * size of trailer header in this format 956 */ 957 958off_t 959bcpio_endrd(void) 960{ 961 return (off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) + 962 (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER)))); 963} 964 965/* 966 * bcpio_wr() 967 * copy the data in the ARCHD to buffer in old binary cpio format 968 * There is a real chance of field overflow with this critter. So we 969 * always check the conversion is ok. nobody in their right mind 970 * should write an archive in this format... 971 * Return 972 * 0 if file has data to be written after the header, 1 if file has NO 973 * data to write after the header, -1 if archive write failed 974 */ 975 976int 977bcpio_wr(ARCHD *arcn) 978{ 979 HD_BCPIO *hd; 980 int nsz; 981 char hdblk[sizeof(HD_BCPIO)]; 982 off_t t_offt; 983 int t_int; 984 time_t t_timet; 985 986 /* 987 * check and repair truncated device and inode fields in the cpio 988 * header 989 */ 990 if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0) 991 return -1; 992 993 if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 994 arcn->sb.st_rdev = 0; 995 hd = (HD_BCPIO *)hdblk; 996 997 switch(arcn->type) { 998 case PAX_CTG: 999 case PAX_REG: 1000 case PAX_HRG: 1001 /* 1002 * caller will copy file data to the archive. tell him how 1003 * much to pad. 1004 */ 1005 arcn->pad = BCPIO_PAD(arcn->sb.st_size); 1006 hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size); 1007 hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size); 1008 hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size); 1009 hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size); 1010 t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1)); 1011 t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2))); 1012 if (arcn->sb.st_size != t_offt) { 1013 tty_warn(1,"File is too large for bcpio format %s", 1014 arcn->org_name); 1015 return 1; 1016 } 1017 break; 1018 case PAX_SLK: 1019 /* 1020 * no file data for the caller to process, the file data has 1021 * the size of the link 1022 */ 1023 arcn->pad = 0L; 1024 hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen); 1025 hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen); 1026 hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen); 1027 hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen); 1028 t_int = (int)(SHRT_EXT(hd->h_filesize_1)); 1029 t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2))); 1030 if (arcn->ln_nlen != t_int) 1031 goto out; 1032 break; 1033 default: 1034 /* 1035 * no file data for the caller to process 1036 */ 1037 arcn->pad = 0L; 1038 hd->h_filesize_1[0] = (char)0; 1039 hd->h_filesize_1[1] = (char)0; 1040 hd->h_filesize_2[0] = (char)0; 1041 hd->h_filesize_2[1] = (char)0; 1042 break; 1043 } 1044 1045 /* 1046 * build up the rest of the fields 1047 */ 1048 hd->h_magic[0] = CHR_WR_2(MAGIC); 1049 hd->h_magic[1] = CHR_WR_3(MAGIC); 1050 hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev); 1051 hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev); 1052 if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev))) 1053 goto out; 1054 hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino); 1055 hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino); 1056 if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino))) 1057 goto out; 1058 hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode); 1059 hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode); 1060 if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode))) 1061 goto out; 1062 hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid); 1063 hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid); 1064 if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid))) 1065 goto out; 1066 hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid); 1067 hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid); 1068 if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid))) 1069 goto out; 1070 hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink); 1071 hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink); 1072 if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink))) 1073 goto out; 1074 hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev); 1075 hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev); 1076 if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev))) 1077 goto out; 1078 hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime); 1079 hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime); 1080 hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime); 1081 hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime); 1082 t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1)); 1083 t_timet = (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2))); 1084 if (arcn->sb.st_mtime != t_timet) 1085 goto out; 1086 nsz = arcn->nlen + 1; 1087 hd->h_namesize[0] = CHR_WR_2(nsz); 1088 hd->h_namesize[1] = CHR_WR_3(nsz); 1089 if (nsz != (int)(SHRT_EXT(hd->h_namesize))) 1090 goto out; 1091 1092 /* 1093 * write the header, the file name and padding as required. 1094 */ 1095 if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) || 1096 (wr_rdbuf(arcn->name, nsz) < 0) || 1097 (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) { 1098 tty_warn(1, "Could not write bcpio header for %s", 1099 arcn->org_name); 1100 return -1; 1101 } 1102 1103 /* 1104 * if we have file data, tell the caller we are done 1105 */ 1106 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 1107 (arcn->type == PAX_HRG)) 1108 return 0; 1109 1110 /* 1111 * if we are not a link, tell the caller we are done, go to next file 1112 */ 1113 if (arcn->type != PAX_SLK) 1114 return 1; 1115 1116 /* 1117 * write the link name, tell the caller we are done. 1118 */ 1119 if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 1120 (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) { 1121 tty_warn(1,"Could not write bcpio link name for %s", 1122 arcn->org_name); 1123 return -1; 1124 } 1125 return 1; 1126 1127 out: 1128 /* 1129 * header field is out of range 1130 */ 1131 tty_warn(1,"Bcpio header field is too small for file %s", 1132 arcn->org_name); 1133 return 1; 1134} 1135