Merge branch 'vendor/GDB'
[dragonfly.git] / contrib / libarchive / libarchive / archive_read_disk_posix.c
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