Example #1
0
ssize_t sys_lgetxattr (const char *path, const char *uname, void *value, size_t size)
{
	const char *name = prefix(uname);

#if defined(HAVE_LGETXATTR)
	return lgetxattr(path, name, value, size);
#elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
	int options = XATTR_NOFOLLOW;
	return getxattr(path, name, value, size, 0, options);
#elif defined(HAVE_LGETEA)
	return lgetea(path, name, value, size);
#elif defined(HAVE_EXTATTR_GET_LINK)
	ssize_t retval;

	retval = extattr_get_link(path, EXTATTR_NAMESPACE_USER, uname, NULL, 0);
    if (retval == -1) {
        LOG(log_maxdebug, logtype_default, "extattr_get_link(): %s",
            strerror(errno));
        return -1;
    }
    if (size == 0)
        /* Only interested in size of xattr */
        return retval;
    if (retval > size) {
        errno = ERANGE;
        return -1;
    }
    return extattr_get_link(path, EXTATTR_NAMESPACE_USER, uname, value, size);

#elif defined(HAVE_ATTR_GET)
	int retval, flags = ATTR_DONTFOLLOW;
	int valuelength = (int)size;
	char *attrname = strchr(name,'.') + 1;
	
	if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;

	retval = attr_get(path, attrname, (char *)value, &valuelength, flags);

	return retval ? retval : valuelength;
#elif defined(HAVE_ATTROPEN)
	ssize_t ret = -1;
	int attrfd = solaris_attropen(path, name, O_RDONLY | O_NOFOLLOW, 0);
	if (attrfd >= 0) {
		ret = solaris_read_xattr(attrfd, value, size);
		close(attrfd);
	}
	return ret;
#else
	errno = ENOSYS;
	return -1;
#endif
}
static int
setup_xattr(struct archive_read_disk *a,
    struct archive_entry *entry, const char *name, int fd)
{
	ssize_t size;
	void *value = NULL;
	const char *accpath;

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

#if HAVE_FGETXATTR
	if (fd >= 0)
		size = fgetxattr(fd, name, NULL, 0);
	else if (!a->follow_symlinks)
		size = lgetxattr(accpath, name, NULL, 0);
	else
		size = getxattr(accpath, name, NULL, 0);
#elif HAVE_FGETEA
	if (fd >= 0)
		size = fgetea(fd, name, NULL, 0);
	else if (!a->follow_symlinks)
		size = lgetea(accpath, name, NULL, 0);
	else
		size = getea(accpath, name, NULL, 0);
#endif

	if (size == -1) {
		archive_set_error(&a->archive, errno,
		    "Couldn't query extended attribute");
		return (ARCHIVE_WARN);
	}

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

#if HAVE_FGETXATTR
	if (fd >= 0)
		size = fgetxattr(fd, name, value, size);
	else if (!a->follow_symlinks)
		size = lgetxattr(accpath, name, value, size);
	else
		size = getxattr(accpath, name, value, size);
#elif HAVE_FGETEA
	if (fd >= 0)
		size = fgetea(fd, name, value, size);
	else if (!a->follow_symlinks)
		size = lgetea(accpath, name, value, size);
	else
		size = getea(accpath, name, value, size);
#endif

	if (size == -1) {
		archive_set_error(&a->archive, errno,
		    "Couldn't read extended attribute");
		return (ARCHIVE_WARN);
	}

	archive_entry_xattr_add_entry(entry, name, value, size);

	free(value);
	return (ARCHIVE_OK);
}
static int
setup_xattr(struct archive_read_disk *a,
    struct archive_entry *entry, const char *name, int fd, const char *accpath)
{
	ssize_t size;
	void *value = NULL;


	if (fd >= 0) {
#if ARCHIVE_XATTR_LINUX
		size = fgetxattr(fd, name, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		size = fgetxattr(fd, name, NULL, 0, 0, 0);
#elif ARCHIVE_XATTR_AIX
		size = fgetea(fd, name, NULL, 0);
#endif
	} else if (!a->follow_symlinks) {
#if ARCHIVE_XATTR_LINUX
		size = lgetxattr(accpath, name, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		size = getxattr(accpath, name, NULL, 0, 0, XATTR_NOFOLLOW);
#elif ARCHIVE_XATTR_AIX
		size = lgetea(accpath, name, NULL, 0);
#endif
	} else {
#if ARCHIVE_XATTR_LINUX
		size = getxattr(accpath, name, NULL, 0);
#elif ARCHIVE_XATTR_DARWIN
		size = getxattr(accpath, name, NULL, 0, 0, 0);
#elif ARCHIVE_XATTR_AIX
		size = getea(accpath, name, NULL, 0);
#endif
	}

	if (size == -1) {
		archive_set_error(&a->archive, errno,
		    "Couldn't query extended attribute");
		return (ARCHIVE_WARN);
	}

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


	if (fd >= 0) {
#if ARCHIVE_XATTR_LINUX
		size = fgetxattr(fd, name, value, size);
#elif ARCHIVE_XATTR_DARWIN
		size = fgetxattr(fd, name, value, size, 0, 0);
#elif ARCHIVE_XATTR_AIX
		size = fgetea(fd, name, value, size);
#endif
	} else if (!a->follow_symlinks) {
#if ARCHIVE_XATTR_LINUX
		size = lgetxattr(accpath, name, value, size);
#elif ARCHIVE_XATTR_DARWIN
		size = getxattr(accpath, name, value, size, 0, XATTR_NOFOLLOW);
#elif ARCHIVE_XATTR_AIX
		size = lgetea(accpath, name, value, size);
#endif
	} else {
#if ARCHIVE_XATTR_LINUX
		size = getxattr(accpath, name, value, size);
#elif ARCHIVE_XATTR_DARWIN
		size = getxattr(accpath, name, value, size, 0, 0);
#elif ARCHIVE_XATTR_AIX
		size = getea(accpath, name, value, size);
#endif
	}

	if (size == -1) {
		archive_set_error(&a->archive, errno,
		    "Couldn't read extended attribute");
		return (ARCHIVE_WARN);
	}

	archive_entry_xattr_add_entry(entry, name, value, size);

	free(value);
	return (ARCHIVE_OK);
}