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: src/usr.bin/cpio/cpio.c,v 1.4 2008/06/24 15:18:40 kientzle Exp $"); 30 31 #include <sys/types.h> 32 #include <archive.h> 33 #include <archive_entry.h> 34 35 #ifdef HAVE_SYS_STAT_H 36 #include <sys/stat.h> 37 #endif 38 #ifdef HAVE_ERRNO_H 39 #include <errno.h> 40 #endif 41 #ifdef HAVE_FCNTL_H 42 #include <fcntl.h> 43 #endif 44 #ifdef HAVE_STDARG_H 45 #include <stdarg.h> 46 #endif 47 #include <stdio.h> 48 #ifdef HAVE_STDLIB_H 49 #include <stdlib.h> 50 #endif 51 #ifdef HAVE_STRING_H 52 #include <string.h> 53 #endif 54 #ifdef HAVE_UNISTD_H 55 #include <unistd.h> 56 #endif 57 58 #include "cpio.h" 59 #include "matching.h" 60 61 static int copy_data(struct archive *, struct archive *); 62 static const char *cpio_rename(const char *name); 63 static int entry_to_archive(struct cpio *, struct archive_entry *); 64 static int file_to_archive(struct cpio *, const char *); 65 static void long_help(void); 66 static void mode_in(struct cpio *); 67 static void mode_list(struct cpio *); 68 static void mode_out(struct cpio *); 69 static void mode_pass(struct cpio *, const char *); 70 static void restore_time(struct cpio *, struct archive_entry *, 71 const char *, int fd); 72 static void usage(void); 73 static void version(void); 74 75 int 76 main(int argc, char *argv[]) 77 { 78 static char buff[16384]; 79 struct cpio _cpio; /* Allocated on stack. */ 80 struct cpio *cpio; 81 int uid, gid; 82 int opt; 83 84 cpio = &_cpio; 85 memset(cpio, 0, sizeof(*cpio)); 86 cpio->buff = buff; 87 cpio->buff_size = sizeof(buff); 88 89 /* Need cpio_progname before calling cpio_warnc. */ 90 if (*argv == NULL) 91 cpio_progname = "bsdcpio"; 92 else { 93 cpio_progname = strrchr(*argv, '/'); 94 if (cpio_progname != NULL) 95 cpio_progname++; 96 else 97 cpio_progname = *argv; 98 } 99 100 cpio->uid_override = -1; 101 cpio->gid_override = -1; 102 cpio->argv = argv; 103 cpio->argc = argc; 104 cpio->line_separator = '\n'; 105 cpio->mode = '\0'; 106 cpio->verbose = 0; 107 cpio->compress = '\0'; 108 /* TODO: Implement old binary format in libarchive, use that here. */ 109 cpio->format = "odc"; /* Default format */ 110 cpio->extract_flags = ARCHIVE_EXTRACT_NO_AUTODIR; 111 cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; 112 cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS; 113 cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT; 114 /* TODO: If run by root, set owner as well. */ 115 cpio->bytes_per_block = 512; 116 cpio->filename = NULL; 117 118 while ((opt = cpio_getopt(cpio)) != -1) { 119 switch (opt) { 120 case '0': /* GNU convention: --null, -0 */ 121 cpio->line_separator = '\0'; 122 break; 123 case 'A': /* NetBSD/OpenBSD */ 124 cpio->option_append = 1; 125 break; 126 case 'a': /* POSIX 1997 */ 127 cpio->option_atime_restore = 1; 128 break; 129 case 'B': /* POSIX 1997 */ 130 cpio->bytes_per_block = 5120; 131 break; 132 case 'C': /* NetBSD/OpenBSD */ 133 cpio->bytes_per_block = atoi(optarg); 134 if (cpio->bytes_per_block <= 0) 135 cpio_errc(1, 0, "Invalid blocksize %s", optarg); 136 break; 137 case 'c': /* POSIX 1997 */ 138 cpio->format = "odc"; 139 break; 140 case 'd': /* POSIX 1997 */ 141 cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR; 142 break; 143 case 'E': /* NetBSD/OpenBSD */ 144 include_from_file(cpio, optarg); 145 break; 146 case 'F': /* NetBSD/OpenBSD/GNU cpio */ 147 cpio->filename = optarg; 148 break; 149 case 'f': /* POSIX 1997 */ 150 exclude(cpio, optarg); 151 break; 152 case 'H': /* GNU cpio (also --format) */ 153 cpio->format = optarg; 154 break; 155 case 'h': 156 long_help(); 157 break; 158 case 'I': /* NetBSD/OpenBSD */ 159 cpio->filename = optarg; 160 break; 161 case 'i': /* POSIX 1997 */ 162 cpio->mode = opt; 163 break; 164 case OPTION_INSECURE: 165 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS; 166 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; 167 break; 168 case 'L': /* GNU cpio */ 169 cpio->option_follow_links = 1; 170 break; 171 case 'l': /* POSIX 1997 */ 172 cpio->option_link = 1; 173 break; 174 case 'm': /* POSIX 1997 */ 175 cpio->extract_flags |= ARCHIVE_EXTRACT_TIME; 176 break; 177 case 'O': /* GNU cpio */ 178 cpio->filename = optarg; 179 break; 180 case 'o': /* POSIX 1997 */ 181 cpio->mode = opt; 182 break; 183 case 'p': /* POSIX 1997 */ 184 cpio->mode = opt; 185 cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; 186 break; 187 case OPTION_QUIET: /* GNU cpio */ 188 cpio->quiet = 1; 189 break; 190 case 'R': /* GNU cpio, also --owner */ 191 if (owner_parse(optarg, &uid, &gid)) 192 usage(); 193 if (uid != -1) 194 cpio->uid_override = uid; 195 if (gid != -1) 196 cpio->gid_override = gid; 197 break; 198 case 'r': /* POSIX 1997 */ 199 cpio->option_rename = 1; 200 break; 201 case 't': /* POSIX 1997 */ 202 cpio->option_list = 1; 203 break; 204 case 'u': /* POSIX 1997 */ 205 cpio->extract_flags 206 &= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; 207 break; 208 case 'v': /* POSIX 1997 */ 209 cpio->verbose++; 210 break; 211 case OPTION_VERSION: /* GNU convention */ 212 version(); 213 break; 214 #if 0 215 /* 216 * cpio_getopt() handles -W specially, so it's not 217 * available here. 218 */ 219 case 'W': /* Obscure, but useful GNU convention. */ 220 break; 221 #endif 222 case 'y': /* tar convention */ 223 cpio->compress = opt; 224 break; 225 case 'Z': /* tar convention */ 226 cpio->compress = opt; 227 break; 228 case 'z': /* tar convention */ 229 cpio->compress = opt; 230 break; 231 default: 232 usage(); 233 } 234 } 235 236 /* TODO: Sanity-check args, error out on nonsensical combinations. */ 237 238 cpio->argc -= optind; 239 cpio->argv += optind; 240 241 switch (cpio->mode) { 242 case 'o': 243 mode_out(cpio); 244 break; 245 case 'i': 246 while (*cpio->argv != NULL) { 247 include(cpio, *cpio->argv); 248 --cpio->argc; 249 ++cpio->argv; 250 } 251 if (cpio->option_list) 252 mode_list(cpio); 253 else 254 mode_in(cpio); 255 break; 256 case 'p': 257 if (*cpio->argv == NULL || **cpio->argv == '\0') 258 cpio_errc(1, 0, 259 "-p mode requires a target directory"); 260 mode_pass(cpio, *cpio->argv); 261 break; 262 default: 263 cpio_errc(1, 0, 264 "Must specify at least one of -i, -o, or -p"); 265 } 266 267 return (0); 268 } 269 270 void 271 usage(void) 272 { 273 const char *p; 274 275 p = cpio_progname; 276 277 fprintf(stderr, "Brief Usage:\n"); 278 fprintf(stderr, " List: %s -it < archive\n", p); 279 fprintf(stderr, " Extract: %s -i < archive\n", p); 280 fprintf(stderr, " Create: %s -o < filenames > archive\n", p); 281 #ifdef HAVE_GETOPT_LONG 282 fprintf(stderr, " Help: %s --help\n", p); 283 #else 284 fprintf(stderr, " Help: %s -h\n", p); 285 #endif 286 exit(1); 287 } 288 289 static const char *long_help_msg = 290 "First option must be a mode specifier:\n" 291 " -i Input -o Output -p Pass\n" 292 "Common Options:\n" 293 " -v Verbose\n" 294 "Create: %p -o [options] < [list of files] > [archive]\n" 295 " -z, -y Compress archive with gzip/bzip2\n" 296 " --format {odc|newc|ustar} Select archive format\n" 297 "List: %p -it < [archive]\n" 298 "Extract: %p -i [options] < [archive]\n"; 299 300 301 /* 302 * Note that the word 'bsdcpio' will always appear in the first line 303 * of output. 304 * 305 * In particular, /bin/sh scripts that need to test for the presence 306 * of bsdcpio can use the following template: 307 * 308 * if (cpio --help 2>&1 | grep bsdcpio >/dev/null 2>&1 ) then \ 309 * echo bsdcpio; else echo not bsdcpio; fi 310 */ 311 static void 312 long_help(void) 313 { 314 const char *prog; 315 const char *p; 316 317 prog = cpio_progname; 318 319 fflush(stderr); 320 321 p = (strcmp(prog,"bsdcpio") != 0) ? "(bsdcpio)" : ""; 322 printf("%s%s: manipulate archive files\n", prog, p); 323 324 for (p = long_help_msg; *p != '\0'; p++) { 325 if (*p == '%') { 326 if (p[1] == 'p') { 327 fputs(prog, stdout); 328 p++; 329 } else 330 putchar('%'); 331 } else 332 putchar(*p); 333 } 334 version(); 335 } 336 337 static void 338 version(void) 339 { 340 fprintf(stdout,"bsdcpio %s -- %s\n", 341 BSDCPIO_VERSION_STRING, 342 archive_version()); 343 exit(0); 344 } 345 346 static void 347 mode_out(struct cpio *cpio) 348 { 349 unsigned long blocks; 350 struct archive_entry *entry, *spare; 351 struct line_reader *lr; 352 const char *p; 353 int r; 354 355 if (cpio->option_append) 356 cpio_errc(1, 0, "Append mode not yet supported."); 357 cpio->archive = archive_write_new(); 358 if (cpio->archive == NULL) 359 cpio_errc(1, 0, "Failed to allocate archive object"); 360 switch (cpio->compress) { 361 case 'j': case 'y': 362 archive_write_set_compression_bzip2(cpio->archive); 363 break; 364 case 'z': 365 archive_write_set_compression_gzip(cpio->archive); 366 break; 367 case 'Z': 368 archive_write_set_compression_compress(cpio->archive); 369 break; 370 default: 371 archive_write_set_compression_none(cpio->archive); 372 break; 373 } 374 r = archive_write_set_format_by_name(cpio->archive, cpio->format); 375 if (r != ARCHIVE_OK) 376 cpio_errc(1, 0, archive_error_string(cpio->archive)); 377 archive_write_set_bytes_per_block(cpio->archive, cpio->bytes_per_block); 378 cpio->linkresolver = archive_entry_linkresolver_new(); 379 archive_entry_linkresolver_set_strategy(cpio->linkresolver, 380 archive_format(cpio->archive)); 381 382 r = archive_write_open_file(cpio->archive, cpio->filename); 383 if (r != ARCHIVE_OK) 384 cpio_errc(1, 0, archive_error_string(cpio->archive)); 385 lr = process_lines_init("-", cpio->line_separator); 386 while ((p = process_lines_next(lr)) != NULL) 387 file_to_archive(cpio, p); 388 process_lines_free(lr); 389 390 /* 391 * The hardlink detection may have queued up a couple of entries 392 * that can now be flushed. 393 */ 394 entry = NULL; 395 archive_entry_linkify(cpio->linkresolver, &entry, &spare); 396 while (entry != NULL) { 397 entry_to_archive(cpio, entry); 398 archive_entry_free(entry); 399 entry = NULL; 400 archive_entry_linkify(cpio->linkresolver, &entry, &spare); 401 } 402 403 r = archive_write_close(cpio->archive); 404 if (r != ARCHIVE_OK) 405 cpio_errc(1, 0, archive_error_string(cpio->archive)); 406 407 if (!cpio->quiet) { 408 blocks = (archive_position_uncompressed(cpio->archive) + 511) 409 / 512; 410 fprintf(stderr, "%lu %s\n", blocks, 411 blocks == 1 ? "block" : "blocks"); 412 } 413 archive_write_finish(cpio->archive); 414 } 415 416 /* 417 * This is used by both out mode (to copy objects from disk into 418 * an archive) and pass mode (to copy objects from disk to 419 * an archive_write_disk "archive"). 420 */ 421 static int 422 file_to_archive(struct cpio *cpio, const char *srcpath) 423 { 424 struct stat st; 425 const char *destpath; 426 struct archive_entry *entry, *spare; 427 size_t len; 428 const char *p; 429 int lnklen; 430 int r; 431 432 /* 433 * Create an archive_entry describing the source file. 434 */ 435 entry = archive_entry_new(); 436 if (entry == NULL) 437 cpio_errc(1, 0, "Couldn't allocate entry"); 438 archive_entry_copy_sourcepath(entry, srcpath); 439 440 /* Get stat information. */ 441 if (cpio->option_follow_links) 442 r = stat(srcpath, &st); 443 else 444 r = lstat(srcpath, &st); 445 if (r != 0) { 446 cpio_warnc(errno, "Couldn't stat \"%s\"", srcpath); 447 archive_entry_free(entry); 448 return (0); 449 } 450 451 if (cpio->uid_override >= 0) 452 st.st_uid = cpio->uid_override; 453 if (cpio->gid_override >= 0) 454 st.st_gid = cpio->uid_override; 455 archive_entry_copy_stat(entry, &st); 456 457 /* If its a symlink, pull the target. */ 458 if (S_ISLNK(st.st_mode)) { 459 lnklen = readlink(srcpath, cpio->buff, cpio->buff_size); 460 if (lnklen < 0) { 461 cpio_warnc(errno, 462 "%s: Couldn't read symbolic link", srcpath); 463 archive_entry_free(entry); 464 return (0); 465 } 466 cpio->buff[lnklen] = 0; 467 archive_entry_set_symlink(entry, cpio->buff); 468 } 469 470 /* 471 * Generate a destination path for this entry. 472 * "destination path" is the name to which it will be copied in 473 * pass mode or the name that will go into the archive in 474 * output mode. 475 */ 476 destpath = srcpath; 477 if (cpio->destdir) { 478 len = strlen(cpio->destdir) + strlen(srcpath) + 8; 479 if (len >= cpio->pass_destpath_alloc) { 480 while (len >= cpio->pass_destpath_alloc) { 481 cpio->pass_destpath_alloc += 512; 482 cpio->pass_destpath_alloc *= 2; 483 } 484 free(cpio->pass_destpath); 485 cpio->pass_destpath = malloc(cpio->pass_destpath_alloc); 486 if (cpio->pass_destpath == NULL) 487 cpio_errc(1, ENOMEM, 488 "Can't allocate path buffer"); 489 } 490 strcpy(cpio->pass_destpath, cpio->destdir); 491 p = srcpath; 492 while (p[0] == '/') 493 ++p; 494 strcat(cpio->pass_destpath, p); 495 destpath = cpio->pass_destpath; 496 } 497 if (cpio->option_rename) 498 destpath = cpio_rename(destpath); 499 if (destpath == NULL) 500 return (0); 501 archive_entry_copy_pathname(entry, destpath); 502 503 /* 504 * If we're trying to preserve hardlinks, match them here. 505 */ 506 spare = NULL; 507 if (cpio->linkresolver != NULL 508 && !S_ISDIR(st.st_mode)) { 509 archive_entry_linkify(cpio->linkresolver, &entry, &spare); 510 } 511 512 if (entry != NULL) { 513 r = entry_to_archive(cpio, entry); 514 archive_entry_free(entry); 515 } 516 if (spare != NULL) { 517 if (r == 0) 518 r = entry_to_archive(cpio, spare); 519 archive_entry_free(spare); 520 } 521 return (r); 522 } 523 524 static int 525 entry_to_archive(struct cpio *cpio, struct archive_entry *entry) 526 { 527 const char *destpath = archive_entry_pathname(entry); 528 const char *srcpath = archive_entry_sourcepath(entry); 529 int fd = -1; 530 ssize_t bytes_read; 531 int r; 532 533 /* Print out the destination name to the user. */ 534 if (cpio->verbose) 535 fprintf(stderr,"%s", destpath); 536 537 /* 538 * Option_link only makes sense in pass mode and for 539 * regular files. Also note: if a link operation fails 540 * because of cross-device restrictions, we'll fall back 541 * to copy mode for that entry. 542 * 543 * TODO: Test other cpio implementations to see if they 544 * hard-link anything other than regular files here. 545 */ 546 if (cpio->option_link 547 && archive_entry_filetype(entry) == AE_IFREG) 548 { 549 struct archive_entry *t; 550 /* Save the original entry in case we need it later. */ 551 t = archive_entry_clone(entry); 552 if (t == NULL) 553 cpio_errc(1, ENOMEM, "Can't create link"); 554 /* Note: link(2) doesn't create parent directories, 555 * so we use archive_write_header() instead as a 556 * convenience. */ 557 archive_entry_set_hardlink(t, srcpath); 558 /* This is a straight link that carries no data. */ 559 archive_entry_set_size(t, 0); 560 r = archive_write_header(cpio->archive, t); 561 archive_entry_free(t); 562 if (r != ARCHIVE_OK) 563 cpio_warnc(archive_errno(cpio->archive), 564 archive_error_string(cpio->archive)); 565 if (r == ARCHIVE_FATAL) 566 exit(1); 567 #ifdef EXDEV 568 if (r != ARCHIVE_OK && archive_errno(cpio->archive) == EXDEV) { 569 /* Cross-device link: Just fall through and use 570 * the original entry to copy the file over. */ 571 cpio_warnc(0, "Copying file instead"); 572 } else 573 #endif 574 return (0); 575 } 576 577 /* 578 * Make sure we can open the file (if necessary) before 579 * trying to write the header. 580 */ 581 if (archive_entry_filetype(entry) == AE_IFREG) { 582 if (archive_entry_size(entry) > 0) { 583 fd = open(srcpath, O_RDONLY); 584 if (fd < 0) { 585 cpio_warnc(errno, 586 "%s: could not open file", srcpath); 587 goto cleanup; 588 } 589 } 590 } else { 591 archive_entry_set_size(entry, 0); 592 } 593 594 r = archive_write_header(cpio->archive, entry); 595 596 if (r != ARCHIVE_OK) 597 cpio_warnc(archive_errno(cpio->archive), 598 "%s: %s", 599 destpath, 600 archive_error_string(cpio->archive)); 601 602 if (r == ARCHIVE_FATAL) 603 exit(1); 604 605 if (r >= ARCHIVE_WARN && fd >= 0) { 606 bytes_read = read(fd, cpio->buff, cpio->buff_size); 607 while (bytes_read > 0) { 608 r = archive_write_data(cpio->archive, 609 cpio->buff, bytes_read); 610 if (r < 0) 611 cpio_errc(1, archive_errno(cpio->archive), 612 archive_error_string(cpio->archive)); 613 if (r < bytes_read) { 614 cpio_warnc(0, 615 "Truncated write; file may have grown while being archived."); 616 } 617 bytes_read = read(fd, cpio->buff, cpio->buff_size); 618 } 619 } 620 621 restore_time(cpio, entry, srcpath, fd); 622 623 cleanup: 624 if (cpio->verbose) 625 fprintf(stderr,"\n"); 626 if (fd >= 0) 627 close(fd); 628 return (0); 629 } 630 631 static void 632 restore_time(struct cpio *cpio, struct archive_entry *entry, 633 const char *name, int fd) 634 { 635 #ifndef HAVE_UTIMES 636 static int warned = 0; 637 638 (void)cpio; /* UNUSED */ 639 (void)entry; /* UNUSED */ 640 (void)name; /* UNUSED */ 641 (void)fd; /* UNUSED */ 642 643 if (!warned) 644 cpio_warnc(0, "Can't restore access times on this platform"); 645 warned = 1; 646 return; 647 #else 648 struct timeval times[2]; 649 650 if (!cpio->option_atime_restore) 651 return; 652 653 times[1].tv_sec = archive_entry_mtime(entry); 654 times[1].tv_usec = archive_entry_mtime_nsec(entry) / 1000; 655 656 times[0].tv_sec = archive_entry_atime(entry); 657 times[0].tv_usec = archive_entry_atime_nsec(entry) / 1000; 658 659 #ifdef HAVE_FUTIMES 660 if (fd >= 0 && futimes(fd, times) == 0) 661 return; 662 #endif 663 664 #ifdef HAVE_LUTIMES 665 if (lutimes(name, times) != 0) 666 #else 667 if (!S_ISLNK(archive_entry_mode(entry)) && utimes(name, times) != 0) 668 #endif 669 cpio_warnc(errno, "Can't update time for %s", name); 670 #endif 671 } 672 673 674 static void 675 mode_in(struct cpio *cpio) 676 { 677 struct archive *a; 678 struct archive_entry *entry; 679 struct archive *ext; 680 const char *destpath; 681 unsigned long blocks; 682 int r; 683 684 ext = archive_write_disk_new(); 685 if (ext == NULL) 686 cpio_errc(1, 0, "Couldn't allocate restore object"); 687 r = archive_write_disk_set_options(ext, cpio->extract_flags); 688 if (r != ARCHIVE_OK) 689 cpio_errc(1, 0, archive_error_string(ext)); 690 a = archive_read_new(); 691 if (a == NULL) 692 cpio_errc(1, 0, "Couldn't allocate archive object"); 693 archive_read_support_compression_all(a); 694 archive_read_support_format_all(a); 695 696 if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block)) 697 cpio_errc(1, archive_errno(a), 698 archive_error_string(a)); 699 for (;;) { 700 r = archive_read_next_header(a, &entry); 701 if (r == ARCHIVE_EOF) 702 break; 703 if (r != ARCHIVE_OK) { 704 cpio_errc(1, archive_errno(a), 705 archive_error_string(a)); 706 } 707 if (excluded(cpio, archive_entry_pathname(entry))) 708 continue; 709 if (cpio->option_rename) { 710 destpath = cpio_rename(archive_entry_pathname(entry)); 711 archive_entry_set_pathname(entry, destpath); 712 } else 713 destpath = archive_entry_pathname(entry); 714 if (destpath == NULL) 715 continue; 716 if (cpio->verbose) 717 fprintf(stdout, "%s\n", destpath); 718 if (cpio->uid_override >= 0) 719 archive_entry_set_uid(entry, cpio->uid_override); 720 if (cpio->gid_override >= 0) 721 archive_entry_set_gid(entry, cpio->gid_override); 722 r = archive_write_header(ext, entry); 723 if (r != ARCHIVE_OK) { 724 fprintf(stderr, "%s: %s\n", 725 archive_entry_pathname(entry), 726 archive_error_string(ext)); 727 } else if (archive_entry_size(entry) > 0) { 728 r = copy_data(a, ext); 729 } 730 } 731 r = archive_read_close(a); 732 if (r != ARCHIVE_OK) 733 cpio_errc(1, 0, archive_error_string(a)); 734 r = archive_write_close(ext); 735 if (r != ARCHIVE_OK) 736 cpio_errc(1, 0, archive_error_string(ext)); 737 if (!cpio->quiet) { 738 blocks = (archive_position_uncompressed(a) + 511) 739 / 512; 740 fprintf(stderr, "%lu %s\n", blocks, 741 blocks == 1 ? "block" : "blocks"); 742 } 743 archive_read_finish(a); 744 archive_write_finish(ext); 745 exit(0); 746 } 747 748 static int 749 copy_data(struct archive *ar, struct archive *aw) 750 { 751 int r; 752 size_t size; 753 const void *block; 754 off_t offset; 755 756 for (;;) { 757 r = archive_read_data_block(ar, &block, &size, &offset); 758 if (r == ARCHIVE_EOF) 759 return (ARCHIVE_OK); 760 if (r != ARCHIVE_OK) { 761 cpio_warnc(archive_errno(ar), 762 "%s", archive_error_string(ar)); 763 return (r); 764 } 765 r = archive_write_data_block(aw, block, size, offset); 766 if (r != ARCHIVE_OK) { 767 cpio_warnc(archive_errno(aw), 768 archive_error_string(aw)); 769 return (r); 770 } 771 } 772 } 773 774 static void 775 mode_list(struct cpio *cpio) 776 { 777 struct archive *a; 778 struct archive_entry *entry; 779 unsigned long blocks; 780 int r; 781 782 a = archive_read_new(); 783 if (a == NULL) 784 cpio_errc(1, 0, "Couldn't allocate archive object"); 785 archive_read_support_compression_all(a); 786 archive_read_support_format_all(a); 787 788 if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block)) 789 cpio_errc(1, archive_errno(a), 790 archive_error_string(a)); 791 for (;;) { 792 r = archive_read_next_header(a, &entry); 793 if (r == ARCHIVE_EOF) 794 break; 795 if (r != ARCHIVE_OK) { 796 cpio_errc(1, archive_errno(a), 797 archive_error_string(a)); 798 } 799 if (excluded(cpio, archive_entry_pathname(entry))) 800 continue; 801 if (cpio->verbose) { 802 /* TODO: uname/gname lookups */ 803 /* TODO: Clean this up. */ 804 fprintf(stdout, 805 "%s%3d %8s%8s " CPIO_FILESIZE_PRINTF " %s\n", 806 archive_entry_strmode(entry), 807 archive_entry_nlink(entry), 808 archive_entry_uname(entry), 809 archive_entry_gname(entry), 810 (CPIO_FILESIZE_TYPE)archive_entry_size(entry), 811 archive_entry_pathname(entry)); 812 } else 813 fprintf(stdout, "%s\n", archive_entry_pathname(entry)); 814 } 815 r = archive_read_close(a); 816 if (r != ARCHIVE_OK) 817 cpio_errc(1, 0, archive_error_string(a)); 818 if (!cpio->quiet) { 819 blocks = (archive_position_uncompressed(a) + 511) 820 / 512; 821 fprintf(stderr, "%lu %s\n", blocks, 822 blocks == 1 ? "block" : "blocks"); 823 } 824 archive_read_finish(a); 825 exit(0); 826 } 827 828 static void 829 mode_pass(struct cpio *cpio, const char *destdir) 830 { 831 struct line_reader *lr; 832 const char *p; 833 int r; 834 835 /* Ensure target dir has a trailing '/' to simplify path surgery. */ 836 cpio->destdir = malloc(strlen(destdir) + 8); 837 strcpy(cpio->destdir, destdir); 838 if (destdir[strlen(destdir) - 1] != '/') 839 strcat(cpio->destdir, "/"); 840 841 cpio->archive = archive_write_disk_new(); 842 if (cpio->archive == NULL) 843 cpio_errc(1, 0, "Failed to allocate archive object"); 844 r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags); 845 if (r != ARCHIVE_OK) 846 cpio_errc(1, 0, archive_error_string(cpio->archive)); 847 cpio->linkresolver = archive_entry_linkresolver_new(); 848 archive_write_disk_set_standard_lookup(cpio->archive); 849 lr = process_lines_init("-", cpio->line_separator); 850 while ((p = process_lines_next(lr)) != NULL) 851 file_to_archive(cpio, p); 852 process_lines_free(lr); 853 854 archive_entry_linkresolver_free(cpio->linkresolver); 855 r = archive_write_close(cpio->archive); 856 if (r != ARCHIVE_OK) 857 cpio_errc(1, 0, archive_error_string(cpio->archive)); 858 archive_write_finish(cpio->archive); 859 } 860 861 /* 862 * Prompt for a new name for this entry. Returns a pointer to the 863 * new name or NULL if the entry should not be copied. This 864 * implements the semantics defined in POSIX.1-1996, which specifies 865 * that an input of '.' means the name should be unchanged. GNU cpio 866 * treats '.' as a literal new name. 867 */ 868 static const char * 869 cpio_rename(const char *name) 870 { 871 static char buff[1024]; 872 FILE *t; 873 char *p, *ret; 874 875 t = fopen("/dev/tty", "r+"); 876 if (t == NULL) 877 return (name); 878 fprintf(t, "%s (Enter/./(new name))? ", name); 879 fflush(t); 880 881 p = fgets(buff, sizeof(buff), t); 882 fclose(t); 883 if (p == NULL) 884 /* End-of-file is a blank line. */ 885 return (NULL); 886 887 while (*p == ' ' || *p == '\t') 888 ++p; 889 if (*p == '\n' || *p == '\0') 890 /* Empty line. */ 891 return (NULL); 892 if (*p == '.' && p[1] == '\n') 893 /* Single period preserves original name. */ 894 return (name); 895 ret = p; 896 /* Trim the final newline. */ 897 while (*p != '\0' && *p != '\n') 898 ++p; 899 /* Overwrite the final \n with a null character. */ 900 *p = '\0'; 901 return (ret); 902 } 903 904 905 /* 906 * Read lines from file and do something with each one. If option_null 907 * is set, lines are terminated with zero bytes; otherwise, they're 908 * terminated with newlines. 909 * 910 * This uses a self-sizing buffer to handle arbitrarily-long lines. 911 */ 912 struct line_reader { 913 FILE *f; 914 char *buff, *buff_end, *line_start, *line_end, *p; 915 char *pathname; 916 size_t buff_length; 917 int separator; 918 int ret; 919 }; 920 921 struct line_reader * 922 process_lines_init(const char *pathname, char separator) 923 { 924 struct line_reader *lr; 925 926 lr = calloc(1, sizeof(*lr)); 927 if (lr == NULL) 928 cpio_errc(1, ENOMEM, "Can't open %s", pathname); 929 930 lr->separator = separator; 931 lr->pathname = strdup(pathname); 932 933 if (strcmp(pathname, "-") == 0) 934 lr->f = stdin; 935 else 936 lr->f = fopen(pathname, "r"); 937 if (lr->f == NULL) 938 cpio_errc(1, errno, "Couldn't open %s", pathname); 939 lr->buff_length = 8192; 940 lr->buff = malloc(lr->buff_length); 941 if (lr->buff == NULL) 942 cpio_errc(1, ENOMEM, "Can't read %s", pathname); 943 lr->line_start = lr->line_end = lr->buff_end = lr->buff; 944 945 return (lr); 946 } 947 948 const char * 949 process_lines_next(struct line_reader *lr) 950 { 951 size_t bytes_wanted, bytes_read, new_buff_size; 952 char *line_start, *p; 953 954 for (;;) { 955 /* If there's a line in the buffer, return it immediately. */ 956 while (lr->line_end < lr->buff_end) { 957 if (*lr->line_end == lr->separator) { 958 *lr->line_end = '\0'; 959 line_start = lr->line_start; 960 lr->line_start = lr->line_end + 1; 961 lr->line_end = lr->line_start; 962 return (line_start); 963 } else 964 lr->line_end++; 965 } 966 967 /* If we're at end-of-file, process the final data. */ 968 if (lr->f == NULL) { 969 /* If there's more text, return one last line. */ 970 if (lr->line_end > lr->line_start) { 971 *lr->line_end = '\0'; 972 line_start = lr->line_start; 973 lr->line_start = lr->line_end + 1; 974 lr->line_end = lr->line_start; 975 return (line_start); 976 } 977 /* Otherwise, we're done. */ 978 return (NULL); 979 } 980 981 /* Buffer only has part of a line. */ 982 if (lr->line_start > lr->buff) { 983 /* Move a leftover fractional line to the beginning. */ 984 memmove(lr->buff, lr->line_start, 985 lr->buff_end - lr->line_start); 986 lr->buff_end -= lr->line_start - lr->buff; 987 lr->line_end -= lr->line_start - lr->buff; 988 lr->line_start = lr->buff; 989 } else { 990 /* Line is too big; enlarge the buffer. */ 991 new_buff_size = lr->buff_length * 2; 992 if (new_buff_size <= lr->buff_length) 993 cpio_errc(1, ENOMEM, 994 "Line too long in %s", lr->pathname); 995 lr->buff_length = new_buff_size; 996 p = realloc(lr->buff, new_buff_size); 997 if (p == NULL) 998 cpio_errc(1, ENOMEM, 999 "Line too long in %s", lr->pathname); 1000 lr->buff_end = p + (lr->buff_end - lr->buff); 1001 lr->line_end = p + (lr->line_end - lr->buff); 1002 lr->line_start = lr->buff = p; 1003 } 1004 1005 /* Get some more data into the buffer. */ 1006 bytes_wanted = lr->buff + lr->buff_length - lr->buff_end; 1007 bytes_read = fread(lr->buff_end, 1, bytes_wanted, lr->f); 1008 lr->buff_end += bytes_read; 1009 1010 if (ferror(lr->f)) 1011 cpio_errc(1, errno, "Can't read %s", lr->pathname); 1012 if (feof(lr->f)) { 1013 if (lr->f != stdin) 1014 fclose(lr->f); 1015 lr->f = NULL; 1016 } 1017 } 1018 } 1019 1020 void 1021 process_lines_free(struct line_reader *lr) 1022 { 1023 free(lr->buff); 1024 free(lr->pathname); 1025 free(lr); 1026 } 1027