MFV r314565,314567,314570:

Update libarchive to version 3.3.1 (and sync with latest vendor dist)

Notable vendor changes:
  PR #501: improvements in ACL path handling
  PR #724: fix hang when reading malformed cpio files
  PR #864: fix out of bounds read with malformed GNU tar archives
  Documentation, style, test suite improvements and typo fixes.

New options to bsdtar that enable or disable reading and/or writing of:
  Access Control Lists (--acls, --no-acls)
  Extended file flags (--fflags, --no-fflags)
  Extended attributes (--xattrs, --no-xattrs)
  Mac OS X metadata (Mac OS X only) (--mac-metadata, --no-mac-metadata)

MFC after:	2 weeks
This commit is contained in:
Martin Matuska 2017-03-02 22:59:35 +00:00
commit 642870485c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=314571
68 changed files with 2999 additions and 8640 deletions

View File

@ -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

View File

@ -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
#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 <sys/types.h> /* Windows requires this before sys/stat.h */
#include <sys/stat.h>
#if HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_DIRECT_H
#include <direct.h>
#define dirent direct
#endif
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_IO_H
#include <io.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <wchar.h>
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
/*
* System-specific tweaks. We really want to minimize these
* as much as possible, since they make it harder to understand
* the mainline code.
*/
/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
#if !defined(__BORLANDC__)
#undef chdir
#define chdir _chdir
#define strdup _strdup
#endif
#endif
/* Visual Studio */
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf sprintf_s
#endif
#if defined(__BORLANDC__)
#pragma warn -8068 /* Constant out of range in comparison. */
#endif
/* Haiku OS and QNX */
#if defined(__HAIKU__) || defined(__QNXNTO__)
/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
#include <stdint.h>
#endif
/* Get a real definition for __FBSDID if we can */
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
/* If not, define it so as to avoid dangling semicolons. */
#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
/*
* Redefine DEFINE_TEST for use in defining the test functions.
*/
#undef DEFINE_TEST
#define DEFINE_TEST(name) void name(void); void name(void)
/* An implementation of the standard assert() macro */
#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
/* chdir() and error if it fails */
#define assertChdir(path) \
assertion_chdir(__FILE__, __LINE__, path)
/* Assert two integers are the same. Reports value of each one if not. */
#define assertEqualInt(v1,v2) \
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
#define assertEqualUTF8String(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
/* Assert that memory is full of a specified byte */
#define assertMemoryFilledWith(v1, l, b) \
assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
/* Assert two files are the same. */
#define assertEqualFile(f1, f2) \
assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
/* Assert that a file is empty. */
#define assertEmptyFile(pathname) \
assertion_empty_file(__FILE__, __LINE__, (pathname))
/* Assert that a file is not empty. */
#define assertNonEmptyFile(pathname) \
assertion_non_empty_file(__FILE__, __LINE__, (pathname))
#define assertFileAtime(pathname, sec, nsec) \
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileAtimeRecent(pathname) \
assertion_file_atime_recent(__FILE__, __LINE__, pathname)
#define assertFileBirthtime(pathname, sec, nsec) \
assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileBirthtimeRecent(pathname) \
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileExists(pathname) \
assertion_file_exists(__FILE__, __LINE__, pathname)
/* Assert that a file exists. */
#define assertFileNotExists(pathname) \
assertion_file_not_exists(__FILE__, __LINE__, pathname)
/* Assert that file contents match a string. */
#define assertFileContents(data, data_size, pathname) \
assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
/* Verify that a file does not contain invalid strings */
#define assertFileContainsNoInvalidStrings(pathname, strings) \
assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
#define assertFileNLinks(pathname, nlinks) \
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size) \
assertion_file_size(__FILE__, __LINE__, pathname, size)
#define assertFileMode(pathname, mode) \
assertion_file_mode(__FILE__, __LINE__, pathname, mode)
#define assertTextFileContents(text, pathname) \
assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
#define assertFileContainsLinesAnyOrder(pathname, lines) \
assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
#define assertIsDir(pathname, mode) \
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2) \
assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsNotHardlink(path1, path2) \
assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsReg(pathname, mode) \
assertion_is_reg(__FILE__, __LINE__, pathname, mode)
#define assertIsSymlink(pathname, contents) \
assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
/* Create a directory, report error if it fails. */
#define assertMakeDir(dirname, mode) \
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
#define assertMakeFile(path, mode, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
#define assertMakeBinFile(path, mode, csize, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
#define assertMakeHardlink(newfile, oldfile) \
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertNodump(path) \
assertion_nodump(__FILE__, __LINE__, path)
#define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask)
#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
/*
* This would be simple with C99 variadic macros, but I don't want to
* require that. Instead, I insert a function call before each
* skipping() call to pass the file and line information down. Crude,
* but effective.
*/
#define skipping \
skipping_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
int assertion_empty_file(const char *, int, const char *);
int assertion_equal_file(const char *, int, const char *, const char *);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int assertion_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
int assertion_file_contents(const char *, int, const void *, int, const char *);
int assertion_file_exists(const char *, int, const char *);
int assertion_file_mode(const char *, int, const char *, int);
int assertion_file_mtime(const char *, int, const char *, long, long);
int assertion_file_mtime_recent(const char *, int, const char *);
int assertion_file_nlinks(const char *, int, const char *, int);
int assertion_file_not_exists(const char *, int, const char *);
int assertion_file_size(const char *, int, const char *, long);
int assertion_is_dir(const char *, int, const char *, int);
int assertion_is_hardlink(const char *, int, const char *, const char *);
int assertion_is_not_hardlink(const char *, int, const char *, const char *);
int assertion_is_reg(const char *, int, const char *, int);
int assertion_is_symlink(const char *, int, const char *, const char *);
int assertion_make_dir(const char *, int, const char *, int);
int assertion_make_file(const char *, int, const char *, int, int, const void *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_nodump(const char *, int, const char *);
int assertion_non_empty_file(const char *, int, const char *);
int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
int assertion_umask(const char *, int, int);
int assertion_utimes(const char *, int, const char *, long, long, long, long );
void skipping_setup(const char *, int);
void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
int systemf(const char * fmt, ...);
/* Delay until time() returns a value after this. */
void sleepUntilAfter(time_t);
/* Return true if this platform can create symlinks. */
int canSymlink(void);
/* Return true if this platform can run the "bzip2" program. */
int canBzip2(void);
/* Return true if this platform can run the "grzip" program. */
int canGrzip(void);
/* Return true if this platform can run the "gzip" program. */
int canGzip(void);
/* Return true if this platform can run the specified command. */
int canRunCommand(const char *);
/* Return true if this platform can run the "lrzip" program. */
int canLrzip(void);
/* Return true if this platform can run the "lz4" program. */
int canLz4(void);
/* Return true if this platform can run the "lzip" program. */
int canLzip(void);
/* Return true if this platform can run the "lzma" program. */
int canLzma(void);
/* Return true if this platform can run the "lzop" program. */
int canLzop(void);
/* Return true if this platform can run the "xz" program. */
int canXz(void);
/* Return true if this filesystem can handle nodump flags. */
int canNodump(void);
/* Return true if the file has large i-node number(>0xffffffff). */
int is_LargeInode(const char *);
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
/* Dump block of bytes to a file. */
void dumpfile(const char *filename, void *, size_t);
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
/* Copies named reference file to the current directory. */
void copy_reference_file(const char *);
/* Extracts a list of files to the current directory.
* List must be NULL terminated.
*/
void extract_reference_files(const char **);
/* Subtract umask from mode */
mode_t umasked(mode_t expected_mode);
/* Path to working directory for current test */
extern const char *testworkdir;
/*
* Special interfaces for program test harness.
*/
/* Pathname of exe to be tested. */
extern const char *testprogfile;
/* Name of exe to use in printf-formatted command strings. */
/* On Windows, this includes leading/trailing quotes. */
extern const char *testprog;
#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif
#include "test_common.h"

View File

@ -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");
}

View File

@ -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 *);

File diff suppressed because it is too large Load Diff

View File

@ -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
#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 <sys/types.h> /* Windows requires this before sys/stat.h */
#include <sys/stat.h>
#if HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_DIRECT_H
#include <direct.h>
#define dirent direct
#endif
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_IO_H
#include <io.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <wchar.h>
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
/*
* System-specific tweaks. We really want to minimize these
* as much as possible, since they make it harder to understand
* the mainline code.
*/
/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
#if !defined(__BORLANDC__)
#undef chdir
#define chdir _chdir
#define strdup _strdup
#endif
#endif
/* Visual Studio */
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf sprintf_s
#endif
#if defined(__BORLANDC__)
#pragma warn -8068 /* Constant out of range in comparison. */
#endif
/* Haiku OS and QNX */
#if defined(__HAIKU__) || defined(__QNXNTO__)
/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
#include <stdint.h>
#endif
/* Get a real definition for __FBSDID if we can */
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
/* If not, define it so as to avoid dangling semicolons. */
#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
/*
* Redefine DEFINE_TEST for use in defining the test functions.
*/
#undef DEFINE_TEST
#define DEFINE_TEST(name) void name(void); void name(void)
/* An implementation of the standard assert() macro */
#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
/* chdir() and error if it fails */
#define assertChdir(path) \
assertion_chdir(__FILE__, __LINE__, path)
/* Assert two integers are the same. Reports value of each one if not. */
#define assertEqualInt(v1,v2) \
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
#define assertEqualUTF8String(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
/* Assert that memory is full of a specified byte */
#define assertMemoryFilledWith(v1, l, b) \
assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
/* Assert two files are the same. */
#define assertEqualFile(f1, f2) \
assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
/* Assert that a file is empty. */
#define assertEmptyFile(pathname) \
assertion_empty_file(__FILE__, __LINE__, (pathname))
/* Assert that a file is not empty. */
#define assertNonEmptyFile(pathname) \
assertion_non_empty_file(__FILE__, __LINE__, (pathname))
#define assertFileAtime(pathname, sec, nsec) \
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileAtimeRecent(pathname) \
assertion_file_atime_recent(__FILE__, __LINE__, pathname)
#define assertFileBirthtime(pathname, sec, nsec) \
assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileBirthtimeRecent(pathname) \
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileExists(pathname) \
assertion_file_exists(__FILE__, __LINE__, pathname)
/* Assert that a file exists. */
#define assertFileNotExists(pathname) \
assertion_file_not_exists(__FILE__, __LINE__, pathname)
/* Assert that file contents match a string. */
#define assertFileContents(data, data_size, pathname) \
assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
/* Verify that a file does not contain invalid strings */
#define assertFileContainsNoInvalidStrings(pathname, strings) \
assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
#define assertFileNLinks(pathname, nlinks) \
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size) \
assertion_file_size(__FILE__, __LINE__, pathname, size)
#define assertFileMode(pathname, mode) \
assertion_file_mode(__FILE__, __LINE__, pathname, mode)
#define assertTextFileContents(text, pathname) \
assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
#define assertFileContainsLinesAnyOrder(pathname, lines) \
assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
#define assertIsDir(pathname, mode) \
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2) \
assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsNotHardlink(path1, path2) \
assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsReg(pathname, mode) \
assertion_is_reg(__FILE__, __LINE__, pathname, mode)
#define assertIsSymlink(pathname, contents) \
assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
/* Create a directory, report error if it fails. */
#define assertMakeDir(dirname, mode) \
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
#define assertMakeFile(path, mode, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
#define assertMakeBinFile(path, mode, csize, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
#define assertMakeHardlink(newfile, oldfile) \
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertNodump(path) \
assertion_nodump(__FILE__, __LINE__, path)
#define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask)
#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
/*
* This would be simple with C99 variadic macros, but I don't want to
* require that. Instead, I insert a function call before each
* skipping() call to pass the file and line information down. Crude,
* but effective.
*/
#define skipping \
skipping_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
int assertion_empty_file(const char *, int, const char *);
int assertion_equal_file(const char *, int, const char *, const char *);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int assertion_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
int assertion_file_contents(const char *, int, const void *, int, const char *);
int assertion_file_exists(const char *, int, const char *);
int assertion_file_mode(const char *, int, const char *, int);
int assertion_file_mtime(const char *, int, const char *, long, long);
int assertion_file_mtime_recent(const char *, int, const char *);
int assertion_file_nlinks(const char *, int, const char *, int);
int assertion_file_not_exists(const char *, int, const char *);
int assertion_file_size(const char *, int, const char *, long);
int assertion_is_dir(const char *, int, const char *, int);
int assertion_is_hardlink(const char *, int, const char *, const char *);
int assertion_is_not_hardlink(const char *, int, const char *, const char *);
int assertion_is_reg(const char *, int, const char *, int);
int assertion_is_symlink(const char *, int, const char *, const char *);
int assertion_make_dir(const char *, int, const char *, int);
int assertion_make_file(const char *, int, const char *, int, int, const void *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_nodump(const char *, int, const char *);
int assertion_non_empty_file(const char *, int, const char *);
int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
int assertion_umask(const char *, int, int);
int assertion_utimes(const char *, int, const char *, long, long, long, long );
void skipping_setup(const char *, int);
void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
int systemf(const char * fmt, ...);
/* Delay until time() returns a value after this. */
void sleepUntilAfter(time_t);
/* Return true if this platform can create symlinks. */
int canSymlink(void);
/* Return true if this platform can run the "bzip2" program. */
int canBzip2(void);
/* Return true if this platform can run the "grzip" program. */
int canGrzip(void);
/* Return true if this platform can run the "gzip" program. */
int canGzip(void);
/* Return true if this platform can run the specified command. */
int canRunCommand(const char *);
/* Return true if this platform can run the "lrzip" program. */
int canLrzip(void);
/* Return true if this platform can run the "lz4" program. */
int canLz4(void);
/* Return true if this platform can run the "lzip" program. */
int canLzip(void);
/* Return true if this platform can run the "lzma" program. */
int canLzma(void);
/* Return true if this platform can run the "lzop" program. */
int canLzop(void);
/* Return true if this platform can run the "xz" program. */
int canXz(void);
/* Return true if this filesystem can handle nodump flags. */
int canNodump(void);
/* Return true if the file has large i-node number(>0xffffffff). */
int is_LargeInode(const char *);
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
/* Dump block of bytes to a file. */
void dumpfile(const char *filename, void *, size_t);
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
/* Copies named reference file to the current directory. */
void copy_reference_file(const char *);
/* Extracts a list of files to the current directory.
* List must be NULL terminated.
*/
void extract_reference_files(const char **);
/* Subtract umask from mode */
mode_t umasked(mode_t expected_mode);
/* Path to working directory for current test */
extern const char *testworkdir;
/*
* Special interfaces for program test harness.
*/
/* Pathname of exe to be tested. */
extern const char *testprogfile;
/* Name of exe to use in printf-formatted command strings. */
/* On Windows, this includes leading/trailing quotes. */
extern const char *testprog;
#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif
#include "test_common.h"

View File

@ -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");
}

View File

@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3002002
#define ARCHIVE_VERSION_NUMBER 3003001
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
#define ARCHIVE_VERSION_ONLY_STRING "3.2.2"
#define ARCHIVE_VERSION_ONLY_STRING "3.3.1"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
@ -1001,6 +1001,10 @@ __LA_DECL int archive_read_disk_set_atime_restored(struct archive *);
#define ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS (0x0008)
/* Default: Xattrs are read from disk. */
#define ARCHIVE_READDISK_NO_XATTR (0x0010)
/* Default: ACLs are read from disk. */
#define ARCHIVE_READDISK_NO_ACL (0x0020)
/* Default: File flags are read from disk. */
#define ARCHIVE_READDISK_NO_FFLAGS (0x0040)
__LA_DECL int archive_read_disk_set_behavior(struct archive *,
int flags);

View File

@ -62,7 +62,7 @@ errmsg(const char *m)
}
}
static void
static __LA_DEAD void
diediedie(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)

View File

@ -143,6 +143,7 @@
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
#include <windows.h>
#include <wincrypt.h>
typedef struct {
int valid;

View File

@ -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 }
};

View File

@ -30,7 +30,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3002002
#define ARCHIVE_VERSION_NUMBER 3003001
/*
* Note: archive_entry.h is for use outside of libarchive; the
@ -66,6 +66,27 @@ typedef int64_t la_int64_t;
# endif
#endif
/* The la_ssize_t should match the type used in 'struct stat' */
#if !defined(__LA_SSIZE_T_DEFINED)
/* Older code relied on the __LA_SSIZE_T macro; after 4.0 we'll switch to the typedef exclusively. */
# if ARCHIVE_VERSION_NUMBER < 4000000
#define __LA_SSIZE_T la_ssize_t
# endif
#define __LA_SSIZE_T_DEFINED
# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
typedef ssize_t la_ssize_t;
# elif defined(_WIN64)
typedef __int64 la_ssize_t;
# else
typedef long la_ssize_t;
# endif
# else
# include <unistd.h> /* ssize_t */
typedef ssize_t la_ssize_t;
# endif
#endif
/* Get a suitable definition for mode_t */
#if ARCHIVE_VERSION_NUMBER >= 3999000
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
@ -526,9 +547,9 @@ __LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type
#define ARCHIVE_ENTRY_ACL_STYLE_COMPACT 0x00000010
__LA_DECL wchar_t *archive_entry_acl_to_text_w(struct archive_entry *,
ssize_t * /* len */, int /* flags */);
la_ssize_t * /* len */, int /* flags */);
__LA_DECL char *archive_entry_acl_to_text(struct archive_entry *,
ssize_t * /* len */, int /* flags */);
la_ssize_t * /* len */, int /* flags */);
__LA_DECL int archive_entry_acl_from_text_w(struct archive_entry *,
const wchar_t * /* wtext */, int /* type */);
__LA_DECL int archive_entry_acl_from_text(struct archive_entry *,

View File

@ -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 ,

View File

@ -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)

View File

@ -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 ,

View File

@ -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)
{

View File

@ -148,23 +148,31 @@
* POSIX.1e draft functions used in archive_read_extract.c.
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
#if HAVE_ACL_USER
#if HAVE_DECL_ACL_USER
#define HAVE_POSIX_ACL 1
#elif HAVE_ACL_TYPE_EXTENDED
#elif HAVE_DECL_ACL_TYPE_EXTENDED && HAVE_MEMBERSHIP_H
#define HAVE_DARWIN_ACL 1
#endif
#if HAVE_DECL_ACL_TYPE_NFS4
#define HAVE_FREEBSD_NFS4_ACL 1
#endif
#endif
/*
* If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
* If this platform has <sys/acl.h>, acl(), facl() and ACLENT_T
* facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
#if HAVE_SYS_ACL_H && HAVE_ACL && HAVE_FACL && HAVE_ACLENT_T && \
HAVE_DECL_GETACL && HAVE_DECL_GETACLCNT && HAVE_DECL_SETACL
#define HAVE_SUN_ACL 1
#if HAVE_ACE_T && HAVE_DECL_ACE_GETACL && HAVE_DECL_ACE_GETACLCNT && \
HAVE_DECL_ACE_SETACL
#define HAVE_SUN_NFS4_ACL 1
#endif
#endif
/* Define if platform supports NFSv4 ACLs */
#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_NFS4_ACL || HAVE_DARWIN_ACL
#define HAVE_NFS4_ACL 1
#endif

View File

@ -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

View File

@ -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);
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
aclp, aclcnt,
#else
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,
#if HAVE_SUN_ACL
"Couldn't translate ACLs: %s", accpath);
#else
"Couldn't translate NFSv4 ACLs: %s", accpath);
#endif
"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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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));

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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");
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);
}
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);
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 */

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
#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()
#include <sys/types.h> /* Windows requires this before sys/stat.h */
#include <sys/stat.h>
#if HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_DIRECT_H
#include <direct.h>
#define dirent direct
#endif
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_IO_H
#include <io.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <wchar.h>
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
/*
* System-specific tweaks. We really want to minimize these
* as much as possible, since they make it harder to understand
* the mainline code.
*/
/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
#if !defined(__BORLANDC__)
#undef chdir
#define chdir _chdir
#define strdup _strdup
#endif
#endif
/* Visual Studio */
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf sprintf_s
#endif
#if defined(__BORLANDC__)
#pragma warn -8068 /* Constant out of range in comparison. */
#endif
/* Haiku OS and QNX */
#if defined(__HAIKU__) || defined(__QNXNTO__)
/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
#include <stdint.h>
#endif
/* Get a real definition for __FBSDID if we can */
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
/* If not, define it so as to avoid dangling semicolons. */
#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
/*
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
* acl_set_file(), and ACL_USER, we assume it has the rest of the
* POSIX.1e draft functions used in archive_read_extract.c.
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
#if HAVE_ACL_USER
#define HAVE_POSIX_ACL 1
#elif HAVE_ACL_TYPE_EXTENDED
#define HAVE_DARWIN_ACL 1
#endif
#endif
/*
* If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
* facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
#define HAVE_SUN_ACL 1
#endif
/* Define if platform supports NFSv4 ACLs */
#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
#define HAVE_NFS4_ACL 1
#endif
/*
* Redefine DEFINE_TEST for use in defining the test functions.
*/
#undef DEFINE_TEST
#define DEFINE_TEST(name) void name(void); void name(void)
/* An implementation of the standard assert() macro */
#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
/* chdir() and error if it fails */
#define assertChdir(path) \
assertion_chdir(__FILE__, __LINE__, path)
/* Assert two integers are the same. Reports value of each one if not. */
#define assertEqualInt(v1,v2) \
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
#define assertEqualUTF8String(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
/* Assert that memory is full of a specified byte */
#define assertMemoryFilledWith(v1, l, b) \
assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
/* Assert two files are the same. */
#define assertEqualFile(f1, f2) \
assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
/* Assert that a file is empty. */
#define assertEmptyFile(pathname) \
assertion_empty_file(__FILE__, __LINE__, (pathname))
/* Assert that a file is not empty. */
#define assertNonEmptyFile(pathname) \
assertion_non_empty_file(__FILE__, __LINE__, (pathname))
#define assertFileAtime(pathname, sec, nsec) \
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileAtimeRecent(pathname) \
assertion_file_atime_recent(__FILE__, __LINE__, pathname)
#define assertFileBirthtime(pathname, sec, nsec) \
assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileBirthtimeRecent(pathname) \
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileExists(pathname) \
assertion_file_exists(__FILE__, __LINE__, pathname)
/* Assert that a file exists. */
#define assertFileNotExists(pathname) \
assertion_file_not_exists(__FILE__, __LINE__, pathname)
/* Assert that file contents match a string. */
#define assertFileContents(data, data_size, pathname) \
assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
/* Verify that a file does not contain invalid strings */
#define assertFileContainsNoInvalidStrings(pathname, strings) \
assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
#define assertFileNLinks(pathname, nlinks) \
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size) \
assertion_file_size(__FILE__, __LINE__, pathname, size)
#define assertFileMode(pathname, mode) \
assertion_file_mode(__FILE__, __LINE__, pathname, mode)
#define assertTextFileContents(text, pathname) \
assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
#define assertFileContainsLinesAnyOrder(pathname, lines) \
assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
#define assertIsDir(pathname, mode) \
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2) \
assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsNotHardlink(path1, path2) \
assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsReg(pathname, mode) \
assertion_is_reg(__FILE__, __LINE__, pathname, mode)
#define assertIsSymlink(pathname, contents) \
assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
/* Create a directory, report error if it fails. */
#define assertMakeDir(dirname, mode) \
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
#define assertMakeFile(path, mode, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
#define assertMakeBinFile(path, mode, csize, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
#define assertMakeHardlink(newfile, oldfile) \
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertNodump(path) \
assertion_nodump(__FILE__, __LINE__, path)
#define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask)
#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
/*
* This would be simple with C99 variadic macros, but I don't want to
* require that. Instead, I insert a function call before each
* skipping() call to pass the file and line information down. Crude,
* but effective.
*/
#define skipping \
skipping_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
int assertion_empty_file(const char *, int, const char *);
int assertion_equal_file(const char *, int, const char *, const char *);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int assertion_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
int assertion_file_contents(const char *, int, const void *, int, const char *);
int assertion_file_exists(const char *, int, const char *);
int assertion_file_mode(const char *, int, const char *, int);
int assertion_file_mtime(const char *, int, const char *, long, long);
int assertion_file_mtime_recent(const char *, int, const char *);
int assertion_file_nlinks(const char *, int, const char *, int);
int assertion_file_not_exists(const char *, int, const char *);
int assertion_file_size(const char *, int, const char *, long);
int assertion_is_dir(const char *, int, const char *, int);
int assertion_is_hardlink(const char *, int, const char *, const char *);
int assertion_is_not_hardlink(const char *, int, const char *, const char *);
int assertion_is_reg(const char *, int, const char *, int);
int assertion_is_symlink(const char *, int, const char *, const char *);
int assertion_make_dir(const char *, int, const char *, int);
int assertion_make_file(const char *, int, const char *, int, int, const void *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_nodump(const char *, int, const char *);
int assertion_non_empty_file(const char *, int, const char *);
int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
int assertion_umask(const char *, int, int);
int assertion_utimes(const char *, int, const char *, long, long, long, long );
void skipping_setup(const char *, int);
void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
int systemf(const char * fmt, ...);
/* Delay until time() returns a value after this. */
void sleepUntilAfter(time_t);
/* Return true if this platform can create symlinks. */
int canSymlink(void);
/* Return true if this platform can run the "bzip2" program. */
int canBzip2(void);
/* Return true if this platform can run the "grzip" program. */
int canGrzip(void);
/* Return true if this platform can run the "gzip" program. */
int canGzip(void);
/* Return true if this platform can run the specified command. */
int canRunCommand(const char *);
/* Return true if this platform can run the "lrzip" program. */
int canLrzip(void);
/* Return true if this platform can run the "lz4" program. */
int canLz4(void);
/* Return true if this platform can run the "lzip" program. */
int canLzip(void);
/* Return true if this platform can run the "lzma" program. */
int canLzma(void);
/* Return true if this platform can run the "lzop" program. */
int canLzop(void);
/* Return true if this platform can run the "xz" program. */
int canXz(void);
/* Return true if this filesystem can handle nodump flags. */
int canNodump(void);
/* Return true if the file has large i-node number(>0xffffffff). */
int is_LargeInode(const char *);
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
/* Dump block of bytes to a file. */
void dumpfile(const char *filename, void *, size_t);
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
/* Copies named reference file to the current directory. */
void copy_reference_file(const char *);
/* Extracts a list of files to the current directory.
* List must be NULL terminated.
*/
void extract_reference_files(const char **);
/* Subtract umask from mode */
mode_t umasked(mode_t expected_mode);
/* Path to working directory for current test */
extern const char *testworkdir;
/*
* Special interfaces for libarchive test harness.
*/
#include "archive.h"
#include "archive_entry.h"
/* ACL structure */
struct archive_test_acl_t {
int type; /* Type of ACL */
int permset; /* Permissions for this class of users. */
int tag; /* Owner, User, Owning group, group, other, etc. */
int qual; /* GID or UID of user/group, depending on tag. */
const char *name; /* Name of user/group, depending on tag. */
};
/* Set ACLs */
void archive_test_set_acls(struct archive_entry *, struct archive_test_acl_t *,
int);
/* Compare ACLs */
void archive_test_compare_acls(struct archive_entry *,
struct archive_test_acl_t *, int, int, int);
/* Special customized read-from-memory interface. */
int read_open_memory(struct archive *, const void *, size_t, size_t);
/* _minimal version exercises a slightly different set of libarchive APIs. */
int read_open_memory_minimal(struct archive *, const void *, size_t, size_t);
/* _seek version produces a seekable file. */
int read_open_memory_seek(struct archive *, const void *, size_t, size_t);
/* Versions of above that accept an archive argument for additional info. */
#define assertA(e) assertion_assert(__FILE__, __LINE__, (e), #e, (a))
#define assertEqualIntA(a,v1,v2) \
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a))
#define assertEqualStringA(a,v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a), 0)
#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif
#include "test_common.h"

View File

@ -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);

View File

@ -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. */

View File

@ -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,86 +731,20 @@ 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
assertMakeFile("pretest", 0644, "a");
if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_NFS4) {
skipping("NFS4 ACLs are not writable on this filesystem");
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);
#if HAVE_SUN_ACL
if (acl->acl_type != ACE_T) {
acl_free(acl);
skipping("NFS4 ACL is not supported on this filesystem");
return;
}
acl_free(acl);
#endif
/* Create a write-to-disk object. */
assert(NULL != (a = archive_write_disk_new()));
archive_write_disk_set_options(a,
@ -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();

View File

@ -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,84 +304,20 @@ 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
assertMakeFile("pretest", 0644, "a");
/* 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);
if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_POSIX1E) {
skipping("POSIX.1e ACLs are not writable on this filesystem");
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);
if (acl2->acl_type != ACLENT_T) {
acl_free(acl2);
skipping("POSIX.1e ACLs are not supported 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()));
archive_write_disk_set_options(a,
@ -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)
aclp = sunacl_get(GETACL, &aclcnt, fd, NULL);
if (aclp == 0)
close(fd);
if (n != 0 && errno == ENOSYS) {
acl_free(acl1);
if (errno == ENOSYS || errno == ENOTSUP) {
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
failure("facl(): errno = %d (%s)", errno, strerror(errno));
assert(aclp != NULL);
if (acl->acl_type != ACLENT_T) {
acl_free(acl);
acl_free(acl1);
close(fd);
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
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);

View File

@ -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);

View File

@ -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]);

View File

@ -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');
}

View File

@ -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. */

View File

@ -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. */

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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';

View File

@ -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 *);

View File

@ -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 }
};

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -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
#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 <sys/types.h> /* Windows requires this before sys/stat.h */
#include <sys/stat.h>
#if HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_DIRECT_H
#include <direct.h>
#define dirent direct
#endif
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_IO_H
#include <io.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <wchar.h>
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
/*
* System-specific tweaks. We really want to minimize these
* as much as possible, since they make it harder to understand
* the mainline code.
*/
/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
#if !defined(__BORLANDC__)
#undef chdir
#define chdir _chdir
#define strdup _strdup
#endif
#endif
/* Visual Studio */
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf sprintf_s
#endif
#if defined(__BORLANDC__)
#pragma warn -8068 /* Constant out of range in comparison. */
#endif
/* Haiku OS and QNX */
#if defined(__HAIKU__) || defined(__QNXNTO__)
/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
#include <stdint.h>
#endif
/* Get a real definition for __FBSDID if we can */
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
/* If not, define it so as to avoid dangling semicolons. */
#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
/*
* Redefine DEFINE_TEST for use in defining the test functions.
*/
#undef DEFINE_TEST
#define DEFINE_TEST(name) void name(void); void name(void)
/* An implementation of the standard assert() macro */
#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
/* chdir() and error if it fails */
#define assertChdir(path) \
assertion_chdir(__FILE__, __LINE__, path)
/* Assert two integers are the same. Reports value of each one if not. */
#define assertEqualInt(v1,v2) \
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
#define assertEqualUTF8String(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
/* Assert that memory is full of a specified byte */
#define assertMemoryFilledWith(v1, l, b) \
assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
/* Assert two files are the same. */
#define assertEqualFile(f1, f2) \
assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
/* Assert that a file is empty. */
#define assertEmptyFile(pathname) \
assertion_empty_file(__FILE__, __LINE__, (pathname))
/* Assert that a file is not empty. */
#define assertNonEmptyFile(pathname) \
assertion_non_empty_file(__FILE__, __LINE__, (pathname))
#define assertFileAtime(pathname, sec, nsec) \
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileAtimeRecent(pathname) \
assertion_file_atime_recent(__FILE__, __LINE__, pathname)
#define assertFileBirthtime(pathname, sec, nsec) \
assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileBirthtimeRecent(pathname) \
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileExists(pathname) \
assertion_file_exists(__FILE__, __LINE__, pathname)
/* Assert that a file exists. */
#define assertFileNotExists(pathname) \
assertion_file_not_exists(__FILE__, __LINE__, pathname)
/* Assert that file contents match a string. */
#define assertFileContents(data, data_size, pathname) \
assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
/* Verify that a file does not contain invalid strings */
#define assertFileContainsNoInvalidStrings(pathname, strings) \
assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
#define assertFileNLinks(pathname, nlinks) \
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size) \
assertion_file_size(__FILE__, __LINE__, pathname, size)
#define assertFileMode(pathname, mode) \
assertion_file_mode(__FILE__, __LINE__, pathname, mode)
#define assertTextFileContents(text, pathname) \
assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
#define assertFileContainsLinesAnyOrder(pathname, lines) \
assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
#define assertIsDir(pathname, mode) \
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2) \
assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsNotHardlink(path1, path2) \
assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsReg(pathname, mode) \
assertion_is_reg(__FILE__, __LINE__, pathname, mode)
#define assertIsSymlink(pathname, contents) \
assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
/* Create a directory, report error if it fails. */
#define assertMakeDir(dirname, mode) \
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
#define assertMakeFile(path, mode, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
#define assertMakeBinFile(path, mode, csize, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
#define assertMakeHardlink(newfile, oldfile) \
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertNodump(path) \
assertion_nodump(__FILE__, __LINE__, path)
#define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask)
#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
/*
* This would be simple with C99 variadic macros, but I don't want to
* require that. Instead, I insert a function call before each
* skipping() call to pass the file and line information down. Crude,
* but effective.
*/
#define skipping \
skipping_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
int assertion_empty_file(const char *, int, const char *);
int assertion_equal_file(const char *, int, const char *, const char *);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int assertion_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
int assertion_file_contents(const char *, int, const void *, int, const char *);
int assertion_file_exists(const char *, int, const char *);
int assertion_file_mode(const char *, int, const char *, int);
int assertion_file_mtime(const char *, int, const char *, long, long);
int assertion_file_mtime_recent(const char *, int, const char *);
int assertion_file_nlinks(const char *, int, const char *, int);
int assertion_file_not_exists(const char *, int, const char *);
int assertion_file_size(const char *, int, const char *, long);
int assertion_is_dir(const char *, int, const char *, int);
int assertion_is_hardlink(const char *, int, const char *, const char *);
int assertion_is_not_hardlink(const char *, int, const char *, const char *);
int assertion_is_reg(const char *, int, const char *, int);
int assertion_is_symlink(const char *, int, const char *, const char *);
int assertion_make_dir(const char *, int, const char *, int);
int assertion_make_file(const char *, int, const char *, int, int, const void *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_nodump(const char *, int, const char *);
int assertion_non_empty_file(const char *, int, const char *);
int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
int assertion_umask(const char *, int, int);
int assertion_utimes(const char *, int, const char *, long, long, long, long );
void skipping_setup(const char *, int);
void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
int systemf(const char * fmt, ...);
/* Delay until time() returns a value after this. */
void sleepUntilAfter(time_t);
/* Return true if this platform can create symlinks. */
int canSymlink(void);
/* Return true if this platform can run the "bzip2" program. */
int canBzip2(void);
/* Return true if this platform can run the "grzip" program. */
int canGrzip(void);
/* Return true if this platform can run the "gzip" program. */
int canGzip(void);
/* Return true if this platform can run the specified command. */
int canRunCommand(const char *);
/* Return true if this platform can run the "lrzip" program. */
int canLrzip(void);
/* Return true if this platform can run the "lz4" program. */
int canLz4(void);
/* Return true if this platform can run the "lzip" program. */
int canLzip(void);
/* Return true if this platform can run the "lzma" program. */
int canLzma(void);
/* Return true if this platform can run the "lzop" program. */
int canLzop(void);
/* Return true if this platform can run the "xz" program. */
int canXz(void);
/* Return true if this filesystem can handle nodump flags. */
int canNodump(void);
/* Return true if the file has large i-node number(>0xffffffff). */
int is_LargeInode(const char *);
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
/* Dump block of bytes to a file. */
void dumpfile(const char *filename, void *, size_t);
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
/* Copies named reference file to the current directory. */
void copy_reference_file(const char *);
/* Extracts a list of files to the current directory.
* List must be NULL terminated.
*/
void extract_reference_files(const char **);
/* Subtract umask from mode */
mode_t umasked(mode_t expected_mode);
/* Path to working directory for current test */
extern const char *testworkdir;
/*
* Special interfaces for program test harness.
*/
/* Pathname of exe to be tested. */
extern const char *testprogfile;
/* Name of exe to use in printf-formatted command strings. */
/* On Windows, this includes leading/trailing quotes. */
extern const char *testprog;
#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif
#include "test_common.h"

View File

@ -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 */
}

View File

@ -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");
}

View File

@ -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",

View File

@ -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");
}

View File

@ -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')

View File

@ -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);

View File

@ -0,0 +1,467 @@
/*
* Copyright (c) 2003-2017 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef TEST_COMMON_H
#define TEST_COMMON_H
/*
* The goal of this file (and the matching test.c) is to
* simplify the very repetitive test-*.c test programs.
*/
#if defined(HAVE_CONFIG_H)
/* Most POSIX platforms use the 'configure' script to build config.h */
#include "config.h"
#elif defined(__FreeBSD__)
/* Building as part of FreeBSD system requires a pre-built config.h. */
#include "config_freebsd.h"
#elif defined(_WIN32) && !defined(__CYGWIN__)
/* Win32 can't run the 'configure' script. */
#include "config_windows.h"
#else
/* Warn if the library hasn't been (automatically or manually) configured. */
#error Oops: No config.h and no pre-built configuration in test.h.
#endif
#include <sys/types.h> /* Windows requires this before sys/stat.h */
#include <sys/stat.h>
#if HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_DIRECT_H
#include <direct.h>
#define dirent direct
#endif
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_IO_H
#include <io.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <wchar.h>
#ifdef HAVE_ACL_LIBACL_H
#include <acl/libacl.h>
#endif
#ifdef HAVE_SYS_ACL_H
#include <sys/acl.h>
#endif
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
/*
* System-specific tweaks. We really want to minimize these
* as much as possible, since they make it harder to understand
* the mainline code.
*/
/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
#if !defined(__BORLANDC__)
#undef chdir
#define chdir _chdir
#define strdup _strdup
#endif
#endif
/* Visual Studio */
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf sprintf_s
#endif
#if defined(__BORLANDC__)
#pragma warn -8068 /* Constant out of range in comparison. */
#endif
/* Haiku OS and QNX */
#if defined(__HAIKU__) || defined(__QNXNTO__)
/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
#include <stdint.h>
#endif
/* Get a real definition for __FBSDID if we can */
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
/* If not, define it so as to avoid dangling semicolons. */
#ifndef __FBSDID
#define __FBSDID(a) struct _undefined_hack
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
/*
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
* acl_set_file(), and ACL_USER, we assume it has the rest of the
* POSIX.1e draft functions used in archive_read_extract.c.
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
#if HAVE_DECL_ACL_USER
#define HAVE_POSIX_ACL 1
#elif HAVE_DECL_ACL_TYPE_EXTENDED
#define HAVE_DARWIN_ACL 1
#endif
#if HAVE_DECL_ACL_TYPE_NFS4
#define HAVE_FREEBSD_NFS4_ACL 1
#endif
#endif
/*
* If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
* facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
*/
#if HAVE_SYS_ACL_H && HAVE_ACL && HAVE_FACL && HAVE_ACLENT_T && \
HAVE_DECL_GETACL && HAVE_DECL_GETACLCNT && HAVE_DECL_SETACL
#define HAVE_SUN_ACL 1
#if HAVE_ACE_T && HAVE_DECL_ACE_GETACL && HAVE_DECL_ACE_GETACLCNT && \
HAVE_DECL_ACE_SETACL
#define HAVE_SUN_NFS4_ACL 1
#endif
#endif
/* Define if platform supports NFSv4 ACLs */
#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_NFS4_ACL || HAVE_DARWIN_ACL
#define HAVE_NFS4_ACL 1
#endif
#define ARCHIVE_TEST_ACL_TYPE_POSIX1E 1
#define ARCHIVE_TEST_ACL_TYPE_NFS4 2
/*
* Redefine DEFINE_TEST for use in defining the test functions.
*/
#undef DEFINE_TEST
#define DEFINE_TEST(name) void name(void); void name(void)
/* An implementation of the standard assert() macro */
#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
/* chdir() and error if it fails */
#define assertChdir(path) \
assertion_chdir(__FILE__, __LINE__, path)
/* Assert two files have the same file flags */
#define assertEqualFflags(patha, pathb) \
assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 0)
/* Assert two integers are the same. Reports value of each one if not. */
#define assertEqualInt(v1,v2) \
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
#define assertEqualUTF8String(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
/* Assert that memory is full of a specified byte */
#define assertMemoryFilledWith(v1, l, b) \
assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
/* Assert two files are the same. */
#define assertEqualFile(f1, f2) \
assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
/* Assert that a file is empty. */
#define assertEmptyFile(pathname) \
assertion_empty_file(__FILE__, __LINE__, (pathname))
/* Assert that a file is not empty. */
#define assertNonEmptyFile(pathname) \
assertion_non_empty_file(__FILE__, __LINE__, (pathname))
#define assertFileAtime(pathname, sec, nsec) \
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileAtimeRecent(pathname) \
assertion_file_atime_recent(__FILE__, __LINE__, pathname)
#define assertFileBirthtime(pathname, sec, nsec) \
assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileBirthtimeRecent(pathname) \
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileExists(pathname) \
assertion_file_exists(__FILE__, __LINE__, pathname)
/* Assert that a file exists. */
#define assertFileNotExists(pathname) \
assertion_file_not_exists(__FILE__, __LINE__, pathname)
/* Assert that file contents match a string. */
#define assertFileContents(data, data_size, pathname) \
assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
/* Verify that a file does not contain invalid strings */
#define assertFileContainsNoInvalidStrings(pathname, strings) \
assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
#define assertFileNLinks(pathname, nlinks) \
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size) \
assertion_file_size(__FILE__, __LINE__, pathname, size)
#define assertFileMode(pathname, mode) \
assertion_file_mode(__FILE__, __LINE__, pathname, mode)
#define assertTextFileContents(text, pathname) \
assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
#define assertFileContainsLinesAnyOrder(pathname, lines) \
assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
#define assertIsDir(pathname, mode) \
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2) \
assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsNotHardlink(path1, path2) \
assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
#define assertIsReg(pathname, mode) \
assertion_is_reg(__FILE__, __LINE__, pathname, mode)
#define assertIsSymlink(pathname, contents) \
assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
/* Create a directory, report error if it fails. */
#define assertMakeDir(dirname, mode) \
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
#define assertMakeFile(path, mode, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
#define assertMakeBinFile(path, mode, csize, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
#define assertMakeHardlink(newfile, oldfile) \
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertSetNodump(path) \
assertion_set_nodump(__FILE__, __LINE__, path)
#define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask)
/* Assert that two files have unequal file flags */
#define assertUnequalFflags(patha, pathb) \
assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 1)
#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
#ifndef PROGRAM
#define assertEntrySetAcls(entry, acls, count) \
assertion_entry_set_acls(__FILE__, __LINE__, entry, acls, count)
#define assertEntryCompareAcls(entry, acls, count, type, mode) \
assertion_entry_compare_acls(__FILE__, __LINE__, entry, acls, count, type, mode)
#endif
/*
* This would be simple with C99 variadic macros, but I don't want to
* require that. Instead, I insert a function call before each
* skipping() call to pass the file and line information down. Crude,
* but effective.
*/
#define skipping \
skipping_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
int assertion_compare_fflags(const char *, int, const char *, const char *,
int);
int assertion_empty_file(const char *, int, const char *);
int assertion_equal_file(const char *, int, const char *, const char *);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int assertion_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
int assertion_file_contents(const char *, int, const void *, int, const char *);
int assertion_file_exists(const char *, int, const char *);
int assertion_file_mode(const char *, int, const char *, int);
int assertion_file_mtime(const char *, int, const char *, long, long);
int assertion_file_mtime_recent(const char *, int, const char *);
int assertion_file_nlinks(const char *, int, const char *, int);
int assertion_file_not_exists(const char *, int, const char *);
int assertion_file_size(const char *, int, const char *, long);
int assertion_is_dir(const char *, int, const char *, int);
int assertion_is_hardlink(const char *, int, const char *, const char *);
int assertion_is_not_hardlink(const char *, int, const char *, const char *);
int assertion_is_reg(const char *, int, const char *, int);
int assertion_is_symlink(const char *, int, const char *, const char *);
int assertion_make_dir(const char *, int, const char *, int);
int assertion_make_file(const char *, int, const char *, int, int, const void *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_non_empty_file(const char *, int, const char *);
int assertion_set_nodump(const char *, int, const char *);
int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
int assertion_umask(const char *, int, int);
int assertion_utimes(const char *, int, const char *, long, long, long, long );
int assertion_version(const char*, int, const char *, const char *);
void skipping_setup(const char *, int);
void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
int systemf(const char * fmt, ...);
/* Delay until time() returns a value after this. */
void sleepUntilAfter(time_t);
/* Return true if this platform can create symlinks. */
int canSymlink(void);
/* Return true if this platform can run the "bzip2" program. */
int canBzip2(void);
/* Return true if this platform can run the "grzip" program. */
int canGrzip(void);
/* Return true if this platform can run the "gzip" program. */
int canGzip(void);
/* Return true if this platform can run the specified command. */
int canRunCommand(const char *);
/* Return true if this platform can run the "lrzip" program. */
int canLrzip(void);
/* Return true if this platform can run the "lz4" program. */
int canLz4(void);
/* Return true if this platform can run the "lzip" program. */
int canLzip(void);
/* Return true if this platform can run the "lzma" program. */
int canLzma(void);
/* Return true if this platform can run the "lzop" program. */
int canLzop(void);
/* Return true if this platform can run the "xz" program. */
int canXz(void);
/* Return true if this filesystem can handle nodump flags. */
int canNodump(void);
/* Set test ACLs */
int setTestAcl(const char *path);
/* Return true if the file has large i-node number(>0xffffffff). */
int is_LargeInode(const char *);
#if HAVE_SUN_ACL
/* Fetch ACLs on Solaris using acl() or facl() */
void *sunacl_get(int cmd, int *aclcnt, int fd, const char *path);
#endif
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
/* Dump block of bytes to a file. */
void dumpfile(const char *filename, void *, size_t);
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
/* Copies named reference file to the current directory. */
void copy_reference_file(const char *);
/* Extracts a list of files to the current directory.
* List must be NULL terminated.
*/
void extract_reference_files(const char **);
/* Subtract umask from mode */
mode_t umasked(mode_t expected_mode);
/* Path to working directory for current test */
extern const char *testworkdir;
#ifndef PROGRAM
/*
* Special interfaces for libarchive test harness.
*/
#include "archive.h"
#include "archive_entry.h"
/* ACL structure */
struct archive_test_acl_t {
int type; /* Type of ACL */
int permset; /* Permissions for this class of users. */
int tag; /* Owner, User, Owning group, group, other, etc. */
int qual; /* GID or UID of user/group, depending on tag. */
const char *name; /* Name of user/group, depending on tag. */
};
/* Set ACLs */
int assertion_entry_set_acls(const char *, int, struct archive_entry *,
struct archive_test_acl_t *, int);
/* Compare ACLs */
int assertion_entry_compare_acls(const char *, int, struct archive_entry *,
struct archive_test_acl_t *, int, int, int);
/* Special customized read-from-memory interface. */
int read_open_memory(struct archive *, const void *, size_t, size_t);
/* _minimal version exercises a slightly different set of libarchive APIs. */
int read_open_memory_minimal(struct archive *, const void *, size_t, size_t);
/* _seek version produces a seekable file. */
int read_open_memory_seek(struct archive *, const void *, size_t, size_t);
/* Versions of above that accept an archive argument for additional info. */
#define assertA(e) assertion_assert(__FILE__, __LINE__, (e), #e, (a))
#define assertEqualIntA(a,v1,v2) \
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a))
#define assertEqualStringA(a,v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a), 0)
#else /* defined(PROGRAM) */
/*
* Special interfaces for program test harness.
*/
/* Pathname of exe to be tested. */
extern const char *testprogfile;
/* Name of exe to use in printf-formatted command strings. */
/* On Windows, this includes leading/trailing quotes. */
extern const char *testprog;
void assertVersion(const char *prog, const char *base);
#endif /* defined(PROGRAM) */
#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif
#endif /* TEST_COMMON_H */

View File

@ -45,6 +45,9 @@
#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
#include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
#endif
#ifdef HAVE_LINUX_FS_H
#include <linux/fs.h>
#endif
#include <limits.h>
#include <locale.h>
#ifdef HAVE_SIGNAL_H
@ -53,22 +56,19 @@
#include <stdarg.h>
#include <time.h>
/*
* This same file is used pretty much verbatim for all test harnesses.
*
* The next few lines are the only differences.
* TODO: Move this into a separate configuration header, have all test
* suites share one copy of this file.
*/
#define KNOWNREF "test_expand.Z.uu"
#define ENVBASE "BSDCAT" /* Prefix for environment variables. */
#define PROGRAM "bsdcat" /* Name of program being tested. */
#define PROGRAM_ALIAS "cat" /* Generic alias for program */
#undef LIBRARY /* Not testing a library. */
#undef EXTRA_DUMP /* How to dump extra data */
#undef EXTRA_ERRNO /* How to dump errno */
/* How to generate extra version info. */
#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "")
/* ACL support */
#ifdef HAVE_ACL_LIBACL_H
#include <acl/libacl.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_ACL_H
#include <sys/acl.h>
#endif
#if HAVE_DARWIN_ACL
#include <membership.h>
#endif
/*
*
@ -217,6 +217,12 @@ invalid_parameter_handler(const wchar_t * expression,
unsigned int line, uintptr_t pReserved)
{
/* nop */
// Silence unused-parameter compiler warnings.
(void)expression;
(void)function;
(void)file;
(void)line;
(void)pReserved;
}
#endif
@ -1413,6 +1419,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect
failure_start(file, line, "assertFileMode not yet implemented for Windows");
(void)mode; /* UNUSED */
(void)r; /* UNUSED */
(void)pathname; /* UNUSED */
(void)expected_mode; /* UNUSED */
#else
{
struct stat st;
@ -1889,9 +1897,103 @@ assertion_utimes(const char *file, int line,
#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
}
/* Compare file flags */
int
assertion_compare_fflags(const char *file, int line, const char *patha,
const char *pathb, int nomatch)
{
#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
struct stat sa, sb;
assertion_count(file, line);
if (stat(patha, &sa) < 0)
return (0);
if (stat(pathb, &sb) < 0)
return (0);
if (!nomatch && sa.st_flags != sb.st_flags) {
failure_start(file, line, "File flags should be identical: "
"%s=%#010x %s=%#010x", patha, sa.st_flags, pathb,
sb.st_flags);
failure_finish(NULL);
return (0);
}
if (nomatch && sa.st_flags == sb.st_flags) {
failure_start(file, line, "File flags should be different: "
"%s=%#010x %s=%#010x", patha, sa.st_flags, pathb,
sb.st_flags);
failure_finish(NULL);
return (0);
}
#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) && \
defined(FS_NODUMP_FL)) || \
(defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
&& defined(EXT2_NODUMP_FL))
int fd, r, flagsa, flagsb;
assertion_count(file, line);
fd = open(patha, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
failure_start(file, line, "Can't open %s\n", patha);
failure_finish(NULL);
return (0);
}
r = ioctl(fd,
#ifdef FS_IOC_GETFLAGS
FS_IOC_GETFLAGS,
#else
EXT2_IOC_GETFLAGS,
#endif
&flagsa);
close(fd);
if (r < 0) {
failure_start(file, line, "Can't get flags %s\n", patha);
failure_finish(NULL);
return (0);
}
fd = open(pathb, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
failure_start(file, line, "Can't open %s\n", pathb);
failure_finish(NULL);
return (0);
}
r = ioctl(fd,
#ifdef FS_IOC_GETFLAGS
FS_IOC_GETFLAGS,
#else
EXT2_IOC_GETFLAGS,
#endif
&flagsb);
close(fd);
if (r < 0) {
failure_start(file, line, "Can't get flags %s\n", pathb);
failure_finish(NULL);
return (0);
}
if (!nomatch && flagsa != flagsb) {
failure_start(file, line, "File flags should be identical: "
"%s=%#010x %s=%#010x", patha, flagsa, pathb, flagsb);
failure_finish(NULL);
return (0);
}
if (nomatch && flagsa == flagsb) {
failure_start(file, line, "File flags should be different: "
"%s=%#010x %s=%#010x", patha, flagsa, pathb, flagsb);
failure_finish(NULL);
return (0);
}
#else
(void)patha; /* UNUSED */
(void)pathb; /* UNUSED */
(void)nomatch; /* UNUSED */
assertion_count(file, line);
#endif
return (1);
}
/* Set nodump, report failures. */
int
assertion_nodump(const char *file, int line, const char *pathname)
assertion_set_nodump(const char *file, int line, const char *pathname)
{
#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
int r;
@ -1903,8 +2005,10 @@ assertion_nodump(const char *file, int line, const char *pathname)
failure_finish(NULL);
return (0);
}
#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
&& defined(EXT2_NODUMP_FL)
#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) && \
defined(FS_NODUMP_FL)) || \
(defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
&& defined(EXT2_NODUMP_FL))
int fd, r, flags;
assertion_count(file, line);
@ -1914,14 +2018,31 @@ assertion_nodump(const char *file, int line, const char *pathname)
failure_finish(NULL);
return (0);
}
r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
r = ioctl(fd,
#ifdef FS_IOC_GETFLAGS
FS_IOC_GETFLAGS,
#else
EXT2_IOC_GETFLAGS,
#endif
&flags);
if (r < 0) {
failure_start(file, line, "Can't get flags %s\n", pathname);
failure_finish(NULL);
return (0);
}
#ifdef FS_NODUMP_FL
flags |= FS_NODUMP_FL;
#else
flags |= EXT2_NODUMP_FL;
r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
#endif
r = ioctl(fd,
#ifdef FS_IOC_SETFLAGS
FS_IOC_SETFLAGS,
#else
EXT2_IOC_SETFLAGS,
#endif
&flags);
if (r < 0) {
failure_start(file, line, "Can't set nodump %s\n", pathname);
failure_finish(NULL);
@ -1935,6 +2056,117 @@ assertion_nodump(const char *file, int line, const char *pathname)
return (1);
}
#ifdef PROGRAM
static void assert_version_id(char **qq, size_t *ss)
{
char *q = *qq;
size_t s = *ss;
/* Version number is a series of digits and periods. */
while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
++q;
--s;
}
if (q[0] == 'd' && q[1] == 'e' && q[2] == 'v') {
q += 3;
s -= 3;
}
/* Skip a single trailing a,b,c, or d. */
if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
++q;
/* Version number terminated by space. */
failure("No space after version: ``%s''", q);
assert(s > 1);
failure("No space after version: ``%s''", q);
assert(*q == ' ');
++q; --s;
*qq = q;
*ss = s;
}
/*
* Check program version
*/
void assertVersion(const char *prog, const char *base)
{
int r;
char *p, *q;
size_t s;
unsigned int prog_len = strlen(base);
r = systemf("%s --version >version.stdout 2>version.stderr", prog);
if (r != 0)
r = systemf("%s -W version >version.stdout 2>version.stderr",
prog);
failure("Unable to run either %s --version or %s -W version",
prog, prog);
if (!assert(r == 0))
return;
/* --version should generate nothing to stdout. */
assertEmptyFile("version.stderr");
/* Verify format of version message. */
q = p = slurpfile(&s, "version.stdout");
/* Version message should start with name of program, then space. */
assert(s > prog_len + 1);
failure("Version must start with '%s': ``%s''", base, p);
if (!assertEqualMem(q, base, prog_len)) {
free(p);
return;
}
q += prog_len; s -= prog_len;
assert(*q == ' ');
q++; s--;
assert_version_id(&q, &s);
/* Separator. */
failure("No `-' between program name and versions: ``%s''", p);
assertEqualMem(q, "- ", 2);
q += 2; s -= 2;
failure("Not long enough for libarchive version: ``%s''", p);
assert(s > 11);
failure("Libarchive version must start with `libarchive': ``%s''", p);
assertEqualMem(q, "libarchive ", 11);
q += 11; s -= 11;
assert_version_id(&q, &s);
/* Skip arbitrary third-party version numbers. */
while (s > 0 && (*q == ' ' || *q == '-' || *q == '/' || *q == '.' ||
isalnum(*q))) {
++q;
--s;
}
/* All terminated by end-of-line. */
assert(s >= 1);
/* Skip an optional CR character (e.g., Windows) */
failure("Version output must end with \\n or \\r\\n");
if (*q == '\r') { ++q; --s; }
assertEqualMem(q, "\n", 1);
free(p);
}
#endif /* PROGRAM */
/*
*
* UTILITIES for use by tests.
@ -2132,11 +2364,10 @@ canXz(void)
/*
* Can this filesystem handle nodump flags.
*/
#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
int
canNodump(void)
{
#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
const char *path = "cannodumptest";
struct stat sb;
@ -2147,15 +2378,10 @@ canNodump(void)
return (0);
if (sb.st_flags & UF_NODUMP)
return (1);
return (0);
}
#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
&& defined(EXT2_NODUMP_FL)
int
canNodump(void)
{
#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) \
&& defined(FS_NODUMP_FL)) || \
(defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
&& defined(EXT2_NODUMP_FL))
const char *path = "cannodumptest";
int fd, r, flags;
@ -2163,35 +2389,273 @@ canNodump(void)
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return (0);
r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
r = ioctl(fd,
#ifdef FS_IOC_GETFLAGS
FS_IOC_GETFLAGS,
#else
EXT2_IOC_GETFLAGS,
#endif
&flags);
if (r < 0)
return (0);
#ifdef FS_NODUMP_FL
flags |= FS_NODUMP_FL;
#else
flags |= EXT2_NODUMP_FL;
r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
#endif
r = ioctl(fd,
#ifdef FS_IOC_SETFLAGS
FS_IOC_SETFLAGS,
#else
EXT2_IOC_SETFLAGS,
#endif
&flags);
if (r < 0)
return (0);
close(fd);
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return (0);
r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
r = ioctl(fd,
#ifdef FS_IOC_GETFLAGS
FS_IOC_GETFLAGS,
#else
EXT2_IOC_GETFLAGS,
#endif
&flags);
if (r < 0)
return (0);
close(fd);
if (flags & EXT2_NODUMP_FL)
return (1);
return (0);
}
#ifdef FS_NODUMP_FL
if (flags & FS_NODUMP_FL)
#else
int
canNodump()
{
if (flags & EXT2_NODUMP_FL)
#endif
return (1);
#endif
return (0);
}
#if HAVE_SUN_ACL
/* Fetch ACLs on Solaris using acl() or facl() */
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 */
/*
* 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

View File

@ -40,9 +40,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

View File

@ -13,7 +13,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
@ -302,14 +303,14 @@ BROKEN_TESTS+= test_fuzz_rar
# Build the test program.
SRCS.libarchive_test= \
${TESTS_SRCS} \
main.c \
read_open_memory.c \
list.h
LIBADD.libarchive_test= archive
.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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}/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
@ -78,11 +78,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
LIBADD.bsdcpio_test= archive

View File

@ -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 \

View File

@ -10,7 +10,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
@ -45,9 +46,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 \
@ -78,11 +81,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
LIBADD.bsdtar_test= archive