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