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