diff options
author | kientzle <kientzle@FreeBSD.org> | 2009-03-06 04:55:51 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2009-03-06 04:55:51 +0000 |
commit | 0e3959e0048adeb8162dda94e7d22719dc53d19d (patch) | |
tree | e7f6ccf2c08974aeaad7391510b0ad147506d8f5 /lib/libarchive/test/test_extattr_freebsd.c | |
parent | 409cc977f6064716e39b1fec8562cb8aaab07e48 (diff) | |
download | FreeBSD-src-0e3959e0048adeb8162dda94e7d22719dc53d19d.zip FreeBSD-src-0e3959e0048adeb8162dda94e7d22719dc53d19d.tar.gz |
Merge r416 from libarchive.googlecode.com:
Restoring POSIX.1e Extended Attributes on FreeBSD, part 1
This implements the basic ability to restore extended attributes
on FreeBSD, including a test suite.
Diffstat (limited to 'lib/libarchive/test/test_extattr_freebsd.c')
-rw-r--r-- | lib/libarchive/test/test_extattr_freebsd.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/lib/libarchive/test/test_extattr_freebsd.c b/lib/libarchive/test/test_extattr_freebsd.c new file mode 100644 index 0000000..72575dd --- /dev/null +++ b/lib/libarchive/test/test_extattr_freebsd.c @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 2003-2009 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +#if defined(__FreeBSD__) && __FreeBSD__ > 4 +#include <sys/extattr.h> +#endif + +/* + * Verify extended attribute restore-to-disk. This test is FreeBSD-specific. + */ + +DEFINE_TEST(test_extattr_freebsd) +{ +#if !defined(__FreeBSD__) + skipping("FreeBSD-specific extattr restore test"); +#elif __FreeBSD__ < 5 + skipping("extattr restore supported only on FreeBSD 5.0 and later"); +#else + char buff[64]; + struct stat st; + struct archive *a; + struct archive_entry *ae; + int n, fd; + int extattr_privilege_bug = 0; + + /* + * First, do a quick manual set/read of an extended attribute + * to verify that the local filesystem does support it. If it + * doesn't, we'll simply skip the remaining tests. + */ + /* Create a test file and try to set an ACL on it. */ + fd = open("pretest", O_RDWR | O_CREAT, 0777); + failure("Could not create test file?!"); + if (!assert(fd >= 0)) + return; + + errno = 0; + n = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, "testattr", "1234", 4); + if (n != 4 && errno == EOPNOTSUPP) { + close(fd); + skipping("extattr tests require that extattr support be enabled on the filesystem"); + return; + } + failure("extattr_set_fd(): errno=%d (%s)", errno, strerror(errno)); + assertEqualInt(4, n); + close(fd); + + /* + * Repeat the above, but with file permissions set to 0000. + * This should work (extattr_set_fd() should follow fd + * permissions, not file permissions), but is known broken on + * some versions of FreeBSD. + */ + fd = open("pretest2", O_RDWR | O_CREAT, 00000); + failure("Could not create test file?!"); + if (!assert(fd >= 0)) + return; + + n = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, "testattr", "1234", 4); + if (n != 4) { + skipping("Restoring xattr to an unwritable file (broken in some versions of FreeBSD"); + extattr_privilege_bug = 1; + } + close(fd); + + /* Create a write-to-disk object. */ + assert(NULL != (a = archive_write_disk_new())); + archive_write_disk_set_options(a, + ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_XATTR); + + /* Populate an archive entry with an extended attribute. */ + ae = archive_entry_new(); + assert(ae != NULL); + archive_entry_set_pathname(ae, "test0"); + archive_entry_set_mtime(ae, 123456, 7890); + archive_entry_set_size(ae, 0); + archive_entry_set_mode(ae, 0755); + archive_entry_xattr_add_entry(ae, "user.foo", "12345", 5); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + + /* Another entry; similar but with mode = 0. */ + ae = archive_entry_new(); + assert(ae != NULL); + archive_entry_set_pathname(ae, "test1"); + archive_entry_set_mtime(ae, 12345678, 7890); + archive_entry_set_size(ae, 0); + archive_entry_set_mode(ae, 0); + archive_entry_xattr_add_entry(ae, "user.bar", "123456", 6); + if (extattr_privilege_bug) + /* If the bug is here, write_header will return warning. */ + assertEqualIntA(a, ARCHIVE_WARN, + archive_write_header(a, ae)); + else + assertEqualIntA(a, ARCHIVE_OK, + archive_write_header(a, ae)); + archive_entry_free(ae); + + /* Close the archive. */ + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualInt(ARCHIVE_OK, archive_write_finish(a)); + + /* Verify the data on disk. */ + assertEqualInt(0, stat("test0", &st)); + assertEqualInt(st.st_mtime, 123456); + /* Verify extattr */ + n = extattr_get_file("test0", EXTATTR_NAMESPACE_USER, + "foo", buff, sizeof(buff)); + if (assertEqualInt(n, 5)) { + buff[n] = '\0'; + assertEqualString(buff, "12345"); + } + + /* Verify the data on disk. */ + assertEqualInt(0, stat("test1", &st)); + assertEqualInt(st.st_mtime, 12345678); + /* Verify extattr */ + n = extattr_get_file("test1", EXTATTR_NAMESPACE_USER, + "bar", buff, sizeof(buff)); + if (extattr_privilege_bug) { + /* If we have the bug, the extattr won't have been written. */ + assertEqualInt(n, -1); + } else { + if (assertEqualInt(n, 6)) { + buff[n] = '\0'; + assertEqualString(buff, "123456"); + } + } +#endif +} |