summaryrefslogtreecommitdiff
path: root/contrib/libarchive
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2017-03-02 22:59:35 +0000
committerMartin Matuska <mm@FreeBSD.org>2017-03-02 22:59:35 +0000
commit642870485c089b57000fe538d3485e272b038d59 (patch)
treeeb88fb7d23d0c851d0e21ab26701dce90d7e7aff /contrib/libarchive
parente052a8b932e5ff38489ab517d092fd05ba650cb0 (diff)
parent46ab065716a6ecbe96471bebf59ab452a0edcdac (diff)
downloadsrc-test2-642870485c089b57000fe538d3485e272b038d59.tar.gz
src-test2-642870485c089b57000fe538d3485e272b038d59.zip
MFV r314565,314567,314570:
Update libarchive to version 3.3.1 (and sync with latest vendor dist) Notable vendor changes: PR #501: improvements in ACL path handling PR #724: fix hang when reading malformed cpio files PR #864: fix out of bounds read with malformed GNU tar archives Documentation, style, test suite improvements and typo fixes. New options to bsdtar that enable or disable reading and/or writing of: Access Control Lists (--acls, --no-acls) Extended file flags (--fflags, --no-fflags) Extended attributes (--xattrs, --no-xattrs) Mac OS X metadata (Mac OS X only) (--mac-metadata, --no-mac-metadata) MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=314571
Diffstat (limited to 'contrib/libarchive')
-rw-r--r--contrib/libarchive/NEWS8
-rw-r--r--contrib/libarchive/cat/test/test.h336
-rw-r--r--contrib/libarchive/cat/test/test_version.c67
-rw-r--r--contrib/libarchive/cpio/cpio.c10
-rw-r--r--contrib/libarchive/cpio/test/main.c3073
-rw-r--r--contrib/libarchive/cpio/test/test.h338
-rw-r--r--contrib/libarchive/cpio/test/test_option_version.c88
-rw-r--r--contrib/libarchive/libarchive/archive.h8
-rw-r--r--contrib/libarchive/libarchive/archive_check_magic.c2
-rw-r--r--contrib/libarchive/libarchive/archive_digest_private.h1
-rw-r--r--contrib/libarchive/libarchive/archive_entry.c130
-rw-r--r--contrib/libarchive/libarchive/archive_entry.h27
-rw-r--r--contrib/libarchive/libarchive/archive_entry_acl.32
-rw-r--r--contrib/libarchive/libarchive/archive_entry_paths.312
-rw-r--r--contrib/libarchive/libarchive/archive_entry_perms.34
-rw-r--r--contrib/libarchive/libarchive/archive_hmac.c4
-rw-r--r--contrib/libarchive/libarchive/archive_platform.h18
-rw-r--r--contrib/libarchive/libarchive/archive_read_disk.322
-rw-r--r--contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c447
-rw-r--r--contrib/libarchive/libarchive/archive_read_disk_posix.c64
-rw-r--r--contrib/libarchive/libarchive/archive_read_disk_private.h12
-rw-r--r--contrib/libarchive/libarchive/archive_read_format.36
-rw-r--r--contrib/libarchive/libarchive/archive_read_open.32
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_tar.c5
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_warc.c23
-rw-r--r--contrib/libarchive/libarchive/archive_write_data.324
-rw-r--r--contrib/libarchive/libarchive/archive_write_disk.379
-rw-r--r--contrib/libarchive/libarchive/archive_write_disk_acl.c181
-rw-r--r--contrib/libarchive/libarchive/archive_write_disk_posix.c97
-rw-r--r--contrib/libarchive/libarchive/archive_write_finish_entry.35
-rw-r--r--contrib/libarchive/libarchive/archive_write_format.31
-rw-r--r--contrib/libarchive/libarchive/archive_write_set_format_iso9660.c6
-rw-r--r--contrib/libarchive/libarchive/test/test.h390
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_nfs4.c12
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_pax.c25
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c175
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c189
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_posix1e.c15
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_text.c28
-rw-r--r--contrib/libarchive/libarchive/test/test_archive_api_feature.c8
-rw-r--r--contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c10
-rw-r--r--contrib/libarchive/libarchive/test/test_compat_star_acl.c12
-rw-r--r--contrib/libarchive/libarchive/test/test_fuzz.c3
-rw-r--r--contrib/libarchive/libarchive/test/test_read_disk.c6
-rw-r--r--contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c14
-rw-r--r--contrib/libarchive/tar/bsdtar.1103
-rw-r--r--contrib/libarchive/tar/bsdtar.c123
-rw-r--r--contrib/libarchive/tar/bsdtar.h59
-rw-r--r--contrib/libarchive/tar/cmdline.c12
-rw-r--r--contrib/libarchive/tar/read.c19
-rw-r--r--contrib/libarchive/tar/test/main.c3072
-rw-r--r--contrib/libarchive/tar/test/test.h338
-rw-r--r--contrib/libarchive/tar/test/test_option_acls.c471
-rw-r--r--contrib/libarchive/tar/test/test_option_fflags.c106
-rw-r--r--contrib/libarchive/tar/test/test_option_nodump.c2
-rw-r--r--contrib/libarchive/tar/test/test_version.c73
-rw-r--r--contrib/libarchive/tar/util.c2
-rw-r--r--contrib/libarchive/tar/write.c21
-rw-r--r--contrib/libarchive/test_utils/test_common.h467
-rw-r--r--contrib/libarchive/test_utils/test_main.c (renamed from contrib/libarchive/cat/test/main.c)728
60 files changed, 2970 insertions, 8615 deletions
diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS
index 7b5c31f75c7d..281c1768c30b 100644
--- a/contrib/libarchive/NEWS
+++ b/contrib/libarchive/NEWS
@@ -1,3 +1,9 @@
+Feb 26, 2017: libarchive 3.3.1 released
+ Security & Feature release
+
+Feb 19, 2017: libarchive 3.3.0 released
+ Security & Feature release
+
Jan 29, 2017: Limited NFSv4 ACL support for Mac OS (Darwin)
Jan 10, 2017: POSIX.1e and NFSv4 ACL support for Solaris and derivates
@@ -5,6 +11,8 @@ Jan 10, 2017: POSIX.1e and NFSv4 ACL support for Solaris and derivates
Dec 27, 2016: NFSv4 ACL read and write support for pax
Deprecated functions: archive_entry_acl_text(), archive_entry_acl_text_w()
+Nov, 2016: libarchive is now being tested by the OSS-Fuzz project
+
Oct 26, 2016: Remove liblzmadec support
Oct 23, 2016: libarchive 3.2.2 released
diff --git a/contrib/libarchive/cat/test/test.h b/contrib/libarchive/cat/test/test.h
index c002a2c27eee..350bcad63464 100644
--- a/contrib/libarchive/cat/test/test.h
+++ b/contrib/libarchive/cat/test/test.h
@@ -27,328 +27,14 @@
/* Every test program should #include "test.h" as the first thing. */
-/*
- * The goal of this file (and the matching test.c) is to
- * simplify the very repetitive test-*.c test programs.
- */
-#if defined(HAVE_CONFIG_H)
-/* Most POSIX platforms use the 'configure' script to build config.h */
-#include "config.h"
-#elif defined(__FreeBSD__)
-/* Building as part of FreeBSD system requires a pre-built config.h. */
-#include "config_freebsd.h"
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-/* Win32 can't run the 'configure' script. */
-#include "config_windows.h"
-#else
-/* Warn if the library hasn't been (automatically or manually) configured. */
-#error Oops: No config.h and no pre-built configuration in test.h.
-#endif
-
-#include <sys/types.h> /* Windows requires this before sys/stat.h */
-#include <sys/stat.h>
-
-#if HAVE_DIRENT_H
-#include <dirent.h>
-#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 <ctype.h>
-#include <time.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <wchar.h>
-#ifdef HAVE_WINDOWS_H
-#include <windows.h>
-#endif
-
-/*
- * System-specific tweaks. We really want to minimize these
- * as much as possible, since they make it harder to understand
- * the mainline code.
- */
-
-/* Windows (including Visual Studio and MinGW but not Cygwin) */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#if !defined(__BORLANDC__)
-#undef chdir
-#define chdir _chdir
-#define strdup _strdup
-#endif
-#endif
-
-/* Visual Studio */
-#if defined(_MSC_VER) && _MSC_VER < 1900
-#define snprintf sprintf_s
-#endif
-
-#if defined(__BORLANDC__)
-#pragma warn -8068 /* Constant out of range in comparison. */
-#endif
-
-/* Haiku OS and QNX */
-#if defined(__HAIKU__) || defined(__QNXNTO__)
-/* Haiku and QNX have 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
-#define O_BINARY 0
-#endif
-
-/*
- * Redefine DEFINE_TEST for use in defining the test functions.
- */
-#undef DEFINE_TEST
-#define DEFINE_TEST(name) void name(void); void name(void)
-
-/* An implementation of the standard assert() macro */
-#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) \
- 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) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
-#define assertEqualUTF8String(v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
-/* As above, but v1 and v2 are wchar_t * */
-#define assertEqualWString(v1,v2) \
- assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-/* As above, but raw blocks of bytes. */
-#define assertEqualMem(v1, v2, l) \
- assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
-/* Assert that memory is full of a specified byte */
-#define assertMemoryFilledWith(v1, l, b) \
- assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
-/* Assert two files are the same. */
-#define assertEqualFile(f1, f2) \
- assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
-/* Assert that a file is empty. */
-#define assertEmptyFile(pathname) \
- assertion_empty_file(__FILE__, __LINE__, (pathname))
-/* Assert that a file is not empty. */
-#define assertNonEmptyFile(pathname) \
- assertion_non_empty_file(__FILE__, __LINE__, (pathname))
-#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(pathname) \
- assertion_file_exists(__FILE__, __LINE__, pathname)
-/* Assert that a file exists. */
-#define assertFileNotExists(pathname) \
- assertion_file_not_exists(__FILE__, __LINE__, pathname)
-/* Assert that file contents match a string. */
-#define assertFileContents(data, data_size, pathname) \
- assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
-/* Verify that a file does not contain invalid strings */
-#define assertFileContainsNoInvalidStrings(pathname, strings) \
- assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
-#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 assertFileMode(pathname, mode) \
- assertion_file_mode(__FILE__, __LINE__, pathname, mode)
-#define assertTextFileContents(text, pathname) \
- assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
-#define assertFileContainsLinesAnyOrder(pathname, lines) \
- assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
-#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, -1, contents)
-#define assertMakeBinFile(path, mode, csize, contents) \
- assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
-#define assertMakeHardlink(newfile, oldfile) \
- assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
-#define assertMakeSymlink(newfile, linkto) \
- assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
-#define assertNodump(path) \
- assertion_nodump(__FILE__, __LINE__, path)
-#define assertUmask(mask) \
- assertion_umask(__FILE__, __LINE__, mask)
-#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
- assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
-
-/*
- * This would be simple with C99 variadic macros, but I don't want to
- * require that. Instead, I insert a function call before each
- * skipping() call to pass the file and line information down. Crude,
- * but effective.
- */
-#define skipping \
- skipping_setup(__FILE__, __LINE__);test_skipping
-
-/* Function declarations. These are defined in test_utility.c. */
-void failure(const char *fmt, ...);
-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, const char *);
-int assertion_equal_file(const char *, int, 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_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
-int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
-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_contains_lines_any_order(const char *, int, const char *, const char **);
-int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
-int assertion_file_contents(const char *, int, const void *, int, const char *);
-int assertion_file_exists(const char *, int, const char *);
-int assertion_file_mode(const char *, int, const char *, int);
-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, 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, int, const void *);
-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_nodump(const char *, int, const char *);
-int assertion_non_empty_file(const char *, int, const char *);
-int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
-int assertion_umask(const char *, int, int);
-int assertion_utimes(const char *, int, const char *, long, long, long, long );
-
-void skipping_setup(const char *, int);
-void test_skipping(const char *fmt, ...);
-
-/* 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 "bzip2" program. */
-int canBzip2(void);
-
-/* Return true if this platform can run the "grzip" program. */
-int canGrzip(void);
-
-/* Return true if this platform can run the "gzip" program. */
-int canGzip(void);
-
-/* Return true if this platform can run the specified command. */
-int canRunCommand(const char *);
-
-/* Return true if this platform can run the "lrzip" program. */
-int canLrzip(void);
-
-/* Return true if this platform can run the "lz4" program. */
-int canLz4(void);
-
-/* Return true if this platform can run the "lzip" program. */
-int canLzip(void);
-
-/* Return true if this platform can run the "lzma" program. */
-int canLzma(void);
-
-/* Return true if this platform can run the "lzop" program. */
-int canLzop(void);
-
-/* Return true if this platform can run the "xz" program. */
-int canXz(void);
-
-/* Return true if this filesystem can handle nodump flags. */
-int canNodump(void);
-
-/* Return true if the file has large i-node number(>0xffffffff). */
-int is_LargeInode(const char *);
-
-/* 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, ...);
-
-/* Dump block of bytes to a file. */
-void dumpfile(const char *filename, void *, size_t);
-
-/* Extracts named reference file to the current directory. */
-void extract_reference_file(const char *);
-/* Copies named reference file to the current directory. */
-void copy_reference_file(const char *);
-
-/* Extracts a list of files to the current directory.
- * List must be NULL terminated.
- */
-void extract_reference_files(const char **);
-
-/* Subtract umask from mode */
-mode_t umasked(mode_t expected_mode);
-
-/* Path to working directory for current test */
-extern const char *testworkdir;
-
-/*
- * Special interfaces for program test harness.
- */
-
-/* Pathname of exe to be tested. */
-extern const char *testprogfile;
-/* Name of exe to use in printf-formatted command strings. */
-/* On Windows, this includes leading/trailing quotes. */
-extern const char *testprog;
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#endif
+#define KNOWNREF "test_expand.Z.uu"
+#define ENVBASE "BSDCAT" /* Prefix for environment variables. */
+#define PROGRAM "bsdcat" /* Name of program being tested. */
+#define PROGRAM_ALIAS "cat" /* Generic alias for program */
+#undef LIBRARY /* Not testing a library. */
+#undef EXTRA_DUMP /* How to dump extra data */
+#undef EXTRA_ERRNO /* How to dump errno */
+/* How to generate extra version info. */
+#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "")
+
+#include "test_common.h"
diff --git a/contrib/libarchive/cat/test/test_version.c b/contrib/libarchive/cat/test/test_version.c
index e587b3440c6d..51a4fd4d9a01 100644
--- a/contrib/libarchive/cat/test/test_version.c
+++ b/contrib/libarchive/cat/test/test_version.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2017 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,68 +30,5 @@
DEFINE_TEST(test_version)
{
- int r;
- char *p, *q;
- size_t s;
-
-
- r = systemf("%s --version >version.stdout 2>version.stderr", testprog);
- failure("Unable to run %s --version", testprog);
- if (!assert(r == 0))
- return;
-
- /* --version should generate nothing to stdout. */
- assertEmptyFile("version.stderr");
- /* Verify format of version message. */
- q = p = slurpfile(&s, "version.stdout");
- /* Version message should start with name of program, then space. */
- assert(s > 6);
- failure("Version must start with 'bsdcat': ``%s''", p);
- if (!assertEqualMem(q, "bsdcat ", 7))
- return;
- q += 7; s -= 7;
- /* Version number is a series of digits and periods. */
- while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
- ++q;
- --s;
- }
- /* Version number terminated by space. */
- failure("No space after bsdcat version: ``%s''", p);
- assert(s > 1);
- /* Skip a single trailing a,b,c, or d. */
- if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
- ++q;
- failure("No space after bsdcat version: ``%s''", p);
- assert(*q == ' ');
- ++q; --s;
- /* Separator. */
- failure("No `-' between bsdcat and libarchive versions: ``%s''", p);
- assertEqualMem(q, "- ", 2);
- q += 2; s -= 2;
- /* libarchive name and version number */
- failure("Not long enough for libarchive version: ``%s''", p);
- assert(s > 11);
- failure("Libarchive version must start with `libarchive': ``%s''", p);
- assertEqualMem(q, "libarchive ", 11);
- q += 11; s -= 11;
- /* Version number is a series of digits and periods. */
- while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
- ++q;
- --s;
- }
- /* Skip a single trailing a,b,c, or d. */
- if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
- ++q;
- /* Skip arbitrary third-party version numbers. */
- while (s > 0 && (*q == ' ' || *q == '-' || *q == '/' || *q == '.' || isalnum(*q))) {
- ++q;
- --s;
- }
- /* All terminated by end-of-line. */
- assert(s >= 1);
- /* Skip an optional CR character (e.g., Windows) */
- failure("Version output must end with \\n or \\r\\n");
- if (*q == '\r') { ++q; --s; }
- assertEqualMem(q, "\n", 1);
- free(p);
+ assertVersion(testprog, "bsdcat");
}
diff --git a/contrib/libarchive/cpio/cpio.c b/contrib/libarchive/cpio/cpio.c
index 30c9ad348dcc..7f1b11973c07 100644
--- a/contrib/libarchive/cpio/cpio.c
+++ b/contrib/libarchive/cpio/cpio.c
@@ -108,22 +108,22 @@ static int entry_to_archive(struct cpio *, struct archive_entry *);
static int file_to_archive(struct cpio *, const char *);
static void free_cache(struct name_cache *cache);
static void list_item_verbose(struct cpio *, struct archive_entry *);
-static void long_help(void);
+static void long_help(void) __LA_DEAD;
static const char *lookup_gname(struct cpio *, gid_t gid);
static int lookup_gname_helper(struct cpio *,
const char **name, id_t gid);
static const char *lookup_uname(struct cpio *, uid_t uid);
static int lookup_uname_helper(struct cpio *,
const char **name, id_t uid);
-static void mode_in(struct cpio *);
-static void mode_list(struct cpio *);
+static void mode_in(struct cpio *) __LA_DEAD;
+static void mode_list(struct cpio *) __LA_DEAD;
static void mode_out(struct cpio *);
static void mode_pass(struct cpio *, const char *);
static const char *remove_leading_slash(const char *);
static int restore_time(struct cpio *, struct archive_entry *,
const char *, int fd);
-static void usage(void);
-static void version(void);
+static void usage(void) __LA_DEAD;
+static void version(void) __LA_DEAD;
static const char * passphrase_callback(struct archive *, void *);
static void passphrase_free(char *);
diff --git a/contrib/libarchive/cpio/test/main.c b/contrib/libarchive/cpio/test/main.c
deleted file mode 100644
index d7c01999f26c..000000000000
--- a/contrib/libarchive/cpio/test/main.c
+++ /dev/null
@@ -1,3073 +0,0 @@
-/*
- * 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"
-#include "test_utils.h"
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#include <errno.h>
-#ifdef HAVE_ICONV_H
-#include <iconv.h>
-#endif
-/*
- * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
- * As the include guards don't agree, the order of include is important.
- */
-#ifdef HAVE_LINUX_EXT2_FS_H
-#include <linux/ext2_fs.h> /* for Linux file flags */
-#endif
-#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
-#include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
-#endif
-#include <limits.h>
-#include <locale.h>
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#include <stdarg.h>
-#include <time.h>
-
-/*
- * 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_option_f.cpio.uu"
-#define ENVBASE "BSDCPIO" /* Prefix for environment variables. */
-#define PROGRAM "bsdcpio" /* Name of program being tested. */
-#define PROGRAM_ALIAS "cpio" /* Generic alias for program */
-#undef LIBRARY /* Not testing a library. */
-#undef EXTRA_DUMP /* How to dump extra data */
-#undef EXTRA_ERRNO /* How to dump errno */
-/* How to generate extra version info. */
-#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "")
-
-/*
- *
- * 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.
- */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <io.h>
-#include <direct.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
-#undef chdir
-#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
-
-#if defined(HAVE__CrtSetReportMode)
-# include <crtdbg.h>
-#endif
-
-mode_t umasked(mode_t expected_mode)
-{
- mode_t mode = umask(0);
- umask(mode);
- return expected_mode & ~mode;
-}
-
-/* Path to working directory for current test */
-const char *testworkdir;
-#ifdef PROGRAM
-/* Pathname of exe to be tested. */
-const char *testprogfile;
-/* Name of exe to use in printf-formatted command strings. */
-/* On Windows, this includes leading/trailing quotes. */
-const char *testprog;
-#endif
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-static void *GetFunctionKernel32(const char *);
-static int my_CreateSymbolicLinkA(const char *, const char *, int);
-static int my_CreateHardLinkA(const char *, const char *);
-static int my_GetFileInformationByName(const char *,
- BY_HANDLE_FILE_INFORMATION *);
-
-static 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);
-}
-
-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);
-}
-
-static 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_FLAG_BACKUP_SEMANTICS, NULL);
- if (h == INVALID_HANDLE_VALUE)
- return (0);
- r = GetFileInformationByHandle(h, bhfi);
- CloseHandle(h);
- return (r);
-}
-#endif
-
-#if defined(HAVE__CrtSetReportMode) && !defined(__WATCOMC__)
-static void
-invalid_parameter_handler(const wchar_t * expression,
- const wchar_t * function, const wchar_t * file,
- unsigned int line, uintptr_t pReserved)
-{
- /* nop */
-}
-#endif
-
-/*
- *
- * OPTIONS FLAGS
- *
- */
-
-/* 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 run the specified tests once and report errors. */
-static int until_failure = 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;
-
-/*
- * Report log information selectively to console and/or disk log.
- */
-static int log_console = 0;
-static FILE *logfile;
-static void
-vlogprintf(const char *fmt, va_list ap)
-{
-#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
-}
-
-static void
-logprintf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vlogprintf(fmt, ap);
- va_end(ap);
-}
-
-/* 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;
- if (fmt == NULL) {
- nextmsg = NULL;
- } else {
- 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 noticeably.
- */
-static const char *skipping_filename;
-static int skipping_line;
-void skipping_setup(const char *filename, int line)
-{
- skipping_filename = filename;
- skipping_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); */
-}
-
-/*
- * For each test source file, we remember how many times each
- * assertion was reported. Cleared before each new test,
- * used by test_summarize().
- */
-static struct line {
- int count;
- int skip;
-} failed_lines[10000];
-const char *failed_filename;
-
-/* 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;
-
- /* Record another failure for this line. */
- ++failures;
- failed_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);
-#if _MSC_VER
- logprintf("%s(%d): ", filename, line);
-#else
- logprintf("%s:%d: ", filename, line);
-#endif
- vlogprintf(fmt, ap);
- va_end(ap);
- 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;
-}
-
-/* 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
-failure_finish(void *extra)
-{
- (void)extra; /* UNUSED (maybe) */
-#ifdef EXTRA_DUMP
- if (extra != NULL) {
- logprintf(" errno: %d\n", EXTRA_ERRNO(extra));
- logprintf(" detail: %s\n", EXTRA_DUMP(extra));
- }
-#endif
-
- if (dump_on_failure) {
- fprintf(stderr,
- " *** forcing core dump so failure can be debugged ***\n");
- abort();
- }
-}
-
-/* Inform user that we're skipping some checks. */
-void
-test_skipping(const char *fmt, ...)
-{
- char buff[1024];
- va_list ap;
-
- va_start(ap, fmt);
- vsprintf(buff, fmt, ap);
- va_end(ap);
- /* Use failure() message if set. */
- msg = nextmsg;
- nextmsg = NULL;
- /* failure_start() isn't quite right, but is awfully convenient. */
- failure_start(skipping_filename, skipping_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[skipping_line].skip = 1;
- ++skips;
-}
-
-/*
- *
- * ASSERTIONS
- *
- */
-
-/* Generic assert() just displays the failed condition. */
-int
-assertion_assert(const char *file, int line, int value,
- const char *condition, void *extra)
-{
- assertion_count(file, line);
- if (!value) {
- failure_start(file, line, "Assertion failed: %s", condition);
- failure_finish(extra);
- }
- return (value);
-}
-
-/* chdir() and report any errors */
-int
-assertion_chdir(const char *file, int line, const char *pathname)
-{
- assertion_count(file, line);
- if (chdir(pathname) == 0)
- return (1);
- failure_start(file, line, "chdir(\"%s\")", pathname);
- failure_finish(NULL);
- return (0);
-
-}
-
-/* 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);
-}
-
-/*
- * Utility to convert a single UTF-8 sequence.
- */
-static int
-_utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
-{
- static const char utf8_count[256] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 00 - 0F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 10 - 1F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20 - 2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30 - 3F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40 - 4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 50 - 5F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60 - 6F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 70 - 7F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 80 - 8F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 90 - 9F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* A0 - AF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* B0 - BF */
- 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* C0 - CF */
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* D0 - DF */
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,/* E0 - EF */
- 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */
- };
- int ch;
- int cnt;
- uint32_t wc;
-
- *pwc = 0;
-
- /* Sanity check. */
- if (n == 0)
- return (0);
- /*
- * Decode 1-4 bytes depending on the value of the first byte.
- */
- ch = (unsigned char)*s;
- if (ch == 0)
- return (0); /* Standard: return 0 for end-of-string. */
- cnt = utf8_count[ch];
-
- /* Invalid sequence or there are not plenty bytes. */
- if (n < (size_t)cnt)
- return (-1);
-
- /* Make a Unicode code point from a single UTF-8 sequence. */
- switch (cnt) {
- case 1: /* 1 byte sequence. */
- *pwc = ch & 0x7f;
- return (cnt);
- case 2: /* 2 bytes sequence. */
- if ((s[1] & 0xc0) != 0x80) return (-1);
- *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
- return (cnt);
- case 3: /* 3 bytes sequence. */
- if ((s[1] & 0xc0) != 0x80) return (-1);
- if ((s[2] & 0xc0) != 0x80) return (-1);
- wc = ((ch & 0x0f) << 12)
- | ((s[1] & 0x3f) << 6)
- | (s[2] & 0x3f);
- if (wc < 0x800)
- return (-1);/* Overlong sequence. */
- break;
- case 4: /* 4 bytes sequence. */
- if (n < 4)
- return (-1);
- if ((s[1] & 0xc0) != 0x80) return (-1);
- if ((s[2] & 0xc0) != 0x80) return (-1);
- if ((s[3] & 0xc0) != 0x80) return (-1);
- wc = ((ch & 0x07) << 18)
- | ((s[1] & 0x3f) << 12)
- | ((s[2] & 0x3f) << 6)
- | (s[3] & 0x3f);
- if (wc < 0x10000)
- return (-1);/* Overlong sequence. */
- break;
- default:
- return (-1);
- }
-
- /* The code point larger than 0x10FFFF is not legal
- * Unicode values. */
- if (wc > 0x10FFFF)
- return (-1);
- /* Correctly gets a Unicode, returns used bytes. */
- *pwc = wc;
- return (cnt);
-}
-
-static void strdump(const char *e, const char *p, int ewidth, int utf8)
-{
- const char *q = p;
-
- logprintf(" %*s = ", ewidth, e);
- if (p == NULL) {
- logprintf("NULL\n");
- return;
- }
- logprintf("\"");
- while (*p != '\0') {
- unsigned int c = 0xff & *p++;
- switch (c) {
- case '\a': logprintf("\\a"); break;
- case '\b': logprintf("\\b"); break;
- case '\n': logprintf("\\n"); break;
- case '\r': logprintf("\\r"); break;
- default:
- if (c >= 32 && c < 127)
- logprintf("%c", c);
- else
- logprintf("\\x%02X", c);
- }
- }
- logprintf("\"");
- logprintf(" (length %d)", q == NULL ? -1 : (int)strlen(q));
-
- /*
- * If the current string is UTF-8, dump its code points.
- */
- if (utf8) {
- size_t len;
- uint32_t uc;
- int n;
- int cnt = 0;
-
- p = q;
- len = strlen(p);
- logprintf(" [");
- while ((n = _utf8_to_unicode(&uc, p, len)) > 0) {
- if (p != q)
- logprintf(" ");
- logprintf("%04X", uc);
- p += n;
- len -= n;
- cnt++;
- }
- logprintf("]");
- logprintf(" (count %d", cnt);
- if (n < 0) {
- logprintf(",unknown %d bytes", len);
- }
- logprintf(")");
-
- }
- logprintf("\n");
-}
-
-/* Verify two strings are equal, dump them if not. */
-int
-assertion_equal_string(const char *file, int line,
- const char *v1, const char *e1,
- const char *v2, const char *e2,
- void *extra, int utf8)
-{
- int l1, l2;
-
- assertion_count(file, line);
- if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0))
- return (1);
- failure_start(file, line, "%s != %s", e1, e2);
- l1 = (int)strlen(e1);
- l2 = (int)strlen(e2);
- if (l1 < l2)
- l1 = l2;
- strdump(e1, v1, l1, utf8);
- strdump(e2, v2, l1, utf8);
- failure_finish(extra);
- return (0);
-}
-
-static void
-wcsdump(const char *e, const wchar_t *w)
-{
- logprintf(" %s = ", e);
- if (w == NULL) {
- logprintf("(null)");
- return;
- }
- logprintf("\"");
- while (*w != L'\0') {
- unsigned int c = *w++;
- if (c >= 32 && c < 127)
- logprintf("%c", c);
- else if (c < 256)
- logprintf("\\x%02X", c);
- else if (c < 0x10000)
- logprintf("\\u%04X", c);
- else
- logprintf("\\U%08X", c);
- }
- logprintf("\"\n");
-}
-
-#ifndef HAVE_WCSCMP
-static int
-wcscmp(const wchar_t *s1, const wchar_t *s2)
-{
-
- while (*s1 == *s2++) {
- if (*s1++ == L'\0')
- return 0;
- }
- if (*s1 > *--s2)
- return 1;
- else
- return -1;
-}
-#endif
-
-/* Verify that two wide strings are equal, dump them if not. */
-int
-assertion_equal_wstring(const char *file, int line,
- const wchar_t *v1, const char *e1,
- const wchar_t *v2, const char *e2,
- void *extra)
-{
- assertion_count(file, line);
- if (v1 == v2)
- return (1);
- if (v1 != NULL && v2 != NULL && wcscmp(v1, v2) == 0)
- return (1);
- failure_start(file, line, "%s != %s", e1, e2);
- wcsdump(e1, v1);
- wcsdump(e2, v2);
- failure_finish(extra);
- return (0);
-}
-
-/*
- * Pretty standard hexdump routine. As a bonus, if ref != NULL, then
- * any bytes in p that differ from ref will be highlighted with '_'
- * before and after the hex value.
- */
-static void
-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) {
- 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 = '_';
- logprintf("%c%02x", sep, 0xff & (int)p[i+j]);
- if (ref != NULL && p[i + j] == ref[i + j])
- sep = ' ';
- }
- for (; j < 16; j++) {
- logprintf("%c ", sep);
- sep = ' ';
- }
- logprintf("%c", sep);
- for (j=0; j < 16 && i + j < l; j++) {
- int c = p[i + j];
- if (c >= ' ' && c <= 126)
- logprintf("%c", c);
- else
- logprintf(".");
- }
- logprintf("\n");
- }
-}
-
-/* Verify that two blocks of memory are the same, display the first
- * block of differences if they're not. */
-int
-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)
-{
- const char *v1 = (const char *)_v1;
- const char *v2 = (const char *)_v2;
- size_t offset;
-
- assertion_count(file, line);
- if (v1 == v2 || (v1 != NULL && v2 != NULL && memcmp(v1, v2, l) == 0))
- return (1);
- if (v1 == NULL || v2 == NULL)
- return (0);
-
- 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) {
- /* Two lines agree, so step forward one line. */
- v1 += 16;
- v2 += 16;
- l -= 16;
- offset += 16;
- }
- logprintf(" Dump of %s\n", e1);
- hexdump(v1, v2, l < 128 ? l : 128, offset);
- logprintf(" Dump of %s\n", e2);
- hexdump(v2, v1, l < 128 ? l : 128, offset);
- logprintf("\n");
- failure_finish(extra);
- return (0);
-}
-
-/* Verify that a block of memory is filled with the specified byte. */
-int
-assertion_memory_filled_with(const char *file, int line,
- const void *_v1, const char *vd,
- size_t l, const char *ld,
- char b, const char *bd, void *extra)
-{
- const char *v1 = (const char *)_v1;
- size_t c = 0;
- size_t i;
- (void)ld; /* UNUSED */
-
- assertion_count(file, line);
-
- for (i = 0; i < l; ++i) {
- if (v1[i] == b) {
- ++c;
- }
- }
- if (c == l)
- return (1);
-
- failure_start(file, line, "%s (size %d) not filled with %s", vd, (int)l, bd);
- logprintf(" Only %d bytes were correct\n", (int)c);
- failure_finish(extra);
- return (0);
-}
-
-/* Verify that the named file exists and is empty. */
-int
-assertion_empty_file(const char *filename, int line, const char *f1)
-{
- char buff[1024];
- struct stat st;
- ssize_t s;
- FILE *f;
-
- assertion_count(filename, line);
-
- if (stat(f1, &st) != 0) {
- failure_start(filename, line, "Stat failed: %s", f1);
- failure_finish(NULL);
- return (0);
- }
- if (st.st_size == 0)
- return (1);
-
- failure_start(filename, 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 = ((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);
- }
- failure_finish(NULL);
- return (0);
-}
-
-/* Verify that the named file exists and is not empty. */
-int
-assertion_non_empty_file(const char *filename, int line, const char *f1)
-{
- struct stat st;
-
- assertion_count(filename, line);
-
- if (stat(f1, &st) != 0) {
- failure_start(filename, line, "Stat failed: %s", f1);
- failure_finish(NULL);
- return (0);
- }
- if (st.st_size == 0) {
- failure_start(filename, 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
-assertion_equal_file(const char *filename, int line, const char *fn1, const char *fn2)
-{
- char buff1[1024];
- char buff2[1024];
- FILE *f1, *f2;
- int n1, n2;
-
- assertion_count(filename, line);
-
- f1 = fopen(fn1, "rb");
- f2 = fopen(fn2, "rb");
- if (f1 == NULL || f2 == NULL) {
- if (f1) fclose(f1);
- if (f2) fclose(f2);
- return (0);
- }
- for (;;) {
- n1 = (int)fread(buff1, 1, sizeof(buff1), f1);
- n2 = (int)fread(buff2, 1, sizeof(buff2), f2);
- if (n1 != n2)
- break;
- if (n1 == 0 && n2 == 0) {
- fclose(f1);
- fclose(f2);
- return (1);
- }
- if (memcmp(buff1, buff2, n1) != 0)
- break;
- }
- fclose(f1);
- fclose(f2);
- failure_start(filename, line, "Files not identical");
- logprintf(" file1=\"%s\"\n", fn1);
- logprintf(" file2=\"%s\"\n", fn2);
- failure_finish(NULL);
- return (0);
-}
-
-/* Verify that the named file does exist. */
-int
-assertion_file_exists(const char *filename, int line, const char *f)
-{
- assertion_count(filename, line);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (!_access(f, 0))
- return (1);
-#else
- if (!access(f, F_OK))
- return (1);
-#endif
- failure_start(filename, line, "File should exist: %s", f);
- failure_finish(NULL);
- return (0);
-}
-
-/* Verify that the named file doesn't exist. */
-int
-assertion_file_not_exists(const char *filename, int line, const char *f)
-{
- assertion_count(filename, line);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (_access(f, 0))
- return (1);
-#else
- if (access(f, F_OK))
- return (1);
-#endif
- failure_start(filename, line, "File should not exist: %s", f);
- failure_finish(NULL);
- return (0);
-}
-
-/* Compare the contents of a file to a block of memory. */
-int
-assertion_file_contents(const char *filename, int line, const void *buff, int s, const char *fn)
-{
- char *contents;
- FILE *f;
- int n;
-
- assertion_count(filename, line);
-
- f = fopen(fn, "rb");
- if (f == NULL) {
- failure_start(filename, line,
- "File should exist: %s", fn);
- failure_finish(NULL);
- return (0);
- }
- contents = malloc(s * 2);
- n = (int)fread(contents, 1, s * 2, f);
- fclose(f);
- if (n == s && memcmp(buff, contents, s) == 0) {
- free(contents);
- return (1);
- }
- failure_start(filename, 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 : s, 0);
- }
- failure_finish(NULL);
- free(contents);
- return (0);
-}
-
-/* Check the contents of a text file, being tolerant of line endings. */
-int
-assertion_text_file_contents(const char *filename, int line, const char *buff, const char *fn)
-{
- char *contents;
- const char *btxt, *ftxt;
- FILE *f;
- int n, s;
-
- assertion_count(filename, line);
- f = fopen(fn, "r");
- if (f == NULL) {
- failure_start(filename, line,
- "File doesn't exist: %s", fn);
- failure_finish(NULL);
- return (0);
- }
- s = (int)strlen(buff);
- contents = malloc(s * 2 + 128);
- n = (int)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;
- }
- break;
- }
- if (*btxt == '\0' && *ftxt == '\0') {
- free(contents);
- return (1);
- }
- failure_start(filename, line, "Contents don't match");
- logprintf(" file=\"%s\"\n", fn);
- if (n > 0) {
- hexdump(contents, buff, n, 0);
- logprintf(" expected\n", fn);
- hexdump(buff, contents, s, 0);
- } else {
- logprintf(" File empty, contents should be:\n");
- hexdump(buff, NULL, s, 0);
- }
- failure_finish(NULL);
- free(contents);
- return (0);
-}
-
-/* Verify that a text file contains the specified lines, regardless of order */
-/* This could be more efficient if we sorted both sets of lines, etc, but
- * since this is used only for testing and only ever deals with a dozen or so
- * lines at a time, this relatively crude approach is just fine. */
-int
-assertion_file_contains_lines_any_order(const char *file, int line,
- const char *pathname, const char *lines[])
-{
- char *buff;
- size_t buff_size;
- size_t expected_count, actual_count, i, j;
- char **expected = NULL;
- char *p, **actual = NULL;
- char c;
- int expected_failure = 0, actual_failure = 0;
-
- assertion_count(file, line);
-
- buff = slurpfile(&buff_size, "%s", pathname);
- if (buff == NULL) {
- failure_start(pathname, line, "Can't read file: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
-
- /* Make a copy of the provided lines and count up the expected
- * file size. */
- for (i = 0; lines[i] != NULL; ++i) {
- }
- expected_count = i;
- if (expected_count) {
- expected = malloc(sizeof(char *) * expected_count);
- if (expected == NULL) {
- failure_start(pathname, line, "Can't allocate memory");
- failure_finish(NULL);
- free(expected);
- return (0);
- }
- for (i = 0; lines[i] != NULL; ++i) {
- expected[i] = strdup(lines[i]);
- }
- }
-
- /* Break the file into lines */
- actual_count = 0;
- for (c = '\0', p = buff; p < buff + buff_size; ++p) {
- if (*p == '\x0d' || *p == '\x0a')
- *p = '\0';
- if (c == '\0' && *p != '\0')
- ++actual_count;
- c = *p;
- }
- if (actual_count) {
- actual = calloc(sizeof(char *), actual_count);
- if (actual == NULL) {
- failure_start(pathname, line, "Can't allocate memory");
- failure_finish(NULL);
- free(expected);
- return (0);
- }
- for (j = 0, p = buff; p < buff + buff_size;
- p += 1 + strlen(p)) {
- if (*p != '\0') {
- actual[j] = p;
- ++j;
- }
- }
- }
-
- /* Erase matching lines from both lists */
- for (i = 0; i < expected_count; ++i) {
- if (expected[i] == NULL)
- continue;
- for (j = 0; j < actual_count; ++j) {
- if (actual[j] == NULL)
- continue;
- if (strcmp(expected[i], actual[j]) == 0) {
- free(expected[i]);
- expected[i] = NULL;
- actual[j] = NULL;
- break;
- }
- }
- }
-
- /* If there's anything left, it's a failure */
- for (i = 0; i < expected_count; ++i) {
- if (expected[i] != NULL)
- ++expected_failure;
- }
- for (j = 0; j < actual_count; ++j) {
- if (actual[j] != NULL)
- ++actual_failure;
- }
- if (expected_failure == 0 && actual_failure == 0) {
- free(buff);
- free(expected);
- free(actual);
- return (1);
- }
- failure_start(file, line, "File doesn't match: %s", pathname);
- for (i = 0; i < expected_count; ++i) {
- if (expected[i] != NULL) {
- logprintf(" Expected but not present: %s\n", expected[i]);
- free(expected[i]);
- }
- }
- for (j = 0; j < actual_count; ++j) {
- if (actual[j] != NULL)
- logprintf(" Present but not expected: %s\n", actual[j]);
- }
- failure_finish(NULL);
- free(buff);
- free(expected);
- free(actual);
- return (0);
-}
-
-/* Verify that a text file does not contains the specified strings */
-int
-assertion_file_contains_no_invalid_strings(const char *file, int line,
- const char *pathname, const char *strings[])
-{
- char *buff;
- int i;
-
- buff = slurpfile(NULL, "%s", pathname);
- if (buff == NULL) {
- failure_start(file, line, "Can't read file: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
-
- for (i = 0; strings[i] != NULL; ++i) {
- if (strstr(buff, strings[i]) != NULL) {
- failure_start(file, line, "Invalid string in %s: %s", pathname,
- strings[i]);
- failure_finish(NULL);
- free(buff);
- return(0);
- }
- }
-
- free(buff);
- 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 fxtime, fbirthtime, fatime, fmtime;
- ULARGE_INTEGER wintm;
- HANDLE h;
- fxtime.dwLowDateTime = 0;
- fxtime.dwHighDateTime = 0;
-
- assertion_count(file, line);
- /* Note: FILE_FLAG_BACKUP_SEMANTICS applies to open
- * a directory file. If not, CreateFile() will fail when
- * the pathname is a directory. */
- h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 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': fxtime = fatime; break;
- case 'b': fxtime = fbirthtime; break;
- case 'm': fxtime = fmtime; break;
- }
- CloseHandle(h);
- if (r == 0) {
- failure_start(file, line, "Can't GetFileTime %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- wintm.LowPart = fxtime.dwLowDateTime;
- wintm.HighPart = fxtime.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;
- /* FreeBSD filesystems that don't support birthtime
- * (e.g., UFS1) always return -1 here. */
- if (filet == -1) {
- return (1);
- }
- 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 %lld, %lld 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 %lld.%09lld, expected %lld.%09lld",
- 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 mode of 'pathname'. */
-int
-assertion_file_mode(const char *file, int line, const char *pathname, int expected_mode)
-{
- int mode;
- int r;
-
- assertion_count(file, line);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- failure_start(file, line, "assertFileMode not yet implemented for Windows");
- (void)mode; /* UNUSED */
- (void)r; /* UNUSED */
-#else
- {
- struct stat st;
- r = lstat(pathname, &st);
- mode = (int)(st.st_mode & 0777);
- }
- if (r == 0 && mode == expected_mode)
- return (1);
- failure_start(file, line, "File %s has mode %o, expected %o",
- pathname, mode, expected_mode);
-#endif
- failure_finish(NULL);
- return (0);
-}
-
-/* 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 && (int)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_t)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_t)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)) {
- if (0 == chmod(dirname, mode)) {
- assertion_file_mode(file, line, 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, int csize, const void *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) {
- size_t wsize;
-
- if (csize < 0)
- wsize = strlen(contents);
- else
- wsize = (size_t)csize;
- if (wsize != fwrite(contents, 1, wsize, 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 (0 != chmod(path, mode)) {
- failure_start(file, line, "Could not chmod %s", path);
- failure_finish(NULL);
- close(fd);
- return (0);
- }
- if (contents != NULL) {
- ssize_t wsize;
-
- if (csize < 0)
- wsize = (ssize_t)strlen(contents);
- else
- wsize = (ssize_t)csize;
- if (wsize != write(fd, contents, wsize)) {
- close(fd);
- failure_start(file, line,
- "Could not write to %s", path);
- failure_finish(NULL);
- close(fd);
- return (0);
- }
- }
- close(fd);
- assertion_file_mode(file, line, path, mode);
- 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);
-}
-
-/* Set times, report failures. */
-int
-assertion_utimes(const char *file, int line,
- const char *pathname, long at, long at_nsec, long mt, long mt_nsec)
-{
- int r;
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
- + (((nsec)/1000)*10))
- HANDLE h;
- ULARGE_INTEGER wintm;
- FILETIME fatime, fmtime;
- FILETIME *pat, *pmt;
-
- assertion_count(file, line);
- h = CreateFileA(pathname,GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (h == INVALID_HANDLE_VALUE) {
- failure_start(file, line, "Can't access %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
-
- if (at > 0 || at_nsec > 0) {
- wintm.QuadPart = WINTIME(at, at_nsec);
- fatime.dwLowDateTime = wintm.LowPart;
- fatime.dwHighDateTime = wintm.HighPart;
- pat = &fatime;
- } else
- pat = NULL;
- if (mt > 0 || mt_nsec > 0) {
- wintm.QuadPart = WINTIME(mt, mt_nsec);
- fmtime.dwLowDateTime = wintm.LowPart;
- fmtime.dwHighDateTime = wintm.HighPart;
- pmt = &fmtime;
- } else
- pmt = NULL;
- if (pat != NULL || pmt != NULL)
- r = SetFileTime(h, NULL, pat, pmt);
- else
- r = 1;
- CloseHandle(h);
- if (r == 0) {
- failure_start(file, line, "Can't SetFileTime %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- return (1);
-#else /* defined(_WIN32) && !defined(__CYGWIN__) */
- struct stat st;
- struct timeval times[2];
-
-#if !defined(__FreeBSD__)
- mt_nsec = at_nsec = 0; /* Generic POSIX only has whole seconds. */
-#endif
- if (mt == 0 && mt_nsec == 0 && at == 0 && at_nsec == 0)
- return (1);
-
- r = lstat(pathname, &st);
- if (r < 0) {
- failure_start(file, line, "Can't stat %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
-
- if (mt == 0 && mt_nsec == 0) {
- mt = st.st_mtime;
-#if defined(__FreeBSD__)
- mt_nsec = st.st_mtimespec.tv_nsec;
- /* FreeBSD generally only stores to microsecond res, so round. */
- mt_nsec = (mt_nsec / 1000) * 1000;
-#endif
- }
- if (at == 0 && at_nsec == 0) {
- at = st.st_atime;
-#if defined(__FreeBSD__)
- at_nsec = st.st_atimespec.tv_nsec;
- /* FreeBSD generally only stores to microsecond res, so round. */
- at_nsec = (at_nsec / 1000) * 1000;
-#endif
- }
-
- times[1].tv_sec = mt;
- times[1].tv_usec = mt_nsec / 1000;
-
- times[0].tv_sec = at;
- times[0].tv_usec = at_nsec / 1000;
-
-#ifdef HAVE_LUTIMES
- r = lutimes(pathname, times);
-#else
- r = utimes(pathname, times);
-#endif
- if (r < 0) {
- failure_start(file, line, "Can't utimes %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- return (1);
-#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
-}
-
-/* Set nodump, report failures. */
-int
-assertion_nodump(const char *file, int line, const char *pathname)
-{
-#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
- int r;
-
- assertion_count(file, line);
- r = chflags(pathname, UF_NODUMP);
- if (r < 0) {
- failure_start(file, line, "Can't set nodump %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
-#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
- && defined(EXT2_NODUMP_FL)
- int fd, r, flags;
-
- assertion_count(file, line);
- fd = open(pathname, O_RDONLY | O_NONBLOCK);
- if (fd < 0) {
- failure_start(file, line, "Can't open %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
- if (r < 0) {
- failure_start(file, line, "Can't get flags %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- flags |= EXT2_NODUMP_FL;
- r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
- if (r < 0) {
- failure_start(file, line, "Can't set nodump %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- close(fd);
-#else
- (void)pathname; /* UNUSED */
- assertion_count(file, line);
-#endif
- 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, 1, "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);
-}
-
-/* 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
-/*
- * Can this platform run the bzip2 program?
- */
-int
-canBzip2(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("bzip2 -d -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the grzip program?
- */
-int
-canGrzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("grzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the gzip program?
- */
-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 lrzip program?
- */
-int
-canRunCommand(const char *cmd)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("%s %s", cmd, redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-int
-canLrzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lrzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the lz4 program?
- */
-int
-canLz4(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lz4 -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the lzip program?
- */
-int
-canLzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the lzma program?
- */
-int
-canLzma(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lzma -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the lzop program?
- */
-int
-canLzop(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lzop -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the xz program?
- */
-int
-canXz(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("xz -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this filesystem handle nodump flags.
- */
-#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
-
-int
-canNodump(void)
-{
- const char *path = "cannodumptest";
- struct stat sb;
-
- assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
- if (chflags(path, UF_NODUMP) < 0)
- return (0);
- if (stat(path, &sb) < 0)
- return (0);
- if (sb.st_flags & UF_NODUMP)
- return (1);
- return (0);
-}
-
-#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
- && defined(EXT2_NODUMP_FL)
-
-int
-canNodump(void)
-{
- const char *path = "cannodumptest";
- int fd, r, flags;
-
- assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
- fd = open(path, O_RDONLY | O_NONBLOCK);
- if (fd < 0)
- return (0);
- r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
- if (r < 0)
- return (0);
- flags |= EXT2_NODUMP_FL;
- r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
- if (r < 0)
- return (0);
- close(fd);
- fd = open(path, O_RDONLY | O_NONBLOCK);
- if (fd < 0)
- return (0);
- r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
- if (r < 0)
- return (0);
- close(fd);
- if (flags & EXT2_NODUMP_FL)
- return (1);
- return (0);
-}
-
-#else
-
-int
-canNodump()
-{
- return (0);
-}
-
-#endif
-
-/*
- * 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.
- */
-int
-systemf(const char *fmt, ...)
-{
- char buff[8192];
- va_list ap;
- int r;
-
- 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);
-}
-
-/*
- * Slurp a file into memory for ease of comparison and testing.
- * Returns size of file in 'sizep' if non-NULL, null-terminates
- * data in memory for ease of use.
- */
-char *
-slurpfile(size_t * sizep, const char *fmt, ...)
-{
- char filename[8192];
- struct stat st;
- va_list ap;
- char *p;
- ssize_t bytes_read;
- FILE *f;
- int r;
-
- va_start(ap, fmt);
- vsprintf(filename, fmt, ap);
- va_end(ap);
-
- f = fopen(filename, "rb");
- if (f == NULL) {
- /* Note: No error; non-existent file is okay here. */
- return (NULL);
- }
- r = fstat(fileno(f), &st);
- if (r != 0) {
- logprintf("Can't stat file %s\n", filename);
- fclose(f);
- return (NULL);
- }
- p = malloc((size_t)st.st_size + 1);
- if (p == NULL) {
- 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 = fread(p, 1, (size_t)st.st_size, f);
- if (bytes_read < st.st_size) {
- 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;
- fclose(f);
- return (p);
-}
-
-/*
- * Slurp a file into memory for ease of comparison and testing.
- * Returns size of file in 'sizep' if non-NULL, null-terminates
- * data in memory for ease of use.
- */
-void
-dumpfile(const char *filename, void *data, size_t len)
-{
- ssize_t bytes_written;
- FILE *f;
-
- f = fopen(filename, "wb");
- if (f == NULL) {
- logprintf("Can't open file %s for writing\n", filename);
- return;
- }
- bytes_written = fwrite(data, 1, len, f);
- if (bytes_written < (ssize_t)len)
- logprintf("Can't write file %s\n", filename);
- fclose(f);
-}
-
-/* Read a uuencoded file from the reference directory, decode, and
- * write the result into the current directory. */
-#define VALID_UUDECODE(c) (c >= 32 && c <= 96)
-#define UUDECODE(c) (((c) - 0x20) & 0x3f)
-void
-extract_reference_file(const char *name)
-{
- char buff[1024];
- FILE *in, *out;
-
- sprintf(buff, "%s/%s.uu", refdir, name);
- in = fopen(buff, "r");
- failure("Couldn't open reference file %s", buff);
- assert(in != NULL);
- if (in == NULL)
- return;
- /* Read up to and including the 'begin' line. */
- for (;;) {
- if (fgets(buff, sizeof(buff), in) == NULL) {
- /* TODO: This is a failure. */
- return;
- }
- if (memcmp(buff, "begin ", 6) == 0)
- break;
- }
- /* Now, decode the rest and write it. */
- out = fopen(name, "wb");
- while (fgets(buff, sizeof(buff), in) != NULL) {
- char *p = buff;
- int bytes;
-
- if (memcmp(buff, "end", 3) == 0)
- break;
-
- bytes = UUDECODE(*p++);
- while (bytes > 0) {
- int n = 0;
- /* Write out 1-3 bytes from that. */
- if (bytes > 0) {
- assert(VALID_UUDECODE(p[0]));
- assert(VALID_UUDECODE(p[1]));
- n = UUDECODE(*p++) << 18;
- n |= UUDECODE(*p++) << 12;
- fputc(n >> 16, out);
- --bytes;
- }
- if (bytes > 0) {
- assert(VALID_UUDECODE(p[0]));
- n |= UUDECODE(*p++) << 6;
- fputc((n >> 8) & 0xFF, out);
- --bytes;
- }
- if (bytes > 0) {
- assert(VALID_UUDECODE(p[0]));
- n |= UUDECODE(*p++);
- fputc(n & 0xFF, out);
- --bytes;
- }
- }
- }
- fclose(out);
- fclose(in);
-}
-
-void
-copy_reference_file(const char *name)
-{
- char buff[1024];
- FILE *in, *out;
- size_t rbytes;
-
- sprintf(buff, "%s/%s", refdir, name);
- in = fopen(buff, "rb");
- failure("Couldn't open reference file %s", buff);
- assert(in != NULL);
- if (in == NULL)
- return;
- /* Now, decode the rest and write it. */
- /* Not a lot of error checking here; the input better be right. */
- out = fopen(name, "wb");
- while ((rbytes = fread(buff, 1, sizeof(buff), in)) > 0) {
- if (fwrite(buff, 1, rbytes, out) != rbytes) {
- logprintf("Error: fwrite\n");
- break;
- }
- }
- fclose(out);
- fclose(in);
-}
-
-int
-is_LargeInode(const char *file)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- BY_HANDLE_FILE_INFORMATION bhfi;
- int r;
-
- r = my_GetFileInformationByName(file, &bhfi);
- if (r != 0)
- return (0);
- return (bhfi.nFileIndexHigh & 0x0000FFFFUL);
-#else
- struct stat st;
- int64_t ino;
-
- if (stat(file, &st) < 0)
- return (0);
- ino = (int64_t)st.st_ino;
- return (ino > 0xffffffff);
-#endif
-}
-
-void
-extract_reference_files(const char **names)
-{
- while (names && *names)
- extract_reference_file(*names++);
-}
-
-/*
- *
- * 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 test_list_t tests[] = {
- #include "list.h"
-};
-
-/*
- * Summarize repeated failures in the just-completed test.
- */
-static void
-test_summarize(int failed, int skips_num)
-{
- unsigned int i;
-
- switch (verbosity) {
- case VERBOSITY_SUMMARY_ONLY:
- printf(failed ? "E" : ".");
- fflush(stdout);
- break;
- case VERBOSITY_PASSFAIL:
- printf(failed ? "FAIL\n" : skips_num ? "ok (S)\n" : "ok\n");
- break;
- }
-
- log_console = (verbosity == VERBOSITY_LIGHT_REPORT);
-
- 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",
- failed_filename, i, failed_lines[i].count);
- }
- /* Clear the failure history for the next file. */
- failed_filename = NULL;
- 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)
-{
- char workdir[1024];
- char logfilename[64];
- int failures_before = failures;
- int skips_before = skips;
- 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: %-64s", 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. */
- snprintf(workdir, sizeof(workdir), "%s/%s", tmpdir, tests[i].name);
- testworkdir = workdir;
- if (!assertMakeDir(testworkdir, 0755)
- || !assertChdir(testworkdir)) {
- fprintf(stderr,
- "ERROR: Can't chdir to work dir %s\n", testworkdir);
- 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.
- */
- testworkdir = NULL;
- /* 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(tests[i].failures, skips - skips_before);
- /* 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__)
- /* 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
- systemf("rm -rf %s", tests[i].name);
- systemf("rm %s", logfilename);
-#endif
- }
- }
- /* 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(" -u Keep running specifies tests until one fails.\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(const char *d)
-{
- size_t tried_size, buff_size;
- char *buff, *tried, *pwd = NULL, *p = NULL;
-
-#ifdef PATH_MAX
- buff_size = PATH_MAX;
-#else
- buff_size = 8192;
-#endif
- buff = calloc(buff_size, 1);
- if (buff == NULL) {
- fprintf(stderr, "Unable to allocate memory\n");
- exit(1);
- }
-
- /* Allocate a buffer to hold the various directories we checked. */
- tried_size = buff_size * 2;
- tried = calloc(tried_size, 1);
- if (tried == NULL) {
- fprintf(stderr, "Unable to allocate memory\n");
- exit(1);
- }
-
- /* If a dir was specified, try that */
- if (d != NULL) {
- pwd = NULL;
- snprintf(buff, buff_size, "%s", d);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
- goto failure;
- }
-
- /* Get the current dir. */
-#ifdef PATH_MAX
- pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
-#else
- pwd = getcwd(NULL, 0);
-#endif
- while (pwd[strlen(pwd) - 1] == '\n')
- pwd[strlen(pwd) - 1] = '\0';
-
- /* Look for a known file. */
- snprintf(buff, buff_size, "%s", pwd);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
-
- snprintf(buff, buff_size, "%s/test", pwd);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
-
-#if defined(LIBRARY)
- snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY);
-#else
- snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM);
-#endif
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
-
-#if defined(PROGRAM_ALIAS)
- snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
-#endif
-
- if (memcmp(pwd, "/usr/obj", 8) == 0) {
- snprintf(buff, buff_size, "%s", pwd + 8);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
-
- snprintf(buff, buff_size, "%s/test", pwd + 8);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
- }
-
-failure:
- printf("Unable to locate known reference file %s\n", KNOWNREF);
- printf(" Checked following directories:\n%s\n", tried);
- printf("Use -r option to specify full path to reference directory\n");
-#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
- DebugBreak();
-#endif
- exit(1);
-
-success:
- free(p);
- free(pwd);
- free(tried);
-
- /* Copy result into a fresh buffer to reduce memory usage. */
- p = strdup(buff);
- free(buff);
- return p;
-}
-
-int
-main(int argc, char **argv)
-{
- static const int limit = sizeof(tests) / sizeof(tests[0]);
- int test_set[sizeof(tests) / sizeof(tests[0])];
- int i = 0, j = 0, tests_run = 0, tests_failed = 0, option;
- time_t now;
- char *refdir_alloc = NULL;
- const char *progname;
- char **saved_argv;
- const char *tmp, *option_arg, *p;
- char tmpdir[256], *pwd, *testprogdir, *tmp2 = NULL, *vlevel = NULL;
- char tmpdir_timestamp[256];
-
- (void)argc; /* UNUSED */
-
- /* Get the current dir. */
-#ifdef PATH_MAX
- pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
-#else
- pwd = getcwd(NULL, 0);
-#endif
- while (pwd[strlen(pwd) - 1] == '\n')
- pwd[strlen(pwd) - 1] = '\0';
-
-#if defined(HAVE__CrtSetReportMode) && !defined(__WATCOMC__)
- /* To stop to run the default invalid parameter handler. */
- _set_invalid_parameter_handler(invalid_parameter_handler);
- /* 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];
- if ((testprogdir = (char *)malloc(strlen(progname) + 1)) == NULL)
- {
- fprintf(stderr, "ERROR: Out of memory.");
- exit(1);
- }
- strcpy(testprogdir, progname);
- while (*p != '\0') {
- /* Support \ or / dir separators for Windows compat. */
- if (*p == '/' || *p == '\\')
- {
- progname = p + 1;
- i = j;
- }
- ++p;
- j++;
- }
- testprogdir[i] = '\0';
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (testprogdir[0] != '/' && testprogdir[0] != '\\' &&
- !(((testprogdir[0] >= 'a' && testprogdir[0] <= 'z') ||
- (testprogdir[0] >= 'A' && testprogdir[0] <= 'Z')) &&
- testprogdir[1] == ':' &&
- (testprogdir[2] == '/' || testprogdir[2] == '\\')))
-#else
- if (testprogdir[0] != '/')
-#endif
- {
- /* Fixup path for relative directories. */
- if ((testprogdir = (char *)realloc(testprogdir,
- strlen(pwd) + 1 + strlen(testprogdir) + 1)) == NULL)
- {
- fprintf(stderr, "ERROR: Out of memory.");
- exit(1);
- }
- memmove(testprogdir + strlen(pwd) + 1, testprogdir,
- strlen(testprogdir) + 1);
- memcpy(testprogdir, pwd, strlen(pwd));
- testprogdir[strlen(pwd)] = '/';
- }
-
-#ifdef PROGRAM
- /* Get the target program from environment, if available. */
- testprogfile = getenv(ENVBASE);
-#endif
-
- if (getenv("TMPDIR") != NULL)
- tmp = getenv("TMPDIR");
- else if (getenv("TMP") != NULL)
- tmp = getenv("TMP");
- else if (getenv("TEMP") != NULL)
- tmp = getenv("TEMP");
- else if (getenv("TEMPDIR") != NULL)
- tmp = getenv("TEMPDIR");
- else
- tmp = "/tmp";
-
- /* Allow -d to be controlled through the environment. */
- if (getenv(ENVBASE "_DEBUG") != NULL)
- dump_on_failure = 1;
-
- /* Allow -v to be controlled through the environment. */
- if (getenv("_VERBOSITY_LEVEL") != NULL)
- {
- vlevel = getenv("_VERBOSITY_LEVEL");
- verbosity = atoi(vlevel);
- if (verbosity < VERBOSITY_SUMMARY_ONLY || verbosity > VERBOSITY_FULL)
- {
- /* Unsupported verbosity levels are silently ignored */
- vlevel = NULL;
- verbosity = VERBOSITY_PASSFAIL;
- }
- }
-
- /* Get the directory holding test files from environment. */
- refdir = getenv(ENVBASE "_TEST_FILES");
-
- /*
- * Parse options, without using getopt(), which isn't available
- * on all platforms.
- */
- ++argv; /* Skip program name */
- while (*argv != NULL) {
- if (**argv != '-')
- break;
- p = *argv++;
- ++p; /* Skip '-' */
- while (*p != '\0') {
- option = *p++;
- option_arg = NULL;
- /* If 'opt' takes an argument, parse that. */
- if (option == 'p' || option == 'r') {
- if (*p != '\0')
- option_arg = p;
- else if (*argv == NULL) {
- fprintf(stderr,
- "Option -%c requires argument.\n",
- option);
- usage(progname);
- } else
- option_arg = *argv++;
- p = ""; /* End of this option word. */
- }
-
- /* Now, handle the option. */
- switch (option) {
- case 'd':
- dump_on_failure = 1;
- break;
- case 'k':
- keep_temp_files = 1;
- break;
- case 'p':
-#ifdef PROGRAM
- testprogfile = option_arg;
-#else
- fprintf(stderr, "-p option not permitted\n");
- usage(progname);
-#endif
- break;
- case 'q':
- if (!vlevel)
- verbosity--;
- break;
- case 'r':
- refdir = option_arg;
- break;
- case 'u':
- until_failure++;
- break;
- case 'v':
- if (!vlevel)
- verbosity++;
- break;
- default:
- fprintf(stderr, "Unrecognized option '%c'\n",
- option);
- usage(progname);
- }
- }
- }
-
- /*
- * Sanity-check that our options make sense.
- */
-#ifdef PROGRAM
- if (testprogfile == NULL)
- {
- if ((tmp2 = (char *)malloc(strlen(testprogdir) + 1 +
- strlen(PROGRAM) + 1)) == NULL)
- {
- fprintf(stderr, "ERROR: Out of memory.");
- exit(1);
- }
- strcpy(tmp2, testprogdir);
- strcat(tmp2, "/");
- strcat(tmp2, PROGRAM);
- testprogfile = tmp2;
- }
-
- {
- 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
-
-#if !defined(_WIN32) && defined(SIGPIPE)
- { /* Ignore SIGPIPE signals */
- struct sigaction sa;
- sa.sa_handler = SIG_IGN;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sigaction(SIGPIPE, &sa, NULL);
- }
-#endif
-
- /*
- * Create a temp directory for the following tests.
- * Include the time the tests started as part of the name,
- * to make it easier to track the results of multiple tests.
- */
- now = time(NULL);
- 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 (assertMakeDir(tmpdir,0755))
- break;
- if (i >= 999) {
- fprintf(stderr,
- "ERROR: Unable to create temp directory %s\n",
- tmpdir);
- exit(1);
- }
- }
-
- /*
- * If the user didn't specify a directory for locating
- * reference files, try to find the reference files in
- * the "usual places."
- */
- refdir = refdir_alloc = get_refdir(refdir);
-
- /*
- * Banner with basic information.
- */
- 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);
-#endif
- printf("Exercising: ");
- fflush(stdout);
- printf("%s\n", EXTRA_VERSION);
- } else {
- printf("Running ");
- fflush(stdout);
- }
-
- /*
- * Run some or all of the individual tests.
- */
- saved_argv = argv;
- do {
- argv = saved_argv;
- do {
- int test_num;
-
- test_num = get_test_set(test_set, limit, *argv, tests);
- if (test_num < 0) {
- printf("*** INVALID Test %s\n", *argv);
- free(refdir_alloc);
- free(testprogdir);
- usage(progname);
- return (1);
- }
- for (i = 0; i < test_num; i++) {
- tests_run++;
- if (test_run(test_set[i], tmpdir)) {
- tests_failed++;
- if (until_failure)
- goto finish;
- }
- }
- if (*argv != NULL)
- argv++;
- } while (*argv != NULL);
- } while (until_failure);
-
-finish:
- /* Must be freed after all tests run */
- free(tmp2);
- free(testprogdir);
- free(pwd);
-
- /*
- * Report summary statistics.
- */
- if (verbosity > VERBOSITY_SUMMARY_ONLY) {
- printf("\n");
- 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 ? 1 : 0);
-}
diff --git a/contrib/libarchive/cpio/test/test.h b/contrib/libarchive/cpio/test/test.h
index c002a2c27eee..1dadf68890bf 100644
--- a/contrib/libarchive/cpio/test/test.h
+++ b/contrib/libarchive/cpio/test/test.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2006 Tim Kientzle
+ * Copyright (c) 2003-2017 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,328 +27,14 @@
/* Every test program should #include "test.h" as the first thing. */
-/*
- * The goal of this file (and the matching test.c) is to
- * simplify the very repetitive test-*.c test programs.
- */
-#if defined(HAVE_CONFIG_H)
-/* Most POSIX platforms use the 'configure' script to build config.h */
-#include "config.h"
-#elif defined(__FreeBSD__)
-/* Building as part of FreeBSD system requires a pre-built config.h. */
-#include "config_freebsd.h"
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-/* Win32 can't run the 'configure' script. */
-#include "config_windows.h"
-#else
-/* Warn if the library hasn't been (automatically or manually) configured. */
-#error Oops: No config.h and no pre-built configuration in test.h.
-#endif
-
-#include <sys/types.h> /* Windows requires this before sys/stat.h */
-#include <sys/stat.h>
-
-#if HAVE_DIRENT_H
-#include <dirent.h>
-#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 <ctype.h>
-#include <time.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <wchar.h>
-#ifdef HAVE_WINDOWS_H
-#include <windows.h>
-#endif
-
-/*
- * System-specific tweaks. We really want to minimize these
- * as much as possible, since they make it harder to understand
- * the mainline code.
- */
-
-/* Windows (including Visual Studio and MinGW but not Cygwin) */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#if !defined(__BORLANDC__)
-#undef chdir
-#define chdir _chdir
-#define strdup _strdup
-#endif
-#endif
-
-/* Visual Studio */
-#if defined(_MSC_VER) && _MSC_VER < 1900
-#define snprintf sprintf_s
-#endif
-
-#if defined(__BORLANDC__)
-#pragma warn -8068 /* Constant out of range in comparison. */
-#endif
-
-/* Haiku OS and QNX */
-#if defined(__HAIKU__) || defined(__QNXNTO__)
-/* Haiku and QNX have 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
-#define O_BINARY 0
-#endif
-
-/*
- * Redefine DEFINE_TEST for use in defining the test functions.
- */
-#undef DEFINE_TEST
-#define DEFINE_TEST(name) void name(void); void name(void)
-
-/* An implementation of the standard assert() macro */
-#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) \
- 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) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
-#define assertEqualUTF8String(v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
-/* As above, but v1 and v2 are wchar_t * */
-#define assertEqualWString(v1,v2) \
- assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-/* As above, but raw blocks of bytes. */
-#define assertEqualMem(v1, v2, l) \
- assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
-/* Assert that memory is full of a specified byte */
-#define assertMemoryFilledWith(v1, l, b) \
- assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
-/* Assert two files are the same. */
-#define assertEqualFile(f1, f2) \
- assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
-/* Assert that a file is empty. */
-#define assertEmptyFile(pathname) \
- assertion_empty_file(__FILE__, __LINE__, (pathname))
-/* Assert that a file is not empty. */
-#define assertNonEmptyFile(pathname) \
- assertion_non_empty_file(__FILE__, __LINE__, (pathname))
-#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(pathname) \
- assertion_file_exists(__FILE__, __LINE__, pathname)
-/* Assert that a file exists. */
-#define assertFileNotExists(pathname) \
- assertion_file_not_exists(__FILE__, __LINE__, pathname)
-/* Assert that file contents match a string. */
-#define assertFileContents(data, data_size, pathname) \
- assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
-/* Verify that a file does not contain invalid strings */
-#define assertFileContainsNoInvalidStrings(pathname, strings) \
- assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
-#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 assertFileMode(pathname, mode) \
- assertion_file_mode(__FILE__, __LINE__, pathname, mode)
-#define assertTextFileContents(text, pathname) \
- assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
-#define assertFileContainsLinesAnyOrder(pathname, lines) \
- assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
-#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, -1, contents)
-#define assertMakeBinFile(path, mode, csize, contents) \
- assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
-#define assertMakeHardlink(newfile, oldfile) \
- assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
-#define assertMakeSymlink(newfile, linkto) \
- assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
-#define assertNodump(path) \
- assertion_nodump(__FILE__, __LINE__, path)
-#define assertUmask(mask) \
- assertion_umask(__FILE__, __LINE__, mask)
-#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
- assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
-
-/*
- * This would be simple with C99 variadic macros, but I don't want to
- * require that. Instead, I insert a function call before each
- * skipping() call to pass the file and line information down. Crude,
- * but effective.
- */
-#define skipping \
- skipping_setup(__FILE__, __LINE__);test_skipping
-
-/* Function declarations. These are defined in test_utility.c. */
-void failure(const char *fmt, ...);
-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, const char *);
-int assertion_equal_file(const char *, int, 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_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
-int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
-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_contains_lines_any_order(const char *, int, const char *, const char **);
-int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
-int assertion_file_contents(const char *, int, const void *, int, const char *);
-int assertion_file_exists(const char *, int, const char *);
-int assertion_file_mode(const char *, int, const char *, int);
-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, 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, int, const void *);
-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_nodump(const char *, int, const char *);
-int assertion_non_empty_file(const char *, int, const char *);
-int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
-int assertion_umask(const char *, int, int);
-int assertion_utimes(const char *, int, const char *, long, long, long, long );
-
-void skipping_setup(const char *, int);
-void test_skipping(const char *fmt, ...);
-
-/* 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 "bzip2" program. */
-int canBzip2(void);
-
-/* Return true if this platform can run the "grzip" program. */
-int canGrzip(void);
-
-/* Return true if this platform can run the "gzip" program. */
-int canGzip(void);
-
-/* Return true if this platform can run the specified command. */
-int canRunCommand(const char *);
-
-/* Return true if this platform can run the "lrzip" program. */
-int canLrzip(void);
-
-/* Return true if this platform can run the "lz4" program. */
-int canLz4(void);
-
-/* Return true if this platform can run the "lzip" program. */
-int canLzip(void);
-
-/* Return true if this platform can run the "lzma" program. */
-int canLzma(void);
-
-/* Return true if this platform can run the "lzop" program. */
-int canLzop(void);
-
-/* Return true if this platform can run the "xz" program. */
-int canXz(void);
-
-/* Return true if this filesystem can handle nodump flags. */
-int canNodump(void);
-
-/* Return true if the file has large i-node number(>0xffffffff). */
-int is_LargeInode(const char *);
-
-/* 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, ...);
-
-/* Dump block of bytes to a file. */
-void dumpfile(const char *filename, void *, size_t);
-
-/* Extracts named reference file to the current directory. */
-void extract_reference_file(const char *);
-/* Copies named reference file to the current directory. */
-void copy_reference_file(const char *);
-
-/* Extracts a list of files to the current directory.
- * List must be NULL terminated.
- */
-void extract_reference_files(const char **);
-
-/* Subtract umask from mode */
-mode_t umasked(mode_t expected_mode);
-
-/* Path to working directory for current test */
-extern const char *testworkdir;
-
-/*
- * Special interfaces for program test harness.
- */
-
-/* Pathname of exe to be tested. */
-extern const char *testprogfile;
-/* Name of exe to use in printf-formatted command strings. */
-/* On Windows, this includes leading/trailing quotes. */
-extern const char *testprog;
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#endif
+#define KNOWNREF "test_option_f.cpio.uu"
+#define ENVBASE "BSDCPIO" /* Prefix for environment variables. */
+#define PROGRAM "bsdcpio" /* Name of program being tested. */
+#define PROGRAM_ALIAS "cpio" /* Generic alias for program */
+#undef LIBRARY /* Not testing a library. */
+#undef EXTRA_DUMP /* How to dump extra data */
+#undef EXTRA_ERRNO /* How to dump errno */
+/* How to generate extra version info. */
+#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "")
+
+#include "test_common.h"
diff --git a/contrib/libarchive/cpio/test/test_option_version.c b/contrib/libarchive/cpio/test/test_option_version.c
index ac58cefda11f..505db27128fe 100644
--- a/contrib/libarchive/cpio/test/test_option_version.c
+++ b/contrib/libarchive/cpio/test/test_option_version.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2017 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,92 +23,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
-__FBSDID("$FreeBSD$");
-
-/*
- * Test that --version option works and generates reasonable output.
- */
-
-static void
-verify(const char *p, size_t s)
-{
- const char *q = p;
-
- /* Version message should start with name of program, then space. */
- failure("version message too short:", p);
- if (!assert(s > 6))
- return;
- failure("Version message should begin with 'bsdcpio': %s", p);
- if (!assertEqualMem(q, "bsdcpio ", 8))
- /* If we're not testing bsdcpio, don't keep going. */
- return;
- q += 8; s -= 8;
- /* Version number is a series of digits and periods. */
- while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
- ++q;
- --s;
- }
- /* Version number terminated by space. */
- failure("Version: %s", p);
- assert(s > 1);
- /* Skip a single trailing a,b,c, or d. */
- if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
- ++q;
- failure("Version: %s", p);
- assert(*q == ' ');
- ++q; --s;
- /* Separator. */
- failure("Version: %s", p);
- assertEqualMem(q, "- ", 2);
- q += 2; s -= 2;
- /* libarchive name and version number */
- assert(s > 11);
- failure("Version: %s", p);
- assertEqualMem(q, "libarchive ", 11);
- q += 11; s -= 11;
- /* Version number is a series of digits and periods. */
- while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
- ++q;
- --s;
- }
- /* Skip a single trailing a,b,c, or d. */
- if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
- ++q;
- /* Skip arbitrary third-party version numbers. */
- while (s > 0 && (*q == ' ' || *q == '-' || *q == '/' || *q == '.' || isalnum(*q))) {
- ++q;
- --s;
- }
- /* All terminated by end-of-line: \r, \r\n, or \n */
- assert(s >= 1);
- failure("Version: %s", p);
- if (*q == '\x0d') {
- if (q[1] != '\0')
- assertEqualMem(q, "\x0d\x0a", 2);
- } else
- assertEqualMem(q, "\x0a", 1);
-}
-
DEFINE_TEST(test_option_version)
{
- int r;
- char *p;
- size_t s;
-
- r = systemf("%s --version >version.stdout 2>version.stderr", testprog);
- if (r != 0)
- r = systemf("%s -W version >version.stdout 2>version.stderr",
- testprog);
- failure("Unable to run either %s --version or %s -W version",
- testprog, testprog);
- if (!assert(r == 0))
- return;
-
- /* --version should generate nothing to stderr. */
- assertEmptyFile("version.stderr");
- /* Verify format of version message. */
- p = slurpfile(&s, "version.stdout");
- verify(p, s);
- free(p);
+ assertVersion(testprog, "bsdcpio");
}
diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h
index 5c4118b1ab13..586c73ad6f24 100644
--- a/contrib/libarchive/libarchive/archive.h
+++ b/contrib/libarchive/libarchive/archive.h
@@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3002002
+#define ARCHIVE_VERSION_NUMBER 3003001
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_ONLY_STRING "3.2.2"
+#define ARCHIVE_VERSION_ONLY_STRING "3.3.1"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
@@ -1001,6 +1001,10 @@ __LA_DECL int archive_read_disk_set_atime_restored(struct archive *);
#define ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS (0x0008)
/* Default: Xattrs are read from disk. */
#define ARCHIVE_READDISK_NO_XATTR (0x0010)
+/* Default: ACLs are read from disk. */
+#define ARCHIVE_READDISK_NO_ACL (0x0020)
+/* Default: File flags are read from disk. */
+#define ARCHIVE_READDISK_NO_FFLAGS (0x0040)
__LA_DECL int archive_read_disk_set_behavior(struct archive *,
int flags);
diff --git a/contrib/libarchive/libarchive/archive_check_magic.c b/contrib/libarchive/libarchive/archive_check_magic.c
index 10e8c3adaddf..89e631442749 100644
--- a/contrib/libarchive/libarchive/archive_check_magic.c
+++ b/contrib/libarchive/libarchive/archive_check_magic.c
@@ -62,7 +62,7 @@ errmsg(const char *m)
}
}
-static void
+static __LA_DEAD void
diediedie(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
diff --git a/contrib/libarchive/libarchive/archive_digest_private.h b/contrib/libarchive/libarchive/archive_digest_private.h
index b58ffb348f60..b4fd6ca22527 100644
--- a/contrib/libarchive/libarchive/archive_digest_private.h
+++ b/contrib/libarchive/libarchive/archive_digest_private.h
@@ -143,6 +143,7 @@
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
+#include <windows.h>
#include <wincrypt.h>
typedef struct {
int valid;
diff --git a/contrib/libarchive/libarchive/archive_entry.c b/contrib/libarchive/libarchive/archive_entry.c
index 23dce58203de..6685a3c29ee9 100644
--- a/contrib/libarchive/libarchive/archive_entry.c
+++ b/contrib/libarchive/libarchive/archive_entry.c
@@ -401,7 +401,7 @@ archive_entry_fflags_text(struct archive_entry *entry)
return (NULL);
}
-int64_t
+la_int64_t
archive_entry_gid(struct archive_entry *entry)
{
return (entry->ae_stat.aest_gid);
@@ -502,7 +502,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
return (archive_mstring_get_mbs_l(&entry->ae_hardlink, p, len, sc));
}
-int64_t
+la_int64_t
archive_entry_ino(struct archive_entry *entry)
{
return (entry->ae_stat.aest_ino);
@@ -514,7 +514,7 @@ archive_entry_ino_is_set(struct archive_entry *entry)
return (entry->ae_set & AE_SET_INO);
}
-int64_t
+la_int64_t
archive_entry_ino64(struct archive_entry *entry)
{
return (entry->ae_stat.aest_ino);
@@ -627,7 +627,7 @@ archive_entry_rdevminor(struct archive_entry *entry)
return minor(entry->ae_stat.aest_rdev);
}
-int64_t
+la_int64_t
archive_entry_size(struct archive_entry *entry)
{
return (entry->ae_stat.aest_size);
@@ -715,7 +715,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
return (archive_mstring_get_mbs_l( &entry->ae_symlink, p, len, sc));
}
-int64_t
+la_int64_t
archive_entry_uid(struct archive_entry *entry)
{
return (entry->ae_stat.aest_uid);
@@ -819,7 +819,7 @@ archive_entry_copy_fflags_text_w(struct archive_entry *entry,
}
void
-archive_entry_set_gid(struct archive_entry *entry, int64_t g)
+archive_entry_set_gid(struct archive_entry *entry, la_int64_t g)
{
entry->stat_valid = 0;
entry->ae_stat.aest_gid = g;
@@ -868,7 +868,7 @@ _archive_entry_copy_gname_l(struct archive_entry *entry,
}
void
-archive_entry_set_ino(struct archive_entry *entry, int64_t ino)
+archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
{
entry->stat_valid = 0;
entry->ae_set |= AE_SET_INO;
@@ -876,7 +876,7 @@ archive_entry_set_ino(struct archive_entry *entry, int64_t ino)
}
void
-archive_entry_set_ino64(struct archive_entry *entry, int64_t ino)
+archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
{
entry->stat_valid = 0;
entry->ae_set |= AE_SET_INO;
@@ -1209,7 +1209,7 @@ archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
}
void
-archive_entry_set_size(struct archive_entry *entry, int64_t s)
+archive_entry_set_size(struct archive_entry *entry, la_int64_t s)
{
entry->stat_valid = 0;
entry->ae_stat.aest_size = s;
@@ -1306,7 +1306,7 @@ _archive_entry_copy_symlink_l(struct archive_entry *entry,
}
void
-archive_entry_set_uid(struct archive_entry *entry, int64_t u)
+archive_entry_set_uid(struct archive_entry *entry, la_int64_t u)
{
entry->stat_valid = 0;
entry->ae_stat.aest_uid = u;
@@ -1649,7 +1649,10 @@ static struct flag {
{ "nosappnd", L"nosappnd", SF_APPEND, 0 },
{ "nosappend", L"nosappend", SF_APPEND, 0 },
#endif
-#ifdef EXT2_APPEND_FL /* 'a' */
+#if defined(FS_APPEND_FL) /* 'a' */
+ { "nosappnd", L"nosappnd", FS_APPEND_FL, 0 },
+ { "nosappend", L"nosappend", FS_APPEND_FL, 0 },
+#elif defined(EXT2_APPEND_FL) /* 'a' */
{ "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0 },
{ "nosappend", L"nosappend", EXT2_APPEND_FL, 0 },
#endif
@@ -1662,7 +1665,11 @@ static struct flag {
{ "noschange", L"noschange", SF_IMMUTABLE, 0 },
{ "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0 },
#endif
-#ifdef EXT2_IMMUTABLE_FL /* 'i' */
+#if defined(FS_IMMUTABLE_FL) /* 'i' */
+ { "noschg", L"noschg", FS_IMMUTABLE_FL, 0 },
+ { "noschange", L"noschange", FS_IMMUTABLE_FL, 0 },
+ { "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0 },
+#elif defined(EXT2_IMMUTABLE_FL) /* 'i' */
{ "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0 },
{ "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0 },
{ "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0 },
@@ -1686,7 +1693,9 @@ static struct flag {
#ifdef UF_NODUMP
{ "nodump", L"nodump", 0, UF_NODUMP},
#endif
-#ifdef EXT2_NODUMP_FL /* 'd' */
+#if defined(FS_NODUMP_FL) /* 'd' */
+ { "nodump", L"nodump", 0, FS_NODUMP_FL},
+#elif defined(EXT2_NODUMP_FL) /* 'd' */
{ "nodump", L"nodump", 0, EXT2_NODUMP_FL},
#endif
#ifdef UF_OPAQUE
@@ -1699,65 +1708,124 @@ static struct flag {
#ifdef UF_COMPRESSED
{ "nocompressed",L"nocompressed", UF_COMPRESSED, 0 },
#endif
-#ifdef EXT2_UNRM_FL
+#if defined(FS_UNRM_FL)
+ { "nouunlink", L"nouunlink", FS_UNRM_FL, 0},
+#elif defined(EXT2_UNRM_FL)
{ "nouunlink", L"nouunlink", EXT2_UNRM_FL, 0},
#endif
-#ifdef EXT2_BTREE_FL
+#if defined(FS_BTREE_FL)
+ { "nobtree", L"nobtree", FS_BTREE_FL, 0 },
+#elif defined(EXT2_BTREE_FL)
{ "nobtree", L"nobtree", EXT2_BTREE_FL, 0 },
#endif
-#ifdef EXT2_ECOMPR_FL
+#if defined(FS_ECOMPR_FL)
+ { "nocomperr", L"nocomperr", FS_ECOMPR_FL, 0 },
+#elif defined(EXT2_ECOMPR_FL)
{ "nocomperr", L"nocomperr", EXT2_ECOMPR_FL, 0 },
#endif
-#ifdef EXT2_COMPR_FL /* 'c' */
+#if defined(FS_COMPR_FL) /* 'c' */
+ { "nocompress", L"nocompress", FS_COMPR_FL, 0 },
+#elif defined(EXT2_COMPR_FL) /* 'c' */
{ "nocompress", L"nocompress", EXT2_COMPR_FL, 0 },
#endif
-#ifdef EXT2_NOATIME_FL /* 'A' */
+#if defined(FS_NOATIME_FL) /* 'A' */
+ { "noatime", L"noatime", 0, FS_NOATIME_FL},
+#elif defined(EXT2_NOATIME_FL) /* 'A' */
{ "noatime", L"noatime", 0, EXT2_NOATIME_FL},
#endif
-#ifdef EXT2_DIRTY_FL
+#if defined(FS_DIRTY_FL)
+ { "nocompdirty",L"nocompdirty", FS_DIRTY_FL, 0},
+#elif defined(EXT2_DIRTY_FL)
{ "nocompdirty",L"nocompdirty", EXT2_DIRTY_FL, 0},
#endif
-#ifdef EXT2_COMPRBLK_FL
-#ifdef EXT2_NOCOMPR_FL
+#if defined(FS_COMPRBLK_FL)
+#if defined(FS_NOCOMPR_FL)
+ { "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, FS_NOCOMPR_FL},
+#else
+ { "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, 0},
+#endif
+#elif defined(EXT2_COMPRBLK_FL)
+#if defined(EXT2_NOCOMPR_FL)
{ "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, EXT2_NOCOMPR_FL},
#else
{ "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, 0},
#endif
#endif
-#ifdef EXT2_DIRSYNC_FL
+#if defined(FS_DIRSYNC_FL)
+ { "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0},
+#elif defined(EXT2_DIRSYNC_FL)
{ "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0},
#endif
-#ifdef EXT2_INDEX_FL
+#if defined(FS_INDEX_FL)
+ { "nohashidx", L"nohashidx", FS_INDEX_FL, 0},
+#elif defined(EXT2_INDEX_FL)
{ "nohashidx", L"nohashidx", EXT2_INDEX_FL, 0},
#endif
-#ifdef EXT2_IMAGIC_FL
+#if defined(FS_IMAGIC_FL)
+ { "noimagic", L"noimagic", FS_IMAGIC_FL, 0},
+#elif defined(EXT2_IMAGIC_FL)
{ "noimagic", L"noimagic", EXT2_IMAGIC_FL, 0},
#endif
-#ifdef EXT3_JOURNAL_DATA_FL
+#if defined(FS_JOURNAL_DATA_FL)
+ { "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0},
+#elif defined(EXT3_JOURNAL_DATA_FL)
{ "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0},
#endif
-#ifdef EXT2_SECRM_FL
+#if defined(FS_SECRM_FL)
+ { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0},
+#elif defined(EXT2_SECRM_FL)
{ "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0},
#endif
-#ifdef EXT2_SYNC_FL
+#if defined(FS_SYNC_FL)
+ { "nosync", L"nosync", FS_SYNC_FL, 0},
+#elif defined(EXT2_SYNC_FL)
{ "nosync", L"nosync", EXT2_SYNC_FL, 0},
#endif
-#ifdef EXT2_NOTAIL_FL
+#if defined(FS_NOTAIL_FL)
+ { "notail", L"notail", 0, FS_NOTAIL_FL},
+#elif defined(EXT2_NOTAIL_FL)
{ "notail", L"notail", 0, EXT2_NOTAIL_FL},
#endif
-#ifdef EXT2_TOPDIR_FL
+#if defined(FS_TOPDIR_FL)
+ { "notopdir", L"notopdir", FS_TOPDIR_FL, 0},
+#elif defined(EXT2_TOPDIR_FL)
{ "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0},
#endif
-#ifdef EXT2_RESERVED_FL
+#ifdef FS_ENCRYPT_FL
+ { "noencrypt", L"noencrypt", FS_ENCRYPT_FL, 0},
+#endif
+#ifdef FS_HUGE_FILE_FL
+ { "nohugefile", L"nohugefile", FS_HUGE_FILE_FL, 0},
+#endif
+#ifdef FS_EXTENT_FL
+ { "noextent", L"noextent", FS_EXTENT_FL, 0},
+#endif
+#ifdef FS_EA_INODE_FL
+ { "noeainode", L"noeainode", FS_EA_INODE_FL, 0},
+#endif
+#ifdef FS_EOFBLOCKS_FL
+ { "noeofblocks",L"noeofblocks", FS_EOFBLOCKS_FL, 0},
+#endif
+#ifdef FS_NOCOW_FL
+ { "nocow", L"nocow", FS_NOCOW_FL, 0},
+#endif
+#ifdef FS_INLINE_DATA_FL
+ { "noinlinedata",L"noinlinedata", FS_INLINE_DATA_FL, 0},
+#endif
+#ifdef FS_PROJINHERIT_FL
+ { "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0},
+#endif
+#if defined(FS_RESERVED_FL)
+ { "noreserved", L"noreserved", FS_RESERVED_FL, 0},
+#elif defined(EXT2_RESERVED_FL)
{ "noreserved", L"noreserved", EXT2_RESERVED_FL, 0},
#endif
-
{ NULL, NULL, 0, 0 }
};
diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h
index 40d6afbf16e4..97758e223d44 100644
--- a/contrib/libarchive/libarchive/archive_entry.h
+++ b/contrib/libarchive/libarchive/archive_entry.h
@@ -30,7 +30,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3002002
+#define ARCHIVE_VERSION_NUMBER 3003001
/*
* Note: archive_entry.h is for use outside of libarchive; the
@@ -66,6 +66,27 @@ typedef int64_t la_int64_t;
# endif
#endif
+/* The la_ssize_t should match the type used in 'struct stat' */
+#if !defined(__LA_SSIZE_T_DEFINED)
+/* Older code relied on the __LA_SSIZE_T macro; after 4.0 we'll switch to the typedef exclusively. */
+# if ARCHIVE_VERSION_NUMBER < 4000000
+#define __LA_SSIZE_T la_ssize_t
+# endif
+#define __LA_SSIZE_T_DEFINED
+# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
+# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
+typedef ssize_t la_ssize_t;
+# elif defined(_WIN64)
+typedef __int64 la_ssize_t;
+# else
+typedef long la_ssize_t;
+# endif
+# else
+# include <unistd.h> /* ssize_t */
+typedef ssize_t la_ssize_t;
+# endif
+#endif
+
/* Get a suitable definition for mode_t */
#if ARCHIVE_VERSION_NUMBER >= 3999000
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
@@ -526,9 +547,9 @@ __LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type
#define ARCHIVE_ENTRY_ACL_STYLE_COMPACT 0x00000010
__LA_DECL wchar_t *archive_entry_acl_to_text_w(struct archive_entry *,
- ssize_t * /* len */, int /* flags */);
+ la_ssize_t * /* len */, int /* flags */);
__LA_DECL char *archive_entry_acl_to_text(struct archive_entry *,
- ssize_t * /* len */, int /* flags */);
+ la_ssize_t * /* len */, int /* flags */);
__LA_DECL int archive_entry_acl_from_text_w(struct archive_entry *,
const wchar_t * /* wtext */, int /* type */);
__LA_DECL int archive_entry_acl_from_text(struct archive_entry *,
diff --git a/contrib/libarchive/libarchive/archive_entry_acl.3 b/contrib/libarchive/libarchive/archive_entry_acl.3
index c5115f7274d3..7ede7b76bc15 100644
--- a/contrib/libarchive/libarchive/archive_entry_acl.3
+++ b/contrib/libarchive/libarchive/archive_entry_acl.3
@@ -32,7 +32,7 @@
.Nm archive_entry_acl_clear ,
.Nm archive_entry_acl_count ,
.Nm archive_entry_acl_from_text ,
-.Nm archive_entry_acl_from_text_w,
+.Nm archive_entry_acl_from_text_w ,
.Nm archive_entry_acl_next ,
.Nm archive_entry_acl_next_w ,
.Nm archive_entry_acl_reset ,
diff --git a/contrib/libarchive/libarchive/archive_entry_paths.3 b/contrib/libarchive/libarchive/archive_entry_paths.3
index fd22cf7e20c1..f647212a98be 100644
--- a/contrib/libarchive/libarchive/archive_entry_paths.3
+++ b/contrib/libarchive/libarchive/archive_entry_paths.3
@@ -31,25 +31,25 @@
.Nm archive_entry_set_hardlink ,
.Nm archive_entry_copy_hardlink ,
.Nm archive_entry_copy_hardlink_w ,
-.Nm archve_entry_update_hardlink_utf8 ,
+.Nm archive_entry_update_hardlink_utf8 ,
.Nm archive_entry_set_link ,
.Nm archive_entry_copy_link ,
.Nm archive_entry_copy_link_w ,
-.Nm archve_entry_update_link_utf8 ,
+.Nm archive_entry_update_link_utf8 ,
.Nm archive_entry_pathname ,
.Nm archive_entry_pathname_w ,
.Nm archive_entry_set_pathname ,
.Nm archive_entry_copy_pathname ,
.Nm archive_entry_copy_pathname_w ,
-.Nm archve_entry_update_pathname_utf8 ,
+.Nm archive_entry_update_pathname_utf8 ,
.Nm archive_entry_sourcepath ,
.Nm archive_entry_copy_sourcepath ,
-.Nm archive_entry_symlink,
-.Nm archive_entry_symlink_w,
+.Nm archive_entry_symlink ,
+.Nm archive_entry_symlink_w ,
.Nm archive_entry_set_symlink ,
.Nm archive_entry_copy_symlink ,
.Nm archive_entry_copy_symlink_w ,
-.Nm archve_entry_update_symlink_utf8
+.Nm archive_entry_update_symlink_utf8
.Nd functions for manipulating path names in archive entry descriptions
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
diff --git a/contrib/libarchive/libarchive/archive_entry_perms.3 b/contrib/libarchive/libarchive/archive_entry_perms.3
index 340c5ea72486..aae3648bb210 100644
--- a/contrib/libarchive/libarchive/archive_entry_perms.3
+++ b/contrib/libarchive/libarchive/archive_entry_perms.3
@@ -34,8 +34,8 @@
.Nm archive_entry_perm ,
.Nm archive_entry_set_perm ,
.Nm archive_entry_strmode ,
-.Nm archive_entry_uname
-.Nm archive_entry_uname_w
+.Nm archive_entry_uname ,
+.Nm archive_entry_uname_w ,
.Nm archive_entry_set_uname ,
.Nm archive_entry_copy_uname ,
.Nm archive_entry_copy_uname_w ,
diff --git a/contrib/libarchive/libarchive/archive_hmac.c b/contrib/libarchive/libarchive/archive_hmac.c
index 1e0ae283bc94..f29965577f01 100644
--- a/contrib/libarchive/libarchive/archive_hmac.c
+++ b/contrib/libarchive/libarchive/archive_hmac.c
@@ -76,6 +76,10 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
+#ifndef BCRYPT_HASH_REUSABLE_FLAG
+# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020
+#endif
+
static int
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
{
diff --git a/contrib/libarchive/libarchive/archive_platform.h b/contrib/libarchive/libarchive/archive_platform.h
index 31383db6850d..7d99d20a1510 100644
--- a/contrib/libarchive/libarchive/archive_platform.h
+++ b/contrib/libarchive/libarchive/archive_platform.h
@@ -148,23 +148,31 @@
* POSIX.1e draft functions used in archive_read_extract.c.
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
-#if HAVE_ACL_USER
+#if HAVE_DECL_ACL_USER
#define HAVE_POSIX_ACL 1
-#elif HAVE_ACL_TYPE_EXTENDED
+#elif HAVE_DECL_ACL_TYPE_EXTENDED && HAVE_MEMBERSHIP_H
#define HAVE_DARWIN_ACL 1
#endif
+#if HAVE_DECL_ACL_TYPE_NFS4
+#define HAVE_FREEBSD_NFS4_ACL 1
+#endif
#endif
/*
- * If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
+ * If this platform has <sys/acl.h>, acl(), facl() and ACLENT_T
* facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
*/
-#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
+#if HAVE_SYS_ACL_H && HAVE_ACL && HAVE_FACL && HAVE_ACLENT_T && \
+ HAVE_DECL_GETACL && HAVE_DECL_GETACLCNT && HAVE_DECL_SETACL
#define HAVE_SUN_ACL 1
+#if HAVE_ACE_T && HAVE_DECL_ACE_GETACL && HAVE_DECL_ACE_GETACLCNT && \
+ HAVE_DECL_ACE_SETACL
+#define HAVE_SUN_NFS4_ACL 1
+#endif
#endif
/* Define if platform supports NFSv4 ACLs */
-#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
+#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_NFS4_ACL || HAVE_DARWIN_ACL
#define HAVE_NFS4_ACL 1
#endif
diff --git a/contrib/libarchive/libarchive/archive_read_disk.3 b/contrib/libarchive/libarchive/archive_read_disk.3
index 2a5c1305ebdf..55e4bbbd87f3 100644
--- a/contrib/libarchive/libarchive/archive_read_disk.3
+++ b/contrib/libarchive/libarchive/archive_read_disk.3
@@ -37,10 +37,7 @@
.Nm archive_read_disk_uname ,
.Nm archive_read_disk_set_uname_lookup ,
.Nm archive_read_disk_set_gname_lookup ,
-.Nm archive_read_disk_set_standard_lookup ,
-.Nm archive_read_close ,
-.Nm archive_read_finish ,
-.Nm archive_read_free
+.Nm archive_read_disk_set_standard_lookup
.Nd functions for reading objects from disk
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@@ -81,12 +78,6 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "int fd"
.Fa "const struct stat *"
.Fc
-.Ft int
-.Fn archive_read_close "struct archive *"
-.Ft int
-.Fn archive_read_finish "struct archive *"
-.Ft int
-.Fn archive_read_free "struct archive *"
.Sh DESCRIPTION
These functions provide an API for reading information about
objects on disk.
@@ -181,17 +172,6 @@ using the currently registered lookup functions above.
This affects the file ownership fields and ACL values in the
.Tn struct archive_entry
object.
-.It Fn archive_read_close
-Does nothing for
-.Tn archive_read_disk
-handles.
-.It Fn archive_read_finish
-This is a deprecated synonym for
-.Fn archive_read_free .
-.It Fn archive_read_free
-Invokes
-.Fn archive_read_close
-if it was not invoked manually, then releases all resources.
.El
More information about the
.Va struct archive
diff --git a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
index ef6875fc8405..06d051a20846 100644
--- a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
+++ b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
@@ -124,11 +124,9 @@ __FBSDID("$FreeBSD$");
#endif
/* NFSv4 platform ACL type */
-#if HAVE_SUN_ACL
-#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
-#elif HAVE_DARWIN_ACL
+#if HAVE_DARWIN_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
-#elif HAVE_ACL_TYPE_NFS4
+#elif HAVE_FREEBSD_NFS4_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
#endif
@@ -203,15 +201,17 @@ archive_read_disk_entry_from_file(struct archive *_a,
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
/* On FreeBSD, we get flags for free with the stat. */
/* TODO: Does this belong in copy_stat()? */
- if (st->st_flags != 0)
+ if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 && st->st_flags != 0)
archive_entry_set_fflags(entry, st->st_flags, 0);
#endif
-#if defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+#if (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+ (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
/* Linux requires an extra ioctl to pull the flags. Although
* this is an extra step, it has a nice side-effect: We get an
* open file descriptor which we can use in the subsequent lookups. */
- if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
+ if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 &&
+ (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
if (fd < 0) {
if (a->tree != NULL)
fd = a->open_on_current_dir(a->tree, path,
@@ -223,7 +223,13 @@ archive_read_disk_entry_from_file(struct archive *_a,
}
if (fd >= 0) {
int stflags;
- r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
+ r = ioctl(fd,
+#if defined(FS_IOC_GETFLAGS)
+ FS_IOC_GETFLAGS,
+#else
+ EXT2_IOC_GETFLAGS,
+#endif
+ &stflags);
if (r == 0 && stflags != 0)
archive_entry_set_fflags(entry, stflags, 0);
}
@@ -269,13 +275,15 @@ archive_read_disk_entry_from_file(struct archive *_a,
}
#endif /* HAVE_READLINK || HAVE_READLINKAT */
- r = setup_acls(a, entry, &fd);
- if (!a->suppress_xattr) {
+ r = 0;
+ if ((a->flags & ARCHIVE_READDISK_NO_ACL) == 0)
+ r = setup_acls(a, entry, &fd);
+ if ((a->flags & ARCHIVE_READDISK_NO_XATTR) == 0) {
r1 = setup_xattrs(a, entry, &fd);
if (r1 < r)
r = r1;
}
- if (a->enable_copyfile) {
+ if (a->flags & ARCHIVE_READDISK_MAC_COPYFILE) {
r1 = setup_mac_metadata(a, entry, &fd);
if (r1 < r)
r = r1;
@@ -321,20 +329,17 @@ setup_mac_metadata(struct archive_read_disk *a,
name = archive_entry_sourcepath(entry);
if (name == NULL)
name = archive_entry_pathname(entry);
+ else if (a->tree != NULL && a->tree_enter_working_dir(a->tree) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't change dir to read extended attributes");
+ return (ARCHIVE_FAILED);
+ }
if (name == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Can't open file to read extended attributes: No name");
return (ARCHIVE_WARN);
}
- if (a->tree != NULL) {
- if (a->tree_enter_working_dir(a->tree) != 0) {
- archive_set_error(&a->archive, errno,
- "Couldn't change dir");
- return (ARCHIVE_FAILED);
- }
- }
-
/* Short-circuit if there's nothing to do. */
have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
if (have_attrs == -1) {
@@ -428,14 +433,71 @@ static void add_trivial_nfs4_acl(struct archive_entry *);
#if HAVE_SUN_ACL
static int
-sun_acl_is_trivial(acl_t *, mode_t, int *trivialp);
+sun_acl_is_trivial(void *, int, mode_t, int, int, int *);
+
+static void *
+sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
+{
+ int cnt, cntcmd;
+ size_t size;
+ void *aclp;
+
+ if (cmd == GETACL) {
+ cntcmd = GETACLCNT;
+ size = sizeof(aclent_t);
+ }
+#if HAVE_SUN_NFS4_ACL
+ else if (cmd == ACE_GETACL) {
+ cntcmd = ACE_GETACLCNT;
+ size = sizeof(ace_t);
+ }
#endif
+ else {
+ errno = EINVAL;
+ *aclcnt = -1;
+ return (NULL);
+ }
+
+ aclp = NULL;
+ cnt = -2;
+
+ while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
+ if (path != NULL)
+ cnt = acl(path, cntcmd, 0, NULL);
+ else
+ cnt = facl(fd, cntcmd, 0, NULL);
+
+ if (cnt > 0) {
+ if (aclp == NULL)
+ aclp = malloc(cnt * size);
+ else
+ aclp = realloc(NULL, cnt * size);
+ if (aclp != NULL) {
+ if (path != NULL)
+ cnt = acl(path, cmd, cnt, aclp);
+ else
+ cnt = facl(fd, cmd, cnt, aclp);
+ }
+ } else {
+ if (aclp != NULL) {
+ free(aclp);
+ aclp = NULL;
+ }
+ break;
+ }
+ }
+
+ *aclcnt = cnt;
+ return (aclp);
+}
+#endif /* HAVE_SUN_ACL */
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
static int translate_acl(struct archive_read_disk *a,
struct archive_entry *entry,
#if HAVE_SUN_ACL
- acl_t *acl,
+ void *aclp,
+ int aclcnt,
#else
acl_t acl,
#endif
@@ -447,40 +509,55 @@ setup_acls(struct archive_read_disk *a,
{
const char *accpath;
#if HAVE_SUN_ACL
- acl_t *acl;
+ void *aclp;
+ int aclcnt;
#else
acl_t acl;
#endif
int r;
- accpath = archive_entry_sourcepath(entry);
- if (accpath == NULL)
- accpath = archive_entry_pathname(entry);
+ accpath = NULL;
- if (*fd < 0 && a->tree != NULL) {
- if (a->follow_symlinks ||
- archive_entry_filetype(entry) != AE_IFLNK)
+#if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_ACL_GET_FD_NP
+ if (*fd < 0)
+#else
+ /* For default ACLs on Linux we need reachable accpath */
+ if (*fd < 0 || S_ISDIR(archive_entry_mode(entry)))
+#endif
+ {
+ accpath = archive_entry_sourcepath(entry);
+ if (accpath == NULL || (a->tree != NULL &&
+ a->tree_enter_working_dir(a->tree) != 0))
+ accpath = archive_entry_pathname(entry);
+ if (accpath == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't determine file path to read ACLs");
+ return (ARCHIVE_WARN);
+ }
+ if (a->tree != NULL &&
+#if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_ACL_GET_FD_NP
+ *fd < 0 &&
+#endif
+ (a->follow_symlinks ||
+ archive_entry_filetype(entry) != AE_IFLNK)) {
*fd = a->open_on_current_dir(a->tree,
accpath, O_RDONLY | O_NONBLOCK);
- if (*fd < 0) {
- if (a->tree_enter_working_dir(a->tree) != 0) {
- archive_set_error(&a->archive, errno,
- "Couldn't access %s", accpath);
- return (ARCHIVE_FAILED);
- }
}
}
archive_entry_acl_clear(entry);
+#if HAVE_SUN_ACL
+ aclp = NULL;
+#else
acl = NULL;
+#endif
#if HAVE_NFS4_ACL
/* Try NFSv4 ACL first. */
if (*fd >= 0)
#if HAVE_SUN_ACL
- /* Solaris reads both POSIX.1e and NFSv4 ACL here */
- facl_get(*fd, 0, &acl);
+ aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL);
#elif HAVE_ACL_GET_FD_NP
acl = acl_get_fd_np(*fd, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
#else
@@ -494,47 +571,62 @@ setup_acls(struct archive_read_disk *a,
&& (archive_entry_filetype(entry) == AE_IFLNK))
/* We can't get the ACL of a symlink, so we assume it can't
have one. */
+#if HAVE_SUN_ACL
+ aclp = NULL;
+#else
acl = NULL;
#endif
+#endif /* !HAVE_ACL_GET_LINK_NP */
else
#if HAVE_SUN_ACL
/* Solaris reads both POSIX.1e and NFSv4 ACLs here */
- acl_get(accpath, 0, &acl);
+ aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath);
#else
acl = acl_get_file(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
#endif
-#if HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL
/* Ignore "trivial" ACLs that just mirror the file mode. */
- if (acl != NULL) {
#if HAVE_SUN_ACL
- if (sun_acl_is_trivial(acl, archive_entry_mode(entry),
- &r) == 0 && r == 1)
-#elif HAVE_ACL_IS_TRIVIAL_NP
- if (acl_is_trivial_np(acl, &r) == 0 && r == 1)
-#endif
- {
- acl_free(acl);
- acl = NULL;
- /*
- * Simultaneous NFSv4 and POSIX.1e ACLs for the same
- * entry are not allowed, so we should return here
- */
- return (ARCHIVE_OK);
- }
+ if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
+ archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)),
+ &r) == 0 && r == 1) {
+ free(aclp);
+ aclp = NULL;
+ return (ARCHIVE_OK);
}
-#endif /* HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL */
- if (acl != NULL) {
- r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
+#elif HAVE_ACL_IS_TRIVIAL_NP
+ if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
acl_free(acl);
- if (r != ARCHIVE_OK) {
- archive_set_error(&a->archive, errno,
+ acl = NULL;
+ return (ARCHIVE_OK);
+ }
+#endif
+
+#if HAVE_SUN_ACL
+ if (aclp != NULL)
+#else
+ if (acl != NULL)
+#endif
+ {
+ r = translate_acl(a, entry,
#if HAVE_SUN_ACL
- "Couldn't translate ACLs: %s", accpath);
+ aclp, aclcnt,
#else
- "Couldn't translate NFSv4 ACLs: %s", accpath);
+ acl,
#endif
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4);
+#if HAVE_SUN_ACL
+ free(aclp);
+ aclp = NULL;
+#else
+ acl_free(acl);
+ acl = NULL;
+#endif
+
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't translate NFSv4 ACLs");
}
#if HAVE_DARWIN_ACL
/*
@@ -543,20 +635,24 @@ setup_acls(struct archive_read_disk *a,
* the archive entry. Otherwise extraction on non-Mac platforms
* would lead to an invalid file mode.
*/
- if (archive_entry_acl_count(entry,
- ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0)
+ if ((archive_entry_acl_types(entry) &
+ ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0)
add_trivial_nfs4_acl(entry);
#endif
return (r);
}
#endif /* HAVE_NFS4_ACL */
-#if HAVE_POSIX_ACL
- /* This code path is skipped on MacOS and Solaris */
+#if HAVE_POSIX_ACL || HAVE_SUN_ACL
+ /* This code path is skipped on MacOS */
/* Retrieve access ACL from file. */
if (*fd >= 0)
+#if HAVE_SUN_ACL
+ aclp = sunacl_get(GETACL, &aclcnt, *fd, NULL);
+#else
acl = acl_get_fd(*fd);
+#endif
#if HAVE_ACL_GET_LINK_NP
else if (!a->follow_symlinks)
acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
@@ -565,32 +661,64 @@ setup_acls(struct archive_read_disk *a,
&& (archive_entry_filetype(entry) == AE_IFLNK))
/* We can't get the ACL of a symlink, so we assume it can't
have one. */
+#if HAVE_SUN_ACL
+ aclp = NULL;
+#else
acl = NULL;
#endif
+#endif /* !HAVE_ACL_GET_LINK_NP */
else
+#if HAVE_SUN_ACL
+ aclp = sunacl_get(GETACL, &aclcnt, 0, accpath);
+#else
acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
+#endif
+
-#if HAVE_ACL_IS_TRIVIAL_NP
/* Ignore "trivial" ACLs that just mirror the file mode. */
- if (acl != NULL && acl_is_trivial_np(acl, &r) == 0) {
- if (r) {
- acl_free(acl);
- acl = NULL;
- }
+#if HAVE_SUN_ACL
+ if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
+ archive_entry_mode(entry), 0, S_ISDIR(archive_entry_mode(entry)),
+ &r) == 0 && r == 1) {
+ free(aclp);
+ aclp = NULL;
+ }
+#elif HAVE_ACL_IS_TRIVIAL_NP
+ if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
+ acl_free(acl);
+ acl = NULL;
}
#endif
- if (acl != NULL) {
- r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+#if HAVE_SUN_ACL
+ if (aclp != NULL)
+#else
+ if (acl != NULL)
+#endif
+ {
+ r = translate_acl(a, entry,
+#if HAVE_SUN_ACL
+ aclp, aclcnt,
+#else
+ acl,
+#endif
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+#if HAVE_SUN_ACL
+ free(aclp);
+ aclp = NULL;
+#else
acl_free(acl);
acl = NULL;
+#endif
+
if (r != ARCHIVE_OK) {
archive_set_error(&a->archive, errno,
- "Couldn't translate access ACLs: %s", accpath);
+ "Couldn't translate access ACLs");
return (r);
}
}
+#if !HAVE_SUN_ACL
/* Only directories can have default ACLs. */
if (S_ISDIR(archive_entry_mode(entry))) {
#if HAVE_ACL_GET_FD_NP
@@ -605,13 +733,13 @@ setup_acls(struct archive_read_disk *a,
acl_free(acl);
if (r != ARCHIVE_OK) {
archive_set_error(&a->archive, errno,
- "Couldn't translate default ACLs: %s",
- accpath);
+ "Couldn't translate default ACLs");
return (r);
}
}
}
-#endif /* HAVE_POSIX_ACL */
+#endif /* !HAVE_SUN_ACL */
+#endif /* HAVE_POSIX_ACL || HAVE_SUN_ACL */
return (ARCHIVE_OK);
}
@@ -657,12 +785,14 @@ static const struct {
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
+#if HAVE_DECL_ACL_SYNCHRONIZE
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+#endif
#else /* POSIX.1e ACL permissions */
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
-#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
+#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFSv4 ACL permissions */
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
@@ -691,14 +821,16 @@ static const struct {
const int archive_inherit;
const int platform_inherit;
} acl_inherit_map[] = {
-#if HAVE_SUN_ACL /* Solaris ACL inheritance flags */
+#if HAVE_SUN_NFS4_ACL /* Solaris ACL inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
+#ifdef ACE_INHERITED_ACE
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
+#endif
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
@@ -713,7 +845,7 @@ static const struct {
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
+#endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
};
#endif /* HAVE_NFS4_ACL */
@@ -856,9 +988,11 @@ add_trivial_nfs4_acl(struct archive_entry *entry)
* This is a FreeBSD acl_is_trivial_np() implementation for Solaris
*/
static int
-sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
+sun_acl_is_trivial(void *aclp, int aclcnt, mode_t mode, int is_nfs4,
+ int is_dir, int *trivialp)
{
int i, p;
+#if HAVE_SUN_NFS4_ACL
const uint32_t rperm = ACE_READ_DATA;
const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
const uint32_t eperm = ACE_EXECUTE;
@@ -869,30 +1003,25 @@ sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
ace_t *ace;
ace_t tace[6];
+#endif
- if (acl == NULL || trivialp == NULL)
+ if (aclp == NULL || trivialp == NULL)
return (-1);
*trivialp = 0;
- /* ACL_IS_TRIVIAL flag must be set for both POSIX.1e and NFSv4 ACLs */
- if ((acl->acl_flags & ACL_IS_TRIVIAL) == 0)
- return (0);
-
/*
* POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
* FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
* including mask.
*/
- if (acl->acl_type == ACLENT_T) {
- if (acl->acl_cnt == 4)
+ if (!is_nfs4) {
+ if (aclcnt == 4)
*trivialp = 1;
return (0);
}
- if (acl->acl_type != ACE_T || acl->acl_entry_size != sizeof(ace_t))
- return (-1);
-
+#if HAVE_SUN_NFS4_ACL
/*
* Continue with checking NFSv4 ACLs
*
@@ -977,13 +1106,13 @@ sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
if (tace[i].a_access_mask != 0)
p++;
}
- if (acl->acl_cnt != p)
+ if (aclcnt != p)
return (0);
p = 0;
for (i = 0; i < 6; i++) {
if (tace[i].a_access_mask != 0) {
- ace = &((ace_t *)acl->acl_aclp)[p];
+ ace = &((ace_t *)aclp)[p];
/*
* Illumos added ACE_DELETE_CHILD to write perms for
* directories. We have to check against that, too.
@@ -991,8 +1120,7 @@ sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
if (ace->a_flags != tace[i].a_flags ||
ace->a_type != tace[i].a_type ||
(ace->a_access_mask != tace[i].a_access_mask &&
- ((acl->acl_flags & ACL_IS_DIR) == 0 ||
- (tace[i].a_access_mask & wperm) == 0 ||
+ (!is_dir || (tace[i].a_access_mask & wperm) == 0 ||
ace->a_access_mask !=
(tace[i].a_access_mask | ACE_DELETE_CHILD))))
return (0);
@@ -1001,6 +1129,9 @@ sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
}
*trivialp = 1;
+#else /* !HAVE_SUN_NFS4_ACL */
+ (void)aclp; /* UNUSED */
+#endif /* !HAVE_SUN_NFS4_ACL */
return (0);
}
#endif /* HAVE_SUN_ACL */
@@ -1011,27 +1142,29 @@ sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
*/
static int
translate_acl(struct archive_read_disk *a,
- struct archive_entry *entry, acl_t *acl, int default_entry_acl_type)
+ struct archive_entry *entry, void *aclp, int aclcnt,
+ int default_entry_acl_type)
{
int e, i;
int ae_id, ae_tag, ae_perm;
int entry_acl_type;
const char *ae_name;
aclent_t *aclent;
+#if HAVE_SUN_NFS4_ACL
ace_t *ace;
+#endif
- (void)default_entry_acl_type;
-
- if (acl->acl_cnt <= 0)
+ if (aclcnt <= 0)
return (ARCHIVE_OK);
- for (e = 0; e < acl->acl_cnt; e++) {
+ for (e = 0; e < aclcnt; e++) {
ae_name = NULL;
ae_tag = 0;
ae_perm = 0;
- if (acl->acl_type == ACE_T) {
- ace = &((ace_t *)acl->acl_aclp)[e];
+#if HAVE_SUN_NFS4_ACL
+ if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ ace = &((ace_t *)aclp)[e];
ae_id = ace->a_who;
switch(ace->a_type) {
@@ -1083,8 +1216,10 @@ translate_acl(struct archive_read_disk *a,
ae_perm |=
acl_perm_map[i].archive_perm;
}
- } else {
- aclent = &((aclent_t *)acl->acl_aclp)[e];
+ } else
+#endif /* HAVE_SUN_NFS4_ACL */
+ if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
+ aclent = &((aclent_t *)aclp)[e];
if ((aclent->a_type & ACL_DEFAULT) != 0)
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
else
@@ -1131,7 +1266,8 @@ translate_acl(struct archive_read_disk *a,
ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;
if ((aclent->a_perm & 4) != 0)
ae_perm |= ARCHIVE_ENTRY_ACL_READ;
- } /* default_entry_acl_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4 */
+ } else
+ return (ARCHIVE_WARN);
archive_entry_acl_add_entry(entry, entry_acl_type,
ae_perm, ae_tag, ae_id, ae_name);
@@ -1148,11 +1284,11 @@ translate_acl(struct archive_read_disk *a,
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
{
acl_tag_t acl_tag;
-#if HAVE_ACL_TYPE_NFS4
+#if HAVE_FREEBSD_NFS4_ACL
acl_entry_type_t acl_type;
int brand;
#endif
-#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
+#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
acl_flagset_t acl_flagset;
#endif
acl_entry_t acl_entry;
@@ -1164,7 +1300,7 @@ translate_acl(struct archive_read_disk *a,
#endif
const char *ae_name;
-#if HAVE_ACL_TYPE_NFS4
+#if HAVE_FREEBSD_NFS4_ACL
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
// Make sure the "brand" on this ACL is consistent
// with the default_entry_acl_type bits provided.
@@ -1255,7 +1391,7 @@ translate_acl(struct archive_read_disk *a,
case ACL_OTHER:
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
break;
-#if HAVE_ACL_TYPE_NFS4
+#if HAVE_FREEBSD_NFS4_ACL
case ACL_EVERYONE:
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
break;
@@ -1290,9 +1426,9 @@ translate_acl(struct archive_read_disk *a,
// XXX acl_type maps to allow/deny/audit/YYYY bits
entry_acl_type = default_entry_acl_type;
#endif
-#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
+#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
-#if HAVE_ACL_TYPE_NFS4
+#if HAVE_FREEBSD_NFS4_ACL
/*
* acl_get_entry_type_np() fails with non-NFSv4 ACLs
*/
@@ -1319,7 +1455,7 @@ translate_acl(struct archive_read_disk *a,
"Invalid NFSv4 ACL entry type");
return (ARCHIVE_WARN);
}
-#endif /* HAVE_ACL_TYPE_NFS4 */
+#endif /* HAVE_FREEBSD_NFS4_ACL */
/*
* Libarchive stores "flag" (NFSv4 inheritance bits)
@@ -1344,7 +1480,7 @@ translate_acl(struct archive_read_disk *a,
ae_perm |= acl_inherit_map[i].archive_inherit;
}
}
-#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL */
+#endif /* HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL */
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
archive_set_error(&a->archive, errno,
@@ -1365,6 +1501,11 @@ translate_acl(struct archive_read_disk *a,
ae_perm |= acl_perm_map[i].archive_perm;
}
+#if HAVE_DARWIN_ACL && !HAVE_DECL_ACL_SYNCHRONIZE
+ /* On Mac OS X without ACL_SYNCHRONIZE assume it is set */
+ ae_perm |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
+#endif
+
archive_entry_acl_add_entry(entry, entry_acl_type,
ae_perm, ae_tag,
ae_id, ae_name);
@@ -1411,15 +1552,10 @@ setup_acls(struct archive_read_disk *a,
static int
setup_xattr(struct archive_read_disk *a,
- struct archive_entry *entry, const char *name, int fd)
+ struct archive_entry *entry, const char *name, int fd, const char *accpath)
{
ssize_t size;
void *value = NULL;
- const char *accpath;
-
- accpath = archive_entry_sourcepath(entry);
- if (accpath == NULL)
- accpath = archive_entry_pathname(entry);
#if HAVE_FGETXATTR
if (fd >= 0)
@@ -1484,21 +1620,23 @@ setup_xattrs(struct archive_read_disk *a,
const char *path;
ssize_t list_size;
- path = archive_entry_sourcepath(entry);
- if (path == NULL)
- path = archive_entry_pathname(entry);
+ path = NULL;
- if (*fd < 0 && a->tree != NULL) {
- if (a->follow_symlinks ||
- archive_entry_filetype(entry) != AE_IFLNK)
- *fd = a->open_on_current_dir(a->tree, path,
- O_RDONLY | O_NONBLOCK);
- if (*fd < 0) {
- if (a->tree_enter_working_dir(a->tree) != 0) {
- archive_set_error(&a->archive, errno,
- "Couldn't access %s", path);
- return (ARCHIVE_FAILED);
- }
+ if (*fd < 0) {
+ path = archive_entry_sourcepath(entry);
+ if (path == NULL || (a->tree != NULL &&
+ a->tree_enter_working_dir(a->tree) != 0))
+ path = archive_entry_pathname(entry);
+ if (path == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't determine file path to read "
+ "extended attributes");
+ return (ARCHIVE_WARN);
+ }
+ if (a->tree != NULL && (a->follow_symlinks ||
+ archive_entry_filetype(entry) != AE_IFLNK)) {
+ *fd = a->open_on_current_dir(a->tree,
+ path, O_RDONLY | O_NONBLOCK);
}
}
@@ -1561,7 +1699,7 @@ setup_xattrs(struct archive_read_disk *a,
if (strncmp(p, "system.", 7) == 0 ||
strncmp(p, "xfsroot.", 8) == 0)
continue;
- setup_xattr(a, entry, p, *fd);
+ setup_xattr(a, entry, p, *fd, path);
}
free(list);
@@ -1582,19 +1720,16 @@ setup_xattrs(struct archive_read_disk *a,
*/
static int
setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
- int namespace, const char *name, const char *fullname, int fd);
+ int namespace, const char *name, const char *fullname, int fd,
+ const char *path);
static int
setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
- int namespace, const char *name, const char *fullname, int fd)
+ int namespace, const char *name, const char *fullname, int fd,
+ const char *accpath)
{
ssize_t size;
void *value = NULL;
- const char *accpath;
-
- accpath = archive_entry_sourcepath(entry);
- if (accpath == NULL)
- accpath = archive_entry_pathname(entry);
if (fd >= 0)
size = extattr_get_fd(fd, namespace, name, NULL, 0);
@@ -1644,21 +1779,23 @@ setup_xattrs(struct archive_read_disk *a,
const char *path;
int namespace = EXTATTR_NAMESPACE_USER;
- path = archive_entry_sourcepath(entry);
- if (path == NULL)
- path = archive_entry_pathname(entry);
+ path = NULL;
- if (*fd < 0 && a->tree != NULL) {
- if (a->follow_symlinks ||
- archive_entry_filetype(entry) != AE_IFLNK)
- *fd = a->open_on_current_dir(a->tree, path,
- O_RDONLY | O_NONBLOCK);
- if (*fd < 0) {
- if (a->tree_enter_working_dir(a->tree) != 0) {
- archive_set_error(&a->archive, errno,
- "Couldn't access %s", path);
- return (ARCHIVE_FAILED);
- }
+ if (*fd < 0) {
+ path = archive_entry_sourcepath(entry);
+ if (path == NULL || (a->tree != NULL &&
+ a->tree_enter_working_dir(a->tree) != 0))
+ path = archive_entry_pathname(entry);
+ if (path == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't determine file path to read "
+ "extended attributes");
+ return (ARCHIVE_WARN);
+ }
+ if (a->tree != NULL && (a->follow_symlinks ||
+ archive_entry_filetype(entry) != AE_IFLNK)) {
+ *fd = a->open_on_current_dir(a->tree,
+ path, O_RDONLY | O_NONBLOCK);
}
}
@@ -1708,7 +1845,7 @@ setup_xattrs(struct archive_read_disk *a,
name = buff + strlen(buff);
memcpy(name, p + 1, len);
name[len] = '\0';
- setup_xattr(a, entry, namespace, name, buff, *fd);
+ setup_xattr(a, entry, namespace, name, buff, *fd, path);
p += 1 + len;
}
diff --git a/contrib/libarchive/libarchive/archive_read_disk_posix.c b/contrib/libarchive/libarchive/archive_read_disk_posix.c
index b89370421c07..6961ae6a42fe 100644
--- a/contrib/libarchive/libarchive/archive_read_disk_posix.c
+++ b/contrib/libarchive/libarchive/archive_read_disk_posix.c
@@ -465,8 +465,7 @@ archive_read_disk_new(void)
a->entry = archive_entry_new2(&a->archive);
a->lookup_uname = trivial_lookup_uname;
a->lookup_gname = trivial_lookup_gname;
- a->enable_copyfile = 1;
- a->traverse_mount_points = 1;
+ a->flags = ARCHIVE_READDISK_MAC_COPYFILE;
a->open_on_current_dir = open_on_current_dir;
a->tree_current_dir_fd = tree_current_dir_fd;
a->tree_enter_working_dir = tree_enter_working_dir;
@@ -563,25 +562,19 @@ archive_read_disk_set_symlink_hybrid(struct archive *_a)
int
archive_read_disk_set_atime_restored(struct archive *_a)
{
-#ifndef HAVE_UTIMES
- static int warning_done = 0;
-#endif
struct archive_read_disk *a = (struct archive_read_disk *)_a;
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
#ifdef HAVE_UTIMES
- a->restore_time = 1;
+ a->flags |= ARCHIVE_READDISK_RESTORE_ATIME;
if (a->tree != NULL)
a->tree->flags |= needsRestoreTimes;
return (ARCHIVE_OK);
#else
- if (warning_done)
- /* Warning was already emitted; suppress further warnings. */
- return (ARCHIVE_OK);
-
+ /* Display warning and unset flag */
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Cannot restore access time on this system");
- warning_done = 1;
+ a->flags &= ~ARCHIVE_READDISK_RESTORE_ATIME;
return (ARCHIVE_WARN);
#endif
}
@@ -595,29 +588,14 @@ archive_read_disk_set_behavior(struct archive *_a, int flags)
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump");
+ a->flags = flags;
+
if (flags & ARCHIVE_READDISK_RESTORE_ATIME)
r = archive_read_disk_set_atime_restored(_a);
else {
- a->restore_time = 0;
if (a->tree != NULL)
a->tree->flags &= ~needsRestoreTimes;
}
- if (flags & ARCHIVE_READDISK_HONOR_NODUMP)
- a->honor_nodump = 1;
- else
- a->honor_nodump = 0;
- if (flags & ARCHIVE_READDISK_MAC_COPYFILE)
- a->enable_copyfile = 1;
- else
- a->enable_copyfile = 0;
- if (flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS)
- a->traverse_mount_points = 0;
- else
- a->traverse_mount_points = 1;
- if (flags & ARCHIVE_READDISK_NO_XATTR)
- a->suppress_xattr = 1;
- else
- a->suppress_xattr = 0;
return (r);
}
@@ -918,7 +896,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
} while (lst == NULL);
#ifdef __APPLE__
- if (a->enable_copyfile) {
+ if (a->flags & ARCHIVE_READDISK_MAC_COPYFILE) {
/* If we're using copyfile(), ignore "._XXX" files. */
const char *bname = strrchr(tree_current_path(t), '/');
if (bname == NULL)
@@ -989,7 +967,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
}
if (t->initial_filesystem_id == -1)
t->initial_filesystem_id = t->current_filesystem_id;
- if (!a->traverse_mount_points) {
+ if (a->flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) {
if (t->initial_filesystem_id != t->current_filesystem_id)
descend = 0;
}
@@ -999,12 +977,14 @@ next_entry(struct archive_read_disk *a, struct tree *t,
* Honor nodump flag.
* If the file is marked with nodump flag, do not return this entry.
*/
- if (a->honor_nodump) {
+ if (a->flags & ARCHIVE_READDISK_HONOR_NODUMP) {
#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
if (st->st_flags & UF_NODUMP)
return (ARCHIVE_RETRY);
-#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) &&\
- defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+#elif (defined(FS_IOC_GETFLAGS) && defined(FS_NODUMP_FL) && \
+ defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+ (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) && \
+ defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
if (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) {
int stflags;
@@ -1013,9 +993,18 @@ next_entry(struct archive_read_disk *a, struct tree *t,
O_RDONLY | O_NONBLOCK | O_CLOEXEC);
__archive_ensure_cloexec_flag(t->entry_fd);
if (t->entry_fd >= 0) {
- r = ioctl(t->entry_fd, EXT2_IOC_GETFLAGS,
+ r = ioctl(t->entry_fd,
+#ifdef FS_IOC_GETFLAGS
+ FS_IOC_GETFLAGS,
+#else
+ EXT2_IOC_GETFLAGS,
+#endif
&stflags);
+#ifdef FS_NODUMP_FL
+ if (r == 0 && (stflags & FS_NODUMP_FL) != 0)
+#else
if (r == 0 && (stflags & EXT2_NODUMP_FL) != 0)
+#endif
return (ARCHIVE_RETRY);
}
}
@@ -1340,10 +1329,11 @@ _archive_read_disk_open(struct archive *_a, const char *pathname)
struct archive_read_disk *a = (struct archive_read_disk *)_a;
if (a->tree != NULL)
- a->tree = tree_reopen(a->tree, pathname, a->restore_time);
+ a->tree = tree_reopen(a->tree, pathname,
+ a->flags & ARCHIVE_READDISK_RESTORE_ATIME);
else
a->tree = tree_open(pathname, a->symlink_mode,
- a->restore_time);
+ a->flags & ARCHIVE_READDISK_RESTORE_ATIME);
if (a->tree == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate tar data");
@@ -2132,7 +2122,7 @@ tree_open(const char *path, int symlink_mode, int restore_time)
static struct tree *
tree_reopen(struct tree *t, const char *path, int restore_time)
{
- t->flags = (restore_time)?needsRestoreTimes:0;
+ t->flags = (restore_time != 0)?needsRestoreTimes:0;
t->flags |= onInitialDir;
t->visit_type = 0;
t->tree_errno = 0;
diff --git a/contrib/libarchive/libarchive/archive_read_disk_private.h b/contrib/libarchive/libarchive/archive_read_disk_private.h
index 9867010100f0..3f55133ec3c6 100644
--- a/contrib/libarchive/libarchive/archive_read_disk_private.h
+++ b/contrib/libarchive/libarchive/archive_read_disk_private.h
@@ -63,16 +63,8 @@ struct archive_read_disk {
int (*tree_current_dir_fd)(struct tree*);
int (*tree_enter_working_dir)(struct tree*);
- /* Set 1 if users request to restore atime . */
- int restore_time;
- /* Set 1 if users request to honor nodump flag . */
- int honor_nodump;
- /* Set 1 if users request to enable mac copyfile. */
- int enable_copyfile;
- /* Set 1 if users request to traverse mount points. */
- int traverse_mount_points;
- /* Set 1 if users want to suppress xattr information. */
- int suppress_xattr;
+ /* Bitfield with ARCHIVE_READDISK_* tunables */
+ int flags;
const char * (*lookup_gname)(void *private, int64_t gid);
void (*cleanup_gname)(void *private);
diff --git a/contrib/libarchive/libarchive/archive_read_format.3 b/contrib/libarchive/libarchive/archive_read_format.3
index 53b9a7e0e607..91c5d2cfd4b6 100644
--- a/contrib/libarchive/libarchive/archive_read_format.3
+++ b/contrib/libarchive/libarchive/archive_read_format.3
@@ -37,9 +37,9 @@
.Nm archive_read_support_format_empty ,
.Nm archive_read_support_format_iso9660 ,
.Nm archive_read_support_format_lha ,
-.Nm archive_read_support_format_mtree,
-.Nm archive_read_support_format_rar,
-.Nm archive_read_support_format_raw,
+.Nm archive_read_support_format_mtree ,
+.Nm archive_read_support_format_rar ,
+.Nm archive_read_support_format_raw ,
.Nm archive_read_support_format_tar ,
.Nm archive_read_support_format_xar ,
.Nm archive_read_support_format_zip
diff --git a/contrib/libarchive/libarchive/archive_read_open.3 b/contrib/libarchive/libarchive/archive_read_open.3
index 4d8272cac873..02494560da4d 100644
--- a/contrib/libarchive/libarchive/archive_read_open.3
+++ b/contrib/libarchive/libarchive/archive_read_open.3
@@ -33,7 +33,7 @@
.Nm archive_read_open_fd ,
.Nm archive_read_open_FILE ,
.Nm archive_read_open_filename ,
-.Nm archive_read_open_memory ,
+.Nm archive_read_open_memory
.Nd functions for reading streaming archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_tar.c b/contrib/libarchive/libarchive/archive_read_support_format_tar.c
index 446d005fffa0..fa63d2f4f391 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_tar.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_tar.c
@@ -847,9 +847,9 @@ tar_read_header(struct archive_read *a, struct tar *tar,
tar->sparse_gnu_pending = 0;
/* Read initial sparse map. */
bytes_read = gnu_sparse_10_read(a, tar, unconsumed);
- tar->entry_bytes_remaining -= bytes_read;
if (bytes_read < 0)
return ((int)bytes_read);
+ tar->entry_bytes_remaining -= bytes_read;
} else {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
@@ -2489,6 +2489,9 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
tar_flush_unconsumed(a, unconsumed);
bytes_read = (ssize_t)(tar->entry_bytes_remaining - remaining);
to_skip = 0x1ff & -bytes_read;
+ /* Fail if tar->entry_bytes_remaing would get negative */
+ if (to_skip > remaining)
+ return (ARCHIVE_FATAL);
if (to_skip != __archive_read_consume(a, to_skip))
return (ARCHIVE_FATAL);
return ((ssize_t)(bytes_read + to_skip));
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_warc.c b/contrib/libarchive/libarchive/archive_read_support_format_warc.c
index 5e22438d268b..e8753853f3c8 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_warc.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_warc.c
@@ -543,7 +543,7 @@ xstrpisotime(const char *s, char **endptr)
/* as a courtesy to our callers, and since this is a non-standard
* routine, we skip leading whitespace */
- while (isblank((unsigned char)*s))
+ while (*s == ' ' || *s == '\t')
++s;
/* read year */
@@ -589,6 +589,7 @@ static unsigned int
_warc_rdver(const char *buf, size_t bsz)
{
static const char magic[] = "WARC/";
+ const char *c;
unsigned int ver = 0U;
unsigned int end = 0U;
@@ -599,9 +600,10 @@ _warc_rdver(const char *buf, size_t bsz)
/* looks good so far, read the version number for a laugh */
buf += sizeof(magic) - 1U;
- if (isdigit(buf[0U]) && (buf[1U] == '.') && isdigit(buf[2U])) {
+ if (isdigit((unsigned char)buf[0U]) && (buf[1U] == '.') &&
+ isdigit((unsigned char)buf[2U])) {
/* we support a maximum of 2 digits in the minor version */
- if (isdigit(buf[3U]))
+ if (isdigit((unsigned char)buf[3U]))
end = 1U;
/* set up major version */
ver = (buf[0U] - '0') * 10000U;
@@ -615,11 +617,12 @@ _warc_rdver(const char *buf, size_t bsz)
* WARC below version 0.12 has a space-separated header
* WARC 0.12 and above terminates the version with a CRLF
*/
+ c = buf + 3U + end;
if (ver >= 1200U) {
- if (memcmp(buf + 3U + end, "\r\n", 2U) != 0)
+ if (memcmp(c, "\r\n", 2U) != 0)
ver = 0U;
} else if (ver < 1200U) {
- if (!isblank(*(buf + 3U + end)))
+ if (*c != ' ' && *c != '\t')
ver = 0U;
}
}
@@ -643,7 +646,7 @@ _warc_rdtyp(const char *buf, size_t bsz)
}
/* overread whitespace */
- while (val < eol && isblank((unsigned char)*val))
+ while (val < eol && (*val == ' ' || *val == '\t'))
++val;
if (val + 8U == eol) {
@@ -673,7 +676,7 @@ _warc_rduri(const char *buf, size_t bsz)
return res;
}
- while (val < eol && isblank((unsigned char)*val))
+ while (val < eol && (*val == ' ' || *val == '\t'))
++val;
/* overread URL designators */
@@ -684,7 +687,7 @@ _warc_rduri(const char *buf, size_t bsz)
/* spaces inside uri are not allowed, CRLF should follow */
for (p = val; p < eol; p++) {
- if (isspace(*p))
+ if (isspace((unsigned char)*p))
return res;
}
@@ -731,10 +734,10 @@ _warc_rdlen(const char *buf, size_t bsz)
}
/* skip leading whitespace */
- while (val < eol && isblank(*val))
+ while (val < eol && (*val == ' ' || *val == '\t'))
val++;
/* there must be at least one digit */
- if (!isdigit(*val))
+ if (!isdigit((unsigned char)*val))
return -1;
len = strtol(val, &on, 10);
if (on != eol) {
diff --git a/contrib/libarchive/libarchive/archive_write_data.3 b/contrib/libarchive/libarchive/archive_write_data.3
index 0cdd25f1f923..9c16cd9b4f70 100644
--- a/contrib/libarchive/libarchive/archive_write_data.3
+++ b/contrib/libarchive/libarchive/archive_write_data.3
@@ -24,11 +24,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 2, 2012
+.Dd February 28, 2017
.Dt ARCHIVE_WRITE_DATA 3
.Os
.Sh NAME
-.Nm archive_write_data
+.Nm archive_write_data ,
+.Nm archive_write_data_block
.Nd functions for creating archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@@ -36,8 +37,27 @@ Streaming Archive Library (libarchive, -larchive)
.In archive.h
.Ft la_ssize_t
.Fn archive_write_data "struct archive *" "const void *" "size_t"
+.Ft la_ssize_t
+.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset"
.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_write_data
+Write data corresponding to the header just written.
+.It Fn archive_write_data_block
Write data corresponding to the header just written.
+This is like
+.Fn archive_write_data
+except that it performs a seek on the file being
+written to the specified offset before writing the data.
+This is useful when restoring sparse files from archive
+formats that support sparse files.
+Returns number of bytes written or -1 on error.
+(Note: This is currently not supported for
+.Tn archive_write
+handles, only for
+.Tn archive_write_disk
+handles.
+.El
.\" .Sh EXAMPLE
.\"
.Sh RETURN VALUES
diff --git a/contrib/libarchive/libarchive/archive_write_disk.3 b/contrib/libarchive/libarchive/archive_write_disk.3
index ba6c9706e8a3..4891b8572efd 100644
--- a/contrib/libarchive/libarchive/archive_write_disk.3
+++ b/contrib/libarchive/libarchive/archive_write_disk.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 2, 2012
+.Dd February 28, 2017
.Dt ARCHIVE_WRITE_DISK 3
.Os
.Sh NAME
@@ -33,14 +33,7 @@
.Nm archive_write_disk_set_skip_file ,
.Nm archive_write_disk_set_group_lookup ,
.Nm archive_write_disk_set_standard_lookup ,
-.Nm archive_write_disk_set_user_lookup ,
-.Nm archive_write_header ,
-.Nm archive_write_data ,
-.Nm archive_write_data_block ,
-.Nm archive_write_finish_entry ,
-.Nm archive_write_close ,
-.Nm archive_write_finish
-.Nm archive_write_free
+.Nm archive_write_disk_set_user_lookup
.Nd functions for creating objects on disk
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@@ -68,20 +61,6 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "uid_t (*)(void *, const char *uname, uid_t uid)"
.Fa "void (*cleanup)(void *)"
.Fc
-.Ft int
-.Fn archive_write_header "struct archive *" "struct archive_entry *"
-.Ft la_ssize_t
-.Fn archive_write_data "struct archive *" "const void *" "size_t"
-.Ft la_ssize_t
-.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset"
-.Ft int
-.Fn archive_write_finish_entry "struct archive *"
-.Ft int
-.Fn archive_write_close "struct archive *"
-.Ft int
-.Fn archive_write_finish "struct archive *"
-.Ft int
-.Fn archive_write_free "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for creating objects on
disk from
@@ -223,60 +202,6 @@ the number of calls to
.Xr getpwnam 3
and
.Xr getgrnam 3 .
-.It Fn archive_write_header
-Build and write a header using the data in the provided
-.Tn struct archive_entry
-structure.
-See
-.Xr archive_entry 3
-for information on creating and populating
-.Tn struct archive_entry
-objects.
-.It Fn archive_write_data
-Write data corresponding to the header just written.
-Returns number of bytes written or -1 on error.
-.It Fn archive_write_data_block
-Write data corresponding to the header just written.
-This is like
-.Fn archive_write_data
-except that it performs a seek on the file being
-written to the specified offset before writing the data.
-This is useful when restoring sparse files from archive
-formats that support sparse files.
-Returns number of bytes written or -1 on error.
-(Note: This is currently not supported for
-.Tn archive_write
-handles, only for
-.Tn archive_write_disk
-handles.)
-.It Fn archive_write_finish_entry
-Close out the entry just written.
-Ordinarily, clients never need to call this, as it
-is called automatically by
-.Fn archive_write_next_header
-and
-.Fn archive_write_close
-as needed.
-However, some file attributes are written to disk only
-after the file is closed, so this can be necessary
-if you need to work with the file on disk right away.
-.It Fn archive_write_close
-Set any attributes that could not be set during the initial restore.
-For example, directory timestamps are not restored initially because
-restoring a subsequent file would alter that timestamp.
-Similarly, non-writable directories are initially created with
-write permissions (so that their contents can be restored).
-The
-.Nm
-library maintains a list of all such deferred attributes and
-sets them when this function is invoked.
-.It Fn archive_write_finish
-This is a deprecated synonym for
-.Fn archive_write_free .
-.It Fn archive_write_free
-Invokes
-.Fn archive_write_close
-if it was not invoked manually, then releases all resources.
.El
More information about the
.Va struct archive
diff --git a/contrib/libarchive/libarchive/archive_write_disk_acl.c b/contrib/libarchive/libarchive/archive_write_disk_acl.c
index 144ab7e72e1b..643f3c3a0733 100644
--- a/contrib/libarchive/libarchive/archive_write_disk_acl.c
+++ b/contrib/libarchive/libarchive/archive_write_disk_acl.c
@@ -61,17 +61,18 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
#else /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
-#if HAVE_SUN_ACL
-#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
-#elif HAVE_DARWIN_ACL
+#if HAVE_DARWIN_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
-#elif HAVE_ACL_TYPE_NFS4
+#elif HAVE_FREEBSD_NFS4_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
#endif
static int set_acl(struct archive *, int fd, const char *,
struct archive_acl *,
- acl_type_t, int archive_entry_acl_type, const char *tn);
+#if !HAVE_SUN_ACL
+ acl_type_t,
+#endif
+ int archive_entry_acl_type, const char *tn);
int
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
@@ -84,7 +85,7 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
#if HAVE_SUN_ACL
/* Solaris writes POSIX.1e access and default ACLs together */
- ret = set_acl(a, fd, name, abstract_acl, ACLENT_T,
+ ret = set_acl(a, fd, name, abstract_acl,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
#else /* HAVE_POSIX_ACL */
if ((archive_acl_types(abstract_acl)
@@ -109,13 +110,16 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
if ((archive_acl_types(abstract_acl) &
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
ret = set_acl(a, fd, name, abstract_acl,
+#if !HAVE_SUN_ACL
ARCHIVE_PLATFORM_ACL_TYPE_NFS4,
+#endif
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
}
#endif /* HAVE_NFS4_ACL */
return (ret);
}
+#if !HAVE_SUN_ACL || HAVE_SUN_NFS4_ACL
/*
* Translate system ACL permissions into libarchive internal structure
*/
@@ -123,7 +127,7 @@ static const struct {
const int archive_perm;
const int platform_perm;
} acl_perm_map[] = {
-#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
+#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL permissions */
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
{ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
@@ -158,12 +162,14 @@ static const struct {
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
+#if HAVE_DECL_ACL_SYNCHRONIZE
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+#endif
#else /* POSIX.1e ACL permissions */
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
-#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
+#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFSv4 ACL permissions */
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
@@ -183,6 +189,7 @@ static const struct {
#endif
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
};
+#endif /* !HAVE_SUN_ACL || HAVE_SUN_NFS4_ACL */
#if HAVE_NFS4_ACL
/*
@@ -192,14 +199,16 @@ static const struct {
const int archive_inherit;
const int platform_inherit;
} acl_inherit_map[] = {
-#if HAVE_SUN_ACL /* Solaris NFSv4 inheritance flags */
+#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
+#ifdef ACE_INHERITED_ACE
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
+#endif
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
@@ -214,29 +223,34 @@ static const struct {
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
+#endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
};
#endif /* HAVE_NFS4_ACL */
static int
set_acl(struct archive *a, int fd, const char *name,
struct archive_acl *abstract_acl,
- acl_type_t acl_type, int ae_requested_type, const char *tname)
+#if !HAVE_SUN_ACL
+ acl_type_t acl_type,
+#endif
+ int ae_requested_type, const char *tname)
{
#if HAVE_SUN_ACL
aclent_t *aclent;
+#if HAVE_SUN_NFS4_ACL
ace_t *ace;
- int e, r;
- acl_t *acl;
+#endif
+ int cmd, e, r;
+ void *aclp;
#else
acl_t acl;
acl_entry_t acl_entry;
acl_permset_t acl_permset;
-#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
+#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
acl_flagset_t acl_flagset;
#endif
#endif /* HAVE_SUN_ACL */
-#if HAVE_ACL_TYPE_NFS4
+#if HAVE_FREEBSD_NFS4_ACL
int r;
#endif
int ret;
@@ -256,31 +270,26 @@ set_acl(struct archive *a, int fd, const char *name,
return (ARCHIVE_OK);
#if HAVE_SUN_ACL
- acl = NULL;
- acl = malloc(sizeof(acl_t));
- if (acl == NULL) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Invalid ACL type");
- return (ARCHIVE_FAILED);
- }
- if (acl_type == ACE_T)
- acl->acl_entry_size = sizeof(ace_t);
- else if (acl_type == ACLENT_T)
- acl->acl_entry_size = sizeof(aclent_t);
- else {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Invalid ACL type");
- acl_free(acl);
+ switch (ae_requested_type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
+ cmd = SETACL;
+ aclp = malloc(entries * sizeof(aclent_t));
+ break;
+#if HAVE_SUN_NFS4_ACL
+ case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
+ cmd = ACE_SETACL;
+ aclp = malloc(entries * sizeof(ace_t));
+ break;
+#endif
+ default:
+ errno = ENOENT;
+ archive_set_error(a, errno, "Invalid ACL type");
return (ARCHIVE_FAILED);
}
- acl->acl_type = acl_type;
- acl->acl_cnt = entries;
- acl->acl_aclp = malloc(entries * acl->acl_entry_size);
- if (acl->acl_aclp == NULL) {
+ if (aclp == NULL) {
archive_set_error(a, errno,
"Can't allocate memory for acl buffer");
- acl_free(acl);
return (ARCHIVE_FAILED);
}
#else /* !HAVE_SUN_ACL */
@@ -297,19 +306,24 @@ set_acl(struct archive *a, int fd, const char *name,
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
#if HAVE_SUN_ACL
- ace = NULL;
aclent = NULL;
- if (acl->acl_type == ACE_T) {
- ace = &((ace_t *)acl->acl_aclp)[e];
- ace->a_who = -1;
- ace->a_access_mask = 0;
- ace->a_flags = 0;
- } else {
- aclent = &((aclent_t *)acl->acl_aclp)[e];
+#if HAVE_SUN_NFS4_ACL
+ ace = NULL;
+#endif
+ if (cmd == SETACL) {
+ aclent = &((aclent_t *)aclp)[e];
aclent->a_id = -1;
aclent->a_type = 0;
aclent->a_perm = 0;
}
+#if HAVE_SUN_NFS4_ACL
+ else { /* cmd == ACE_SETACL */
+ ace = &((ace_t *)aclp)[e];
+ ace->a_who = -1;
+ ace->a_access_mask = 0;
+ ace->a_flags = 0;
+ }
+#endif /* HAVE_SUN_NFS4_ACL */
#else /* !HAVE_SUN_ACL */
#if HAVE_DARWIN_ACL
/*
@@ -346,45 +360,63 @@ set_acl(struct archive *a, int fd, const char *name,
#if HAVE_SUN_ACL
case ARCHIVE_ENTRY_ACL_USER:
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
- if (acl->acl_type == ACE_T)
- ace->a_who = ae_uid;
- else {
+ if (aclent != NULL) {
aclent->a_id = ae_uid;
aclent->a_type |= USER;
}
+#if HAVE_SUN_NFS4_ACL
+ else {
+ ace->a_who = ae_uid;
+ }
+#endif
break;
case ARCHIVE_ENTRY_ACL_GROUP:
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
- if (acl->acl_type == ACE_T) {
- ace->a_who = ae_gid;
- ace->a_flags |= ACE_IDENTIFIER_GROUP;
- } else {
+ if (aclent != NULL) {
aclent->a_id = ae_gid;
aclent->a_type |= GROUP;
}
+#if HAVE_SUN_NFS4_ACL
+ else {
+ ace->a_who = ae_gid;
+ ace->a_flags |= ACE_IDENTIFIER_GROUP;
+ }
+#endif
break;
case ARCHIVE_ENTRY_ACL_USER_OBJ:
- if (acl->acl_type == ACE_T)
- ace->a_flags |= ACE_OWNER;
- else
+ if (aclent != NULL)
aclent->a_type |= USER_OBJ;
+#if HAVE_SUN_NFS4_ACL
+ else {
+ ace->a_flags |= ACE_OWNER;
+ }
+#endif
break;
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
- if (acl->acl_type == ACE_T) {
+ if (aclent != NULL)
+ aclent->a_type |= GROUP_OBJ;
+#if HAVE_SUN_NFS4_ACL
+ else {
ace->a_flags |= ACE_GROUP;
ace->a_flags |= ACE_IDENTIFIER_GROUP;
- } else
- aclent->a_type |= GROUP_OBJ;
+ }
+
+#endif
break;
case ARCHIVE_ENTRY_ACL_MASK:
- aclent->a_type |= CLASS_OBJ;
+ if (aclent != NULL)
+ aclent->a_type |= CLASS_OBJ;
break;
case ARCHIVE_ENTRY_ACL_OTHER:
- aclent->a_type |= OTHER_OBJ;
+ if (aclent != NULL)
+ aclent->a_type |= OTHER_OBJ;
break;
+#if HAVE_SUN_NFS4_ACL
case ARCHIVE_ENTRY_ACL_EVERYONE:
- ace->a_flags |= ACE_EVERYONE;
+ if (ace != NULL)
+ ace->a_flags |= ACE_EVERYONE;
break;
+#endif
#else /* !HAVE_SUN_ACL */
case ARCHIVE_ENTRY_ACL_USER:
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
@@ -425,7 +457,7 @@ set_acl(struct archive *a, int fd, const char *name,
case ARCHIVE_ENTRY_ACL_OTHER:
acl_set_tag_type(acl_entry, ACL_OTHER);
break;
-#if HAVE_ACL_TYPE_NFS4 /* FreeBSD only */
+#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD only */
case ARCHIVE_ENTRY_ACL_EVERYONE:
acl_set_tag_type(acl_entry, ACL_EVERYONE);
break;
@@ -439,10 +471,11 @@ set_acl(struct archive *a, int fd, const char *name,
goto exit_free;
}
-#if HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL
+#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_ACL
r = 0;
switch (ae_type) {
#if HAVE_SUN_ACL
+#if HAVE_SUN_NFS4_ACL
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
if (ace != NULL)
ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
@@ -467,6 +500,7 @@ set_acl(struct archive *a, int fd, const char *name,
else
r = -1;
break;
+#endif
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
if (aclent == NULL)
r = -1;
@@ -497,7 +531,7 @@ set_acl(struct archive *a, int fd, const char *name,
#endif /* !HAVE_SUN_ACL */
default:
archive_set_error(a, ARCHIVE_ERRNO_MISC,
- "Unknown ACL entry type");
+ "Unsupported ACL entry type");
ret = ARCHIVE_FAILED;
goto exit_free;
}
@@ -511,17 +545,20 @@ set_acl(struct archive *a, int fd, const char *name,
ret = ARCHIVE_FAILED;
goto exit_free;
}
-#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL */
+#endif /* HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_ACL */
#if HAVE_SUN_ACL
- if (acl->acl_type == ACLENT_T) {
+ if (aclent != NULL) {
if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
aclent->a_perm |= 1;
if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
aclent->a_perm |= 2;
if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
aclent->a_perm |= 4;
- } else
+ }
+#if HAVE_SUN_NFS4_ACL
+ else /* falls through to for statement below, ace != NULL */
+#endif
#else
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
archive_set_error(a, errno,
@@ -536,6 +573,7 @@ set_acl(struct archive *a, int fd, const char *name,
goto exit_free;
}
#endif /* !HAVE_SUN_ACL */
+#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
if (ae_permset & acl_perm_map[i].archive_perm) {
#if HAVE_SUN_ACL
@@ -552,10 +590,11 @@ set_acl(struct archive *a, int fd, const char *name,
#endif
}
}
+#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
#if HAVE_NFS4_ACL
-#if HAVE_SUN_ACL
- if (acl_type == ACE_T)
+#if HAVE_SUN_NFS4_ACL
+ if (ace != NULL)
#elif HAVE_DARWIN_ACL
if (acl_type == ACL_TYPE_EXTENDED)
#else /* FreeBSD */
@@ -611,7 +650,7 @@ set_acl(struct archive *a, int fd, const char *name,
#endif
{
#if HAVE_SUN_ACL
- if (facl_set(fd, acl) == 0)
+ if (facl(fd, cmd, entries, aclp) == 0)
#elif HAVE_ACL_SET_FD_NP
if (acl_set_fd_np(fd, acl, acl_type) == 0)
#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
@@ -630,7 +669,7 @@ set_acl(struct archive *a, int fd, const char *name,
} else
#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */
#if HAVE_SUN_ACL
- if (acl_set(name, acl) != 0)
+ if (acl(name, cmd, entries, aclp) != 0)
#elif HAVE_ACL_SET_LINK_NP
if (acl_set_link_np(name, acl_type, acl) != 0)
#else
@@ -648,7 +687,11 @@ set_acl(struct archive *a, int fd, const char *name,
}
}
exit_free:
+#if HAVE_SUN_ACL
+ free(aclp);
+#else
acl_free(acl);
+#endif
return (ret);
}
#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c
index a799524d4934..f6c24d1288b6 100644
--- a/contrib/libarchive/libarchive/archive_write_disk_posix.c
+++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c
@@ -1712,7 +1712,8 @@ _archive_write_disk_finish_entry(struct archive *_a)
const void *metadata;
size_t metadata_size;
metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
- if (metadata == NULL || metadata_size == 0) {
+ if ((a->todo & TODO_MAC_METADATA) == 0 ||
+ metadata == NULL || metadata_size == 0) {
#endif
r2 = archive_write_disk_set_acls(&a->archive, a->fd,
archive_entry_pathname(a->entry),
@@ -2067,6 +2068,7 @@ create_filesystem_object(struct archive_write_disk *a)
int r;
/* these for check_symlinks_fsobj */
char *linkname_copy; /* non-const copy of linkname */
+ struct stat st;
struct archive_string error_string;
int error_number;
@@ -2131,11 +2133,20 @@ create_filesystem_object(struct archive_write_disk *a)
a->todo = 0;
a->deferred = 0;
} else if (r == 0 && a->filesize > 0) {
- a->fd = open(a->name, O_WRONLY | O_TRUNC | O_BINARY
- | O_CLOEXEC | O_NOFOLLOW);
- __archive_ensure_cloexec_flag(a->fd);
- if (a->fd < 0)
+#ifdef HAVE_LSTAT
+ r = lstat(a->name, &st);
+#else
+ r = stat(a->name, &st);
+#endif
+ if (r != 0)
r = errno;
+ else if ((st.st_mode & AE_IFMT) == AE_IFREG) {
+ a->fd = open(a->name, O_WRONLY | O_TRUNC |
+ O_BINARY | O_CLOEXEC | O_NOFOLLOW);
+ __archive_ensure_cloexec_flag(a->fd);
+ if (a->fd < 0)
+ r = errno;
+ }
}
return (r);
#endif
@@ -2283,7 +2294,8 @@ _archive_write_disk_close(struct archive *_a)
chmod(p->name, p->mode);
if (p->fixup & TODO_ACLS)
#ifdef HAVE_DARWIN_ACL
- if (p->mac_metadata == NULL ||
+ if ((p->fixup & TODO_MAC_METADATA) == 0 ||
+ p->mac_metadata == NULL ||
p->mac_metadata_size == 0)
#endif
archive_write_disk_set_acls(&a->archive,
@@ -2455,7 +2467,7 @@ fsobj_error(int *a_eno, struct archive_string *a_estr,
if (a_eno)
*a_eno = err;
if (a_estr)
- archive_string_sprintf(a_estr, errstr, path);
+ archive_string_sprintf(a_estr, "%s%s", errstr, path);
}
/*
@@ -2561,7 +2573,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
* with the deep-directory editing.
*/
fsobj_error(a_eno, a_estr, errno,
- "Could not stat %s", path);
+ "Could not stat ", path);
res = ARCHIVE_FAILED;
break;
}
@@ -2570,7 +2582,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
if (chdir(head) != 0) {
tail[0] = c;
fsobj_error(a_eno, a_estr, errno,
- "Could not chdir %s", path);
+ "Could not chdir ", path);
res = (ARCHIVE_FATAL);
break;
}
@@ -2587,7 +2599,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
if (unlink(head)) {
tail[0] = c;
fsobj_error(a_eno, a_estr, errno,
- "Could not remove symlink %s",
+ "Could not remove symlink ",
path);
res = ARCHIVE_FAILED;
break;
@@ -2606,7 +2618,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
/*
if (!S_ISLNK(path)) {
fsobj_error(a_eno, a_estr, 0,
- "Removing symlink %s", path);
+ "Removing symlink ", path);
}
*/
/* Symlink gone. No more problem! */
@@ -2618,7 +2630,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
tail[0] = c;
fsobj_error(a_eno, a_estr, 0,
"Cannot remove intervening "
- "symlink %s", path);
+ "symlink ", path);
res = ARCHIVE_FAILED;
break;
}
@@ -2640,7 +2652,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
} else {
fsobj_error(a_eno, a_estr,
errno,
- "Could not stat %s", path);
+ "Could not stat ", path);
res = (ARCHIVE_FAILED);
break;
}
@@ -2649,7 +2661,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
tail[0] = c;
fsobj_error(a_eno, a_estr,
errno,
- "Could not chdir %s", path);
+ "Could not chdir ", path);
res = (ARCHIVE_FATAL);
break;
}
@@ -2662,14 +2674,14 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
tail[0] = c;
fsobj_error(a_eno, a_estr, 0,
"Cannot extract through "
- "symlink %s", path);
+ "symlink ", path);
res = ARCHIVE_FAILED;
break;
}
} else {
tail[0] = c;
fsobj_error(a_eno, a_estr, 0,
- "Cannot extract through symlink %s", path);
+ "Cannot extract through symlink ", path);
res = ARCHIVE_FAILED;
break;
}
@@ -3455,12 +3467,19 @@ set_fflags(struct archive_write_disk *a)
#ifdef UF_APPEND
critical_flags |= UF_APPEND;
#endif
-#ifdef EXT2_APPEND_FL
+#if defined(FS_APPEND_FL)
+ critical_flags |= FS_APPEND_FL;
+#elif defined(EXT2_APPEND_FL)
critical_flags |= EXT2_APPEND_FL;
#endif
-#ifdef EXT2_IMMUTABLE_FL
+#if defined(FS_IMMUTABLE_FL)
+ critical_flags |= FS_IMMUTABLE_FL;
+#elif defined(EXT2_IMMUTABLE_FL)
critical_flags |= EXT2_IMMUTABLE_FL;
#endif
+#ifdef FS_JOURNAL_DATA_FL
+ critical_flags |= FS_JOURNAL_DATA_FL;
+#endif
if (a->todo & TODO_FFLAGS) {
archive_entry_fflags(a->entry, &set, &clear);
@@ -3572,7 +3591,10 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
return (ARCHIVE_WARN);
}
-#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+#elif (defined(FS_IOC_GETFLAGS) && defined(FS_IOC_SETFLAGS) && \
+ defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+ (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && \
+ defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
/*
* Linux uses ioctl() to read and write file flags.
*/
@@ -3585,7 +3607,7 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
int newflags, oldflags;
int sf_mask = 0;
- if (set == 0 && clear == 0)
+ if (set == 0 && clear == 0)
return (ARCHIVE_OK);
/* Only regular files and dirs can have flags. */
if (!S_ISREG(mode) && !S_ISDIR(mode))
@@ -3606,12 +3628,19 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
* defines. (?) The code below degrades reasonably gracefully
* if sf_mask is incomplete.
*/
-#ifdef EXT2_IMMUTABLE_FL
+#if defined(FS_IMMUTABLE_FL)
+ sf_mask |= FS_IMMUTABLE_FL;
+#elif defined(EXT2_IMMUTABLE_FL)
sf_mask |= EXT2_IMMUTABLE_FL;
#endif
-#ifdef EXT2_APPEND_FL
+#if defined(FS_APPEND_FL)
+ sf_mask |= FS_APPEND_FL;
+#elif defined(EXT2_APPEND_FL)
sf_mask |= EXT2_APPEND_FL;
#endif
+#if defined(FS_JOURNAL_DATA_FL)
+ sf_mask |= FS_JOURNAL_DATA_FL;
+#endif
/*
* XXX As above, this would be way simpler if we didn't have
* to read the current flags from disk. XXX
@@ -3619,12 +3648,24 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
ret = ARCHIVE_OK;
/* Read the current file flags. */
- if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) < 0)
+ if (ioctl(myfd,
+#ifdef FS_IOC_GETFLAGS
+ FS_IOC_GETFLAGS,
+#else
+ EXT2_IOC_GETFLAGS,
+#endif
+ &oldflags) < 0)
goto fail;
/* Try setting the flags as given. */
newflags = (oldflags & ~clear) | set;
- if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+ if (ioctl(myfd,
+#ifdef FS_IOC_SETFLAGS
+ FS_IOC_SETFLAGS,
+#else
+ EXT2_IOC_SETFLAGS,
+#endif
+ &newflags) >= 0)
goto cleanup;
if (errno != EPERM)
goto fail;
@@ -3633,7 +3674,13 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
newflags &= ~sf_mask;
oldflags &= sf_mask;
newflags |= oldflags;
- if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+ if (ioctl(myfd,
+#ifdef FS_IOC_SETFLAGS
+ FS_IOC_SETFLAGS,
+#else
+ EXT2_IOC_SETFLAGS,
+#endif
+ &newflags) >= 0)
goto cleanup;
/* We couldn't set the flags, so report the failure. */
diff --git a/contrib/libarchive/libarchive/archive_write_finish_entry.3 b/contrib/libarchive/libarchive/archive_write_finish_entry.3
index c5ef69ebc941..dc1b94b82a5c 100644
--- a/contrib/libarchive/libarchive/archive_write_finish_entry.3
+++ b/contrib/libarchive/libarchive/archive_write_finish_entry.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 2, 2012
+.Dd February 28, 2017
.Dt ARCHIVE_WRITE_FINISH_ENTRY 3
.Os
.Sh NAME
@@ -45,6 +45,9 @@ is called automatically by
and
.Fn archive_write_close
as needed.
+For
+.Tn archive_write_disk
+handles, this flushes pending file attribute changes like modification time.
.\" .Sh EXAMPLE
.Sh RETURN VALUES
This function returns
diff --git a/contrib/libarchive/libarchive/archive_write_format.3 b/contrib/libarchive/libarchive/archive_write_format.3
index d4ba6abff5a0..aaafb0a8617c 100644
--- a/contrib/libarchive/libarchive/archive_write_format.3
+++ b/contrib/libarchive/libarchive/archive_write_format.3
@@ -108,7 +108,6 @@ Streaming Archive Library (libarchive, -larchive)
These functions set the format that will be used for the archive.
.Pp
The library can write a variety of common archive formats.
-
.Bl -tag -width indent
.It Fn archive_write_set_format
Sets the format based on the format code (see
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c b/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c
index 4e910979e096..c0ca435d15c7 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c
@@ -4074,8 +4074,10 @@ write_information_block(struct archive_write *a)
memset(info.s, 0, info_size);
opt = 0;
#if defined(HAVE__CTIME64_S)
- __time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
- _ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
+ {
+ __time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
+ _ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
+ }
#elif defined(HAVE_CTIME_R)
ctime_r(&(iso9660->birth_time), buf);
#else
diff --git a/contrib/libarchive/libarchive/test/test.h b/contrib/libarchive/libarchive/test/test.h
index dc3f59048a1b..fd679f5f2ffe 100644
--- a/contrib/libarchive/libarchive/test/test.h
+++ b/contrib/libarchive/libarchive/test/test.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2006 Tim Kientzle
+ * Copyright (c) 2003-2017 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -21,388 +21,16 @@
* 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.
- *
- * $FreeBSD$
*/
/* Every test program should #include "test.h" as the first thing. */
-/*
- * The goal of this file (and the matching test.c) is to
- * simplify the very repetitive test-*.c test programs.
- */
-#if defined(HAVE_CONFIG_H)
-/* Most POSIX platforms use the 'configure' script to build config.h */
-#include "config.h"
-#elif defined(__FreeBSD__)
-/* Building as part of FreeBSD system requires a pre-built config.h. */
-#include "config_freebsd.h"
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-/* Win32 can't run the 'configure' script. */
-#include "config_windows.h"
-#else
-/* Warn if the library hasn't been (automatically or manually) configured. */
-#error Oops: No config.h and no pre-built configuration in test.h.
-#endif
-
-#include <sys/types.h> /* Windows requires this before sys/stat.h */
-#include <sys/stat.h>
-
-#if HAVE_DIRENT_H
-#include <dirent.h>
-#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 <ctype.h>
-#include <time.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <wchar.h>
-#ifdef HAVE_WINDOWS_H
-#include <windows.h>
-#endif
-
-/*
- * System-specific tweaks. We really want to minimize these
- * as much as possible, since they make it harder to understand
- * the mainline code.
- */
-
-/* Windows (including Visual Studio and MinGW but not Cygwin) */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#if !defined(__BORLANDC__)
-#undef chdir
-#define chdir _chdir
-#define strdup _strdup
-#endif
-#endif
-
-/* Visual Studio */
-#if defined(_MSC_VER) && _MSC_VER < 1900
-#define snprintf sprintf_s
-#endif
-
-#if defined(__BORLANDC__)
-#pragma warn -8068 /* Constant out of range in comparison. */
-#endif
-
-/* Haiku OS and QNX */
-#if defined(__HAIKU__) || defined(__QNXNTO__)
-/* Haiku and QNX have 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
-#define O_BINARY 0
-#endif
-
-/*
- * If this platform has <sys/acl.h>, acl_create(), acl_init(),
- * acl_set_file(), and ACL_USER, we assume it has the rest of the
- * POSIX.1e draft functions used in archive_read_extract.c.
- */
-#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
-#if HAVE_ACL_USER
-#define HAVE_POSIX_ACL 1
-#elif HAVE_ACL_TYPE_EXTENDED
-#define HAVE_DARWIN_ACL 1
-#endif
-#endif
-
-/*
- * If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
- * facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
- */
-#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
-#define HAVE_SUN_ACL 1
-#endif
-
-/* Define if platform supports NFSv4 ACLs */
-#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
-#define HAVE_NFS4_ACL 1
-#endif
-
-/*
- * Redefine DEFINE_TEST for use in defining the test functions.
- */
-#undef DEFINE_TEST
-#define DEFINE_TEST(name) void name(void); void name(void)
-
-/* An implementation of the standard assert() macro */
-#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) \
- 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) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
-#define assertEqualUTF8String(v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
-/* As above, but v1 and v2 are wchar_t * */
-#define assertEqualWString(v1,v2) \
- assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-/* As above, but raw blocks of bytes. */
-#define assertEqualMem(v1, v2, l) \
- assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
-/* Assert that memory is full of a specified byte */
-#define assertMemoryFilledWith(v1, l, b) \
- assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
-/* Assert two files are the same. */
-#define assertEqualFile(f1, f2) \
- assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
-/* Assert that a file is empty. */
-#define assertEmptyFile(pathname) \
- assertion_empty_file(__FILE__, __LINE__, (pathname))
-/* Assert that a file is not empty. */
-#define assertNonEmptyFile(pathname) \
- assertion_non_empty_file(__FILE__, __LINE__, (pathname))
-#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(pathname) \
- assertion_file_exists(__FILE__, __LINE__, pathname)
-/* Assert that a file exists. */
-#define assertFileNotExists(pathname) \
- assertion_file_not_exists(__FILE__, __LINE__, pathname)
-/* Assert that file contents match a string. */
-#define assertFileContents(data, data_size, pathname) \
- assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
-/* Verify that a file does not contain invalid strings */
-#define assertFileContainsNoInvalidStrings(pathname, strings) \
- assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
-#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 assertFileMode(pathname, mode) \
- assertion_file_mode(__FILE__, __LINE__, pathname, mode)
-#define assertTextFileContents(text, pathname) \
- assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
-#define assertFileContainsLinesAnyOrder(pathname, lines) \
- assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
-#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, -1, contents)
-#define assertMakeBinFile(path, mode, csize, contents) \
- assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
-#define assertMakeHardlink(newfile, oldfile) \
- assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
-#define assertMakeSymlink(newfile, linkto) \
- assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
-#define assertNodump(path) \
- assertion_nodump(__FILE__, __LINE__, path)
-#define assertUmask(mask) \
- assertion_umask(__FILE__, __LINE__, mask)
-#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
- assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
-
-/*
- * This would be simple with C99 variadic macros, but I don't want to
- * require that. Instead, I insert a function call before each
- * skipping() call to pass the file and line information down. Crude,
- * but effective.
- */
-#define skipping \
- skipping_setup(__FILE__, __LINE__);test_skipping
-
-/* Function declarations. These are defined in test_utility.c. */
-void failure(const char *fmt, ...);
-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, const char *);
-int assertion_equal_file(const char *, int, 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_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
-int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
-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_contains_lines_any_order(const char *, int, const char *, const char **);
-int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
-int assertion_file_contents(const char *, int, const void *, int, const char *);
-int assertion_file_exists(const char *, int, const char *);
-int assertion_file_mode(const char *, int, const char *, int);
-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, 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, int, const void *);
-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_nodump(const char *, int, const char *);
-int assertion_non_empty_file(const char *, int, const char *);
-int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
-int assertion_umask(const char *, int, int);
-int assertion_utimes(const char *, int, const char *, long, long, long, long );
-
-void skipping_setup(const char *, int);
-void test_skipping(const char *fmt, ...);
-
-/* 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 "bzip2" program. */
-int canBzip2(void);
-
-/* Return true if this platform can run the "grzip" program. */
-int canGrzip(void);
-
-/* Return true if this platform can run the "gzip" program. */
-int canGzip(void);
-
-/* Return true if this platform can run the specified command. */
-int canRunCommand(const char *);
-
-/* Return true if this platform can run the "lrzip" program. */
-int canLrzip(void);
-
-/* Return true if this platform can run the "lz4" program. */
-int canLz4(void);
-
-/* Return true if this platform can run the "lzip" program. */
-int canLzip(void);
-
-/* Return true if this platform can run the "lzma" program. */
-int canLzma(void);
-
-/* Return true if this platform can run the "lzop" program. */
-int canLzop(void);
-
-/* Return true if this platform can run the "xz" program. */
-int canXz(void);
-
-/* Return true if this filesystem can handle nodump flags. */
-int canNodump(void);
-
-/* Return true if the file has large i-node number(>0xffffffff). */
-int is_LargeInode(const char *);
-
-/* 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, ...);
-
-/* Dump block of bytes to a file. */
-void dumpfile(const char *filename, void *, size_t);
-
-/* Extracts named reference file to the current directory. */
-void extract_reference_file(const char *);
-/* Copies named reference file to the current directory. */
-void copy_reference_file(const char *);
-
-/* Extracts a list of files to the current directory.
- * List must be NULL terminated.
- */
-void extract_reference_files(const char **);
-
-/* Subtract umask from mode */
-mode_t umasked(mode_t expected_mode);
-
-/* Path to working directory for current test */
-extern const char *testworkdir;
-
-/*
- * Special interfaces for libarchive test harness.
- */
-
-#include "archive.h"
-#include "archive_entry.h"
-
-/* ACL structure */
-struct archive_test_acl_t {
- int type; /* Type of ACL */
- int permset; /* Permissions for this class of users. */
- int tag; /* Owner, User, Owning group, group, other, etc. */
- int qual; /* GID or UID of user/group, depending on tag. */
- const char *name; /* Name of user/group, depending on tag. */
-};
-
-/* Set ACLs */
-void archive_test_set_acls(struct archive_entry *, struct archive_test_acl_t *,
- int);
-
-/* Compare ACLs */
-void archive_test_compare_acls(struct archive_entry *,
- struct archive_test_acl_t *, int, int, int);
-
-/* Special customized read-from-memory interface. */
-int read_open_memory(struct archive *, const void *, size_t, size_t);
-/* _minimal version exercises a slightly different set of libarchive APIs. */
-int read_open_memory_minimal(struct archive *, const void *, size_t, size_t);
-/* _seek version produces a seekable file. */
-int read_open_memory_seek(struct archive *, const void *, size_t, size_t);
-
-/* Versions of above that accept an archive argument for additional info. */
-#define assertA(e) assertion_assert(__FILE__, __LINE__, (e), #e, (a))
-#define assertEqualIntA(a,v1,v2) \
- assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a))
-#define assertEqualStringA(a,v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a), 0)
+#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 EXTRA_DUMP(x) archive_error_string((struct archive *)(x))
+#define EXTRA_ERRNO(x) archive_errno((struct archive *)(x))
+#define EXTRA_VERSION archive_version_details()
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#endif
+#include "test_common.h"
diff --git a/contrib/libarchive/libarchive/test/test_acl_nfs4.c b/contrib/libarchive/libarchive/test/test_acl_nfs4.c
index f4e66f52294e..fdc0191516e1 100644
--- a/contrib/libarchive/libarchive/test/test_acl_nfs4.c
+++ b/contrib/libarchive/libarchive/test/test_acl_nfs4.c
@@ -159,7 +159,7 @@ DEFINE_TEST(test_acl_nfs4)
archive_entry_set_mode(ae, S_IFREG | 0777);
/* Store and read back some basic ACL entries. */
- archive_test_set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
+ assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
/* Check that entry contains only NFSv4 types */
assert((archive_entry_acl_types(ae) &
@@ -169,21 +169,21 @@ DEFINE_TEST(test_acl_nfs4)
assertEqualInt(4,
archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
- archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
+ assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
/* A more extensive set of ACLs. */
- archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
+ assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
assertEqualInt(32,
archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
- archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
+ assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
/*
* Check that clearing ACLs gets rid of them all by repeating
* the first test.
*/
- archive_test_set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
+ assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
failure("Basic ACLs shouldn't be stored as extended ACLs");
assertEqualInt(4,
archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
@@ -192,7 +192,7 @@ DEFINE_TEST(test_acl_nfs4)
* Different types of malformed ACL entries that should
* fail when added to existing NFS4 ACLs.
*/
- archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
+ assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
for (i = 0; i < (int)(sizeof(acls_bad)/sizeof(acls_bad[0])); ++i) {
struct archive_test_acl_t *p = &acls_bad[i];
failure("Malformed ACL test #%d", i);
diff --git a/contrib/libarchive/libarchive/test/test_acl_pax.c b/contrib/libarchive/libarchive/test/test_acl_pax.c
index 8dfa0e031312..8566f55a51a4 100644
--- a/contrib/libarchive/libarchive/test/test_acl_pax.c
+++ b/contrib/libarchive/libarchive/test/test_acl_pax.c
@@ -238,23 +238,22 @@ DEFINE_TEST(test_acl_pax_posix1e)
archive_entry_set_mode(ae, S_IFREG | 0777);
/* Basic owner/owning group should just update mode bits. */
- archive_test_set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
+ assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
assertA(0 == archive_write_header(a, ae));
/* With any extended ACL entry, we should read back a full set. */
- archive_test_set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
+ assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
assertA(0 == archive_write_header(a, ae));
-
/* A more extensive set of ACLs. */
- archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
+ assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
assertA(0 == archive_write_header(a, ae));
/*
* Check that clearing ACLs gets rid of them all by repeating
* the first test.
*/
- archive_test_set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
+ assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
assertA(0 == archive_write_header(a, ae));
archive_entry_free(ae);
@@ -296,7 +295,7 @@ DEFINE_TEST(test_acl_pax_posix1e)
assertA(0 == archive_read_next_header(a, &ae));
failure("One extended ACL should flag all ACLs to be returned.");
assert(4 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
- archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
+ assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142);
failure("Basic ACLs should set mode to 0142, not %04o",
archive_entry_mode(ae)&0777);
@@ -306,7 +305,7 @@ DEFINE_TEST(test_acl_pax_posix1e)
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
- archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
+ assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543);
failure("Basic ACLs should set mode to 0543, not %04o",
archive_entry_mode(ae)&0777);
@@ -350,15 +349,15 @@ DEFINE_TEST(test_acl_pax_nfs4)
archive_entry_set_mode(ae, S_IFREG | 0777);
/* NFS4 ACLs mirroring 0754 file mode */
- archive_test_set_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]));
+ assertEntrySetAcls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]));
assertA(0 == archive_write_header(a, ae));
/* A more extensive set of NFS4 ACLs. */
- archive_test_set_acls(ae, acls4, sizeof(acls4)/sizeof(acls4[0]));
+ assertEntrySetAcls(ae, acls4, sizeof(acls4)/sizeof(acls4[0]));
assertA(0 == archive_write_header(a, ae));
/* Set with special (audit, alarm) NFS4 ACLs. */
- archive_test_set_acls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]));
+ assertEntrySetAcls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]));
assertA(0 == archive_write_header(a, ae));
archive_entry_free(ae);
@@ -393,21 +392,21 @@ DEFINE_TEST(test_acl_pax_nfs4)
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(3, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ALLOW));
- archive_test_compare_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
+ assertEntryCompareAcls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0);
/* Second item has has more fine-grained NFS4 ACLs */
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
- archive_test_compare_acls(ae, acls4, sizeof(acls4)/sizeof(acls4[0]),
+ assertEntryCompareAcls(ae, acls4, sizeof(acls4)/sizeof(acls4[0]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
/* Third item has has audit and alarm NFS4 ACLs */
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
- archive_test_compare_acls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]),
+ assertEntryCompareAcls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
/* Close the archive. */
diff --git a/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c b/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c
index 01c1dc589f6f..c8854082ab1b 100644
--- a/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c
+++ b/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c
@@ -254,12 +254,14 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
int i;
archive_entry_acl_clear(ae);
+#if !HAVE_DARWIN_ACL
if (start > 0) {
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_add_entry(ae,
acls[0].type, acls[0].permset, acls[0].tag,
acls[0].qual, acls[0].name));
}
+#endif
for (i = start; i < end; i++) {
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_add_entry(ae,
@@ -269,14 +271,14 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
}
static int
-#ifdef HAVE_SUN_ACL
+#ifdef HAVE_SUN_NFS4_ACL
acl_permset_to_bitmap(uint32_t a_access_mask)
#else
acl_permset_to_bitmap(acl_permset_t opaque_ps)
#endif
{
static struct { int machine; int portable; } perms[] = {
-#ifdef HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
+#ifdef HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL permissions */
{ACE_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
{ACE_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
{ACE_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
@@ -311,7 +313,9 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
{ACL_READ_SECURITY, ARCHIVE_ENTRY_ACL_READ_ACL},
{ACL_WRITE_SECURITY, ARCHIVE_ENTRY_ACL_WRITE_ACL},
{ACL_CHANGE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
+#if HAVE_DECL_ACL_SYNCHRONIZE
{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE},
+#endif
#else /* FreeBSD NFSv4 ACL permissions */
{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
{ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
@@ -337,7 +341,7 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
int i, permset = 0;
for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
-#if HAVE_SUN_ACL
+#if HAVE_SUN_NFS4_ACL
if (a_access_mask & perms[i].machine)
#else
if (acl_get_perm_np(opaque_ps, perms[i].machine))
@@ -347,21 +351,23 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
}
static int
-#if HAVE_SUN_ACL
+#if HAVE_SUN_NFS4_ACL
acl_flagset_to_bitmap(uint16_t a_flags)
#else
acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
#endif
{
static struct { int machine; int portable; } flags[] = {
-#if HAVE_SUN_ACL /* Solaris NFSv4 ACL inheritance flags */
+#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL inheritance flags */
{ACE_FILE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
{ACE_DIRECTORY_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
{ACE_NO_PROPAGATE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
{ACE_INHERIT_ONLY_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
{ACE_SUCCESSFUL_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
{ACE_FAILED_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
+#ifdef ACE_INHERITED_ACE
{ACE_INHERITED_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED}
+#endif
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 ACL inheritance flags */
{ACL_ENTRY_INHERITED, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED},
{ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
@@ -380,7 +386,7 @@ acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
int i, flagset = 0;
for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
-#if HAVE_SUN_ACL
+#if HAVE_SUN_NFS4_ACL
if (a_flags & flags[i].machine)
#else
if (acl_get_flag_np(opaque_fs, flags[i].machine))
@@ -390,13 +396,13 @@ acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
}
static int
-#if HAVE_SUN_ACL
+#if HAVE_SUN_NFS4_ACL
acl_match(ace_t *ace, struct myacl_t *myacl)
#else
acl_match(acl_entry_t aclent, struct myacl_t *myacl)
#endif
{
-#if !HAVE_SUN_ACL
+#if !HAVE_SUN_NFS4_ACL
#if HAVE_DARWIN_ACL
void *q;
uid_t ugid;
@@ -409,10 +415,10 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
acl_tag_t tag_type;
acl_permset_t opaque_ps;
acl_flagset_t opaque_fs;
-#endif /* !HAVE_SUN_ACL */
+#endif /* !HAVE_SUN_NFS4_ACL */
int perms;
-#if HAVE_SUN_ACL
+#if HAVE_SUN_NFS4_ACL
perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags);
#else
acl_get_tag_type(aclent, &tag_type);
@@ -428,7 +434,7 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
if (perms != myacl->permset)
return (0);
-#if HAVE_SUN_ACL
+#if HAVE_SUN_NFS4_ACL
switch (ace->a_type) {
case ACE_ACCESS_ALLOWED_ACE_TYPE:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
@@ -507,7 +513,7 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
default:
return (0);
}
-#else /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
+#else /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
switch (entry_type) {
case ACL_ENTRY_TYPE_ALLOW:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
@@ -559,14 +565,15 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
break;
}
-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
+#endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
return (1);
}
static void
compare_acls(
-#if HAVE_SUN_ACL
- acl_t *acl,
+#if HAVE_SUN_NFS4_ACL
+ void *aclp,
+ int aclcnt,
#else
acl_t acl,
#endif
@@ -575,7 +582,7 @@ compare_acls(
int *marker;
int matched;
int i, n;
-#if HAVE_SUN_ACL
+#if HAVE_SUN_NFS4_ACL
int e;
ace_t *acl_entry;
#else
@@ -587,26 +594,28 @@ compare_acls(
marker = malloc(sizeof(marker[0]) * (n + 1));
for (i = 0; i < n; i++)
marker[i] = i + start;
+#if !HAVE_DARWIN_ACL
/* Always include the first ACE. */
if (start > 0) {
marker[n] = 0;
++n;
}
+#endif
/*
* Iterate over acls in system acl object, try to match each
* one with an item in the myacls array.
*/
-#if HAVE_SUN_ACL
- for (e = 0; e < acl->acl_cnt; e++)
+#if HAVE_SUN_NFS4_ACL
+ for (e = 0; e < aclcnt; e++)
#elif HAVE_DARWIN_ACL
while (0 == acl_get_entry(acl, entry_id, &acl_entry))
#else
while (1 == acl_get_entry(acl, entry_id, &acl_entry))
#endif
{
-#if HAVE_SUN_ACL
- acl_entry = &((ace_t *)acl->acl_aclp)[e];
+#if HAVE_SUN_NFS4_ACL
+ acl_entry = &((ace_t *)aclp)[e];
#else
/* After the first time... */
entry_id = ACL_NEXT_ENTRY;
@@ -711,11 +720,10 @@ DEFINE_TEST(test_acl_platform_nfs4)
skipping("NFS4 ACLs are not supported on this platform");
#else
char buff[64];
+ int i;
struct stat st;
struct archive *a;
struct archive_entry *ae;
- int i, n;
- char *func;
#if HAVE_DARWIN_ACL /* On MacOS we skip trivial ACLs in some tests */
const int regcnt = acls_reg_cnt - 4;
const int dircnt = acls_dir_cnt - 4;
@@ -723,85 +731,19 @@ DEFINE_TEST(test_acl_platform_nfs4)
const int regcnt = acls_reg_cnt;
const int dircnt = acls_dir_cnt;
#endif
-#if HAVE_SUN_ACL
- acl_t *acl;
-#else /* !HAVE_SUN_ACL */
-#if HAVE_DARWIN_ACL
- acl_entry_t aclent;
- acl_permset_t permset;
- const uid_t uid = 1000;
- uuid_t uuid;
-#endif /* HAVE_DARWIN_ACL */
+#if HAVE_SUN_NFS4_ACL
+ void *aclp;
+ int aclcnt;
+#else /* !HAVE_SUN_NFS4_ACL */
acl_t acl;
-#endif /* !HAVE_SUN_ACL */
-
- /*
- * First, do a quick manual set/read of ACL data to
- * verify that the local filesystem does support ACLs.
- * If it doesn't, we'll simply skip the remaining tests.
- */
-#if HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4
- acl = acl_from_text("owner@:rwxp::allow,group@:rwp:f:allow");
- failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
- assert((void *)acl != NULL);
-#elif HAVE_DARWIN_ACL
- acl = acl_init(1);
- assert((void *)acl != NULL);
- assertEqualInt(0, acl_create_entry(&acl, &aclent));
- assertEqualInt(0, acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW));
- assertEqualInt(0, acl_get_permset(aclent, &permset));
- assertEqualInt(0, acl_add_perm(permset, ACL_READ_DATA));
- assertEqualInt(0, acl_add_perm(permset, ACL_WRITE_DATA));
- assertEqualInt(0, acl_add_perm(permset, ACL_APPEND_DATA));
- assertEqualInt(0, acl_add_perm(permset, ACL_EXECUTE));
- assertEqualInt(0, acl_set_permset(aclent, permset));
- assertEqualInt(0, mbr_identifier_to_uuid(ID_TYPE_UID, &uid,
- sizeof(uid_t), uuid));
- assertEqualInt(0, acl_set_qualifier(aclent, uuid));
-#endif
-
- /* Create a test dir and try to set an ACL on it. */
- if (!assertMakeDir("pretest", 0755)) {
-#if !HAVE_SUN_ACL
- acl_free(acl);
#endif
- return;
- }
-#if HAVE_SUN_ACL
- func = "acl_get()";
- n = acl_get("pretest", 0, &acl);
-#else
- func = "acl_set_file()";
-#if HAVE_DARWIN_ACL
- n = acl_set_file("pretest", ACL_TYPE_EXTENDED, acl);
-#else
- n = acl_set_file("pretest", ACL_TYPE_NFS4, acl);
-#endif
- acl_free(acl);
-#endif
- if (n != 0) {
-#if HAVE_SUN_ACL
- if (errno == ENOSYS)
-#else
- if (errno == EOPNOTSUPP || errno == EINVAL)
-#endif
- {
- skipping("NFS4 ACL is not supported on this filesystem");
- return;
- }
- }
- failure("%s: errno = %d (%s)", func, errno, strerror(errno));
- assertEqualInt(0, n);
+ assertMakeFile("pretest", 0644, "a");
-#if HAVE_SUN_ACL
- if (acl->acl_type != ACE_T) {
- acl_free(acl);
- skipping("NFS4 ACL is not supported on this filesystem");
+ if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_NFS4) {
+ skipping("NFS4 ACLs are not writable on this filesystem");
return;
}
- acl_free(acl);
-#endif
/* Create a write-to-disk object. */
assert(NULL != (a = archive_write_disk_new()));
@@ -848,10 +790,10 @@ DEFINE_TEST(test_acl_platform_nfs4)
/* Verify the data on disk. */
assertEqualInt(0, stat("testall", &st));
assertEqualInt(st.st_mtime, 123456);
-#if HAVE_SUN_ACL
- n = acl_get("testall", 0, &acl);
- failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
- assertEqualInt(0, n);
+#if HAVE_SUN_NFS4_ACL
+ aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "testall");
+ failure("acl(): errno = %d (%s)", errno, strerror(errno));
+ assert(aclp != NULL);
#else
#if HAVE_DARWIN_ACL
acl = acl_get_file("testall", ACL_TYPE_EXTENDED);
@@ -861,18 +803,25 @@ DEFINE_TEST(test_acl_platform_nfs4)
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
assert(acl != (acl_t)NULL);
#endif
+#if HAVE_SUN_NFS4_ACL
+ compare_acls(aclp, aclcnt, acls_reg, "testall", 0, regcnt);
+ free(aclp);
+ aclp = NULL;
+#else
compare_acls(acl, acls_reg, "testall", 0, regcnt);
acl_free(acl);
+#endif
+
/* Verify single-permission dirs on disk. */
for (i = 0; i < dircnt; ++i) {
sprintf(buff, "dir%d", i);
assertEqualInt(0, stat(buff, &st));
assertEqualInt(st.st_mtime, 123456 + i);
-#if HAVE_SUN_ACL
- n = acl_get(buff, 0, &acl);
- failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
- assertEqualInt(0, n);
+#if HAVE_SUN_NFS4_ACL
+ aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, buff);
+ failure("acl(): errno = %d (%s)", errno, strerror(errno));
+ assert(aclp != NULL);
#else
#if HAVE_DARWIN_ACL
acl = acl_get_file(buff, ACL_TYPE_EXTENDED);
@@ -883,17 +832,23 @@ DEFINE_TEST(test_acl_platform_nfs4)
strerror(errno));
assert(acl != (acl_t)NULL);
#endif
+#if HAVE_SUN_NFS4_ACL
+ compare_acls(aclp, aclcnt, acls_dir, buff, i, i + 1);
+ free(aclp);
+ aclp = NULL;
+#else
compare_acls(acl, acls_dir, buff, i, i + 1);
acl_free(acl);
+#endif
}
/* Verify "dirall" on disk. */
assertEqualInt(0, stat("dirall", &st));
assertEqualInt(st.st_mtime, 123456);
-#if HAVE_SUN_ACL
- n = acl_get("dirall", 0, &acl);
- failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
- assertEqualInt(0, n);
+#if HAVE_SUN_NFS4_ACL
+ aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "dirall");
+ failure("acl(): errno = %d (%s)", errno, strerror(errno));
+ assert(aclp != NULL);
#else
#if HAVE_DARWIN_ACL
acl = acl_get_file("dirall", ACL_TYPE_EXTENDED);
@@ -903,8 +858,14 @@ DEFINE_TEST(test_acl_platform_nfs4)
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
assert(acl != (acl_t)NULL);
#endif
+#if HAVE_SUN_NFS4_ACL
+ compare_acls(aclp, aclcnt, acls_dir, "dirall", 0, dircnt);
+ free(aclp);
+ aclp = NULL;
+#else
compare_acls(acl, acls_dir, "dirall", 0, dircnt);
acl_free(acl);
+#endif
/* Read and compare ACL via archive_read_disk */
a = archive_read_disk_new();
diff --git a/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c b/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c
index 1d55a33eb951..0224a57f1c23 100644
--- a/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c
+++ b/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c
@@ -226,7 +226,7 @@ acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
static void
#if HAVE_SUN_ACL
-compare_acls(acl_t *acl, struct archive_test_acl_t *myacls, int n)
+compare_acls(void *aclp, int aclcnt, struct archive_test_acl_t *myacls, int n)
#else
compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
#endif
@@ -254,8 +254,8 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
* one with an item in the myacls array.
*/
#if HAVE_SUN_ACL
- for(e = 0; e < acl->acl_cnt; e++) {
- acl_entry = &((aclent_t *)acl->acl_aclp)[e];
+ for(e = 0; e < aclcnt; e++) {
+ acl_entry = &((aclent_t *)aclp)[e];
#else
while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
/* After the first time... */
@@ -304,83 +304,19 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
struct stat st;
struct archive *a;
struct archive_entry *ae;
- int n, fd;
- char *func;
#if HAVE_SUN_ACL
- acl_t *acl, *acl2;
+ void *aclp;
+ int aclcnt;
#else
acl_t acl;
#endif
- /*
- * First, do a quick manual set/read of ACL data to
- * verify that the local filesystem does support ACLs.
- * If it doesn't, we'll simply skip the remaining tests.
- */
-#if HAVE_SUN_ACL
- n = acl_fromtext("user::rwx,user:1:rw-,group::rwx,group:15:r-x,other:rwx,mask:rwx", &acl);
- failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
- assertEqualInt(0, n);
-#else
- acl = acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx");
- failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
- assert((void *)acl != NULL);
-#endif
-
- /* Create a test file and try ACL on it. */
- fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
- failure("Could not create test file?!");
- if (!assert(fd >= 0)) {
- acl_free(acl);
- return;
- }
-
-#if HAVE_SUN_ACL
- n = facl_get(fd, 0, &acl2);
- if (n != 0) {
- close(fd);
- acl_free(acl);
- }
- if (errno == ENOSYS) {
- skipping("POSIX.1e ACLs are not supported on this filesystem");
- return;
- }
- failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
- assertEqualInt(0, n);
+ assertMakeFile("pretest", 0644, "a");
- if (acl2->acl_type != ACLENT_T) {
- acl_free(acl2);
- skipping("POSIX.1e ACLs are not supported on this filesystem");
+ if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_POSIX1E) {
+ skipping("POSIX.1e ACLs are not writable on this filesystem");
return;
}
- acl_free(acl2);
-
- func = "facl_set()";
- n = facl_set(fd, acl);
-#else
- func = "acl_set_fd()";
- n = acl_set_fd(fd, acl);
-#endif
- acl_free(acl);
- if (n != 0) {
-#if HAVE_SUN_ACL
- if (errno == ENOSYS)
-#else
- if (errno == EOPNOTSUPP || errno == EINVAL)
-#endif
- {
- close(fd);
- skipping("POSIX.1e ACLs are not supported on this filesystem");
- return;
- }
- }
- failure("%s: errno = %d (%s)", func, errno, strerror(errno));
- assertEqualInt(0, n);
-
-#if HAVE_SUN_ACL
-
-#endif
- close(fd);
/* Create a write-to-disk object. */
assert(NULL != (a = archive_write_disk_new()));
@@ -393,7 +329,7 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
archive_entry_set_pathname(ae, "test0");
archive_entry_set_mtime(ae, 123456, 7890);
archive_entry_set_size(ae, 0);
- archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
+ assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
archive_entry_free(ae);
@@ -405,16 +341,23 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
assertEqualInt(0, stat("test0", &st));
assertEqualInt(st.st_mtime, 123456);
#if HAVE_SUN_ACL
- n = acl_get("test0", 0, &acl);
- failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
- assertEqualInt(0, n);
+ aclp = sunacl_get(GETACL, &aclcnt, 0, "test0");
+ failure("acl(): errno = %d (%s)", errno, strerror(errno));
+ assert(aclp != NULL);
#else
acl = acl_get_file("test0", ACL_TYPE_ACCESS);
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
assert(acl != (acl_t)NULL);
#endif
+#if HAVE_SUN_ACL
+ compare_acls(aclp, aclcnt, acls2, sizeof(acls2)/sizeof(acls2[0]));
+ free(aclp);
+ aclp = NULL;
+#else
compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0]));
acl_free(acl);
+#endif
+
#endif /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
}
@@ -432,7 +375,8 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
char *func, *acl_text;
const char *acl1_text, *acl2_text, *acl3_text;
#if HAVE_SUN_ACL
- acl_t *acl, *acl1, *acl2, *acl3;
+ void *aclp;
+ int aclcnt;
#else
acl_t acl1, acl2, acl3;
#endif
@@ -451,9 +395,14 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
"user:1:rw-,"
"group:15:r-x,"
"mask:rwx";
- n = acl_fromtext(acl1_text, &acl1);
- failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
- assertEqualInt(0, n);
+ aclent_t aclp1[] = {
+ { USER_OBJ, -1, 4 | 2 | 1 },
+ { USER, 1, 4 | 2 },
+ { GROUP_OBJ, -1, 4 | 2 | 1 },
+ { GROUP, 15, 4 | 1 },
+ { CLASS_OBJ, -1, 4 | 2 | 1 },
+ { OTHER_OBJ, -1, 4 | 2 | 1 }
+ };
#else
acl1_text = "user::rwx\n"
"group::rwx\n"
@@ -468,41 +417,36 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
failure("Could not create test file?!");
if (!assert(fd >= 0)) {
+#if !HAVE_SUN_ACL
acl_free(acl1);
+#endif
return;
}
#if HAVE_SUN_ACL
/* Check if Solaris filesystem supports POSIX.1e ACLs */
- n = facl_get(fd, 0, &acl);
- if (n != 0)
- close(fd);
- if (n != 0 && errno == ENOSYS) {
- acl_free(acl1);
- skipping("POSIX.1e ACLs are not supported on this filesystem");
- return;
- }
- failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
- assertEqualInt(0, n);
-
- if (acl->acl_type != ACLENT_T) {
- acl_free(acl);
- acl_free(acl1);
+ aclp = sunacl_get(GETACL, &aclcnt, fd, NULL);
+ if (aclp == 0)
close(fd);
+ if (errno == ENOSYS || errno == ENOTSUP) {
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
+ failure("facl(): errno = %d (%s)", errno, strerror(errno));
+ assert(aclp != NULL);
- func = "facl_set()";
- n = facl_set(fd, acl1);
+ func = "facl()";
+ n = facl(fd, SETACL, (int)(sizeof(aclp1)/sizeof(aclp1[0])), aclp1);
#else
func = "acl_set_fd()";
n = acl_set_fd(fd, acl1);
#endif
+#if !HAVE_SUN_ACL
acl_free(acl1);
+#endif
if (n != 0) {
#if HAVE_SUN_ACL
- if (errno == ENOSYS)
+ if (errno == ENOSYS || errno == ENOTSUP)
#else
if (errno == EOPNOTSUPP || errno == EINVAL)
#endif
@@ -537,9 +481,14 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
"user:1:r--,"
"group:15:r--,"
"mask:rwx";
- n = acl_fromtext(acl2_text, &acl2);
- failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
- assertEqualInt(0, n);
+ aclent_t aclp2[] = {
+ { USER_OBJ, -1, 4 | 2 | 1 },
+ { USER, 1, 4 },
+ { GROUP_OBJ, -1, 4 | 2 | 1},
+ { GROUP, 15, 4 },
+ { CLASS_OBJ, -1, 4 | 2 | 1},
+ { OTHER_OBJ, -1, 0 }
+ };
#else
acl2_text = "user::rwx\n"
"group::rwx\n"
@@ -554,25 +503,27 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
failure("Could not create test file?!");
if (!assert(fd >= 0)) {
+#if !HAVE_SUN_ACL
acl_free(acl2);
+#endif
return;
}
#if HAVE_SUN_ACL
- func = "facl_set()";
- n = facl_set(fd, acl2);
+ func = "facl()";
+ n = facl(fd, SETACL, (int)(sizeof(aclp2) / sizeof(aclp2[0])), aclp2);
#else
func = "acl_set_fd()";
n = acl_set_fd(fd, acl2);
-#endif
acl_free(acl2);
+#endif
if (n != 0)
close(fd);
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
assertEqualInt(0, n);
close(fd);
- /* Create directory d2 with default ACLs */
- assertMakeDir("d2", 0755);
+ /* Create nested directory d2 with default ACLs */
+ assertMakeDir("d/d2", 0755);
#if HAVE_SUN_ACL
acl3_text = "user::rwx,"
@@ -587,9 +538,20 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
"default:group:15:r--,"
"default:mask:rwx,"
"default:other:r-x";
- n = acl_fromtext(acl3_text, &acl3);
- failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
- assertEqualInt(0, n);
+ aclent_t aclp3[] = {
+ { USER_OBJ, -1, 4 | 2 | 1 },
+ { USER, 2, 4 },
+ { GROUP_OBJ, -1, 4 | 1 },
+ { GROUP, 16, 2 },
+ { CLASS_OBJ, -1, 4 | 2 | 1 },
+ { OTHER_OBJ, -1, 4 | 1 },
+ { USER_OBJ | ACL_DEFAULT, -1, 4 | 2 | 1 },
+ { USER | ACL_DEFAULT, 1, 4 },
+ { GROUP_OBJ | ACL_DEFAULT, -1, 4 | 1 },
+ { GROUP | ACL_DEFAULT, 15, 4 },
+ { CLASS_OBJ | ACL_DEFAULT, -1, 4 | 2 | 1},
+ { OTHER_OBJ | ACL_DEFAULT, -1, 4 | 1 }
+ };
#else
acl3_text = "user::rwx\n"
"user:1:r--\n"
@@ -603,14 +565,13 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
#endif
#if HAVE_SUN_ACL
- func = "acl_set()";
- n = acl_set("d2", acl3);
+ func = "acl()";
+ n = acl("d/d2", SETACL, (int)(sizeof(aclp3) / sizeof(aclp3[0])), aclp3);
#else
func = "acl_set_file()";
- n = acl_set_file("d2", ACL_TYPE_DEFAULT, acl3);
-#endif
+ n = acl_set_file("d/d2", ACL_TYPE_DEFAULT, acl3);
acl_free(acl3);
-
+#endif
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
assertEqualInt(0, n);
@@ -640,7 +601,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
acl_text = archive_entry_acl_to_text(ae, NULL, flags);
assertEqualString(acl_text, acl2_text);
free(acl_text);
- } else if (strcmp(archive_entry_pathname(ae), "./d2") == 0) {
+ } else if (strcmp(archive_entry_pathname(ae), "./d/d2") == 0) {
acl_text = archive_entry_acl_to_text(ae, NULL, dflags);
assertEqualString(acl_text, acl3_text);
free(acl_text);
diff --git a/contrib/libarchive/libarchive/test/test_acl_posix1e.c b/contrib/libarchive/libarchive/test/test_acl_posix1e.c
index 01167dae20b0..fa2628dbe794 100644
--- a/contrib/libarchive/libarchive/test/test_acl_posix1e.c
+++ b/contrib/libarchive/libarchive/test/test_acl_posix1e.c
@@ -116,16 +116,15 @@ DEFINE_TEST(test_acl_posix1e)
* triggering unnecessary extensions. It's better to identify
* trivial ACLs at the point they are being read from disk.
*/
- archive_test_set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
+ assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
failure("Basic ACLs shouldn't be stored as extended ACLs");
assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
failure("Basic ACLs should set mode to 0142, not %04o",
archive_entry_mode(ae)&0777);
assert((archive_entry_mode(ae) & 0777) == 0142);
-
/* With any extended ACL entry, we should read back a full set. */
- archive_test_set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
+ assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
failure("One extended ACL should flag all ACLs to be returned.");
/* Check that entry contains only POSIX.1e types */
@@ -135,7 +134,7 @@ DEFINE_TEST(test_acl_posix1e)
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0);
assert(4 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
- archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
+ assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142);
failure("Basic ACLs should set mode to 0142, not %04o",
archive_entry_mode(ae)&0777);
@@ -143,9 +142,9 @@ DEFINE_TEST(test_acl_posix1e)
/* A more extensive set of ACLs. */
- archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
+ assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
assertEqualInt(6, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
- archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
+ assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543);
failure("Basic ACLs should set mode to 0543, not %04o",
archive_entry_mode(ae)&0777);
@@ -155,7 +154,7 @@ DEFINE_TEST(test_acl_posix1e)
* Check that clearing ACLs gets rid of them all by repeating
* the first test.
*/
- archive_test_set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
+ assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
failure("Basic ACLs shouldn't be stored as extended ACLs");
assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
failure("Basic ACLs should set mode to 0142, not %04o",
@@ -166,7 +165,7 @@ DEFINE_TEST(test_acl_posix1e)
* Different types of malformed ACL entries that should
* fail when added to existing POSIX.1e ACLs.
*/
- archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
+ assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
for (i = 0; i < (int)(sizeof(acls_nfs4)/sizeof(acls_nfs4[0])); ++i) {
struct archive_test_acl_t *p = &acls_nfs4[i];
failure("Malformed ACL test #%d", i);
diff --git a/contrib/libarchive/libarchive/test/test_acl_text.c b/contrib/libarchive/libarchive/test/test_acl_text.c
index f3d2b10edcfe..80728932cb54 100644
--- a/contrib/libarchive/libarchive/test/test_acl_text.c
+++ b/contrib/libarchive/libarchive/test/test_acl_text.c
@@ -282,7 +282,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text(ae, acltext[5],
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0755);
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
@@ -291,7 +291,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text(ae, acltext[7],
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
assertEqualInt(11, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
@@ -303,7 +303,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text_w(ae, ws,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0755);
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
@@ -314,7 +314,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text_w(ae, ws,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
assertEqualInt(11, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
@@ -324,7 +324,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text(ae, acltext[7],
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0);
assertEqualInt(5, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
@@ -334,7 +334,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text_w(ae, ws,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0);
assertEqualInt(5, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
@@ -344,7 +344,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text(ae, acltext[1],
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
assertEqualInt(11, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
@@ -355,7 +355,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text_w(ae, ws,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
assertEqualInt(11, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
@@ -365,7 +365,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text(ae, acltext[2],
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
assertEqualInt(11, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
@@ -376,7 +376,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text_w(ae, ws,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
assertEqualInt(11, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
@@ -386,7 +386,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text(ae, acltext[10],
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
- archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
+ assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
@@ -398,7 +398,7 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_from_text_w(ae, ws,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
- archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
+ assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
@@ -416,7 +416,7 @@ DEFINE_TEST(test_acl_to_text)
assert((ae = archive_entry_new()) != NULL);
/* Write POSIX.1e ACLs */
- archive_test_set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
+ assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
/* No flags should give output like getfacl(1) on linux */
compare_acl_text(ae, 0, acltext[0]);
@@ -457,7 +457,7 @@ DEFINE_TEST(test_acl_to_text)
ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT, acltext[8]);
/* Write NFSv4 ACLs */
- archive_test_set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
+ assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
/* NFSv4 ACLs like getfacl(1) on FreeBSD */
compare_acl_text(ae, 0, acltext[9]);
diff --git a/contrib/libarchive/libarchive/test/test_archive_api_feature.c b/contrib/libarchive/libarchive/test/test_archive_api_feature.c
index f2925b573d18..e4239feba178 100644
--- a/contrib/libarchive/libarchive/test/test_archive_api_feature.c
+++ b/contrib/libarchive/libarchive/test/test_archive_api_feature.c
@@ -42,8 +42,12 @@ DEFINE_TEST(test_archive_api_feature)
if (strlen(buff) < strlen(archive_version_string())) {
p = archive_version_string() + strlen(buff);
failure("Version string is: %s", archive_version_string());
- assert(*p == 'a' || *p == 'b' || *p == 'c' || *p == 'd');
- ++p;
+ if (p[0] == 'd'&& p[1] == 'e' && p[2] == 'v')
+ p += 3;
+ else {
+ assert(*p == 'a' || *p == 'b' || *p == 'c' || *p == 'd');
+ ++p;
+ }
failure("Version string is: %s", archive_version_string());
assert(*p == '\0');
}
diff --git a/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c b/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c
index 3d063c1db9e6..815977290670 100644
--- a/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c
+++ b/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c
@@ -227,7 +227,7 @@ DEFINE_TEST(test_compat_solaris_tar_acl)
failure("One extended ACL should flag all ACLs to be returned.");
assertEqualInt(7, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0644);
failure("Basic ACLs should set mode to 0644, not %04o",
archive_entry_mode(ae)&0777);
@@ -237,28 +237,28 @@ DEFINE_TEST(test_compat_solaris_tar_acl)
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
- archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
+ assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0750);
failure("Basic ACLs should set mode to 0750, not %04o",
archive_entry_mode(ae)&0777);
assert((archive_entry_mode(ae) & 0777) == 0750);
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
- archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
+ assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0750);
/* Third item has NFS4 ACLs */
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
- archive_test_compare_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
+ assertEntryCompareAcls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
/* Fourth item has NFS4 ACLs and inheritance flags */
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(5, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
- archive_test_compare_acls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
+ assertEntryCompareAcls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
/* Close the archive. */
diff --git a/contrib/libarchive/libarchive/test/test_compat_star_acl.c b/contrib/libarchive/libarchive/test/test_compat_star_acl.c
index f2a78b2d2ce4..824710194c18 100644
--- a/contrib/libarchive/libarchive/test/test_compat_star_acl.c
+++ b/contrib/libarchive/libarchive/test/test_compat_star_acl.c
@@ -249,7 +249,7 @@ DEFINE_TEST(test_compat_star_acl_posix1e)
failure("One extended ACL should flag all ACLs to be returned.");
assertEqualInt(5, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
- archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+ assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142);
failure("Basic ACLs should set mode to 0142, not %04o",
archive_entry_mode(ae)&0777);
@@ -259,7 +259,7 @@ DEFINE_TEST(test_compat_star_acl_posix1e)
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(7, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
- archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
+ assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543);
failure("Basic ACLs should set mode to 0543, not %04o",
archive_entry_mode(ae)&0777);
@@ -269,7 +269,7 @@ DEFINE_TEST(test_compat_star_acl_posix1e)
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
- archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
+ assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0142);
failure("Basic ACLs should set mode to 0142, not %04o",
archive_entry_mode(ae)&0777);
@@ -298,21 +298,21 @@ DEFINE_TEST(test_compat_star_acl_nfs4)
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(3, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ALLOW));
- archive_test_compare_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
+ assertEntryCompareAcls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0);
/* Second item has has fine-grained NFS4 ACLs */
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
- archive_test_compare_acls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
+ assertEntryCompareAcls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
/* Third item has file and directory inheritance NFS4 ACLs */
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(5, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
- archive_test_compare_acls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]),
+ assertEntryCompareAcls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
/* Close the archive. */
diff --git a/contrib/libarchive/libarchive/test/test_fuzz.c b/contrib/libarchive/libarchive/test/test_fuzz.c
index e896f607e418..61c2dfc0fcdf 100644
--- a/contrib/libarchive/libarchive/test/test_fuzz.c
+++ b/contrib/libarchive/libarchive/test/test_fuzz.c
@@ -110,8 +110,9 @@ test_fuzz(const struct files *filesets)
} else {
for (i = 0; filesets[n].names[i] != NULL; ++i)
{
+ char *newraw;
tmp = slurpfile(&size, filesets[n].names[i]);
- char *newraw = realloc(rawimage, oldsize + size);
+ newraw = realloc(rawimage, oldsize + size);
if (!assert(newraw != NULL))
{
free(rawimage);
diff --git a/contrib/libarchive/libarchive/test/test_read_disk.c b/contrib/libarchive/libarchive/test/test_read_disk.c
index 4cc2eb4c3459..a57da1a537bf 100644
--- a/contrib/libarchive/libarchive/test/test_read_disk.c
+++ b/contrib/libarchive/libarchive/test/test_read_disk.c
@@ -61,6 +61,7 @@ uname_lookup(void *d, int64_t u)
return ("NOTFOO");
}
+#if !defined(__CYGWIN__) && !defined(__HAIKU__)
/* We test GID lookup by looking up the name of group number zero and
* checking it against the following list. If your system uses a
* different conventional name for group number zero, please extend
@@ -71,13 +72,16 @@ static const char *zero_groups[] = {
"root", /* Linux */
"wheel" /* BSD */
};
+#endif
DEFINE_TEST(test_read_disk)
{
struct archive *a;
int gmagic = 0x13579, umagic = 0x1234;
+#if !defined(__CYGWIN__) && !defined(__HAIKU__)
const char *p;
size_t i;
+#endif
assert((a = archive_read_disk_new()) != NULL);
@@ -115,8 +119,6 @@ DEFINE_TEST(test_read_disk)
/* 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
/* XXX Someday, we may need to generalize this the
* same way we generalized the group name check below.
diff --git a/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c b/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c
index c9aca8fa985d..705b3d989cd5 100644
--- a/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c
+++ b/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c
@@ -1228,11 +1228,11 @@ test_restore_atime(void)
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
/*
- * Test4: Traversals with archive_read_disk_set_atime_restored() and
- * archive_read_disk_honor_nodump().
+ * Test4: Traversals with ARCHIVE_READDISK_RESTORE_ATIME and
+ * ARCHIVE_READDISK_HONOR_NODUMP
*/
- assertNodump("at/f1");
- assertNodump("at/f2");
+ assertSetNodump("at/f1");
+ assertSetNodump("at/f2");
assertUtimes("at/f1", 886600, 0, 886600, 0);
assertUtimes("at/f2", 886611, 0, 886611, 0);
assertUtimes("at/fe", 886611, 0, 886611, 0);
@@ -1450,7 +1450,7 @@ test_nodump(void)
assertMakeFile("nd/f1", 0644, "0123456789");
assertMakeFile("nd/f2", 0644, "hello world");
assertMakeFile("nd/fe", 0644, NULL);
- assertNodump("nd/f2");
+ assertSetNodump("nd/f2");
assertUtimes("nd/f1", 886600, 0, 886600, 0);
assertUtimes("nd/f2", 886611, 0, 886611, 0);
assertUtimes("nd/fe", 886611, 0, 886611, 0);
@@ -1460,7 +1460,7 @@ test_nodump(void)
assert((a = archive_read_disk_new()) != NULL);
/*
- * Test1: Traversals without archive_read_disk_honor_nodump().
+ * Test1: Traversals without ARCHIVE_READDISK_HONOR_NODUMP
*/
failure("Directory traversals should work as well");
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd"));
@@ -1513,7 +1513,7 @@ test_nodump(void)
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
/*
- * Test2: Traversals with archive_read_disk_honor_nodump().
+ * Test2: Traversals with ARCHIVE_READDISK_HONOR_NODUMP
*/
assertUtimes("nd/f1", 886600, 0, 886600, 0);
assertUtimes("nd/f2", 886611, 0, 886611, 0);
diff --git a/contrib/libarchive/tar/bsdtar.1 b/contrib/libarchive/tar/bsdtar.1
index 9eadaaf885b1..3e7abe884126 100644
--- a/contrib/libarchive/tar/bsdtar.1
+++ b/contrib/libarchive/tar/bsdtar.1
@@ -1,4 +1,5 @@
.\" Copyright (c) 2003-2007 Tim Kientzle
+.\" Copyright (c) 2017 Martin Matuska
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -24,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 16, 2014
+.Dd February 25, 2017
.Dt TAR 1
.Os
.Sh NAME
@@ -124,7 +125,7 @@ Unless specifically stated otherwise, options are applicable in
all operating modes.
.Bl -tag -width indent
.It Cm @ Ns Pa archive
-(c and r mode only)
+(c and r modes only)
The specified archive is opened and the entries
in it will be appended to the current archive.
As a simple example,
@@ -164,6 +165,16 @@ and gzip compression,
.Dl Nm Fl a Fl jcf Pa archive.xxx source.c source.h
if it is unknown suffix or no suffix, creates a new archive with
restricted pax format and bzip2 compression.
+.It Fl Fl acls
+(c, r, u, x modes only)
+Archive or extract POSIX.1e or NFSv4 ACLs. This is the reverse of
+.Fl Fl no-acls
+and the default behavior in c, r, and u modes (except Mac OS X) or if
+.Nm
+is run in x mode as root. On Mac OS X this option translates extended ACLs
+to NFSv4 ACLs. To store extended ACLs the
+.Fl Fl mac-metadata
+option is preferred.
.It Fl B , Fl Fl read-full-blocks
Ignored for compatibility with other
.Xr tar 1
@@ -188,15 +199,18 @@ options and before extracting any files.
(x mode only)
Before removing file system objects to replace them, clear platform-specific
file flags that might prevent removal.
-.It Fl Fl disable-copyfile
-Mac OS X specific.
-Disable the use of
-.Xr copyfile 3 .
.It Fl Fl exclude Ar pattern
Do not process files or directories that match the
specified pattern.
Note that exclusions take precedence over patterns or filenames
specified on the command line.
+.It Fl Fl fflags
+(c, r, u, x modes only)
+Archive or extract file flags. This is the reverse of
+.Fl Fl no-fflags
+and the default behavior in c, r, and u modes or if
+.Nm
+is run in x mode as root.
.It Fl Fl format Ar format
(c, r, u mode only)
Use the specified format for the created archive.
@@ -245,11 +259,11 @@ On create, this sets the group name that will be stored
in the archive;
the name will not be verified against the system group database.
.It Fl H
-(c and r mode only)
+(c and r modes only)
Symbolic links named on the command line will be followed; the
target of the link will be archived, not the link itself.
.It Fl h
-(c and r mode only)
+(c and r modes only)
Synonym for
.Fl L .
.It Fl I
@@ -259,7 +273,8 @@ Synonym for
Show usage.
.It Fl Fl hfsCompression
(x mode only)
-Mac OS X specific(v10.6 or later). Compress extracted regular files with HFS+ compression.
+Mac OS X specific (v10.6 or later). Compress extracted regular files with HFS+
+compression.
.It Fl Fl ignore-zeros
An alias of
.Fl Fl options Cm read_concatenated_archives
@@ -310,7 +325,7 @@ later copies will not overwrite earlier copies.
Do not overwrite existing files that are newer than the
versions appearing in the archive being extracted.
.It Fl L , Fl Fl dereference
-(c and r mode only)
+(c and r modes only)
All symbolic links will be followed.
Normally, symbolic links are archived as such.
With this option, the target of the link will be archived instead.
@@ -345,6 +360,16 @@ In extract or list modes, this option is ignored.
(x mode only)
Do not extract modification time.
By default, the modification time is set to the time stored in the archive.
+.It Fl Fl mac-metadata
+(c, r, u and x mode only)
+Mac OS X specific. Archive or extract extended ACLs and extended attributes
+using
+.Xr copyfile 3
+in AppleDouble format. This is the reverse of
+.Fl Fl no-mac-metadata .
+and the default behavior in c, r, and u modes or if
+.Nm
+is run in x mode as root.
.It Fl n , Fl Fl norecurse , Fl Fl no-recursion
(c, r, u modes only)
Do not recursively archive the contents of directories.
@@ -385,6 +410,30 @@ This is often used to read filenames output by the
.Fl print0
option to
.Xr find 1 .
+.It Fl Fl no-acls
+(c, r, u, x modes only)
+Do not archive or extract POSIX.1e or NFSv4 ACLs. This is the reverse of
+.Fl Fl acls
+and the default behavior if
+.Nm
+is run as non-root in x mode (on Mac OS X also in c, r and u modes).
+.It Fl Fl no-fflags
+(c, r, u, x modes only)
+Do not archive or extract file flags. This is the reverse of
+.Fl Fl fflags
+and the default behavior if
+.Nm
+is run as non-root in x mode.
+.It Fl Fl no-mac-metadata
+(x mode only)
+Mac OS X specific. Do not archive or extract ACLs and extended attributes using
+.Xr copyfile 3
+in AppleDouble format. This is the reverse of
+.Fl Fl mac-metadata .
+and the default behavior if
+.Nm
+is run as non-root in x mode.
+.It Fl n , Fl Fl norecurse , Fl Fl no-recursion
.It Fl Fl no-same-owner
(x mode only)
Do not extract owner and group IDs.
@@ -402,6 +451,13 @@ This is the reverse of
and the default behavior if
.Nm
is run as non-root.
+.It Fl Fl no-xattrs
+(c, r, u, x modes only)
+Do not archive or extract extended attributes. This is the reverse of
+.Fl Fl xattrs
+and the default behavior if
+.Nm
+is run as non-root in x mode.
.It Fl Fl numeric-owner
This is equivalent to
.Fl Fl uname
@@ -583,14 +639,18 @@ This option suppresses these behaviors.
.It Fl p , Fl Fl insecure , Fl Fl preserve-permissions
(x mode only)
Preserve file permissions.
-Attempt to restore the full permissions, including owner, file modes, file
-flags and ACLs, if available, for each item extracted from the archive.
-This is the default, if
+Attempt to restore the full permissions, including owner, file modes, ACLs,
+extended atributes and extended file flags, if available, for each item
+extracted from the archive. This is te reverse of
+.Fl Fl no-same-permissions
+and the default if
.Nm
-is being run by root and can be overridden by also specifying
-.Fl Fl no-same-owner
-and
-.Fl Fl no-same-permissions .
+is being run by root and can be partially overridden by also specifying
+.Fl Fl no-acls ,
+.Fl Fl no-fflags ,
+.Fl Fl no-mac-metadata
+or
+.Fl Fl no-xattrs .
.It Fl Fl passphrase Ar passphrase
The
.Pa passphrase
@@ -692,7 +752,7 @@ you probably want to use
.Fl n
as well.
.It Fl Fl totals
-(c, r, u mode only)
+(c, r, u modes only)
After archiving all files, print a summary to stderr.
.It Fl U , Fl Fl unlink , Fl Fl unlink-first
(x mode only)
@@ -754,6 +814,13 @@ Read a list of exclusion patterns from the specified file.
See
.Fl Fl exclude
for more information about the handling of exclusions.
+.It Fl Fl xattrs
+(c, r, u, x modes only)
+Archive or extract extended attributes. This is the reverse of
+.Fl Fl no-xattrs
+and the default behavior in c, r, and u modes or if
+.Nm
+is run in x mode as root.
.It Fl y
(c mode only)
Compress the resulting archive with
diff --git a/contrib/libarchive/tar/bsdtar.c b/contrib/libarchive/tar/bsdtar.c
index 4db3340e92f7..d15214065472 100644
--- a/contrib/libarchive/tar/bsdtar.c
+++ b/contrib/libarchive/tar/bsdtar.c
@@ -118,11 +118,11 @@ need_report(void)
}
#endif
-static void long_help(void);
+static void long_help(void) __LA_DEAD;
static void only_mode(struct bsdtar *, const char *opt,
const char *valid);
static void set_mode(struct bsdtar *, char opt);
-static void version(void);
+static void version(void) __LA_DEAD;
/* A basic set of security flags to request from libarchive. */
#define SECURITY \
@@ -137,7 +137,6 @@ main(int argc, char **argv)
char compression, compression2;
const char *compression_name, *compression2_name;
const char *compress_program;
- char option_a, option_o;
char possible_help_request;
char buff[16];
@@ -150,7 +149,7 @@ main(int argc, char **argv)
bsdtar->fd = -1; /* Mark as "unused" */
bsdtar->gid = -1;
bsdtar->uid = -1;
- option_a = option_o = 0;
+ bsdtar->flags = 0;
compression = compression2 = '\0';
compression_name = compression2_name = NULL;
compress_program = NULL;
@@ -233,6 +232,14 @@ main(int argc, char **argv)
if (getenv(COPYFILE_DISABLE_VAR))
bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_MAC_COPYFILE;
#endif
+#if defined(__APPLE__)
+ /*
+ * On Mac OS ACLs are archived with copyfile() (--mac-metadata)
+ * Translation to NFSv4 ACLs has to be requested explicitly with --acls
+ */
+ bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_ACL;
+#endif
+
bsdtar->matching = archive_match_new();
if (bsdtar->matching == NULL)
lafe_errc(1, errno, "Out of memory");
@@ -252,7 +259,12 @@ main(int argc, char **argv)
while ((opt = bsdtar_getopt(bsdtar)) != -1) {
switch (opt) {
case 'a': /* GNU tar */
- option_a = 1; /* Record it and resolve it later. */
+ bsdtar->flags |= OPTFLAG_AUTO_COMPRESS;
+ break;
+ case OPTION_ACLS: /* GNU tar */
+ bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL;
+ bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_ACL;
+ bsdtar->flags |= OPTFLAG_ACLS;
break;
case 'B': /* GNU tar */
/* libarchive doesn't need this; just ignore it. */
@@ -285,24 +297,26 @@ main(int argc, char **argv)
set_mode(bsdtar, opt);
break;
case OPTION_CHECK_LINKS: /* GNU tar */
- bsdtar->option_warn_links = 1;
+ bsdtar->flags |= OPTFLAG_WARN_LINKS;
break;
case OPTION_CHROOT: /* NetBSD */
- bsdtar->option_chroot = 1;
+ bsdtar->flags |= OPTFLAG_CHROOT;
break;
case OPTION_CLEAR_NOCHANGE_FFLAGS:
bsdtar->extract_flags |=
ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS;
break;
- case OPTION_DISABLE_COPYFILE: /* Mac OS X */
- bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_MAC_COPYFILE;
- break;
case OPTION_EXCLUDE: /* GNU tar */
if (archive_match_exclude_pattern(
bsdtar->matching, bsdtar->argument) != ARCHIVE_OK)
lafe_errc(1, 0,
"Couldn't exclude %s\n", bsdtar->argument);
break;
+ case OPTION_FFLAGS:
+ bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
+ bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_FFLAGS;
+ bsdtar->flags |= OPTFLAG_FFLAGS;
+ break;
case OPTION_FORMAT: /* GNU tar, others */
cset_set_format(bsdtar->cset, bsdtar->argument);
break;
@@ -344,7 +358,7 @@ main(int argc, char **argv)
ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED;
break;
case OPTION_IGNORE_ZEROS:
- bsdtar->option_ignore_zeros = 1;
+ bsdtar->flags |= OPTFLAG_IGNORE_ZEROS;
break;
case 'I': /* GNU tar */
/*
@@ -398,7 +412,7 @@ main(int argc, char **argv)
break;
case 'l': /* SUSv2 and GNU tar beginning with 1.16 */
/* GNU tar 1.13 used -l for --one-file-system */
- bsdtar->option_warn_links = 1;
+ bsdtar->flags |= OPTFLAG_WARN_LINKS;
break;
case OPTION_LRZIP:
case OPTION_LZ4:
@@ -421,8 +435,13 @@ main(int argc, char **argv)
case 'm': /* SUSv2 */
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_TIME;
break;
+ case OPTION_MAC_METADATA: /* Mac OS X */
+ bsdtar->readdisk_flags |= ARCHIVE_READDISK_MAC_COPYFILE;
+ bsdtar->extract_flags |= ARCHIVE_EXTRACT_MAC_METADATA;
+ bsdtar->flags |= OPTFLAG_MAC_METADATA;
+ break;
case 'n': /* GNU tar */
- bsdtar->option_no_subdirs = 1;
+ bsdtar->flags |= OPTFLAG_NO_SUBDIRS;
break;
/*
* Selecting files by time:
@@ -466,6 +485,21 @@ main(int argc, char **argv)
bsdtar->extract_flags |=
ARCHIVE_EXTRACT_NO_HFS_COMPRESSION;
break;
+ case OPTION_NO_ACLS: /* GNU tar */
+ bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_ACL;
+ bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_ACL;
+ bsdtar->flags |= OPTFLAG_NO_ACLS;
+ break;
+ case OPTION_NO_FFLAGS:
+ bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_FFLAGS;
+ bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_FFLAGS;
+ bsdtar->flags |= OPTFLAG_NO_FFLAGS;
+ break;
+ case OPTION_NO_MAC_METADATA: /* Mac OS X */
+ bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_MAC_COPYFILE;
+ bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_MAC_METADATA;
+ bsdtar->flags |= OPTFLAG_NO_MAC_METADATA;
+ break;
case OPTION_NO_SAME_OWNER: /* GNU tar */
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
break;
@@ -476,23 +510,24 @@ main(int argc, char **argv)
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_FFLAGS;
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_MAC_METADATA;
break;
- case OPTION_NO_XATTR: /* Issue #131 */
+ case OPTION_NO_XATTRS: /* GNU tar */
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_XATTR;
bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_XATTR;
+ bsdtar->flags |= OPTFLAG_NO_XATTRS;
break;
case OPTION_NULL: /* GNU tar */
- bsdtar->option_null++;
+ bsdtar->flags |= OPTFLAG_NULL;
break;
case OPTION_NUMERIC_OWNER: /* GNU tar */
bsdtar->uname = "";
bsdtar->gname = "";
- bsdtar->option_numeric_owner++;
+ bsdtar->flags |= OPTFLAG_NUMERIC_OWNER;
break;
case 'O': /* GNU tar */
- bsdtar->option_stdout = 1;
+ bsdtar->flags |= OPTFLAG_STDOUT;
break;
case 'o': /* SUSv2 and GNU conflict here, but not fatally */
- option_o = 1; /* Record it and resolve it later. */
+ bsdtar->flags |= OPTFLAG_O;
break;
/*
* Selecting files by time:
@@ -548,7 +583,7 @@ main(int argc, char **argv)
#endif
case 'P': /* GNU tar */
bsdtar->extract_flags &= ~SECURITY;
- bsdtar->option_absolute_paths = 1;
+ bsdtar->flags |= OPTFLAG_ABSOLUTE_PATHS;
break;
case 'p': /* GNU tar, star */
bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM;
@@ -564,7 +599,7 @@ main(int argc, char **argv)
cset_set_format(bsdtar->cset, "pax");
break;
case 'q': /* FreeBSD GNU tar --fast-read, NetBSD -q */
- bsdtar->option_fast_read = 1;
+ bsdtar->flags |= OPTFLAG_FAST_READ;
break;
case 'r': /* SUSv2 */
set_mode(bsdtar, opt);
@@ -601,11 +636,11 @@ main(int argc, char **argv)
bsdtar->verbose++;
break;
case OPTION_TOTALS: /* GNU tar */
- bsdtar->option_totals++;
+ bsdtar->flags |= OPTFLAG_TOTALS;
break;
case 'U': /* GNU tar */
bsdtar->extract_flags |= ARCHIVE_EXTRACT_UNLINK;
- bsdtar->option_unlink_first = 1;
+ bsdtar->flags |= OPTFLAG_UNLINK_FIRST;
break;
case 'u': /* SUSv2 */
set_mode(bsdtar, opt);
@@ -643,7 +678,7 @@ main(int argc, char **argv)
break;
#endif
case 'w': /* SUSv2 */
- bsdtar->option_interactive = 1;
+ bsdtar->flags |= OPTFLAG_INTERACTIVE;
break;
case 'X': /* GNU tar */
if (archive_match_exclude_pattern_from_file(
@@ -655,6 +690,11 @@ main(int argc, char **argv)
case 'x': /* SUSv2 */
set_mode(bsdtar, opt);
break;
+ case OPTION_XATTRS: /* GNU tar */
+ bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR;
+ bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_XATTR;
+ bsdtar->flags |= OPTFLAG_XATTRS;
+ break;
case 'y': /* FreeBSD version of GNU tar */
if (compression != '\0')
lafe_errc(1, 0,
@@ -703,11 +743,11 @@ main(int argc, char **argv)
"Must specify one of -c, -r, -t, -u, -x");
/* Check boolean options only permitted in certain modes. */
- if (option_a)
+ if (bsdtar->flags & OPTFLAG_AUTO_COMPRESS)
only_mode(bsdtar, "-a", "c");
if (bsdtar->readdisk_flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS)
only_mode(bsdtar, "--one-file-system", "cru");
- if (bsdtar->option_fast_read)
+ if (bsdtar->flags & OPTFLAG_FAST_READ)
only_mode(bsdtar, "--fast-read", "xt");
if (bsdtar->extract_flags & ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED)
only_mode(bsdtar, "--hfsCompression", "x");
@@ -715,9 +755,23 @@ main(int argc, char **argv)
only_mode(bsdtar, "--nopreserveHFSCompression", "x");
if (bsdtar->readdisk_flags & ARCHIVE_READDISK_HONOR_NODUMP)
only_mode(bsdtar, "--nodump", "cru");
- if (bsdtar->readdisk_flags & ARCHIVE_READDISK_NO_XATTR)
- only_mode(bsdtar, "--no-xattr", "crux");
- if (option_o > 0) {
+ if (bsdtar->flags & OPTFLAG_ACLS)
+ only_mode(bsdtar, "--acls", "crux");
+ if (bsdtar->flags & OPTFLAG_NO_ACLS)
+ only_mode(bsdtar, "--no-acls", "crux");
+ if (bsdtar->flags & OPTFLAG_XATTRS)
+ only_mode(bsdtar, "--xattrs", "crux");
+ if (bsdtar->flags & OPTFLAG_NO_XATTRS)
+ only_mode(bsdtar, "--no-xattrs", "crux");
+ if (bsdtar->flags & OPTFLAG_FFLAGS)
+ only_mode(bsdtar, "--fflags", "crux");
+ if (bsdtar->flags & OPTFLAG_NO_FFLAGS)
+ only_mode(bsdtar, "--no-fflags", "crux");
+ if (bsdtar->flags & OPTFLAG_MAC_METADATA)
+ only_mode(bsdtar, "--mac-metadata", "crux");
+ if (bsdtar->flags & OPTFLAG_NO_MAC_METADATA)
+ only_mode(bsdtar, "--no-mac-metadata", "crux");
+ if (bsdtar->flags & OPTFLAG_O) {
switch (bsdtar->mode) {
case 'c':
/*
@@ -730,7 +784,7 @@ main(int argc, char **argv)
break;
case 'x':
/* POSIX-compatible behavior. */
- bsdtar->option_no_owner = 1;
+ bsdtar->flags |= OPTFLAG_NO_OWNER;
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
break;
default:
@@ -738,16 +792,17 @@ main(int argc, char **argv)
break;
}
}
- if (bsdtar->option_no_subdirs)
+ if (bsdtar->flags & OPTFLAG_NO_SUBDIRS)
only_mode(bsdtar, "-n", "cru");
- if (bsdtar->option_stdout)
+ if (bsdtar->flags & OPTFLAG_STDOUT)
only_mode(bsdtar, "-O", "xt");
- if (bsdtar->option_unlink_first)
+ if (bsdtar->flags & OPTFLAG_UNLINK_FIRST)
only_mode(bsdtar, "-U", "x");
- if (bsdtar->option_warn_links)
+ if (bsdtar->flags & OPTFLAG_WARN_LINKS)
only_mode(bsdtar, "--check-links", "cr");
- if (option_a && cset_auto_compress(bsdtar->cset, bsdtar->filename)) {
+ if ((bsdtar->flags & OPTFLAG_AUTO_COMPRESS) &&
+ cset_auto_compress(bsdtar->cset, bsdtar->filename)) {
/* Ignore specified compressions if auto-compress works. */
compression = '\0';
compression2 = '\0';
diff --git a/contrib/libarchive/tar/bsdtar.h b/contrib/libarchive/tar/bsdtar.h
index 3c4d629fad37..2bf42e8b28e7 100644
--- a/contrib/libarchive/tar/bsdtar.h
+++ b/contrib/libarchive/tar/bsdtar.h
@@ -50,6 +50,7 @@ struct bsdtar {
int bytes_per_block; /* -b block_size */
int bytes_in_last_block; /* See -b handling. */
int verbose; /* -v */
+ unsigned int flags; /* Bitfield of boolean options */
int extract_flags; /* Flags for extract operation */
int readdisk_flags; /* Flags for read disk operation */
int strip_components; /* Remove this many leading dirs */
@@ -60,20 +61,7 @@ struct bsdtar {
const char *passphrase; /* --passphrase */
char mode; /* Program mode: 'c', 't', 'r', 'u', 'x' */
char symlink_mode; /* H or L, per BSD conventions */
- char option_absolute_paths; /* -P */
- char option_chroot; /* --chroot */
- char option_fast_read; /* --fast-read */
const char *option_options; /* --options */
- char option_ignore_zeros; /* --ignore-zeros */
- char option_interactive; /* -w */
- char option_no_owner; /* -o */
- char option_no_subdirs; /* -n */
- char option_numeric_owner; /* --numeric-owner */
- char option_null; /* --null */
- char option_stdout; /* -O */
- char option_totals; /* --totals */
- char option_unlink_first; /* -U */
- char option_warn_links; /* --check-links */
char day_first; /* show day before month in -tv output */
struct creation_set *cset;
@@ -114,14 +102,40 @@ struct bsdtar {
char *ppbuff; /* for util.c */
};
+/* Options for flags bitfield */
+#define OPTFLAG_AUTO_COMPRESS (0x00000001) /* -a */
+#define OPTFLAG_ABSOLUTE_PATHS (0x00000002) /* -P */
+#define OPTFLAG_CHROOT (0x00000004) /* --chroot */
+#define OPTFLAG_FAST_READ (0x00000008) /* --fast-read */
+#define OPTFLAG_IGNORE_ZEROS (0x00000010) /* --ignore-zeros */
+#define OPTFLAG_INTERACTIVE (0x00000020) /* -w */
+#define OPTFLAG_NO_OWNER (0x00000040) /* -o */
+#define OPTFLAG_NO_SUBDIRS (0x00000080) /* -n */
+#define OPTFLAG_NULL (0x00000100) /* --null */
+#define OPTFLAG_NUMERIC_OWNER (0x00000200) /* --numeric-owner */
+#define OPTFLAG_O (0x00000400) /* -o */
+#define OPTFLAG_STDOUT (0x00000800) /* -O */
+#define OPTFLAG_TOTALS (0x00001000) /* --totals */
+#define OPTFLAG_UNLINK_FIRST (0x00002000) /* -U */
+#define OPTFLAG_WARN_LINKS (0x00004000) /* --check-links */
+#define OPTFLAG_NO_XATTRS (0x00008000) /* --no-xattrs */
+#define OPTFLAG_XATTRS (0x00010000) /* --xattrs */
+#define OPTFLAG_NO_ACLS (0x00020000) /* --no-acls */
+#define OPTFLAG_ACLS (0x00040000) /* --acls */
+#define OPTFLAG_NO_FFLAGS (0x00080000) /* --no-fflags */
+#define OPTFLAG_FFLAGS (0x00100000) /* --fflags */
+#define OPTFLAG_NO_MAC_METADATA (0x00200000) /* --no-mac-metadata */
+#define OPTFLAG_MAC_METADATA (0x00400000) /* --mac-metadata */
+
/* Fake short equivalents for long options that otherwise lack them. */
enum {
- OPTION_B64ENCODE = 1,
+ OPTION_ACLS = 1,
+ OPTION_B64ENCODE,
OPTION_CHECK_LINKS,
OPTION_CHROOT,
OPTION_CLEAR_NOCHANGE_FFLAGS,
- OPTION_DISABLE_COPYFILE,
OPTION_EXCLUDE,
+ OPTION_FFLAGS,
OPTION_FORMAT,
OPTION_GID,
OPTION_GNAME,
@@ -136,15 +150,19 @@ enum {
OPTION_LZIP,
OPTION_LZMA,
OPTION_LZOP,
+ OPTION_MAC_METADATA,
OPTION_NEWER_CTIME,
OPTION_NEWER_CTIME_THAN,
OPTION_NEWER_MTIME,
OPTION_NEWER_MTIME_THAN,
OPTION_NODUMP,
OPTION_NOPRESERVE_HFS_COMPRESSION,
+ OPTION_NO_ACLS,
+ OPTION_NO_FFLAGS,
+ OPTION_NO_MAC_METADATA,
OPTION_NO_SAME_OWNER,
OPTION_NO_SAME_PERMISSIONS,
- OPTION_NO_XATTR,
+ OPTION_NO_XATTRS,
OPTION_NULL,
OPTION_NUMERIC_OWNER,
OPTION_OLDER_CTIME,
@@ -162,7 +180,8 @@ enum {
OPTION_UNAME,
OPTION_USE_COMPRESS_PROGRAM,
OPTION_UUENCODE,
- OPTION_VERSION
+ OPTION_VERSION,
+ OPTION_XATTRS
};
int bsdtar_getopt(struct bsdtar *);
@@ -170,7 +189,7 @@ void do_chdir(struct bsdtar *);
int edit_pathname(struct bsdtar *, struct archive_entry *);
int need_report(void);
int pathcmp(const char *a, const char *b);
-void safe_fprintf(FILE *, const char *fmt, ...);
+void safe_fprintf(FILE *, const char *fmt, ...) __LA_PRINTF(2, 3);
void set_chdir(struct bsdtar *, const char *newdir);
const char *tar_i64toa(int64_t);
void tar_mode_c(struct bsdtar *bsdtar);
@@ -178,8 +197,8 @@ void tar_mode_r(struct bsdtar *bsdtar);
void tar_mode_t(struct bsdtar *bsdtar);
void tar_mode_u(struct bsdtar *bsdtar);
void tar_mode_x(struct bsdtar *bsdtar);
-void usage(void);
-int yes(const char *fmt, ...);
+void usage(void) __LA_DEAD;
+int yes(const char *fmt, ...) __LA_PRINTF(1, 2);
#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
void add_substitution(struct bsdtar *, const char *);
diff --git a/contrib/libarchive/tar/cmdline.c b/contrib/libarchive/tar/cmdline.c
index c87741cc565e..e36c545b3336 100644
--- a/contrib/libarchive/tar/cmdline.c
+++ b/contrib/libarchive/tar/cmdline.c
@@ -65,6 +65,7 @@ static const struct bsdtar_option {
} tar_longopts[] = {
{ "absolute-paths", 0, 'P' },
{ "append", 0, 'r' },
+ { "acls", 0, OPTION_ACLS },
{ "auto-compress", 0, 'a' },
{ "b64encode", 0, OPTION_B64ENCODE },
{ "block-size", 1, 'b' },
@@ -81,11 +82,12 @@ static const struct bsdtar_option {
{ "create", 0, 'c' },
{ "dereference", 0, 'L' },
{ "directory", 1, 'C' },
- { "disable-copyfile", 0, OPTION_DISABLE_COPYFILE },
+ { "disable-copyfile", 0, OPTION_NO_MAC_METADATA },
{ "exclude", 1, OPTION_EXCLUDE },
{ "exclude-from", 1, 'X' },
{ "extract", 0, 'x' },
{ "fast-read", 0, 'q' },
+ { "fflags", 0, OPTION_FFLAGS },
{ "file", 1, 'f' },
{ "files-from", 1, 'T' },
{ "format", 1, OPTION_FORMAT },
@@ -108,6 +110,7 @@ static const struct bsdtar_option {
{ "lzip", 0, OPTION_LZIP },
{ "lzma", 0, OPTION_LZMA },
{ "lzop", 0, OPTION_LZOP },
+ { "mac-metadata", 0, OPTION_MAC_METADATA },
{ "modification-time", 0, 'm' },
{ "newer", 1, OPTION_NEWER_CTIME },
{ "newer-ctime", 1, OPTION_NEWER_CTIME },
@@ -115,10 +118,14 @@ static const struct bsdtar_option {
{ "newer-mtime", 1, OPTION_NEWER_MTIME },
{ "newer-mtime-than", 1, OPTION_NEWER_MTIME_THAN },
{ "newer-than", 1, OPTION_NEWER_CTIME_THAN },
+ { "no-acls", 0, OPTION_NO_ACLS },
+ { "no-fflags", 0, OPTION_NO_FFLAGS },
+ { "no-mac-metadata", 0, OPTION_NO_MAC_METADATA },
{ "no-recursion", 0, 'n' },
{ "no-same-owner", 0, OPTION_NO_SAME_OWNER },
{ "no-same-permissions", 0, OPTION_NO_SAME_PERMISSIONS },
- { "no-xattr", 0, OPTION_NO_XATTR },
+ { "no-xattr", 0, OPTION_NO_XATTRS },
+ { "no-xattrs", 0, OPTION_NO_XATTRS },
{ "nodump", 0, OPTION_NODUMP },
{ "nopreserveHFSCompression",0, OPTION_NOPRESERVE_HFS_COMPRESSION },
{ "norecurse", 0, 'n' },
@@ -151,6 +158,7 @@ static const struct bsdtar_option {
{ "uuencode", 0, OPTION_UUENCODE },
{ "verbose", 0, 'v' },
{ "version", 0, OPTION_VERSION },
+ { "xattrs", 0, OPTION_XATTRS },
{ "xz", 0, 'J' },
{ NULL, 0, 0 }
};
diff --git a/contrib/libarchive/tar/read.c b/contrib/libarchive/tar/read.c
index 902ba7b2428d..bf7d55b81cb9 100644
--- a/contrib/libarchive/tar/read.c
+++ b/contrib/libarchive/tar/read.c
@@ -105,7 +105,7 @@ tar_mode_x(struct bsdtar *bsdtar)
writer = archive_write_disk_new();
if (writer == NULL)
lafe_errc(1, ENOMEM, "Cannot allocate disk writer object");
- if (!bsdtar->option_numeric_owner)
+ if ((bsdtar->flags & OPTFLAG_NUMERIC_OWNER) == 0)
archive_write_disk_set_standard_lookup(writer);
archive_write_disk_set_options(writer, bsdtar->extract_flags);
@@ -177,7 +177,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
if (bsdtar->names_from_file != NULL)
if (archive_match_include_pattern_from_file(
bsdtar->matching, bsdtar->names_from_file,
- bsdtar->option_null) != ARCHIVE_OK)
+ (bsdtar->flags & OPTFLAG_NULL)) != ARCHIVE_OK)
lafe_errc(1, 0, "Error inclusion pattern: %s",
archive_error_string(bsdtar->matching));
@@ -208,7 +208,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
}
if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options))
lafe_errc(1, 0, "%s", archive_error_string(a));
- if (bsdtar->option_ignore_zeros)
+ if (bsdtar->flags & OPTFLAG_IGNORE_ZEROS)
if (archive_read_set_options(a,
"read_concatenated_archives") != ARCHIVE_OK)
lafe_errc(1, 0, "%s", archive_error_string(a));
@@ -234,7 +234,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
&progress_data);
}
- if (mode == 'x' && bsdtar->option_chroot) {
+ if (mode == 'x' && (bsdtar->flags & OPTFLAG_CHROOT)) {
#if HAVE_CHROOT
if (chroot(".") != 0)
lafe_errc(1, errno, "Can't chroot to \".\"");
@@ -245,7 +245,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
}
#if defined(_WIN32) && !defined(__CYGWIN__)
- if (mode == 'x' && bsdtar->option_stdout) {
+ if (mode == 'x' && (bsdtar->flags & OPTFLAG_STDOUT)) {
_setmode(1, _O_BINARY);
}
#endif
@@ -253,7 +253,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
for (;;) {
/* Support --fast-read option */
const char *p;
- if (bsdtar->option_fast_read &&
+ if ((bsdtar->flags & OPTFLAG_FAST_READ) &&
archive_match_path_unmatched_inclusions(bsdtar->matching) == 0)
break;
@@ -307,7 +307,8 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
if (mode == 't') {
/* Perversely, gtar uses -O to mean "send to stderr"
* when used with -t. */
- out = bsdtar->option_stdout ? stderr : stdout;
+ out = (bsdtar->flags & OPTFLAG_STDOUT) ?
+ stderr : stdout;
/*
* TODO: Provide some reasonable way to
@@ -345,7 +346,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
if (edit_pathname(bsdtar, entry))
continue; /* Excluded by a rewrite failure. */
- if (bsdtar->option_interactive &&
+ if ((bsdtar->flags & OPTFLAG_INTERACTIVE) &&
!yes("extract '%s'", archive_entry_pathname(entry)))
continue;
@@ -364,7 +365,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
/* TODO siginfo_printinfo(bsdtar, 0); */
- if (bsdtar->option_stdout)
+ if (bsdtar->flags & OPTFLAG_STDOUT)
r = archive_read_data_into_fd(a, 1);
else
r = archive_read_extract2(a, entry, writer);
diff --git a/contrib/libarchive/tar/test/main.c b/contrib/libarchive/tar/test/main.c
deleted file mode 100644
index 4f498b6ac4fe..000000000000
--- a/contrib/libarchive/tar/test/main.c
+++ /dev/null
@@ -1,3072 +0,0 @@
-/*
- * 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"
-#include "test_utils.h"
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#include <errno.h>
-#ifdef HAVE_ICONV_H
-#include <iconv.h>
-#endif
-/*
- * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
- * As the include guards don't agree, the order of include is important.
- */
-#ifdef HAVE_LINUX_EXT2_FS_H
-#include <linux/ext2_fs.h> /* for Linux file flags */
-#endif
-#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
-#include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
-#endif
-#include <limits.h>
-#include <locale.h>
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#include <stdarg.h>
-#include <time.h>
-
-/*
- * 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_patterns_2.tar.uu"
-#define ENVBASE "BSDTAR" /* Prefix for environment variables. */
-#define PROGRAM "bsdtar" /* Name of program being tested. */
-#define PROGRAM_ALIAS "tar" /* Generic alias for program */
-#undef LIBRARY /* Not testing a library. */
-#undef EXTRA_DUMP /* How to dump extra data */
-#undef EXTRA_ERRNO /* How to dump errno */
-/* How to generate extra version info. */
-#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "")
-
-/*
- *
- * 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.
- */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <io.h>
-#include <direct.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
-#undef chdir
-#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
-
-#if defined(HAVE__CrtSetReportMode)
-# include <crtdbg.h>
-#endif
-
-mode_t umasked(mode_t expected_mode)
-{
- mode_t mode = umask(0);
- umask(mode);
- return expected_mode & ~mode;
-}
-
-/* Path to working directory for current test */
-const char *testworkdir;
-#ifdef PROGRAM
-/* Pathname of exe to be tested. */
-const char *testprogfile;
-/* Name of exe to use in printf-formatted command strings. */
-/* On Windows, this includes leading/trailing quotes. */
-const char *testprog;
-#endif
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-static void *GetFunctionKernel32(const char *);
-static int my_CreateSymbolicLinkA(const char *, const char *, int);
-static int my_CreateHardLinkA(const char *, const char *);
-static int my_GetFileInformationByName(const char *,
- BY_HANDLE_FILE_INFORMATION *);
-
-static 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);
-}
-
-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);
-}
-
-static 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_FLAG_BACKUP_SEMANTICS, NULL);
- if (h == INVALID_HANDLE_VALUE)
- return (0);
- r = GetFileInformationByHandle(h, bhfi);
- CloseHandle(h);
- return (r);
-}
-#endif
-
-#if defined(HAVE__CrtSetReportMode) && !defined(__WATCOMC__)
-static void
-invalid_parameter_handler(const wchar_t * expression,
- const wchar_t * function, const wchar_t * file,
- unsigned int line, uintptr_t pReserved)
-{
- /* nop */
-}
-#endif
-
-/*
- *
- * OPTIONS FLAGS
- *
- */
-
-/* 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 run the specified tests once and report errors. */
-static int until_failure = 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;
-
-/*
- * Report log information selectively to console and/or disk log.
- */
-static int log_console = 0;
-static FILE *logfile;
-static void
-vlogprintf(const char *fmt, va_list ap)
-{
-#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
-}
-
-static void
-logprintf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vlogprintf(fmt, ap);
- va_end(ap);
-}
-
-/* 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;
- if (fmt == NULL) {
- nextmsg = NULL;
- } else {
- 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 noticeably.
- */
-static const char *skipping_filename;
-static int skipping_line;
-void skipping_setup(const char *filename, int line)
-{
- skipping_filename = filename;
- skipping_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); */
-}
-
-/*
- * For each test source file, we remember how many times each
- * assertion was reported. Cleared before each new test,
- * used by test_summarize().
- */
-static struct line {
- int count;
- int skip;
-} failed_lines[10000];
-const char *failed_filename;
-
-/* 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;
-
- /* Record another failure for this line. */
- ++failures;
- failed_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);
-#if _MSC_VER
- logprintf("%s(%d): ", filename, line);
-#else
- logprintf("%s:%d: ", filename, line);
-#endif
- vlogprintf(fmt, ap);
- va_end(ap);
- 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;
-}
-
-/* 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
-failure_finish(void *extra)
-{
- (void)extra; /* UNUSED (maybe) */
-#ifdef EXTRA_DUMP
- if (extra != NULL) {
- logprintf(" errno: %d\n", EXTRA_ERRNO(extra));
- logprintf(" detail: %s\n", EXTRA_DUMP(extra));
- }
-#endif
-
- if (dump_on_failure) {
- fprintf(stderr,
- " *** forcing core dump so failure can be debugged ***\n");
- abort();
- }
-}
-
-/* Inform user that we're skipping some checks. */
-void
-test_skipping(const char *fmt, ...)
-{
- char buff[1024];
- va_list ap;
-
- va_start(ap, fmt);
- vsprintf(buff, fmt, ap);
- va_end(ap);
- /* Use failure() message if set. */
- msg = nextmsg;
- nextmsg = NULL;
- /* failure_start() isn't quite right, but is awfully convenient. */
- failure_start(skipping_filename, skipping_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[skipping_line].skip = 1;
- ++skips;
-}
-
-/*
- *
- * ASSERTIONS
- *
- */
-
-/* Generic assert() just displays the failed condition. */
-int
-assertion_assert(const char *file, int line, int value,
- const char *condition, void *extra)
-{
- assertion_count(file, line);
- if (!value) {
- failure_start(file, line, "Assertion failed: %s", condition);
- failure_finish(extra);
- }
- return (value);
-}
-
-/* chdir() and report any errors */
-int
-assertion_chdir(const char *file, int line, const char *pathname)
-{
- assertion_count(file, line);
- if (chdir(pathname) == 0)
- return (1);
- failure_start(file, line, "chdir(\"%s\")", pathname);
- failure_finish(NULL);
- return (0);
-
-}
-
-/* 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);
-}
-
-/*
- * Utility to convert a single UTF-8 sequence.
- */
-static int
-_utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
-{
- static const char utf8_count[256] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 00 - 0F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 10 - 1F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20 - 2F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30 - 3F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40 - 4F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 50 - 5F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60 - 6F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 70 - 7F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 80 - 8F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 90 - 9F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* A0 - AF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* B0 - BF */
- 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* C0 - CF */
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* D0 - DF */
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,/* E0 - EF */
- 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */
- };
- int ch;
- int cnt;
- uint32_t wc;
-
- *pwc = 0;
-
- /* Sanity check. */
- if (n == 0)
- return (0);
- /*
- * Decode 1-4 bytes depending on the value of the first byte.
- */
- ch = (unsigned char)*s;
- if (ch == 0)
- return (0); /* Standard: return 0 for end-of-string. */
- cnt = utf8_count[ch];
-
- /* Invalid sequence or there are not plenty bytes. */
- if (n < (size_t)cnt)
- return (-1);
-
- /* Make a Unicode code point from a single UTF-8 sequence. */
- switch (cnt) {
- case 1: /* 1 byte sequence. */
- *pwc = ch & 0x7f;
- return (cnt);
- case 2: /* 2 bytes sequence. */
- if ((s[1] & 0xc0) != 0x80) return (-1);
- *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
- return (cnt);
- case 3: /* 3 bytes sequence. */
- if ((s[1] & 0xc0) != 0x80) return (-1);
- if ((s[2] & 0xc0) != 0x80) return (-1);
- wc = ((ch & 0x0f) << 12)
- | ((s[1] & 0x3f) << 6)
- | (s[2] & 0x3f);
- if (wc < 0x800)
- return (-1);/* Overlong sequence. */
- break;
- case 4: /* 4 bytes sequence. */
- if (n < 4)
- return (-1);
- if ((s[1] & 0xc0) != 0x80) return (-1);
- if ((s[2] & 0xc0) != 0x80) return (-1);
- if ((s[3] & 0xc0) != 0x80) return (-1);
- wc = ((ch & 0x07) << 18)
- | ((s[1] & 0x3f) << 12)
- | ((s[2] & 0x3f) << 6)
- | (s[3] & 0x3f);
- if (wc < 0x10000)
- return (-1);/* Overlong sequence. */
- break;
- default:
- return (-1);
- }
-
- /* The code point larger than 0x10FFFF is not legal
- * Unicode values. */
- if (wc > 0x10FFFF)
- return (-1);
- /* Correctly gets a Unicode, returns used bytes. */
- *pwc = wc;
- return (cnt);
-}
-
-static void strdump(const char *e, const char *p, int ewidth, int utf8)
-{
- const char *q = p;
-
- logprintf(" %*s = ", ewidth, e);
- if (p == NULL) {
- logprintf("NULL\n");
- return;
- }
- logprintf("\"");
- while (*p != '\0') {
- unsigned int c = 0xff & *p++;
- switch (c) {
- case '\a': logprintf("\\a"); break;
- case '\b': logprintf("\\b"); break;
- case '\n': logprintf("\\n"); break;
- case '\r': logprintf("\\r"); break;
- default:
- if (c >= 32 && c < 127)
- logprintf("%c", c);
- else
- logprintf("\\x%02X", c);
- }
- }
- logprintf("\"");
- logprintf(" (length %d)", q == NULL ? -1 : (int)strlen(q));
-
- /*
- * If the current string is UTF-8, dump its code points.
- */
- if (utf8) {
- size_t len;
- uint32_t uc;
- int n;
- int cnt = 0;
-
- p = q;
- len = strlen(p);
- logprintf(" [");
- while ((n = _utf8_to_unicode(&uc, p, len)) > 0) {
- if (p != q)
- logprintf(" ");
- logprintf("%04X", uc);
- p += n;
- len -= n;
- cnt++;
- }
- logprintf("]");
- logprintf(" (count %d", cnt);
- if (n < 0) {
- logprintf(",unknown %d bytes", len);
- }
- logprintf(")");
-
- }
- logprintf("\n");
-}
-
-/* Verify two strings are equal, dump them if not. */
-int
-assertion_equal_string(const char *file, int line,
- const char *v1, const char *e1,
- const char *v2, const char *e2,
- void *extra, int utf8)
-{
- int l1, l2;
-
- assertion_count(file, line);
- if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0))
- return (1);
- failure_start(file, line, "%s != %s", e1, e2);
- l1 = (int)strlen(e1);
- l2 = (int)strlen(e2);
- if (l1 < l2)
- l1 = l2;
- strdump(e1, v1, l1, utf8);
- strdump(e2, v2, l1, utf8);
- failure_finish(extra);
- return (0);
-}
-
-static void
-wcsdump(const char *e, const wchar_t *w)
-{
- logprintf(" %s = ", e);
- if (w == NULL) {
- logprintf("(null)");
- return;
- }
- logprintf("\"");
- while (*w != L'\0') {
- unsigned int c = *w++;
- if (c >= 32 && c < 127)
- logprintf("%c", c);
- else if (c < 256)
- logprintf("\\x%02X", c);
- else if (c < 0x10000)
- logprintf("\\u%04X", c);
- else
- logprintf("\\U%08X", c);
- }
- logprintf("\"\n");
-}
-
-#ifndef HAVE_WCSCMP
-static int
-wcscmp(const wchar_t *s1, const wchar_t *s2)
-{
-
- while (*s1 == *s2++) {
- if (*s1++ == L'\0')
- return 0;
- }
- if (*s1 > *--s2)
- return 1;
- else
- return -1;
-}
-#endif
-
-/* Verify that two wide strings are equal, dump them if not. */
-int
-assertion_equal_wstring(const char *file, int line,
- const wchar_t *v1, const char *e1,
- const wchar_t *v2, const char *e2,
- void *extra)
-{
- assertion_count(file, line);
- if (v1 == v2)
- return (1);
- if (v1 != NULL && v2 != NULL && wcscmp(v1, v2) == 0)
- return (1);
- failure_start(file, line, "%s != %s", e1, e2);
- wcsdump(e1, v1);
- wcsdump(e2, v2);
- failure_finish(extra);
- return (0);
-}
-
-/*
- * Pretty standard hexdump routine. As a bonus, if ref != NULL, then
- * any bytes in p that differ from ref will be highlighted with '_'
- * before and after the hex value.
- */
-static void
-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) {
- 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 = '_';
- logprintf("%c%02x", sep, 0xff & (int)p[i+j]);
- if (ref != NULL && p[i + j] == ref[i + j])
- sep = ' ';
- }
- for (; j < 16; j++) {
- logprintf("%c ", sep);
- sep = ' ';
- }
- logprintf("%c", sep);
- for (j=0; j < 16 && i + j < l; j++) {
- int c = p[i + j];
- if (c >= ' ' && c <= 126)
- logprintf("%c", c);
- else
- logprintf(".");
- }
- logprintf("\n");
- }
-}
-
-/* Verify that two blocks of memory are the same, display the first
- * block of differences if they're not. */
-int
-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)
-{
- const char *v1 = (const char *)_v1;
- const char *v2 = (const char *)_v2;
- size_t offset;
-
- assertion_count(file, line);
- if (v1 == v2 || (v1 != NULL && v2 != NULL && memcmp(v1, v2, l) == 0))
- return (1);
- if (v1 == NULL || v2 == NULL)
- return (0);
-
- 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) {
- /* Two lines agree, so step forward one line. */
- v1 += 16;
- v2 += 16;
- l -= 16;
- offset += 16;
- }
- logprintf(" Dump of %s\n", e1);
- hexdump(v1, v2, l < 128 ? l : 128, offset);
- logprintf(" Dump of %s\n", e2);
- hexdump(v2, v1, l < 128 ? l : 128, offset);
- logprintf("\n");
- failure_finish(extra);
- return (0);
-}
-
-/* Verify that a block of memory is filled with the specified byte. */
-int
-assertion_memory_filled_with(const char *file, int line,
- const void *_v1, const char *vd,
- size_t l, const char *ld,
- char b, const char *bd, void *extra)
-{
- const char *v1 = (const char *)_v1;
- size_t c = 0;
- size_t i;
- (void)ld; /* UNUSED */
-
- assertion_count(file, line);
-
- for (i = 0; i < l; ++i) {
- if (v1[i] == b) {
- ++c;
- }
- }
- if (c == l)
- return (1);
-
- failure_start(file, line, "%s (size %d) not filled with %s", vd, (int)l, bd);
- logprintf(" Only %d bytes were correct\n", (int)c);
- failure_finish(extra);
- return (0);
-}
-
-/* Verify that the named file exists and is empty. */
-int
-assertion_empty_file(const char *filename, int line, const char *f1)
-{
- char buff[1024];
- struct stat st;
- ssize_t s;
- FILE *f;
-
- assertion_count(filename, line);
-
- if (stat(f1, &st) != 0) {
- failure_start(filename, line, "Stat failed: %s", f1);
- failure_finish(NULL);
- return (0);
- }
- if (st.st_size == 0)
- return (1);
-
- failure_start(filename, 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 = ((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);
- }
- failure_finish(NULL);
- return (0);
-}
-
-/* Verify that the named file exists and is not empty. */
-int
-assertion_non_empty_file(const char *filename, int line, const char *f1)
-{
- struct stat st;
-
- assertion_count(filename, line);
-
- if (stat(f1, &st) != 0) {
- failure_start(filename, line, "Stat failed: %s", f1);
- failure_finish(NULL);
- return (0);
- }
- if (st.st_size == 0) {
- failure_start(filename, 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
-assertion_equal_file(const char *filename, int line, const char *fn1, const char *fn2)
-{
- char buff1[1024];
- char buff2[1024];
- FILE *f1, *f2;
- int n1, n2;
-
- assertion_count(filename, line);
-
- f1 = fopen(fn1, "rb");
- f2 = fopen(fn2, "rb");
- if (f1 == NULL || f2 == NULL) {
- if (f1) fclose(f1);
- if (f2) fclose(f2);
- return (0);
- }
- for (;;) {
- n1 = (int)fread(buff1, 1, sizeof(buff1), f1);
- n2 = (int)fread(buff2, 1, sizeof(buff2), f2);
- if (n1 != n2)
- break;
- if (n1 == 0 && n2 == 0) {
- fclose(f1);
- fclose(f2);
- return (1);
- }
- if (memcmp(buff1, buff2, n1) != 0)
- break;
- }
- fclose(f1);
- fclose(f2);
- failure_start(filename, line, "Files not identical");
- logprintf(" file1=\"%s\"\n", fn1);
- logprintf(" file2=\"%s\"\n", fn2);
- failure_finish(NULL);
- return (0);
-}
-
-/* Verify that the named file does exist. */
-int
-assertion_file_exists(const char *filename, int line, const char *f)
-{
- assertion_count(filename, line);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (!_access(f, 0))
- return (1);
-#else
- if (!access(f, F_OK))
- return (1);
-#endif
- failure_start(filename, line, "File should exist: %s", f);
- failure_finish(NULL);
- return (0);
-}
-
-/* Verify that the named file doesn't exist. */
-int
-assertion_file_not_exists(const char *filename, int line, const char *f)
-{
- assertion_count(filename, line);
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (_access(f, 0))
- return (1);
-#else
- if (access(f, F_OK))
- return (1);
-#endif
- failure_start(filename, line, "File should not exist: %s", f);
- failure_finish(NULL);
- return (0);
-}
-
-/* Compare the contents of a file to a block of memory. */
-int
-assertion_file_contents(const char *filename, int line, const void *buff, int s, const char *fn)
-{
- char *contents;
- FILE *f;
- int n;
-
- assertion_count(filename, line);
-
- f = fopen(fn, "rb");
- if (f == NULL) {
- failure_start(filename, line,
- "File should exist: %s", fn);
- failure_finish(NULL);
- return (0);
- }
- contents = malloc(s * 2);
- n = (int)fread(contents, 1, s * 2, f);
- fclose(f);
- if (n == s && memcmp(buff, contents, s) == 0) {
- free(contents);
- return (1);
- }
- failure_start(filename, 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 : s, 0);
- }
- failure_finish(NULL);
- free(contents);
- return (0);
-}
-
-/* Check the contents of a text file, being tolerant of line endings. */
-int
-assertion_text_file_contents(const char *filename, int line, const char *buff, const char *fn)
-{
- char *contents;
- const char *btxt, *ftxt;
- FILE *f;
- int n, s;
-
- assertion_count(filename, line);
- f = fopen(fn, "r");
- if (f == NULL) {
- failure_start(filename, line,
- "File doesn't exist: %s", fn);
- failure_finish(NULL);
- return (0);
- }
- s = (int)strlen(buff);
- contents = malloc(s * 2 + 128);
- n = (int)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;
- }
- break;
- }
- if (*btxt == '\0' && *ftxt == '\0') {
- free(contents);
- return (1);
- }
- failure_start(filename, line, "Contents don't match");
- logprintf(" file=\"%s\"\n", fn);
- if (n > 0) {
- hexdump(contents, buff, n, 0);
- logprintf(" expected\n", fn);
- hexdump(buff, contents, s, 0);
- } else {
- logprintf(" File empty, contents should be:\n");
- hexdump(buff, NULL, s, 0);
- }
- failure_finish(NULL);
- free(contents);
- return (0);
-}
-
-/* Verify that a text file contains the specified lines, regardless of order */
-/* This could be more efficient if we sorted both sets of lines, etc, but
- * since this is used only for testing and only ever deals with a dozen or so
- * lines at a time, this relatively crude approach is just fine. */
-int
-assertion_file_contains_lines_any_order(const char *file, int line,
- const char *pathname, const char *lines[])
-{
- char *buff;
- size_t buff_size;
- size_t expected_count, actual_count, i, j;
- char **expected = NULL;
- char *p, **actual = NULL;
- char c;
- int expected_failure = 0, actual_failure = 0, retval = 0;
-
- assertion_count(file, line);
-
- buff = slurpfile(&buff_size, "%s", pathname);
- if (buff == NULL) {
- failure_start(pathname, line, "Can't read file: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
-
- /* Make a copy of the provided lines and count up the expected
- * file size. */
- for (i = 0; lines[i] != NULL; ++i) {
- }
- expected_count = i;
- if (expected_count) {
- expected = malloc(sizeof(char *) * expected_count);
- if (expected == NULL) {
- failure_start(pathname, line, "Can't allocate memory");
- failure_finish(NULL);
- goto done;
- }
- for (i = 0; lines[i] != NULL; ++i) {
- expected[i] = strdup(lines[i]);
- }
- }
-
- /* Break the file into lines */
- actual_count = 0;
- for (c = '\0', p = buff; p < buff + buff_size; ++p) {
- if (*p == '\x0d' || *p == '\x0a')
- *p = '\0';
- if (c == '\0' && *p != '\0')
- ++actual_count;
- c = *p;
- }
- if (actual_count) {
- actual = calloc(sizeof(char *), actual_count);
- if (actual == NULL) {
- failure_start(pathname, line, "Can't allocate memory");
- failure_finish(NULL);
- goto done;
- }
- for (j = 0, p = buff; p < buff + buff_size;
- p += 1 + strlen(p)) {
- if (*p != '\0') {
- actual[j] = p;
- ++j;
- }
- }
- }
-
- /* Erase matching lines from both lists */
- for (i = 0; i < expected_count; ++i) {
- if (expected[i] == NULL)
- continue;
- for (j = 0; j < actual_count; ++j) {
- if (actual[j] == NULL)
- continue;
- if (strcmp(expected[i], actual[j]) == 0) {
- free(expected[i]);
- expected[i] = NULL;
- actual[j] = NULL;
- break;
- }
- }
- }
-
- /* If there's anything left, it's a failure */
- for (i = 0; i < expected_count; ++i) {
- if (expected[i] != NULL)
- ++expected_failure;
- }
- for (j = 0; j < actual_count; ++j) {
- if (actual[j] != NULL)
- ++actual_failure;
- }
- if (expected_failure == 0 && actual_failure == 0) {
- retval = 1;
- goto done;
- }
- failure_start(file, line, "File doesn't match: %s", pathname);
- for (i = 0; i < expected_count; ++i) {
- if (expected[i] != NULL)
- logprintf(" Expected but not present: %s\n", expected[i]);
- }
- for (j = 0; j < actual_count; ++j) {
- if (actual[j] != NULL)
- logprintf(" Present but not expected: %s\n", actual[j]);
- }
- failure_finish(NULL);
-done:
- free(actual);
- free(buff);
- for (i = 0; i < expected_count; ++i)
- free(expected[i]);
- free(expected);
-
- return (retval);
-}
-
-/* Verify that a text file does not contains the specified strings */
-int
-assertion_file_contains_no_invalid_strings(const char *file, int line,
- const char *pathname, const char *strings[])
-{
- char *buff;
- int i;
-
- buff = slurpfile(NULL, "%s", pathname);
- if (buff == NULL) {
- failure_start(file, line, "Can't read file: %s", pathname);
- failure_finish(NULL);
- return (0);
- }
-
- for (i = 0; strings[i] != NULL; ++i) {
- if (strstr(buff, strings[i]) != NULL) {
- failure_start(file, line, "Invalid string in %s: %s", pathname,
- strings[i]);
- failure_finish(NULL);
- free(buff);
- return(0);
- }
- }
-
- free(buff);
- 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 fxtime, fbirthtime, fatime, fmtime;
- ULARGE_INTEGER wintm;
- HANDLE h;
- fxtime.dwLowDateTime = 0;
- fxtime.dwHighDateTime = 0;
-
- assertion_count(file, line);
- /* Note: FILE_FLAG_BACKUP_SEMANTICS applies to open
- * a directory file. If not, CreateFile() will fail when
- * the pathname is a directory. */
- h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL,
- OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 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': fxtime = fatime; break;
- case 'b': fxtime = fbirthtime; break;
- case 'm': fxtime = fmtime; break;
- }
- CloseHandle(h);
- if (r == 0) {
- failure_start(file, line, "Can't GetFileTime %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- wintm.LowPart = fxtime.dwLowDateTime;
- wintm.HighPart = fxtime.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;
- /* FreeBSD filesystems that don't support birthtime
- * (e.g., UFS1) always return -1 here. */
- if (filet == -1) {
- return (1);
- }
- 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 %lld, %lld 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 %lld.%09lld, expected %lld.%09lld",
- 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 mode of 'pathname'. */
-int
-assertion_file_mode(const char *file, int line, const char *pathname, int expected_mode)
-{
- int mode;
- int r;
-
- assertion_count(file, line);
-#if defined(_WIN32) && !defined(__CYGWIN__)
- failure_start(file, line, "assertFileMode not yet implemented for Windows");
- (void)mode; /* UNUSED */
- (void)r; /* UNUSED */
-#else
- {
- struct stat st;
- r = lstat(pathname, &st);
- mode = (int)(st.st_mode & 0777);
- }
- if (r == 0 && mode == expected_mode)
- return (1);
- failure_start(file, line, "File %s has mode %o, expected %o",
- pathname, mode, expected_mode);
-#endif
- failure_finish(NULL);
- return (0);
-}
-
-/* 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 && (int)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_t)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_t)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[301];
- 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) - 1);
- 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)) {
- if (0 == chmod(dirname, mode)) {
- assertion_file_mode(file, line, 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, int csize, const void *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) {
- size_t wsize;
-
- if (csize < 0)
- wsize = strlen(contents);
- else
- wsize = (size_t)csize;
- if (wsize != fwrite(contents, 1, wsize, 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 (0 != chmod(path, mode)) {
- failure_start(file, line, "Could not chmod %s", path);
- failure_finish(NULL);
- close(fd);
- return (0);
- }
- if (contents != NULL) {
- ssize_t wsize;
-
- if (csize < 0)
- wsize = (ssize_t)strlen(contents);
- else
- wsize = (ssize_t)csize;
- if (wsize != write(fd, contents, wsize)) {
- close(fd);
- failure_start(file, line,
- "Could not write to %s", path);
- failure_finish(NULL);
- close(fd);
- return (0);
- }
- }
- close(fd);
- assertion_file_mode(file, line, path, mode);
- 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);
-}
-
-/* Set times, report failures. */
-int
-assertion_utimes(const char *file, int line,
- const char *pathname, long at, long at_nsec, long mt, long mt_nsec)
-{
- int r;
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
- + (((nsec)/1000)*10))
- HANDLE h;
- ULARGE_INTEGER wintm;
- FILETIME fatime, fmtime;
- FILETIME *pat, *pmt;
-
- assertion_count(file, line);
- h = CreateFileA(pathname,GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (h == INVALID_HANDLE_VALUE) {
- failure_start(file, line, "Can't access %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
-
- if (at > 0 || at_nsec > 0) {
- wintm.QuadPart = WINTIME(at, at_nsec);
- fatime.dwLowDateTime = wintm.LowPart;
- fatime.dwHighDateTime = wintm.HighPart;
- pat = &fatime;
- } else
- pat = NULL;
- if (mt > 0 || mt_nsec > 0) {
- wintm.QuadPart = WINTIME(mt, mt_nsec);
- fmtime.dwLowDateTime = wintm.LowPart;
- fmtime.dwHighDateTime = wintm.HighPart;
- pmt = &fmtime;
- } else
- pmt = NULL;
- if (pat != NULL || pmt != NULL)
- r = SetFileTime(h, NULL, pat, pmt);
- else
- r = 1;
- CloseHandle(h);
- if (r == 0) {
- failure_start(file, line, "Can't SetFileTime %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- return (1);
-#else /* defined(_WIN32) && !defined(__CYGWIN__) */
- struct stat st;
- struct timeval times[2];
-
-#if !defined(__FreeBSD__)
- mt_nsec = at_nsec = 0; /* Generic POSIX only has whole seconds. */
-#endif
- if (mt == 0 && mt_nsec == 0 && at == 0 && at_nsec == 0)
- return (1);
-
- r = lstat(pathname, &st);
- if (r < 0) {
- failure_start(file, line, "Can't stat %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
-
- if (mt == 0 && mt_nsec == 0) {
- mt = st.st_mtime;
-#if defined(__FreeBSD__)
- mt_nsec = st.st_mtimespec.tv_nsec;
- /* FreeBSD generally only stores to microsecond res, so round. */
- mt_nsec = (mt_nsec / 1000) * 1000;
-#endif
- }
- if (at == 0 && at_nsec == 0) {
- at = st.st_atime;
-#if defined(__FreeBSD__)
- at_nsec = st.st_atimespec.tv_nsec;
- /* FreeBSD generally only stores to microsecond res, so round. */
- at_nsec = (at_nsec / 1000) * 1000;
-#endif
- }
-
- times[1].tv_sec = mt;
- times[1].tv_usec = mt_nsec / 1000;
-
- times[0].tv_sec = at;
- times[0].tv_usec = at_nsec / 1000;
-
-#ifdef HAVE_LUTIMES
- r = lutimes(pathname, times);
-#else
- r = utimes(pathname, times);
-#endif
- if (r < 0) {
- failure_start(file, line, "Can't utimes %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- return (1);
-#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
-}
-
-/* Set nodump, report failures. */
-int
-assertion_nodump(const char *file, int line, const char *pathname)
-{
-#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
- int r;
-
- assertion_count(file, line);
- r = chflags(pathname, UF_NODUMP);
- if (r < 0) {
- failure_start(file, line, "Can't set nodump %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
-#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
- && defined(EXT2_NODUMP_FL)
- int fd, r, flags;
-
- assertion_count(file, line);
- fd = open(pathname, O_RDONLY | O_NONBLOCK);
- if (fd < 0) {
- failure_start(file, line, "Can't open %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
- if (r < 0) {
- failure_start(file, line, "Can't get flags %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- flags |= EXT2_NODUMP_FL;
- r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
- if (r < 0) {
- failure_start(file, line, "Can't set nodump %s\n", pathname);
- failure_finish(NULL);
- return (0);
- }
- close(fd);
-#else
- (void)pathname; /* UNUSED */
- assertion_count(file, line);
-#endif
- 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, 1, "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);
-}
-
-/* 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
-/*
- * Can this platform run the bzip2 program?
- */
-int
-canBzip2(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("bzip2 -d -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the grzip program?
- */
-int
-canGrzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("grzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the gzip program?
- */
-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 lrzip program?
- */
-int
-canRunCommand(const char *cmd)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("%s %s", cmd, redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-int
-canLrzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lrzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the lz4 program?
- */
-int
-canLz4(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lz4 -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the lzip program?
- */
-int
-canLzip(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lzip -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the lzma program?
- */
-int
-canLzma(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lzma -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the lzop program?
- */
-int
-canLzop(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("lzop -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this platform run the xz program?
- */
-int
-canXz(void)
-{
- static int tested = 0, value = 0;
- if (!tested) {
- tested = 1;
- if (systemf("xz -V %s", redirectArgs) == 0)
- value = 1;
- }
- return (value);
-}
-
-/*
- * Can this filesystem handle nodump flags.
- */
-#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
-
-int
-canNodump(void)
-{
- const char *path = "cannodumptest";
- struct stat sb;
-
- assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
- if (chflags(path, UF_NODUMP) < 0)
- return (0);
- if (stat(path, &sb) < 0)
- return (0);
- if (sb.st_flags & UF_NODUMP)
- return (1);
- return (0);
-}
-
-#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
- && defined(EXT2_NODUMP_FL)
-
-int
-canNodump(void)
-{
- const char *path = "cannodumptest";
- int fd, r, flags;
-
- assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
- fd = open(path, O_RDONLY | O_NONBLOCK);
- if (fd < 0)
- return (0);
- r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
- if (r < 0)
- return (0);
- flags |= EXT2_NODUMP_FL;
- r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
- if (r < 0)
- return (0);
- close(fd);
- fd = open(path, O_RDONLY | O_NONBLOCK);
- if (fd < 0)
- return (0);
- r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
- if (r < 0)
- return (0);
- close(fd);
- if (flags & EXT2_NODUMP_FL)
- return (1);
- return (0);
-}
-
-#else
-
-int
-canNodump()
-{
- return (0);
-}
-
-#endif
-
-/*
- * 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.
- */
-int
-systemf(const char *fmt, ...)
-{
- char buff[8192];
- va_list ap;
- int r;
-
- 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);
-}
-
-/*
- * Slurp a file into memory for ease of comparison and testing.
- * Returns size of file in 'sizep' if non-NULL, null-terminates
- * data in memory for ease of use.
- */
-char *
-slurpfile(size_t * sizep, const char *fmt, ...)
-{
- char filename[8192];
- struct stat st;
- va_list ap;
- char *p;
- ssize_t bytes_read;
- FILE *f;
- int r;
-
- va_start(ap, fmt);
- vsprintf(filename, fmt, ap);
- va_end(ap);
-
- f = fopen(filename, "rb");
- if (f == NULL) {
- /* Note: No error; non-existent file is okay here. */
- return (NULL);
- }
- r = fstat(fileno(f), &st);
- if (r != 0) {
- logprintf("Can't stat file %s\n", filename);
- fclose(f);
- return (NULL);
- }
- p = malloc((size_t)st.st_size + 1);
- if (p == NULL) {
- 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 = fread(p, 1, (size_t)st.st_size, f);
- if (bytes_read < st.st_size) {
- 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;
- fclose(f);
- return (p);
-}
-
-/*
- * Slurp a file into memory for ease of comparison and testing.
- * Returns size of file in 'sizep' if non-NULL, null-terminates
- * data in memory for ease of use.
- */
-void
-dumpfile(const char *filename, void *data, size_t len)
-{
- ssize_t bytes_written;
- FILE *f;
-
- f = fopen(filename, "wb");
- if (f == NULL) {
- logprintf("Can't open file %s for writing\n", filename);
- return;
- }
- bytes_written = fwrite(data, 1, len, f);
- if (bytes_written < (ssize_t)len)
- logprintf("Can't write file %s\n", filename);
- fclose(f);
-}
-
-/* Read a uuencoded file from the reference directory, decode, and
- * write the result into the current directory. */
-#define VALID_UUDECODE(c) (c >= 32 && c <= 96)
-#define UUDECODE(c) (((c) - 0x20) & 0x3f)
-void
-extract_reference_file(const char *name)
-{
- char buff[1024];
- FILE *in, *out;
-
- sprintf(buff, "%s/%s.uu", refdir, name);
- in = fopen(buff, "r");
- failure("Couldn't open reference file %s", buff);
- assert(in != NULL);
- if (in == NULL)
- return;
- /* Read up to and including the 'begin' line. */
- for (;;) {
- if (fgets(buff, sizeof(buff), in) == NULL) {
- /* TODO: This is a failure. */
- goto done;
- }
- if (memcmp(buff, "begin ", 6) == 0)
- break;
- }
- /* Now, decode the rest and write it. */
- out = fopen(name, "wb");
- while (fgets(buff, sizeof(buff), in) != NULL) {
- char *p = buff;
- int bytes;
-
- if (memcmp(buff, "end", 3) == 0)
- break;
-
- bytes = UUDECODE(*p++);
- while (bytes > 0) {
- int n = 0;
- /* Write out 1-3 bytes from that. */
- if (bytes > 0) {
- assert(VALID_UUDECODE(p[0]));
- assert(VALID_UUDECODE(p[1]));
- n = UUDECODE(*p++) << 18;
- n |= UUDECODE(*p++) << 12;
- fputc(n >> 16, out);
- --bytes;
- }
- if (bytes > 0) {
- assert(VALID_UUDECODE(p[0]));
- n |= UUDECODE(*p++) << 6;
- fputc((n >> 8) & 0xFF, out);
- --bytes;
- }
- if (bytes > 0) {
- assert(VALID_UUDECODE(p[0]));
- n |= UUDECODE(*p++);
- fputc(n & 0xFF, out);
- --bytes;
- }
- }
- }
- fclose(out);
-done:
- fclose(in);
-}
-
-void
-copy_reference_file(const char *name)
-{
- char buff[1024];
- FILE *in, *out;
- size_t rbytes;
-
- sprintf(buff, "%s/%s", refdir, name);
- in = fopen(buff, "rb");
- failure("Couldn't open reference file %s", buff);
- assert(in != NULL);
- if (in == NULL)
- return;
- /* Now, decode the rest and write it. */
- /* Not a lot of error checking here; the input better be right. */
- out = fopen(name, "wb");
- while ((rbytes = fread(buff, 1, sizeof(buff), in)) > 0) {
- if (fwrite(buff, 1, rbytes, out) != rbytes) {
- logprintf("Error: fwrite\n");
- break;
- }
- }
- fclose(out);
- fclose(in);
-}
-
-int
-is_LargeInode(const char *file)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- BY_HANDLE_FILE_INFORMATION bhfi;
- int r;
-
- r = my_GetFileInformationByName(file, &bhfi);
- if (r != 0)
- return (0);
- return (bhfi.nFileIndexHigh & 0x0000FFFFUL);
-#else
- struct stat st;
- int64_t ino;
-
- if (stat(file, &st) < 0)
- return (0);
- ino = (int64_t)st.st_ino;
- return (ino > 0xffffffff);
-#endif
-}
-
-void
-extract_reference_files(const char **names)
-{
- while (names && *names)
- extract_reference_file(*names++);
-}
-
-/*
- *
- * 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 test_list_t tests[] = {
- #include "list.h"
-};
-
-/*
- * Summarize repeated failures in the just-completed test.
- */
-static void
-test_summarize(int failed, int skips_num)
-{
- unsigned int i;
-
- switch (verbosity) {
- case VERBOSITY_SUMMARY_ONLY:
- printf(failed ? "E" : ".");
- fflush(stdout);
- break;
- case VERBOSITY_PASSFAIL:
- printf(failed ? "FAIL\n" : skips_num ? "ok (S)\n" : "ok\n");
- break;
- }
-
- log_console = (verbosity == VERBOSITY_LIGHT_REPORT);
-
- 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",
- failed_filename, i, failed_lines[i].count);
- }
- /* Clear the failure history for the next file. */
- failed_filename = NULL;
- 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)
-{
- char workdir[1024];
- char logfilename[64];
- int failures_before = failures;
- int skips_before = skips;
- 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: %-64s", 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. */
- snprintf(workdir, sizeof(workdir), "%s/%s", tmpdir, tests[i].name);
- testworkdir = workdir;
- if (!assertMakeDir(testworkdir, 0755)
- || !assertChdir(testworkdir)) {
- fprintf(stderr,
- "ERROR: Can't chdir to work dir %s\n", testworkdir);
- 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.
- */
- testworkdir = NULL;
- /* 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(tests[i].failures, skips - skips_before);
- /* 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__)
- /* 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
- systemf("rm -rf %s", tests[i].name);
- systemf("rm %s", logfilename);
-#endif
- }
- }
- /* 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(" -u Keep running specifies tests until one fails.\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(const char *d)
-{
- size_t tried_size, buff_size;
- char *buff, *tried, *pwd = NULL, *p = NULL;
-
-#ifdef PATH_MAX
- buff_size = PATH_MAX;
-#else
- buff_size = 8192;
-#endif
- buff = calloc(buff_size, 1);
- if (buff == NULL) {
- fprintf(stderr, "Unable to allocate memory\n");
- exit(1);
- }
-
- /* Allocate a buffer to hold the various directories we checked. */
- tried_size = buff_size * 2;
- tried = calloc(tried_size, 1);
- if (tried == NULL) {
- fprintf(stderr, "Unable to allocate memory\n");
- exit(1);
- }
-
- /* If a dir was specified, try that */
- if (d != NULL) {
- pwd = NULL;
- snprintf(buff, buff_size, "%s", d);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
- goto failure;
- }
-
- /* Get the current dir. */
-#ifdef PATH_MAX
- pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
-#else
- pwd = getcwd(NULL, 0);
-#endif
- while (pwd[strlen(pwd) - 1] == '\n')
- pwd[strlen(pwd) - 1] = '\0';
-
- /* Look for a known file. */
- snprintf(buff, buff_size, "%s", pwd);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
-
- snprintf(buff, buff_size, "%s/test", pwd);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
-
-#if defined(LIBRARY)
- snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY);
-#else
- snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM);
-#endif
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
-
-#if defined(PROGRAM_ALIAS)
- snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
-#endif
-
- if (memcmp(pwd, "/usr/obj", 8) == 0) {
- snprintf(buff, buff_size, "%s", pwd + 8);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
-
- snprintf(buff, buff_size, "%s/test", pwd + 8);
- p = slurpfile(NULL, "%s/%s", buff, KNOWNREF);
- if (p != NULL) goto success;
- strncat(tried, buff, tried_size - strlen(tried) - 1);
- strncat(tried, "\n", tried_size - strlen(tried) - 1);
- }
-
-failure:
- printf("Unable to locate known reference file %s\n", KNOWNREF);
- printf(" Checked following directories:\n%s\n", tried);
- printf("Use -r option to specify full path to reference directory\n");
-#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
- DebugBreak();
-#endif
- exit(1);
-
-success:
- free(p);
- free(pwd);
- free(tried);
-
- /* Copy result into a fresh buffer to reduce memory usage. */
- p = strdup(buff);
- free(buff);
- return p;
-}
-
-int
-main(int argc, char **argv)
-{
- static const int limit = sizeof(tests) / sizeof(tests[0]);
- int test_set[sizeof(tests) / sizeof(tests[0])];
- int i = 0, j = 0, tests_run = 0, tests_failed = 0, option;
- time_t now;
- char *refdir_alloc = NULL;
- const char *progname;
- char **saved_argv;
- const char *tmp, *option_arg, *p;
- char tmpdir[256], *pwd, *testprogdir, *tmp2 = NULL, *vlevel = NULL;
- char tmpdir_timestamp[256];
-
- (void)argc; /* UNUSED */
-
- /* Get the current dir. */
-#ifdef PATH_MAX
- pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
-#else
- pwd = getcwd(NULL, 0);
-#endif
- while (pwd[strlen(pwd) - 1] == '\n')
- pwd[strlen(pwd) - 1] = '\0';
-
-#if defined(HAVE__CrtSetReportMode) && !defined(__WATCOMC__)
- /* To stop to run the default invalid parameter handler. */
- _set_invalid_parameter_handler(invalid_parameter_handler);
- /* 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];
- if ((testprogdir = (char *)malloc(strlen(progname) + 1)) == NULL)
- {
- fprintf(stderr, "ERROR: Out of memory.");
- exit(1);
- }
- strcpy(testprogdir, progname);
- while (*p != '\0') {
- /* Support \ or / dir separators for Windows compat. */
- if (*p == '/' || *p == '\\')
- {
- progname = p + 1;
- i = j;
- }
- ++p;
- j++;
- }
- testprogdir[i] = '\0';
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (testprogdir[0] != '/' && testprogdir[0] != '\\' &&
- !(((testprogdir[0] >= 'a' && testprogdir[0] <= 'z') ||
- (testprogdir[0] >= 'A' && testprogdir[0] <= 'Z')) &&
- testprogdir[1] == ':' &&
- (testprogdir[2] == '/' || testprogdir[2] == '\\')))
-#else
- if (testprogdir[0] != '/')
-#endif
- {
- /* Fixup path for relative directories. */
- if ((testprogdir = (char *)realloc(testprogdir,
- strlen(pwd) + 1 + strlen(testprogdir) + 1)) == NULL)
- {
- fprintf(stderr, "ERROR: Out of memory.");
- exit(1);
- }
- memmove(testprogdir + strlen(pwd) + 1, testprogdir,
- strlen(testprogdir) + 1);
- memcpy(testprogdir, pwd, strlen(pwd));
- testprogdir[strlen(pwd)] = '/';
- }
-
-#ifdef PROGRAM
- /* Get the target program from environment, if available. */
- testprogfile = getenv(ENVBASE);
-#endif
-
- if (getenv("TMPDIR") != NULL)
- tmp = getenv("TMPDIR");
- else if (getenv("TMP") != NULL)
- tmp = getenv("TMP");
- else if (getenv("TEMP") != NULL)
- tmp = getenv("TEMP");
- else if (getenv("TEMPDIR") != NULL)
- tmp = getenv("TEMPDIR");
- else
- tmp = "/tmp";
-
- /* Allow -d to be controlled through the environment. */
- if (getenv(ENVBASE "_DEBUG") != NULL)
- dump_on_failure = 1;
-
- /* Allow -v to be controlled through the environment. */
- if (getenv("_VERBOSITY_LEVEL") != NULL)
- {
- vlevel = getenv("_VERBOSITY_LEVEL");
- verbosity = atoi(vlevel);
- if (verbosity < VERBOSITY_SUMMARY_ONLY || verbosity > VERBOSITY_FULL)
- {
- /* Unsupported verbosity levels are silently ignored */
- vlevel = NULL;
- verbosity = VERBOSITY_PASSFAIL;
- }
- }
-
- /* Get the directory holding test files from environment. */
- refdir = getenv(ENVBASE "_TEST_FILES");
-
- /*
- * Parse options, without using getopt(), which isn't available
- * on all platforms.
- */
- ++argv; /* Skip program name */
- while (*argv != NULL) {
- if (**argv != '-')
- break;
- p = *argv++;
- ++p; /* Skip '-' */
- while (*p != '\0') {
- option = *p++;
- option_arg = NULL;
- /* If 'opt' takes an argument, parse that. */
- if (option == 'p' || option == 'r') {
- if (*p != '\0')
- option_arg = p;
- else if (*argv == NULL) {
- fprintf(stderr,
- "Option -%c requires argument.\n",
- option);
- usage(progname);
- } else
- option_arg = *argv++;
- p = ""; /* End of this option word. */
- }
-
- /* Now, handle the option. */
- switch (option) {
- case 'd':
- dump_on_failure = 1;
- break;
- case 'k':
- keep_temp_files = 1;
- break;
- case 'p':
-#ifdef PROGRAM
- testprogfile = option_arg;
-#else
- fprintf(stderr, "-p option not permitted\n");
- usage(progname);
-#endif
- break;
- case 'q':
- if (!vlevel)
- verbosity--;
- break;
- case 'r':
- refdir = option_arg;
- break;
- case 'u':
- until_failure++;
- break;
- case 'v':
- if (!vlevel)
- verbosity++;
- break;
- default:
- fprintf(stderr, "Unrecognized option '%c'\n",
- option);
- usage(progname);
- }
- }
- }
-
- /*
- * Sanity-check that our options make sense.
- */
-#ifdef PROGRAM
- if (testprogfile == NULL)
- {
- if ((tmp2 = (char *)malloc(strlen(testprogdir) + 1 +
- strlen(PROGRAM) + 1)) == NULL)
- {
- fprintf(stderr, "ERROR: Out of memory.");
- exit(1);
- }
- strcpy(tmp2, testprogdir);
- strcat(tmp2, "/");
- strcat(tmp2, PROGRAM);
- testprogfile = tmp2;
- }
-
- {
- 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
-
-#if !defined(_WIN32) && defined(SIGPIPE)
- { /* Ignore SIGPIPE signals */
- struct sigaction sa;
- sa.sa_handler = SIG_IGN;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sigaction(SIGPIPE, &sa, NULL);
- }
-#endif
-
- /*
- * Create a temp directory for the following tests.
- * Include the time the tests started as part of the name,
- * to make it easier to track the results of multiple tests.
- */
- now = time(NULL);
- for (i = 0; ; i++) {
- strftime(tmpdir_timestamp, sizeof(tmpdir_timestamp),
- "%Y-%m-%dT%H.%M.%S",
- localtime(&now));
- snprintf(tmpdir, sizeof(tmpdir), "%s/%s.%s-%03d", tmp,
- progname, tmpdir_timestamp, i);
- if (assertMakeDir(tmpdir,0755))
- break;
- if (i >= 999) {
- fprintf(stderr,
- "ERROR: Unable to create temp directory %s\n",
- tmpdir);
- exit(1);
- }
- }
-
- /*
- * If the user didn't specify a directory for locating
- * reference files, try to find the reference files in
- * the "usual places."
- */
- refdir = refdir_alloc = get_refdir(refdir);
-
- /*
- * Banner with basic information.
- */
- 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);
-#endif
- printf("Exercising: ");
- fflush(stdout);
- printf("%s\n", EXTRA_VERSION);
- } else {
- printf("Running ");
- fflush(stdout);
- }
-
- /*
- * Run some or all of the individual tests.
- */
- saved_argv = argv;
- do {
- argv = saved_argv;
- do {
- int test_num;
-
- test_num = get_test_set(test_set, limit, *argv, tests);
- if (test_num < 0) {
- printf("*** INVALID Test %s\n", *argv);
- free(refdir_alloc);
- free(testprogdir);
- usage(progname);
- return (1);
- }
- for (i = 0; i < test_num; i++) {
- tests_run++;
- if (test_run(test_set[i], tmpdir)) {
- tests_failed++;
- if (until_failure)
- goto finish;
- }
- }
- if (*argv != NULL)
- argv++;
- } while (*argv != NULL);
- } while (until_failure);
-
-finish:
- /* Must be freed after all tests run */
- free(tmp2);
- free(testprogdir);
- free(pwd);
-
- /*
- * Report summary statistics.
- */
- if (verbosity > VERBOSITY_SUMMARY_ONLY) {
- printf("\n");
- 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 ? 1 : 0);
-}
diff --git a/contrib/libarchive/tar/test/test.h b/contrib/libarchive/tar/test/test.h
index c002a2c27eee..1e1bee80709c 100644
--- a/contrib/libarchive/tar/test/test.h
+++ b/contrib/libarchive/tar/test/test.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2006 Tim Kientzle
+ * Copyright (c) 2003-2017 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,328 +27,14 @@
/* Every test program should #include "test.h" as the first thing. */
-/*
- * The goal of this file (and the matching test.c) is to
- * simplify the very repetitive test-*.c test programs.
- */
-#if defined(HAVE_CONFIG_H)
-/* Most POSIX platforms use the 'configure' script to build config.h */
-#include "config.h"
-#elif defined(__FreeBSD__)
-/* Building as part of FreeBSD system requires a pre-built config.h. */
-#include "config_freebsd.h"
-#elif defined(_WIN32) && !defined(__CYGWIN__)
-/* Win32 can't run the 'configure' script. */
-#include "config_windows.h"
-#else
-/* Warn if the library hasn't been (automatically or manually) configured. */
-#error Oops: No config.h and no pre-built configuration in test.h.
-#endif
-
-#include <sys/types.h> /* Windows requires this before sys/stat.h */
-#include <sys/stat.h>
-
-#if HAVE_DIRENT_H
-#include <dirent.h>
-#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 <ctype.h>
-#include <time.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <wchar.h>
-#ifdef HAVE_WINDOWS_H
-#include <windows.h>
-#endif
-
-/*
- * System-specific tweaks. We really want to minimize these
- * as much as possible, since they make it harder to understand
- * the mainline code.
- */
-
-/* Windows (including Visual Studio and MinGW but not Cygwin) */
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#if !defined(__BORLANDC__)
-#undef chdir
-#define chdir _chdir
-#define strdup _strdup
-#endif
-#endif
-
-/* Visual Studio */
-#if defined(_MSC_VER) && _MSC_VER < 1900
-#define snprintf sprintf_s
-#endif
-
-#if defined(__BORLANDC__)
-#pragma warn -8068 /* Constant out of range in comparison. */
-#endif
-
-/* Haiku OS and QNX */
-#if defined(__HAIKU__) || defined(__QNXNTO__)
-/* Haiku and QNX have 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
-#define O_BINARY 0
-#endif
-
-/*
- * Redefine DEFINE_TEST for use in defining the test functions.
- */
-#undef DEFINE_TEST
-#define DEFINE_TEST(name) void name(void); void name(void)
-
-/* An implementation of the standard assert() macro */
-#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) \
- 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) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
-#define assertEqualUTF8String(v1,v2) \
- assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
-/* As above, but v1 and v2 are wchar_t * */
-#define assertEqualWString(v1,v2) \
- assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
-/* As above, but raw blocks of bytes. */
-#define assertEqualMem(v1, v2, l) \
- assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
-/* Assert that memory is full of a specified byte */
-#define assertMemoryFilledWith(v1, l, b) \
- assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
-/* Assert two files are the same. */
-#define assertEqualFile(f1, f2) \
- assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
-/* Assert that a file is empty. */
-#define assertEmptyFile(pathname) \
- assertion_empty_file(__FILE__, __LINE__, (pathname))
-/* Assert that a file is not empty. */
-#define assertNonEmptyFile(pathname) \
- assertion_non_empty_file(__FILE__, __LINE__, (pathname))
-#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(pathname) \
- assertion_file_exists(__FILE__, __LINE__, pathname)
-/* Assert that a file exists. */
-#define assertFileNotExists(pathname) \
- assertion_file_not_exists(__FILE__, __LINE__, pathname)
-/* Assert that file contents match a string. */
-#define assertFileContents(data, data_size, pathname) \
- assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
-/* Verify that a file does not contain invalid strings */
-#define assertFileContainsNoInvalidStrings(pathname, strings) \
- assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
-#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 assertFileMode(pathname, mode) \
- assertion_file_mode(__FILE__, __LINE__, pathname, mode)
-#define assertTextFileContents(text, pathname) \
- assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
-#define assertFileContainsLinesAnyOrder(pathname, lines) \
- assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
-#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, -1, contents)
-#define assertMakeBinFile(path, mode, csize, contents) \
- assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
-#define assertMakeHardlink(newfile, oldfile) \
- assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
-#define assertMakeSymlink(newfile, linkto) \
- assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
-#define assertNodump(path) \
- assertion_nodump(__FILE__, __LINE__, path)
-#define assertUmask(mask) \
- assertion_umask(__FILE__, __LINE__, mask)
-#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
- assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
-
-/*
- * This would be simple with C99 variadic macros, but I don't want to
- * require that. Instead, I insert a function call before each
- * skipping() call to pass the file and line information down. Crude,
- * but effective.
- */
-#define skipping \
- skipping_setup(__FILE__, __LINE__);test_skipping
-
-/* Function declarations. These are defined in test_utility.c. */
-void failure(const char *fmt, ...);
-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, const char *);
-int assertion_equal_file(const char *, int, 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_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
-int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
-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_contains_lines_any_order(const char *, int, const char *, const char **);
-int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
-int assertion_file_contents(const char *, int, const void *, int, const char *);
-int assertion_file_exists(const char *, int, const char *);
-int assertion_file_mode(const char *, int, const char *, int);
-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, 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, int, const void *);
-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_nodump(const char *, int, const char *);
-int assertion_non_empty_file(const char *, int, const char *);
-int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
-int assertion_umask(const char *, int, int);
-int assertion_utimes(const char *, int, const char *, long, long, long, long );
-
-void skipping_setup(const char *, int);
-void test_skipping(const char *fmt, ...);
-
-/* 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 "bzip2" program. */
-int canBzip2(void);
-
-/* Return true if this platform can run the "grzip" program. */
-int canGrzip(void);
-
-/* Return true if this platform can run the "gzip" program. */
-int canGzip(void);
-
-/* Return true if this platform can run the specified command. */
-int canRunCommand(const char *);
-
-/* Return true if this platform can run the "lrzip" program. */
-int canLrzip(void);
-
-/* Return true if this platform can run the "lz4" program. */
-int canLz4(void);
-
-/* Return true if this platform can run the "lzip" program. */
-int canLzip(void);
-
-/* Return true if this platform can run the "lzma" program. */
-int canLzma(void);
-
-/* Return true if this platform can run the "lzop" program. */
-int canLzop(void);
-
-/* Return true if this platform can run the "xz" program. */
-int canXz(void);
-
-/* Return true if this filesystem can handle nodump flags. */
-int canNodump(void);
-
-/* Return true if the file has large i-node number(>0xffffffff). */
-int is_LargeInode(const char *);
-
-/* 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, ...);
-
-/* Dump block of bytes to a file. */
-void dumpfile(const char *filename, void *, size_t);
-
-/* Extracts named reference file to the current directory. */
-void extract_reference_file(const char *);
-/* Copies named reference file to the current directory. */
-void copy_reference_file(const char *);
-
-/* Extracts a list of files to the current directory.
- * List must be NULL terminated.
- */
-void extract_reference_files(const char **);
-
-/* Subtract umask from mode */
-mode_t umasked(mode_t expected_mode);
-
-/* Path to working directory for current test */
-extern const char *testworkdir;
-
-/*
- * Special interfaces for program test harness.
- */
-
-/* Pathname of exe to be tested. */
-extern const char *testprogfile;
-/* Name of exe to use in printf-formatted command strings. */
-/* On Windows, this includes leading/trailing quotes. */
-extern const char *testprog;
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#endif
+#define KNOWNREF "test_patterns_2.tar.uu"
+#define ENVBASE "BSDTAR" /* Prefix for environment variables. */
+#define PROGRAM "bsdtar" /* Name of program being tested. */
+#define PROGRAM_ALIAS "tar" /* Generic alias for program */
+#undef LIBRARY /* Not testing a library. */
+#undef EXTRA_DUMP /* How to dump extra data */
+#undef EXTRA_ERRNO /* How to dump errno */
+/* How to generate extra version info. */
+#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "")
+
+#include "test_common.h"
diff --git a/contrib/libarchive/tar/test/test_option_acls.c b/contrib/libarchive/tar/test/test_option_acls.c
new file mode 100644
index 000000000000..5c3fbfd156c8
--- /dev/null
+++ b/contrib/libarchive/tar/test/test_option_acls.c
@@ -0,0 +1,471 @@
+/*-
+ * Copyright (c) 2017 Martin Matuska
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
+static const acl_perm_t acl_perms[] = {
+#if HAVE_DARWIN_ACL
+ ACL_READ_DATA,
+ ACL_LIST_DIRECTORY,
+ ACL_WRITE_DATA,
+ ACL_ADD_FILE,
+ ACL_EXECUTE,
+ ACL_SEARCH,
+ ACL_DELETE,
+ ACL_APPEND_DATA,
+ ACL_ADD_SUBDIRECTORY,
+ ACL_DELETE_CHILD,
+ ACL_READ_ATTRIBUTES,
+ ACL_WRITE_ATTRIBUTES,
+ ACL_READ_EXTATTRIBUTES,
+ ACL_WRITE_EXTATTRIBUTES,
+ ACL_READ_SECURITY,
+ ACL_WRITE_SECURITY,
+ ACL_CHANGE_OWNER,
+ ACL_SYNCHRONIZE
+#else /* !HAVE_DARWIN_ACL */
+ ACL_EXECUTE,
+ ACL_WRITE,
+ ACL_READ,
+#if HAVE_FREEBSD_NFS4_ACL
+ ACL_READ_DATA,
+ ACL_LIST_DIRECTORY,
+ ACL_WRITE_DATA,
+ ACL_ADD_FILE,
+ ACL_APPEND_DATA,
+ ACL_ADD_SUBDIRECTORY,
+ ACL_READ_NAMED_ATTRS,
+ ACL_WRITE_NAMED_ATTRS,
+ ACL_DELETE_CHILD,
+ ACL_READ_ATTRIBUTES,
+ ACL_WRITE_ATTRIBUTES,
+ ACL_DELETE,
+ ACL_READ_ACL,
+ ACL_WRITE_ACL,
+ ACL_WRITE_OWNER,
+ ACL_SYNCHRONIZE
+#endif /* HAVE_FREEBSD_NFS4_ACL */
+#endif /* !HAVE_DARWIN_ACL */
+};
+#if HAVE_DARWIN_ACL || HAVE_FREEBSD_NFS4_ACL
+static const acl_flag_t acl_flags[] = {
+#if HAVE_DARWIN_ACL
+ ACL_FLAG_DEFER_INHERIT,
+ ACL_FLAG_NO_INHERIT,
+ ACL_ENTRY_INHERITED,
+ ACL_ENTRY_FILE_INHERIT,
+ ACL_ENTRY_DIRECTORY_INHERIT,
+ ACL_ENTRY_LIMIT_INHERIT,
+ ACL_ENTRY_ONLY_INHERIT
+#else /* HAVE_FREEBSD_NFS4_ACL */
+ ACL_ENTRY_FILE_INHERIT,
+ ACL_ENTRY_DIRECTORY_INHERIT,
+ ACL_ENTRY_NO_PROPAGATE_INHERIT,
+ ACL_ENTRY_INHERIT_ONLY,
+ ACL_ENTRY_SUCCESSFUL_ACCESS,
+ ACL_ENTRY_FAILED_ACCESS,
+ ACL_ENTRY_INHERITED
+#endif /* HAVE_FREEBSD_NFS4_ACL */
+};
+#endif /* HAVE_DARWIN_ACL || HAVE_FREEBSD_NFS4_ACL */
+
+/*
+ * Compare two ACL entries on FreeBSD or on Mac OS X
+ */
+static int
+compare_acl_entry(acl_entry_t ae_a, acl_entry_t ae_b, int is_nfs4)
+{
+ acl_tag_t tag_a, tag_b;
+ acl_permset_t permset_a, permset_b;
+ int perm_a, perm_b, perm_start, perm_end;
+ void *qual_a, *qual_b;
+#if HAVE_FREEBSD_NFS4_ACL
+ acl_entry_type_t type_a, type_b;
+#endif
+#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
+ acl_flagset_t flagset_a, flagset_b;
+ int flag_a, flag_b;
+#endif
+ int i, r;
+
+
+ /* Compare ACL tag */
+ r = acl_get_tag_type(ae_a, &tag_a);
+ failure("acl_get_tag_type() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ r = acl_get_tag_type(ae_b, &tag_b);
+ failure("acl_get_tag_type() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ if (tag_a != tag_b)
+ return (0);
+
+ /* Compare ACL qualifier */
+#if HAVE_DARWIN_ACL
+ if (tag_a == ACL_EXTENDED_ALLOW || tag_b == ACL_EXTENDED_DENY)
+#else
+ if (tag_a == ACL_USER || tag_a == ACL_GROUP)
+#endif
+ {
+ qual_a = acl_get_qualifier(ae_a);
+ failure("acl_get_qualifier() error: %s", strerror(errno));
+ if (assert(qual_a != NULL) == 0)
+ return (-1);
+ qual_b = acl_get_qualifier(ae_b);
+ failure("acl_get_qualifier() error: %s", strerror(errno));
+ if (assert(qual_b != NULL) == 0) {
+ acl_free(qual_a);
+ return (-1);
+ }
+#if HAVE_DARWIN_ACL
+ if (memcmp(((guid_t *)qual_a)->g_guid,
+ ((guid_t *)qual_b)->g_guid, KAUTH_GUID_SIZE) != 0)
+#else
+ if ((tag_a == ACL_USER &&
+ (*(uid_t *)qual_a != *(uid_t *)qual_b)) ||
+ (tag_a == ACL_GROUP &&
+ (*(gid_t *)qual_a != *(gid_t *)qual_b)))
+#endif
+ {
+ acl_free(qual_a);
+ acl_free(qual_b);
+ return (0);
+ }
+ acl_free(qual_a);
+ acl_free(qual_b);
+ }
+
+#if HAVE_FREEBSD_NFS4_ACL
+ if (is_nfs4) {
+ /* Compare NFS4 ACL type */
+ r = acl_get_entry_type_np(ae_a, &type_a);
+ failure("acl_get_entry_type_np() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ r = acl_get_entry_type_np(ae_b, &type_b);
+ failure("acl_get_entry_type_np() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ if (type_a != type_b)
+ return (0);
+ }
+#endif
+
+ /* Compare ACL perms */
+ r = acl_get_permset(ae_a, &permset_a);
+ failure("acl_get_permset() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ r = acl_get_permset(ae_b, &permset_b);
+ failure("acl_get_permset() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+
+ perm_start = 0;
+ perm_end = (int)(sizeof(acl_perms) / sizeof(acl_perms[0]));
+#if HAVE_FREEBSD_NFS4_ACL
+ if (is_nfs4)
+ perm_start = 3;
+ else
+ perm_end = 3;
+#endif
+ /* Cycle through all perms and compare their value */
+ for (i = perm_start; i < perm_end; i++) {
+#if HAVE_LIBACL
+ perm_a = acl_get_perm(permset_a, acl_perms[i]);
+ perm_b = acl_get_perm(permset_b, acl_perms[i]);
+#else
+ perm_a = acl_get_perm_np(permset_a, acl_perms[i]);
+ perm_b = acl_get_perm_np(permset_b, acl_perms[i]);
+#endif
+ if (perm_a == -1 || perm_b == -1)
+ return (-1);
+ if (perm_a != perm_b)
+ return (0);
+ }
+
+#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
+ if (is_nfs4) {
+ r = acl_get_flagset_np(ae_a, &flagset_a);
+ failure("acl_get_flagset_np() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ r = acl_get_flagset_np(ae_b, &flagset_b);
+ failure("acl_get_flagset_np() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ /* Cycle through all flags and compare their status */
+ for (i = 0; i < (int)(sizeof(acl_flags) / sizeof(acl_flags[0]));
+ i++) {
+ flag_a = acl_get_flag_np(flagset_a, acl_flags[i]);
+ flag_b = acl_get_flag_np(flagset_b, acl_flags[i]);
+ if (flag_a == -1 || flag_b == -1)
+ return (-1);
+ if (flag_a != flag_b)
+ return (0);
+ }
+ }
+#else /* HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL*/
+ (void)is_nfs4; /* UNUSED */
+#endif
+ return (1);
+}
+#endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
+
+#if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL
+/*
+ * Clear default ACLs or inheritance flags
+ */
+static void
+clear_inheritance_flags(const char *path, int type)
+{
+ switch (type) {
+ case ARCHIVE_TEST_ACL_TYPE_POSIX1E:
+#if HAVE_POSIX_ACL
+ acl_delete_def_file(path);
+#else
+ /* Solaris */
+ setTestAcl(path);
+#endif
+ break;
+ case ARCHIVE_TEST_ACL_TYPE_NFS4:
+#if HAVE_NFS4_ACL
+ setTestAcl(path);
+#endif
+ break;
+ default:
+ (void)path; /* UNUSED */
+ break;
+ }
+}
+
+static int
+compare_acls(const char *path_a, const char *path_b)
+{
+ int ret = 1;
+ int is_nfs4 = 0;
+#if HAVE_SUN_ACL
+ void *acl_a, *acl_b;
+ int aclcnt_a, aclcnt_b;
+ aclent_t *aclent_a, *aclent_b;
+ ace_t *ace_a, *ace_b;
+ int e;
+#else
+ acl_t acl_a, acl_b;
+ acl_entry_t aclent_a, aclent_b;
+ int a, b, r;
+#endif
+
+ acl_a = NULL;
+ acl_b = NULL;
+#if HAVE_SUN_ACL
+ acl_a = sunacl_get(GETACL, &aclcnt_a, 0, path_a);
+ if (acl_a == NULL) {
+#if HAVE_SUN_NFS4_ACL
+ is_nfs4 = 1;
+ acl_a = sunacl_get(ACE_GETACL, &aclcnt_a, 0, path_a);
+#endif
+ failure("acl_get() error: %s", strerror(errno));
+ if (assert(acl_a != NULL) == 0)
+ return (-1);
+#if HAVE_SUN_NFS4_ACL
+ acl_b = sunacl_get(ACE_GETACL, &aclcnt_b, 0, path_b);
+#endif
+ } else
+ acl_b = sunacl_get(GETACL, &aclcnt_b, 0, path_b);
+ if (acl_b == NULL && (errno == ENOSYS || errno == ENOTSUP)) {
+ free(acl_a);
+ return (0);
+ }
+ failure("acl_get() error: %s", strerror(errno));
+ if (assert(acl_b != NULL) == 0) {
+ free(acl_a);
+ return (-1);
+ }
+
+ if (aclcnt_a != aclcnt_b) {
+ ret = 0;
+ goto exit_free;
+ }
+
+ for (e = 0; e < aclcnt_a; e++) {
+ if (!is_nfs4) {
+ aclent_a = &((aclent_t *)acl_a)[e];
+ aclent_b = &((aclent_t *)acl_b)[e];
+ if (aclent_a->a_type != aclent_b->a_type ||
+ aclent_a->a_id != aclent_b->a_id ||
+ aclent_a->a_perm != aclent_b->a_perm) {
+ ret = 0;
+ goto exit_free;
+ }
+ }
+#if HAVE_SUN_NFS4_ACL
+ else {
+ ace_a = &((ace_t *)acl_a)[e];
+ ace_b = &((ace_t *)acl_b)[e];
+ if (ace_a->a_who != ace_b->a_who ||
+ ace_a->a_access_mask != ace_b->a_access_mask ||
+ ace_a->a_flags != ace_b->a_flags ||
+ ace_a->a_type != ace_b->a_type) {
+ ret = 0;
+ goto exit_free;
+ }
+ }
+#endif
+ }
+#else /* !HAVE_SUN_ACL */
+#if HAVE_DARWIN_ACL
+ is_nfs4 = 1;
+ acl_a = acl_get_file(path_a, ACL_TYPE_EXTENDED);
+#elif HAVE_FREEBSD_NFS4_ACL
+ acl_a = acl_get_file(path_a, ACL_TYPE_NFS4);
+ if (acl_a != NULL)
+ is_nfs4 = 1;
+#endif
+#if !HAVE_DARWIN_ACL
+ if (acl_a == NULL)
+ acl_a = acl_get_file(path_a, ACL_TYPE_ACCESS);
+#endif
+ failure("acl_get_file() error: %s (%s)", path_a, strerror(errno));
+ if (assert(acl_a != NULL) == 0)
+ return (-1);
+#if HAVE_DARWIN_ACL
+ acl_b = acl_get_file(path_b, ACL_TYPE_EXTENDED);
+#elif HAVE_FREEBSD_NFS4_ACL
+ acl_b = acl_get_file(path_b, ACL_TYPE_NFS4);
+#endif
+#if !HAVE_DARWIN_ACL
+ if (acl_b == NULL) {
+#if HAVE_FREEBSD_NFS4_ACL
+ if (is_nfs4) {
+ acl_free(acl_a);
+ return (0);
+ }
+#endif
+ acl_b = acl_get_file(path_b, ACL_TYPE_ACCESS);
+ }
+ failure("acl_get_file() error: %s (%s)", path_b, strerror(errno));
+ if (assert(acl_b != NULL) == 0) {
+ acl_free(acl_a);
+ return (-1);
+ }
+#endif
+ a = acl_get_entry(acl_a, ACL_FIRST_ENTRY, &aclent_a);
+ if (a == -1) {
+ ret = 0;
+ goto exit_free;
+ }
+ b = acl_get_entry(acl_b, ACL_FIRST_ENTRY, &aclent_b);
+ if (b == -1) {
+ ret = 0;
+ goto exit_free;
+ }
+#if HAVE_DARWIN_ACL
+ while (a == 0 && b == 0)
+#else /* FreeBSD, Linux */
+ while (a == 1 && b == 1)
+#endif
+ {
+ r = compare_acl_entry(aclent_a, aclent_b, is_nfs4);
+ if (r != 1) {
+ ret = r;
+ goto exit_free;
+ }
+ a = acl_get_entry(acl_a, ACL_NEXT_ENTRY, &aclent_a);
+ b = acl_get_entry(acl_b, ACL_NEXT_ENTRY, &aclent_b);
+ }
+ /* Entry count must match */
+ if (a != b)
+ ret = 0;
+#endif /* !HAVE_SUN_ACL */
+exit_free:
+#if HAVE_SUN_ACL
+ free(acl_a);
+ free(acl_b);
+#else
+ acl_free(acl_a);
+ acl_free(acl_b);
+#endif
+ return (ret);
+}
+#endif /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
+
+DEFINE_TEST(test_option_acls)
+{
+#if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_POSIX_ACL
+ skipping("ACLs are not supported on this platform");
+#else /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
+ int acltype, r;
+
+ assertMakeFile("f", 0644, "a");
+ acltype = setTestAcl("f");
+ if (acltype == 0) {
+ skipping("Can't write ACLs on the filesystem");
+ return;
+ }
+
+ /* Archive it with acls */
+ r = systemf("%s -c --no-mac-metadata --acls -f acls.tar f >acls.out 2>acls.err", testprog);
+ assertEqualInt(r, 0);
+
+ /* Archive it without acls */
+ r = systemf("%s -c --no-mac-metadata --no-acls -f noacls.tar f >noacls.out 2>noacls.err", testprog);
+ assertEqualInt(r, 0);
+
+ /* Extract acls with acls */
+ assertMakeDir("acls_acls", 0755);
+ clear_inheritance_flags("acls_acls", acltype);
+ r = systemf("%s -x -C acls_acls --no-same-permissions --acls -f acls.tar >acls_acls.out 2>acls_acls.err", testprog);
+ assertEqualInt(r, 0);
+ r = compare_acls("f", "acls_acls/f");
+ assertEqualInt(r, 1);
+
+ /* Extractl acls without acls */
+ assertMakeDir("acls_noacls", 0755);
+ clear_inheritance_flags("acls_noacls", acltype);
+ r = systemf("%s -x -C acls_noacls -p --no-acls -f acls.tar >acls_noacls.out 2>acls_noacls.err", testprog);
+ assertEqualInt(r, 0);
+ r = compare_acls("f", "acls_noacls/f");
+ assertEqualInt(r, 0);
+
+ /* Extract noacls with acls flag */
+ assertMakeDir("noacls_acls", 0755);
+ clear_inheritance_flags("noacls_acls", acltype);
+ r = systemf("%s -x -C noacls_acls --no-same-permissions --acls -f noacls.tar >noacls_acls.out 2>noacls_acls.err", testprog);
+ assertEqualInt(r, 0);
+ r = compare_acls("f", "noacls_acls/f");
+ assertEqualInt(r, 0);
+
+ /* Extract noacls with noacls */
+ assertMakeDir("noacls_noacls", 0755);
+ clear_inheritance_flags("noacls_noacls", acltype);
+ r = systemf("%s -x -C noacls_noacls -p --no-acls -f noacls.tar >noacls_noacls.out 2>noacls_noacls.err", testprog);
+ assertEqualInt(r, 0);
+ r = compare_acls("f", "noacls_noacls/f");
+ assertEqualInt(r, 0);
+#endif /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
+}
diff --git a/contrib/libarchive/tar/test/test_option_fflags.c b/contrib/libarchive/tar/test/test_option_fflags.c
new file mode 100644
index 000000000000..77a4e3e19f0f
--- /dev/null
+++ b/contrib/libarchive/tar/test/test_option_fflags.c
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2017 Martin Matuska
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+static void
+clear_fflags(const char *pathname)
+{
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS)
+ chflags(pathname, 0);
+#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
+ (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
+ int fd;
+
+ fd = open(pathname, O_RDONLY | O_NONBLOCK);
+ if (fd < 0)
+ return;
+ ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+ FS_IOC_GETFLAGS,
+#else
+ EXT2_IOC_GETFLAGS,
+#endif
+ 0);
+#else
+ (void)pathname; /* UNUSED */
+#endif
+ return;
+}
+
+DEFINE_TEST(test_option_fflags)
+{
+ int r;
+
+ if (!canNodump()) {
+ skipping("Can't test nodump flag on this filesystem");
+ return;
+ }
+
+ /* Create a file. */
+ assertMakeFile("f", 0644, "a");
+
+ /* Set nodump flag on the file */
+ assertSetNodump("f");
+
+ /* FreeBSD ZFS workaround: ZFS sets uarch on all touched files and dirs */
+ chmod("f", 0644);
+
+ /* Archive it with fflags */
+ r = systemf("%s -c --fflags -f fflags.tar f >fflags.out 2>fflags.err", testprog);
+ assertEqualInt(r, 0);
+
+ /* Archive it without fflags */
+ r = systemf("%s -c --no-fflags -f nofflags.tar f >nofflags.out 2>nofflags.err", testprog);
+ assertEqualInt(r, 0);
+
+ /* Extract fflags with fflags */
+ assertMakeDir("fflags_fflags", 0755);
+ clear_fflags("fflags_fflags");
+ r = systemf("%s -x -C fflags_fflags --no-same-permissions --fflags -f fflags.tar >fflags_fflags.out 2>fflags_fflags.err", testprog);
+ assertEqualInt(r, 0);
+ assertEqualFflags("f", "fflags_fflags/f");
+
+ /* Extract fflags without fflags */
+ assertMakeDir("fflags_nofflags", 0755);
+ clear_fflags("fflags_nofflags");
+ r = systemf("%s -x -C fflags_nofflags -p --no-fflags -f fflags.tar >fflags_nofflags.out 2>fflags_nofflags.err", testprog);
+ assertEqualInt(r, 0);
+ assertUnequalFflags("f", "fflags_nofflags/f");
+
+ /* Extract nofflags with fflags */
+ assertMakeDir("nofflags_fflags", 0755);
+ clear_fflags("nofflags_fflags");
+ r = systemf("%s -x -C nofflags_fflags --no-same-permissions --fflags -f nofflags.tar >nofflags_fflags.out 2>nofflags_fflags.err", testprog);
+ assertEqualInt(r, 0);
+ assertUnequalFflags("f", "nofflags_fflags/f");
+
+ /* Extract nofflags with nofflags */
+ assertMakeDir("nofflags_nofflags", 0755);
+ clear_fflags("nofflags_nofflags");
+ r = systemf("%s -x -C nofflags_nofflags -p --no-fflags -f nofflags.tar >nofflags_nofflags.out 2>nofflags_nofflags.err", testprog);
+ assertEqualInt(r, 0);
+ assertUnequalFflags("f", "nofflags_nofflags/f");
+}
diff --git a/contrib/libarchive/tar/test/test_option_nodump.c b/contrib/libarchive/tar/test/test_option_nodump.c
index 768f64a6dd37..815b08ed9251 100644
--- a/contrib/libarchive/tar/test/test_option_nodump.c
+++ b/contrib/libarchive/tar/test/test_option_nodump.c
@@ -36,7 +36,7 @@ DEFINE_TEST(test_option_nodump)
assertMakeFile("file1", 0644, "file1");
assertMakeFile("file2", 0644, "file2");
assertMakeFile("file3", 0644, "file3");
- assertNodump("file2");
+ assertSetNodump("file2");
/* Test 1: Without --nodump */
assertEqualInt(0, systemf("%s -cf test1.tar file1 file2 file3",
diff --git a/contrib/libarchive/tar/test/test_version.c b/contrib/libarchive/tar/test/test_version.c
index 93e826d4005d..1b896c0c49d1 100644
--- a/contrib/libarchive/tar/test/test_version.c
+++ b/contrib/libarchive/tar/test/test_version.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2017 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
-__FBSDID("$FreeBSD$");
/*
* Test that --version option works and generates reasonable output.
@@ -31,73 +30,5 @@ __FBSDID("$FreeBSD$");
DEFINE_TEST(test_version)
{
- int r;
- char *p, *q;
- size_t s;
-
-
- r = systemf("%s --version >version.stdout 2>version.stderr", testprog);
- if (r != 0)
- r = systemf("%s -W version >version.stdout 2>version.stderr",
- testprog);
- failure("Unable to run either %s --version or %s -W version",
- testprog, testprog);
- if (!assert(r == 0))
- return;
-
- /* --version should generate nothing to stdout. */
- assertEmptyFile("version.stderr");
- /* Verify format of version message. */
- q = p = slurpfile(&s, "version.stdout");
- /* Version message should start with name of program, then space. */
- assert(s > 6);
- failure("Version must start with 'bsdtar': ``%s''", p);
- if (!assertEqualMem(q, "bsdtar ", 7))
- goto done;
- q += 7; s -= 7;
- /* Version number is a series of digits and periods. */
- while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
- ++q;
- --s;
- }
- /* Version number terminated by space. */
- failure("No space after bsdtar version: ``%s''", p);
- assert(s > 1);
- /* Skip a single trailing a,b,c, or d. */
- if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
- ++q;
- failure("No space after bsdtar version: ``%s''", p);
- assert(*q == ' ');
- ++q; --s;
- /* Separator. */
- failure("No `-' between bsdtar and libarchive versions: ``%s''", p);
- assertEqualMem(q, "- ", 2);
- q += 2; s -= 2;
- /* libarchive name and version number */
- failure("Not long enough for libarchive version: ``%s''", p);
- assert(s > 11);
- failure("Libarchive version must start with `libarchive': ``%s''", p);
- assertEqualMem(q, "libarchive ", 11);
- q += 11; s -= 11;
- /* Version number is a series of digits and periods. */
- while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
- ++q;
- --s;
- }
- /* Skip a single trailing a,b,c, or d. */
- if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
- ++q;
- /* Skip arbitrary third-party version numbers. */
- while (s > 0 && (*q == ' ' || *q == '-' || *q == '/' || *q == '.' || isalnum(*q))) {
- ++q;
- --s;
- }
- /* All terminated by end-of-line. */
- assert(s >= 1);
- /* Skip an optional CR character (e.g., Windows) */
- failure("Version output must end with \\n or \\r\\n");
- if (*q == '\r') { ++q; --s; }
- assertEqualMem(q, "\n", 1);
-done:
- free(p);
+ assertVersion(testprog, "bsdtar");
}
diff --git a/contrib/libarchive/tar/util.c b/contrib/libarchive/tar/util.c
index 84dc53f7dcad..7b52e4081588 100644
--- a/contrib/libarchive/tar/util.c
+++ b/contrib/libarchive/tar/util.c
@@ -534,7 +534,7 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
}
}
- if (!bsdtar->option_absolute_paths) {
+ if ((bsdtar->flags & OPTFLAG_ABSOLUTE_PATHS) == 0) {
/* By default, don't write or restore absolute pathnames. */
name = strip_absolute_path(bsdtar, name);
if (*name == '\0')
diff --git a/contrib/libarchive/tar/write.c b/contrib/libarchive/tar/write.c
index 4265d1411ae8..4c9bb65c85f3 100644
--- a/contrib/libarchive/tar/write.c
+++ b/contrib/libarchive/tar/write.c
@@ -583,7 +583,7 @@ cleanup:
archive_read_free(bsdtar->diskreader);
bsdtar->diskreader = NULL;
- if (bsdtar->option_totals) {
+ if (bsdtar->flags & OPTFLAG_TOTALS) {
fprintf(stderr, "Total bytes written: %s\n",
tar_i64toa(archive_filter_bytes(a, -1)));
}
@@ -606,7 +606,8 @@ archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
bsdtar->next_line_is_dir = 0;
- lr = lafe_line_reader(bsdtar->names_from_file, bsdtar->option_null);
+ lr = lafe_line_reader(bsdtar->names_from_file,
+ (bsdtar->flags & OPTFLAG_NULL));
while ((line = lafe_line_reader_next(lr)) != NULL) {
if (bsdtar->next_line_is_dir) {
if (*line != '\0')
@@ -617,7 +618,8 @@ archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
bsdtar->return_value = 1;
}
bsdtar->next_line_is_dir = 0;
- } else if (!bsdtar->option_null && strcmp(line, "-C") == 0)
+ } else if (((bsdtar->flags & OPTFLAG_NULL) == 0) &&
+ strcmp(line, "-C") == 0)
bsdtar->next_line_is_dir = 1;
else {
if (*line != '/')
@@ -690,7 +692,7 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) {
if (archive_match_excluded(bsdtar->matching, in_entry))
continue;
- if (bsdtar->option_interactive &&
+ if ((bsdtar->flags & OPTFLAG_INTERACTIVE) &&
!yes("copy '%s'", archive_entry_pathname(in_entry)))
continue;
if (bsdtar->verbose > 1) {
@@ -809,11 +811,11 @@ excluded_callback(struct archive *a, void *_data, struct archive_entry *entry)
{
struct bsdtar *bsdtar = (struct bsdtar *)_data;
- if (bsdtar->option_no_subdirs)
+ if (bsdtar->flags & OPTFLAG_NO_SUBDIRS)
return;
if (!archive_read_disk_can_descend(a))
return;
- if (bsdtar->option_interactive &&
+ if ((bsdtar->flags & OPTFLAG_INTERACTIVE) &&
!yes("add '%s'", archive_entry_pathname(entry)))
return;
archive_read_disk_descend(a);
@@ -844,12 +846,13 @@ metadata_filter(struct archive *a, void *_data, struct archive_entry *entry)
* check would veto this file, we shouldn't bother
* the user with it.
*/
- if (bsdtar->option_interactive &&
+ if ((bsdtar->flags & OPTFLAG_INTERACTIVE) &&
!yes("add '%s'", archive_entry_pathname(entry)))
return (0);
/* Note: if user vetoes, we won't descend. */
- if (!bsdtar->option_no_subdirs && archive_read_disk_can_descend(a))
+ if (((bsdtar->flags & OPTFLAG_NO_SUBDIRS) == 0) &&
+ archive_read_disk_can_descend(a))
archive_read_disk_descend(a);
return (1);
@@ -1010,7 +1013,7 @@ report_write(struct bsdtar *bsdtar, struct archive *a,
uncomp = archive_filter_bytes(a, 0);
fprintf(stderr, "In: %d files, %s bytes;",
archive_file_count(a), tar_i64toa(uncomp));
- if (comp > uncomp)
+ if (comp >= uncomp)
compression = 0;
else
compression = (int)((uncomp - comp) * 100 / uncomp);
diff --git a/contrib/libarchive/test_utils/test_common.h b/contrib/libarchive/test_utils/test_common.h
new file mode 100644
index 000000000000..0078054178f0
--- /dev/null
+++ b/contrib/libarchive/test_utils/test_common.h
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2003-2017 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef TEST_COMMON_H
+#define TEST_COMMON_H
+
+/*
+ * The goal of this file (and the matching test.c) is to
+ * simplify the very repetitive test-*.c test programs.
+ */
+#if defined(HAVE_CONFIG_H)
+/* Most POSIX platforms use the 'configure' script to build config.h */
+#include "config.h"
+#elif defined(__FreeBSD__)
+/* Building as part of FreeBSD system requires a pre-built config.h. */
+#include "config_freebsd.h"
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+/* Win32 can't run the 'configure' script. */
+#include "config_windows.h"
+#else
+/* Warn if the library hasn't been (automatically or manually) configured. */
+#error Oops: No config.h and no pre-built configuration in test.h.
+#endif
+
+#include <sys/types.h> /* Windows requires this before sys/stat.h */
+#include <sys/stat.h>
+
+#if HAVE_DIRENT_H
+#include <dirent.h>
+#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 <ctype.h>
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <wchar.h>
+#ifdef HAVE_ACL_LIBACL_H
+#include <acl/libacl.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#include <sys/acl.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+/*
+ * System-specific tweaks. We really want to minimize these
+ * as much as possible, since they make it harder to understand
+ * the mainline code.
+ */
+
+/* Windows (including Visual Studio and MinGW but not Cygwin) */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#if !defined(__BORLANDC__)
+#undef chdir
+#define chdir _chdir
+#define strdup _strdup
+#endif
+#endif
+
+/* Visual Studio */
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#define snprintf sprintf_s
+#endif
+
+#if defined(__BORLANDC__)
+#pragma warn -8068 /* Constant out of range in comparison. */
+#endif
+
+/* Haiku OS and QNX */
+#if defined(__HAIKU__) || defined(__QNXNTO__)
+/* Haiku and QNX have 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
+#define O_BINARY 0
+#endif
+
+/*
+ * If this platform has <sys/acl.h>, acl_create(), acl_init(),
+ * acl_set_file(), and ACL_USER, we assume it has the rest of the
+ * POSIX.1e draft functions used in archive_read_extract.c.
+ */
+#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
+#if HAVE_DECL_ACL_USER
+#define HAVE_POSIX_ACL 1
+#elif HAVE_DECL_ACL_TYPE_EXTENDED
+#define HAVE_DARWIN_ACL 1
+#endif
+#if HAVE_DECL_ACL_TYPE_NFS4
+#define HAVE_FREEBSD_NFS4_ACL 1
+#endif
+#endif
+
+/*
+ * If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
+ * facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
+ */
+#if HAVE_SYS_ACL_H && HAVE_ACL && HAVE_FACL && HAVE_ACLENT_T && \
+ HAVE_DECL_GETACL && HAVE_DECL_GETACLCNT && HAVE_DECL_SETACL
+#define HAVE_SUN_ACL 1
+#if HAVE_ACE_T && HAVE_DECL_ACE_GETACL && HAVE_DECL_ACE_GETACLCNT && \
+ HAVE_DECL_ACE_SETACL
+#define HAVE_SUN_NFS4_ACL 1
+#endif
+#endif
+
+/* Define if platform supports NFSv4 ACLs */
+#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_NFS4_ACL || HAVE_DARWIN_ACL
+#define HAVE_NFS4_ACL 1
+#endif
+
+#define ARCHIVE_TEST_ACL_TYPE_POSIX1E 1
+#define ARCHIVE_TEST_ACL_TYPE_NFS4 2
+
+/*
+ * Redefine DEFINE_TEST for use in defining the test functions.
+ */
+#undef DEFINE_TEST
+#define DEFINE_TEST(name) void name(void); void name(void)
+
+/* An implementation of the standard assert() macro */
+#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 files have the same file flags */
+#define assertEqualFflags(patha, pathb) \
+ assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 0)
+/* Assert two integers are the same. Reports value of each one if not. */
+#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) \
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
+#define assertEqualUTF8String(v1,v2) \
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
+/* As above, but v1 and v2 are wchar_t * */
+#define assertEqualWString(v1,v2) \
+ assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
+/* As above, but raw blocks of bytes. */
+#define assertEqualMem(v1, v2, l) \
+ assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
+/* Assert that memory is full of a specified byte */
+#define assertMemoryFilledWith(v1, l, b) \
+ assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
+/* Assert two files are the same. */
+#define assertEqualFile(f1, f2) \
+ assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
+/* Assert that a file is empty. */
+#define assertEmptyFile(pathname) \
+ assertion_empty_file(__FILE__, __LINE__, (pathname))
+/* Assert that a file is not empty. */
+#define assertNonEmptyFile(pathname) \
+ assertion_non_empty_file(__FILE__, __LINE__, (pathname))
+#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(pathname) \
+ assertion_file_exists(__FILE__, __LINE__, pathname)
+/* Assert that a file exists. */
+#define assertFileNotExists(pathname) \
+ assertion_file_not_exists(__FILE__, __LINE__, pathname)
+/* Assert that file contents match a string. */
+#define assertFileContents(data, data_size, pathname) \
+ assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
+/* Verify that a file does not contain invalid strings */
+#define assertFileContainsNoInvalidStrings(pathname, strings) \
+ assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
+#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 assertFileMode(pathname, mode) \
+ assertion_file_mode(__FILE__, __LINE__, pathname, mode)
+#define assertTextFileContents(text, pathname) \
+ assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
+#define assertFileContainsLinesAnyOrder(pathname, lines) \
+ assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
+#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, -1, contents)
+#define assertMakeBinFile(path, mode, csize, contents) \
+ assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
+#define assertMakeHardlink(newfile, oldfile) \
+ assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
+#define assertMakeSymlink(newfile, linkto) \
+ assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
+#define assertSetNodump(path) \
+ assertion_set_nodump(__FILE__, __LINE__, path)
+#define assertUmask(mask) \
+ assertion_umask(__FILE__, __LINE__, mask)
+/* Assert that two files have unequal file flags */
+#define assertUnequalFflags(patha, pathb) \
+ assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 1)
+#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
+ assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
+#ifndef PROGRAM
+#define assertEntrySetAcls(entry, acls, count) \
+ assertion_entry_set_acls(__FILE__, __LINE__, entry, acls, count)
+#define assertEntryCompareAcls(entry, acls, count, type, mode) \
+ assertion_entry_compare_acls(__FILE__, __LINE__, entry, acls, count, type, mode)
+#endif
+
+/*
+ * This would be simple with C99 variadic macros, but I don't want to
+ * require that. Instead, I insert a function call before each
+ * skipping() call to pass the file and line information down. Crude,
+ * but effective.
+ */
+#define skipping \
+ skipping_setup(__FILE__, __LINE__);test_skipping
+
+/* Function declarations. These are defined in test_utility.c. */
+void failure(const char *fmt, ...);
+int assertion_assert(const char *, int, int, const char *, void *);
+int assertion_chdir(const char *, int, const char *);
+int assertion_compare_fflags(const char *, int, const char *, const char *,
+ int);
+int assertion_empty_file(const char *, int, const char *);
+int assertion_equal_file(const char *, int, 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_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
+int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
+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_contains_lines_any_order(const char *, int, const char *, const char **);
+int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
+int assertion_file_contents(const char *, int, const void *, int, const char *);
+int assertion_file_exists(const char *, int, const char *);
+int assertion_file_mode(const char *, int, const char *, int);
+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, 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, int, const void *);
+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, const char *);
+int assertion_set_nodump(const char *, int, const char *);
+int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
+int assertion_umask(const char *, int, int);
+int assertion_utimes(const char *, int, const char *, long, long, long, long );
+int assertion_version(const char*, int, const char *, const char *);
+
+void skipping_setup(const char *, int);
+void test_skipping(const char *fmt, ...);
+
+/* 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 "bzip2" program. */
+int canBzip2(void);
+
+/* Return true if this platform can run the "grzip" program. */
+int canGrzip(void);
+
+/* Return true if this platform can run the "gzip" program. */
+int canGzip(void);
+
+/* Return true if this platform can run the specified command. */
+int canRunCommand(const char *);
+
+/* Return true if this platform can run the "lrzip" program. */
+int canLrzip(void);
+
+/* Return true if this platform can run the "lz4" program. */
+int canLz4(void);
+
+/* Return true if this platform can run the "lzip" program. */
+int canLzip(void);
+
+/* Return true if this platform can run the "lzma" program. */
+int canLzma(void);
+
+/* Return true if this platform can run the "lzop" program. */
+int canLzop(void);
+
+/* Return true if this platform can run the "xz" program. */
+int canXz(void);
+
+/* Return true if this filesystem can handle nodump flags. */
+int canNodump(void);
+
+/* Set test ACLs */
+int setTestAcl(const char *path);
+
+/* Return true if the file has large i-node number(>0xffffffff). */
+int is_LargeInode(const char *);
+
+#if HAVE_SUN_ACL
+/* Fetch ACLs on Solaris using acl() or facl() */
+void *sunacl_get(int cmd, int *aclcnt, int fd, const char *path);
+#endif
+
+/* 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, ...);
+
+/* Dump block of bytes to a file. */
+void dumpfile(const char *filename, void *, size_t);
+
+/* Extracts named reference file to the current directory. */
+void extract_reference_file(const char *);
+/* Copies named reference file to the current directory. */
+void copy_reference_file(const char *);
+
+/* Extracts a list of files to the current directory.
+ * List must be NULL terminated.
+ */
+void extract_reference_files(const char **);
+
+/* Subtract umask from mode */
+mode_t umasked(mode_t expected_mode);
+
+/* Path to working directory for current test */
+extern const char *testworkdir;
+
+#ifndef PROGRAM
+/*
+ * Special interfaces for libarchive test harness.
+ */
+
+#include "archive.h"
+#include "archive_entry.h"
+
+/* ACL structure */
+struct archive_test_acl_t {
+ int type; /* Type of ACL */
+ int permset; /* Permissions for this class of users. */
+ int tag; /* Owner, User, Owning group, group, other, etc. */
+ int qual; /* GID or UID of user/group, depending on tag. */
+ const char *name; /* Name of user/group, depending on tag. */
+};
+
+/* Set ACLs */
+int assertion_entry_set_acls(const char *, int, struct archive_entry *,
+ struct archive_test_acl_t *, int);
+
+/* Compare ACLs */
+int assertion_entry_compare_acls(const char *, int, struct archive_entry *,
+ struct archive_test_acl_t *, int, int, int);
+
+/* Special customized read-from-memory interface. */
+int read_open_memory(struct archive *, const void *, size_t, size_t);
+/* _minimal version exercises a slightly different set of libarchive APIs. */
+int read_open_memory_minimal(struct archive *, const void *, size_t, size_t);
+/* _seek version produces a seekable file. */
+int read_open_memory_seek(struct archive *, const void *, size_t, size_t);
+
+/* Versions of above that accept an archive argument for additional info. */
+#define assertA(e) assertion_assert(__FILE__, __LINE__, (e), #e, (a))
+#define assertEqualIntA(a,v1,v2) \
+ assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a))
+#define assertEqualStringA(a,v1,v2) \
+ assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a), 0)
+
+#else /* defined(PROGRAM) */
+/*
+ * Special interfaces for program test harness.
+ */
+
+/* Pathname of exe to be tested. */
+extern const char *testprogfile;
+/* Name of exe to use in printf-formatted command strings. */
+/* On Windows, this includes leading/trailing quotes. */
+extern const char *testprog;
+
+void assertVersion(const char *prog, const char *base);
+
+#endif /* defined(PROGRAM) */
+
+#ifdef USE_DMALLOC
+#include <dmalloc.h>
+#endif
+
+#endif /* TEST_COMMON_H */
diff --git a/contrib/libarchive/cat/test/main.c b/contrib/libarchive/test_utils/test_main.c
index cdfdd9bd6d75..86ab5f1a489f 100644
--- a/contrib/libarchive/cat/test/main.c
+++ b/contrib/libarchive/test_utils/test_main.c
@@ -45,6 +45,9 @@
#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
#include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
#endif
+#ifdef HAVE_LINUX_FS_H
+#include <linux/fs.h>
+#endif
#include <limits.h>
#include <locale.h>
#ifdef HAVE_SIGNAL_H
@@ -53,22 +56,19 @@
#include <stdarg.h>
#include <time.h>
-/*
- * 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.
- */
-#define KNOWNREF "test_expand.Z.uu"
-#define ENVBASE "BSDCAT" /* Prefix for environment variables. */
-#define PROGRAM "bsdcat" /* Name of program being tested. */
-#define PROGRAM_ALIAS "cat" /* Generic alias for program */
-#undef LIBRARY /* Not testing a library. */
-#undef EXTRA_DUMP /* How to dump extra data */
-#undef EXTRA_ERRNO /* How to dump errno */
-/* How to generate extra version info. */
-#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "")
+/* ACL support */
+#ifdef HAVE_ACL_LIBACL_H
+#include <acl/libacl.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#include <sys/acl.h>
+#endif
+#if HAVE_DARWIN_ACL
+#include <membership.h>
+#endif
/*
*
@@ -217,6 +217,12 @@ invalid_parameter_handler(const wchar_t * expression,
unsigned int line, uintptr_t pReserved)
{
/* nop */
+ // Silence unused-parameter compiler warnings.
+ (void)expression;
+ (void)function;
+ (void)file;
+ (void)line;
+ (void)pReserved;
}
#endif
@@ -1413,6 +1419,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect
failure_start(file, line, "assertFileMode not yet implemented for Windows");
(void)mode; /* UNUSED */
(void)r; /* UNUSED */
+ (void)pathname; /* UNUSED */
+ (void)expected_mode; /* UNUSED */
#else
{
struct stat st;
@@ -1889,9 +1897,103 @@ assertion_utimes(const char *file, int line,
#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
}
+/* Compare file flags */
+int
+assertion_compare_fflags(const char *file, int line, const char *patha,
+ const char *pathb, int nomatch)
+{
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
+ struct stat sa, sb;
+
+ assertion_count(file, line);
+
+ if (stat(patha, &sa) < 0)
+ return (0);
+ if (stat(pathb, &sb) < 0)
+ return (0);
+ if (!nomatch && sa.st_flags != sb.st_flags) {
+ failure_start(file, line, "File flags should be identical: "
+ "%s=%#010x %s=%#010x", patha, sa.st_flags, pathb,
+ sb.st_flags);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (nomatch && sa.st_flags == sb.st_flags) {
+ failure_start(file, line, "File flags should be different: "
+ "%s=%#010x %s=%#010x", patha, sa.st_flags, pathb,
+ sb.st_flags);
+ failure_finish(NULL);
+ return (0);
+ }
+#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) && \
+ defined(FS_NODUMP_FL)) || \
+ (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
+ && defined(EXT2_NODUMP_FL))
+ int fd, r, flagsa, flagsb;
+
+ assertion_count(file, line);
+ fd = open(patha, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ failure_start(file, line, "Can't open %s\n", patha);
+ failure_finish(NULL);
+ return (0);
+ }
+ r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+ FS_IOC_GETFLAGS,
+#else
+ EXT2_IOC_GETFLAGS,
+#endif
+ &flagsa);
+ close(fd);
+ if (r < 0) {
+ failure_start(file, line, "Can't get flags %s\n", patha);
+ failure_finish(NULL);
+ return (0);
+ }
+ fd = open(pathb, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ failure_start(file, line, "Can't open %s\n", pathb);
+ failure_finish(NULL);
+ return (0);
+ }
+ r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+ FS_IOC_GETFLAGS,
+#else
+ EXT2_IOC_GETFLAGS,
+#endif
+ &flagsb);
+ close(fd);
+ if (r < 0) {
+ failure_start(file, line, "Can't get flags %s\n", pathb);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (!nomatch && flagsa != flagsb) {
+ failure_start(file, line, "File flags should be identical: "
+ "%s=%#010x %s=%#010x", patha, flagsa, pathb, flagsb);
+ failure_finish(NULL);
+ return (0);
+ }
+ if (nomatch && flagsa == flagsb) {
+ failure_start(file, line, "File flags should be different: "
+ "%s=%#010x %s=%#010x", patha, flagsa, pathb, flagsb);
+ failure_finish(NULL);
+ return (0);
+ }
+#else
+ (void)patha; /* UNUSED */
+ (void)pathb; /* UNUSED */
+ (void)nomatch; /* UNUSED */
+ assertion_count(file, line);
+#endif
+ return (1);
+}
+
/* Set nodump, report failures. */
int
-assertion_nodump(const char *file, int line, const char *pathname)
+assertion_set_nodump(const char *file, int line, const char *pathname)
{
#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
int r;
@@ -1903,8 +2005,10 @@ assertion_nodump(const char *file, int line, const char *pathname)
failure_finish(NULL);
return (0);
}
-#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
- && defined(EXT2_NODUMP_FL)
+#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) && \
+ defined(FS_NODUMP_FL)) || \
+ (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
+ && defined(EXT2_NODUMP_FL))
int fd, r, flags;
assertion_count(file, line);
@@ -1914,14 +2018,31 @@ assertion_nodump(const char *file, int line, const char *pathname)
failure_finish(NULL);
return (0);
}
- r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+ r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+ FS_IOC_GETFLAGS,
+#else
+ EXT2_IOC_GETFLAGS,
+#endif
+ &flags);
if (r < 0) {
failure_start(file, line, "Can't get flags %s\n", pathname);
failure_finish(NULL);
return (0);
}
+#ifdef FS_NODUMP_FL
+ flags |= FS_NODUMP_FL;
+#else
flags |= EXT2_NODUMP_FL;
- r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+#endif
+
+ r = ioctl(fd,
+#ifdef FS_IOC_SETFLAGS
+ FS_IOC_SETFLAGS,
+#else
+ EXT2_IOC_SETFLAGS,
+#endif
+ &flags);
if (r < 0) {
failure_start(file, line, "Can't set nodump %s\n", pathname);
failure_finish(NULL);
@@ -1935,6 +2056,117 @@ assertion_nodump(const char *file, int line, const char *pathname)
return (1);
}
+#ifdef PROGRAM
+static void assert_version_id(char **qq, size_t *ss)
+{
+ char *q = *qq;
+ size_t s = *ss;
+
+ /* Version number is a series of digits and periods. */
+ while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
+ ++q;
+ --s;
+ }
+
+ if (q[0] == 'd' && q[1] == 'e' && q[2] == 'v') {
+ q += 3;
+ s -= 3;
+ }
+
+ /* Skip a single trailing a,b,c, or d. */
+ if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
+ ++q;
+
+ /* Version number terminated by space. */
+ failure("No space after version: ``%s''", q);
+ assert(s > 1);
+ failure("No space after version: ``%s''", q);
+ assert(*q == ' ');
+
+ ++q; --s;
+
+ *qq = q;
+ *ss = s;
+}
+
+
+/*
+ * Check program version
+ */
+void assertVersion(const char *prog, const char *base)
+{
+ int r;
+ char *p, *q;
+ size_t s;
+ unsigned int prog_len = strlen(base);
+
+ r = systemf("%s --version >version.stdout 2>version.stderr", prog);
+ if (r != 0)
+ r = systemf("%s -W version >version.stdout 2>version.stderr",
+ prog);
+
+ failure("Unable to run either %s --version or %s -W version",
+ prog, prog);
+ if (!assert(r == 0))
+ return;
+
+ /* --version should generate nothing to stdout. */
+ assertEmptyFile("version.stderr");
+
+ /* Verify format of version message. */
+ q = p = slurpfile(&s, "version.stdout");
+
+ /* Version message should start with name of program, then space. */
+ assert(s > prog_len + 1);
+
+ failure("Version must start with '%s': ``%s''", base, p);
+ if (!assertEqualMem(q, base, prog_len)) {
+ free(p);
+ return;
+ }
+
+ q += prog_len; s -= prog_len;
+
+ assert(*q == ' ');
+ q++; s--;
+
+ assert_version_id(&q, &s);
+
+ /* Separator. */
+ failure("No `-' between program name and versions: ``%s''", p);
+ assertEqualMem(q, "- ", 2);
+ q += 2; s -= 2;
+
+ failure("Not long enough for libarchive version: ``%s''", p);
+ assert(s > 11);
+
+ failure("Libarchive version must start with `libarchive': ``%s''", p);
+ assertEqualMem(q, "libarchive ", 11);
+
+ q += 11; s -= 11;
+
+ assert_version_id(&q, &s);
+
+ /* Skip arbitrary third-party version numbers. */
+ while (s > 0 && (*q == ' ' || *q == '-' || *q == '/' || *q == '.' ||
+ isalnum(*q))) {
+ ++q;
+ --s;
+ }
+
+ /* All terminated by end-of-line. */
+ assert(s >= 1);
+
+ /* Skip an optional CR character (e.g., Windows) */
+ failure("Version output must end with \\n or \\r\\n");
+
+ if (*q == '\r') { ++q; --s; }
+ assertEqualMem(q, "\n", 1);
+
+ free(p);
+}
+#endif /* PROGRAM */
+
/*
*
* UTILITIES for use by tests.
@@ -2132,11 +2364,10 @@ canXz(void)
/*
* Can this filesystem handle nodump flags.
*/
-#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
-
int
canNodump(void)
{
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
const char *path = "cannodumptest";
struct stat sb;
@@ -2147,15 +2378,10 @@ canNodump(void)
return (0);
if (sb.st_flags & UF_NODUMP)
return (1);
- return (0);
-}
-
-#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
- && defined(EXT2_NODUMP_FL)
-
-int
-canNodump(void)
-{
+#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) \
+ && defined(FS_NODUMP_FL)) || \
+ (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
+ && defined(EXT2_NODUMP_FL))
const char *path = "cannodumptest";
int fd, r, flags;
@@ -2163,35 +2389,273 @@ canNodump(void)
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return (0);
- r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+ r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+ FS_IOC_GETFLAGS,
+#else
+ EXT2_IOC_GETFLAGS,
+#endif
+ &flags);
if (r < 0)
return (0);
+#ifdef FS_NODUMP_FL
+ flags |= FS_NODUMP_FL;
+#else
flags |= EXT2_NODUMP_FL;
- r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
+#endif
+ r = ioctl(fd,
+#ifdef FS_IOC_SETFLAGS
+ FS_IOC_SETFLAGS,
+#else
+ EXT2_IOC_SETFLAGS,
+#endif
+ &flags);
if (r < 0)
return (0);
close(fd);
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return (0);
- r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
+ r = ioctl(fd,
+#ifdef FS_IOC_GETFLAGS
+ FS_IOC_GETFLAGS,
+#else
+ EXT2_IOC_GETFLAGS,
+#endif
+ &flags);
if (r < 0)
return (0);
close(fd);
+#ifdef FS_NODUMP_FL
+ if (flags & FS_NODUMP_FL)
+#else
if (flags & EXT2_NODUMP_FL)
+#endif
return (1);
+#endif
return (0);
}
-#else
-
-int
-canNodump()
+#if HAVE_SUN_ACL
+/* Fetch ACLs on Solaris using acl() or facl() */
+void *
+sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
{
- return (0);
+ int cnt, cntcmd;
+ size_t size;
+ void *aclp;
+
+ if (cmd == GETACL) {
+ cntcmd = GETACLCNT;
+ size = sizeof(aclent_t);
+ }
+#if HAVE_SUN_NFS4_ACL
+ else if (cmd == ACE_GETACL) {
+ cntcmd = ACE_GETACLCNT;
+ size = sizeof(ace_t);
+ }
+#endif
+ else {
+ errno = EINVAL;
+ *aclcnt = -1;
+ return (NULL);
+ }
+
+ aclp = NULL;
+ cnt = -2;
+ while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
+ if (path != NULL)
+ cnt = acl(path, cntcmd, 0, NULL);
+ else
+ cnt = facl(fd, cntcmd, 0, NULL);
+
+ if (cnt > 0) {
+ if (aclp == NULL)
+ aclp = malloc(cnt * size);
+ else
+ aclp = realloc(NULL, cnt * size);
+ if (aclp != NULL) {
+ if (path != NULL)
+ cnt = acl(path, cmd, cnt, aclp);
+ else
+ cnt = facl(fd, cmd, cnt, aclp);
+ }
+ } else {
+ if (aclp != NULL) {
+ free(aclp);
+ aclp = NULL;
+ }
+ break;
+ }
+ }
+
+ *aclcnt = cnt;
+ return (aclp);
}
+#endif /* HAVE_SUN_ACL */
+
+/*
+ * Set test ACLs on a path
+ * Return values:
+ * 0: error setting ACLs
+ * ARCHIVE_TEST_ACL_TYPE_POSIX1E: POSIX.1E ACLs have been set
+ * ARCHIVE_TEST_ACL_TYPE_NFS4: NFSv4 or extended ACLs have been set
+ */
+int
+setTestAcl(const char *path)
+{
+#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
+ int r = 1;
+#if !HAVE_SUN_ACL
+ acl_t acl;
+#endif
+#if HAVE_POSIX_ACL /* Linux, FreeBSD POSIX.1e */
+ const char *acltext_posix1e = "user:1:rw-,"
+ "group:15:r-x,"
+ "user::rwx,"
+ "group::rwx,"
+ "other::r-x,"
+ "mask::rwx";
+#elif HAVE_SUN_ACL /* Solaris POSIX.1e */
+ aclent_t aclp_posix1e[] = {
+ { USER_OBJ, -1, 4 | 2 | 1 },
+ { USER, 1, 4 | 2 },
+ { GROUP_OBJ, -1, 4 | 2 | 1 },
+ { GROUP, 15, 4 | 1 },
+ { CLASS_OBJ, -1, 4 | 2 | 1 },
+ { OTHER_OBJ, -1, 4 | 2 | 1 }
+ };
+#endif
+#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFS4 */
+ const char *acltext_nfs4 = "user:1:rwpaRcs::allow:1,"
+ "group:15:rxaRcs::allow:15,"
+ "owner@:rwpxaARWcCos::allow,"
+ "group@:rwpxaRcs::allow,"
+ "everyone@:rxaRcs::allow";
+#elif HAVE_SUN_NFS4_ACL /* Solaris NFS4 */
+ ace_t aclp_nfs4[] = {
+ { 1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA |
+ ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS | ACE_READ_ACL |
+ ACE_SYNCHRONIZE, 0, ACE_ACCESS_ALLOWED_ACE_TYPE },
+ { 15, ACE_READ_DATA | ACE_EXECUTE | ACE_READ_ATTRIBUTES |
+ ACE_READ_NAMED_ATTRS | ACE_READ_ACL | ACE_SYNCHRONIZE,
+ ACE_IDENTIFIER_GROUP, ACE_ACCESS_ALLOWED_ACE_TYPE },
+ { -1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA |
+ ACE_EXECUTE | ACE_READ_ATTRIBUTES | ACE_WRITE_ATTRIBUTES |
+ ACE_READ_NAMED_ATTRS | ACE_WRITE_NAMED_ATTRS |
+ ACE_READ_ACL | ACE_WRITE_ACL | ACE_WRITE_OWNER | ACE_SYNCHRONIZE,
+ ACE_OWNER, ACE_ACCESS_ALLOWED_ACE_TYPE },
+ { -1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA |
+ ACE_EXECUTE | ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
+ ACE_READ_ACL | ACE_SYNCHRONIZE, ACE_GROUP | ACE_IDENTIFIER_GROUP,
+ ACE_ACCESS_ALLOWED_ACE_TYPE },
+ { -1, ACE_READ_DATA | ACE_EXECUTE | ACE_READ_ATTRIBUTES |
+ ACE_READ_NAMED_ATTRS | ACE_READ_ACL | ACE_SYNCHRONIZE,
+ ACE_EVERYONE, ACE_ACCESS_ALLOWED_ACE_TYPE }
+ };
+#elif HAVE_DARWIN_ACL /* Mac OS X */
+ acl_entry_t aclent;
+ acl_permset_t permset;
+ const uid_t uid = 1;
+ uuid_t uuid;
+ int i;
+ const acl_perm_t acl_perms[] = {
+ ACL_READ_DATA,
+ ACL_WRITE_DATA,
+ ACL_APPEND_DATA,
+ ACL_EXECUTE,
+ ACL_READ_ATTRIBUTES,
+ ACL_READ_EXTATTRIBUTES,
+ ACL_READ_SECURITY,
+#if HAVE_DECL_ACL_SYNCHRONIZE
+ ACL_SYNCHRONIZE
+#endif
+ };
+#endif /* HAVE_DARWIN_ACL */
+
+#if HAVE_FREEBSD_NFS4_ACL
+ acl = acl_from_text(acltext_nfs4);
+ failure("acl_from_text() error: %s", strerror(errno));
+ if (assert(acl != NULL) == 0)
+ return (0);
+#elif HAVE_DARWIN_ACL
+ acl = acl_init(1);
+ failure("acl_init() error: %s", strerror(errno));
+ if (assert(acl != NULL) == 0)
+ return (0);
+ r = acl_create_entry(&acl, &aclent);
+ failure("acl_create_entry() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ r = acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW);
+ failure("acl_set_tag_type() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ r = acl_get_permset(aclent, &permset);
+ failure("acl_get_permset() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ for (i = 0; i < (int)(sizeof(acl_perms) / sizeof(acl_perms[0])); i++) {
+ r = acl_add_perm(permset, acl_perms[i]);
+ failure("acl_add_perm() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ }
+ r = acl_set_permset(aclent, permset);
+ failure("acl_set_permset() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ r = mbr_identifier_to_uuid(ID_TYPE_UID, &uid, sizeof(uid_t), uuid);
+ failure("mbr_identifier_to_uuid() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ r = acl_set_qualifier(aclent, uuid);
+ failure("acl_set_qualifier() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+#endif /* HAVE_DARWIN_ACL */
+
+#if HAVE_NFS4_ACL
+#if HAVE_FREEBSD_NFS4_ACL
+ r = acl_set_file(path, ACL_TYPE_NFS4, acl);
+ acl_free(acl);
+#elif HAVE_SUN_NFS4_ACL
+ r = acl(path, ACE_SETACL,
+ (int)(sizeof(aclp_nfs4)/sizeof(aclp_nfs4[0])), aclp_nfs4);
+#elif HAVE_DARWIN_ACL
+ r = acl_set_file(path, ACL_TYPE_EXTENDED, acl);
+ acl_free(acl);
+#endif
+ if (r == 0)
+ return (ARCHIVE_TEST_ACL_TYPE_NFS4);
+#endif /* HAVE_NFS4_ACL */
+
+#if HAVE_POSIX_ACL || HAVE_SUN_ACL
+#if HAVE_POSIX_ACL
+ acl = acl_from_text(acltext_posix1e);
+ failure("acl_from_text() error: %s", strerror(errno));
+ if (assert(acl != NULL) == 0)
+ return (0);
+ r = acl_set_file(path, ACL_TYPE_ACCESS, acl);
+ acl_free(acl);
+#elif HAVE_SUN_ACL
+ r = acl(path, SETACL,
+ (int)(sizeof(aclp_posix1e)/sizeof(aclp_posix1e[0])), aclp_posix1e);
#endif
+ if (r == 0)
+ return (ARCHIVE_TEST_ACL_TYPE_POSIX1E);
+ else
+ return (0);
+#endif /* HAVE_POSIX_ACL || HAVE_SUN_ACL */
+#if HAVE_DARWIN_ACL
+testacl_free:
+ acl_free(acl);
+#endif
+#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
+ (void)path; /* UNUSED */
+ return (0);
+}
/*
* Sleep as needed; useful for verifying disk timestamp changes by
@@ -2422,6 +2886,190 @@ extract_reference_files(const char **names)
extract_reference_file(*names++);
}
+#ifndef PROGRAM
+/* Set ACLs */
+int
+assertion_entry_set_acls(const char *file, int line, struct archive_entry *ae,
+ struct archive_test_acl_t *acls, int n)
+{
+ int i, r, ret;
+
+ assertion_count(file, line);
+
+ ret = 0;
+ archive_entry_acl_clear(ae);
+ for (i = 0; i < n; i++) {
+ r = archive_entry_acl_add_entry(ae,
+ acls[i].type, acls[i].permset, acls[i].tag,
+ acls[i].qual, acls[i].name);
+ if (r != 0) {
+ ret = 1;
+ failure_start(file, line, "type=%#010x, ",
+ "permset=%#010x, tag=%d, qual=%d name=%s",
+ acls[i].type, acls[i].permset, acls[i].tag,
+ acls[i].qual, acls[i].name);
+ failure_finish(NULL);
+ }
+ }
+
+ return (ret);
+}
+
+static int
+archive_test_acl_match(struct archive_test_acl_t *acl, int type, int permset,
+ int tag, int qual, const char *name)
+{
+ if (type != acl->type)
+ return (0);
+ if (permset != acl->permset)
+ return (0);
+ if (tag != acl->tag)
+ return (0);
+ if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
+ return (1);
+ if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ)
+ return (1);
+ if (tag == ARCHIVE_ENTRY_ACL_EVERYONE)
+ return (1);
+ if (tag == ARCHIVE_ENTRY_ACL_OTHER)
+ return (1);
+ if (qual != acl->qual)
+ return (0);
+ if (name == NULL) {
+ if (acl->name == NULL || acl->name[0] == '\0')
+ return (1);
+ return (0);
+ }
+ if (acl->name == NULL) {
+ if (name[0] == '\0')
+ return (1);
+ return (0);
+ }
+ return (0 == strcmp(name, acl->name));
+}
+
+/* Compare ACLs */
+int
+assertion_entry_compare_acls(const char *file, int line,
+ struct archive_entry *ae, struct archive_test_acl_t *acls, int cnt,
+ int want_type, int mode)
+{
+ int *marker;
+ int i, r, n, ret;
+ int type, permset, tag, qual;
+ int matched;
+ const char *name;
+
+ assertion_count(file, line);
+
+ ret = 0;
+ n = 0;
+ marker = malloc(sizeof(marker[0]) * cnt);
+
+ for (i = 0; i < cnt; i++) {
+ if ((acls[i].type & want_type) != 0) {
+ marker[n] = i;
+ n++;
+ }
+ }
+
+ if (n == 0) {
+ failure_start(file, line, "No ACL's to compare, type mask: %d",
+ want_type);
+ return (1);
+ }
+
+ while (0 == (r = archive_entry_acl_next(ae, want_type,
+ &type, &permset, &tag, &qual, &name))) {
+ for (i = 0, matched = 0; i < n && !matched; i++) {
+ if (archive_test_acl_match(&acls[marker[i]], type,
+ permset, tag, qual, name)) {
+ /* We found a match; remove it. */
+ marker[i] = marker[n - 1];
+ n--;
+ matched = 1;
+ }
+ }
+ if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+ && tag == ARCHIVE_ENTRY_ACL_USER_OBJ) {
+ if (!matched) {
+ failure_start(file, line, "No match for "
+ "user_obj perm");
+ failure_finish(NULL);
+ ret = 1;
+ }
+ if ((permset << 6) != (mode & 0700)) {
+ failure_start(file, line, "USER_OBJ permset "
+ "(%02o) != user mode (%02o)", permset,
+ 07 & (mode >> 6));
+ failure_finish(NULL);
+ ret = 1;
+ }
+ } else if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+ && tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ) {
+ if (!matched) {
+ failure_start(file, line, "No match for "
+ "group_obj perm");
+ failure_finish(NULL);
+ ret = 1;
+ }
+ if ((permset << 3) != (mode & 0070)) {
+ failure_start(file, line, "GROUP_OBJ permset "
+ "(%02o) != group mode (%02o)", permset,
+ 07 & (mode >> 3));
+ failure_finish(NULL);
+ ret = 1;
+ }
+ } else if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+ && tag == ARCHIVE_ENTRY_ACL_OTHER) {
+ if (!matched) {
+ failure_start(file, line, "No match for "
+ "other perm");
+ failure_finish(NULL);
+ ret = 1;
+ }
+ if ((permset << 0) != (mode & 0007)) {
+ failure_start(file, line, "OTHER permset "
+ "(%02o) != other mode (%02o)", permset,
+ mode & 07);
+ failure_finish(NULL);
+ ret = 1;
+ }
+ } else if (matched != 1) {
+ failure_start(file, line, "Could not find match for "
+ "ACL (type=%#010x,permset=%#010x,tag=%d,qual=%d,"
+ "name=``%s'')", type, permset, tag, qual, name);
+ failure_finish(NULL);
+ ret = 1;
+ }
+ }
+ if (r != ARCHIVE_EOF) {
+ failure_start(file, line, "Should not exit before EOF");
+ failure_finish(NULL);
+ ret = 1;
+ }
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0 &&
+ (mode_t)(mode & 0777) != (archive_entry_mode(ae) & 0777)) {
+ failure_start(file, line, "Mode (%02o) and entry mode (%02o) "
+ "mismatch", mode, archive_entry_mode(ae));
+ failure_finish(NULL);
+ ret = 1;
+ }
+ if (n != 0) {
+ failure_start(file, line, "Could not find match for ACL "
+ "(type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s'')",
+ acls[marker[0]].type, acls[marker[0]].permset,
+ acls[marker[0]].tag, acls[marker[0]].qual,
+ acls[marker[0]].name);
+ failure_finish(NULL);
+ ret = 1;
+ /* Number of ACLs not matched should == 0 */
+ }
+ free(marker);
+ return (ret);
+}
+#endif /* !defined(PROGRAM) */
+
/*
*
* TEST management