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 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "bsdtar_platform.h" 27 __FBSDID("$FreeBSD$"); 28 29 #ifdef HAVE_SYS_TYPES_H 30 #include <sys/types.h> 31 #endif 32 #ifdef HAVE_SYS_IOCTL_H 33 #include <sys/ioctl.h> 34 #endif 35 #ifdef HAVE_SYS_STAT_H 36 #include <sys/stat.h> 37 #endif 38 #ifdef HAVE_ATTR_XATTR_H 39 #include <attr/xattr.h> 40 #endif 41 #ifdef HAVE_ERRNO_H 42 #include <errno.h> 43 #endif 44 #ifdef HAVE_FCNTL_H 45 #include <fcntl.h> 46 #endif 47 #ifdef HAVE_GRP_H 48 #include <grp.h> 49 #endif 50 #ifdef HAVE_IO_H 51 #include <io.h> 52 #endif 53 #ifdef HAVE_LIBGEN_H 54 #include <libgen.h> 55 #endif 56 #ifdef HAVE_LIMITS_H 57 #include <limits.h> 58 #endif 59 #ifdef HAVE_LINUX_FS_H 60 #include <linux/fs.h> /* for Linux file flags */ 61 #endif 62 /* 63 * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. 64 * As the include guards don't agree, the order of include is important. 65 */ 66 #ifdef HAVE_LINUX_EXT2_FS_H 67 #include <linux/ext2_fs.h> /* for Linux file flags */ 68 #endif 69 #if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) 70 /* This header exists but is broken on Cygwin. */ 71 #include <ext2fs/ext2_fs.h> 72 #endif 73 #ifdef HAVE_PATHS_H 74 #include <paths.h> 75 #endif 76 #ifdef HAVE_PWD_H 77 #include <pwd.h> 78 #endif 79 #ifdef HAVE_STDINT_H 80 #include <stdint.h> 81 #endif 82 #include <stdio.h> 83 #ifdef HAVE_STDLIB_H 84 #include <stdlib.h> 85 #endif 86 #ifdef HAVE_STRING_H 87 #include <string.h> 88 #endif 89 #ifdef HAVE_UNISTD_H 90 #include <unistd.h> 91 #endif 92 93 #include "bsdtar.h" 94 #include "err.h" 95 #include "line_reader.h" 96 #include "tree.h" 97 98 #ifndef O_BINARY 99 #define O_BINARY 0 100 #endif 101 102 struct archive_dir_entry { 103 struct archive_dir_entry *next; 104 time_t mtime_sec; 105 int mtime_nsec; 106 char *name; 107 }; 108 109 struct archive_dir { 110 struct archive_dir_entry *head, *tail; 111 }; 112 113 static void add_dir_list(struct bsdtar *bsdtar, const char *path, 114 time_t mtime_sec, int mtime_nsec); 115 static int append_archive(struct bsdtar *, struct archive *, 116 struct archive *ina); 117 static int append_archive_filename(struct bsdtar *, 118 struct archive *, const char *fname); 119 static void archive_names_from_file(struct bsdtar *bsdtar, 120 struct archive *a); 121 static int copy_file_data(struct bsdtar *, struct archive *a, 122 struct archive *ina, struct archive_entry *); 123 static int new_enough(struct bsdtar *, const char *path, 124 const struct stat *); 125 static void report_write(struct bsdtar *, struct archive *, 126 struct archive_entry *, int64_t progress); 127 static void test_for_append(struct bsdtar *); 128 static void write_archive(struct archive *, struct bsdtar *); 129 static void write_entry(struct bsdtar *, struct archive *, 130 struct archive_entry *); 131 static void write_file(struct bsdtar *, struct archive *, 132 struct archive_entry *); 133 static int write_file_data(struct bsdtar *, struct archive *, 134 struct archive_entry *, int fd, size_t align); 135 static void write_hierarchy(struct bsdtar *, struct archive *, 136 const char *); 137 138 #if defined(_WIN32) && !defined(__CYGWIN__) 139 /* Not a full lseek() emulation, but enough for our needs here. */ 140 static int 141 seek_file(int fd, int64_t offset, int whence) 142 { 143 LARGE_INTEGER distance; 144 (void)whence; /* UNUSED */ 145 distance.QuadPart = offset; 146 return (SetFilePointerEx((HANDLE)_get_osfhandle(fd), 147 distance, NULL, FILE_BEGIN) ? 1 : -1); 148 } 149 #define open _open 150 #define close _close 151 #define read _read 152 #define lseek seek_file 153 #endif 154 155 void 156 tar_mode_c(struct bsdtar *bsdtar) 157 { 158 struct archive *a; 159 int r; 160 161 if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) 162 lafe_errc(1, 0, "no files or directories specified"); 163 164 a = archive_write_new(); 165 166 /* Support any format that the library supports. */ 167 if (bsdtar->create_format == NULL) { 168 r = archive_write_set_format_pax_restricted(a); 169 bsdtar->create_format = "pax restricted"; 170 } else { 171 r = archive_write_set_format_by_name(a, bsdtar->create_format); 172 } 173 if (r != ARCHIVE_OK) { 174 fprintf(stderr, "Can't use format %s: %s\n", 175 bsdtar->create_format, 176 archive_error_string(a)); 177 usage(); 178 } 179 180 archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); 181 archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block); 182 183 if (bsdtar->compress_program) { 184 archive_write_set_compression_program(a, bsdtar->compress_program); 185 } else { 186 switch (bsdtar->create_compression) { 187 case 0: 188 r = ARCHIVE_OK; 189 break; 190 case 'j': case 'y': 191 r = archive_write_set_compression_bzip2(a); 192 break; 193 case 'J': 194 r = archive_write_set_compression_xz(a); 195 break; 196 case OPTION_LZIP: 197 r = archive_write_set_compression_lzip(a); 198 break; 199 case OPTION_LZMA: 200 r = archive_write_set_compression_lzma(a); 201 break; 202 case 'z': 203 r = archive_write_set_compression_gzip(a); 204 break; 205 case 'Z': 206 r = archive_write_set_compression_compress(a); 207 break; 208 default: 209 lafe_errc(1, 0, 210 "Unrecognized compression option -%c", 211 bsdtar->create_compression); 212 } 213 if (r != ARCHIVE_OK) { 214 lafe_errc(1, 0, 215 "Unsupported compression option -%c", 216 bsdtar->create_compression); 217 } 218 } 219 220 if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) 221 lafe_errc(1, 0, "%s", archive_error_string(a)); 222 if (ARCHIVE_OK != archive_write_open_file(a, bsdtar->filename)) 223 lafe_errc(1, 0, "%s", archive_error_string(a)); 224 write_archive(a, bsdtar); 225 } 226 227 /* 228 * Same as 'c', except we only support tar or empty formats in 229 * uncompressed files on disk. 230 */ 231 void 232 tar_mode_r(struct bsdtar *bsdtar) 233 { 234 int64_t end_offset; 235 int format; 236 struct archive *a; 237 struct archive_entry *entry; 238 int r; 239 240 /* Sanity-test some arguments and the file. */ 241 test_for_append(bsdtar); 242 243 format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; 244 245 #if defined(__BORLANDC__) 246 bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY); 247 #else 248 bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY, 0666); 249 #endif 250 if (bsdtar->fd < 0) 251 lafe_errc(1, errno, 252 "Cannot open %s", bsdtar->filename); 253 254 a = archive_read_new(); 255 archive_read_support_filter_all(a); 256 archive_read_support_format_tar(a); 257 archive_read_support_format_gnutar(a); 258 r = archive_read_open_fd(a, bsdtar->fd, 10240); 259 if (r != ARCHIVE_OK) 260 lafe_errc(1, archive_errno(a), 261 "Can't read archive %s: %s", bsdtar->filename, 262 archive_error_string(a)); 263 while (0 == archive_read_next_header(a, &entry)) { 264 if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { 265 archive_read_free(a); 266 close(bsdtar->fd); 267 lafe_errc(1, 0, 268 "Cannot append to compressed archive."); 269 } 270 /* Keep going until we hit end-of-archive */ 271 format = archive_format(a); 272 } 273 274 end_offset = archive_read_header_position(a); 275 archive_read_free(a); 276 277 /* Re-open archive for writing */ 278 a = archive_write_new(); 279 /* 280 * Set the format to be used for writing. To allow people to 281 * extend empty files, we need to allow them to specify the format, 282 * which opens the possibility that they will specify a format that 283 * doesn't match the existing format. Hence, the following bit 284 * of arcane ugliness. 285 */ 286 287 if (bsdtar->create_format != NULL) { 288 /* If the user requested a format, use that, but ... */ 289 archive_write_set_format_by_name(a, 290 bsdtar->create_format); 291 /* ... complain if it's not compatible. */ 292 format &= ARCHIVE_FORMAT_BASE_MASK; 293 if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK) 294 && format != ARCHIVE_FORMAT_EMPTY) { 295 lafe_errc(1, 0, 296 "Format %s is incompatible with the archive %s.", 297 bsdtar->create_format, bsdtar->filename); 298 } 299 } else { 300 /* 301 * Just preserve the current format, with a little care 302 * for formats that libarchive can't write. 303 */ 304 if (format == ARCHIVE_FORMAT_EMPTY) 305 format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; 306 archive_write_set_format(a, format); 307 } 308 if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0) 309 lafe_errc(1, errno, "Could not seek to archive end"); 310 if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) 311 lafe_errc(1, 0, "%s", archive_error_string(a)); 312 if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) 313 lafe_errc(1, 0, "%s", archive_error_string(a)); 314 315 write_archive(a, bsdtar); /* XXX check return val XXX */ 316 317 close(bsdtar->fd); 318 bsdtar->fd = -1; 319 } 320 321 void 322 tar_mode_u(struct bsdtar *bsdtar) 323 { 324 int64_t end_offset; 325 struct archive *a; 326 struct archive_entry *entry; 327 int format; 328 struct archive_dir_entry *p; 329 struct archive_dir archive_dir; 330 331 bsdtar->archive_dir = &archive_dir; 332 memset(&archive_dir, 0, sizeof(archive_dir)); 333 334 format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; 335 336 /* Sanity-test some arguments and the file. */ 337 test_for_append(bsdtar); 338 339 bsdtar->fd = open(bsdtar->filename, O_RDWR | O_BINARY); 340 if (bsdtar->fd < 0) 341 lafe_errc(1, errno, 342 "Cannot open %s", bsdtar->filename); 343 344 a = archive_read_new(); 345 archive_read_support_filter_all(a); 346 archive_read_support_format_tar(a); 347 archive_read_support_format_gnutar(a); 348 if (archive_read_open_fd(a, bsdtar->fd, bsdtar->bytes_per_block) 349 != ARCHIVE_OK) { 350 lafe_errc(1, 0, 351 "Can't open %s: %s", bsdtar->filename, 352 archive_error_string(a)); 353 } 354 355 /* Build a list of all entries and their recorded mod times. */ 356 while (0 == archive_read_next_header(a, &entry)) { 357 if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) { 358 archive_read_free(a); 359 close(bsdtar->fd); 360 lafe_errc(1, 0, 361 "Cannot append to compressed archive."); 362 } 363 add_dir_list(bsdtar, archive_entry_pathname(entry), 364 archive_entry_mtime(entry), 365 archive_entry_mtime_nsec(entry)); 366 /* Record the last format determination we see */ 367 format = archive_format(a); 368 /* Keep going until we hit end-of-archive */ 369 } 370 371 end_offset = archive_read_header_position(a); 372 archive_read_free(a); 373 374 /* Re-open archive for writing. */ 375 a = archive_write_new(); 376 /* 377 * Set format to same one auto-detected above. 378 */ 379 archive_write_set_format(a, format); 380 archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); 381 archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block); 382 383 if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0) 384 lafe_errc(1, errno, "Could not seek to archive end"); 385 if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) 386 lafe_errc(1, 0, "%s", archive_error_string(a)); 387 if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) 388 lafe_errc(1, 0, "%s", archive_error_string(a)); 389 390 write_archive(a, bsdtar); 391 392 close(bsdtar->fd); 393 bsdtar->fd = -1; 394 395 while (bsdtar->archive_dir->head != NULL) { 396 p = bsdtar->archive_dir->head->next; 397 free(bsdtar->archive_dir->head->name); 398 free(bsdtar->archive_dir->head); 399 bsdtar->archive_dir->head = p; 400 } 401 bsdtar->archive_dir->tail = NULL; 402 } 403 404 405 /* 406 * Write user-specified files/dirs to opened archive. 407 */ 408 static void 409 write_archive(struct archive *a, struct bsdtar *bsdtar) 410 { 411 const char *arg; 412 struct archive_entry *entry, *sparse_entry; 413 414 /* Choose a suitable copy buffer size */ 415 bsdtar->buff_size = 64 * 1024; 416 while (bsdtar->buff_size < (size_t)bsdtar->bytes_per_block) 417 bsdtar->buff_size *= 2; 418 /* Try to compensate for space we'll lose to alignment. */ 419 bsdtar->buff_size += 16 * 1024; 420 421 /* Allocate a buffer for file data. */ 422 if ((bsdtar->buff = malloc(bsdtar->buff_size)) == NULL) 423 lafe_errc(1, 0, "cannot allocate memory"); 424 425 if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) 426 lafe_errc(1, 0, "cannot create link resolver"); 427 archive_entry_linkresolver_set_strategy(bsdtar->resolver, 428 archive_format(a)); 429 if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) 430 lafe_errc(1, 0, "Cannot create read_disk object"); 431 archive_read_disk_set_standard_lookup(bsdtar->diskreader); 432 433 if (bsdtar->names_from_file != NULL) 434 archive_names_from_file(bsdtar, a); 435 436 while (*bsdtar->argv) { 437 arg = *bsdtar->argv; 438 if (arg[0] == '-' && arg[1] == 'C') { 439 arg += 2; 440 if (*arg == '\0') { 441 bsdtar->argv++; 442 arg = *bsdtar->argv; 443 if (arg == NULL) { 444 lafe_warnc(0, "%s", 445 "Missing argument for -C"); 446 bsdtar->return_value = 1; 447 goto cleanup; 448 } 449 if (*arg == '\0') { 450 lafe_warnc(0, 451 "Meaningless argument for -C: ''"); 452 bsdtar->return_value = 1; 453 goto cleanup; 454 } 455 } 456 set_chdir(bsdtar, arg); 457 } else { 458 if (*arg != '/' && (arg[0] != '@' || arg[1] != '/')) 459 do_chdir(bsdtar); /* Handle a deferred -C */ 460 if (*arg == '@') { 461 if (append_archive_filename(bsdtar, a, 462 arg + 1) != 0) 463 break; 464 } else 465 write_hierarchy(bsdtar, a, arg); 466 } 467 bsdtar->argv++; 468 } 469 470 entry = NULL; 471 archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); 472 while (entry != NULL) { 473 write_file(bsdtar, a, entry); 474 archive_entry_free(entry); 475 entry = NULL; 476 archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); 477 } 478 479 if (archive_write_close(a)) { 480 lafe_warnc(0, "%s", archive_error_string(a)); 481 bsdtar->return_value = 1; 482 } 483 484 cleanup: 485 /* Free file data buffer. */ 486 free(bsdtar->buff); 487 archive_entry_linkresolver_free(bsdtar->resolver); 488 bsdtar->resolver = NULL; 489 archive_read_free(bsdtar->diskreader); 490 bsdtar->diskreader = NULL; 491 492 if (bsdtar->option_totals) { 493 fprintf(stderr, "Total bytes written: %s\n", 494 tar_i64toa(archive_position_compressed(a))); 495 } 496 497 archive_write_free(a); 498 } 499 500 /* 501 * Archive names specified in file. 502 * 503 * Unless --null was specified, a line containing exactly "-C" will 504 * cause the next line to be a directory to pass to chdir(). If 505 * --null is specified, then a line "-C" is just another filename. 506 */ 507 static void 508 archive_names_from_file(struct bsdtar *bsdtar, struct archive *a) 509 { 510 struct lafe_line_reader *lr; 511 const char *line; 512 513 bsdtar->next_line_is_dir = 0; 514 515 lr = lafe_line_reader(bsdtar->names_from_file, bsdtar->option_null); 516 while ((line = lafe_line_reader_next(lr)) != NULL) { 517 if (bsdtar->next_line_is_dir) { 518 if (*line != '\0') 519 set_chdir(bsdtar, line); 520 else { 521 lafe_warnc(0, 522 "Meaningless argument for -C: ''"); 523 bsdtar->return_value = 1; 524 } 525 bsdtar->next_line_is_dir = 0; 526 } else if (!bsdtar->option_null && strcmp(line, "-C") == 0) 527 bsdtar->next_line_is_dir = 1; 528 else { 529 if (*line != '/') 530 do_chdir(bsdtar); /* Handle a deferred -C */ 531 write_hierarchy(bsdtar, a, line); 532 } 533 } 534 lafe_line_reader_free(lr); 535 if (bsdtar->next_line_is_dir) 536 lafe_errc(1, errno, 537 "Unexpected end of filename list; " 538 "directory expected after -C"); 539 } 540 541 /* 542 * Copy from specified archive to current archive. Returns non-zero 543 * for write errors (which force us to terminate the entire archiving 544 * operation). If there are errors reading the input archive, we set 545 * bsdtar->return_value but return zero, so the overall archiving 546 * operation will complete and return non-zero. 547 */ 548 static int 549 append_archive_filename(struct bsdtar *bsdtar, struct archive *a, 550 const char *raw_filename) 551 { 552 struct archive *ina; 553 const char *filename = raw_filename; 554 int rc; 555 556 if (strcmp(filename, "-") == 0) 557 filename = NULL; /* Library uses NULL for stdio. */ 558 559 ina = archive_read_new(); 560 archive_read_support_format_all(ina); 561 archive_read_support_filter_all(ina); 562 if (archive_read_open_file(ina, filename, bsdtar->bytes_per_block)) { 563 lafe_warnc(0, "%s", archive_error_string(ina)); 564 bsdtar->return_value = 1; 565 return (0); 566 } 567 568 rc = append_archive(bsdtar, a, ina); 569 570 if (rc != ARCHIVE_OK) { 571 lafe_warnc(0, "Error reading archive %s: %s", 572 raw_filename, archive_error_string(ina)); 573 bsdtar->return_value = 1; 574 } 575 archive_read_free(ina); 576 577 return (rc); 578 } 579 580 static int 581 append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) 582 { 583 struct archive_entry *in_entry; 584 int e; 585 586 while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) { 587 if (!new_enough(bsdtar, archive_entry_pathname(in_entry), 588 archive_entry_stat(in_entry))) 589 continue; 590 if (lafe_excluded(bsdtar->matching, archive_entry_pathname(in_entry))) 591 continue; 592 if (bsdtar->option_interactive && 593 !yes("copy '%s'", archive_entry_pathname(in_entry))) 594 continue; 595 if (bsdtar->verbose) 596 safe_fprintf(stderr, "a %s", 597 archive_entry_pathname(in_entry)); 598 if (need_report()) 599 report_write(bsdtar, a, in_entry, 0); 600 601 e = archive_write_header(a, in_entry); 602 if (e != ARCHIVE_OK) { 603 if (!bsdtar->verbose) 604 lafe_warnc(0, "%s: %s", 605 archive_entry_pathname(in_entry), 606 archive_error_string(a)); 607 else 608 fprintf(stderr, ": %s", archive_error_string(a)); 609 } 610 if (e == ARCHIVE_FATAL) 611 exit(1); 612 613 if (e >= ARCHIVE_WARN) { 614 if (archive_entry_size(in_entry) == 0) 615 archive_read_data_skip(ina); 616 else if (copy_file_data(bsdtar, a, ina, in_entry)) 617 exit(1); 618 } 619 620 if (bsdtar->verbose) 621 fprintf(stderr, "\n"); 622 } 623 624 return (e == ARCHIVE_EOF ? ARCHIVE_OK : e); 625 } 626 627 /* Helper function to copy data between archives. */ 628 static int 629 copy_file_data(struct bsdtar *bsdtar, struct archive *a, 630 struct archive *ina, struct archive_entry *entry) 631 { 632 ssize_t bytes_read; 633 ssize_t bytes_written; 634 int64_t progress = 0; 635 636 bytes_read = archive_read_data(ina, bsdtar->buff, bsdtar->buff_size); 637 while (bytes_read > 0) { 638 if (need_report()) 639 report_write(bsdtar, a, entry, progress); 640 641 bytes_written = archive_write_data(a, bsdtar->buff, 642 bytes_read); 643 if (bytes_written < bytes_read) { 644 lafe_warnc(0, "%s", archive_error_string(a)); 645 return (-1); 646 } 647 progress += bytes_written; 648 bytes_read = archive_read_data(ina, bsdtar->buff, bsdtar->buff_size); 649 } 650 651 return (0); 652 } 653 654 /* 655 * Add the file or dir hierarchy named by 'path' to the archive 656 */ 657 static void 658 write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) 659 { 660 struct archive_entry *entry = NULL, *spare_entry = NULL; 661 struct tree *tree; 662 char symlink_mode = bsdtar->symlink_mode; 663 dev_t first_dev = 0; 664 int dev_recorded = 0; 665 int tree_ret; 666 667 tree = tree_open(path); 668 669 if (!tree) { 670 lafe_warnc(errno, "%s: Cannot open", path); 671 bsdtar->return_value = 1; 672 return; 673 } 674 675 while ((tree_ret = tree_next(tree)) != 0) { 676 int r; 677 const char *name = tree_current_path(tree); 678 const struct stat *st = NULL; /* info to use for this entry */ 679 const struct stat *lst = NULL; /* lstat() information */ 680 int descend; 681 682 if (tree_ret == TREE_ERROR_FATAL) 683 lafe_errc(1, tree_errno(tree), 684 "%s: Unable to continue traversing directory tree", 685 name); 686 if (tree_ret == TREE_ERROR_DIR) { 687 lafe_warnc(errno, 688 "%s: Couldn't visit directory", name); 689 bsdtar->return_value = 1; 690 } 691 if (tree_ret != TREE_REGULAR) 692 continue; 693 694 /* 695 * If this file/dir is excluded by a filename 696 * pattern, skip it. 697 */ 698 if (lafe_excluded(bsdtar->matching, name)) 699 continue; 700 701 /* 702 * Get lstat() info from the tree library. 703 */ 704 lst = tree_current_lstat(tree); 705 if (lst == NULL) { 706 /* Couldn't lstat(); must not exist. */ 707 lafe_warnc(errno, "%s: Cannot stat", name); 708 /* Return error if files disappear during traverse. */ 709 bsdtar->return_value = 1; 710 continue; 711 } 712 713 /* 714 * Distinguish 'L'/'P'/'H' symlink following. 715 */ 716 switch(symlink_mode) { 717 case 'H': 718 /* 'H': After the first item, rest like 'P'. */ 719 symlink_mode = 'P'; 720 /* 'H': First item (from command line) like 'L'. */ 721 /* FALLTHROUGH */ 722 case 'L': 723 /* 'L': Do descend through a symlink to dir. */ 724 descend = tree_current_is_dir(tree); 725 /* 'L': Follow symlinks to files. */ 726 archive_read_disk_set_symlink_logical(bsdtar->diskreader); 727 /* 'L': Archive symlinks as targets, if we can. */ 728 st = tree_current_stat(tree); 729 if (st != NULL) 730 break; 731 /* If stat fails, we have a broken symlink; 732 * in that case, don't follow the link. */ 733 /* FALLTHROUGH */ 734 default: 735 /* 'P': Don't descend through a symlink to dir. */ 736 descend = tree_current_is_physical_dir(tree); 737 /* 'P': Don't follow symlinks to files. */ 738 archive_read_disk_set_symlink_physical(bsdtar->diskreader); 739 /* 'P': Archive symlinks as symlinks. */ 740 st = lst; 741 break; 742 } 743 744 if (bsdtar->option_no_subdirs) 745 descend = 0; 746 747 /* 748 * Are we about to cross to a new filesystem? 749 */ 750 if (!dev_recorded) { 751 /* This is the initial file system. */ 752 first_dev = lst->st_dev; 753 dev_recorded = 1; 754 } else if (lst->st_dev == first_dev) { 755 /* The starting file system is always acceptable. */ 756 } else if (descend == 0) { 757 /* We're not descending, so no need to check. */ 758 } else if (bsdtar->option_dont_traverse_mounts) { 759 descend = 0; 760 } else { 761 /* We're prepared to cross a mount point. */ 762 763 /* XXX TODO: check whether this filesystem is 764 * synthetic and/or local. Add a new 765 * --local-only option to skip non-local 766 * filesystems. Skip synthetic filesystems 767 * regardless. 768 * 769 * The results should be cached, since 770 * tree.c doesn't usually visit a directory 771 * and the directory contents together. A simple 772 * move-to-front list should perform quite well. 773 * 774 * This is going to be heavily OS dependent: 775 * FreeBSD's statfs() in conjunction with getvfsbyname() 776 * provides all of this; NetBSD's statvfs() does 777 * most of it; other systems will vary. 778 */ 779 } 780 781 /* 782 * In -u mode, check that the file is newer than what's 783 * already in the archive; in all modes, obey --newerXXX flags. 784 */ 785 if (!new_enough(bsdtar, name, st)) { 786 if (!descend) 787 continue; 788 if (bsdtar->option_interactive && 789 !yes("add '%s'", name)) 790 continue; 791 tree_descend(tree); 792 continue; 793 } 794 795 archive_entry_free(entry); 796 entry = archive_entry_new(); 797 798 archive_entry_set_pathname(entry, name); 799 archive_entry_copy_sourcepath(entry, 800 tree_current_access_path(tree)); 801 802 /* Populate the archive_entry with metadata from the disk. */ 803 /* XXX TODO: Arrange to open a regular file before 804 * calling this so we can pass in an fd and shorten 805 * the race to query metadata. The linkify dance 806 * makes this more complex than it might sound. */ 807 #if defined(_WIN32) && !defined(__CYGWIN__) 808 /* TODO: tree.c uses stat(), which is badly broken 809 * on Windows. To fix this, we should 810 * deprecate tree_current_stat() and provide a new 811 * call tree_populate_entry(t, entry). This call 812 * would use stat() internally on POSIX and 813 * GetInfoByFileHandle() internally on Windows. 814 * This would be another step towards a tree-walker 815 * that can be integrated deep into libarchive. 816 * For now, just set st to NULL on Windows; 817 * archive_read_disk_entry_from_file() should 818 * be smart enough to use platform-appropriate 819 * ways to probe file information. 820 */ 821 st = NULL; 822 #endif 823 r = archive_read_disk_entry_from_file(bsdtar->diskreader, 824 entry, -1, st); 825 if (bsdtar->uid >= 0) { 826 archive_entry_set_uid(entry, bsdtar->uid); 827 if (!bsdtar->uname) 828 archive_entry_set_uname(entry, 829 archive_read_disk_uname(bsdtar->diskreader, 830 bsdtar->uid)); 831 } 832 if (bsdtar->gid >= 0) { 833 archive_entry_set_gid(entry, bsdtar->gid); 834 if (!bsdtar->gname) 835 archive_entry_set_gname(entry, 836 archive_read_disk_gname(bsdtar->diskreader, 837 bsdtar->gid)); 838 } 839 if (bsdtar->uname) 840 archive_entry_set_uname(entry, bsdtar->uname); 841 if (bsdtar->gname) 842 archive_entry_set_gname(entry, bsdtar->gname); 843 if (r != ARCHIVE_OK) 844 lafe_warnc(archive_errno(bsdtar->diskreader), 845 "%s", archive_error_string(bsdtar->diskreader)); 846 if (r < ARCHIVE_WARN) 847 continue; 848 849 /* XXX TODO: Just use flag data from entry; avoid the 850 * duplicate check here. */ 851 852 /* 853 * If this file/dir is flagged "nodump" and we're 854 * honoring such flags, skip this file/dir. 855 */ 856 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP) 857 /* BSD systems store flags in struct stat */ 858 if (bsdtar->option_honor_nodump && 859 (lst->st_flags & UF_NODUMP)) 860 continue; 861 #endif 862 863 #if defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) 864 /* Linux uses ioctl to read flags. */ 865 if (bsdtar->option_honor_nodump) { 866 int fd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY); 867 if (fd >= 0) { 868 unsigned long fflags; 869 int r = ioctl(fd, EXT2_IOC_GETFLAGS, &fflags); 870 close(fd); 871 if (r >= 0 && (fflags & EXT2_NODUMP_FL)) 872 continue; 873 } 874 } 875 #endif 876 877 #ifdef __APPLE__ 878 if (bsdtar->enable_copyfile) { 879 /* If we're using copyfile(), ignore "._XXX" files. */ 880 const char *bname = strrchr(name, '/'); 881 if (bname == NULL) 882 bname = name; 883 else 884 ++bname; 885 if (bname[0] == '.' && bname[1] == '_') 886 continue; 887 } else { 888 /* If not, drop the copyfile() data. */ 889 archive_entry_copy_mac_metadata(entry, NULL, 0); 890 } 891 #endif 892 893 /* 894 * If the user vetoes this file/directory, skip it. 895 * We want this to be fairly late; if some other 896 * check would veto this file, we shouldn't bother 897 * the user with it. 898 */ 899 if (bsdtar->option_interactive && 900 !yes("add '%s'", name)) 901 continue; 902 903 if (descend) 904 tree_descend(tree); 905 906 /* 907 * Rewrite the pathname to be archived. If rewrite 908 * fails, skip the entry. 909 */ 910 if (edit_pathname(bsdtar, entry)) 911 continue; 912 913 /* Display entry as we process it. 914 * This format is required by SUSv2. */ 915 if (bsdtar->verbose) 916 safe_fprintf(stderr, "a %s", 917 archive_entry_pathname(entry)); 918 919 /* Non-regular files get archived with zero size. */ 920 if (archive_entry_filetype(entry) != AE_IFREG) 921 archive_entry_set_size(entry, 0); 922 923 archive_entry_linkify(bsdtar->resolver, &entry, &spare_entry); 924 925 while (entry != NULL) { 926 write_file(bsdtar, a, entry); 927 archive_entry_free(entry); 928 entry = spare_entry; 929 spare_entry = NULL; 930 } 931 932 if (bsdtar->verbose) 933 fprintf(stderr, "\n"); 934 } 935 archive_entry_free(entry); 936 tree_close(tree); 937 } 938 939 /* 940 * Write a single file (or directory or other filesystem object) to 941 * the archive. 942 */ 943 static void 944 write_file(struct bsdtar *bsdtar, struct archive *a, 945 struct archive_entry *entry) 946 { 947 write_entry(bsdtar, a, entry); 948 } 949 950 /* 951 * Write a single entry to the archive. 952 */ 953 static void 954 write_entry(struct bsdtar *bsdtar, struct archive *a, 955 struct archive_entry *entry) 956 { 957 int fd = -1; 958 int e; 959 size_t align = 4096; 960 961 if (archive_entry_size(entry) > 0) { 962 const char *pathname = archive_entry_sourcepath(entry); 963 /* TODO: Use O_DIRECT here and set 'align' to the 964 * actual filesystem block size. As of July 2010, new 965 * directory-traversal code is going in that will make 966 * it much easier to track filesystem properties like 967 * this during the traversal. */ 968 fd = open(pathname, O_RDONLY | O_BINARY); 969 align = 4096; 970 if (fd == -1) { 971 bsdtar->return_value = 1; 972 if (!bsdtar->verbose) 973 lafe_warnc(errno, 974 "%s: could not open file", pathname); 975 else 976 fprintf(stderr, ": %s", strerror(errno)); 977 return; 978 } 979 } 980 981 e = archive_write_header(a, entry); 982 if (e != ARCHIVE_OK) { 983 if (!bsdtar->verbose) 984 lafe_warnc(0, "%s: %s", 985 archive_entry_pathname(entry), 986 archive_error_string(a)); 987 else 988 fprintf(stderr, ": %s", archive_error_string(a)); 989 } 990 991 if (e == ARCHIVE_FATAL) 992 exit(1); 993 994 /* 995 * If we opened a file earlier, write it out now. Note that 996 * the format handler might have reset the size field to zero 997 * to inform us that the archive body won't get stored. In 998 * that case, just skip the write. 999 */ 1000 if (e >= ARCHIVE_WARN && fd >= 0 && archive_entry_size(entry) > 0) { 1001 if (write_file_data(bsdtar, a, entry, fd, align)) 1002 exit(1); 1003 } 1004 1005 /* 1006 * If we opened a file, close it now even if there was an error 1007 * which made us decide not to write the archive body. 1008 */ 1009 if (fd >= 0) 1010 close(fd); 1011 } 1012 1013 static void 1014 report_write(struct bsdtar *bsdtar, struct archive *a, 1015 struct archive_entry *entry, int64_t progress) 1016 { 1017 uint64_t comp, uncomp; 1018 int compression; 1019 1020 if (bsdtar->verbose) 1021 fprintf(stderr, "\n"); 1022 comp = archive_position_compressed(a); 1023 uncomp = archive_position_uncompressed(a); 1024 fprintf(stderr, "In: %d files, %s bytes;", 1025 archive_file_count(a), tar_i64toa(uncomp)); 1026 if (comp > uncomp) 1027 compression = 0; 1028 else 1029 compression = (int)((uncomp - comp) * 100 / uncomp); 1030 fprintf(stderr, 1031 " Out: %s bytes, compression %d%%\n", 1032 tar_i64toa(comp), compression); 1033 /* Can't have two calls to tar_i64toa() pending, so split the output. */ 1034 safe_fprintf(stderr, "Current: %s (%s", 1035 archive_entry_pathname(entry), 1036 tar_i64toa(progress)); 1037 fprintf(stderr, "/%s bytes)\n", 1038 tar_i64toa(archive_entry_size(entry))); 1039 } 1040 1041 1042 /* Helper function to copy file to archive. */ 1043 static int 1044 write_file_data(struct bsdtar *bsdtar, struct archive *a, 1045 struct archive_entry *entry, int fd, size_t align) 1046 { 1047 ssize_t bytes_read; 1048 ssize_t bytes_written; 1049 int64_t progress = 0; 1050 size_t buff_size; 1051 char *buff = bsdtar->buff; 1052 1053 /* Round 'buff' up to the next multiple of 'align' and reduce 1054 * 'buff_size' accordingly. */ 1055 buff = (char *)((((uintptr_t)buff + align - 1) / align) * align); 1056 buff_size = bsdtar->buff + bsdtar->buff_size - buff; 1057 buff_size = (buff_size / align) * align; 1058 1059 bytes_read = read(fd, buff, buff_size); 1060 while (bytes_read > 0) { 1061 if (need_report()) 1062 report_write(bsdtar, a, entry, progress); 1063 1064 bytes_written = archive_write_data(a, buff, bytes_read); 1065 if (bytes_written < 0) { 1066 /* Write failed; this is bad */ 1067 lafe_warnc(0, "%s", archive_error_string(a)); 1068 return (-1); 1069 } 1070 if (bytes_written < bytes_read) { 1071 /* Write was truncated; warn but continue. */ 1072 lafe_warnc(0, 1073 "%s: Truncated write; file may have grown while being archived.", 1074 archive_entry_pathname(entry)); 1075 return (0); 1076 } 1077 progress += bytes_written; 1078 bytes_read = read(fd, buff, buff_size); 1079 } 1080 if (bytes_read < 0) { 1081 lafe_warnc(errno, 1082 "%s: Read error", 1083 archive_entry_pathname(entry)); 1084 bsdtar->return_value = 1; 1085 } 1086 return 0; 1087 } 1088 1089 /* 1090 * Test if the specified file is new enough to include in the archive. 1091 */ 1092 static int 1093 new_enough(struct bsdtar *bsdtar, const char *path, const struct stat *st) 1094 { 1095 struct archive_dir_entry *p; 1096 1097 /* 1098 * If this file/dir is excluded by a time comparison, skip it. 1099 */ 1100 if (bsdtar->newer_ctime_filter) { 1101 if (st->st_ctime < bsdtar->newer_ctime_sec) 1102 return (0); /* Too old, skip it. */ 1103 if (st->st_ctime == bsdtar->newer_ctime_sec 1104 && ARCHIVE_STAT_CTIME_NANOS(st) 1105 <= bsdtar->newer_ctime_nsec) 1106 return (0); /* Too old, skip it. */ 1107 } 1108 if (bsdtar->newer_mtime_filter) { 1109 if (st->st_mtime < bsdtar->newer_mtime_sec) 1110 return (0); /* Too old, skip it. */ 1111 if (st->st_mtime == bsdtar->newer_mtime_sec 1112 && ARCHIVE_STAT_MTIME_NANOS(st) 1113 <= bsdtar->newer_mtime_nsec) 1114 return (0); /* Too old, skip it. */ 1115 } 1116 1117 /* 1118 * In -u mode, we only write an entry if it's newer than 1119 * what was already in the archive. 1120 */ 1121 if (bsdtar->archive_dir != NULL && 1122 bsdtar->archive_dir->head != NULL) { 1123 for (p = bsdtar->archive_dir->head; p != NULL; p = p->next) { 1124 if (pathcmp(path, p->name)==0) 1125 return (p->mtime_sec < st->st_mtime || 1126 (p->mtime_sec == st->st_mtime && 1127 p->mtime_nsec 1128 < ARCHIVE_STAT_MTIME_NANOS(st))); 1129 } 1130 } 1131 1132 /* If the file wasn't rejected, include it. */ 1133 return (1); 1134 } 1135 1136 /* 1137 * Add an entry to the dir list for 'u' mode. 1138 * 1139 * XXX TODO: Make this fast. 1140 */ 1141 static void 1142 add_dir_list(struct bsdtar *bsdtar, const char *path, 1143 time_t mtime_sec, int mtime_nsec) 1144 { 1145 struct archive_dir_entry *p; 1146 1147 /* 1148 * Search entire list to see if this file has appeared before. 1149 * If it has, override the timestamp data. 1150 */ 1151 p = bsdtar->archive_dir->head; 1152 while (p != NULL) { 1153 if (strcmp(path, p->name)==0) { 1154 p->mtime_sec = mtime_sec; 1155 p->mtime_nsec = mtime_nsec; 1156 return; 1157 } 1158 p = p->next; 1159 } 1160 1161 p = malloc(sizeof(*p)); 1162 if (p == NULL) 1163 lafe_errc(1, ENOMEM, "Can't read archive directory"); 1164 1165 p->name = strdup(path); 1166 if (p->name == NULL) 1167 lafe_errc(1, ENOMEM, "Can't read archive directory"); 1168 p->mtime_sec = mtime_sec; 1169 p->mtime_nsec = mtime_nsec; 1170 p->next = NULL; 1171 if (bsdtar->archive_dir->tail == NULL) { 1172 bsdtar->archive_dir->head = bsdtar->archive_dir->tail = p; 1173 } else { 1174 bsdtar->archive_dir->tail->next = p; 1175 bsdtar->archive_dir->tail = p; 1176 } 1177 } 1178 1179 static void 1180 test_for_append(struct bsdtar *bsdtar) 1181 { 1182 struct stat s; 1183 1184 if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) 1185 lafe_errc(1, 0, "no files or directories specified"); 1186 if (bsdtar->filename == NULL) 1187 lafe_errc(1, 0, "Cannot append to stdout."); 1188 1189 if (bsdtar->create_compression != 0) 1190 lafe_errc(1, 0, 1191 "Cannot append to %s with compression", bsdtar->filename); 1192 1193 if (stat(bsdtar->filename, &s) != 0) 1194 return; 1195 1196 if (!S_ISREG(s.st_mode) && !S_ISBLK(s.st_mode)) 1197 lafe_errc(1, 0, 1198 "Cannot append to %s: not a regular file.", 1199 bsdtar->filename); 1200 1201 /* Is this an appropriate check here on Windows? */ 1202 /* 1203 if (GetFileType(handle) != FILE_TYPE_DISK) 1204 lafe_errc(1, 0, "Cannot append"); 1205 */ 1206 1207 } 1208