MFV r316454,316455:
Vendor changes (FreeBSD-related): Report which extended attributes could not be restored Update archive_read_disk.3 and archive_write_disk.3 manual pages Plug memory leaks in xattr tests. MFC after: 1 week
This commit is contained in:
commit
43f9e382c0
@ -24,11 +24,12 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 30, 2016
|
||||
.Dd April 3, 2017
|
||||
.Dt ARCHIVE_READ_DISK 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_disk_new ,
|
||||
.Nm archive_read_disk_set_behavior ,
|
||||
.Nm archive_read_disk_set_symlink_logical ,
|
||||
.Nm archive_read_disk_set_symlink_physical ,
|
||||
.Nm archive_read_disk_set_symlink_hybrid ,
|
||||
@ -46,6 +47,8 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Ft struct archive *
|
||||
.Fn archive_read_disk_new "void"
|
||||
.Ft int
|
||||
.Fn archive_read_disk_set_behavior "struct archive *" "int"
|
||||
.Ft int
|
||||
.Fn archive_read_disk_set_symlink_logical "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_disk_set_symlink_physical "struct archive *"
|
||||
@ -89,6 +92,51 @@ objects.
|
||||
Allocates and initializes a
|
||||
.Tn struct archive
|
||||
object suitable for reading object information from disk.
|
||||
.It Fn archive_read_disk_set_behavior
|
||||
Configures various behavior options when reading entries from disk.
|
||||
The flags field consists of a bitwise OR of one or more of the
|
||||
following values:
|
||||
.Bl -tag -compact -width "indent"
|
||||
.It Cm ARCHIVE_READDISK_HONOR_NODUMP
|
||||
Skip files and directories with the nodump file attribute (file flag) set.
|
||||
By default, the nodump file atrribute is ignored.
|
||||
.It Cm ARCHIVE_READDISK_MAC_COPYFILE
|
||||
Mac OS X specific. Read metadata (ACLs and extended attributes) with
|
||||
.Xr copyfile 3 .
|
||||
By default, metadata is read using
|
||||
.Xr copyfile 3 .
|
||||
.It Cm ARCHIVE_READDISK_NO_ACL
|
||||
Do not read Access Control Lists.
|
||||
By default, ACLs are read from disk.
|
||||
.It Cm ARCHIVE_READDISK_NO_FFLAGS
|
||||
Do not read file attributes (file flags).
|
||||
By default, file attributes are read from disk.
|
||||
See
|
||||
.Xr chattr 1
|
||||
.Pq Linux
|
||||
or
|
||||
.Xr chflags 1
|
||||
.Pq FreeBSD, Mac OS X
|
||||
for more information on file attributes.
|
||||
.It Cm ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS
|
||||
Do not traverse mount points.
|
||||
By defaut, moint points are traversed.
|
||||
.It Cm ARCHIVE_READDISK_NO_XATTR
|
||||
Do not read extended file attributes (xattrs).
|
||||
By default, extended file attributes are read from disk.
|
||||
See
|
||||
.Xr xattr 7
|
||||
.Pq Linux ,
|
||||
.Xr xattr 2
|
||||
.Pq Mac OS X ,
|
||||
or
|
||||
.Xr getextattr 8
|
||||
.Pq FreeBSD
|
||||
for more information on extended file attributes.
|
||||
.It Cm ARCHIVE_READDISK_RESTORE_ATIME
|
||||
Restore access time of traversed files.
|
||||
By default, access time of traversed files is not restored.
|
||||
.El
|
||||
.It Xo
|
||||
.Fn archive_read_disk_set_symlink_logical ,
|
||||
.Fn archive_read_disk_set_symlink_physical ,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 28, 2017
|
||||
.Dd April 3, 2017
|
||||
.Dt ARCHIVE_WRITE_DISK 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -96,6 +96,33 @@ performance optimization in practice.
|
||||
The options field consists of a bitwise OR of one or more of the
|
||||
following values:
|
||||
.Bl -tag -compact -width "indent"
|
||||
.It Cm ARCHIVE_EXTRACT_ACL
|
||||
Attempt to restore Access Control Lists.
|
||||
By default, extended ACLs are ignored.
|
||||
.It Cm ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS
|
||||
Before removing a file system object prior to replacing it, clear
|
||||
platform-specific file flags which might prevent its removal.
|
||||
.It Cm ARCHIVE_EXTRACT_FFLAGS
|
||||
Attempt to restore file attributes (file flags).
|
||||
By default, file attributes are ignored.
|
||||
See
|
||||
.Xr chattr 1
|
||||
.Pq Linux
|
||||
or
|
||||
.Xr chflags 1
|
||||
.Pq FreeBSD, Mac OS X
|
||||
for more information on file attributes.
|
||||
.It Cm ARCHIVE_EXTRACT_MAC_METADATA
|
||||
Mac OS X specific. Restore metadata using
|
||||
.Xr copyfile 3 .
|
||||
By default,
|
||||
.Xr copyfile 3
|
||||
metadata is ignored.
|
||||
.It Cm ARCHIVE_EXTRACT_NO_OVERWRITE
|
||||
Existing files on disk will not be overwritten.
|
||||
By default, existing regular files are truncated and overwritten;
|
||||
existing directories will have their permissions updated;
|
||||
other pre-existing objects are unlinked and recreated from scratch.
|
||||
.It Cm ARCHIVE_EXTRACT_OWNER
|
||||
The user and group IDs should be set on the restored file.
|
||||
By default, the user and group IDs are not restored.
|
||||
@ -111,43 +138,9 @@ is not specified, then SUID and SGID bits will only be restored
|
||||
if the default user and group IDs of newly-created objects on disk
|
||||
happen to match those specified in the archive entry.
|
||||
By default, only basic permissions are restored, and umask is obeyed.
|
||||
.It Cm ARCHIVE_EXTRACT_TIME
|
||||
The timestamps (mtime, ctime, and atime) should be restored.
|
||||
By default, they are ignored.
|
||||
Note that restoring of atime is not currently supported.
|
||||
.It Cm ARCHIVE_EXTRACT_NO_OVERWRITE
|
||||
Existing files on disk will not be overwritten.
|
||||
By default, existing regular files are truncated and overwritten;
|
||||
existing directories will have their permissions updated;
|
||||
other pre-existing objects are unlinked and recreated from scratch.
|
||||
.It Cm ARCHIVE_EXTRACT_UNLINK
|
||||
Existing files on disk will be unlinked before any attempt to
|
||||
create them.
|
||||
In some cases, this can prove to be a significant performance improvement.
|
||||
By default, existing files are truncated and rewritten, but
|
||||
the file is not recreated.
|
||||
In particular, the default behavior does not break existing hard links.
|
||||
.It Cm ARCHIVE_EXTRACT_ACL
|
||||
Attempt to restore ACLs.
|
||||
By default, extended ACLs are ignored.
|
||||
.It Cm ARCHIVE_EXTRACT_FFLAGS
|
||||
Attempt to restore extended file flags.
|
||||
By default, file flags are ignored.
|
||||
.It Cm ARCHIVE_EXTRACT_XATTR
|
||||
Attempt to restore POSIX.1e extended attributes.
|
||||
By default, they are ignored.
|
||||
.It Cm ARCHIVE_EXTRACT_SECURE_SYMLINKS
|
||||
Refuse to extract any object whose final location would be altered
|
||||
by a symlink on disk.
|
||||
This is intended to help guard against a variety of mischief
|
||||
caused by archives that (deliberately or otherwise) extract
|
||||
files outside of the current directory.
|
||||
The default is not to perform this check.
|
||||
If
|
||||
.Cm ARCHIVE_EXTRACT_UNLINK
|
||||
is specified together with this option, the library will
|
||||
remove any intermediate symlinks it finds and return an
|
||||
error only if such symlink could not be removed.
|
||||
.It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS
|
||||
Refuse to extract an absolute path.
|
||||
The default is to not refuse such paths.
|
||||
.It Cm ARCHIVE_EXTRACT_SECURE_NODOTDOT
|
||||
Refuse to extract a path that contains a
|
||||
.Pa ..
|
||||
@ -156,16 +149,45 @@ The default is to not refuse such paths.
|
||||
Note that paths ending in
|
||||
.Pa ..
|
||||
always cause an error, regardless of this flag.
|
||||
.It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS
|
||||
Refuse to extract an absolute path.
|
||||
The default is to not refuse such paths.
|
||||
.It Cm ARCHIVE_EXTRACT_SECURE_SYMLINKS
|
||||
Refuse to extract any object whose final location would be altered
|
||||
by a symlink on disk.
|
||||
This is intended to help guard against a variety of mischief
|
||||
caused by archives that (deliberately or otherwise) extract
|
||||
files outside of the current directory.
|
||||
The default is not to perform this check.
|
||||
If
|
||||
.It Cm ARCHIVE_EXTRACT_SPARSE
|
||||
Scan data for blocks of NUL bytes and try to recreate them with holes.
|
||||
This results in sparse files, independent of whether the archive format
|
||||
supports or uses them.
|
||||
.It Cm ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS
|
||||
Before removing a file system object prior to replacing it, clear
|
||||
platform-specific file flags which might prevent its removal.
|
||||
.Cm ARCHIVE_EXTRACT_UNLINK
|
||||
is specified together with this option, the library will
|
||||
remove any intermediate symlinks it finds and return an
|
||||
error only if such symlink could not be removed.
|
||||
.It Cm ARCHIVE_EXTRACT_TIME
|
||||
The timestamps (mtime, ctime, and atime) should be restored.
|
||||
By default, they are ignored.
|
||||
Note that restoring of atime is not currently supported.
|
||||
.It Cm ARCHIVE_EXTRACT_UNLINK
|
||||
Existing files on disk will be unlinked before any attempt to
|
||||
create them.
|
||||
In some cases, this can prove to be a significant performance improvement.
|
||||
By default, existing files are truncated and rewritten, but
|
||||
the file is not recreated.
|
||||
In particular, the default behavior does not break existing hard links.
|
||||
.It Cm ARCHIVE_EXTRACT_XATTR
|
||||
Attempt to restore extended file attributes.
|
||||
By default, they are ignored.
|
||||
See
|
||||
.Xr xattr 7
|
||||
.Pq Linux ,
|
||||
.Xr xattr 2
|
||||
.Pq Mac OS X ,
|
||||
or
|
||||
.Xr getextattr 8
|
||||
.Pq FreeBSD
|
||||
for more information on extended file attributes.
|
||||
.El
|
||||
.It Xo
|
||||
.Fn archive_write_disk_set_group_lookup ,
|
||||
|
@ -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);
|
||||
#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 @@ 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 != (ssize_t)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
|
||||
|
@ -35,6 +35,7 @@ DEFINE_TEST(test_xattr_platform)
|
||||
struct archive_entry *ae;
|
||||
const char *name;
|
||||
const void *value;
|
||||
void *rvalue;
|
||||
size_t size, insize;
|
||||
int e, r;
|
||||
const char *attrname = "user.libarchive.test";
|
||||
@ -95,8 +96,9 @@ DEFINE_TEST(test_xattr_platform)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
value = getXattr("writetest", attrname, &insize);
|
||||
rvalue = getXattr("writetest", attrname, &insize);
|
||||
if (assertEqualInt(insize, strlen(writeval) + 1) != 0)
|
||||
assertEqualMem(value, writeval, insize);
|
||||
assertEqualMem(rvalue, writeval, insize);
|
||||
free(rvalue);
|
||||
#endif
|
||||
}
|
||||
|
@ -360,8 +360,10 @@ compare_acls(const char *path_a, const char *path_b)
|
||||
if (richacl_a != NULL) {
|
||||
richacl_b = richacl_get_file(path_b);
|
||||
if (richacl_b == NULL &&
|
||||
(errno == ENODATA || errno == ENOTSUP || errno == ENOSYS))
|
||||
(errno == ENODATA || errno == ENOTSUP || errno == ENOSYS)) {
|
||||
richacl_free(richacl_a);
|
||||
return (0);
|
||||
}
|
||||
failure("richacl_get_file() error: %s (%s)", path_b,
|
||||
strerror(errno));
|
||||
if (assert(richacl_b != NULL) == 0) {
|
||||
|
@ -33,7 +33,7 @@ DEFINE_TEST(test_option_xattrs)
|
||||
|
||||
const char *testattr = "user.libarchive.test";
|
||||
const char *testval = "testval";
|
||||
const void *readval;
|
||||
void *readval;
|
||||
size_t size;
|
||||
int r;
|
||||
|
||||
@ -62,6 +62,7 @@ DEFINE_TEST(test_option_xattrs)
|
||||
readval = getXattr("xattrs_xattrs/f", testattr, &size);
|
||||
if(assertEqualInt(size, strlen(testval) + 1) != 0)
|
||||
assertEqualMem(readval, testval, size);
|
||||
free(readval);
|
||||
|
||||
/* Extract xattrs without xattrs */
|
||||
assertMakeDir("xattrs_noxattrs", 0755);
|
||||
|
@ -348,7 +348,7 @@ int canNodump(void);
|
||||
int setTestAcl(const char *path);
|
||||
|
||||
/* Get extended attribute */
|
||||
const void *getXattr(const char *, const char *, size_t *);
|
||||
void *getXattr(const char *, const char *, size_t *);
|
||||
|
||||
/* Set extended attribute */
|
||||
int setXattr(const char *, const char *, const void *, size_t);
|
||||
|
@ -2451,8 +2451,8 @@ canNodump(void)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Get extended attribute from a path */
|
||||
const void *
|
||||
/* Get extended attribute value from a path */
|
||||
void *
|
||||
getXattr(const char *path, const char *name, size_t *sizep)
|
||||
{
|
||||
void *value = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user