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