2 * Copyright (c) 2003-2009 Tim Kientzle
3 * Copyright (c) 2010-2012 Michihiro NAKAJIMA
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
28 /* This is the tree-walking code for POSIX systems. */
29 #if !defined(_WIN32) || defined(__CYGWIN__)
31 #include "archive_platform.h"
32 __FBSDID("$FreeBSD$");
34 #ifdef HAVE_SYS_PARAM_H
35 #include <sys/param.h>
37 #ifdef HAVE_SYS_MOUNT_H
38 #include <sys/mount.h>
40 #ifdef HAVE_SYS_STAT_H
43 #ifdef HAVE_SYS_STATFS_H
44 #include <sys/statfs.h>
46 #ifdef HAVE_SYS_STATVFS_H
47 #include <sys/statvfs.h>
49 #ifdef HAVE_SYS_TIME_H
52 #ifdef HAVE_LINUX_MAGIC_H
53 #include <linux/magic.h>
55 #ifdef HAVE_LINUX_FS_H
59 * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
60 * As the include guards don't agree, the order of include is important.
62 #ifdef HAVE_LINUX_EXT2_FS_H
63 #include <linux/ext2_fs.h> /* for Linux file flags */
65 #if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
66 #include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
92 #ifdef HAVE_SYS_IOCTL_H
93 #include <sys/ioctl.h>
97 #include "archive_string.h"
98 #include "archive_entry.h"
99 #include "archive_private.h"
100 #include "archive_read_disk_private.h"
103 #error fchdir function required.
113 * This is a new directory-walking system that addresses a number
114 * of problems I've had with fts(3). In particular, it has no
115 * pathname-length limits (other than the size of 'int'), handles
116 * deep logical traversals, uses considerably less memory, and has
117 * an opaque interface (easier to modify in the future).
119 * Internally, it keeps a single list of "tree_entry" items that
120 * represent filesystem objects that require further attention.
121 * Non-directories are not kept in memory: they are pulled from
122 * readdir(), returned to the client, then freed as soon as possible.
123 * Any directory entry to be traversed gets pushed onto the stack.
125 * There is surprisingly little information that needs to be kept for
126 * each item on the stack. Just the name, depth (represented here as the
127 * string length of the parent directory's pathname), and some markers
128 * indicating how to get back to the parent (via chdir("..") for a
129 * regular dir or via fchdir(2) for a symlink).
134 * 3) Arbitrary logical traversals by closing/reopening intermediate fds.
137 struct restore_time
{
149 struct tree_entry
*next
;
150 struct tree_entry
*parent
;
151 struct archive_string name
;
152 size_t dirname_length
;
157 /* How to return back to the parent of a symlink. */
158 int symlink_parent_fd
;
159 /* How to restore time of a directory. */
160 struct restore_time restore_time
;
168 #if defined(HAVE_READDIR_R)
177 * Buffer used for reading file contents.
179 /* Exactly allocated memory pointer. */
180 unsigned char *allocation_ptr
;
181 /* Pointer adjusted to the filesystem alignment . */
186 /* Definitions for tree_entry.flags bitmap. */
187 #define isDir 1 /* This entry is a regular directory. */
188 #define isDirLink 2 /* This entry is a symbolic link to a directory. */
189 #define needsFirstVisit 4 /* This is an initial entry. */
190 #define needsDescent 8 /* This entry needs to be previsited. */
191 #define needsOpen 16 /* This is a directory that needs to be opened. */
192 #define needsAscent 32 /* This entry needs to be postvisited. */
195 * Local data for this package.
198 struct tree_entry
*stack
;
199 struct tree_entry
*current
;
201 #define INVALID_DIR_HANDLE NULL
203 #if defined(HAVE_READDIR_R)
204 struct dirent
*dirent
;
205 size_t dirent_allocated
;
209 /* Error code from last failed operation. */
212 /* Dynamically-sized buffer for holding path */
213 struct archive_string path
;
215 /* Last path element */
216 const char *basename
;
217 /* Leading dir length */
218 size_t dirname_length
;
230 /* How to restore time of a file. */
231 struct restore_time restore_time
;
233 struct entry_sparse
{
236 } *sparse_list
, *current_sparse
;
238 int sparse_list_size
;
240 char initial_symlink_mode
;
242 struct filesystem
*current_filesystem
;
243 struct filesystem
*filesystem_table
;
244 int initial_filesystem_id
;
245 int current_filesystem_id
;
246 int max_filesystem_id
;
247 int allocated_filesytem
;
251 int64_t entry_remaining_bytes
;
253 unsigned char *entry_buff
;
254 size_t entry_buff_size
;
257 /* Definitions for tree.flags bitmap. */
258 #define hasStat 16 /* The st entry is valid. */
259 #define hasLstat 32 /* The lst entry is valid. */
260 #define onWorkingDir 64 /* We are on the working dir where we are
261 * reading directory entry at this time. */
262 #define needsRestoreTimes 128
263 #define onInitialDir 256 /* We are on the initial dir. */
266 tree_dir_next_posix(struct tree
*t
);
268 #ifdef HAVE_DIRENT_D_NAMLEN
269 /* BSD extension; avoids need for a strlen() call. */
270 #define D_NAMELEN(dp) (dp)->d_namlen
272 #define D_NAMELEN(dp) (strlen((dp)->d_name))
275 /* Initiate/terminate a tree traversal. */
276 static struct tree
*tree_open(const char *, int, int);
277 static struct tree
*tree_reopen(struct tree
*, const char *, int);
278 static void tree_close(struct tree
*);
279 static void tree_free(struct tree
*);
280 static void tree_push(struct tree
*, const char *, int, int64_t, int64_t,
281 struct restore_time
*);
282 static int tree_enter_initial_dir(struct tree
*);
283 static int tree_enter_working_dir(struct tree
*);
284 static int tree_current_dir_fd(struct tree
*);
287 * tree_next() returns Zero if there is no next entry, non-zero if
288 * there is. Note that directories are visited three times.
289 * Directories are always visited first as part of enumerating their
290 * parent; that is a "regular" visit. If tree_descend() is invoked at
291 * that time, the directory is added to a work list and will
292 * subsequently be visited two more times: once just after descending
293 * into the directory ("postdescent") and again just after ascending
294 * back to the parent ("postascent").
296 * TREE_ERROR_DIR is returned if the descent failed (because the
297 * directory couldn't be opened, for instance). This is returned
298 * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
299 * fatal error, but it does imply that the relevant subtree won't be
300 * visited. TREE_ERROR_FATAL is returned for an error that left the
301 * traversal completely hosed. Right now, this is only returned for
302 * chdir() failures during ascent.
304 #define TREE_REGULAR 1
305 #define TREE_POSTDESCENT 2
306 #define TREE_POSTASCENT 3
307 #define TREE_ERROR_DIR -1
308 #define TREE_ERROR_FATAL -2
310 static int tree_next(struct tree
*);
313 * Return information about the current entry.
317 * The current full pathname, length of the full pathname, and a name
318 * that can be used to access the file. Because tree does use chdir
319 * extensively, the access path is almost never the same as the full
322 * TODO: On platforms that support it, use openat()-style operations
323 * to eliminate the chdir() operations entirely while still supporting
324 * arbitrarily deep traversals. This makes access_path troublesome to
325 * support, of course, which means we'll need a rich enough interface
326 * that clients can function without it. (In particular, we'll need
327 * tree_current_open() that returns an open file descriptor.)
330 static const char *tree_current_path(struct tree
*);
331 static const char *tree_current_access_path(struct tree
*);
334 * Request the lstat() or stat() data for the current path. Since the
335 * tree package needs to do some of this anyway, and caches the
336 * results, you should take advantage of it here if you need it rather
337 * than make a redundant stat() or lstat() call of your own.
339 static const struct stat
*tree_current_stat(struct tree
*);
340 static const struct stat
*tree_current_lstat(struct tree
*);
341 static int tree_current_is_symblic_link_target(struct tree
*);
343 /* The following functions use tricks to avoid a certain number of
344 * stat()/lstat() calls. */
345 /* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
346 static int tree_current_is_physical_dir(struct tree
*);
347 /* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
348 static int tree_current_is_dir(struct tree
*);
349 static int update_current_filesystem(struct archive_read_disk
*a
,
351 static int setup_current_filesystem(struct archive_read_disk
*);
352 static int tree_target_is_same_as_parent(struct tree
*, const struct stat
*);
354 static int _archive_read_disk_open(struct archive
*, const char *);
355 static int _archive_read_free(struct archive
*);
356 static int _archive_read_close(struct archive
*);
357 static int _archive_read_data_block(struct archive
*,
358 const void **, size_t *, int64_t *);
359 static int _archive_read_next_header(struct archive
*,
360 struct archive_entry
**);
361 static int _archive_read_next_header2(struct archive
*,
362 struct archive_entry
*);
363 static const char *trivial_lookup_gname(void *, int64_t gid
);
364 static const char *trivial_lookup_uname(void *, int64_t uid
);
365 static int setup_sparse(struct archive_read_disk
*, struct archive_entry
*);
366 static int close_and_restore_time(int fd
, struct tree
*,
367 struct restore_time
*);
368 static int open_on_current_dir(struct tree
*, const char *, int);
369 static int tree_dup(int);
372 static struct archive_vtable
*
373 archive_read_disk_vtable(void)
375 static struct archive_vtable av
;
376 static int inited
= 0;
379 av
.archive_free
= _archive_read_free
;
380 av
.archive_close
= _archive_read_close
;
381 av
.archive_read_data_block
= _archive_read_data_block
;
382 av
.archive_read_next_header
= _archive_read_next_header
;
383 av
.archive_read_next_header2
= _archive_read_next_header2
;
390 archive_read_disk_gname(struct archive
*_a
, int64_t gid
)
392 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
393 if (ARCHIVE_OK
!= __archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
394 ARCHIVE_STATE_ANY
, "archive_read_disk_gname"))
396 if (a
->lookup_gname
== NULL
)
398 return ((*a
->lookup_gname
)(a
->lookup_gname_data
, gid
));
402 archive_read_disk_uname(struct archive
*_a
, int64_t uid
)
404 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
405 if (ARCHIVE_OK
!= __archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
406 ARCHIVE_STATE_ANY
, "archive_read_disk_uname"))
408 if (a
->lookup_uname
== NULL
)
410 return ((*a
->lookup_uname
)(a
->lookup_uname_data
, uid
));
414 archive_read_disk_set_gname_lookup(struct archive
*_a
,
416 const char * (*lookup_gname
)(void *private, int64_t gid
),
417 void (*cleanup_gname
)(void *private))
419 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
420 archive_check_magic(&a
->archive
, ARCHIVE_READ_DISK_MAGIC
,
421 ARCHIVE_STATE_ANY
, "archive_read_disk_set_gname_lookup");
423 if (a
->cleanup_gname
!= NULL
&& a
->lookup_gname_data
!= NULL
)
424 (a
->cleanup_gname
)(a
->lookup_gname_data
);
426 a
->lookup_gname
= lookup_gname
;
427 a
->cleanup_gname
= cleanup_gname
;
428 a
->lookup_gname_data
= private_data
;
433 archive_read_disk_set_uname_lookup(struct archive
*_a
,
435 const char * (*lookup_uname
)(void *private, int64_t uid
),
436 void (*cleanup_uname
)(void *private))
438 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
439 archive_check_magic(&a
->archive
, ARCHIVE_READ_DISK_MAGIC
,
440 ARCHIVE_STATE_ANY
, "archive_read_disk_set_uname_lookup");
442 if (a
->cleanup_uname
!= NULL
&& a
->lookup_uname_data
!= NULL
)
443 (a
->cleanup_uname
)(a
->lookup_uname_data
);
445 a
->lookup_uname
= lookup_uname
;
446 a
->cleanup_uname
= cleanup_uname
;
447 a
->lookup_uname_data
= private_data
;
452 * Create a new archive_read_disk object and initialize it with global state.
455 archive_read_disk_new(void)
457 struct archive_read_disk
*a
;
459 a
= (struct archive_read_disk
*)calloc(1, sizeof(*a
));
462 a
->archive
.magic
= ARCHIVE_READ_DISK_MAGIC
;
463 a
->archive
.state
= ARCHIVE_STATE_NEW
;
464 a
->archive
.vtable
= archive_read_disk_vtable();
465 a
->entry
= archive_entry_new2(&a
->archive
);
466 a
->lookup_uname
= trivial_lookup_uname
;
467 a
->lookup_gname
= trivial_lookup_gname
;
468 a
->enable_copyfile
= 1;
469 a
->traverse_mount_points
= 1;
470 a
->open_on_current_dir
= open_on_current_dir
;
471 a
->tree_current_dir_fd
= tree_current_dir_fd
;
472 a
->tree_enter_working_dir
= tree_enter_working_dir
;
473 return (&a
->archive
);
477 _archive_read_free(struct archive
*_a
)
479 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
484 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
485 ARCHIVE_STATE_ANY
| ARCHIVE_STATE_FATAL
, "archive_read_free");
487 if (a
->archive
.state
!= ARCHIVE_STATE_CLOSED
)
488 r
= _archive_read_close(&a
->archive
);
493 if (a
->cleanup_gname
!= NULL
&& a
->lookup_gname_data
!= NULL
)
494 (a
->cleanup_gname
)(a
->lookup_gname_data
);
495 if (a
->cleanup_uname
!= NULL
&& a
->lookup_uname_data
!= NULL
)
496 (a
->cleanup_uname
)(a
->lookup_uname_data
);
497 archive_string_free(&a
->archive
.error_string
);
498 archive_entry_free(a
->entry
);
499 a
->archive
.magic
= 0;
500 __archive_clean(&a
->archive
);
506 _archive_read_close(struct archive
*_a
)
508 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
510 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
511 ARCHIVE_STATE_ANY
| ARCHIVE_STATE_FATAL
, "archive_read_close");
513 if (a
->archive
.state
!= ARCHIVE_STATE_FATAL
)
514 a
->archive
.state
= ARCHIVE_STATE_CLOSED
;
522 setup_symlink_mode(struct archive_read_disk
*a
, char symlink_mode
,
525 a
->symlink_mode
= symlink_mode
;
526 a
->follow_symlinks
= follow_symlinks
;
527 if (a
->tree
!= NULL
) {
528 a
->tree
->initial_symlink_mode
= a
->symlink_mode
;
529 a
->tree
->symlink_mode
= a
->symlink_mode
;
534 archive_read_disk_set_symlink_logical(struct archive
*_a
)
536 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
537 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
538 ARCHIVE_STATE_ANY
, "archive_read_disk_set_symlink_logical");
539 setup_symlink_mode(a
, 'L', 1);
544 archive_read_disk_set_symlink_physical(struct archive
*_a
)
546 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
547 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
548 ARCHIVE_STATE_ANY
, "archive_read_disk_set_symlink_physical");
549 setup_symlink_mode(a
, 'P', 0);
554 archive_read_disk_set_symlink_hybrid(struct archive
*_a
)
556 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
557 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
558 ARCHIVE_STATE_ANY
, "archive_read_disk_set_symlink_hybrid");
559 setup_symlink_mode(a
, 'H', 1);/* Follow symlinks initially. */
564 archive_read_disk_set_atime_restored(struct archive
*_a
)
567 static int warning_done
= 0;
569 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
570 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
571 ARCHIVE_STATE_ANY
, "archive_read_disk_restore_atime");
575 a
->tree
->flags
|= needsRestoreTimes
;
579 /* Warning was already emitted; suppress further warnings. */
582 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
583 "Cannot restore access time on this system");
585 return (ARCHIVE_WARN
);
590 archive_read_disk_set_behavior(struct archive
*_a
, int flags
)
592 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
595 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
596 ARCHIVE_STATE_ANY
, "archive_read_disk_honor_nodump");
598 if (flags
& ARCHIVE_READDISK_RESTORE_ATIME
)
599 r
= archive_read_disk_set_atime_restored(_a
);
603 a
->tree
->flags
&= ~needsRestoreTimes
;
605 if (flags
& ARCHIVE_READDISK_HONOR_NODUMP
)
609 if (flags
& ARCHIVE_READDISK_MAC_COPYFILE
)
610 a
->enable_copyfile
= 1;
612 a
->enable_copyfile
= 0;
613 if (flags
& ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS
)
614 a
->traverse_mount_points
= 0;
616 a
->traverse_mount_points
= 1;
617 if (flags
& ARCHIVE_READDISK_NO_XATTR
)
618 a
->suppress_xattr
= 1;
620 a
->suppress_xattr
= 0;
625 * Trivial implementations of gname/uname lookup functions.
626 * These are normally overridden by the client, but these stub
627 * versions ensure that we always have something that works.
630 trivial_lookup_gname(void *private_data
, int64_t gid
)
632 (void)private_data
; /* UNUSED */
633 (void)gid
; /* UNUSED */
638 trivial_lookup_uname(void *private_data
, int64_t uid
)
640 (void)private_data
; /* UNUSED */
641 (void)uid
; /* UNUSED */
646 * Allocate memory for the reading buffer adjusted to the filesystem
650 setup_suitable_read_buffer(struct archive_read_disk
*a
)
652 struct tree
*t
= a
->tree
;
653 struct filesystem
*cf
= t
->current_filesystem
;
657 if (cf
->allocation_ptr
== NULL
) {
658 /* If we couldn't get a filesystem alignment,
659 * we use 4096 as default value but we won't use
660 * O_DIRECT to open() and openat() operations. */
661 long xfer_align
= (cf
->xfer_align
== -1)?4096:cf
->xfer_align
;
663 if (cf
->max_xfer_size
!= -1)
664 asize
= cf
->max_xfer_size
+ xfer_align
;
666 long incr
= cf
->incr_xfer_size
;
667 /* Some platform does not set a proper value to
670 incr
= cf
->min_xfer_size
;
671 if (cf
->min_xfer_size
< 0) {
675 asize
= cf
->min_xfer_size
;
677 /* Increase a buffer size up to 64K bytes in
678 * a proper incremant size. */
679 while (asize
< 1024*64)
681 /* Take a margin to adjust to the filesystem
685 cf
->allocation_ptr
= malloc(asize
);
686 if (cf
->allocation_ptr
== NULL
) {
687 archive_set_error(&a
->archive
, ENOMEM
,
688 "Couldn't allocate memory");
689 a
->archive
.state
= ARCHIVE_STATE_FATAL
;
690 return (ARCHIVE_FATAL
);
694 * Calculate proper address for the filesystem.
696 s
= (uintptr_t)cf
->allocation_ptr
;
702 * Set a read buffer pointer in the proper alignment of
703 * the current filesystem.
705 cf
->buff
= cf
->allocation_ptr
+ s
;
706 cf
->buff_size
= asize
- xfer_align
;
712 _archive_read_data_block(struct archive
*_a
, const void **buff
,
713 size_t *size
, int64_t *offset
)
715 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
716 struct tree
*t
= a
->tree
;
720 int empty_sparse_region
= 0;
722 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
, ARCHIVE_STATE_DATA
,
723 "archive_read_data_block");
725 if (t
->entry_eof
|| t
->entry_remaining_bytes
<= 0) {
727 goto abort_read_data
;
731 * Open the current file.
733 if (t
->entry_fd
< 0) {
734 int flags
= O_RDONLY
| O_BINARY
| O_CLOEXEC
;
737 * Eliminate or reduce cache effects if we can.
739 * Carefully consider this to be enabled.
741 #if defined(O_DIRECT) && 0/* Disabled for now */
742 if (t
->current_filesystem
->xfer_align
!= -1 &&
746 #if defined(O_NOATIME)
748 * Linux has O_NOATIME flag; use it if we need.
750 if ((t
->flags
& needsRestoreTimes
) != 0 &&
751 t
->restore_time
.noatime
== 0)
755 t
->entry_fd
= open_on_current_dir(t
,
756 tree_current_access_path(t
), flags
);
757 __archive_ensure_cloexec_flag(t
->entry_fd
);
758 #if defined(O_NOATIME)
760 * When we did open the file with O_NOATIME flag,
761 * if successful, set 1 to t->restore_time.noatime
762 * not to restore an atime of the file later.
763 * if failed by EPERM, retry it without O_NOATIME flag.
765 if (flags
& O_NOATIME
) {
766 if (t
->entry_fd
>= 0)
767 t
->restore_time
.noatime
= 1;
768 else if (errno
== EPERM
) {
775 if (t
->entry_fd
< 0) {
776 archive_set_error(&a
->archive
, errno
,
777 "Couldn't open %s", tree_current_path(t
));
779 tree_enter_initial_dir(t
);
780 goto abort_read_data
;
782 tree_enter_initial_dir(t
);
786 * Allocate read buffer if not allocated.
788 if (t
->current_filesystem
->allocation_ptr
== NULL
) {
789 r
= setup_suitable_read_buffer(a
);
790 if (r
!= ARCHIVE_OK
) {
791 a
->archive
.state
= ARCHIVE_STATE_FATAL
;
792 goto abort_read_data
;
795 t
->entry_buff
= t
->current_filesystem
->buff
;
796 t
->entry_buff_size
= t
->current_filesystem
->buff_size
;
798 buffbytes
= t
->entry_buff_size
;
799 if ((int64_t)buffbytes
> t
->current_sparse
->length
)
800 buffbytes
= t
->current_sparse
->length
;
802 if (t
->current_sparse
->length
== 0)
803 empty_sparse_region
= 1;
807 * TODO: Should we consider t->current_filesystem->xfer_align?
809 if (t
->current_sparse
->offset
> t
->entry_total
) {
810 if (lseek(t
->entry_fd
,
811 (off_t
)t
->current_sparse
->offset
, SEEK_SET
) < 0) {
812 archive_set_error(&a
->archive
, errno
, "Seek error");
814 a
->archive
.state
= ARCHIVE_STATE_FATAL
;
815 goto abort_read_data
;
817 bytes
= t
->current_sparse
->offset
- t
->entry_total
;
818 t
->entry_remaining_bytes
-= bytes
;
819 t
->entry_total
+= bytes
;
823 * Read file contents.
826 bytes
= read(t
->entry_fd
, t
->entry_buff
, buffbytes
);
828 archive_set_error(&a
->archive
, errno
, "Read error");
830 a
->archive
.state
= ARCHIVE_STATE_FATAL
;
831 goto abort_read_data
;
836 * Return an EOF unless we've read a leading empty sparse region, which
837 * is used to represent fully-sparse files.
839 if (bytes
== 0 && !empty_sparse_region
) {
843 goto abort_read_data
;
845 *buff
= t
->entry_buff
;
847 *offset
= t
->entry_total
;
848 t
->entry_total
+= bytes
;
849 t
->entry_remaining_bytes
-= bytes
;
850 if (t
->entry_remaining_bytes
== 0) {
851 /* Close the current file descriptor */
852 close_and_restore_time(t
->entry_fd
, t
, &t
->restore_time
);
856 t
->current_sparse
->offset
+= bytes
;
857 t
->current_sparse
->length
-= bytes
;
858 if (t
->current_sparse
->length
== 0 && !t
->entry_eof
)
865 *offset
= t
->entry_total
;
866 if (t
->entry_fd
>= 0) {
867 /* Close the current file descriptor */
868 close_and_restore_time(t
->entry_fd
, t
, &t
->restore_time
);
875 next_entry(struct archive_read_disk
*a
, struct tree
*t
,
876 struct archive_entry
*entry
)
878 const struct stat
*st
; /* info to use for this entry */
879 const struct stat
*lst
;/* lstat() information */
887 switch (tree_next(t
)) {
888 case TREE_ERROR_FATAL
:
889 archive_set_error(&a
->archive
, t
->tree_errno
,
890 "%s: Unable to continue traversing directory tree",
891 tree_current_path(t
));
892 a
->archive
.state
= ARCHIVE_STATE_FATAL
;
893 tree_enter_initial_dir(t
);
894 return (ARCHIVE_FATAL
);
896 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
897 "%s: Couldn't visit directory",
898 tree_current_path(t
));
899 tree_enter_initial_dir(t
);
900 return (ARCHIVE_FAILED
);
902 tree_enter_initial_dir(t
);
903 return (ARCHIVE_EOF
);
904 case TREE_POSTDESCENT
:
905 case TREE_POSTASCENT
:
908 lst
= tree_current_lstat(t
);
910 archive_set_error(&a
->archive
, errno
,
912 tree_current_path(t
));
913 tree_enter_initial_dir(t
);
914 return (ARCHIVE_FAILED
);
918 } while (lst
== NULL
);
921 if (a
->enable_copyfile
) {
922 /* If we're using copyfile(), ignore "._XXX" files. */
923 const char *bname
= strrchr(tree_current_path(t
), '/');
925 bname
= tree_current_path(t
);
928 if (bname
[0] == '.' && bname
[1] == '_')
929 return (ARCHIVE_RETRY
);
933 archive_entry_copy_pathname(entry
, tree_current_path(t
));
935 * Perform path matching.
938 r
= archive_match_path_excluded(a
->matching
, entry
);
940 archive_set_error(&(a
->archive
), errno
,
941 "Faild : %s", archive_error_string(a
->matching
));
945 if (a
->excluded_cb_func
)
946 a
->excluded_cb_func(&(a
->archive
),
947 a
->excluded_cb_data
, entry
);
948 return (ARCHIVE_RETRY
);
953 * Distinguish 'L'/'P'/'H' symlink following.
955 switch(t
->symlink_mode
) {
957 /* 'H': After the first item, rest like 'P'. */
958 t
->symlink_mode
= 'P';
959 /* 'H': First item (from command line) like 'L'. */
962 /* 'L': Do descend through a symlink to dir. */
963 descend
= tree_current_is_dir(t
);
964 /* 'L': Follow symlinks to files. */
965 a
->symlink_mode
= 'L';
966 a
->follow_symlinks
= 1;
967 /* 'L': Archive symlinks as targets, if we can. */
968 st
= tree_current_stat(t
);
969 if (st
!= NULL
&& !tree_target_is_same_as_parent(t
, st
))
971 /* If stat fails, we have a broken symlink;
972 * in that case, don't follow the link. */
975 /* 'P': Don't descend through a symlink to dir. */
976 descend
= tree_current_is_physical_dir(t
);
977 /* 'P': Don't follow symlinks to files. */
978 a
->symlink_mode
= 'P';
979 a
->follow_symlinks
= 0;
980 /* 'P': Archive symlinks as symlinks. */
985 if (update_current_filesystem(a
, st
->st_dev
) != ARCHIVE_OK
) {
986 a
->archive
.state
= ARCHIVE_STATE_FATAL
;
987 tree_enter_initial_dir(t
);
988 return (ARCHIVE_FATAL
);
990 if (t
->initial_filesystem_id
== -1)
991 t
->initial_filesystem_id
= t
->current_filesystem_id
;
992 if (!a
->traverse_mount_points
) {
993 if (t
->initial_filesystem_id
!= t
->current_filesystem_id
)
996 t
->descend
= descend
;
1000 * If the file is marked with nodump flag, do not return this entry.
1002 if (a
->honor_nodump
) {
1003 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
1004 if (st
->st_flags
& UF_NODUMP
)
1005 return (ARCHIVE_RETRY
);
1006 #elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) &&\
1007 defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
1008 if (S_ISREG(st
->st_mode
) || S_ISDIR(st
->st_mode
)) {
1011 t
->entry_fd
= open_on_current_dir(t
,
1012 tree_current_access_path(t
),
1013 O_RDONLY
| O_NONBLOCK
| O_CLOEXEC
);
1014 __archive_ensure_cloexec_flag(t
->entry_fd
);
1015 if (t
->entry_fd
>= 0) {
1016 r
= ioctl(t
->entry_fd
, EXT2_IOC_GETFLAGS
,
1018 if (r
== 0 && (stflags
& EXT2_NODUMP_FL
) != 0)
1019 return (ARCHIVE_RETRY
);
1025 archive_entry_copy_stat(entry
, st
);
1027 /* Save the times to be restored. This must be in before
1028 * calling archive_read_disk_descend() or any chance of it,
1029 * especially, invokng a callback. */
1030 t
->restore_time
.mtime
= archive_entry_mtime(entry
);
1031 t
->restore_time
.mtime_nsec
= archive_entry_mtime_nsec(entry
);
1032 t
->restore_time
.atime
= archive_entry_atime(entry
);
1033 t
->restore_time
.atime_nsec
= archive_entry_atime_nsec(entry
);
1034 t
->restore_time
.filetype
= archive_entry_filetype(entry
);
1035 t
->restore_time
.noatime
= t
->current_filesystem
->noatime
;
1038 * Perform time matching.
1041 r
= archive_match_time_excluded(a
->matching
, entry
);
1043 archive_set_error(&(a
->archive
), errno
,
1044 "Faild : %s", archive_error_string(a
->matching
));
1048 if (a
->excluded_cb_func
)
1049 a
->excluded_cb_func(&(a
->archive
),
1050 a
->excluded_cb_data
, entry
);
1051 return (ARCHIVE_RETRY
);
1055 /* Lookup uname/gname */
1056 name
= archive_read_disk_uname(&(a
->archive
), archive_entry_uid(entry
));
1058 archive_entry_copy_uname(entry
, name
);
1059 name
= archive_read_disk_gname(&(a
->archive
), archive_entry_gid(entry
));
1061 archive_entry_copy_gname(entry
, name
);
1064 * Perform owner matching.
1067 r
= archive_match_owner_excluded(a
->matching
, entry
);
1069 archive_set_error(&(a
->archive
), errno
,
1070 "Faild : %s", archive_error_string(a
->matching
));
1074 if (a
->excluded_cb_func
)
1075 a
->excluded_cb_func(&(a
->archive
),
1076 a
->excluded_cb_data
, entry
);
1077 return (ARCHIVE_RETRY
);
1082 * Invoke a meta data filter callback.
1084 if (a
->metadata_filter_func
) {
1085 if (!a
->metadata_filter_func(&(a
->archive
),
1086 a
->metadata_filter_data
, entry
))
1087 return (ARCHIVE_RETRY
);
1091 * Populate the archive_entry with metadata from the disk.
1093 archive_entry_copy_sourcepath(entry
, tree_current_access_path(t
));
1094 r
= archive_read_disk_entry_from_file(&(a
->archive
), entry
,
1101 _archive_read_next_header(struct archive
*_a
, struct archive_entry
**entryp
)
1104 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1106 ret
= _archive_read_next_header2(_a
, a
->entry
);
1112 _archive_read_next_header2(struct archive
*_a
, struct archive_entry
*entry
)
1114 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1118 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
1119 ARCHIVE_STATE_HEADER
| ARCHIVE_STATE_DATA
,
1120 "archive_read_next_header2");
1123 if (t
->entry_fd
>= 0) {
1124 close_and_restore_time(t
->entry_fd
, t
, &t
->restore_time
);
1129 r
= next_entry(a
, t
, entry
);
1130 if (t
->entry_fd
>= 0) {
1135 if (r
== ARCHIVE_RETRY
) {
1136 archive_entry_clear(entry
);
1142 /* Return to the initial directory. */
1143 tree_enter_initial_dir(t
);
1146 * EOF and FATAL are persistent at this layer. By
1147 * modifying the state, we guarantee that future calls to
1148 * read a header or read data will fail.
1152 a
->archive
.state
= ARCHIVE_STATE_EOF
;
1156 /* Overwrite the sourcepath based on the initial directory. */
1157 archive_entry_copy_sourcepath(entry
, tree_current_path(t
));
1159 if (archive_entry_filetype(entry
) == AE_IFREG
) {
1160 t
->nlink
= archive_entry_nlink(entry
);
1161 t
->entry_remaining_bytes
= archive_entry_size(entry
);
1162 t
->entry_eof
= (t
->entry_remaining_bytes
== 0)? 1: 0;
1163 if (!t
->entry_eof
&&
1164 setup_sparse(a
, entry
) != ARCHIVE_OK
)
1165 return (ARCHIVE_FATAL
);
1167 t
->entry_remaining_bytes
= 0;
1170 a
->archive
.state
= ARCHIVE_STATE_DATA
;
1175 a
->archive
.state
= ARCHIVE_STATE_FATAL
;
1179 __archive_reset_read_data(&a
->archive
);
1184 setup_sparse(struct archive_read_disk
*a
, struct archive_entry
*entry
)
1186 struct tree
*t
= a
->tree
;
1187 int64_t length
, offset
;
1190 t
->sparse_count
= archive_entry_sparse_reset(entry
);
1191 if (t
->sparse_count
+1 > t
->sparse_list_size
) {
1192 free(t
->sparse_list
);
1193 t
->sparse_list_size
= t
->sparse_count
+ 1;
1194 t
->sparse_list
= malloc(sizeof(t
->sparse_list
[0]) *
1195 t
->sparse_list_size
);
1196 if (t
->sparse_list
== NULL
) {
1197 t
->sparse_list_size
= 0;
1198 archive_set_error(&a
->archive
, ENOMEM
,
1199 "Can't allocate data");
1200 a
->archive
.state
= ARCHIVE_STATE_FATAL
;
1201 return (ARCHIVE_FATAL
);
1204 for (i
= 0; i
< t
->sparse_count
; i
++) {
1205 archive_entry_sparse_next(entry
, &offset
, &length
);
1206 t
->sparse_list
[i
].offset
= offset
;
1207 t
->sparse_list
[i
].length
= length
;
1210 t
->sparse_list
[i
].offset
= 0;
1211 t
->sparse_list
[i
].length
= archive_entry_size(entry
);
1213 t
->sparse_list
[i
].offset
= archive_entry_size(entry
);
1214 t
->sparse_list
[i
].length
= 0;
1216 t
->current_sparse
= t
->sparse_list
;
1218 return (ARCHIVE_OK
);
1222 archive_read_disk_set_matching(struct archive
*_a
, struct archive
*_ma
,
1223 void (*_excluded_func
)(struct archive
*, void *, struct archive_entry
*),
1226 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1227 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
1228 ARCHIVE_STATE_ANY
, "archive_read_disk_set_matching");
1230 a
->excluded_cb_func
= _excluded_func
;
1231 a
->excluded_cb_data
= _client_data
;
1232 return (ARCHIVE_OK
);
1236 archive_read_disk_set_metadata_filter_callback(struct archive
*_a
,
1237 int (*_metadata_filter_func
)(struct archive
*, void *,
1238 struct archive_entry
*), void *_client_data
)
1240 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1242 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
, ARCHIVE_STATE_ANY
,
1243 "archive_read_disk_set_metadata_filter_callback");
1245 a
->metadata_filter_func
= _metadata_filter_func
;
1246 a
->metadata_filter_data
= _client_data
;
1247 return (ARCHIVE_OK
);
1251 archive_read_disk_can_descend(struct archive
*_a
)
1253 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1254 struct tree
*t
= a
->tree
;
1256 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
1257 ARCHIVE_STATE_HEADER
| ARCHIVE_STATE_DATA
,
1258 "archive_read_disk_can_descend");
1260 return (t
->visit_type
== TREE_REGULAR
&& t
->descend
);
1264 * Called by the client to mark the directory just returned from
1265 * tree_next() as needing to be visited.
1268 archive_read_disk_descend(struct archive
*_a
)
1270 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1271 struct tree
*t
= a
->tree
;
1273 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
1274 ARCHIVE_STATE_HEADER
| ARCHIVE_STATE_DATA
,
1275 "archive_read_disk_descend");
1277 if (t
->visit_type
!= TREE_REGULAR
|| !t
->descend
)
1278 return (ARCHIVE_OK
);
1280 if (tree_current_is_physical_dir(t
)) {
1281 tree_push(t
, t
->basename
, t
->current_filesystem_id
,
1282 t
->lst
.st_dev
, t
->lst
.st_ino
, &t
->restore_time
);
1283 t
->stack
->flags
|= isDir
;
1284 } else if (tree_current_is_dir(t
)) {
1285 tree_push(t
, t
->basename
, t
->current_filesystem_id
,
1286 t
->st
.st_dev
, t
->st
.st_ino
, &t
->restore_time
);
1287 t
->stack
->flags
|= isDirLink
;
1290 return (ARCHIVE_OK
);
1294 archive_read_disk_open(struct archive
*_a
, const char *pathname
)
1296 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1298 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
1299 ARCHIVE_STATE_NEW
| ARCHIVE_STATE_CLOSED
,
1300 "archive_read_disk_open");
1301 archive_clear_error(&a
->archive
);
1303 return (_archive_read_disk_open(_a
, pathname
));
1307 archive_read_disk_open_w(struct archive
*_a
, const wchar_t *pathname
)
1309 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1310 struct archive_string path
;
1313 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
,
1314 ARCHIVE_STATE_NEW
| ARCHIVE_STATE_CLOSED
,
1315 "archive_read_disk_open_w");
1316 archive_clear_error(&a
->archive
);
1318 /* Make a char string from a wchar_t string. */
1319 archive_string_init(&path
);
1320 if (archive_string_append_from_wcs(&path
, pathname
,
1321 wcslen(pathname
)) != 0) {
1322 if (errno
== ENOMEM
)
1323 archive_set_error(&a
->archive
, ENOMEM
,
1324 "Can't allocate memory");
1326 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
1327 "Can't convert a path to a char string");
1328 a
->archive
.state
= ARCHIVE_STATE_FATAL
;
1329 ret
= ARCHIVE_FATAL
;
1331 ret
= _archive_read_disk_open(_a
, path
.s
);
1333 archive_string_free(&path
);
1338 _archive_read_disk_open(struct archive
*_a
, const char *pathname
)
1340 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1342 if (a
->tree
!= NULL
)
1343 a
->tree
= tree_reopen(a
->tree
, pathname
, a
->restore_time
);
1345 a
->tree
= tree_open(pathname
, a
->symlink_mode
,
1347 if (a
->tree
== NULL
) {
1348 archive_set_error(&a
->archive
, ENOMEM
,
1349 "Can't allocate tar data");
1350 a
->archive
.state
= ARCHIVE_STATE_FATAL
;
1351 return (ARCHIVE_FATAL
);
1353 a
->archive
.state
= ARCHIVE_STATE_HEADER
;
1355 return (ARCHIVE_OK
);
1359 * Return a current filesystem ID which is index of the filesystem entry
1360 * you've visited through archive_read_disk.
1363 archive_read_disk_current_filesystem(struct archive
*_a
)
1365 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1367 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
, ARCHIVE_STATE_DATA
,
1368 "archive_read_disk_current_filesystem");
1370 return (a
->tree
->current_filesystem_id
);
1374 update_current_filesystem(struct archive_read_disk
*a
, int64_t dev
)
1376 struct tree
*t
= a
->tree
;
1379 if (t
->current_filesystem
!= NULL
&&
1380 t
->current_filesystem
->dev
== dev
)
1381 return (ARCHIVE_OK
);
1383 for (i
= 0; i
< t
->max_filesystem_id
; i
++) {
1384 if (t
->filesystem_table
[i
].dev
== dev
) {
1385 /* There is the filesytem ID we've already generated. */
1386 t
->current_filesystem_id
= i
;
1387 t
->current_filesystem
= &(t
->filesystem_table
[i
]);
1388 return (ARCHIVE_OK
);
1393 * This is the new filesytem which we have to generate a new ID for.
1395 fid
= t
->max_filesystem_id
++;
1396 if (t
->max_filesystem_id
> t
->allocated_filesytem
) {
1400 s
= t
->max_filesystem_id
* 2;
1401 p
= realloc(t
->filesystem_table
,
1402 s
* sizeof(*t
->filesystem_table
));
1404 archive_set_error(&a
->archive
, ENOMEM
,
1405 "Can't allocate tar data");
1406 return (ARCHIVE_FATAL
);
1408 t
->filesystem_table
= (struct filesystem
*)p
;
1409 t
->allocated_filesytem
= s
;
1411 t
->current_filesystem_id
= fid
;
1412 t
->current_filesystem
= &(t
->filesystem_table
[fid
]);
1413 t
->current_filesystem
->dev
= dev
;
1414 t
->current_filesystem
->allocation_ptr
= NULL
;
1415 t
->current_filesystem
->buff
= NULL
;
1417 /* Setup the current filesystem properties which depend on
1418 * platform specific. */
1419 return (setup_current_filesystem(a
));
1423 * Returns 1 if current filesystem is generated filesystem, 0 if it is not
1424 * or -1 if it is unknown.
1427 archive_read_disk_current_filesystem_is_synthetic(struct archive
*_a
)
1429 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1431 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
, ARCHIVE_STATE_DATA
,
1432 "archive_read_disk_current_filesystem");
1434 return (a
->tree
->current_filesystem
->synthetic
);
1438 * Returns 1 if current filesystem is remote filesystem, 0 if it is not
1439 * or -1 if it is unknown.
1442 archive_read_disk_current_filesystem_is_remote(struct archive
*_a
)
1444 struct archive_read_disk
*a
= (struct archive_read_disk
*)_a
;
1446 archive_check_magic(_a
, ARCHIVE_READ_DISK_MAGIC
, ARCHIVE_STATE_DATA
,
1447 "archive_read_disk_current_filesystem");
1449 return (a
->tree
->current_filesystem
->remote
);
1452 #if defined(_PC_REC_INCR_XFER_SIZE) && defined(_PC_REC_MAX_XFER_SIZE) &&\
1453 defined(_PC_REC_MIN_XFER_SIZE) && defined(_PC_REC_XFER_ALIGN)
1455 get_xfer_size(struct tree
*t
, int fd
, const char *path
)
1457 t
->current_filesystem
->xfer_align
= -1;
1460 t
->current_filesystem
->incr_xfer_size
=
1461 fpathconf(fd
, _PC_REC_INCR_XFER_SIZE
);
1462 t
->current_filesystem
->max_xfer_size
=
1463 fpathconf(fd
, _PC_REC_MAX_XFER_SIZE
);
1464 t
->current_filesystem
->min_xfer_size
=
1465 fpathconf(fd
, _PC_REC_MIN_XFER_SIZE
);
1466 t
->current_filesystem
->xfer_align
=
1467 fpathconf(fd
, _PC_REC_XFER_ALIGN
);
1468 } else if (path
!= NULL
) {
1469 t
->current_filesystem
->incr_xfer_size
=
1470 pathconf(path
, _PC_REC_INCR_XFER_SIZE
);
1471 t
->current_filesystem
->max_xfer_size
=
1472 pathconf(path
, _PC_REC_MAX_XFER_SIZE
);
1473 t
->current_filesystem
->min_xfer_size
=
1474 pathconf(path
, _PC_REC_MIN_XFER_SIZE
);
1475 t
->current_filesystem
->xfer_align
=
1476 pathconf(path
, _PC_REC_XFER_ALIGN
);
1478 /* At least we need an alignment size. */
1479 if (t
->current_filesystem
->xfer_align
== -1)
1480 return ((errno
== EINVAL
)?1:-1);
1486 get_xfer_size(struct tree
*t
, int fd
, const char *path
)
1488 (void)t
; /* UNUSED */
1489 (void)fd
; /* UNUSED */
1490 (void)path
; /* UNUSED */
1491 return (1);/* Not supported */
1495 #if defined(HAVE_STATFS) && defined(HAVE_FSTATFS) && defined(MNT_LOCAL) \
1496 && !defined(ST_LOCAL)
1499 * Gather current filesystem properties on FreeBSD, OpenBSD and Mac OS X.
1502 setup_current_filesystem(struct archive_read_disk
*a
)
1504 struct tree
*t
= a
->tree
;
1506 #if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC)
1510 #if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
1514 t
->current_filesystem
->synthetic
= -1;
1515 t
->current_filesystem
->remote
= -1;
1516 if (tree_current_is_symblic_link_target(t
)) {
1517 #if defined(HAVE_OPENAT)
1519 * Get file system statistics on any directory
1522 int fd
= openat(tree_current_dir_fd(t
),
1523 tree_current_access_path(t
), O_RDONLY
| O_CLOEXEC
);
1524 __archive_ensure_cloexec_flag(fd
);
1526 archive_set_error(&a
->archive
, errno
,
1528 return (ARCHIVE_FAILED
);
1530 r
= fstatfs(fd
, &sfs
);
1532 xr
= get_xfer_size(t
, fd
, NULL
);
1535 if (tree_enter_working_dir(t
) != 0) {
1536 archive_set_error(&a
->archive
, errno
, "fchdir failed");
1537 return (ARCHIVE_FAILED
);
1539 r
= statfs(tree_current_access_path(t
), &sfs
);
1541 xr
= get_xfer_size(t
, -1, tree_current_access_path(t
));
1544 r
= fstatfs(tree_current_dir_fd(t
), &sfs
);
1546 xr
= get_xfer_size(t
, tree_current_dir_fd(t
), NULL
);
1548 if (r
== -1 || xr
== -1) {
1549 archive_set_error(&a
->archive
, errno
, "statfs failed");
1550 return (ARCHIVE_FAILED
);
1551 } else if (xr
== 1) {
1552 /* pathconf(_PC_REX_*) operations are not supported. */
1553 t
->current_filesystem
->xfer_align
= sfs
.f_bsize
;
1554 t
->current_filesystem
->max_xfer_size
= -1;
1555 t
->current_filesystem
->min_xfer_size
= sfs
.f_iosize
;
1556 t
->current_filesystem
->incr_xfer_size
= sfs
.f_iosize
;
1558 if (sfs
.f_flags
& MNT_LOCAL
)
1559 t
->current_filesystem
->remote
= 0;
1561 t
->current_filesystem
->remote
= 1;
1563 #if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC)
1564 r
= getvfsbyname(sfs
.f_fstypename
, &vfc
);
1566 archive_set_error(&a
->archive
, errno
, "getvfsbyname failed");
1567 return (ARCHIVE_FAILED
);
1569 if (vfc
.vfc_flags
& VFCF_SYNTHETIC
)
1570 t
->current_filesystem
->synthetic
= 1;
1572 t
->current_filesystem
->synthetic
= 0;
1575 #if defined(MNT_NOATIME)
1576 if (sfs
.f_flags
& MNT_NOATIME
)
1577 t
->current_filesystem
->noatime
= 1;
1580 t
->current_filesystem
->noatime
= 0;
1582 #if defined(HAVE_READDIR_R)
1583 /* Set maximum filename length. */
1584 #if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
1585 t
->current_filesystem
->name_max
= sfs
.f_namemax
;
1587 # if defined(_PC_NAME_MAX)
1588 /* Mac OS X does not have f_namemax in struct statfs. */
1589 if (tree_current_is_symblic_link_target(t
)) {
1590 if (tree_enter_working_dir(t
) != 0) {
1591 archive_set_error(&a
->archive
, errno
, "fchdir failed");
1592 return (ARCHIVE_FAILED
);
1594 nm
= pathconf(tree_current_access_path(t
), _PC_NAME_MAX
);
1596 nm
= fpathconf(tree_current_dir_fd(t
), _PC_NAME_MAX
);
1601 t
->current_filesystem
->name_max
= NAME_MAX
;
1603 t
->current_filesystem
->name_max
= nm
;
1605 #endif /* HAVE_READDIR_R */
1606 return (ARCHIVE_OK
);
1609 #elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL)
1612 * Gather current filesystem properties on NetBSD
1615 setup_current_filesystem(struct archive_read_disk
*a
)
1617 struct tree
*t
= a
->tree
;
1621 t
->current_filesystem
->synthetic
= -1;
1622 if (tree_enter_working_dir(t
) != 0) {
1623 archive_set_error(&a
->archive
, errno
, "fchdir failed");
1624 return (ARCHIVE_FAILED
);
1626 if (tree_current_is_symblic_link_target(t
)) {
1627 r
= statvfs(tree_current_access_path(t
), &sfs
);
1629 xr
= get_xfer_size(t
, -1, tree_current_access_path(t
));
1631 #ifdef HAVE_FSTATVFS
1632 r
= fstatvfs(tree_current_dir_fd(t
), &sfs
);
1634 xr
= get_xfer_size(t
, tree_current_dir_fd(t
), NULL
);
1636 r
= statvfs(".", &sfs
);
1638 xr
= get_xfer_size(t
, -1, ".");
1641 if (r
== -1 || xr
== -1) {
1642 t
->current_filesystem
->remote
= -1;
1643 archive_set_error(&a
->archive
, errno
, "statvfs failed");
1644 return (ARCHIVE_FAILED
);
1645 } else if (xr
== 1) {
1646 /* Usuall come here unless NetBSD supports _PC_REC_XFER_ALIGN
1647 * for pathconf() function. */
1648 t
->current_filesystem
->xfer_align
= sfs
.f_frsize
;
1649 t
->current_filesystem
->max_xfer_size
= -1;
1650 #if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
1651 t
->current_filesystem
->min_xfer_size
= sfs
.f_iosize
;
1652 t
->current_filesystem
->incr_xfer_size
= sfs
.f_iosize
;
1654 t
->current_filesystem
->min_xfer_size
= sfs
.f_bsize
;
1655 t
->current_filesystem
->incr_xfer_size
= sfs
.f_bsize
;
1658 if (sfs
.f_flag
& ST_LOCAL
)
1659 t
->current_filesystem
->remote
= 0;
1661 t
->current_filesystem
->remote
= 1;
1663 #if defined(ST_NOATIME)
1664 if (sfs
.f_flag
& ST_NOATIME
)
1665 t
->current_filesystem
->noatime
= 1;
1668 t
->current_filesystem
->noatime
= 0;
1670 /* Set maximum filename length. */
1671 t
->current_filesystem
->name_max
= sfs
.f_namemax
;
1672 return (ARCHIVE_OK
);
1675 #elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_LINUX_MAGIC_H) &&\
1676 defined(HAVE_STATFS) && defined(HAVE_FSTATFS)
1678 * Note: statfs is deprecated since LSB 3.2
1681 #ifndef CIFS_SUPER_MAGIC
1682 #define CIFS_SUPER_MAGIC 0xFF534D42
1684 #ifndef DEVFS_SUPER_MAGIC
1685 #define DEVFS_SUPER_MAGIC 0x1373
1689 * Gather current filesystem properties on Linux
1692 setup_current_filesystem(struct archive_read_disk
*a
)
1694 struct tree
*t
= a
->tree
;
1696 #if defined(HAVE_STATVFS)
1697 struct statvfs svfs
;
1699 int r
, vr
= 0, xr
= 0;
1701 if (tree_current_is_symblic_link_target(t
)) {
1702 #if defined(HAVE_OPENAT)
1704 * Get file system statistics on any directory
1707 int fd
= openat(tree_current_dir_fd(t
),
1708 tree_current_access_path(t
), O_RDONLY
| O_CLOEXEC
);
1709 __archive_ensure_cloexec_flag(fd
);
1711 archive_set_error(&a
->archive
, errno
,
1713 return (ARCHIVE_FAILED
);
1715 #if defined(HAVE_FSTATVFS)
1716 vr
= fstatvfs(fd
, &svfs
);/* for f_flag, mount flags */
1718 r
= fstatfs(fd
, &sfs
);
1720 xr
= get_xfer_size(t
, fd
, NULL
);
1723 if (tree_enter_working_dir(t
) != 0) {
1724 archive_set_error(&a
->archive
, errno
, "fchdir failed");
1725 return (ARCHIVE_FAILED
);
1727 #if defined(HAVE_STATVFS)
1728 vr
= statvfs(tree_current_access_path(t
), &svfs
);
1730 r
= statfs(tree_current_access_path(t
), &sfs
);
1732 xr
= get_xfer_size(t
, -1, tree_current_access_path(t
));
1736 #if defined(HAVE_FSTATVFS)
1737 vr
= fstatvfs(tree_current_dir_fd(t
), &svfs
);
1739 r
= fstatfs(tree_current_dir_fd(t
), &sfs
);
1741 xr
= get_xfer_size(t
, tree_current_dir_fd(t
), NULL
);
1743 if (tree_enter_working_dir(t
) != 0) {
1744 archive_set_error(&a
->archive
, errno
, "fchdir failed");
1745 return (ARCHIVE_FAILED
);
1747 #if defined(HAVE_STATVFS)
1748 vr
= statvfs(".", &svfs
);
1750 r
= statfs(".", &sfs
);
1752 xr
= get_xfer_size(t
, -1, ".");
1755 if (r
== -1 || xr
== -1 || vr
== -1) {
1756 t
->current_filesystem
->synthetic
= -1;
1757 t
->current_filesystem
->remote
= -1;
1758 archive_set_error(&a
->archive
, errno
, "statfs failed");
1759 return (ARCHIVE_FAILED
);
1760 } else if (xr
== 1) {
1761 /* pathconf(_PC_REX_*) operations are not supported. */
1762 #if defined(HAVE_STATVFS)
1763 t
->current_filesystem
->xfer_align
= svfs
.f_frsize
;
1764 t
->current_filesystem
->max_xfer_size
= -1;
1765 t
->current_filesystem
->min_xfer_size
= svfs
.f_bsize
;
1766 t
->current_filesystem
->incr_xfer_size
= svfs
.f_bsize
;
1768 t
->current_filesystem
->xfer_align
= sfs
.f_frsize
;
1769 t
->current_filesystem
->max_xfer_size
= -1;
1770 t
->current_filesystem
->min_xfer_size
= sfs
.f_bsize
;
1771 t
->current_filesystem
->incr_xfer_size
= sfs
.f_bsize
;
1774 switch (sfs
.f_type
) {
1775 case AFS_SUPER_MAGIC
:
1776 case CIFS_SUPER_MAGIC
:
1777 case CODA_SUPER_MAGIC
:
1778 case NCP_SUPER_MAGIC
:/* NetWare */
1779 case NFS_SUPER_MAGIC
:
1780 case SMB_SUPER_MAGIC
:
1781 t
->current_filesystem
->remote
= 1;
1782 t
->current_filesystem
->synthetic
= 0;
1784 case DEVFS_SUPER_MAGIC
:
1785 case PROC_SUPER_MAGIC
:
1786 case USBDEVICE_SUPER_MAGIC
:
1787 t
->current_filesystem
->remote
= 0;
1788 t
->current_filesystem
->synthetic
= 1;
1791 t
->current_filesystem
->remote
= 0;
1792 t
->current_filesystem
->synthetic
= 0;
1796 #if defined(ST_NOATIME)
1797 #if defined(HAVE_STATVFS)
1798 if (svfs
.f_flag
& ST_NOATIME
)
1800 if (sfs
.f_flag
& ST_NOATIME
)
1802 t
->current_filesystem
->noatime
= 1;
1805 t
->current_filesystem
->noatime
= 0;
1807 #if defined(HAVE_READDIR_R)
1808 /* Set maximum filename length. */
1809 t
->current_filesystem
->name_max
= sfs
.f_namelen
;
1811 return (ARCHIVE_OK
);
1814 #elif defined(HAVE_SYS_STATVFS_H) &&\
1815 (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS))
1818 * Gather current filesystem properties on other posix platform.
1821 setup_current_filesystem(struct archive_read_disk
*a
)
1823 struct tree
*t
= a
->tree
;
1827 t
->current_filesystem
->synthetic
= -1;/* Not supported */
1828 t
->current_filesystem
->remote
= -1;/* Not supported */
1829 if (tree_current_is_symblic_link_target(t
)) {
1830 #if defined(HAVE_OPENAT)
1832 * Get file system statistics on any directory
1835 int fd
= openat(tree_current_dir_fd(t
),
1836 tree_current_access_path(t
), O_RDONLY
| O_CLOEXEC
);
1837 __archive_ensure_cloexec_flag(fd
);
1839 archive_set_error(&a
->archive
, errno
,
1841 return (ARCHIVE_FAILED
);
1843 r
= fstatvfs(fd
, &sfs
);
1845 xr
= get_xfer_size(t
, fd
, NULL
);
1848 if (tree_enter_working_dir(t
) != 0) {
1849 archive_set_error(&a
->archive
, errno
, "fchdir failed");
1850 return (ARCHIVE_FAILED
);
1852 r
= statvfs(tree_current_access_path(t
), &sfs
);
1854 xr
= get_xfer_size(t
, -1, tree_current_access_path(t
));
1857 #ifdef HAVE_FSTATVFS
1858 r
= fstatvfs(tree_current_dir_fd(t
), &sfs
);
1860 xr
= get_xfer_size(t
, tree_current_dir_fd(t
), NULL
);
1862 if (tree_enter_working_dir(t
) != 0) {
1863 archive_set_error(&a
->archive
, errno
, "fchdir failed");
1864 return (ARCHIVE_FAILED
);
1866 r
= statvfs(".", &sfs
);
1868 xr
= get_xfer_size(t
, -1, ".");
1871 if (r
== -1 || xr
== -1) {
1872 t
->current_filesystem
->synthetic
= -1;
1873 t
->current_filesystem
->remote
= -1;
1874 archive_set_error(&a
->archive
, errno
, "statvfs failed");
1875 return (ARCHIVE_FAILED
);
1876 } else if (xr
== 1) {
1877 /* pathconf(_PC_REX_*) operations are not supported. */
1878 t
->current_filesystem
->xfer_align
= sfs
.f_frsize
;
1879 t
->current_filesystem
->max_xfer_size
= -1;
1880 t
->current_filesystem
->min_xfer_size
= sfs
.f_bsize
;
1881 t
->current_filesystem
->incr_xfer_size
= sfs
.f_bsize
;
1884 #if defined(ST_NOATIME)
1885 if (sfs
.f_flag
& ST_NOATIME
)
1886 t
->current_filesystem
->noatime
= 1;
1889 t
->current_filesystem
->noatime
= 0;
1891 #if defined(HAVE_READDIR_R)
1892 /* Set maximum filename length. */
1893 t
->current_filesystem
->name_max
= sfs
.f_namemax
;
1895 return (ARCHIVE_OK
);
1901 * Generic: Gather current filesystem properties.
1902 * TODO: Is this generic function really needed?
1905 setup_current_filesystem(struct archive_read_disk
*a
)
1907 struct tree
*t
= a
->tree
;
1908 #if defined(_PC_NAME_MAX) && defined(HAVE_READDIR_R)
1911 t
->current_filesystem
->synthetic
= -1;/* Not supported */
1912 t
->current_filesystem
->remote
= -1;/* Not supported */
1913 t
->current_filesystem
->noatime
= 0;
1914 (void)get_xfer_size(t
, -1, ".");/* Dummy call to avoid build error. */
1915 t
->current_filesystem
->xfer_align
= -1;/* Unknown */
1916 t
->current_filesystem
->max_xfer_size
= -1;
1917 t
->current_filesystem
->min_xfer_size
= -1;
1918 t
->current_filesystem
->incr_xfer_size
= -1;
1920 #if defined(HAVE_READDIR_R)
1921 /* Set maximum filename length. */
1922 # if defined(_PC_NAME_MAX)
1923 if (tree_current_is_symblic_link_target(t
)) {
1924 if (tree_enter_working_dir(t
) != 0) {
1925 archive_set_error(&a
->archive
, errno
, "fchdir failed");
1926 return (ARCHIVE_FAILED
);
1928 nm
= pathconf(tree_current_access_path(t
), _PC_NAME_MAX
);
1930 nm
= fpathconf(tree_current_dir_fd(t
), _PC_NAME_MAX
);
1932 # endif /* _PC_NAME_MAX */
1934 * Some sysmtes (HP-UX or others?) incorrectly defined
1935 * NAME_MAX macro to be a smaller value.
1937 # if defined(NAME_MAX) && NAME_MAX >= 255
1938 t
->current_filesystem
->name_max
= NAME_MAX
;
1940 /* No way to get a trusted value of maximum filename
1942 t
->current_filesystem
->name_max
= PATH_MAX
;
1943 # endif /* NAME_MAX */
1944 # if defined(_PC_NAME_MAX)
1946 t
->current_filesystem
->name_max
= nm
;
1947 # endif /* _PC_NAME_MAX */
1948 #endif /* HAVE_READDIR_R */
1949 return (ARCHIVE_OK
);
1955 close_and_restore_time(int fd
, struct tree
*t
, struct restore_time
*rt
)
1958 (void)t
; /* UNUSED */
1959 (void)rt
; /* UNUSED */
1962 #if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
1963 struct timespec timespecs
[2];
1965 struct timeval times
[2];
1967 if ((t
->flags
& needsRestoreTimes
) == 0 || rt
->noatime
) {
1974 #if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
1975 if (rt
->mtime
== (time_t)-1) {
1976 timespecs
[1].tv_sec
= 0;
1977 timespecs
[1].tv_nsec
= UTIME_OMIT
;
1979 timespecs
[1].tv_sec
= rt
->mtime
;
1980 timespecs
[1].tv_nsec
= rt
->mtime_nsec
;
1983 if (rt
->atime
== (time_t)-1) {
1984 timespecs
[0].tv_sec
= 0;
1985 timespecs
[0].tv_nsec
= UTIME_OMIT
;
1987 timespecs
[0].tv_sec
= rt
->atime
;
1988 timespecs
[0].tv_nsec
= rt
->atime_nsec
;
1990 /* futimens() is defined in POSIX.1-2008. */
1991 if (futimens(fd
, timespecs
) == 0)
1995 times
[1].tv_sec
= rt
->mtime
;
1996 times
[1].tv_usec
= rt
->mtime_nsec
/ 1000;
1998 times
[0].tv_sec
= rt
->atime
;
1999 times
[0].tv_usec
= rt
->atime_nsec
/ 1000;
2001 #if !defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES) && !defined(__CYGWIN__)
2002 if (futimes(fd
, times
) == 0)
2006 #if defined(HAVE_FUTIMESAT)
2007 if (futimesat(tree_current_dir_fd(t
), rt
->name
, times
) == 0)
2011 if (lutimes(rt
->name
, times
) != 0)
2013 if (AE_IFLNK
!= rt
->filetype
&& utimes(rt
->name
, times
) != 0)
2021 open_on_current_dir(struct tree
*t
, const char *path
, int flags
)
2024 return (openat(tree_current_dir_fd(t
), path
, flags
));
2026 if (tree_enter_working_dir(t
) != 0)
2028 return (open(path
, flags
));
2036 #ifdef F_DUPFD_CLOEXEC
2037 static volatile int can_dupfd_cloexec
= 1;
2039 if (can_dupfd_cloexec
) {
2040 new_fd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 0);
2043 /* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,
2044 * but it cannot be used. So we have to try dup(). */
2045 /* We won't try F_DUPFD_CLOEXEC. */
2046 can_dupfd_cloexec
= 0;
2048 #endif /* F_DUPFD_CLOEXEC */
2050 __archive_ensure_cloexec_flag(new_fd
);
2055 * Add a directory path to the current stack.
2058 tree_push(struct tree
*t
, const char *path
, int filesystem_id
,
2059 int64_t dev
, int64_t ino
, struct restore_time
*rt
)
2061 struct tree_entry
*te
;
2063 te
= malloc(sizeof(*te
));
2064 memset(te
, 0, sizeof(*te
));
2065 te
->next
= t
->stack
;
2066 te
->parent
= t
->current
;
2068 te
->depth
= te
->parent
->depth
+ 1;
2070 archive_string_init(&te
->name
);
2071 te
->symlink_parent_fd
= -1;
2072 archive_strcpy(&te
->name
, path
);
2073 te
->flags
= needsDescent
| needsOpen
| needsAscent
;
2074 te
->filesystem_id
= filesystem_id
;
2077 te
->dirname_length
= t
->dirname_length
;
2078 te
->restore_time
.name
= te
->name
.s
;
2080 te
->restore_time
.mtime
= rt
->mtime
;
2081 te
->restore_time
.mtime_nsec
= rt
->mtime_nsec
;
2082 te
->restore_time
.atime
= rt
->atime
;
2083 te
->restore_time
.atime_nsec
= rt
->atime_nsec
;
2084 te
->restore_time
.filetype
= rt
->filetype
;
2085 te
->restore_time
.noatime
= rt
->noatime
;
2090 * Append a name to the current dir path.
2093 tree_append(struct tree
*t
, const char *name
, size_t name_length
)
2097 t
->path
.s
[t
->dirname_length
] = '\0';
2098 t
->path
.length
= t
->dirname_length
;
2099 /* Strip trailing '/' from name, unless entire name is "/". */
2100 while (name_length
> 1 && name
[name_length
- 1] == '/')
2103 /* Resize pathname buffer as needed. */
2104 size_needed
= name_length
+ t
->dirname_length
+ 2;
2105 archive_string_ensure(&t
->path
, size_needed
);
2106 /* Add a separating '/' if it's needed. */
2107 if (t
->dirname_length
> 0 && t
->path
.s
[archive_strlen(&t
->path
)-1] != '/')
2108 archive_strappend_char(&t
->path
, '/');
2109 t
->basename
= t
->path
.s
+ archive_strlen(&t
->path
);
2110 archive_strncat(&t
->path
, name
, name_length
);
2111 t
->restore_time
.name
= t
->basename
;
2115 * Open a directory tree for traversal.
2117 static struct tree
*
2118 tree_open(const char *path
, int symlink_mode
, int restore_time
)
2122 if ((t
= malloc(sizeof(*t
))) == NULL
)
2124 memset(t
, 0, sizeof(*t
));
2125 archive_string_init(&t
->path
);
2126 archive_string_ensure(&t
->path
, 31);
2127 t
->initial_symlink_mode
= symlink_mode
;
2128 return (tree_reopen(t
, path
, restore_time
));
2131 static struct tree
*
2132 tree_reopen(struct tree
*t
, const char *path
, int restore_time
)
2134 t
->flags
= (restore_time
)?needsRestoreTimes
:0;
2135 t
->flags
|= onInitialDir
;
2138 t
->dirname_length
= 0;
2142 t
->d
= INVALID_DIR_HANDLE
;
2143 t
->symlink_mode
= t
->initial_symlink_mode
;
2144 archive_string_empty(&t
->path
);
2147 t
->entry_remaining_bytes
= 0;
2148 t
->initial_filesystem_id
= -1;
2150 /* First item is set up a lot like a symlink traversal. */
2151 tree_push(t
, path
, 0, 0, 0, NULL
);
2152 t
->stack
->flags
= needsFirstVisit
;
2153 t
->maxOpenCount
= t
->openCount
= 1;
2154 t
->initial_dir_fd
= open(".", O_RDONLY
| O_CLOEXEC
);
2155 __archive_ensure_cloexec_flag(t
->initial_dir_fd
);
2156 t
->working_dir_fd
= tree_dup(t
->initial_dir_fd
);
2161 tree_descent(struct tree
*t
)
2163 int flag
, new_fd
, r
= 0;
2165 t
->dirname_length
= archive_strlen(&t
->path
);
2166 flag
= O_RDONLY
| O_CLOEXEC
;
2167 #if defined(O_DIRECTORY)
2168 flag
|= O_DIRECTORY
;
2170 new_fd
= open_on_current_dir(t
, t
->stack
->name
.s
, flag
);
2171 __archive_ensure_cloexec_flag(new_fd
);
2173 t
->tree_errno
= errno
;
2177 /* If it is a link, set up fd for the ascent. */
2178 if (t
->stack
->flags
& isDirLink
) {
2179 t
->stack
->symlink_parent_fd
= t
->working_dir_fd
;
2181 if (t
->openCount
> t
->maxOpenCount
)
2182 t
->maxOpenCount
= t
->openCount
;
2184 close(t
->working_dir_fd
);
2185 /* Renew the current working directory. */
2186 t
->working_dir_fd
= new_fd
;
2187 t
->flags
&= ~onWorkingDir
;
2193 * We've finished a directory; ascend back to the parent.
2196 tree_ascend(struct tree
*t
)
2198 struct tree_entry
*te
;
2199 int new_fd
, r
= 0, prev_dir_fd
;
2202 prev_dir_fd
= t
->working_dir_fd
;
2203 if (te
->flags
& isDirLink
)
2204 new_fd
= te
->symlink_parent_fd
;
2206 new_fd
= open_on_current_dir(t
, "..", O_RDONLY
| O_CLOEXEC
);
2207 __archive_ensure_cloexec_flag(new_fd
);
2210 t
->tree_errno
= errno
;
2211 r
= TREE_ERROR_FATAL
;
2213 /* Renew the current working directory. */
2214 t
->working_dir_fd
= new_fd
;
2215 t
->flags
&= ~onWorkingDir
;
2216 /* Current directory has been changed, we should
2217 * close an fd of previous working directory. */
2218 close_and_restore_time(prev_dir_fd
, t
, &te
->restore_time
);
2219 if (te
->flags
& isDirLink
) {
2221 te
->symlink_parent_fd
= -1;
2229 * Return to the initial directory where tree_open() was performed.
2232 tree_enter_initial_dir(struct tree
*t
)
2236 if ((t
->flags
& onInitialDir
) == 0) {
2237 r
= fchdir(t
->initial_dir_fd
);
2239 t
->flags
&= ~onWorkingDir
;
2240 t
->flags
|= onInitialDir
;
2247 * Restore working directory of directory traversals.
2250 tree_enter_working_dir(struct tree
*t
)
2255 * Change the current directory if really needed.
2256 * Sometimes this is unneeded when we did not do
2259 if (t
->depth
> 0 && (t
->flags
& onWorkingDir
) == 0) {
2260 r
= fchdir(t
->working_dir_fd
);
2262 t
->flags
&= ~onInitialDir
;
2263 t
->flags
|= onWorkingDir
;
2270 tree_current_dir_fd(struct tree
*t
)
2272 return (t
->working_dir_fd
);
2276 * Pop the working stack.
2279 tree_pop(struct tree
*t
)
2281 struct tree_entry
*te
;
2283 t
->path
.s
[t
->dirname_length
] = '\0';
2284 t
->path
.length
= t
->dirname_length
;
2285 if (t
->stack
== t
->current
&& t
->current
!= NULL
)
2286 t
->current
= t
->current
->parent
;
2288 t
->stack
= te
->next
;
2289 t
->dirname_length
= te
->dirname_length
;
2290 t
->basename
= t
->path
.s
+ t
->dirname_length
;
2291 while (t
->basename
[0] == '/')
2293 archive_string_free(&te
->name
);
2298 * Get the next item in the tree traversal.
2301 tree_next(struct tree
*t
)
2305 while (t
->stack
!= NULL
) {
2306 /* If there's an open dir, get the next entry from there. */
2307 if (t
->d
!= INVALID_DIR_HANDLE
) {
2308 r
= tree_dir_next_posix(t
);
2314 if (t
->stack
->flags
& needsFirstVisit
) {
2315 /* Top stack item needs a regular visit. */
2316 t
->current
= t
->stack
;
2317 tree_append(t
, t
->stack
->name
.s
,
2318 archive_strlen(&(t
->stack
->name
)));
2319 /* t->dirname_length = t->path_length; */
2321 t
->stack
->flags
&= ~needsFirstVisit
;
2322 return (t
->visit_type
= TREE_REGULAR
);
2323 } else if (t
->stack
->flags
& needsDescent
) {
2324 /* Top stack item is dir to descend into. */
2325 t
->current
= t
->stack
;
2326 tree_append(t
, t
->stack
->name
.s
,
2327 archive_strlen(&(t
->stack
->name
)));
2328 t
->stack
->flags
&= ~needsDescent
;
2329 r
= tree_descent(t
);
2334 t
->visit_type
= TREE_POSTDESCENT
;
2335 return (t
->visit_type
);
2336 } else if (t
->stack
->flags
& needsOpen
) {
2337 t
->stack
->flags
&= ~needsOpen
;
2338 r
= tree_dir_next_posix(t
);
2342 } else if (t
->stack
->flags
& needsAscent
) {
2343 /* Top stack item is dir and we're done with it. */
2346 t
->visit_type
= r
!= 0 ? r
: TREE_POSTASCENT
;
2347 return (t
->visit_type
);
2349 /* Top item on stack is dead. */
2351 t
->flags
&= ~hasLstat
;
2352 t
->flags
&= ~hasStat
;
2355 return (t
->visit_type
= 0);
2359 tree_dir_next_posix(struct tree
*t
)
2366 #if defined(HAVE_READDIR_R)
2370 #if defined(HAVE_FDOPENDIR)
2371 t
->d
= fdopendir(tree_dup(t
->working_dir_fd
));
2372 #else /* HAVE_FDOPENDIR */
2373 if (tree_enter_working_dir(t
) == 0) {
2374 t
->d
= opendir(".");
2375 #if HAVE_DIRFD || defined(dirfd)
2376 __archive_ensure_cloexec_flag(dirfd(t
->d
));
2379 #endif /* HAVE_FDOPENDIR */
2381 r
= tree_ascend(t
); /* Undo "chdir" */
2383 t
->tree_errno
= errno
;
2384 t
->visit_type
= r
!= 0 ? r
: TREE_ERROR_DIR
;
2385 return (t
->visit_type
);
2387 #if defined(HAVE_READDIR_R)
2388 dirent_size
= offsetof(struct dirent
, d_name
) +
2389 t
->filesystem_table
[t
->current
->filesystem_id
].name_max
+ 1;
2390 if (t
->dirent
== NULL
|| t
->dirent_allocated
< dirent_size
) {
2392 t
->dirent
= malloc(dirent_size
);
2393 if (t
->dirent
== NULL
) {
2395 t
->d
= INVALID_DIR_HANDLE
;
2396 (void)tree_ascend(t
);
2398 t
->tree_errno
= ENOMEM
;
2399 t
->visit_type
= TREE_ERROR_DIR
;
2400 return (t
->visit_type
);
2402 t
->dirent_allocated
= dirent_size
;
2404 #endif /* HAVE_READDIR_R */
2408 #if defined(HAVE_READDIR_R)
2409 r
= readdir_r(t
->d
, t
->dirent
, &t
->de
);
2411 /* Note: According to the man page, return value 9 indicates
2412 * that the readdir_r was not successful and the error code
2413 * is set to the global errno variable. And then if the end
2414 * of directory entries was reached, the return value is 9
2415 * and the third parameter is set to NULL and errno is
2420 if (r
!= 0 || t
->de
== NULL
) {
2422 t
->de
= readdir(t
->d
);
2423 if (t
->de
== NULL
) {
2427 t
->d
= INVALID_DIR_HANDLE
;
2430 t
->visit_type
= TREE_ERROR_DIR
;
2431 return (t
->visit_type
);
2435 name
= t
->de
->d_name
;
2436 namelen
= D_NAMELEN(t
->de
);
2437 t
->flags
&= ~hasLstat
;
2438 t
->flags
&= ~hasStat
;
2439 if (name
[0] == '.' && name
[1] == '\0')
2441 if (name
[0] == '.' && name
[1] == '.' && name
[2] == '\0')
2443 tree_append(t
, name
, namelen
);
2444 return (t
->visit_type
= TREE_REGULAR
);
2450 * Get the stat() data for the entry just returned from tree_next().
2452 static const struct stat
*
2453 tree_current_stat(struct tree
*t
)
2455 if (!(t
->flags
& hasStat
)) {
2457 if (fstatat(tree_current_dir_fd(t
),
2458 tree_current_access_path(t
), &t
->st
, 0) != 0)
2460 if (tree_enter_working_dir(t
) != 0)
2462 if (stat(tree_current_access_path(t
), &t
->st
) != 0)
2465 t
->flags
|= hasStat
;
2471 * Get the lstat() data for the entry just returned from tree_next().
2473 static const struct stat
*
2474 tree_current_lstat(struct tree
*t
)
2476 if (!(t
->flags
& hasLstat
)) {
2478 if (fstatat(tree_current_dir_fd(t
),
2479 tree_current_access_path(t
), &t
->lst
,
2480 AT_SYMLINK_NOFOLLOW
) != 0)
2482 if (tree_enter_working_dir(t
) != 0)
2484 if (lstat(tree_current_access_path(t
), &t
->lst
) != 0)
2487 t
->flags
|= hasLstat
;
2493 * Test whether current entry is a dir or link to a dir.
2496 tree_current_is_dir(struct tree
*t
)
2498 const struct stat
*st
;
2500 * If we already have lstat() info, then try some
2501 * cheap tests to determine if this is a dir.
2503 if (t
->flags
& hasLstat
) {
2504 /* If lstat() says it's a dir, it must be a dir. */
2505 st
= tree_current_lstat(t
);
2508 if (S_ISDIR(st
->st_mode
))
2510 /* Not a dir; might be a link to a dir. */
2511 /* If it's not a link, then it's not a link to a dir. */
2512 if (!S_ISLNK(st
->st_mode
))
2515 * It's a link, but we don't know what it's a link to,
2516 * so we'll have to use stat().
2520 st
= tree_current_stat(t
);
2521 /* If we can't stat it, it's not a dir. */
2524 /* Use the definitive test. Hopefully this is cached. */
2525 return (S_ISDIR(st
->st_mode
));
2529 * Test whether current entry is a physical directory. Usually, we
2530 * already have at least one of stat() or lstat() in memory, so we
2531 * use tricks to try to avoid an extra trip to the disk.
2534 tree_current_is_physical_dir(struct tree
*t
)
2536 const struct stat
*st
;
2539 * If stat() says it isn't a dir, then it's not a dir.
2540 * If stat() data is cached, this check is free, so do it first.
2542 if (t
->flags
& hasStat
) {
2543 st
= tree_current_stat(t
);
2546 if (!S_ISDIR(st
->st_mode
))
2551 * Either stat() said it was a dir (in which case, we have
2552 * to determine whether it's really a link to a dir) or
2553 * stat() info wasn't available. So we use lstat(), which
2554 * hopefully is already cached.
2557 st
= tree_current_lstat(t
);
2558 /* If we can't stat it, it's not a dir. */
2561 /* Use the definitive test. Hopefully this is cached. */
2562 return (S_ISDIR(st
->st_mode
));
2566 * Test whether the same file has been in the tree as its parent.
2569 tree_target_is_same_as_parent(struct tree
*t
, const struct stat
*st
)
2571 struct tree_entry
*te
;
2573 for (te
= t
->current
->parent
; te
!= NULL
; te
= te
->parent
) {
2574 if (te
->dev
== (int64_t)st
->st_dev
&&
2575 te
->ino
== (int64_t)st
->st_ino
)
2582 * Test whether the current file is symbolic link target and
2583 * on the other filesystem.
2586 tree_current_is_symblic_link_target(struct tree
*t
)
2588 static const struct stat
*lst
, *st
;
2590 lst
= tree_current_lstat(t
);
2591 st
= tree_current_stat(t
);
2592 return (st
!= NULL
&& lst
!= NULL
&&
2593 (int64_t)st
->st_dev
== t
->current_filesystem
->dev
&&
2594 st
->st_dev
!= lst
->st_dev
);
2598 * Return the access path for the entry just returned from tree_next().
2601 tree_current_access_path(struct tree
*t
)
2603 return (t
->basename
);
2607 * Return the full path for the entry just returned from tree_next().
2610 tree_current_path(struct tree
*t
)
2616 * Terminate the traversal.
2619 tree_close(struct tree
*t
)
2624 if (t
->entry_fd
>= 0) {
2625 close_and_restore_time(t
->entry_fd
, t
, &t
->restore_time
);
2628 /* Close the handle of readdir(). */
2629 if (t
->d
!= INVALID_DIR_HANDLE
) {
2631 t
->d
= INVALID_DIR_HANDLE
;
2633 /* Release anything remaining in the stack. */
2634 while (t
->stack
!= NULL
) {
2635 if (t
->stack
->flags
& isDirLink
)
2636 close(t
->stack
->symlink_parent_fd
);
2639 if (t
->working_dir_fd
>= 0) {
2640 close(t
->working_dir_fd
);
2641 t
->working_dir_fd
= -1;
2643 if (t
->initial_dir_fd
>= 0) {
2644 close(t
->initial_dir_fd
);
2645 t
->initial_dir_fd
= -1;
2650 * Release any resources.
2653 tree_free(struct tree
*t
)
2659 archive_string_free(&t
->path
);
2660 #if defined(HAVE_READDIR_R)
2663 free(t
->sparse_list
);
2664 for (i
= 0; i
< t
->max_filesystem_id
; i
++)
2665 free(t
->filesystem_table
[i
].allocation_ptr
);
2666 free(t
->filesystem_table
);