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