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); }