1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2003-2007 Tim Kientzle 5 * All rights reserved. 6 */ 7 8 9 #include "cpio_platform.h" 10 11 #include "lafe_getline.h" 12 13 #include <sys/types.h> 14 #include <archive.h> 15 #include <archive_entry.h> 16 17 #ifdef HAVE_SYS_MKDEV_H 18 #include <sys/mkdev.h> 19 #endif 20 #ifdef HAVE_SYS_STAT_H 21 #include <sys/stat.h> 22 #endif 23 #ifdef HAVE_SYS_TIME_H 24 #include <sys/time.h> 25 #endif 26 #ifdef HAVE_ERRNO_H 27 #include <errno.h> 28 #endif 29 #ifdef HAVE_FCNTL_H 30 #include <fcntl.h> 31 #endif 32 #ifdef HAVE_GRP_H 33 #include <grp.h> 34 #endif 35 #ifdef HAVE_LOCALE_H 36 #include <locale.h> 37 #endif 38 #ifdef HAVE_LIMITS_H 39 #include <limits.h> 40 #endif 41 #ifdef HAVE_PWD_H 42 #include <pwd.h> 43 #endif 44 #ifdef HAVE_SIGNAL_H 45 #include <signal.h> 46 #endif 47 #ifdef HAVE_STDARG_H 48 #include <stdarg.h> 49 #endif 50 #ifdef HAVE_STDINT_H 51 #include <stdint.h> 52 #endif 53 #include <stdio.h> 54 #ifdef HAVE_STDLIB_H 55 #include <stdlib.h> 56 #endif 57 #ifdef HAVE_STRING_H 58 #include <string.h> 59 #endif 60 #ifdef HAVE_UNISTD_H 61 #include <unistd.h> 62 #endif 63 #ifdef HAVE_TIME_H 64 #include <time.h> 65 #endif 66 67 #include "cpio.h" 68 #include "lafe_err.h" 69 #include "line_reader.h" 70 #include "passphrase.h" 71 72 /* Fixed size of uname/gname caches. */ 73 #define name_cache_size 101 74 75 #ifndef O_BINARY 76 #define O_BINARY 0 77 #endif 78 79 struct name_cache { 80 int probes; 81 int hits; 82 size_t size; 83 struct { 84 id_t id; 85 char *name; 86 } cache[name_cache_size]; 87 }; 88 89 static int extract_data(struct archive *, struct archive *); 90 const char * cpio_i64toa(int64_t); 91 static void cpio_rename(struct archive_entry *); 92 static int entry_to_archive(struct cpio *, struct archive_entry *); 93 static int file_to_archive(struct cpio *, const char *); 94 static void free_cache(struct name_cache *cache); 95 static void list_item_verbose(struct cpio *, struct archive_entry *); 96 static __LA_NORETURN void long_help(void); 97 static const char *lookup_gname(struct cpio *, gid_t gid); 98 static int lookup_gname_helper(struct cpio *, 99 const char **name, id_t gid); 100 static const char *lookup_uname(struct cpio *, uid_t uid); 101 static int lookup_uname_helper(struct cpio *, 102 const char **name, id_t uid); 103 static __LA_NORETURN void mode_in(struct cpio *); 104 static __LA_NORETURN void mode_list(struct cpio *); 105 static void mode_out(struct cpio *); 106 static void mode_pass(struct cpio *, const char *); 107 static const char *remove_leading_slash(const char *); 108 static int restore_time(struct cpio *, struct archive_entry *, 109 const char *, int fd); 110 static __LA_NORETURN void usage(void); 111 static __LA_NORETURN void version(void); 112 static const char * passphrase_callback(struct archive *, void *); 113 static void passphrase_free(char *); 114 115 int 116 main(int argc, char *argv[]) 117 { 118 struct cpio _cpio; /* Allocated on stack. */ 119 struct cpio *cpio; 120 struct cpio_owner owner; 121 const char *errmsg; 122 char *tptr; 123 int opt; 124 long t; 125 126 cpio = &_cpio; 127 memset(cpio, 0, sizeof(*cpio)); 128 129 #if defined(HAVE_SIGACTION) 130 { 131 struct sigaction sa; 132 sigemptyset(&sa.sa_mask); 133 sa.sa_flags = 0; 134 #ifdef SIGPIPE 135 /* Ignore SIGPIPE signals. */ 136 sa.sa_handler = SIG_IGN; 137 sigaction(SIGPIPE, &sa, NULL); 138 #endif 139 #ifdef SIGCHLD 140 /* Do not ignore SIGCHLD. */ 141 sa.sa_handler = SIG_DFL; 142 sigaction(SIGCHLD, &sa, NULL); 143 #endif 144 } 145 #endif 146 147 /* Set lafe_progname before calling lafe_warnc. */ 148 lafe_setprogname(*argv, "bsdcpio"); 149 150 #if HAVE_SETLOCALE 151 if (setlocale(LC_ALL, "") == NULL) 152 lafe_warnc(0, "Failed to set default locale"); 153 #endif 154 155 cpio->uid_override = -1; 156 cpio->uname_override = NULL; 157 cpio->gid_override = -1; 158 cpio->gname_override = NULL; 159 cpio->argv = argv; 160 cpio->argc = argc; 161 cpio->mode = '\0'; 162 cpio->verbose = 0; 163 cpio->compress = '\0'; 164 cpio->extract_flags = ARCHIVE_EXTRACT_NO_AUTODIR; 165 cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; 166 cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS; 167 cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT; 168 cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; 169 cpio->extract_flags |= ARCHIVE_EXTRACT_PERM; 170 cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; 171 cpio->extract_flags |= ARCHIVE_EXTRACT_ACL; 172 #if !defined(_WIN32) && !defined(__CYGWIN__) 173 if (geteuid() == 0) 174 cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER; 175 #endif 176 cpio->bytes_per_block = 512; 177 cpio->filename = NULL; 178 179 cpio->matching = archive_match_new(); 180 if (cpio->matching == NULL) 181 lafe_errc(1, 0, "Out of memory"); 182 183 while ((opt = cpio_getopt(cpio)) != -1) { 184 switch (opt) { 185 case '0': /* GNU convention: --null, -0 */ 186 cpio->option_null = 1; 187 break; 188 case '6': /* in/out: assume/create 6th edition (PWB) format */ 189 cpio->option_pwb = 1; 190 break; 191 case '7': /* out: create archive using 7th Edition binary format */ 192 cpio->format = "bin"; 193 break; 194 case 'A': /* NetBSD/OpenBSD */ 195 cpio->option_append = 1; 196 break; 197 case 'a': /* POSIX 1997 */ 198 cpio->option_atime_restore = 1; 199 break; 200 case 'B': /* POSIX 1997 */ 201 cpio->bytes_per_block = 5120; 202 break; 203 case OPTION_B64ENCODE: 204 cpio->add_filter = opt; 205 break; 206 case 'C': /* NetBSD/OpenBSD */ 207 errno = 0; 208 tptr = NULL; 209 t = strtol(cpio->argument, &tptr, 10); 210 if (errno || t <= 0 || t > INT_MAX || *(cpio->argument) == '\0' || 211 tptr == NULL || *tptr != '\0') { 212 lafe_errc(1, 0, "Invalid blocksize: %s", 213 cpio->argument); 214 } 215 cpio->bytes_per_block = (int)t; 216 break; 217 case 'c': /* POSIX 1997 */ 218 cpio->format = "odc"; 219 break; 220 case 'd': /* POSIX 1997 */ 221 cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR; 222 break; 223 case 'E': /* NetBSD/OpenBSD */ 224 if (archive_match_include_pattern_from_file( 225 cpio->matching, cpio->argument, 226 cpio->option_null) != ARCHIVE_OK) 227 lafe_errc(1, 0, "%s", 228 archive_error_string(cpio->matching)); 229 break; 230 case 'F': /* NetBSD/OpenBSD/GNU cpio */ 231 cpio->filename = cpio->argument; 232 break; 233 case 'f': /* POSIX 1997 */ 234 if (archive_match_exclude_pattern(cpio->matching, 235 cpio->argument) != ARCHIVE_OK) 236 lafe_errc(1, 0, "%s", 237 archive_error_string(cpio->matching)); 238 break; 239 case OPTION_GRZIP: 240 cpio->compress = opt; 241 break; 242 case 'H': /* GNU cpio (also --format) */ 243 cpio->format = cpio->argument; 244 break; 245 case 'h': 246 long_help(); 247 /* NOTREACHED */ 248 case 'I': /* NetBSD/OpenBSD */ 249 cpio->filename = cpio->argument; 250 break; 251 case 'i': /* POSIX 1997 */ 252 if (cpio->mode != '\0' && cpio->mode != opt) 253 lafe_errc(1, 0, 254 "Cannot use both -i and -%c", cpio->mode); 255 cpio->mode = opt; 256 break; 257 case 'J': /* GNU tar, others */ 258 cpio->compress = opt; 259 break; 260 case 'j': /* GNU tar, others */ 261 cpio->compress = opt; 262 break; 263 case OPTION_INSECURE: 264 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS; 265 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; 266 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; 267 break; 268 case 'L': /* GNU cpio */ 269 cpio->option_follow_links = 1; 270 break; 271 case 'l': /* POSIX 1997 */ 272 cpio->option_link = 1; 273 break; 274 case OPTION_LRZIP: 275 case OPTION_LZ4: 276 case OPTION_LZMA: /* GNU tar, others */ 277 case OPTION_LZOP: /* GNU tar, others */ 278 case OPTION_ZSTD: 279 cpio->compress = opt; 280 break; 281 case 'm': /* POSIX 1997 */ 282 cpio->extract_flags |= ARCHIVE_EXTRACT_TIME; 283 break; 284 case 'n': /* GNU cpio */ 285 cpio->option_numeric_uid_gid = 1; 286 break; 287 case OPTION_NO_PRESERVE_OWNER: /* GNU cpio */ 288 cpio->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; 289 break; 290 case 'O': /* GNU cpio */ 291 cpio->filename = cpio->argument; 292 break; 293 case 'o': /* POSIX 1997 */ 294 if (cpio->mode != '\0' && cpio->mode != opt) 295 lafe_errc(1, 0, 296 "Cannot use both -o and -%c", cpio->mode); 297 cpio->mode = opt; 298 break; 299 case 'p': /* POSIX 1997 */ 300 if (cpio->mode != '\0' && cpio->mode != opt) 301 lafe_errc(1, 0, 302 "Cannot use both -p and -%c", cpio->mode); 303 cpio->mode = opt; 304 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; 305 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; 306 break; 307 case OPTION_PASSPHRASE: 308 cpio->passphrase = cpio->argument; 309 break; 310 case OPTION_PRESERVE_OWNER: 311 cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER; 312 break; 313 case OPTION_QUIET: /* GNU cpio */ 314 cpio->quiet = 1; 315 break; 316 case 'R': /* GNU cpio, also --owner */ 317 errmsg = NULL; 318 if (owner_parse(cpio->argument, &owner, &errmsg) != 0) { 319 if (!errmsg) 320 errmsg = "Error parsing owner"; 321 lafe_warnc(0, "%s", errmsg); 322 usage(); 323 } 324 if (owner.uid != -1) 325 cpio->uid_override = owner.uid; 326 if (owner.uname != NULL) { 327 free(cpio->uname_override); 328 cpio->uname_override = owner.uname; 329 } 330 if (owner.gid != -1) 331 cpio->gid_override = owner.gid; 332 if (owner.gname != NULL) { 333 free(cpio->gname_override); 334 cpio->gname_override = owner.gname; 335 } 336 break; 337 case 'r': /* POSIX 1997 */ 338 cpio->option_rename = 1; 339 break; 340 case 't': /* POSIX 1997 */ 341 cpio->option_list = 1; 342 break; 343 case 'u': /* POSIX 1997 */ 344 cpio->extract_flags 345 &= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; 346 break; 347 case OPTION_UUENCODE: 348 cpio->add_filter = opt; 349 break; 350 case 'v': /* POSIX 1997 */ 351 cpio->verbose++; 352 break; 353 case 'V': /* GNU cpio */ 354 cpio->dot++; 355 break; 356 case OPTION_VERSION: /* GNU convention */ 357 version(); 358 /* NOTREACHED */ 359 #if 0 360 /* 361 * cpio_getopt() handles -W specially, so it's not 362 * available here. 363 */ 364 case 'W': /* Obscure, but useful GNU convention. */ 365 break; 366 #endif 367 case 'y': /* tar convention */ 368 cpio->compress = opt; 369 break; 370 case 'Z': /* tar convention */ 371 cpio->compress = opt; 372 break; 373 case 'z': /* tar convention */ 374 cpio->compress = opt; 375 break; 376 default: 377 usage(); 378 } 379 } 380 381 /* 382 * Sanity-check args, error out on nonsensical combinations. 383 */ 384 /* -t implies -i if no mode was specified. */ 385 if (cpio->option_list && cpio->mode == '\0') 386 cpio->mode = 'i'; 387 /* -t requires -i */ 388 if (cpio->option_list && cpio->mode != 'i') 389 lafe_errc(1, 0, "Option -t requires -i"); 390 /* -n requires -it */ 391 if (cpio->option_numeric_uid_gid && !cpio->option_list) 392 lafe_errc(1, 0, "Option -n requires -it"); 393 /* Can only specify format when writing */ 394 if (cpio->format != NULL && cpio->mode != 'o') 395 lafe_errc(1, 0, "Option --format requires -o"); 396 /* -l requires -p */ 397 if (cpio->option_link && cpio->mode != 'p') 398 lafe_errc(1, 0, "Option -l requires -p"); 399 /* -v overrides -V */ 400 if (cpio->dot && cpio->verbose) 401 cpio->dot = 0; 402 /* TODO: Flag other nonsensical combinations. */ 403 404 switch (cpio->mode) { 405 case 'o': 406 if (cpio->format == NULL) { 407 if (cpio->option_pwb) 408 cpio->format = "pwb"; 409 else 410 cpio->format = "cpio"; 411 } 412 mode_out(cpio); 413 break; 414 case 'i': 415 while (*cpio->argv != NULL) { 416 if (archive_match_include_pattern(cpio->matching, 417 *cpio->argv) != ARCHIVE_OK) 418 lafe_errc(1, 0, "%s", 419 archive_error_string(cpio->matching)); 420 --cpio->argc; 421 ++cpio->argv; 422 } 423 if (cpio->option_list) 424 mode_list(cpio); 425 else 426 mode_in(cpio); 427 /* NOTREACHED */ 428 case 'p': 429 if (*cpio->argv == NULL || **cpio->argv == '\0') 430 lafe_errc(1, 0, 431 "-p mode requires a target directory"); 432 mode_pass(cpio, *cpio->argv); 433 break; 434 default: 435 lafe_errc(1, 0, 436 "Must specify one of -i, -o, or -p"); 437 } 438 439 archive_match_free(cpio->matching); 440 free_cache(cpio->uname_cache); 441 free(cpio->uname_override); 442 free_cache(cpio->gname_cache); 443 free(cpio->gname_override); 444 archive_read_close(cpio->archive_read_disk); 445 archive_read_free(cpio->archive_read_disk); 446 free(cpio->destdir); 447 448 passphrase_free(cpio->ppbuff); 449 return (cpio->return_value); 450 } 451 452 static void 453 usage(void) 454 { 455 const char *p; 456 457 p = lafe_getprogname(); 458 459 fprintf(stderr, "Brief Usage:\n"); 460 fprintf(stderr, " List: %s -it < archive\n", p); 461 fprintf(stderr, " Extract: %s -i < archive\n", p); 462 fprintf(stderr, " Create: %s -o < filenames > archive\n", p); 463 fprintf(stderr, " Help: %s --help\n", p); 464 exit(1); 465 } 466 467 static const char *long_help_msg = 468 "First option must be a mode specifier:\n" 469 " -i Input -o Output -p Pass\n" 470 "Common Options:\n" 471 " -v Verbose filenames -V one dot per file\n" 472 "Create: %p -o [options] < [list of files] > [archive]\n" 473 " -J,-y,-z,--lzma Compress archive with xz/bzip2/gzip/lzma\n" 474 " --format {pwb|bin|odc|newc|ustar} Select archive format\n" 475 "List: %p -it < [archive]\n" 476 "Extract: %p -i [options] < [archive]\n"; 477 478 479 /* 480 * Note that the word 'bsdcpio' will always appear in the first line 481 * of output. 482 * 483 * In particular, /bin/sh scripts that need to test for the presence 484 * of bsdcpio can use the following template: 485 * 486 * if (cpio --help 2>&1 | grep bsdcpio >/dev/null 2>&1 ) then \ 487 * echo bsdcpio; else echo not bsdcpio; fi 488 */ 489 static void 490 long_help(void) 491 { 492 const char *prog; 493 const char *p; 494 495 prog = lafe_getprogname(); 496 497 fflush(stderr); 498 499 p = (strcmp(prog,"bsdcpio") != 0) ? "(bsdcpio)" : ""; 500 printf("%s%s: manipulate archive files\n", prog, p); 501 502 for (p = long_help_msg; *p != '\0'; p++) { 503 if (*p == '%') { 504 if (p[1] == 'p') { 505 fputs(prog, stdout); 506 p++; 507 } else 508 putchar('%'); 509 } else 510 putchar(*p); 511 } 512 version(); 513 } 514 515 static void 516 version(void) 517 { 518 fprintf(stdout,"bsdcpio %s - %s \n", 519 BSDCPIO_VERSION_STRING, 520 archive_version_details()); 521 exit(0); 522 } 523 524 static void 525 mode_out(struct cpio *cpio) 526 { 527 struct archive_entry *entry, *spare; 528 struct lafe_line_reader *lr; 529 const char *p; 530 int r; 531 532 if (cpio->option_append) 533 lafe_errc(1, 0, "Append mode not yet supported"); 534 535 cpio->archive_read_disk = archive_read_disk_new(); 536 if (cpio->archive_read_disk == NULL) 537 lafe_errc(1, 0, "Failed to allocate archive object"); 538 if (cpio->option_follow_links) 539 archive_read_disk_set_symlink_logical(cpio->archive_read_disk); 540 else 541 archive_read_disk_set_symlink_physical(cpio->archive_read_disk); 542 archive_read_disk_set_standard_lookup(cpio->archive_read_disk); 543 544 cpio->archive = archive_write_new(); 545 if (cpio->archive == NULL) 546 lafe_errc(1, 0, "Failed to allocate archive object"); 547 switch (cpio->compress) { 548 case OPTION_GRZIP: 549 r = archive_write_add_filter_grzip(cpio->archive); 550 break; 551 case 'J': 552 r = archive_write_add_filter_xz(cpio->archive); 553 break; 554 case OPTION_LRZIP: 555 r = archive_write_add_filter_lrzip(cpio->archive); 556 break; 557 case OPTION_LZ4: 558 r = archive_write_add_filter_lz4(cpio->archive); 559 break; 560 case OPTION_LZMA: 561 r = archive_write_add_filter_lzma(cpio->archive); 562 break; 563 case OPTION_LZOP: 564 r = archive_write_add_filter_lzop(cpio->archive); 565 break; 566 case OPTION_ZSTD: 567 r = archive_write_add_filter_zstd(cpio->archive); 568 break; 569 case 'j': case 'y': 570 r = archive_write_add_filter_bzip2(cpio->archive); 571 break; 572 case 'z': 573 r = archive_write_add_filter_gzip(cpio->archive); 574 break; 575 case 'Z': 576 r = archive_write_add_filter_compress(cpio->archive); 577 break; 578 default: 579 r = archive_write_add_filter_none(cpio->archive); 580 break; 581 } 582 if (r < ARCHIVE_WARN) 583 lafe_errc(1, 0, "Requested compression not available"); 584 switch (cpio->add_filter) { 585 case 0: 586 r = ARCHIVE_OK; 587 break; 588 case OPTION_B64ENCODE: 589 r = archive_write_add_filter_b64encode(cpio->archive); 590 break; 591 case OPTION_UUENCODE: 592 r = archive_write_add_filter_uuencode(cpio->archive); 593 break; 594 } 595 if (r < ARCHIVE_WARN) 596 lafe_errc(1, 0, "Requested filter not available"); 597 r = archive_write_set_format_by_name(cpio->archive, cpio->format); 598 if (r != ARCHIVE_OK) 599 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 600 archive_write_set_bytes_per_block(cpio->archive, cpio->bytes_per_block); 601 cpio->linkresolver = archive_entry_linkresolver_new(); 602 archive_entry_linkresolver_set_strategy(cpio->linkresolver, 603 archive_format(cpio->archive)); 604 if (cpio->passphrase != NULL) 605 r = archive_write_set_passphrase(cpio->archive, 606 cpio->passphrase); 607 else 608 r = archive_write_set_passphrase_callback(cpio->archive, cpio, 609 &passphrase_callback); 610 if (r != ARCHIVE_OK) 611 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 612 613 /* 614 * The main loop: Copy each file into the output archive. 615 */ 616 r = archive_write_open_filename(cpio->archive, cpio->filename); 617 if (r != ARCHIVE_OK) 618 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 619 lr = lafe_line_reader("-", cpio->option_null); 620 while ((p = lafe_line_reader_next(lr)) != NULL) 621 file_to_archive(cpio, p); 622 lafe_line_reader_free(lr); 623 624 /* 625 * The hardlink detection may have queued up a couple of entries 626 * that can now be flushed. 627 */ 628 entry = NULL; 629 archive_entry_linkify(cpio->linkresolver, &entry, &spare); 630 while (entry != NULL) { 631 entry_to_archive(cpio, entry); 632 archive_entry_free(entry); 633 entry = NULL; 634 archive_entry_linkify(cpio->linkresolver, &entry, &spare); 635 } 636 637 r = archive_write_close(cpio->archive); 638 if (cpio->dot) 639 fprintf(stderr, "\n"); 640 if (r != ARCHIVE_OK) 641 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 642 643 if (!cpio->quiet) { 644 int64_t blocks = 645 (archive_filter_bytes(cpio->archive, 0) + 511) 646 / 512; 647 fprintf(stderr, "%lld %s\n", (long long)blocks, 648 blocks == 1 ? "block" : "blocks"); 649 } 650 archive_write_free(cpio->archive); 651 archive_entry_linkresolver_free(cpio->linkresolver); 652 } 653 654 static const char * 655 remove_leading_slash(const char *p) 656 { 657 const char *rp; 658 659 /* Remove leading "//./" or "//?/" or "//?/UNC/" 660 * (absolute path prefixes used by Windows API) */ 661 if ((p[0] == '/' || p[0] == '\\') && 662 (p[1] == '/' || p[1] == '\\') && 663 (p[2] == '.' || p[2] == '?') && 664 (p[3] == '/' || p[3] == '\\')) 665 { 666 if (p[2] == '?' && 667 (p[4] == 'U' || p[4] == 'u') && 668 (p[5] == 'N' || p[5] == 'n') && 669 (p[6] == 'C' || p[6] == 'c') && 670 (p[7] == '/' || p[7] == '\\')) 671 p += 8; 672 else 673 p += 4; 674 } 675 do { 676 rp = p; 677 /* Remove leading drive letter from archives created 678 * on Windows. */ 679 if (((p[0] >= 'a' && p[0] <= 'z') || 680 (p[0] >= 'A' && p[0] <= 'Z')) && 681 p[1] == ':') { 682 p += 2; 683 } 684 /* Remove leading "/../", "//", etc. */ 685 while (p[0] == '/' || p[0] == '\\') { 686 if (p[1] == '.' && p[2] == '.' && 687 (p[3] == '/' || p[3] == '\\')) { 688 p += 3; /* Remove "/..", leave "/" 689 * for next pass. */ 690 } else 691 p += 1; /* Remove "/". */ 692 } 693 } while (rp != p); 694 return (p); 695 } 696 697 /* 698 * This is used by both out mode (to copy objects from disk into 699 * an archive) and pass mode (to copy objects from disk to 700 * an archive_write_disk "archive"). 701 */ 702 static int 703 file_to_archive(struct cpio *cpio, const char *srcpath) 704 { 705 struct archive_entry *entry, *spare; 706 size_t len; 707 int r; 708 709 /* 710 * Create an archive_entry describing the source file. 711 * 712 */ 713 entry = archive_entry_new(); 714 if (entry == NULL) 715 lafe_errc(1, 0, "Couldn't allocate entry"); 716 archive_entry_copy_sourcepath(entry, srcpath); 717 r = archive_read_disk_entry_from_file(cpio->archive_read_disk, 718 entry, -1, NULL); 719 if (r < ARCHIVE_FAILED) 720 lafe_errc(1, 0, "%s", 721 archive_error_string(cpio->archive_read_disk)); 722 if (r < ARCHIVE_OK) 723 lafe_warnc(0, "%s", 724 archive_error_string(cpio->archive_read_disk)); 725 if (r <= ARCHIVE_FAILED) { 726 archive_entry_free(entry); 727 cpio->return_value = 1; 728 return (r); 729 } 730 731 if (cpio->uid_override >= 0) 732 archive_entry_set_uid(entry, cpio->uid_override); 733 if (cpio->uname_override != NULL) 734 archive_entry_set_uname(entry, cpio->uname_override); 735 if (cpio->gid_override >= 0) 736 archive_entry_set_gid(entry, cpio->gid_override); 737 if (cpio->gname_override != NULL) 738 archive_entry_set_gname(entry, cpio->gname_override); 739 740 /* 741 * Generate a destination path for this entry. 742 * "destination path" is the name to which it will be copied in 743 * pass mode or the name that will go into the archive in 744 * output mode. 745 */ 746 if (cpio->destdir) { 747 len = cpio->destdir_len + strlen(srcpath) + 8; 748 if (len >= cpio->pass_destpath_alloc) { 749 while (len >= cpio->pass_destpath_alloc) { 750 cpio->pass_destpath_alloc += 512; 751 cpio->pass_destpath_alloc *= 2; 752 } 753 free(cpio->pass_destpath); 754 cpio->pass_destpath = malloc(cpio->pass_destpath_alloc); 755 if (cpio->pass_destpath == NULL) 756 lafe_errc(1, ENOMEM, 757 "Can't allocate path buffer"); 758 } 759 strcpy(cpio->pass_destpath, cpio->destdir); 760 strcat(cpio->pass_destpath, remove_leading_slash(srcpath)); 761 archive_entry_set_pathname(entry, cpio->pass_destpath); 762 } else { 763 archive_entry_set_pathname(entry, srcpath); 764 } 765 if (cpio->option_rename) 766 cpio_rename(entry); 767 768 if (archive_entry_pathname(entry) == NULL) { 769 archive_entry_free(entry); 770 return (0); 771 } 772 773 /* 774 * If we're trying to preserve hardlinks, match them here. 775 */ 776 spare = NULL; 777 if (cpio->linkresolver != NULL 778 && archive_entry_filetype(entry) != AE_IFDIR) { 779 archive_entry_linkify(cpio->linkresolver, &entry, &spare); 780 } 781 782 if (entry != NULL) { 783 r = entry_to_archive(cpio, entry); 784 archive_entry_free(entry); 785 if (spare != NULL) { 786 if (r == 0) 787 r = entry_to_archive(cpio, spare); 788 archive_entry_free(spare); 789 } 790 } 791 return (r); 792 } 793 794 static int 795 entry_to_archive(struct cpio *cpio, struct archive_entry *entry) 796 { 797 const char *destpath = archive_entry_pathname(entry); 798 const char *srcpath = archive_entry_sourcepath(entry); 799 int fd = -1; 800 int r; 801 802 /* Print out the destination name to the user. */ 803 if (cpio->verbose) 804 fprintf(stderr,"%s", destpath); 805 if (cpio->dot) 806 fprintf(stderr, "."); 807 808 /* 809 * Option_link only makes sense in pass mode and for 810 * regular files. Also note: if a link operation fails 811 * because of cross-device restrictions, we'll fall back 812 * to copy mode for that entry. 813 * 814 * TODO: Test other cpio implementations to see if they 815 * hard-link anything other than regular files here. 816 */ 817 if (cpio->option_link 818 && archive_entry_filetype(entry) == AE_IFREG) 819 { 820 struct archive_entry *t; 821 /* Save the original entry in case we need it later. */ 822 t = archive_entry_clone(entry); 823 if (t == NULL) 824 lafe_errc(1, ENOMEM, "Can't create link"); 825 /* Note: link(2) doesn't create parent directories, 826 * so we use archive_write_header() instead as a 827 * convenience. */ 828 archive_entry_set_hardlink(t, srcpath); 829 /* This is a straight link that carries no data. */ 830 archive_entry_set_size(t, 0); 831 r = archive_write_header(cpio->archive, t); 832 archive_entry_free(t); 833 if (r != ARCHIVE_OK) 834 lafe_warnc(archive_errno(cpio->archive), 835 "%s", archive_error_string(cpio->archive)); 836 if (r == ARCHIVE_FATAL) 837 exit(1); 838 #ifdef EXDEV 839 if (r != ARCHIVE_OK && archive_errno(cpio->archive) == EXDEV) { 840 /* Cross-device link: Just fall through and use 841 * the original entry to copy the file over. */ 842 lafe_warnc(0, "Copying file instead"); 843 } else 844 #endif 845 return (0); 846 } 847 848 /* 849 * Make sure we can open the file (if necessary) before 850 * trying to write the header. 851 */ 852 if (archive_entry_filetype(entry) == AE_IFREG) { 853 if (archive_entry_size(entry) > 0) { 854 fd = open(srcpath, O_RDONLY | O_BINARY); 855 if (fd < 0) { 856 lafe_warnc(errno, 857 "%s: could not open file", srcpath); 858 goto cleanup; 859 } 860 } 861 } else { 862 archive_entry_set_size(entry, 0); 863 } 864 865 r = archive_write_header(cpio->archive, entry); 866 867 if (r != ARCHIVE_OK) 868 lafe_warnc(archive_errno(cpio->archive), 869 "%s: %s", 870 srcpath, 871 archive_error_string(cpio->archive)); 872 873 if (r == ARCHIVE_FATAL) 874 exit(1); 875 876 if (r >= ARCHIVE_WARN && archive_entry_size(entry) > 0 && fd >= 0) { 877 static char buff[16384]; 878 ssize_t bytes_read; 879 880 bytes_read = read(fd, buff, sizeof(buff)); 881 while (bytes_read > 0) { 882 ssize_t bytes_write; 883 bytes_write = archive_write_data(cpio->archive, 884 buff, bytes_read); 885 if (bytes_write < 0) 886 lafe_errc(1, archive_errno(cpio->archive), 887 "%s", archive_error_string(cpio->archive)); 888 if (bytes_write < bytes_read) { 889 lafe_warnc(0, 890 "Truncated write; file may have " 891 "grown while being archived"); 892 } 893 bytes_read = read(fd, buff, sizeof(buff)); 894 } 895 } 896 897 fd = restore_time(cpio, entry, srcpath, fd); 898 899 cleanup: 900 if (cpio->verbose) 901 fprintf(stderr,"\n"); 902 if (fd >= 0) 903 close(fd); 904 return (0); 905 } 906 907 static int 908 restore_time(struct cpio *cpio, struct archive_entry *entry, 909 const char *name, int fd) 910 { 911 #ifndef HAVE_UTIMES 912 static int warned = 0; 913 914 (void)cpio; /* UNUSED */ 915 (void)entry; /* UNUSED */ 916 (void)name; /* UNUSED */ 917 918 if (!warned) 919 lafe_warnc(0, "Can't restore access times on this platform"); 920 warned = 1; 921 return (fd); 922 #else 923 #if defined(_WIN32) && !defined(__CYGWIN__) 924 struct __timeval times[2]; 925 #else 926 struct timeval times[2]; 927 #endif 928 929 if (!cpio->option_atime_restore) 930 return (fd); 931 932 times[1].tv_sec = archive_entry_mtime(entry); 933 times[1].tv_usec = archive_entry_mtime_nsec(entry) / 1000; 934 935 times[0].tv_sec = archive_entry_atime(entry); 936 times[0].tv_usec = archive_entry_atime_nsec(entry) / 1000; 937 938 #if defined(HAVE_FUTIMES) && !defined(__CYGWIN__) 939 if (fd >= 0 && futimes(fd, times) == 0) 940 return (fd); 941 #endif 942 /* 943 * Some platform cannot restore access times if the file descriptor 944 * is still opened. 945 */ 946 if (fd >= 0) { 947 close(fd); 948 fd = -1; 949 } 950 951 #ifdef HAVE_LUTIMES 952 if (lutimes(name, times) != 0) 953 #else 954 if ((AE_IFLNK != archive_entry_filetype(entry)) 955 && utimes(name, times) != 0) 956 #endif 957 lafe_warnc(errno, "Can't update time for %s", name); 958 #endif 959 return (fd); 960 } 961 962 963 static void 964 mode_in(struct cpio *cpio) 965 { 966 struct archive *a; 967 struct archive_entry *entry; 968 struct archive *ext; 969 const char *destpath; 970 int r; 971 972 ext = archive_write_disk_new(); 973 if (ext == NULL) 974 lafe_errc(1, 0, "Couldn't allocate restore object"); 975 r = archive_write_disk_set_options(ext, cpio->extract_flags); 976 if (r != ARCHIVE_OK) 977 lafe_errc(1, 0, "%s", archive_error_string(ext)); 978 a = archive_read_new(); 979 if (a == NULL) 980 lafe_errc(1, 0, "Couldn't allocate archive object"); 981 archive_read_support_filter_all(a); 982 archive_read_support_format_all(a); 983 if (cpio->option_pwb) 984 archive_read_set_options(a, "pwb"); 985 if (cpio->passphrase != NULL) 986 r = archive_read_add_passphrase(a, cpio->passphrase); 987 else 988 r = archive_read_set_passphrase_callback(a, cpio, 989 &passphrase_callback); 990 if (r != ARCHIVE_OK) 991 lafe_errc(1, 0, "%s", archive_error_string(a)); 992 993 if (archive_read_open_filename(a, cpio->filename, 994 cpio->bytes_per_block)) 995 lafe_errc(1, archive_errno(a), 996 "%s", archive_error_string(a)); 997 for (;;) { 998 r = archive_read_next_header(a, &entry); 999 if (r == ARCHIVE_EOF) 1000 break; 1001 if (r != ARCHIVE_OK) { 1002 lafe_errc(1, archive_errno(a), 1003 "%s", archive_error_string(a)); 1004 } 1005 if (archive_match_path_excluded(cpio->matching, entry)) 1006 continue; 1007 if (cpio->option_rename) 1008 cpio_rename(entry); 1009 destpath = archive_entry_pathname(entry); 1010 if (destpath == NULL) 1011 continue; 1012 if (cpio->verbose) 1013 fprintf(stderr, "%s\n", destpath); 1014 if (cpio->dot) 1015 fprintf(stderr, "."); 1016 if (cpio->uid_override >= 0) 1017 archive_entry_set_uid(entry, cpio->uid_override); 1018 if (cpio->uname_override != NULL) 1019 archive_entry_set_uname(entry, cpio->uname_override); 1020 if (cpio->gid_override >= 0) 1021 archive_entry_set_gid(entry, cpio->gid_override); 1022 if (cpio->gname_override != NULL) 1023 archive_entry_set_gname(entry, cpio->gname_override); 1024 r = archive_write_header(ext, entry); 1025 if (r != ARCHIVE_OK) { 1026 fprintf(stderr, "%s: %s\n", 1027 archive_entry_pathname(entry), 1028 archive_error_string(ext)); 1029 cpio->return_value = 1; 1030 } else if (!archive_entry_size_is_set(entry) 1031 || archive_entry_size(entry) > 0) { 1032 r = extract_data(a, ext); 1033 if (r != ARCHIVE_OK) 1034 cpio->return_value = 1; 1035 } 1036 } 1037 r = archive_read_close(a); 1038 if (cpio->dot) 1039 fprintf(stderr, "\n"); 1040 if (r != ARCHIVE_OK) 1041 lafe_errc(1, 0, "%s", archive_error_string(a)); 1042 r = archive_write_close(ext); 1043 if (r != ARCHIVE_OK) 1044 lafe_errc(1, 0, "%s", archive_error_string(ext)); 1045 if (!cpio->quiet) { 1046 int64_t blocks = (archive_filter_bytes(a, 0) + 511) 1047 / 512; 1048 fprintf(stderr, "%lld %s\n", (long long)blocks, 1049 blocks == 1 ? "block" : "blocks"); 1050 } 1051 archive_read_free(a); 1052 archive_write_free(ext); 1053 exit(cpio->return_value); 1054 } 1055 1056 /* 1057 * Exits if there's a fatal error. Returns ARCHIVE_OK 1058 * if everything is kosher. 1059 */ 1060 static int 1061 extract_data(struct archive *ar, struct archive *aw) 1062 { 1063 int r; 1064 size_t size; 1065 const void *block; 1066 int64_t offset; 1067 1068 for (;;) { 1069 r = archive_read_data_block(ar, &block, &size, &offset); 1070 if (r == ARCHIVE_EOF) 1071 return (ARCHIVE_OK); 1072 if (r != ARCHIVE_OK) { 1073 lafe_warnc(archive_errno(ar), 1074 "%s", archive_error_string(ar)); 1075 exit(1); 1076 } 1077 r = (int)archive_write_data_block(aw, block, size, offset); 1078 if (r != ARCHIVE_OK) { 1079 lafe_warnc(archive_errno(aw), 1080 "%s", archive_error_string(aw)); 1081 return (r); 1082 } 1083 } 1084 } 1085 1086 static void 1087 mode_list(struct cpio *cpio) 1088 { 1089 struct archive *a; 1090 struct archive_entry *entry; 1091 int r; 1092 1093 a = archive_read_new(); 1094 if (a == NULL) 1095 lafe_errc(1, 0, "Couldn't allocate archive object"); 1096 archive_read_support_filter_all(a); 1097 archive_read_support_format_all(a); 1098 if (cpio->option_pwb) 1099 archive_read_set_options(a, "pwb"); 1100 if (cpio->passphrase != NULL) 1101 r = archive_read_add_passphrase(a, cpio->passphrase); 1102 else 1103 r = archive_read_set_passphrase_callback(a, cpio, 1104 &passphrase_callback); 1105 if (r != ARCHIVE_OK) 1106 lafe_errc(1, 0, "%s", archive_error_string(a)); 1107 1108 if (archive_read_open_filename(a, cpio->filename, 1109 cpio->bytes_per_block)) 1110 lafe_errc(1, archive_errno(a), 1111 "%s", archive_error_string(a)); 1112 for (;;) { 1113 r = archive_read_next_header(a, &entry); 1114 if (r == ARCHIVE_EOF) 1115 break; 1116 if (r != ARCHIVE_OK) { 1117 lafe_errc(1, archive_errno(a), 1118 "%s", archive_error_string(a)); 1119 } 1120 if (archive_match_path_excluded(cpio->matching, entry)) 1121 continue; 1122 if (cpio->verbose) 1123 list_item_verbose(cpio, entry); 1124 else 1125 fprintf(stdout, "%s\n", archive_entry_pathname(entry)); 1126 } 1127 r = archive_read_close(a); 1128 if (r != ARCHIVE_OK) 1129 lafe_errc(1, 0, "%s", archive_error_string(a)); 1130 if (!cpio->quiet) { 1131 int64_t blocks = (archive_filter_bytes(a, 0) + 511) 1132 / 512; 1133 fprintf(stderr, "%lld %s\n", (long long)blocks, 1134 blocks == 1 ? "block" : "blocks"); 1135 } 1136 archive_read_free(a); 1137 exit(0); 1138 } 1139 1140 /* 1141 * Display information about the current file. 1142 * 1143 * The format here roughly duplicates the output of 'ls -l'. 1144 * This is based on SUSv2, where 'tar tv' is documented as 1145 * listing additional information in an "unspecified format," 1146 * and 'pax -l' is documented as using the same format as 'ls -l'. 1147 */ 1148 static void 1149 list_item_verbose(struct cpio *cpio, struct archive_entry *entry) 1150 { 1151 char size[32]; 1152 char date[32]; 1153 char uids[22], gids[22]; 1154 const char *uname, *gname; 1155 FILE *out = stdout; 1156 const char *fmt; 1157 time_t mtime; 1158 static time_t now; 1159 struct tm *ltime; 1160 #if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) 1161 struct tm tmbuf; 1162 #endif 1163 1164 if (!now) 1165 time(&now); 1166 1167 if (cpio->option_numeric_uid_gid) { 1168 /* Format numeric uid/gid for display. */ 1169 strcpy(uids, cpio_i64toa(archive_entry_uid(entry))); 1170 uname = uids; 1171 strcpy(gids, cpio_i64toa(archive_entry_gid(entry))); 1172 gname = gids; 1173 } else { 1174 /* Use uname if it's present, else lookup name from uid. */ 1175 uname = archive_entry_uname(entry); 1176 if (uname == NULL) 1177 uname = lookup_uname(cpio, (uid_t)archive_entry_uid(entry)); 1178 /* Use gname if it's present, else lookup name from gid. */ 1179 gname = archive_entry_gname(entry); 1180 if (gname == NULL) 1181 gname = lookup_gname(cpio, (uid_t)archive_entry_gid(entry)); 1182 } 1183 1184 /* Print device number or file size. */ 1185 if (archive_entry_filetype(entry) == AE_IFCHR 1186 || archive_entry_filetype(entry) == AE_IFBLK) { 1187 snprintf(size, sizeof(size), "%lu,%lu", 1188 (unsigned long)archive_entry_rdevmajor(entry), 1189 (unsigned long)archive_entry_rdevminor(entry)); 1190 } else { 1191 strcpy(size, cpio_i64toa(archive_entry_size(entry))); 1192 } 1193 1194 /* Format the time using 'ls -l' conventions. */ 1195 mtime = archive_entry_mtime(entry); 1196 #if defined(_WIN32) && !defined(__CYGWIN__) 1197 /* Windows' strftime function does not support %e format. */ 1198 if (mtime - now > 365*86400/2 1199 || mtime - now < -365*86400/2) 1200 fmt = cpio->day_first ? "%d %b %Y" : "%b %d %Y"; 1201 else 1202 fmt = cpio->day_first ? "%d %b %H:%M" : "%b %d %H:%M"; 1203 #else 1204 if (mtime - now > 365*86400/2 1205 || mtime - now < -365*86400/2) 1206 fmt = cpio->day_first ? "%e %b %Y" : "%b %e %Y"; 1207 else 1208 fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M"; 1209 #endif 1210 #if defined(HAVE_LOCALTIME_S) 1211 ltime = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf; 1212 #elif defined(HAVE_LOCALTIME_R) 1213 ltime = localtime_r(&mtime, &tmbuf); 1214 #else 1215 ltime = localtime(&mtime); 1216 #endif 1217 if (ltime != NULL) 1218 strftime(date, sizeof(date), fmt, ltime); 1219 else 1220 strcpy(date, "invalid mtime"); 1221 1222 fprintf(out, "%s%3u %-8s %-8s %8s %12s %s", 1223 archive_entry_strmode(entry), 1224 archive_entry_nlink(entry), 1225 uname, gname, size, date, 1226 archive_entry_pathname(entry)); 1227 1228 /* Extra information for links. */ 1229 if (archive_entry_hardlink(entry)) /* Hard link */ 1230 fprintf(out, " link to %s", archive_entry_hardlink(entry)); 1231 else if (archive_entry_symlink(entry)) /* Symbolic link */ 1232 fprintf(out, " -> %s", archive_entry_symlink(entry)); 1233 fprintf(out, "\n"); 1234 } 1235 1236 static void 1237 mode_pass(struct cpio *cpio, const char *destdir) 1238 { 1239 struct lafe_line_reader *lr; 1240 const char *p; 1241 int r; 1242 1243 /* Ensure target dir has a trailing '/' to simplify path surgery. */ 1244 cpio->destdir_len = strlen(destdir); 1245 cpio->destdir = malloc(cpio->destdir_len + 8); 1246 memcpy(cpio->destdir, destdir, cpio->destdir_len); 1247 if (cpio->destdir_len == 0 || destdir[cpio->destdir_len - 1] != '/') 1248 cpio->destdir[cpio->destdir_len++] = '/'; 1249 cpio->destdir[cpio->destdir_len] = '\0'; 1250 1251 cpio->archive = archive_write_disk_new(); 1252 if (cpio->archive == NULL) 1253 lafe_errc(1, 0, "Failed to allocate archive object"); 1254 r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags); 1255 if (r != ARCHIVE_OK) 1256 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 1257 cpio->linkresolver = archive_entry_linkresolver_new(); 1258 archive_write_disk_set_standard_lookup(cpio->archive); 1259 1260 cpio->archive_read_disk = archive_read_disk_new(); 1261 if (cpio->archive_read_disk == NULL) 1262 lafe_errc(1, 0, "Failed to allocate archive object"); 1263 if (cpio->option_follow_links) 1264 archive_read_disk_set_symlink_logical(cpio->archive_read_disk); 1265 else 1266 archive_read_disk_set_symlink_physical(cpio->archive_read_disk); 1267 archive_read_disk_set_standard_lookup(cpio->archive_read_disk); 1268 1269 lr = lafe_line_reader("-", cpio->option_null); 1270 while ((p = lafe_line_reader_next(lr)) != NULL) 1271 file_to_archive(cpio, p); 1272 lafe_line_reader_free(lr); 1273 1274 archive_entry_linkresolver_free(cpio->linkresolver); 1275 r = archive_write_close(cpio->archive); 1276 if (cpio->dot) 1277 fprintf(stderr, "\n"); 1278 if (r != ARCHIVE_OK) 1279 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); 1280 1281 if (!cpio->quiet) { 1282 int64_t blocks = 1283 (archive_filter_bytes(cpio->archive, 0) + 511) 1284 / 512; 1285 fprintf(stderr, "%lu %s\n", (unsigned long)blocks, 1286 blocks == 1 ? "block" : "blocks"); 1287 } 1288 1289 archive_write_free(cpio->archive); 1290 free(cpio->pass_destpath); 1291 } 1292 1293 /* 1294 * Prompt for a new name for this entry. Returns a pointer to the 1295 * new name or NULL if the entry should not be copied. This 1296 * implements the semantics defined in POSIX.1-1996, which specifies 1297 * that an input of '.' means the name should be unchanged. GNU cpio 1298 * treats '.' as a literal new name. 1299 */ 1300 void 1301 cpio_rename(struct archive_entry *entry) 1302 { 1303 char *buff = NULL, *p, *ret = NULL; 1304 FILE *t; 1305 size_t n = 0; 1306 ssize_t r; 1307 #if defined(_WIN32) && !defined(__CYGWIN__) 1308 FILE *to; 1309 1310 t = fopen("CONIN$", "r"); 1311 if (t == NULL) 1312 return; 1313 to = fopen("CONOUT$", "w"); 1314 if (to == NULL) { 1315 fclose(t); 1316 return; 1317 } 1318 fprintf(to, "%s (Enter/./(new name))? ", archive_entry_pathname(entry)); 1319 fclose(to); 1320 #else 1321 t = fopen("/dev/tty", "r+"); 1322 if (t == NULL) 1323 return; 1324 fprintf(t, "%s (Enter/./(new name))? ", archive_entry_pathname(entry)); 1325 fflush(t); 1326 #endif 1327 1328 r = getline(&buff, &n, t); 1329 fclose(t); 1330 if (r < 1) 1331 /* End-of-file is a blank line. */ 1332 goto done; 1333 p = buff; 1334 1335 while (*p == ' ' || *p == '\t') 1336 ++p; 1337 if (*p == '\n' || *p == '\0') 1338 /* Empty line. */ 1339 goto done; 1340 if (*p == '.' && p[1] == '\n') { 1341 /* Single period preserves original name. */ 1342 free(buff); 1343 return; 1344 } 1345 ret = p; 1346 /* Trim the final newline. */ 1347 while (*p != '\0' && *p != '\n') 1348 ++p; 1349 /* Overwrite the final \n with a null character. */ 1350 *p = '\0'; 1351 done: 1352 archive_entry_set_pathname(entry, ret); 1353 free(buff); 1354 } 1355 1356 static void 1357 free_cache(struct name_cache *cache) 1358 { 1359 size_t i; 1360 1361 if (cache != NULL) { 1362 for (i = 0; i < cache->size; i++) 1363 free(cache->cache[i].name); 1364 free(cache); 1365 } 1366 } 1367 1368 /* 1369 * Lookup uname/gname from uid/gid, return NULL if no match. 1370 */ 1371 static const char * 1372 lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable, 1373 int (*lookup_fn)(struct cpio *, const char **, id_t), id_t id) 1374 { 1375 char asnum[16]; 1376 struct name_cache *cache; 1377 const char *name; 1378 int slot; 1379 1380 1381 if (*name_cache_variable == NULL) { 1382 *name_cache_variable = calloc(1, sizeof(struct name_cache)); 1383 if (*name_cache_variable == NULL) 1384 lafe_errc(1, ENOMEM, "No more memory"); 1385 (*name_cache_variable)->size = name_cache_size; 1386 } 1387 1388 cache = *name_cache_variable; 1389 cache->probes++; 1390 1391 slot = id % cache->size; 1392 if (cache->cache[slot].name != NULL) { 1393 if (cache->cache[slot].id == id) { 1394 cache->hits++; 1395 return (cache->cache[slot].name); 1396 } 1397 free(cache->cache[slot].name); 1398 cache->cache[slot].name = NULL; 1399 } 1400 1401 if (lookup_fn(cpio, &name, id)) { 1402 /* If lookup failed, format it as a number. */ 1403 snprintf(asnum, sizeof(asnum), "%u", (unsigned)id); 1404 name = asnum; 1405 } 1406 1407 cache->cache[slot].name = strdup(name); 1408 if (cache->cache[slot].name != NULL) { 1409 cache->cache[slot].id = id; 1410 return (cache->cache[slot].name); 1411 } 1412 1413 /* 1414 * Conveniently, NULL marks an empty slot, so 1415 * if the strdup() fails, we've just failed to 1416 * cache it. No recovery necessary. 1417 */ 1418 return (NULL); 1419 } 1420 1421 static const char * 1422 lookup_uname(struct cpio *cpio, uid_t uid) 1423 { 1424 return (lookup_name(cpio, &cpio->uname_cache, 1425 &lookup_uname_helper, (id_t)uid)); 1426 } 1427 1428 static int 1429 lookup_uname_helper(struct cpio *cpio, const char **name, id_t id) 1430 { 1431 struct passwd *pwent; 1432 1433 (void)cpio; /* UNUSED */ 1434 1435 errno = 0; 1436 pwent = getpwuid((uid_t)id); 1437 if (pwent == NULL) { 1438 if (errno && errno != ENOENT) 1439 lafe_warnc(errno, "getpwuid(%s) failed", 1440 cpio_i64toa((int64_t)id)); 1441 return 1; 1442 } 1443 1444 *name = pwent->pw_name; 1445 return 0; 1446 } 1447 1448 static const char * 1449 lookup_gname(struct cpio *cpio, gid_t gid) 1450 { 1451 return (lookup_name(cpio, &cpio->gname_cache, 1452 &lookup_gname_helper, (id_t)gid)); 1453 } 1454 1455 static int 1456 lookup_gname_helper(struct cpio *cpio, const char **name, id_t id) 1457 { 1458 struct group *grent; 1459 1460 (void)cpio; /* UNUSED */ 1461 1462 errno = 0; 1463 grent = getgrgid((gid_t)id); 1464 if (grent == NULL) { 1465 if (errno && errno != ENOENT) 1466 lafe_warnc(errno, "getgrgid(%s) failed", 1467 cpio_i64toa((int64_t)id)); 1468 return 1; 1469 } 1470 1471 *name = grent->gr_name; 1472 return 0; 1473 } 1474 1475 /* 1476 * It would be nice to just use printf() for formatting large numbers, 1477 * but the compatibility problems are a big headache. Hence the 1478 * following simple utility function. 1479 */ 1480 const char * 1481 cpio_i64toa(int64_t n0) 1482 { 1483 /* 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice. 1484 * We also need 1 byte for '-' and 1 for '\0'. 1485 */ 1486 static char buff[22]; 1487 int64_t n = n0 < 0 ? -n0 : n0; 1488 char *p = buff + sizeof(buff); 1489 1490 *--p = '\0'; 1491 do { 1492 *--p = '0' + (int)(n % 10); 1493 n /= 10; 1494 } while (n > 0); 1495 if (n0 < 0) 1496 *--p = '-'; 1497 return p; 1498 } 1499 1500 #define PPBUFF_SIZE 1024 1501 static const char * 1502 passphrase_callback(struct archive *a, void *_client_data) 1503 { 1504 struct cpio *cpio = (struct cpio *)_client_data; 1505 (void)a; /* UNUSED */ 1506 1507 if (cpio->ppbuff == NULL) { 1508 cpio->ppbuff = malloc(PPBUFF_SIZE); 1509 if (cpio->ppbuff == NULL) 1510 lafe_errc(1, errno, "Out of memory"); 1511 } 1512 return lafe_readpassphrase("Enter passphrase:", 1513 cpio->ppbuff, PPBUFF_SIZE); 1514 } 1515 1516 static void 1517 passphrase_free(char *ppbuff) 1518 { 1519 if (ppbuff != NULL) { 1520 memset(ppbuff, 0, PPBUFF_SIZE); 1521 free(ppbuff); 1522 } 1523 } 1524