From: Tim Kientzle Date: Mon, 5 May 2008 22:09:38 +0000 (-0400) Subject: More test files from my local tree that somehow didn't make it into p4. X-Git-Tag: v2.6.0~264 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4beb0209a750c36bfe738e5b63378d3a2cc4d8cd;p=thirdparty%2Flibarchive.git More test files from my local tree that somehow didn't make it into p4. SVN-Revision: 28 --- diff --git a/libarchive/test/test_link_resolver.c b/libarchive/test/test_link_resolver.c new file mode 100644 index 000000000..a51e4a4dd --- /dev/null +++ b/libarchive/test/test_link_resolver.c @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2003-2007 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$"); + +static void test_linkify_tar(void) +{ + struct archive_entry *entry, *e2; + struct archive_entry_linkresolver *resolver; + + /* Initialize the resolver. */ + assert(NULL != (resolver = archive_entry_linkresolver_new())); + archive_entry_linkresolver_set_strategy(resolver, + ARCHIVE_FORMAT_TAR_USTAR); + + /* Create an entry with only 1 link and try to linkify it. */ + assert(NULL != (entry = archive_entry_new())); + archive_entry_set_pathname(entry, "test1"); + archive_entry_set_ino(entry, 1); + archive_entry_set_dev(entry, 2); + archive_entry_set_nlink(entry, 1); + archive_entry_set_size(entry, 10); + archive_entry_linkify(resolver, &entry, &e2); + + /* Shouldn't have been changed. */ + assert(e2 == NULL); + assertEqualInt(10, archive_entry_size(entry)); + assertEqualString("test1", archive_entry_pathname(entry)); + + /* Now, try again with an entry that has 2 links. */ + archive_entry_set_pathname(entry, "test2"); + archive_entry_set_nlink(entry, 2); + archive_entry_set_ino(entry, 2); + archive_entry_linkify(resolver, &entry, &e2); + /* Shouldn't be altered, since it wasn't seen before. */ + assert(e2 == NULL); + assertEqualString("test2", archive_entry_pathname(entry)); + assertEqualString(NULL, archive_entry_hardlink(entry)); + assertEqualInt(10, archive_entry_size(entry)); + + /* Match again and make sure it does get altered. */ + archive_entry_linkify(resolver, &entry, &e2); + assert(e2 == NULL); + assertEqualString("test2", archive_entry_pathname(entry)); + assertEqualString("test2", archive_entry_hardlink(entry)); + assertEqualInt(0, archive_entry_size(entry)); + + + archive_entry_free(entry); + archive_entry_linkresolver_free(resolver); +} + +static void test_linkify_old_cpio(void) +{ + struct archive_entry *entry, *e2; + struct archive_entry_linkresolver *resolver; + + /* Initialize the resolver. */ + assert(NULL != (resolver = archive_entry_linkresolver_new())); + archive_entry_linkresolver_set_strategy(resolver, + ARCHIVE_FORMAT_CPIO_POSIX); + + /* Create an entry with 2 link and try to linkify it. */ + assert(NULL != (entry = archive_entry_new())); + archive_entry_set_pathname(entry, "test1"); + archive_entry_set_ino(entry, 1); + archive_entry_set_dev(entry, 2); + archive_entry_set_nlink(entry, 2); + archive_entry_set_size(entry, 10); + archive_entry_linkify(resolver, &entry, &e2); + + /* Shouldn't have been changed. */ + assert(e2 == NULL); + assertEqualInt(10, archive_entry_size(entry)); + assertEqualString("test1", archive_entry_pathname(entry)); + + /* Still shouldn't be matched. */ + archive_entry_linkify(resolver, &entry, &e2); + assert(e2 == NULL); + assertEqualString("test1", archive_entry_pathname(entry)); + assertEqualString(NULL, archive_entry_hardlink(entry)); + assertEqualInt(10, archive_entry_size(entry)); + + archive_entry_free(entry); + archive_entry_linkresolver_free(resolver); +} + +static void test_linkify_new_cpio(void) +{ + struct archive_entry *entry, *e2; + struct archive_entry_linkresolver *resolver; + + /* Initialize the resolver. */ + assert(NULL != (resolver = archive_entry_linkresolver_new())); + archive_entry_linkresolver_set_strategy(resolver, + ARCHIVE_FORMAT_CPIO_SVR4_NOCRC); + + /* Create an entry with only 1 link and try to linkify it. */ + assert(NULL != (entry = archive_entry_new())); + archive_entry_set_pathname(entry, "test1"); + archive_entry_set_ino(entry, 1); + archive_entry_set_dev(entry, 2); + archive_entry_set_nlink(entry, 1); + archive_entry_set_size(entry, 10); + archive_entry_linkify(resolver, &entry, &e2); + + /* Shouldn't have been changed. */ + assert(e2 == NULL); + assertEqualInt(10, archive_entry_size(entry)); + assertEqualString("test1", archive_entry_pathname(entry)); + + /* Now, try again with an entry that has 3 links. */ + archive_entry_set_pathname(entry, "test2"); + archive_entry_set_nlink(entry, 3); + archive_entry_set_ino(entry, 2); + archive_entry_linkify(resolver, &entry, &e2); + + /* First time, it just gets swallowed. */ + assert(entry == NULL); + assert(e2 == NULL); + + /* Match again. */ + assert(NULL != (entry = archive_entry_new())); + archive_entry_set_pathname(entry, "test3"); + archive_entry_set_ino(entry, 2); + archive_entry_set_dev(entry, 2); + archive_entry_set_nlink(entry, 2); + archive_entry_set_size(entry, 10); + archive_entry_linkify(resolver, &entry, &e2); + + /* Should get back "test2" and nothing else. */ + assertEqualString("test2", archive_entry_pathname(entry)); + assertEqualInt(0, archive_entry_size(entry)); + archive_entry_free(entry); + assert(NULL == e2); + archive_entry_free(e2); /* This should be a no-op. */ + + /* Match a third time. */ + assert(NULL != (entry = archive_entry_new())); + archive_entry_set_pathname(entry, "test4"); + archive_entry_set_ino(entry, 2); + archive_entry_set_dev(entry, 2); + archive_entry_set_nlink(entry, 3); + archive_entry_set_size(entry, 10); + archive_entry_linkify(resolver, &entry, &e2); + + /* Should get back "test3". */ + assertEqualString("test3", archive_entry_pathname(entry)); + assertEqualInt(0, archive_entry_size(entry)); + + /* Since "test4" was the last link, should get it back also. */ + assertEqualString("test4", archive_entry_pathname(e2)); + assertEqualInt(10, archive_entry_size(e2)); + + archive_entry_free(entry); + archive_entry_free(e2); + archive_entry_linkresolver_free(resolver); +} + +DEFINE_TEST(test_link_resolver) +{ + test_linkify_tar(); + test_linkify_old_cpio(); + test_linkify_new_cpio(); +} diff --git a/libarchive/test/test_read_format_tar_empty_filename.c b/libarchive/test/test_read_format_tar_empty_filename.c new file mode 100644 index 000000000..d9ba69bd9 --- /dev/null +++ b/libarchive/test/test_read_format_tar_empty_filename.c @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2003-2007 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$"); + +/* + * Tar entries with empty filenames are unusual, but shouldn't crash us. + */ +DEFINE_TEST(test_read_format_tar_empty_filename) +{ + char name[] = "test_read_format_tar_empty_filename.tar"; + struct archive_entry *ae; + struct archive *a; + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + extract_reference_file(name); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); + + /* Read first entry. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("", archive_entry_pathname(ae)); + assertEqualInt(1208628157, archive_entry_mtime(ae)); + assertEqualInt(1000, archive_entry_uid(ae)); + assertEqualString("tim", archive_entry_uname(ae)); + assertEqualInt(0, archive_entry_gid(ae)); + assertEqualString("wheel", archive_entry_gname(ae)); + assertEqualInt(040775, archive_entry_mode(ae)); + + /* Verify the end-of-archive. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify that the format detection worked. */ + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); + + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); +#if ARCHIVE_API_VERSION > 1 + assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); +#else + archive_read_finish(a); +#endif +} diff --git a/libarchive/test/test_read_format_tar_empty_filename.tar.uu b/libarchive/test/test_read_format_tar_empty_filename.tar.uu new file mode 100644 index 000000000..7a34c82ca --- /dev/null +++ b/libarchive/test/test_read_format_tar_empty_filename.tar.uu @@ -0,0 +1,38 @@ +begin 644 test_compat_tar_1.tar +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````#`P,# 0) { + for (; i < dlen; i++) + filename[i] = 'a'; + filename[i++] = '/'; + separator = 1; + } + for (; i < dlen + flen + separator; i++) + filename[i] = 'b'; + filename[i++] = '\0'; + + strcpy(dirname, filename); + + /* Create a new archive in memory. */ + assert((a = archive_write_new()) != NULL); + assertA(0 == archive_write_set_format_ustar(a)); + assertA(0 == archive_write_set_compression_none(a)); + assertA(0 == archive_write_set_bytes_per_block(a,0)); + assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); + + /* + * Write a file to it. + */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, filename); + archive_entry_set_mode(ae, S_IFREG | 0755); + failure("dlen=%d, flen=%d", dlen, flen); + if (flen > 100) { + assertEqualIntA(a, ARCHIVE_WARN, archive_write_header(a, ae)); + } else { + assertEqualIntA(a, 0, archive_write_header(a, ae)); + } + archive_entry_free(ae); + + /* + * Write a dir to it (without trailing '/'). + */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, dirname); + archive_entry_set_mode(ae, S_IFDIR | 0755); + failure("dlen=%d, flen=%d", dlen, flen); + if (flen >= 100) { + assertEqualIntA(a, ARCHIVE_WARN, archive_write_header(a, ae)); + } else { + assertEqualIntA(a, 0, archive_write_header(a, ae)); + } + archive_entry_free(ae); + + /* Tar adds a '/' to directory names. */ + strcat(dirname, "/"); + + /* + * Write a dir to it (with trailing '/'). + */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, dirname); + archive_entry_set_mode(ae, S_IFDIR | 0755); + failure("dlen=%d, flen=%d", dlen, flen); + if (flen >= 100) { + assertEqualIntA(a, ARCHIVE_WARN, archive_write_header(a, ae)); + } else { + assertEqualIntA(a, 0, archive_write_header(a, ae)); + } + archive_entry_free(ae); + + /* Close out the archive. */ + assertA(0 == archive_write_close(a)); + assertA(0 == archive_write_finish(a)); + + /* + * Now, read the data back. + */ + assert((a = archive_read_new()) != NULL); + assertA(0 == archive_read_support_format_all(a)); + assertA(0 == archive_read_support_compression_all(a)); + assertA(0 == archive_read_open_memory(a, buff, used)); + + if (flen <= 100) { + /* Read the file and check the filename. */ + assertA(0 == archive_read_next_header(a, &ae)); + failure("dlen=%d, flen=%d", dlen, flen); + assertEqualString(filename, archive_entry_pathname(ae)); + assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); + } + + /* + * Read the two dirs and check the names. + * + * Both dirs should read back with the same name, since + * tar should add a trailing '/' to any dir that doesn't + * already have one. + */ + if (flen <= 99) { + assertA(0 == archive_read_next_header(a, &ae)); + assert((S_IFDIR | 0755) == archive_entry_mode(ae)); + failure("dlen=%d, flen=%d", dlen, flen); + assertEqualString(dirname, archive_entry_pathname(ae)); + } + + if (flen <= 99) { + assertA(0 == archive_read_next_header(a, &ae)); + assert((S_IFDIR | 0755) == archive_entry_mode(ae)); + assertEqualString(dirname, archive_entry_pathname(ae)); + } + + /* Verify the end of the archive. */ + failure("This fails if entries were written that should not have been written. dlen=%d, flen=%d", dlen, flen); + assertEqualInt(1, archive_read_next_header(a, &ae)); + assert(0 == archive_read_close(a)); + assert(0 == archive_read_finish(a)); +} + +DEFINE_TEST(test_ustar_filenames) +{ + int dlen, flen; + + /* Try a bunch of different file/dir lengths that add up + * to just a little less or a little more than 100 bytes. + * This exercises the code that splits paths between ustar + * filename and prefix fields. + */ + for (dlen = 5; dlen < 70; dlen += 5) { + for (flen = 100 - dlen - 5; flen < 100 - dlen + 5; flen++) { + test_filename(NULL, dlen, flen); + test_filename("/", dlen, flen); + } + } + + /* Probe the 100-char limit for paths with no '/'. */ + for (flen = 90; flen < 110; flen++) { + test_filename(NULL, 0, flen); + test_filename("/", dlen, flen); + } + + /* XXXX TODO Probe the 100-char limit with a dir prefix. */ + /* XXXX TODO Probe the 255-char total limit. */ +} diff --git a/libarchive/test/test_write_format_tar_ustar.c b/libarchive/test/test_write_format_tar_ustar.c new file mode 100644 index 000000000..53eb07cf7 --- /dev/null +++ b/libarchive/test/test_write_format_tar_ustar.c @@ -0,0 +1,342 @@ +/*- + * Copyright (c) 2003-2007 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$"); + +static int +is_null(const char *p, size_t l) +{ + while (l > 0) { + if (*p != '\0') + return (0); + --l; + ++p; + } + return (1); +} + +/* Verify the contents, then erase them to NUL bytes. */ +/* Tar requires all "unused" bytes be set to NUL; this allows us + * to easily verify that by invoking is_null() over the entire header + * after verifying each field. */ +#define myAssertEqualMem(a,b,s) assertEqualMem(a, b, s); memset(a, 0, s) + +/* + * Detailed verification that 'ustar' archives are written with + * the correct format. + */ +DEFINE_TEST(test_write_format_tar_ustar) +{ + struct archive *a; + struct archive_entry *entry; + char *buff, *e; + size_t buffsize = 100000; + size_t used; + int i; + char f99[100]; + char f100[101]; + char f256[257]; + + for (i = 0; i < 99; ++i) + f99[i] = 'a' + i % 26; + f99[99] = '\0'; + + for (i = 0; i < 100; ++i) + f100[i] = 'A' + i % 26; + f100[100] = '\0'; + + for (i = 0; i < 256; ++i) + f256[i] = 'A' + i % 26; + f256[155] = '/'; + f256[256] = '\0'; + + buff = malloc(buffsize); + + /* Create a new archive in memory. */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, 0, archive_write_set_format_ustar(a)); + assertEqualIntA(a, 0, archive_write_set_compression_none(a)); + assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used)); + + /* + * Add various files to it. + * TODO: Extend this to cover more filetypes. + */ + + /* "file" with 10 bytes of content */ + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_mtime(entry, 1, 10); + archive_entry_set_pathname(entry, "file"); + archive_entry_set_mode(entry, S_IFREG | 0664); + archive_entry_set_size(entry, 10); + archive_entry_set_uid(entry, 80); + archive_entry_set_gid(entry, 90); + archive_entry_set_dev(entry, 12); + archive_entry_set_ino(entry, 89); + archive_entry_set_nlink(entry, 2); + assertEqualIntA(a, 0, archive_write_header(a, entry)); + archive_entry_free(entry); + assertEqualIntA(a, 10, archive_write_data(a, "1234567890", 10)); + + /* Hardlink to "file" with 10 bytes of content */ + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_mtime(entry, 1, 10); + archive_entry_set_pathname(entry, "linkfile"); + archive_entry_set_mode(entry, S_IFREG | 0664); + /* TODO: Put this back and fix the bug. */ + /* archive_entry_set_size(entry, 10); */ + archive_entry_set_uid(entry, 80); + archive_entry_set_gid(entry, 90); + archive_entry_set_dev(entry, 12); + archive_entry_set_ino(entry, 89); + archive_entry_set_nlink(entry, 2); + assertEqualIntA(a, 0, archive_write_header(a, entry)); + archive_entry_free(entry); + /* Write of data to dir should fail == zero bytes get written. */ + assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); + + /* "dir" */ + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_mtime(entry, 2, 20); + archive_entry_set_pathname(entry, "dir"); + archive_entry_set_mode(entry, S_IFDIR | 0775); + archive_entry_set_size(entry, 10); + archive_entry_set_nlink(entry, 2); + assertEqualIntA(a, 0, archive_write_header(a, entry)); + archive_entry_free(entry); + /* Write of data to dir should fail == zero bytes get written. */ + assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); + + /* "symlink" pointing to "file" */ + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_mtime(entry, 3, 30); + archive_entry_set_pathname(entry, "symlink"); + archive_entry_set_mode(entry, S_IFLNK | 0664); + archive_entry_set_symlink(entry,"file"); + archive_entry_set_size(entry, 0); + archive_entry_set_uid(entry, 88); + archive_entry_set_gid(entry, 98); + archive_entry_set_dev(entry, 12); + archive_entry_set_ino(entry, 90); + archive_entry_set_nlink(entry, 1); + assertEqualIntA(a, 0, archive_write_header(a, entry)); + archive_entry_free(entry); + /* Write of data to symlink should fail == zero bytes get written. */ + assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); + + /* file with 99-char filename. */ + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_mtime(entry, 1, 10); + archive_entry_set_pathname(entry, f99); + archive_entry_set_mode(entry, S_IFREG | 0664); + archive_entry_set_size(entry, 0); + archive_entry_set_uid(entry, 82); + archive_entry_set_gid(entry, 93); + archive_entry_set_dev(entry, 102); + archive_entry_set_ino(entry, 7); + archive_entry_set_nlink(entry, 1); + assertEqualIntA(a, 0, archive_write_header(a, entry)); + archive_entry_free(entry); + + /* file with 100-char filename. */ + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_mtime(entry, 1, 10); + archive_entry_set_pathname(entry, f100); + archive_entry_set_mode(entry, S_IFREG | 0664); + archive_entry_set_size(entry, 0); + archive_entry_set_uid(entry, 82); + archive_entry_set_gid(entry, 93); + archive_entry_set_dev(entry, 102); + archive_entry_set_ino(entry, 7); + archive_entry_set_nlink(entry, 1); + assertEqualIntA(a, 0, archive_write_header(a, entry)); + archive_entry_free(entry); + + /* file with 256-char filename. */ + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_mtime(entry, 1, 10); + archive_entry_set_pathname(entry, f256); + archive_entry_set_mode(entry, S_IFREG | 0664); + archive_entry_set_size(entry, 0); + archive_entry_set_uid(entry, 82); + archive_entry_set_gid(entry, 93); + archive_entry_set_dev(entry, 102); + archive_entry_set_ino(entry, 7); + archive_entry_set_nlink(entry, 1); + assertEqualIntA(a, 0, archive_write_header(a, entry)); + archive_entry_free(entry); + + assert(0 == archive_write_finish(a)); + + /* + * Verify the archive format. + */ + e = buff; + + /* "file" */ + myAssertEqualMem(e + 0, "file", 5); /* Filename */ + myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ + myAssertEqualMem(e + 108, "000120 ", 8); /* uid */ + myAssertEqualMem(e + 116, "000132 ", 8); /* gid */ + myAssertEqualMem(e + 124, "00000000012 ", 12); /* size */ + myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ + myAssertEqualMem(e + 148, "010034\0 ", 8); /* checksum */ + myAssertEqualMem(e + 156, "0", 1); /* linkflag */ + myAssertEqualMem(e + 157, "", 1); /* linkname */ + myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ + myAssertEqualMem(e + 265, "", 1); /* uname */ + myAssertEqualMem(e + 297, "", 1); /* gname */ + myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ + myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ + myAssertEqualMem(e + 345, "", 1); /* prefix */ + assert(is_null(e + 0, 512)); + myAssertEqualMem(e + 512, "1234567890", 10); + assert(is_null(e + 512, 512)); + e += 1024; + + /* hardlink to "file" */ + myAssertEqualMem(e + 0, "linkfile", 9); /* Filename */ + myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ + myAssertEqualMem(e + 108, "000120 ", 8); /* uid */ + myAssertEqualMem(e + 116, "000132 ", 8); /* gid */ + myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ + myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ + myAssertEqualMem(e + 148, "010707\0 ", 8); /* checksum */ + myAssertEqualMem(e + 156, "0", 1); /* linkflag */ + myAssertEqualMem(e + 157, "", 1); /* linkname */ + myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ + myAssertEqualMem(e + 265, "", 1); /* uname */ + myAssertEqualMem(e + 297, "", 1); /* gname */ + myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ + myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ + myAssertEqualMem(e + 345, "", 1); /* prefix */ + assert(is_null(e + 0, 512)); + e += 512; + + /* "dir" */ + myAssertEqualMem(e + 0, "dir/", 4); /* Filename */ + myAssertEqualMem(e + 100, "000775 ", 8); /* mode */ + myAssertEqualMem(e + 108, "000000 ", 8); /* uid */ + myAssertEqualMem(e + 116, "000000 ", 8); /* gid */ + myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ + myAssertEqualMem(e + 136, "00000000002 ", 12); /* mtime */ + myAssertEqualMem(e + 148, "007747\0 ", 8); /* checksum */ + myAssertEqualMem(e + 156, "5", 1); /* typeflag */ + myAssertEqualMem(e + 157, "", 1); /* linkname */ + myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ + myAssertEqualMem(e + 265, "", 1); /* uname */ + myAssertEqualMem(e + 297, "", 1); /* gname */ + myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ + myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ + myAssertEqualMem(e + 345, "", 1); /* prefix */ + assert(is_null(e + 0, 512)); + e += 512; + + /* "symlink" pointing to "file" */ + myAssertEqualMem(e + 0, "symlink", 8); /* Filename */ + myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ + myAssertEqualMem(e + 108, "000130 ", 8); /* uid */ + myAssertEqualMem(e + 116, "000142 ", 8); /* gid */ + myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ + myAssertEqualMem(e + 136, "00000000003 ", 12); /* mtime */ + myAssertEqualMem(e + 148, "011446\0 ", 8); /* checksum */ + myAssertEqualMem(e + 156, "2", 1); /* linkflag */ + myAssertEqualMem(e + 157, "file", 5); /* linkname */ + myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ + myAssertEqualMem(e + 265, "", 1); /* uname */ + myAssertEqualMem(e + 297, "", 1); /* gname */ + myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ + myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ + myAssertEqualMem(e + 345, "", 1); /* prefix */ + assert(is_null(e + 0, 512)); + e += 512; + + /* File with 99-char filename */ + myAssertEqualMem(e + 0, f99, 100); /* Filename */ + myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ + myAssertEqualMem(e + 108, "000122 ", 8); /* uid */ + myAssertEqualMem(e + 116, "000135 ", 8); /* gid */ + myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ + myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ + myAssertEqualMem(e + 148, "034242\0 ", 8); /* checksum */ + myAssertEqualMem(e + 156, "0", 1); /* linkflag */ + myAssertEqualMem(e + 157, "", 1); /* linkname */ + myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ + myAssertEqualMem(e + 265, "", 1); /* uname */ + myAssertEqualMem(e + 297, "", 1); /* gname */ + myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ + myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ + myAssertEqualMem(e + 345, "", 1); /* prefix */ + assert(is_null(e + 0, 512)); + e += 512; + + /* File with 100-char filename */ + myAssertEqualMem(e + 0, f100, 100); /* Filename */ + myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ + myAssertEqualMem(e + 108, "000122 ", 8); /* uid */ + myAssertEqualMem(e + 116, "000135 ", 8); /* gid */ + myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ + myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ + myAssertEqualMem(e + 148, "026230\0 ", 8); /* checksum */ + myAssertEqualMem(e + 156, "0", 1); /* linkflag */ + myAssertEqualMem(e + 157, "", 1); /* linkname */ + myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ + myAssertEqualMem(e + 265, "", 1); /* uname */ + myAssertEqualMem(e + 297, "", 1); /* gname */ + myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ + myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ + myAssertEqualMem(e + 345, "", 1); /* prefix */ + assert(is_null(e + 0, 512)); + e += 512; + + /* File with 256-char filename */ + myAssertEqualMem(e + 0, f256 + 156, 100); /* Filename */ + myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ + myAssertEqualMem(e + 108, "000122 ", 8); /* uid */ + myAssertEqualMem(e + 116, "000135 ", 8); /* gid */ + myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ + myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ + myAssertEqualMem(e + 148, "055570\0 ", 8); /* checksum */ + myAssertEqualMem(e + 156, "0", 1); /* linkflag */ + myAssertEqualMem(e + 157, "", 1); /* linkname */ + myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ + myAssertEqualMem(e + 265, "", 1); /* uname */ + myAssertEqualMem(e + 297, "", 1); /* gname */ + myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ + myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ + myAssertEqualMem(e + 345, f256, 155); /* prefix */ + assert(is_null(e + 0, 512)); + e += 512; + + /* TODO: Verify other types of entries. */ + + /* Last entry is end-of-archive marker. */ + assert(is_null(e, 1024)); + e += 1024; + + assertEqualInt(used, e - buff); + + free(buff); +}