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