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