From: Tim Kientzle Date: Sat, 6 Sep 2008 16:33:54 +0000 (-0400) Subject: IFC X-Git-Tag: v2.6.0~97 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e9c0ba8344e41be4057740c4915c7a296d40288e;p=thirdparty%2Flibarchive.git IFC SVN-Revision: 196 --- diff --git a/libarchive/archive_entry_link_resolver.c b/libarchive/archive_entry_link_resolver.c index 6f3069cc6..9300fe311 100644 --- a/libarchive/archive_entry_link_resolver.c +++ b/libarchive/archive_entry_link_resolver.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_link_resolver.c,v 1.3 2008/06/15 04:31:43 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_link_resolver.c,v 1.4 2008/09/05 06:15:25 kientzle Exp $"); #ifdef HAVE_SYS_STAT_H #include diff --git a/libarchive/archive_write_disk.c b/libarchive/archive_write_disk.c index 750b09fba..40b401443 100644 --- a/libarchive/archive_write_disk.c +++ b/libarchive/archive_write_disk.c @@ -25,7 +25,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.33 2008/09/01 02:50:24 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.35 2008/09/05 06:13:11 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include @@ -1011,7 +1011,7 @@ create_filesystem_object(struct archive_write_disk *a) * If the hardlink does carry data, let the last * archive entry decide ownership. */ - if (r == 0 && a->filesize == 0) { + if (r == 0 && a->filesize <= 0) { a->todo = 0; a->deferred = 0; } if (r == 0 && a->filesize > 0) { diff --git a/libarchive/test/test_write_disk.c b/libarchive/test/test_write_disk.c index c786a762b..4abba62de 100644 --- a/libarchive/test/test_write_disk.c +++ b/libarchive/test/test_write_disk.c @@ -23,7 +23,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "test.h" -__FBSDID("$FreeBSD: src/lib/libarchive/test/test_write_disk.c,v 1.13 2008/09/01 05:38:33 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/test/test_write_disk.c,v 1.14 2008/09/05 06:13:11 kientzle Exp $"); #if ARCHIVE_VERSION_NUMBER >= 1009000 diff --git a/libarchive/test/test_write_disk_hardlink.c b/libarchive/test/test_write_disk_hardlink.c index 74e75a633..5fd626b35 100644 --- a/libarchive/test/test_write_disk_hardlink.c +++ b/libarchive/test/test_write_disk_hardlink.c @@ -23,7 +23,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "test.h" -__FBSDID("$FreeBSD: src/lib/libarchive/test/test_write_disk_hardlink.c,v 1.4 2008/09/01 05:38:33 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/test/test_write_disk_hardlink.c,v 1.5 2008/09/05 06:13:11 kientzle Exp $"); #define UMASK 022 @@ -61,14 +61,15 @@ DEFINE_TEST(test_write_disk_hardlink) archive_entry_set_mode(ae, S_IFREG | 0755); archive_entry_set_size(ae, sizeof(data)); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); + assertEqualInt(sizeof(data), + archive_write_data(ad, data, sizeof(data))); assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); archive_entry_free(ae); - /* Link. */ + /* Link. Size of zero means this doesn't carry data. */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "link1b"); - archive_entry_set_mode(ae, S_IFREG | 0600); + archive_entry_set_mode(ae, S_IFREG | 0642); archive_entry_set_size(ae, 0); archive_entry_copy_hardlink(ae, "link1a"); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); @@ -77,6 +78,34 @@ DEFINE_TEST(test_write_disk_hardlink) assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); archive_entry_free(ae); + /* + * Repeat tar approach test, but use unset to mark the + * hardlink as having no data. + */ + + /* Regular file. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "link2a"); + archive_entry_set_mode(ae, S_IFREG | 0755); + archive_entry_set_size(ae, sizeof(data)); + assertEqualIntA(ad, 0, archive_write_header(ad, ae)); + assertEqualInt(sizeof(data), + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + archive_entry_free(ae); + + /* Link. Unset size means this doesn't carry data. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "link2b"); + archive_entry_set_mode(ae, S_IFREG | 0642); + archive_entry_unset_size(ae); + archive_entry_copy_hardlink(ae, "link2a"); + assertEqualIntA(ad, 0, archive_write_header(ad, ae)); + assertEqualInt(ARCHIVE_WARN, + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + archive_entry_free(ae); + /* * Second, try an old-cpio-like approach; a regular file, then * another identical one (which has been marked hardlink). @@ -84,7 +113,7 @@ DEFINE_TEST(test_write_disk_hardlink) /* Regular file. */ assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link2a"); + archive_entry_copy_pathname(ae, "link3a"); archive_entry_set_mode(ae, S_IFREG | 0600); archive_entry_set_size(ae, sizeof(data)); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); @@ -94,10 +123,10 @@ DEFINE_TEST(test_write_disk_hardlink) /* Link. */ assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link2b"); + archive_entry_copy_pathname(ae, "link3b"); archive_entry_set_mode(ae, S_IFREG | 0755); archive_entry_set_size(ae, sizeof(data)); - archive_entry_copy_hardlink(ae, "link2a"); + archive_entry_copy_hardlink(ae, "link3a"); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); @@ -110,7 +139,7 @@ DEFINE_TEST(test_write_disk_hardlink) /* Regular file. */ assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link3a"); + archive_entry_copy_pathname(ae, "link4a"); archive_entry_set_mode(ae, S_IFREG | 0600); archive_entry_set_size(ae, 0); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); @@ -124,10 +153,10 @@ DEFINE_TEST(test_write_disk_hardlink) /* Link. */ assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link3b"); + archive_entry_copy_pathname(ae, "link4b"); archive_entry_set_mode(ae, S_IFREG | 0755); archive_entry_set_size(ae, sizeof(data)); - archive_entry_copy_hardlink(ae, "link3a"); + archive_entry_copy_hardlink(ae, "link4a"); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); @@ -139,36 +168,63 @@ DEFINE_TEST(test_write_disk_hardlink) #endif /* Test the entries on disk. */ + + /* Test #1 */ assert(0 == stat("link1a", &st)); + /* If the hardlink was successfully created and the archive + * doesn't carry data for it, we consider it to be + * non-authoritive for meta data as well. This is consistent + * with GNU tar and BSD pax. */ assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK); assertEqualInt(st.st_size, sizeof(data)); assertEqualInt(st.st_nlink, 2); assert(0 == stat("link1b", &st2)); - assertEqualInt(st2.st_mode, (S_IFREG | 0755) & ~UMASK); - assertEqualInt(st2.st_size, sizeof(data)); - assertEqualInt(st2.st_nlink, 2); + assertEqualInt(st.st_mode, st2.st_mode); + assertEqualInt(st.st_size, st2.st_size); + assertEqualInt(st.st_nlink, st2.st_nlink); assertEqualInt(st.st_ino, st2.st_ino); assertEqualInt(st.st_dev, st2.st_dev); + /* Test #2: Should produce identical results to test #1 */ + /* Note that marking a hardlink with size = 0 is treated the + * same as having an unset size. This is partly for backwards + * compatibility (we used to not have unset tracking, so + * relied on size == 0) and partly to match the model used by + * common file formats that store a size of zero for + * hardlinks. */ assert(0 == stat("link2a", &st)); assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK); assertEqualInt(st.st_size, sizeof(data)); assertEqualInt(st.st_nlink, 2); assert(0 == stat("link2b", &st2)); + assertEqualInt(st.st_mode, st2.st_mode); + assertEqualInt(st.st_size, st2.st_size); + assertEqualInt(st.st_nlink, st2.st_nlink); + assertEqualInt(st.st_ino, st2.st_ino); + assertEqualInt(st.st_dev, st2.st_dev); + + /* Test #3 */ + assert(0 == stat("link3a", &st)); + assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK); + assertEqualInt(st.st_size, sizeof(data)); + assertEqualInt(st.st_nlink, 2); + + assert(0 == stat("link3b", &st2)); assertEqualInt(st2.st_mode, (S_IFREG | 0755) & ~UMASK); assertEqualInt(st2.st_size, sizeof(data)); assertEqualInt(st2.st_nlink, 2); assertEqualInt(st.st_ino, st2.st_ino); assertEqualInt(st.st_dev, st2.st_dev); - assert(0 == stat("link3a", &st)); + /* Test #4 */ + assert(0 == stat("link4a", &st)); assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK); assertEqualInt(st.st_size, sizeof(data)); assertEqualInt(st.st_nlink, 2); - assert(0 == stat("link3b", &st2)); + assert(0 == stat("link4b", &st2)); assertEqualInt(st2.st_mode, (S_IFREG | 0755) & ~UMASK); assertEqualInt(st2.st_size, sizeof(data)); assertEqualInt(st2.st_nlink, 2);