static int
setup_xattrs(struct archive_read_disk *a,
    struct archive_entry *entry, int *fd)
{
	char *list, *p;
	const char *path;
	ssize_t list_size;

	path = NULL;

	if (*fd < 0) {
		path = archive_read_disk_entry_setup_path(a, entry, fd);
		if (path == NULL)
			return (ARCHIVE_WARN);
	}

	if (*fd >= 0) {
#if ARCHIVE_XATTR_LINUX
		list_size = flistxattr(*fd, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		list_size = flistxattr(*fd, NULL, 0, 0);
#elif ARCHIVE_XATTR_AIX
		list_size = flistea(*fd, NULL, 0);
#endif
	} else if (!a->follow_symlinks) {
#if ARCHIVE_XATTR_LINUX
		list_size = llistxattr(path, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		list_size = listxattr(path, NULL, 0, XATTR_NOFOLLOW);
#elif ARCHIVE_XATTR_AIX
		list_size = llistea(path, NULL, 0);
#endif
	} else {
#if ARCHIVE_XATTR_LINUX
		list_size = listxattr(path, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		list_size = listxattr(path, NULL, 0, 0);
#elif ARCHIVE_XATTR_AIX
		list_size = listea(path, NULL, 0);
#endif
	}

	if (list_size == -1) {
		if (errno == ENOTSUP || errno == ENOSYS)
			return (ARCHIVE_OK);
		archive_set_error(&a->archive, errno,
			"Couldn't list extended attributes");
		return (ARCHIVE_WARN);
	}

	if (list_size == 0)
		return (ARCHIVE_OK);

	if ((list = malloc(list_size)) == NULL) {
		archive_set_error(&a->archive, errno, "Out of memory");
		return (ARCHIVE_FATAL);
	}

	if (*fd >= 0) {
#if ARCHIVE_XATTR_LINUX
		list_size = flistxattr(*fd, list, list_size);
#elif ARCHIVE_XATTR_DARWIN
		list_size = flistxattr(*fd, list, list_size, 0);
#elif ARCHIVE_XATTR_AIX
		list_size = flistea(*fd, list, list_size);
#endif
	} else if (!a->follow_symlinks) {
#if ARCHIVE_XATTR_LINUX
		list_size = llistxattr(path, list, list_size);
#elif ARCHIVE_XATTR_DARWIN
		list_size = listxattr(path, list, list_size, XATTR_NOFOLLOW);
#elif ARCHIVE_XATTR_AIX
		list_size = llistea(path, list, list_size);
#endif
	} else {
#if ARCHIVE_XATTR_LINUX
		list_size = listxattr(path, list, list_size);
#elif ARCHIVE_XATTR_DARWIN
		list_size = listxattr(path, list, list_size, 0);
#elif ARCHIVE_XATTR_AIX
		list_size = listea(path, list, list_size);
#endif
	}

	if (list_size == -1) {
		archive_set_error(&a->archive, errno,
			"Couldn't retrieve extended attributes");
		free(list);
		return (ARCHIVE_WARN);
	}

	for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
#if ARCHIVE_XATTR_LINUX
		/* Linux: skip POSIX.1e ACL extended attributes */
		if (strncmp(p, "system.", 7) == 0 &&
		   (strcmp(p + 7, "posix_acl_access") == 0 ||
		    strcmp(p + 7, "posix_acl_default") == 0))
			continue;
		if (strncmp(p, "trusted.SGI_", 12) == 0 &&
		   (strcmp(p + 12, "ACL_DEFAULT") == 0 ||
		    strcmp(p + 12, "ACL_FILE") == 0))
			continue;

		/* Linux: xfsroot namespace is obsolete and unsupported */
		if (strncmp(p, "xfsroot.", 8) == 0)
			continue;
#endif
		setup_xattr(a, entry, p, *fd, path);
	}

	free(list);
	return (ARCHIVE_OK);
}
Пример #2
0
static int
setup_xattrs(struct archive_read_disk *a,
    struct archive_entry *entry, int *fd)
{
	char *list, *p;
	const char *path;
	ssize_t list_size;

	path = archive_entry_sourcepath(entry);
	if (path == NULL)
		path = archive_entry_pathname(entry);

	if (*fd < 0 && a->tree != NULL) {
		if (a->follow_symlinks ||
		    archive_entry_filetype(entry) != AE_IFLNK)
			*fd = a->open_on_current_dir(a->tree, path,
				O_RDONLY | O_NONBLOCK);
		if (*fd < 0) {
			if (a->tree_enter_working_dir(a->tree) != 0) {
				archive_set_error(&a->archive, errno,
				    "Couldn't access %s", path);
				return (ARCHIVE_FAILED);
			}
		}
	}

#if HAVE_FLISTXATTR
	if (*fd >= 0)
		list_size = flistxattr(*fd, NULL, 0);
	else if (!a->follow_symlinks)
		list_size = llistxattr(path, NULL, 0);
	else
		list_size = listxattr(path, NULL, 0);
#elif HAVE_FLISTEA
	if (*fd >= 0)
		list_size = flistea(*fd, NULL, 0);
	else if (!a->follow_symlinks)
		list_size = llistea(path, NULL, 0);
	else
		list_size = listea(path, NULL, 0);
#endif

	if (list_size == -1) {
		if (errno == ENOTSUP || errno == ENOSYS)
			return (ARCHIVE_OK);
		archive_set_error(&a->archive, errno,
			"Couldn't list extended attributes");
		return (ARCHIVE_WARN);
	}

	if (list_size == 0)
		return (ARCHIVE_OK);

	if ((list = malloc(list_size)) == NULL) {
		archive_set_error(&a->archive, errno, "Out of memory");
		return (ARCHIVE_FATAL);
	}

#if HAVE_FLISTXATTR
	if (*fd >= 0)
		list_size = flistxattr(*fd, list, list_size);
	else if (!a->follow_symlinks)
		list_size = llistxattr(path, list, list_size);
	else
		list_size = listxattr(path, list, list_size);
#elif HAVE_FLISTEA
	if (*fd >= 0)
		list_size = flistea(*fd, list, list_size);
	else if (!a->follow_symlinks)
		list_size = llistea(path, list, list_size);
	else
		list_size = listea(path, list, list_size);
#endif

	if (list_size == -1) {
		archive_set_error(&a->archive, errno,
			"Couldn't retrieve extended attributes");
		free(list);
		return (ARCHIVE_WARN);
	}

	for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
		if (strncmp(p, "system.", 7) == 0 ||
				strncmp(p, "xfsroot.", 8) == 0)
			continue;
		setup_xattr(a, entry, p, *fd);
	}

	free(list);
	return (ARCHIVE_OK);
}