archive_read_disk_entry_from_file.c revision 368708
1/*-
2 * Copyright (c) 2003-2009 Tim Kientzle
3 * Copyright (c) 2010-2012 Michihiro NAKAJIMA
4 * Copyright (c) 2016 Martin Matuska
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
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#include "archive_platform.h"
29__FBSDID("$FreeBSD");
30
31/* This is the tree-walking code for POSIX systems. */
32#if !defined(_WIN32) || defined(__CYGWIN__)
33
34#ifdef HAVE_SYS_TYPES_H
35#include <sys/types.h>
36#endif
37#ifdef HAVE_SYS_EXTATTR_H
38#include <sys/extattr.h>
39#endif
40#ifdef HAVE_SYS_IOCTL_H
41#include <sys/ioctl.h>
42#endif
43#ifdef HAVE_SYS_PARAM_H
44#include <sys/param.h>
45#endif
46#ifdef HAVE_SYS_STAT_H
47#include <sys/stat.h>
48#endif
49#if defined(HAVE_SYS_XATTR_H)
50#include <sys/xattr.h>
51#elif defined(HAVE_ATTR_XATTR_H)
52#include <attr/xattr.h>
53#endif
54#ifdef HAVE_SYS_EA_H
55#include <sys/ea.h>
56#endif
57#ifdef HAVE_COPYFILE_H
58#include <copyfile.h>
59#endif
60#ifdef HAVE_ERRNO_H
61#include <errno.h>
62#endif
63#ifdef HAVE_FCNTL_H
64#include <fcntl.h>
65#endif
66#ifdef HAVE_LIMITS_H
67#include <limits.h>
68#endif
69#ifdef HAVE_LINUX_TYPES_H
70#include <linux/types.h>
71#endif
72#ifdef HAVE_LINUX_FIEMAP_H
73#include <linux/fiemap.h>
74#endif
75#ifdef HAVE_LINUX_FS_H
76#include <linux/fs.h>
77#endif
78/*
79 * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
80 * As the include guards don't agree, the order of include is important.
81 */
82#ifdef HAVE_LINUX_EXT2_FS_H
83#include <linux/ext2_fs.h>      /* for Linux file flags */
84#endif
85#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
86#include <ext2fs/ext2_fs.h>     /* Linux file flags, broken on Cygwin */
87#endif
88#ifdef HAVE_PATHS_H
89#include <paths.h>
90#endif
91#ifdef HAVE_UNISTD_H
92#include <unistd.h>
93#endif
94
95#include "archive.h"
96#include "archive_entry.h"
97#include "archive_private.h"
98#include "archive_read_disk_private.h"
99
100#ifndef O_CLOEXEC
101#define O_CLOEXEC	0
102#endif
103
104static int setup_mac_metadata(struct archive_read_disk *,
105    struct archive_entry *, int *fd);
106#ifdef ARCHIVE_XATTR_FREEBSD
107static int setup_xattrs_namespace(struct archive_read_disk *,
108    struct archive_entry *, int *, int);
109#endif
110static int setup_xattrs(struct archive_read_disk *,
111    struct archive_entry *, int *fd);
112static int setup_sparse(struct archive_read_disk *,
113    struct archive_entry *, int *fd);
114#if defined(HAVE_LINUX_FIEMAP_H)
115static int setup_sparse_fiemap(struct archive_read_disk *,
116    struct archive_entry *, int *fd);
117#endif
118
119#if !ARCHIVE_ACL_SUPPORT
120int
121archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
122    struct archive_entry *entry, int *fd)
123{
124	(void)a;      /* UNUSED */
125	(void)entry;  /* UNUSED */
126	(void)fd;     /* UNUSED */
127	return (ARCHIVE_OK);
128}
129#endif
130
131/*
132 * Enter working directory and return working pathname of archive_entry.
133 * If a pointer to an integer is provided and its value is below zero
134 * open a file descriptor on this pathname.
135 */
136const char *
137archive_read_disk_entry_setup_path(struct archive_read_disk *a,
138    struct archive_entry *entry, int *fd)
139{
140	const char *path;
141
142	path = archive_entry_sourcepath(entry);
143
144	if (path == NULL || (a->tree != NULL &&
145	    a->tree_enter_working_dir(a->tree) != 0))
146		path = archive_entry_pathname(entry);
147	if (path == NULL) {
148		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
149		   "Couldn't determine path");
150	} else if (fd != NULL && *fd < 0 && a->tree != NULL &&
151	    (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)) {
152		*fd = a->open_on_current_dir(a->tree, path,
153		    O_RDONLY | O_NONBLOCK);
154	}
155	return (path);
156}
157
158int
159archive_read_disk_entry_from_file(struct archive *_a,
160    struct archive_entry *entry,
161    int fd,
162    const struct stat *st)
163{
164	struct archive_read_disk *a = (struct archive_read_disk *)_a;
165	const char *path, *name;
166	struct stat s;
167	int initial_fd = fd;
168	int r, r1;
169
170	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
171		"archive_read_disk_entry_from_file");
172
173	archive_clear_error(_a);
174	path = archive_entry_sourcepath(entry);
175	if (path == NULL)
176		path = archive_entry_pathname(entry);
177
178	if (a->tree == NULL) {
179		if (st == NULL) {
180#if HAVE_FSTAT
181			if (fd >= 0) {
182				if (fstat(fd, &s) != 0) {
183					archive_set_error(&a->archive, errno,
184					    "Can't fstat");
185					return (ARCHIVE_FAILED);
186				}
187			} else
188#endif
189#if HAVE_LSTAT
190			if (!a->follow_symlinks) {
191				if (lstat(path, &s) != 0) {
192					archive_set_error(&a->archive, errno,
193					    "Can't lstat %s", path);
194					return (ARCHIVE_FAILED);
195				}
196			} else
197#endif
198			if (la_stat(path, &s) != 0) {
199				archive_set_error(&a->archive, errno,
200				    "Can't stat %s", path);
201				return (ARCHIVE_FAILED);
202			}
203			st = &s;
204		}
205		archive_entry_copy_stat(entry, st);
206	}
207
208	/* Lookup uname/gname */
209	name = archive_read_disk_uname(_a, archive_entry_uid(entry));
210	if (name != NULL)
211		archive_entry_copy_uname(entry, name);
212	name = archive_read_disk_gname(_a, archive_entry_gid(entry));
213	if (name != NULL)
214		archive_entry_copy_gname(entry, name);
215
216#ifdef HAVE_STRUCT_STAT_ST_FLAGS
217	/* On FreeBSD, we get flags for free with the stat. */
218	/* TODO: Does this belong in copy_stat()? */
219	if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 && st->st_flags != 0)
220		archive_entry_set_fflags(entry, st->st_flags, 0);
221#endif
222
223#if (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
224    (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
225	/* Linux requires an extra ioctl to pull the flags.  Although
226	 * this is an extra step, it has a nice side-effect: We get an
227	 * open file descriptor which we can use in the subsequent lookups. */
228	if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 &&
229	    (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
230		if (fd < 0) {
231			if (a->tree != NULL)
232				fd = a->open_on_current_dir(a->tree, path,
233					O_RDONLY | O_NONBLOCK | O_CLOEXEC);
234			else
235				fd = open(path, O_RDONLY | O_NONBLOCK |
236						O_CLOEXEC);
237			__archive_ensure_cloexec_flag(fd);
238		}
239		if (fd >= 0) {
240			int stflags;
241			r = ioctl(fd,
242#if defined(FS_IOC_GETFLAGS)
243			    FS_IOC_GETFLAGS,
244#else
245			    EXT2_IOC_GETFLAGS,
246#endif
247			    &stflags);
248			if (r == 0 && stflags != 0)
249				archive_entry_set_fflags(entry, stflags, 0);
250		}
251	}
252#endif
253
254#if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
255	if (S_ISLNK(st->st_mode)) {
256		size_t linkbuffer_len = st->st_size;
257		char *linkbuffer;
258		int lnklen;
259
260		linkbuffer = malloc(linkbuffer_len + 1);
261		if (linkbuffer == NULL) {
262			archive_set_error(&a->archive, ENOMEM,
263			    "Couldn't read link data");
264			return (ARCHIVE_FAILED);
265		}
266		if (a->tree != NULL) {
267#ifdef HAVE_READLINKAT
268			lnklen = readlinkat(a->tree_current_dir_fd(a->tree),
269			    path, linkbuffer, linkbuffer_len);
270#else
271			if (a->tree_enter_working_dir(a->tree) != 0) {
272				archive_set_error(&a->archive, errno,
273				    "Couldn't read link data");
274				free(linkbuffer);
275				return (ARCHIVE_FAILED);
276			}
277			lnklen = readlink(path, linkbuffer, linkbuffer_len);
278#endif /* HAVE_READLINKAT */
279		} else
280			lnklen = readlink(path, linkbuffer, linkbuffer_len);
281		if (lnklen < 0) {
282			archive_set_error(&a->archive, errno,
283			    "Couldn't read link data");
284			free(linkbuffer);
285			return (ARCHIVE_FAILED);
286		}
287		linkbuffer[lnklen] = '\0';
288		archive_entry_set_symlink(entry, linkbuffer);
289		free(linkbuffer);
290	}
291#endif /* HAVE_READLINK || HAVE_READLINKAT */
292
293	r = 0;
294	if ((a->flags & ARCHIVE_READDISK_NO_ACL) == 0)
295		r = archive_read_disk_entry_setup_acls(a, entry, &fd);
296	if ((a->flags & ARCHIVE_READDISK_NO_XATTR) == 0) {
297		r1 = setup_xattrs(a, entry, &fd);
298		if (r1 < r)
299			r = r1;
300	}
301	if (a->flags & ARCHIVE_READDISK_MAC_COPYFILE) {
302		r1 = setup_mac_metadata(a, entry, &fd);
303		if (r1 < r)
304			r = r1;
305	}
306	r1 = setup_sparse(a, entry, &fd);
307	if (r1 < r)
308		r = r1;
309
310	/* If we opened the file earlier in this function, close it. */
311	if (initial_fd != fd)
312		close(fd);
313	return (r);
314}
315
316#if defined(__APPLE__) && defined(HAVE_COPYFILE_H)
317/*
318 * The Mac OS "copyfile()" API copies the extended metadata for a
319 * file into a separate file in AppleDouble format (see RFC 1740).
320 *
321 * Mac OS tar and cpio implementations store this extended
322 * metadata as a separate entry just before the regular entry
323 * with a "._" prefix added to the filename.
324 *
325 * Note that this is currently done unconditionally; the tar program has
326 * an option to discard this information before the archive is written.
327 *
328 * TODO: If there's a failure, report it and return ARCHIVE_WARN.
329 */
330static int
331setup_mac_metadata(struct archive_read_disk *a,
332    struct archive_entry *entry, int *fd)
333{
334	int tempfd = -1;
335	int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR;
336	struct stat copyfile_stat;
337	int ret = ARCHIVE_OK;
338	void *buff = NULL;
339	int have_attrs;
340	const char *name, *tempdir;
341	struct archive_string tempfile;
342
343	(void)fd; /* UNUSED */
344
345	name = archive_read_disk_entry_setup_path(a, entry, NULL);
346	if (name == NULL)
347		return (ARCHIVE_WARN);
348
349	/* Short-circuit if there's nothing to do. */
350	have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
351	if (have_attrs == -1) {
352		archive_set_error(&a->archive, errno,
353			"Could not check extended attributes");
354		return (ARCHIVE_WARN);
355	}
356	if (have_attrs == 0)
357		return (ARCHIVE_OK);
358
359	tempdir = NULL;
360	if (issetugid() == 0)
361		tempdir = getenv("TMPDIR");
362	if (tempdir == NULL)
363		tempdir = _PATH_TMP;
364	archive_string_init(&tempfile);
365	archive_strcpy(&tempfile, tempdir);
366	archive_strcat(&tempfile, "tar.md.XXXXXX");
367	tempfd = mkstemp(tempfile.s);
368	if (tempfd < 0) {
369		archive_set_error(&a->archive, errno,
370		    "Could not open extended attribute file");
371		ret = ARCHIVE_WARN;
372		goto cleanup;
373	}
374	__archive_ensure_cloexec_flag(tempfd);
375
376	/* XXX I wish copyfile() could pack directly to a memory
377	 * buffer; that would avoid the temp file here.  For that
378	 * matter, it would be nice if fcopyfile() actually worked,
379	 * that would reduce the many open/close races here. */
380	if (copyfile(name, tempfile.s, 0, copyfile_flags | COPYFILE_PACK)) {
381		archive_set_error(&a->archive, errno,
382		    "Could not pack extended attributes");
383		ret = ARCHIVE_WARN;
384		goto cleanup;
385	}
386	if (fstat(tempfd, &copyfile_stat)) {
387		archive_set_error(&a->archive, errno,
388		    "Could not check size of extended attributes");
389		ret = ARCHIVE_WARN;
390		goto cleanup;
391	}
392	buff = malloc(copyfile_stat.st_size);
393	if (buff == NULL) {
394		archive_set_error(&a->archive, errno,
395		    "Could not allocate memory for extended attributes");
396		ret = ARCHIVE_WARN;
397		goto cleanup;
398	}
399	if (copyfile_stat.st_size != read(tempfd, buff, copyfile_stat.st_size)) {
400		archive_set_error(&a->archive, errno,
401		    "Could not read extended attributes into memory");
402		ret = ARCHIVE_WARN;
403		goto cleanup;
404	}
405	archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size);
406
407cleanup:
408	if (tempfd >= 0) {
409		close(tempfd);
410		unlink(tempfile.s);
411	}
412	archive_string_free(&tempfile);
413	free(buff);
414	return (ret);
415}
416
417#else
418
419/*
420 * Stub implementation for non-Mac systems.
421 */
422static int
423setup_mac_metadata(struct archive_read_disk *a,
424    struct archive_entry *entry, int *fd)
425{
426	(void)a; /* UNUSED */
427	(void)entry; /* UNUSED */
428	(void)fd; /* UNUSED */
429	return (ARCHIVE_OK);
430}
431#endif
432
433#if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_AIX
434
435/*
436 * Linux, Darwin and AIX extended attribute support.
437 *
438 * TODO:  By using a stack-allocated buffer for the first
439 * call to getxattr(), we might be able to avoid the second
440 * call entirely.  We only need the second call if the
441 * stack-allocated buffer is too small.  But a modest buffer
442 * of 1024 bytes or so will often be big enough.  Same applies
443 * to listxattr().
444 */
445
446
447static int
448setup_xattr(struct archive_read_disk *a,
449    struct archive_entry *entry, const char *name, int fd, const char *accpath)
450{
451	ssize_t size;
452	void *value = NULL;
453
454
455	if (fd >= 0) {
456#if ARCHIVE_XATTR_LINUX
457		size = fgetxattr(fd, name, NULL, 0);
458#elif ARCHIVE_XATTR_DARWIN
459		size = fgetxattr(fd, name, NULL, 0, 0, 0);
460#elif ARCHIVE_XATTR_AIX
461		size = fgetea(fd, name, NULL, 0);
462#endif
463	} else if (!a->follow_symlinks) {
464#if ARCHIVE_XATTR_LINUX
465		size = lgetxattr(accpath, name, NULL, 0);
466#elif ARCHIVE_XATTR_DARWIN
467		size = getxattr(accpath, name, NULL, 0, 0, XATTR_NOFOLLOW);
468#elif ARCHIVE_XATTR_AIX
469		size = lgetea(accpath, name, NULL, 0);
470#endif
471	} else {
472#if ARCHIVE_XATTR_LINUX
473		size = getxattr(accpath, name, NULL, 0);
474#elif ARCHIVE_XATTR_DARWIN
475		size = getxattr(accpath, name, NULL, 0, 0, 0);
476#elif ARCHIVE_XATTR_AIX
477		size = getea(accpath, name, NULL, 0);
478#endif
479	}
480
481	if (size == -1) {
482		archive_set_error(&a->archive, errno,
483		    "Couldn't query extended attribute");
484		return (ARCHIVE_WARN);
485	}
486
487	if (size > 0 && (value = malloc(size)) == NULL) {
488		archive_set_error(&a->archive, errno, "Out of memory");
489		return (ARCHIVE_FATAL);
490	}
491
492
493	if (fd >= 0) {
494#if ARCHIVE_XATTR_LINUX
495		size = fgetxattr(fd, name, value, size);
496#elif ARCHIVE_XATTR_DARWIN
497		size = fgetxattr(fd, name, value, size, 0, 0);
498#elif ARCHIVE_XATTR_AIX
499		size = fgetea(fd, name, value, size);
500#endif
501	} else if (!a->follow_symlinks) {
502#if ARCHIVE_XATTR_LINUX
503		size = lgetxattr(accpath, name, value, size);
504#elif ARCHIVE_XATTR_DARWIN
505		size = getxattr(accpath, name, value, size, 0, XATTR_NOFOLLOW);
506#elif ARCHIVE_XATTR_AIX
507		size = lgetea(accpath, name, value, size);
508#endif
509	} else {
510#if ARCHIVE_XATTR_LINUX
511		size = getxattr(accpath, name, value, size);
512#elif ARCHIVE_XATTR_DARWIN
513		size = getxattr(accpath, name, value, size, 0, 0);
514#elif ARCHIVE_XATTR_AIX
515		size = getea(accpath, name, value, size);
516#endif
517	}
518
519	if (size == -1) {
520		archive_set_error(&a->archive, errno,
521		    "Couldn't read extended attribute");
522		return (ARCHIVE_WARN);
523	}
524
525	archive_entry_xattr_add_entry(entry, name, value, size);
526
527	free(value);
528	return (ARCHIVE_OK);
529}
530
531static int
532setup_xattrs(struct archive_read_disk *a,
533    struct archive_entry *entry, int *fd)
534{
535	char *list, *p;
536	const char *path;
537	ssize_t list_size;
538
539	path = NULL;
540
541	if (*fd < 0) {
542		path = archive_read_disk_entry_setup_path(a, entry, fd);
543		if (path == NULL)
544			return (ARCHIVE_WARN);
545	}
546
547	if (*fd >= 0) {
548#if ARCHIVE_XATTR_LINUX
549		list_size = flistxattr(*fd, NULL, 0);
550#elif ARCHIVE_XATTR_DARWIN
551		list_size = flistxattr(*fd, NULL, 0, 0);
552#elif ARCHIVE_XATTR_AIX
553		list_size = flistea(*fd, NULL, 0);
554#endif
555	} else if (!a->follow_symlinks) {
556#if ARCHIVE_XATTR_LINUX
557		list_size = llistxattr(path, NULL, 0);
558#elif ARCHIVE_XATTR_DARWIN
559		list_size = listxattr(path, NULL, 0, XATTR_NOFOLLOW);
560#elif ARCHIVE_XATTR_AIX
561		list_size = llistea(path, NULL, 0);
562#endif
563	} else {
564#if ARCHIVE_XATTR_LINUX
565		list_size = listxattr(path, NULL, 0);
566#elif ARCHIVE_XATTR_DARWIN
567		list_size = listxattr(path, NULL, 0, 0);
568#elif ARCHIVE_XATTR_AIX
569		list_size = listea(path, NULL, 0);
570#endif
571	}
572
573	if (list_size == -1) {
574		if (errno == ENOTSUP || errno == ENOSYS)
575			return (ARCHIVE_OK);
576		archive_set_error(&a->archive, errno,
577			"Couldn't list extended attributes");
578		return (ARCHIVE_WARN);
579	}
580
581	if (list_size == 0)
582		return (ARCHIVE_OK);
583
584	if ((list = malloc(list_size)) == NULL) {
585		archive_set_error(&a->archive, errno, "Out of memory");
586		return (ARCHIVE_FATAL);
587	}
588
589	if (*fd >= 0) {
590#if ARCHIVE_XATTR_LINUX
591		list_size = flistxattr(*fd, list, list_size);
592#elif ARCHIVE_XATTR_DARWIN
593		list_size = flistxattr(*fd, list, list_size, 0);
594#elif ARCHIVE_XATTR_AIX
595		list_size = flistea(*fd, list, list_size);
596#endif
597	} else if (!a->follow_symlinks) {
598#if ARCHIVE_XATTR_LINUX
599		list_size = llistxattr(path, list, list_size);
600#elif ARCHIVE_XATTR_DARWIN
601		list_size = listxattr(path, list, list_size, XATTR_NOFOLLOW);
602#elif ARCHIVE_XATTR_AIX
603		list_size = llistea(path, list, list_size);
604#endif
605	} else {
606#if ARCHIVE_XATTR_LINUX
607		list_size = listxattr(path, list, list_size);
608#elif ARCHIVE_XATTR_DARWIN
609		list_size = listxattr(path, list, list_size, 0);
610#elif ARCHIVE_XATTR_AIX
611		list_size = listea(path, list, list_size);
612#endif
613	}
614
615	if (list_size == -1) {
616		archive_set_error(&a->archive, errno,
617			"Couldn't retrieve extended attributes");
618		free(list);
619		return (ARCHIVE_WARN);
620	}
621
622	for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
623#if ARCHIVE_XATTR_LINUX
624		/* Linux: skip POSIX.1e ACL extended attributes */
625		if (strncmp(p, "system.", 7) == 0 &&
626		   (strcmp(p + 7, "posix_acl_access") == 0 ||
627		    strcmp(p + 7, "posix_acl_default") == 0))
628			continue;
629		if (strncmp(p, "trusted.SGI_", 12) == 0 &&
630		   (strcmp(p + 12, "ACL_DEFAULT") == 0 ||
631		    strcmp(p + 12, "ACL_FILE") == 0))
632			continue;
633
634		/* Linux: xfsroot namespace is obsolete and unsupported */
635		if (strncmp(p, "xfsroot.", 8) == 0)
636			continue;
637#endif
638		setup_xattr(a, entry, p, *fd, path);
639	}
640
641	free(list);
642	return (ARCHIVE_OK);
643}
644
645#elif ARCHIVE_XATTR_FREEBSD
646
647/*
648 * FreeBSD extattr interface.
649 */
650
651/* TODO: Implement this.  Follow the Linux model above, but
652 * with FreeBSD-specific system calls, of course.  Be careful
653 * to not include the system extattrs that hold ACLs; we handle
654 * those separately.
655 */
656static int
657setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
658    int namespace, const char *name, const char *fullname, int fd,
659    const char *path);
660
661static int
662setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
663    int namespace, const char *name, const char *fullname, int fd,
664    const char *accpath)
665{
666	ssize_t size;
667	void *value = NULL;
668
669	if (fd >= 0)
670		size = extattr_get_fd(fd, namespace, name, NULL, 0);
671	else if (!a->follow_symlinks)
672		size = extattr_get_link(accpath, namespace, name, NULL, 0);
673	else
674		size = extattr_get_file(accpath, namespace, name, NULL, 0);
675
676	if (size == -1) {
677		archive_set_error(&a->archive, errno,
678		    "Couldn't query extended attribute");
679		return (ARCHIVE_WARN);
680	}
681
682	if (size > 0 && (value = malloc(size)) == NULL) {
683		archive_set_error(&a->archive, errno, "Out of memory");
684		return (ARCHIVE_FATAL);
685	}
686
687	if (fd >= 0)
688		size = extattr_get_fd(fd, namespace, name, value, size);
689	else if (!a->follow_symlinks)
690		size = extattr_get_link(accpath, namespace, name, value, size);
691	else
692		size = extattr_get_file(accpath, namespace, name, value, size);
693
694	if (size == -1) {
695		free(value);
696		archive_set_error(&a->archive, errno,
697		    "Couldn't read extended attribute");
698		return (ARCHIVE_WARN);
699	}
700
701	archive_entry_xattr_add_entry(entry, fullname, value, size);
702
703	free(value);
704	return (ARCHIVE_OK);
705}
706
707static int
708setup_xattrs_namespace(struct archive_read_disk *a,
709    struct archive_entry *entry, int *fd, int namespace)
710{
711	char buff[512];
712	char *list, *p;
713	ssize_t list_size;
714	const char *path;
715
716	path = NULL;
717
718	if (*fd < 0) {
719		path = archive_read_disk_entry_setup_path(a, entry, fd);
720		if (path == NULL)
721			return (ARCHIVE_WARN);
722	}
723
724	if (*fd >= 0)
725		list_size = extattr_list_fd(*fd, namespace, NULL, 0);
726	else if (!a->follow_symlinks)
727		list_size = extattr_list_link(path, namespace, NULL, 0);
728	else
729		list_size = extattr_list_file(path, namespace, NULL, 0);
730
731	if (list_size == -1 && errno == EOPNOTSUPP)
732		return (ARCHIVE_OK);
733	if (list_size == -1 && errno == EPERM)
734		return (ARCHIVE_OK);
735	if (list_size == -1) {
736		archive_set_error(&a->archive, errno,
737			"Couldn't list extended attributes");
738		return (ARCHIVE_WARN);
739	}
740
741	if (list_size == 0)
742		return (ARCHIVE_OK);
743
744	if ((list = malloc(list_size)) == NULL) {
745		archive_set_error(&a->archive, errno, "Out of memory");
746		return (ARCHIVE_FATAL);
747	}
748
749	if (*fd >= 0)
750		list_size = extattr_list_fd(*fd, namespace, list, list_size);
751	else if (!a->follow_symlinks)
752		list_size = extattr_list_link(path, namespace, list, list_size);
753	else
754		list_size = extattr_list_file(path, namespace, list, list_size);
755
756	if (list_size == -1) {
757		archive_set_error(&a->archive, errno,
758			"Couldn't retrieve extended attributes");
759		free(list);
760		return (ARCHIVE_WARN);
761	}
762
763	p = list;
764	while ((p - list) < list_size) {
765		size_t len = 255 & (int)*p;
766		char *name;
767
768		if (namespace == EXTATTR_NAMESPACE_SYSTEM) {
769			if (!strcmp(p + 1, "nfs4.acl") ||
770			    !strcmp(p + 1, "posix1e.acl_access") ||
771			    !strcmp(p + 1, "posix1e.acl_default")) {
772				p += 1 + len;
773				continue;
774			}
775			strcpy(buff, "system.");
776		} else {
777			strcpy(buff, "user.");
778		}
779		name = buff + strlen(buff);
780		memcpy(name, p + 1, len);
781		name[len] = '\0';
782		setup_xattr(a, entry, namespace, name, buff, *fd, path);
783		p += 1 + len;
784	}
785
786	free(list);
787	return (ARCHIVE_OK);
788}
789
790static int
791setup_xattrs(struct archive_read_disk *a,
792    struct archive_entry *entry, int *fd)
793{
794	int namespaces[2];
795	int i, res;
796
797	namespaces[0] = EXTATTR_NAMESPACE_USER;
798	namespaces[1] = EXTATTR_NAMESPACE_SYSTEM;
799
800	for (i = 0; i < 2; i++) {
801		res = setup_xattrs_namespace(a, entry, fd,
802		    namespaces[i]);
803		switch (res) {
804			case (ARCHIVE_OK):
805			case (ARCHIVE_WARN):
806				break;
807			default:
808				return (res);
809		}
810	}
811
812	return (ARCHIVE_OK);
813}
814
815#else
816
817/*
818 * Generic (stub) extended attribute support.
819 */
820static int
821setup_xattrs(struct archive_read_disk *a,
822    struct archive_entry *entry, int *fd)
823{
824	(void)a;     /* UNUSED */
825	(void)entry; /* UNUSED */
826	(void)fd;    /* UNUSED */
827	return (ARCHIVE_OK);
828}
829
830#endif
831
832#if defined(HAVE_LINUX_FIEMAP_H)
833
834/*
835 * Linux FIEMAP sparse interface.
836 *
837 * The FIEMAP ioctl returns an "extent" for each physical allocation
838 * on disk.  We need to process those to generate a more compact list
839 * of logical file blocks.  We also need to be very careful to use
840 * FIEMAP_FLAG_SYNC here, since there are reports that Linux sometimes
841 * does not report allocations for newly-written data that hasn't
842 * been synced to disk.
843 *
844 * It's important to return a minimal sparse file list because we want
845 * to not trigger sparse file extensions if we don't have to, since
846 * not all readers support them.
847 */
848
849static int
850setup_sparse_fiemap(struct archive_read_disk *a,
851    struct archive_entry *entry, int *fd)
852{
853	char buff[4096];
854	struct fiemap *fm;
855	struct fiemap_extent *fe;
856	int64_t size;
857	int count, do_fiemap, iters;
858	int exit_sts = ARCHIVE_OK;
859	const char *path;
860
861	if (archive_entry_filetype(entry) != AE_IFREG
862	    || archive_entry_size(entry) <= 0
863	    || archive_entry_hardlink(entry) != NULL)
864		return (ARCHIVE_OK);
865
866	if (*fd < 0) {
867		path = archive_read_disk_entry_setup_path(a, entry, NULL);
868		if (path == NULL)
869			return (ARCHIVE_FAILED);
870
871		if (a->tree != NULL)
872			*fd = a->open_on_current_dir(a->tree, path,
873				O_RDONLY | O_NONBLOCK | O_CLOEXEC);
874		else
875			*fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
876		if (*fd < 0) {
877			archive_set_error(&a->archive, errno,
878			    "Can't open `%s'", path);
879			return (ARCHIVE_FAILED);
880		}
881		__archive_ensure_cloexec_flag(*fd);
882	}
883
884	/* Initialize buffer to avoid the error valgrind complains about. */
885	memset(buff, 0, sizeof(buff));
886	count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe);
887	fm = (struct fiemap *)buff;
888	fm->fm_start = 0;
889	fm->fm_length = ~0ULL;;
890	fm->fm_flags = FIEMAP_FLAG_SYNC;
891	fm->fm_extent_count = count;
892	do_fiemap = 1;
893	size = archive_entry_size(entry);
894	for (iters = 0; ; ++iters) {
895		int i, r;
896
897		r = ioctl(*fd, FS_IOC_FIEMAP, fm);
898		if (r < 0) {
899			/* When something error happens, it is better we
900			 * should return ARCHIVE_OK because an earlier
901			 * version(<2.6.28) cannot perform FS_IOC_FIEMAP. */
902			goto exit_setup_sparse_fiemap;
903		}
904		if (fm->fm_mapped_extents == 0) {
905			if (iters == 0) {
906				/* Fully sparse file; insert a zero-length "data" entry */
907				archive_entry_sparse_add_entry(entry, 0, 0);
908			}
909			break;
910		}
911		fe = fm->fm_extents;
912		for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) {
913			if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
914				/* The fe_length of the last block does not
915				 * adjust itself to its size files. */
916				int64_t length = fe->fe_length;
917				if (fe->fe_logical + length > (uint64_t)size)
918					length -= fe->fe_logical + length - size;
919				if (fe->fe_logical == 0 && length == size) {
920					/* This is not sparse. */
921					do_fiemap = 0;
922					break;
923				}
924				if (length > 0)
925					archive_entry_sparse_add_entry(entry,
926					    fe->fe_logical, length);
927			}
928			if (fe->fe_flags & FIEMAP_EXTENT_LAST)
929				do_fiemap = 0;
930		}
931		if (do_fiemap) {
932			fe = fm->fm_extents + fm->fm_mapped_extents -1;
933			fm->fm_start = fe->fe_logical + fe->fe_length;
934		} else
935			break;
936	}
937exit_setup_sparse_fiemap:
938	return (exit_sts);
939}
940
941#if !defined(SEEK_HOLE) || !defined(SEEK_DATA)
942static int
943setup_sparse(struct archive_read_disk *a,
944    struct archive_entry *entry, int *fd)
945{
946	return setup_sparse_fiemap(a, entry, fd);
947}
948#endif
949#endif	/* defined(HAVE_LINUX_FIEMAP_H) */
950
951#if defined(SEEK_HOLE) && defined(SEEK_DATA)
952
953/*
954 * SEEK_HOLE sparse interface (FreeBSD, Linux, Solaris)
955 */
956
957static int
958setup_sparse(struct archive_read_disk *a,
959    struct archive_entry *entry, int *fd)
960{
961	int64_t size;
962	off_t initial_off;
963	off_t off_s, off_e;
964	int exit_sts = ARCHIVE_OK;
965	int check_fully_sparse = 0;
966	const char *path;
967
968	if (archive_entry_filetype(entry) != AE_IFREG
969	    || archive_entry_size(entry) <= 0
970	    || archive_entry_hardlink(entry) != NULL)
971		return (ARCHIVE_OK);
972
973	/* Does filesystem support the reporting of hole ? */
974	if (*fd < 0)
975		path = archive_read_disk_entry_setup_path(a, entry, fd);
976	else
977		path = NULL;
978
979	if (*fd >= 0) {
980#ifdef _PC_MIN_HOLE_SIZE
981		if (fpathconf(*fd, _PC_MIN_HOLE_SIZE) <= 0)
982			return (ARCHIVE_OK);
983#endif
984		initial_off = lseek(*fd, 0, SEEK_CUR);
985		if (initial_off != 0)
986			lseek(*fd, 0, SEEK_SET);
987	} else {
988		if (path == NULL)
989			return (ARCHIVE_FAILED);
990#ifdef _PC_MIN_HOLE_SIZE
991		if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
992			return (ARCHIVE_OK);
993#endif
994		*fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
995		if (*fd < 0) {
996			archive_set_error(&a->archive, errno,
997			    "Can't open `%s'", path);
998			return (ARCHIVE_FAILED);
999		}
1000		__archive_ensure_cloexec_flag(*fd);
1001		initial_off = 0;
1002	}
1003
1004#ifndef _PC_MIN_HOLE_SIZE
1005	/* Check if the underlying filesystem supports seek hole */
1006	off_s = lseek(*fd, 0, SEEK_HOLE);
1007	if (off_s < 0)
1008#if defined(HAVE_LINUX_FIEMAP_H)
1009		return setup_sparse_fiemap(a, entry, fd);
1010#else
1011		goto exit_setup_sparse;
1012#endif
1013	else if (off_s > 0)
1014		lseek(*fd, 0, SEEK_SET);
1015#endif
1016
1017	off_s = 0;
1018	size = archive_entry_size(entry);
1019	while (off_s < size) {
1020		off_s = lseek(*fd, off_s, SEEK_DATA);
1021		if (off_s == (off_t)-1) {
1022			if (errno == ENXIO) {
1023				/* no more hole */
1024				if (archive_entry_sparse_count(entry) == 0) {
1025					/* Potentially a fully-sparse file. */
1026					check_fully_sparse = 1;
1027				}
1028				break;
1029			}
1030			archive_set_error(&a->archive, errno,
1031			    "lseek(SEEK_HOLE) failed");
1032			exit_sts = ARCHIVE_FAILED;
1033			goto exit_setup_sparse;
1034		}
1035		off_e = lseek(*fd, off_s, SEEK_HOLE);
1036		if (off_e == (off_t)-1) {
1037			if (errno == ENXIO) {
1038				off_e = lseek(*fd, 0, SEEK_END);
1039				if (off_e != (off_t)-1)
1040					break;/* no more data */
1041			}
1042			archive_set_error(&a->archive, errno,
1043			    "lseek(SEEK_DATA) failed");
1044			exit_sts = ARCHIVE_FAILED;
1045			goto exit_setup_sparse;
1046		}
1047		if (off_s == 0 && off_e == size)
1048			break;/* This is not sparse. */
1049		archive_entry_sparse_add_entry(entry, off_s,
1050			off_e - off_s);
1051		off_s = off_e;
1052	}
1053
1054	if (check_fully_sparse) {
1055		if (lseek(*fd, 0, SEEK_HOLE) == 0 &&
1056			lseek(*fd, 0, SEEK_END) == size) {
1057			/* Fully sparse file; insert a zero-length "data" entry */
1058			archive_entry_sparse_add_entry(entry, 0, 0);
1059		}
1060	}
1061exit_setup_sparse:
1062	lseek(*fd, initial_off, SEEK_SET);
1063	return (exit_sts);
1064}
1065
1066#elif !defined(HAVE_LINUX_FIEMAP_H)
1067
1068/*
1069 * Generic (stub) sparse support.
1070 */
1071static int
1072setup_sparse(struct archive_read_disk *a,
1073    struct archive_entry *entry, int *fd)
1074{
1075	(void)a;     /* UNUSED */
1076	(void)entry; /* UNUSED */
1077	(void)fd;    /* UNUSED */
1078	return (ARCHIVE_OK);
1079}
1080
1081#endif
1082
1083#endif /* !defined(_WIN32) || defined(__CYGWIN__) */
1084
1085