Report names of extended attributes that could not be restored
Remove xattr namespace limitations for AIX and Darwin
On Linux, skip all known ACL extended attributes and obsolete xfsroot
diff --git a/libarchive/archive_read_disk_entry_from_file.c b/libarchive/archive_read_disk_entry_from_file.c
index 9d845fa..700f9e3 100644
--- a/libarchive/archive_read_disk_entry_from_file.c
+++ b/libarchive/archive_read_disk_entry_from_file.c
@@ -613,9 +613,21 @@
 	}
 
 	for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
-		if (strncmp(p, "system.", 7) == 0 ||
-				strncmp(p, "xfsroot.", 8) == 0)
+#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);
 	}
 
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
index c875f69..6ad5399 100644
--- a/libarchive/archive_write_disk_posix.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -4092,61 +4092,86 @@
 set_xattrs(struct archive_write_disk *a)
 {
 	struct archive_entry *entry = a->entry;
-	static int warning_done = 0;
+	struct archive_string errlist;
 	int ret = ARCHIVE_OK;
 	int i = archive_entry_xattr_reset(entry);
+	short fail = 0;
+
+	archive_string_init(&errlist);
 
 	while (i--) {
 		const char *name;
 		const void *value;
 		size_t size;
+		int e;
+
 		archive_entry_xattr_next(entry, &name, &value, &size);
-		if (name != NULL &&
-				strncmp(name, "xfsroot.", 8) != 0 &&
-				strncmp(name, "system.", 7) != 0) {
-			int e;
-			if (a->fd >= 0) {
+
+		if (name == NULL)
+			continue;
 #if ARCHIVE_XATTR_LINUX
-				e = fsetxattr(a->fd, name, value, size, 0);
-#elif ARCHIVE_XATTR_DARWIN
-				e = fsetxattr(a->fd, name, value, size, 0, 0);
-#elif ARCHIVE_XATTR_AIX
-				e = fsetea(a->fd, name, value, size, 0);
+		/* Linux: quietly skip POSIX.1e ACL extended attributes */
+		if (strncmp(name, "system.", 7) == 0 &&
+		   (strcmp(name + 7, "posix_acl_access") == 0 ||
+		    strcmp(name + 7, "posix_acl_default") == 0))
+			continue;
+		if (strncmp(name, "trusted.SGI_", 12) == 0 &&
+		   (strcmp(name + 12, "ACL_DEFAULT") == 0 ||
+		    strcmp(name + 12, "ACL_FILE") == 0))
+			continue;
+
+		/* Linux: xfsroot namespace is obsolete and unsupported */
+		if (strncmp(name, "xfsroot.", 8) == 0) {
+			fail = 1;
+			archive_strcat(&errlist, name);
+			archive_strappend_char(&errlist, ' ');
+			continue;
+		}
 #endif
-			} else {
+
+		if (a->fd >= 0) {
 #if ARCHIVE_XATTR_LINUX
-				e = lsetxattr(archive_entry_pathname(entry),
-				    name, value, size, 0);
+			e = fsetxattr(a->fd, name, value, size, 0);
 #elif ARCHIVE_XATTR_DARWIN
-				e = setxattr(archive_entry_pathname(entry),
-				    name, value, size, 0, XATTR_NOFOLLOW);
+			e = fsetxattr(a->fd, name, value, size, 0, 0);
 #elif ARCHIVE_XATTR_AIX
-				e = lsetea(archive_entry_pathname(entry),
-				    name, value, size, 0);
+			e = fsetea(a->fd, name, value, size, 0);
 #endif
-			}
-			if (e == -1) {
-				if (errno == ENOTSUP || errno == ENOSYS) {
-					if (!warning_done) {
-						warning_done = 1;
-						archive_set_error(&a->archive,
-						    errno,
-						    "Cannot restore extended "
-						    "attributes on this file "
-						    "system");
-					}
-				} else
-					archive_set_error(&a->archive, errno,
-					    "Failed to set extended attribute");
-				ret = ARCHIVE_WARN;
-			}
 		} else {
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "Invalid extended attribute encountered");
+#if ARCHIVE_XATTR_LINUX
+			e = lsetxattr(archive_entry_pathname(entry),
+			    name, value, size, 0);
+#elif ARCHIVE_XATTR_DARWIN
+			e = setxattr(archive_entry_pathname(entry),
+			    name, value, size, 0, XATTR_NOFOLLOW);
+#elif ARCHIVE_XATTR_AIX
+			e = lsetea(archive_entry_pathname(entry),
+			    name, value, size, 0);
+#endif
+		}
+		if (e == -1) {
 			ret = ARCHIVE_WARN;
+			archive_strcat(&errlist, name);
+			archive_strappend_char(&errlist, ' ');
+			if (errno != ENOTSUP && errno != ENOSYS)
+				fail = 1;
 		}
 	}
+
+	if (ret == ARCHIVE_WARN) {
+		if (fail && errlist.length > 0) {
+			errlist.length--;
+			errlist.s[errlist.length] = '\0';
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Cannot restore extended attributes: %s",
+			    errlist.s);
+		} else
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Cannot restore extended "
+			    "attributes on this file system.");
+	}
+
+	archive_string_free(&errlist);
 	return (ret);
 }
 #elif ARCHIVE_XATTR_FREEBSD
@@ -4157,9 +4182,12 @@
 set_xattrs(struct archive_write_disk *a)
 {
 	struct archive_entry *entry = a->entry;
-	static int warning_done = 0;
+	struct archive_string errlist;
 	int ret = ARCHIVE_OK;
 	int i = archive_entry_xattr_reset(entry);
+	short fail = 0;
+
+	archive_string_init(&errlist);
 
 	while (i--) {
 		const char *name;
@@ -4175,15 +4203,13 @@
 				name += 5;
 				namespace = EXTATTR_NAMESPACE_USER;
 			} else {
-				/* Warn about other extended attributes. */
-				archive_set_error(&a->archive,
-				    ARCHIVE_ERRNO_FILE_FORMAT,
-				    "Can't restore extended attribute ``%s''",
-				    name);
+				/* Other namespaces are unsupported */
+				archive_strcat(&errlist, name);
+				archive_strappend_char(&errlist, ' ');
+				fail = 1;
 				ret = ARCHIVE_WARN;
 				continue;
 			}
-			errno = 0;
 
 			if (a->fd >= 0) {
 				e = extattr_set_fd(a->fd, namespace, name,
@@ -4194,24 +4220,30 @@
 				    name, value, size);
 			}
 			if (e != (int)size) {
-				if (errno == ENOTSUP || errno == ENOSYS) {
-					if (!warning_done) {
-						warning_done = 1;
-						archive_set_error(&a->archive,
-						    errno,
-						    "Cannot restore extended "
-						    "attributes on this file "
-						    "system");
-					}
-				} else {
-					archive_set_error(&a->archive, errno,
-					    "Failed to set extended attribute");
-				}
-
+				archive_strcat(&errlist, name);
+				archive_strappend_char(&errlist, ' ');
 				ret = ARCHIVE_WARN;
+				if (errno != ENOTSUP && errno != ENOSYS)
+					fail = 1;
 			}
 		}
 	}
+
+	if (ret == ARCHIVE_WARN) {
+		if (fail && errlist.length > 0) {
+			errlist.length--;
+			errlist.s[errlist.length] = '\0';
+
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Cannot restore extended attributes: %s",
+			    errlist.s);
+		} else
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Cannot restore extended "
+			    "attributes on this file system.");
+	}
+
+	archive_string_free(&errlist);
 	return (ret);
 }
 #else