1 /*- 2 * Copyright (c) 2003-2007 Tim Kientzle 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 28 #include "cpio_platform.h" 29 __FBSDID("$FreeBSD$"); 30 31 #include <sys/types.h> 32 #include <archive.h> 33 #include <archive_entry.h> 34 35 #ifdef HAVE_SYS_MKDEV_H 36 #include <sys/mkdev.h> 37 #endif 38 #ifdef HAVE_SYS_STAT_H 39 #include <sys/stat.h> 40 #endif 41 #ifdef HAVE_SYS_TIME_H 42 #include <sys/time.h> 43 #endif 44 #ifdef HAVE_ERRNO_H 45 #include <errno.h> 46 #endif 47 #ifdef HAVE_FCNTL_H 48 #include <fcntl.h> 49 #endif 50 #ifdef HAVE_GRP_H 51 #include <grp.h> 52 #endif 53 #ifdef HAVE_PWD_H 54 #include <pwd.h> 55 #endif 56 #ifdef HAVE_STDARG_H 57 #include <stdarg.h> 58 #endif 59 #ifdef HAVE_STDINT_H 60 #include <stdint.h> 61 #endif 62 #include <stdio.h> 63 #ifdef HAVE_STDLIB_H 64 #include <stdlib.h> 65 #endif 66 #ifdef HAVE_STRING_H 67 #include <string.h> 68 #endif 69 #ifdef HAVE_UNISTD_H 70 #include <unistd.h> 71 #endif 72 #ifdef HAVE_SYS_TIME_H 73 #include <sys/time.h> 74 #endif 75 #ifdef HAVE_TIME_H 76 #include <time.h> 77 #endif 78 79 #include "cpio.h" 80 #include "err.h" 81 #include "line_reader.h" 82 #include "matching.h" 83 84 /* Fixed size of uname/gname caches. */ 85 #define name_cache_size 101 86 87 #ifndef O_BINARY 88 #define O_BINARY 0 89 #endif 90 91 struct name_cache { 92 int probes; 93 int hits; 94 size_t size; 95 struct { 96 id_t id; 97 char *name; 98 } cache[name_cache_size]; 99 }; 100 101 static int extract_data(struct archive *, struct archive *); 102 const char * cpio_i64toa(int64_t); 103 static const char *cpio_rename(const char *name); 104 static int entry_to_archive(struct cpio *, struct archive_entry *); 105 static int file_to_archive(struct cpio *, const char *); 106 static void free_cache(struct name_cache *cache); 107 static void list_item_verbose(struct cpio *, struct archive_entry *); 108 static void long_help(void); 109 static const char *lookup_gname(struct cpio *, gid_t gid); 110 static int lookup_gname_helper(struct cpio *, 111 const char **name, id_t gid); 112 static const char *lookup_uname(struct cpio *, uid_t uid); 113 static int lookup_uname_helper(struct cpio *, 114 const char **name, id_t uid); 115 static void mode_in(struct cpio *); 116 static void mode_list(struct cpio *); 117 static void mode_out(struct cpio *); 118 static void mode_pass(struct cpio *, const char *); 119 static int restore_time(struct cpio *, struct archive_entry *, 120 const char *, int fd); 121 static void usage(void); 122 static void version(void); 123 124 int 125 main(int argc, char *argv[]) 126 { 127 static char buff[16384]; 128 struct cpio _cpio; /* Allocated on stack. */ 129 struct cpio *cpio; 130 const char *errmsg; 131 int uid, gid; 132 int opt; 133 134 cpio = &_cpio; 135 memset(cpio, 0, sizeof(*cpio)); 136 cpio->buff = buff; 137 cpio->buff_size = sizeof(buff); 138 139 /* Need lafe_progname before calling lafe_warnc. */ 140 if (*argv == NULL) 141 lafe_progname = "bsdcpio"; 142 else { 143 #if defined(_WIN32) && !defined(__CYGWIN__) 144 lafe_progname = strrchr(*argv, '\\'); 145 #else 146 lafe_progname = strrchr(*argv, '/'); 147 #endif 148 if (lafe_progname != NULL) 149 lafe_progname++; 150 else 151 lafe_progname = *argv; 152 } 153 154 cpio->uid_override = -1; 155 cpio->gid_override = -1; 156 cpio->argv = argv; 157 cpio->argc = argc; 158 cpio->mode = '\0'; 159 cpio->verbose = 0; 160 cpio->compress = '\0'; 161 cpio->extract_flags = ARCHIVE_EXTRACT_NO_AUTODIR; 162 cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; 163 cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS; 164 cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT; 165 cpio->extract_flags |= ARCHIVE_EXTRACT_PERM; 166 cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; 167 cpio->extract_flags |= ARCHIVE_EXTRACT_ACL; 168 #if !defined(_WIN32) && !defined(__CYGWIN__) 169 if (geteuid() == 0) 170 cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER; 171 #endif 172 cpio->bytes_per_block = 512; 173 cpio->filename = NULL; 174 175 while ((opt = cpio_getopt(cpio)) != -1) { 176 switch (opt) { 177 case '0': /* GNU convention: --null, -0 */ 178 cpio->option_null = 1; 179 break; 180 case 'A': /* NetBSD/OpenBSD */ 181 cpio->option_append = 1; 182 break; 183 case 'a': /* POSIX 1997 */ 184 cpio->option_atime_restore = 1; 185 break; 186 case 'B': /* POSIX 1997 */ 187 cpio->bytes_per_block = 5120; 188 break; 189 case 'C': /* NetBSD/OpenBSD */ 190 cpio->bytes_per_block = atoi(cpio->optarg); 191 if (cpio->bytes_per_block <= 0) 192 lafe_errc(1, 0, "Invalid blocksize %s", cpio->optarg); 193 break; 194 case 'c': /* POSIX 1997 */ 195 cpio->format = "odc"; 196 break; 197 case 'd': /* POSIX 1997 */ 198 cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR; 199 break; 200 case 'E': /* NetBSD/OpenBSD */ 201 lafe_include_from_file(&cpio->matching, 202 cpio->optarg, cpio->option_null); 203 break; 204 case 'F': /* NetBSD/OpenBSD/GNU cpio */ 205 cpio->filename = cpio->optarg; 206 break; 207 case 'f': /* POSIX 1997 */ 208 lafe_exclude(&cpio->matching, cpio->optarg); 209 break; 210 case 'H': /* GNU cpio (also --format) */ 211 cpio->format = cpio->optarg; 212 break; 213 case 'h': 214 long_help(); 215 break; 216 case 'I': /* NetBSD/OpenBSD */ 217 cpio->filename = cpio->optarg; 218 break; 219 case 'i': /* POSIX 1997 */ 220 if (cpio->mode != '\0') 221 lafe_errc(1, 0, 222 "Cannot use both -i and -%c", cpio->mode); 223 cpio->mode = opt; 224 break; 225 case 'J': /* GNU tar, others */ 226 cpio->compress = opt; 227 break; 228 case 'j': /* GNU tar, others */ 229 cpio->compress = opt; 230 break; 231 case OPTION_INSECURE: 232 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS; 233 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; 234 break; 235 case 'L': /* GNU cpio */ 236 cpio->option_follow_links = 1; 237 break; 238 case 'l': /* POSIX 1997 */ 239 cpio->option_link = 1; 240 break; 241 case OPTION_LZMA: /* GNU tar, others */ 242 cpio->compress = opt; 243 break; 244 case 'm': /* POSIX 1997 */ 245 cpio->extract_flags |= ARCHIVE_EXTRACT_TIME; 246 break; 247 case 'n': /* GNU cpio */ 248 cpio->option_numeric_uid_gid = 1; 249 break; 250 case OPTION_NO_PRESERVE_OWNER: /* GNU cpio */ 251 cpio->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; 252 break; 253 case 'O': /* GNU cpio */ 254 cpio->filename = cpio->optarg; 255 break; 256 case 'o': /* POSIX 1997 */ 257 if (cpio->mode != '\0') 258 lafe_errc(1, 0, 259 "Cannot use both -o and -%c", cpio->mode); 260 cpio->mode = opt; 261 break; 262 case 'p': /* POSIX 1997 */ 263 if (cpio->mode != '\0') 264 lafe_errc(1, 0, 265 "Cannot use both -p and -%c", cpio->mode); 266 cpio->mode = opt; 267 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; 268 break; 269 case OPTION_PRESERVE_OWNER: 270 cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER; 271 break; 272 case OPTION_QUIET: /* GNU cpio */ 273 cpio->quiet = 1; 274 break; 275 case 'R': /* GNU cpio, also --owner */ 276 /* TODO: owner_parse should return uname/gname 277 * also; use that to set [ug]name_override. */ 278 errmsg = owner_parse(cpio->optarg, &uid, &gid); 279 if (errmsg) { 280 lafe_warnc(-1, "%s", errmsg); 281 usage(); 282 } 283 if (uid != -1) { 284 cpio->uid_override = uid; 285 cpio->uname_override = NULL; 286 } 287 if (gid != -1) { 288 cpio->gid_override = gid; 289 cpio->gname_override = NULL; 290 } 291 break; 292 case 'r': /* POSIX 1997 */ 293 cpio->option_rename = 1; 294 break; 295 case 't': /* POSIX 1997 */ 296 cpio->option_list = 1; 297 break; 298 case 'u': /* POSIX 1997 */ 299 cpio->extract_flags 300 &= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; 301 break; 302 case 'v': /* POSIX 1997 */ 303 cpio->verbose++; 304 break; 305 case OPTION_VERSION: /* GNU convention */ 306 version(); 307 break; 308 #if 0 309 /* 310 * cpio_getopt() handles -W specially, so it's not 311 * available here. 312 */ 313 case 'W': /* Obscure, but useful GNU convention. */ 314 break; 315 #endif 316 case 'y': /* tar convention */ 317 cpio->compress = opt; 318 break; 319 case 'Z': /* tar convention */ 320 cpio->compress = opt; 321 break; 322 case 'z': /* tar convention */ 323 cpio->compress = opt; 324 break; 325 default: 326 usage(); 327 } 328 } 329 330 /* 331 * Sanity-check args, error out on nonsensical combinations. 332 */ 333 /* -t implies -i if no mode was specified. */ 334 if (cpio->option_list && cpio->mode == '\0') 335 cpio->mode = 'i'; 336 /* -t requires -i */ 337 if (cpio->option_list && cpio->mode != 'i') 338 lafe_errc(1, 0, "Option -t requires -i"); 339 /* -n requires -it */ 340 if (cpio->option_numeric_uid_gid && !cpio->option_list) 341 lafe_errc(1, 0, "Option -n requires -it"); 342 /* Can only specify format when writing */ 343 if (cpio->format != NULL && cpio->mode != 'o') 344 lafe_errc(1, 0, "Option --format requires -o"); 345 /* -l requires -p */ 346 if (cpio->option_link && cpio->mode != 'p') 347 lafe_errc(1, 0, "Option -l requires -p"); 348 /* TODO: Flag other nonsensical combinations. */ 349 350 switch (cpio->mode) { 351 case 'o': 352 /* TODO: Implement old binary format in libarchive, 353 use that here. */ 354 if (cpio->format == NULL) 355 cpio->format = "odc"; /* Default format */ 356 357 mode_out(cpio); 358 break; 359 case 'i': 360 while (*cpio->argv != NULL) { 361 lafe_include(&cpio->matching, *cpio->argv); 362 --cpio->argc; 363 ++cpio->argv; 364 } 365 if (cpio->option_list) 366 mode_list(cpio); 367 else 368 mode_in(cpio); 369 break; 370 case 'p': 371 if (*cpio->argv == NULL || **cpio->argv == '\0') 372 lafe_errc(1, 0, 373 "-p mode requires a target directory"); 374 mode_pass(cpio, *cpio->argv); 375 break; 376 default: 377 lafe_errc(1, 0, 378 "Must specify at least one of -i, -o, or -p"); 379 } 380 381 free_cache(cpio->gname_cache); 382 free_cache(cpio->uname_cache); 383 return (cpio->return_value); 384 } 385 386 static void 387 usage(void) 388 { 389 const char *p; 390 391 p = lafe_progname; 392 393 fprintf(stderr, "Brief Usage:\n"); 394 fprintf(stderr, " List: %s -it < archive\n", p); 395 fprintf(stderr, " Extract: %s -i < archive\n", p); 396 fprintf(stderr, " Create: %s -o < filenames > archive\n", p); 397 fprintf(stderr, " Help: %s --help\n", p); 398 exit(1); 399 } 400 401 static const char *long_help_msg = 402 "First option must be a mode specifier:\n" 403 " -i Input -o Output -p Pass\n" 404 "Common Options:\n" 405 " -v Verbose\n" 406 "Create: %p -o [options] < [list of files] > [archive]\n" 407 " -J,-y,-z,--lzma Compress archive with xz/bzip2/gzip/lzma\n" 408 " --format {odc|newc|ustar} Select archive format\n" 409 "List: %p -it < [archive]\n" 410 "Extract: %p -i [options] < [archive]\n"; 411 412 413 /* 414 * Note that the word 'bsdcpio' will always appear in the first line 415 * of output. 416 * 417 * In particular, /bin/sh scripts that need to test for the presence 418 * of bsdcpio can use the following template: 419 * 420 * if (cpio --help 2>&1 | grep bsdcpio >/dev/null 2>&1 ) then \ 421 * echo bsdcpio; else echo not bsdcpio; fi 422 */ 423 static void 424 long_help(void) 425 { 426 const char *prog; 427 const char *p; 428 429 prog = lafe_progname; 430 431 fflush(stderr); 432 433 p = (strcmp(prog,"bsdcpio") != 0) ? "(bsdcpio)" : ""; 434 printf("%s%s: manipulate archive files\n", prog, p); 435 436 for (p = long_help_msg; *p != '\0'; p++) { 437 if (*p == '%') { 438 if (p[1] == 'p') { 439 fputs(prog, stdout); 440 p++; 441 } else 442 putchar('%'); 443 } else 444 putchar(*p); 445 } 446 version(); 447 } 448 449 static void 450 version(void) 451 { 452 fprintf(stdout,"bsdcpio %s -- %s\n", 453 BSDCPIO_VERSION_STRING, 454 archive_version()); 455 exit(0); 456 } 457 458 static void 459 mode_out(struct cpio *cpio) 460 { 461 struct archive_entry *entry, *spare; 462 struct lafe_line_reader *lr; 463 const char *p; 464 int r; 465 466 if (cpio->option_append) 467 lafe_errc(1, 0, "Append mode not yet supported."); 468 469 cpio->archive_read_disk = archive_read_disk_new(); 470 if (cpio->archive_read_disk == NULL) 471 lafe_errc(1, 0, "Failed to allocate archive object"); 472 if (cpio->option_follow_links) 473 archive_read_disk_set_symlink_logical(cpio->archive_read_disk); 474 else 475 archive_read_disk_set_symlink_physical(cpio->archive_read_disk); 476 archive_read_disk_set_standard_lookup(cpio->archive_read_disk); 477 478 cpio->archive = archive_write_new(); 479 if (cpio->archive == NULL) 480 lafe_errc(1, 0, "Failed to allocate archive object"); 481 switch (cpio->compress) { 482 case 'J': 483 r = archive_write_set_compression_xz(cpio->archive); 484 break; 485 case OPTION_LZMA: 486 r = archive_write_set_compression_lzma(cpio->archive); 487 break; 488 case 'j': case 'y': 489 r = archive_write_set_compression_bzip2(cpio->archive); 490 break; 491 case 'z': 492 r = archive_write_set_compression_gzip(cpio->archive); 493 break; 494 case 'Z': 495 r = archive_write_set_compression_compress(cpio->archive); 496 break; 497 default: 498 r = archive_write_set_compression_none(cpio->archive); 499 break; 500 } 501 if (r < ARCHIVE_WARN) 502 lafe_errc(1, 0, "Requested compression not available"); 503 r = archive_write_set_format_by_name(cpio->archive, cpio->format); 504 if (r != ARCHIVE_OK) 505 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 506 archive_write_set_bytes_per_block(cpio->archive, cpio->bytes_per_block); 507 cpio->linkresolver = archive_entry_linkresolver_new(); 508 archive_entry_linkresolver_set_strategy(cpio->linkresolver, 509 archive_format(cpio->archive)); 510 511 /* 512 * The main loop: Copy each file into the output archive. 513 */ 514 r = archive_write_open_file(cpio->archive, cpio->filename); 515 if (r != ARCHIVE_OK) 516 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 517 lr = lafe_line_reader("-", cpio->option_null); 518 while ((p = lafe_line_reader_next(lr)) != NULL) 519 file_to_archive(cpio, p); 520 lafe_line_reader_free(lr); 521 522 /* 523 * The hardlink detection may have queued up a couple of entries 524 * that can now be flushed. 525 */ 526 entry = NULL; 527 archive_entry_linkify(cpio->linkresolver, &entry, &spare); 528 while (entry != NULL) { 529 entry_to_archive(cpio, entry); 530 archive_entry_free(entry); 531 entry = NULL; 532 archive_entry_linkify(cpio->linkresolver, &entry, &spare); 533 } 534 535 r = archive_write_close(cpio->archive); 536 if (r != ARCHIVE_OK) 537 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 538 539 if (!cpio->quiet) { 540 int64_t blocks = 541 (archive_position_uncompressed(cpio->archive) + 511) 542 / 512; 543 fprintf(stderr, "%lu %s\n", (unsigned long)blocks, 544 blocks == 1 ? "block" : "blocks"); 545 } 546 archive_write_finish(cpio->archive); 547 } 548 549 /* 550 * This is used by both out mode (to copy objects from disk into 551 * an archive) and pass mode (to copy objects from disk to 552 * an archive_write_disk "archive"). 553 */ 554 static int 555 file_to_archive(struct cpio *cpio, const char *srcpath) 556 { 557 const char *destpath; 558 struct archive_entry *entry, *spare; 559 size_t len; 560 const char *p; 561 int r; 562 563 /* 564 * Create an archive_entry describing the source file. 565 * 566 */ 567 entry = archive_entry_new(); 568 if (entry == NULL) 569 lafe_errc(1, 0, "Couldn't allocate entry"); 570 archive_entry_copy_sourcepath(entry, srcpath); 571 r = archive_read_disk_entry_from_file(cpio->archive_read_disk, 572 entry, -1, NULL); 573 if (r < ARCHIVE_FAILED) 574 lafe_errc(1, 0, "%s", 575 archive_error_string(cpio->archive_read_disk)); 576 if (r < ARCHIVE_OK) 577 lafe_warnc(0, "%s", 578 archive_error_string(cpio->archive_read_disk)); 579 if (r <= ARCHIVE_FAILED) { 580 cpio->return_value = 1; 581 return (r); 582 } 583 584 if (cpio->uid_override >= 0) { 585 archive_entry_set_uid(entry, cpio->uid_override); 586 archive_entry_set_uname(entry, cpio->uname_override); 587 } 588 if (cpio->gid_override >= 0) { 589 archive_entry_set_gid(entry, cpio->gid_override); 590 archive_entry_set_gname(entry, cpio->gname_override); 591 } 592 593 /* 594 * Generate a destination path for this entry. 595 * "destination path" is the name to which it will be copied in 596 * pass mode or the name that will go into the archive in 597 * output mode. 598 */ 599 destpath = srcpath; 600 if (cpio->destdir) { 601 len = strlen(cpio->destdir) + strlen(srcpath) + 8; 602 if (len >= cpio->pass_destpath_alloc) { 603 while (len >= cpio->pass_destpath_alloc) { 604 cpio->pass_destpath_alloc += 512; 605 cpio->pass_destpath_alloc *= 2; 606 } 607 free(cpio->pass_destpath); 608 cpio->pass_destpath = malloc(cpio->pass_destpath_alloc); 609 if (cpio->pass_destpath == NULL) 610 lafe_errc(1, ENOMEM, 611 "Can't allocate path buffer"); 612 } 613 strcpy(cpio->pass_destpath, cpio->destdir); 614 p = srcpath; 615 while (p[0] == '/') 616 ++p; 617 strcat(cpio->pass_destpath, p); 618 destpath = cpio->pass_destpath; 619 } 620 if (cpio->option_rename) 621 destpath = cpio_rename(destpath); 622 if (destpath == NULL) 623 return (0); 624 archive_entry_copy_pathname(entry, destpath); 625 626 /* 627 * If we're trying to preserve hardlinks, match them here. 628 */ 629 spare = NULL; 630 if (cpio->linkresolver != NULL 631 && archive_entry_filetype(entry) != AE_IFDIR) { 632 archive_entry_linkify(cpio->linkresolver, &entry, &spare); 633 } 634 635 if (entry != NULL) { 636 r = entry_to_archive(cpio, entry); 637 archive_entry_free(entry); 638 if (spare != NULL) { 639 if (r == 0) 640 r = entry_to_archive(cpio, spare); 641 archive_entry_free(spare); 642 } 643 } 644 return (r); 645 } 646 647 static int 648 entry_to_archive(struct cpio *cpio, struct archive_entry *entry) 649 { 650 const char *destpath = archive_entry_pathname(entry); 651 const char *srcpath = archive_entry_sourcepath(entry); 652 int fd = -1; 653 ssize_t bytes_read; 654 int r; 655 656 /* Print out the destination name to the user. */ 657 if (cpio->verbose) 658 fprintf(stderr,"%s", destpath); 659 660 /* 661 * Option_link only makes sense in pass mode and for 662 * regular files. Also note: if a link operation fails 663 * because of cross-device restrictions, we'll fall back 664 * to copy mode for that entry. 665 * 666 * TODO: Test other cpio implementations to see if they 667 * hard-link anything other than regular files here. 668 */ 669 if (cpio->option_link 670 && archive_entry_filetype(entry) == AE_IFREG) 671 { 672 struct archive_entry *t; 673 /* Save the original entry in case we need it later. */ 674 t = archive_entry_clone(entry); 675 if (t == NULL) 676 lafe_errc(1, ENOMEM, "Can't create link"); 677 /* Note: link(2) doesn't create parent directories, 678 * so we use archive_write_header() instead as a 679 * convenience. */ 680 archive_entry_set_hardlink(t, srcpath); 681 /* This is a straight link that carries no data. */ 682 archive_entry_set_size(t, 0); 683 r = archive_write_header(cpio->archive, t); 684 archive_entry_free(t); 685 if (r != ARCHIVE_OK) 686 lafe_warnc(archive_errno(cpio->archive), 687 "%s", archive_error_string(cpio->archive)); 688 if (r == ARCHIVE_FATAL) 689 exit(1); 690 #ifdef EXDEV 691 if (r != ARCHIVE_OK && archive_errno(cpio->archive) == EXDEV) { 692 /* Cross-device link: Just fall through and use 693 * the original entry to copy the file over. */ 694 lafe_warnc(0, "Copying file instead"); 695 } else 696 #endif 697 return (0); 698 } 699 700 /* 701 * Make sure we can open the file (if necessary) before 702 * trying to write the header. 703 */ 704 if (archive_entry_filetype(entry) == AE_IFREG) { 705 if (archive_entry_size(entry) > 0) { 706 fd = open(srcpath, O_RDONLY | O_BINARY); 707 if (fd < 0) { 708 lafe_warnc(errno, 709 "%s: could not open file", srcpath); 710 goto cleanup; 711 } 712 } 713 } else { 714 archive_entry_set_size(entry, 0); 715 } 716 717 r = archive_write_header(cpio->archive, entry); 718 719 if (r != ARCHIVE_OK) 720 lafe_warnc(archive_errno(cpio->archive), 721 "%s: %s", 722 srcpath, 723 archive_error_string(cpio->archive)); 724 725 if (r == ARCHIVE_FATAL) 726 exit(1); 727 728 if (r >= ARCHIVE_WARN && fd >= 0) { 729 bytes_read = read(fd, cpio->buff, cpio->buff_size); 730 while (bytes_read > 0) { 731 r = archive_write_data(cpio->archive, 732 cpio->buff, bytes_read); 733 if (r < 0) 734 lafe_errc(1, archive_errno(cpio->archive), 735 "%s", archive_error_string(cpio->archive)); 736 if (r < bytes_read) { 737 lafe_warnc(0, 738 "Truncated write; file may have grown while being archived."); 739 } 740 bytes_read = read(fd, cpio->buff, cpio->buff_size); 741 } 742 } 743 744 fd = restore_time(cpio, entry, srcpath, fd); 745 746 cleanup: 747 if (cpio->verbose) 748 fprintf(stderr,"\n"); 749 if (fd >= 0) 750 close(fd); 751 return (0); 752 } 753 754 static int 755 restore_time(struct cpio *cpio, struct archive_entry *entry, 756 const char *name, int fd) 757 { 758 #ifndef HAVE_UTIMES 759 static int warned = 0; 760 761 (void)cpio; /* UNUSED */ 762 (void)entry; /* UNUSED */ 763 (void)name; /* UNUSED */ 764 765 if (!warned) 766 lafe_warnc(0, "Can't restore access times on this platform"); 767 warned = 1; 768 return (fd); 769 #else 770 #if defined(_WIN32) && !defined(__CYGWIN__) 771 struct __timeval times[2]; 772 #else 773 struct timeval times[2]; 774 #endif 775 776 if (!cpio->option_atime_restore) 777 return (fd); 778 779 times[1].tv_sec = archive_entry_mtime(entry); 780 times[1].tv_usec = archive_entry_mtime_nsec(entry) / 1000; 781 782 times[0].tv_sec = archive_entry_atime(entry); 783 times[0].tv_usec = archive_entry_atime_nsec(entry) / 1000; 784 785 #if defined(HAVE_FUTIMES) && !defined(__CYGWIN__) 786 if (fd >= 0 && futimes(fd, times) == 0) 787 return (fd); 788 #endif 789 /* 790 * Some platform cannot restore access times if the file descriptor 791 * is still opened. 792 */ 793 if (fd >= 0) { 794 close(fd); 795 fd = -1; 796 } 797 798 #ifdef HAVE_LUTIMES 799 if (lutimes(name, times) != 0) 800 #else 801 if ((AE_IFLNK != archive_entry_filetype(entry)) 802 && utimes(name, times) != 0) 803 #endif 804 lafe_warnc(errno, "Can't update time for %s", name); 805 #endif 806 return (fd); 807 } 808 809 810 static void 811 mode_in(struct cpio *cpio) 812 { 813 struct archive *a; 814 struct archive_entry *entry; 815 struct archive *ext; 816 const char *destpath; 817 int r; 818 819 ext = archive_write_disk_new(); 820 if (ext == NULL) 821 lafe_errc(1, 0, "Couldn't allocate restore object"); 822 r = archive_write_disk_set_options(ext, cpio->extract_flags); 823 if (r != ARCHIVE_OK) 824 lafe_errc(1, 0, "%s", archive_error_string(ext)); 825 a = archive_read_new(); 826 if (a == NULL) 827 lafe_errc(1, 0, "Couldn't allocate archive object"); 828 archive_read_support_compression_all(a); 829 archive_read_support_format_all(a); 830 831 if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block)) 832 lafe_errc(1, archive_errno(a), 833 "%s", archive_error_string(a)); 834 for (;;) { 835 r = archive_read_next_header(a, &entry); 836 if (r == ARCHIVE_EOF) 837 break; 838 if (r != ARCHIVE_OK) { 839 lafe_errc(1, archive_errno(a), 840 "%s", archive_error_string(a)); 841 } 842 if (lafe_excluded(cpio->matching, archive_entry_pathname(entry))) 843 continue; 844 if (cpio->option_rename) { 845 destpath = cpio_rename(archive_entry_pathname(entry)); 846 archive_entry_set_pathname(entry, destpath); 847 } else 848 destpath = archive_entry_pathname(entry); 849 if (destpath == NULL) 850 continue; 851 if (cpio->verbose) 852 fprintf(stdout, "%s\n", destpath); 853 if (cpio->uid_override >= 0) 854 archive_entry_set_uid(entry, cpio->uid_override); 855 if (cpio->gid_override >= 0) 856 archive_entry_set_gid(entry, cpio->gid_override); 857 r = archive_write_header(ext, entry); 858 if (r != ARCHIVE_OK) { 859 fprintf(stderr, "%s: %s\n", 860 archive_entry_pathname(entry), 861 archive_error_string(ext)); 862 } else if (archive_entry_size(entry) > 0) { 863 r = extract_data(a, ext); 864 if (r != ARCHIVE_OK) 865 cpio->return_value = 1; 866 } 867 } 868 r = archive_read_close(a); 869 if (r != ARCHIVE_OK) 870 lafe_errc(1, 0, "%s", archive_error_string(a)); 871 r = archive_write_close(ext); 872 if (r != ARCHIVE_OK) 873 lafe_errc(1, 0, "%s", archive_error_string(ext)); 874 if (!cpio->quiet) { 875 int64_t blocks = (archive_position_uncompressed(a) + 511) 876 / 512; 877 fprintf(stderr, "%lu %s\n", (unsigned long)blocks, 878 blocks == 1 ? "block" : "blocks"); 879 } 880 archive_read_finish(a); 881 archive_write_finish(ext); 882 exit(cpio->return_value); 883 } 884 885 /* 886 * Exits if there's a fatal error. Returns ARCHIVE_OK 887 * if everything is kosher. 888 */ 889 static int 890 extract_data(struct archive *ar, struct archive *aw) 891 { 892 int r; 893 size_t size; 894 const void *block; 895 off_t offset; 896 897 for (;;) { 898 r = archive_read_data_block(ar, &block, &size, &offset); 899 if (r == ARCHIVE_EOF) 900 return (ARCHIVE_OK); 901 if (r != ARCHIVE_OK) { 902 lafe_warnc(archive_errno(ar), 903 "%s", archive_error_string(ar)); 904 exit(1); 905 } 906 r = archive_write_data_block(aw, block, size, offset); 907 if (r != ARCHIVE_OK) { 908 lafe_warnc(archive_errno(aw), 909 "%s", archive_error_string(aw)); 910 return (r); 911 } 912 } 913 } 914 915 static void 916 mode_list(struct cpio *cpio) 917 { 918 struct archive *a; 919 struct archive_entry *entry; 920 int r; 921 922 a = archive_read_new(); 923 if (a == NULL) 924 lafe_errc(1, 0, "Couldn't allocate archive object"); 925 archive_read_support_compression_all(a); 926 archive_read_support_format_all(a); 927 928 if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block)) 929 lafe_errc(1, archive_errno(a), 930 "%s", archive_error_string(a)); 931 for (;;) { 932 r = archive_read_next_header(a, &entry); 933 if (r == ARCHIVE_EOF) 934 break; 935 if (r != ARCHIVE_OK) { 936 lafe_errc(1, archive_errno(a), 937 "%s", archive_error_string(a)); 938 } 939 if (lafe_excluded(cpio->matching, archive_entry_pathname(entry))) 940 continue; 941 if (cpio->verbose) 942 list_item_verbose(cpio, entry); 943 else 944 fprintf(stdout, "%s\n", archive_entry_pathname(entry)); 945 } 946 r = archive_read_close(a); 947 if (r != ARCHIVE_OK) 948 lafe_errc(1, 0, "%s", archive_error_string(a)); 949 if (!cpio->quiet) { 950 int64_t blocks = (archive_position_uncompressed(a) + 511) 951 / 512; 952 fprintf(stderr, "%lu %s\n", (unsigned long)blocks, 953 blocks == 1 ? "block" : "blocks"); 954 } 955 archive_read_finish(a); 956 exit(0); 957 } 958 959 /* 960 * Display information about the current file. 961 * 962 * The format here roughly duplicates the output of 'ls -l'. 963 * This is based on SUSv2, where 'tar tv' is documented as 964 * listing additional information in an "unspecified format," 965 * and 'pax -l' is documented as using the same format as 'ls -l'. 966 */ 967 static void 968 list_item_verbose(struct cpio *cpio, struct archive_entry *entry) 969 { 970 char size[32]; 971 char date[32]; 972 char uids[16], gids[16]; 973 const char *uname, *gname; 974 FILE *out = stdout; 975 const char *fmt; 976 time_t mtime; 977 static time_t now; 978 979 if (!now) 980 time(&now); 981 982 if (cpio->option_numeric_uid_gid) { 983 /* Format numeric uid/gid for display. */ 984 strcpy(uids, cpio_i64toa(archive_entry_uid(entry))); 985 uname = uids; 986 strcpy(gids, cpio_i64toa(archive_entry_gid(entry))); 987 gname = gids; 988 } else { 989 /* Use uname if it's present, else lookup name from uid. */ 990 uname = archive_entry_uname(entry); 991 if (uname == NULL) 992 uname = lookup_uname(cpio, archive_entry_uid(entry)); 993 /* Use gname if it's present, else lookup name from gid. */ 994 gname = archive_entry_gname(entry); 995 if (gname == NULL) 996 gname = lookup_gname(cpio, archive_entry_gid(entry)); 997 } 998 999 /* Print device number or file size. */ 1000 if (archive_entry_filetype(entry) == AE_IFCHR 1001 || archive_entry_filetype(entry) == AE_IFBLK) { 1002 snprintf(size, sizeof(size), "%lu,%lu", 1003 (unsigned long)archive_entry_rdevmajor(entry), 1004 (unsigned long)archive_entry_rdevminor(entry)); 1005 } else { 1006 strcpy(size, cpio_i64toa(archive_entry_size(entry))); 1007 } 1008 1009 /* Format the time using 'ls -l' conventions. */ 1010 mtime = archive_entry_mtime(entry); 1011 #if defined(_WIN32) && !defined(__CYGWIN__) 1012 /* Windows' strftime function does not support %e format. */ 1013 if (mtime - now > 365*86400/2 1014 || mtime - now < -365*86400/2) 1015 fmt = cpio->day_first ? "%d %b %Y" : "%b %d %Y"; 1016 else 1017 fmt = cpio->day_first ? "%d %b %H:%M" : "%b %d %H:%M"; 1018 #else 1019 if (abs(mtime - now) > (365/2)*86400) 1020 fmt = cpio->day_first ? "%e %b %Y" : "%b %e %Y"; 1021 else 1022 fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M"; 1023 #endif 1024 strftime(date, sizeof(date), fmt, localtime(&mtime)); 1025 1026 fprintf(out, "%s%3d %-8s %-8s %8s %12s %s", 1027 archive_entry_strmode(entry), 1028 archive_entry_nlink(entry), 1029 uname, gname, size, date, 1030 archive_entry_pathname(entry)); 1031 1032 /* Extra information for links. */ 1033 if (archive_entry_hardlink(entry)) /* Hard link */ 1034 fprintf(out, " link to %s", archive_entry_hardlink(entry)); 1035 else if (archive_entry_symlink(entry)) /* Symbolic link */ 1036 fprintf(out, " -> %s", archive_entry_symlink(entry)); 1037 fprintf(out, "\n"); 1038 } 1039 1040 static void 1041 mode_pass(struct cpio *cpio, const char *destdir) 1042 { 1043 struct lafe_line_reader *lr; 1044 const char *p; 1045 int r; 1046 1047 /* Ensure target dir has a trailing '/' to simplify path surgery. */ 1048 cpio->destdir = malloc(strlen(destdir) + 8); 1049 strcpy(cpio->destdir, destdir); 1050 if (destdir[strlen(destdir) - 1] != '/') 1051 strcat(cpio->destdir, "/"); 1052 1053 cpio->archive = archive_write_disk_new(); 1054 if (cpio->archive == NULL) 1055 lafe_errc(1, 0, "Failed to allocate archive object"); 1056 r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags); 1057 if (r != ARCHIVE_OK) 1058 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 1059 cpio->linkresolver = archive_entry_linkresolver_new(); 1060 archive_write_disk_set_standard_lookup(cpio->archive); 1061 1062 cpio->archive_read_disk = archive_read_disk_new(); 1063 if (cpio->archive_read_disk == NULL) 1064 lafe_errc(1, 0, "Failed to allocate archive object"); 1065 if (cpio->option_follow_links) 1066 archive_read_disk_set_symlink_logical(cpio->archive_read_disk); 1067 else 1068 archive_read_disk_set_symlink_physical(cpio->archive_read_disk); 1069 archive_read_disk_set_standard_lookup(cpio->archive_read_disk); 1070 1071 lr = lafe_line_reader("-", cpio->option_null); 1072 while ((p = lafe_line_reader_next(lr)) != NULL) 1073 file_to_archive(cpio, p); 1074 lafe_line_reader_free(lr); 1075 1076 archive_entry_linkresolver_free(cpio->linkresolver); 1077 r = archive_write_close(cpio->archive); 1078 if (r != ARCHIVE_OK) 1079 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 1080 1081 if (!cpio->quiet) { 1082 int64_t blocks = 1083 (archive_position_uncompressed(cpio->archive) + 511) 1084 / 512; 1085 fprintf(stderr, "%lu %s\n", (unsigned long)blocks, 1086 blocks == 1 ? "block" : "blocks"); 1087 } 1088 1089 archive_write_finish(cpio->archive); 1090 } 1091 1092 /* 1093 * Prompt for a new name for this entry. Returns a pointer to the 1094 * new name or NULL if the entry should not be copied. This 1095 * implements the semantics defined in POSIX.1-1996, which specifies 1096 * that an input of '.' means the name should be unchanged. GNU cpio 1097 * treats '.' as a literal new name. 1098 */ 1099 static const char * 1100 cpio_rename(const char *name) 1101 { 1102 static char buff[1024]; 1103 FILE *t; 1104 char *p, *ret; 1105 1106 t = fopen("/dev/tty", "r+"); 1107 if (t == NULL) 1108 return (name); 1109 fprintf(t, "%s (Enter/./(new name))? ", name); 1110 fflush(t); 1111 1112 p = fgets(buff, sizeof(buff), t); 1113 fclose(t); 1114 if (p == NULL) 1115 /* End-of-file is a blank line. */ 1116 return (NULL); 1117 1118 while (*p == ' ' || *p == '\t') 1119 ++p; 1120 if (*p == '\n' || *p == '\0') 1121 /* Empty line. */ 1122 return (NULL); 1123 if (*p == '.' && p[1] == '\n') 1124 /* Single period preserves original name. */ 1125 return (name); 1126 ret = p; 1127 /* Trim the final newline. */ 1128 while (*p != '\0' && *p != '\n') 1129 ++p; 1130 /* Overwrite the final \n with a null character. */ 1131 *p = '\0'; 1132 return (ret); 1133 } 1134 1135 static void 1136 free_cache(struct name_cache *cache) 1137 { 1138 size_t i; 1139 1140 if (cache != NULL) { 1141 for (i = 0; i < cache->size; i++) 1142 free(cache->cache[i].name); 1143 free(cache); 1144 } 1145 } 1146 1147 /* 1148 * Lookup uname/gname from uid/gid, return NULL if no match. 1149 */ 1150 static const char * 1151 lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable, 1152 int (*lookup_fn)(struct cpio *, const char **, id_t), id_t id) 1153 { 1154 char asnum[16]; 1155 struct name_cache *cache; 1156 const char *name; 1157 int slot; 1158 1159 1160 if (*name_cache_variable == NULL) { 1161 *name_cache_variable = malloc(sizeof(struct name_cache)); 1162 if (*name_cache_variable == NULL) 1163 lafe_errc(1, ENOMEM, "No more memory"); 1164 memset(*name_cache_variable, 0, sizeof(struct name_cache)); 1165 (*name_cache_variable)->size = name_cache_size; 1166 } 1167 1168 cache = *name_cache_variable; 1169 cache->probes++; 1170 1171 slot = id % cache->size; 1172 if (cache->cache[slot].name != NULL) { 1173 if (cache->cache[slot].id == id) { 1174 cache->hits++; 1175 return (cache->cache[slot].name); 1176 } 1177 free(cache->cache[slot].name); 1178 cache->cache[slot].name = NULL; 1179 } 1180 1181 if (lookup_fn(cpio, &name, id) == 0) { 1182 if (name == NULL || name[0] == '\0') { 1183 /* If lookup failed, format it as a number. */ 1184 snprintf(asnum, sizeof(asnum), "%u", (unsigned)id); 1185 name = asnum; 1186 } 1187 cache->cache[slot].name = strdup(name); 1188 if (cache->cache[slot].name != NULL) { 1189 cache->cache[slot].id = id; 1190 return (cache->cache[slot].name); 1191 } 1192 /* 1193 * Conveniently, NULL marks an empty slot, so 1194 * if the strdup() fails, we've just failed to 1195 * cache it. No recovery necessary. 1196 */ 1197 } 1198 return (NULL); 1199 } 1200 1201 static const char * 1202 lookup_uname(struct cpio *cpio, uid_t uid) 1203 { 1204 return (lookup_name(cpio, &cpio->uname_cache, 1205 &lookup_uname_helper, (id_t)uid)); 1206 } 1207 1208 static int 1209 lookup_uname_helper(struct cpio *cpio, const char **name, id_t id) 1210 { 1211 struct passwd *pwent; 1212 1213 (void)cpio; /* UNUSED */ 1214 1215 errno = 0; 1216 pwent = getpwuid((uid_t)id); 1217 if (pwent == NULL) { 1218 *name = NULL; 1219 if (errno != 0 && errno != ENOENT) 1220 lafe_warnc(errno, "getpwuid(%d) failed", id); 1221 return (errno); 1222 } 1223 1224 *name = pwent->pw_name; 1225 return (0); 1226 } 1227 1228 static const char * 1229 lookup_gname(struct cpio *cpio, gid_t gid) 1230 { 1231 return (lookup_name(cpio, &cpio->gname_cache, 1232 &lookup_gname_helper, (id_t)gid)); 1233 } 1234 1235 static int 1236 lookup_gname_helper(struct cpio *cpio, const char **name, id_t id) 1237 { 1238 struct group *grent; 1239 1240 (void)cpio; /* UNUSED */ 1241 1242 errno = 0; 1243 grent = getgrgid((gid_t)id); 1244 if (grent == NULL) { 1245 *name = NULL; 1246 if (errno != 0) 1247 lafe_warnc(errno, "getgrgid(%d) failed", id); 1248 return (errno); 1249 } 1250 1251 *name = grent->gr_name; 1252 return (0); 1253 } 1254 1255 /* 1256 * It would be nice to just use printf() for formatting large numbers, 1257 * but the compatibility problems are a big headache. Hence the 1258 * following simple utility function. 1259 */ 1260 const char * 1261 cpio_i64toa(int64_t n0) 1262 { 1263 // 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice. 1264 // We also need 1 byte for '-' and 1 for '\0'. 1265 static char buff[22]; 1266 int64_t n = n0 < 0 ? -n0 : n0; 1267 char *p = buff + sizeof(buff); 1268 1269 *--p = '\0'; 1270 do { 1271 *--p = '0' + (int)(n % 10); 1272 n /= 10; 1273 } while (n > 0); 1274 if (n0 < 0) 1275 *--p = '-'; 1276 return p; 1277 } 1278