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$");
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#if defined(HAVE_SYS_XATTR_H)
53#include <sys/xattr.h>
54#elif defined(HAVE_ATTR_XATTR_H)
55#include <attr/xattr.h>
56#endif
57#ifdef HAVE_SYS_EA_H
58#include <sys/ea.h>
59#endif
60#ifdef HAVE_ACL_LIBACL_H
61#include <acl/libacl.h>
62#endif
63#ifdef HAVE_COPYFILE_H
64#include <copyfile.h>
65#endif
66#ifdef HAVE_ERRNO_H
67#include <errno.h>
68#endif
69#ifdef HAVE_FCNTL_H
70#include <fcntl.h>
71#endif
72#ifdef HAVE_LIMITS_H
73#include <limits.h>
74#endif
75#ifdef HAVE_LINUX_TYPES_H
76#include <linux/types.h>
77#endif
78#ifdef HAVE_LINUX_FIEMAP_H
79#include <linux/fiemap.h>
80#endif
81#ifdef HAVE_LINUX_FS_H
82#include <linux/fs.h>
83#endif
84/*
85 * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
86 * As the include guards don't agree, the order of include is important.
87 */
88#ifdef HAVE_LINUX_EXT2_FS_H
89#include <linux/ext2_fs.h>      /* for Linux file flags */
90#endif
91#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
92#include <ext2fs/ext2_fs.h>     /* Linux file flags, broken on Cygwin */
93#endif
94#ifdef HAVE_PATHS_H
95#include <paths.h>
96#endif
97#ifdef HAVE_UNISTD_H
98#include <unistd.h>
99#endif
100
101#include "archive.h"
102#include "archive_entry.h"
103#include "archive_private.h"
104#include "archive_read_disk_private.h"
105
106#ifndef O_CLOEXEC
107#define O_CLOEXEC	0
108#endif
109
110/*
111 * Linux and FreeBSD plug this obvious hole in POSIX.1e in
112 * different ways.
113 */
114#if HAVE_ACL_GET_PERM
115#define	ACL_GET_PERM acl_get_perm
116#elif HAVE_ACL_GET_PERM_NP
117#define	ACL_GET_PERM acl_get_perm_np
118#endif
119
120static int setup_acls(struct archive_read_disk *,
121    struct archive_entry *, int *fd);
122static int setup_mac_metadata(struct archive_read_disk *,
123    struct archive_entry *, int *fd);
124static int setup_xattrs(struct archive_read_disk *,
125    struct archive_entry *, int *fd);
126static int setup_sparse(struct archive_read_disk *,
127    struct archive_entry *, int *fd);
128
129int
130archive_read_disk_entry_from_file(struct archive *_a,
131    struct archive_entry *entry,
132    int fd,
133    const struct stat *st)
134{
135	struct archive_read_disk *a = (struct archive_read_disk *)_a;
136	const char *path, *name;
137	struct stat s;
138	int initial_fd = fd;
139	int r, r1;
140
141	archive_clear_error(_a);
142	path = archive_entry_sourcepath(entry);
143	if (path == NULL)
144		path = archive_entry_pathname(entry);
145
146	if (a->tree == NULL) {
147		if (st == NULL) {
148#if HAVE_FSTAT
149			if (fd >= 0) {
150				if (fstat(fd, &s) != 0) {
151					archive_set_error(&a->archive, errno,
152					    "Can't fstat");
153					return (ARCHIVE_FAILED);
154				}
155			} else
156#endif
157#if HAVE_LSTAT
158			if (!a->follow_symlinks) {
159				if (lstat(path, &s) != 0) {
160					archive_set_error(&a->archive, errno,
161					    "Can't lstat %s", path);
162					return (ARCHIVE_FAILED);
163				}
164			} else
165#endif
166			if (stat(path, &s) != 0) {
167				archive_set_error(&a->archive, errno,
168				    "Can't stat %s", path);
169				return (ARCHIVE_FAILED);
170			}
171			st = &s;
172		}
173		archive_entry_copy_stat(entry, st);
174	}
175
176	/* Lookup uname/gname */
177	name = archive_read_disk_uname(_a, archive_entry_uid(entry));
178	if (name != NULL)
179		archive_entry_copy_uname(entry, name);
180	name = archive_read_disk_gname(_a, archive_entry_gid(entry));
181	if (name != NULL)
182		archive_entry_copy_gname(entry, name);
183
184#ifdef HAVE_STRUCT_STAT_ST_FLAGS
185	/* On FreeBSD, we get flags for free with the stat. */
186	/* TODO: Does this belong in copy_stat()? */
187	if (st->st_flags != 0)
188		archive_entry_set_fflags(entry, st->st_flags, 0);
189#endif
190
191#if defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
192	/* Linux requires an extra ioctl to pull the flags.  Although
193	 * this is an extra step, it has a nice side-effect: We get an
194	 * open file descriptor which we can use in the subsequent lookups. */
195	if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
196		if (fd < 0) {
197			if (a->tree != NULL)
198				fd = a->open_on_current_dir(a->tree, path,
199					O_RDONLY | O_NONBLOCK | O_CLOEXEC);
200			else
201				fd = open(path, O_RDONLY | O_NONBLOCK |
202						O_CLOEXEC);
203			__archive_ensure_cloexec_flag(fd);
204		}
205		if (fd >= 0) {
206			int stflags;
207			r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
208			if (r == 0 && stflags != 0)
209				archive_entry_set_fflags(entry, stflags, 0);
210		}
211	}
212#endif
213
214#if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
215	if (S_ISLNK(st->st_mode)) {
216		size_t linkbuffer_len = st->st_size + 1;
217		char *linkbuffer;
218		int lnklen;
219
220		linkbuffer = malloc(linkbuffer_len);
221		if (linkbuffer == NULL) {
222			archive_set_error(&a->archive, ENOMEM,
223			    "Couldn't read link data");
224			return (ARCHIVE_FAILED);
225		}
226		if (a->tree != NULL) {
227#ifdef HAVE_READLINKAT
228			lnklen = readlinkat(a->tree_current_dir_fd(a->tree),
229			    path, linkbuffer, linkbuffer_len);
230#else
231			if (a->tree_enter_working_dir(a->tree) != 0) {
232				archive_set_error(&a->archive, errno,
233				    "Couldn't read link data");
234				free(linkbuffer);
235				return (ARCHIVE_FAILED);
236			}
237			lnklen = readlink(path, linkbuffer, linkbuffer_len);
238#endif /* HAVE_READLINKAT */
239		} else
240			lnklen = readlink(path, linkbuffer, linkbuffer_len);
241		if (lnklen < 0) {
242			archive_set_error(&a->archive, errno,
243			    "Couldn't read link data");
244			free(linkbuffer);
245			return (ARCHIVE_FAILED);
246		}
247		linkbuffer[lnklen] = 0;
248		archive_entry_set_symlink(entry, linkbuffer);
249		free(linkbuffer);
250	}
251#endif /* HAVE_READLINK || HAVE_READLINKAT */
252
253	r = setup_acls(a, entry, &fd);
254	r1 = setup_xattrs(a, entry, &fd);
255	if (r1 < r)
256		r = r1;
257	if (a->enable_copyfile) {
258		r1 = setup_mac_metadata(a, entry, &fd);
259		if (r1 < r)
260			r = r1;
261	}
262	r1 = setup_sparse(a, entry, &fd);
263	if (r1 < r)
264		r = r1;
265
266	/* If we opened the file earlier in this function, close it. */
267	if (initial_fd != fd)
268		close(fd);
269	return (r);
270}
271
272#if defined(__APPLE__) && defined(HAVE_COPYFILE_H)
273/*
274 * The Mac OS "copyfile()" API copies the extended metadata for a
275 * file into a separate file in AppleDouble format (see RFC 1740).
276 *
277 * Mac OS tar and cpio implementations store this extended
278 * metadata as a separate entry just before the regular entry
279 * with a "._" prefix added to the filename.
280 *
281 * Note that this is currently done unconditionally; the tar program has
282 * an option to discard this information before the archive is written.
283 *
284 * TODO: If there's a failure, report it and return ARCHIVE_WARN.
285 */
286static int
287setup_mac_metadata(struct archive_read_disk *a,
288    struct archive_entry *entry, int *fd)
289{
290	int tempfd = -1;
291	int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR;
292	struct stat copyfile_stat;
293	int ret = ARCHIVE_OK;
294	void *buff = NULL;
295	int have_attrs;
296	const char *name, *tempdir;
297	struct archive_string tempfile;
298
299	(void)fd; /* UNUSED */
300	name = archive_entry_sourcepath(entry);
301	if (name == NULL)
302		name = archive_entry_pathname(entry);
303	if (name == NULL) {
304		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
305		    "Can't open file to read extended attributes: No name");
306		return (ARCHIVE_WARN);
307	}
308
309	if (a->tree != NULL) {
310		if (a->tree_enter_working_dir(a->tree) != 0) {
311			archive_set_error(&a->archive, errno,
312				    "Couldn't change dir");
313				return (ARCHIVE_FAILED);
314		}
315	}
316
317	/* Short-circuit if there's nothing to do. */
318	have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
319	if (have_attrs == -1) {
320		archive_set_error(&a->archive, errno,
321			"Could not check extended attributes");
322		return (ARCHIVE_WARN);
323	}
324	if (have_attrs == 0)
325		return (ARCHIVE_OK);
326
327	tempdir = NULL;
328	if (issetugid() == 0)
329		tempdir = getenv("TMPDIR");
330	if (tempdir == NULL)
331		tempdir = _PATH_TMP;
332	archive_string_init(&tempfile);
333	archive_strcpy(&tempfile, tempdir);
334	archive_strcat(&tempfile, "tar.md.XXXXXX");
335	tempfd = mkstemp(tempfile.s);
336	if (tempfd < 0) {
337		archive_set_error(&a->archive, errno,
338		    "Could not open extended attribute file");
339		ret = ARCHIVE_WARN;
340		goto cleanup;
341	}
342	__archive_ensure_cloexec_flag(tempfd);
343
344	/* XXX I wish copyfile() could pack directly to a memory
345	 * buffer; that would avoid the temp file here.  For that
346	 * matter, it would be nice if fcopyfile() actually worked,
347	 * that would reduce the many open/close races here. */
348	if (copyfile(name, tempfile.s, 0, copyfile_flags | COPYFILE_PACK)) {
349		archive_set_error(&a->archive, errno,
350		    "Could not pack extended attributes");
351		ret = ARCHIVE_WARN;
352		goto cleanup;
353	}
354	if (fstat(tempfd, &copyfile_stat)) {
355		archive_set_error(&a->archive, errno,
356		    "Could not check size of extended attributes");
357		ret = ARCHIVE_WARN;
358		goto cleanup;
359	}
360	buff = malloc(copyfile_stat.st_size);
361	if (buff == NULL) {
362		archive_set_error(&a->archive, errno,
363		    "Could not allocate memory for extended attributes");
364		ret = ARCHIVE_WARN;
365		goto cleanup;
366	}
367	if (copyfile_stat.st_size != read(tempfd, buff, copyfile_stat.st_size)) {
368		archive_set_error(&a->archive, errno,
369		    "Could not read extended attributes into memory");
370		ret = ARCHIVE_WARN;
371		goto cleanup;
372	}
373	archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size);
374
375cleanup:
376	if (tempfd >= 0) {
377		close(tempfd);
378		unlink(tempfile.s);
379	}
380	archive_string_free(&tempfile);
381	free(buff);
382	return (ret);
383}
384
385#else
386
387/*
388 * Stub implementation for non-Mac systems.
389 */
390static int
391setup_mac_metadata(struct archive_read_disk *a,
392    struct archive_entry *entry, int *fd)
393{
394	(void)a; /* UNUSED */
395	(void)entry; /* UNUSED */
396	(void)fd; /* UNUSED */
397	return (ARCHIVE_OK);
398}
399#endif
400
401
402#if defined(HAVE_POSIX_ACL) && defined(ACL_TYPE_NFS4)
403static int translate_acl(struct archive_read_disk *a,
404    struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
405
406static int
407setup_acls(struct archive_read_disk *a,
408    struct archive_entry *entry, int *fd)
409{
410	const char	*accpath;
411	acl_t		 acl;
412#if HAVE_ACL_IS_TRIVIAL_NP
413	int		r;
414#endif
415
416	accpath = archive_entry_sourcepath(entry);
417	if (accpath == NULL)
418		accpath = archive_entry_pathname(entry);
419
420	archive_entry_acl_clear(entry);
421
422	/* Try NFS4 ACL first. */
423	if (*fd >= 0)
424		acl = acl_get_fd(*fd);
425#if HAVE_ACL_GET_LINK_NP
426	else if (!a->follow_symlinks)
427		acl = acl_get_link_np(accpath, ACL_TYPE_NFS4);
428#else
429	else if ((!a->follow_symlinks)
430	    && (archive_entry_filetype(entry) == AE_IFLNK))
431		/* We can't get the ACL of a symlink, so we assume it can't
432		   have one. */
433		acl = NULL;
434#endif
435	else
436		acl = acl_get_file(accpath, ACL_TYPE_NFS4);
437#if HAVE_ACL_IS_TRIVIAL_NP
438	/* Ignore "trivial" ACLs that just mirror the file mode. */
439	acl_is_trivial_np(acl, &r);
440	if (r) {
441		acl_free(acl);
442		acl = NULL;
443	}
444#endif
445	if (acl != NULL) {
446		translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
447		acl_free(acl);
448		return (ARCHIVE_OK);
449	}
450
451	/* Retrieve access ACL from file. */
452	if (*fd >= 0)
453		acl = acl_get_fd(*fd);
454#if HAVE_ACL_GET_LINK_NP
455	else if (!a->follow_symlinks)
456		acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
457#else
458	else if ((!a->follow_symlinks)
459	    && (archive_entry_filetype(entry) == AE_IFLNK))
460		/* We can't get the ACL of a symlink, so we assume it can't
461		   have one. */
462		acl = NULL;
463#endif
464	else
465		acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
466	if (acl != NULL) {
467		translate_acl(a, entry, acl,
468		    ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
469		acl_free(acl);
470	}
471
472	/* Only directories can have default ACLs. */
473	if (S_ISDIR(archive_entry_mode(entry))) {
474		acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
475		if (acl != NULL) {
476			translate_acl(a, entry, acl,
477			    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
478			acl_free(acl);
479		}
480	}
481	return (ARCHIVE_OK);
482}
483
484/*
485 * Translate system ACL into libarchive internal structure.
486 */
487
488static struct {
489        int archive_perm;
490        int platform_perm;
491} acl_perm_map[] = {
492        {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
493        {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
494        {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
495        {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
496        {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
497        {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
498        {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
499        {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
500        {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
501        {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
502        {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
503        {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
504        {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
505        {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
506        {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
507        {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
508        {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
509        {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
510        {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
511};
512
513static struct {
514        int archive_inherit;
515        int platform_inherit;
516} acl_inherit_map[] = {
517        {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
518	{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
519	{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
520	{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
521};
522
523static int
524translate_acl(struct archive_read_disk *a,
525    struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
526{
527	acl_tag_t	 acl_tag;
528	acl_entry_type_t acl_type;
529	acl_flagset_t	 acl_flagset;
530	acl_entry_t	 acl_entry;
531	acl_permset_t	 acl_permset;
532	int		 brand, i, r, entry_acl_type;
533	int		 s, ae_id, ae_tag, ae_perm;
534	const char	*ae_name;
535
536	// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
537	// Make sure the "brand" on this ACL is consistent
538	// with the default_entry_acl_type bits provided.
539	acl_get_brand_np(acl, &brand);
540	switch (brand) {
541	case ACL_BRAND_POSIX:
542		switch (default_entry_acl_type) {
543		case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
544		case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
545			break;
546		default:
547			// XXX set warning message?
548			return ARCHIVE_FAILED;
549		}
550		break;
551	case ACL_BRAND_NFS4:
552		if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
553			// XXX set warning message?
554			return ARCHIVE_FAILED;
555		}
556		break;
557	default:
558		// XXX set warning message?
559		return ARCHIVE_FAILED;
560		break;
561	}
562
563
564	s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
565	while (s == 1) {
566		ae_id = -1;
567		ae_name = NULL;
568		ae_perm = 0;
569
570		acl_get_tag_type(acl_entry, &acl_tag);
571		switch (acl_tag) {
572		case ACL_USER:
573			ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
574			ae_name = archive_read_disk_uname(&a->archive, ae_id);
575			ae_tag = ARCHIVE_ENTRY_ACL_USER;
576			break;
577		case ACL_GROUP:
578			ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);
579			ae_name = archive_read_disk_gname(&a->archive, ae_id);
580			ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
581			break;
582		case ACL_MASK:
583			ae_tag = ARCHIVE_ENTRY_ACL_MASK;
584			break;
585		case ACL_USER_OBJ:
586			ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
587			break;
588		case ACL_GROUP_OBJ:
589			ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
590			break;
591		case ACL_OTHER:
592			ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
593			break;
594		case ACL_EVERYONE:
595			ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
596			break;
597		default:
598			/* Skip types that libarchive can't support. */
599			s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
600			continue;
601		}
602
603		// XXX acl type maps to allow/deny/audit/YYYY bits
604		// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
605		// non-NFSv4 ACLs
606		entry_acl_type = default_entry_acl_type;
607		r = acl_get_entry_type_np(acl_entry, &acl_type);
608		if (r == 0) {
609			switch (acl_type) {
610			case ACL_ENTRY_TYPE_ALLOW:
611				entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
612				break;
613			case ACL_ENTRY_TYPE_DENY:
614				entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
615				break;
616			case ACL_ENTRY_TYPE_AUDIT:
617				entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
618				break;
619			case ACL_ENTRY_TYPE_ALARM:
620				entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
621				break;
622			}
623		}
624
625		/*
626		 * Libarchive stores "flag" (NFSv4 inheritance bits)
627		 * in the ae_perm bitmap.
628		 */
629		acl_get_flagset_np(acl_entry, &acl_flagset);
630                for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
631			if (acl_get_flag_np(acl_flagset,
632					    acl_inherit_map[i].platform_inherit))
633				ae_perm |= acl_inherit_map[i].archive_inherit;
634
635                }
636
637		acl_get_permset(acl_entry, &acl_permset);
638                for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
639			/*
640			 * acl_get_perm() is spelled differently on different
641			 * platforms; see above.
642			 */
643			if (ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm))
644				ae_perm |= acl_perm_map[i].archive_perm;
645		}
646
647		archive_entry_acl_add_entry(entry, entry_acl_type,
648					    ae_perm, ae_tag,
649					    ae_id, ae_name);
650
651		s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
652	}
653	return (ARCHIVE_OK);
654}
655#else
656static int
657setup_acls(struct archive_read_disk *a,
658    struct archive_entry *entry, int *fd)
659{
660	(void)a;      /* UNUSED */
661	(void)entry;  /* UNUSED */
662	(void)fd;     /* UNUSED */
663	return (ARCHIVE_OK);
664}
665#endif
666
667#if (HAVE_FGETXATTR && HAVE_FLISTXATTR && HAVE_LISTXATTR && \
668    HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR) || \
669    (HAVE_FGETEA && HAVE_FLISTEA && HAVE_LISTEA)
670
671/*
672 * Linux and AIX extended attribute support.
673 *
674 * TODO:  By using a stack-allocated buffer for the first
675 * call to getxattr(), we might be able to avoid the second
676 * call entirely.  We only need the second call if the
677 * stack-allocated buffer is too small.  But a modest buffer
678 * of 1024 bytes or so will often be big enough.  Same applies
679 * to listxattr().
680 */
681
682
683static int
684setup_xattr(struct archive_read_disk *a,
685    struct archive_entry *entry, const char *name, int fd)
686{
687	ssize_t size;
688	void *value = NULL;
689	const char *accpath;
690
691	accpath = archive_entry_sourcepath(entry);
692	if (accpath == NULL)
693		accpath = archive_entry_pathname(entry);
694
695#if HAVE_FGETXATTR
696	if (fd >= 0)
697		size = fgetxattr(fd, name, NULL, 0);
698	else if (!a->follow_symlinks)
699		size = lgetxattr(accpath, name, NULL, 0);
700	else
701		size = getxattr(accpath, name, NULL, 0);
702#elif HAVE_FGETEA
703	if (fd >= 0)
704		size = fgetea(fd, name, NULL, 0);
705	else if (!a->follow_symlinks)
706		size = lgetea(accpath, name, NULL, 0);
707	else
708		size = getea(accpath, name, NULL, 0);
709#endif
710
711	if (size == -1) {
712		archive_set_error(&a->archive, errno,
713		    "Couldn't query extended attribute");
714		return (ARCHIVE_WARN);
715	}
716
717	if (size > 0 && (value = malloc(size)) == NULL) {
718		archive_set_error(&a->archive, errno, "Out of memory");
719		return (ARCHIVE_FATAL);
720	}
721
722#if HAVE_FGETXATTR
723	if (fd >= 0)
724		size = fgetxattr(fd, name, value, size);
725	else if (!a->follow_symlinks)
726		size = lgetxattr(accpath, name, value, size);
727	else
728		size = getxattr(accpath, name, value, size);
729#elif HAVE_FGETEA
730	if (fd >= 0)
731		size = fgetea(fd, name, value, size);
732	else if (!a->follow_symlinks)
733		size = lgetea(accpath, name, value, size);
734	else
735		size = getea(accpath, name, value, size);
736#endif
737
738	if (size == -1) {
739		archive_set_error(&a->archive, errno,
740		    "Couldn't read extended attribute");
741		return (ARCHIVE_WARN);
742	}
743
744	archive_entry_xattr_add_entry(entry, name, value, size);
745
746	free(value);
747	return (ARCHIVE_OK);
748}
749
750static int
751setup_xattrs(struct archive_read_disk *a,
752    struct archive_entry *entry, int *fd)
753{
754	char *list, *p;
755	const char *path;
756	ssize_t list_size;
757
758	path = archive_entry_sourcepath(entry);
759	if (path == NULL)
760		path = archive_entry_pathname(entry);
761
762	if (*fd < 0 && a->tree != NULL) {
763		if (a->follow_symlinks ||
764		    archive_entry_filetype(entry) != AE_IFLNK)
765			*fd = a->open_on_current_dir(a->tree, path,
766				O_RDONLY | O_NONBLOCK);
767		if (*fd < 0) {
768			if (a->tree_enter_working_dir(a->tree) != 0) {
769				archive_set_error(&a->archive, errno,
770				    "Couldn't access %s", path);
771				return (ARCHIVE_FAILED);
772			}
773		}
774	}
775
776#if HAVE_FLISTXATTR
777	if (*fd >= 0)
778		list_size = flistxattr(*fd, NULL, 0);
779	else if (!a->follow_symlinks)
780		list_size = llistxattr(path, NULL, 0);
781	else
782		list_size = listxattr(path, NULL, 0);
783#elif HAVE_FLISTEA
784	if (*fd >= 0)
785		list_size = flistea(*fd, NULL, 0);
786	else if (!a->follow_symlinks)
787		list_size = llistea(path, NULL, 0);
788	else
789		list_size = listea(path, NULL, 0);
790#endif
791
792	if (list_size == -1) {
793		if (errno == ENOTSUP || errno == ENOSYS)
794			return (ARCHIVE_OK);
795		archive_set_error(&a->archive, errno,
796			"Couldn't list extended attributes");
797		return (ARCHIVE_WARN);
798	}
799
800	if (list_size == 0)
801		return (ARCHIVE_OK);
802
803	if ((list = malloc(list_size)) == NULL) {
804		archive_set_error(&a->archive, errno, "Out of memory");
805		return (ARCHIVE_FATAL);
806	}
807
808#if HAVE_FLISTXATTR
809	if (*fd >= 0)
810		list_size = flistxattr(*fd, list, list_size);
811	else if (!a->follow_symlinks)
812		list_size = llistxattr(path, list, list_size);
813	else
814		list_size = listxattr(path, list, list_size);
815#elif HAVE_FLISTEA
816	if (*fd >= 0)
817		list_size = flistea(*fd, list, list_size);
818	else if (!a->follow_symlinks)
819		list_size = llistea(path, list, list_size);
820	else
821		list_size = listea(path, list, list_size);
822#endif
823
824	if (list_size == -1) {
825		archive_set_error(&a->archive, errno,
826			"Couldn't retrieve extended attributes");
827		free(list);
828		return (ARCHIVE_WARN);
829	}
830
831	for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
832		if (strncmp(p, "system.", 7) == 0 ||
833				strncmp(p, "xfsroot.", 8) == 0)
834			continue;
835		setup_xattr(a, entry, p, *fd);
836	}
837
838	free(list);
839	return (ARCHIVE_OK);
840}
841
842#elif HAVE_EXTATTR_GET_FILE && HAVE_EXTATTR_LIST_FILE && \
843    HAVE_DECL_EXTATTR_NAMESPACE_USER
844
845/*
846 * FreeBSD extattr interface.
847 */
848
849/* TODO: Implement this.  Follow the Linux model above, but
850 * with FreeBSD-specific system calls, of course.  Be careful
851 * to not include the system extattrs that hold ACLs; we handle
852 * those separately.
853 */
854static int
855setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
856    int namespace, const char *name, const char *fullname, int fd);
857
858static int
859setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
860    int namespace, const char *name, const char *fullname, int fd)
861{
862	ssize_t size;
863	void *value = NULL;
864	const char *accpath;
865
866	accpath = archive_entry_sourcepath(entry);
867	if (accpath == NULL)
868		accpath = archive_entry_pathname(entry);
869
870	if (fd >= 0)
871		size = extattr_get_fd(fd, namespace, name, NULL, 0);
872	else if (!a->follow_symlinks)
873		size = extattr_get_link(accpath, namespace, name, NULL, 0);
874	else
875		size = extattr_get_file(accpath, namespace, name, NULL, 0);
876
877	if (size == -1) {
878		archive_set_error(&a->archive, errno,
879		    "Couldn't query extended attribute");
880		return (ARCHIVE_WARN);
881	}
882
883	if (size > 0 && (value = malloc(size)) == NULL) {
884		archive_set_error(&a->archive, errno, "Out of memory");
885		return (ARCHIVE_FATAL);
886	}
887
888	if (fd >= 0)
889		size = extattr_get_fd(fd, namespace, name, value, size);
890	else if (!a->follow_symlinks)
891		size = extattr_get_link(accpath, namespace, name, value, size);
892	else
893		size = extattr_get_file(accpath, namespace, name, value, size);
894
895	if (size == -1) {
896		free(value);
897		archive_set_error(&a->archive, errno,
898		    "Couldn't read extended attribute");
899		return (ARCHIVE_WARN);
900	}
901
902	archive_entry_xattr_add_entry(entry, fullname, value, size);
903
904	free(value);
905	return (ARCHIVE_OK);
906}
907
908static int
909setup_xattrs(struct archive_read_disk *a,
910    struct archive_entry *entry, int *fd)
911{
912	char buff[512];
913	char *list, *p;
914	ssize_t list_size;
915	const char *path;
916	int namespace = EXTATTR_NAMESPACE_USER;
917
918	path = archive_entry_sourcepath(entry);
919	if (path == NULL)
920		path = archive_entry_pathname(entry);
921
922	if (*fd < 0 && a->tree != NULL) {
923		if (a->follow_symlinks ||
924		    archive_entry_filetype(entry) != AE_IFLNK)
925			*fd = a->open_on_current_dir(a->tree, path,
926				O_RDONLY | O_NONBLOCK);
927		if (*fd < 0) {
928			if (a->tree_enter_working_dir(a->tree) != 0) {
929				archive_set_error(&a->archive, errno,
930				    "Couldn't access %s", path);
931				return (ARCHIVE_FAILED);
932			}
933		}
934	}
935
936	if (*fd >= 0)
937		list_size = extattr_list_fd(*fd, namespace, NULL, 0);
938	else if (!a->follow_symlinks)
939		list_size = extattr_list_link(path, namespace, NULL, 0);
940	else
941		list_size = extattr_list_file(path, namespace, NULL, 0);
942
943	if (list_size == -1 && errno == EOPNOTSUPP)
944		return (ARCHIVE_OK);
945	if (list_size == -1) {
946		archive_set_error(&a->archive, errno,
947			"Couldn't list extended attributes");
948		return (ARCHIVE_WARN);
949	}
950
951	if (list_size == 0)
952		return (ARCHIVE_OK);
953
954	if ((list = malloc(list_size)) == NULL) {
955		archive_set_error(&a->archive, errno, "Out of memory");
956		return (ARCHIVE_FATAL);
957	}
958
959	if (*fd >= 0)
960		list_size = extattr_list_fd(*fd, namespace, list, list_size);
961	else if (!a->follow_symlinks)
962		list_size = extattr_list_link(path, namespace, list, list_size);
963	else
964		list_size = extattr_list_file(path, namespace, list, list_size);
965
966	if (list_size == -1) {
967		archive_set_error(&a->archive, errno,
968			"Couldn't retrieve extended attributes");
969		free(list);
970		return (ARCHIVE_WARN);
971	}
972
973	p = list;
974	while ((p - list) < list_size) {
975		size_t len = 255 & (int)*p;
976		char *name;
977
978		strcpy(buff, "user.");
979		name = buff + strlen(buff);
980		memcpy(name, p + 1, len);
981		name[len] = '\0';
982		setup_xattr(a, entry, namespace, name, buff, *fd);
983		p += 1 + len;
984	}
985
986	free(list);
987	return (ARCHIVE_OK);
988}
989
990#else
991
992/*
993 * Generic (stub) extended attribute support.
994 */
995static int
996setup_xattrs(struct archive_read_disk *a,
997    struct archive_entry *entry, int *fd)
998{
999	(void)a;     /* UNUSED */
1000	(void)entry; /* UNUSED */
1001	(void)fd;    /* UNUSED */
1002	return (ARCHIVE_OK);
1003}
1004
1005#endif
1006
1007#if defined(HAVE_LINUX_FIEMAP_H)
1008
1009/*
1010 * Linux sparse interface.
1011 *
1012 * The FIEMAP ioctl returns an "extent" for each physical allocation
1013 * on disk.  We need to process those to generate a more compact list
1014 * of logical file blocks.  We also need to be very careful to use
1015 * FIEMAP_FLAG_SYNC here, since there are reports that Linux sometimes
1016 * does not report allocations for newly-written data that hasn't
1017 * been synced to disk.
1018 *
1019 * It's important to return a minimal sparse file list because we want
1020 * to not trigger sparse file extensions if we don't have to, since
1021 * not all readers support them.
1022 */
1023
1024static int
1025setup_sparse(struct archive_read_disk *a,
1026    struct archive_entry *entry, int *fd)
1027{
1028	char buff[4096];
1029	struct fiemap *fm;
1030	struct fiemap_extent *fe;
1031	int64_t size;
1032	int count, do_fiemap;
1033	int exit_sts = ARCHIVE_OK;
1034
1035	if (archive_entry_filetype(entry) != AE_IFREG
1036	    || archive_entry_size(entry) <= 0
1037	    || archive_entry_hardlink(entry) != NULL)
1038		return (ARCHIVE_OK);
1039
1040	if (*fd < 0) {
1041		const char *path;
1042
1043		path = archive_entry_sourcepath(entry);
1044		if (path == NULL)
1045			path = archive_entry_pathname(entry);
1046		if (a->tree != NULL)
1047			*fd = a->open_on_current_dir(a->tree, path,
1048				O_RDONLY | O_NONBLOCK | O_CLOEXEC);
1049		else
1050			*fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
1051		if (*fd < 0) {
1052			archive_set_error(&a->archive, errno,
1053			    "Can't open `%s'", path);
1054			return (ARCHIVE_FAILED);
1055		}
1056		__archive_ensure_cloexec_flag(*fd);
1057	}
1058
1059	/* Initialize buffer to avoid the error valgrind complains about. */
1060	memset(buff, 0, sizeof(buff));
1061	count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe);
1062	fm = (struct fiemap *)buff;
1063	fm->fm_start = 0;
1064	fm->fm_length = ~0ULL;;
1065	fm->fm_flags = FIEMAP_FLAG_SYNC;
1066	fm->fm_extent_count = count;
1067	do_fiemap = 1;
1068	size = archive_entry_size(entry);
1069	for (;;) {
1070		int i, r;
1071
1072		r = ioctl(*fd, FS_IOC_FIEMAP, fm);
1073		if (r < 0) {
1074			/* When something error happens, it is better we
1075			 * should return ARCHIVE_OK because an earlier
1076			 * version(<2.6.28) cannot perfom FS_IOC_FIEMAP. */
1077			goto exit_setup_sparse;
1078		}
1079		if (fm->fm_mapped_extents == 0)
1080			break;
1081		fe = fm->fm_extents;
1082		for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) {
1083			if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
1084				/* The fe_length of the last block does not
1085				 * adjust itself to its size files. */
1086				int64_t length = fe->fe_length;
1087				if (fe->fe_logical + length > (uint64_t)size)
1088					length -= fe->fe_logical + length - size;
1089				if (fe->fe_logical == 0 && length == size) {
1090					/* This is not sparse. */
1091					do_fiemap = 0;
1092					break;
1093				}
1094				if (length > 0)
1095					archive_entry_sparse_add_entry(entry,
1096					    fe->fe_logical, length);
1097			}
1098			if (fe->fe_flags & FIEMAP_EXTENT_LAST)
1099				do_fiemap = 0;
1100		}
1101		if (do_fiemap) {
1102			fe = fm->fm_extents + fm->fm_mapped_extents -1;
1103			fm->fm_start = fe->fe_logical + fe->fe_length;
1104		} else
1105			break;
1106	}
1107exit_setup_sparse:
1108	return (exit_sts);
1109}
1110
1111#elif defined(SEEK_HOLE) && defined(SEEK_DATA) && defined(_PC_MIN_HOLE_SIZE)
1112
1113/*
1114 * FreeBSD and Solaris sparse interface.
1115 */
1116
1117static int
1118setup_sparse(struct archive_read_disk *a,
1119    struct archive_entry *entry, int *fd)
1120{
1121	int64_t size;
1122	off_t initial_off; /* FreeBSD/Solaris only, so off_t okay here */
1123	off_t off_s, off_e; /* FreeBSD/Solaris only, so off_t okay here */
1124	int exit_sts = ARCHIVE_OK;
1125
1126	if (archive_entry_filetype(entry) != AE_IFREG
1127	    || archive_entry_size(entry) <= 0
1128	    || archive_entry_hardlink(entry) != NULL)
1129		return (ARCHIVE_OK);
1130
1131	/* Does filesystem support the reporting of hole ? */
1132	if (*fd < 0 && a->tree != NULL) {
1133		const char *path;
1134
1135		path = archive_entry_sourcepath(entry);
1136		if (path == NULL)
1137			path = archive_entry_pathname(entry);
1138		*fd = a->open_on_current_dir(a->tree, path,
1139				O_RDONLY | O_NONBLOCK);
1140		if (*fd < 0) {
1141			archive_set_error(&a->archive, errno,
1142			    "Can't open `%s'", path);
1143			return (ARCHIVE_FAILED);
1144		}
1145	}
1146
1147	if (*fd >= 0) {
1148		if (fpathconf(*fd, _PC_MIN_HOLE_SIZE) <= 0)
1149			return (ARCHIVE_OK);
1150		initial_off = lseek(*fd, 0, SEEK_CUR);
1151		if (initial_off != 0)
1152			lseek(*fd, 0, SEEK_SET);
1153	} else {
1154		const char *path;
1155
1156		path = archive_entry_sourcepath(entry);
1157		if (path == NULL)
1158			path = archive_entry_pathname(entry);
1159
1160		if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
1161			return (ARCHIVE_OK);
1162		*fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
1163		if (*fd < 0) {
1164			archive_set_error(&a->archive, errno,
1165			    "Can't open `%s'", path);
1166			return (ARCHIVE_FAILED);
1167		}
1168		__archive_ensure_cloexec_flag(*fd);
1169		initial_off = 0;
1170	}
1171
1172	off_s = 0;
1173	size = archive_entry_size(entry);
1174	while (off_s < size) {
1175		off_s = lseek(*fd, off_s, SEEK_DATA);
1176		if (off_s == (off_t)-1) {
1177			if (errno == ENXIO)
1178				break;/* no more hole */
1179			archive_set_error(&a->archive, errno,
1180			    "lseek(SEEK_HOLE) failed");
1181			exit_sts = ARCHIVE_FAILED;
1182			goto exit_setup_sparse;
1183		}
1184		off_e = lseek(*fd, off_s, SEEK_HOLE);
1185		if (off_e == (off_t)-1) {
1186			if (errno == ENXIO) {
1187				off_e = lseek(*fd, 0, SEEK_END);
1188				if (off_e != (off_t)-1)
1189					break;/* no more data */
1190			}
1191			archive_set_error(&a->archive, errno,
1192			    "lseek(SEEK_DATA) failed");
1193			exit_sts = ARCHIVE_FAILED;
1194			goto exit_setup_sparse;
1195		}
1196		if (off_s == 0 && off_e == size)
1197			break;/* This is not spase. */
1198		archive_entry_sparse_add_entry(entry, off_s,
1199			off_e - off_s);
1200		off_s = off_e;
1201	}
1202exit_setup_sparse:
1203	lseek(*fd, initial_off, SEEK_SET);
1204	return (exit_sts);
1205}
1206
1207#else
1208
1209/*
1210 * Generic (stub) sparse support.
1211 */
1212static int
1213setup_sparse(struct archive_read_disk *a,
1214    struct archive_entry *entry, int *fd)
1215{
1216	(void)a;     /* UNUSED */
1217	(void)entry; /* UNUSED */
1218	(void)fd;    /* UNUSED */
1219	return (ARCHIVE_OK);
1220}
1221
1222#endif
1223
1224#endif /* !defined(_WIN32) || defined(__CYGWIN__) */
1225
1226