]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Report names of extended attributes that could not be restored
authorMartin Matuska <martin@matuska.org>
Wed, 29 Mar 2017 21:16:02 +0000 (23:16 +0200)
committerMartin Matuska <martin@matuska.org>
Wed, 29 Mar 2017 22:38:33 +0000 (00:38 +0200)
Remove xattr namespace limitations for AIX and Darwin
On Linux, skip all known ACL extended attributes and obsolete xfsroot

libarchive/archive_read_disk_entry_from_file.c
libarchive/archive_write_disk_posix.c

index 9d845fa0ef933015ac42251db7e3084723cd23c0..700f9e3ae1af5fd379edc499e686dbaa7f0a0c31 100644 (file)
@@ -613,9 +613,21 @@ setup_xattrs(struct archive_read_disk *a,
        }
 
        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);
        }
 
index c875f69470b222a86576aff2d45ea36766469815..6ad53992fd820242c92d2c916eecb4dd96327b41 100644 (file)
@@ -4092,61 +4092,86 @@ static int
 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);
+               /* 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
+
+               if (a->fd >= 0) {
+#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);
+                       e = fsetxattr(a->fd, name, value, size, 0, 0);
 #elif ARCHIVE_XATTR_AIX
-                               e = fsetea(a->fd, name, value, size, 0);
+                       e = fsetea(a->fd, name, value, size, 0);
 #endif
-                       } else {
+               } else {
 #if ARCHIVE_XATTR_LINUX
-                               e = lsetxattr(archive_entry_pathname(entry),
-                                   name, value, size, 0);
+                       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);
+                       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);
+                       e = lsetea(archive_entry_pathname(entry),
+                           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 (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 @@ static int
 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 @@ set_xattrs(struct archive_write_disk *a)
                                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 @@ set_xattrs(struct archive_write_disk *a)
                                    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