Import libarchive-3.0.2.
[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 xvfsconf 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 (sfs.f_flags & MNT_NOATIME)
1325                 t->current_filesystem->noatime = 1;
1326         else
1327                 t->current_filesystem->noatime = 0;
1328
1329 #if defined(HAVE_READDIR_R)
1330         /* Set maximum filename length. */
1331 #if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
1332         t->current_filesystem->name_max = sfs.f_namemax;
1333 #else
1334         /* Mac OS X does not have f_namemax in struct statfs. */
1335         if (tree_current_is_symblic_link_target(t))
1336                 nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
1337         else
1338                 nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
1339         if (nm == -1)
1340                 t->current_filesystem->name_max = NAME_MAX;
1341         else
1342                 t->current_filesystem->name_max = nm;
1343 #endif
1344 #endif /* HAVE_READDIR_R */
1345         return (ARCHIVE_OK);
1346 }
1347
1348 #elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL)
1349
1350 /*
1351  * Gather current filesystem properties on NetBSD
1352  */
1353 static int
1354 setup_current_filesystem(struct archive_read_disk *a)
1355 {
1356         struct tree *t = a->tree;
1357         struct statvfs sfs;
1358         int r, xr = 0;
1359
1360         t->current_filesystem->synthetic = -1;
1361         if (tree_current_is_symblic_link_target(t)) {
1362                 r = statvfs(tree_current_access_path(t), &sfs);
1363                 if (r == 0)
1364                         xr = get_xfer_size(t, -1, tree_current_access_path(t));
1365         } else {
1366 #ifdef HAVE_FSTATVFS
1367                 r = fstatvfs(tree_current_dir_fd(t), &sfs);
1368                 if (r == 0)
1369                         xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
1370 #else
1371                 r = statvfs(".", &sfs);
1372                 if (r == 0)
1373                         xr = get_xfer_size(t, -1, ".");
1374 #endif
1375         }
1376         if (r == -1 || xr == -1) {
1377                 t->current_filesystem->remote = -1;
1378                 archive_set_error(&a->archive, errno, "statvfs failed");
1379                 return (ARCHIVE_FAILED);
1380         } else if (xr == 1) {
1381                 /* Usuall come here unless NetBSD supports _PC_REC_XFER_ALIGN
1382                  * for pathconf() function. */
1383                 t->current_filesystem->xfer_align = sfs.f_frsize;
1384                 t->current_filesystem->max_xfer_size = -1;
1385                 t->current_filesystem->min_xfer_size = sfs.f_iosize;
1386                 t->current_filesystem->incr_xfer_size = sfs.f_iosize;
1387         }
1388         if (sfs.f_flag & ST_LOCAL)
1389                 t->current_filesystem->remote = 0;
1390         else
1391                 t->current_filesystem->remote = 1;
1392
1393         if (sfs.f_flag & ST_NOATIME)
1394                 t->current_filesystem->noatime = 1;
1395         else
1396                 t->current_filesystem->noatime = 0;
1397
1398         /* Set maximum filename length. */
1399         t->current_filesystem->name_max = sfs.f_namemax;
1400         return (ARCHIVE_OK);
1401 }
1402
1403 #elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_LINUX_MAGIC_H) &&\
1404         defined(HAVE_STATFS) && defined(HAVE_FSTATFS)
1405 /*
1406  * Note: statfs is deprecated since LSB 3.2
1407  */
1408
1409 #ifndef CIFS_SUPER_MAGIC
1410 #define CIFS_SUPER_MAGIC 0xFF534D42
1411 #endif
1412 #ifndef DEVFS_SUPER_MAGIC
1413 #define DEVFS_SUPER_MAGIC 0x1373
1414 #endif
1415
1416 /*
1417  * Gather current filesystem properties on Linux
1418  */
1419 static int
1420 setup_current_filesystem(struct archive_read_disk *a)
1421 {
1422         struct tree *t = a->tree;
1423         struct statfs sfs;
1424         struct statvfs svfs;
1425         int r, vr = 0, xr = 0;
1426
1427         if (tree_current_is_symblic_link_target(t)) {
1428 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
1429                 /*
1430                  * Get file system statistics on any directory
1431                  * where current is.
1432                  */
1433                 int fd = openat(tree_current_dir_fd(t),
1434                     tree_current_access_path(t), O_RDONLY);
1435                 if (fd < 0) {
1436                         archive_set_error(&a->archive, errno,
1437                             "openat failed");
1438                         return (ARCHIVE_FAILED);
1439                 }
1440                 vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */
1441                 r = fstatfs(fd, &sfs);
1442                 if (r == 0)
1443                         xr = get_xfer_size(t, fd, NULL);
1444                 close(fd);
1445 #else
1446                 vr = statvfs(tree_current_access_path(t), &svfs);
1447                 r = statfs(tree_current_access_path(t), &sfs);
1448                 if (r == 0)
1449                         xr = get_xfer_size(t, -1, tree_current_access_path(t));
1450 #endif
1451         } else {
1452 #ifdef HAVE_FSTATFS
1453                 vr = fstatvfs(tree_current_dir_fd(t), &svfs);
1454                 r = fstatfs(tree_current_dir_fd(t), &sfs);
1455                 if (r == 0)
1456                         xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
1457 #elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
1458 #error "Unexpected case. Please tell us about this error."
1459 #else
1460                 vr = statvfs(".", &svfs);
1461                 r = statfs(".", &sfs);
1462                 if (r == 0)
1463                         xr = get_xfer_size(t, -1, ".");
1464 #endif
1465         }
1466         if (r == -1 || xr == -1 || vr == -1) {
1467                 t->current_filesystem->synthetic = -1;
1468                 t->current_filesystem->remote = -1;
1469                 archive_set_error(&a->archive, errno, "statfs failed");
1470                 return (ARCHIVE_FAILED);
1471         } else if (xr == 1) {
1472                 /* pathconf(_PC_REX_*) operations are not supported. */
1473                 t->current_filesystem->xfer_align = svfs.f_frsize;
1474                 t->current_filesystem->max_xfer_size = -1;
1475                 t->current_filesystem->min_xfer_size = svfs.f_bsize;
1476                 t->current_filesystem->incr_xfer_size = svfs.f_bsize;
1477         }
1478         switch (sfs.f_type) {
1479         case AFS_SUPER_MAGIC:
1480         case CIFS_SUPER_MAGIC:
1481         case CODA_SUPER_MAGIC:
1482         case NCP_SUPER_MAGIC:/* NetWare */
1483         case NFS_SUPER_MAGIC:
1484         case SMB_SUPER_MAGIC:
1485                 t->current_filesystem->remote = 1;
1486                 t->current_filesystem->synthetic = 0;
1487                 break;
1488         case DEVFS_SUPER_MAGIC:
1489         case PROC_SUPER_MAGIC:
1490         case USBDEVICE_SUPER_MAGIC:
1491                 t->current_filesystem->remote = 0;
1492                 t->current_filesystem->synthetic = 1;
1493                 break;
1494         default:
1495                 t->current_filesystem->remote = 0;
1496                 t->current_filesystem->synthetic = 0;
1497                 break;
1498         }
1499
1500 #if defined(ST_NOATIME)
1501         if (svfs.f_flag & ST_NOATIME)
1502                 t->current_filesystem->noatime = 1;
1503         else
1504 #endif
1505                 t->current_filesystem->noatime = 0;
1506
1507 #if defined(HAVE_READDIR_R)
1508         /* Set maximum filename length. */
1509         t->current_filesystem->name_max = sfs.f_namelen;
1510 #endif
1511         return (ARCHIVE_OK);
1512 }
1513
1514 #elif defined(HAVE_SYS_STATVFS_H) &&\
1515         (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS))
1516
1517 /*
1518  * Gather current filesystem properties on other posix platform.
1519  */
1520 static int
1521 setup_current_filesystem(struct archive_read_disk *a)
1522 {
1523         struct tree *t = a->tree;
1524         struct statvfs sfs;
1525         int r, xr = 0;
1526
1527         t->current_filesystem->synthetic = -1;/* Not supported */
1528         t->current_filesystem->remote = -1;/* Not supported */
1529         if (tree_current_is_symblic_link_target(t)) {
1530 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
1531                 /*
1532                  * Get file system statistics on any directory
1533                  * where current is.
1534                  */
1535                 int fd = openat(tree_current_dir_fd(t),
1536                     tree_current_access_path(t), O_RDONLY);
1537                 if (fd < 0) {
1538                         archive_set_error(&a->archive, errno,
1539                             "openat failed");
1540                         return (ARCHIVE_FAILED);
1541                 }
1542                 r = fstatvfs(fd, &sfs);
1543                 if (r == 0)
1544                         xr = get_xfer_size(t, fd, NULL);
1545                 close(fd);
1546 #else
1547                 r = statvfs(tree_current_access_path(t), &sfs);
1548                 if (r == 0)
1549                         xr = get_xfer_size(t, -1, tree_current_access_path(t));
1550 #endif
1551         } else {
1552 #ifdef HAVE_FSTATVFS
1553                 r = fstatvfs(tree_current_dir_fd(t), &sfs);
1554                 if (r == 0)
1555                         xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
1556 #elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
1557 #error "Unexpected case. Please tell us about this error."
1558 #else
1559                 r = statvfs(".", &sfs);
1560                 if (r == 0)
1561                         xr = get_xfer_size(t, -1, ".");
1562 #endif
1563         }
1564         if (r == -1 || xr == -1) {
1565                 t->current_filesystem->synthetic = -1;
1566                 t->current_filesystem->remote = -1;
1567                 archive_set_error(&a->archive, errno, "statvfs failed");
1568                 return (ARCHIVE_FAILED);
1569         } else if (xr == 1) {
1570                 /* pathconf(_PC_REX_*) operations are not supported. */
1571                 t->current_filesystem->xfer_align = sfs.f_frsize;
1572                 t->current_filesystem->max_xfer_size = -1;
1573                 t->current_filesystem->min_xfer_size = sfs.f_bsize;
1574                 t->current_filesystem->incr_xfer_size = sfs.f_bsize;
1575         }
1576
1577 #if defined(ST_NOATIME)
1578         if (sfs.f_flag & ST_NOATIME)
1579                 t->current_filesystem->noatime = 1;
1580         else
1581 #endif
1582                 t->current_filesystem->noatime = 0;
1583
1584 #if defined(HAVE_READDIR_R)
1585         /* Set maximum filename length. */
1586         t->current_filesystem->name_max = sfs.f_namemax;
1587 #endif
1588         return (ARCHIVE_OK);
1589 }
1590
1591 #else
1592
1593 /*
1594  * Generic: Gather current filesystem properties.
1595  * TODO: Is this generic function really needed?
1596  */
1597 static int
1598 setup_current_filesystem(struct archive_read_disk *a)
1599 {
1600         struct tree *t = a->tree;
1601 #if defined(_PC_NAME_MAX) && defined(HAVE_READDIR_R)
1602         long nm;
1603 #endif
1604         t->current_filesystem->synthetic = -1;/* Not supported */
1605         t->current_filesystem->remote = -1;/* Not supported */
1606         t->current_filesystem->noatime = 0;
1607         (void)get_xfer_size(t, -1, ".");/* Dummy call to avoid build error. */
1608         t->current_filesystem->xfer_align = -1;/* Unknown */
1609         t->current_filesystem->max_xfer_size = -1;
1610         t->current_filesystem->min_xfer_size = -1;
1611         t->current_filesystem->incr_xfer_size = -1;
1612
1613 #if defined(HAVE_READDIR_R)
1614         /* Set maximum filename length. */
1615 #  if defined(_PC_NAME_MAX)
1616         if (tree_current_is_symblic_link_target(t))
1617                 nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
1618         else
1619                 nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
1620         if (nm == -1)
1621 #  endif /* _PC_NAME_MAX */
1622                 /*
1623                  * Some sysmtes (HP-UX or others?) incorrectly defined
1624                  * NAME_MAX macro to be a smaller value.
1625                  */
1626 #  if defined(NAME_MAX) && NAME_MAX >= 255
1627                 t->current_filesystem->name_max = NAME_MAX;
1628 #  else
1629                 /* No way to get a trusted value of maximum filename
1630                  * length. */
1631                 t->current_filesystem->name_max = PATH_MAX;
1632 #  endif /* NAME_MAX */
1633 #  if defined(_PC_NAME_MAX)
1634         else
1635                 t->current_filesystem->name_max = nm;
1636 #  endif /* _PC_NAME_MAX */
1637 #endif /* HAVE_READDIR_R */
1638         return (ARCHIVE_OK);
1639 }
1640
1641 #endif
1642
1643 static int
1644 close_and_restore_time(int fd, struct tree *t, struct restore_time *rt)
1645 {
1646 #ifndef HAVE_UTIMES
1647         (void)a; /* UNUSED */
1648         return (close(fd));
1649 #else
1650 #if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
1651         struct timespec timespecs[2];
1652 #endif
1653         struct timeval times[2];
1654
1655         if ((t->flags & needsRestoreTimes) == 0 || rt->noatime) {
1656                 if (fd >= 0)
1657                         return (close(fd));
1658                 else
1659                         return (0);
1660         }
1661
1662 #if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
1663         timespecs[1].tv_sec = rt->mtime;
1664         timespecs[1].tv_nsec = rt->mtime_nsec;
1665
1666         timespecs[0].tv_sec = rt->atime;
1667         timespecs[0].tv_nsec = rt->atime_nsec;
1668         /* futimens() is defined in POSIX.1-2008. */
1669         if (futimens(fd, timespecs) == 0)
1670                 return (close(fd));
1671 #endif
1672
1673         times[1].tv_sec = rt->mtime;
1674         times[1].tv_usec = rt->mtime_nsec / 1000;
1675
1676         times[0].tv_sec = rt->atime;
1677         times[0].tv_usec = rt->atime_nsec / 1000;
1678
1679 #if !defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES) && !defined(__CYGWIN__)
1680         if (futimes(fd, times) == 0)
1681                 return (close(fd));
1682 #endif
1683         close(fd);
1684 #if defined(HAVE_FUTIMESAT)
1685         if (futimesat(tree_current_dir_fd(t), rt->name, times) == 0)
1686                 return (0);
1687 #endif
1688 #ifdef HAVE_LUTIMES
1689         if (lutimes(rt->name, times) != 0)
1690 #else
1691         if (AE_IFLNK != rt->filetype && utimes(rt->name, times) != 0)
1692 #endif
1693                 return (-1);
1694 #endif
1695         return (0);
1696 }
1697
1698 /*
1699  * Add a directory path to the current stack.
1700  */
1701 static void
1702 tree_push(struct tree *t, const char *path, int filesystem_id,
1703     int64_t dev, int64_t ino, struct restore_time *rt)
1704 {
1705         struct tree_entry *te;
1706
1707         te = malloc(sizeof(*te));
1708         memset(te, 0, sizeof(*te));
1709         te->next = t->stack;
1710         te->parent = t->current;
1711         if (te->parent)
1712                 te->depth = te->parent->depth + 1;
1713         t->stack = te;
1714         archive_string_init(&te->name);
1715         te->symlink_parent_fd = -1;
1716         archive_strcpy(&te->name, path);
1717         te->flags = needsDescent | needsOpen | needsAscent;
1718         te->filesystem_id = filesystem_id;
1719         te->dev = dev;
1720         te->ino = ino;
1721         te->dirname_length = t->dirname_length;
1722         te->restore_time.name = te->name.s;
1723         if (rt != NULL) {
1724                 te->restore_time.mtime = rt->mtime;
1725                 te->restore_time.mtime_nsec = rt->mtime_nsec;
1726                 te->restore_time.atime = rt->atime;
1727                 te->restore_time.atime_nsec = rt->atime_nsec;
1728                 te->restore_time.filetype = rt->filetype;
1729                 te->restore_time.noatime = rt->noatime;
1730         }
1731 }
1732
1733 /*
1734  * Append a name to the current dir path.
1735  */
1736 static void
1737 tree_append(struct tree *t, const char *name, size_t name_length)
1738 {
1739         size_t size_needed;
1740
1741         t->path.s[t->dirname_length] = '\0';
1742         t->path.length = t->dirname_length;
1743         /* Strip trailing '/' from name, unless entire name is "/". */
1744         while (name_length > 1 && name[name_length - 1] == '/')
1745                 name_length--;
1746
1747         /* Resize pathname buffer as needed. */
1748         size_needed = name_length + t->dirname_length + 2;
1749         archive_string_ensure(&t->path, size_needed);
1750         /* Add a separating '/' if it's needed. */
1751         if (t->dirname_length > 0 && t->path.s[archive_strlen(&t->path)-1] != '/')
1752                 archive_strappend_char(&t->path, '/');
1753         t->basename = t->path.s + archive_strlen(&t->path);
1754         archive_strncat(&t->path, name, name_length);
1755         t->restore_time.name = t->basename;
1756 }
1757
1758 /*
1759  * Open a directory tree for traversal.
1760  */
1761 static struct tree *
1762 tree_open(const char *path, int symlink_mode, int restore_time)
1763 {
1764         struct tree *t;
1765
1766         if ((t = malloc(sizeof(*t))) == NULL)
1767                 return (NULL);
1768         memset(t, 0, sizeof(*t));
1769         archive_string_init(&t->path);
1770         archive_string_ensure(&t->path, 31);
1771         t->initial_symlink_mode = symlink_mode;
1772         return (tree_reopen(t, path, restore_time));
1773 }
1774
1775 static struct tree *
1776 tree_reopen(struct tree *t, const char *path, int restore_time)
1777 {
1778         t->flags = (restore_time)?needsRestoreTimes:0;
1779         t->visit_type = 0;
1780         t->tree_errno = 0;
1781         t->dirname_length = 0;
1782         t->depth = 0;
1783         t->descend = 0;
1784         t->current = NULL;
1785         t->d = INVALID_DIR_HANDLE;
1786         t->symlink_mode = t->initial_symlink_mode;
1787         archive_string_empty(&t->path);
1788         t->entry_fd = -1;
1789         t->entry_eof = 0;
1790         t->entry_remaining_bytes = 0;
1791
1792         /* First item is set up a lot like a symlink traversal. */
1793         tree_push(t, path, 0, 0, 0, NULL);
1794         t->stack->flags = needsFirstVisit;
1795         t->maxOpenCount = t->openCount = 1;
1796         t->initial_dir_fd = open(".", O_RDONLY);
1797         t->working_dir_fd = dup(t->initial_dir_fd);
1798         return (t);
1799 }
1800
1801 static int
1802 tree_descent(struct tree *t)
1803 {
1804         int r = 0;
1805
1806 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
1807         int new_fd;
1808         t->dirname_length = archive_strlen(&t->path);
1809         new_fd = openat(t->working_dir_fd, t->stack->name.s, O_RDONLY);
1810         if (new_fd < 0) {
1811                 t->tree_errno = errno;
1812                 r = TREE_ERROR_DIR;
1813         } else {
1814                 t->depth++;
1815                 /* If it is a link, set up fd for the ascent. */
1816                 if (t->stack->flags & isDirLink) {
1817                         t->stack->symlink_parent_fd = t->working_dir_fd;
1818                         t->openCount++;
1819                         if (t->openCount > t->maxOpenCount)
1820                                 t->maxOpenCount = t->openCount;
1821                 } else
1822                         close(t->working_dir_fd);
1823                 t->working_dir_fd = new_fd;
1824         }
1825 #else
1826         /* If it is a link, set up fd for the ascent. */
1827         if (t->stack->flags & isDirLink)
1828                 t->stack->symlink_parent_fd = t->working_dir_fd;
1829         else {
1830                 close(t->working_dir_fd);
1831                 t->openCount--;
1832         }
1833         t->working_dir_fd = -1;
1834         t->dirname_length = archive_strlen(&t->path);
1835         if (chdir(t->stack->name.s) != 0)
1836         {
1837                 t->tree_errno = errno;
1838                 r = TREE_ERROR_DIR;
1839         } else {
1840                 t->depth++;
1841                 t->working_dir_fd = open(".", O_RDONLY);
1842                 t->openCount++;
1843                 if (t->openCount > t->maxOpenCount)
1844                         t->maxOpenCount = t->openCount;
1845         }
1846 #endif
1847         return (r);
1848 }
1849
1850 /*
1851  * We've finished a directory; ascend back to the parent.
1852  */
1853 static int
1854 tree_ascend(struct tree *t)
1855 {
1856         struct tree_entry *te;
1857         int r = 0, prev_dir_fd;
1858
1859         te = t->stack;
1860         prev_dir_fd = t->working_dir_fd;
1861 #if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
1862         if (te->flags & isDirLink)
1863                 t->working_dir_fd = te->symlink_parent_fd;
1864         else {
1865                 int new_fd = openat(t->working_dir_fd, "..", O_RDONLY);
1866                 if (new_fd < 0) {
1867                         t->tree_errno = errno;
1868                         r = TREE_ERROR_FATAL;
1869                 } else
1870                         t->working_dir_fd = new_fd;
1871         }
1872 #else
1873         if (te->flags & isDirLink) {
1874                 if (fchdir(te->symlink_parent_fd) != 0) {
1875                         t->tree_errno = errno;
1876                         r = TREE_ERROR_FATAL;
1877                 } else
1878                         t->working_dir_fd = te->symlink_parent_fd;
1879         } else {
1880                 if (chdir("..") != 0) {
1881                         t->tree_errno = errno;
1882                         r = TREE_ERROR_FATAL;
1883                 } else
1884                         t->working_dir_fd = open(".", O_RDONLY);
1885         }
1886 #endif
1887         if (r == 0) {
1888                 /* Current directory has been changed, we should
1889                  * close an fd of previous working directory. */
1890                 close_and_restore_time(prev_dir_fd, t, &te->restore_time);
1891                 if (te->flags & isDirLink) {
1892                         t->openCount--;
1893                         te->symlink_parent_fd = -1;
1894                 }
1895                 t->depth--;
1896         }
1897         return (r);
1898 }
1899
1900 /*
1901  * Return to the initial directory where tree_open() was performed.
1902  */
1903 static int
1904 tree_enter_initial_dir(struct tree *t)
1905 {
1906         int r = 0;
1907
1908         if (t->flags & onWorkingDir) {
1909                 r = fchdir(t->initial_dir_fd);
1910                 if (r == 0)
1911                         t->flags &= ~onWorkingDir;
1912         }
1913         return (r);
1914 }
1915
1916 /*
1917  * Restore working directory of directory traversals.
1918  */
1919 static int
1920 tree_enter_working_dir(struct tree *t)
1921 {
1922         int r = 0;
1923
1924         /*
1925          * Change the current directory if really needed.
1926          * Sometimes this is unneeded when we did not do
1927          * descent.
1928          */
1929         if (t->depth > 0 && (t->flags & onWorkingDir) == 0) {
1930                 r = fchdir(t->working_dir_fd);
1931                 if (r == 0)
1932                         t->flags |= onWorkingDir;
1933         }
1934         return (r);
1935 }
1936
1937 static int
1938 tree_current_dir_fd(struct tree *t)
1939 {
1940         return (t->working_dir_fd);
1941 }
1942
1943 /*
1944  * Pop the working stack.
1945  */
1946 static void
1947 tree_pop(struct tree *t)
1948 {
1949         struct tree_entry *te;
1950
1951         t->path.s[t->dirname_length] = '\0';
1952         t->path.length = t->dirname_length;
1953         if (t->stack == t->current && t->current != NULL)
1954                 t->current = t->current->parent;
1955         te = t->stack;
1956         t->stack = te->next;
1957         t->dirname_length = te->dirname_length;
1958         t->basename = t->path.s + t->dirname_length;
1959         while (t->basename[0] == '/')
1960                 t->basename++;
1961         archive_string_free(&te->name);
1962         free(te);
1963 }
1964
1965 /*
1966  * Get the next item in the tree traversal.
1967  */
1968 static int
1969 tree_next(struct tree *t)
1970 {
1971         int r;
1972
1973         while (t->stack != NULL) {
1974                 /* If there's an open dir, get the next entry from there. */
1975                 if (t->d != INVALID_DIR_HANDLE) {
1976                         r = tree_dir_next_posix(t);
1977                         if (r == 0)
1978                                 continue;
1979                         return (r);
1980                 }
1981
1982                 if (t->stack->flags & needsFirstVisit) {
1983                         /* Top stack item needs a regular visit. */
1984                         t->current = t->stack;
1985                         tree_append(t, t->stack->name.s,
1986                             archive_strlen(&(t->stack->name)));
1987                         /* t->dirname_length = t->path_length; */
1988                         /* tree_pop(t); */
1989                         t->stack->flags &= ~needsFirstVisit;
1990                         return (t->visit_type = TREE_REGULAR);
1991                 } else if (t->stack->flags & needsDescent) {
1992                         /* Top stack item is dir to descend into. */
1993                         t->current = t->stack;
1994                         tree_append(t, t->stack->name.s,
1995                             archive_strlen(&(t->stack->name)));
1996                         t->stack->flags &= ~needsDescent;
1997                         r = tree_descent(t);
1998                         if (r != 0) {
1999                                 tree_pop(t);
2000                                 t->visit_type = r;
2001                         } else
2002                                 t->visit_type = TREE_POSTDESCENT;
2003                         return (t->visit_type);
2004                 } else if (t->stack->flags & needsOpen) {
2005                         t->stack->flags &= ~needsOpen;
2006                         r = tree_dir_next_posix(t);
2007                         if (r == 0)
2008                                 continue;
2009                         return (r);
2010                 } else if (t->stack->flags & needsAscent) {
2011                         /* Top stack item is dir and we're done with it. */
2012                         r = tree_ascend(t);
2013                         tree_pop(t);
2014                         t->visit_type = r != 0 ? r : TREE_POSTASCENT;
2015                         return (t->visit_type);
2016                 } else {
2017                         /* Top item on stack is dead. */
2018                         tree_pop(t);
2019                         t->flags &= ~hasLstat;
2020                         t->flags &= ~hasStat;
2021                 }
2022         }
2023         return (t->visit_type = 0);
2024 }
2025
2026 static int
2027 tree_dir_next_posix(struct tree *t)
2028 {
2029         int r;
2030         const char *name;
2031         size_t namelen;
2032
2033         if (t->d == NULL) {
2034 #if defined(HAVE_READDIR_R)
2035                 size_t dirent_size;
2036 #endif
2037
2038 #if defined(HAVE_FDOPENDIR)
2039                 if ((t->d = fdopendir(dup(t->working_dir_fd))) == NULL) {
2040 #else
2041                 if ((t->d = opendir(".")) == NULL) {
2042 #endif
2043                         r = tree_ascend(t); /* Undo "chdir" */
2044                         tree_pop(t);
2045                         t->tree_errno = errno;
2046                         t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
2047                         return (t->visit_type);
2048                 }
2049 #if defined(HAVE_READDIR_R)
2050                 dirent_size = offsetof(struct dirent, d_name) +
2051                   t->filesystem_table[t->current->filesystem_id].name_max + 1;
2052                 if (t->dirent == NULL || t->dirent_allocated < dirent_size) {
2053                         free(t->dirent);
2054                         t->dirent = malloc(dirent_size);
2055                         if (t->dirent == NULL) {
2056                                 closedir(t->d);
2057                                 t->d = INVALID_DIR_HANDLE;
2058                                 (void)tree_ascend(t);
2059                                 tree_pop(t);
2060                                 t->tree_errno = ENOMEM;
2061                                 t->visit_type = TREE_ERROR_DIR;
2062                                 return (t->visit_type);
2063                         }
2064                         t->dirent_allocated = dirent_size;
2065                 }
2066 #endif /* HAVE_READDIR_R */
2067         }
2068         for (;;) {
2069 #if defined(HAVE_READDIR_R)
2070                 r = readdir_r(t->d, t->dirent, &t->de);
2071                 if (r != 0 || t->de == NULL) {
2072 #else
2073                 errno = 0;
2074                 t->de = readdir(t->d);
2075                 if (t->de == NULL) {
2076                         r = errno;
2077 #endif
2078                         closedir(t->d);
2079                         t->d = INVALID_DIR_HANDLE;
2080                         if (r != 0) {
2081                                 t->tree_errno = r;
2082                                 t->visit_type = TREE_ERROR_DIR;
2083                                 return (t->visit_type);
2084                         } else
2085                                 return (0);
2086                 }
2087                 name = t->de->d_name;
2088                 namelen = D_NAMELEN(t->de);
2089                 t->flags &= ~hasLstat;
2090                 t->flags &= ~hasStat;
2091                 if (name[0] == '.' && name[1] == '\0')
2092                         continue;
2093                 if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
2094                         continue;
2095                 tree_append(t, name, namelen);
2096                 return (t->visit_type = TREE_REGULAR);
2097         }
2098 }
2099
2100
2101 /*
2102  * Get the stat() data for the entry just returned from tree_next().
2103  */
2104 static const struct stat *
2105 tree_current_stat(struct tree *t)
2106 {
2107         if (!(t->flags & hasStat)) {
2108 #ifdef HAVE_FSTATAT
2109                 if (fstatat(tree_current_dir_fd(t),
2110                     tree_current_access_path(t), &t->st, 0) != 0)
2111 #else
2112                 if (stat(tree_current_access_path(t), &t->st) != 0)
2113 #endif
2114                         return NULL;
2115                 t->flags |= hasStat;
2116         }
2117         return (&t->st);
2118 }
2119
2120 /*
2121  * Get the lstat() data for the entry just returned from tree_next().
2122  */
2123 static const struct stat *
2124 tree_current_lstat(struct tree *t)
2125 {
2126         if (!(t->flags & hasLstat)) {
2127 #ifdef HAVE_FSTATAT
2128                 if (fstatat(tree_current_dir_fd(t),
2129                     tree_current_access_path(t), &t->lst,
2130                     AT_SYMLINK_NOFOLLOW) != 0)
2131 #else
2132                 if (lstat(tree_current_access_path(t), &t->lst) != 0)
2133 #endif
2134                         return NULL;
2135                 t->flags |= hasLstat;
2136         }
2137         return (&t->lst);
2138 }
2139
2140 /*
2141  * Test whether current entry is a dir or link to a dir.
2142  */
2143 static int
2144 tree_current_is_dir(struct tree *t)
2145 {
2146         const struct stat *st;
2147         /*
2148          * If we already have lstat() info, then try some
2149          * cheap tests to determine if this is a dir.
2150          */
2151         if (t->flags & hasLstat) {
2152                 /* If lstat() says it's a dir, it must be a dir. */
2153                 if (S_ISDIR(tree_current_lstat(t)->st_mode))
2154                         return 1;
2155                 /* Not a dir; might be a link to a dir. */
2156                 /* If it's not a link, then it's not a link to a dir. */
2157                 if (!S_ISLNK(tree_current_lstat(t)->st_mode))
2158                         return 0;
2159                 /*
2160                  * It's a link, but we don't know what it's a link to,
2161                  * so we'll have to use stat().
2162                  */
2163         }
2164
2165         st = tree_current_stat(t);
2166         /* If we can't stat it, it's not a dir. */
2167         if (st == NULL)
2168                 return 0;
2169         /* Use the definitive test.  Hopefully this is cached. */
2170         return (S_ISDIR(st->st_mode));
2171 }
2172
2173 /*
2174  * Test whether current entry is a physical directory.  Usually, we
2175  * already have at least one of stat() or lstat() in memory, so we
2176  * use tricks to try to avoid an extra trip to the disk.
2177  */
2178 static int
2179 tree_current_is_physical_dir(struct tree *t)
2180 {
2181         const struct stat *st;
2182
2183         /*
2184          * If stat() says it isn't a dir, then it's not a dir.
2185          * If stat() data is cached, this check is free, so do it first.
2186          */
2187         if ((t->flags & hasStat)
2188             && (!S_ISDIR(tree_current_stat(t)->st_mode)))
2189                 return 0;
2190
2191         /*
2192          * Either stat() said it was a dir (in which case, we have
2193          * to determine whether it's really a link to a dir) or
2194          * stat() info wasn't available.  So we use lstat(), which
2195          * hopefully is already cached.
2196          */
2197
2198         st = tree_current_lstat(t);
2199         /* If we can't stat it, it's not a dir. */
2200         if (st == NULL)
2201                 return 0;
2202         /* Use the definitive test.  Hopefully this is cached. */
2203         return (S_ISDIR(st->st_mode));
2204 }
2205
2206 /*
2207  * Test whether the same file has been in the tree as its parent.
2208  */
2209 static int
2210 tree_target_is_same_as_parent(struct tree *t, const struct stat *st)
2211 {
2212         struct tree_entry *te;
2213
2214         for (te = t->current->parent; te != NULL; te = te->parent) {
2215                 if (te->dev == st->st_dev && te->ino == st->st_ino)
2216                         return (1);
2217         }
2218         return (0);
2219 }
2220
2221 /*
2222  * Test whether the current file is symbolic link target and
2223  * on the other filesystem.
2224  */
2225 static int
2226 tree_current_is_symblic_link_target(struct tree *t)
2227 {
2228         static const struct stat *lst, *st;
2229
2230         lst = tree_current_lstat(t);
2231         st = tree_current_stat(t);
2232         return (st != NULL && st->st_dev == t->current_filesystem->dev &&
2233             st->st_dev != lst->st_dev);
2234 }
2235
2236 /*
2237  * Return the access path for the entry just returned from tree_next().
2238  */
2239 static const char *
2240 tree_current_access_path(struct tree *t)
2241 {
2242         return (t->basename);
2243 }
2244
2245 /*
2246  * Return the full path for the entry just returned from tree_next().
2247  */
2248 static const char *
2249 tree_current_path(struct tree *t)
2250 {
2251         return (t->path.s);
2252 }
2253
2254 /*
2255  * Terminate the traversal.
2256  */
2257 static void
2258 tree_close(struct tree *t)
2259 {
2260
2261         if (t == NULL)
2262                 return;
2263         if (t->entry_fd >= 0) {
2264                 close_and_restore_time(t->entry_fd, t, &t->restore_time);
2265                 t->entry_fd = -1;
2266         }
2267         /* Close the handle of readdir(). */
2268         if (t->d != INVALID_DIR_HANDLE) {
2269                 closedir(t->d);
2270                 t->d = INVALID_DIR_HANDLE;
2271         }
2272         /* Release anything remaining in the stack. */
2273         while (t->stack != NULL) {
2274                 if (t->stack->flags & isDirLink)
2275                         close(t->stack->symlink_parent_fd);
2276                 tree_pop(t);
2277         }
2278         if (t->working_dir_fd >= 0) {
2279                 close(t->working_dir_fd);
2280                 t->working_dir_fd = -1;
2281         }
2282         if (t->initial_dir_fd >= 0) {
2283                 close(t->initial_dir_fd);
2284                 t->initial_dir_fd = -1;
2285         }
2286 }
2287
2288 /*
2289  * Release any resources.
2290  */
2291 static void
2292 tree_free(struct tree *t)
2293 {
2294         int i;
2295
2296         if (t == NULL)
2297                 return;
2298         archive_string_free(&t->path);
2299 #if defined(HAVE_READDIR_R)
2300         free(t->dirent);
2301 #endif
2302         free(t->sparse_list);
2303         for (i = 0; i < t->max_filesystem_id; i++)
2304                 free(t->filesystem_table[i].allocation_ptr);
2305         free(t->filesystem_table);
2306         free(t);
2307 }
2308
2309 #endif