archive_read_disk_posix.c revision 232153
174840Sken/*-
274840Sken * Copyright (c) 2003-2009 Tim Kientzle
374840Sken * Copyright (c) 2010,2011 Michihiro NAKAJIMA
474840Sken * All rights reserved.
574840Sken *
674840Sken * Redistribution and use in source and binary forms, with or without
774840Sken * modification, are permitted provided that the following conditions
874840Sken * are met:
974840Sken * 1. Redistributions of source code must retain the above copyright
1074840Sken *    notice, this list of conditions and the following disclaimer
1174840Sken *    in this position and unchanged.
1274840Sken * 2. Redistributions in binary form must reproduce the above copyright
1374840Sken *    notice, this list of conditions and the following disclaimer in the
1474840Sken *    documentation and/or other materials provided with the distribution.
1574840Sken *
1674840Sken * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
1774840Sken * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1874840Sken * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1974840Sken * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
2074840Sken * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2174840Sken * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2274840Sken * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2374840Sken * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2474840Sken * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2574840Sken * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2674840Sken */
2774840Sken
2874840Sken/* This is the tree-walking code for POSIX systems. */
2974840Sken#if !defined(_WIN32) || defined(__CYGWIN__)
3074840Sken
3174840Sken#include "archive_platform.h"
3274840Sken__FBSDID("$FreeBSD$");
3374840Sken
3474840Sken#ifdef HAVE_SYS_PARAM_H
3574840Sken#include <sys/param.h>
3674840Sken#endif
37116189Sobrien#ifdef HAVE_SYS_MOUNT_H
38116189Sobrien#include <sys/mount.h>
3974840Sken#endif
4079418Sjulian#ifdef HAVE_SYS_STAT_H
4179418Sjulian#include <sys/stat.h>
4274840Sken#endif
4374840Sken#ifdef HAVE_SYS_STATFS_H
4474840Sken#include <sys/statfs.h>
4574840Sken#endif
4674840Sken#ifdef HAVE_SYS_STATVFS_H
4774840Sken#include <sys/statvfs.h>
4874840Sken#endif
4974840Sken#ifdef HAVE_SYS_TIME_H
5074840Sken#include <sys/time.h>
5174840Sken#endif
5274840Sken#ifdef HAVE_LINUX_MAGIC_H
5374840Sken#include <linux/magic.h>
5474840Sken#endif
5574840Sken#ifdef HAVE_DIRECT_H
5674840Sken#include <direct.h>
5774840Sken#endif
5874840Sken#ifdef HAVE_DIRENT_H
5974840Sken#include <dirent.h>
6074840Sken#endif
6174840Sken#ifdef HAVE_ERRNO_H
6274840Sken#include <errno.h>
6374840Sken#endif
6474840Sken#ifdef HAVE_FCNTL_H
6592741Salfred#include <fcntl.h>
6674840Sken#endif
6774840Sken#ifdef HAVE_LIMITS_H
6874840Sken#include <limits.h>
6974840Sken#endif
7074840Sken#ifdef HAVE_STDLIB_H
7174840Sken#include <stdlib.h>
7274840Sken#endif
7374840Sken#ifdef HAVE_STRING_H
7474840Sken#include <string.h>
7574840Sken#endif
7683289Speter#ifdef HAVE_UNISTD_H
7774840Sken#include <unistd.h>
7874840Sken#endif
7974840Sken
8074840Sken#include "archive.h"
8174840Sken#include "archive_string.h"
8274840Sken#include "archive_entry.h"
8374840Sken#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
118struct 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
128struct 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
144struct 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 */
178struct 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
244static int
245tree_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. */
255static struct tree *tree_open(const char *, int, int);
256static struct tree *tree_reopen(struct tree *, const char *, int);
257static void tree_close(struct tree *);
258static void tree_free(struct tree *);
259static void tree_push(struct tree *, const char *, int, int64_t, int64_t,
260		struct restore_time *);
261static int tree_enter_initial_dir(struct tree *);
262static int tree_enter_working_dir(struct tree *);
263static 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
289static 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 */
309static const char *tree_current_path(struct tree *);
310static 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 */
318static const struct stat *tree_current_stat(struct tree *);
319static const struct stat *tree_current_lstat(struct tree *);
320static 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) */
325static int tree_current_is_physical_dir(struct tree *);
326/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
327static int tree_current_is_dir(struct tree *);
328static int update_current_filesystem(struct archive_read_disk *a,
329		    int64_t dev);
330static int setup_current_filesystem(struct archive_read_disk *);
331static int tree_target_is_same_as_parent(struct tree *, const struct stat *);
332
333static int	_archive_read_disk_open(struct archive *, const char *);
334static int	_archive_read_free(struct archive *);
335static int	_archive_read_close(struct archive *);
336static int	_archive_read_data_block(struct archive *,
337		    const void **, size_t *, int64_t *);
338static int	_archive_read_next_header2(struct archive *,
339		    struct archive_entry *);
340static const char *trivial_lookup_gname(void *, int64_t gid);
341static const char *trivial_lookup_uname(void *, int64_t uid);
342static int	setup_sparse(struct archive_read_disk *, struct archive_entry *);
343static int	close_and_restore_time(int fd, struct tree *,
344		    struct restore_time *);
345
346
347static struct archive_vtable *
348archive_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
363const char *
364archive_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
375const char *
376archive_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
387int
388archive_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
406int
407archive_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 */
428struct archive *
429archive_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
446static 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
474static 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
490static void
491setup_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
502int
503archive_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
512int
513archive_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
522int
523archive_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
532int
533archive_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 */
563static const char *
564trivial_lookup_gname(void *private_data, int64_t gid)
565{
566	(void)private_data; /* UNUSED */
567	(void)gid; /* UNUSED */
568	return (NULL);
569}
570
571static const char *
572trivial_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 */
583static int
584setup_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
645static 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 > (size_t)t->current_sparse->length)
737		buffbytes = (size_t)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
792abort_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
804static 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
983static int
984setup_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 */
1025int
1026archive_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
1053int
1054archive_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
1066int
1067archive_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
1093static 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 */
1118int
1119archive_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
1129static int
1130update_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 */
1180int
1181archive_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 */
1195int
1196archive_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)
1208static int
1209get_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
1239static int
1240get_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 */
1255static int
1256setup_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 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 */
1355static int
1356setup_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 */
1421static int
1422setup_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 */
1522static int
1523setup_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 */
1599static int
1600setup_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
1645static int
1646close_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 */
1703static void
1704tree_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 */
1738static void
1739tree_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 */
1763static struct tree *
1764tree_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
1777static struct tree *
1778tree_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
1803static int
1804tree_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 */
1855static int
1856tree_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 */
1905static int
1906tree_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 */
1921static int
1922tree_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
1939static int
1940tree_current_dir_fd(struct tree *t)
1941{
1942	return (t->working_dir_fd);
1943}
1944
1945/*
1946 * Pop the working stack.
1947 */
1948static void
1949tree_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 */
1970static int
1971tree_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
2028static int
2029tree_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 */
2106static const struct stat *
2107tree_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 */
2125static const struct stat *
2126tree_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 */
2145static int
2146tree_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 */
2180static int
2181tree_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 */
2211static int
2212tree_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 == (int64_t)st->st_dev &&
2218		    te->ino == (int64_t)st->st_ino)
2219			return (1);
2220	}
2221	return (0);
2222}
2223
2224/*
2225 * Test whether the current file is symbolic link target and
2226 * on the other filesystem.
2227 */
2228static int
2229tree_current_is_symblic_link_target(struct tree *t)
2230{
2231	static const struct stat *lst, *st;
2232
2233	lst = tree_current_lstat(t);
2234	st = tree_current_stat(t);
2235	return (st != NULL &&
2236	    (int64_t)st->st_dev == t->current_filesystem->dev &&
2237	    st->st_dev != lst->st_dev);
2238}
2239
2240/*
2241 * Return the access path for the entry just returned from tree_next().
2242 */
2243static const char *
2244tree_current_access_path(struct tree *t)
2245{
2246	return (t->basename);
2247}
2248
2249/*
2250 * Return the full path for the entry just returned from tree_next().
2251 */
2252static const char *
2253tree_current_path(struct tree *t)
2254{
2255	return (t->path.s);
2256}
2257
2258/*
2259 * Terminate the traversal.
2260 */
2261static void
2262tree_close(struct tree *t)
2263{
2264
2265	if (t == NULL)
2266		return;
2267	if (t->entry_fd >= 0) {
2268		close_and_restore_time(t->entry_fd, t, &t->restore_time);
2269		t->entry_fd = -1;
2270	}
2271	/* Close the handle of readdir(). */
2272	if (t->d != INVALID_DIR_HANDLE) {
2273		closedir(t->d);
2274		t->d = INVALID_DIR_HANDLE;
2275	}
2276	/* Release anything remaining in the stack. */
2277	while (t->stack != NULL) {
2278		if (t->stack->flags & isDirLink)
2279			close(t->stack->symlink_parent_fd);
2280		tree_pop(t);
2281	}
2282	if (t->working_dir_fd >= 0) {
2283		close(t->working_dir_fd);
2284		t->working_dir_fd = -1;
2285	}
2286	if (t->initial_dir_fd >= 0) {
2287		close(t->initial_dir_fd);
2288		t->initial_dir_fd = -1;
2289	}
2290}
2291
2292/*
2293 * Release any resources.
2294 */
2295static void
2296tree_free(struct tree *t)
2297{
2298	int i;
2299
2300	if (t == NULL)
2301		return;
2302	archive_string_free(&t->path);
2303#if defined(HAVE_READDIR_R)
2304	free(t->dirent);
2305#endif
2306	free(t->sparse_list);
2307	for (i = 0; i < t->max_filesystem_id; i++)
2308		free(t->filesystem_table[i].allocation_ptr);
2309	free(t->filesystem_table);
2310	free(t);
2311}
2312
2313#endif
2314