From b95297b3935c0225e8af302c9984c9719013d8c4 Mon Sep 17 00:00:00 2001 From: mm Date: Thu, 16 Mar 2017 23:08:18 +0000 Subject: [PATCH] MFC r314571: 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) git-svn-id: svn://svn.freebsd.org/base/stable/10@315433 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- contrib/libarchive/NEWS | 8 + contrib/libarchive/cat/test/test.h | 336 +- contrib/libarchive/cat/test/test_version.c | 67 +- contrib/libarchive/cpio/cpio.c | 10 +- contrib/libarchive/cpio/test/main.c | 3073 ----------------- contrib/libarchive/cpio/test/test.h | 338 +- .../cpio/test/test_option_version.c | 88 +- contrib/libarchive/libarchive/archive.h | 8 +- .../libarchive/archive_check_magic.c | 2 +- .../libarchive/archive_digest_private.h | 1 + contrib/libarchive/libarchive/archive_entry.c | 130 +- contrib/libarchive/libarchive/archive_entry.h | 27 +- .../libarchive/libarchive/archive_entry_acl.3 | 2 +- .../libarchive/archive_entry_paths.3 | 12 +- .../libarchive/archive_entry_perms.3 | 4 +- contrib/libarchive/libarchive/archive_hmac.c | 4 + .../libarchive/libarchive/archive_platform.h | 18 +- .../libarchive/libarchive/archive_read_disk.3 | 22 +- .../archive_read_disk_entry_from_file.c | 447 ++- .../libarchive/archive_read_disk_posix.c | 64 +- .../libarchive/archive_read_disk_private.h | 12 +- .../libarchive/archive_read_format.3 | 6 +- .../libarchive/libarchive/archive_read_open.3 | 2 +- .../archive_read_support_format_tar.c | 5 +- .../archive_read_support_format_warc.c | 23 +- .../libarchive/archive_write_data.3 | 24 +- .../libarchive/archive_write_disk.3 | 79 +- .../libarchive/archive_write_disk_acl.c | 181 +- .../libarchive/archive_write_disk_posix.c | 97 +- .../libarchive/archive_write_finish_entry.3 | 5 +- .../libarchive/archive_write_format.3 | 1 - .../archive_write_set_format_iso9660.c | 6 +- contrib/libarchive/libarchive/test/test.h | 390 +-- .../libarchive/test/test_acl_nfs4.c | 12 +- .../libarchive/libarchive/test/test_acl_pax.c | 25 +- .../libarchive/test/test_acl_platform_nfs4.c | 175 +- .../test/test_acl_platform_posix1e.c | 189 +- .../libarchive/test/test_acl_posix1e.c | 15 +- .../libarchive/test/test_acl_text.c | 28 +- .../test/test_archive_api_feature.c | 8 +- .../test/test_compat_solaris_tar_acl.c | 10 +- .../libarchive/test/test_compat_star_acl.c | 12 +- .../libarchive/libarchive/test/test_fuzz.c | 3 +- .../libarchive/test/test_read_disk.c | 6 +- .../test_read_disk_directory_traversals.c | 14 +- contrib/libarchive/tar/bsdtar.1 | 103 +- contrib/libarchive/tar/bsdtar.c | 123 +- contrib/libarchive/tar/bsdtar.h | 59 +- contrib/libarchive/tar/cmdline.c | 12 +- contrib/libarchive/tar/read.c | 19 +- contrib/libarchive/tar/test/main.c | 3072 ---------------- contrib/libarchive/tar/test/test.h | 338 +- .../libarchive/tar/test/test_option_acls.c | 471 +++ .../libarchive/tar/test/test_option_fflags.c | 106 + .../libarchive/tar/test/test_option_nodump.c | 2 +- contrib/libarchive/tar/test/test_version.c | 73 +- contrib/libarchive/tar/util.c | 2 +- contrib/libarchive/tar/write.c | 21 +- contrib/libarchive/test_utils/test_common.h | 467 +++ .../test/main.c => test_utils/test_main.c} | 728 +++- lib/libarchive/config_freebsd.h | 4 +- lib/libarchive/tests/Makefile | 7 +- usr.bin/bsdcat/Makefile | 2 +- usr.bin/bsdcat/tests/Makefile | 10 +- usr.bin/cpio/Makefile | 2 +- usr.bin/cpio/tests/Makefile | 10 +- usr.bin/tar/Makefile | 2 +- usr.bin/tar/tests/Makefile | 11 +- 68 files changed, 2996 insertions(+), 8637 deletions(-) delete mode 100644 contrib/libarchive/cpio/test/main.c delete mode 100644 contrib/libarchive/tar/test/main.c create mode 100644 contrib/libarchive/tar/test/test_option_acls.c create mode 100644 contrib/libarchive/tar/test/test_option_fflags.c create mode 100644 contrib/libarchive/test_utils/test_common.h rename contrib/libarchive/{cat/test/main.c => test_utils/test_main.c} (81%) diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS index 7b5c31f75..281c1768c 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 c002a2c27..350bcad63 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 /* Windows requires this before sys/stat.h */ -#include - -#if HAVE_DIRENT_H -#include -#endif -#ifdef HAVE_DIRECT_H -#include -#define dirent direct -#endif -#include -#include -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#ifdef HAVE_WINDOWS_H -#include -#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 -#endif - -/* Get a real definition for __FBSDID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#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 -#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 e587b3440..51a4fd4d9 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 30c9ad348..7f1b11973 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 d7c01999f..000000000 --- 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 -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif -#include -#ifdef HAVE_ICONV_H -#include -#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 /* for Linux file flags */ -#endif -#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) -#include /* Linux file flags, broken on Cygwin */ -#endif -#include -#include -#ifdef HAVE_SIGNAL_H -#include -#endif -#include -#include - -/* - * 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 -#include -#include -#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 -#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] ...\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 to executable to be tested.\n"); - printf(" Default: path taken from " ENVBASE " environment variable.\n"); -#endif - printf(" -q Quiet.\n"); - printf(" -r 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 c002a2c27..1dadf6889 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 /* Windows requires this before sys/stat.h */ -#include - -#if HAVE_DIRENT_H -#include -#endif -#ifdef HAVE_DIRECT_H -#include -#define dirent direct -#endif -#include -#include -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#ifdef HAVE_WINDOWS_H -#include -#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 -#endif - -/* Get a real definition for __FBSDID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#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 -#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 ac58cefda..505db2712 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 5c4118b1a..586c73ad6 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 #include /* 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 10e8c3ada..89e631442 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 b58ffb348..b4fd6ca22 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 #include typedef struct { int valid; diff --git a/contrib/libarchive/libarchive/archive_entry.c b/contrib/libarchive/libarchive/archive_entry.c index 556c402af..d0f2e75ca 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 40d6afbf1..97758e223 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 /* 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 c5115f727..7ede7b76b 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 fd22cf7e2..f647212a9 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 340c5ea72..aae3648bb 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 1e0ae283b..f29965577 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 31383db68..7d99d20a1 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 , acl_get(), facl_get(), acl_set(), + * If this platform has , 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 2a5c1305e..55e4bbbd8 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 ef6875fc8..06d051a20 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 b89370421..6961ae6a4 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 986701010..3f55133ec 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 53b9a7e0e..91c5d2cfd 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 4d8272cac..02494560d 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 446d005ff..fa63d2f4f 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 5e22438d2..e8753853f 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 0cdd25f1f..9c16cd9b4 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 ba6c9706e..4891b8572 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 144ab7e72..643f3c3a0 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 a799524d4..f6c24d128 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,11 +3628,18 @@ 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 @@ -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 c5ef69ebc..dc1b94b82 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 d4ba6abff..aaafb0a86 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 4e910979e..c0ca435d1 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 dc3f59048..fd679f5f2 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 /* Windows requires this before sys/stat.h */ -#include - -#if HAVE_DIRENT_H -#include -#endif -#ifdef HAVE_DIRECT_H -#include -#define dirent direct -#endif -#include -#include -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#ifdef HAVE_WINDOWS_H -#include -#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 -#endif - -/* Get a real definition for __FBSDID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#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 , 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 , 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 -#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 f4e66f522..fdc019151 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 8dfa0e031..8566f55a5 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 01c1dc589..c8854082a 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 1d55a33eb..0224a57f1 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 01167dae2..fa2628dbe 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 f3d2b10ed..80728932c 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 f2925b573..e4239feba 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 3d063c1db..815977290 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 f2a78b2d2..824710194 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 e896f607e..61c2dfc0f 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 4cc2eb4c3..a57da1a53 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 c9aca8fa9..705b3d989 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 9eadaaf88..3e7abe884 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 4db3340e9..d15214065 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 3c4d629fa..2bf42e8b2 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 c87741cc5..e36c545b3 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 902ba7b24..bf7d55b81 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 4f498b6ac..000000000 --- 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 -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif -#include -#ifdef HAVE_ICONV_H -#include -#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 /* for Linux file flags */ -#endif -#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) -#include /* Linux file flags, broken on Cygwin */ -#endif -#include -#include -#ifdef HAVE_SIGNAL_H -#include -#endif -#include -#include - -/* - * 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 -#include -#include -#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 -#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] ...\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 to executable to be tested.\n"); - printf(" Default: path taken from " ENVBASE " environment variable.\n"); -#endif - printf(" -q Quiet.\n"); - printf(" -r 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 c002a2c27..1e1bee807 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 /* Windows requires this before sys/stat.h */ -#include - -#if HAVE_DIRENT_H -#include -#endif -#ifdef HAVE_DIRECT_H -#include -#define dirent direct -#endif -#include -#include -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#ifdef HAVE_WINDOWS_H -#include -#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 -#endif - -/* Get a real definition for __FBSDID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#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 -#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 000000000..5c3fbfd15 --- /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 000000000..77a4e3e19 --- /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 768f64a6d..815b08ed9 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 93e826d40..1b896c0c4 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 84dc53f7d..7b52e4081 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 4265d1411..4c9bb65c8 100644 --- a/contrib/libarchive/tar/write.c +++ b/contrib/libarchive/tar/write.c @@ -583,7 +583,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) 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 000000000..007805417 --- /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 /* Windows requires this before sys/stat.h */ +#include + +#if HAVE_DIRENT_H +#include +#endif +#ifdef HAVE_DIRECT_H +#include +#define dirent direct +#endif +#include +#include +#ifdef HAVE_IO_H +#include +#endif +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#ifdef HAVE_ACL_LIBACL_H +#include +#endif +#ifdef HAVE_SYS_ACL_H +#include +#endif +#ifdef HAVE_WINDOWS_H +#include +#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 +#endif + +/* Get a real definition for __FBSDID if we can */ +#if HAVE_SYS_CDEFS_H +#include +#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 , 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 , 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 +#endif + +#endif /* TEST_COMMON_H */ diff --git a/contrib/libarchive/cat/test/main.c b/contrib/libarchive/test_utils/test_main.c similarity index 81% rename from contrib/libarchive/cat/test/main.c rename to contrib/libarchive/test_utils/test_main.c index cdfdd9bd6..86ab5f1a4 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 /* Linux file flags, broken on Cygwin */ #endif +#ifdef HAVE_LINUX_FS_H +#include +#endif #include #include #ifdef HAVE_SIGNAL_H @@ -53,22 +56,19 @@ #include #include -/* - * 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 +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_ACL_H +#include +#endif +#if HAVE_DARWIN_ACL +#include +#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 diff --git a/lib/libarchive/config_freebsd.h b/lib/libarchive/config_freebsd.h index 24e2d753e..fe16eb2cb 100644 --- a/lib/libarchive/config_freebsd.h +++ b/lib/libarchive/config_freebsd.h @@ -38,9 +38,9 @@ #define HAVE_ACL_SET_FD_NP 1 #define HAVE_ACL_SET_FILE 1 #define HAVE_ACL_SET_LINK_NP 1 -#define HAVE_ACL_USER 1 -#define HAVE_ACL_TYPE_NFS4 1 #define HAVE_ARC4RANDOM_BUF 1 +#define HAVE_DECL_ACL_USER 1 +#define HAVE_DECL_ACL_TYPE_NFS4 1 #define HAVE_EXTATTR_GET_FILE 1 #define HAVE_EXTATTR_LIST_FILE 1 #define HAVE_EXTATTR_SET_FD 1 diff --git a/lib/libarchive/tests/Makefile b/lib/libarchive/tests/Makefile index eed7b9700..880e67628 100644 --- a/lib/libarchive/tests/Makefile +++ b/lib/libarchive/tests/Makefile @@ -12,7 +12,8 @@ BINDIR= ${TESTSDIR} PROGS+= libarchive_test CFLAGS+= -I${.CURDIR} -I${.CURDIR:H} -I${.OBJDIR} -CFLAGS+= -I${LIBARCHIVEDIR}/libarchive -I${LIBARCHIVEDIR}/test_utils +CFLAGS+= -I${LIBARCHIVEDIR}/libarchive -I${LIBARCHIVEDIR}/libarchive/test +CFLAGS+= -I${LIBARCHIVEDIR}/test_utils CFLAGS+= -DHAVE_LIBLZMA=1 -DHAVE_LZMA_H=1 # Uncomment to link against dmalloc @@ -300,7 +301,6 @@ BROKEN_TESTS+= test_fuzz_rar # Build the test program. SRCS.libarchive_test= \ ${TESTS_SRCS} \ - main.c \ read_open_memory.c \ list.h @@ -308,7 +308,8 @@ DPADD.libarchive_test= ${LIBARCHIVE} LDADD.libarchive_test= -larchive .PATH: ${LIBARCHIVEDIR}/test_utils -SRCS.libarchive_test+= test_utils.c +SRCS.libarchive_test+= test_main.c \ + test_utils.c # list.h is just a list of all tests, as indicated by DEFINE_TEST macro lines list.h: ${TESTS_SRCS} Makefile diff --git a/usr.bin/bsdcat/Makefile b/usr.bin/bsdcat/Makefile index f3dd81221..c5e8c024a 100644 --- a/usr.bin/bsdcat/Makefile +++ b/usr.bin/bsdcat/Makefile @@ -6,7 +6,7 @@ _LIBARCHIVEDIR= ${SRCTOP}/contrib/libarchive _LIBARCHIVECONFDIR= ${SRCTOP}/lib/libarchive PROG= bsdcat -BSDCAT_VERSION_STRING= 3.2.2 +BSDCAT_VERSION_STRING= 3.3.1 .PATH: ${_LIBARCHIVEDIR}/cat SRCS= bsdcat.c cmdline.c diff --git a/usr.bin/bsdcat/tests/Makefile b/usr.bin/bsdcat/tests/Makefile index d8e8ac80b..a23650572 100644 --- a/usr.bin/bsdcat/tests/Makefile +++ b/usr.bin/bsdcat/tests/Makefile @@ -14,8 +14,8 @@ CFLAGS+= -DPLATFORM_CONFIG_H=\"${SRCTOP}/lib/libarchive/config_freebsd.h\" CFLAGS+= -I${SRCTOP}/lib/libarchive -I${.OBJDIR} CFLAGS+= -I${.OBJDIR} -CFLAGS+= -I${_LIBARCHIVEDIR}/cat -I${_LIBARCHIVEDIR}/libarchive_fe -CFLAGS+= -I${_LIBARCHIVEDIR}/test_utils +CFLAGS+= -I${_LIBARCHIVEDIR}/cat -I${_LIBARCHIVEDIR}/cat/test +CFLAGS+= -I${_LIBARCHIVEDIR}/libarchive_fe -I${_LIBARCHIVEDIR}/test_utils # Uncomment to link against dmalloc #LDADD+= -L/usr/local/lib -ldmalloc @@ -40,11 +40,11 @@ TESTS_SRCS= \ test_version.c SRCS.bsdcat_test= list.h \ - ${TESTS_SRCS} \ - main.c + ${TESTS_SRCS} .PATH: ${_LIBARCHIVEDIR}/test_utils -SRCS.bsdcat_test+= test_utils.c +SRCS.bsdcat_test+= test_main.c \ + test_utils.c LIBADD.bsdcat_test= archive diff --git a/usr.bin/cpio/Makefile b/usr.bin/cpio/Makefile index f1ca14393..a1f823b20 100644 --- a/usr.bin/cpio/Makefile +++ b/usr.bin/cpio/Makefile @@ -6,7 +6,7 @@ LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive LIBARCHIVECONFDIR= ${.CURDIR}/../../lib/libarchive PROG= bsdcpio -BSDCPIO_VERSION_STRING= 3.2.2 +BSDCPIO_VERSION_STRING= 3.3.1 .PATH: ${LIBARCHIVEDIR}/cpio SRCS= cpio.c cmdline.c diff --git a/usr.bin/cpio/tests/Makefile b/usr.bin/cpio/tests/Makefile index 38e7f20fe..06a4d5986 100644 --- a/usr.bin/cpio/tests/Makefile +++ b/usr.bin/cpio/tests/Makefile @@ -15,8 +15,8 @@ CFLAGS+= -DPLATFORM_CONFIG_H=\"${SRCTOP}/lib/libarchive/config_freebsd.h\" CFLAGS+= -I${SRCTOP}/lib/libarchive -I${.OBJDIR} CFLAGS+= -I${.OBJDIR} -CFLAGS+= -I${LIBARCHIVEDIR}/cpio -I${LIBARCHIVEDIR}/libarchive_fe -CFLAGS+= -I${LIBARCHIVEDIR}/test_utils +CFLAGS+= -I${LIBARCHIVEDIR}/cpio -I${LIBARCHIVEDIR}/cpio/test +CFLAGS+= -I${LIBARCHIVEDIR}/libarchive_fe -I${LIBARCHIVEDIR}/test_utils # Uncomment to link against dmalloc #LDADD+= -L/usr/local/lib -ldmalloc @@ -79,11 +79,11 @@ TESTS_SRCS= \ SRCS.bsdcpio_test= list.h \ ${CPIO_SRCS} \ - ${TESTS_SRCS} \ - main.c + ${TESTS_SRCS} .PATH: ${LIBARCHIVEDIR}/test_utils -SRCS.bsdcpio_test+= test_utils.c +SRCS.bsdcpio_test+= test_main.c \ + test_utils.c DPADD.bsdcpio_test= ${LIBARCHIVE} LDADD.bsdcpio_test= -larchive diff --git a/usr.bin/tar/Makefile b/usr.bin/tar/Makefile index bf7924a7d..538be165f 100644 --- a/usr.bin/tar/Makefile +++ b/usr.bin/tar/Makefile @@ -4,7 +4,7 @@ LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive PROG= bsdtar -BSDTAR_VERSION_STRING= 3.2.2 +BSDTAR_VERSION_STRING= 3.3.1 .PATH: ${LIBARCHIVEDIR}/tar SRCS= bsdtar.c \ diff --git a/usr.bin/tar/tests/Makefile b/usr.bin/tar/tests/Makefile index d77c1ea0a..583c6eedf 100644 --- a/usr.bin/tar/tests/Makefile +++ b/usr.bin/tar/tests/Makefile @@ -11,7 +11,8 @@ BINDIR= ${TESTSDIR} CFLAGS+= -DPLATFORM_CONFIG_H=\"${SRCTOP}/lib/libarchive/config_freebsd.h\" CFLAGS+= -I${SRCTOP}/lib/libarchive -I${.OBJDIR} -CFLAGS+= -I${LIBARCHIVEDIR}/tar -I${LIBARCHIVEDIR}/test_utils +CFLAGS+= -I${LIBARCHIVEDIR}/tar -I${LIBARCHIVEDIR}/tar/test +CFLAGS+= -I${LIBARCHIVEDIR}/test_utils # Uncomment to link against dmalloc #LDADD+= -L/usr/local/lib -ldmalloc @@ -46,9 +47,11 @@ TESTS_SRCS= \ test_option_U_upper.c \ test_option_X_upper.c \ test_option_a.c \ + test_option_acls.c \ test_option_b.c \ test_option_b64encode.c \ test_option_exclude.c \ + test_option_fflags.c \ test_option_gid_gname.c \ test_option_grzip.c \ test_option_j.c \ @@ -79,11 +82,11 @@ TESTS_SRCS= \ SRCS.bsdtar_test= \ ${TESTS_SRCS} \ - list.h \ - main.c + list.h .PATH: ${LIBARCHIVEDIR}/test_utils -SRCS.bsdtar_test+= test_utils.c +SRCS.bsdtar_test+= test_main.c \ + test_utils.c DPADD.bsdtar_test= ${LIBARCHIVE} LDADD.bsdtar_test= -larchive -- 2.45.0