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