summaryrefslogtreecommitdiffstats
path: root/lib/libarchive
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2009-12-30 05:59:21 +0000
committerkientzle <kientzle@FreeBSD.org>2009-12-30 05:59:21 +0000
commitfa94194ff849f6933fedb15396e96731eb2c4157 (patch)
treea878f899f5526c6be691b6194342f1ddd9a9fdd9 /lib/libarchive
parentc6d0b4dd8b2ab36f3e73a6ad81509d14d32bafae (diff)
downloadFreeBSD-src-fa94194ff849f6933fedb15396e96731eb2c4157.zip
FreeBSD-src-fa94194ff849f6933fedb15396e96731eb2c4157.tar.gz
A raft of test changes and improvements from the Googlecode repository.
In particular, this includes tests for the new features I've merged over the last few days.
Diffstat (limited to 'lib/libarchive')
-rw-r--r--lib/libarchive/test/Makefile27
-rw-r--r--lib/libarchive/test/main.c1983
-rw-r--r--lib/libarchive/test/test.h227
-rw-r--r--lib/libarchive/test/test_acl_pax.c14
-rw-r--r--lib/libarchive/test/test_compat_bzip2.c5
-rw-r--r--lib/libarchive/test/test_compat_cpio.c106
-rw-r--r--lib/libarchive/test/test_compat_cpio_1.cpio.uu19
-rw-r--r--lib/libarchive/test/test_compat_lzma.c155
-rw-r--r--lib/libarchive/test/test_compat_lzma_1.tlz.uu10
-rw-r--r--lib/libarchive/test/test_compat_lzma_2.tlz.uu9
-rw-r--r--lib/libarchive/test/test_compat_lzma_3.tlz.uu9
-rw-r--r--lib/libarchive/test/test_compat_solaris_tar_acl.c6
-rw-r--r--lib/libarchive/test/test_entry.c37
-rw-r--r--lib/libarchive/test/test_entry_strmode.c16
-rw-r--r--lib/libarchive/test/test_extattr_freebsd.c16
-rw-r--r--lib/libarchive/test/test_fuzz.c132
-rw-r--r--lib/libarchive/test/test_fuzz_1.iso.Z.uu495
-rw-r--r--lib/libarchive/test/test_open_fd.c13
-rw-r--r--lib/libarchive/test/test_open_file.c4
-rw-r--r--lib/libarchive/test/test_pax_filename_encoding.c30
-rw-r--r--lib/libarchive/test/test_read_compress_program.c14
-rw-r--r--lib/libarchive/test/test_read_data_large.c22
-rw-r--r--lib/libarchive/test/test_read_disk.c6
-rw-r--r--lib/libarchive/test/test_read_disk_entry_from_file.c10
-rw-r--r--lib/libarchive/test/test_read_extract.c108
-rw-r--r--lib/libarchive/test/test_read_format_ar.ar.uu12
-rw-r--r--lib/libarchive/test/test_read_format_ar.c42
-rw-r--r--lib/libarchive/test/test_read_format_cpio_bin_bz2.c9
-rw-r--r--lib/libarchive/test/test_read_format_cpio_bin_lzma.c60
-rw-r--r--lib/libarchive/test/test_read_format_iso.iso.Z.uu26
-rw-r--r--lib/libarchive/test/test_read_format_iso_gz.c11
-rw-r--r--lib/libarchive/test/test_read_format_iso_joliet.iso.Z.uu66
-rw-r--r--lib/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu71
-rw-r--r--lib/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu68
-rw-r--r--lib/libarchive/test/test_read_format_iso_multi_extent.c94
-rw-r--r--lib/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu67
-rw-r--r--lib/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu206
-rw-r--r--lib/libarchive/test/test_read_format_iso_rockridge_ce.iso.Z.uu63
-rw-r--r--lib/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu208
-rw-r--r--lib/libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu304
-rw-r--r--lib/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu63
-rw-r--r--lib/libarchive/test/test_read_format_isojoliet_bz2.c96
-rw-r--r--lib/libarchive/test/test_read_format_isojoliet_long.c141
-rw-r--r--lib/libarchive/test/test_read_format_isojoliet_rr.c159
-rw-r--r--lib/libarchive/test/test_read_format_isorr_bz2.c214
-rw-r--r--lib/libarchive/test/test_read_format_isorr_ce.c223
-rw-r--r--lib/libarchive/test/test_read_format_isorr_new_bz2.c204
-rw-r--r--lib/libarchive/test/test_read_format_isorr_rr_moved.c270
-rw-r--r--lib/libarchive/test/test_read_format_isozisofs_bz2.c187
-rw-r--r--lib/libarchive/test/test_read_format_mtree.c86
-rw-r--r--lib/libarchive/test/test_read_format_mtree.mtree.uu13
-rw-r--r--lib/libarchive/test/test_read_format_pax_bz2.c8
-rw-r--r--lib/libarchive/test/test_read_format_tar.c18
-rw-r--r--lib/libarchive/test/test_read_format_tbz.c8
-rw-r--r--lib/libarchive/test/test_read_format_tlz.c60
-rw-r--r--lib/libarchive/test/test_read_large.c35
-rw-r--r--lib/libarchive/test/test_tar_large.c2
-rw-r--r--lib/libarchive/test/test_write_compress_program.c13
-rw-r--r--lib/libarchive/test/test_write_disk.c63
-rw-r--r--lib/libarchive/test/test_write_disk_failures.c6
-rw-r--r--lib/libarchive/test/test_write_disk_hardlink.c110
-rw-r--r--lib/libarchive/test/test_write_disk_perms.c6
-rw-r--r--lib/libarchive/test/test_write_disk_secure.c13
-rw-r--r--lib/libarchive/test/test_write_disk_sparse.c36
-rw-r--r--lib/libarchive/test/test_write_disk_symlink.c117
-rw-r--r--lib/libarchive/test/test_write_disk_times.c68
-rw-r--r--lib/libarchive/test/test_write_format_cpio_empty.c2
-rw-r--r--lib/libarchive/test/test_write_format_cpio_newc.c11
-rw-r--r--lib/libarchive/test/test_write_format_cpio_odc.c27
-rw-r--r--lib/libarchive/test/test_write_format_tar_ustar.c3
-rw-r--r--lib/libarchive/test/test_write_format_zip.c180
-rw-r--r--lib/libarchive/test/test_write_format_zip_empty.c56
-rw-r--r--lib/libarchive/test/test_write_format_zip_no_compression.c304
73 files changed, 6267 insertions, 1315 deletions
diff --git a/lib/libarchive/test/Makefile b/lib/libarchive/test/Makefile
index dec95fd..4d88151 100644
--- a/lib/libarchive/test/Makefile
+++ b/lib/libarchive/test/Makefile
@@ -14,8 +14,10 @@ TESTS= \
test_archive_api_feature.c \
test_bad_fd.c \
test_compat_bzip2.c \
+ test_compat_cpio.c \
test_compat_gtar.c \
test_compat_gzip.c \
+ test_compat_lzma.c \
test_compat_solaris_tar_acl.c \
test_compat_tar_hardlink.c \
test_compat_xz.c \
@@ -42,6 +44,7 @@ TESTS= \
test_read_format_cpio_bin_be.c \
test_read_format_cpio_bin_bz2.c \
test_read_format_cpio_bin_gz.c \
+ test_read_format_cpio_bin_lzma.c \
test_read_format_cpio_bin_xz.c \
test_read_format_cpio_odc.c \
test_read_format_cpio_svr4_gzip.c \
@@ -51,8 +54,15 @@ TESTS= \
test_read_format_gtar_lzma.c \
test_read_format_gtar_sparse.c \
test_read_format_iso_gz.c \
+ test_read_format_iso_multi_extent.c \
+ test_read_format_isorr_rr_moved.c \
test_read_format_isojoliet_bz2.c \
+ test_read_format_isojoliet_long.c \
+ test_read_format_isojoliet_rr.c \
test_read_format_isorr_bz2.c \
+ test_read_format_isorr_ce.c \
+ test_read_format_isorr_new_bz2.c \
+ test_read_format_isozisofs_bz2.c \
test_read_format_mtree.c \
test_read_format_pax_bz2.c \
test_read_format_raw.c \
@@ -60,6 +70,7 @@ TESTS= \
test_read_format_tar_empty_filename.c \
test_read_format_tbz.c \
test_read_format_tgz.c \
+ test_read_format_tlz.c \
test_read_format_txz.c \
test_read_format_tz.c \
test_read_format_zip.c \
@@ -82,6 +93,7 @@ TESTS= \
test_write_disk_perms.c \
test_write_disk_secure.c \
test_write_disk_sparse.c \
+ test_write_disk_symlink.c \
test_write_disk_times.c \
test_write_format_ar.c \
test_write_format_cpio.c \
@@ -94,6 +106,9 @@ TESTS= \
test_write_format_tar.c \
test_write_format_tar_empty.c \
test_write_format_tar_ustar.c \
+ test_write_format_zip.c \
+ test_write_format_zip_empty.c \
+ test_write_format_zip_no_compression.c \
test_write_open_memory.c
@@ -108,16 +123,12 @@ NO_MAN=yes
PROG=libarchive_test
INTERNALPROG=yes # Don't install this; it's just for testing
-DPADD=${LIBBZ2} ${LIBZ}
+DPADD=${LIBBZ2} ${LIBZ} ${LIBMD} ${LIBCRYPTO} ${LIBBSDXML}
CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\"
-LDADD= -lz -lbz2 -lmd -lcrypto
+LDADD= -lz -lbz2 -lmd -lcrypto -lbsdxml
CFLAGS+= -g
CFLAGS+= -I${LA_SRCDIR} -I.
-# Uncomment to build and test lzma support via liblzmadec
-#CFLAGS+= -I/usr/local/include -DHAVE_LIBLZMADEC=1 -DHAVE_LZMADEC_H=1
-#LDADD+= -L/usr/local/lib -llzmadec
-
# Uncomment to build and test lzma and xz support via liblzma
#CFLAGS+= -I/usr/local/include -DHAVE_LIBLZMA=1 -DHAVE_LZMA_H=1
#LDADD+= -L/usr/local/lib -llzma
@@ -125,11 +136,11 @@ CFLAGS+= -I${LA_SRCDIR} -I.
# Uncomment to link against dmalloc
#LDADD+= -L/usr/local/lib -ldmalloc
#CFLAGS+= -I/usr/local/include -DUSE_DMALLOC
-WARNS=6
+#WARNS=6
# Build libarchive_test and run it.
check test: libarchive_test
- ./libarchive_test -v -r ${.CURDIR}
+ ./libarchive_test -r ${.CURDIR}
# list.h is just a list of all tests, as indicated by DEFINE_TEST macro lines
list.h: ${TESTS} Makefile
diff --git a/lib/libarchive/test/main.c b/lib/libarchive/test/main.c
index 0d16c81..5f8cbc3 100644
--- a/lib/libarchive/test/main.c
+++ b/lib/libarchive/test/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2009 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,74 +23,142 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * Various utility routines useful for test programs.
- * Each test program is linked against this file.
- */
#include "test.h"
-
#include <errno.h>
#include <locale.h>
#include <stdarg.h>
#include <time.h>
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <crtdbg.h>
-#include <windows.h>
-#include <winbase.h>
-#endif
/*
* This same file is used pretty much verbatim for all test harnesses.
*
* The next few lines are the only differences.
+ * TODO: Move this into a separate configuration header, have all test
+ * suites share one copy of this file.
*/
+__FBSDID("$FreeBSD$");
+#define KNOWNREF "test_compat_gtar_1.tar.uu"
+#define ENVBASE "LIBARCHIVE" /* Prefix for environment variables. */
#undef PROGRAM /* Testing a library, not a program. */
#define LIBRARY "libarchive"
-#define ENVBASE "LIBARCHIVE" /* Prefix for environment variables. */
#define EXTRA_DUMP(x) archive_error_string((struct archive *)(x))
#define EXTRA_VERSION archive_version()
-#define KNOWNREF "test_compat_gtar_1.tar.uu"
-__FBSDID("$FreeBSD$");
/*
- * "list.h" is simply created by "grep DEFINE_TEST"; it has
- * a line like
- * DEFINE_TEST(test_function)
- * for each test.
- * Include it here with a suitable DEFINE_TEST to declare all of the
- * test functions.
+ *
+ * Windows support routines
+ *
+ * Note: Configuration is a tricky issue. Using HAVE_* feature macros
+ * in the test harness is dangerous because they cover up
+ * configuration errors. The classic example of this is omitting a
+ * configure check. If libarchive and libarchive_test both look for
+ * the same feature macro, such errors are hard to detect. Platform
+ * macros (e.g., _WIN32 or __GNUC__) are a little better, but can
+ * easily lead to very messy code. It's best to limit yourself
+ * to only the most generic programming techniques in the test harness
+ * and thus avoid conditionals altogether. Where that's not possible,
+ * try to minimize conditionals by grouping platform-specific tests in
+ * one place (e.g., test_acl_freebsd) or by adding new assert()
+ * functions (e.g., assertMakeHardlink()) to cover up platform
+ * differences. Platform-specific coding in libarchive_test is often
+ * a symptom that some capability is missing from libarchive itself.
*/
-#undef DEFINE_TEST
-#define DEFINE_TEST(name) void name(void);
-#include "list.h"
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <io.h>
+#include <windows.h>
+#ifndef F_OK
+#define F_OK (0)
+#endif
+#ifndef S_ISDIR
+#define S_ISDIR(m) ((m) & _S_IFDIR)
+#endif
+#ifndef S_ISREG
+#define S_ISREG(m) ((m) & _S_IFREG)
+#endif
+#if !defined(__BORLANDC__)
+#define access _access
+#define chdir _chdir
+#endif
+#ifndef fileno
+#define fileno _fileno
+#endif
+/*#define fstat _fstat64*/
+#if !defined(__BORLANDC__)
+#define getcwd _getcwd
+#endif
+#define lstat stat
+/*#define lstat _stat64*/
+/*#define stat _stat64*/
+#define rmdir _rmdir
+#if !defined(__BORLANDC__)
+#define strdup _strdup
+#define umask _umask
+#endif
+#define int64_t __int64
+#endif
-/* Interix doesn't define these in a standard header. */
-#if __INTERIX__
-extern char *optarg;
-extern int optind;
+#if defined(HAVE__CrtSetReportMode)
+# include <crtdbg.h>
#endif
-/* Enable core dump on failure. */
-static int dump_on_failure = 0;
-/* Default is to remove temp dirs for successful tests. */
-static int keep_temp_files = 0;
-/* Default is to print some basic information about each test. */
-static int quiet_flag = 0;
-/* Default is to summarize repeated failures. */
-static int verbose = 0;
-/* Cumulative count of component failures. */
-static int failures = 0;
-/* Cumulative count of skipped component tests. */
-static int skips = 0;
-/* Cumulative count of assertions. */
-static int assertions = 0;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+void *GetFunctionKernel32(const char *name)
+{
+ static HINSTANCE lib;
+ static int set;
+ if (!set) {
+ set = 1;
+ lib = LoadLibrary("kernel32.dll");
+ }
+ if (lib == NULL) {
+ fprintf(stderr, "Can't load kernel32.dll?!\n");
+ exit(1);
+ }
+ return (void *)GetProcAddress(lib, name);
+}
-/* Directory where uuencoded reference files can be found. */
-static const char *refdir;
+static int
+my_CreateSymbolicLinkA(const char *linkname, const char *target, int flags)
+{
+ static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, DWORD);
+ static int set;
+ if (!set) {
+ set = 1;
+ f = GetFunctionKernel32("CreateSymbolicLinkA");
+ }
+ return f == NULL ? 0 : (*f)(linkname, target, flags);
+}
+static int
+my_CreateHardLinkA(const char *linkname, const char *target)
+{
+ static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES);
+ static int set;
+ if (!set) {
+ set = 1;
+ f = GetFunctionKernel32("CreateHardLinkA");
+ }
+ return f == NULL ? 0 : (*f)(linkname, target, NULL);
+}
-#if defined(_WIN32) && !defined(__CYGWIN__)
+int
+my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+ HANDLE h;
+ int r;
+
+ memset(bhfi, 0, sizeof(*bhfi));
+ h = CreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return (0);
+ r = GetFileInformationByHandle(h, bhfi);
+ CloseHandle(h);
+ return (r);
+}
+#endif
+#if defined(HAVE__CrtSetReportMode)
static void
invalid_parameter_handler(const wchar_t * expression,
const wchar_t * function, const wchar_t * file,
@@ -98,123 +166,181 @@ invalid_parameter_handler(const wchar_t * expression,
{
/* nop */
}
-
#endif
/*
- * My own implementation of the standard assert() macro emits the
- * message in the same format as GCC (file:line: message).
- * It also includes some additional useful information.
- * This makes it a lot easier to skim through test failures in
- * Emacs. ;-)
*
- * It also supports a few special features specifically to simplify
- * test harnesses:
- * failure(fmt, args) -- Stores a text string that gets
- * printed if the following assertion fails, good for
- * explaining subtle tests.
+ * OPTIONS FLAGS
+ *
*/
-static char msg[4096];
-/*
- * For each test source file, we remember how many times each
- * failure was reported.
- */
-static const char *failed_filename = NULL;
-static struct line {
- int line;
- int count;
- int critical;
-} failed_lines[1000];
+/* Enable core dump on failure. */
+static int dump_on_failure = 0;
+/* Default is to remove temp dirs and log data for successful tests. */
+static int keep_temp_files = 0;
+/* Default is to just report pass/fail for each test. */
+static int verbosity = 0;
+#define VERBOSITY_SUMMARY_ONLY -1 /* -q */
+#define VERBOSITY_PASSFAIL 0 /* Default */
+#define VERBOSITY_LIGHT_REPORT 1 /* -v */
+#define VERBOSITY_FULL 2 /* -vv */
+/* A few places generate even more output for verbosity > VERBOSITY_FULL,
+ * mostly for debugging the test harness itself. */
+/* Cumulative count of assertion failures. */
+static int failures = 0;
+/* Cumulative count of reported skips. */
+static int skips = 0;
+/* Cumulative count of assertions checked. */
+static int assertions = 0;
+
+/* Directory where uuencoded reference files can be found. */
+static const char *refdir;
/*
- * Called at the beginning of each assert() function.
+ * Report log information selectively to console and/or disk log.
*/
+static int log_console = 0;
+static FILE *logfile;
static void
-count_assertion(const char *file, int line)
+vlogprintf(const char *fmt, va_list ap)
{
- (void)file; /* UNUSED */
- (void)line; /* UNUSED */
- ++assertions;
- /* Uncomment to print file:line after every assertion.
- * Verbose, but occasionally useful in tracking down crashes. */
- /* printf("Checked %s:%d\n", file, line); */
+#ifdef va_copy
+ va_list lfap;
+ va_copy(lfap, ap);
+#endif
+ if (log_console)
+ vfprintf(stdout, fmt, ap);
+ if (logfile != NULL)
+#ifdef va_copy
+ vfprintf(logfile, fmt, lfap);
+ va_end(lfap);
+#else
+ vfprintf(logfile, fmt, ap);
+#endif
}
-/*
- * Count this failure; return the number of previous failures.
- */
-static int
-previous_failures(const char *filename, int line, int critical)
+static void
+logprintf(const char *fmt, ...)
{
- unsigned int i;
- int count;
-
- if (failed_filename == NULL || strcmp(failed_filename, filename) != 0)
- memset(failed_lines, 0, sizeof(failed_lines));
- failed_filename = filename;
+ va_list ap;
+ va_start(ap, fmt);
+ vlogprintf(fmt, ap);
+ va_end(ap);
+}
- for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].line == line) {
- count = failed_lines[i].count;
- failed_lines[i].count++;
- return (count);
- }
- if (failed_lines[i].line == 0) {
- failed_lines[i].line = line;
- failed_lines[i].count = 1;
- failed_lines[i].critical = critical;
- return (0);
- }
- }
- return (0);
+/* Set up a message to display only if next assertion fails. */
+static char msgbuff[4096];
+static const char *msg, *nextmsg;
+void
+failure(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(msgbuff, fmt, ap);
+ va_end(ap);
+ nextmsg = msgbuff;
}
/*
* Copy arguments into file-local variables.
+ * This was added to permit vararg assert() functions without needing
+ * variadic wrapper macros. Turns out that the vararg capability is almost
+ * never used, so almost all of the vararg assertions can be simplified
+ * by removing the vararg capability and reworking the wrapper macro to
+ * pass __FILE__, __LINE__ directly into the function instead of using
+ * this hook. I suspect this machinery is used so rarely that we
+ * would be better off just removing it entirely. That would simplify
+ * the code here noticably.
*/
static const char *test_filename;
static int test_line;
static void *test_extra;
-void test_setup(const char *filename, int line)
+void assertion_setup(const char *filename, int line)
{
test_filename = filename;
test_line = line;
}
+/* Called at the beginning of each assert() function. */
+static void
+assertion_count(const char *file, int line)
+{
+ (void)file; /* UNUSED */
+ (void)line; /* UNUSED */
+ ++assertions;
+ /* Proper handling of "failure()" message. */
+ msg = nextmsg;
+ nextmsg = NULL;
+ /* Uncomment to print file:line after every assertion.
+ * Verbose, but occasionally useful in tracking down crashes. */
+ /* printf("Checked %s:%d\n", file, line); */
+}
+
/*
- * Inform user that we're skipping a test.
+ * For each test source file, we remember how many times each
+ * assertion was reported. Cleared before each new test,
+ * used by test_summarize().
*/
-void
-test_skipping(const char *fmt, ...)
+static struct line {
+ int count;
+ int skip;
+} failed_lines[10000];
+
+/* Count this failure, setup up log destination and handle initial report. */
+static void
+failure_start(const char *filename, int line, const char *fmt, ...)
{
va_list ap;
- if (previous_failures(test_filename, test_line, 0))
- return;
+ /* Record another failure for this line. */
+ ++failures;
+ /* test_filename = filename; */
+ failed_lines[line].count++;
+
+ /* Determine whether to log header to console. */
+ switch (verbosity) {
+ case VERBOSITY_LIGHT_REPORT:
+ log_console = (failed_lines[line].count < 2);
+ break;
+ default:
+ log_console = (verbosity >= VERBOSITY_FULL);
+ }
+ /* Log file:line header for this failure */
va_start(ap, fmt);
- fprintf(stderr, " *** SKIPPING: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
+#if _MSC_VER
+ logprintf("%s(%d): ", filename, line);
+#else
+ logprintf("%s:%d: ", filename, line);
+#endif
+ vlogprintf(fmt, ap);
va_end(ap);
- ++skips;
+ logprintf("\n");
+
+ if (msg != NULL && msg[0] != '\0') {
+ logprintf(" Description: %s\n", msg);
+ msg = NULL;
+ }
+
+ /* Determine whether to log details to console. */
+ if (verbosity == VERBOSITY_LIGHT_REPORT)
+ log_console = 0;
}
-/* Common handling of failed tests. */
+/* Complete reporting of failed tests. */
+/*
+ * The 'extra' hook here is used by libarchive to include libarchive
+ * error messages with assertion failures. It could also be used
+ * to add strerror() output, for example. Just define the EXTRA_DUMP()
+ * macro appropriately.
+ */
static void
-report_failure(void *extra)
+failure_finish(void *extra)
{
- if (msg[0] != '\0') {
- fprintf(stderr, " Description: %s\n", msg);
- msg[0] = '\0';
- }
-
+ (void)extra; /* UNUSED (maybe) */
#ifdef EXTRA_DUMP
if (extra != NULL)
- fprintf(stderr, " detail: %s\n", EXTRA_DUMP(extra));
-#else
- (void)extra; /* UNUSED */
+ logprintf(" detail: %s\n", EXTRA_DUMP(extra));
#endif
if (dump_on_failure) {
@@ -225,203 +351,154 @@ report_failure(void *extra)
}
}
-/*
- * Summarize repeated failures in the just-completed test file.
- * The reports above suppress multiple failures from the same source
- * line; this reports on any tests that did fail multiple times.
- */
-static int
-summarize_comparator(const void *a0, const void *b0)
-{
- const struct line *a = a0, *b = b0;
- if (a->line == 0 && b->line == 0)
- return (0);
- if (a->line == 0)
- return (1);
- if (b->line == 0)
- return (-1);
- return (a->line - b->line);
-}
-
-static void
-summarize(void)
-{
- unsigned int i;
-
- qsort(failed_lines, sizeof(failed_lines)/sizeof(failed_lines[0]),
- sizeof(failed_lines[0]), summarize_comparator);
- for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
- if (failed_lines[i].line == 0)
- break;
- if (failed_lines[i].count > 1 && failed_lines[i].critical)
- fprintf(stderr, "%s:%d: Failed %d times\n",
- failed_filename, failed_lines[i].line,
- failed_lines[i].count);
- }
- /* Clear the failure history for the next file. */
- memset(failed_lines, 0, sizeof(failed_lines));
-}
-
-/* Set up a message to display only after a test fails. */
+/* Inform user that we're skipping some checks. */
void
-failure(const char *fmt, ...)
+test_skipping(const char *fmt, ...)
{
+ char buff[1024];
va_list ap;
+
va_start(ap, fmt);
- vsprintf(msg, fmt, ap);
+ vsprintf(buff, fmt, ap);
va_end(ap);
+ /* failure_start() isn't quite right, but is awfully convenient. */
+ failure_start(test_filename, test_line, "SKIPPING: %s", buff);
+ --failures; /* Undo failures++ in failure_start() */
+ /* Don't failure_finish() here. */
+ /* Mark as skip, so doesn't count as failed test. */
+ failed_lines[test_line].skip = 1;
+ ++skips;
}
+/*
+ *
+ * ASSERTIONS
+ *
+ */
+
/* Generic assert() just displays the failed condition. */
int
-test_assert(const char *file, int line, int value, const char *condition, void *extra)
+assertion_assert(const char *file, int line, int value,
+ const char *condition, void *extra)
{
- count_assertion(file, line);
- if (value) {
- msg[0] = '\0';
- return (value);
+ assertion_count(file, line);
+ if (!value) {
+ failure_start(file, line, "Assertion failed: %s", condition);
+ failure_finish(extra);
}
- failures ++;
- if (!verbose && previous_failures(file, line, 1))
- return (value);
- fprintf(stderr, "%s:%d: Assertion failed\n", file, line);
- fprintf(stderr, " Condition: %s\n", condition);
- report_failure(extra);
return (value);
}
-/* assertEqualInt() displays the values of the two integers. */
+/* chdir() and report any errors */
int
-test_assert_equal_int(const char *file, int line,
- int v1, const char *e1, int v2, const char *e2, void *extra)
+assertion_chdir(const char *file, int line, const char *pathname)
{
- count_assertion(file, line);
- if (v1 == v2) {
- msg[0] = '\0';
+ assertion_count(file, line);
+ if (chdir(pathname) == 0)
return (1);
- }
- failures ++;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Ints not equal\n",
- file, line);
- fprintf(stderr, " %s=%d\n", e1, v1);
- fprintf(stderr, " %s=%d\n", e2, v2);
- report_failure(extra);
+ failure_start(file, line, "chdir(\"%s\")", pathname);
+ failure_finish(NULL);
return (0);
+
}
-static void strdump(const char *p)
+/* Verify two integers are equal. */
+int
+assertion_equal_int(const char *file, int line,
+ long long v1, const char *e1, long long v2, const char *e2, void *extra)
{
+ assertion_count(file, line);
+ if (v1 == v2)
+ return (1);
+ failure_start(file, line, "%s != %s", e1, e2);
+ logprintf(" %s=%lld (0x%llx, 0%llo)\n", e1, v1, v1, v1);
+ logprintf(" %s=%lld (0x%llx, 0%llo)\n", e2, v2, v2, v2);
+ failure_finish(extra);
+ return (0);
+}
+
+static void strdump(const char *e, const char *p)
+{
+ const char *q = p;
+
+ logprintf(" %s = ", e);
if (p == NULL) {
- fprintf(stderr, "(null)");
+ logprintf("NULL");
return;
}
- fprintf(stderr, "\"");
+ logprintf("\"");
while (*p != '\0') {
unsigned int c = 0xff & *p++;
switch (c) {
- case '\a': fprintf(stderr, "\a"); break;
- case '\b': fprintf(stderr, "\b"); break;
- case '\n': fprintf(stderr, "\n"); break;
- case '\r': fprintf(stderr, "\r"); break;
+ case '\a': printf("\a"); break;
+ case '\b': printf("\b"); break;
+ case '\n': printf("\n"); break;
+ case '\r': printf("\r"); break;
default:
if (c >= 32 && c < 127)
- fprintf(stderr, "%c", c);
+ logprintf("%c", c);
else
- fprintf(stderr, "\\x%02X", c);
+ logprintf("\\x%02X", c);
}
}
- fprintf(stderr, "\"");
+ logprintf("\"");
+ logprintf(" (length %d)\n", q == NULL ? -1 : (int)strlen(q));
}
-/* assertEqualString() displays the values of the two strings. */
+/* Verify two strings are equal, dump them if not. */
int
-test_assert_equal_string(const char *file, int line,
+assertion_equal_string(const char *file, int line,
const char *v1, const char *e1,
const char *v2, const char *e2,
void *extra)
{
- count_assertion(file, line);
- if (v1 == NULL || v2 == NULL) {
- if (v1 == v2) {
- msg[0] = '\0';
- return (1);
- }
- } else if (strcmp(v1, v2) == 0) {
- msg[0] = '\0';
+ assertion_count(file, line);
+ if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0))
return (1);
- }
- failures ++;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Strings not equal\n",
- file, line);
- fprintf(stderr, " %s = ", e1);
- strdump(v1);
- fprintf(stderr, " (length %d)\n", v1 == NULL ? 0 : (int)strlen(v1));
- fprintf(stderr, " %s = ", e2);
- strdump(v2);
- fprintf(stderr, " (length %d)\n", v2 == NULL ? 0 : (int)strlen(v2));
- report_failure(extra);
+ failure_start(file, line, "%s != %s", e1, e2);
+ strdump(e1, v1);
+ strdump(e2, v2);
+ failure_finish(extra);
return (0);
}
-static void wcsdump(const wchar_t *w)
+static void
+wcsdump(const char *e, const wchar_t *w)
{
+ logprintf(" %s = ", e);
if (w == NULL) {
- fprintf(stderr, "(null)");
+ logprintf("(null)");
return;
}
- fprintf(stderr, "\"");
+ logprintf("\"");
while (*w != L'\0') {
unsigned int c = *w++;
if (c >= 32 && c < 127)
- fprintf(stderr, "%c", c);
+ logprintf("%c", c);
else if (c < 256)
- fprintf(stderr, "\\x%02X", c);
+ logprintf("\\x%02X", c);
else if (c < 0x10000)
- fprintf(stderr, "\\u%04X", c);
+ logprintf("\\u%04X", c);
else
- fprintf(stderr, "\\U%08X", c);
+ logprintf("\\U%08X", c);
}
- fprintf(stderr, "\"");
+ logprintf("\"\n");
}
-/* assertEqualWString() displays the values of the two strings. */
+/* Verify that two wide strings are equal, dump them if not. */
int
-test_assert_equal_wstring(const char *file, int line,
+assertion_equal_wstring(const char *file, int line,
const wchar_t *v1, const char *e1,
const wchar_t *v2, const char *e2,
void *extra)
{
- count_assertion(file, line);
- if (v1 == NULL) {
- if (v2 == NULL) {
- msg[0] = '\0';
- return (1);
- }
- } else if (v2 == NULL) {
- if (v1 == NULL) {
- msg[0] = '\0';
- return (1);
- }
- } else if (wcscmp(v1, v2) == 0) {
- msg[0] = '\0';
+ assertion_count(file, line);
+ if (v1 == v2 || wcscmp(v1, v2) == 0)
return (1);
- }
- failures ++;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: Unicode strings not equal\n",
- file, line);
- fprintf(stderr, " %s = ", e1);
- wcsdump(v1);
- fprintf(stderr, "\n");
- fprintf(stderr, " %s = ", e2);
- wcsdump(v2);
- fprintf(stderr, "\n");
- report_failure(extra);
+ failure_start(file, line, "%s != %s", e1, e2);
+ wcsdump(e1, v1);
+ wcsdump(e2, v2);
+ failure_finish(extra);
return (0);
}
@@ -436,35 +513,40 @@ hexdump(const char *p, const char *ref, size_t l, size_t offset)
size_t i, j;
char sep;
+ if (p == NULL) {
+ logprintf("(null)\n");
+ return;
+ }
for(i=0; i < l; i+=16) {
- fprintf(stderr, "%04x", (unsigned)(i + offset));
+ logprintf("%04x", (unsigned)(i + offset));
sep = ' ';
for (j = 0; j < 16 && i + j < l; j++) {
if (ref != NULL && p[i + j] != ref[i + j])
sep = '_';
- fprintf(stderr, "%c%02x", sep, 0xff & (int)p[i+j]);
+ logprintf("%c%02x", sep, 0xff & (int)p[i+j]);
if (ref != NULL && p[i + j] == ref[i + j])
sep = ' ';
}
for (; j < 16; j++) {
- fprintf(stderr, "%c ", sep);
+ logprintf("%c ", sep);
sep = ' ';
}
- fprintf(stderr, "%c", sep);
+ logprintf("%c", sep);
for (j=0; j < 16 && i + j < l; j++) {
int c = p[i + j];
if (c >= ' ' && c <= 126)
- fprintf(stderr, "%c", c);
+ logprintf("%c", c);
else
- fprintf(stderr, ".");
+ logprintf(".");
}
- fprintf(stderr, "\n");
+ logprintf("\n");
}
}
-/* assertEqualMem() displays the values of the two memory blocks. */
+/* Verify that two blocks of memory are the same, display the first
+ * block of differences if they're not. */
int
-test_assert_equal_mem(const char *file, int line,
+assertion_equal_mem(const char *file, int line,
const void *_v1, const char *e1,
const void *_v2, const char *e2,
size_t l, const char *ld, void *extra)
@@ -473,202 +555,908 @@ test_assert_equal_mem(const char *file, int line,
const char *v2 = (const char *)_v2;
size_t offset;
- count_assertion(file, line);
- if (v1 == NULL || v2 == NULL) {
- if (v1 == v2) {
- msg[0] = '\0';
- return (1);
- }
- } else if (memcmp(v1, v2, l) == 0) {
- msg[0] = '\0';
+ assertion_count(file, line);
+ if (v1 == v2 || (v1 != NULL && v2 != NULL && memcmp(v1, v2, l) == 0))
return (1);
- }
- failures ++;
- if (!verbose && previous_failures(file, line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Assertion failed: memory not equal\n",
- file, line);
- fprintf(stderr, " size %s = %d\n", ld, (int)l);
+
+ failure_start(file, line, "%s != %s", e1, e2);
+ logprintf(" size %s = %d\n", ld, (int)l);
/* Dump 48 bytes (3 lines) so that the first difference is
* in the second line. */
offset = 0;
while (l > 64 && memcmp(v1, v2, 32) == 0) {
- /* The first two lines agree, so step forward one line. */
+ /* Two lines agree, so step forward one line. */
v1 += 16;
v2 += 16;
l -= 16;
offset += 16;
}
- fprintf(stderr, " Dump of %s\n", e1);
+ logprintf(" Dump of %s\n", e1);
hexdump(v1, v2, l < 64 ? l : 64, offset);
- fprintf(stderr, " Dump of %s\n", e2);
+ logprintf(" Dump of %s\n", e2);
hexdump(v2, v1, l < 64 ? l : 64, offset);
- fprintf(stderr, "\n");
- report_failure(extra);
+ logprintf("\n");
+ failure_finish(extra);
return (0);
}
+/* Verify that the named file exists and is empty. */
int
-test_assert_empty_file(const char *f1fmt, ...)
+assertion_empty_file(const char *f1fmt, ...)
{
char buff[1024];
char f1[1024];
struct stat st;
va_list ap;
ssize_t s;
- int fd;
-
+ FILE *f;
+ assertion_count(test_filename, test_line);
va_start(ap, f1fmt);
vsprintf(f1, f1fmt, ap);
va_end(ap);
if (stat(f1, &st) != 0) {
- fprintf(stderr, "%s:%d: Could not stat: %s\n", test_filename, test_line, f1);
- report_failure(NULL);
+ failure_start(test_filename, test_line, "Stat failed: %s", f1);
+ failure_finish(NULL);
return (0);
}
if (st.st_size == 0)
return (1);
- failures ++;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
-
- fprintf(stderr, "%s:%d: File not empty: %s\n", test_filename, test_line, f1);
- fprintf(stderr, " File size: %d\n", (int)st.st_size);
- fprintf(stderr, " Contents:\n");
- fd = open(f1, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, " Unable to open %s\n", f1);
+ failure_start(test_filename, test_line, "File should be empty: %s", f1);
+ logprintf(" File size: %d\n", (int)st.st_size);
+ logprintf(" Contents:\n");
+ f = fopen(f1, "rb");
+ if (f == NULL) {
+ logprintf(" Unable to open %s\n", f1);
} else {
- s = sizeof(buff) < st.st_size ? sizeof(buff) : st.st_size;
- s = read(fd, buff, s);
+ s = ((off_t)sizeof(buff) < st.st_size) ?
+ (ssize_t)sizeof(buff) : (ssize_t)st.st_size;
+ s = fread(buff, 1, s, f);
hexdump(buff, NULL, s, 0);
+ fclose(f);
}
- report_failure(NULL);
+ failure_finish(NULL);
return (0);
}
-/* assertEqualFile() asserts that two files have the same contents. */
+/* Verify that the named file exists and is not empty. */
+int
+assertion_non_empty_file(const char *f1fmt, ...)
+{
+ char f1[1024];
+ struct stat st;
+ va_list ap;
+
+ assertion_count(test_filename, test_line);
+ va_start(ap, f1fmt);
+ vsprintf(f1, f1fmt, ap);
+ va_end(ap);
+
+ if (stat(f1, &st) != 0) {
+ failure_start(test_filename, test_line, "Stat failed: %s", f1);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (st.st_size == 0) {
+ failure_start(test_filename, test_line, "File empty: %s", f1);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (1);
+}
+
+/* Verify that two files have the same contents. */
/* TODO: hexdump the first bytes that actually differ. */
int
-test_assert_equal_file(const char *f1, const char *f2pattern, ...)
+assertion_equal_file(const char *fn1, const char *f2pattern, ...)
{
- char f2[1024];
+ char fn2[1024];
va_list ap;
char buff1[1024];
char buff2[1024];
- int fd1, fd2;
+ FILE *f1, *f2;
int n1, n2;
+ assertion_count(test_filename, test_line);
va_start(ap, f2pattern);
- vsprintf(f2, f2pattern, ap);
+ vsprintf(fn2, f2pattern, ap);
va_end(ap);
- fd1 = open(f1, O_RDONLY);
- fd2 = open(f2, O_RDONLY);
+ f1 = fopen(fn1, "rb");
+ f2 = fopen(fn2, "rb");
for (;;) {
- n1 = read(fd1, buff1, sizeof(buff1));
- n2 = read(fd2, buff2, sizeof(buff2));
+ n1 = fread(buff1, 1, sizeof(buff1), f1);
+ n2 = fread(buff2, 1, sizeof(buff2), f2);
if (n1 != n2)
break;
- if (n1 == 0 && n2 == 0)
+ if (n1 == 0 && n2 == 0) {
+ fclose(f1);
+ fclose(f2);
return (1);
+ }
if (memcmp(buff1, buff2, n1) != 0)
break;
}
- failures ++;
- if (!verbose && previous_failures(test_filename, test_line, 1))
- return (0);
- fprintf(stderr, "%s:%d: Files are not identical\n",
- test_filename, test_line);
- fprintf(stderr, " file1=\"%s\"\n", f1);
- fprintf(stderr, " file2=\"%s\"\n", f2);
- report_failure(test_extra);
+ fclose(f1);
+ fclose(f2);
+ failure_start(test_filename, test_line, "Files not identical");
+ logprintf(" file1=\"%s\"\n", fn1);
+ logprintf(" file2=\"%s\"\n", fn2);
+ failure_finish(test_extra);
return (0);
}
+/* Verify that the named file does exist. */
int
-test_assert_file_exists(const char *fpattern, ...)
+assertion_file_exists(const char *fpattern, ...)
{
char f[1024];
va_list ap;
+ assertion_count(test_filename, test_line);
va_start(ap, fpattern);
vsprintf(f, fpattern, ap);
va_end(ap);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (!_access(f, 0))
+ return (1);
+#else
if (!access(f, F_OK))
return (1);
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File doesn't exist\n",
- test_filename, test_line);
- fprintf(stderr, " file=\"%s\"\n", f);
- report_failure(test_extra);
- }
+#endif
+ failure_start(test_filename, test_line, "File should exist: %s", f);
+ failure_finish(test_extra);
return (0);
}
+/* Verify that the named file doesn't exist. */
int
-test_assert_file_not_exists(const char *fpattern, ...)
+assertion_file_not_exists(const char *fpattern, ...)
{
char f[1024];
va_list ap;
+ assertion_count(test_filename, test_line);
va_start(ap, fpattern);
vsprintf(f, fpattern, ap);
va_end(ap);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (_access(f, 0))
+ return (1);
+#else
if (access(f, F_OK))
return (1);
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File exists and shouldn't\n",
- test_filename, test_line);
- fprintf(stderr, " file=\"%s\"\n", f);
- report_failure(test_extra);
- }
+#endif
+ failure_start(test_filename, test_line, "File should not exist: %s", f);
+ failure_finish(test_extra);
return (0);
}
-/* assertFileContents() asserts the contents of a file. */
+/* Compare the contents of a file to a block of memory. */
int
-test_assert_file_contents(const void *buff, int s, const char *fpattern, ...)
+assertion_file_contents(const void *buff, int s, const char *fpattern, ...)
{
- char f[1024];
+ char fn[1024];
va_list ap;
char *contents;
- int fd;
+ FILE *f;
int n;
+ assertion_count(test_filename, test_line);
va_start(ap, fpattern);
- vsprintf(f, fpattern, ap);
+ vsprintf(fn, fpattern, ap);
va_end(ap);
- fd = open(f, O_RDONLY);
+ f = fopen(fn, "rb");
+ if (f == NULL) {
+ failure_start(test_filename, test_line,
+ "File should exist: %s", fn);
+ failure_finish(test_extra);
+ return (0);
+ }
contents = malloc(s * 2);
- n = read(fd, contents, s * 2);
+ n = fread(contents, 1, s * 2, f);
+ fclose(f);
if (n == s && memcmp(buff, contents, s) == 0) {
free(contents);
return (1);
}
- failures ++;
- if (!previous_failures(test_filename, test_line, 1)) {
- fprintf(stderr, "%s:%d: File contents don't match\n",
- test_filename, test_line);
- fprintf(stderr, " file=\"%s\"\n", f);
- if (n > 0)
- hexdump(contents, buff, n, 0);
- else {
- fprintf(stderr, " File empty, contents should be:\n");
- hexdump(buff, NULL, s, 0);
+ failure_start(test_filename, test_line, "File contents don't match");
+ logprintf(" file=\"%s\"\n", fn);
+ if (n > 0)
+ hexdump(contents, buff, n > 512 ? 512 : n, 0);
+ else {
+ logprintf(" File empty, contents should be:\n");
+ hexdump(buff, NULL, s > 512 ? 512 : n, 0);
+ }
+ failure_finish(test_extra);
+ free(contents);
+ return (0);
+}
+
+/* Check the contents of a text file, being tolerant of line endings. */
+int
+assertion_text_file_contents(const char *buff, const char *fn)
+{
+ char *contents;
+ const char *btxt, *ftxt;
+ FILE *f;
+ int n, s;
+
+ assertion_count(test_filename, test_line);
+ f = fopen(fn, "r");
+ s = strlen(buff);
+ contents = malloc(s * 2 + 128);
+ n = fread(contents, 1, s * 2 + 128 - 1, f);
+ if (n >= 0)
+ contents[n] = '\0';
+ fclose(f);
+ /* Compare texts. */
+ btxt = buff;
+ ftxt = (const char *)contents;
+ while (*btxt != '\0' && *ftxt != '\0') {
+ if (*btxt == *ftxt) {
+ ++btxt;
+ ++ftxt;
+ continue;
+ }
+ if (btxt[0] == '\n' && ftxt[0] == '\r' && ftxt[1] == '\n') {
+ /* Pass over different new line characters. */
+ ++btxt;
+ ftxt += 2;
+ continue;
}
- report_failure(test_extra);
+ break;
}
+ if (*btxt == '\0' && *ftxt == '\0') {
+ free(contents);
+ return (1);
+ }
+ failure_start(test_filename, test_line, "Contents don't match");
+ logprintf(" file=\"%s\"\n", fn);
+ if (n > 0)
+ hexdump(contents, buff, n, 0);
+ else {
+ logprintf(" File empty, contents should be:\n");
+ hexdump(buff, NULL, s, 0);
+ }
+ failure_finish(test_extra);
free(contents);
return (0);
}
+/* Test that two paths point to the same file. */
+/* As a side-effect, asserts that both files exist. */
+static int
+is_hardlink(const char *file, int line,
+ const char *path1, const char *path2)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ BY_HANDLE_FILE_INFORMATION bhfi1, bhfi2;
+ int r;
+
+ assertion_count(file, line);
+ r = my_GetFileInformationByName(path1, &bhfi1);
+ if (r == 0) {
+ failure_start(file, line, "File %s can't be inspected?", path1);
+ failure_finish(NULL);
+ return (0);
+ }
+ r = my_GetFileInformationByName(path2, &bhfi2);
+ if (r == 0) {
+ failure_start(file, line, "File %s can't be inspected?", path2);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (bhfi1.dwVolumeSerialNumber == bhfi2.dwVolumeSerialNumber
+ && bhfi1.nFileIndexHigh == bhfi2.nFileIndexHigh
+ && bhfi1.nFileIndexLow == bhfi2.nFileIndexLow);
+#else
+ struct stat st1, st2;
+ int r;
+
+ assertion_count(file, line);
+ r = lstat(path1, &st1);
+ if (r != 0) {
+ failure_start(file, line, "File should exist: %s", path1);
+ failure_finish(NULL);
+ return (0);
+ }
+ r = lstat(path2, &st2);
+ if (r != 0) {
+ failure_start(file, line, "File should exist: %s", path2);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev);
+#endif
+}
+
+int
+assertion_is_hardlink(const char *file, int line,
+ const char *path1, const char *path2)
+{
+ if (is_hardlink(file, line, path1, path2))
+ return (1);
+ failure_start(file, line,
+ "Files %s and %s are not hardlinked", path1, path2);
+ failure_finish(NULL);
+ return (0);
+}
+
+int
+assertion_is_not_hardlink(const char *file, int line,
+ const char *path1, const char *path2)
+{
+ if (!is_hardlink(file, line, path1, path2))
+ return (1);
+ failure_start(file, line,
+ "Files %s and %s should not be hardlinked", path1, path2);
+ failure_finish(NULL);
+ return (0);
+}
+
+/* Verify a/b/mtime of 'pathname'. */
+/* If 'recent', verify that it's within last 10 seconds. */
+static int
+assertion_file_time(const char *file, int line,
+ const char *pathname, long t, long nsec, char type, int recent)
+{
+ long long filet, filet_nsec;
+ int r;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define EPOC_TIME (116444736000000000ULL)
+ FILETIME ftime, fbirthtime, fatime, fmtime;
+ ULARGE_INTEGER wintm;
+ HANDLE h;
+ ftime.dwLowDateTime = 0;
+ ftime.dwHighDateTime = 0;
+
+ assertion_count(file, line);
+ h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ failure_start(file, line, "Can't access %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ r = GetFileTime(h, &fbirthtime, &fatime, &fmtime);
+ switch (type) {
+ case 'a': ftime = fatime; break;
+ case 'b': ftime = fbirthtime; break;
+ case 'm': ftime = fmtime; break;
+ }
+ CloseHandle(h);
+ if (r == 0) {
+ failure_start(file, line, "Can't GetFileTime %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ wintm.LowPart = ftime.dwLowDateTime;
+ wintm.HighPart = ftime.dwHighDateTime;
+ filet = (wintm.QuadPart - EPOC_TIME) / 10000000;
+ filet_nsec = ((wintm.QuadPart - EPOC_TIME) % 10000000) * 100;
+ nsec = (nsec / 100) * 100; /* Round the request */
+#else
+ struct stat st;
+
+ assertion_count(file, line);
+ r = lstat(pathname, &st);
+ if (r != 0) {
+ failure_start(file, line, "Can't stat %s\n", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ switch (type) {
+ case 'a': filet = st.st_atime; break;
+ case 'm': filet = st.st_mtime; break;
+ case 'b': filet = 0; break;
+ default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type);
+ exit(1);
+ }
+#if defined(__FreeBSD__)
+ switch (type) {
+ case 'a': filet_nsec = st.st_atimespec.tv_nsec; break;
+ case 'b': filet = st.st_birthtime;
+ filet_nsec = st.st_birthtimespec.tv_nsec; break;
+ case 'm': filet_nsec = st.st_mtimespec.tv_nsec; break;
+ default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type);
+ exit(1);
+ }
+ /* FreeBSD generally only stores to microsecond res, so round. */
+ filet_nsec = (filet_nsec / 1000) * 1000;
+ nsec = (nsec / 1000) * 1000;
+#else
+ filet_nsec = nsec = 0; /* Generic POSIX only has whole seconds. */
+ if (type == 'b') return (1); /* Generic POSIX doesn't have birthtime */
+#if defined(__HAIKU__)
+ if (type == 'a') return (1); /* Haiku doesn't have atime. */
+#endif
+#endif
+#endif
+ if (recent) {
+ /* Check that requested time is up-to-date. */
+ time_t now = time(NULL);
+ if (filet < now - 10 || filet > now + 1) {
+ failure_start(file, line,
+ "File %s has %ctime %ld, %ld seconds ago\n",
+ pathname, type, filet, now - filet);
+ failure_finish(NULL);
+ return (0);
+ }
+ } else if (filet != t || filet_nsec != nsec) {
+ failure_start(file, line,
+ "File %s has %ctime %ld.%09ld, expected %ld.%09ld",
+ pathname, type, filet, filet_nsec, t, nsec);
+ failure_finish(NULL);
+ return (0);
+ }
+ return (1);
+}
+
+/* Verify atime of 'pathname'. */
+int
+assertion_file_atime(const char *file, int line,
+ const char *pathname, long t, long nsec)
+{
+ return assertion_file_time(file, line, pathname, t, nsec, 'a', 0);
+}
+
+/* Verify atime of 'pathname' is up-to-date. */
+int
+assertion_file_atime_recent(const char *file, int line, const char *pathname)
+{
+ return assertion_file_time(file, line, pathname, 0, 0, 'a', 1);
+}
+
+/* Verify birthtime of 'pathname'. */
+int
+assertion_file_birthtime(const char *file, int line,
+ const char *pathname, long t, long nsec)
+{
+ return assertion_file_time(file, line, pathname, t, nsec, 'b', 0);
+}
+
+/* Verify birthtime of 'pathname' is up-to-date. */
+int
+assertion_file_birthtime_recent(const char *file, int line,
+ const char *pathname)
+{
+ return assertion_file_time(file, line, pathname, 0, 0, 'b', 1);
+}
+
+/* Verify mtime of 'pathname'. */
+int
+assertion_file_mtime(const char *file, int line,
+ const char *pathname, long t, long nsec)
+{
+ return assertion_file_time(file, line, pathname, t, nsec, 'm', 0);
+}
+
+/* Verify mtime of 'pathname' is up-to-date. */
+int
+assertion_file_mtime_recent(const char *file, int line, const char *pathname)
+{
+ return assertion_file_time(file, line, pathname, 0, 0, 'm', 1);
+}
+
+/* Verify number of links to 'pathname'. */
+int
+assertion_file_nlinks(const char *file, int line,
+ const char *pathname, int nlinks)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ int r;
+
+ assertion_count(file, line);
+ r = my_GetFileInformationByName(pathname, &bhfi);
+ if (r != 0 && bhfi.nNumberOfLinks == (DWORD)nlinks)
+ return (1);
+ failure_start(file, line, "File %s has %d links, expected %d",
+ pathname, bhfi.nNumberOfLinks, nlinks);
+ failure_finish(NULL);
+ return (0);
+#else
+ struct stat st;
+ int r;
+
+ assertion_count(file, line);
+ r = lstat(pathname, &st);
+ if (r == 0 && st.st_nlink == nlinks)
+ return (1);
+ failure_start(file, line, "File %s has %d links, expected %d",
+ pathname, st.st_nlink, nlinks);
+ failure_finish(NULL);
+ return (0);
+#endif
+}
+
+/* Verify size of 'pathname'. */
+int
+assertion_file_size(const char *file, int line, const char *pathname, long size)
+{
+ int64_t filesize;
+ int r;
+
+ assertion_count(file, line);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ {
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ r = !my_GetFileInformationByName(pathname, &bhfi);
+ filesize = ((int64_t)bhfi.nFileSizeHigh << 32) + bhfi.nFileSizeLow;
+ }
+#else
+ {
+ struct stat st;
+ r = lstat(pathname, &st);
+ filesize = st.st_size;
+ }
+#endif
+ if (r == 0 && filesize == size)
+ return (1);
+ failure_start(file, line, "File %s has size %ld, expected %ld",
+ pathname, (long)filesize, (long)size);
+ failure_finish(NULL);
+ return (0);
+}
+
+/* Assert that 'pathname' is a dir. If mode >= 0, verify that too. */
+int
+assertion_is_dir(const char *file, int line, const char *pathname, int mode)
+{
+ struct stat st;
+ int r;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ (void)mode; /* UNUSED */
+#endif
+ assertion_count(file, line);
+ r = lstat(pathname, &st);
+ if (r != 0) {
+ failure_start(file, line, "Dir should exist: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ failure_start(file, line, "%s is not a dir", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ /* Windows doesn't handle permissions the same way as POSIX,
+ * so just ignore the mode tests. */
+ /* TODO: Can we do better here? */
+ if (mode >= 0 && mode != (st.st_mode & 07777)) {
+ failure_start(file, line, "Dir %s has wrong mode", pathname);
+ logprintf(" Expected: 0%3o\n", mode);
+ logprintf(" Found: 0%3o\n", st.st_mode & 07777);
+ failure_finish(NULL);
+ return (0);
+ }
+#endif
+ return (1);
+}
+
+/* Verify that 'pathname' is a regular file. If 'mode' is >= 0,
+ * verify that too. */
+int
+assertion_is_reg(const char *file, int line, const char *pathname, int mode)
+{
+ struct stat st;
+ int r;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ (void)mode; /* UNUSED */
+#endif
+ assertion_count(file, line);
+ r = lstat(pathname, &st);
+ if (r != 0 || !S_ISREG(st.st_mode)) {
+ failure_start(file, line, "File should exist: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ /* Windows doesn't handle permissions the same way as POSIX,
+ * so just ignore the mode tests. */
+ /* TODO: Can we do better here? */
+ if (mode >= 0 && mode != (st.st_mode & 07777)) {
+ failure_start(file, line, "File %s has wrong mode", pathname);
+ logprintf(" Expected: 0%3o\n", mode);
+ logprintf(" Found: 0%3o\n", st.st_mode & 07777);
+ failure_finish(NULL);
+ return (0);
+ }
+#endif
+ return (1);
+}
+
+/* Check whether 'pathname' is a symbolic link. If 'contents' is
+ * non-NULL, verify that the symlink has those contents. */
+static int
+is_symlink(const char *file, int line,
+ const char *pathname, const char *contents)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ (void)pathname; /* UNUSED */
+ (void)contents; /* UNUSED */
+ assertion_count(file, line);
+ /* Windows sort-of has real symlinks, but they're only usable
+ * by privileged users and are crippled even then, so there's
+ * really not much point in bothering with this. */
+ return (0);
+#else
+ char buff[300];
+ struct stat st;
+ ssize_t linklen;
+ int r;
+
+ assertion_count(file, line);
+ r = lstat(pathname, &st);
+ if (r != 0) {
+ failure_start(file, line,
+ "Symlink should exist: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (!S_ISLNK(st.st_mode))
+ return (0);
+ if (contents == NULL)
+ return (1);
+ linklen = readlink(pathname, buff, sizeof(buff));
+ if (linklen < 0) {
+ failure_start(file, line, "Can't read symlink %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+ buff[linklen] = '\0';
+ if (strcmp(buff, contents) != 0)
+ return (0);
+ return (1);
+#endif
+}
+
+/* Assert that path is a symlink that (optionally) contains contents. */
+int
+assertion_is_symlink(const char *file, int line,
+ const char *path, const char *contents)
+{
+ if (is_symlink(file, line, path, contents))
+ return (1);
+ if (contents)
+ failure_start(file, line, "File %s is not a symlink to %s",
+ path, contents);
+ else
+ failure_start(file, line, "File %s is not a symlink", path);
+ failure_finish(NULL);
+ return (0);
+}
+
+
+/* Create a directory and report any errors. */
+int
+assertion_make_dir(const char *file, int line, const char *dirname, int mode)
+{
+ assertion_count(file, line);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ (void)mode; /* UNUSED */
+ if (0 == _mkdir(dirname))
+ return (1);
+#else
+ if (0 == mkdir(dirname, mode))
+ return (1);
+#endif
+ failure_start(file, line, "Could not create directory %s", dirname);
+ failure_finish(NULL);
+ return(0);
+}
+
+/* Create a file with the specified contents and report any failures. */
+int
+assertion_make_file(const char *file, int line,
+ const char *path, int mode, const char *contents)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* TODO: Rework this to set file mode as well. */
+ FILE *f;
+ (void)mode; /* UNUSED */
+ assertion_count(file, line);
+ f = fopen(path, "wb");
+ if (f == NULL) {
+ failure_start(file, line, "Could not create file %s", path);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (contents != NULL) {
+ if (strlen(contents)
+ != fwrite(contents, 1, strlen(contents), f)) {
+ fclose(f);
+ failure_start(file, line,
+ "Could not write file %s", path);
+ failure_finish(NULL);
+ return (0);
+ }
+ }
+ fclose(f);
+ return (1);
+#else
+ int fd;
+ assertion_count(file, line);
+ fd = open(path, O_CREAT | O_WRONLY, mode >= 0 ? mode : 0644);
+ if (fd < 0) {
+ failure_start(file, line, "Could not create %s", path);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (contents != NULL) {
+ if ((ssize_t)strlen(contents)
+ != write(fd, contents, strlen(contents))) {
+ close(fd);
+ failure_start(file, line, "Could not write to %s", path);
+ failure_finish(NULL);
+ return (0);
+ }
+ }
+ close(fd);
+ return (1);
+#endif
+}
+
+/* Create a hardlink and report any failures. */
+int
+assertion_make_hardlink(const char *file, int line,
+ const char *newpath, const char *linkto)
+{
+ int succeeded;
+
+ assertion_count(file, line);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ succeeded = my_CreateHardLinkA(newpath, linkto);
+#elif HAVE_LINK
+ succeeded = !link(linkto, newpath);
+#else
+ succeeded = 0;
+#endif
+ if (succeeded)
+ return (1);
+ failure_start(file, line, "Could not create hardlink");
+ logprintf(" New link: %s\n", newpath);
+ logprintf(" Old name: %s\n", linkto);
+ failure_finish(NULL);
+ return(0);
+}
+
+/* Create a symlink and report any failures. */
+int
+assertion_make_symlink(const char *file, int line,
+ const char *newpath, const char *linkto)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ int targetIsDir = 0; /* TODO: Fix this */
+ assertion_count(file, line);
+ if (my_CreateSymbolicLinkA(newpath, linkto, targetIsDir))
+ return (1);
+#elif HAVE_SYMLINK
+ assertion_count(file, line);
+ if (0 == symlink(linkto, newpath))
+ return (1);
+#endif
+ failure_start(file, line, "Could not create symlink");
+ logprintf(" New link: %s\n", newpath);
+ logprintf(" Old name: %s\n", linkto);
+ failure_finish(NULL);
+ return(0);
+}
+
+/* Set umask, report failures. */
+int
+assertion_umask(const char *file, int line, int mask)
+{
+ assertion_count(file, line);
+ (void)file; /* UNUSED */
+ (void)line; /* UNUSED */
+ umask(mask);
+ return (1);
+}
+
+/*
+ *
+ * UTILITIES for use by tests.
+ *
+ */
+
+/*
+ * Check whether platform supports symlinks. This is intended
+ * for tests to use in deciding whether to bother testing symlink
+ * support; if the platform doesn't support symlinks, there's no point
+ * in checking whether the program being tested can create them.
+ *
+ * Note that the first time this test is called, we actually go out to
+ * disk to create and verify a symlink. This is necessary because
+ * symlink support is actually a property of a particular filesystem
+ * and can thus vary between directories on a single system. After
+ * the first call, this returns the cached result from memory, so it's
+ * safe to call it as often as you wish.
+ */
+int
+canSymlink(void)
+{
+ /* Remember the test result */
+ static int value = 0, tested = 0;
+ if (tested)
+ return (value);
+
+ ++tested;
+ assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
+ /* Note: Cygwin has its own symlink() emulation that does not
+ * use the Win32 CreateSymbolicLink() function. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ value = my_CreateSymbolicLinkA("canSymlink.1", "canSymlink.0", 0)
+ && is_symlink(__FILE__, __LINE__, "canSymlink.1", "canSymlink.0");
+#elif HAVE_SYMLINK
+ value = (0 == symlink("canSymlink.0", "canSymlink.1"))
+ && is_symlink(__FILE__, __LINE__, "canSymlink.1","canSymlink.0");
+#endif
+ return (value);
+}
+
+/*
+ * Can this platform run the gzip program?
+ */
+/* Platform-dependent options for hiding the output of a subcommand. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static const char *redirectArgs = ">NUL 2>NUL"; /* Win32 cmd.exe */
+#else
+static const char *redirectArgs = ">/dev/null 2>/dev/null"; /* POSIX 'sh' */
+#endif
+int
+canGzip(void)
+{
+ static int tested = 0, value = 0;
+ if (!tested) {
+ tested = 1;
+ if (systemf("gzip -V %s", redirectArgs) == 0)
+ value = 1;
+ }
+ return (value);
+}
+
+/*
+ * Can this platform run the gunzip program?
+ */
+int
+canGunzip(void)
+{
+ static int tested = 0, value = 0;
+ if (!tested) {
+ tested = 1;
+ if (systemf("gunzip -V %s", redirectArgs) == 0)
+ value = 1;
+ }
+ return (value);
+}
+
+/*
+ * Sleep as needed; useful for verifying disk timestamp changes by
+ * ensuring that the wall-clock time has actually changed before we
+ * go back to re-read something from disk.
+ */
+void
+sleepUntilAfter(time_t t)
+{
+ while (t >= time(NULL))
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ Sleep(500);
+#else
+ sleep(1);
+#endif
+}
+
/*
* Call standard system() call, but build up the command line using
* sprintf() conventions.
@@ -682,6 +1470,8 @@ systemf(const char *fmt, ...)
va_start(ap, fmt);
vsprintf(buff, fmt, ap);
+ if (verbosity > VERBOSITY_FULL)
+ logprintf("Cmd: %s\n", buff);
r = system(buff);
va_end(ap);
return (r);
@@ -700,176 +1490,48 @@ slurpfile(size_t * sizep, const char *fmt, ...)
va_list ap;
char *p;
ssize_t bytes_read;
- int fd;
+ FILE *f;
int r;
va_start(ap, fmt);
vsprintf(filename, fmt, ap);
va_end(ap);
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
+ f = fopen(filename, "rb");
+ if (f == NULL) {
/* Note: No error; non-existent file is okay here. */
return (NULL);
}
- r = fstat(fd, &st);
+ r = fstat(fileno(f), &st);
if (r != 0) {
- fprintf(stderr, "Can't stat file %s\n", filename);
- close(fd);
+ logprintf("Can't stat file %s\n", filename);
+ fclose(f);
return (NULL);
}
- p = malloc(st.st_size + 1);
+ p = malloc((size_t)st.st_size + 1);
if (p == NULL) {
- fprintf(stderr, "Can't allocate %ld bytes of memory to read file %s\n", (long int)st.st_size, filename);
- close(fd);
+ logprintf("Can't allocate %ld bytes of memory to read file %s\n",
+ (long int)st.st_size, filename);
+ fclose(f);
return (NULL);
}
- bytes_read = read(fd, p, st.st_size);
+ bytes_read = fread(p, 1, (size_t)st.st_size, f);
if (bytes_read < st.st_size) {
- fprintf(stderr, "Can't read file %s\n", filename);
- close(fd);
+ logprintf("Can't read file %s\n", filename);
+ fclose(f);
free(p);
return (NULL);
}
p[st.st_size] = '\0';
if (sizep != NULL)
*sizep = (size_t)st.st_size;
- close(fd);
+ fclose(f);
return (p);
}
-/*
- * "list.h" is automatically generated; it just has a lot of lines like:
- * DEFINE_TEST(function_name)
- * It's used above to declare all of the test functions.
- * We reuse it here to define a list of all tests (functions and names).
- */
-#undef DEFINE_TEST
-#define DEFINE_TEST(n) { n, #n },
-struct { void (*func)(void); const char *name; } tests[] = {
- #include "list.h"
-};
-
-/*
- * This is well-intentioned, but sometimes the standard libraries
- * leave open file descriptors and expect to be able to come back to
- * them (e.g., for username lookups or logging). Closing these
- * descriptors out from under those libraries creates havoc.
- *
- * Maybe there's some reasonably portable way to tell if a descriptor
- * is open without using close()?
- */
-#if 0
-static void
-close_descriptors(int warn)
-{
- int i;
- int left_open = 0;
-
- for (i = 3; i < 100; ++i) {
- if (close(i) == 0)
- ++left_open;
- }
- if (warn && left_open > 0) {
- fprintf(stderr, " ** %d descriptors unclosed\n", left_open);
- failures += left_open;
- report_failure(NULL);
- }
-}
-#endif
-
-/*
- * Each test is run in a private work dir. Those work dirs
- * do have consistent and predictable names, in case a group
- * of tests need to collaborate. However, there is no provision
- * for requiring that tests run in a certain order.
- */
-static int test_run(int i, const char *tmpdir)
-{
- int failures_before = failures;
-
- if (!quiet_flag) {
- printf("%d: %s\n", i, tests[i].name);
- fflush(stdout);
- }
-
- /*
- * Always explicitly chdir() in case the last test moved us to
- * a strange place.
- */
- if (chdir(tmpdir)) {
- fprintf(stderr,
- "ERROR: Couldn't chdir to temp dir %s\n",
- tmpdir);
- exit(1);
- }
- /* Create a temp directory for this specific test. */
- if (mkdir(tests[i].name, 0755)) {
- fprintf(stderr,
- "ERROR: Couldn't create temp dir ``%s''\n",
- tests[i].name);
- exit(1);
- }
- /* Chdir() to that work directory. */
- if (chdir(tests[i].name)) {
- fprintf(stderr,
- "ERROR: Couldn't chdir to temp dir ``%s''\n",
- tests[i].name);
- exit(1);
- }
- /* Explicitly reset the locale before each test. */
- setlocale(LC_ALL, "C");
- /* Make sure there are no stray descriptors going into the test. */
- /* TODO: Find a better way to identify file descriptor leaks. */
- //close_descriptors(0);
- /* Run the actual test. */
- (*tests[i].func)();
- /* Close stray descriptors, record as errors against this test. */
- //close_descriptors(1);
- /* Summarize the results of this test. */
- summarize();
- /* If there were no failures, we can remove the work dir. */
- if (failures == failures_before) {
- if (!keep_temp_files && chdir(tmpdir) == 0) {
-#if !defined(_WIN32) || defined(__CYGWIN__)
- systemf("rm -rf %s", tests[i].name);
-#else
- systemf("rmdir /S /Q %s", tests[i].name);
-#endif
- }
- }
- /* Return appropriate status. */
- return (failures == failures_before ? 0 : 1);
-}
-
-static void usage(const char *program)
-{
- static const int limit = sizeof(tests) / sizeof(tests[0]);
- int i;
-
- printf("Usage: %s [options] <test> <test> ...\n", program);
- printf("Default is to run all tests.\n");
- printf("Otherwise, specify the numbers of the tests you wish to run.\n");
- printf("Options:\n");
- printf(" -d Dump core after any failure, for debugging.\n");
- printf(" -k Keep all temp files.\n");
- printf(" Default: temp files for successful tests deleted.\n");
-#ifdef PROGRAM
- printf(" -p <path> Path to executable to be tested.\n");
- printf(" Default: path taken from " ENVBASE " environment variable.\n");
-#endif
- printf(" -q Quiet.\n");
- printf(" -r <dir> Path to dir containing reference files.\n");
- printf(" Default: Current directory.\n");
- printf(" -v Verbose.\n");
- printf("Available tests:\n");
- for (i = 0; i < limit; i++)
- printf(" %d: %s\n", i, tests[i].name);
- exit(1);
-}
-
+/* Read a uuencoded file from the reference directory, decode, and
+ * write the result into the current directory. */
#define UUDECODE(c) (((c) - 0x20) & 0x3f)
-
void
extract_reference_file(const char *name)
{
@@ -893,7 +1555,7 @@ extract_reference_file(const char *name)
}
/* Now, decode the rest and write it. */
/* Not a lot of error checking here; the input better be right. */
- out = fopen(name, "w");
+ out = fopen(name, "wb");
while (fgets(buff, sizeof(buff), in) != NULL) {
char *p = buff;
int bytes;
@@ -927,48 +1589,211 @@ extract_reference_file(const char *name)
fclose(in);
}
+/*
+ *
+ * TEST management
+ *
+ */
+
+/*
+ * "list.h" is simply created by "grep DEFINE_TEST test_*.c"; it has
+ * a line like
+ * DEFINE_TEST(test_function)
+ * for each test.
+ */
+
+/* Use "list.h" to declare all of the test functions. */
+#undef DEFINE_TEST
+#define DEFINE_TEST(name) void name(void);
+#include "list.h"
+
+/* Use "list.h" to create a list of all tests (functions and names). */
+#undef DEFINE_TEST
+#define DEFINE_TEST(n) { n, #n, 0 },
+struct { void (*func)(void); const char *name; int failures; } tests[] = {
+ #include "list.h"
+};
+
+/*
+ * Summarize repeated failures in the just-completed test.
+ */
+static void
+test_summarize(const char *filename, int failed)
+{
+ unsigned int i;
+
+ switch (verbosity) {
+ case VERBOSITY_SUMMARY_ONLY:
+ printf(failed ? "E" : ".");
+ fflush(stdout);
+ break;
+ case VERBOSITY_PASSFAIL:
+ printf(failed ? "FAIL\n" : "ok\n");
+ break;
+ }
+
+ log_console = (verbosity == VERBOSITY_LIGHT_REPORT);
-/* Since gzip is by far the most popular external compression program
- * available, we try to use it in the read_program and write_program
- * tests. But if it's not available, then we can't use it. This
- * function just tries to run gzip/gunzip to see if they're available.
- * If not, some of the external compression program tests will be
- * skipped. */
-const char *
-external_gzip_program(int un)
+ for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) {
+ if (failed_lines[i].count > 1 && !failed_lines[i].skip)
+ logprintf("%s:%d: Summary: Failed %d times\n",
+ filename, i, failed_lines[i].count);
+ }
+ /* Clear the failure history for the next file. */
+ memset(failed_lines, 0, sizeof(failed_lines));
+}
+
+/*
+ * Actually run a single test, with appropriate setup and cleanup.
+ */
+static int
+test_run(int i, const char *tmpdir)
{
- static int tested = 0;
- static const char *compress_prog = NULL;
- static const char *decompress_prog = NULL;
- /* Args vary depending on the command interpreter we're using. */
+ char logfilename[64];
+ int failures_before = failures;
+ int oldumask;
+
+ switch (verbosity) {
+ case VERBOSITY_SUMMARY_ONLY: /* No per-test reports at all */
+ break;
+ case VERBOSITY_PASSFAIL: /* rest of line will include ok/FAIL marker */
+ printf("%3d: %-50s", i, tests[i].name);
+ fflush(stdout);
+ break;
+ default: /* Title of test, details will follow */
+ printf("%3d: %s\n", i, tests[i].name);
+ }
+
+ /* Chdir to the top-level work directory. */
+ if (!assertChdir(tmpdir)) {
+ fprintf(stderr,
+ "ERROR: Can't chdir to top work dir %s\n", tmpdir);
+ exit(1);
+ }
+ /* Create a log file for this test. */
+ sprintf(logfilename, "%s.log", tests[i].name);
+ logfile = fopen(logfilename, "w");
+ fprintf(logfile, "%s\n\n", tests[i].name);
+ /* Chdir() to a work dir for this specific test. */
+ if (!assertMakeDir(tests[i].name, 0755)
+ || !assertChdir(tests[i].name)) {
+ fprintf(stderr,
+ "ERROR: Can't chdir to work dir %s/%s\n",
+ tmpdir, tests[i].name);
+ exit(1);
+ }
+ /* Explicitly reset the locale before each test. */
+ setlocale(LC_ALL, "C");
+ /* Record the umask before we run the test. */
+ umask(oldumask = umask(0));
+ /*
+ * Run the actual test.
+ */
+ (*tests[i].func)();
+ /*
+ * Clean up and report afterwards.
+ */
+ /* Restore umask */
+ umask(oldumask);
+ /* Reset locale. */
+ setlocale(LC_ALL, "C");
+ /* Reset directory. */
+ if (!assertChdir(tmpdir)) {
+ fprintf(stderr, "ERROR: Couldn't chdir to temp dir %s\n",
+ tmpdir);
+ exit(1);
+ }
+ /* Report per-test summaries. */
+ tests[i].failures = failures - failures_before;
+ test_summarize(test_filename, tests[i].failures);
+ /* Close the per-test log file. */
+ fclose(logfile);
+ logfile = NULL;
+ /* If there were no failures, we can remove the work dir and logfile. */
+ if (tests[i].failures == 0) {
+ if (!keep_temp_files && assertChdir(tmpdir)) {
#if defined(_WIN32) && !defined(__CYGWIN__)
- static const char *args = "-V >NUL 2>NUL"; /* Win32 cmd.exe */
+ /* Make sure not to leave empty directories.
+ * Sometimes a processing of closing files used by tests
+ * is not done, then rmdir will be failed and it will
+ * leave a empty test directory. So we should wait a few
+ * seconds and retry rmdir. */
+ int r, t;
+ for (t = 0; t < 10; t++) {
+ if (t > 0)
+ Sleep(1000);
+ r = systemf("rmdir /S /Q %s", tests[i].name);
+ if (r == 0)
+ break;
+ }
+ systemf("del %s", logfilename);
#else
- static const char *args = "-V >/dev/null 2>/dev/null"; /* POSIX 'sh' */
+ systemf("rm -rf %s", tests[i].name);
+ systemf("rm %s", logfilename);
#endif
-
- if (!tested) {
- if (systemf("gunzip %s", args) == 0)
- decompress_prog = "gunzip";
- if (systemf("gzip %s", args) == 0)
- compress_prog = "gzip";
- tested = 1;
+ }
}
- return (un ? decompress_prog : compress_prog);
+ /* Return appropriate status. */
+ return (tests[i].failures);
+}
+
+/*
+ *
+ *
+ * MAIN and support routines.
+ *
+ *
+ */
+
+static void
+usage(const char *program)
+{
+ static const int limit = sizeof(tests) / sizeof(tests[0]);
+ int i;
+
+ printf("Usage: %s [options] <test> <test> ...\n", program);
+ printf("Default is to run all tests.\n");
+ printf("Otherwise, specify the numbers of the tests you wish to run.\n");
+ printf("Options:\n");
+ printf(" -d Dump core after any failure, for debugging.\n");
+ printf(" -k Keep all temp files.\n");
+ printf(" Default: temp files for successful tests deleted.\n");
+#ifdef PROGRAM
+ printf(" -p <path> Path to executable to be tested.\n");
+ printf(" Default: path taken from " ENVBASE " environment variable.\n");
+#endif
+ printf(" -q Quiet.\n");
+ printf(" -r <dir> Path to dir containing reference files.\n");
+ printf(" Default: Current directory.\n");
+ printf(" -v Verbose.\n");
+ printf("Available tests:\n");
+ for (i = 0; i < limit; i++)
+ printf(" %d: %s\n", i, tests[i].name);
+ exit(1);
}
static char *
-get_refdir(void)
+get_refdir(const char *d)
{
char tried[512] = { '\0' };
char buff[128];
char *pwd, *p;
+ /* If a dir was specified, try that */
+ if (d != NULL) {
+ pwd = NULL;
+ snprintf(buff, sizeof(buff), "%s", d);
+ p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
+ if (p != NULL) goto success;
+ strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
+ strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
+ goto failure;
+ }
+
/* Get the current dir. */
pwd = getcwd(NULL, 0);
while (pwd[strlen(pwd) - 1] == '\n')
pwd[strlen(pwd) - 1] = '\0';
- printf("PWD: %s\n", pwd);
/* Look for a known file. */
snprintf(buff, sizeof(buff), "%s", pwd);
@@ -983,7 +1808,11 @@ get_refdir(void)
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
+#if defined(LIBRARY)
snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY);
+#else
+ snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM);
+#endif
p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
if (p != NULL) goto success;
strncat(tried, buff, sizeof(tried) - strlen(tried) - 1);
@@ -1003,11 +1832,12 @@ get_refdir(void)
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
}
+failure:
+ printf("Unable to locate known reference file %s\n", KNOWNREF);
+ printf(" Checked following directories:\n%s\n", tried);
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
DebugBreak();
#endif
- printf("Unable to locate known reference file %s\n", KNOWNREF);
- printf(" Checked following directories:\n%s\n", tried);
exit(1);
success:
@@ -1016,31 +1846,42 @@ success:
return strdup(buff);
}
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
{
static const int limit = sizeof(tests) / sizeof(tests[0]);
int i, tests_run = 0, tests_failed = 0, option;
time_t now;
char *refdir_alloc = NULL;
- const char *progname = LIBRARY "_test";
+ const char *progname;
const char *tmp, *option_arg, *p;
char tmpdir[256];
char tmpdir_timestamp[256];
(void)argc; /* UNUSED */
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(HAVE__CrtSetReportMode)
/* To stop to run the default invalid parameter handler. */
_set_invalid_parameter_handler(invalid_parameter_handler);
- /* for open() to a binary mode. */
- _set_fmode(_O_BINARY);
/* Disable annoying assertion message box. */
_CrtSetReportMode(_CRT_ASSERT, 0);
#endif
+ /*
+ * Name of this program, used to build root of our temp directory
+ * tree.
+ */
+ progname = p = argv[0];
+ while (*p != '\0') {
+ /* Support \ or / dir separators for Windows compat. */
+ if (*p == '/' || *p == '\\')
+ progname = p + 1;
+ ++p;
+ }
+
#ifdef PROGRAM
/* Get the target program from environment, if available. */
- testprog = getenv(ENVBASE);
+ testprogfile = getenv(ENVBASE);
#endif
if (getenv("TMPDIR") != NULL)
@@ -1098,19 +1939,19 @@ int main(int argc, char **argv)
break;
case 'p':
#ifdef PROGRAM
- testprog = option_arg;
+ testprogfile = option_arg;
#else
usage(progname);
#endif
break;
case 'q':
- quiet_flag++;
+ verbosity--;
break;
case 'r':
refdir = option_arg;
break;
case 'v':
- verbose = 1;
+ verbosity++;
break;
default:
usage(progname);
@@ -1122,8 +1963,26 @@ int main(int argc, char **argv)
* Sanity-check that our options make sense.
*/
#ifdef PROGRAM
- if (testprog == NULL)
+ if (testprogfile == NULL)
usage(progname);
+ {
+ char *testprg;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* Command.com sometimes rejects '/' separators. */
+ testprg = strdup(testprogfile);
+ for (i = 0; testprg[i] != '\0'; i++) {
+ if (testprg[i] == '/')
+ testprg[i] = '\\';
+ }
+ testprogfile = testprg;
+#endif
+ /* Quote the name that gets put into shell command lines. */
+ testprg = malloc(strlen(testprogfile) + 3);
+ strcpy(testprg, "\"");
+ strcat(testprg, testprogfile);
+ strcat(testprg, "\"");
+ testprog = testprg;
+ }
#endif
/*
@@ -1132,19 +1991,20 @@ int main(int argc, char **argv)
* to make it easier to track the results of multiple tests.
*/
now = time(NULL);
- for (i = 0; i < 1000; i++) {
+ for (i = 0; ; i++) {
strftime(tmpdir_timestamp, sizeof(tmpdir_timestamp),
"%Y-%m-%dT%H.%M.%S",
localtime(&now));
sprintf(tmpdir, "%s/%s.%s-%03d", tmp, progname,
tmpdir_timestamp, i);
- if (mkdir(tmpdir,0755) == 0)
+ if (assertMakeDir(tmpdir,0755))
break;
- if (errno == EEXIST)
- continue;
- fprintf(stderr, "ERROR: Unable to create temp directory %s\n",
- tmpdir);
- exit(1);
+ if (i >= 999) {
+ fprintf(stderr,
+ "ERROR: Unable to create temp directory %s\n",
+ tmpdir);
+ exit(1);
+ }
}
/*
@@ -1152,14 +2012,16 @@ int main(int argc, char **argv)
* reference files, try to find the reference files in
* the "usual places."
*/
- if (refdir == NULL)
- refdir = refdir_alloc = get_refdir();
+ refdir = refdir_alloc = get_refdir(refdir);
/*
* Banner with basic information.
*/
- if (!quiet_flag) {
- printf("Running tests in: %s\n", tmpdir);
+ printf("\n");
+ printf("If tests fail or crash, details will be in:\n");
+ printf(" %s\n", tmpdir);
+ printf("\n");
+ if (verbosity > VERBOSITY_SUMMARY_ONLY) {
printf("Reference files will be read from: %s\n", refdir);
#ifdef PROGRAM
printf("Running tests on: %s\n", testprog);
@@ -1167,6 +2029,9 @@ int main(int argc, char **argv)
printf("Exercising: ");
fflush(stdout);
printf("%s\n", EXTRA_VERSION);
+ } else {
+ printf("Running ");
+ fflush(stdout);
}
/*
@@ -1212,20 +2077,38 @@ int main(int argc, char **argv)
/*
* Report summary statistics.
*/
- if (!quiet_flag) {
+ if (verbosity > VERBOSITY_SUMMARY_ONLY) {
printf("\n");
- printf("%d of %d tests reported failures\n",
- tests_failed, tests_run);
- printf(" Total of %d assertions checked.\n", assertions);
- printf(" Total of %d assertions failed.\n", failures);
- printf(" Total of %d reported skips.\n", skips);
+ printf("Totals:\n");
+ printf(" Tests run: %8d\n", tests_run);
+ printf(" Tests failed: %8d\n", tests_failed);
+ printf(" Assertions checked:%8d\n", assertions);
+ printf(" Assertions failed: %8d\n", failures);
+ printf(" Skips reported: %8d\n", skips);
+ }
+ if (failures) {
+ printf("\n");
+ printf("Failing tests:\n");
+ for (i = 0; i < limit; ++i) {
+ if (tests[i].failures)
+ printf(" %d: %s (%d failures)\n", i,
+ tests[i].name, tests[i].failures);
+ }
+ printf("\n");
+ printf("Details for failing tests: %s\n", tmpdir);
+ printf("\n");
+ } else {
+ if (verbosity == VERBOSITY_SUMMARY_ONLY)
+ printf("\n");
+ printf("%d tests passed, no failures\n", tests_run);
}
free(refdir_alloc);
/* If the final tmpdir is empty, we can remove it. */
/* This should be the usual case when all tests succeed. */
+ assertChdir("..");
rmdir(tmpdir);
- return (tests_failed);
+ return (tests_failed ? 1 : 0);
}
diff --git a/lib/libarchive/test/test.h b/lib/libarchive/test/test.h
index 94c66e8..6ea7b57 100644
--- a/lib/libarchive/test/test.h
+++ b/lib/libarchive/test/test.h
@@ -45,43 +45,85 @@
#error Oops: No config.h and no pre-built configuration in test.h.
#endif
-#if !defined(_WIN32) || defined(__CYGWIN__)
+#include <sys/types.h> /* Windows requires this before sys/stat.h */
+#include <sys/stat.h>
+
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+#if HAVE_DIRENT_H
#include <dirent.h>
-#else
+#endif
+#ifdef HAVE_DIRECT_H
#include <direct.h>
+#define dirent direct
#endif
#include <errno.h>
#include <fcntl.h>
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
-#if !defined(_WIN32) || defined(__CYGWIN__)
+#include <time.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <wchar.h>
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
#endif
-/* No non-FreeBSD platform will have __FBSDID, so just define it here. */
-#ifdef __FreeBSD__
-#include <sys/cdefs.h> /* For __FBSDID */
-#else
-/* Some non-FreeBSD platforms such as newlib-derived ones like
- * cygwin, have __FBSDID, so this definition must be guarded.
+/*
+ * System-specific tweaks. We really want to minimize these
+ * as much as possible, since they make it harder to understand
+ * the mainline code.
*/
-#ifndef __FBSDID
-#define __FBSDID(a) /* null */
+
+/* Windows (including Visual Studio and MinGW but not Cygwin) */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#if !defined(__BORLANDC__)
+#define strdup _strdup
#endif
+#define LOCALE_UTF8 NULL
+#else
+#define LOCALE_UTF8 "de_DE.UTF-8"
#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
+/* Visual Studio */
+#ifdef _MSC_VER
#define snprintf sprintf_s
-#define LOCALE_DE "deu"
-#else
-#define LOCALE_DE "de_DE.UTF-8"
+#endif
+
+#if defined(__BORLANDC__)
+#pragma warn -8068 /* Constant out of range in comparison. */
+#endif
+
+/* Cygwin */
+#if defined(__CYGWIN__)
+/* Cygwin-1.7.x is lazy about populating nlinks, so don't
+ * expect it to be accurate. */
+# define NLINKS_INACCURATE_FOR_DIRS
+#endif
+
+/* Haiku OS */
+#if defined(__HAIKU__)
+/* Haiku has typedefs in stdint.h (needed for int64_t) */
+#include <stdint.h>
+#endif
+
+/* Get a real definition for __FBSDID if we can */
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+
+/* If not, define it so as to avoid dangling semicolons. */
+#ifndef __FBSDID
+#define __FBSDID(a) struct _undefined_hack
#endif
#ifndef O_BINARY
@@ -95,38 +137,81 @@
#define DEFINE_TEST(name) void name(void); void name(void)
/* An implementation of the standard assert() macro */
-#define assert(e) test_assert(__FILE__, __LINE__, (e), #e, NULL)
-
+#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
+/* chdir() and error if it fails */
+#define assertChdir(path) \
+ assertion_chdir(__FILE__, __LINE__, path)
/* Assert two integers are the same. Reports value of each one if not. */
-#define assertEqualInt(v1,v2) \
- test_assert_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-
+#define assertEqualInt(v1,v2) \
+ assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
- test_assert_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
- test_assert_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
+ assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
- test_assert_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
+ assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
/* Assert two files are the same; allow printf-style expansion of second name.
* See below for comments about variable arguments here...
*/
#define assertEqualFile \
- test_setup(__FILE__, __LINE__);test_assert_equal_file
+ assertion_setup(__FILE__, __LINE__);assertion_equal_file
/* Assert that a file is empty; supports printf-style arguments. */
#define assertEmptyFile \
- test_setup(__FILE__, __LINE__);test_assert_empty_file
+ assertion_setup(__FILE__, __LINE__);assertion_empty_file
+/* Assert that a file is not empty; supports printf-style arguments. */
+#define assertNonEmptyFile \
+ assertion_setup(__FILE__, __LINE__);assertion_non_empty_file
+#define assertFileAtime(pathname, sec, nsec) \
+ assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
+#define assertFileAtimeRecent(pathname) \
+ assertion_file_atime_recent(__FILE__, __LINE__, pathname)
+#define assertFileBirthtime(pathname, sec, nsec) \
+ assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
+#define assertFileBirthtimeRecent(pathname) \
+ assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileExists \
- test_setup(__FILE__, __LINE__);test_assert_file_exists
+ assertion_setup(__FILE__, __LINE__);assertion_file_exists
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileNotExists \
- test_setup(__FILE__, __LINE__);test_assert_file_not_exists
+ assertion_setup(__FILE__, __LINE__);assertion_file_not_exists
/* Assert that file contents match a string; supports printf-style arguments. */
#define assertFileContents \
- test_setup(__FILE__, __LINE__);test_assert_file_contents
+ assertion_setup(__FILE__, __LINE__);assertion_file_contents
+#define assertFileMtime(pathname, sec, nsec) \
+ assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
+#define assertFileMtimeRecent(pathname) \
+ assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
+#define assertFileNLinks(pathname, nlinks) \
+ assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
+#define assertFileSize(pathname, size) \
+ assertion_file_size(__FILE__, __LINE__, pathname, size)
+#define assertTextFileContents \
+ assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
+#define assertIsDir(pathname, mode) \
+ assertion_is_dir(__FILE__, __LINE__, pathname, mode)
+#define assertIsHardlink(path1, path2) \
+ assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
+#define assertIsNotHardlink(path1, path2) \
+ assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
+#define assertIsReg(pathname, mode) \
+ assertion_is_reg(__FILE__, __LINE__, pathname, mode)
+#define assertIsSymlink(pathname, contents) \
+ assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
+/* Create a directory, report error if it fails. */
+#define assertMakeDir(dirname, mode) \
+ assertion_make_dir(__FILE__, __LINE__, dirname, mode)
+#define assertMakeFile(path, mode, contents) \
+ assertion_make_file(__FILE__, __LINE__, path, mode, contents)
+#define assertMakeHardlink(newfile, oldfile) \
+ assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
+#define assertMakeSymlink(newfile, linkto) \
+ assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
+#define assertUmask(mask) \
+ assertion_umask(__FILE__, __LINE__, mask)
/*
* This would be simple with C99 variadic macros, but I don't want to
@@ -135,26 +220,60 @@
* but effective.
*/
#define skipping \
- test_setup(__FILE__, __LINE__);test_skipping
+ assertion_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
-void test_setup(const char *, int);
+int assertion_assert(const char *, int, int, const char *, void *);
+int assertion_chdir(const char *, int, const char *);
+int assertion_empty_file(const char *, ...);
+int assertion_equal_file(const char *, const char *, ...);
+int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
+int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
+int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
+int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
+int assertion_file_atime(const char *, int, const char *, long, long);
+int assertion_file_atime_recent(const char *, int, const char *);
+int assertion_file_birthtime(const char *, int, const char *, long, long);
+int assertion_file_birthtime_recent(const char *, int, const char *);
+int assertion_file_contents(const void *, int, const char *, ...);
+int assertion_file_exists(const char *, ...);
+int assertion_file_mtime(const char *, int, const char *, long, long);
+int assertion_file_mtime_recent(const char *, int, const char *);
+int assertion_file_nlinks(const char *, int, const char *, int);
+int assertion_file_not_exists(const char *, ...);
+int assertion_file_size(const char *, int, const char *, long);
+int assertion_is_dir(const char *, int, const char *, int);
+int assertion_is_hardlink(const char *, int, const char *, const char *);
+int assertion_is_not_hardlink(const char *, int, const char *, const char *);
+int assertion_is_reg(const char *, int, const char *, int);
+int assertion_is_symlink(const char *, int, const char *, const char *);
+int assertion_make_dir(const char *, int, const char *, int);
+int assertion_make_file(const char *, int, const char *, int, const char *);
+int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
+int assertion_make_symlink(const char *, int, const char *newpath, const char *);
+int assertion_non_empty_file(const char *, ...);
+int assertion_text_file_contents(const char *buff, const char *f);
+int assertion_umask(const char *, int, int);
+void assertion_setup(const char *, int);
+
void test_skipping(const char *fmt, ...);
-int test_assert(const char *, int, int, const char *, void *);
-int test_assert_empty_file(const char *, ...);
-int test_assert_equal_file(const char *, const char *, ...);
-int test_assert_equal_int(const char *, int, int, const char *, int, const char *, void *);
-int test_assert_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
-int test_assert_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
-int test_assert_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
-int test_assert_file_contents(const void *, int, const char *, ...);
-int test_assert_file_exists(const char *, ...);
-int test_assert_file_not_exists(const char *, ...);
/* Like sprintf, then system() */
int systemf(const char * fmt, ...);
+/* Delay until time() returns a value after this. */
+void sleepUntilAfter(time_t);
+
+/* Return true if this platform can create symlinks. */
+int canSymlink(void);
+
+/* Return true if this platform can run the "gzip" program. */
+int canGzip(void);
+
+/* Return true if this platform can run the "gunzip" program. */
+int canGunzip(void);
+
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
@@ -162,9 +281,6 @@ char *slurpfile(size_t *, const char *fmt, ...);
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
-/* Get external gzip program name */
-const char *external_gzip_program(int un);
-
/*
* Special interfaces for libarchive test harness.
*/
@@ -177,20 +293,9 @@ int read_open_memory(struct archive *, void *, size_t, size_t);
/* "2" version exercises a slightly different set of libarchive APIs. */
int read_open_memory2(struct archive *, void *, size_t, size_t);
-/*
- * ARCHIVE_VERSION_STAMP first appeared in 1.9 and libarchive 2.2.4.
- * We can approximate it for earlier versions, though.
- * This is used to disable tests of features not present in the current
- * version.
- */
-#ifndef ARCHIVE_VERSION_STAMP
-#define ARCHIVE_VERSION_STAMP \
- (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000)
-#endif
-
/* Versions of above that accept an archive argument for additional info. */
-#define assertA(e) test_assert(__FILE__, __LINE__, (e), #e, (a))
+#define assertA(e) assertion_assert(__FILE__, __LINE__, (e), #e, (a))
#define assertEqualIntA(a,v1,v2) \
- test_assert_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a))
+ assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a))
#define assertEqualStringA(a,v1,v2) \
- test_assert_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a))
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a))
diff --git a/lib/libarchive/test/test_acl_pax.c b/lib/libarchive/test/test_acl_pax.c
index 5898a66..f6b065d 100644
--- a/lib/libarchive/test/test_acl_pax.c
+++ b/lib/libarchive/test/test_acl_pax.c
@@ -406,7 +406,7 @@ DEFINE_TEST(test_acl_pax)
struct archive *a;
struct archive_entry *ae;
size_t used;
- int fd;
+ FILE *f;
/* Write an archive to memory. */
assert(NULL != (a = archive_write_new()));
@@ -453,14 +453,14 @@ DEFINE_TEST(test_acl_pax)
#endif
/* Write out the data we generated to a file for manual inspection. */
- assert(-1 < (fd = open("testout", O_WRONLY | O_CREAT | O_TRUNC, 0775)));
- assert(used == (size_t)write(fd, buff, (unsigned int)used));
- close(fd);
+ assert(NULL != (f = fopen("testout", "wb")));
+ assertEqualInt(used, (size_t)fwrite(buff, 1, (unsigned int)used, f));
+ fclose(f);
/* Write out the reference data to a file for manual inspection. */
- assert(-1 < (fd = open("reference", O_WRONLY | O_CREAT | O_TRUNC, 0775)));
- assert(sizeof(reference) == write(fd, reference, sizeof(reference)));
- close(fd);
+ assert(NULL != (f = fopen("reference", "wb")));
+ assert(sizeof(reference) == fwrite(reference, 1, sizeof(reference), f));
+ fclose(f);
/* Assert that the generated data matches the built-in reference data.*/
failure("Generated pax archive does not match reference; check 'testout' and 'reference' files.");
diff --git a/lib/libarchive/test/test_compat_bzip2.c b/lib/libarchive/test/test_compat_bzip2.c
index cbd113b..96eacad 100644
--- a/lib/libarchive/test/test_compat_bzip2.c
+++ b/lib/libarchive/test/test_compat_bzip2.c
@@ -47,7 +47,10 @@ compat_bzip2(const char *name)
int i;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ if (ARCHIVE_OK != archive_read_support_compression_bzip2(a)) {
+ skipping("Unsupported bzip2");
+ return;
+ }
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
diff --git a/lib/libarchive/test/test_compat_cpio.c b/lib/libarchive/test/test_compat_cpio.c
new file mode 100644
index 0000000..b0ead39
--- /dev/null
+++ b/lib/libarchive/test/test_compat_cpio.c
@@ -0,0 +1,106 @@
+/*-
+ * 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$");
+
+/*
+ * Verify our ability to read various sample files.
+ * It should be easy to add any new sample files sent in by users
+ * to this collection of tests.
+ */
+
+/* Copy this function for each test file and adjust it accordingly. */
+
+/*
+ * test_compat_cpio_1.cpio checks heuristics for avoiding false
+ * hardlinks. foo1 and foo2 are files that have nlinks=1 and so
+ * should not be marked as hardlinks even though they have identical
+ * ino values. bar1 and bar2 have nlinks=2 so should be marked
+ * as hardlinks.
+ */
+static void
+test_compat_cpio_1(void)
+{
+ char name[] = "test_compat_cpio_1.cpio";
+ 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, 17));
+
+ /* Read first entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("foo1", archive_entry_pathname(ae));
+ assertEqualString(NULL, archive_entry_hardlink(ae));
+ assertEqualInt(1260250228, archive_entry_mtime(ae));
+ assertEqualInt(1000, archive_entry_uid(ae));
+ assertEqualInt(1000, archive_entry_gid(ae));
+ assertEqualInt(0100644, archive_entry_mode(ae));
+
+ /* Read second entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("foo2", archive_entry_pathname(ae));
+ assertEqualString(NULL, archive_entry_hardlink(ae));
+ assertEqualInt(1260250228, archive_entry_mtime(ae));
+ assertEqualInt(1000, archive_entry_uid(ae));
+ assertEqualInt(1000, archive_entry_gid(ae));
+ assertEqualInt(0100644, archive_entry_mode(ae));
+
+ /* Read third entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("bar1", archive_entry_pathname(ae));
+ assertEqualString(NULL, archive_entry_hardlink(ae));
+ assertEqualInt(1260250228, archive_entry_mtime(ae));
+ assertEqualInt(1000, archive_entry_uid(ae));
+ assertEqualInt(1000, archive_entry_gid(ae));
+ assertEqualInt(0100644, archive_entry_mode(ae));
+
+ /* Read fourth entry. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("bar2", archive_entry_pathname(ae));
+ assertEqualString("bar1", archive_entry_hardlink(ae));
+ assertEqualInt(1260250228, archive_entry_mtime(ae));
+ assertEqualInt(1000, archive_entry_uid(ae));
+ assertEqualInt(1000, archive_entry_gid(ae));
+ assertEqualInt(0100644, archive_entry_mode(ae));
+
+ /* Verify that the format detection worked. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+}
+
+
+DEFINE_TEST(test_compat_cpio)
+{
+ test_compat_cpio_1();
+}
+
+
diff --git a/lib/libarchive/test/test_compat_cpio_1.cpio.uu b/lib/libarchive/test/test_compat_cpio_1.cpio.uu
new file mode 100644
index 0000000..3f0ee52
--- /dev/null
+++ b/lib/libarchive/test/test_compat_cpio_1.cpio.uu
@@ -0,0 +1,19 @@
+$FreeBSD$
+
+begin 644 test_compat_cpio_1.cpio
+M,#<P-S`Q,#`U-CEE8F4P,#`P.#%A-#`P,#`P,V4X,#`P,#`S93@P,#`P,#`P
+M,31B,61E-#<T,#`P,#`P,#0P,#`P,#`P,#`P,#`P,#4T,#`P,#`P,#`P,#`P
+M,#`P,#`P,#`P,#`U,#`P,#`P,#!F;V\Q``!F;V\*,#<P-S`Q,#`U-CEE8F4P
+M,#`P.#%A-#`P,#`P,V4X,#`P,#`S93@P,#`P,#`P,31B,61E-#<T,#`P,#`P
+M,#0P,#`P,#`P,#`P,#`P,#4T,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`U,#`P
+M,#`P,#!F;V\R``!B87(*,#<P-S`Q,#`U-CEE8F4P,#`P.#%A-#`P,#`P,V4X
+M,#`P,#`S93@P,#`P,#`P,C1B,61E-#<T,#`P,#`P,#0P,#`P,#`P,#`P,#`P
+M,#4T,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`U,#`P,#`P,#!B87(Q``!B87H*
+M,#<P-S`Q,#`U-CEE8F4P,#`P.#%A-#`P,#`P,V4X,#`P,#`S93@P,#`P,#`P
+M,C1B,61E-#<T,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#4T,#`P,#`P,#`P,#`P
+M,#`P,#`P,#`P,#`U,#`P,#`P,#!B87(R```P-S`W,#$P,#`P,#`P,#`P,#`P
+M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`Q,#`P,#`P,#`P,#`P,#`P,#`P
+M,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,&(P,#`P,#`P
+/,%1204E,15(A(2$`````
+`
+end
diff --git a/lib/libarchive/test/test_compat_lzma.c b/lib/libarchive/test/test_compat_lzma.c
new file mode 100644
index 0000000..7269a4c
--- /dev/null
+++ b/lib/libarchive/test/test_compat_lzma.c
@@ -0,0 +1,155 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2008 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$");
+
+/*
+Execute the following to rebuild the data for this program:
+ tail -n +33 test_compat_lzma.c | /bin/sh
+
+# Use lzma command of XZ Utils.
+name=test_compat_lzma_1
+zcmd=lzma
+zsuffix=lzma
+ztar_suffix=tlz
+dir="$name`date +%Y%m%d%H%M%S`.$USER"
+mktarfile()
+{
+mkdir $dir
+echo "f1" > $dir/f1
+echo "f2" > $dir/f2
+echo "f3" > $dir/f3
+mkdir $dir/d1
+echo "f1" > $dir/d1/f1
+echo "f2" > $dir/d1/f2
+echo "f3" > $dir/d1/f3
+(cd $dir; tar cf ../$name.tar f1 f2 f3 d1/f1 d1/f2 d1/f3)
+rm -r $dir
+}
+mktarfile
+$zcmd $name.tar
+mv $name.tar.$zsuffix $name.$ztar_suffix
+echo "This is unrelated junk data at the end of the file" >> $name.$ztar_suffix
+uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu
+rm -f $name.$ztar_suffix
+#
+# Use option -e
+#
+name=test_compat_lzma_2
+dir="$name`date +%Y%m%d%H%M%S`.$USER"
+mktarfile
+$zcmd -e $name.tar
+mv $name.tar.$zsuffix $name.$ztar_suffix
+uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu
+rm -f $name.$ztar_suffix
+#
+# Use lzma command of LZMA SDK with option -d12.
+#
+name=test_compat_lzma_3
+zcmd=lzmasdk # Change this path to use lzma of LZMA SDK.
+dir="$name`date +%Y%m%d%H%M%S`.$USER"
+mktarfile
+$zcmd e -d12 $name.tar $name.$ztar_suffix
+rm -f $name.tar
+uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu
+rm -f $name.$ztar_suffix
+
+exit 0
+*/
+
+/*
+ * Verify our ability to read sample files compatibly with unlzma.
+ *
+ * In particular:
+ * * unlzma will read multiple lzma streams, concatenating the output
+ * * unlzma will read lzma streams which is made by lzma with option -e,
+ * concatenating the output
+ *
+ * Verify our ability to read sample files compatibly with lzma of
+ * LZMA SDK.
+ * * lzma will read lzma streams which is made by lzma with option -d12,
+ * concatenating the output
+ */
+
+/*
+ * All of the sample files have the same contents; they're just
+ * compressed in different ways.
+ */
+static void
+compat_lzma(const char *name)
+{
+ const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL };
+ struct archive_entry *ae;
+ struct archive *a;
+ int i, r;
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ r = archive_read_support_compression_lzma(a);
+ if (r == ARCHIVE_WARN) {
+ skipping("lzma reading not fully supported on this platform");
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ extract_reference_file(name);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
+
+ /* Read entries, match up names with list above. */
+ for (i = 0; i < 6; ++i) {
+ failure("Could not read file %d (%s) from %s", i, n[i], name);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae));
+ assertEqualString(n[i], archive_entry_pathname(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_LZMA);
+ assertEqualString(archive_compression_name(a), "lzma");
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+}
+
+
+DEFINE_TEST(test_compat_lzma)
+{
+ /* This sample has been added junk datas to its tail. */
+ compat_lzma("test_compat_lzma_1.tlz");
+ /* This sample has been made by lzma with option -e,
+ * the first byte of which is 0x5e.
+ * Not supported in libarchive 2.7.* and earlier */
+ compat_lzma("test_compat_lzma_2.tlz");
+ /* This sample has been made by lzma of LZMA SDK with
+ * option -d12, second byte and third byte of which is
+ * not zero.
+ * Not supported in libarchive 2.7.* and earlier */
+ compat_lzma("test_compat_lzma_3.tlz");
+}
diff --git a/lib/libarchive/test/test_compat_lzma_1.tlz.uu b/lib/libarchive/test/test_compat_lzma_1.tlz.uu
new file mode 100644
index 0000000..3b63211
--- /dev/null
+++ b/lib/libarchive/test/test_compat_lzma_1.tlz.uu
@@ -0,0 +1,10 @@
+$FreeBSD$
+
+begin 644 test_compat_lzma_1.tlz
+M70``@`#__________P`S##P;IXPT!HUK`DO\DC[V2OB%Z^'=ZT59ANYMTD(/
+M^W;\8!%O7<+P&=#(9W<_!$Z.7/Y<&\(8+E0^,_-\Z"D^P'N0J^4-UH"WMJ<&
+MV-P6=Y[-FY$IFNZ="RF24TO.B7EP[F]BGMJSP[]OZ_P9/#J'T=;7E&&A@J<[
+MA^C'Q*/Y&I)2^T930'MJTK-98U0D9R*-X2^5__6H:+A4:&ES(&ES('5N<F5L
+F871E9"!J=6YK(&1A=&$@870@=&AE(&5N9"!O9B!T:&4@9FEL90H`
+`
+end
diff --git a/lib/libarchive/test/test_compat_lzma_2.tlz.uu b/lib/libarchive/test/test_compat_lzma_2.tlz.uu
new file mode 100644
index 0000000..3d73898
--- /dev/null
+++ b/lib/libarchive/test/test_compat_lzma_2.tlz.uu
@@ -0,0 +1,9 @@
+$FreeBSD$
+
+begin 644 test_compat_lzma_2.tlz
+M7@``@`#__________P`S##P;IXPT!HUK`DO\DC[V2OB%Z^'<FN`(!=!,)@8W
+M9R(6\QIOTA6SGM20X;2'6#3B&HC%2XOX2?D['5WD"`>`W2"/3R1F1:P:&Q9A
+MGH2JJI9$C?8.=WTE:O<1WA@X>DK-Y#SW;I2!P;NYG^2"-(D9/E(D_0XK_H,\
+95*/V"T#E9ZO][@'R,6E&^A([.##_\M#YU@``
+`
+end
diff --git a/lib/libarchive/test/test_compat_lzma_3.tlz.uu b/lib/libarchive/test/test_compat_lzma_3.tlz.uu
new file mode 100644
index 0000000..b8d61b7
--- /dev/null
+++ b/lib/libarchive/test/test_compat_lzma_3.tlz.uu
@@ -0,0 +1,9 @@
+$FreeBSD$
+
+begin 644 test_compat_lzma_3.tlz
+M70`0````'``````````S##P;IXPT!HUK`DO\DC[V2OB%Z^'=ZT59ANYMTD(1
+M$Y^=;\4%U_CXKQ*F$OFZKEQUG)1U8="](V<2K"U1\Z6%H(UNQ[Y3.=D'>_G-
+MCO71X+M*7WH7$D1&E9Y$XHW,(`[X";GGTO+,'&1?F%<@`.$-OV;8P1?*M$A"
+:MA+1XONREMK,1('455L=X1>WC#1YW"('I@``
+`
+end
diff --git a/lib/libarchive/test/test_compat_solaris_tar_acl.c b/lib/libarchive/test/test_compat_solaris_tar_acl.c
index ec3955e..af4f9d3 100644
--- a/lib/libarchive/test/test_compat_solaris_tar_acl.c
+++ b/lib/libarchive/test/test_compat_solaris_tar_acl.c
@@ -50,9 +50,9 @@ DEFINE_TEST(test_compat_solaris_tar_acl)
/* Archive has 1 entry with some ACLs set on it. */
assertA(0 == archive_read_next_header(a, &ae));
- failure("Basic ACLs should set mode to 0640, not %04o",
+ failure("Basic ACLs should set mode to 0644, not %04o",
archive_entry_mode(ae)&0777);
- assertEqualInt((archive_entry_mode(ae) & 0777), 0640);
+ assertEqualInt((archive_entry_mode(ae) & 0777), 0644);
assertEqualInt(7, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
@@ -77,7 +77,7 @@ DEFINE_TEST(test_compat_solaris_tar_acl)
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
&type, &permset, &tag, &qual, &name));
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
- assertEqualInt(000, permset);
+ assertEqualInt(004, permset);
assertEqualInt(ARCHIVE_ENTRY_ACL_OTHER, tag);
assertEqualInt(-1, qual);
assert(name == NULL);
diff --git a/lib/libarchive/test/test_entry.c b/lib/libarchive/test/test_entry.c
index b79e822..bd946c4 100644
--- a/lib/libarchive/test/test_entry.c
+++ b/lib/libarchive/test/test_entry.c
@@ -51,13 +51,40 @@ DEFINE_TEST(test_entry)
const char *xname; /* For xattr tests. */
const void *xval; /* For xattr tests. */
size_t xsize; /* For xattr tests. */
- int c;
wchar_t wc;
long l;
assert((e = archive_entry_new()) != NULL);
/*
+ * Verify that the AE_IF* defines match S_IF* defines
+ * on this platform. See comments in archive_entry.h.
+ */
+#ifdef S_IFREG
+ assertEqualInt(S_IFREG, AE_IFREG);
+#endif
+#ifdef S_IFLNK
+ assertEqualInt(S_IFLNK, AE_IFLNK);
+#endif
+#ifdef S_IFSOCK
+ assertEqualInt(S_IFSOCK, AE_IFSOCK);
+#endif
+#ifdef S_IFCHR
+ assertEqualInt(S_IFCHR, AE_IFCHR);
+#endif
+/* Work around MinGW, which defines S_IFBLK wrong. */
+/* sourceforge.net/tracker/?func=detail&atid=102435&aid=1942809&group_id=2435 */
+#if defined(S_IFBLK) && !defined(_WIN32)
+ assertEqualInt(S_IFBLK, AE_IFBLK);
+#endif
+#ifdef S_IFDIR
+ assertEqualInt(S_IFDIR, AE_IFDIR);
+#endif
+#ifdef S_IFIFO
+ assertEqualInt(S_IFIFO, AE_IFIFO);
+#endif
+
+ /*
* Basic set/read tests for all fields.
* We should be able to set any field and read
* back the same value.
@@ -414,7 +441,7 @@ DEFINE_TEST(test_entry)
skipping("ACL preserved by archive_entry_clone()");
#else
/* Verify ACL was copied. */
- assertEqualInt(4, c = archive_entry_acl_reset(e2,
+ assertEqualInt(4, archive_entry_acl_reset(e2,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
/* First three are standard permission bits. */
assertEqualInt(0, archive_entry_acl_next(e2,
@@ -455,7 +482,7 @@ DEFINE_TEST(test_entry)
skipping("xattr data preserved by archive_entry_clone");
#else
/* Verify xattr was copied. */
- assertEqualInt(1, c = archive_entry_xattr_reset(e2));
+ assertEqualInt(1, archive_entry_xattr_reset(e2));
assertEqualInt(0, archive_entry_xattr_next(e2, &xname, &xval, &xsize));
assertEqualString(xname, "xattr1");
assertEqualString(xval, "xattrvalue");
@@ -539,7 +566,7 @@ DEFINE_TEST(test_entry)
skipping("ACL held by clone of archive_entry");
#else
/* Verify ACL was unchanged. */
- assertEqualInt(4, c = archive_entry_acl_reset(e2,
+ assertEqualInt(4, archive_entry_acl_reset(e2,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
/* First three are standard permission bits. */
assertEqualInt(0, archive_entry_acl_next(e2,
@@ -807,7 +834,7 @@ DEFINE_TEST(test_entry)
/*
* Exercise the character-conversion logic, if we can.
*/
- if (NULL == setlocale(LC_ALL, LOCALE_DE)) {
+ if (NULL == LOCALE_UTF8 || NULL == setlocale(LC_ALL, LOCALE_UTF8)) {
skipping("Can't exercise charset-conversion logic without"
" a suitable locale.");
} else {
diff --git a/lib/libarchive/test/test_entry_strmode.c b/lib/libarchive/test/test_entry_strmode.c
index 5ede8b6..70c0e75 100644
--- a/lib/libarchive/test/test_entry_strmode.c
+++ b/lib/libarchive/test/test_entry_strmode.c
@@ -31,11 +31,11 @@ DEFINE_TEST(test_entry_strmode)
assert((entry = archive_entry_new()) != NULL);
- archive_entry_set_mode(entry, S_IFREG | 0642);
+ archive_entry_set_mode(entry, AE_IFREG | 0642);
assertEqualString(archive_entry_strmode(entry), "-rw-r---w- ");
/* Regular file + hardlink still shows as regular file. */
- archive_entry_set_mode(entry, S_IFREG | 0644);
+ archive_entry_set_mode(entry, AE_IFREG | 0644);
archive_entry_set_hardlink(entry, "link");
assertEqualString(archive_entry_strmode(entry), "-rw-r--r-- ");
@@ -44,22 +44,22 @@ DEFINE_TEST(test_entry_strmode)
assertEqualString(archive_entry_strmode(entry), "hrw-r----- ");
archive_entry_set_hardlink(entry, NULL);
- archive_entry_set_mode(entry, S_IFDIR | 0777);
+ archive_entry_set_mode(entry, AE_IFDIR | 0777);
assertEqualString(archive_entry_strmode(entry), "drwxrwxrwx ");
- archive_entry_set_mode(entry, S_IFBLK | 03642);
+ archive_entry_set_mode(entry, AE_IFBLK | 03642);
assertEqualString(archive_entry_strmode(entry), "brw-r-S-wT ");
- archive_entry_set_mode(entry, S_IFCHR | 05777);
+ archive_entry_set_mode(entry, AE_IFCHR | 05777);
assertEqualString(archive_entry_strmode(entry), "crwsrwxrwt ");
- archive_entry_set_mode(entry, S_IFSOCK | 0222);
+ archive_entry_set_mode(entry, AE_IFSOCK | 0222);
assertEqualString(archive_entry_strmode(entry), "s-w--w--w- ");
- archive_entry_set_mode(entry, S_IFIFO | 0444);
+ archive_entry_set_mode(entry, AE_IFIFO | 0444);
assertEqualString(archive_entry_strmode(entry), "pr--r--r-- ");
- archive_entry_set_mode(entry, S_IFLNK | 04000);
+ archive_entry_set_mode(entry, AE_IFLNK | 04000);
assertEqualString(archive_entry_strmode(entry), "l--S------ ");
archive_entry_acl_add_entry(entry, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
diff --git a/lib/libarchive/test/test_extattr_freebsd.c b/lib/libarchive/test/test_extattr_freebsd.c
index 19881c2..de3ae2a 100644
--- a/lib/libarchive/test/test_extattr_freebsd.c
+++ b/lib/libarchive/test/test_extattr_freebsd.c
@@ -85,7 +85,7 @@ DEFINE_TEST(test_extattr_freebsd)
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");
+ skipping("Restoring xattr to an unwritable file seems to be broken on this platform");
extattr_privilege_bug = 1;
}
close(fd);
@@ -114,17 +114,15 @@ DEFINE_TEST(test_extattr_freebsd)
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));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
archive_entry_free(ae);
/* Close the archive. */
- assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
+ if (extattr_privilege_bug)
+ /* If the bug is here, write_close will return warning. */
+ assertEqualIntA(a, ARCHIVE_WARN, archive_write_close(a));
+ else
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
/* Verify the data on disk. */
diff --git a/lib/libarchive/test/test_fuzz.c b/lib/libarchive/test/test_fuzz.c
index 9c5a056..7e3f28d 100644
--- a/lib/libarchive/test/test_fuzz.c
+++ b/lib/libarchive/test/test_fuzz.c
@@ -44,86 +44,87 @@ __FBSDID("$FreeBSD$");
* post-failure diagnostics.
*/
-/* Because this works for any archive, I can just re-use the archives
- * developed for other tests. I've not included all of the compressed
- * archives here, though; I don't want to spend all of my test time
- * testing zlib and bzlib. */
-static const char *
-files[] = {
- "test_fuzz_1.iso",
- "test_compat_bzip2_1.tbz",
- "test_compat_gtar_1.tar",
- "test_compat_tar_hardlink_1.tar",
- "test_compat_zip_1.zip",
- "test_read_format_gtar_sparse_1_17_posix10_modified.tar",
- "test_read_format_tar_empty_filename.tar",
- "test_read_format_zip.zip",
- NULL
+/* Because this works for any archive, we can just re-use the archives
+ * developed for other tests. */
+static struct {
+ int uncompress; /* If 1, decompress the file before fuzzing. */
+ const char *name;
+} files[] = {
+ {0, "test_fuzz_1.iso.Z"}, /* Exercise compress decompressor. */
+ {1, "test_fuzz_1.iso.Z"},
+ {0, "test_compat_bzip2_1.tbz"}, /* Exercise bzip2 decompressor. */
+ {1, "test_compat_bzip2_1.tbz"},
+ {0, "test_compat_gtar_1.tar"},
+ {0, "test_compat_gzip_1.tgz"}, /* Exercise gzip decompressor. */
+ {0, "test_compat_gzip_2.tgz"}, /* Exercise gzip decompressor. */
+ {0, "test_compat_tar_hardlink_1.tar"},
+ {0, "test_compat_xz_1.txz"}, /* Exercise xz decompressor. */
+ {0, "test_compat_zip_1.zip"},
+ {0, "test_read_format_ar.ar"},
+ {0, "test_read_format_cpio_bin_be.cpio"},
+ {0, "test_read_format_gtar_sparse_1_17_posix10_modified.tar"},
+ {0, "test_read_format_mtree.mtree"},
+ {0, "test_read_format_tar_empty_filename.tar"},
+ {0, "test_read_format_zip.zip"},
+ {1, NULL}
};
-#define UnsupportedCompress(r, a) \
- (r != ARCHIVE_OK && \
- (strcmp(archive_error_string(a), \
- "Unrecognized archive format") == 0 && \
- archive_compression(a) == ARCHIVE_COMPRESSION_NONE))
-
DEFINE_TEST(test_fuzz)
{
- const char **filep;
const void *blk;
size_t blk_size;
off_t blk_offset;
+ int n;
- for (filep = files; *filep != NULL; ++filep) {
+ for (n = 0; files[n].name != NULL; ++n) {
+ const size_t buffsize = 30000000;
+ const char *filename = files[n].name;
struct archive_entry *ae;
struct archive *a;
char *rawimage, *image;
size_t size;
- int i, r;
-
- extract_reference_file(*filep);
- rawimage = slurpfile(&size, *filep);
- assert(rawimage != NULL);
- image = malloc(size);
- assert(image != NULL);
- srand(time(NULL));
+ int i;
- assert((a = archive_read_new()) != NULL);
- assert(0 == archive_read_support_compression_all(a));
- assert(0 == archive_read_support_format_all(a));
- assert(0 == archive_read_open_memory(a, rawimage, size));
- r = archive_read_next_header(a, &ae);
- if (UnsupportedCompress(r, a)) {
- skipping("Skipping GZIP/BZIP2 compression check: "
- "This version of libarchive was compiled "
- "without gzip/bzip2 support");
- assert(0 == archive_read_close(a));
- assert(0 == archive_read_finish(a));
- continue;
- }
- assert(0 == r);
- if (r == ARCHIVE_OK) {
- char buff[20];
-
- r = archive_read_data(a, buff, 19);
- if (r < ARCHIVE_OK && strcmp(archive_error_string(a),
- "libarchive compiled without deflate support (no libz)") == 0) {
- skipping("Skipping ZIP compression check: %s",
- archive_error_string(a));
- assert(0 == archive_read_close(a));
- assert(0 == archive_read_finish(a));
+ extract_reference_file(filename);
+ if (files[n].uncompress) {
+ int r;
+ /* Use format_raw to decompress the data. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_format_raw(a));
+ r = archive_read_open_filename(a, filename, 16384);
+ if (r != ARCHIVE_OK) {
+ archive_read_finish(a);
+ skipping("Cannot uncompress %s", filename);
continue;
}
- while (0 == archive_read_data_block(a, &blk,
- &blk_size, &blk_offset))
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae));
+ rawimage = malloc(buffsize);
+ size = archive_read_data(a, rawimage, buffsize);
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_next_header(a, &ae));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_finish(a));
+ assert(size > 0);
+ failure("Internal buffer is not big enough for "
+ "uncompressed test file: %s", filename);
+ if (!assert(size < buffsize))
+ continue;
+ } else {
+ rawimage = slurpfile(&size, filename);
+ if (!assert(rawimage != NULL))
continue;
-
}
- assert(0 == archive_read_close(a));
- assert(0 == archive_read_finish(a));
+ image = malloc(size);
+ assert(image != NULL);
+ srand((unsigned)time(NULL));
for (i = 0; i < 100; ++i) {
- int j, fd, numbytes;
+ FILE *f;
+ int j, numbytes;
/* Fuzz < 1% of the bytes in the archive. */
memcpy(image, rawimage, size);
@@ -133,11 +134,10 @@ DEFINE_TEST(test_fuzz)
/* Save the messed-up image to a file.
* If we crash, that file will be useful. */
- fd = open("after.test.failure.send.this.file."
- "to.libarchive.maintainers.with.system.details",
- O_WRONLY | O_CREAT | O_TRUNC, 0744);
- write(fd, image, (off_t)size);
- close(fd);
+ f = fopen("after.test.failure.send.this.file."
+ "to.libarchive.maintainers.with.system.details", "wb");
+ fwrite(image, 1, (size_t)size, f);
+ fclose(f);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
diff --git a/lib/libarchive/test/test_fuzz_1.iso.Z.uu b/lib/libarchive/test/test_fuzz_1.iso.Z.uu
new file mode 100644
index 0000000..6044296
--- /dev/null
+++ b/lib/libarchive/test/test_fuzz_1.iso.Z.uu
@@ -0,0 +1,495 @@
+$FreeBSD$
+
+begin 644 test_fuzz_1.iso.Z
+M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR
+MI,F3*%.J7,FRI<N7,&/*G$FSILV;.'/JW,FSI\^?0(,*'4JTJ-&C2),J7<JT
+MJ=.G4*-*G4JUJM6K6+-JW<JUJ]>O8,.*'4NVK-FS:-.J7<NVK=NW<./*G4NW
+MKMV[>//JW<NWK]^_@`,+'DRXL.'#B!,K7LRXL>/'D"-+GDRYLN7+F#-KWLRY
+ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
+MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
+MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA
+MA!1***`43S11X88<1GA0%`(,)$`4'QT(0``F'H@``@"(PJ)`"(A"04(6#"0"
+M`!P4E..+`;'(Q@(6),!``^"$>&)`*`+0X9),-NGDDU!&*>645%9IY9589JGE
+MEEQ>V<0224SQA!%3@!#F$R#D8(,-,+R`!)D@&)$$$T5,D<445!2AH1!5S$E$
+M$5*`8`((%Q8QQ!-2/"A@"U*\0(05BDI11!!4(`H""D.D`$(,.>0P`PA%N)#%
+M$U4X<0010=!Y:::;=GH#"$JX`,6D4HCIQ`NQ3C$$$G,RD82I708K;+`R$(A#
+M##'(4&P.R<8P`X'@%`O#L<DNV^RS,(!#X+;<=DL@`-)2JRP,S,K@++0'#JON
+MNNRVZ^Z[\,8K[[STUBOE?_@N)H"`!!H8D!$`R`%`&0,#(`0`4P!`A)(,@]#P
+MPPX[/(3"`$@!P!,`-`'QQA%O;!"((D91P@M%<)1BB@"L&'`"`R4@!P8):6`C
+M`.X45#./*0/P8Y!#%HDDDB9V+#3'1`]M=-%('ZUTTDPO[7334#\M==143VUU
+MU5A?K7767&]]M<9+`)`$PA<C2+;#8R>,L<,Y`&"#VP#``,`7`"!A=L(.`SPV
+M$P"4G'`69%/1=\8,'UR%V`#PO7#)%CML`L,3+VQQR1-C;/'"$E/<0L5S4VP%
+MQ9E/#D`074-=^M2G,QTNLN.6>VZVJU=+[K70>FO[MN`:R[JUYF(+3KKV!B_\
+M\,07;_SQR"</9;[,'_8/OP6:V/STU%=O_?78%_=E$B!,$08=(#CQAAT@*`L"
+MN3HDF_ZGX2K0QAIIS/&&&7.4[T*!(+101?Z!MJ!$_F\`P1C(X(+X!7"`7R!#
+M&@26O08Z\($0C*`$LW*@'/WL9^(0R(%(]P$`I$.#HPN""$=(PA*:\(0BS)D'
+M0"@'.7RA#>,K`QD.-`Z!A(B#`%B'0`800A3Z\(<I/%`(!$*`T0&@B.$@XNBV
+M5<1M*#$(_2IB-9Y((!D4\1E4A,$,BIB,+-*@B,/(8@V*V(LLVJ"(M\CB#8H8
+MBRSBH(BKR&(.BEB*+`:AB)_(HA"*F(DL#J&(D\@B$8K8B"P6H8B'R*(1BAB(
+M+!ZAB'O((A**6(<L)J&(;\BB$HJ8ABPNH8ACR"(3BMB%+#:AB%?(HA.*2**`
+M%!&*,'A"$</FRB7"``I%+%DM81F%(OX@BU(H8MMV2:`I%'$&6:1"$3='3!A4
+MH8@GR*(5#D0.@13`B!ULAT`,T$,@>K.$1[I10`Y@Q`-Q0R`L(]V!K"$0!903
+M`-`0R`+>J0R!,."=Q!!(`][I"X$XX)VX$,@#WBD+@4#@G:P02`3>:0J!2."=
+MH!#(!-ZI"8',2)T`H(1`*O!.1PBD1AA%A$`N\$Y!"`1F&.6#0#+P3CL(1&88
+MA8-`-O!.-0@D1Q@E@T`Z\$XO"&2%&,6"0#J(48L%Q&$8Y5M`AHA1@`7D1A@%
+M@D!&\$X="(0$[Z2!0$KP3A<(Y'$818%`HHG1<@A$K!BE:D!4\,YN"&0%[[R&
+M0%CPSF@(9',8789`O(K18@CD!>_\A4#DAM%<""0&[YR%0&3PSE8(!)D8/85`
+MM(K14`BD!N_<A$#>AM%*".0&[WR$0'#PSD0(I&T8'81`K(K1/@AD!^^\@T!X
+M\,XX"*0'[UR#0'SP3H(%Y)<8I5M`I(I1P`6$=!A-6$`.AE&-!61B&#V"0!:&
+M4=(%I&08A>V_WHG9@$@7HX`-B-TPF@*!C`VCYA"($MZ)U8"$#:/>$`C?,(H-
+M@6@,H](0B!/>R0R!8`RCQA`(%-X)#(&0"*.Z$(C%,$H+@20,HZX0B.`PB@J!
+M'`ZCHA#(YS#*"8&D$J.6$(A0,0H)@0`.HXH0B!;>20B!;.&=?A`(%]Z)!X&4
+M$J,,!(!/,<H&@=`-HV80"!C>.>2`A.&=*PZ(&-XIN("$$J/[#8A.,6JW@!`,
+MHP<+2)`Q2MN`G.&=;PL(&MXIMX!T$J-L#8A-,7H.@>@6HUP-2(\Q^@V!M.&=
+MV1"(&]XY#8%D$J/-$(A,,7H,@=@6H\$0B,`PN@N!S.&=M1`('=[Y"H%4$J.I
+M$(A+,3H*@<@6HYT02(TQ>@F!Y.&=D1"('MZY"(%$$J.%$(A*,?H'@;@6HZ<.
+M2(PQ^NB`U!JC=PX((-[YY8`T$J-'#HA),?KB@*@6HX<+2(LQBK&`Q!JC8PN(
+M(=XYL8`D$J.X#8A(,0K:@)@6HX@-2(HQ"M>`M!JCZ!`((][YN(`4$J/@$(A'
+M,:H-@8@6H]002(DQZ@R!I!JCR!"()-XI#($$$J.\$(A&,6H+@7@6H[`02(@Q
+MJ@J!E!JCI!`()M[I"8'T$:,C#TA%,;KP@&@6H_,.2(<QNNV`A!JCPPY(R3&Z
+MZH#D$:.3#DA$,;KG@%@6HV,.2(8QNN2`=!JC,PY(R#'ZN8#4$:,##DA#,;K>
+M@$@6HPL+2(4QRMN`9!JCI`U(QS'*V(#$$:-T#4A"K3O!NMO][GC/>WBDAZ,C
+M^3T@&0P`#@7R0<%_\_`CS-E/3]3"%\9PA@.IH0`&'Q`=#@#QF/\[`(9(`-(5
+M42!)[#P3!^)$T1?H\P&9HNFM.!`LFGZ+`^FBZ;\XD#":?HP#*:/ISSB0-)I^
+MC0-IH^G?.)`XFGZ.`ZFCZ>\XD#R:?H\#Z:/I_SB00)I^D`,II.D/.9!$FGZ1
+M`VFDZ1\YD$B:?I(#J:3I+SF03)I^DP/II.D_.9!0FGZ4`RFEZ4\YD%2:?I4#
+M02*F)TL#$3:FATL#43*FUTL#\4NF%TP#T3:F9TP#@4RFITP#L3FF]TP#$4VF
+M-TT#44T%0'D`H$T&@'F(IWDW<@`8)1#GE``M&!#LI``Q"$\`L``U6$\,4(/Y
+MU``UV$\.4(,!]0`U6%`04(,)%0$UV%`24(,1-0$U6%$44(,:50$UZ%$64(,B
+M=0$U:%(84(,JE0$UZ%(:4(,RM0$U:%,<4(,ZU0$UZ%,>4(-"]0$UV#@UR#<A
+M4(,`(P(U*%4C4(-610(UJ%4E4(->90(U*%8G4(-FA0(U2%4J4(-NM0(U*%<L
+M4(-VU0(UJ%<N4(-^]0(U*%@P4(.&%0,UJ%@R4(..-0,U*%DT4(.650,UJ%DV
+M4(.>=0,U*%HX4(.FE0,UJ%HZ4(.NM0,U*%L\4(.VU0,UJ%L^4(,$\P,U2#=`
+M4(,G5H,)(P0UJ#%#4(/2A2J:1SJ3HGFP900UB%E'4(.`A00U6%Y)4(/II00U
+MB%5+4(/QQ00U6%]-4(/YY00UV%]/4(,!!@4U6&!14(,))@4UV&!34(,11@4U
+M6&%54(,99@4UV&%74(,AA@4U6&)94(,II@4UV&);4(,QQ@4U6&-=4(,"XP4U
+MV&-?4(-!!@8U.&1A4(,K)@8U*#AC4(/[108U:#=E4(,'8P8U2%MG4(-O@P8U
+M*#=I4(-LI08UV&9K4(-<Q08U6&=M4(-YY@8UV&=O4(.!!@<U6&AQ4(.))@<U
+MV&AS4(.11@<U6&EU4(.99@<UV&EW4(.AA@<U6&IY4(.II@<UV&I[4(.QQ@<U
+M6&M]4(.GY@<U^&A_4(-W!@@U^&6!4(-')@@U^&*#4(.'0P@UB#&%4(-C8P@U
+M.#&'4(.XA0@U"%J)4(.(I0@U"%>+4(/QQ@@U^#B-4(/YY@@UV&^/4(,!!PDU
+M6'"14(,))PDUV'"34(,11PDU6'&54(,99PDUV'&74(,AAPDU6'*94(,CIPDU
+MN'";4(/SQ@DUN&V=4(/#Y@DUN&J?4(.3!@HUN&>A4(-C)@HUN&2C4(,S1@HU
+M^#FE4(,#9@HUN%ZG4(,+@PHUR%NI4(.DI0HUR%BK4(-TQ0ITIW<8FJ$:NJ$<
+MRAL'4C,7!``A`@LH,SK#=@LEBEQ&I*(LNJ(NVJ(P^J(R&J,T.J,V6J,X>J,Z
+M&@0A$@LF8B1!,&RX8"(\M*-&FJ-(>J1*FJ1,NJ0K&B*R8"*?%Z0`D`LF<DU.
+MVJ1:FJ5<NJ5>^J0`,`LFPDVC$R*T8"(OPJ,`4`LFPC)E"@"V8"+N]*;O($_'
+M%2+P8$]W"@#QH$][*@_^M*?S(%![2@\&M:?UH%![:@\.M:?W(%%[B@\6M:?Y
+ML%%[J@\?M:?[,%)[R@\GM:?]L%)[Z@\OM:?_,%-[ZG<6I*9)`@`\]:8"8"(K
+M]*8#8"(=]*8$$#1[6@`F,D1O:@`F(DYJ>@`FHE9JB@`FTEYJF@`F$F=JJ@`F
+M4F]JN@`F$DUOR@`F(E9OV@`F4EYOZ@`FDF9J^@`FTFYJ"@$F$G=J&@$FPDQJ
+M*@$FXE5O.@$F$EYJ2@$F4F9J6@$FDFYJ:@$FTG9J>@$F@DQOB@$FHE5OF@$F
+MTEUJJ@$F$F9JN@$F4FYJR@$FDG9JV@$F,DQJZ@$F8E5O^@$FHEUJ"@(FTF5J
+M&@(F$FYJ*@(F4G9J.@(F\DMO2@(F(E5O6@(F8EUJ:@(FDF5J>@(FTFUJB@(F
+M$G9JF@(FHDMJJ@(FXE1JN@(F(EUOR@(F4F5JV@(FDFUJZ@(FTG5J^@(F0DMJ
+M"@,FHE1JZB^$\Z8R8")1IJ8S8"+5IJ8T8")9IZ8U8"*MI*8V8")&I:8W8"+*
+MI:8X8")-IJ8Y8"+1IJ8Z8")5IZ8[8"*I]*8\8")"]:8]8"+&I:8^8"))IJ8_
+M8"+-IJ9`8")1IZ9!8"*E]*9"8"(^]:9#8"+"I:9$8")%IJ9%8"+)IJ9&8")-
+MIZ9'8"*A]*9(8"(Z]:9)8"*^I:9*8")!]J9+8"+%IJ9,8"))IZ9-8"*=]*9.
+M8"(V]:9/8"*Z]:908"(]]J918"+!IJ928")%IZ938"*9]*948"(R]:958"*V
+M]:8@&#![>@4FTFMJB@4F$G1JF@4F4DEOJ@4FXE)ON@4F(EMOR@4F4F-OV@4F
+MDFMJZ@4FTG-J^@4F$DEO"@8FHE)O&@8FXEIO*@8F$F-O.@8F4FMO"GD`D'-J
+M6@8FTDAO:@8F8E)O>@8FHEIOB@8FTF)OF@8F$FMOJ@8F4G-JN@8FDDAOR@8F
+M(E)OV@8F8EIOZ@8FDF)O^@8FTFIO"@<F$G-J&@<F4DAO*@<FXE%O.@<F(EIO
+M2@<F4F)O6@<FDFIO:@<FTG)J>@<F$DAOB@<FHE%OF@<FXEEOJ@<F$F)ON@<F
+M4FIOR@<FDG)JV@<FTD=OZ@<F4E%O^@<FHEEO"@@FTF%O&@@F$FIO*@@F4G)O
+M.@@FDD=O2@@F$E%O6@@F8EEO:@@FDF%O>@@FTFEOB@@F$G)OF@@F4D=OJ@@F
+MTE!ON@@F(EEOR@@F4F%OV@@FDFEOZ@@FTG%O^@@F$D=O"@DFDE!O&@DFXEAO
+M*@DF$F%O.@DF4FEO2@DFDG%O6@DFTD9O:@DF4E!O>@DFHEAOB@DFTF!OF@DF
+M$FEOJ@DF4G%ON@DFDD9OR@DF$E!OV@DF8EAOZ@DFDF!O^@DFTFAO"@HF$G%O
+M&@HF4D9O*@HFTD]O.@HF(EAO2@HF4F!O6@HFDFAO:@HFTG!O>@HF$D9OB@HF
+MDD]OF@HFXE=OJ@HF$F!ON@HF4FAOR@HFDG!OV@HFTD5OZ@HF4D]O^@HFHE=&
+MU*%F?=9HG=;LP7<U\Z,:E'$;E',GDD8;U*5V_:5X?==W;20GTD8W)-<!$%`\
+ME->$K=>%?=@WRM<!4%"O!-B&=4V('=F&/=F'K=B*Q4UJBB0-QB*9?2*1EDZ*
+M77'NU-D`4*?S1-IY>D^DW:?[1-J`^D^D/:@#1=J&>E"DG:@+1=J,^E"D_:@3
+M1=J2>E%\#0"5RE&DC:D@-=R;2E*D[:DH-=RARE*D3:HP-=RG2E.=;2(XI=@'
+MPE/9'2)`I=@\1%2*741(I=C7Q%2*S4U0I=CD1%79S2)8E=TLPU79[4Y@I=CS
+M1%:*?4]HI=C[5%[9_4]LE=T#!5?9?5!TE=T+A5>*_5!\I=@3!5C9/2.$I=@<
+MA5C972.,E=TD!5F*#3.4I=@LA5G9+3.<I=@T!5K9G2.DE=T\A5J*O4*LI=@=
+M!%O9[3"TE=U#A%O9?2.\E=U4!5R*C57$I=CV_:9(\CC,I=C1!%V*+5;4I=CE
+MA5V*S58`D]UP]5V*35?CI=B;<UZ*[57KE=V`]5Z*+3?SI=B(=5^*S5C[E=W(
+M]%^*K54#EMV8=6"*_38+IMB@]6"*35H3IMAM<V&*;54;IMBP]6&*35LCIMBX
+M=6**S5LKEMV_]&+9+54SEMVD<V.*?3`[IM@3\V.*O3!#EMTE<V39#3!+EMW2
+M]62*;3=3IMAC<V6*O5Y;IMAA\V79S3=CEMT:<V:*O5]KIM@8\V:*/6!SIM@D
+M<F?9;3%[EMT)\V>*+3B#IMB'<VB*_3F+IMBI]&C9+523EMV`<VF*O6*;IM@O
+M]FF*/6.CIMBE=&K9[5.KEMUT\VJ*/62SIMA'=FN*O62[IMBA]&N*K5/#EMT$
+M<VR*'63+IMA?]FR*/6;3IMB==&V*;5/;EMVZ]6V*W6/CIMAW=FZ*O6?KIMB9
+M]&Z*+5/SEMVV=6^*+3#[IMB/]F^*/6D#I]B5='"*[5(+E]VR]7"*76,3I]BG
+M=G&*O6H;I]B1]'&*K5(CE]VN=7**'6,KI]BU]G**/6PSI]B-='.*;5([I]BJ
+M]7.*W6)#I]BQ=G2*O6U+I]B)]'2*+5)3I]BF=76*G6);I]BM]G6*/6]CI]B%
+M=':*[5%KI]BB]7:*76)SI]BIYEC9O7`1EMV!5&G9K5$9E]V>U4;9'6(%E=VE
+MIEC9/7(-EMU]%&G975$5E]V:E4;9W6$!E=VA9EC977()EMUYU&C9'5$1E]V6
+M54;9G6']E-V=)EC9'7(%EMUUE&C9W5`-E]V2%4;976'YE-V9YE?9W7$!EMUQ
+M5&C9G5`)E]V.U479'6'UE-V5IE<7JM;JO_[LW_[0(5(6-!`[,A`^`B1"0B1&
+M<C((`P7$Z@MU*@52@%<%`BB`!7!6.[A00:`=8*F!4`#009$*"`,@WA@$*F`$
+M()8#V!GW#QQ@P)ZQ`8G$$"@"&$L7\)T``-(*@C8A".T@R,2_FZ)X>H3.L'\]
+M(_\!C0````4@`32`"%`!%H0&^``!0`0\"!30`G9`#0@#B<00U!D`((,0A`R"
+M,^H?S\!_%P1%!($:&``2@1-H`L!J=-S``'``!T("[($0T`$.A!\X`2M@`+B`
+M19`(/D$UF`$!@*3Z(`3A@S3!%[@&9>")H$,HZ)M002O8!`2:X<F#@#`0"L)!
+M2`@%X0?$6*]J("1"@H#/!@(L6#6S:B"L$)CQJ8:@'0P`"*#QP!`[($,J1@"L
+M@E>06P4,%[()9<@6S$I>L`VHE8$P`L3@#D$'KC`,!L$S.`1K81IT?[@P%^K"
+MQG`%W5@W*83`,!@*PQ&R!;N@0/B"!2$"]D`R6!!F(1I<@[9P#>[":4@-JZ$U
+MO(8X(<A$PL5#"0,"S+"$4?!`4,$!6``#`"H\AJJP(+3"90@+V:$SC(89\`BJ
+M0!W1`G,&./0[*((&?D)RB`.]H`XD"#QP#$K`9F@&GV$\3(-'4*;XJH$P1.;@
+M/3P94_`3)H,KF`6#0#',@6#0!\9"C0@$"R(\Y(!I4%+D*@`P:9((04@B#C$-
+M7D+3(S>HX$3$@AOD(OK#X180!,!&9(8$X1TBQ)VX!D7B@9@T3H0@.)&46`>C
+MH.E!+"Z1(L;$<F@,CTL[R(C*4"!V1"'($P]B3SPD/Q$`3!&",$6(8@9<B;"$
+ML21%F*@%F2)&3(8W<2#F1(]8%4'B51R)DP:+$`0LXA5CH%&$)<AD+%9$F7@,
+MGR):9(=3D1:V12,8$K$B200`7"WVU$,G^!7O(H'0*GIQ*?;#O@@5TV)@-(AN
+MT2IF0)]X&(E:[5F,=+`QXL/;XPEYU4O<BV;1'U9&P%@&J2(T'(S@@#-.&I:6
+M>T#C0T02NZ<T!H#3*!FYX%DD"%'Q%5[&CT@8WV)6I&B]QS:J1,<(`T!+9"R+
+MD]$IKD:IV!H%XVN\CIO1,$X:?A9\E&-1'(VPA+0\1XN8&BGC7Z2.!-$U:L;,
+MV#-D(P`@9\7'.XK&%'%\="-OA(Z^436>1^%8'3%C<5R/1,(],K/D(Q_M(G@D
+M$*1C//)%Z;@?P^!PA(U#T#W2LN93(*'@@80!!T-!ED<&"1PM8W\DCFRP/6I'
+M`,#)HD^%]!D7<F)HR.@X.OQBAV2-Z=$Z`L@0&2!')"&K/B<2+!((R2$1E2)^
+M;(HM<CKRQQCI'VFDD>2,:V'2L+'LDR.9(^/HD621/+)(9/@BT>-:5(_L\3^*
+M2+@(`*A8]VF2%Q)@K,C\:!ZKY)"\DC(R2Q[)$<G#P@^8I(^P1+J,22!))04B
+MC$2311)$ND<25G[>)&Z$)79C3OY&.VDE!X).Q(YJTCTRL/3C)T_$^K&//E)*
+MDDD.22C/I*%DBXA22]9(+EF_VD^C#`#O!U)&R049)!LD1_R0$+(P<LGN%7\^
+MY?P1E:AQ2KK(2ND@466F7)-<LGC5'U<)2_B&H-2/9K)6$DD0&2%'9.O*/[R2
+M0&B,7UDF:>6I'):ITC@>QLK5?Y(E#-@OS))2OL([>2FQI*;$E5FQE00@:VDY
+MH&2LG)2E,E@^2SQ)+%5E5J0E!<A:#IALF2Z=)4[LEFGR6Q9++JE+$I"U)!'T
+MLDYNRT(I83#EC-R76=%F-2!K:3$"YJP<F):R8'I+(XDP#^,PB4#6,F$X3"$I
+M+-EEM,R.7-)@52!K*3@VIJF\EQ(S7U),=WD8F4D&LI:'PV2J2Y09$`[EP629
+M2V'26*L.9"T_A\RTEVH17^9)V(@DL:'1/)I(,VDJS:<09!:B0&B(]"\T&DC]
+M-PY)I<`,@]PR90[-6PG`MF%`F(0#X1LN1WR((JA@*+":[6`53A4/"2UOY1"$
+M`DP`6P5-`!!O>HPXF1EUT4)"Q#T8*=$FQUR70K-=2L.E23@+I^$\G)DAR-Q-
+M@7`C\B:*I)K[T&^>S+E9,PVFFI2'FZ<@0$T8(37UY@RLFANR7D+,CADX/V;/
+M0()J,R!0%<=Y"04/WQR5H?-J:L2L63DG)HA$G+@S=^K.W=D8@DSJ!`"K,VK>
+MQA,A#B-G['R86)-@UDZ5>3L59T%HG,)S;)X,?6@#C^??I)D`P&9>SEO88]K+
+M0,`JK#,<1D1>Q0?/)9U$GK-3>69/RZDO;R'O?)_P,W[*S[D09+SG5?F4Q;-Z
+MRLKK23G7I^V$C0#`=ZI#_$D]`P`_1)>R,SB23JTI.-M@CXDS`X&KA$^R.3Y!
+M(>S<GY/S0;I-]SD_.Z@'_:`@-"L$&0BZ5?"G;CR@YY-_:M";*0WK9T$`G]'S
+M.TY/T(E!9V;_U)[M4QKVF'HS$!['!-V;G[!\]L84FD%M)0MM@R$TB2K1)<I$
+M@T*0X:%?Q8324`2*/A4HX&2@II-(!%``0$(#@@2-H?/Q<QK/&@HT5^CVE(8U
+M9A>,0))6$(Z@^*2"F:!O6L\BVC:/:,\8`G$S`.S,L=)$^Z@?_:.`M",$F3T:
+M$*+)#P4:)U1RVE`SFD/;H,#PF@``;%9"Z2E&>=79/)Z_<QVJ3QRZ,M<@W,16
+M4#0@/(X>HZT&@E@YI,2S@@K1'SDH1^<579Y;<T8&TEE*2VNI+24(0::4GA4I
+M.D:IJ`HUHF>T#0[2@F!(P>C4K*0&5)&646#:2$]GC_%6`Z&\H%(I^#K-9RM-
+MGA$3EC;0TWE+NZDW_::!-,A`4X$@38VIYR2>B72.+E)FVDF%*0#0I0'AE)K3
+MQXE,4>@U39_9U'\R3P#:8]+,0&`KT]1U!E$Y2D9=*?;DI+<3G"K4A<I0Y6>0
+M\:<"`:#.T]:93@LJ-EV@VC2+YAMQ6A#**><<GOEPBA+1=5I'@ZDS!0#M9B#`
+ME8"J2@FJ+Z6C'G.##LZ&2E-KJDU%FD$FI;X57JH_7RI)C:EV5(L^U((@43\J
+M)26>!=2>`LME6E*;J1;M,7%G(-`5EEI-A^@]M:('E7VV4VYZ4[NJ5_VJZR_(
+M1-6YPE.3J3IEJD#5I`I5E%H05NI$#8=)59D:U!NJ56]G&EVC!\&-4E`XZE)'
+M*EHMG3(U`^)1;.4R[PI8/:R(-;%FCR!36`/"Y@BH%=6G_E4L&EA/YR,M")+4
+M&W9.>HI4S2;:S*1L,ZTZ57#P20/`6`T(=*7'R*N!X%6HZD"]H))UKC+2K:I%
+M%:MMO:VX-3\$F=6Z5\JJ4FV6LI6=-D\`T%B)*P$5J5<UM`+6H)IO>DQX&0B`
+MQ;62S[Z:7&FG/HVE:C*W:M?MREWM0Y!YKG_%M\K5B_I*K^LV7:N\-2"TUK=*
+M-N/J60VN396V-M>X41#DAG2UH-9TJ<)7T2I?NZM__:\`UCP$F3(S$.PK>X6<
+M/=6O[M?EJE8W*@``KP$ANA[8>CI>\2E&-:\:%0FFFX&`6.[K*I64"I:\9M7_
+MR34#K(D]L2BV.@29#7M8Q.M[%;%TE<3*T@%;7X]K+PVQ%K:\(E1^"BX*`F/Q
+ML-15O\+8V9I04ZR1/;)(EC@$F;8S$'[LA$6GR%7(YM@1NT^YYHHM"!WVR8;4
+M&UM=-VE=!:!W=2`$`#9*$/0J$.55<12VXEBL&F.K[(P<K`%`9#Z6)$MGZZR=
+M50U!1LX&!&0"6:,L<!VRPA6`7E:"D%D!@-B4H<CTDLI*T&I==^RM+*U,=K$@
+M084U$+0*D%6S73:?.EI9>F<[K:?]M(D3`%#:R>)B+>J4;;/8]5MN43T+`/BL
+MEBV;7%;*LEDBRV.[RT#`+)<VO_[94TMK2RRH_;7`-MA2AB!C:R]+J8VM@#:^
+M#M=1&Q`L[:MUKZ9VU@9:KMECPLQ`>!NYUJK*6N5*69FKL/VVX#;<&H8@8VTW
+MR[%=L]PVHU;6M5IL`P*N?;9^5ELF6_YZ.WM,N1D(H"7;LM)MVVB_K*\5MP`W
+MX`I<^@D`[NUG.;>9]L)NVNQ*;@L"MH6WL7;72EMERV/3SD`@+?H6Q"9<'>MO
+M.>W`_;@@-^22A2!C<4<+PN6W7E;&,MR"6Q#R+<1-L!N7RJ9:(PD`PJP&(;,#
+MP<P"C0J:9G6MO.6UT_;-YM&+>5I$KM$]NDA7*009HAL0VD:?C;@_=^+26T$;
+M23&KH0V;F[5U%E!%2T49;<IULVJRM);<@$!:>HS(&@A6)>-66*G+8$=KTGV[
+M<#?NZH0@<W97R\F5N.D6PZY;!\MT`8#3?;EF-=KFW86K:GN,=AD(L$7MOEB@
+M2W'_K=Q]O)`W\LJ$('-X7\O=C;J#M^.NW+H;$-(NX/VMF+??JMS""P"ZS$"@
+M+8I7\(I>L*MJ):_K?;VPMR0$&=,[6RZOZ)RW;;>_4MZ"D'@_[]K-O*.7YO:8
+M<#,0<$OJ1;:,=^HZWMC+?)NO\XT(08;XWA;;FT"!+^NEN;.W(*!>W[MXV6ZW
+M;;!(L.P,!-YR?-'MZIVY>O7YJM_URWX'0I`1O[N%^E91ZXM^;V'T+0C&E_NJ
+MWJ];?]$H`%"C8A;G"@2=FTKY*J9%N9I6\WY+.*LP!4(#;K\0.`(?W2#S@`'`
+M+WFZ,!<!*UP%3','K22\NI,4T7;63\AUSZ?73<#!]VWF4?@;$'A+C]%9`T&J
+ME-^8BVK/:[Z1P#@X!P_<(`.#!8(,?K61U?SR7QN\12OP!=:_R-?[JEMO.V<*
+M`NF8P1J8XZ9@#JJ#J[`5_KA;Q@G+WU_:>&<L`.C!P\7&9F"\>WZ)<(_),@/A
+M8$!A,CR$,^P5?L-P&-P&&30L$-0P$(ZWMS?YYM[AFOZ,2$"%MDF8_IIA`-!M
+M!L+$6,.AMPWOW3C,B!NQIPTRA5@@'.([#'7SL!+6N]YV#A<$.VQ41?"6'<.)
+M&`5?WR/88\+.0%@8B-@2"V(W[(A;L2M&L4'&%$^7+0Q3]S``A<0%81)WXC`Z
+M@D&Q*B[#&=;F(@D!+&<XZ)D-`#U7V[)A4=Q_!6L>[9<"`1J_XFE,C6]JD)'&
+M@P,#!]Y`#(P7L0?FAE@7I,):2_I9U>$JWKNE518'A(718YS*0``8J;CZ=F-O
+M6XWKL3U>J$'&'0L$>$R)?;$\5L29>'`0A)+QA_'P/V;&@]AJ#03I$H_G[SP&
+MO_<X(DMDFAID%+)`8,C]>!L+882<8?-Q0>#'N_B8]F*-3(-[K2SM,55F(-B-
+MALR%E:_'G<@P.2;7TB"3D@7"2L[(H/<7`V3P6Y$+`D8.R>?T$Y/D*"QS!W&V
+M&0AC@R77XN_K=F6R4W[*?33('&7S0HM_JBVVLG6C(-QDH,Q9A7)./L@;>`KK
+M4`#0=0;">E'*5IDI]U>HS);;L@<-,F59O53ER;J$>3+B(`A)&0EOY+`\BF^A
+M,#X1Q'BS@I`"_`F3\;Y=QGRY&=_1/`HO!4)C=LN0.3)?PR#SF`%`V-#&7]DA
+M[V2W^XV_)@C6K.)XZY9C@J!).3(ZSJ-Q.2"LEQZC5`8"WT#+=!D30V3)3)MK
+M<RX,,JU9OLSE!:N6AVMEOLQZN20'W>S:8YS+0-`8L)DWU^6F;)N;LW.>AD'&
+M.-N7W8Q[>_,M3AP%X34'9Z)<@S-LCXDR`V&_).?JO)S7\G,^S^A9_049\*Q?
+MJ+,>MLY863H'!.2\G1&S%.[+8[G:#`2,,9[?<WDNLNDY0`OH#!5D]+-_<<^7
+MF/!B7P#`G@.">*[/H3@Q#^*L,Q`&3'].T!PX_0[H#<VA(TB0H=`"!D&?XX!L
+MH`,"?X;0.MDT>]N_/&;SJC'>N0;8YZ9H":U1X:RX-#`=.D?K:/\09&YT0"`1
+MF/GW/F3.7'4)[6>^NJ'9LV)2<SRDY6MI!=$!0=EQ#H)@,2[TB)[-.SI+:VGY
+M$&2,RD"HTCA92&]FW0L`?'29%L-#V3X79>],-@A"PK#231I`;^DY3:?I0Y!1
+M+@/A38?I[GNEW6Z7+@A@FBMK78.LF54T^.TQ3<90XL^6>H#5='=>Q'4Z4DMJ
+M]Q!D$K6$$=%Q^CKC:0>#IC-S2[[*)QD`1)N!<#C@])B6TY,Z5:OJ\!!D1K6%
+MP=2G^CI;ZIK9J<6TH7:[/:;J#(3/8:IOM7E>U<`Z6&N'(*.K-0RL]M7#U54'
+MA%*-HL'R?5;,6I1%!V8"3$T+<Y!UU"993<)9:NEAA+6W_M;((<APZX"02H(T
+MG\[47+,S5]UNB*2/JE`NP3GP!-/HTXRMBG5`^!P])G,-!*'2J^<U/0;7`#M@
+M]X8@HZ]%S+'VUW9Y7`.`<MVL"S7"QM4`P+@,!,#1KY\U$1;8&#MC!X<@([%-
+MS,&VV!T9`!3L@,"O&_:GAL^A.LD,A!53L=<TI-;8,#MFWX8@H[)5S,=VV0&Y
+M8P<$BFVRE_)_YK'-9B"\F);]J/^US#[:2+LU!)F@[6)N=M&VRS4[(+#LGIV6
+M?S:U!0!19R#,&**=K5MOTO[:8+LT!)FL+6.<=M=>T$P[(`QMJAV;%?01E-8N
+M>J8>8\.L<;GSV1Z"</98VIBPS;?[MF0(,GH[()02<[U_D375A:2%]M#RXG<]
+MFEEAGW;2>91L!X09TV-BUT#P*5Q[.'MMO\VY._>XU3$%`7/OZ<+]L,ETX`8`
+M@YMM*V?9#+&%RT"@&YF["V=7STV[:_=B"#*NV\>8;<V]H"VW0!#=@AJN$NJ3
+M;;5#=9$9"$,F=KODV6V[F[?S#@PQJ2`D[]'-C6,U5L[=`0%VJV[RS+K[:X])
+M-@/AR"AO4,V\G[?Y/M]W(<B`;X$@OJGW7@;9BSAZ$X3I';S;Z_#VV=V[W@*`
+MIC,0ELSX1MGE&WT+\`'>%H(,_Q8(_MM]"V?9K6K5=T%HW_5[AE9B9XVSP2_<
+M-@C46J"BV6L=H>$W<X6SNE(@A'`"3L)+.%8(,B,<`(02PEV]#7>Z+M(?F%TK
+M;I',N)<T:7[<(+*T'G`E@P23UT#0*?^[>`=P$T[$B[A3"#(^7"``<05NMWDW
+MYDSA*WQ[^^?\S6-]RT`@&$&<BB]?(\[%NSA4"#)67"!@<2:.K9VX_04`25S*
+MU.IS;;U#=?1ROXNZJA[F#E[!F;,7O^-X7.EN45RZNQGX@@[C5F:-DVX/?J@!
+M0+$9"%\FB[MM*IS'&[DC!PI!YI`+A$1.QNGXT_;3>QR.%^0)[K`).<1..@-A
+MS"CR#,W('[DI/^4V(<B`<H$@RBOYC/;D9%J2>QE!WL)+MUW]OW@5@[]HPKS!
+M&[4EO]MI$,ZR2H$PS%&Y,3_F(B'(%',`T$E8^/NNX_U572?NK"N\27#C7IOH
+M>D:6UE4N9I!@^!H(-F64BV4DBLS+N3G?"$'FFPN$<.[**?@E)]/+O)E+<0P]
+MSD]J^1H(ND6<XV=R?L[[N3\7I`#@GKN9/KZ\&S@`4.=JAI8_\W>NO]-7SHWC
+MKU5&NW-@/E/_N46_Z!0AR#CT`4S0R;=!%^@!(9_/<QS.8X/-0+@S^AQ:WV",
+MSM);.D,(,B;=SG1T`&[0-[J<4>@+O*`+7P!0=`;"GDGI%]NE"_6A#L=[NIZ9
+MZ4+<H,?T@(#21WHVSZX7O(WN\FK=RR5Z)X?F(!+.=DH_0]2[NCD/,EL](&02
+M9Y[3/7H'AN'@.`0O[G$<`."U/Y37L#R'YU&C'A#V3(_)7P-!I@!U5NS5^[HI
+M#S)X7=`@=2WNA<,Z`!CK3KV-$V<`T+\&@FW9ZR_;KTOV<QYD&KNA&>R+O(4"
+M@,`>$/1Z8G?AH3K'*!J(/EU]^2O'Z@!TLJOV<AYD1'M`$!ADO8G[<<QIV0/"
+M8__LMIS']IJ!\&@@N]%>[<#]D0>9W>YH,#LIU^RN'8!M<G]\U1DZCPTZ`V'2
+M^'8L'=RK.QX/,M!=TACW>KY6B7M`Z.VX/:Z#65P>@.,V.9_;'/RT._=;"6<7
+MI:6Q[O!]@`<9]QX0*DEL+^.S_19*\R,]PX,R6W?K?1&NH_9'FT>S>T"8-#T&
+M@@T$ES+=[7A\?_"V.\@H>$VSW??YZ9SO!<&^A_<!'ZHIV$"0+0W^5T/X$2_?
+M`8"']S057J5OT0D?$!C\AE_OH1J##80:$^)1-8F_\<X[R,AX49/BB7"0.?$!
+M`<2_>(KN0`%`KAD(IZ;&IW8<S^1SO)$O"$F^G3=W(G_A:VY!H/%#WHR/Y9XS
+M$%:-DM_B33[,]^T@P^5538\/V4?>U.!TV:[3WS9YO[GFG:NB=],^T;6\,\96
+M?-+5B/D]'[.#3)X/")'DOO]R.V]9T;IGEN'4W'Y;<QONN)_ZMRRM93X@K)H>
+M@\(&@DKY\B^9SVMZ<!UD*KVL.?/Q&P#\>5&_YO%[F^>>`("%#037@NF'^*9_
+M]1H[R*AZ6P/J`[*G#PB7/LOG][$,PP9"C&GUFQO6"WN,'61ZO4#X]5*>>!/V
+ME3OK`P*KU_6G?BS3L(%0:X`]S1WVV%Y@!YEI+Q"J?;+'WYG=G1I[75/J!_VN
+M+_)R32`,&VNOH;.]NP?602;="YM:;Y>YO:\I]^J=RD?K-S^,XWQMW:O6FLY/
+M>4+O`?-HFQ0(!__=*_P<'602/@!H)((^WQ/\?+/?$7V27O2+EDDK]D>?1^7]
+M#4."0&P@F!1V7\H7OLD/T`RO((S\;U^UE[U!=_@0']J;=5(,`(C80%`M)+^B
+MG_R=KZ6#C,T7"#B?Y;?MX^Y.0[Y`6/D1G,*R<="^V)'80&@Q.9^?\_RIS_`!
+M@-,7"%!?Z*_N<%_E?[ZSP?=U_MR?5"8V$&)-U.>J5#_M;^@@0_8%@MG7^MR;
+MZZ_5JR]MP/[`%_M/%0#4G(&P;<[^OU?[@#\]!YF]+Q#Z/MR?XG+?P;9]:V/W
+ME7WBM_(`&,[K<KD-HP.^57?\1'\Q8RLO*1`X?^#__$XYR'C^+DGOB33BYN^)
+M7H*38T:/S3>^D2RMA%_;($$L-A!$BM]?Z:`_]\/D($/[!8+M/_STW,*OU=&?
+M2)9[FC;WT;[(<[&!8%INO^Y__I(YR"Q_@=#\@3])Q\J]7]PT?G"?^?,^&!L(
+M*<;Y0__QSY:#S/<7".'?^COZ!3W]S<WV;_F/O\>0L8'0:L0_^;__,3G(S'^!
+M4/_5O^O'G.>?NO'^#7W<W7P5<PP$\X;]A_\M@/=8D'$`RANE'YFV_[D;`^#6
+MU_WE&U%=F375:7#(6'H7]B5_FE\`L"0)!",@`V@"5F%!1@D(`!02$=\'.//I
+M=X;>NA:.N6O_W36G.EU_VEP>]0`&!/-&CP''#`0>A0)X`@Z!$EB0\0/J&Q'@
+M<*4"LH`R'TVWT]$Q`X%H(002@53@&Q9D0('^1A)XG1V!`4$0V`0F=3L='C,0
+ME!A38!5H!N9@0888*'!H@5@9%A@02(%?H,NWT_$Q`T&J40:>@7A@^Q5DT($&
+M!QOHA:F!`0$9&`?&?P!`RS$0+!QW8!ZH"#I?088AJ'#X@2L7'Q@0V(&#X`4(
+M^>5R4AWEQ\MU@`(?YE<`PEDWDL.Q"(Z"D5>0$0H&!(%$"WCW@8!:5,4W`WIB
+M-2#K=P.N?RH8MN((!@0+1X^!R`P$&D4B2`K^@B!7D+$+2AR0H$%W"@(`J6`E
+M6``B08S,0.!9^(+`8#3X=@49S:#%40PN:,-@0-`+*H/"WWP%R0P$(08T*`V.
+M@R)7D/$-:AS7(.94#08$SR`WJ.+U&)3,0%!JB(/D8#TH<`49\:#'D0Z><>=@
+M0!`.NH.#6,HQ$(P<]*`]:!#*80"`0"AR[(.:73X8$,R#`&$PQN\!9O[>2C?G
+M77[<WR>81Y5()L=!Z!$&6T$&1Q@0]!&JH"?8#79-5I?%1P.*9K(@\(0#AEUY
+ME$(8$(P</08H,Q!4%`7A1Z@3FEA!ADTH$."$_A_39]")A"12!1CW68(]!BDS
+M$&@6.>%.Z!0F64&&4B@0,(5!86Z'E?F$*H=1B/@AA0``*C,0=!A-X5,H%L)B
+M76%!`!96A>(=5B85NAQ:8?#W#@(`K,Q`$&J$A6-A7?A?!1EQH4`P%Z*%'-[*
+MY14*!&=ATC>2>6H9X4G88\`R`T')01?:A8RA=A5D((8"@6+(%\)X*U=>:'.T
+MA2^AJI4!YEP;(,_E`:Z"+^`:!&=-2`(!:=@8GH:X59!A&@(`>41)6!BJ>*Z@
+M6D?#Q8(9WPU'"Z9!I15DJ',@0;C,0!!1+(:H87`(3@49O:%`\!M.AOJ>@[4:
+MMH81X2+68_`R`X%E`1P*A]2A315D0(<"@72('$Y\6U1Q*'1@AK?A6`;,#`09
+MQG18'9Z'^%B+4!"4A]LAWN=@88=&!WCX_Z%ZQ,Q`T&F8A^AA?MA-!1GUH4!P
+M'[:'K*"#-1X*!.RA8.B5V6I68:B&S`P$(0=^J!\^B+-4D+$@"@0-(H`8&KI3
+M_:'3(1\*A3379CB`=88QFC*&_%V((>"`)!"8B!!BBFA+!1DH(@!01[B&\)\E
+M&!N"9BNADE8;-GKSH2>51TV(4@<2!,T,!`V%@Z@B#HF\4Y#Q(PH$0:*%Z`1B
+M3BWBB]@<,F$``#4S$$@60B*1:"6^95%B04`E*HE@(.9T)&H=&V*"N-AA,P-!
+MA5$E7HEH(OP49)")`H&9R"7*@9B3E"@0;(D&(EM'&,:(RV"/P<T,!)G&F9@F
+M_HFY4Y"Q)PH$?>*;^/BMB06!FU@G`F(+77*(!($S`T''X2<"BI1BX11D0(H"
+M@:1H*%J"@F)!4"@NBO<;GG@2>HC%F"9(U7&"&*&HJ-+!6?"10-`J5HJP8I'X
+M'A4$<02,2`">A#-BNP8+LH0W8NO'(=:"`0"FJ'8@0>C,0)!03(JQ8K(85@$`
+MQ:)`<"QNBLM@D/$JSHK&WYUX*[Z%[,Q`X%@@B\IBM[@+!1G9HD"P+4*+)V&0
+MT2S*'6%B6ABJP3,#083!+7J+\&+[$V2PBP*!NT@NJGC@8D$P+H**G)Q)^!;2
+M,P-!I?$NQHL$8UH39`",`H'`>"_Z>```O1@0V(O\(G/G+PYBC9!`D'$,C`5C
+MQLBA!!D58T!P,2Z,(1O"&!`HC!'C\2?QN8>78'DW^9UWE5]5)R*>C`$BG,4=
+M"00SH\9H,]YF`$#-F#,RA(Y4##C-77RK7Z\X"^:(&5!IU3$"`!E'CP'0#`0%
+M!<9X,SZ-UD.0L30*!$TCR!CJZ8QM1+6((*J+BQU!,Q`H%DXCU"@V0A!!AM<H
+M$("-5F-`-C4&!%5CR6@M6H!Y(@"`T`P$F\VKQ:BEBM=B4#<V[HVZ4)`Q-PH$
+M=6.=&(25=4OB&6<V!@1HH]NX-?:%I!=#,Q!$&F$CWR@Y4@]!AN,H$$".::-=
+M]C<&!(&C"P0TFHPN8.$XED$T`T'%$3E.CJ@COA!DD(X"@>F8.6)REF-`@#DJ
+MCDN?F*@93H0MVLHHY[6,J.++&#IVB<%<'H4<"03#8^IH/$X004;Q"`"D$;8B
+MW(@K^HRHW^<(X#E%`AYER/%A*ZQC0%!Q]!@8S4`04)R.QV/XN!X$&=VC0/`]
+MOHYDFO+(/#Z)A1Q',Q`8%N"C^"@_<FE52D$`/Z*/PU7Y&!"<C[3C(,<X[G0E
+MD$"08,2/\V,!V1X$&0%D0#!`XH_7F?LH$-R/_6,MQS627@)8HT%`&I`8)'H0
+M9%20/&.5ET`"``MD!-DH<H<]!DHS$$0<%V0&J4*.!T&&"2D0H)`,)%;&06J-
+MM>,$V2'BCM,:B&CY^8Z@H>AXYP4`M)%`$$2ND$2D;@4`#)%'9`?9"D*/*N&N
+M:"-V71K?KX@;YE$N9$`0<?08,,U`T$^DD$5D%^D<!!E9I$"P1<:07A@264;0
+MD/ZC];C3T30#@6#!17J1<*2*!0"PD0*!&TE&KEQA9$`P1HJ0A"/P.);A-`-!
+M@?%&QI&$)'009`"2`H$@>4<:='1D0&!'\I%L'HF8]_$T`T&B,4@6DICD<A!D
+M4)("@26Y2"YHB&1`H$A"DJ:>)#E?`34#0<-Q26:2K*1Q$&2@D@*!*OE)8DZ<
+M9$#@29*2(Z(/>3J1BH+9&[5#SG$PHRD)9WE&`@$QV4H>DZP:`&!,*I-*),7'
+M1+Z":QVO"$7:AD1CSU!:P9(!0</18R`U`T$^L4HBD^!D;!!D<),"@3<Y2YYQ
+MRV08@49*D/\CS<?4#`1^Q3<93LZ3N$&0\4X*!/'D.:G9D9,!@3F)2P:3NF3>
+M!]4,!`&&/$E/'I2S09`Q4`H$!:4^Z4[=DP%!/OE/_HYP(JI'U0P$A89!B5!N
+ME*Y!D'%1"@09I4-9Y2V4`4%#.5'VD'YDD8?5#`0)AT;)4;Z4J4&0L5(*!"VE
+M2+E6?90!04AY4DZ,$F'DU^_ICO_>1<A#\I1[%YR5&`D$1R5,J50F!T%&4HD8
+M-9,HH9'61$:33Z0)%D7:CJ]?'C53!@0)1X\!U@P$]81+N52.E<,6`/!5"@1A
+MI4WI8#F57<0Z.4*BC#T&63,0Z!5B)5EI5VX&089<*1#0E6KE%G56!@1IY4[Y
+M&@YB_05!T%_4E7=E8FD9!!F%Y4!P6/:5>65!P%<*EJKB(!9H$`2!!F*I6&Z6
+MD4&0<5D.!)DE9`D`-)8"P6-)6>:-;%K!01`4')HE9^E:,@9!AFHY$+"6HN5G
+M*1"$EJ>E\ZCB\9(9G&?8"0Z6-5H>)1>U'J]E<5D;!!G#I4!`%_65N6)_UY71
+MAM,DCBA%ZHC8BFPI$!0</48\01#$$ZVE<>E=IF\VR'8)52*7!<%RF5L>A7&C
+M74$0V!7=Y7?I7OH%089Z.1"PEZ*E=CD0<)?L(\267Q`$^45[^5[^EWE!D+%?
+M#@3]I6@I7PH$].5YN17&C7T&0=!G^)<`9H1)%P09#>9`\&"*E@.F0%!@*IAN
+MX2`6<!`$`0>$*6&.F&]!D/%A#@0AIFA980H$%R:'F1G>D#XE10A46H2\(]VV
+M.*J1>%L>M14-!#LFB>EC:@9!1H^9>D"5S67JEVC9@"YA>%@TYE$GID`0</08
+M[`1!P$Z(F#]FE:D5!!E1YD`P98J60J96E"ZVDZB>7$$0R!54II5I9H8%08:8
+M.1"0F:)EEBD0;)DNII)Y4M47!$%]46:>F7@F5Q!DT)D#@9TI6JJ9`@&;&6=6
+MDWE?GD$0Y!EW9IZI:%X%08:A.1`@FJ(EGRD0^)F#YG19Y/4;!$&_D6@NFIRF
+M5!!D8)H#@:8I6CJ:`@&D66EBE6Y>C)D[9H(LXR9H8]:08*9HF$<%1:1'IVEK
+M%@9!!JTI$`Q%S.4S*1OZ=]*D54E-6IK69!X%:@H$_4:/<4X0!.?$IGEK/IL]
+M09"Q;`X$S:9HJ6L&!+SFJ6E#TGQN!4'@5CB;T&:X210$&=WF0/!MBI;3I@OR
+M9>*8J%Y\01#$%^"FN"EO_@1!AKLY$,";HF6Y*1"<F]IFK%GDU1D$09T1;\Z;
+M!.?<!0``G`.!P"E:VIL"`;[9;[*;8QGN%Q#D&P-GP6EQU@1!AL0)`%"<HB7"
+M*1`HG`^GH\A;ZI`N(S"9`-%$(LJ+F6-B*R;10-!R7IPPIUH09+R<`0%*).6A
+MG#:1G+E$GGY3Y6P8;,9K5^6V.45B*QJGQAES'IW/09"A!`T$3)!HN0(%!///
+M2;D`61,J)ZI70Q`$-43%B71NG2A!D'%U1A[C91)4$#2=(2<)"0!4$P1!-:%U
+M<IULYT@09*"=(4C8^74*!%EG?NF]`0!F!4%@5JR=;6??Z1$$&7GG0+!WBI9P
+MIT"@=MJ=^EMZ01"D%WRGW^EX9@1!AN(Y$#">HF7@*1`,GF4G7`D`M!D$09O1
+M>#Z>H&=&MWD6!)ZG:"EY"@249^89(")!<U.\\7F&GK#G0Q!DM)YA)^<Y$)2>
+MJJ<IF3)*?JSF[NAJ?H9$Y0>71SE-2T7L:7PV!4$&'#00R$%.)SWD5N9`4V=`
+M$!`1FUJ4I*)#$`0ZQ#2%!PU#C)H?Q'U^G^!G^%D('4(!@#I0$)B?!L'1>#0>
+MGW=E+[1!B)_P9_QI0MR8CB+[:7]F!T'&]3D09)^BI?))>*R;CJ*D<@(-!-J$
+M]@E^OD[>I_RI@"Z@\"?YR0X4!`]H^ED0K)_WYU+I?OY"#&@&"@RA33AGU:GS
+M5:`@:-)9@IA`\E<'JG,Z6/JG0,!_YIX!I=$9@KZ@KL&-`*(,!#<#$":#V@P$
+M%%9!HHA9'Z.!>$.HARB*F+4^&H@'#V5CA$HV2*B3`H,NH7+!C5"G$`1U"F1U
+M(\0I8I;KN"AB%7D*09"G3%,_*!/JA4H0-T(6.A!LH39H:5,01*'/%E;1IQ`$
+M?0H76M9\H7!H`W$CK*$#01M:AHJA`@$9>H4"`(`*00"HN*%]6!PJB#8/-T(?
+M.A#\H64H'2H0V*%[Z*!"$`PJ@.@@*HE2#S>"(SH00*)EJ"$J$""B>ZBA0A`8
+M*I'H)"J*X@LW@B<Z$("B9:@E*A!@HGMHHD(0)"JAZ"@JB^X'-X(K.A#`HF6H
+M*2H0H*)[**-"$#`JL>@L*HS:!S>"+SH0`*-EJ"TJ$."B>^BC0A`\*L'H,"J-
+MQ@<W@C,Z$$"C9:@Q*A`@HWNHI$(02"K1Z#0JCK('-X(W.A"`HV6H-2H08*-[
+M:*5"$%0JX>@X*H^>!S>".SH0P*-EJ#DJ$*"C>RBF0A!@*O'H/"J0B@<W@C\Z
+M$`"D9:@]*A#@HWOHID(0;"H!Z4`JD78'-X)#.A!`I&6H02H0(*1[J*="$'@J
+M$>E$*I)B!S>"1SH0@*1EJ$4J$&"D>VBH0A"$*B'I2"J33@<W@DLZ$,"D9:A)
+M*A"@I'LHJ4(0D"HQZ4PJE#H'-X)/.A``I66H32H0X*1[Z*E"$)PJ0>E0*I4F
+M!S>"4SH00*5EJ%$J$""E>ZCF@:9H65WH5"J6/@?BQ`CD`@F.56E!@)7NH:T*
+M(A65CJ5P*7!P([2EZ)04&J+X'7\85A&KB%DAPEL:E_ZEN\&-L)=J$'UI&4J7
+M)@EYJ0\T`O$0?BE@ZIC:!C="K2)F,:9EZ&"*)!2F>^A(I$$4$8WI8^J9Q@8W
+M@F:*&YE0D>EBFH,"`+R*F'5-=*:?:6O*&MP(J:D&L9J6H:*IHW2:9D$:!#?!
+MFKJFO.EI<"/@IDB";EJ&QJ9(PFRZAQ(K8A8YL9OVILRI:+""C$#*:1D*G)X(
+MPND>BJR(62S"<MJ<;J>=0>,T`F6G92ARJD%$IWLHLR)FL0S:*7>JGF(&-X)Y
+MJD&@IV7H=:I!@*=[*+0B9KD3Z>EZJI].!C>"?:I!X*=EJ'N*),"G>RBU(F;-
+M$_GI?JJ@.@8W@H&J02"H9:A_BB0`J'LHMB)FW1,)ZH*JH28&-X*%JD%@J&6H
+M@XHD0*A[J"BD0>P3&>J&JJ(2!C>"B8HDH*AEJ(>*)("H>RBX(F;]$RGJBJJC
+M_@4W@HVJ0>"H9:B+>B+`J'LHN2)F#10YZHZJI.H%-X*1JD$@J66HCXHD`*E[
+M*+HB9AT42>J2JJ76!3>"E:I!8*EEJ).*)$"I>RB[(F8M%%GJEJJFP@4W@IFJ
+M0:"I9:B7BB2`J7LHO")F/11IZIJJIZX%-X*=JD'@J66HFXHDP*E[*+TB9DT4
+M>>J>JJB:!3>"H:I!(*IEJ)^*)`"J>RB^(F;-"(GJHJJIA@4W@J6J06"J9:BC
+MBB1`JGLHOR)F<129ZJ:JJG(%-X*IJD&@JF6HIXHD@*I[*,`B9M4(J>JJJJM>
+M!3>"K:I!X*IEJ*N*),"J>RC!(F:1%+GJKJJL2@4W@K&J02"K9:BOBB0`JWLH
+MPB)FP0S)ZK*JK38%-X*UJD%@JV6HLXHD0*M[*,,B9K$4V>JVJJXB!3>"N:I!
+MH*MEJ+>*)("K>RC$(F;)#.GJNJJO#@4W@KVJ0>"K9:B[BB3`JWLHQ2)FT13Y
+MZKZJL/H$-X+!JD$@K&6HOXHD`*Q[*,8B9D6=GJ.[%I8NK!RK5W`C6*P:!,9J
+M#]&``$##.@)!K'LHQR)F\10):\?JLM8$-X+*JD&PK&4HR(HDB*R,D<^)58`L
+M8M8*T;*^K$`K3'`C\*P:A,]:ALJL2`+-NH>2+&)6!_&S!JU0ZTIP(S"M&H33
+M6H82K4B"T;J'HBQBEL/PM$:M8*M)<"-PK1J$UUJ&4JU(@M6ZA[(L8M;FE+%Z
+M8AMKV"JW)@4W`MNJ0;BM(RLL6+(J"2.0V;J'PBQB%O3D@[ZA<VOA:A3<"("K
+M!B&XOJUKW=YJMR()>&O."FQB%32+F!4\#:Z!J.&JN3*LP-,(=+DRKK/AWIJX
+M(@F+:]X:36(5.(N8!4-AKIMKZQH4W`BIJP:QNH*N_MW>6KEJ$)^KZ:JS<E$C
+MT!?%NKJNP"M/<"/P+&*6[TJ[/I=[:^R*),RNNNOD"@``+6*6#P66$J[!:_4*
+MLSZO(Y#TBI;RKL7K:4JTB%G%U.]JO8ZO,\&-\+UJ$.'K\4I1W0C0JP:AO:JO
+M<!56@;2(6?*4^$J^WJ\NP8TPOVH0]2O\2C;MK><KDI"^-J_/90"`53`M8I9'
+MY;^F"'$K_NK`H@0W`@*K02BP!.SZ^DZ-0/UK!1N_`@!0BYA55"VPERGU^L".
+ML"3!C=#!:A`?K`;[OT:P(Q`%*[D6L%@%U2)FN57V*PEKPX8$-X(,JT'0L"`L
+M.F7"CD`I[`NK=6$56(N8-55-KYGK#:O$9@0W0A&K01RQVZL.BR3PL"KL](15
+M<"UBUF.%Q"ZQ7&Q'<"-@L1J$%KN].K%(`A3;P^9#6`78(F:M5S5L%^O&4@0W
+M@AJK0;"Q9^R!\,6.0&)L'6O`/E@CD(35QKZQ@.Q#<".0+6*6'UO'[JUR+))`
+MQU:Q,Q!6@;:(60;6'QO(3K(*P8WPR&H0D>PA.\CVL:<IVX(D9%F2+"4KRCY/
+M`(`G>R*`LIILW#`"9;*,+%*%5;PM8I:3%<J.LK3LW@K+:A"R;"IKR@8`J&PK
+MB\:V6B.0JS7+UK*B[(TPMXA9PFPJ>\LB";FL+XLB8!5WBYCE;`VSQ.PD>R-$
+MLQK$-)O*'K,:1#+KS.ZQ>XN8]6Y1L]4L('LCA+,:Q#B;RF*S2((V^\UB%7^+
+MF/5PD;/EK!M[(\2S&L0\F\JBLTB".OO.%EPCD,M%S]:S7.R-,+B(60)M*HO/
+M(@GZ[#][N(A9&-<62]`2LS?"0ZM!1+3;ZT&K022T_^SB(F;]70/M1'O#W@@>
+MK08!TJ:R%BV2@-'JL5C%XR)F>5XAK4A+PMX(+JT&`=.FLB4MDG#2_K.3BYC5
+M>\6T,NT#>R/TM!K$3YO*UK1(PDW[SUXN8M;V!=0&M?CKC<#4:A!.;2I+U"()
+M1NT_N[F(6?G74PO5DJ\WPE:K072UJ>Q4BR14M?_LYR)FD5\2[5<;R`(Y(Q!;
+MN[V*M4@"6?O/CBYBUA'FU;JUU>N-@-=J$'IM*JO6:A!R+4O[A8U`/]A>R]<"
+MKS?"Z2)F);:I[%^+)`2V_^SJ(F8]86WM8MO%0A4C$&:[O3JV&@1D^\^^+F(6
+M)W;&-K":[4AK,(Q`IJTSN[=:MAJ$9VO8SBYBEBYVVHJPJ:T->R/0MAJ$;>O:
+MW@BDK0;1V@JQ&^SM(F:A8IEM;JO:&K<:!'*[O?*V2()O2]RV5UC%[B)F$63)
+MK7([T_8-(Q!VN[TRMTB"<VO8_BYB%DAVVR:QVNW]>B.0MQJ$>?O;<K?7[6DZ
+MO(A9/]EYF]XJL3?"?*M!U+?O+7N+)+BWTZT56S>,0%N9?7O?ZK8#KIA5X+ZW
+M^BV2P-\&N(VLV#`"Y66*[8$+MMX(RXN81>&FLL>+@GN:/B]BUEF6W5JX8"U9
+M-@*)N-MKAJM!;+C_[/0B9@%G%2Z)&[3>""ZN!@'CIK(@K@:!XAJVUXN8I9W%
+MN#+NRWHC]+@:Q(^;RM:X2,*-^\]N+V(6?0;D!KD=ZXW`Y&H03FXJ2^0B"4;N
+M/_N]B%D/VI,+Y2ZL-\*6JT%TN:GLE(LD5+G_[/@B9IUH7NZ7NZ_>"&JN!L'F
+MIK)B+I)`YOZSYXN89:&-N&YNZWHCY+D:Q)Z[O<:Y2,*<^\^N+V(6D,;G]KF:
+MZXV`Z&H0BN[V"N@B"8*N8?N^B%F!FH'+Z`:O-\*EJT%DNN_MHXLD1+J&[?PB
+M9NEI;>ZFJZW>"*:N!H'JIK*>+I(`ZD*XKFSV-`()#E^KJKNDW@CWBYB%ZY:A
+MK2Z2\.K^L_N+F,6LI;JZ[JYZ(Q2[&L2QF\KVNAK$K[N'_B](`J^VZ":[%RX`
+M0.V>"-;N]LKL(@G.[C\KP(A9#!NRB^VJJC?"N*M!E+NI[+8;`'2[AJT!(V:5
+M;.;NN:NIW@CRK@9![Z:RZBZ2P.[^LPJ,F,6SU;OVKJ)Z(P2\&L3`F\KFNTC"
+MOOO/.C!BUM1&\!:\>NJ-`/%J$!)O*HOP(@D*[S\KP8A9:]O$2_&JJ3?"QZM!
+MA+RI[,6+)&2\_ZP%(V9M;=?NR!OE8FTC$,R[O9J\2`+*^\]J,&)6ZB;RRKR[
+M+NHV`OF\J:S+JT'8O(:M!R-F`6^:+M`+M=X(2J\&P?2^MSRO!D'T_K,BC)BE
+MO?V\3J^.>B-DO1K$UIO*1KU(PM1+Z_ZR)HR81;\UO5VOD`L`I+T:Q-K[WH*]
+M2(+8^\^J,&(6!,?VMKTS+]ZK0>B][RW<BR3(O6?O,[N_C4`)'-?+]VJH-X(+
+M(V8EOJFLWXLD`+Z%[QXKPXA949SBN_@JJ#?"Y:M!9+ZIK..K04"^_ZP-@R0L
+M<9KOYJN?W@BF[XF`^J:RGB^2`/K^LSJ,F#7&I;ZJKWIZ(]2^&L3MF\JVO@'`
+MZ_O/^C!B5I"1Z^:^O.F-0/QJ$,9O&<K[(@F^[S\KQ(A9E!SNB_PVIS?"]*M!
+M5+^I[/*+)#2_>Z@1(V:U<M;O]=N;W@CBKP9!_J:RVB^2P/W^LTJ,F"7/E;_F
+MKVMZ(\2_&L3\F\JFOTC"^OO/.C%B%CM'_]:_G^F-``!K$`)P*HO_(@GZ[S\K
+MQ8A9(MT`3``_IC?"`ZQ!1,"I[`&,)"3`_ZP5(V;U&,?O!`R8W@@>L`8!`I>A
+M%C"2@`'_LUJ,F-742<`B\%]Z([3`&L0+G,J6P$C"";R'>C%BUD\7\\;`!B]/
+M-P+YP-LK#8PDV,#_K!@C9B%V,#`0/);>"$JP!L$$I[(\L`9!!!NV9HR8Y=DU
+MP4[P5'HC9,$:Q!:<RD;!2,(4_,^J,6+6;<<%=\%#Z8V`!FL0:G`J"P8C"6+P
+M/^L+:1"PW0_,!F^I-\(=C"3DP=OK&XPDQ,'_K!PC9H%W:_`>+)/>"(:P!H$(
+MI[)^,.-QFMHQ8I9TIP<KPDKJC4`):Q"6\/;:"",)C_`_J\>(61I>(HP)3Z0W
+MPBBL093"J>PFC"1TPH:M'R-FN7BF\"D\D-X(LK`&00NGLJHPDL`*_[."C)@E
+MY-7"MO`\>B,$PQK$,)S*YL)(PB[\SQHR8A:61PP7P^/HC0`-:Q#2<"J+#",)
+MRO`_J\B(65'>-$P-3Z,WPC>L083#J>PUC"1DP_^L(R-F>7F7\#B\H-X([K`&
+M`0]OK^8PDH`._[.2C)@5Z,7#\O!^>B/TPQK$/[R]UL-(PCULV%HR8E:N)PX'
+MQ+/HC<`0:Q`.<2I+$",)!K%AJ\F(6<_>0PP1CZ(WPD:L073$J>Q$C"14Q/^L
+M)R-F(7L>\4<\B=X(*K$&P1*GLB(QDD`2_[.BC)CE[;7$+O$@>B/DQ!K$3IS*
+MQL1(PDS\SYHR8M:Z!Q#WQ-CO#3,"*<7;*U",)`C%_ZPJ(V;%?#PQ4PR'W@A6
+ML0:!%:>R2+$&`14;MJZ,F(7T[;U:\3P,`)3%&L19_-YVQ4C"5_S/RC)B5M"7
+M%:?%3.B-0!=K$'9Q*LL6(PEN<>6+5=@R8E;6=Q?CQ3#HC4`8:Q"&<2J[%R,)
+M??$_J\N(66_?88P8AZ`WPF2L053&J>QBC"0TQO^L+R-F&7Z6\65<@=X(HK$&
+M01JGLIHQDL`9_[/"C)A5_"W%IC$%W"6-0+/Q]IH:(PFK\3]KS(A9OU]I7!NS
+MGS?";ZQ!!,>I;&RL0>3&AJTR(V95?\+Q<&Q\W@C.L08!':>RQC&2@!S_L\Z,
+MF)7^1<?2,>QY(W3'&L1WG,I6QTC"=?S/2C-B5O\''H?'H.>-P!YK$.YQ*DL>
+M(PGF\3]KS8A9"2!M#!\_P0#`?JQ!],?;ZWR,)-3'_ZPV(V8Q@>_Q?^QWW@@*
+ML@;!(*>R`C*20"`;MMZ,F.4%-L@.<MMY(V3(&L2&G,I&R$C"A/S/BC-B%AS(
+M(7?(7.>-@")K$"IR*@LB(PDB\C]KSHA9@N"*S"(CG3?"C:Q!Y,BI[(N,),3(
+M_ZPZ(V91@CKRCAQSW@A&L@:!)*>R/C*2`"3_L^Z,F(4(^L=*\B)<"(Y`5_+V
+MVB0C"4_R/RO/B%G)8)*<)5N<-\*8K$&4R:ELE:Q!=,F&K3TC9FV#9O*93'#>
+M"'*R!D$GI[)J,I+`)O^S^HR8U0[6R7:RO'DC!,H:Q*"<RN;)2,*>_,_Z,V+6
+M/T@H%\KAYHT`*6L0DG(JBR@C"8KR/RO0B%D0X:1,*3^;-\*GK$&$RJGLI8PD
+M9,K_K$$C9A&$6/*H;`PGA",0K+R]FLI(`JK\SRHT8A9)&"O+RM4PB30"^<K;
+MJZNL0=C*AJU#(V8!A:(RL,QIW@C*L@;!+*>RO+(&02P;MA*-F$45-LO.LJ)Y
+M(V3+&L2VG,I&RTC"M/S/6C1B5F"(%G?+0NF-@"YK$.KR>PLN(PGB\C^KT8A9
+M>R&WS"Z?F3?"O:Q!Y,NI[+N,),3+@C$`X-&(69*AOKPO6YDWPL&L023,J:R_
+MC"0`S/^L2"-F,8<*\\+\8]X(%K,&@3&GL@XSD@`Q_[,FC9AU'&;,&C.)>2.4
+MS!K$R9S*=LQ(PL?\SZHT8I9VB#*GS!+FC4`S:Q`V<RK+,B,)+O,_Z]*(607B
+MNHPSW\(MP@A4-+^W.S.2T#/_LS*-F/4?WLQ'\W]Y(T3-&L34G,H.S1K$TEPP
+MVS1B5H5(-5?-[N6-`#9K$&)S*HLU(PE:\S^KTXA93N+83#9[ES?"VZQ!Q,VI
+M[-F,)*3-_ZQ/(V8EB7+SW%Q<W@A^LP8!.*>R=C.2@#?_LT*-F$4G&LV",SD<
+M)8Y`C_-[6S@C"8?S/VO4B%F*(N0<.0^C-\+FK$%TSN]MXZQ!5,X%LU(C9GV*
+MGO/G'!$#`*JS!L$ZO[>B,Y)`.A?,3HV8I2D&SJZS8GDCY,X:Q.Z<RL;.2,+L
+M7#!+-6)6K?@K]\Y+Z(V`/&L0RO/V"CPC"<+S/VO5B%G/(N_,/-N5-\+UK$%D
+MSZGL\XPD1,^&K58C9NV+K?/V+(G>".:S!H$^O[?>,Y(`/O^S7HV8!3&FS^JS
+M('HCU,\:Q/W\WK;/2,+[7#"+-6(6R8@_Y\];,0!`0&L0!O1[RS\C"?YSY8M`
+MZ[Y(XPC4@Z:R,ZA`4(/NH3Z*F)4U+L\3M/UY(W30&L0'O;WNH&_-:1JEB%EM
+MXP$=0C?/`,`*K4&TT.\M"8TDF-"&K9@B9B6.+O0+_8+>"#JT!L%#O[<R-))`
+M0Q?,9XJ8U3GZLJBM#ZT_RXTCT!)=^.ZM0322,$07S&R*F#4[]M!.]&F\IHQ`
+M6_1[FT1K$%*TD5GK4J$:A!7*17?1(C2<,@*IT>]M%JU!A-$%\Q,Z$*"AVC,;
+M/4_>"$&H!C&$8M`XZ!^680PI8A;_>,86H4EH(GV$+M(QBAXM-MX(A+0&84B_
+MMWTTDO!'?[,9AI4B9D&0AS0C[4DKTJ`T;NM(%XPW@B:M07#2[VTDC21,TA+T
+M*/V8`@KM0`"@`%`!P@P`E`1``5\`I\`L4`I(0!$``F`(0\`2\$LG`43`$>!+
+M_PIY@A2P*P0!IH(O#05@")7"H<`$@`#/]!-@!1#3=4+W4`5``5``HD`%Q`F6
+M0C<]!20!6$"<,"?XTG8"GJ`G=`]Z`C--!20!0\`4`#=-"E.`+WTH.`$.R1#P
+M31,!8<(00$U7`4*`KS`%]-*!@A%@*<C3AD(2("=L(^_T$^`$=`^D@C(=*D`(
+M];0S#5`+U`2UF?`GX-,*=1(`*)@)#_4SG03D(U)`%@`"6`%/`!-0!30!OO2?
+MH"M(`;=TI5!06PKW=#[]3?\*!K44D(\TU$Y`>N5*_]1`=5`M5`_51'51;50?
+MU4AU4JU4+]5,=5/M5#_54'54+55/U51U56U57]58=5:M56_57'57[55_U6!U
+M6"U6C]5D=5EM5I_5:'5:K5:OU6QU6^U6O]5P=5PM5\_5='5=;5??U7AU7JU7
+M[]5\=5_M5__5@'5@+5@/UH1U86U8']:(=6*M6"_6C'5C[5@_UI!U9"U93]:4
+M=65M65_6F'5FK5EOUIQU9^U9?]:@=6@M6H_6I'5I;5J?UJAU:JU:K]:L=6OM
+M6K_6L'5L+5O/UK1U;6U;W]:X=6ZM6^_6O'5O[5O_UL!U<"U<#]?$=7%M7!_7
+MR'5RK5POU\QU<^U</]?0=70M74_7U'5U;5U?U]AU=JU=;]?<=7?M77_7X'5X
+M+5Z/U^1U>6U>G]?H=7JM7J_7['5[[5Z_U_!U?"U?S]?T=7UM7]_7^'5^K5_O
+MU_QU?^U?_]<`=H`M8`_8!':!;6`?V`AV@JU@+]@,=H/M8#_8$':$+6%/V!1V
+MA6UA7]@8=H:M86_8'':'[6%_V"!VB"UBC]@D=HEM8I_8*':*K6*OV"QVB^UB
+4O]@P=HPM8\_8-':-;6/?V#BVW0$`
+`
+end
diff --git a/lib/libarchive/test/test_open_fd.c b/lib/libarchive/test/test_open_fd.c
index 0aec1d5..7551dd0 100644
--- a/lib/libarchive/test/test_open_fd.c
+++ b/lib/libarchive/test/test_open_fd.c
@@ -25,6 +25,13 @@
#include "test.h"
__FBSDID("$FreeBSD$");
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define open _open
+#if !defined(__BORLANDC__)
+#define lseek _lseek
+#endif
+#define close _close
+#endif
DEFINE_TEST(test_open_fd)
{
@@ -33,7 +40,11 @@ DEFINE_TEST(test_open_fd)
struct archive *a;
int fd;
- fd = open("test.tar", O_RDWR | O_CREAT, 0777);
+#if defined(__BORLANDC__)
+ fd = open("test.tar", O_RDWR | O_CREAT | O_BINARY);
+#else
+ fd = open("test.tar", O_RDWR | O_CREAT | O_BINARY, 0777);
+#endif
assert(fd >= 0);
if (fd < 0)
return;
diff --git a/lib/libarchive/test/test_open_file.c b/lib/libarchive/test/test_open_file.c
index e931163..7e6c571 100644
--- a/lib/libarchive/test/test_open_file.c
+++ b/lib/libarchive/test/test_open_file.c
@@ -32,7 +32,7 @@ DEFINE_TEST(test_open_file)
struct archive *a;
FILE *f;
- f = fopen("test.tar", "w");
+ f = fopen("test.tar", "wb");
assert(f != NULL);
if (f == NULL)
return;
@@ -73,7 +73,7 @@ DEFINE_TEST(test_open_file)
/*
* Now, read the data back.
*/
- f = fopen("test.tar", "r");
+ f = fopen("test.tar", "rb");
assert(f != NULL);
if (f == NULL)
return;
diff --git a/lib/libarchive/test/test_pax_filename_encoding.c b/lib/libarchive/test/test_pax_filename_encoding.c
index 45f9848..5affe9f 100644
--- a/lib/libarchive/test/test_pax_filename_encoding.c
+++ b/lib/libarchive/test/test_pax_filename_encoding.c
@@ -107,9 +107,10 @@ test_pax_filename_encoding_2(void)
* de_DE.UTF-8 seems to be commonly supported.
*/
/* If it doesn't exist, just warn and return. */
- if (NULL == setlocale(LC_ALL, LOCALE_DE)) {
+ if (LOCALE_UTF8 == NULL
+ || NULL == setlocale(LC_ALL, LOCALE_UTF8)) {
skipping("invalid encoding tests require a suitable locale;"
- " %s not available on this system", LOCALE_DE);
+ " %s not available on this system", LOCALE_UTF8);
return;
}
@@ -151,11 +152,7 @@ test_pax_filename_encoding_2(void)
archive_entry_free(entry);
assertEqualInt(0, archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
assertEqualInt(0, archive_write_finish(a));
-#endif
/*
* Now read the entries back.
@@ -181,11 +178,7 @@ test_pax_filename_encoding_2(void)
assertEqualString(longname, archive_entry_pathname(entry));
assertEqualInt(0, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
assertEqualInt(0, archive_read_finish(a));
-#endif
}
/*
@@ -227,6 +220,15 @@ test_pax_filename_encoding_3(void)
return;
}
+ /* Skip test if archive_entry_update_pathname_utf8() is broken. */
+ /* In particular, this is currently broken on Win32 because
+ * setlocale() does not set the default encoding for CP_ACP. */
+ entry = archive_entry_new();
+ if (archive_entry_update_pathname_utf8(entry, badname_utf8)) {
+ skipping("Cannot test conversion failures.");
+ return;
+ }
+
assert((a = archive_write_new()) != NULL);
assertEqualIntA(a, 0, archive_write_set_format_pax(a));
assertEqualIntA(a, 0, archive_write_set_compression_none(a));
@@ -274,11 +276,7 @@ test_pax_filename_encoding_3(void)
archive_entry_free(entry);
assertEqualInt(0, archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
assertEqualInt(0, archive_write_finish(a));
-#endif
/*
* Now read the entries back.
@@ -322,11 +320,7 @@ test_pax_filename_encoding_3(void)
assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &entry));
assertEqualInt(0, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
assertEqualInt(0, archive_read_finish(a));
-#endif
}
DEFINE_TEST(test_pax_filename_encoding)
diff --git a/lib/libarchive/test/test_read_compress_program.c b/lib/libarchive/test/test_read_compress_program.c
index 042c615..12e6afc 100644
--- a/lib/libarchive/test/test_read_compress_program.c
+++ b/lib/libarchive/test/test_read_compress_program.c
@@ -37,7 +37,6 @@ DEFINE_TEST(test_read_compress_program)
int r;
struct archive_entry *ae;
struct archive *a;
- const char *extprog;
/*
* First, test handling when a non-existent compression
@@ -53,26 +52,23 @@ DEFINE_TEST(test_read_compress_program)
assertEqualIntA(a, ARCHIVE_OK, r);
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
- assertEqualIntA(a, ARCHIVE_OK,
- archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualIntA(a, ARCHIVE_FATAL,
- archive_read_next_header(a, &ae));
- assertEqualIntA(a, ARCHIVE_WARN, archive_read_close(a));
+ archive_read_open_memory(a, archive, sizeof(archive)));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
/*
* If we have "gzip -d", try using that.
*/
- if ((extprog = external_gzip_program(1)) == NULL) {
- skipping("There is no gzip uncompression "
- "program in this platform");
+ if (!canGunzip()) {
+ skipping("Can't run gunzip program on this platform");
return;
}
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_compression_none(a));
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_program(a, extprog));
+ archive_read_support_compression_program(a, "gunzip"));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
diff --git a/lib/libarchive/test/test_read_data_large.c b/lib/libarchive/test/test_read_data_large.c
index 76b9e12..ecacf65 100644
--- a/lib/libarchive/test/test_read_data_large.c
+++ b/lib/libarchive/test/test_read_data_large.c
@@ -33,6 +33,11 @@ __FBSDID("$FreeBSD$");
* had a bug relating to this, fixed in Nov 2006).
*/
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define open _open
+#define close _close
+#endif
+
char buff1[11000000];
char buff2[10000000];
char buff3[10000000];
@@ -43,6 +48,7 @@ DEFINE_TEST(test_read_data_large)
struct archive *a;
char tmpfilename[] = "largefile";
int tmpfilefd;
+ FILE *f;
unsigned int i;
size_t used;
@@ -96,7 +102,11 @@ DEFINE_TEST(test_read_data_large)
assertA(0 == archive_read_support_compression_all(a));
assertA(0 == archive_read_open_memory(a, buff1, sizeof(buff1)));
assertA(0 == archive_read_next_header(a, &ae));
- tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT, 0777);
+#if defined(__BORLANDC__)
+ tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY);
+#else
+ tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY, 0777);
+#endif
assert(tmpfilefd != 0);
assertEqualIntA(a, 0, archive_read_data_into_fd(a, tmpfilefd));
assert(0 == archive_read_close(a));
@@ -107,11 +117,9 @@ DEFINE_TEST(test_read_data_large)
#endif
close(tmpfilefd);
- tmpfilefd = open(tmpfilename, O_RDONLY);
- assert(tmpfilefd != 0);
- assertEqualIntA(NULL, sizeof(buff3), read(tmpfilefd, buff3, sizeof(buff3)));
- close(tmpfilefd);
+ f = fopen(tmpfilename, "rb");
+ assert(f != NULL);
+ assertEqualInt(sizeof(buff3), fread(buff3, 1, sizeof(buff3), f));
+ fclose(f);
assert(0 == memcmp(buff2, buff3, sizeof(buff3)));
-
- unlink(tmpfilename);
}
diff --git a/lib/libarchive/test/test_read_disk.c b/lib/libarchive/test/test_read_disk.c
index cd87c5b..5666656 100644
--- a/lib/libarchive/test/test_read_disk.c
+++ b/lib/libarchive/test/test_read_disk.c
@@ -111,8 +111,10 @@ DEFINE_TEST(test_read_disk)
if (archive_read_disk_set_standard_lookup(a) != ARCHIVE_OK) {
skipping("standard uname/gname lookup");
} else {
-#if defined(__CYGWIN__)
- skipping("standard uname/gname lookup; typically no user with uid=0 on cygwin platform");
+#if defined(__CYGWIN__) || defined(__HAIKU__)
+ /* Some platforms don't have predictable names for
+ * uid=0, so we skip this part of the test. */
+ skipping("standard uname/gname lookup");
i = 0;
p = zero_groups[0]; /* avoid unused warnings */
#else
diff --git a/lib/libarchive/test/test_read_disk_entry_from_file.c b/lib/libarchive/test/test_read_disk_entry_from_file.c
index 8b3b6d7..652b5e4 100644
--- a/lib/libarchive/test/test_read_disk_entry_from_file.c
+++ b/lib/libarchive/test/test_read_disk_entry_from_file.c
@@ -45,7 +45,7 @@ DEFINE_TEST(test_read_disk_entry_from_file)
{
struct archive *a;
struct archive_entry *entry;
- int fd;
+ FILE *f;
assert((a = archive_read_disk_new()) != NULL);
@@ -57,10 +57,10 @@ DEFINE_TEST(test_read_disk_entry_from_file)
assertEqualString(archive_read_disk_gname(a, 0), "FOOGROUP");
/* Create a file on disk. */
- fd = open("foo", O_WRONLY | O_CREAT, 0777);
- assert(fd >= 0);
- assertEqualInt(4, write(fd, "1234", 4));
- close(fd);
+ f = fopen("foo", "wb");
+ assert(f != NULL);
+ assertEqualInt(4, fwrite("1234", 1, 4, f));
+ fclose(f);
/* Use archive_read_disk_entry_from_file to get information about it. */
entry = archive_entry_new();
diff --git a/lib/libarchive/test/test_read_extract.c b/lib/libarchive/test/test_read_extract.c
index 887ddfd..10bd014 100644
--- a/lib/libarchive/test/test_read_extract.c
+++ b/lib/libarchive/test/test_read_extract.c
@@ -32,22 +32,15 @@ DEFINE_TEST(test_read_extract)
{
struct archive_entry *ae;
struct archive *a;
-#if !defined(_WIN32) || defined(__CYGWIN__)
- struct stat st;
-#endif
size_t used;
- int i;
+ int i, numEntries = 0;
char *buff, *file_buff;
-#if !defined(_WIN32) || defined(__CYGWIN__)
- int fd;
- ssize_t bytes_read;
-#endif
buff = malloc(BUFF_SIZE);
file_buff = malloc(FILE_BUFF_SIZE);
/* Force the umask to something predictable. */
- umask(022);
+ assertUmask(022);
/* Create a new archive in memory containing various types of entries. */
assert((a = archive_write_new()) != NULL);
@@ -55,12 +48,14 @@ DEFINE_TEST(test_read_extract)
assertA(0 == archive_write_set_compression_none(a));
assertA(0 == archive_write_open_memory(a, buff, BUFF_SIZE, &used));
/* A directory to be restored with EXTRACT_PERM. */
+ ++numEntries;
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "dir_0775");
archive_entry_set_mode(ae, S_IFDIR | 0775);
assertA(0 == archive_write_header(a, ae));
archive_entry_free(ae);
/* A regular file. */
+ ++numEntries;
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "file");
archive_entry_set_mode(ae, S_IFREG | 0755);
@@ -71,49 +66,53 @@ DEFINE_TEST(test_read_extract)
assertA(FILE_BUFF_SIZE == archive_write_data(a, file_buff, FILE_BUFF_SIZE));
archive_entry_free(ae);
/* A directory that should obey umask when restored. */
+ ++numEntries;
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "dir");
archive_entry_set_mode(ae, S_IFDIR | 0777);
assertA(0 == archive_write_header(a, ae));
archive_entry_free(ae);
/* A file in the directory. */
+ ++numEntries;
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "dir/file");
archive_entry_set_mode(ae, S_IFREG | 0700);
assertA(0 == archive_write_header(a, ae));
archive_entry_free(ae);
/* A file in a dir that is not already in the archive. */
+ ++numEntries;
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "dir2/file");
archive_entry_set_mode(ae, S_IFREG | 0000);
assertA(0 == archive_write_header(a, ae));
archive_entry_free(ae);
/* A dir with a trailing /. */
+ ++numEntries;
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "dir3/.");
archive_entry_set_mode(ae, S_IFDIR | 0710);
assertA(0 == archive_write_header(a, ae));
archive_entry_free(ae);
/* Multiple dirs with a single entry. */
+ ++numEntries;
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "dir4/a/../b/../c/");
archive_entry_set_mode(ae, S_IFDIR | 0711);
assertA(0 == archive_write_header(a, ae));
archive_entry_free(ae);
/* A symlink. */
- assert((ae = archive_entry_new()) != NULL);
- archive_entry_copy_pathname(ae, "symlink");
- archive_entry_set_mode(ae, S_IFLNK | 0755);
- archive_entry_set_symlink(ae, "file");
- assertA(0 == archive_write_header(a, ae));
- archive_entry_free(ae);
+ if (canSymlink()) {
+ ++numEntries;
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "symlink");
+ archive_entry_set_mode(ae, AE_IFLNK | 0755);
+ archive_entry_set_symlink(ae, "file");
+ assertA(0 == archive_write_header(a, ae));
+ archive_entry_free(ae);
+ }
/* Close out the archive. */
assertA(0 == archive_write_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
assertA(0 == archive_write_finish(a));
-#endif
/* Extract the entries to disk. */
assert((a = archive_read_new()) != NULL);
@@ -125,75 +124,44 @@ DEFINE_TEST(test_read_extract)
assertA(0 == archive_read_next_header(a, &ae));
assertA(0 == archive_read_extract(a, ae, ARCHIVE_EXTRACT_PERM));
/* Rest of entries get restored with no flags. */
- for (i = 0; i < 7; i++) {
- failure("Error reading entry %d", i+1);
+ for (i = 1; i < numEntries; i++) {
+ failure("Error reading entry %d", i);
assertA(0 == archive_read_next_header(a, &ae));
+ failure("Failed to extract entry %d: %s", i,
+ archive_entry_pathname(ae));
assertA(0 == archive_read_extract(a, ae, 0));
}
assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
assert(0 == archive_read_finish(a));
-#endif
-#if !defined(_WIN32) || defined(__CYGWIN__)
/* Test the entries on disk. */
/* This first entry was extracted with ARCHIVE_EXTRACT_PERM,
* so the permissions should have been restored exactly,
* including resetting the gid bit on those platforms
* where gid is inherited by subdirs. */
- assert(0 == stat("dir_0775", &st));
failure("This was 0775 in archive, and should be 0775 on disk");
- assertEqualInt(st.st_mode, S_IFDIR | 0775);
+ assertIsDir("dir_0775", 0775);
/* Everything else was extracted without ARCHIVE_EXTRACT_PERM,
* so there may be some sloppiness about gid bits on directories. */
- assert(0 == stat("file", &st));
- failure("st.st_mode=%o should be %o", st.st_mode, S_IFREG | 0755);
- assertEqualInt(st.st_mode, S_IFREG | 0755);
- failure("The file extracted to disk is the wrong size.");
- assert(st.st_size == FILE_BUFF_SIZE);
- fd = open("file", O_RDONLY);
- failure("The file on disk could not be opened.");
- assert(fd != 0);
- bytes_read = read(fd, buff, FILE_BUFF_SIZE);
- close(fd);
- failure("The file contents read from disk are the wrong size");
- assert(bytes_read == FILE_BUFF_SIZE);
- failure("The file contents on disk do not match the file contents that were put into the archive.");
- assert(memcmp(buff, file_buff, FILE_BUFF_SIZE) == 0);
- assert(0 == stat("dir", &st));
- failure("This was 0777 in archive, but umask should make it 0755");
+ assertIsReg("file", 0755);
+ assertFileSize("file", FILE_BUFF_SIZE);
+ assertFileContents(file_buff, FILE_BUFF_SIZE, "file");
/* If EXTRACT_PERM wasn't used, be careful to ignore sgid bit
* when checking dir modes, as some systems inherit sgid bit
* from the parent dir. */
- assertEqualInt(0755, st.st_mode & 0777);
- assert(0 == stat("dir/file", &st));
- assert(st.st_mode == (S_IFREG | 0700));
- assert(0 == stat("dir2", &st));
- assertEqualInt(0755, st.st_mode & 0777);
- assert(0 == stat("dir2/file", &st));
- assert(st.st_mode == (S_IFREG | 0000));
- assert(0 == stat("dir3", &st));
- assertEqualInt(0710, st.st_mode & 0777);
- assert(0 == stat("dir4", &st));
- assertEqualInt(0755, st.st_mode & 0777);
- assert(0 == stat("dir4/a", &st));
- assertEqualInt(0755, st.st_mode & 0777);
- assert(0 == stat("dir4/b", &st));
- assertEqualInt(0755, st.st_mode & 0777);
- assert(0 == stat("dir4/c", &st));
- assertEqualInt(0711, st.st_mode & 0777);
- assert(0 == lstat("symlink", &st));
- assert(S_ISLNK(st.st_mode));
-#if HAVE_LCHMOD
- /* Systems that lack lchmod() can't set symlink perms, so skip this. */
- assert((st.st_mode & 07777) == 0755);
-#endif
- assert(0 == stat("symlink", &st));
- assert(st.st_mode == (S_IFREG | 0755));
-#endif
+ failure("This was 0777 in archive, but umask should make it 0755");
+ assertIsDir("dir", 0755);
+ assertIsReg("dir/file", 0700);
+ assertIsDir("dir2", 0755);
+ assertIsReg("dir2/file", 0000);
+ assertIsDir("dir3", 0710);
+ assertIsDir("dir4", 0755);
+ assertIsDir("dir4/a", 0755);
+ assertIsDir("dir4/b", 0755);
+ assertIsDir("dir4/c", 0711);
+ if (canSymlink())
+ assertIsSymlink("symlink", "file");
free(buff);
free(file_buff);
diff --git a/lib/libarchive/test/test_read_format_ar.ar.uu b/lib/libarchive/test/test_read_format_ar.ar.uu
new file mode 100644
index 0000000..70507cc
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_ar.ar.uu
@@ -0,0 +1,12 @@
+$FreeBSD$
+
+begin 755 test_read_format_ar.ar
+M(3QA<F-H/@HO+R`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
+M("`@("`@("`@("`T,"`@("`@("`@8`IY>7ET='1S<W-A86%F9F8N;R\*:&AH
+M:&IJ:FIK:VMK;&QL;"YO+PH*+S`@("`@("`@("`@("`@(#$Q-S4T-C4V-3(@
+M(#$P,#$@(#`@("`@(#$P,#8T-"`@."`@("`@("`@(&`*-34V-C<W.#AG9VAH
+M+F\O("`@("`@("`@,3$W-30V-38V."`@,3`P,2`@,"`@("`@,3`P-C0T("`T
+M("`@("`@("`@8`HS,S,S+S$Y("`@("`@("`@("`@(#$Q-S4T-C4W,3,@(#$P
+H,#$@(#`@("`@(#$P,#8T-"`@.2`@("`@("`@(&`*.3@W-C4T,S(Q"@``
+`
+end
diff --git a/lib/libarchive/test/test_read_format_ar.c b/lib/libarchive/test/test_read_format_ar.c
index f4b31de..fc95978 100644
--- a/lib/libarchive/test/test_read_format_ar.c
+++ b/lib/libarchive/test/test_read_format_ar.c
@@ -28,46 +28,19 @@
#include "test.h"
__FBSDID("$FreeBSD$");
-#if ARCHIVE_VERSION_NUMBER >= 1009000
-/*
- * This "archive" is created by "GNU ar". Here we try to verify
- * our GNU format handling functionality.
- */
-static unsigned char archive[] = {
-'!','<','a','r','c','h','>',10,'/','/',' ',' ',' ',' ',' ',' ',' ',
-' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
-' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
-' ',' ',' ',' ',' ','4','0',' ',' ',' ',' ',' ',' ',' ',' ','`',10,
-'y','y','y','t','t','t','s','s','s','a','a','a','f','f','f','.','o',
-'/',10,'h','h','h','h','j','j','j','j','k','k','k','k','l','l','l',
-'l','.','o','/',10,10,'/','0',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
-' ',' ',' ',' ','1','1','7','5','4','6','5','6','5','2',' ',' ','1',
-'0','0','1',' ',' ','0',' ',' ',' ',' ',' ','1','0','0','6','4','4',
-' ',' ','8',' ',' ',' ',' ',' ',' ',' ',' ',' ','`',10,'5','5','6',
-'6','7','7','8','8','g','g','h','h','.','o','/',' ',' ',' ',' ',' ',
-' ',' ',' ',' ','1','1','7','5','4','6','5','6','6','8',' ',' ','1',
-'0','0','1',' ',' ','0',' ',' ',' ',' ',' ','1','0','0','6','4','4',
-' ',' ','4',' ',' ',' ',' ',' ',' ',' ',' ',' ','`',10,'3','3','3',
-'3','/','1','9',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
-'1','1','7','5','4','6','5','7','1','3',' ',' ','1','0','0','1',' ',
-' ','0',' ',' ',' ',' ',' ','1','0','0','6','4','4',' ',' ','9',' ',
-' ',' ',' ',' ',' ',' ',' ',' ','`',10,'9','8','7','6','5','4','3',
-'2','1',10};
-
-char buff[64];
-#endif
DEFINE_TEST(test_read_format_ar)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("test_read_support_format_ar()");
-#else
+ char buff[64];
+ const char reffile[] = "test_read_format_ar.ar";
struct archive_entry *ae;
struct archive *a;
+
+ extract_reference_file(reffile);
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_compression_all(a));
assertA(0 == archive_read_support_format_all(a));
- assertA(0 == archive_read_open_memory(a, archive, sizeof(archive)));
+ assertA(0 == archive_read_open_file(a, reffile, 7));
/* Filename table. */
assertA(0 == archive_read_next_header(a, &ae));
@@ -110,10 +83,5 @@ DEFINE_TEST(test_read_format_ar)
/* Test EOF */
assertA(1 == archive_read_next_header(a, &ae));
assert(0 == archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
assert(0 == archive_read_finish(a));
-#endif
-#endif
}
diff --git a/lib/libarchive/test/test_read_format_cpio_bin_bz2.c b/lib/libarchive/test/test_read_format_cpio_bin_bz2.c
index 90270c8..f7c4efb 100644
--- a/lib/libarchive/test/test_read_format_cpio_bin_bz2.c
+++ b/lib/libarchive/test/test_read_format_cpio_bin_bz2.c
@@ -36,10 +36,15 @@ DEFINE_TEST(test_read_format_cpio_bin_bz2)
{
struct archive_entry *ae;
struct archive *a;
+ int r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK,
- archive_read_support_compression_all(a));
+ r = archive_read_support_compression_bzip2(a);
+ if (r != ARCHIVE_OK) {
+ skipping("bzip2 support unavailable");
+ archive_read_close(a);
+ return;
+ }
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
diff --git a/lib/libarchive/test/test_read_format_cpio_bin_lzma.c b/lib/libarchive/test/test_read_format_cpio_bin_lzma.c
new file mode 100644
index 0000000..26c0440
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_cpio_bin_lzma.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * 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 unsigned char archive[] = {
+ 93, 0, 0,128, 0,255,255,255,255,255,255,255,255, 0, 99,156,
+ 62,160, 67,124,230, 93,220,235,118, 29, 75, 27,226,158, 67,149,
+151, 96, 22, 54,198,209, 63,104,209,148,249,238, 71,187,201,243,
+162, 1, 42, 47, 43,178, 35, 90, 6,156,208, 74,107, 91,229,126,
+ 5, 85,255,136,255, 64, 0
+};
+
+DEFINE_TEST(test_read_format_cpio_bin_lzma)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ int r;
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ r = archive_read_support_compression_lzma(a);
+ if (r == ARCHIVE_WARN) {
+ skipping("lzma reading not fully supported on this platform");
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, archive, sizeof(archive)));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_LZMA);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+}
+
diff --git a/lib/libarchive/test/test_read_format_iso.iso.Z.uu b/lib/libarchive/test/test_read_format_iso.iso.Z.uu
new file mode 100644
index 0000000..2f5cbd7
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso.iso.Z.uu
@@ -0,0 +1,26 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso.iso.Z
+M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR
+MI,F3*%.J7,FRI<N7,&/*G$FSILV;.'/JW,FSI\^?0(,*'4JTJ-&C2),J7<JT
+MJ=.G4*-*G4JUJM6K6+-JW<JUJ]>O8,.*'4NVK-FS:-.J7<NVK=NW<./*G4NW
+MKMV[>//JW<NWK]^_@`,+'DRXL.'#B!,K7LRXL>/'D"-+GDRYLN7+F#-KWLRY
+ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
+MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
+MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA
+MA!1***`43S11X88<1G@0#`6!Z-&!``1`XH$((`"``@4I,$%"%0PD`@`7%%2C
+MB@*IF,8"!UR``0O@"!#0B0=V:.212":IY)),-NGDDU!&*>645%9IY952-K%$
+M$E,\8<04('#Y!`@YV&`##"\@\24(1B3!1!%39#$%%45H*$05;A)1A!0@F`#"
+MA44,\804#PK8@A0O$&%%H5(4$005@X*`PA`I@!!##CG,`$(1+F3Q1!5.'$%$
+M$&]*2JFEF-X`@A(N0.&H%%TZ\0*K4PR!A)M,)!$JEKSVRJL,!-800PPPW"##
+M##+04,,-!((#+`S"$FLLLLHR"P,X!&:K[;8$`O!LM,4>F^RRS1;IZ[GHIJON
+MNNRVZ^Z[\,8K+Y/_U;O8/P(2:*"]_/;K[[\`!UR=EDF`T,0;;H#@Q!MV0*CJ
+ML3HDJ\.R('RK0!MKI#''&V;,4;$+,+B@:0MO@$!'&7/0T8*"89#QA1EOR-%&
+M&'2XH'')80BL\\X\]^SSSV<=6..00!=M]-%()ZWTTDPW[?334$?=&XD!U4BU
+MU%AGK?767'?M]==@ARWVV%K/./1`-PZD(X\^`BEDB4,>:+:-`.`8T-H]_A@D
+MT26:2/;?@`<N^."$%V[XX8@GKOCBC#?N^..01R[YY)17;OGEF&>N^>:<=^[Y
+MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,<N^^RTUV[[[;CGKOONO/?N^^_`!R_\
+M\,07;_SQR">O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(<O_OCDEV_^
+L^>BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`]`,`
+`
+end
diff --git a/lib/libarchive/test/test_read_format_iso_gz.c b/lib/libarchive/test/test_read_format_iso_gz.c
index 73c8415..2289379 100644
--- a/lib/libarchive/test/test_read_format_iso_gz.c
+++ b/lib/libarchive/test/test_read_format_iso_gz.c
@@ -29,20 +29,13 @@ DEFINE_TEST(test_read_format_iso_gz)
{
struct archive_entry *ae;
struct archive *a;
- int r;
- const char *name = "test_read_format_iso_gz.iso.gz";
+ const char *name = "test_read_format_iso.iso.Z";
extract_reference_file(name);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_compression_all(a));
- r = archive_read_support_compression_gzip(a);
- if (r == ARCHIVE_WARN) {
- skipping("gzip reading not fully supported on this platform");
- assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
- return;
- }
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
@@ -50,7 +43,7 @@ DEFINE_TEST(test_read_format_iso_gz)
assertEqualIntA(a, ARCHIVE_OK,
archive_read_next_header(a, &ae));
assertEqualInt(archive_compression(a),
- ARCHIVE_COMPRESSION_GZIP);
+ ARCHIVE_COMPRESSION_COMPRESS);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
diff --git a/lib/libarchive/test/test_read_format_iso_joliet.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_joliet.iso.Z.uu
new file mode 100644
index 0000000..b6ac252
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_joliet.iso.Z.uu
@@ -0,0 +1,66 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso_joliet.iso.Z
+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
+(&(_R.(_T:!4`
+`
+end
diff --git a/lib/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu
new file mode 100644
index 0000000..9babf69
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu
@@ -0,0 +1,71 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso_joliet_long.iso.Z
+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
+4>9B(F9B*N9B,V9B.^9B0&9F2J90`
+`
+end
diff --git a/lib/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu
new file mode 100644
index 0000000..fdccb0c
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu
@@ -0,0 +1,68 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso_joliet_rockridge.iso.Z
+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
+.V9(N^9(P&9,R.9,T^8(`
+`
+end
diff --git a/lib/libarchive/test/test_read_format_iso_multi_extent.c b/lib/libarchive/test/test_read_format_iso_multi_extent.c
new file mode 100644
index 0000000..9697a4b
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_multi_extent.c
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * 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$");
+
+DEFINE_TEST(test_read_format_iso_multi_extent)
+{
+ const char *refname = "test_read_format_iso_multi_extent.iso.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *p;
+ size_t size;
+ off_t offset;
+ int i;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_format_all(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Retrieve each of the 2 files on the ISO image and
+ * verify that each one is what we expect. */
+ for (i = 0; i < 2; ++i) {
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+
+ if (strcmp(".", archive_entry_pathname(ae)) == 0) {
+ /* '.' root directory. */
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(262280, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "head--head--head", 16);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else {
+ failure("Saw a file that shouldn't have been there");
+ assertEqualString(archive_entry_pathname(ae), "");
+ }
+ }
+
+ /* End of archive. */
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
+
+ /* Close the archive. */
+ assertEqualInt(0, archive_read_close(a));
+ assertEqualInt(0, archive_read_finish(a));
+}
+
+
diff --git a/lib/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu
new file mode 100644
index 0000000..3ce33dc
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu
@@ -0,0 +1,67 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso_multi_extent.iso.Z
+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
+0^9`0&9$2.9$469$6>9%O"```
+`
+end
diff --git a/lib/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu
new file mode 100644
index 0000000..218631c
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu
@@ -0,0 +1,206 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso_rockridge.iso.Z
+M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR
+MI,F3*%.J7,FRI<N7,&/*G$FSILV;.'/JW,FSI\^?0(,*'4JTJ-&C2),J7<JT
+MJ=.G4*-*G4JUJM6K6+-JW<JUJ]>O8,.*'4NVK-FS:-.J7<NVK=NW<./*G4NW
+MKMV[>//JW<NWK]^_@`,+'DRXL.'#B!,K7LRXL>/'D"-+GDRYLN7+F#-KWLRY
+ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
+MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
+MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA
+MA!1***`43S11X88<1GA0#Q@,A$$/'QT(0``F'H@``@!84)`%$R14P4`B`'!!
+M03>R*!"+1@0@0`(GDB!`0"D>V.&12":IY)),-NGDDU!&*>645%9IY9583MG$
+M$DE,\8014X#0Y1,@Y&"##3"\@`28(!B1!!-%3)'%%%04H:$05;Q)1!%2@&`"
+M"!<6,<034CPH8`M2O$"$%89*44005!`*`@I#I`!"##GD,`,(1;B0Q1-5.'$$
+M$4'`.6FEEV9Z`PA*N`#%HU)XZ<0+K4XQ!!)O,I&$J%GVZFNO,A"8`PPYR'`#
+MIC'4,$.P,)#`[+#%'IM#LLL22`*!V&:K+8$`/$NLL<@JRRP)1OYJ[KGHIJON
+MNNRVZ^Z[\,;;Y'_T+O:/@`0:6.^^_/;K[[\`5[=E$B!,48<;!9<!!PC&IJI#
+MLCHLR["P"K2Q1AISO&'&'`R[4"`(B()<1QID7`KR&20S#((+++^`\1L!QRSS
+MS#37;'-:!]Y(I$`#`!#BSD0D(<7-1!=M]-%()ZWTTDPW[?334+]F8D`WFMBS
+M0"$&$/3047?M]==@ARWVV&27;?;9:">-B(TX`J!C0#SZ"&0`0NY\XH%30'%`
+M`+Z\`X`44A000"!08$%N.T$,%$0[5P\TP-0"^5B0`%08H4$`#O3X8Y!M)+#!
+M!`^`0$+GGX=.PA!%<!!`!@6Q;E`[!;5C!ML$Y3A0W)O3/>2)1*((N."$&QX`
+MXHHS7M#C!4E.$.668Z[YW*-[#KKHI$]/`@!P^%Q0B&^[C:#<0>Z>X@!;_QY`
+M(DXT@<"!9*0A1^&')R[0XKL/)`#D1-8O$/.79PX^W<_CG/1,!P`Z`$`#!=$`
+M%<+`BX#P(@R5^]_U[!:``[@)3B[800S,A[XF).!`9D@#&\H`OP"0(A`#"00I
+M]!>0^R6/A0#@G_,D&$"Z5<]T?#A@`A?80``\,(*YFR#O3K0`)`2A4+IRPA(R
+MN,'`G2]]#3@0&L(@!S*P(0UN6$,)3YC"%4X.?R>"H0S]%\0:1J]THC,$`$ZA
+M,ZJ=XB!FC!R1%""G)B1QB1K\FQ,;D3X&'&@.>6C#%;-8PG:$8B"A:`<84?3"
+MR4V!"0LP$0%".,+*]:]'`P"2`$B`24V>T7IK8^-`+O!&@]Q0='(D8AWO*`,F
+MFH^/38@B```I2"RN00:%/*1`$KG(18KQD7[T'@`&0(<VP,&2F#OE)TVG3$6L
+ML8TV*F5!.H<!!Q3@!$),T0)6N:LES,"5>X3B'P,YR#7,()>(5&3R?.E()CA`
+M10$AIC$)``!D.D"9^!R@Z!CQS%%*DR#*3&4`MID%.W:3!N`4'"QE2<MRT@"=
+MNU0G01@YT5\R`0('HN>0Z#G,8AZS>??4YS*I)U)']%,@I(2C!`5*4(,JL08)
+M#<!"QUG++-8`H@'AY3H;N;Q'1N!`0V*1CB8IPC+8LY,QY&0`,IG4@/)3E"C]
+MYT"H:4ULLI2;2K1!3&<Z2W+:T@8X!8!.)\K.GEX4GATU)HOH:<]\HG&D0DR;
+M7#,RNY^)2)AP^UX0Q=<[/0*OD/(+"/V^R%/['56";K4>`&8'3:KAU7MFY.O=
+M`F"^X,6O>(WC65D-"U(S)I:`<PVM:$=+VM):A$^*5``5#D%9*20!"E_`U+0@
+MA80B@`!#0UC";9-`A"/8=E=UDL*M@B`JVT(!0Y$:%!-`<-PG6(&W<2I8%:``
+M!4)1H4V2JNX4DH"%-KW)MG*BDYT*9B?B4B$)0\@;G((P!=L.R@E4",(0KALT
+M6S&W"D+0U11JVR<C2"IO@DJ"FX8`J20\P0D%`Y5P.P6A]AH7O_KEKYCV!%\!
+M)X%/8D+P<9/0A"-F`016>`(3JM`$V^[)5JZ%0J3Z*ZGWQG>^&?:O%#I\W@.[
+MP+0XSK&.=QPS-)2!#6QX@P)X3.0B&_G(2$ZRDI?,Y"8[^<E0CK*4ITSE*EOY
+MREC.LI:WS.4N>_G+8`ZSF,=,YC*;^<QH3K.:U\SF-KOYS7".LYSG3.<ZV_G.
+M>,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8
+MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC.
+MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV
+MMK?-[6Y[^]O@#K>XQTWN<IO[W.A.M[K7S>YVN_O=\(ZWO.=-[WK;^][XSK>^
+M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W
+MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/N<QG3O.:V_SF.,^YSG?.
+M\Y[[_.=`#[K0AT[THAO]Z$A/NM*7SO2F._WI4(^ZU*=.]:I;_>I8S[K6M\[U
+MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O<YT[WNMO][GC/N][WSO>^
+M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^<Y[
+M_O.@#[WH1T_ZTIO^]*A/O>I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^
+M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[
+MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\`
+M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($<V($>
+M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\
+MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5:
+MN(5<V(5>^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X
+MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6
+M>(F8F(F:N(F<V(F>^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT
+M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2
+M.(W46(W6>(W8F(W:N(W<V(W>^(W@&([B.([D6([F>([HF([JN([LV([N^([P
+M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`.
+M^9`0&9$2.9$469$6>9$8F9$:N9$<V9$>^9$@&9(B.9(D69(F>9(HF9(JN9(L
+MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91*
+MN91,V91.^910&952.9546956>958F95:N95<V95>^95@&99B.99D699F>99H
+MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B&
+M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F<V9F>^9F@&9JB.9JD
+M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S"
+M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W<V9W>^9W@
+M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^
+M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$<
+MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z
+MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58
+MFJ5:NJ5<VJ5>^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V
+M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4
+M6JF6>JF8FJF:NJF<VJF>^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR
+M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0
+M&JW2.JW46JW6>JW8FJW:NJW<VJW>^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N
+M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`,
+MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$<V[$>^[$@&[(B.[(D6[(F>[(HF[(J
+MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1(
+MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5<V[5>^[5@&[9B.[9D6[9F
+M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$
+M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F<V[F>^[F@&[JB
+M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O`
+M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W<V[W>
+M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\
+MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$:
+MO,$<W,$>_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X
+MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56
+M?,58G,5:O,5<W,5>_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T
+M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2
+M/,F47,F6?,F8G,F:O,F<W,F>_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP
+M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S.
+M_,S0',W2/,W47,W6?,W8G,W:O,W<W,W>_,W@',[B/,[D7,[F?,[HG,[JO,[L
+MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`*
+MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$<W=$>_=$@'=(B/=(D7=(F?=(H
+MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1&
+M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5<W=5>_=5@'=9B/=9D
+M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B"
+M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F<W=F>_=F@
+M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^
+M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W<
+MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z
+MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8
+MGN$:ON$<WN$>_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V
+M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54
+M7N56?N58GN5:ON5<WN5>_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R
+M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0
+M'NF2/NF47NF6?NF8GNF:ONF<WNF>_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN
+M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS,
+MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW<WNW>_NW@'N[B/N[D7N[F?N[HGN[J
+MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`(
+MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$<W_$>__$@'_(B/_(D7_(F
+M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$
+M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5<W_5>__5@'_9B
+M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>`
+M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F<W_F>
+M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\
+MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W:
+MO_W<W_W>__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X
+MG__ZO__\W__^__\`,``*P`%(``N@`3R`"#`!*L`%R``;H`-\@!`P`DK`"4@!
+M*Z`%O(`8,`-JP`W(`3N@!_R`(#`$BL`12`)+H`D\@2@P!:K`%<@"6Z`+?($P
+M,`;*P!E(`VN@#;R!.#`'ZL`=R`-[H`_\@4`P"`K!(4@$BZ`1/()(,`DJP27(
+M!)N@$WR"4#`*2L$I2`6KH!6\@E@P"VK!+<@%NZ`7_()@,`R*P3%(!LN@&3R#
+M:#`-JL$UR`;;H!M\@W`P#LK!.4@'ZZ`=O(-X,`_JP3W(!_N@'_R#@#`0"L)!
+M2`@+H2$\A(@P$2K"1<@(&Z$C?(20,!)*PDE("2NA);R$F#`3:L)-R`D[H2?\
+MA*`P%(K"44@*2Z$I/(6H,!6JPE7("ENA*WR%L#`6RL)92`MKH2V\A;@P%^K"
+M7<@+>Z$O_(7`,!@*PV%(#(NA,3R&R#`9*L-ER`R;H3-\AM`P&DK#:4@-JZ$U
+MO(;8,!MJPVW(#;NA-_R&X#`<BL-Q2`[+H3D\A^@P':K#=<@.VZ$[?(?P,![*
+MPWE(#^NA/;R'^#`?ZL-]R`_[H3_\AP`Q(`K$@4@0"Z)!/(@(,2$JQ(7($!NB
+M0WR($#$B2L2)2!$KHD6\B!@Q(VK$C<@1.Z)'_(@@,22*Q)%($DNB23R)*#$E
+MJL25R!);HDM\B3`Q)LK$F4@3:Z)-O(DX,2?JQ)W($WNB3_R)0#$H"L6A2!2+
+MHE$\BD@Q*2K%I<@4FZ)3?(I0,2I*Q:E(%:NB5;R*6#$K:L6MR!6[HE?\BF`Q
+M+(K%L4@6RZ)9/(MH,2VJQ;7(%MNB6WR+<#$NRL6Y2!?KHEV\BW@Q+^K%O<@7
+M^Z)?_(N`,3`*QL%(&`NC83R,B#$Q*L;%R!@;HV-\C)`Q,DK&R4@9*Z-EO(R8
+M,3-JQLW(&3NC9_R,H#$TBL;12!I+HVD\C:@Q-:K&U<@:6Z-K?(VP,3;*QME(
+M&VNC;;R-N#$WZL;=R!M[HV_\C<`Q.`K'X4@<BZ-Q/([(,3DJQ^7(')NC<WR.
+MT#$Z2L?I2!VKHW6\CM@Q.VK'[<@=NZ-W_([@,3R*Q_%('LNC>3R/Z#$]JL?U
+MR![;HWM\C_`Q/LK'^4@?ZZ-]O(_X,3_JQ_W('_NC?_R/`#)`"L@!22`+I($\
+MD`@R02K(!<D@&Z2#?)`0,D)*R`E)(2NDA;R0&#)#:L@-R2$[I(?\D"`R1(K(
+M$4DB2Z2)/)$H,D6JR!7)(ENDBWR1,#)&RL@922-KI(V\D3@R1^K('<DC>Z2/
+M_)%`,D@*R2%))(NDD3R22#))*LDER22;I)-\DE`R2DK)*4DEJZ25O))8,DMJ
+MR2W));NDE_R28#),BLDQ22;+I)D\DV@R3:K)-<DFVZ2;?)-P,D[*R3E))^ND
+MG;R3>#)/ZLD]R2?[I)_\DX`R4`K*04DH"Z6A/)2(,E$JRD7)*!NEHWR4D#)2
+M2LI)22DKI:6\E)@R4VK*3<DI.Z6G_)2@,E2*RE%)*DNEJ3R5J#)5JLI5R2I;
+MI:M\E;`R5LK*64DK:Z6MO)6X,E?JREW)*WNEK_R5P#)8"LMA22R+I;$\EL@R
+M62K+9<DLFZ6S?);0,EI*RVE)+:NEM;R6V#);:LMMR2V[I;?\EN`R7(K+<4DN
+MRZ6Y/)?H,EVJRW7)+MNENWR7\#)>RLMY22_KI;V\E_@R7^K+?<DO^Z6__)<`
+M,V`*S(%),`NFP3R8"#-A*LR%R3`;IL-\F!`S8DK,B4DQ*Z;%O)@8,V-JS(W)
+M,3NFQ_R8(#-DBLR123)+ILD\F2@S9:K,E<DR6Z;+?)DP,V;*S)E),VNFS;R9
+M.#-GZLR=R3-[IL_\F4`S:`K-H4DTBZ;1/)I(,VDJS:7)-)NFTWR:4#-J2LVI
+M236KIM6\FE@S:VK-K<DUNZ;7_)I@,VR*S;%)-LNFV3R;:#-MJLVUR3;;IMM\
+MFW`S;LK-N4DWZZ;=O)MX,V_JS;W)-_NFW_R;@#-P"L[!23@+I^$\G(@S<2K.
+MQ<DX&Z?C?)R0,W)*SLE).2NGY;R<F#-S:L[-R3D[I^?\G*`S=(K.T4DZ2Z?I
+M/)VH,W6JSM7).ENGZWR=L#-VRL[923MKI^V\G;@S=^K.W<D[>Z?O_)W`,W@*
+MS^%)/(NG\3R>R#-Y*L_ER3R;I_-\GM`S>DK/Z4D]JZ?UO)[8,WMJS^W)/;NG
+M]_R>X#-\BL_Q23[+I_D\G^@S?:K/]<D^VZ?[?)_P,W[*S_E)/^NG_;R?^#-_
+MZL_]R3_[I__\GP`T@`K0`4I`"Z@!/:`(-($JT`7*0!NH`WV@$#2"2M`)2D$K
+MJ`6]H!@T@VK0#<I!.Z@'_:`@-(2*T!%*0DNH"3VA*#2%JM`5RD);J`M]H3`T
+MALK0&4I#:Z@-O:$X-(?JT!W*0WNH#_VA0#2("M$A2D2+J!$]HD@TB2K1)<I$
+MFZ@3?:)0-(I*T2E*1:NH%;VB6#2+:M$MRD6[J!?]HF`TC(K1,4I&RZ@9/:-H
+M-(VJT37*1MNH&WVC<#2.RM$Y2D?KJ!V]HW@TC^K1/<I'^Z@?_:.`-)`*TD%*
+M2`NI(3VDB#21*M)%RD@;J2-]I)`TDDK224I)*ZDEO:28-)-JTDW*23NI)_VD
+MH#24BM)12DI+J2D]I:@TE:K25<I*6ZDK?:6P-);*TEE*2VNI+;VEN#27ZM)=
+MRDM[J2_]I<`TF`K384I,BZDQ/:;(-)DJTV7*3)NI,WVFT#2:2M-I2DVKJ36]
+MIM@TFVK3;<I-NZDW_:;@-)R*TW%*3LNI.3VGZ#2=JM-URD[;J3M]I_`TGLK3
+M>4I/ZZD]O:?X-)_JTWW*3_NI/_VG`#6@"M2!2E`+JD$]J`@UH2K4A<I0&ZI#
+M?:@0-:)*U(E*42NJ1;VH&#6C:M2-RE$[JD?]J"`UI(K4D4I22ZI)/:DH-:6J
+MU)7*4ENJ2WVI,#6FRM292E-KJDV]J3@UI^K4G<I3>ZI/_:E`-:@*U:%*5(NJ
+M43VJ2#6I*M6ERE2;JE-]JE`UJDK5J4I5JZI5O:I8-:MJU:W*5;NJ5_VJ8#6L
+MBM6Q2E;+JED]JV@UK:K5M<I6VZI;?:MP-:[*U;E*5^NJ7;VK>#6OZM6]RE?[
+MJE_]JX`UL`K6P4I8"ZMA/:R(-;$JUL7*6!NK8WVLD#6R2M;)2EDKJV6]K)@U
+MLVK6S<I9.ZMG_:R@-;2*UM%*6DNK:3VMJ#6UJM;5REI;JVM]K;`UMLK6V4I;
+M:ZMMO:VX-;?JUMW*6WNK;_VMP#6X"M?A2ER+JW$]KL@UN2K7Y<I<FZMS?:[0
+M-;I*U^E*7:NK=;VNV#6[:M?MREV[JW?]KN`UO(K7\4I>RZMY/:_H-;VJU_7*
+M7MNK>WVO\#6^RM?Y2E_KJWV]K_@UO^K7_<I?^ZM__:\`-L`*V`%+8`NL@3VP
+M"#;!*M@%RV`;K(-]L!`VPDK8"4MA*ZR%O;`8-L-JV`W+83NLA_VP(#;$BM@1
+M2V)+K(D]L2@VQ:K8%<MB6ZR+?;$P-L;*V!E+8VNLC;VQ.#;'ZM@=RV-[K(_]
+ML4`VR`K9(4MDBZR1/;)(-LDJV27+9)NLDWVR4#;*2MDI2V6KK)6]LE@VRVK9
+M+<MENZR7_;)@-LR*V3%+9LNLF3VS:#;-JMDURV;;K)M]LW`VSLK9.4MGZZR=
+MO;-X-L_JV3W+9_NLG_VS@#;0"MI!2V@+K:$]M(@VT2K:1<MH&ZVC?;20-M)*
+MVDE+:2NMI;VTF#;3:MI-RVD[K:?]M*`VU(K:44MJ2ZVI/;6H-M6JVE7+:ENM
+MJWVUL#;6RMI92VMKK:V]M;@VU^K:7<MK>ZVO_;7`-M@*VV%+;(NML3VVR#;9
+M*MMERVR;K;-]MM`VVDK;:4MMJZVUO;;8-MMJVVW+;;NMM_VVX#;<BMMQ2V[+
+MK;D]M^@VW:K;=<MNVZV[?;?P-M[*VWE+;^NMO;VW^#;?ZMM]RV_[K;_]MP`W
+MX`K<@4MP"Z[!/;@(-^$JW(7+<!NNPWVX$#?B2MR)2W$KKL6]N!@WXVK<C<MQ
+M.Z['_;@@-^2*W)%+<DNNR3VY*#?EJMR5RW);KLM]N3`WYLK<F4MS:Z[-O;DX
+M-^?JW)W+<WNNS_VY0#?H"MVA2W2+KM$]ND@WZ2K=I<MTFZ[3?;I0-^I*W:E+
+M=:NNU;VZ6#?K:MVMRW6[KM?]NF`W[(K=L4MVRZ[9/;MH-^VJW;7+=MNNVWV[
+M<#?NRMVY2W?KKMV]NW@W[^K=O<MW^Z[?_;N`-_`*WL%+>`NOX3V\B#?Q*M[%
+MRW@;K^-]O)`W\DK>R4MY*Z_EO;R8-_-JWLW+>3NOY_V\H#?TBM[12WI+K^D]
+MO:@W]:K>U<MZ6Z_K?;VP-_;*WME+>VNO[;V]N#?WZM[=RWM[K^_]O<`W^`K?
+MX4M\BZ_Q/;[(-_DJW^7+?)NO\WV^T#?Z2M_I2WVKK_6]OM@W^VK?[<M]NZ_W
+M_;[@-_R*W_%+?LNO^3V_Z#?]JM_URW[;K_M]O_`W_LK?^4M_ZZ_]O;_X-__J
+MW_W+?_NO__V_`#@`"^`!3(`+L`$^P`@X`2O@!<R`&[`#?L`0.`)+X`E,@2NP
+M!;[`&#@#:^`-S($[L`?^P"`X!(O@$4R"2[`)/L$H.`6KX!7,@ENP"W[!,#@&
+MR^`93(-KL`V^P3@X!^O@'<R#>[`/_L%`.`@+X2%,A(NP$3["2#@)*^$ES(2;
+ML!-^PE`X"DOA*4R%J[`5OL)8.`MKX2W,A;NP%_["8#@,B^$Q3(;+L!D^PV@X
+M#:OA-<R&V[`;?L-P.`[+X3E,A^NP';[#>#@/Z^$]S(?[L!_^PX`X$`OB04R(
+M"[$A/L2(.!$KXD7,B!NQ(W[$D#@22^))3(DKL26^Q)@X$VOB3<R).[$G_L2@
+M.!2+XE%,BDNQ*3[%J#@5J^)5S(I;L2M^Q;`X%LOB64R+:[$MOL6X.!?KXO`+
+`
+end
diff --git a/lib/libarchive/test/test_read_format_iso_rockridge_ce.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_rockridge_ce.iso.Z.uu
new file mode 100644
index 0000000..818bb0e
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_rockridge_ce.iso.Z.uu
@@ -0,0 +1,63 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso_rockridge_ce.iso.Z
+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
+(>(F8F(F:^!,`
+`
+end
diff --git a/lib/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu
new file mode 100644
index 0000000..dd013ff
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu
@@ -0,0 +1,208 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso_rockridge_new.iso.Z
+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
+M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`.
+M^9`0&9$2.9$469$6>9$8F9$:N9$<V9$>^9$@&9(B.9(D69(F>9(HF9(JN9(L
+MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91*
+MN91,V91.^910&952.9546956>958F95:N95<V95>^95@&99B.99D699F>99H
+MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B&
+M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F<V9F>^9F@&9JB.9JD
+M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S"
+M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W<V9W>^9W@
+M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^
+M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$<
+MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z
+MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58
+MFJ5:NJ5<VJ5>^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V
+M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4
+M6JF6>JF8FJF:NJF<VJF>^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR
+M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0
+M&JW2.JW46JW6>JW8FJW:NJW<VJW>^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N
+M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`,
+MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$<V[$>^[$@&[(B.[(D6[(F>[(HF[(J
+MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1(
+MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5<V[5>^[5@&[9B.[9D6[9F
+M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$
+M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F<V[F>^[F@&[JB
+M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O`
+M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W<V[W>
+M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\
+MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$:
+MO,$<W,$>_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X
+MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56
+M?,58G,5:O,5<W,5>_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T
+M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2
+M/,F47,F6?,F8G,F:O,F<W,F>_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP
+M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S.
+M_,S0',W2/,W47,W6?,W8G,W:O,W<W,W>_,W@',[B/,[D7,[F?,[HG,[JO,[L
+MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`*
+MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$<W=$>_=$@'=(B/=(D7=(F?=(H
+MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1&
+M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5<W=5>_=5@'=9B/=9D
+M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B"
+M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F<W=F>_=F@
+M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^
+M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W<
+MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z
+MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8
+MGN$:ON$<WN$>_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V
+M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54
+M7N56?N58GN5:ON5<WN5>_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R
+M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0
+M'NF2/NF47NF6?NF8GNF:ONF<WNF>_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN
+M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS,
+MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW<WNW>_NW@'N[B/N[D7N[F?N[HGN[J
+MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`(
+MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$<W_$>__$@'_(B/_(D7_(F
+M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$
+M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5<W_5>__5@'_9B
+M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>`
+M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F<W_F>
+M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\
+MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W:
+MO_W<W_W>__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X
+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
+DV#@;:^-MS(V[L3?^QN`X'(OC<4R.R[$Y/L?H.!VKXW7,CKDM
+`
+end
diff --git a/lib/libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu
new file mode 100644
index 0000000..69de12b
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu
@@ -0,0 +1,304 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso_rockridge_rr_moved.iso.Z
+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
+M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`.
+M^9`0&9$2.9$469$6>9$8F9$:N9$<V9$>^9$@&9(B.9(D69(F>9(HF9(JN9(L
+MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91*
+MN91,V91.^910&952.9546956>958F95:N95<V95>^95@&99B.99D699F>99H
+MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B&
+M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F<V9F>^9F@&9JB.9JD
+M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S"
+M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W<V9W>^9W@
+M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^
+M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$<
+MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z
+MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58
+MFJ5:NJ5<VJ5>^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V
+M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4
+M6JF6>JF8FJF:NJF<VJF>^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR
+M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0
+M&JW2.JW46JW6>JW8FJW:NJW<VJW>^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N
+M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`,
+MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$<V[$>^[$@&[(B.[(D6[(F>[(HF[(J
+MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1(
+MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5<V[5>^[5@&[9B.[9D6[9F
+M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$
+M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F<V[F>^[F@&[JB
+M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O`
+M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W<V[W>
+M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\
+MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$:
+MO,$<W,$>_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X
+MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56
+M?,58G,5:O,5<W,5>_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T
+M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2
+M/,F47,F6?,F8G,F:O,F<W,F>_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP
+M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S.
+M_,S0',W2/,W47,W6?,W8G,W:O,W<W,W>_,W@',[B/,[D7,[F?,[HG,[JO,[L
+MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`*
+MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$<W=$>_=$@'=(B/=(D7=(F?=(H
+MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1&
+M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5<W=5>_=5@'=9B/=9D
+M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B"
+M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F<W=F>_=F@
+M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^
+M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W<
+MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z
+MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8
+MGN$:ON$<WN$>_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V
+M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54
+M7N56?N58GN5:ON5<WN5>_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R
+M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0
+M'NF2/NF47NF6?NF8GNF:ONF<WNF>_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN
+M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS,
+MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW<WNW>_NW@'N[B/N[D7N[F?N[HGN[J
+MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`(
+MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$<W_$>__$@'_(B/_(D7_(F
+M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$
+M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5<W_5>__5@'_9B
+M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>`
+M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F<W_F>
+M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\
+MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W:
+MO_W<W_W>__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X
+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
+'BP!CP+@7`0``
+`
+end
diff --git a/lib/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu
new file mode 100644
index 0000000..00896e1
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu
@@ -0,0 +1,63 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso_zisofs.iso.Z
+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
+@>(F8F(F:N(F<V(F>^(F@&(JB.(JD6(JF>(JHF(JJN'``
+`
+end
diff --git a/lib/libarchive/test/test_read_format_isojoliet_bz2.c b/lib/libarchive/test/test_read_format_isojoliet_bz2.c
index 9ee87c9..b2f22a7 100644
--- a/lib/libarchive/test/test_read_format_isojoliet_bz2.c
+++ b/lib/libarchive/test/test_read_format_isojoliet_bz2.c
@@ -46,49 +46,39 @@ else
TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/long-joliet-file-name.textfile /tmp/iso/dir
TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink
fi
-mkhybrid -J -uid 1 -gid 2 /tmp/iso | bzip2 > test_read_format_isojoliet_bz2.iso.bz2
-F=test_read_format_isojoliet_bz2.iso.bz2
+F=test_read_format_iso_joliet.iso.Z
+mkhybrid -J -uid 1 -gid 2 /tmp/iso | compress > $F
uuencode $F $F > $F.uu
exit 1
*/
-static void
-joliettest(int withrr)
+DEFINE_TEST(test_read_format_isojoliet_bz2)
{
- const char *refname = "test_read_format_isojoliet_bz2.iso.bz2";
+ const char *refname = "test_read_format_iso_joliet.iso.Z";
struct archive_entry *ae;
struct archive *a;
const void *p;
size_t size;
off_t offset;
- int r;
-
- if (withrr) {
- refname = "test_read_format_isojolietrr_bz2.iso.bz2";
- }
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- r = archive_read_support_compression_bzip2(a);
- if (r == ARCHIVE_WARN) {
- skipping("bzip2 reading not fully supported on this platform");
- assertEqualInt(0, archive_read_finish(a));
- return;
- }
- assertEqualInt(0, r);
+ assertEqualInt(0, archive_read_support_compression_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
+ archive_read_set_options(a, "iso9660:!rockridge"));
+ assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
/* First entry is '.' root directory. */
assertEqualInt(0, archive_read_next_header(a, &ae));
assertEqualString(".", archive_entry_pathname(ae));
- assert(S_ISDIR(archive_entry_stat(ae)->st_mode));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
assertEqualInt(2048, archive_entry_size(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(0, archive_entry_mtime_nsec(ae));
assertEqualInt(86401, archive_entry_ctime(ae));
- assertEqualInt(0, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
assertEqualInt(0, archive_entry_uid(ae));
assertEqualIntA(a, ARCHIVE_EOF,
archive_read_data_block(a, &p, &size, &offset));
@@ -97,100 +87,48 @@ joliettest(int withrr)
/* A directory. */
assertEqualInt(0, archive_read_next_header(a, &ae));
assertEqualString("dir", archive_entry_pathname(ae));
- assert(S_ISDIR(archive_entry_stat(ae)->st_mode));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
assertEqualInt(2048, archive_entry_size(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(86401, archive_entry_atime(ae));
- if (withrr) {
- assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
- assertEqualInt(1, archive_entry_uid(ae));
- assertEqualInt(2, archive_entry_gid(ae));
- }
/* A regular file with two names ("hardlink" gets returned
* first, so it's not marked as a hardlink). */
assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString("hardlink", archive_entry_pathname(ae));
- assert(S_ISREG(archive_entry_stat(ae)->st_mode));
+ assertEqualString("long-joliet-file-name.textfile",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assert(archive_entry_hardlink(ae) == NULL);
assertEqualInt(6, archive_entry_size(ae));
assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset));
assertEqualInt(6, (int)size);
assertEqualInt(0, offset);
assertEqualInt(0, memcmp(p, "hello\n", 6));
- if (withrr) {
- assertEqualInt(86401, archive_entry_mtime(ae));
- assertEqualInt(86401, archive_entry_atime(ae));
- /* TODO: Actually, libarchive should be able to
- * compute nlinks correctly even without RR
- * extensions. See comments in libarchive source. */
- assertEqualInt(2, archive_entry_nlink(ae));
- assertEqualInt(1, archive_entry_uid(ae));
- assertEqualInt(2, archive_entry_gid(ae));
- }
/* Second name for the same regular file (this happens to be
* returned second, so does get marked as a hardlink). */
assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString("hardlink", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assertEqualString("long-joliet-file-name.textfile",
- archive_entry_pathname(ae));
- assert(S_ISREG(archive_entry_stat(ae)->st_mode));
- assertEqualString("hardlink", archive_entry_hardlink(ae));
+ archive_entry_hardlink(ae));
assert(!archive_entry_size_is_set(ae));
- if (withrr) {
- assertEqualInt(86401, archive_entry_mtime(ae));
- assertEqualInt(86401, archive_entry_atime(ae));
- /* TODO: See above. */
- assertEqualInt(2, archive_entry_nlink(ae));
- assertEqualInt(1, archive_entry_uid(ae));
- assertEqualInt(2, archive_entry_gid(ae));
- }
/* A symlink to the regular file. */
assertEqualInt(0, archive_read_next_header(a, &ae));
assertEqualString("symlink", archive_entry_pathname(ae));
- if (withrr) {
- assert(S_ISLNK(archive_entry_stat(ae)->st_mode));
- assertEqualString("long-joliet-file-name.textfile",
- archive_entry_symlink(ae));
- }
assertEqualInt(0, archive_entry_size(ae));
assertEqualInt(172802, archive_entry_mtime(ae));
assertEqualInt(172802, archive_entry_atime(ae));
- if (withrr) {
- assertEqualInt(1, archive_entry_nlink(ae));
- assertEqualInt(1, archive_entry_uid(ae));
- assertEqualInt(2, archive_entry_gid(ae));
- }
/* End of archive. */
assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Verify archive format. */
- assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_BZIP2);
- if (withrr) {
- assertEqualInt(archive_format(a),
- ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
- }
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
/* Close the archive. */
assertEqualInt(0, archive_read_close(a));
assertEqualInt(0, archive_read_finish(a));
}
-
-DEFINE_TEST(test_read_format_isojoliet_bz2)
-{
- joliettest(0);
-
- /* XXXX This doesn't work today; can it be made to work? */
-#if 0
- joliettest(1);
-#else
- skipping("Mixed Joliet/RR not fully supported yet.");
-#endif
-}
-
-
-
-
diff --git a/lib/libarchive/test/test_read_format_isojoliet_long.c b/lib/libarchive/test/test_read_format_isojoliet_long.c
new file mode 100644
index 0000000..acd220f
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_isojoliet_long.c
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * 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$");
+
+/*
+Execute the following to rebuild the data for this program:
+ tail -n +35 test_read_format_isojoliet_long.c | /bin/sh
+
+rm -rf /tmp/iso
+mkdir /tmp/iso
+num=0
+file="";
+while [ $num -lt 100 ]
+do
+ num=$((num+10))
+ file="${file}1234567890"
+done
+dir="${file}dir"
+mkdir /tmp/iso/${dir}
+file="${file}123"
+echo "hello" > /tmp/iso/${file}
+ln /tmp/iso/${file} /tmp/iso/hardlink
+if [ "$(uname -s)" = "Linux" ]; then # gnu coreutils touch doesn't have -h
+TZ=utc touch -afm -t 197001020000.01 /tmp/iso /tmp/iso/${file} /tmp/iso/${dir}
+else
+TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/${file} /tmp/iso/${dir}
+fi
+F=test_read_format_iso_joliet_long.iso.Z
+mkhybrid -J -joliet-long -uid 1 -gid 2 /tmp/iso | compress > $F
+uuencode $F $F > $F.uu
+rm -rf /tmp/iso
+exit 1
+ */
+
+DEFINE_TEST(test_read_format_isojoliet_long)
+{
+ const char *refname = "test_read_format_iso_joliet_long.iso.Z";
+ char pathname[104];
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *p;
+ size_t size;
+ off_t offset;
+ int i;
+
+ for (i = 0; i < 100; i++)
+ pathname[i] = '0' + ((i+1) % 10);
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_format_all(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_set_options(a, "iso9660:!rockridge"));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* First entry is '.' root directory. */
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(86401, archive_entry_ctime(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(0, archive_entry_uid(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+
+ /* A directory. */
+ pathname[100] = 'd';
+ pathname[101] = 'i';
+ pathname[102] = 'r';
+ pathname[103] = '\0';
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString(pathname, archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+
+ /* A regular file with two names (pathname gets returned
+ * first, so it's not marked as a hardlink). */
+ pathname[100] = '1';
+ pathname[101] = '2';
+ pathname[102] = '3';
+ pathname[103] = '\0';
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString(pathname, archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assert(archive_entry_hardlink(ae) == NULL);
+ assertEqualInt(6, archive_entry_size(ae));
+ assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(6, (int)size);
+ assertEqualInt(0, offset);
+ assertEqualInt(0, memcmp(p, "hello\n", 6));
+
+ /* Second name for the same regular file (this happens to be
+ * returned second, so does get marked as a hardlink). */
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString("hardlink", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString(pathname, archive_entry_hardlink(ae));
+ assert(!archive_entry_size_is_set(ae));
+
+ /* End of archive. */
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+
+ /* Close the archive. */
+ assertEqualInt(0, archive_read_close(a));
+ assertEqualInt(0, archive_read_finish(a));
+}
+
diff --git a/lib/libarchive/test/test_read_format_isojoliet_rr.c b/lib/libarchive/test/test_read_format_isojoliet_rr.c
new file mode 100644
index 0000000..394df14
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_isojoliet_rr.c
@@ -0,0 +1,159 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Based on libarchive/test/test_read_format_isorr_bz2.c with
+ * bugs introduced by Andreas Henriksson <andreas@fatal.se> for
+ * testing ISO9660 image with Joliet extension.
+ *
+ * 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$");
+
+/*
+Execute the following to rebuild the data for this program:
+ tail -n +35 test_read_format_isojoliet_rr.c | /bin/sh
+
+rm -rf /tmp/iso
+mkdir /tmp/iso
+mkdir /tmp/iso/dir
+file="long-joliet-file-name.textfile"
+echo "hello" >/tmp/iso/$file
+ln /tmp/iso/$file /tmp/iso/hardlink
+(cd /tmp/iso; ln -s $file symlink)
+if [ "$(uname -s)" = "Linux" ]; then # gnu coreutils touch doesn't have -h
+TZ=utc touch -afm -t 197001020000.01 /tmp/iso/hardlink /tmp/iso/$file /tmp/iso/dir
+TZ=utc touch -afm -t 197001030000.02 /tmp/iso/symlink
+TZ=utc touch -afm -t 197001020000.01 /tmp/iso
+else
+TZ=utc touch -afhm -t 197001020000.01 /tmp/iso/hardlink /tmp/iso/$file /tmp/iso/dir
+TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink
+TZ=utc touch -afhm -t 197001020000.01 /tmp/iso
+fi
+F=test_read_format_iso_joliet_rockridge.iso.Z
+mkhybrid -J -uid 1 -gid 2 /tmp/iso | compress > $F
+uuencode $F $F > $F.uu
+exit 1
+ */
+
+DEFINE_TEST(test_read_format_isojoliet_rr)
+{
+ const char *refname = "test_read_format_iso_joliet_rockridge.iso.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *p;
+ size_t size;
+ off_t offset;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_format_all(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* First entry is '.' root directory. */
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+
+ /* A directory. */
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString("dir", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+
+ /* A regular file with two names ("hardlink" gets returned
+ * first, so it's not marked as a hardlink). */
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString("long-joliet-file-name.textfile",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assert(archive_entry_hardlink(ae) == NULL);
+ assertEqualInt(6, archive_entry_size(ae));
+ assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(6, (int)size);
+ assertEqualInt(0, offset);
+ assertEqualInt(0, memcmp(p, "hello\n", 6));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ /* mkisofs records their access time. */
+ /*assertEqualInt(86401, archive_entry_atime(ae));*/
+ /* TODO: Actually, libarchive should be able to
+ * compute nlinks correctly even without RR
+ * extensions. See comments in libarchive source. */
+ assertEqualInt(2, archive_entry_nlink(ae));
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+
+ /* Second name for the same regular file (this happens to be
+ * returned second, so does get marked as a hardlink). */
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString("hardlink", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("long-joliet-file-name.textfile",
+ archive_entry_hardlink(ae));
+ assert(!archive_entry_size_is_set(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ /* TODO: See above. */
+ assertEqualInt(2, archive_entry_nlink(ae));
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+
+ /* A symlink to the regular file. */
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+ assertEqualString("symlink", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("long-joliet-file-name.textfile",
+ archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(172802, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+
+ /* End of archive. */
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
+
+ /* Close the archive. */
+ assertEqualInt(0, archive_read_close(a));
+ assertEqualInt(0, archive_read_finish(a));
+}
+
diff --git a/lib/libarchive/test/test_read_format_isorr_bz2.c b/lib/libarchive/test/test_read_format_isorr_bz2.c
index 250019f..730c112 100644
--- a/lib/libarchive/test/test_read_format_isorr_bz2.c
+++ b/lib/libarchive/test/test_read_format_isorr_bz2.c
@@ -26,124 +26,178 @@
__FBSDID("$FreeBSD$");
/*
+PLEASE use old cdrtools; mkisofs verion is 2.01.
+This version mkisofs made wrong "SL" System Use Entry of RRIP.
+
Execute the following command to rebuild the data for this program:
- tail -n +32 test_read_format_isorr_bz2.c | /bin/sh
+ tail -n +34 test_read_format_isorr_bz2.c | /bin/sh
rm -rf /tmp/iso
mkdir /tmp/iso
mkdir /tmp/iso/dir
echo "hello" >/tmp/iso/file
-dd if=/dev/zero bs=1 count=12345678 >>/tmp/iso/file
+dd if=/dev/zero count=1 bs=12345678 >>/tmp/iso/file
ln /tmp/iso/file /tmp/iso/hardlink
(cd /tmp/iso; ln -s file symlink)
+(cd /tmp/iso; ln -s /tmp/ symlink2)
+(cd /tmp/iso; ln -s /tmp/../ symlink3)
+(cd /tmp/iso; ln -s .././../tmp/ symlink4)
+(cd /tmp/iso; ln -s .///file symlink5)
+(cd /tmp/iso; ln -s /tmp//../ symlink6)
TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir
-TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink
-mkhybrid -R -uid 1 -gid 2 /tmp/iso | bzip2 > test_read_format_isorr_bz2.iso.bz2
-F=test_read_format_isorr_bz2.iso.bz2
+TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink /tmp/iso/symlink5
+F=test_read_format_iso_rockridge.iso.Z
+mkhybrid -R -uid 1 -gid 2 /tmp/iso | compress > $F
uuencode $F $F > $F.uu
exit 1
*/
DEFINE_TEST(test_read_format_isorr_bz2)
{
- const char *refname = "test_read_format_isorr_bz2.iso.bz2";
+ const char *refname = "test_read_format_iso_rockridge.iso.Z";
struct archive_entry *ae;
struct archive *a;
const void *p;
size_t size;
off_t offset;
- int r;
+ int i;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
- r = archive_read_support_compression_bzip2(a);
- if (r == ARCHIVE_WARN) {
- skipping("bzip2 reading not fully supported on this platform");
- assertEqualInt(0, archive_read_finish(a));
- return;
- }
- assertEqualInt(0, r);
+ assertEqualInt(0, archive_read_support_compression_all(a));
assertEqualInt(0, archive_read_support_format_all(a));
assertEqualInt(ARCHIVE_OK,
archive_read_open_filename(a, refname, 10240));
- /* First entry is '.' root directory. */
- assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString(".", archive_entry_pathname(ae));
- assert(S_ISDIR(archive_entry_stat(ae)->st_mode));
- assertEqualInt(2048, archive_entry_size(ae));
- assertEqualInt(86401, archive_entry_mtime(ae));
- assertEqualInt(0, archive_entry_mtime_nsec(ae));
- assertEqualInt(86401, archive_entry_ctime(ae));
- assertEqualInt(0, archive_entry_stat(ae)->st_nlink);
- assertEqualInt(0, archive_entry_uid(ae));
- assertEqualIntA(a, ARCHIVE_EOF,
- archive_read_data_block(a, &p, &size, &offset));
- assertEqualInt((int)size, 0);
-
- /* A directory. */
- assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString("dir", archive_entry_pathname(ae));
- assert(S_ISDIR(archive_entry_stat(ae)->st_mode));
- assertEqualInt(2048, archive_entry_size(ae));
- assertEqualInt(86401, archive_entry_mtime(ae));
- assertEqualInt(86401, archive_entry_atime(ae));
- assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
- assertEqualInt(1, archive_entry_uid(ae));
- assertEqualInt(2, archive_entry_gid(ae));
+ /* Retrieve each of the 8 files on the ISO image and
+ * verify that each one is what we expect. */
+ for (i = 0; i < 10; ++i) {
+ assertEqualInt(0, archive_read_next_header(a, &ae));
- /* A regular file. */
- assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString("file", archive_entry_pathname(ae));
- assert(S_ISREG(archive_entry_stat(ae)->st_mode));
- assertEqualInt(12345684, archive_entry_size(ae));
- assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset));
- assertEqualInt(0, offset);
- assertEqualMem(p, "hello\n", 6);
- assertEqualInt(86401, archive_entry_mtime(ae));
- assertEqualInt(86401, archive_entry_atime(ae));
- assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
- assertEqualInt(1, archive_entry_uid(ae));
- assertEqualInt(2, archive_entry_gid(ae));
-
- /* A hardlink to the regular file. */
- assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString("hardlink", archive_entry_pathname(ae));
- assert(S_ISREG(archive_entry_stat(ae)->st_mode));
- assertEqualString("file", archive_entry_hardlink(ae));
- assert(!archive_entry_size_is_set(ae));
- assertEqualInt(86401, archive_entry_mtime(ae));
- assertEqualInt(86401, archive_entry_atime(ae));
- assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
- assertEqualInt(1, archive_entry_uid(ae));
- assertEqualInt(2, archive_entry_gid(ae));
-
- /* A symlink to the regular file. */
- assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString("symlink", archive_entry_pathname(ae));
- assert(S_ISLNK(archive_entry_stat(ae)->st_mode));
- assertEqualString("file", archive_entry_symlink(ae));
- assertEqualInt(0, archive_entry_size(ae));
- assertEqualInt(172802, archive_entry_mtime(ae));
- assertEqualInt(172802, archive_entry_atime(ae));
- assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
- assertEqualInt(1, archive_entry_uid(ae));
- assertEqualInt(2, archive_entry_gid(ae));
+ if (strcmp(".", archive_entry_pathname(ae)) == 0) {
+ /* '.' root directory. */
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ /* Now, we read timestamp recorded by RRIP "TF". */
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ /* Now, we read links recorded by RRIP "PX". */
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualString("hardlink", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(12345684, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello\n", 6);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
+ /* A hardlink to the regular file. */
+ /* Note: If "hardlink" gets returned before "file",
+ * then "hardlink" will get returned as a regular file
+ * and "file" will get returned as the hardlink.
+ * This test should tolerate that, since it's a
+ * perfectly permissible thing for libarchive to do. */
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("hardlink", archive_entry_hardlink(ae));
+ assertEqualInt(0, archive_entry_size_is_set(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to the regular file. */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("file", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(172802, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink2", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to /tmp (an absolute path) */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("/tmp", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink3", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to /tmp/.. (with a ".." component) */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("/tmp/..", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink4", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to a path with ".." and "." components */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString(".././../tmp",
+ archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink5", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to the regular file with "/" components. */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString(".///file", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(172802, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink6", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to /tmp//..
+ * (with "/" and ".." components) */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("/tmp//..", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else {
+ failure("Saw a file that shouldn't have been there");
+ assertEqualString(archive_entry_pathname(ae), "");
+ }
+ }
/* End of archive. */
assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Verify archive format. */
- assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_BZIP2);
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
/* Close the archive. */
assertEqualInt(0, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
assertEqualInt(0, archive_read_finish(a));
-#endif
}
diff --git a/lib/libarchive/test/test_read_format_isorr_ce.c b/lib/libarchive/test/test_read_format_isorr_ce.c
new file mode 100644
index 0000000..c9cd059
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_isorr_ce.c
@@ -0,0 +1,223 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * 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$");
+
+/*
+Execute the following command to rebuild the data for this program:
+ tail -n +32 test_read_format_isorr_ce.c | /bin/sh
+
+dirname=/tmp/iso
+#
+rm -rf $dirname
+mkdir $dirname
+#
+num=0
+file=""
+while [ $num -lt 150 ]
+do
+ num=$((num+1))
+ file="a$file"
+done
+#
+num=0
+while [ $num -lt 3 ]
+do
+ num=$((num+1))
+ file="a$file"
+ echo "hello $((num+150))" > $dirname/$file
+ dd if=/dev/zero count=1 bs=4080 >> $dirname/$file
+ (cd $dirname; ln -s $file sym$num)
+done
+#
+mkdir $dirname/dir
+#
+time1="197001020000.01"
+time2="197001030000.02"
+TZ=utc touch -afhm -t $time1 $dirname/dir $dirname/aaaa*
+TZ=utc touch -afhm -t $time2 $dirname/sym*
+TZ=utc touch -afhm -t $time1 $dirname
+#
+F=test_read_format_iso_rockridge_ce.iso.Z
+mkisofs -R -uid 1 -gid 2 $dirname | compress > $F
+uuencode $F $F > $F.uu
+rm -rf $dirname
+exit 1
+ */
+
+/*
+ * Test reading SUSP "CE" extension is works fine.
+ */
+
+static void
+mkpath(char *p, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ p[i] = 'a';
+ p[len] = '\0';
+}
+
+DEFINE_TEST(test_read_format_isorr_ce)
+{
+ const char *refname = "test_read_format_iso_rockridge_ce.iso.Z";
+ char path1[160];
+ char path2[160];
+ char path3[160];
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *p;
+ size_t size;
+ off_t offset;
+ int i;
+
+ mkpath(path1, 151);
+ mkpath(path2, 152);
+ mkpath(path3, 153);
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_format_all(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Retrieve each of the 8 files on the ISO image and
+ * verify that each one is what we expect. */
+ for (i = 0; i < 8; ++i) {
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+
+ if (strcmp(".", archive_entry_pathname(ae)) == 0) {
+ /* '.' root directory. */
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ /* Now, we read timestamp recorded by RRIP "TF". */
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ /* Now, we read links recorded by RRIP "PX". */
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp(path1, archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualString(path1, archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(4090, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello 151\n", 10);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp(path2, archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualString(path2, archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(4090, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello 152\n", 10);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp(path3, archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualString(path3, archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(4090, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello 153\n", 10);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("sym1", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to the regular file. */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString(path1, archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("sym2", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to the regular file. */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString(path2, archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("sym3", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to the regular file. */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString(path3, archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else {
+ failure("Saw a file that shouldn't have been there");
+ assertEqualString(archive_entry_pathname(ae), "");
+ }
+ }
+
+ /* End of archive. */
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
+
+ /* Close the archive. */
+ assertEqualInt(0, archive_read_close(a));
+ assertEqualInt(0, archive_read_finish(a));
+}
+
+
diff --git a/lib/libarchive/test/test_read_format_isorr_new_bz2.c b/lib/libarchive/test/test_read_format_isorr_new_bz2.c
new file mode 100644
index 0000000..5fa2492
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_isorr_new_bz2.c
@@ -0,0 +1,204 @@
+/*-
+ * 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$");
+
+
+/*
+PLEASE use latest cdrtools at least mkisofs version is 2.01.01a63 or later.
+Old version mkisofs made wrong "SL" System Use Entry of RRIP.
+
+Execute the following command to rebuild the data for this program:
+ tail -n +34 test_read_format_isorr_new_bz2.c | /bin/sh
+
+rm -rf /tmp/iso
+mkdir /tmp/iso
+mkdir /tmp/iso/dir
+echo "hello" >/tmp/iso/file
+dd if=/dev/zero count=1 bs=12345678 >>/tmp/iso/file
+ln /tmp/iso/file /tmp/iso/hardlink
+(cd /tmp/iso; ln -s file symlink)
+(cd /tmp/iso; ln -s /tmp/ symlink2)
+(cd /tmp/iso; ln -s /tmp/../ symlink3)
+(cd /tmp/iso; ln -s .././../tmp/ symlink4)
+(cd /tmp/iso; ln -s .///file symlink5)
+(cd /tmp/iso; ln -s /tmp//../ symlink6)
+TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir
+TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink
+F=test_read_format_iso_rockridge_new.iso.Z
+mkhybrid -R -uid 1 -gid 2 /tmp/iso | compress > $F
+uuencode $F $F > $F.uu
+exit 1
+ */
+
+DEFINE_TEST(test_read_format_isorr_new_bz2)
+{
+ const char *refname = "test_read_format_iso_rockridge_new.iso.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *p;
+ size_t size;
+ off_t offset;
+ int i;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_format_all(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Retrieve each of the 8 files on the ISO image and
+ * verify that each one is what we expect. */
+ for (i = 0; i < 10; ++i) {
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+
+ if (strcmp(".", archive_entry_pathname(ae)) == 0) {
+ /* '.' root directory. */
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ /* Now, we read timestamp recorded by RRIP "TF". */
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ /* Now, we read links recorded by RRIP "PX". */
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualString("hardlink", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(12345684, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello\n", 6);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
+ /* A hardlink to the regular file. */
+ /* Note: If "hardlink" gets returned before "file",
+ * then "hardlink" will get returned as a regular file
+ * and "file" will get returned as the hardlink.
+ * This test should tolerate that, since it's a
+ * perfectly permissible thing for libarchive to do. */
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("hardlink", archive_entry_hardlink(ae));
+ assertEqualInt(0, archive_entry_size_is_set(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to the regular file. */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("file", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(172802, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink2", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to /tmp/ (an absolute path) */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("/tmp/", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink3", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to /tmp/../ (with a ".." component) */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("/tmp/../", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink4", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to a path with ".." and "." components */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString(".././../tmp/",
+ archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink5", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to the regular file with "/" components. */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString(".///file", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(172802, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink6", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to /tmp//../
+ * (with "/" and ".." components) */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("/tmp//../", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else {
+ failure("Saw a file that shouldn't have been there");
+ assertEqualString(archive_entry_pathname(ae), "");
+ }
+ }
+
+ /* End of archive. */
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
+
+ /* Close the archive. */
+ assertEqualInt(0, archive_read_close(a));
+ assertEqualInt(0, archive_read_finish(a));
+}
+
+
diff --git a/lib/libarchive/test/test_read_format_isorr_rr_moved.c b/lib/libarchive/test/test_read_format_isorr_rr_moved.c
new file mode 100644
index 0000000..0aeb226
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_isorr_rr_moved.c
@@ -0,0 +1,270 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * 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$");
+
+/*
+Execute the following command to rebuild the data for this program:
+ tail -n +32 test_read_format_isorr_rr_moved.c | /bin/sh
+
+dirname=/tmp/iso
+rm -rf $dirname
+mkdir -p $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10
+echo "hello" >$dirname/file
+dd if=/dev/zero count=1 bs=12345678 >>$dirname/file
+deepfile=$dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10/deep
+echo "hello" >$deepfile
+dd if=/dev/zero count=1 bs=12345678 >>$deepfile
+time="197001020000.01"
+TZ=utc touch -afhm -t $time $deepfile
+TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10
+TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9
+TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8
+TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7
+TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6
+TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5
+TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4
+TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3
+TZ=utc touch -afhm -t $time $dirname/dir1/dir2
+TZ=utc touch -afhm -t $time $dirname/dir1
+TZ=utc touch -afhm -t $time $dirname/file
+TZ=utc touch -afhm -t $time $dirname
+F=test_read_format_isorr_rockridge_moved.iso.Z
+mkhybrid -R -uid 1 -gid 2 $dirname | compress > $F
+uuencode $F $F > $F.uu
+exit 1
+ */
+
+DEFINE_TEST(test_read_format_isorr_rr_moved)
+{
+ const char *refname = "test_read_format_iso_rockridge_rr_moved.iso.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *p;
+ size_t size;
+ off_t offset;
+ int i;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_format_all(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Retrieve each of the 8 files on the ISO image and
+ * verify that each one is what we expect. */
+ for (i = 0; i < 13; ++i) {
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+
+ if (strcmp(".", archive_entry_pathname(ae)) == 0) {
+ /* '.' root directory. */
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ /* Now, we read timestamp recorded by RRIP "TF". */
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ /* Now, we read links recorded by RRIP "PX". */
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ } else if (strcmp("dir1", archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir1", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("dir1/dir2",
+ archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir1/dir2",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("dir1/dir2/dir3",
+ archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir1/dir2/dir3",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("dir1/dir2/dir3/dir4",
+ archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir1/dir2/dir3/dir4",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("dir1/dir2/dir3/dir4/dir5",
+ archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir1/dir2/dir3/dir4/dir5",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6",
+ archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7",
+ archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7"
+ "/dir8",
+ archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7"
+ "/dir8",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7"
+ "/dir8/dir9",
+ archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7"
+ "/dir8/dir9",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7"
+ "/dir8/dir9/dir10",
+ archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7"
+ "/dir8/dir9/dir10",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(12345684, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello\n", 6);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7"
+ "/dir8/dir9/dir10/deep",
+ archive_entry_pathname(ae)) == 0) {
+ /* A regular file. */
+ assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7"
+ "/dir8/dir9/dir10/deep",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(12345684, archive_entry_size(ae));
+ assertEqualInt(0,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello\n", 6);
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else {
+ failure("Saw a file that shouldn't have been there");
+ assertEqualString(archive_entry_pathname(ae), "");
+ }
+ }
+
+ /* End of archive. */
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
+
+ /* Close the archive. */
+ assertEqualInt(0, archive_read_close(a));
+ assertEqualInt(0, archive_read_finish(a));
+}
+
+
diff --git a/lib/libarchive/test/test_read_format_isozisofs_bz2.c b/lib/libarchive/test/test_read_format_isozisofs_bz2.c
new file mode 100644
index 0000000..56c39c0
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_isozisofs_bz2.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$");
+
+/*
+Execute the following command to rebuild the data for this program:
+ tail -n +32 test_read_format_isozisofs_bz2.c | /bin/sh
+
+rm -rf /tmp/iso /tmp/ziso
+mkdir /tmp/iso
+mkdir /tmp/iso/dir
+echo "hello" >/tmp/iso/file
+dd if=/dev/zero count=1 bs=12345678 >>/tmp/iso/file
+ln /tmp/iso/file /tmp/iso/hardlink
+(cd /tmp/iso; ln -s file symlink)
+(cd /tmp/iso; ln -s /tmp/ symlink2)
+(cd /tmp/iso; ln -s /tmp/../ symlink3)
+(cd /tmp/iso; ln -s .././../tmp/ symlink4)
+TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir
+TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink
+mkzftree /tmp/iso /tmp/ziso
+TZ=utc touch -afhm -t 197001020000.01 /tmp/ziso /tmp/ziso/file /tmp/ziso/dir
+TZ=utc touch -afhm -t 197001030000.02 /tmp/ziso/symlink
+F=test_read_format_iso_zisofs.iso.Z
+mkhybrid -R -uid 1 -gid 2 -z /tmp/ziso | compress > $F
+uuencode $F $F > $F.uu
+exit 1
+
+ */
+
+DEFINE_TEST(test_read_format_isozisofs_bz2)
+{
+ const char *refname = "test_read_format_iso_zisofs.iso.Z";
+ struct archive_entry *ae;
+ struct archive *a;
+ const void *p;
+ size_t size;
+ off_t offset;
+ int i;
+
+ extract_reference_file(refname);
+ assert((a = archive_read_new()) != NULL);
+ assertEqualInt(0, archive_read_support_compression_all(a));
+ assertEqualInt(0, archive_read_support_format_all(a));
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Retrieve each of the 8 files on the ISO image and
+ * verify that each one is what we expect. */
+ for (i = 0; i < 8; ++i) {
+ assertEqualInt(0, archive_read_next_header(a, &ae));
+
+ if (strcmp(".", archive_entry_pathname(ae)) == 0) {
+ /* '.' root directory. */
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ /* Now, we read timestamp recorded by RRIP "TF". */
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ /* Now, we read links recorded by RRIP "PX". */
+ assertEqualInt(3, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_data_block(a, &p, &size, &offset));
+ assertEqualInt((int)size, 0);
+ } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) {
+ /* A directory. */
+ assertEqualString("dir", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) {
+ int r;
+ /* A regular file. */
+ assertEqualString("hardlink", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualInt(12345684, archive_entry_size(ae));
+ r = archive_read_data_block(a, &p, &size, &offset);
+ if (r == ARCHIVE_FAILED) {
+ skipping("Can't read body of ZISOFS entry.");
+ } else {
+ assertEqualInt(ARCHIVE_OK, r);
+ assertEqualInt(0, offset);
+ assertEqualMem(p, "hello\n", 6);
+ }
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
+ /* A hardlink to the regular file. */
+ /* Note: If "hardlink" gets returned before "file",
+ * then "hardlink" will get returned as a regular file
+ * and "file" will get returned as the hardlink.
+ * This test should tolerate that, since it's a
+ * perfectly permissible thing for libarchive to do. */
+ assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("hardlink", archive_entry_hardlink(ae));
+ assertEqualInt(0, archive_entry_size_is_set(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
+ assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to the regular file. */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("file", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(172802, archive_entry_mtime(ae));
+ assertEqualInt(172802, archive_entry_atime(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink2", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to /tmp (an absolute path) */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("/tmp", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink3", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to /tmp/.. (with a ".." component) */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString("/tmp/..", archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else if (strcmp("symlink4", archive_entry_pathname(ae)) == 0) {
+ /* A symlink to a path with ".." and "." components */
+ assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
+ assertEqualString(".././../tmp",
+ archive_entry_symlink(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+ assertEqualInt(1, archive_entry_uid(ae));
+ assertEqualInt(2, archive_entry_gid(ae));
+ } else {
+ failure("Saw a file that shouldn't have been there");
+ assertEqualString(archive_entry_pathname(ae), "");
+ }
+ }
+
+ /* End of archive. */
+ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
+
+ /* Close the archive. */
+ assertEqualInt(0, archive_read_close(a));
+ assertEqualInt(0, archive_read_finish(a));
+}
+
+
diff --git a/lib/libarchive/test/test_read_format_mtree.c b/lib/libarchive/test/test_read_format_mtree.c
index b13034f..5001e4d 100644
--- a/lib/libarchive/test/test_read_format_mtree.c
+++ b/lib/libarchive/test/test_read_format_mtree.c
@@ -25,34 +25,16 @@
#include "test.h"
__FBSDID("$FreeBSD$");
-/* Single entry with a hardlink. */
-static unsigned char archive[] = {
- "#mtree\n"
- "file type=file uid=18 mode=0123 size=3\n"
- "dir type=dir\n"
- " file\\040with\\040space type=file uid=18\n"
- " ..\n"
- "file\\04with\\040space type=file\n"
- "dir2 type=dir\n"
- " dir3a type=dir\n"
- " indir3a type=file\n"
- "dir2/fullindir2 type=file mode=0777\n"
- " ..\n"
- " indir2 type=file\n"
- " dir3b type=dir\n"
- " indir3b type=file\n"
- " ..\n"
- " ..\n"
- "notindir type=file\n"
- "dir2/fullindir2 mode=0644\n"
-};
-
-DEFINE_TEST(test_read_format_mtree)
+static void
+test_read_format_mtree1(void)
{
+ const char reffile[] = "test_read_format_mtree.mtree";
char buff[16];
struct archive_entry *ae;
struct archive *a;
- int fd;
+ FILE *f;
+
+ extract_reference_file(reffile);
/*
* An access error occurred on some platform when mtree
@@ -60,29 +42,28 @@ DEFINE_TEST(test_read_format_mtree)
* the routine which open a directory that we create
* "dir" and "dir2" directories.
*/
- assertEqualInt(0, mkdir("dir", 0775));
- assertEqualInt(0, mkdir("dir2", 0775));
+ assertMakeDir("dir", 0775);
+ assertMakeDir("dir2", 0775);
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));
- assertEqualIntA(a, ARCHIVE_OK,
- archive_read_open_memory(a, archive, sizeof(archive)));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_file(a, reffile, 11));
/*
* Read "file", whose data is available on disk.
*/
- fd = open("file", O_WRONLY | O_CREAT, 0777);
- assert(fd >= 0);
- assertEqualInt(3, write(fd, "hi\n", 3));
- close(fd);
+ f = fopen("file", "wb");
+ assert(f != NULL);
+ assertEqualInt(3, fwrite("hi\n", 1, 3, f));
+ fclose(f);
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
assertEqualString(archive_entry_pathname(ae), "file");
assertEqualInt(archive_entry_uid(ae), 18);
- assert(S_ISREG(archive_entry_mode(ae)));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
assertEqualInt(archive_entry_size(ae), 3);
assertEqualInt(3, archive_read_data(a, buff, 3));
@@ -90,13 +71,13 @@ DEFINE_TEST(test_read_format_mtree)
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString(archive_entry_pathname(ae), "dir");
- assert(S_ISDIR(archive_entry_mode(ae)));
+ assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString(archive_entry_pathname(ae), "dir/file with space");
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
- assertEqualString(archive_entry_pathname(ae), "file\\04with space");
+ assertEqualString(archive_entry_pathname(ae), "file with space");
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualString(archive_entry_pathname(ae), "dir2");
@@ -125,11 +106,38 @@ DEFINE_TEST(test_read_format_mtree)
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
-#endif
}
+static void
+test_read_format_mtree2(void)
+{
+ static char archive[] =
+ "#mtree\n"
+ "d type=dir content=.\n";
+ 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));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, archive, sizeof(archive)));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
+ assertEqualString(archive_entry_pathname(ae), "d");
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+}
+
+
+
+DEFINE_TEST(test_read_format_mtree)
+{
+ test_read_format_mtree1();
+ test_read_format_mtree2();
+}
diff --git a/lib/libarchive/test/test_read_format_mtree.mtree.uu b/lib/libarchive/test/test_read_format_mtree.mtree.uu
new file mode 100644
index 0000000..9fa0d9b
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_mtree.mtree.uu
@@ -0,0 +1,13 @@
+$FreeBSD$
+
+begin 644 test_read_format_mtree.mtree
+M(VUT<F5E"F9I;&4@='EP93UF:6QE('5I9#TQ."!M;V1E/3`Q,C,@<VEZ93TS
+M"F1I<B!T>7!E/61I<@H@9FEL95PP-#!W:71H7#`T,'-P86-E('1Y<&4]9FEL
+M92!U:60],3@*("XN"F9I;&5<,#0P=VET:%PP-#!S<&%C92!T>7!E/69I;&4*
+M9&ER,B!T>7!E/61I<@H@9&ER,V$@='EP93UD:7(*("!I;F1I<C-A('1Y<&4]
+M9FEL90ID:7(R+V9U;&QI;F1I<C(@='EP93UF:6QE(&UO9&4],#<W-PH@("XN
+M"B!I;F1I<C(@='EP93UF:6QE"B!D:7(S8B!T>7!E/61I<@H@(&EN9&ER,V(@
+M='EP93UF:6QE"B`@+BX*("XN"FYO=&EN9&ER('1Y<&4]9FEL90ID:7(R+V9U
+3;&QI;F1I<C(@;6]D93TP-C0T"@``
+`
+end
diff --git a/lib/libarchive/test/test_read_format_pax_bz2.c b/lib/libarchive/test/test_read_format_pax_bz2.c
index a0b74e1..aa2a5cf 100644
--- a/lib/libarchive/test/test_read_format_pax_bz2.c
+++ b/lib/libarchive/test/test_read_format_pax_bz2.c
@@ -44,9 +44,15 @@ DEFINE_TEST(test_read_format_pax_bz2)
{
struct archive_entry *ae;
struct archive *a;
+ int r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a,ARCHIVE_OK, archive_read_support_compression_all(a));
+ r = archive_read_support_compression_bzip2(a);
+ if (r != ARCHIVE_OK) {
+ archive_read_close(a);
+ skipping("Bzip2 unavailable");
+ return;
+ }
assertEqualIntA(a,ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a,ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
diff --git a/lib/libarchive/test/test_read_format_tar.c b/lib/libarchive/test/test_read_format_tar.c
index e34da1b..980866d 100644
--- a/lib/libarchive/test/test_read_format_tar.c
+++ b/lib/libarchive/test/test_read_format_tar.c
@@ -101,9 +101,9 @@ static unsigned char archive1[] = {
static void verify1(struct archive_entry *ae)
{
/* A hardlink is not a symlink. */
- assert(!S_ISLNK(archive_entry_mode(ae)));
+ assert(archive_entry_filetype(ae) != AE_IFLNK);
/* Nor is it a directory. */
- assert(!S_ISDIR(archive_entry_mode(ae)));
+ assert(archive_entry_filetype(ae) != AE_IFDIR);
assertEqualInt(archive_entry_mode(ae) & 0777, 0644);
assertEqualInt(archive_entry_uid(ae), 1000);
assertEqualInt(archive_entry_gid(ae), 1000);
@@ -132,7 +132,7 @@ static unsigned char archive2[] = {
static void verify2(struct archive_entry *ae)
{
- assert(S_ISLNK(archive_entry_mode(ae)));
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
assertEqualInt(archive_entry_uid(ae), 1000);
assertEqualInt(archive_entry_gid(ae), 1000);
@@ -161,7 +161,7 @@ static unsigned char archive3[] = {
static void verify3(struct archive_entry *ae)
{
- assert(S_ISCHR(archive_entry_mode(ae)));
+ assertEqualInt(archive_entry_filetype(ae), AE_IFCHR);
assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
assertEqualInt(archive_entry_uid(ae), 1000);
assertEqualInt(archive_entry_gid(ae), 1000);
@@ -190,7 +190,7 @@ static unsigned char archive4[] = {
static void verify4(struct archive_entry *ae)
{
- assert(S_ISBLK(archive_entry_mode(ae)));
+ assertEqualInt(archive_entry_filetype(ae), AE_IFBLK);
assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
assertEqualInt(archive_entry_uid(ae), 1000);
assertEqualInt(archive_entry_gid(ae), 1000);
@@ -219,7 +219,7 @@ static unsigned char archive5[] = {
static void verify5(struct archive_entry *ae)
{
- assert(S_ISDIR(archive_entry_mode(ae)));
+ assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
assertEqualInt(archive_entry_mtime(ae), 1131430878);
assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
assertEqualInt(archive_entry_uid(ae), 1000);
@@ -245,7 +245,7 @@ static unsigned char archive6[] = {
static void verify6(struct archive_entry *ae)
{
- assert(S_ISFIFO(archive_entry_mode(ae)));
+ assertEqualInt(archive_entry_filetype(ae), AE_IFIFO);
assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
assertEqualInt(archive_entry_uid(ae), 1000);
assertEqualInt(archive_entry_gid(ae), 1000);
@@ -316,7 +316,7 @@ static unsigned char archiveK[] = {
static void verifyK(struct archive_entry *ae)
{
- assert(S_ISLNK(archive_entry_mode(ae)));
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
assertEqualInt(archive_entry_uid(ae), 1000);
assertEqualInt(archive_entry_gid(ae), 1000);
@@ -402,7 +402,7 @@ static unsigned char archivexL[] = {
static void verifyxL(struct archive_entry *ae)
{
- assert(S_ISLNK(archive_entry_mode(ae)));
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
assertEqualInt(archive_entry_mode(ae) & 0777, 0755);
assertEqualInt(archive_entry_uid(ae), 1000);
assertEqualInt(archive_entry_gid(ae), 1000);
diff --git a/lib/libarchive/test/test_read_format_tbz.c b/lib/libarchive/test/test_read_format_tbz.c
index 00d4094..be99b36 100644
--- a/lib/libarchive/test/test_read_format_tbz.c
+++ b/lib/libarchive/test/test_read_format_tbz.c
@@ -37,9 +37,15 @@ DEFINE_TEST(test_read_format_tbz)
{
struct archive_entry *ae;
struct archive *a;
+ int r;
assert((a = archive_read_new()) != NULL);
- assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ r = archive_read_support_compression_bzip2(a);
+ if (r != ARCHIVE_OK) {
+ skipping("Bzip2 support");
+ archive_read_finish(a);
+ return;
+ }
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
diff --git a/lib/libarchive/test/test_read_format_tlz.c b/lib/libarchive/test/test_read_format_tlz.c
new file mode 100644
index 0000000..652d1cd
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_tlz.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
+ * 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 unsigned char archive[] = {
+ 93, 0, 0,128, 0,255,255,255,255,255,255,255,255, 0, 23, 0,
+ 51, 80, 24,164,204,238, 45, 77, 28,191, 13,144, 8, 10, 70, 5,
+173,215, 47,132,237,145,162, 96, 6,131,168,152, 8,135,161,189,
+ 73,110,132, 27,195, 52,109,203, 22, 17,168,211, 18,181, 76, 93,
+120, 88,154,155,244,141,193,206,170,224, 80,137,134, 67, 1, 9,
+123,121,189, 74,137,197, 63,255,214, 55,119, 0
+};
+
+DEFINE_TEST(test_read_format_tlz)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ int r;
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
+ r = archive_read_support_compression_lzma(a);
+ if (r == ARCHIVE_WARN) {
+ skipping("lzma reading not fully supported on this platform");
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ return;
+ }
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, archive, sizeof(archive)));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_LZMA);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+}
diff --git a/lib/libarchive/test/test_read_large.c b/lib/libarchive/test/test_read_large.c
index c524ae8..ba716c2 100644
--- a/lib/libarchive/test/test_read_large.c
+++ b/lib/libarchive/test/test_read_large.c
@@ -29,6 +29,11 @@ static unsigned char testdata[10 * 1024 * 1024];
static unsigned char testdatacopy[10 * 1024 * 1024];
static unsigned char buff[11 * 1024 * 1024];
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define open _open
+#define close _close
+#endif
+
/* Check correct behavior on large reads. */
DEFINE_TEST(test_read_large)
{
@@ -38,6 +43,7 @@ DEFINE_TEST(test_read_large)
size_t used;
struct archive *a;
struct archive_entry *entry;
+ FILE *f;
for (i = 0; i < sizeof(testdata); i++)
testdata[i] = (unsigned char)(rand());
@@ -52,11 +58,7 @@ DEFINE_TEST(test_read_large)
assertA(0 == archive_write_header(a, entry));
archive_entry_free(entry);
assertA(sizeof(testdata) == archive_write_data(a, testdata, sizeof(testdata)));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
assertA(0 == archive_write_finish(a));
-#endif
assert(NULL != (a = archive_read_new()));
assertA(0 == archive_read_support_format_all(a));
@@ -64,11 +66,7 @@ DEFINE_TEST(test_read_large)
assertA(0 == archive_read_open_memory(a, buff, sizeof(buff)));
assertA(0 == archive_read_next_header(a, &entry));
assertA(0 == archive_read_data_into_buffer(a, testdatacopy, sizeof(testdatacopy)));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
-#else
assertA(0 == archive_read_finish(a));
-#endif
assert(0 == memcmp(testdata, testdatacopy, sizeof(testdata)));
@@ -77,18 +75,19 @@ DEFINE_TEST(test_read_large)
assertA(0 == archive_read_support_compression_all(a));
assertA(0 == archive_read_open_memory(a, buff, sizeof(buff)));
assertA(0 == archive_read_next_header(a, &entry));
- assert(0 < (tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY, 0755)));
- assertA(0 == archive_read_data_into_fd(a, tmpfilefd));
- close(tmpfilefd);
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_read_finish(a);
+#if defined(__BORLANDC__)
+ tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY);
#else
- assertA(0 == archive_read_finish(a));
+ tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY, 0755);
#endif
- tmpfilefd = open(tmpfilename, O_RDONLY);
- read(tmpfilefd, testdatacopy, sizeof(testdatacopy));
+ assert(0 < tmpfilefd);
+ assertA(0 == archive_read_data_into_fd(a, tmpfilefd));
close(tmpfilefd);
- assert(0 == memcmp(testdata, testdatacopy, sizeof(testdata)));
+ assertA(0 == archive_read_finish(a));
- unlink(tmpfilename);
+ f = fopen(tmpfilename, "rb");
+ assertEqualInt(sizeof(testdatacopy),
+ fread(testdatacopy, 1, sizeof(testdatacopy), f));
+ fclose(f);
+ assert(0 == memcmp(testdata, testdatacopy, sizeof(testdata)));
}
diff --git a/lib/libarchive/test/test_tar_large.c b/lib/libarchive/test/test_tar_large.c
index b2b8e5d..92ca839 100644
--- a/lib/libarchive/test/test_tar_large.c
+++ b/lib/libarchive/test/test_tar_large.c
@@ -190,7 +190,7 @@ memory_read_skip(struct archive *a, void *_private, off_t skip)
}
if (private->filebytes > 0) {
if (private->filebytes < skip)
- skip = private->filebytes;
+ skip = (off_t)private->filebytes;
private->filebytes -= skip;
} else {
skip = 0;
diff --git a/lib/libarchive/test/test_write_compress_program.c b/lib/libarchive/test/test_write_compress_program.c
index 713638e..34d0680 100644
--- a/lib/libarchive/test/test_write_compress_program.c
+++ b/lib/libarchive/test/test_write_compress_program.c
@@ -38,12 +38,9 @@ DEFINE_TEST(test_write_compress_program)
size_t used;
int blocksize = 1024;
int r;
- const char *compprog, *decompprog;
- decompprog = external_gzip_program(1);
- if ((compprog = external_gzip_program(0)) == NULL) {
- skipping("There is no gzip compression "
- "program in this platform");
+ if (!canGzip()) {
+ skipping("Cannot run 'gzip'");
return;
}
@@ -51,7 +48,7 @@ DEFINE_TEST(test_write_compress_program)
/* Write it through an external "gzip" program. */
assert((a = archive_write_new()) != NULL);
assertA(0 == archive_write_set_format_ustar(a));
- r = archive_write_set_compression_program(a, compprog);
+ r = archive_write_set_compression_program(a, "gzip");
if (r == ARCHIVE_FATAL) {
skipping("Write compression via external "
"program unsupported on this platform");
@@ -91,8 +88,8 @@ DEFINE_TEST(test_write_compress_program)
/* The compression_gzip() handler will fall back to gunzip
* automatically, but if we know gunzip isn't available, then
* skip the rest. */
- if (r != ARCHIVE_OK && decompprog == NULL) {
- skipping("No gzip decompression is available; "
+ if (r != ARCHIVE_OK && !canGunzip()) {
+ skipping("No libz and no gunzip program, "
"unable to verify gzip compression");
assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
return;
diff --git a/lib/libarchive/test/test_write_disk.c b/lib/libarchive/test/test_write_disk.c
index c0b22e5..f3f4e56 100644
--- a/lib/libarchive/test/test_write_disk.c
+++ b/lib/libarchive/test/test_write_disk.c
@@ -28,6 +28,14 @@ __FBSDID("$FreeBSD$");
#if ARCHIVE_VERSION_NUMBER >= 1009000
#define UMASK 022
+/*
+ * When comparing mode values, ignore high-order bits
+ * that are set on some OSes. This should cover the bits
+ * we're interested in (standard mode bits + file type bits)
+ * while ignoring extra markers such as Haiku/BeOS index
+ * flags.
+ */
+#define MODE_MASK 0777777
static void create(struct archive_entry *ae, const char *msg)
{
@@ -46,14 +54,15 @@ static void create(struct archive_entry *ae, const char *msg)
#endif
/* Test the entries on disk. */
assert(0 == stat(archive_entry_pathname(ae), &st));
- failure("st.st_mode=%o archive_entry_mode(ae)=%o",
- st.st_mode, archive_entry_mode(ae));
+ failure("%s", msg);
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
/* When verifying a dir, ignore the S_ISGID bit, as some systems set
* that automatically. */
if (archive_entry_filetype(ae) == AE_IFDIR)
st.st_mode &= ~S_ISGID;
-#if !defined(_WIN32) || defined(__CYGWIN__)
- assertEqualInt(st.st_mode, archive_entry_mode(ae) & ~UMASK);
+ assertEqualInt(st.st_mode & MODE_MASK,
+ archive_entry_mode(ae) & ~UMASK & MODE_MASK);
#endif
}
@@ -61,8 +70,6 @@ static void create_reg_file(struct archive_entry *ae, const char *msg)
{
static const char data[]="abcdefghijklmnopqrstuvwxyz";
struct archive *ad;
- struct stat st;
- time_t now;
/* Write the entry to disk. */
assert((ad = archive_write_disk_new()) != NULL);
@@ -96,28 +103,20 @@ static void create_reg_file(struct archive_entry *ae, const char *msg)
assertEqualInt(0, archive_write_finish(ad));
#endif
/* Test the entries on disk. */
- assert(0 == stat(archive_entry_pathname(ae), &st));
- failure("st.st_mode=%o archive_entry_mode(ae)=%o",
- st.st_mode, archive_entry_mode(ae));
-#if !defined(_WIN32) || defined(__CYGWIN__)
- assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK));
-#endif
- assertEqualInt(st.st_size, sizeof(data));
+ assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777);
+ assertFileSize(archive_entry_pathname(ae), sizeof(data));
/* test_write_disk_times has more detailed tests of this area. */
- assertEqualInt(st.st_mtime, 123456789);
- failure("No atime was specified, so atime should get set to current time");
- now = time(NULL);
- assert(st.st_atime <= now && st.st_atime > now - 5);
+ assertFileMtime(archive_entry_pathname(ae), 123456789, 0);
+ failure("No atime given, so atime should get set to current time");
+ assertFileAtimeRecent(archive_entry_pathname(ae));
}
static void create_reg_file2(struct archive_entry *ae, const char *msg)
{
const int datasize = 100000;
char *data;
- char *compare;
struct archive *ad;
- struct stat st;
- int i, fd;
+ int i;
data = malloc(datasize);
for (i = 0; i < datasize; i++)
@@ -137,26 +136,12 @@ static void create_reg_file2(struct archive_entry *ae, const char *msg)
archive_write_data_block(ad, data + i, 1000, i));
}
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(ad);
-#else
assertEqualInt(0, archive_write_finish(ad));
-#endif
- /* Test the entries on disk. */
- assert(0 == stat(archive_entry_pathname(ae), &st));
- failure("st.st_mode=%o archive_entry_mode(ae)=%o",
- st.st_mode, archive_entry_mode(ae));
-#if !defined(_WIN32) || defined(__CYGWIN__)
- assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK));
-#endif
- assertEqualInt(st.st_size, i);
- compare = malloc(datasize);
- fd = open(archive_entry_pathname(ae), O_RDONLY);
- assertEqualInt(datasize, read(fd, compare, datasize));
- close(fd);
- assert(memcmp(compare, data, datasize) == 0);
- free(compare);
+ /* Test the entries on disk. */
+ assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777);
+ assertFileSize(archive_entry_pathname(ae), i);
+ assertFileContents(data, datasize, archive_entry_pathname(ae));
free(data);
}
@@ -268,7 +253,7 @@ DEFINE_TEST(test_write_disk)
struct archive_entry *ae;
/* Force the umask to something predictable. */
- umask(UMASK);
+ assertUmask(UMASK);
/* A regular file. */
assert((ae = archive_entry_new()) != NULL);
diff --git a/lib/libarchive/test/test_write_disk_failures.c b/lib/libarchive/test/test_write_disk_failures.c
index 1befbac..f74c947 100644
--- a/lib/libarchive/test/test_write_disk_failures.c
+++ b/lib/libarchive/test/test_write_disk_failures.c
@@ -42,13 +42,13 @@ DEFINE_TEST(test_write_disk_failures)
int fd;
/* Force the umask to something predictable. */
- umask(UMASK);
+ assertUmask(UMASK);
/* A directory that we can't write to. */
- assertEqualInt(0, mkdir("dir", 0555));
+ assertMakeDir("dir", 0555);
/* Can we? */
- fd = open("dir/testfile", O_WRONLY | O_CREAT, 0777);
+ fd = open("dir/testfile", O_WRONLY | O_CREAT | O_BINARY, 0777);
if (fd >= 0) {
/* Apparently, we can, so the test below won't work. */
close(fd);
diff --git a/lib/libarchive/test/test_write_disk_hardlink.c b/lib/libarchive/test/test_write_disk_hardlink.c
index 2ab2420..5756602 100644
--- a/lib/libarchive/test/test_write_disk_hardlink.c
+++ b/lib/libarchive/test/test_write_disk_hardlink.c
@@ -43,16 +43,16 @@ __FBSDID("$FreeBSD$");
*/
DEFINE_TEST(test_write_disk_hardlink)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000
- skipping("archive_write_disk_hardlink tests");
+#if defined(__HAIKU__)
+ skipping("archive_write_disk_hardlink; hardlinks are not supported on bfs");
#else
static const char data[]="abcdefghijklmnopqrstuvwxyz";
struct archive *ad;
struct archive_entry *ae;
- struct stat st, st2;
+ int r;
/* Force the umask to something predictable. */
- umask(UMASK);
+ assertUmask(UMASK);
/* Write entries to disk. */
assert((ad = archive_write_disk_new()) != NULL);
@@ -79,10 +79,12 @@ DEFINE_TEST(test_write_disk_hardlink)
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));
- assertEqualInt(ARCHIVE_WARN,
- archive_write_data(ad, data, sizeof(data)));
- assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
+ assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
+ if (r >= ARCHIVE_WARN) {
+ assertEqualInt(ARCHIVE_WARN,
+ archive_write_data(ad, data, sizeof(data)));
+ assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
+ }
archive_entry_free(ae);
/*
@@ -107,10 +109,12 @@ DEFINE_TEST(test_write_disk_hardlink)
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));
+ assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
+ if (r >= ARCHIVE_WARN) {
+ assertEqualInt(ARCHIVE_WARN,
+ archive_write_data(ad, data, sizeof(data)));
+ assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
+ }
archive_entry_free(ae);
/*
@@ -134,9 +138,12 @@ DEFINE_TEST(test_write_disk_hardlink)
archive_entry_set_mode(ae, S_IFREG | 0755);
archive_entry_set_size(ae, sizeof(data));
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));
+ assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
+ if (r > ARCHIVE_WARN) {
+ assertEqualInt(sizeof(data),
+ archive_write_data(ad, data, sizeof(data)));
+ assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
+ }
archive_entry_free(ae);
/*
@@ -164,34 +171,26 @@ DEFINE_TEST(test_write_disk_hardlink)
archive_entry_set_mode(ae, S_IFREG | 0755);
archive_entry_set_size(ae, sizeof(data));
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));
+ assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
+ if (r > ARCHIVE_FAILED) {
+ assertEqualInt(sizeof(data),
+ archive_write_data(ad, data, sizeof(data)));
+ assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
+ }
archive_entry_free(ae);
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(ad);
-#else
assertEqualInt(0, archive_write_finish(ad));
-#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 & E_MASK, (S_IFREG | 0755) & ~UMASK);
- assertEqualInt(st.st_size, sizeof(data));
- assertEqualInt(st.st_nlink, 2);
-
- assert(0 == stat("link1b", &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);
+ assertIsReg("link1a", 0755 & ~UMASK);
+ assertFileSize("link1a", sizeof(data));
+ assertFileNLinks("link1a", 2);
+ assertIsHardlink("link1a", "link1b");
/* Test #2: Should produce identical results to test #1 */
/* Note that marking a hardlink with size = 0 is treated the
@@ -200,42 +199,21 @@ DEFINE_TEST(test_write_disk_hardlink)
* 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 & E_MASK, (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);
+ assertIsReg("link2a", 0755 & ~UMASK);
+ assertFileSize("link2a", sizeof(data));
+ assertFileNLinks("link2a", 2);
+ assertIsHardlink("link2a", "link2b");
/* Test #3 */
- assert(0 == stat("link3a", &st));
- assertEqualInt(st.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK);
- assertEqualInt(st.st_size, sizeof(data));
- assertEqualInt(st.st_nlink, 2);
-
- assert(0 == stat("link3b", &st2));
- assertEqualInt(st2.st_mode & E_MASK, (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);
+ assertIsReg("link3a", 0755 & ~UMASK);
+ assertFileSize("link3a", sizeof(data));
+ assertFileNLinks("link3a", 2);
+ assertIsHardlink("link3a", "link3b");
/* Test #4 */
- assert(0 == stat("link4a", &st));
- assertEqualInt(st.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK);
- assertEqualInt(st.st_size, sizeof(data));
- assertEqualInt(st.st_nlink, 2);
-
- assert(0 == stat("link4b", &st2));
- assertEqualInt(st2.st_mode & E_MASK, (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);
+ assertIsReg("link4a", 0755 & ~UMASK);
+ assertFileNLinks("link4a", 2);
+ assertFileSize("link4a", sizeof(data));
+ assertIsHardlink("link4a", "link4b");
#endif
}
diff --git a/lib/libarchive/test/test_write_disk_perms.c b/lib/libarchive/test/test_write_disk_perms.c
index 3d9be27..f53ce19 100644
--- a/lib/libarchive/test/test_write_disk_perms.c
+++ b/lib/libarchive/test/test_write_disk_perms.c
@@ -60,7 +60,7 @@ searchgid(void)
_searched = 1;
/* Create a file on disk in the current default dir. */
- fd = open("test_gid", O_CREAT, 0664);
+ fd = open("test_gid", O_CREAT | O_BINARY, 0664);
failure("Couldn't create a file for gid testing.");
assert(fd > 0);
@@ -132,6 +132,8 @@ DEFINE_TEST(test_write_disk_perms)
struct archive_entry *ae;
struct stat st;
+ assertUmask(UMASK);
+
/*
* Set ownership of the current directory to the group of this
* process. Otherwise, the SGID tests below fail if the
@@ -182,7 +184,7 @@ DEFINE_TEST(test_write_disk_perms)
/* Overwrite an existing dir. */
/* For dir, the first perms should get left. */
- assert(mkdir("dir_overwrite_0744", 0744) == 0);
+ assertMakeDir("dir_overwrite_0744", 0744);
/* Check original perms. */
assert(0 == stat("dir_overwrite_0744", &st));
failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode);
diff --git a/lib/libarchive/test/test_write_disk_secure.c b/lib/libarchive/test/test_write_disk_secure.c
index d417489..74506f1 100644
--- a/lib/libarchive/test/test_write_disk_secure.c
+++ b/lib/libarchive/test/test_write_disk_secure.c
@@ -36,13 +36,13 @@ DEFINE_TEST(test_write_disk_secure)
{
#if ARCHIVE_VERSION_NUMBER < 1009000
skipping("archive_write_disk interface");
-#else
+#elif !defined(_WIN32) || defined(__CYGWIN__)
struct archive *a;
struct archive_entry *ae;
struct stat st;
/* Start with a known umask. */
- umask(UMASK);
+ assertUmask(UMASK);
/* Create an archive_write_disk object. */
assert((a = archive_write_disk_new()) != NULL);
@@ -55,7 +55,6 @@ DEFINE_TEST(test_write_disk_secure)
archive_entry_free(ae);
assert(0 == archive_write_finish_entry(a));
-#if !defined(_WIN32) || defined(__CYGWIN__)
/* Write a symlink to the dir above. */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "link_to_dir");
@@ -150,7 +149,6 @@ DEFINE_TEST(test_write_disk_secure)
assertEqualInt(0, lstat("link_to_dir4", &st));
assert(S_ISDIR(st.st_mode));
archive_entry_free(ae);
-#endif
/*
* As above, but a link to a non-dir, so the link should get replaced.
@@ -180,14 +178,8 @@ DEFINE_TEST(test_write_disk_secure)
assert(S_ISDIR(st.st_mode));
archive_entry_free(ae);
-
-#if ARCHIVE_VERSION_NUMBER < 2000000
- archive_write_finish(a);
-#else
assert(0 == archive_write_finish(a));
-#endif
-#if !defined(_WIN32) || defined(__CYGWIN__)
/* Test the entries on disk. */
assert(0 == lstat("dir", &st));
failure("dir: st.st_mode=%o", st.st_mode);
@@ -220,5 +212,4 @@ DEFINE_TEST(test_write_disk_secure)
failure("link_to_dir2/filec: st.st_mode=%o", st.st_mode);
assert((st.st_mode & 07777) == 0755);
#endif
-#endif
}
diff --git a/lib/libarchive/test/test_write_disk_sparse.c b/lib/libarchive/test/test_write_disk_sparse.c
index c9c00d3..b613f56 100644
--- a/lib/libarchive/test/test_write_disk_sparse.c
+++ b/lib/libarchive/test/test_write_disk_sparse.c
@@ -40,7 +40,7 @@ verify_write_data(struct archive *a, int sparse)
size_t buff_size = 64 * 1024;
char *buff, *p;
const char *msg = sparse ? "sparse" : "non-sparse";
- int fd;
+ FILE *f;
buff = malloc(buff_size);
assert(buff != NULL);
@@ -78,12 +78,12 @@ verify_write_data(struct archive *a, int sparse)
/* Test the entry on disk. */
assert(0 == stat(archive_entry_pathname(ae), &st));
assertEqualInt(st.st_size, 8 * buff_size);
- fd = open(archive_entry_pathname(ae), O_RDONLY);
- if (!assert(fd >= 0))
+ f = fopen(archive_entry_pathname(ae), "rb");
+ if (!assert(f != NULL))
return;
/* Check first block. */
- assertEqualInt(buff_size, read(fd, buff, buff_size));
+ assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
failure("%s", msg);
assertEqualMem(buff, data, sizeof(data));
for (p = buff + sizeof(data); p < buff + buff_size; ++p) {
@@ -93,7 +93,7 @@ verify_write_data(struct archive *a, int sparse)
}
/* Check second block. */
- assertEqualInt(buff_size, read(fd, buff, buff_size));
+ assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
for (p = buff; p < buff + buff_size; ++p) {
failure("offset: %d, %s", (int)(p - buff), msg);
if (p == buff + buff_size / 2 - 3) {
@@ -104,7 +104,7 @@ verify_write_data(struct archive *a, int sparse)
}
/* Check third block. */
- assertEqualInt(buff_size, read(fd, buff, buff_size));
+ assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
for (p = buff; p < buff + buff_size - sizeof(data); ++p) {
failure("offset: %d, %s", (int)(p - buff), msg);
if (!assertEqualInt(0, *p))
@@ -115,7 +115,7 @@ verify_write_data(struct archive *a, int sparse)
/* XXX more XXX */
- assertEqualInt(0, close(fd));
+ assertEqualInt(0, fclose(f));
archive_entry_free(ae);
free(buff);
}
@@ -132,7 +132,7 @@ verify_write_data_block(struct archive *a, int sparse)
size_t buff_size = 64 * 1024;
char *buff, *p;
const char *msg = sparse ? "sparse" : "non-sparse";
- int fd;
+ FILE *f;
buff = malloc(buff_size);
assert(buff != NULL);
@@ -174,12 +174,12 @@ verify_write_data_block(struct archive *a, int sparse)
/* Test the entry on disk. */
assert(0 == stat(archive_entry_pathname(ae), &st));
assertEqualInt(st.st_size, 8 * buff_size);
- fd = open(archive_entry_pathname(ae), O_RDONLY);
- if (!assert(fd >= 0))
+ f = fopen(archive_entry_pathname(ae), "rb");
+ if (!assert(f != NULL))
return;
/* Check 100-byte gap at beginning */
- assertEqualInt(100, read(fd, buff, 100));
+ assertEqualInt(100, fread(buff, 1, 100, f));
failure("%s", msg);
for (p = buff; p < buff + 100; ++p) {
failure("offset: %d, %s", (int)(p - buff), msg);
@@ -188,7 +188,7 @@ verify_write_data_block(struct archive *a, int sparse)
}
/* Check first block. */
- assertEqualInt(buff_size, read(fd, buff, buff_size));
+ assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
failure("%s", msg);
assertEqualMem(buff, data, sizeof(data));
for (p = buff + sizeof(data); p < buff + buff_size; ++p) {
@@ -198,7 +198,7 @@ verify_write_data_block(struct archive *a, int sparse)
}
/* Check 100-byte gap */
- assertEqualInt(100, read(fd, buff, 100));
+ assertEqualInt(100, fread(buff, 1, 100, f));
failure("%s", msg);
for (p = buff; p < buff + 100; ++p) {
failure("offset: %d, %s", (int)(p - buff), msg);
@@ -207,7 +207,7 @@ verify_write_data_block(struct archive *a, int sparse)
}
/* Check second block. */
- assertEqualInt(buff_size, read(fd, buff, buff_size));
+ assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
for (p = buff; p < buff + buff_size; ++p) {
failure("offset: %d, %s", (int)(p - buff), msg);
if (p == buff + buff_size / 2 - 3) {
@@ -218,7 +218,7 @@ verify_write_data_block(struct archive *a, int sparse)
}
/* Check 100-byte gap */
- assertEqualInt(100, read(fd, buff, 100));
+ assertEqualInt(100, fread(buff, 1, 100, f));
failure("%s", msg);
for (p = buff; p < buff + 100; ++p) {
failure("offset: %d, %s", (int)(p - buff), msg);
@@ -227,7 +227,7 @@ verify_write_data_block(struct archive *a, int sparse)
}
/* Check third block. */
- assertEqualInt(buff_size, read(fd, buff, buff_size));
+ assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
for (p = buff; p < buff + buff_size - sizeof(data); ++p) {
failure("offset: %d, %s", (int)(p - buff), msg);
if (!assertEqualInt(0, *p))
@@ -237,7 +237,7 @@ verify_write_data_block(struct archive *a, int sparse)
assertEqualMem(buff + buff_size - sizeof(data), data, sizeof(data));
/* Check another block size beyond last we wrote. */
- assertEqualInt(buff_size, read(fd, buff, buff_size));
+ assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
failure("%s", msg);
for (p = buff; p < buff + buff_size; ++p) {
failure("offset: %d, %s", (int)(p - buff), msg);
@@ -248,7 +248,7 @@ verify_write_data_block(struct archive *a, int sparse)
/* XXX more XXX */
- assertEqualInt(0, close(fd));
+ assertEqualInt(0, fclose(f));
free(buff);
archive_entry_free(ae);
}
diff --git a/lib/libarchive/test/test_write_disk_symlink.c b/lib/libarchive/test/test_write_disk_symlink.c
new file mode 100644
index 0000000..861f3bf
--- /dev/null
+++ b/lib/libarchive/test/test_write_disk_symlink.c
@@ -0,0 +1,117 @@
+/*-
+ * 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$");
+
+/*
+ * Exercise symlink recreation.
+ */
+DEFINE_TEST(test_write_disk_symlink)
+{
+ static const char data[]="abcdefghijklmnopqrstuvwxyz";
+ struct archive *ad;
+ struct archive_entry *ae;
+ int r;
+
+ if (!canSymlink()) {
+ skipping("Symlinks not supported");
+ return;
+ }
+
+ /* Write entries to disk. */
+ assert((ad = archive_write_disk_new()) != NULL);
+
+ /*
+ * First, create a regular file then a symlink to that file.
+ */
+
+ /* Regular file: link1a */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "link1a");
+ archive_entry_set_mode(ae, AE_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);
+
+ /* Symbolic Link: link1b -> link1a */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "link1b");
+ archive_entry_set_mode(ae, AE_IFLNK | 0642);
+ archive_entry_set_size(ae, 0);
+ archive_entry_copy_symlink(ae, "link1a");
+ assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
+ if (r >= ARCHIVE_WARN)
+ assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
+ archive_entry_free(ae);
+
+ /*
+ * We should be able to do this in the other order as well,
+ * of course.
+ */
+
+ /* Symbolic link: link2b -> link2a */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "link2b");
+ archive_entry_set_mode(ae, AE_IFLNK | 0642);
+ archive_entry_unset_size(ae);
+ archive_entry_copy_symlink(ae, "link2a");
+ assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
+ if (r >= ARCHIVE_WARN) {
+ assertEqualInt(ARCHIVE_WARN,
+ archive_write_data(ad, data, sizeof(data)));
+ assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
+ }
+ archive_entry_free(ae);
+
+ /* File: link2a */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_copy_pathname(ae, "link2a");
+ archive_entry_set_mode(ae, AE_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);
+
+ assertEqualInt(ARCHIVE_OK, archive_write_finish(ad));
+
+ /* Test the entries on disk. */
+
+ /* Test #1 */
+ assertIsReg("link1a", -1);
+ assertFileSize("link1a", sizeof(data));
+ assertFileNLinks("link1a", 1);
+ assertIsSymlink("link1b", "link1a");
+
+ /* Test #2: Should produce identical results to test #1 */
+ assertIsReg("link2a", -1);
+ assertFileSize("link2a", sizeof(data));
+ assertFileNLinks("link2a", 1);
+ assertIsSymlink("link2b", "link2a");
+}
diff --git a/lib/libarchive/test/test_write_disk_times.c b/lib/libarchive/test/test_write_disk_times.c
index 2891e36..13841cf 100644
--- a/lib/libarchive/test/test_write_disk_times.c
+++ b/lib/libarchive/test/test_write_disk_times.c
@@ -35,8 +35,6 @@ DEFINE_TEST(test_write_disk_times)
{
struct archive *a;
struct archive_entry *ae;
- struct stat st;
- time_t now = time(NULL);
/* Create an archive_write_disk object. */
assert((a = archive_write_disk_new()) != NULL);
@@ -55,9 +53,8 @@ DEFINE_TEST(test_write_disk_times)
assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a));
archive_entry_free(ae);
/* Verify */
- assertEqualInt(0, stat("file1", &st));
- assertEqualInt(123456, st.st_atime);
- assertEqualInt(234567, st.st_mtime);
+ assertFileAtime("file1", 123456, 0);
+ assertFileMtime("file1", 234567, 0);
/*
* mtime specified, but not atime
@@ -69,11 +66,8 @@ DEFINE_TEST(test_write_disk_times)
assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a));
archive_entry_free(ae);
- /* Verify: Current atime and mtime as specified. */
- assertEqualInt(0, stat("file2", &st));
- assertEqualInt(234567, st.st_mtime);
- failure("now: %ld st.st_atime: %ld", (long)now, (long)st.st_atime);
- assert(st.st_atime >= now && st.st_atime < now + 3);
+ assertFileMtime("file2", 234567, 0);
+ assertFileAtimeRecent("file2");
/*
* atime specified, but not mtime
@@ -86,10 +80,8 @@ DEFINE_TEST(test_write_disk_times)
assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a));
archive_entry_free(ae);
/* Verify: Current mtime and atime as specified. */
- assertEqualInt(0, stat("file3", &st));
- assertEqualInt(345678, st.st_atime);
- failure("now: %ld st.st_mtime: %ld", (long)now, (long)st.st_mtime);
- assert(st.st_mtime >= now && st.st_mtime < now + 3);
+ assertFileAtime("file3", 345678, 0);
+ assertFileMtimeRecent("file3");
/*
* Neither atime nor mtime specified.
@@ -101,11 +93,8 @@ DEFINE_TEST(test_write_disk_times)
assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a));
archive_entry_free(ae);
/* Verify: Current mtime and atime. */
- assertEqualInt(0, stat("file4", &st));
- failure("now: %ld st.st_atime: %ld", (long)now, (long)st.st_atime);
- assert(st.st_atime >= now && st.st_atime < now + 3);
- failure("now: %ld st.st_mtime: %ld", (long)now, (long)st.st_mtime);
- assert(st.st_mtime >= now && st.st_mtime < now + 3);
+ assertFileAtimeRecent("file4");
+ assertFileMtimeRecent("file4");
#if defined(__FreeBSD__)
/*
@@ -120,12 +109,8 @@ DEFINE_TEST(test_write_disk_times)
assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a));
archive_entry_free(ae);
/* Verify */
- /* FreeBSD can only store usec resolution, hence rounding here. */
- assertEqualInt(0, stat("file10", &st));
- assertEqualInt(1234567, st.st_atime);
- assertEqualInt(23000, st.st_atimespec.tv_nsec);
- assertEqualInt(2345678, st.st_mtime);
- assertEqualInt(4000, st.st_mtimespec.tv_nsec);
+ assertFileMtime("file10", 2345678, 4567);
+ assertFileAtime("file10", 1234567, 23456);
/*
* Birthtime, mtime and atime on FreeBSD
@@ -141,14 +126,9 @@ DEFINE_TEST(test_write_disk_times)
assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a));
archive_entry_free(ae);
/* Verify */
- /* FreeBSD can only store usec resolution, hence rounding here. */
- assertEqualInt(0, stat("file11", &st));
- assertEqualInt(1234567, st.st_atime);
- assertEqualInt(23000, st.st_atimespec.tv_nsec);
- assertEqualInt(3456789, st.st_birthtime);
- assertEqualInt(12000, st.st_birthtimespec.tv_nsec);
- assertEqualInt(12345678, st.st_mtime);
- assertEqualInt(4000, st.st_mtimespec.tv_nsec);
+ assertFileAtime("file11", 1234567, 23456);
+ assertFileBirthtime("file11", 3456789, 12345);
+ assertFileMtime("file11", 12345678, 4567);
/*
* Birthtime only on FreeBSD.
@@ -161,14 +141,9 @@ DEFINE_TEST(test_write_disk_times)
assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a));
archive_entry_free(ae);
/* Verify */
- /* FreeBSD can only store usec resolution, hence rounding here. */
- assertEqualInt(0, stat("file12", &st));
- assertEqualInt(3456789, st.st_birthtime);
- assertEqualInt(12000, st.st_birthtimespec.tv_nsec);
- failure("now: %ld st.st_atime: %ld", (long)now, (long)st.st_atime);
- assert(st.st_atime >= now && st.st_atime < now + 3);
- failure("now: %ld st.st_mtime: %ld", (long)now, (long)st.st_mtime);
- assert(st.st_mtime >= now && st.st_mtime < now + 3);
+ assertFileAtimeRecent("file12");
+ assertFileBirthtime("file12", 3456789, 12345);
+ assertFileMtimeRecent("file12");
/*
* mtime only on FreeBSD.
@@ -181,14 +156,9 @@ DEFINE_TEST(test_write_disk_times)
assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a));
archive_entry_free(ae);
/* Verify */
- /* FreeBSD can only store usec resolution, hence rounding here. */
- assertEqualInt(0, stat("file13", &st));
- assertEqualInt(4567890, st.st_birthtime);
- assertEqualInt(23000, st.st_birthtimespec.tv_nsec);
- assertEqualInt(4567890, st.st_mtime);
- assertEqualInt(23000, st.st_mtimespec.tv_nsec);
- failure("now: %ld st.st_atime: %ld", (long)now, (long)st.st_atime);
- assert(st.st_atime >= now && st.st_atime < now + 3);
+ assertFileAtimeRecent("file13");
+ assertFileBirthtime("file13", 4567890, 23456);
+ assertFileMtime("file13", 4567890, 23456);
#else
skipping("Platform-specific time restore tests");
#endif
diff --git a/lib/libarchive/test/test_write_format_cpio_empty.c b/lib/libarchive/test/test_write_format_cpio_empty.c
index 81f17a4..fed26ec0 100644
--- a/lib/libarchive/test/test_write_format_cpio_empty.c
+++ b/lib/libarchive/test/test_write_format_cpio_empty.c
@@ -71,5 +71,5 @@ DEFINE_TEST(test_write_format_cpio_empty)
failure("Empty cpio archive should be exactly 87 bytes, was %d.", used);
assert(used == 87);
failure("Empty cpio archive is incorrectly formatted.");
- assert(memcmp(buff, ref, 87) == 0);
+ assertEqualMem(buff, ref, 87);
}
diff --git a/lib/libarchive/test/test_write_format_cpio_newc.c b/lib/libarchive/test/test_write_format_cpio_newc.c
index 512df74..447d111 100644
--- a/lib/libarchive/test/test_write_format_cpio_newc.c
+++ b/lib/libarchive/test/test_write_format_cpio_newc.c
@@ -52,7 +52,7 @@ DEFINE_TEST(test_write_format_cpio_newc)
{
struct archive *a;
struct archive_entry *entry;
- char *buff, *e;
+ char *buff, *e, *file;
size_t buffsize = 100000;
size_t used;
@@ -99,7 +99,8 @@ DEFINE_TEST(test_write_format_cpio_newc)
assert((entry = archive_entry_new()) != NULL);
archive_entry_set_mtime(entry, 3, 30);
archive_entry_set_pathname(entry, "lnk");
- archive_entry_set_mode(entry, S_IFLNK | 0664);
+ archive_entry_set_mode(entry, 0664);
+ archive_entry_set_filetype(entry, AE_IFLNK);
archive_entry_set_size(entry, 0);
archive_entry_set_uid(entry, 83);
archive_entry_set_gid(entry, 93);
@@ -123,9 +124,10 @@ DEFINE_TEST(test_write_format_cpio_newc)
e = buff;
/* First entry is "file" */
+ file = e;
assert(is_hex(e, 110)); /* Entire header is hex digits. */
assertEqualMem(e + 0, "070701", 6); /* Magic */
- assertEqualMem(e + 6, "00000059", 8); /* ino */
+ assert(memcmp(e + 6, "00000000", 8) != 0); /* ino != 0 */
assertEqualMem(e + 14, "000081b4", 8); /* Mode */
assertEqualMem(e + 22, "00000050", 8); /* uid */
assertEqualMem(e + 30, "0000005a", 8); /* gid */
@@ -166,7 +168,8 @@ DEFINE_TEST(test_write_format_cpio_newc)
/* Third entry is "lnk" */
assert(is_hex(e, 110)); /* Entire header is hex digits. */
assertEqualMem(e + 0, "070701", 6); /* Magic */
- assertEqualMem(e + 6, "00000058", 8); /* ino */
+ assert(memcmp(e + 6, file + 6, 8) != 0); /* ino != file ino */
+ assert(memcmp(e + 6, "00000000", 8) != 0); /* ino != 0 */
assertEqualMem(e + 14, "0000a1b4", 8); /* Mode */
assertEqualMem(e + 22, "00000053", 8); /* uid */
assertEqualMem(e + 30, "0000005d", 8); /* gid */
diff --git a/lib/libarchive/test/test_write_format_cpio_odc.c b/lib/libarchive/test/test_write_format_cpio_odc.c
index 73cc3e6..309e003 100644
--- a/lib/libarchive/test/test_write_format_cpio_odc.c
+++ b/lib/libarchive/test/test_write_format_cpio_odc.c
@@ -46,7 +46,7 @@ DEFINE_TEST(test_write_format_cpio_odc)
{
struct archive *a;
struct archive_entry *entry;
- char *buff, *e;
+ char *buff, *e, *file;
size_t buffsize = 100000;
size_t used;
@@ -109,7 +109,8 @@ DEFINE_TEST(test_write_format_cpio_odc)
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_mode(entry, 0664);
+ archive_entry_set_filetype(entry, AE_IFLNK);
archive_entry_set_symlink(entry,"file");
archive_entry_set_size(entry, 0);
archive_entry_set_uid(entry, 88);
@@ -130,14 +131,29 @@ DEFINE_TEST(test_write_format_cpio_odc)
/*
* Verify the archive format.
+ *
+ * Notes on the ino validation: cpio does not actually require
+ * that the ino values written to the archive match those read
+ * from disk. It really requires that:
+ * * matching non-zero ino values be written as matching
+ * non-zero values
+ * * non-matching non-zero ino values be written as non-matching
+ * non-zero values
+ * Libarchive further ensures that zero ino values get written
+ * as zeroes. This allows the cpio writer to generate
+ * synthetic ino values for the archive that may be different
+ * than those on disk in order to avoid problems due to truncation.
+ * This is especially needed for odc (POSIX format) that
+ * only supports 18-bit ino values.
*/
e = buff;
/* "file" */
+ file = e; /* Remember where this starts... */
assert(is_octal(e, 76)); /* Entire header is octal digits. */
assertEqualMem(e + 0, "070707", 6); /* Magic */
assertEqualMem(e + 6, "000014", 6); /* dev */
- assertEqualMem(e + 12, "000131", 6); /* ino */
+ assert(memcmp(e + 12, "000000", 6) != 0); /* ino must be != 0 */
assertEqualMem(e + 18, "100664", 6); /* Mode */
assertEqualMem(e + 24, "000120", 6); /* uid */
assertEqualMem(e + 30, "000132", 6); /* gid */
@@ -154,7 +170,7 @@ DEFINE_TEST(test_write_format_cpio_odc)
assert(is_octal(e, 76)); /* Entire header is octal digits. */
assertEqualMem(e + 0, "070707", 6); /* Magic */
assertEqualMem(e + 6, "000014", 6); /* dev */
- assertEqualMem(e + 12, "000131", 6); /* ino */
+ assertEqualMem(e + 12, file + 12, 6); /* ino must match above */
assertEqualMem(e + 18, "100664", 6); /* Mode */
assertEqualMem(e + 24, "000120", 6); /* uid */
assertEqualMem(e + 30, "000132", 6); /* gid */
@@ -187,7 +203,8 @@ DEFINE_TEST(test_write_format_cpio_odc)
assert(is_octal(e, 76)); /* Entire header is octal digits. */
assertEqualMem(e + 0, "070707", 6); /* Magic */
assertEqualMem(e + 6, "000014", 6); /* dev */
- assertEqualMem(e + 12, "000132", 6); /* ino */
+ assert(memcmp(e + 12, file + 12, 6) != 0); /* ino must != file ino */
+ assert(memcmp(e + 12, "000000", 6) != 0); /* ino must != 0 */
assertEqualMem(e + 18, "120664", 6); /* Mode */
assertEqualMem(e + 24, "000130", 6); /* uid */
assertEqualMem(e + 30, "000142", 6); /* gid */
diff --git a/lib/libarchive/test/test_write_format_tar_ustar.c b/lib/libarchive/test/test_write_format_tar_ustar.c
index 3adacb4..f66fd7a 100644
--- a/lib/libarchive/test/test_write_format_tar_ustar.c
+++ b/lib/libarchive/test/test_write_format_tar_ustar.c
@@ -133,7 +133,8 @@ DEFINE_TEST(test_write_format_tar_ustar)
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_mode(entry, 0664);
+ archive_entry_set_filetype(entry, AE_IFLNK);
archive_entry_set_symlink(entry,"file");
archive_entry_set_size(entry, 0);
archive_entry_set_uid(entry, 88);
diff --git a/lib/libarchive/test/test_write_format_zip.c b/lib/libarchive/test/test_write_format_zip.c
new file mode 100644
index 0000000..f4c51f3
--- /dev/null
+++ b/lib/libarchive/test/test_write_format_zip.c
@@ -0,0 +1,180 @@
+/*-
+ * Copyright (c) 2003-2008 Tim Kientzle
+ * Copyright (c) 2008 Anselm Strauss
+ * 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.
+ */
+
+/*
+ * Development supported by Google Summer of Code 2008.
+ */
+
+/* TODO: reader does not yet restore permissions. */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_write_format_zip)
+{
+ char filedata[64];
+ struct archive_entry *ae;
+ struct archive *a;
+ size_t used;
+ size_t buffsize = 1000000;
+ char *buff;
+ const char *compression_type;
+
+ buff = malloc(buffsize);
+
+ /* Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a));
+#ifdef HAVE_ZLIB_H
+ compression_type = "zip:compression=deflate";
+#else
+ compression_type = "zip:compression=store";
+#endif
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_format_options(a, compression_type));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_open_memory(a, buff, buffsize, &used));
+
+ /*
+ * Write a file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "file");
+ assertEqualString("file", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
+ archive_entry_set_size(ae, 8);
+
+ assertEqualInt(0, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualInt(8, archive_write_data(a, "12345678", 9));
+ assertEqualInt(0, archive_write_data(a, "1", 1));
+
+ /*
+ * Write another file to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 1, 10);
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(10, archive_entry_mtime_nsec(ae));
+ archive_entry_copy_pathname(ae, "file2");
+ assertEqualString("file2", archive_entry_pathname(ae));
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
+ archive_entry_set_size(ae, 4);
+
+ assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualInt(4, archive_write_data(a, "1234", 5));
+
+ /*
+ * Write a directory to it.
+ */
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_mtime(ae, 11, 110);
+ archive_entry_copy_pathname(ae, "dir");
+ archive_entry_set_mode(ae, S_IFDIR | 0755);
+ archive_entry_set_size(ae, 512);
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ failure("size should be zero so that applications know not to write");
+ assertEqualInt(0, archive_entry_size(ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));
+
+ /* Close out the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_write_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+
+ /*
+ * Now, read the data back.
+ */
+ ae = NULL;
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, buff, used));
+
+ /*
+ * Read and verify first file.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(1, archive_entry_mtime(ae));
+ /* Zip doesn't store high-resolution mtime. */
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
+ //assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 8,
+ archive_read_data(a, filedata, sizeof(filedata)));
+ assertEqualMem(filedata, "12345678", 8);
+
+
+ /*
+ * Read the second file back.
+ */
+ if (!assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae))){
+ free(buff);
+ return;
+ }
+ assertEqualInt(1, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ //assert((S_IFREG | 0755) == archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 4,
+ archive_read_data(a, filedata, sizeof(filedata)));
+ assertEqualMem(filedata, "1234", 4);
+
+ /*
+ * Read the dir entry back.
+ */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt(11, archive_entry_mtime(ae));
+ assertEqualInt(0, archive_entry_mtime_nsec(ae));
+ assertEqualInt(0, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_ctime(ae));
+ assertEqualString("dir/", archive_entry_pathname(ae));
+ //assertEqualInt((S_IFDIR | 0755), archive_entry_mode(ae));
+ assertEqualInt(0, archive_entry_size(ae));
+ assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));
+
+ /* Verify the end of the archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ free(buff);
+}
diff --git a/lib/libarchive/test/test_write_format_zip_empty.c b/lib/libarchive/test/test_write_format_zip_empty.c
new file mode 100644
index 0000000..ef90b8d
--- /dev/null
+++ b/lib/libarchive/test/test_write_format_zip_empty.c
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2008 Anselm Strauss
+ * 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.
+ */
+
+/*
+ * Development supported by Google Summer of Code 2008.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_write_format_zip_empty)
+{
+ struct archive *a;
+ char buff[256];
+ size_t used;
+
+ /* Zip format: Create a new archive in memory. */
+ assert((a = archive_write_new()) != NULL);
+ assertA(0 == archive_write_set_format_zip(a));
+ assertA(0 == archive_write_set_compression_none(a));
+ assertA(0 == archive_write_set_bytes_per_block(a, 1));
+ assertA(0 == archive_write_set_bytes_in_last_block(a, 1));
+ assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ /* Close out the archive without writing anything. */
+ assertA(0 == archive_write_close(a));
+ assertA(0 == archive_write_finish(a));
+
+ /* Verify the correct format for an empy Zip archive. */
+ assertEqualInt(used, 22);
+ assertEqualMem(buff,
+ "PK\005\006\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
+ 22);
+}
diff --git a/lib/libarchive/test/test_write_format_zip_no_compression.c b/lib/libarchive/test/test_write_format_zip_no_compression.c
new file mode 100644
index 0000000..63e76b6
--- /dev/null
+++ b/lib/libarchive/test/test_write_format_zip_no_compression.c
@@ -0,0 +1,304 @@
+/*-
+ * Copyright (c) 2008 Anselm Strauss
+ * 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.
+ */
+
+/*
+ * Development supported by Google Summer of Code 2008.
+ */
+
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static unsigned long
+bitcrc32(unsigned long c, void *_p, size_t s)
+{
+ /* This is a drop-in replacement for crc32() from zlib.
+ * Libarchive should be able to correctly generate
+ * uncompressed zip archives (including correct CRCs) even
+ * when zlib is unavailable, and this function helps us verify
+ * that. Yes, this is very, very slow and unsuitable for
+ * production use, but it's correct, compact, and works well
+ * enough for this particular usage. Libarchive internally
+ * uses a much more efficient implementation. */
+ const unsigned char *p = _p;
+ int bitctr;
+
+ if (p == NULL)
+ return (0);
+
+ for (; s > 0; --s) {
+ c ^= *p++;
+ for (bitctr = 8; bitctr > 0; --bitctr) {
+ if (c & 1) c = (c >> 1);
+ else c = (c >> 1) ^ 0xedb88320;
+ c ^= 0x80000000;
+ }
+ }
+ return (c);
+}
+
+/* Quick and dirty: Read 2-byte and 4-byte integers from Zip file. */
+static int i2(const char *p) { return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); }
+static int i4(const char *p) { return (i2(p) | (i2(p + 2) << 16)); }
+
+DEFINE_TEST(test_write_format_zip_no_compression)
+{
+ /* Buffer data */
+ struct archive *a;
+ struct archive_entry *entry;
+ char buff[100000];
+ const char *buffend;
+ /* p is the pointer to walk over the central directory,
+ * q walks over the local headers, the data and the data descriptors. */
+ const char *p, *q;
+ size_t used;
+
+ /* File data */
+ char file_name[] = "file";
+ char file_data1[] = {'1', '2', '3', '4', '5'};
+ char file_data2[] = {'6', '7', '8', '9', '0'};
+ int file_perm = 00644;
+ short file_uid = 10;
+ short file_gid = 20;
+
+ /* Folder data */
+ char folder_name[] = "folder/";
+ int folder_perm = 00755;
+ short folder_uid = 30;
+ short folder_gid = 40;
+
+ /* Time data */
+ time_t t = time(NULL);
+ struct tm *tm = localtime(&t);
+
+ /* Misc variables */
+ unsigned long crc;
+
+ /* Create new ZIP archive in memory without padding. */
+ assert((a = archive_write_new()) != NULL);
+ assertA(0 == archive_write_set_format_zip(a));
+ assertA(0 == archive_write_set_format_options(a, "zip:compression=store"));
+ assertA(0 == archive_write_set_compression_none(a));
+ assertA(0 == archive_write_set_bytes_per_block(a, 1));
+ assertA(0 == archive_write_set_bytes_in_last_block(a, 1));
+ assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
+
+ /* Write entries. */
+
+ /* Regular file */
+ assert((entry = archive_entry_new()) != NULL);
+ archive_entry_set_pathname(entry, file_name);
+ archive_entry_set_mode(entry, S_IFREG | 0644);
+ archive_entry_set_size(entry, sizeof(file_data1) + sizeof(file_data2));
+ archive_entry_set_uid(entry, file_uid);
+ archive_entry_set_gid(entry, file_gid);
+ archive_entry_set_mtime(entry, t, 0);
+ archive_entry_set_atime(entry, t, 0);
+ archive_entry_set_ctime(entry, t, 0);
+ assertEqualIntA(a, 0, archive_write_header(a, entry));
+ assertEqualIntA(a, sizeof(file_data1), archive_write_data(a, file_data1, sizeof(file_data1)));
+ assertEqualIntA(a, sizeof(file_data2), archive_write_data(a, file_data2, sizeof(file_data2)));
+ archive_entry_free(entry);
+
+ /* Folder */
+ assert((entry = archive_entry_new()) != NULL);
+ archive_entry_set_pathname(entry, folder_name);
+ archive_entry_set_mode(entry, S_IFDIR | folder_perm);
+ archive_entry_set_size(entry, 0);
+ archive_entry_set_uid(entry, folder_uid);
+ archive_entry_set_gid(entry, folder_gid);
+ archive_entry_set_mtime(entry, t, 0);
+ archive_entry_set_atime(entry, t, 0);
+ archive_entry_set_ctime(entry, t, 0);
+ assertEqualIntA(a, 0, archive_write_header(a, entry));
+ archive_entry_free(entry);
+
+ /* Close the archive . */
+ assertA(0 == archive_write_close(a));
+ assertA(0 == archive_write_finish(a));
+
+ /* Remember the end of the archive in memory. */
+ buffend = buff + used;
+
+ /* Verify "End of Central Directory" record. */
+ /* Get address of end-of-central-directory record. */
+ p = buffend - 22; /* Assumes there is no zip comment field. */
+ failure("End-of-central-directory begins with PK\\005\\006 signature");
+ assertEqualMem(p, "PK\005\006", 4);
+ failure("This must be disk 0");
+ assertEqualInt(i2(p + 4), 0);
+ failure("Central dir must start on disk 0");
+ assertEqualInt(i2(p + 6), 0);
+ failure("All central dir entries are on this disk");
+ assertEqualInt(i2(p + 8), i2(p + 10));
+ failure("CD start (%d) + CD length (%d) should == archive size - 22",
+ i4(p + 12), i4(p + 16));
+ assertEqualInt(i4(p + 12) + i4(p + 16), used - 22);
+ failure("no zip comment");
+ assertEqualInt(i2(p + 20), 0);
+
+ /* Get address of first entry in central directory. */
+ p = buff + i4(buffend - 6);
+ failure("Central file record at offset %d should begin with"
+ " PK\\001\\002 signature",
+ i4(buffend - 10));
+
+ /* Verify file entry in central directory. */
+ assertEqualMem(p, "PK\001\002", 4); /* Signature */
+ assertEqualInt(i2(p + 4), 3 * 256 + 20); /* Version made by */
+ assertEqualInt(i2(p + 6), 20); /* Version needed to extract */
+ assertEqualInt(i2(p + 8), 8); /* Flags */
+ assertEqualInt(i2(p + 10), 0); /* Compression method */
+ assertEqualInt(i2(p + 12), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */
+ assertEqualInt(i2(p + 14), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */
+ crc = bitcrc32(0, file_data1, sizeof(file_data1));
+ crc = bitcrc32(crc, file_data2, sizeof(file_data2));
+ assertEqualInt(i4(p + 16), crc); /* CRC-32 */
+ assertEqualInt(i4(p + 20), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */
+ assertEqualInt(i4(p + 24), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */
+ assertEqualInt(i2(p + 28), strlen(file_name)); /* Pathname length */
+ assertEqualInt(i2(p + 30), 13); /* Extra field length */
+ assertEqualInt(i2(p + 32), 0); /* File comment length */
+ assertEqualInt(i2(p + 34), 0); /* Disk number start */
+ assertEqualInt(i2(p + 36), 0); /* Internal file attrs */
+ assertEqualInt(i4(p + 38) >> 16 & 01777, file_perm); /* External file attrs */
+ assertEqualInt(i4(p + 42), 0); /* Offset of local header */
+ assertEqualMem(p + 46, file_name, strlen(file_name)); /* Pathname */
+ p = p + 46 + strlen(file_name);
+ assertEqualInt(i2(p), 0x5455); /* 'UT' extension header */
+ assertEqualInt(i2(p + 2), 5); /* 'UT' size */
+ assertEqualInt(p[4], 7); /* 'UT' flags */
+ assertEqualInt(i4(p + 5), t); /* 'UT' mtime */
+ p = p + 9;
+ assertEqualInt(i2(p), 0x7855); /* 'Ux' extension header */
+ assertEqualInt(i2(p + 2), 0); /* 'Ux' size */
+ p = p + 4;
+
+ /* Verify local header of file entry. */
+ q = buff;
+ assertEqualMem(q, "PK\003\004", 4); /* Signature */
+ assertEqualInt(i2(q + 4), 20); /* Version needed to extract */
+ assertEqualInt(i2(q + 6), 8); /* Flags */
+ assertEqualInt(i2(q + 8), 0); /* Compression method */
+ assertEqualInt(i2(q + 10), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */
+ assertEqualInt(i2(q + 12), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */
+ assertEqualInt(i4(q + 14), 0); /* CRC-32 */
+ assertEqualInt(i4(q + 18), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */
+ assertEqualInt(i4(q + 22), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */
+ assertEqualInt(i2(q + 26), strlen(file_name)); /* Pathname length */
+ assertEqualInt(i2(q + 28), 25); /* Extra field length */
+ assertEqualMem(q + 30, file_name, strlen(file_name)); /* Pathname */
+ q = q + 30 + strlen(file_name);
+ assertEqualInt(i2(q), 0x5455); /* 'UT' extension header */
+ assertEqualInt(i2(q + 2), 13); /* 'UT' size */
+ assertEqualInt(q[4], 7); /* 'UT' flags */
+ assertEqualInt(i4(q + 5), t); /* 'UT' mtime */
+ assertEqualInt(i4(q + 9), t); /* 'UT' atime */
+ assertEqualInt(i4(q + 13), t); /* 'UT' ctime */
+ q = q + 17;
+ assertEqualInt(i2(q), 0x7855); /* 'Ux' extension header */
+ assertEqualInt(i2(q + 2), 4); /* 'Ux' size */
+ assertEqualInt(i2(q + 4), file_uid); /* 'Ux' UID */
+ assertEqualInt(i2(q + 6), file_gid); /* 'Ux' GID */
+ q = q + 8;
+
+ /* Verify data of file entry. */
+ assertEqualMem(q, file_data1, sizeof(file_data1));
+ assertEqualMem(q + sizeof(file_data1), file_data2, sizeof(file_data2));
+ q = q + sizeof(file_data1) + sizeof(file_data2);
+
+ /* Verify data descriptor of file entry. */
+ assertEqualMem(q, "PK\007\010", 4); /* Signature */
+ assertEqualInt(i4(q + 4), crc); /* CRC-32 */
+ assertEqualInt(i4(q + 8), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */
+ assertEqualInt(i4(q + 12), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */
+ q = q + 16;
+
+ /* Verify folder entry in central directory. */
+ assertEqualMem(p, "PK\001\002", 4); /* Signature */
+ assertEqualInt(i2(p + 4), 3 * 256 + 20); /* Version made by */
+ assertEqualInt(i2(p + 6), 20); /* Version needed to extract */
+ assertEqualInt(i2(p + 8), 8); /* Flags */
+ assertEqualInt(i2(p + 10), 0); /* Compression method */
+ assertEqualInt(i2(p + 12), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */
+ assertEqualInt(i2(p + 14), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */
+ crc = 0;
+ assertEqualInt(i4(p + 16), crc); /* CRC-32 */
+ assertEqualInt(i4(p + 20), 0); /* Compressed size */
+ assertEqualInt(i4(p + 24), 0); /* Uncompressed size */
+ assertEqualInt(i2(p + 28), strlen(folder_name)); /* Pathname length */
+ assertEqualInt(i2(p + 30), 13); /* Extra field length */
+ assertEqualInt(i2(p + 32), 0); /* File comment length */
+ assertEqualInt(i2(p + 34), 0); /* Disk number start */
+ assertEqualInt(i2(p + 36), 0); /* Internal file attrs */
+ assertEqualInt(i4(p + 38) >> 16 & 01777, folder_perm); /* External file attrs */
+ assertEqualInt(i4(p + 42), q - buff); /* Offset of local header */
+ assertEqualMem(p + 46, folder_name, strlen(folder_name)); /* Pathname */
+ p = p + 46 + strlen(folder_name);
+ assertEqualInt(i2(p), 0x5455); /* 'UT' extension header */
+ assertEqualInt(i2(p + 2), 5); /* 'UT' size */
+ assertEqualInt(p[4], 7); /* 'UT' flags */
+ assertEqualInt(i4(p + 5), t); /* 'UT' mtime */
+ p = p + 9;
+ assertEqualInt(i2(p), 0x7855); /* 'Ux' extension header */
+ assertEqualInt(i2(p + 2), 0); /* 'Ux' size */
+ p = p + 4;
+
+ /* Verify local header of folder entry. */
+ assertEqualMem(q, "PK\003\004", 4); /* Signature */
+ assertEqualInt(i2(q + 4), 20); /* Version needed to extract */
+ assertEqualInt(i2(q + 6), 8); /* Flags */
+ assertEqualInt(i2(q + 8), 0); /* Compression method */
+ assertEqualInt(i2(q + 10), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */
+ assertEqualInt(i2(q + 12), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */
+ assertEqualInt(i4(q + 14), 0); /* CRC-32 */
+ assertEqualInt(i4(q + 18), 0); /* Compressed size */
+ assertEqualInt(i4(q + 22), 0); /* Uncompressed size */
+ assertEqualInt(i2(q + 26), strlen(folder_name)); /* Pathname length */
+ assertEqualInt(i2(q + 28), 25); /* Extra field length */
+ assertEqualMem(q + 30, folder_name, strlen(folder_name)); /* Pathname */
+ q = q + 30 + strlen(folder_name);
+ assertEqualInt(i2(q), 0x5455); /* 'UT' extension header */
+ assertEqualInt(i2(q + 2), 13); /* 'UT' size */
+ assertEqualInt(q[4], 7); /* 'UT' flags */
+ assertEqualInt(i4(q + 5), t); /* 'UT' mtime */
+ assertEqualInt(i4(q + 9), t); /* 'UT' atime */
+ assertEqualInt(i4(q + 13), t); /* 'UT' ctime */
+ q = q + 17;
+ assertEqualInt(i2(q), 0x7855); /* 'Ux' extension header */
+ assertEqualInt(i2(q + 2), 4); /* 'Ux' size */
+ assertEqualInt(i2(q + 4), folder_uid); /* 'Ux' UID */
+ assertEqualInt(i2(q + 6), folder_gid); /* 'Ux' GID */
+ q = q + 8;
+
+ /* There should not be any data in the folder entry,
+ * meaning next is the data descriptor header. */
+
+ /* Verify data descriptor of folder entry. */
+ assertEqualMem(q, "PK\007\010", 4); /* Signature */
+ assertEqualInt(i4(q + 4), crc); /* CRC-32 */
+ assertEqualInt(i4(q + 8), 0); /* Compressed size */
+ assertEqualInt(i4(q + 12), 0); /* Uncompressed size */
+ q = q + 16;
+}
OpenPOWER on IntegriCloud