diff options
author | Martin Matuska <martin@matuska.org> | 2017-03-23 15:27:59 +0100 |
---|---|---|
committer | Martin Matuska <martin@matuska.org> | 2017-03-23 15:34:25 +0100 |
commit | 365a91def0c9c173b93643698d6ee4e8e0fc2746 (patch) | |
tree | 07d2501b3c9d6df8988c88ffab3c24b9521d97d2 /test_utils/test_main.c | |
parent | 3627d67e773badf49b746e5e1d2fefdfe08b66b9 (diff) | |
download | libarchive-365a91def0c9c173b93643698d6ee4e8e0fc2746.tar.gz |
Improve extended attribute support
Mac OS X changes:
- add support for extended file attributes via sys/xattr.h
- when extracting an archive entry that has mac_metadata and
mac_metadata is requested to be extracted, extended attributes
are restored only from mac_metadata.
- by default, extended attributes are stored both in mac_metadata and
SCHILY.xattr/LIBARCHIVE.xattr. This is subject to review and change.
To match behavior on other platforms, store extended attributes on
FreeBSD with extattr_set_link() if no fd is provided.
Detection of extended attributes support in configure stage has been
rewritten.
Added xattr platform test to libarchive and xattrs option test to bsdtar.
Diffstat (limited to 'test_utils/test_main.c')
-rw-r--r-- | test_utils/test_main.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/test_utils/test_main.c b/test_utils/test_main.c index 0ef6d6fc..36dfc82f 100644 --- a/test_utils/test_main.c +++ b/test_utils/test_main.c @@ -67,6 +67,17 @@ #ifdef HAVE_SYS_ACL_H #include <sys/acl.h> #endif +#ifdef HAVE_SYS_EA_H +#include <sys/ea.h> +#endif +#ifdef HAVE_SYS_EXTATTR_H +#include <sys/extattr.h> +#endif +#if HAVE_SYS_XATTR_H +#include <sys/xattr.h> +#elif HAVE_ATTR_XATTR_H +#include <attr/xattr.h> +#endif #ifdef HAVE_SYS_RICHACL_H #include <sys/richacl.h> #endif @@ -2440,6 +2451,83 @@ canNodump(void) return (0); } +/* Get extended attribute from a path */ +const void * +getXattr(const char *path, const char *name, size_t *sizep) +{ + void *value = NULL; +#if ARCHIVE_XATTR_SUPPORT + ssize_t size; +#if ARCHIVE_XATTR_LINUX + size = lgetxattr(path, name, NULL, 0); +#elif ARCHIVE_XATTR_DARWIN + size = getxattr(path, name, NULL, 0, 0, XATTR_NOFOLLOW); +#elif ARCHIVE_XATTR_AIX + size = lgetea(path, name, NULL, 0); +#elif ARCHIVE_XATTR_FREEBSD + size = extattr_get_link(path, EXTATTR_NAMESPACE_USER, name + 5, + NULL, 0); +#endif + + if (size >= 0) { + value = malloc(size); +#if ARCHIVE_XATTR_LINUX + size = lgetxattr(path, name, value, size); +#elif ARCHIVE_XATTR_DARWIN + size = getxattr(path, name, value, size, 0, XATTR_NOFOLLOW); +#elif ARCHIVE_XATTR_AIX + size = lgetea(path, name, value, size); +#elif ARCHIVE_XATTR_FREEBSD + size = extattr_get_link(path, EXTATTR_NAMESPACE_USER, name + 5, + value, size); +#endif + if (size < 0) { + free(value); + value = NULL; + } + } + if (size < 0) + *sizep = 0; + else + *sizep = (size_t)size; +#else /* !ARCHIVE_XATTR_SUPPORT */ + (void)path; /* UNUSED */ + (void)name; /* UNUSED */ + *sizep = 0; +#endif /* !ARCHIVE_XATTR_SUPPORT */ + return (value); +} + +/* + * Set extended attribute on a path + * Returns 0 on error, 1 on success + */ +int +setXattr(const char *path, const char *name, const void *value, size_t size) +{ +#if ARCHIVE_XATTR_SUPPORT +#if ARCHIVE_XATTR_LINUX + if (lsetxattr(path, name, value, size, 0) == 0) +#elif ARCHIVE_XATTR_DARWIN + if (setxattr(path, name, value, size, 0, XATTR_NOFOLLOW) == 0) +#elif ARCHIVE_XATTR_AIX + if (lsetea(path, name, value, size, 0) == 0) +#elif ARCHIVE_XATTR_FREEBSD + if (extattr_set_link(path, EXTATTR_NAMESPACE_USER, name + 5, value, + size) > -1) +#else + if (0) +#endif + return (1); +#else /* !ARCHIVE_XATTR_SUPPORT */ + (void)path; /* UNUSED */ + (void)name; /* UNUSED */ + (void)value; /* UNUSED */ + (void)size; /* UNUSED */ +#endif /* !ARCHIVE_XATTR_SUPPORT */ + return (0); +} + #if ARCHIVE_ACL_SUNOS /* Fetch ACLs on Solaris using acl() or facl() */ void * |