Update vendor/libarchive to git a15c7f7b496ba4cefbcaf6f8ac637db4f3009a58
Documentation, style, test suite changes and typo fixes. New bsdtar tests for --acls and --fflags options.
This commit is contained in:
parent
4b729aff5b
commit
46ab065716
@ -15,7 +15,7 @@ endif()
|
||||
# RelWithDebInfo : Release build with Debug Info
|
||||
# MinSizeRel : Release Min Size build
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
|
||||
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE)
|
||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||
# Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the
|
||||
# value type is "UNINITIALIZED".
|
||||
@ -579,6 +579,7 @@ int main(void) { return FS_IOC_GETFLAGS; }" HAVE_WORKING_FS_IOC_GETFLAGS)
|
||||
|
||||
LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H)
|
||||
LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H)
|
||||
LA_CHECK_INCLUDE_FILE("membership.h" HAVE_MEMBERSHIP_H)
|
||||
LA_CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H)
|
||||
LA_CHECK_INCLUDE_FILE("paths.h" HAVE_PATHS_H)
|
||||
LA_CHECK_INCLUDE_FILE("poll.h" HAVE_POLL_H)
|
||||
@ -1618,29 +1619,29 @@ IF(ENABLE_ACL)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_is_trivial_np HAVE_ACL_IS_TRIVIAL_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_set_link_np HAVE_ACL_SET_LINK_NP)
|
||||
CHECK_SYMBOL_EXISTS(ACL_TYPE_NFS4 "${INCLUDES}" HAVE_ACL_TYPE_NFS4)
|
||||
CHECK_SYMBOL_EXISTS(ACL_TYPE_NFS4 "${INCLUDES}" HAVE_DECL_ACL_TYPE_NFS4)
|
||||
|
||||
# MacOS has an acl.h that isn't POSIX. It can be detected by
|
||||
# checking for ACL_USER
|
||||
CHECK_SYMBOL_EXISTS(ACL_USER "${INCLUDES}" HAVE_ACL_USER)
|
||||
CHECK_SYMBOL_EXISTS(ACL_USER "${INCLUDES}" HAVE_DECL_ACL_USER)
|
||||
CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
|
||||
#include <sys/acl.h>
|
||||
int main(void) { return ACL_TYPE_EXTENDED; }" HAVE_ACL_TYPE_EXTENDED)
|
||||
int main(void) { return ACL_TYPE_EXTENDED; }" HAVE_DECL_ACL_TYPE_EXTENDED)
|
||||
CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
|
||||
#include <sys/acl.h>
|
||||
int main(void) { return ACL_SYNCHRONIZE; }" HAVE_DECL_ACL_SYNCHRONIZE)
|
||||
|
||||
# Solaris and derivates ACLs
|
||||
CHECK_LIBRARY_EXISTS(sec "acl_get" "" HAVE_LIBSEC)
|
||||
IF(HAVE_LIBSEC)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "sec")
|
||||
FIND_LIBRARY(SEC_LIBRARY NAMES sec)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${SEC_LIBRARY})
|
||||
ENDIF(HAVE_LIBSEC)
|
||||
#
|
||||
CHECK_TYPE_EXISTS(aclent_t "${INCLUDES}" HAVE_ACLENT_T)
|
||||
CHECK_TYPE_EXISTS(ace_t "${INCLUDES}" HAVE_ACE_T)
|
||||
CHECK_FUNCTION_EXISTS(acl_get HAVE_FACL_GET)
|
||||
CHECK_FUNCTION_EXISTS(facl_get HAVE_FACL_GET)
|
||||
CHECK_FUNCTION_EXISTS(acl_set HAVE_FACL_SET)
|
||||
CHECK_FUNCTION_EXISTS(facl_set HAVE_FACL_SET)
|
||||
CHECK_FUNCTION_EXISTS(acl HAVE_ACL)
|
||||
CHECK_FUNCTION_EXISTS(facl HAVE_FACL)
|
||||
CHECK_SYMBOL_EXISTS(GETACL "${INCLUDES}" HAVE_DECL_GETACL)
|
||||
CHECK_SYMBOL_EXISTS(GETACLCNT "${INCLUDES}" HAVE_DECL_GETACLCNT)
|
||||
CHECK_SYMBOL_EXISTS(SETACL "${INCLUDES}" HAVE_DECL_SETACL)
|
||||
CHECK_SYMBOL_EXISTS(ACE_GETACL "${INCLUDES}" HAVE_DECL_ACE_GETACL)
|
||||
CHECK_SYMBOL_EXISTS(ACE_GETACLCNT "${INCLUDES}" HAVE_DECL_ACE_GETACLCNT)
|
||||
CHECK_SYMBOL_EXISTS(ACE_SETACL "${INCLUDES}" HAVE_DECL_ACE_SETACL)
|
||||
ELSE(ENABLE_ACL)
|
||||
# If someone runs cmake, then disables ACL support, we need
|
||||
# to forcibly override the cached values for these.
|
||||
@ -1655,15 +1656,20 @@ ELSE(ENABLE_ACL)
|
||||
SET(HAVE_ACL_SET_FD FALSE)
|
||||
SET(HAVE_ACL_SET_FD_NP FALSE)
|
||||
SET(HAVE_ACL_SET_FILE FALSE)
|
||||
SET(HAVE_ACL_TYPE_NFS4 FALSE)
|
||||
SET(HAVE_ACL_USER FALSE)
|
||||
SET(HAVE_ACL_TYPE_EXTENDED FALSE)
|
||||
SET(HAVE_ACL_GET FALSE)
|
||||
SET(HAVE_ACLENT_T FALSE)
|
||||
SET(HAVE_ACE_T FALSE)
|
||||
SET(HAVE_FACL_GET FALSE)
|
||||
SET(HAVE_ACL_SET FALSE)
|
||||
SET(HAVE_FACL_SET FALSE)
|
||||
SET(HAVE_DECL_ACL_TYPE_NFS4 FALSE)
|
||||
SET(HAVE_DECL_ACL_USER FALSE)
|
||||
SET(HAVE_DECL_ACL_SYNCHRONIZE FALSE)
|
||||
SET(HAVE_DECL_GETACL FALSE)
|
||||
SET(HAVE_DECL_GETACLCNT FALSE)
|
||||
SET(HAVE_DECL_SETACL FALSE)
|
||||
SET(HAVE_DECL_ACE_GETACL FALSE)
|
||||
SET(HAVE_DECL_ACE_GETACLCNT FALSE)
|
||||
SET(HAVE_DECL_ACE_SETACL FALSE)
|
||||
SET(HAVE_ACL FALSE)
|
||||
SET(HAVE_FACL FALSE)
|
||||
ENDIF(ENABLE_ACL)
|
||||
|
||||
#
|
||||
|
@ -23,7 +23,7 @@ TESTS_ENVIRONMENT= $(libarchive_TESTS_ENVIRONMENT) $(bsdtar_TESTS_ENVIRONMENT) $
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-bsdtar --enable-bsdcpio
|
||||
# The next line is commented out by default in shipping libarchive releases.
|
||||
# It is uncommented by default in trunk.
|
||||
# DEV_CFLAGS=-Werror -Wextra -Wunused -Wshadow -Wmissing-prototypes -Wcast-qual -g
|
||||
DEV_CFLAGS=-Werror -Wextra -Wunused -Wshadow -Wmissing-prototypes -Wcast-qual -g
|
||||
AM_CFLAGS=$(DEV_CFLAGS)
|
||||
PLATFORMCPPFLAGS = @PLATFORMCPPFLAGS@
|
||||
AM_CPPFLAGS=$(PLATFORMCPPFLAGS)
|
||||
@ -951,10 +951,12 @@ bsdtar_test_SOURCES= \
|
||||
tar/test/test_option_T_upper.c \
|
||||
tar/test/test_option_U_upper.c \
|
||||
tar/test/test_option_X_upper.c \
|
||||
tar/test/test_option_acls.c \
|
||||
tar/test/test_option_a.c \
|
||||
tar/test/test_option_b.c \
|
||||
tar/test/test_option_b64encode.c \
|
||||
tar/test/test_option_exclude.c \
|
||||
tar/test/test_option_fflags.c \
|
||||
tar/test/test_option_gid_gname.c \
|
||||
tar/test/test_option_grzip.c \
|
||||
tar/test/test_option_j.c \
|
||||
|
@ -326,15 +326,6 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the `acl_set_file' function. */
|
||||
#cmakedefine HAVE_ACL_SET_FILE 1
|
||||
|
||||
/* True for FreeBSD with NFSv4 ACL support */
|
||||
#cmakedefine HAVE_ACL_TYPE_NFS4 1
|
||||
|
||||
/* True for MacOS ACL support */
|
||||
#cmakedefine HAVE_ACL_TYPE_EXTENDED 1
|
||||
|
||||
/* True for systems with POSIX ACL support */
|
||||
#cmakedefine HAVE_ACL_USER 1
|
||||
|
||||
/* Define to 1 if you have the `arc4random_buf' function. */
|
||||
#cmakedefine HAVE_ARC4RANDOM_BUF 1
|
||||
|
||||
@ -371,6 +362,34 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the `cygwin_conv_path' function. */
|
||||
#cmakedefine HAVE_CYGWIN_CONV_PATH 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ACE_GETACL', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_ACE_GETACL 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ACE_GETACLCNT', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_ACE_GETACLCNT 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ACE_SETACL', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_ACE_SETACL 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ACL_SYNCHRONIZE', and to 0 if
|
||||
you don't. */
|
||||
#cmakedefine HAVE_DECL_ACL_SYNCHRONIZE 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ACL_TYPE_EXTENDED', and to 0 if
|
||||
you don't. */
|
||||
#cmakedefine HAVE_DECL_ACL_TYPE_EXTENDED 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ACL_TYPE_NFS4', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_ACL_TYPE_NFS4 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ACL_USER', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_ACL_USER 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `INT32_MAX', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_INT32_MAX 1
|
||||
@ -395,6 +414,10 @@ typedef uint64_t uintmax_t;
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_INTMAX_MIN 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `SETACL', and to 0 if you don't.
|
||||
*/
|
||||
#cmakedefine HAVE_DECL_SETACL 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_SIZE_MAX 1
|
||||
@ -468,6 +491,14 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if EXTATTR_NAMESPACE_USER is defined in sys/extattr.h. */
|
||||
#cmakedefine HAVE_DECL_EXTATTR_NAMESPACE_USER 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `GETACL', and to 0 if you don't.
|
||||
*/
|
||||
#cmakedefine HAVE_DECL_GETACL 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `GETACLCNT', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_GETACLCNT 1
|
||||
|
||||
/* Define to 1 if you have the `fchdir' function. */
|
||||
#cmakedefine HAVE_FCHDIR 1
|
||||
|
||||
@ -742,6 +773,9 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the `mbrtowc' function. */
|
||||
#cmakedefine HAVE_MBRTOWC 1
|
||||
|
||||
/* Define to 1 if you have the <membership.h> header file. */
|
||||
#cmakedefine HAVE_MEMBERSHIP_H 1
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#cmakedefine HAVE_MEMMOVE 1
|
||||
|
||||
|
@ -1 +1 @@
|
||||
3003001
|
||||
3003002dev
|
||||
|
@ -29,6 +29,11 @@ IF(ENABLE_CAT AND ENABLE_TEST)
|
||||
# Register target
|
||||
#
|
||||
ADD_EXECUTABLE(bsdcat_test ${bsdcat_test_SOURCES})
|
||||
IF(ENABLE_ACL)
|
||||
IF(HAVE_LIBACL)
|
||||
TARGET_LINK_LIBRARIES(bsdcat_test ${ACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBACL)
|
||||
ENDIF(ENABLE_ACL)
|
||||
SET_PROPERTY(TARGET bsdcat_test PROPERTY COMPILE_DEFINITIONS LIST_H)
|
||||
|
||||
#
|
||||
|
33
configure.ac
33
configure.ac
@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front.
|
||||
dnl In particular, this allows the version macro to be used in AC_INIT
|
||||
|
||||
dnl These first two version numbers are updated automatically on each release.
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.3.1])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3003001])
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.3.2dev])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3003002])
|
||||
|
||||
dnl bsdtar and bsdcpio versioning tracks libarchive
|
||||
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
|
||||
@ -699,6 +699,7 @@ AC_ARG_ENABLE([acl],
|
||||
if test "x$enable_acl" != "xno"; then
|
||||
AC_CHECK_HEADERS([acl/libacl.h])
|
||||
AC_CHECK_HEADERS([sys/acl.h])
|
||||
AC_CHECK_HEADERS([membership.h])
|
||||
AC_CHECK_LIB([acl],[acl_get_file])
|
||||
AC_CHECK_FUNCS([acl_create_entry acl_get_fd_np])
|
||||
AC_CHECK_FUNCS([acl_init acl_set_fd acl_set_fd_np acl_set_file])
|
||||
@ -737,31 +738,23 @@ if test "x$enable_acl" != "xno"; then
|
||||
#endif
|
||||
])
|
||||
|
||||
# Check for ACL_TYPE_NFS4
|
||||
AC_CHECK_DECL([ACL_TYPE_NFS4],
|
||||
[AC_DEFINE(HAVE_ACL_TYPE_NFS4, 1, [True for FreeBSD with NFSv4 ACL support])],
|
||||
[],
|
||||
[#include <sys/acl.h>])
|
||||
# FreeBSD and POSIX
|
||||
# MacOS has no ACL_USER in acl.h
|
||||
AC_CHECK_DECLS([ACL_TYPE_NFS4, ACL_USER],
|
||||
[], [],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/acl.h>])
|
||||
|
||||
# MacOS has an acl.h that isn't POSIX. It can be detected by
|
||||
# checking for ACL_USER
|
||||
AC_CHECK_DECL([ACL_USER],
|
||||
[AC_DEFINE(HAVE_ACL_USER, 1, [True for systems with POSIX ACL support])],
|
||||
[],
|
||||
[#include <sys/acl.h>])
|
||||
|
||||
# MacOS has ACL_TYPE_EXTENDED instead
|
||||
AC_CHECK_DECL([ACL_TYPE_EXTENDED],
|
||||
[AC_DEFINE(HAVE_ACL_TYPE_EXTENDED, 1, [True for MacOS ACL support])],
|
||||
[],
|
||||
# FreeBSD and MacOS ACL support
|
||||
AC_CHECK_DECLS([ACL_TYPE_EXTENDED, ACL_SYNCHRONIZE], [], [],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/acl.h>])
|
||||
|
||||
# Solaris and derivates ACLs
|
||||
AC_CHECK_LIB([sec], [acl_get])
|
||||
AC_CHECK_TYPES([aclent_t], [], [], [[#include <sys/acl.h>]])
|
||||
AC_CHECK_TYPES([ace_t], [], [], [[#include <sys/acl.h>]])
|
||||
AC_CHECK_FUNCS(acl_get facl_get acl_set facl_set)
|
||||
AC_CHECK_FUNCS(acl facl)
|
||||
AC_CHECK_DECLS([GETACL, SETACL, GETACLCNT, ACE_GETACL, ACE_SETACL, ACE_GETACLCNT], [], [], [#include <sys/acl.h>])
|
||||
fi
|
||||
|
||||
# Additional requirements
|
||||
|
10
cpio/cpio.c
10
cpio/cpio.c
@ -108,22 +108,22 @@ static int entry_to_archive(struct cpio *, struct archive_entry *);
|
||||
static int file_to_archive(struct cpio *, const char *);
|
||||
static void free_cache(struct name_cache *cache);
|
||||
static void list_item_verbose(struct cpio *, struct archive_entry *);
|
||||
static void long_help(void);
|
||||
static void long_help(void) __LA_DEAD;
|
||||
static const char *lookup_gname(struct cpio *, gid_t gid);
|
||||
static int lookup_gname_helper(struct cpio *,
|
||||
const char **name, id_t gid);
|
||||
static const char *lookup_uname(struct cpio *, uid_t uid);
|
||||
static int lookup_uname_helper(struct cpio *,
|
||||
const char **name, id_t uid);
|
||||
static void mode_in(struct cpio *);
|
||||
static void mode_list(struct cpio *);
|
||||
static void mode_in(struct cpio *) __LA_DEAD;
|
||||
static void mode_list(struct cpio *) __LA_DEAD;
|
||||
static void mode_out(struct cpio *);
|
||||
static void mode_pass(struct cpio *, const char *);
|
||||
static const char *remove_leading_slash(const char *);
|
||||
static int restore_time(struct cpio *, struct archive_entry *,
|
||||
const char *, int fd);
|
||||
static void usage(void);
|
||||
static void version(void);
|
||||
static void usage(void) __LA_DEAD;
|
||||
static void version(void) __LA_DEAD;
|
||||
static const char * passphrase_callback(struct archive *, void *);
|
||||
static void passphrase_free(char *);
|
||||
|
||||
|
@ -62,6 +62,11 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
|
||||
# Register target
|
||||
#
|
||||
ADD_EXECUTABLE(bsdcpio_test ${bsdcpio_test_SOURCES})
|
||||
IF(ENABLE_ACL)
|
||||
IF(HAVE_LIBACL)
|
||||
TARGET_LINK_LIBRARIES(bsdcpio_test ${ACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBACL)
|
||||
ENDIF(ENABLE_ACL)
|
||||
SET_PROPERTY(TARGET bsdcpio_test PROPERTY COMPILE_DEFINITIONS LIST_H)
|
||||
|
||||
#
|
||||
|
@ -36,7 +36,7 @@
|
||||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||
*/
|
||||
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3003001
|
||||
#define ARCHIVE_VERSION_NUMBER 3003002
|
||||
|
||||
#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.3.1"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.3.2dev"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
|
@ -62,7 +62,7 @@ errmsg(const char *m)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static __LA_DEAD void
|
||||
diediedie(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
|
||||
|
@ -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;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3003001
|
||||
#define ARCHIVE_VERSION_NUMBER 3003002
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
|
@ -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 ,
|
||||
|
@ -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: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
|
||||
#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
|
||||
|
||||
@ -435,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
|
||||
@ -454,7 +509,8 @@ 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
|
||||
@ -491,14 +547,17 @@ setup_acls(struct archive_read_disk *a,
|
||||
|
||||
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
|
||||
@ -512,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,
|
||||
"Couldn't translate "
|
||||
#if !HAVE_SUN_ACL
|
||||
"NFSv4 "
|
||||
#endif
|
||||
"ACLs");
|
||||
"Couldn't translate NFSv4 ACLs");
|
||||
}
|
||||
#if HAVE_DARWIN_ACL
|
||||
/*
|
||||
@ -569,12 +643,16 @@ setup_acls(struct archive_read_disk *a,
|
||||
}
|
||||
#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);
|
||||
@ -583,25 +661,56 @@ 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");
|
||||
@ -609,6 +718,7 @@ setup_acls(struct archive_read_disk *a,
|
||||
}
|
||||
}
|
||||
|
||||
#if !HAVE_SUN_ACL
|
||||
/* Only directories can have default ACLs. */
|
||||
if (S_ISDIR(archive_entry_mode(entry))) {
|
||||
#if HAVE_ACL_GET_FD_NP
|
||||
@ -628,7 +738,8 @@ setup_acls(struct archive_read_disk *a,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_POSIX_ACL */
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
#endif /* HAVE_POSIX_ACL || HAVE_SUN_ACL */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -674,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},
|
||||
@ -708,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},
|
||||
@ -730,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 */
|
||||
|
||||
@ -873,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;
|
||||
@ -886,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
|
||||
*
|
||||
@ -994,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.
|
||||
@ -1008,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);
|
||||
@ -1018,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 */
|
||||
@ -1028,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) {
|
||||
@ -1100,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
|
||||
@ -1148,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);
|
||||
@ -1165,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;
|
||||
@ -1181,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.
|
||||
@ -1272,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;
|
||||
@ -1307,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
|
||||
*/
|
||||
@ -1336,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)
|
||||
@ -1361,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,
|
||||
@ -1382,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);
|
||||
|
@ -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)
|
||||
|
@ -600,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;
|
||||
@ -686,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;
|
||||
}
|
||||
|
||||
@ -736,7 +737,7 @@ _warc_rdlen(const char *buf, size_t bsz)
|
||||
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 */
|
||||
|
@ -2467,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2573,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;
|
||||
}
|
||||
@ -2582,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;
|
||||
}
|
||||
@ -2599,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;
|
||||
@ -2618,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! */
|
||||
@ -2630,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;
|
||||
}
|
||||
@ -2652,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;
|
||||
}
|
||||
@ -2661,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;
|
||||
}
|
||||
@ -2674,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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
@ -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,17 +503,19 @@ 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));
|
||||
@ -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("d/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("d/d2", ACL_TYPE_DEFAULT, acl3);
|
||||
#endif
|
||||
acl_free(acl3);
|
||||
|
||||
#endif
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
|
@ -1231,8 +1231,8 @@ test_restore_atime(void)
|
||||
* 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);
|
||||
|
23
tar/bsdtar.1
23
tar/bsdtar.1
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 24, 2017
|
||||
.Dd February 25, 2017
|
||||
.Dt TAR 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -450,14 +450,7 @@ This is the reverse of
|
||||
.Fl p
|
||||
and the default behavior if
|
||||
.Nm
|
||||
is run as non-root and can be overridden by also specifying
|
||||
.Fl Fl acls ,
|
||||
.Fl Fl fflags ,
|
||||
.Fl Fl mac-metadata,
|
||||
.Fl Fl same-owner ,
|
||||
.Fl Fl same-permissions
|
||||
and
|
||||
.Fl Fl xattrs .
|
||||
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
|
||||
@ -648,15 +641,15 @@ This option suppresses these behaviors.
|
||||
Preserve file permissions.
|
||||
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 the default, if
|
||||
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
|
||||
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,
|
||||
.Fl Fl no-same-owner ,
|
||||
.Fl Fl no-same-permissions
|
||||
and
|
||||
.Fl Fl no-mac-metadata
|
||||
or
|
||||
.Fl Fl no-xattrs .
|
||||
.It Fl Fl passphrase Ar passphrase
|
||||
The
|
||||
|
@ -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 \
|
||||
|
@ -189,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);
|
||||
@ -197,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 *);
|
||||
|
@ -34,9 +34,11 @@ IF(ENABLE_TAR AND ENABLE_TEST)
|
||||
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
|
||||
@ -71,6 +73,11 @@ IF(ENABLE_TAR AND ENABLE_TEST)
|
||||
# Register target
|
||||
#
|
||||
ADD_EXECUTABLE(bsdtar_test ${bsdtar_test_SOURCES})
|
||||
IF(ENABLE_ACL)
|
||||
IF(HAVE_LIBACL)
|
||||
TARGET_LINK_LIBRARIES(bsdtar_test ${ACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBACL)
|
||||
ENDIF(ENABLE_ACL)
|
||||
SET_PROPERTY(TARGET bsdtar_test PROPERTY COMPILE_DEFINITIONS LIST_H)
|
||||
|
||||
#
|
||||
|
471
tar/test/test_option_acls.c
Normal file
471
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 */
|
||||
}
|
74
tar/test/test_option_fflags.c
Normal file
74
tar/test/test_option_fflags.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*-
|
||||
* 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$");
|
||||
|
||||
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");
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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",
|
||||
|
@ -73,6 +73,12 @@
|
||||
#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
|
||||
@ -127,26 +133,37 @@
|
||||
* 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
|
||||
#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_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
|
||||
#define HAVE_SUN_ACL 1
|
||||
#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
|
||||
#define HAVE_NFS4_ACL 1
|
||||
#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.
|
||||
*/
|
||||
@ -158,6 +175,9 @@
|
||||
/* 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)
|
||||
@ -239,10 +259,13 @@
|
||||
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 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
|
||||
@ -265,6 +288,8 @@
|
||||
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 *);
|
||||
@ -295,8 +320,8 @@ 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_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 );
|
||||
@ -347,9 +372,17 @@ 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, ...);
|
||||
|
@ -56,6 +56,20 @@
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
/* 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
|
||||
|
||||
/*
|
||||
*
|
||||
* Windows support routines
|
||||
@ -1883,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;
|
||||
@ -2256,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;
|
||||
|
||||
@ -2271,16 +2378,10 @@ canNodump(void)
|
||||
return (0);
|
||||
if (sb.st_flags & UF_NODUMP)
|
||||
return (1);
|
||||
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
|
||||
canNodump(void)
|
||||
{
|
||||
const char *path = "cannodumptest";
|
||||
int fd, r, flags;
|
||||
|
||||
@ -2331,18 +2432,230 @@ canNodump(void)
|
||||
if (flags & EXT2_NODUMP_FL)
|
||||
#endif
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
canNodump()
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
#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
|
||||
|
Loading…
x
Reference in New Issue
Block a user