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:
Martin Matuska 2017-03-02 21:13:25 +00:00
parent 4b729aff5b
commit 46ab065716
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/libarchive/dist/; revision=314567
39 changed files with 1586 additions and 625 deletions

View File

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

View File

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

View File

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

View File

@ -1 +1 @@
3003001
3003002dev

View File

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

View File

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

View File

@ -108,22 +108,22 @@ static int entry_to_archive(struct cpio *, struct archive_entry *);
static int file_to_archive(struct cpio *, const char *);
static void free_cache(struct name_cache *cache);
static void list_item_verbose(struct cpio *, struct archive_entry *);
static void long_help(void);
static void long_help(void) __LA_DEAD;
static const char *lookup_gname(struct cpio *, gid_t gid);
static int lookup_gname_helper(struct cpio *,
const char **name, id_t gid);
static const char *lookup_uname(struct cpio *, uid_t uid);
static int lookup_uname_helper(struct cpio *,
const char **name, id_t uid);
static void mode_in(struct cpio *);
static void mode_list(struct cpio *);
static void mode_in(struct cpio *) __LA_DEAD;
static void mode_list(struct cpio *) __LA_DEAD;
static void mode_out(struct cpio *);
static void mode_pass(struct cpio *, const char *);
static const char *remove_leading_slash(const char *);
static int restore_time(struct cpio *, struct archive_entry *,
const char *, int fd);
static void usage(void);
static void version(void);
static void usage(void) __LA_DEAD;
static void version(void) __LA_DEAD;
static const char * passphrase_callback(struct archive *, void *);
static void passphrase_free(char *);

View File

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

View File

@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 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);

View File

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

View File

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

View File

@ -30,7 +30,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3003001
#define ARCHIVE_VERSION_NUMBER 3003002
/*
* Note: archive_entry.h is for use outside of libarchive; the

View File

@ -32,7 +32,7 @@
.Nm archive_entry_acl_clear ,
.Nm archive_entry_acl_count ,
.Nm archive_entry_acl_from_text ,
.Nm archive_entry_acl_from_text_w,
.Nm archive_entry_acl_from_text_w ,
.Nm archive_entry_acl_next ,
.Nm archive_entry_acl_next_w ,
.Nm archive_entry_acl_reset ,

View File

@ -31,25 +31,25 @@
.Nm archive_entry_set_hardlink ,
.Nm archive_entry_copy_hardlink ,
.Nm archive_entry_copy_hardlink_w ,
.Nm archve_entry_update_hardlink_utf8 ,
.Nm archive_entry_update_hardlink_utf8 ,
.Nm archive_entry_set_link ,
.Nm archive_entry_copy_link ,
.Nm archive_entry_copy_link_w ,
.Nm archve_entry_update_link_utf8 ,
.Nm archive_entry_update_link_utf8 ,
.Nm archive_entry_pathname ,
.Nm archive_entry_pathname_w ,
.Nm archive_entry_set_pathname ,
.Nm archive_entry_copy_pathname ,
.Nm archive_entry_copy_pathname_w ,
.Nm archve_entry_update_pathname_utf8 ,
.Nm archive_entry_update_pathname_utf8 ,
.Nm archive_entry_sourcepath ,
.Nm archive_entry_copy_sourcepath ,
.Nm archive_entry_symlink,
.Nm archive_entry_symlink_w,
.Nm archive_entry_symlink ,
.Nm archive_entry_symlink_w ,
.Nm archive_entry_set_symlink ,
.Nm archive_entry_copy_symlink ,
.Nm archive_entry_copy_symlink_w ,
.Nm archve_entry_update_symlink_utf8
.Nm archive_entry_update_symlink_utf8
.Nd functions for manipulating path names in archive entry descriptions
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)

View File

@ -34,8 +34,8 @@
.Nm archive_entry_perm ,
.Nm archive_entry_set_perm ,
.Nm archive_entry_strmode ,
.Nm archive_entry_uname
.Nm archive_entry_uname_w
.Nm archive_entry_uname ,
.Nm archive_entry_uname_w ,
.Nm archive_entry_set_uname ,
.Nm archive_entry_copy_uname ,
.Nm archive_entry_copy_uname_w ,

View File

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

View File

@ -37,10 +37,7 @@
.Nm archive_read_disk_uname ,
.Nm archive_read_disk_set_uname_lookup ,
.Nm archive_read_disk_set_gname_lookup ,
.Nm archive_read_disk_set_standard_lookup ,
.Nm archive_read_close ,
.Nm archive_read_finish ,
.Nm archive_read_free
.Nm archive_read_disk_set_standard_lookup
.Nd functions for reading objects from disk
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@ -81,12 +78,6 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "int fd"
.Fa "const struct stat *"
.Fc
.Ft int
.Fn archive_read_close "struct archive *"
.Ft int
.Fn archive_read_finish "struct archive *"
.Ft int
.Fn archive_read_free "struct archive *"
.Sh DESCRIPTION
These functions provide an API for reading information about
objects on disk.
@ -181,17 +172,6 @@ using the currently registered lookup functions above.
This affects the file ownership fields and ACL values in the
.Tn struct archive_entry
object.
.It Fn archive_read_close
Does nothing for
.Tn archive_read_disk
handles.
.It Fn archive_read_finish
This is a deprecated synonym for
.Fn archive_read_free .
.It Fn archive_read_free
Invokes
.Fn archive_read_close
if it was not invoked manually, then releases all resources.
.El
More information about the
.Va struct archive

View File

@ -124,11 +124,9 @@ __FBSDID("$FreeBSD: 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);

View File

@ -37,9 +37,9 @@
.Nm archive_read_support_format_empty ,
.Nm archive_read_support_format_iso9660 ,
.Nm archive_read_support_format_lha ,
.Nm archive_read_support_format_mtree,
.Nm archive_read_support_format_rar,
.Nm archive_read_support_format_raw,
.Nm archive_read_support_format_mtree ,
.Nm archive_read_support_format_rar ,
.Nm archive_read_support_format_raw ,
.Nm archive_read_support_format_tar ,
.Nm archive_read_support_format_xar ,
.Nm archive_read_support_format_zip

View File

@ -33,7 +33,7 @@
.Nm archive_read_open_fd ,
.Nm archive_read_open_FILE ,
.Nm archive_read_open_filename ,
.Nm archive_read_open_memory ,
.Nm archive_read_open_memory
.Nd functions for reading streaming archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)

View File

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

View File

@ -24,11 +24,12 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 2, 2012
.Dd February 28, 2017
.Dt ARCHIVE_WRITE_DATA 3
.Os
.Sh NAME
.Nm archive_write_data
.Nm archive_write_data ,
.Nm archive_write_data_block
.Nd functions for creating archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@ -36,8 +37,27 @@ Streaming Archive Library (libarchive, -larchive)
.In archive.h
.Ft la_ssize_t
.Fn archive_write_data "struct archive *" "const void *" "size_t"
.Ft la_ssize_t
.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset"
.Sh DESCRIPTION
.Bl -tag -width indent
.It Fn archive_write_data
Write data corresponding to the header just written.
.It Fn archive_write_data_block
Write data corresponding to the header just written.
This is like
.Fn archive_write_data
except that it performs a seek on the file being
written to the specified offset before writing the data.
This is useful when restoring sparse files from archive
formats that support sparse files.
Returns number of bytes written or -1 on error.
(Note: This is currently not supported for
.Tn archive_write
handles, only for
.Tn archive_write_disk
handles.
.El
.\" .Sh EXAMPLE
.\"
.Sh RETURN VALUES

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 2, 2012
.Dd February 28, 2017
.Dt ARCHIVE_WRITE_DISK 3
.Os
.Sh NAME
@ -33,14 +33,7 @@
.Nm archive_write_disk_set_skip_file ,
.Nm archive_write_disk_set_group_lookup ,
.Nm archive_write_disk_set_standard_lookup ,
.Nm archive_write_disk_set_user_lookup ,
.Nm archive_write_header ,
.Nm archive_write_data ,
.Nm archive_write_data_block ,
.Nm archive_write_finish_entry ,
.Nm archive_write_close ,
.Nm archive_write_finish
.Nm archive_write_free
.Nm archive_write_disk_set_user_lookup
.Nd functions for creating objects on disk
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
@ -68,20 +61,6 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "uid_t (*)(void *, const char *uname, uid_t uid)"
.Fa "void (*cleanup)(void *)"
.Fc
.Ft int
.Fn archive_write_header "struct archive *" "struct archive_entry *"
.Ft la_ssize_t
.Fn archive_write_data "struct archive *" "const void *" "size_t"
.Ft la_ssize_t
.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset"
.Ft int
.Fn archive_write_finish_entry "struct archive *"
.Ft int
.Fn archive_write_close "struct archive *"
.Ft int
.Fn archive_write_finish "struct archive *"
.Ft int
.Fn archive_write_free "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for creating objects on
disk from
@ -223,60 +202,6 @@ the number of calls to
.Xr getpwnam 3
and
.Xr getgrnam 3 .
.It Fn archive_write_header
Build and write a header using the data in the provided
.Tn struct archive_entry
structure.
See
.Xr archive_entry 3
for information on creating and populating
.Tn struct archive_entry
objects.
.It Fn archive_write_data
Write data corresponding to the header just written.
Returns number of bytes written or -1 on error.
.It Fn archive_write_data_block
Write data corresponding to the header just written.
This is like
.Fn archive_write_data
except that it performs a seek on the file being
written to the specified offset before writing the data.
This is useful when restoring sparse files from archive
formats that support sparse files.
Returns number of bytes written or -1 on error.
(Note: This is currently not supported for
.Tn archive_write
handles, only for
.Tn archive_write_disk
handles.)
.It Fn archive_write_finish_entry
Close out the entry just written.
Ordinarily, clients never need to call this, as it
is called automatically by
.Fn archive_write_next_header
and
.Fn archive_write_close
as needed.
However, some file attributes are written to disk only
after the file is closed, so this can be necessary
if you need to work with the file on disk right away.
.It Fn archive_write_close
Set any attributes that could not be set during the initial restore.
For example, directory timestamps are not restored initially because
restoring a subsequent file would alter that timestamp.
Similarly, non-writable directories are initially created with
write permissions (so that their contents can be restored).
The
.Nm
library maintains a list of all such deferred attributes and
sets them when this function is invoked.
.It Fn archive_write_finish
This is a deprecated synonym for
.Fn archive_write_free .
.It Fn archive_write_free
Invokes
.Fn archive_write_close
if it was not invoked manually, then releases all resources.
.El
More information about the
.Va struct archive

View File

@ -61,17 +61,18 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
#else /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
#if HAVE_SUN_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
#elif HAVE_DARWIN_ACL
#if HAVE_DARWIN_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
#elif HAVE_ACL_TYPE_NFS4
#elif HAVE_FREEBSD_NFS4_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
#endif
static int set_acl(struct archive *, int fd, const char *,
struct archive_acl *,
acl_type_t, int archive_entry_acl_type, const char *tn);
#if !HAVE_SUN_ACL
acl_type_t,
#endif
int archive_entry_acl_type, const char *tn);
int
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
@ -84,7 +85,7 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
#if HAVE_SUN_ACL
/* Solaris writes POSIX.1e access and default ACLs together */
ret = set_acl(a, fd, name, abstract_acl, ACLENT_T,
ret = set_acl(a, fd, name, abstract_acl,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
#else /* HAVE_POSIX_ACL */
if ((archive_acl_types(abstract_acl)
@ -109,13 +110,16 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
if ((archive_acl_types(abstract_acl) &
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
ret = set_acl(a, fd, name, abstract_acl,
#if !HAVE_SUN_ACL
ARCHIVE_PLATFORM_ACL_TYPE_NFS4,
#endif
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
}
#endif /* HAVE_NFS4_ACL */
return (ret);
}
#if !HAVE_SUN_ACL || HAVE_SUN_NFS4_ACL
/*
* Translate system ACL permissions into libarchive internal structure
*/
@ -123,7 +127,7 @@ static const struct {
const int archive_perm;
const int platform_perm;
} acl_perm_map[] = {
#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL permissions */
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
{ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
@ -158,12 +162,14 @@ static const struct {
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
#if HAVE_DECL_ACL_SYNCHRONIZE
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
#endif
#else /* POSIX.1e ACL permissions */
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFSv4 ACL permissions */
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
@ -183,6 +189,7 @@ static const struct {
#endif
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
};
#endif /* !HAVE_SUN_ACL || HAVE_SUN_NFS4_ACL */
#if HAVE_NFS4_ACL
/*
@ -192,14 +199,16 @@ static const struct {
const int archive_inherit;
const int platform_inherit;
} acl_inherit_map[] = {
#if HAVE_SUN_ACL /* Solaris NFSv4 inheritance flags */
#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
#ifdef ACE_INHERITED_ACE
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
#endif
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
@ -214,29 +223,34 @@ static const struct {
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
#endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
};
#endif /* HAVE_NFS4_ACL */
static int
set_acl(struct archive *a, int fd, const char *name,
struct archive_acl *abstract_acl,
acl_type_t acl_type, int ae_requested_type, const char *tname)
#if !HAVE_SUN_ACL
acl_type_t acl_type,
#endif
int ae_requested_type, const char *tname)
{
#if HAVE_SUN_ACL
aclent_t *aclent;
#if HAVE_SUN_NFS4_ACL
ace_t *ace;
int e, r;
acl_t *acl;
#endif
int cmd, e, r;
void *aclp;
#else
acl_t acl;
acl_entry_t acl_entry;
acl_permset_t acl_permset;
#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
acl_flagset_t acl_flagset;
#endif
#endif /* HAVE_SUN_ACL */
#if HAVE_ACL_TYPE_NFS4
#if HAVE_FREEBSD_NFS4_ACL
int r;
#endif
int ret;
@ -256,31 +270,26 @@ set_acl(struct archive *a, int fd, const char *name,
return (ARCHIVE_OK);
#if HAVE_SUN_ACL
acl = NULL;
acl = malloc(sizeof(acl_t));
if (acl == NULL) {
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Invalid ACL type");
switch (ae_requested_type) {
case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
cmd = SETACL;
aclp = malloc(entries * sizeof(aclent_t));
break;
#if HAVE_SUN_NFS4_ACL
case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
cmd = ACE_SETACL;
aclp = malloc(entries * sizeof(ace_t));
break;
#endif
default:
errno = ENOENT;
archive_set_error(a, errno, "Invalid ACL type");
return (ARCHIVE_FAILED);
}
if (acl_type == ACE_T)
acl->acl_entry_size = sizeof(ace_t);
else if (acl_type == ACLENT_T)
acl->acl_entry_size = sizeof(aclent_t);
else {
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Invalid ACL type");
acl_free(acl);
return (ARCHIVE_FAILED);
}
acl->acl_type = acl_type;
acl->acl_cnt = entries;
acl->acl_aclp = malloc(entries * acl->acl_entry_size);
if (acl->acl_aclp == NULL) {
if (aclp == NULL) {
archive_set_error(a, errno,
"Can't allocate memory for acl buffer");
acl_free(acl);
return (ARCHIVE_FAILED);
}
#else /* !HAVE_SUN_ACL */
@ -297,19 +306,24 @@ set_acl(struct archive *a, int fd, const char *name,
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
#if HAVE_SUN_ACL
ace = NULL;
aclent = NULL;
if (acl->acl_type == ACE_T) {
ace = &((ace_t *)acl->acl_aclp)[e];
ace->a_who = -1;
ace->a_access_mask = 0;
ace->a_flags = 0;
} else {
aclent = &((aclent_t *)acl->acl_aclp)[e];
#if HAVE_SUN_NFS4_ACL
ace = NULL;
#endif
if (cmd == SETACL) {
aclent = &((aclent_t *)aclp)[e];
aclent->a_id = -1;
aclent->a_type = 0;
aclent->a_perm = 0;
}
#if HAVE_SUN_NFS4_ACL
else { /* cmd == ACE_SETACL */
ace = &((ace_t *)aclp)[e];
ace->a_who = -1;
ace->a_access_mask = 0;
ace->a_flags = 0;
}
#endif /* HAVE_SUN_NFS4_ACL */
#else /* !HAVE_SUN_ACL */
#if HAVE_DARWIN_ACL
/*
@ -346,45 +360,63 @@ set_acl(struct archive *a, int fd, const char *name,
#if HAVE_SUN_ACL
case ARCHIVE_ENTRY_ACL_USER:
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
if (acl->acl_type == ACE_T)
ace->a_who = ae_uid;
else {
if (aclent != NULL) {
aclent->a_id = ae_uid;
aclent->a_type |= USER;
}
#if HAVE_SUN_NFS4_ACL
else {
ace->a_who = ae_uid;
}
#endif
break;
case ARCHIVE_ENTRY_ACL_GROUP:
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
if (acl->acl_type == ACE_T) {
ace->a_who = ae_gid;
ace->a_flags |= ACE_IDENTIFIER_GROUP;
} else {
if (aclent != NULL) {
aclent->a_id = ae_gid;
aclent->a_type |= GROUP;
}
#if HAVE_SUN_NFS4_ACL
else {
ace->a_who = ae_gid;
ace->a_flags |= ACE_IDENTIFIER_GROUP;
}
#endif
break;
case ARCHIVE_ENTRY_ACL_USER_OBJ:
if (acl->acl_type == ACE_T)
ace->a_flags |= ACE_OWNER;
else
if (aclent != NULL)
aclent->a_type |= USER_OBJ;
#if HAVE_SUN_NFS4_ACL
else {
ace->a_flags |= ACE_OWNER;
}
#endif
break;
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
if (acl->acl_type == ACE_T) {
if (aclent != NULL)
aclent->a_type |= GROUP_OBJ;
#if HAVE_SUN_NFS4_ACL
else {
ace->a_flags |= ACE_GROUP;
ace->a_flags |= ACE_IDENTIFIER_GROUP;
} else
aclent->a_type |= GROUP_OBJ;
}
#endif
break;
case ARCHIVE_ENTRY_ACL_MASK:
aclent->a_type |= CLASS_OBJ;
if (aclent != NULL)
aclent->a_type |= CLASS_OBJ;
break;
case ARCHIVE_ENTRY_ACL_OTHER:
aclent->a_type |= OTHER_OBJ;
if (aclent != NULL)
aclent->a_type |= OTHER_OBJ;
break;
#if HAVE_SUN_NFS4_ACL
case ARCHIVE_ENTRY_ACL_EVERYONE:
ace->a_flags |= ACE_EVERYONE;
if (ace != NULL)
ace->a_flags |= ACE_EVERYONE;
break;
#endif
#else /* !HAVE_SUN_ACL */
case ARCHIVE_ENTRY_ACL_USER:
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
@ -425,7 +457,7 @@ set_acl(struct archive *a, int fd, const char *name,
case ARCHIVE_ENTRY_ACL_OTHER:
acl_set_tag_type(acl_entry, ACL_OTHER);
break;
#if HAVE_ACL_TYPE_NFS4 /* FreeBSD only */
#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD only */
case ARCHIVE_ENTRY_ACL_EVERYONE:
acl_set_tag_type(acl_entry, ACL_EVERYONE);
break;
@ -439,10 +471,11 @@ set_acl(struct archive *a, int fd, const char *name,
goto exit_free;
}
#if HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL
#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_ACL
r = 0;
switch (ae_type) {
#if HAVE_SUN_ACL
#if HAVE_SUN_NFS4_ACL
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
if (ace != NULL)
ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
@ -467,6 +500,7 @@ set_acl(struct archive *a, int fd, const char *name,
else
r = -1;
break;
#endif
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
if (aclent == NULL)
r = -1;
@ -497,7 +531,7 @@ set_acl(struct archive *a, int fd, const char *name,
#endif /* !HAVE_SUN_ACL */
default:
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Unknown ACL entry type");
"Unsupported ACL entry type");
ret = ARCHIVE_FAILED;
goto exit_free;
}
@ -511,17 +545,20 @@ set_acl(struct archive *a, int fd, const char *name,
ret = ARCHIVE_FAILED;
goto exit_free;
}
#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL */
#endif /* HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_ACL */
#if HAVE_SUN_ACL
if (acl->acl_type == ACLENT_T) {
if (aclent != NULL) {
if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
aclent->a_perm |= 1;
if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
aclent->a_perm |= 2;
if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
aclent->a_perm |= 4;
} else
}
#if HAVE_SUN_NFS4_ACL
else /* falls through to for statement below, ace != NULL */
#endif
#else
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
archive_set_error(a, errno,
@ -536,6 +573,7 @@ set_acl(struct archive *a, int fd, const char *name,
goto exit_free;
}
#endif /* !HAVE_SUN_ACL */
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
if (ae_permset & acl_perm_map[i].archive_perm) {
#if HAVE_SUN_ACL
@ -552,10 +590,11 @@ set_acl(struct archive *a, int fd, const char *name,
#endif
}
}
#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
#if HAVE_NFS4_ACL
#if HAVE_SUN_ACL
if (acl_type == ACE_T)
#if HAVE_SUN_NFS4_ACL
if (ace != NULL)
#elif HAVE_DARWIN_ACL
if (acl_type == ACL_TYPE_EXTENDED)
#else /* FreeBSD */
@ -611,7 +650,7 @@ set_acl(struct archive *a, int fd, const char *name,
#endif
{
#if HAVE_SUN_ACL
if (facl_set(fd, acl) == 0)
if (facl(fd, cmd, entries, aclp) == 0)
#elif HAVE_ACL_SET_FD_NP
if (acl_set_fd_np(fd, acl, acl_type) == 0)
#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
@ -630,7 +669,7 @@ set_acl(struct archive *a, int fd, const char *name,
} else
#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */
#if HAVE_SUN_ACL
if (acl_set(name, acl) != 0)
if (acl(name, cmd, entries, aclp) != 0)
#elif HAVE_ACL_SET_LINK_NP
if (acl_set_link_np(name, acl_type, acl) != 0)
#else
@ -648,7 +687,11 @@ set_acl(struct archive *a, int fd, const char *name,
}
}
exit_free:
#if HAVE_SUN_ACL
free(aclp);
#else
acl_free(acl);
#endif
return (ret);
}
#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */

View File

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

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 2, 2012
.Dd February 28, 2017
.Dt ARCHIVE_WRITE_FINISH_ENTRY 3
.Os
.Sh NAME
@ -45,6 +45,9 @@ is called automatically by
and
.Fn archive_write_close
as needed.
For
.Tn archive_write_disk
handles, this flushes pending file attribute changes like modification time.
.\" .Sh EXAMPLE
.Sh RETURN VALUES
This function returns

View File

@ -108,7 +108,6 @@ Streaming Archive Library (libarchive, -larchive)
These functions set the format that will be used for the archive.
.Pp
The library can write a variety of common archive formats.
.Bl -tag -width indent
.It Fn archive_write_set_format
Sets the format based on the format code (see

View File

@ -254,12 +254,14 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
int i;
archive_entry_acl_clear(ae);
#if !HAVE_DARWIN_ACL
if (start > 0) {
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_add_entry(ae,
acls[0].type, acls[0].permset, acls[0].tag,
acls[0].qual, acls[0].name));
}
#endif
for (i = start; i < end; i++) {
assertEqualInt(ARCHIVE_OK,
archive_entry_acl_add_entry(ae,
@ -269,14 +271,14 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
}
static int
#ifdef HAVE_SUN_ACL
#ifdef HAVE_SUN_NFS4_ACL
acl_permset_to_bitmap(uint32_t a_access_mask)
#else
acl_permset_to_bitmap(acl_permset_t opaque_ps)
#endif
{
static struct { int machine; int portable; } perms[] = {
#ifdef HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
#ifdef HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL permissions */
{ACE_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
{ACE_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
{ACE_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
@ -311,7 +313,9 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
{ACL_READ_SECURITY, ARCHIVE_ENTRY_ACL_READ_ACL},
{ACL_WRITE_SECURITY, ARCHIVE_ENTRY_ACL_WRITE_ACL},
{ACL_CHANGE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
#if HAVE_DECL_ACL_SYNCHRONIZE
{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE},
#endif
#else /* FreeBSD NFSv4 ACL permissions */
{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
{ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
@ -337,7 +341,7 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
int i, permset = 0;
for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
#if HAVE_SUN_ACL
#if HAVE_SUN_NFS4_ACL
if (a_access_mask & perms[i].machine)
#else
if (acl_get_perm_np(opaque_ps, perms[i].machine))
@ -347,21 +351,23 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
}
static int
#if HAVE_SUN_ACL
#if HAVE_SUN_NFS4_ACL
acl_flagset_to_bitmap(uint16_t a_flags)
#else
acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
#endif
{
static struct { int machine; int portable; } flags[] = {
#if HAVE_SUN_ACL /* Solaris NFSv4 ACL inheritance flags */
#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL inheritance flags */
{ACE_FILE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
{ACE_DIRECTORY_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
{ACE_NO_PROPAGATE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
{ACE_INHERIT_ONLY_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
{ACE_SUCCESSFUL_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
{ACE_FAILED_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
#ifdef ACE_INHERITED_ACE
{ACE_INHERITED_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED}
#endif
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 ACL inheritance flags */
{ACL_ENTRY_INHERITED, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED},
{ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
@ -380,7 +386,7 @@ acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
int i, flagset = 0;
for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
#if HAVE_SUN_ACL
#if HAVE_SUN_NFS4_ACL
if (a_flags & flags[i].machine)
#else
if (acl_get_flag_np(opaque_fs, flags[i].machine))
@ -390,13 +396,13 @@ acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
}
static int
#if HAVE_SUN_ACL
#if HAVE_SUN_NFS4_ACL
acl_match(ace_t *ace, struct myacl_t *myacl)
#else
acl_match(acl_entry_t aclent, struct myacl_t *myacl)
#endif
{
#if !HAVE_SUN_ACL
#if !HAVE_SUN_NFS4_ACL
#if HAVE_DARWIN_ACL
void *q;
uid_t ugid;
@ -409,10 +415,10 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
acl_tag_t tag_type;
acl_permset_t opaque_ps;
acl_flagset_t opaque_fs;
#endif /* !HAVE_SUN_ACL */
#endif /* !HAVE_SUN_NFS4_ACL */
int perms;
#if HAVE_SUN_ACL
#if HAVE_SUN_NFS4_ACL
perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags);
#else
acl_get_tag_type(aclent, &tag_type);
@ -428,7 +434,7 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
if (perms != myacl->permset)
return (0);
#if HAVE_SUN_ACL
#if HAVE_SUN_NFS4_ACL
switch (ace->a_type) {
case ACE_ACCESS_ALLOWED_ACE_TYPE:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
@ -507,7 +513,7 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
default:
return (0);
}
#else /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
#else /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
switch (entry_type) {
case ACL_ENTRY_TYPE_ALLOW:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
@ -559,14 +565,15 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
break;
}
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
#endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
return (1);
}
static void
compare_acls(
#if HAVE_SUN_ACL
acl_t *acl,
#if HAVE_SUN_NFS4_ACL
void *aclp,
int aclcnt,
#else
acl_t acl,
#endif
@ -575,7 +582,7 @@ compare_acls(
int *marker;
int matched;
int i, n;
#if HAVE_SUN_ACL
#if HAVE_SUN_NFS4_ACL
int e;
ace_t *acl_entry;
#else
@ -587,26 +594,28 @@ compare_acls(
marker = malloc(sizeof(marker[0]) * (n + 1));
for (i = 0; i < n; i++)
marker[i] = i + start;
#if !HAVE_DARWIN_ACL
/* Always include the first ACE. */
if (start > 0) {
marker[n] = 0;
++n;
}
#endif
/*
* Iterate over acls in system acl object, try to match each
* one with an item in the myacls array.
*/
#if HAVE_SUN_ACL
for (e = 0; e < acl->acl_cnt; e++)
#if HAVE_SUN_NFS4_ACL
for (e = 0; e < aclcnt; e++)
#elif HAVE_DARWIN_ACL
while (0 == acl_get_entry(acl, entry_id, &acl_entry))
#else
while (1 == acl_get_entry(acl, entry_id, &acl_entry))
#endif
{
#if HAVE_SUN_ACL
acl_entry = &((ace_t *)acl->acl_aclp)[e];
#if HAVE_SUN_NFS4_ACL
acl_entry = &((ace_t *)aclp)[e];
#else
/* After the first time... */
entry_id = ACL_NEXT_ENTRY;
@ -711,11 +720,10 @@ DEFINE_TEST(test_acl_platform_nfs4)
skipping("NFS4 ACLs are not supported on this platform");
#else
char buff[64];
int i;
struct stat st;
struct archive *a;
struct archive_entry *ae;
int i, n;
char *func;
#if HAVE_DARWIN_ACL /* On MacOS we skip trivial ACLs in some tests */
const int regcnt = acls_reg_cnt - 4;
const int dircnt = acls_dir_cnt - 4;
@ -723,86 +731,20 @@ DEFINE_TEST(test_acl_platform_nfs4)
const int regcnt = acls_reg_cnt;
const int dircnt = acls_dir_cnt;
#endif
#if HAVE_SUN_ACL
acl_t *acl;
#else /* !HAVE_SUN_ACL */
#if HAVE_DARWIN_ACL
acl_entry_t aclent;
acl_permset_t permset;
const uid_t uid = 1000;
uuid_t uuid;
#endif /* HAVE_DARWIN_ACL */
#if HAVE_SUN_NFS4_ACL
void *aclp;
int aclcnt;
#else /* !HAVE_SUN_NFS4_ACL */
acl_t acl;
#endif /* !HAVE_SUN_ACL */
/*
* First, do a quick manual set/read of ACL data to
* verify that the local filesystem does support ACLs.
* If it doesn't, we'll simply skip the remaining tests.
*/
#if HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4
acl = acl_from_text("owner@:rwxp::allow,group@:rwp:f:allow");
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
assert((void *)acl != NULL);
#elif HAVE_DARWIN_ACL
acl = acl_init(1);
assert((void *)acl != NULL);
assertEqualInt(0, acl_create_entry(&acl, &aclent));
assertEqualInt(0, acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW));
assertEqualInt(0, acl_get_permset(aclent, &permset));
assertEqualInt(0, acl_add_perm(permset, ACL_READ_DATA));
assertEqualInt(0, acl_add_perm(permset, ACL_WRITE_DATA));
assertEqualInt(0, acl_add_perm(permset, ACL_APPEND_DATA));
assertEqualInt(0, acl_add_perm(permset, ACL_EXECUTE));
assertEqualInt(0, acl_set_permset(aclent, permset));
assertEqualInt(0, mbr_identifier_to_uuid(ID_TYPE_UID, &uid,
sizeof(uid_t), uuid));
assertEqualInt(0, acl_set_qualifier(aclent, uuid));
#endif
/* Create a test dir and try to set an ACL on it. */
if (!assertMakeDir("pretest", 0755)) {
#if !HAVE_SUN_ACL
acl_free(acl);
#endif
assertMakeFile("pretest", 0644, "a");
if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_NFS4) {
skipping("NFS4 ACLs are not writable on this filesystem");
return;
}
#if HAVE_SUN_ACL
func = "acl_get()";
n = acl_get("pretest", 0, &acl);
#else
func = "acl_set_file()";
#if HAVE_DARWIN_ACL
n = acl_set_file("pretest", ACL_TYPE_EXTENDED, acl);
#else
n = acl_set_file("pretest", ACL_TYPE_NFS4, acl);
#endif
acl_free(acl);
#endif
if (n != 0) {
#if HAVE_SUN_ACL
if (errno == ENOSYS)
#else
if (errno == EOPNOTSUPP || errno == EINVAL)
#endif
{
skipping("NFS4 ACL is not supported on this filesystem");
return;
}
}
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
assertEqualInt(0, n);
#if HAVE_SUN_ACL
if (acl->acl_type != ACE_T) {
acl_free(acl);
skipping("NFS4 ACL is not supported on this filesystem");
return;
}
acl_free(acl);
#endif
/* Create a write-to-disk object. */
assert(NULL != (a = archive_write_disk_new()));
archive_write_disk_set_options(a,
@ -848,10 +790,10 @@ DEFINE_TEST(test_acl_platform_nfs4)
/* Verify the data on disk. */
assertEqualInt(0, stat("testall", &st));
assertEqualInt(st.st_mtime, 123456);
#if HAVE_SUN_ACL
n = acl_get("testall", 0, &acl);
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#if HAVE_SUN_NFS4_ACL
aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "testall");
failure("acl(): errno = %d (%s)", errno, strerror(errno));
assert(aclp != NULL);
#else
#if HAVE_DARWIN_ACL
acl = acl_get_file("testall", ACL_TYPE_EXTENDED);
@ -861,18 +803,25 @@ DEFINE_TEST(test_acl_platform_nfs4)
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
assert(acl != (acl_t)NULL);
#endif
#if HAVE_SUN_NFS4_ACL
compare_acls(aclp, aclcnt, acls_reg, "testall", 0, regcnt);
free(aclp);
aclp = NULL;
#else
compare_acls(acl, acls_reg, "testall", 0, regcnt);
acl_free(acl);
#endif
/* Verify single-permission dirs on disk. */
for (i = 0; i < dircnt; ++i) {
sprintf(buff, "dir%d", i);
assertEqualInt(0, stat(buff, &st));
assertEqualInt(st.st_mtime, 123456 + i);
#if HAVE_SUN_ACL
n = acl_get(buff, 0, &acl);
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#if HAVE_SUN_NFS4_ACL
aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, buff);
failure("acl(): errno = %d (%s)", errno, strerror(errno));
assert(aclp != NULL);
#else
#if HAVE_DARWIN_ACL
acl = acl_get_file(buff, ACL_TYPE_EXTENDED);
@ -883,17 +832,23 @@ DEFINE_TEST(test_acl_platform_nfs4)
strerror(errno));
assert(acl != (acl_t)NULL);
#endif
#if HAVE_SUN_NFS4_ACL
compare_acls(aclp, aclcnt, acls_dir, buff, i, i + 1);
free(aclp);
aclp = NULL;
#else
compare_acls(acl, acls_dir, buff, i, i + 1);
acl_free(acl);
#endif
}
/* Verify "dirall" on disk. */
assertEqualInt(0, stat("dirall", &st));
assertEqualInt(st.st_mtime, 123456);
#if HAVE_SUN_ACL
n = acl_get("dirall", 0, &acl);
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#if HAVE_SUN_NFS4_ACL
aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "dirall");
failure("acl(): errno = %d (%s)", errno, strerror(errno));
assert(aclp != NULL);
#else
#if HAVE_DARWIN_ACL
acl = acl_get_file("dirall", ACL_TYPE_EXTENDED);
@ -903,8 +858,14 @@ DEFINE_TEST(test_acl_platform_nfs4)
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
assert(acl != (acl_t)NULL);
#endif
#if HAVE_SUN_NFS4_ACL
compare_acls(aclp, aclcnt, acls_dir, "dirall", 0, dircnt);
free(aclp);
aclp = NULL;
#else
compare_acls(acl, acls_dir, "dirall", 0, dircnt);
acl_free(acl);
#endif
/* Read and compare ACL via archive_read_disk */
a = archive_read_disk_new();

View File

@ -226,7 +226,7 @@ acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
static void
#if HAVE_SUN_ACL
compare_acls(acl_t *acl, struct archive_test_acl_t *myacls, int n)
compare_acls(void *aclp, int aclcnt, struct archive_test_acl_t *myacls, int n)
#else
compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
#endif
@ -254,8 +254,8 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
* one with an item in the myacls array.
*/
#if HAVE_SUN_ACL
for(e = 0; e < acl->acl_cnt; e++) {
acl_entry = &((aclent_t *)acl->acl_aclp)[e];
for(e = 0; e < aclcnt; e++) {
acl_entry = &((aclent_t *)aclp)[e];
#else
while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
/* After the first time... */
@ -304,84 +304,20 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
struct stat st;
struct archive *a;
struct archive_entry *ae;
int n, fd;
char *func;
#if HAVE_SUN_ACL
acl_t *acl, *acl2;
void *aclp;
int aclcnt;
#else
acl_t acl;
#endif
/*
* First, do a quick manual set/read of ACL data to
* verify that the local filesystem does support ACLs.
* If it doesn't, we'll simply skip the remaining tests.
*/
#if HAVE_SUN_ACL
n = acl_fromtext("user::rwx,user:1:rw-,group::rwx,group:15:r-x,other:rwx,mask:rwx", &acl);
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#else
acl = acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx");
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
assert((void *)acl != NULL);
#endif
assertMakeFile("pretest", 0644, "a");
/* Create a test file and try ACL on it. */
fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
failure("Could not create test file?!");
if (!assert(fd >= 0)) {
acl_free(acl);
if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_POSIX1E) {
skipping("POSIX.1e ACLs are not writable on this filesystem");
return;
}
#if HAVE_SUN_ACL
n = facl_get(fd, 0, &acl2);
if (n != 0) {
close(fd);
acl_free(acl);
}
if (errno == ENOSYS) {
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
if (acl2->acl_type != ACLENT_T) {
acl_free(acl2);
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
acl_free(acl2);
func = "facl_set()";
n = facl_set(fd, acl);
#else
func = "acl_set_fd()";
n = acl_set_fd(fd, acl);
#endif
acl_free(acl);
if (n != 0) {
#if HAVE_SUN_ACL
if (errno == ENOSYS)
#else
if (errno == EOPNOTSUPP || errno == EINVAL)
#endif
{
close(fd);
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
}
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
assertEqualInt(0, n);
#if HAVE_SUN_ACL
#endif
close(fd);
/* Create a write-to-disk object. */
assert(NULL != (a = archive_write_disk_new()));
archive_write_disk_set_options(a,
@ -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);

View File

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

View File

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

View File

@ -118,11 +118,11 @@ need_report(void)
}
#endif
static void long_help(void);
static void long_help(void) __LA_DEAD;
static void only_mode(struct bsdtar *, const char *opt,
const char *valid);
static void set_mode(struct bsdtar *, char opt);
static void version(void);
static void version(void) __LA_DEAD;
/* A basic set of security flags to request from libarchive. */
#define SECURITY \

View File

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

View File

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

@ -0,0 +1,471 @@
/*-
* Copyright (c) 2017 Martin Matuska
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
__FBSDID("$FreeBSD$");
#if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
static const acl_perm_t acl_perms[] = {
#if HAVE_DARWIN_ACL
ACL_READ_DATA,
ACL_LIST_DIRECTORY,
ACL_WRITE_DATA,
ACL_ADD_FILE,
ACL_EXECUTE,
ACL_SEARCH,
ACL_DELETE,
ACL_APPEND_DATA,
ACL_ADD_SUBDIRECTORY,
ACL_DELETE_CHILD,
ACL_READ_ATTRIBUTES,
ACL_WRITE_ATTRIBUTES,
ACL_READ_EXTATTRIBUTES,
ACL_WRITE_EXTATTRIBUTES,
ACL_READ_SECURITY,
ACL_WRITE_SECURITY,
ACL_CHANGE_OWNER,
ACL_SYNCHRONIZE
#else /* !HAVE_DARWIN_ACL */
ACL_EXECUTE,
ACL_WRITE,
ACL_READ,
#if HAVE_FREEBSD_NFS4_ACL
ACL_READ_DATA,
ACL_LIST_DIRECTORY,
ACL_WRITE_DATA,
ACL_ADD_FILE,
ACL_APPEND_DATA,
ACL_ADD_SUBDIRECTORY,
ACL_READ_NAMED_ATTRS,
ACL_WRITE_NAMED_ATTRS,
ACL_DELETE_CHILD,
ACL_READ_ATTRIBUTES,
ACL_WRITE_ATTRIBUTES,
ACL_DELETE,
ACL_READ_ACL,
ACL_WRITE_ACL,
ACL_WRITE_OWNER,
ACL_SYNCHRONIZE
#endif /* HAVE_FREEBSD_NFS4_ACL */
#endif /* !HAVE_DARWIN_ACL */
};
#if HAVE_DARWIN_ACL || HAVE_FREEBSD_NFS4_ACL
static const acl_flag_t acl_flags[] = {
#if HAVE_DARWIN_ACL
ACL_FLAG_DEFER_INHERIT,
ACL_FLAG_NO_INHERIT,
ACL_ENTRY_INHERITED,
ACL_ENTRY_FILE_INHERIT,
ACL_ENTRY_DIRECTORY_INHERIT,
ACL_ENTRY_LIMIT_INHERIT,
ACL_ENTRY_ONLY_INHERIT
#else /* HAVE_FREEBSD_NFS4_ACL */
ACL_ENTRY_FILE_INHERIT,
ACL_ENTRY_DIRECTORY_INHERIT,
ACL_ENTRY_NO_PROPAGATE_INHERIT,
ACL_ENTRY_INHERIT_ONLY,
ACL_ENTRY_SUCCESSFUL_ACCESS,
ACL_ENTRY_FAILED_ACCESS,
ACL_ENTRY_INHERITED
#endif /* HAVE_FREEBSD_NFS4_ACL */
};
#endif /* HAVE_DARWIN_ACL || HAVE_FREEBSD_NFS4_ACL */
/*
* Compare two ACL entries on FreeBSD or on Mac OS X
*/
static int
compare_acl_entry(acl_entry_t ae_a, acl_entry_t ae_b, int is_nfs4)
{
acl_tag_t tag_a, tag_b;
acl_permset_t permset_a, permset_b;
int perm_a, perm_b, perm_start, perm_end;
void *qual_a, *qual_b;
#if HAVE_FREEBSD_NFS4_ACL
acl_entry_type_t type_a, type_b;
#endif
#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
acl_flagset_t flagset_a, flagset_b;
int flag_a, flag_b;
#endif
int i, r;
/* Compare ACL tag */
r = acl_get_tag_type(ae_a, &tag_a);
failure("acl_get_tag_type() error: %s", strerror(errno));
if (assertEqualInt(r, 0) == 0)
return (-1);
r = acl_get_tag_type(ae_b, &tag_b);
failure("acl_get_tag_type() error: %s", strerror(errno));
if (assertEqualInt(r, 0) == 0)
return (-1);
if (tag_a != tag_b)
return (0);
/* Compare ACL qualifier */
#if HAVE_DARWIN_ACL
if (tag_a == ACL_EXTENDED_ALLOW || tag_b == ACL_EXTENDED_DENY)
#else
if (tag_a == ACL_USER || tag_a == ACL_GROUP)
#endif
{
qual_a = acl_get_qualifier(ae_a);
failure("acl_get_qualifier() error: %s", strerror(errno));
if (assert(qual_a != NULL) == 0)
return (-1);
qual_b = acl_get_qualifier(ae_b);
failure("acl_get_qualifier() error: %s", strerror(errno));
if (assert(qual_b != NULL) == 0) {
acl_free(qual_a);
return (-1);
}
#if HAVE_DARWIN_ACL
if (memcmp(((guid_t *)qual_a)->g_guid,
((guid_t *)qual_b)->g_guid, KAUTH_GUID_SIZE) != 0)
#else
if ((tag_a == ACL_USER &&
(*(uid_t *)qual_a != *(uid_t *)qual_b)) ||
(tag_a == ACL_GROUP &&
(*(gid_t *)qual_a != *(gid_t *)qual_b)))
#endif
{
acl_free(qual_a);
acl_free(qual_b);
return (0);
}
acl_free(qual_a);
acl_free(qual_b);
}
#if HAVE_FREEBSD_NFS4_ACL
if (is_nfs4) {
/* Compare NFS4 ACL type */
r = acl_get_entry_type_np(ae_a, &type_a);
failure("acl_get_entry_type_np() error: %s", strerror(errno));
if (assertEqualInt(r, 0) == 0)
return (-1);
r = acl_get_entry_type_np(ae_b, &type_b);
failure("acl_get_entry_type_np() error: %s", strerror(errno));
if (assertEqualInt(r, 0) == 0)
return (-1);
if (type_a != type_b)
return (0);
}
#endif
/* Compare ACL perms */
r = acl_get_permset(ae_a, &permset_a);
failure("acl_get_permset() error: %s", strerror(errno));
if (assertEqualInt(r, 0) == 0)
return (-1);
r = acl_get_permset(ae_b, &permset_b);
failure("acl_get_permset() error: %s", strerror(errno));
if (assertEqualInt(r, 0) == 0)
return (-1);
perm_start = 0;
perm_end = (int)(sizeof(acl_perms) / sizeof(acl_perms[0]));
#if HAVE_FREEBSD_NFS4_ACL
if (is_nfs4)
perm_start = 3;
else
perm_end = 3;
#endif
/* Cycle through all perms and compare their value */
for (i = perm_start; i < perm_end; i++) {
#if HAVE_LIBACL
perm_a = acl_get_perm(permset_a, acl_perms[i]);
perm_b = acl_get_perm(permset_b, acl_perms[i]);
#else
perm_a = acl_get_perm_np(permset_a, acl_perms[i]);
perm_b = acl_get_perm_np(permset_b, acl_perms[i]);
#endif
if (perm_a == -1 || perm_b == -1)
return (-1);
if (perm_a != perm_b)
return (0);
}
#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
if (is_nfs4) {
r = acl_get_flagset_np(ae_a, &flagset_a);
failure("acl_get_flagset_np() error: %s", strerror(errno));
if (assertEqualInt(r, 0) == 0)
return (-1);
r = acl_get_flagset_np(ae_b, &flagset_b);
failure("acl_get_flagset_np() error: %s", strerror(errno));
if (assertEqualInt(r, 0) == 0)
return (-1);
/* Cycle through all flags and compare their status */
for (i = 0; i < (int)(sizeof(acl_flags) / sizeof(acl_flags[0]));
i++) {
flag_a = acl_get_flag_np(flagset_a, acl_flags[i]);
flag_b = acl_get_flag_np(flagset_b, acl_flags[i]);
if (flag_a == -1 || flag_b == -1)
return (-1);
if (flag_a != flag_b)
return (0);
}
}
#else /* HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL*/
(void)is_nfs4; /* UNUSED */
#endif
return (1);
}
#endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
#if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL
/*
* Clear default ACLs or inheritance flags
*/
static void
clear_inheritance_flags(const char *path, int type)
{
switch (type) {
case ARCHIVE_TEST_ACL_TYPE_POSIX1E:
#if HAVE_POSIX_ACL
acl_delete_def_file(path);
#else
/* Solaris */
setTestAcl(path);
#endif
break;
case ARCHIVE_TEST_ACL_TYPE_NFS4:
#if HAVE_NFS4_ACL
setTestAcl(path);
#endif
break;
default:
(void)path; /* UNUSED */
break;
}
}
static int
compare_acls(const char *path_a, const char *path_b)
{
int ret = 1;
int is_nfs4 = 0;
#if HAVE_SUN_ACL
void *acl_a, *acl_b;
int aclcnt_a, aclcnt_b;
aclent_t *aclent_a, *aclent_b;
ace_t *ace_a, *ace_b;
int e;
#else
acl_t acl_a, acl_b;
acl_entry_t aclent_a, aclent_b;
int a, b, r;
#endif
acl_a = NULL;
acl_b = NULL;
#if HAVE_SUN_ACL
acl_a = sunacl_get(GETACL, &aclcnt_a, 0, path_a);
if (acl_a == NULL) {
#if HAVE_SUN_NFS4_ACL
is_nfs4 = 1;
acl_a = sunacl_get(ACE_GETACL, &aclcnt_a, 0, path_a);
#endif
failure("acl_get() error: %s", strerror(errno));
if (assert(acl_a != NULL) == 0)
return (-1);
#if HAVE_SUN_NFS4_ACL
acl_b = sunacl_get(ACE_GETACL, &aclcnt_b, 0, path_b);
#endif
} else
acl_b = sunacl_get(GETACL, &aclcnt_b, 0, path_b);
if (acl_b == NULL && (errno == ENOSYS || errno == ENOTSUP)) {
free(acl_a);
return (0);
}
failure("acl_get() error: %s", strerror(errno));
if (assert(acl_b != NULL) == 0) {
free(acl_a);
return (-1);
}
if (aclcnt_a != aclcnt_b) {
ret = 0;
goto exit_free;
}
for (e = 0; e < aclcnt_a; e++) {
if (!is_nfs4) {
aclent_a = &((aclent_t *)acl_a)[e];
aclent_b = &((aclent_t *)acl_b)[e];
if (aclent_a->a_type != aclent_b->a_type ||
aclent_a->a_id != aclent_b->a_id ||
aclent_a->a_perm != aclent_b->a_perm) {
ret = 0;
goto exit_free;
}
}
#if HAVE_SUN_NFS4_ACL
else {
ace_a = &((ace_t *)acl_a)[e];
ace_b = &((ace_t *)acl_b)[e];
if (ace_a->a_who != ace_b->a_who ||
ace_a->a_access_mask != ace_b->a_access_mask ||
ace_a->a_flags != ace_b->a_flags ||
ace_a->a_type != ace_b->a_type) {
ret = 0;
goto exit_free;
}
}
#endif
}
#else /* !HAVE_SUN_ACL */
#if HAVE_DARWIN_ACL
is_nfs4 = 1;
acl_a = acl_get_file(path_a, ACL_TYPE_EXTENDED);
#elif HAVE_FREEBSD_NFS4_ACL
acl_a = acl_get_file(path_a, ACL_TYPE_NFS4);
if (acl_a != NULL)
is_nfs4 = 1;
#endif
#if !HAVE_DARWIN_ACL
if (acl_a == NULL)
acl_a = acl_get_file(path_a, ACL_TYPE_ACCESS);
#endif
failure("acl_get_file() error: %s (%s)", path_a, strerror(errno));
if (assert(acl_a != NULL) == 0)
return (-1);
#if HAVE_DARWIN_ACL
acl_b = acl_get_file(path_b, ACL_TYPE_EXTENDED);
#elif HAVE_FREEBSD_NFS4_ACL
acl_b = acl_get_file(path_b, ACL_TYPE_NFS4);
#endif
#if !HAVE_DARWIN_ACL
if (acl_b == NULL) {
#if HAVE_FREEBSD_NFS4_ACL
if (is_nfs4) {
acl_free(acl_a);
return (0);
}
#endif
acl_b = acl_get_file(path_b, ACL_TYPE_ACCESS);
}
failure("acl_get_file() error: %s (%s)", path_b, strerror(errno));
if (assert(acl_b != NULL) == 0) {
acl_free(acl_a);
return (-1);
}
#endif
a = acl_get_entry(acl_a, ACL_FIRST_ENTRY, &aclent_a);
if (a == -1) {
ret = 0;
goto exit_free;
}
b = acl_get_entry(acl_b, ACL_FIRST_ENTRY, &aclent_b);
if (b == -1) {
ret = 0;
goto exit_free;
}
#if HAVE_DARWIN_ACL
while (a == 0 && b == 0)
#else /* FreeBSD, Linux */
while (a == 1 && b == 1)
#endif
{
r = compare_acl_entry(aclent_a, aclent_b, is_nfs4);
if (r != 1) {
ret = r;
goto exit_free;
}
a = acl_get_entry(acl_a, ACL_NEXT_ENTRY, &aclent_a);
b = acl_get_entry(acl_b, ACL_NEXT_ENTRY, &aclent_b);
}
/* Entry count must match */
if (a != b)
ret = 0;
#endif /* !HAVE_SUN_ACL */
exit_free:
#if HAVE_SUN_ACL
free(acl_a);
free(acl_b);
#else
acl_free(acl_a);
acl_free(acl_b);
#endif
return (ret);
}
#endif /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
DEFINE_TEST(test_option_acls)
{
#if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_POSIX_ACL
skipping("ACLs are not supported on this platform");
#else /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
int acltype, r;
assertMakeFile("f", 0644, "a");
acltype = setTestAcl("f");
if (acltype == 0) {
skipping("Can't write ACLs on the filesystem");
return;
}
/* Archive it with acls */
r = systemf("%s -c --no-mac-metadata --acls -f acls.tar f >acls.out 2>acls.err", testprog);
assertEqualInt(r, 0);
/* Archive it without acls */
r = systemf("%s -c --no-mac-metadata --no-acls -f noacls.tar f >noacls.out 2>noacls.err", testprog);
assertEqualInt(r, 0);
/* Extract acls with acls */
assertMakeDir("acls_acls", 0755);
clear_inheritance_flags("acls_acls", acltype);
r = systemf("%s -x -C acls_acls --no-same-permissions --acls -f acls.tar >acls_acls.out 2>acls_acls.err", testprog);
assertEqualInt(r, 0);
r = compare_acls("f", "acls_acls/f");
assertEqualInt(r, 1);
/* Extractl acls without acls */
assertMakeDir("acls_noacls", 0755);
clear_inheritance_flags("acls_noacls", acltype);
r = systemf("%s -x -C acls_noacls -p --no-acls -f acls.tar >acls_noacls.out 2>acls_noacls.err", testprog);
assertEqualInt(r, 0);
r = compare_acls("f", "acls_noacls/f");
assertEqualInt(r, 0);
/* Extract noacls with acls flag */
assertMakeDir("noacls_acls", 0755);
clear_inheritance_flags("noacls_acls", acltype);
r = systemf("%s -x -C noacls_acls --no-same-permissions --acls -f noacls.tar >noacls_acls.out 2>noacls_acls.err", testprog);
assertEqualInt(r, 0);
r = compare_acls("f", "noacls_acls/f");
assertEqualInt(r, 0);
/* Extract noacls with noacls */
assertMakeDir("noacls_noacls", 0755);
clear_inheritance_flags("noacls_noacls", acltype);
r = systemf("%s -x -C noacls_noacls -p --no-acls -f noacls.tar >noacls_noacls.out 2>noacls_noacls.err", testprog);
assertEqualInt(r, 0);
r = compare_acls("f", "noacls_noacls/f");
assertEqualInt(r, 0);
#endif /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
}

View File

@ -0,0 +1,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");
}

View File

@ -36,7 +36,7 @@ DEFINE_TEST(test_option_nodump)
assertMakeFile("file1", 0644, "file1");
assertMakeFile("file2", 0644, "file2");
assertMakeFile("file3", 0644, "file3");
assertNodump("file2");
assertSetNodump("file2");
/* Test 1: Without --nodump */
assertEqualInt(0, systemf("%s -cf test1.tar file1 file2 file3",

View File

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

View File

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