1 /*- 2 * Copyright (c) 2003-2009 Tim Kientzle 3 * Copyright (c) 2010,2011 Michihiro NAKAJIMA 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer 11 * in this position and unchanged. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* This is the tree-walking code for POSIX systems. */ 29 #if !defined(_WIN32) || defined(__CYGWIN__) 30 31 #include "archive_platform.h" 32 __FBSDID("$FreeBSD$"); 33 34 #ifdef HAVE_SYS_PARAM_H 35 #include <sys/param.h> 36 #endif 37 #ifdef HAVE_SYS_MOUNT_H 38 #include <sys/mount.h> 39 #endif 40 #ifdef HAVE_SYS_STAT_H 41 #include <sys/stat.h> 42 #endif 43 #ifdef HAVE_SYS_STATFS_H 44 #include <sys/statfs.h> 45 #endif 46 #ifdef HAVE_SYS_STATVFS_H 47 #include <sys/statvfs.h> 48 #endif 49 #ifdef HAVE_SYS_TIME_H 50 #include <sys/time.h> 51 #endif 52 #ifdef HAVE_LINUX_MAGIC_H 53 #include <linux/magic.h> 54 #endif 55 #ifdef HAVE_DIRECT_H 56 #include <direct.h> 57 #endif 58 #ifdef HAVE_DIRENT_H 59 #include <dirent.h> 60 #endif 61 #ifdef HAVE_ERRNO_H 62 #include <errno.h> 63 #endif 64 #ifdef HAVE_FCNTL_H 65 #include <fcntl.h> 66 #endif 67 #ifdef HAVE_LIMITS_H 68 #include <limits.h> 69 #endif 70 #ifdef HAVE_STDLIB_H 71 #include <stdlib.h> 72 #endif 73 #ifdef HAVE_STRING_H 74 #include <string.h> 75 #endif 76 #ifdef HAVE_UNISTD_H 77 #include <unistd.h> 78 #endif 79 80 #include "archive.h" 81 #include "archive_string.h" 82 #include "archive_entry.h" 83 #include "archive_private.h" 84 #include "archive_read_disk_private.h" 85 86 #ifndef HAVE_FCHDIR 87 #error fchdir function required. 88 #endif 89 #ifndef O_BINARY 90 #define O_BINARY 0 91 #endif 92 93 /*- 94 * This is a new directory-walking system that addresses a number 95 * of problems I've had with fts(3). In particular, it has no 96 * pathname-length limits (other than the size of 'int'), handles 97 * deep logical traversals, uses considerably less memory, and has 98 * an opaque interface (easier to modify in the future). 99 * 100 * Internally, it keeps a single list of "tree_entry" items that 101 * represent filesystem objects that require further attention. 102 * Non-directories are not kept in memory: they are pulled from 103 * readdir(), returned to the client, then freed as soon as possible. 104 * Any directory entry to be traversed gets pushed onto the stack. 105 * 106 * There is surprisingly little information that needs to be kept for 107 * each item on the stack. Just the name, depth (represented here as the 108 * string length of the parent directory's pathname), and some markers 109 * indicating how to get back to the parent (via chdir("..") for a 110 * regular dir or via fchdir(2) for a symlink). 111 */ 112 /* 113 * TODO: 114 * 1) Loop checking. 115 * 3) Arbitrary logical traversals by closing/reopening intermediate fds. 116 */ 117 118 struct restore_time { 119 const char *name; 120 time_t mtime; 121 long mtime_nsec; 122 time_t atime; 123 long atime_nsec; 124 mode_t filetype; 125 int noatime; 126 }; 127 128 struct tree_entry { 129 int depth; 130 struct tree_entry *next; 131 struct tree_entry *parent; 132 struct archive_string name; 133 size_t dirname_length; 134 int64_t dev; 135 int64_t ino; 136 int flags; 137 int filesystem_id; 138 /* How to return back to the parent of a symlink. */ 139 int symlink_parent_fd; 140 /* How to restore time of a directory. */ 141 struct restore_time restore_time; 142 }; 143 144 struct filesystem { 145 int64_t dev; 146 int synthetic; 147 int remote; 148 int noatime; 149 #if defined(HAVE_READDIR_R) 150 size_t name_max; 151 #endif 152 long incr_xfer_size; 153 long max_xfer_size; 154 long min_xfer_size; 155 long xfer_align; 156 157 /* 158 * Buffer used for reading file contents. 159 */ 160 /* Exactly allocated memory pointer. */ 161 unsigned char *allocation_ptr; 162 /* Pointer adjusted to the filesystem alignment . */ 163 unsigned char *buff; 164 size_t buff_size; 165 }; 166 167 /* Definitions for tree_entry.flags bitmap. */ 168 #define isDir 1 /* This entry is a regular directory. */ 169 #define isDirLink 2 /* This entry is a symbolic link to a directory. */ 170 #define needsFirstVisit 4 /* This is an initial entry. */ 171 #define needsDescent 8 /* This entry needs to be previsited. */ 172 #define needsOpen 16 /* This is a directory that needs to be opened. */ 173 #define needsAscent 32 /* This entry needs to be postvisited. */ 174 175 /* 176 * Local data for this package. 177 */ 178 struct tree { 179 struct tree_entry *stack; 180 struct tree_entry *current; 181 DIR *d; 182 #define INVALID_DIR_HANDLE NULL 183 struct dirent *de; 184 #if defined(HAVE_READDIR_R) 185 struct dirent *dirent; 186 size_t dirent_allocated; 187 #endif 188 int flags; 189 int visit_type; 190 /* Error code from last failed operation. */ 191 int tree_errno; 192 193 /* Dynamically-sized buffer for holding path */ 194 struct archive_string path; 195 196 /* Last path element */ 197 const char *basename; 198 /* Leading dir length */ 199 size_t dirname_length; 200 201 int depth; 202 int openCount; 203 int maxOpenCount; 204 int initial_dir_fd; 205 int working_dir_fd; 206 207 struct stat lst; 208 struct stat st; 209 int descend; 210 int nlink; 211 /* How to restore time of a file. */ 212 struct restore_time restore_time; 213 214 struct entry_sparse { 215 int64_t length; 216 int64_t offset; 217 } *sparse_list, *current_sparse; 218 int sparse_count; 219 int sparse_list_size; 220 221 char initial_symlink_mode; 222 char symlink_mode; 223 struct filesystem *current_filesystem; 224 struct filesystem *filesystem_table; 225 int current_filesystem_id; 226 int max_filesystem_id; 227 int allocated_filesytem; 228 229 int entry_fd; 230 int entry_eof; 231 int64_t entry_remaining_bytes; 232 int64_t entry_total; 233 unsigned char *entry_buff; 234 size_t entry_buff_size; 235 }; 236 237 /* Definitions for tree.flags bitmap. */ 238 #define hasStat 16 /* The st entry is valid. */ 239 #define hasLstat 32 /* The lst entry is valid. */ 240 #define onWorkingDir 64 /* We are on the working dir where we are 241 * reading directory entry at this time. */ 242 #define needsRestoreTimes 128 243 244 static int 245 tree_dir_next_posix(struct tree *t); 246 247 #ifdef HAVE_DIRENT_D_NAMLEN 248 /* BSD extension; avoids need for a strlen() call. */ 249 #define D_NAMELEN(dp) (dp)->d_namlen 250 #else 251 #define D_NAMELEN(dp) (strlen((dp)->d_name)) 252 #endif 253 254 /* Initiate/terminate a tree traversal. */ 255 static struct tree *tree_open(const char *, int, int); 256 static struct tree *tree_reopen(struct tree *, const char *, int); 257 static void tree_close(struct tree *); 258 static void tree_free(struct tree *); 259 static void tree_push(struct tree *, const char *, int, int64_t, int64_t, 260 struct restore_time *); 261 static int tree_enter_initial_dir(struct tree *); 262 static int tree_enter_working_dir(struct tree *); 263 static int tree_current_dir_fd(struct tree *); 264 265 /* 266 * tree_next() returns Zero if there is no next entry, non-zero if 267 * there is. Note that directories are visited three times. 268 * Directories are always visited first as part of enumerating their 269 * parent; that is a "regular" visit. If tree_descend() is invoked at 270 * that time, the directory is added to a work list and will 271 * subsequently be visited two more times: once just after descending 272 * into the directory ("postdescent") and again just after ascending 273 * back to the parent ("postascent"). 274 * 275 * TREE_ERROR_DIR is returned if the descent failed (because the 276 * directory couldn't be opened, for instance). This is returned 277 * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a 278 * fatal error, but it does imply that the relevant subtree won't be 279 * visited. TREE_ERROR_FATAL is returned for an error that left the 280 * traversal completely hosed. Right now, this is only returned for 281 * chdir() failures during ascent. 282 */ 283 #define TREE_REGULAR 1 284 #define TREE_POSTDESCENT 2 285 #define TREE_POSTASCENT 3 286 #define TREE_ERROR_DIR -1 287 #define TREE_ERROR_FATAL -2 288 289 static int tree_next(struct tree *); 290 291 /* 292 * Return information about the current entry. 293 */ 294 295 /* 296 * The current full pathname, length of the full pathname, and a name 297 * that can be used to access the file. Because tree does use chdir 298 * extensively, the access path is almost never the same as the full 299 * current path. 300 * 301 * TODO: On platforms that support it, use openat()-style operations 302 * to eliminate the chdir() operations entirely while still supporting 303 * arbitrarily deep traversals. This makes access_path troublesome to 304 * support, of course, which means we'll need a rich enough interface 305 * that clients can function without it. (In particular, we'll need 306 * tree_current_open() that returns an open file descriptor.) 307 * 308 */ 309 static const char *tree_current_path(struct tree *); 310 static const char *tree_current_access_path(struct tree *); 311 312 /* 313 * Request the lstat() or stat() data for the current path. Since the 314 * tree package needs to do some of this anyway, and caches the 315 * results, you should take advantage of it here if you need it rather 316 * than make a redundant stat() or lstat() call of your own. 317 */ 318 static const struct stat *tree_current_stat(struct tree *); 319 static const struct stat *tree_current_lstat(struct tree *); 320 static int tree_current_is_symblic_link_target(struct tree *); 321 322 /* The following functions use tricks to avoid a certain number of 323 * stat()/lstat() calls. */ 324 /* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */ 325 static int tree_current_is_physical_dir(struct tree *); 326 /* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */ 327 static int tree_current_is_dir(struct tree *); 328 static int update_current_filesystem(struct archive_read_disk *a, 329 int64_t dev); 330 static int setup_current_filesystem(struct archive_read_disk *); 331 static int tree_target_is_same_as_parent(struct tree *, const struct stat *); 332 333 static int _archive_read_disk_open(struct archive *, const char *); 334 static int _archive_read_free(struct archive *); 335 static int _archive_read_close(struct archive *); 336 static int _archive_read_data_block(struct archive *, 337 const void **, size_t *, int64_t *); 338 static int _archive_read_next_header2(struct archive *, 339 struct archive_entry *); 340 static const char *trivial_lookup_gname(void *, int64_t gid); 341 static const char *trivial_lookup_uname(void *, int64_t uid); 342 static int setup_sparse(struct archive_read_disk *, struct archive_entry *); 343 static int close_and_restore_time(int fd, struct tree *, 344 struct restore_time *); 345 346 347 static struct archive_vtable * 348 archive_read_disk_vtable(void) 349 { 350 static struct archive_vtable av; 351 static int inited = 0; 352 353 if (!inited) { 354 av.archive_free = _archive_read_free; 355 av.archive_close = _archive_read_close; 356 av.archive_read_data_block = _archive_read_data_block; 357 av.archive_read_next_header2 = _archive_read_next_header2; 358 inited = 1; 359 } 360 return (&av); 361 } 362 363 const char * 364 archive_read_disk_gname(struct archive *_a, int64_t gid) 365 { 366 struct archive_read_disk *a = (struct archive_read_disk *)_a; 367 if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 368 ARCHIVE_STATE_ANY, "archive_read_disk_gname")) 369 return (NULL); 370 if (a->lookup_gname == NULL) 371 return (NULL); 372 return ((*a->lookup_gname)(a->lookup_gname_data, gid)); 373 } 374 375 const char * 376 archive_read_disk_uname(struct archive *_a, int64_t uid) 377 { 378 struct archive_read_disk *a = (struct archive_read_disk *)_a; 379 if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 380 ARCHIVE_STATE_ANY, "archive_read_disk_uname")) 381 return (NULL); 382 if (a->lookup_uname == NULL) 383 return (NULL); 384 return ((*a->lookup_uname)(a->lookup_uname_data, uid)); 385 } 386 387 int 388 archive_read_disk_set_gname_lookup(struct archive *_a, 389 void *private_data, 390 const char * (*lookup_gname)(void *private, int64_t gid), 391 void (*cleanup_gname)(void *private)) 392 { 393 struct archive_read_disk *a = (struct archive_read_disk *)_a; 394 archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, 395 ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup"); 396 397 if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) 398 (a->cleanup_gname)(a->lookup_gname_data); 399 400 a->lookup_gname = lookup_gname; 401 a->cleanup_gname = cleanup_gname; 402 a->lookup_gname_data = private_data; 403 return (ARCHIVE_OK); 404 } 405 406 int 407 archive_read_disk_set_uname_lookup(struct archive *_a, 408 void *private_data, 409 const char * (*lookup_uname)(void *private, int64_t uid), 410 void (*cleanup_uname)(void *private)) 411 { 412 struct archive_read_disk *a = (struct archive_read_disk *)_a; 413 archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, 414 ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup"); 415 416 if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) 417 (a->cleanup_uname)(a->lookup_uname_data); 418 419 a->lookup_uname = lookup_uname; 420 a->cleanup_uname = cleanup_uname; 421 a->lookup_uname_data = private_data; 422 return (ARCHIVE_OK); 423 } 424 425 /* 426 * Create a new archive_read_disk object and initialize it with global state. 427 */ 428 struct archive * 429 archive_read_disk_new(void) 430 { 431 struct archive_read_disk *a; 432 433 a = (struct archive_read_disk *)malloc(sizeof(*a)); 434 if (a == NULL) 435 return (NULL); 436 memset(a, 0, sizeof(*a)); 437 a->archive.magic = ARCHIVE_READ_DISK_MAGIC; 438 a->archive.state = ARCHIVE_STATE_NEW; 439 a->archive.vtable = archive_read_disk_vtable(); 440 a->lookup_uname = trivial_lookup_uname; 441 a->lookup_gname = trivial_lookup_gname; 442 a->entry_wd_fd = -1; 443 return (&a->archive); 444 } 445 446 static int 447 _archive_read_free(struct archive *_a) 448 { 449 struct archive_read_disk *a = (struct archive_read_disk *)_a; 450 int r; 451 452 if (_a == NULL) 453 return (ARCHIVE_OK); 454 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 455 ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free"); 456 457 if (a->archive.state != ARCHIVE_STATE_CLOSED) 458 r = _archive_read_close(&a->archive); 459 else 460 r = ARCHIVE_OK; 461 462 tree_free(a->tree); 463 if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) 464 (a->cleanup_gname)(a->lookup_gname_data); 465 if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) 466 (a->cleanup_uname)(a->lookup_uname_data); 467 archive_string_free(&a->archive.error_string); 468 a->archive.magic = 0; 469 __archive_clean(&a->archive); 470 free(a); 471 return (r); 472 } 473 474 static int 475 _archive_read_close(struct archive *_a) 476 { 477 struct archive_read_disk *a = (struct archive_read_disk *)_a; 478 479 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 480 ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close"); 481 482 if (a->archive.state != ARCHIVE_STATE_FATAL) 483 a->archive.state = ARCHIVE_STATE_CLOSED; 484 485 tree_close(a->tree); 486 487 return (ARCHIVE_OK); 488 } 489 490 static void 491 setup_symlink_mode(struct archive_read_disk *a, char symlink_mode, 492 int follow_symlinks) 493 { 494 a->symlink_mode = symlink_mode; 495 a->follow_symlinks = follow_symlinks; 496 if (a->tree != NULL) { 497 a->tree->initial_symlink_mode = a->symlink_mode; 498 a->tree->symlink_mode = a->symlink_mode; 499 } 500 } 501 502 int 503 archive_read_disk_set_symlink_logical(struct archive *_a) 504 { 505 struct archive_read_disk *a = (struct archive_read_disk *)_a; 506 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 507 ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical"); 508 setup_symlink_mode(a, 'L', 1); 509 return (ARCHIVE_OK); 510 } 511 512 int 513 archive_read_disk_set_symlink_physical(struct archive *_a) 514 { 515 struct archive_read_disk *a = (struct archive_read_disk *)_a; 516 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 517 ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical"); 518 setup_symlink_mode(a, 'P', 0); 519 return (ARCHIVE_OK); 520 } 521 522 int 523 archive_read_disk_set_symlink_hybrid(struct archive *_a) 524 { 525 struct archive_read_disk *a = (struct archive_read_disk *)_a; 526 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 527 ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid"); 528 setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */ 529 return (ARCHIVE_OK); 530 } 531 532 int 533 archive_read_disk_set_atime_restored(struct archive *_a) 534 { 535 #ifndef HAVE_UTIMES 536 static int warning_done = 0; 537 #endif 538 struct archive_read_disk *a = (struct archive_read_disk *)_a; 539 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 540 ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime"); 541 #ifdef HAVE_UTIMES 542 a->restore_time = 1; 543 if (a->tree != NULL) 544 a->tree->flags |= needsRestoreTimes; 545 return (ARCHIVE_OK); 546 #else 547 if (warning_done) 548 /* Warning was already emitted; suppress further warnings. */ 549 return (ARCHIVE_OK); 550 551 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 552 "Cannot restore access time on this system"); 553 warning_done = 1; 554 return (ARCHIVE_WARN); 555 #endif 556 } 557 558 /* 559 * Trivial implementations of gname/uname lookup functions. 560 * These are normally overridden by the client, but these stub 561 * versions ensure that we always have something that works. 562 */ 563 static const char * 564 trivial_lookup_gname(void *private_data, int64_t gid) 565 { 566 (void)private_data; /* UNUSED */ 567 (void)gid; /* UNUSED */ 568 return (NULL); 569 } 570 571 static const char * 572 trivial_lookup_uname(void *private_data, int64_t uid) 573 { 574 (void)private_data; /* UNUSED */ 575 (void)uid; /* UNUSED */ 576 return (NULL); 577 } 578 579 /* 580 * Allocate memory for the reading buffer adjusted to the filesystem 581 * alignment. 582 */ 583 static int 584 setup_suitable_read_buffer(struct archive_read_disk *a) 585 { 586 struct tree *t = a->tree; 587 struct filesystem *cf = t->current_filesystem; 588 size_t asize; 589 size_t s; 590 591 if (cf->allocation_ptr == NULL) { 592 /* If we couldn't get a filesystem alignment, 593 * we use 4096 as default value but we won't use 594 * O_DIRECT to open() and openat() operations. */ 595 long xfer_align = (cf->xfer_align == -1)?4096:cf->xfer_align; 596 597 if (cf->max_xfer_size != -1) 598 asize = cf->max_xfer_size + xfer_align; 599 else { 600 long incr = cf->incr_xfer_size; 601 /* Some platform does not set a proper value to 602 * incr_xfer_size.*/ 603 if (incr < 0) 604 incr = cf->min_xfer_size; 605 if (cf->min_xfer_size < 0) { 606 incr = xfer_align; 607 asize = xfer_align; 608 } else 609 asize = cf->min_xfer_size; 610 611 /* Increase a buffer size up to 64K bytes in 612 * a proper incremant size. */ 613 while (asize < 1024*64) 614 asize += incr; 615 /* Take a margin to adjust to the filesystem 616 * alignment. */ 617 asize += xfer_align; 618 } 619 cf->allocation_ptr = malloc(asize); 620 if (cf->allocation_ptr == NULL) { 621 archive_set_error(&a->archive, ENOMEM, 622 "Couldn't allocate memory"); 623 a->archive.state = ARCHIVE_STATE_FATAL; 624 return (ARCHIVE_FATAL); 625 } 626 627 /* 628 * Calculate proper address for the filesystem. 629 */ 630 s = (uintptr_t)cf->allocation_ptr; 631 s %= xfer_align; 632 if (s > 0) 633 s = xfer_align - s; 634 635 /* 636 * Set a read buffer pointer in the proper alignment of 637 * the current filesystem. 638 */ 639 cf->buff = cf->allocation_ptr + s; 640 cf->buff_size = asize - xfer_align; 641 } 642 return (ARCHIVE_OK); 643 } 644 645 static int 646 _archive_read_data_block(struct archive *_a, const void **buff, 647 size_t *size, int64_t *offset) 648 { 649 struct archive_read_disk *a = (struct archive_read_disk *)_a; 650 struct tree *t = a->tree; 651 int r; 652 ssize_t bytes; 653 size_t buffbytes; 654 655 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, 656 "archive_read_data_block"); 657 658 if (t->entry_eof || t->entry_remaining_bytes <= 0) { 659 r = ARCHIVE_EOF; 660 goto abort_read_data; 661 } 662 663 /* 664 * Open the current file. 665 */ 666 if (t->entry_fd < 0) { 667 int flags = O_RDONLY | O_BINARY; 668 669 /* 670 * Eliminate or reduce cache effects if we can. 671 * 672 * Carefully consider this to be enabled. 673 */ 674 #if defined(O_DIRECT) && 0/* Disabled for now */ 675 if (t->current_filesystem->xfer_align != -1 && 676 t->nlink == 1) 677 flags |= O_DIRECT; 678 #endif 679 #if defined(O_NOATIME) 680 /* 681 * Linux has O_NOATIME flag; use it if we need. 682 */ 683 if ((t->flags & needsRestoreTimes) != 0 && 684 t->restore_time.noatime == 0) 685 flags |= O_NOATIME; 686 do { 687 #endif 688 #ifdef HAVE_OPENAT 689 t->entry_fd = openat(tree_current_dir_fd(t), 690 tree_current_access_path(t), flags); 691 #else 692 tree_enter_working_dir(t); 693 t->entry_fd = open(tree_current_access_path(t), flags); 694 #endif 695 #if defined(O_NOATIME) 696 /* 697 * When we did open the file with O_NOATIME flag, 698 * if successful, set 1 to t->restore_time.noatime 699 * not to restore an atime of the file later. 700 * if failed by EPERM, retry it without O_NOATIME flag. 701 */ 702 if (flags & O_NOATIME) { 703 if (t->entry_fd >= 0) 704 t->restore_time.noatime = 1; 705 else if (errno == EPERM) { 706 flags &= ~O_NOATIME; 707 continue; 708 } 709 } 710 } while (0); 711 #endif 712 if (t->entry_fd < 0) { 713 archive_set_error(&a->archive, errno, 714 "Couldn't open %s", tree_current_path(t)); 715 r = ARCHIVE_FAILED; 716 tree_enter_initial_dir(t); 717 goto abort_read_data; 718 } 719 tree_enter_initial_dir(t); 720 } 721 722 /* 723 * Allocate read buffer if not allocated. 724 */ 725 if (t->current_filesystem->allocation_ptr == NULL) { 726 r = setup_suitable_read_buffer(a); 727 if (r != ARCHIVE_OK) { 728 a->archive.state = ARCHIVE_STATE_FATAL; 729 goto abort_read_data; 730 } 731 } 732 t->entry_buff = t->current_filesystem->buff; 733 t->entry_buff_size = t->current_filesystem->buff_size; 734 735 buffbytes = t->entry_buff_size; 736 if (buffbytes > t->current_sparse->length) 737 buffbytes = t->current_sparse->length; 738 739 /* 740 * Skip hole. 741 * TODO: Should we consider t->current_filesystem->xfer_align? 742 */ 743 if (t->current_sparse->offset > t->entry_total) { 744 if (lseek(t->entry_fd, 745 (off_t)t->current_sparse->offset, SEEK_SET) < 0) { 746 archive_set_error(&a->archive, errno, "Seek error"); 747 r = ARCHIVE_FATAL; 748 a->archive.state = ARCHIVE_STATE_FATAL; 749 goto abort_read_data; 750 } 751 bytes = t->current_sparse->offset - t->entry_total; 752 t->entry_remaining_bytes -= bytes; 753 t->entry_total += bytes; 754 } 755 756 /* 757 * Read file contents. 758 */ 759 if (buffbytes > 0) { 760 bytes = read(t->entry_fd, t->entry_buff, buffbytes); 761 if (bytes < 0) { 762 archive_set_error(&a->archive, errno, "Read error"); 763 r = ARCHIVE_FATAL; 764 a->archive.state = ARCHIVE_STATE_FATAL; 765 goto abort_read_data; 766 } 767 } else 768 bytes = 0; 769 if (bytes == 0) { 770 /* Get EOF */ 771 t->entry_eof = 1; 772 r = ARCHIVE_EOF; 773 goto abort_read_data; 774 } 775 *buff = t->entry_buff; 776 *size = bytes; 777 *offset = t->entry_total; 778 t->entry_total += bytes; 779 t->entry_remaining_bytes -= bytes; 780 if (t->entry_remaining_bytes == 0) { 781 /* Close the current file descriptor */ 782 close_and_restore_time(t->entry_fd, t, &t->restore_time); 783 t->entry_fd = -1; 784 t->entry_eof = 1; 785 } 786 t->current_sparse->offset += bytes; 787 t->current_sparse->length -= bytes; 788 if (t->current_sparse->length == 0 && !t->entry_eof) 789 t->current_sparse++; 790 return (ARCHIVE_OK); 791 792 abort_read_data: 793 *buff = NULL; 794 *size = 0; 795 *offset = t->entry_total; 796 if (t->entry_fd >= 0) { 797 /* Close the current file descriptor */ 798 close_and_restore_time(t->entry_fd, t, &t->restore_time); 799 t->entry_fd = -1; 800 } 801 return (r); 802 } 803 804 static int 805 _archive_read_next_header2(struct archive *_a, struct archive_entry *entry) 806 { 807 struct archive_read_disk *a = (struct archive_read_disk *)_a; 808 struct tree *t; 809 const struct stat *st; /* info to use for this entry */ 810 const struct stat *lst;/* lstat() information */ 811 int descend, fd = -1, r; 812 813 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 814 ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, 815 "archive_read_next_header2"); 816 817 t = a->tree; 818 if (t->entry_fd >= 0) { 819 close_and_restore_time(t->entry_fd, t, &t->restore_time); 820 t->entry_fd = -1; 821 } 822 #if !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)) 823 /* Restore working directory. */ 824 tree_enter_working_dir(t); 825 #endif 826 st = NULL; 827 lst = NULL; 828 do { 829 switch (tree_next(t)) { 830 case TREE_ERROR_FATAL: 831 archive_set_error(&a->archive, t->tree_errno, 832 "%s: Unable to continue traversing directory tree", 833 tree_current_path(t)); 834 a->archive.state = ARCHIVE_STATE_FATAL; 835 tree_enter_initial_dir(t); 836 return (ARCHIVE_FATAL); 837 case TREE_ERROR_DIR: 838 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 839 "%s: Couldn't visit directory", 840 tree_current_path(t)); 841 tree_enter_initial_dir(t); 842 return (ARCHIVE_FAILED); 843 case 0: 844 tree_enter_initial_dir(t); 845 return (ARCHIVE_EOF); 846 case TREE_POSTDESCENT: 847 case TREE_POSTASCENT: 848 break; 849 case TREE_REGULAR: 850 lst = tree_current_lstat(t); 851 if (lst == NULL) { 852 archive_set_error(&a->archive, errno, 853 "%s: Cannot stat", 854 tree_current_path(t)); 855 tree_enter_initial_dir(t); 856 return (ARCHIVE_FAILED); 857 } 858 break; 859 } 860 } while (lst == NULL); 861 862 /* 863 * Distinguish 'L'/'P'/'H' symlink following. 864 */ 865 switch(t->symlink_mode) { 866 case 'H': 867 /* 'H': After the first item, rest like 'P'. */ 868 t->symlink_mode = 'P'; 869 /* 'H': First item (from command line) like 'L'. */ 870 /* FALLTHROUGH */ 871 case 'L': 872 /* 'L': Do descend through a symlink to dir. */ 873 descend = tree_current_is_dir(t); 874 /* 'L': Follow symlinks to files. */ 875 a->symlink_mode = 'L'; 876 a->follow_symlinks = 1; 877 /* 'L': Archive symlinks as targets, if we can. */ 878 st = tree_current_stat(t); 879 if (st != NULL && !tree_target_is_same_as_parent(t, st)) 880 break; 881 /* If stat fails, we have a broken symlink; 882 * in that case, don't follow the link. */ 883 /* FALLTHROUGH */ 884 default: 885 /* 'P': Don't descend through a symlink to dir. */ 886 descend = tree_current_is_physical_dir(t); 887 /* 'P': Don't follow symlinks to files. */ 888 a->symlink_mode = 'P'; 889 a->follow_symlinks = 0; 890 /* 'P': Archive symlinks as symlinks. */ 891 st = lst; 892 break; 893 } 894 895 if (update_current_filesystem(a, st->st_dev) != ARCHIVE_OK) { 896 a->archive.state = ARCHIVE_STATE_FATAL; 897 tree_enter_initial_dir(t); 898 return (ARCHIVE_FATAL); 899 } 900 t->descend = descend; 901 902 archive_entry_set_pathname(entry, tree_current_path(t)); 903 archive_entry_copy_sourcepath(entry, tree_current_access_path(t)); 904 archive_entry_copy_stat(entry, st); 905 906 /* Save the times to be restored. */ 907 t->restore_time.mtime = archive_entry_mtime(entry); 908 t->restore_time.mtime_nsec = archive_entry_mtime_nsec(entry); 909 t->restore_time.atime = archive_entry_atime(entry); 910 t->restore_time.atime_nsec = archive_entry_atime_nsec(entry); 911 t->restore_time.filetype = archive_entry_filetype(entry); 912 t->restore_time.noatime = t->current_filesystem->noatime; 913 914 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) 915 /* 916 * Open the current file to freely gather its metadata anywhere in 917 * working directory. 918 * Note: A symbolic link file cannot be opened with O_NOFOLLOW. 919 */ 920 if (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK) 921 fd = openat(tree_current_dir_fd(t), tree_current_access_path(t), 922 O_RDONLY | O_NONBLOCK); 923 /* Restore working directory if openat() operation failed or 924 * the file is a symbolic link. */ 925 if (fd < 0) 926 tree_enter_working_dir(t); 927 928 /* The current direcotry fd is needed at 929 * archive_read_disk_entry_from_file() function to read link data 930 * with readlinkat(). */ 931 a->entry_wd_fd = tree_current_dir_fd(t); 932 #endif 933 934 /* 935 * Populate the archive_entry with metadata from the disk. 936 */ 937 r = archive_read_disk_entry_from_file(&(a->archive), entry, fd, st); 938 939 /* Close the file descriptor used for reding the current file 940 * metadata at archive_read_disk_entry_from_file(). */ 941 if (fd >= 0) 942 close(fd); 943 944 /* Return to the initial directory. */ 945 tree_enter_initial_dir(t); 946 archive_entry_copy_sourcepath(entry, tree_current_path(t)); 947 948 /* 949 * EOF and FATAL are persistent at this layer. By 950 * modifying the state, we guarantee that future calls to 951 * read a header or read data will fail. 952 */ 953 switch (r) { 954 case ARCHIVE_EOF: 955 a->archive.state = ARCHIVE_STATE_EOF; 956 break; 957 case ARCHIVE_OK: 958 case ARCHIVE_WARN: 959 t->entry_total = 0; 960 if (archive_entry_filetype(entry) == AE_IFREG) { 961 t->nlink = archive_entry_nlink(entry); 962 t->entry_remaining_bytes = archive_entry_size(entry); 963 t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0; 964 if (!t->entry_eof && 965 setup_sparse(a, entry) != ARCHIVE_OK) 966 return (ARCHIVE_FATAL); 967 } else { 968 t->entry_remaining_bytes = 0; 969 t->entry_eof = 1; 970 } 971 a->archive.state = ARCHIVE_STATE_DATA; 972 break; 973 case ARCHIVE_RETRY: 974 break; 975 case ARCHIVE_FATAL: 976 a->archive.state = ARCHIVE_STATE_FATAL; 977 break; 978 } 979 980 return (r); 981 } 982 983 static int 984 setup_sparse(struct archive_read_disk *a, struct archive_entry *entry) 985 { 986 struct tree *t = a->tree; 987 int64_t length, offset; 988 int i; 989 990 t->sparse_count = archive_entry_sparse_reset(entry); 991 if (t->sparse_count+1 > t->sparse_list_size) { 992 free(t->sparse_list); 993 t->sparse_list_size = t->sparse_count + 1; 994 t->sparse_list = malloc(sizeof(t->sparse_list[0]) * 995 t->sparse_list_size); 996 if (t->sparse_list == NULL) { 997 t->sparse_list_size = 0; 998 archive_set_error(&a->archive, ENOMEM, 999 "Can't allocate data"); 1000 a->archive.state = ARCHIVE_STATE_FATAL; 1001 return (ARCHIVE_FATAL); 1002 } 1003 } 1004 for (i = 0; i < t->sparse_count; i++) { 1005 archive_entry_sparse_next(entry, &offset, &length); 1006 t->sparse_list[i].offset = offset; 1007 t->sparse_list[i].length = length; 1008 } 1009 if (i == 0) { 1010 t->sparse_list[i].offset = 0; 1011 t->sparse_list[i].length = archive_entry_size(entry); 1012 } else { 1013 t->sparse_list[i].offset = archive_entry_size(entry); 1014 t->sparse_list[i].length = 0; 1015 } 1016 t->current_sparse = t->sparse_list; 1017 1018 return (ARCHIVE_OK); 1019 } 1020 1021 /* 1022 * Called by the client to mark the directory just returned from 1023 * tree_next() as needing to be visited. 1024 */ 1025 int 1026 archive_read_disk_descend(struct archive *_a) 1027 { 1028 struct archive_read_disk *a = (struct archive_read_disk *)_a; 1029 struct tree *t = a->tree; 1030 1031 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, 1032 "archive_read_disk_descend"); 1033 1034 if (t->visit_type != TREE_REGULAR || !t->descend) { 1035 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1036 "Ignored the request descending the current object"); 1037 return (ARCHIVE_WARN); 1038 } 1039 1040 if (tree_current_is_physical_dir(t)) { 1041 tree_push(t, t->basename, t->current_filesystem_id, 1042 t->lst.st_dev, t->lst.st_ino, &t->restore_time); 1043 t->stack->flags |= isDir; 1044 } else if (tree_current_is_dir(t)) { 1045 tree_push(t, t->basename, t->current_filesystem_id, 1046 t->st.st_dev, t->st.st_ino, &t->restore_time); 1047 t->stack->flags |= isDirLink; 1048 } 1049 t->descend = 0; 1050 return (ARCHIVE_OK); 1051 } 1052 1053 int 1054 archive_read_disk_open(struct archive *_a, const char *pathname) 1055 { 1056 struct archive_read_disk *a = (struct archive_read_disk *)_a; 1057 1058 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 1059 ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED, 1060 "archive_read_disk_open"); 1061 archive_clear_error(&a->archive); 1062 1063 return (_archive_read_disk_open(_a, pathname)); 1064 } 1065 1066 int 1067 archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname) 1068 { 1069 struct archive_read_disk *a = (struct archive_read_disk *)_a; 1070 struct archive_string path; 1071 int ret; 1072 1073 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, 1074 ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED, 1075 "archive_read_disk_open_w"); 1076 archive_clear_error(&a->archive); 1077 1078 /* Make a char string from a wchar_t string. */ 1079 archive_string_init(&path); 1080 if (archive_string_append_from_wcs(&path, pathname, 1081 wcslen(pathname)) != 0) { 1082 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1083 "Can't convert a path to a char string"); 1084 a->archive.state = ARCHIVE_STATE_FATAL; 1085 ret = ARCHIVE_FATAL; 1086 } else 1087 ret = _archive_read_disk_open(_a, path.s); 1088 1089 archive_string_free(&path); 1090 return (ret); 1091 } 1092 1093 static int 1094 _archive_read_disk_open(struct archive *_a, const char *pathname) 1095 { 1096 struct archive_read_disk *a = (struct archive_read_disk *)_a; 1097 1098 if (a->tree != NULL) 1099 a->tree = tree_reopen(a->tree, pathname, a->restore_time); 1100 else 1101 a->tree = tree_open(pathname, a->symlink_mode, 1102 a->restore_time); 1103 if (a->tree == NULL) { 1104 archive_set_error(&a->archive, ENOMEM, 1105 "Can't allocate tar data"); 1106 a->archive.state = ARCHIVE_STATE_FATAL; 1107 return (ARCHIVE_FATAL); 1108 } 1109 a->archive.state = ARCHIVE_STATE_HEADER; 1110 1111 return (ARCHIVE_OK); 1112 } 1113 1114 /* 1115 * Return a current filesystem ID which is index of the filesystem entry 1116 * you've visited through archive_read_disk. 1117 */ 1118 int 1119 archive_read_disk_current_filesystem(struct archive *_a) 1120 { 1121 struct archive_read_disk *a = (struct archive_read_disk *)_a; 1122 1123 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, 1124 "archive_read_disk_current_filesystem"); 1125 1126 return (a->tree->current_filesystem_id); 1127 } 1128 1129 static int 1130 update_current_filesystem(struct archive_read_disk *a, int64_t dev) 1131 { 1132 struct tree *t = a->tree; 1133 int i, fid; 1134 1135 if (t->current_filesystem != NULL && 1136 t->current_filesystem->dev == dev) 1137 return (ARCHIVE_OK); 1138 1139 for (i = 0; i < t->max_filesystem_id; i++) { 1140 if (t->filesystem_table[i].dev == dev) { 1141 /* There is the filesytem ID we've already generated. */ 1142 t->current_filesystem_id = i; 1143 t->current_filesystem = &(t->filesystem_table[i]); 1144 return (ARCHIVE_OK); 1145 } 1146 } 1147 1148 /* 1149 * This is the new filesytem which we have to generate a new ID for. 1150 */ 1151 fid = t->max_filesystem_id++; 1152 if (t->max_filesystem_id > t->allocated_filesytem) { 1153 size_t s; 1154 1155 s = t->max_filesystem_id * 2; 1156 t->filesystem_table = realloc(t->filesystem_table, 1157 s * sizeof(*t->filesystem_table)); 1158 if (t->filesystem_table == NULL) { 1159 archive_set_error(&a->archive, ENOMEM, 1160 "Can't allocate tar data"); 1161 return (ARCHIVE_FATAL); 1162 } 1163 t->allocated_filesytem = s; 1164 } 1165 t->current_filesystem_id = fid; 1166 t->current_filesystem = &(t->filesystem_table[fid]); 1167 t->current_filesystem->dev = dev; 1168 t->current_filesystem->allocation_ptr = NULL; 1169 t->current_filesystem->buff = NULL; 1170 1171 /* Setup the current filesystem properties which depend on 1172 * platform specific. */ 1173 return (setup_current_filesystem(a)); 1174 } 1175 1176 /* 1177 * Returns 1 if current filesystem is generated filesystem, 0 if it is not 1178 * or -1 if it is unknown. 1179 */ 1180 int 1181 archive_read_disk_current_filesystem_is_synthetic(struct archive *_a) 1182 { 1183 struct archive_read_disk *a = (struct archive_read_disk *)_a; 1184 1185 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, 1186 "archive_read_disk_current_filesystem"); 1187 1188 return (a->tree->current_filesystem->synthetic); 1189 } 1190 1191 /* 1192 * Returns 1 if current filesystem is remote filesystem, 0 if it is not 1193 * or -1 if it is unknown. 1194 */ 1195 int 1196 archive_read_disk_current_filesystem_is_remote(struct archive *_a) 1197 { 1198 struct archive_read_disk *a = (struct archive_read_disk *)_a; 1199 1200 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, 1201 "archive_read_disk_current_filesystem"); 1202 1203 return (a->tree->current_filesystem->remote); 1204 } 1205 1206 #if defined(_PC_REC_INCR_XFER_SIZE) && defined(_PC_REC_MAX_XFER_SIZE) &&\ 1207 defined(_PC_REC_MIN_XFER_SIZE) && defined(_PC_REC_XFER_ALIGN) 1208 static int 1209 get_xfer_size(struct tree *t, int fd, const char *path) 1210 { 1211 t->current_filesystem->xfer_align = -1; 1212 errno = 0; 1213 if (fd >= 0) { 1214 t->current_filesystem->incr_xfer_size = 1215 fpathconf(fd, _PC_REC_INCR_XFER_SIZE); 1216 t->current_filesystem->max_xfer_size = 1217 fpathconf(fd, _PC_REC_MAX_XFER_SIZE); 1218 t->current_filesystem->min_xfer_size = 1219 fpathconf(fd, _PC_REC_MIN_XFER_SIZE); 1220 t->current_filesystem->xfer_align = 1221 fpathconf(fd, _PC_REC_XFER_ALIGN); 1222 } else if (path != NULL) { 1223 t->current_filesystem->incr_xfer_size = 1224 pathconf(path, _PC_REC_INCR_XFER_SIZE); 1225 t->current_filesystem->max_xfer_size = 1226 pathconf(path, _PC_REC_MAX_XFER_SIZE); 1227 t->current_filesystem->min_xfer_size = 1228 pathconf(path, _PC_REC_MIN_XFER_SIZE); 1229 t->current_filesystem->xfer_align = 1230 pathconf(path, _PC_REC_XFER_ALIGN); 1231 } 1232 /* At least we need an alignment size. */ 1233 if (t->current_filesystem->xfer_align == -1) 1234 return ((errno == EINVAL)?1:-1); 1235 else 1236 return (0); 1237 } 1238 #else 1239 static int 1240 get_xfer_size(struct tree *t, int fd, const char *path) 1241 { 1242 (void)t; /* UNUSED */ 1243 (void)fd; /* UNUSED */ 1244 (void)path; /* UNUSED */ 1245 return (1);/* Not supported */ 1246 } 1247 #endif 1248 1249 #if defined(HAVE_STATFS) && defined(HAVE_FSTATFS) && defined(MNT_LOCAL) \ 1250 && !defined(ST_LOCAL) 1251 1252 /* 1253 * Gather current filesystem properties on FreeBSD, OpenBSD and Mac OS X. 1254 */ 1255 static int 1256 setup_current_filesystem(struct archive_read_disk *a) 1257 { 1258 struct tree *t = a->tree; 1259 struct statfs sfs; 1260 #if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC) 1261 struct vfsconf vfc; 1262 #endif 1263 int r, xr = 0; 1264 #if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX) 1265 long nm; 1266 #endif 1267 1268 t->current_filesystem->synthetic = -1; 1269 t->current_filesystem->remote = -1; 1270 if (tree_current_is_symblic_link_target(t)) { 1271 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) 1272 /* 1273 * Get file system statistics on any directory 1274 * where current is. 1275 */ 1276 int fd = openat(tree_current_dir_fd(t), 1277 tree_current_access_path(t), O_RDONLY); 1278 if (fd < 0) { 1279 archive_set_error(&a->archive, errno, 1280 "openat failed"); 1281 return (ARCHIVE_FAILED); 1282 } 1283 r = fstatfs(fd, &sfs); 1284 if (r == 0) 1285 xr = get_xfer_size(t, fd, NULL); 1286 close(fd); 1287 #else 1288 r = statfs(tree_current_access_path(t), &sfs); 1289 if (r == 0) 1290 xr = get_xfer_size(t, -1, tree_current_access_path(t)); 1291 #endif 1292 } else { 1293 r = fstatfs(tree_current_dir_fd(t), &sfs); 1294 if (r == 0) 1295 xr = get_xfer_size(t, tree_current_dir_fd(t), NULL); 1296 } 1297 if (r == -1 || xr == -1) { 1298 archive_set_error(&a->archive, errno, "statfs failed"); 1299 return (ARCHIVE_FAILED); 1300 } else if (xr == 1) { 1301 /* pathconf(_PC_REX_*) operations are not supported. */ 1302 t->current_filesystem->xfer_align = sfs.f_bsize; 1303 t->current_filesystem->max_xfer_size = -1; 1304 t->current_filesystem->min_xfer_size = sfs.f_iosize; 1305 t->current_filesystem->incr_xfer_size = sfs.f_iosize; 1306 } 1307 if (sfs.f_flags & MNT_LOCAL) 1308 t->current_filesystem->remote = 0; 1309 else 1310 t->current_filesystem->remote = 1; 1311 1312 #if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC) 1313 r = getvfsbyname(sfs.f_fstypename, &vfc); 1314 if (r == -1) { 1315 archive_set_error(&a->archive, errno, "getvfsbyname failed"); 1316 return (ARCHIVE_FAILED); 1317 } 1318 if (vfc.vfc_flags & VFCF_SYNTHETIC) 1319 t->current_filesystem->synthetic = 1; 1320 else 1321 t->current_filesystem->synthetic = 0; 1322 #endif 1323 1324 #if defined(MNT_NOATIME) 1325 if (sfs.f_flags & MNT_NOATIME) 1326 t->current_filesystem->noatime = 1; 1327 else 1328 #endif 1329 t->current_filesystem->noatime = 0; 1330 1331 #if defined(HAVE_READDIR_R) 1332 /* Set maximum filename length. */ 1333 #if defined(HAVE_STRUCT_STATFS_F_NAMEMAX) 1334 t->current_filesystem->name_max = sfs.f_namemax; 1335 #else 1336 /* Mac OS X does not have f_namemax in struct statfs. */ 1337 if (tree_current_is_symblic_link_target(t)) 1338 nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); 1339 else 1340 nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); 1341 if (nm == -1) 1342 t->current_filesystem->name_max = NAME_MAX; 1343 else 1344 t->current_filesystem->name_max = nm; 1345 #endif 1346 #endif /* HAVE_READDIR_R */ 1347 return (ARCHIVE_OK); 1348 } 1349 1350 #elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL) 1351 1352 /* 1353 * Gather current filesystem properties on NetBSD 1354 */ 1355 static int 1356 setup_current_filesystem(struct archive_read_disk *a) 1357 { 1358 struct tree *t = a->tree; 1359 struct statvfs sfs; 1360 int r, xr = 0; 1361 1362 t->current_filesystem->synthetic = -1; 1363 if (tree_current_is_symblic_link_target(t)) { 1364 r = statvfs(tree_current_access_path(t), &sfs); 1365 if (r == 0) 1366 xr = get_xfer_size(t, -1, tree_current_access_path(t)); 1367 } else { 1368 #ifdef HAVE_FSTATVFS 1369 r = fstatvfs(tree_current_dir_fd(t), &sfs); 1370 if (r == 0) 1371 xr = get_xfer_size(t, tree_current_dir_fd(t), NULL); 1372 #else 1373 r = statvfs(".", &sfs); 1374 if (r == 0) 1375 xr = get_xfer_size(t, -1, "."); 1376 #endif 1377 } 1378 if (r == -1 || xr == -1) { 1379 t->current_filesystem->remote = -1; 1380 archive_set_error(&a->archive, errno, "statvfs failed"); 1381 return (ARCHIVE_FAILED); 1382 } else if (xr == 1) { 1383 /* Usuall come here unless NetBSD supports _PC_REC_XFER_ALIGN 1384 * for pathconf() function. */ 1385 t->current_filesystem->xfer_align = sfs.f_frsize; 1386 t->current_filesystem->max_xfer_size = -1; 1387 t->current_filesystem->min_xfer_size = sfs.f_iosize; 1388 t->current_filesystem->incr_xfer_size = sfs.f_iosize; 1389 } 1390 if (sfs.f_flag & ST_LOCAL) 1391 t->current_filesystem->remote = 0; 1392 else 1393 t->current_filesystem->remote = 1; 1394 1395 if (sfs.f_flag & ST_NOATIME) 1396 t->current_filesystem->noatime = 1; 1397 else 1398 t->current_filesystem->noatime = 0; 1399 1400 /* Set maximum filename length. */ 1401 t->current_filesystem->name_max = sfs.f_namemax; 1402 return (ARCHIVE_OK); 1403 } 1404 1405 #elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_LINUX_MAGIC_H) &&\ 1406 defined(HAVE_STATFS) && defined(HAVE_FSTATFS) 1407 /* 1408 * Note: statfs is deprecated since LSB 3.2 1409 */ 1410 1411 #ifndef CIFS_SUPER_MAGIC 1412 #define CIFS_SUPER_MAGIC 0xFF534D42 1413 #endif 1414 #ifndef DEVFS_SUPER_MAGIC 1415 #define DEVFS_SUPER_MAGIC 0x1373 1416 #endif 1417 1418 /* 1419 * Gather current filesystem properties on Linux 1420 */ 1421 static int 1422 setup_current_filesystem(struct archive_read_disk *a) 1423 { 1424 struct tree *t = a->tree; 1425 struct statfs sfs; 1426 struct statvfs svfs; 1427 int r, vr = 0, xr = 0; 1428 1429 if (tree_current_is_symblic_link_target(t)) { 1430 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) 1431 /* 1432 * Get file system statistics on any directory 1433 * where current is. 1434 */ 1435 int fd = openat(tree_current_dir_fd(t), 1436 tree_current_access_path(t), O_RDONLY); 1437 if (fd < 0) { 1438 archive_set_error(&a->archive, errno, 1439 "openat failed"); 1440 return (ARCHIVE_FAILED); 1441 } 1442 vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */ 1443 r = fstatfs(fd, &sfs); 1444 if (r == 0) 1445 xr = get_xfer_size(t, fd, NULL); 1446 close(fd); 1447 #else 1448 vr = statvfs(tree_current_access_path(t), &svfs); 1449 r = statfs(tree_current_access_path(t), &sfs); 1450 if (r == 0) 1451 xr = get_xfer_size(t, -1, tree_current_access_path(t)); 1452 #endif 1453 } else { 1454 #ifdef HAVE_FSTATFS 1455 vr = fstatvfs(tree_current_dir_fd(t), &svfs); 1456 r = fstatfs(tree_current_dir_fd(t), &sfs); 1457 if (r == 0) 1458 xr = get_xfer_size(t, tree_current_dir_fd(t), NULL); 1459 #elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) 1460 #error "Unexpected case. Please tell us about this error." 1461 #else 1462 vr = statvfs(".", &svfs); 1463 r = statfs(".", &sfs); 1464 if (r == 0) 1465 xr = get_xfer_size(t, -1, "."); 1466 #endif 1467 } 1468 if (r == -1 || xr == -1 || vr == -1) { 1469 t->current_filesystem->synthetic = -1; 1470 t->current_filesystem->remote = -1; 1471 archive_set_error(&a->archive, errno, "statfs failed"); 1472 return (ARCHIVE_FAILED); 1473 } else if (xr == 1) { 1474 /* pathconf(_PC_REX_*) operations are not supported. */ 1475 t->current_filesystem->xfer_align = svfs.f_frsize; 1476 t->current_filesystem->max_xfer_size = -1; 1477 t->current_filesystem->min_xfer_size = svfs.f_bsize; 1478 t->current_filesystem->incr_xfer_size = svfs.f_bsize; 1479 } 1480 switch (sfs.f_type) { 1481 case AFS_SUPER_MAGIC: 1482 case CIFS_SUPER_MAGIC: 1483 case CODA_SUPER_MAGIC: 1484 case NCP_SUPER_MAGIC:/* NetWare */ 1485 case NFS_SUPER_MAGIC: 1486 case SMB_SUPER_MAGIC: 1487 t->current_filesystem->remote = 1; 1488 t->current_filesystem->synthetic = 0; 1489 break; 1490 case DEVFS_SUPER_MAGIC: 1491 case PROC_SUPER_MAGIC: 1492 case USBDEVICE_SUPER_MAGIC: 1493 t->current_filesystem->remote = 0; 1494 t->current_filesystem->synthetic = 1; 1495 break; 1496 default: 1497 t->current_filesystem->remote = 0; 1498 t->current_filesystem->synthetic = 0; 1499 break; 1500 } 1501 1502 #if defined(ST_NOATIME) 1503 if (svfs.f_flag & ST_NOATIME) 1504 t->current_filesystem->noatime = 1; 1505 else 1506 #endif 1507 t->current_filesystem->noatime = 0; 1508 1509 #if defined(HAVE_READDIR_R) 1510 /* Set maximum filename length. */ 1511 t->current_filesystem->name_max = sfs.f_namelen; 1512 #endif 1513 return (ARCHIVE_OK); 1514 } 1515 1516 #elif defined(HAVE_SYS_STATVFS_H) &&\ 1517 (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) 1518 1519 /* 1520 * Gather current filesystem properties on other posix platform. 1521 */ 1522 static int 1523 setup_current_filesystem(struct archive_read_disk *a) 1524 { 1525 struct tree *t = a->tree; 1526 struct statvfs sfs; 1527 int r, xr = 0; 1528 1529 t->current_filesystem->synthetic = -1;/* Not supported */ 1530 t->current_filesystem->remote = -1;/* Not supported */ 1531 if (tree_current_is_symblic_link_target(t)) { 1532 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) 1533 /* 1534 * Get file system statistics on any directory 1535 * where current is. 1536 */ 1537 int fd = openat(tree_current_dir_fd(t), 1538 tree_current_access_path(t), O_RDONLY); 1539 if (fd < 0) { 1540 archive_set_error(&a->archive, errno, 1541 "openat failed"); 1542 return (ARCHIVE_FAILED); 1543 } 1544 r = fstatvfs(fd, &sfs); 1545 if (r == 0) 1546 xr = get_xfer_size(t, fd, NULL); 1547 close(fd); 1548 #else 1549 r = statvfs(tree_current_access_path(t), &sfs); 1550 if (r == 0) 1551 xr = get_xfer_size(t, -1, tree_current_access_path(t)); 1552 #endif 1553 } else { 1554 #ifdef HAVE_FSTATVFS 1555 r = fstatvfs(tree_current_dir_fd(t), &sfs); 1556 if (r == 0) 1557 xr = get_xfer_size(t, tree_current_dir_fd(t), NULL); 1558 #elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) 1559 #error "Unexpected case. Please tell us about this error." 1560 #else 1561 r = statvfs(".", &sfs); 1562 if (r == 0) 1563 xr = get_xfer_size(t, -1, "."); 1564 #endif 1565 } 1566 if (r == -1 || xr == -1) { 1567 t->current_filesystem->synthetic = -1; 1568 t->current_filesystem->remote = -1; 1569 archive_set_error(&a->archive, errno, "statvfs failed"); 1570 return (ARCHIVE_FAILED); 1571 } else if (xr == 1) { 1572 /* pathconf(_PC_REX_*) operations are not supported. */ 1573 t->current_filesystem->xfer_align = sfs.f_frsize; 1574 t->current_filesystem->max_xfer_size = -1; 1575 t->current_filesystem->min_xfer_size = sfs.f_bsize; 1576 t->current_filesystem->incr_xfer_size = sfs.f_bsize; 1577 } 1578 1579 #if defined(ST_NOATIME) 1580 if (sfs.f_flag & ST_NOATIME) 1581 t->current_filesystem->noatime = 1; 1582 else 1583 #endif 1584 t->current_filesystem->noatime = 0; 1585 1586 #if defined(HAVE_READDIR_R) 1587 /* Set maximum filename length. */ 1588 t->current_filesystem->name_max = sfs.f_namemax; 1589 #endif 1590 return (ARCHIVE_OK); 1591 } 1592 1593 #else 1594 1595 /* 1596 * Generic: Gather current filesystem properties. 1597 * TODO: Is this generic function really needed? 1598 */ 1599 static int 1600 setup_current_filesystem(struct archive_read_disk *a) 1601 { 1602 struct tree *t = a->tree; 1603 #if defined(_PC_NAME_MAX) && defined(HAVE_READDIR_R) 1604 long nm; 1605 #endif 1606 t->current_filesystem->synthetic = -1;/* Not supported */ 1607 t->current_filesystem->remote = -1;/* Not supported */ 1608 t->current_filesystem->noatime = 0; 1609 (void)get_xfer_size(t, -1, ".");/* Dummy call to avoid build error. */ 1610 t->current_filesystem->xfer_align = -1;/* Unknown */ 1611 t->current_filesystem->max_xfer_size = -1; 1612 t->current_filesystem->min_xfer_size = -1; 1613 t->current_filesystem->incr_xfer_size = -1; 1614 1615 #if defined(HAVE_READDIR_R) 1616 /* Set maximum filename length. */ 1617 # if defined(_PC_NAME_MAX) 1618 if (tree_current_is_symblic_link_target(t)) 1619 nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); 1620 else 1621 nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); 1622 if (nm == -1) 1623 # endif /* _PC_NAME_MAX */ 1624 /* 1625 * Some sysmtes (HP-UX or others?) incorrectly defined 1626 * NAME_MAX macro to be a smaller value. 1627 */ 1628 # if defined(NAME_MAX) && NAME_MAX >= 255 1629 t->current_filesystem->name_max = NAME_MAX; 1630 # else 1631 /* No way to get a trusted value of maximum filename 1632 * length. */ 1633 t->current_filesystem->name_max = PATH_MAX; 1634 # endif /* NAME_MAX */ 1635 # if defined(_PC_NAME_MAX) 1636 else 1637 t->current_filesystem->name_max = nm; 1638 # endif /* _PC_NAME_MAX */ 1639 #endif /* HAVE_READDIR_R */ 1640 return (ARCHIVE_OK); 1641 } 1642 1643 #endif 1644 1645 static int 1646 close_and_restore_time(int fd, struct tree *t, struct restore_time *rt) 1647 { 1648 #ifndef HAVE_UTIMES 1649 (void)a; /* UNUSED */ 1650 return (close(fd)); 1651 #else 1652 #if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__) 1653 struct timespec timespecs[2]; 1654 #endif 1655 struct timeval times[2]; 1656 1657 if ((t->flags & needsRestoreTimes) == 0 || rt->noatime) { 1658 if (fd >= 0) 1659 return (close(fd)); 1660 else 1661 return (0); 1662 } 1663 1664 #if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__) 1665 timespecs[1].tv_sec = rt->mtime; 1666 timespecs[1].tv_nsec = rt->mtime_nsec; 1667 1668 timespecs[0].tv_sec = rt->atime; 1669 timespecs[0].tv_nsec = rt->atime_nsec; 1670 /* futimens() is defined in POSIX.1-2008. */ 1671 if (futimens(fd, timespecs) == 0) 1672 return (close(fd)); 1673 #endif 1674 1675 times[1].tv_sec = rt->mtime; 1676 times[1].tv_usec = rt->mtime_nsec / 1000; 1677 1678 times[0].tv_sec = rt->atime; 1679 times[0].tv_usec = rt->atime_nsec / 1000; 1680 1681 #if !defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES) && !defined(__CYGWIN__) 1682 if (futimes(fd, times) == 0) 1683 return (close(fd)); 1684 #endif 1685 close(fd); 1686 #if defined(HAVE_FUTIMESAT) 1687 if (futimesat(tree_current_dir_fd(t), rt->name, times) == 0) 1688 return (0); 1689 #endif 1690 #ifdef HAVE_LUTIMES 1691 if (lutimes(rt->name, times) != 0) 1692 #else 1693 if (AE_IFLNK != rt->filetype && utimes(rt->name, times) != 0) 1694 #endif 1695 return (-1); 1696 #endif 1697 return (0); 1698 } 1699 1700 /* 1701 * Add a directory path to the current stack. 1702 */ 1703 static void 1704 tree_push(struct tree *t, const char *path, int filesystem_id, 1705 int64_t dev, int64_t ino, struct restore_time *rt) 1706 { 1707 struct tree_entry *te; 1708 1709 te = malloc(sizeof(*te)); 1710 memset(te, 0, sizeof(*te)); 1711 te->next = t->stack; 1712 te->parent = t->current; 1713 if (te->parent) 1714 te->depth = te->parent->depth + 1; 1715 t->stack = te; 1716 archive_string_init(&te->name); 1717 te->symlink_parent_fd = -1; 1718 archive_strcpy(&te->name, path); 1719 te->flags = needsDescent | needsOpen | needsAscent; 1720 te->filesystem_id = filesystem_id; 1721 te->dev = dev; 1722 te->ino = ino; 1723 te->dirname_length = t->dirname_length; 1724 te->restore_time.name = te->name.s; 1725 if (rt != NULL) { 1726 te->restore_time.mtime = rt->mtime; 1727 te->restore_time.mtime_nsec = rt->mtime_nsec; 1728 te->restore_time.atime = rt->atime; 1729 te->restore_time.atime_nsec = rt->atime_nsec; 1730 te->restore_time.filetype = rt->filetype; 1731 te->restore_time.noatime = rt->noatime; 1732 } 1733 } 1734 1735 /* 1736 * Append a name to the current dir path. 1737 */ 1738 static void 1739 tree_append(struct tree *t, const char *name, size_t name_length) 1740 { 1741 size_t size_needed; 1742 1743 t->path.s[t->dirname_length] = '\0'; 1744 t->path.length = t->dirname_length; 1745 /* Strip trailing '/' from name, unless entire name is "/". */ 1746 while (name_length > 1 && name[name_length - 1] == '/') 1747 name_length--; 1748 1749 /* Resize pathname buffer as needed. */ 1750 size_needed = name_length + t->dirname_length + 2; 1751 archive_string_ensure(&t->path, size_needed); 1752 /* Add a separating '/' if it's needed. */ 1753 if (t->dirname_length > 0 && t->path.s[archive_strlen(&t->path)-1] != '/') 1754 archive_strappend_char(&t->path, '/'); 1755 t->basename = t->path.s + archive_strlen(&t->path); 1756 archive_strncat(&t->path, name, name_length); 1757 t->restore_time.name = t->basename; 1758 } 1759 1760 /* 1761 * Open a directory tree for traversal. 1762 */ 1763 static struct tree * 1764 tree_open(const char *path, int symlink_mode, int restore_time) 1765 { 1766 struct tree *t; 1767 1768 if ((t = malloc(sizeof(*t))) == NULL) 1769 return (NULL); 1770 memset(t, 0, sizeof(*t)); 1771 archive_string_init(&t->path); 1772 archive_string_ensure(&t->path, 31); 1773 t->initial_symlink_mode = symlink_mode; 1774 return (tree_reopen(t, path, restore_time)); 1775 } 1776 1777 static struct tree * 1778 tree_reopen(struct tree *t, const char *path, int restore_time) 1779 { 1780 t->flags = (restore_time)?needsRestoreTimes:0; 1781 t->visit_type = 0; 1782 t->tree_errno = 0; 1783 t->dirname_length = 0; 1784 t->depth = 0; 1785 t->descend = 0; 1786 t->current = NULL; 1787 t->d = INVALID_DIR_HANDLE; 1788 t->symlink_mode = t->initial_symlink_mode; 1789 archive_string_empty(&t->path); 1790 t->entry_fd = -1; 1791 t->entry_eof = 0; 1792 t->entry_remaining_bytes = 0; 1793 1794 /* First item is set up a lot like a symlink traversal. */ 1795 tree_push(t, path, 0, 0, 0, NULL); 1796 t->stack->flags = needsFirstVisit; 1797 t->maxOpenCount = t->openCount = 1; 1798 t->initial_dir_fd = open(".", O_RDONLY); 1799 t->working_dir_fd = dup(t->initial_dir_fd); 1800 return (t); 1801 } 1802 1803 static int 1804 tree_descent(struct tree *t) 1805 { 1806 int r = 0; 1807 1808 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) 1809 int new_fd; 1810 t->dirname_length = archive_strlen(&t->path); 1811 new_fd = openat(t->working_dir_fd, t->stack->name.s, O_RDONLY); 1812 if (new_fd < 0) { 1813 t->tree_errno = errno; 1814 r = TREE_ERROR_DIR; 1815 } else { 1816 t->depth++; 1817 /* If it is a link, set up fd for the ascent. */ 1818 if (t->stack->flags & isDirLink) { 1819 t->stack->symlink_parent_fd = t->working_dir_fd; 1820 t->openCount++; 1821 if (t->openCount > t->maxOpenCount) 1822 t->maxOpenCount = t->openCount; 1823 } else 1824 close(t->working_dir_fd); 1825 t->working_dir_fd = new_fd; 1826 } 1827 #else 1828 /* If it is a link, set up fd for the ascent. */ 1829 if (t->stack->flags & isDirLink) 1830 t->stack->symlink_parent_fd = t->working_dir_fd; 1831 else { 1832 close(t->working_dir_fd); 1833 t->openCount--; 1834 } 1835 t->working_dir_fd = -1; 1836 t->dirname_length = archive_strlen(&t->path); 1837 if (chdir(t->stack->name.s) != 0) 1838 { 1839 t->tree_errno = errno; 1840 r = TREE_ERROR_DIR; 1841 } else { 1842 t->depth++; 1843 t->working_dir_fd = open(".", O_RDONLY); 1844 t->openCount++; 1845 if (t->openCount > t->maxOpenCount) 1846 t->maxOpenCount = t->openCount; 1847 } 1848 #endif 1849 return (r); 1850 } 1851 1852 /* 1853 * We've finished a directory; ascend back to the parent. 1854 */ 1855 static int 1856 tree_ascend(struct tree *t) 1857 { 1858 struct tree_entry *te; 1859 int r = 0, prev_dir_fd; 1860 1861 te = t->stack; 1862 prev_dir_fd = t->working_dir_fd; 1863 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) 1864 if (te->flags & isDirLink) 1865 t->working_dir_fd = te->symlink_parent_fd; 1866 else { 1867 int new_fd = openat(t->working_dir_fd, "..", O_RDONLY); 1868 if (new_fd < 0) { 1869 t->tree_errno = errno; 1870 r = TREE_ERROR_FATAL; 1871 } else 1872 t->working_dir_fd = new_fd; 1873 } 1874 #else 1875 if (te->flags & isDirLink) { 1876 if (fchdir(te->symlink_parent_fd) != 0) { 1877 t->tree_errno = errno; 1878 r = TREE_ERROR_FATAL; 1879 } else 1880 t->working_dir_fd = te->symlink_parent_fd; 1881 } else { 1882 if (chdir("..") != 0) { 1883 t->tree_errno = errno; 1884 r = TREE_ERROR_FATAL; 1885 } else 1886 t->working_dir_fd = open(".", O_RDONLY); 1887 } 1888 #endif 1889 if (r == 0) { 1890 /* Current directory has been changed, we should 1891 * close an fd of previous working directory. */ 1892 close_and_restore_time(prev_dir_fd, t, &te->restore_time); 1893 if (te->flags & isDirLink) { 1894 t->openCount--; 1895 te->symlink_parent_fd = -1; 1896 } 1897 t->depth--; 1898 } 1899 return (r); 1900 } 1901 1902 /* 1903 * Return to the initial directory where tree_open() was performed. 1904 */ 1905 static int 1906 tree_enter_initial_dir(struct tree *t) 1907 { 1908 int r = 0; 1909 1910 if (t->flags & onWorkingDir) { 1911 r = fchdir(t->initial_dir_fd); 1912 if (r == 0) 1913 t->flags &= ~onWorkingDir; 1914 } 1915 return (r); 1916 } 1917 1918 /* 1919 * Restore working directory of directory traversals. 1920 */ 1921 static int 1922 tree_enter_working_dir(struct tree *t) 1923 { 1924 int r = 0; 1925 1926 /* 1927 * Change the current directory if really needed. 1928 * Sometimes this is unneeded when we did not do 1929 * descent. 1930 */ 1931 if (t->depth > 0 && (t->flags & onWorkingDir) == 0) { 1932 r = fchdir(t->working_dir_fd); 1933 if (r == 0) 1934 t->flags |= onWorkingDir; 1935 } 1936 return (r); 1937 } 1938 1939 static int 1940 tree_current_dir_fd(struct tree *t) 1941 { 1942 return (t->working_dir_fd); 1943 } 1944 1945 /* 1946 * Pop the working stack. 1947 */ 1948 static void 1949 tree_pop(struct tree *t) 1950 { 1951 struct tree_entry *te; 1952 1953 t->path.s[t->dirname_length] = '\0'; 1954 t->path.length = t->dirname_length; 1955 if (t->stack == t->current && t->current != NULL) 1956 t->current = t->current->parent; 1957 te = t->stack; 1958 t->stack = te->next; 1959 t->dirname_length = te->dirname_length; 1960 t->basename = t->path.s + t->dirname_length; 1961 while (t->basename[0] == '/') 1962 t->basename++; 1963 archive_string_free(&te->name); 1964 free(te); 1965 } 1966 1967 /* 1968 * Get the next item in the tree traversal. 1969 */ 1970 static int 1971 tree_next(struct tree *t) 1972 { 1973 int r; 1974 1975 while (t->stack != NULL) { 1976 /* If there's an open dir, get the next entry from there. */ 1977 if (t->d != INVALID_DIR_HANDLE) { 1978 r = tree_dir_next_posix(t); 1979 if (r == 0) 1980 continue; 1981 return (r); 1982 } 1983 1984 if (t->stack->flags & needsFirstVisit) { 1985 /* Top stack item needs a regular visit. */ 1986 t->current = t->stack; 1987 tree_append(t, t->stack->name.s, 1988 archive_strlen(&(t->stack->name))); 1989 /* t->dirname_length = t->path_length; */ 1990 /* tree_pop(t); */ 1991 t->stack->flags &= ~needsFirstVisit; 1992 return (t->visit_type = TREE_REGULAR); 1993 } else if (t->stack->flags & needsDescent) { 1994 /* Top stack item is dir to descend into. */ 1995 t->current = t->stack; 1996 tree_append(t, t->stack->name.s, 1997 archive_strlen(&(t->stack->name))); 1998 t->stack->flags &= ~needsDescent; 1999 r = tree_descent(t); 2000 if (r != 0) { 2001 tree_pop(t); 2002 t->visit_type = r; 2003 } else 2004 t->visit_type = TREE_POSTDESCENT; 2005 return (t->visit_type); 2006 } else if (t->stack->flags & needsOpen) { 2007 t->stack->flags &= ~needsOpen; 2008 r = tree_dir_next_posix(t); 2009 if (r == 0) 2010 continue; 2011 return (r); 2012 } else if (t->stack->flags & needsAscent) { 2013 /* Top stack item is dir and we're done with it. */ 2014 r = tree_ascend(t); 2015 tree_pop(t); 2016 t->visit_type = r != 0 ? r : TREE_POSTASCENT; 2017 return (t->visit_type); 2018 } else { 2019 /* Top item on stack is dead. */ 2020 tree_pop(t); 2021 t->flags &= ~hasLstat; 2022 t->flags &= ~hasStat; 2023 } 2024 } 2025 return (t->visit_type = 0); 2026 } 2027 2028 static int 2029 tree_dir_next_posix(struct tree *t) 2030 { 2031 int r; 2032 const char *name; 2033 size_t namelen; 2034 2035 if (t->d == NULL) { 2036 #if defined(HAVE_READDIR_R) 2037 size_t dirent_size; 2038 #endif 2039 2040 #if defined(HAVE_FDOPENDIR) 2041 if ((t->d = fdopendir(dup(t->working_dir_fd))) == NULL) { 2042 #else 2043 if ((t->d = opendir(".")) == NULL) { 2044 #endif 2045 r = tree_ascend(t); /* Undo "chdir" */ 2046 tree_pop(t); 2047 t->tree_errno = errno; 2048 t->visit_type = r != 0 ? r : TREE_ERROR_DIR; 2049 return (t->visit_type); 2050 } 2051 #if defined(HAVE_READDIR_R) 2052 dirent_size = offsetof(struct dirent, d_name) + 2053 t->filesystem_table[t->current->filesystem_id].name_max + 1; 2054 if (t->dirent == NULL || t->dirent_allocated < dirent_size) { 2055 free(t->dirent); 2056 t->dirent = malloc(dirent_size); 2057 if (t->dirent == NULL) { 2058 closedir(t->d); 2059 t->d = INVALID_DIR_HANDLE; 2060 (void)tree_ascend(t); 2061 tree_pop(t); 2062 t->tree_errno = ENOMEM; 2063 t->visit_type = TREE_ERROR_DIR; 2064 return (t->visit_type); 2065 } 2066 t->dirent_allocated = dirent_size; 2067 } 2068 #endif /* HAVE_READDIR_R */ 2069 } 2070 for (;;) { 2071 #if defined(HAVE_READDIR_R) 2072 r = readdir_r(t->d, t->dirent, &t->de); 2073 if (r != 0 || t->de == NULL) { 2074 #else 2075 errno = 0; 2076 t->de = readdir(t->d); 2077 if (t->de == NULL) { 2078 r = errno; 2079 #endif 2080 closedir(t->d); 2081 t->d = INVALID_DIR_HANDLE; 2082 if (r != 0) { 2083 t->tree_errno = r; 2084 t->visit_type = TREE_ERROR_DIR; 2085 return (t->visit_type); 2086 } else 2087 return (0); 2088 } 2089 name = t->de->d_name; 2090 namelen = D_NAMELEN(t->de); 2091 t->flags &= ~hasLstat; 2092 t->flags &= ~hasStat; 2093 if (name[0] == '.' && name[1] == '\0') 2094 continue; 2095 if (name[0] == '.' && name[1] == '.' && name[2] == '\0') 2096 continue; 2097 tree_append(t, name, namelen); 2098 return (t->visit_type = TREE_REGULAR); 2099 } 2100 } 2101 2102 2103 /* 2104 * Get the stat() data for the entry just returned from tree_next(). 2105 */ 2106 static const struct stat * 2107 tree_current_stat(struct tree *t) 2108 { 2109 if (!(t->flags & hasStat)) { 2110 #ifdef HAVE_FSTATAT 2111 if (fstatat(tree_current_dir_fd(t), 2112 tree_current_access_path(t), &t->st, 0) != 0) 2113 #else 2114 if (stat(tree_current_access_path(t), &t->st) != 0) 2115 #endif 2116 return NULL; 2117 t->flags |= hasStat; 2118 } 2119 return (&t->st); 2120 } 2121 2122 /* 2123 * Get the lstat() data for the entry just returned from tree_next(). 2124 */ 2125 static const struct stat * 2126 tree_current_lstat(struct tree *t) 2127 { 2128 if (!(t->flags & hasLstat)) { 2129 #ifdef HAVE_FSTATAT 2130 if (fstatat(tree_current_dir_fd(t), 2131 tree_current_access_path(t), &t->lst, 2132 AT_SYMLINK_NOFOLLOW) != 0) 2133 #else 2134 if (lstat(tree_current_access_path(t), &t->lst) != 0) 2135 #endif 2136 return NULL; 2137 t->flags |= hasLstat; 2138 } 2139 return (&t->lst); 2140 } 2141 2142 /* 2143 * Test whether current entry is a dir or link to a dir. 2144 */ 2145 static int 2146 tree_current_is_dir(struct tree *t) 2147 { 2148 const struct stat *st; 2149 /* 2150 * If we already have lstat() info, then try some 2151 * cheap tests to determine if this is a dir. 2152 */ 2153 if (t->flags & hasLstat) { 2154 /* If lstat() says it's a dir, it must be a dir. */ 2155 if (S_ISDIR(tree_current_lstat(t)->st_mode)) 2156 return 1; 2157 /* Not a dir; might be a link to a dir. */ 2158 /* If it's not a link, then it's not a link to a dir. */ 2159 if (!S_ISLNK(tree_current_lstat(t)->st_mode)) 2160 return 0; 2161 /* 2162 * It's a link, but we don't know what it's a link to, 2163 * so we'll have to use stat(). 2164 */ 2165 } 2166 2167 st = tree_current_stat(t); 2168 /* If we can't stat it, it's not a dir. */ 2169 if (st == NULL) 2170 return 0; 2171 /* Use the definitive test. Hopefully this is cached. */ 2172 return (S_ISDIR(st->st_mode)); 2173 } 2174 2175 /* 2176 * Test whether current entry is a physical directory. Usually, we 2177 * already have at least one of stat() or lstat() in memory, so we 2178 * use tricks to try to avoid an extra trip to the disk. 2179 */ 2180 static int 2181 tree_current_is_physical_dir(struct tree *t) 2182 { 2183 const struct stat *st; 2184 2185 /* 2186 * If stat() says it isn't a dir, then it's not a dir. 2187 * If stat() data is cached, this check is free, so do it first. 2188 */ 2189 if ((t->flags & hasStat) 2190 && (!S_ISDIR(tree_current_stat(t)->st_mode))) 2191 return 0; 2192 2193 /* 2194 * Either stat() said it was a dir (in which case, we have 2195 * to determine whether it's really a link to a dir) or 2196 * stat() info wasn't available. So we use lstat(), which 2197 * hopefully is already cached. 2198 */ 2199 2200 st = tree_current_lstat(t); 2201 /* If we can't stat it, it's not a dir. */ 2202 if (st == NULL) 2203 return 0; 2204 /* Use the definitive test. Hopefully this is cached. */ 2205 return (S_ISDIR(st->st_mode)); 2206 } 2207 2208 /* 2209 * Test whether the same file has been in the tree as its parent. 2210 */ 2211 static int 2212 tree_target_is_same_as_parent(struct tree *t, const struct stat *st) 2213 { 2214 struct tree_entry *te; 2215 2216 for (te = t->current->parent; te != NULL; te = te->parent) { 2217 if (te->dev == st->st_dev && te->ino == st->st_ino) 2218 return (1); 2219 } 2220 return (0); 2221 } 2222 2223 /* 2224 * Test whether the current file is symbolic link target and 2225 * on the other filesystem. 2226 */ 2227 static int 2228 tree_current_is_symblic_link_target(struct tree *t) 2229 { 2230 static const struct stat *lst, *st; 2231 2232 lst = tree_current_lstat(t); 2233 st = tree_current_stat(t); 2234 return (st != NULL && st->st_dev == t->current_filesystem->dev && 2235 st->st_dev != lst->st_dev); 2236 } 2237 2238 /* 2239 * Return the access path for the entry just returned from tree_next(). 2240 */ 2241 static const char * 2242 tree_current_access_path(struct tree *t) 2243 { 2244 return (t->basename); 2245 } 2246 2247 /* 2248 * Return the full path for the entry just returned from tree_next(). 2249 */ 2250 static const char * 2251 tree_current_path(struct tree *t) 2252 { 2253 return (t->path.s); 2254 } 2255 2256 /* 2257 * Terminate the traversal. 2258 */ 2259 static void 2260 tree_close(struct tree *t) 2261 { 2262 2263 if (t == NULL) 2264 return; 2265 if (t->entry_fd >= 0) { 2266 close_and_restore_time(t->entry_fd, t, &t->restore_time); 2267 t->entry_fd = -1; 2268 } 2269 /* Close the handle of readdir(). */ 2270 if (t->d != INVALID_DIR_HANDLE) { 2271 closedir(t->d); 2272 t->d = INVALID_DIR_HANDLE; 2273 } 2274 /* Release anything remaining in the stack. */ 2275 while (t->stack != NULL) { 2276 if (t->stack->flags & isDirLink) 2277 close(t->stack->symlink_parent_fd); 2278 tree_pop(t); 2279 } 2280 if (t->working_dir_fd >= 0) { 2281 close(t->working_dir_fd); 2282 t->working_dir_fd = -1; 2283 } 2284 if (t->initial_dir_fd >= 0) { 2285 close(t->initial_dir_fd); 2286 t->initial_dir_fd = -1; 2287 } 2288 } 2289 2290 /* 2291 * Release any resources. 2292 */ 2293 static void 2294 tree_free(struct tree *t) 2295 { 2296 int i; 2297 2298 if (t == NULL) 2299 return; 2300 archive_string_free(&t->path); 2301 #if defined(HAVE_READDIR_R) 2302 free(t->dirent); 2303 #endif 2304 free(t->sparse_list); 2305 for (i = 0; i < t->max_filesystem_id; i++) 2306 free(t->filesystem_table[i].allocation_ptr); 2307 free(t->filesystem_table); 2308 free(t); 2309 } 2310 2311 #endif 2312