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:
commit
642870485c
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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
@ -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"
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -62,7 +62,7 @@ errmsg(const char *m)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static __LA_DEAD void
|
||||
diediedie(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
|
||||
|
@ -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;
|
||||
|
@ -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 }
|
||||
};
|
||||
|
||||
|
@ -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 *,
|
||||
|
@ -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 ,
|
||||
|
@ -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)
|
||||
|
@ -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 ,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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';
|
||||
|
@ -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 *);
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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
@ -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"
|
||||
|
471
contrib/libarchive/tar/test/test_option_acls.c
Normal file
471
contrib/libarchive/tar/test/test_option_acls.c
Normal 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 */
|
||||
}
|
106
contrib/libarchive/tar/test/test_option_fflags.c
Normal file
106
contrib/libarchive/tar/test/test_option_fflags.c
Normal 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");
|
||||
}
|
@ -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",
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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')
|
||||
|
@ -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);
|
||||
|
467
contrib/libarchive/test_utils/test_common.h
Normal file
467
contrib/libarchive/test_utils/test_common.h
Normal 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 */
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user