Ticket #53712: patch-3.3.1_to_master.diff

File patch-3.3.1_to_master.diff, 319.2 KB (added by ballapete (Peter "Pete" Dyballa), 7 years ago)
  • new file libarchive/files/patch-3.3.1_to_master.diff

    diff --git libarchive/files/patch-3.3.1_to_master.diff libarchive/files/patch-3.3.1_to_master.diff
    new file mode 100644
    index 0000000000..91daa6d023
    - +  
     1--- CMakeLists.txt.orig
     2+++ CMakeLists.txt
     3@@ -15,7 +15,7 @@ endif()
     4 #   RelWithDebInfo : Release build with Debug Info
     5 #   MinSizeRel     : Release Min Size build
     6 IF(NOT CMAKE_BUILD_TYPE)
     7-  SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
     8+  SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE)
     9 ENDIF(NOT CMAKE_BUILD_TYPE)
     10 # Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the
     11 # value type is "UNINITIALIZED".
     12@@ -579,6 +579,7 @@ int main(void) { return FS_IOC_GETFLAGS; }" HAVE_WORKING_FS_IOC_GETFLAGS)
     13 
     14 LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H)
     15 LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H)
     16+LA_CHECK_INCLUDE_FILE("membership.h" HAVE_MEMBERSHIP_H)
     17 LA_CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H)
     18 LA_CHECK_INCLUDE_FILE("paths.h" HAVE_PATHS_H)
     19 LA_CHECK_INCLUDE_FILE("poll.h" HAVE_POLL_H)
     20@@ -601,6 +602,7 @@ LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
     21 LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
     22 LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
     23 LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
     24+LA_CHECK_INCLUDE_FILE("sys/richacl.h" HAVE_SYS_RICHACL_H)
     25 LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
     26 LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
     27 LA_CHECK_INCLUDE_FILE("sys/statfs.h" HAVE_SYS_STATFS_H)
     28@@ -618,6 +620,9 @@ LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
     29 LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
     30 IF(ENABLE_CNG)
     31   LA_CHECK_INCLUDE_FILE("Bcrypt.h" HAVE_BCRYPT_H)
     32+  IF(HAVE_BCRYPT_H)
     33+    LIST(APPEND ADDITIONAL_LIBS "Bcrypt")
     34+  ENDIF(HAVE_BCRYPT_H)
     35 ELSE(ENABLE_CNG)
     36   UNSET(HAVE_BCRYPT_H CACHE)
     37 ENDIF(ENABLE_CNG)
     38@@ -1592,78 +1597,212 @@ ENDIF(ENABLE_XATTR)
     39 # which makes the following checks rather more complex than I would like.
     40 #
     41 IF(ENABLE_ACL)
     42+  # Solaris and derivates ACLs
     43+  CHECK_FUNCTION_EXISTS(acl HAVE_ACL)
     44+  CHECK_FUNCTION_EXISTS(facl HAVE_FACL)
     45+
     46+  # Libacl
     47   CHECK_LIBRARY_EXISTS(acl "acl_get_file" "" HAVE_LIBACL)
     48   IF(HAVE_LIBACL)
     49     SET(CMAKE_REQUIRED_LIBRARIES "acl")
     50     FIND_LIBRARY(ACL_LIBRARY NAMES acl)
     51     LIST(APPEND ADDITIONAL_LIBS ${ACL_LIBRARY})
     52   ENDIF(HAVE_LIBACL)
     53-  #
     54-  CHECK_FUNCTION_EXISTS_GLIBC(acl_create_entry HAVE_ACL_CREATE_ENTRY)
     55-  CHECK_FUNCTION_EXISTS_GLIBC(acl_init HAVE_ACL_INIT)
     56-  CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd HAVE_ACL_SET_FD)
     57-  CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd_np HAVE_ACL_SET_FD_NP)
     58-  CHECK_FUNCTION_EXISTS_GLIBC(acl_set_file HAVE_ACL_SET_FILE)
     59-  CHECK_TYPE_EXISTS(acl_permset_t "${INCLUDES}"    HAVE_ACL_PERMSET_T)
     60-
     61-  # The "acl_get_perm()" function was omitted from the POSIX draft.
     62-  # (It's a pretty obvious oversight; otherwise, there's no way to
     63-  # test for specific permissions in a permset.)  Linux uses the obvious
     64-  # name, FreeBSD adds _np to mark it as "non-Posix extension."
     65-  # Test for both as a double-check that we really have POSIX-style ACL support.
     66-  CHECK_FUNCTION_EXISTS(acl_get_fd_np HAVE_ACL_GET_FD_NP)
     67-  CHECK_FUNCTION_EXISTS(acl_get_perm HAVE_ACL_GET_PERM)
     68-  CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
     69-  CHECK_FUNCTION_EXISTS(acl_get_link HAVE_ACL_GET_LINK)
     70-  CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
     71-  CHECK_FUNCTION_EXISTS(acl_is_trivial_np HAVE_ACL_IS_TRIVIAL_NP)
     72-  CHECK_FUNCTION_EXISTS(acl_set_link_np HAVE_ACL_SET_LINK_NP)
     73-  CHECK_SYMBOL_EXISTS(ACL_TYPE_NFS4 "${INCLUDES}" HAVE_ACL_TYPE_NFS4)
     74-
     75-  # MacOS has an acl.h that isn't POSIX.  It can be detected by
     76-  # checking for ACL_USER
     77-  CHECK_SYMBOL_EXISTS(ACL_USER "${INCLUDES}" HAVE_ACL_USER)
     78-  CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
     79+
     80+  CHECK_TYPE_EXISTS(acl_t "sys/types.h;sys/acl.h" HAVE_ACL_T)
     81+  CHECK_TYPE_EXISTS(acl_entry_t "sys/types.h;sys/acl.h" HAVE_ACL_ENTRY_T)
     82+  CHECK_TYPE_EXISTS(acl_permset_t "sys/types.h;sys/acl.h" HAVE_ACL_PERMSET_T)
     83+  CHECK_TYPE_EXISTS(acl_tag_t "sys/types.h;sys/acl.h" HAVE_ACL_TAG_T)
     84+
     85+  IF(HAVE_ACL AND HAVE_FACL)
     86+    CHECK_TYPE_EXISTS(aclent_t "sys/acl.h" HAVE_ACLENT_T)
     87+    IF(HAVE_ACLENT_T)
     88+      CHECK_SYMBOL_EXISTS(GETACL "sys/acl.h" HAVE_DECL_GETACL)
     89+      CHECK_SYMBOL_EXISTS(GETACLCNT "sys/acl.h" HAVE_DECL_GETACLCNT)
     90+      CHECK_SYMBOL_EXISTS(SETACL "sys/acl.h" HAVE_DECL_SETACL)
     91+      IF(HAVE_DECL_GETACL AND
     92+         HAVE_DECL_GETACLCNT AND
     93+         HAVE_DECL_SETACL)
     94+        SET(ARCHIVE_ACL_SUNOS TRUE)
     95+      ENDIF()
     96+      CHECK_TYPE_EXISTS(ace_t "sys/acl.h" HAVE_ACE_T)
     97+      IF(HAVE_ACE_T)
     98+        CHECK_SYMBOL_EXISTS(ACE_GETACL "sys/acl.h" HAVE_DECL_ACE_GETACL)
     99+        CHECK_SYMBOL_EXISTS(ACE_GETACLCNT "sys/acl.h" HAVE_DECL_ACE_GETACLCNT)
     100+        CHECK_SYMBOL_EXISTS(ACE_SETACL "sys/acl.h" HAVE_DECL_ACE_SETACL)
     101+        IF(HAVE_DECL_ACE_GETACL AND
     102+           HAVE_DECL_ACE_GETACLCNT AND
     103+           HAVE_DECL_ACE_SETACL)
     104+          SET(ARCHIVE_ACL_SUNOS_NFS4 TRUE)
     105+        ENDIF()
     106+      ENDIF(HAVE_ACE_T)
     107+    ENDIF(HAVE_ACLENT_T)
     108+  ENDIF(HAVE_ACL AND HAVE_FACL)
     109+
     110+  IF(HAVE_ACL_T AND HAVE_ACL_ENTRY_T AND HAVE_ACL_PERMSET_T AND HAVE_ACL_TAG_T)
     111+    CHECK_FUNCTION_EXISTS_GLIBC(acl_add_perm HAVE_ACL_ADD_PERM)
     112+    CHECK_FUNCTION_EXISTS_GLIBC(acl_clear_perms HAVE_ACL_CLEAR_PERMS)
     113+    CHECK_FUNCTION_EXISTS_GLIBC(acl_create_entry HAVE_ACL_CREATE_ENTRY)
     114+    CHECK_FUNCTION_EXISTS_GLIBC(acl_delete_def_file HAVE_ACL_DELETE_DEF_FILE)
     115+    CHECK_FUNCTION_EXISTS_GLIBC(acl_free HAVE_ACL_FREE)
     116+    CHECK_FUNCTION_EXISTS_GLIBC(acl_get_entry HAVE_ACL_GET_ENTRY)
     117+    CHECK_FUNCTION_EXISTS_GLIBC(acl_get_fd HAVE_ACL_GET_FD)
     118+    CHECK_FUNCTION_EXISTS_GLIBC(acl_get_file HAVE_ACL_GET_FILE)
     119+    CHECK_FUNCTION_EXISTS_GLIBC(acl_get_permset HAVE_ACL_GET_PERMSET)
     120+    CHECK_FUNCTION_EXISTS_GLIBC(acl_get_qualifier HAVE_ACL_GET_QUALIFIER)
     121+    CHECK_FUNCTION_EXISTS_GLIBC(acl_get_tag_type HAVE_ACL_GET_TAG_TYPE)
     122+    CHECK_FUNCTION_EXISTS_GLIBC(acl_init HAVE_ACL_INIT)
     123+    CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd HAVE_ACL_SET_FD)
     124+    CHECK_FUNCTION_EXISTS_GLIBC(acl_set_file HAVE_ACL_SET_FILE)
     125+    CHECK_FUNCTION_EXISTS_GLIBC(acl_set_qualifier HAVE_ACL_SET_QUALIFIER)
     126+    CHECK_FUNCTION_EXISTS_GLIBC(acl_set_tag_type HAVE_ACL_SET_TAG_TYPE)
     127+    IF(HAVE_ACL_ADD_PERM AND
     128+       HAVE_ACL_CLEAR_PERMS AND
     129+       HAVE_ACL_CREATE_ENTRY AND
     130+       HAVE_ACL_DELETE_DEF_FILE AND
     131+       HAVE_ACL_FREE AND
     132+       HAVE_ACL_GET_ENTRY AND
     133+       HAVE_ACL_GET_FD AND
     134+       HAVE_ACL_GET_FILE AND
     135+       HAVE_ACL_GET_PERMSET AND
     136+       HAVE_ACL_GET_QUALIFIER AND
     137+       HAVE_ACL_GET_TAG_TYPE AND
     138+       HAVE_ACL_INIT AND
     139+       HAVE_ACL_SET_FD AND
     140+       HAVE_ACL_SET_FILE AND
     141+       HAVE_ACL_SET_QUALIFIER AND
     142+       HAVE_ACL_SET_TAG_TYPE)
     143+         SET(HAVE_POSIX_ACL_FUNCS 1)
     144+    ENDIF()
     145+
     146+    CHECK_FUNCTION_EXISTS_GLIBC(acl_get_perm HAVE_ACL_GET_PERM)
     147+
     148+    IF(HAVE_POSIX_ACL_FUNCS AND HAVE_ACL_LIBACL_H AND HAVE_LIBACL AND
     149+       HAVE_ACL_GET_PERM)
     150+      SET(ARCHIVE_ACL_LIBACL TRUE)
     151+    ELSE()
     152+      CHECK_FUNCTION_EXISTS(acl_add_flag_np HAVE_ACL_ADD_FLAG_NP)
     153+      CHECK_FUNCTION_EXISTS(acl_clear_flags_np HAVE_ACL_CLEAR_FLAGS_NP)
     154+      CHECK_FUNCTION_EXISTS(acl_get_brand_np HAVE_ACL_GET_BRAND_NP)
     155+      CHECK_FUNCTION_EXISTS(acl_get_entry_type_np HAVE_ACL_GET_ENTRY_TYPE_NP)
     156+      CHECK_FUNCTION_EXISTS(acl_get_flag_np HAVE_ACL_GET_FLAG_NP)
     157+      CHECK_FUNCTION_EXISTS(acl_get_flagset_np HAVE_ACL_GET_FLAGSET_NP)
     158+      CHECK_FUNCTION_EXISTS(acl_get_fd_np HAVE_ACL_GET_FD_NP)
     159+      CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
     160+      CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
     161+      CHECK_FUNCTION_EXISTS(acl_is_trivial_np HAVE_ACL_IS_TRIVIAL_NP)
     162+      CHECK_FUNCTION_EXISTS(acl_set_entry_type_np HAVE_ACL_SET_ENTRY_TYPE_NP)
     163+      CHECK_FUNCTION_EXISTS(acl_set_fd_np HAVE_ACL_SET_FD_NP)
     164+      CHECK_FUNCTION_EXISTS(acl_set_link_np HAVE_ACL_SET_LINK_NP)
     165+      CHECK_FUNCTION_EXISTS(mbr_gid_to_uuid HAVE_MBR_GID_TO_UUID)
     166+      CHECK_FUNCTION_EXISTS(mbr_uid_to_uuid HAVE_MBR_UID_TO_UUID)
     167+      CHECK_FUNCTION_EXISTS(mbr_uuid_to_id HAVE_MBR_UUID_TO_ID)
     168+
     169+      CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
     170+#include <sys/acl.h>
     171+int main(void) { return ACL_TYPE_EXTENDED; }" HAVE_DECL_ACL_TYPE_EXTENDED)
     172+      CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
     173 #include <sys/acl.h>
     174-int main(void) { return ACL_TYPE_EXTENDED; }" HAVE_ACL_TYPE_EXTENDED)
     175+int main(void) { return ACL_SYNCHRONIZE; }" HAVE_DECL_ACL_SYNCHRONIZE)
     176+      CHECK_SYMBOL_EXISTS(ACL_TYPE_NFS4 "sys/acl.h" HAVE_DECL_ACL_TYPE_NFS4)
     177+      CHECK_SYMBOL_EXISTS(ACL_USER "sys/acl.h" HAVE_DECL_ACL_USER)
     178+
     179+      IF(HAVE_POSIX_ACL_FUNCS AND
     180+         HAVE_ACL_GET_FD_NP AND
     181+         HAVE_ACL_GET_PERM_NP AND
     182+         NOT HAVE_ACL_GET_PERM AND
     183+         HAVE_ACL_SET_FD_NP)
     184+        IF(HAVE_DECL_ACL_USER)
     185+          SET(ARCHIVE_ACL_FREEBSD TRUE)
     186+          IF(HAVE_DECL_ACL_TYPE_NFS4 AND
     187+             HAVE_ACL_ADD_FLAG_NP AND
     188+             HAVE_ACL_CLEAR_FLAGS_NP AND
     189+             HAVE_ACL_GET_BRAND_NP AND
     190+             HAVE_ACL_GET_ENTRY_TYPE_NP AND
     191+             HAVE_ACL_GET_FLAGSET_NP AND
     192+             HAVE_ACL_SET_ENTRY_TYPE_NP)
     193+            SET(ARCHIVE_ACL_FREEBSD_NFS4 TRUE)
     194+          ENDIF()
     195+        ELSEIF(HAVE_DECL_ACL_TYPE_EXTENDED AND
     196+               HAVE_MEMBERSHIP_H AND
     197+               HAVE_ACL_ADD_FLAG_NP AND
     198+               HAVE_ACL_CLEAR_FLAGS_NP AND
     199+               HAVE_ACL_GET_FLAGSET_NP AND
     200+               HAVE_ACL_GET_LINK_NP AND
     201+               HAVE_ACL_SET_LINK_NP AND
     202+               HAVE_MBR_UID_TO_UUID AND
     203+               HAVE_MBR_GID_TO_UUID AND
     204+               HAVE_MBR_UUID_TO_ID)
     205+          SET(ARCHIVE_ACL_DARWIN TRUE)
     206+        ENDIF()
     207+      ENDIF()
     208+    ENDIF()
     209+  ENDIF(HAVE_ACL_T AND HAVE_ACL_ENTRY_T AND HAVE_ACL_PERMSET_T AND
     210+        HAVE_ACL_TAG_T)
     211+
     212+  # Richacl
     213+  CHECK_LIBRARY_EXISTS(richacl "richacl_get_file" "" HAVE_LIBRICHACL)
     214+  IF(HAVE_LIBRICHACL)
     215+    SET(CMAKE_REQUIRED_LIBRARIES "richacl")
     216+    FIND_LIBRARY(RICHACL_LIBRARY NAMES richacl)
     217+    LIST(APPEND ADDITIONAL_LIBS ${RICHACL_LIBRARY})
     218+  ENDIF(HAVE_LIBRICHACL)
     219+
     220+  CHECK_STRUCT_HAS_MEMBER("struct richace" e_type "sys/richacl.h"
     221+    HAVE_STRUCT_RICHACE)
     222+  CHECK_STRUCT_HAS_MEMBER("struct richacl" a_flags "sys/richacl.h"
     223+    HAVE_STRUCT_RICHACL)
     224+
     225+  IF(HAVE_LIBRICHACL AND HAVE_STRUCT_RICHACL AND HAVE_STRUCT_RICHACE)
     226+    CHECK_FUNCTION_EXISTS_GLIBC(richacl_alloc HAVE_RICHACL_ALLOC)
     227+    CHECK_FUNCTION_EXISTS_GLIBC(richacl_equiv_mode HAVE_RICHACL_EQUIV_MODE)
     228+    CHECK_FUNCTION_EXISTS_GLIBC(richacl_free HAVE_RICHACL_FREE)
     229+    CHECK_FUNCTION_EXISTS_GLIBC(richacl_get_fd HAVE_RICHACL_GET_FD)
     230+    CHECK_FUNCTION_EXISTS_GLIBC(richacl_get_file HAVE_RICHACL_GET_FILE)
     231+    CHECK_FUNCTION_EXISTS_GLIBC(richacl_set_fd HAVE_RICHACL_SET_FD)
     232+    CHECK_FUNCTION_EXISTS_GLIBC(richacl_set_file HAVE_RICHACL_SET_FILE)
     233+    IF(HAVE_RICHACL_ALLOC AND
     234+       HAVE_RICHACL_EQUIV_MODE AND
     235+       HAVE_RICHACL_FREE AND
     236+       HAVE_RICHACL_GET_FD AND
     237+       HAVE_RICHACL_GET_FILE AND
     238+       HAVE_RICHACL_SET_FD AND
     239+       HAVE_RICHACL_SET_FILE)
     240+      SET(ARCHIVE_ACL_LIBRICHACL TRUE)
     241+    ENDIF()
     242+  ENDIF(HAVE_LIBRICHACL AND HAVE_STRUCT_RICHACL AND HAVE_STRUCT_RICHACE)
     243+
     244+  IF(ARCHIVE_ACL_DARWIN)
     245+    MESSAGE(STATUS "ACL support: Darwin (limited NFSv4)")
     246+  ELSEIF(ARCHIVE_ACL_FREEBSD_NFS4)
     247+    MESSAGE(STATUS "ACL support: FreeBSD (POSIX.1e and NFSv4)")
     248+  ELSEIF(ARCHIVE_ACL_FREEBSD)
     249+    MESSAGE(STATUS "ACL support: FreeBSD (POSIX.1e)")
     250+  ELSEIF(ARCHIVE_ACL_LIBACL OR ARCHIVE_ACL_LIBRICHACL)
     251+    IF(ARCHIVE_ACL_LIBACL AND ARCHIVE_ACL_LIBRICHACL)
     252+      MESSAGE(STATUS "ACL support: libacl (POSIX.1e) + librichacl (NFSv4)")
     253+    ELSEIF(ARCHIVE_ACL_LIBRICHACL)
     254+      MESSAGE(STATUS "ACL support: librichacl (NFSv4)")
     255+    ELSE()
     256+      MESSAGE(STATUS "ACL support: libacl (POSIX.1e)")
     257+    ENDIF()
     258+  ELSEIF(ARCHIVE_ACL_SUNOS_NFS4)
     259+    MESSAGE(STATUS "ACL support: Solaris (POSIX.1e and NFSv4)")
     260+  ELSEIF(ARCHIVE_ACL_SUNOS)
     261+    MESSAGE(STATUS "ACL support: Solaris (POSIX.1e)")
     262+  ELSE()
     263+    MESSAGE(STATUS "ACL support: none")
     264+  ENDIF()
     265 
     266-  # Solaris and derivates ACLs
     267-  CHECK_LIBRARY_EXISTS(sec "acl_get" "" HAVE_LIBSEC)
     268-  IF(HAVE_LIBSEC)
     269-    SET(CMAKE_REQUIRED_LIBRARIES "sec")
     270-    FIND_LIBRARY(SEC_LIBRARY NAMES sec)
     271-    LIST(APPEND ADDITIONAL_LIBS ${SEC_LIBRARY})
     272-  ENDIF(HAVE_LIBSEC)
     273-  #
     274-  CHECK_TYPE_EXISTS(aclent_t "${INCLUDES}" HAVE_ACLENT_T)
     275-  CHECK_TYPE_EXISTS(ace_t "${INCLUDES}" HAVE_ACE_T)
     276-  CHECK_FUNCTION_EXISTS(acl_get HAVE_FACL_GET)
     277-  CHECK_FUNCTION_EXISTS(facl_get HAVE_FACL_GET)
     278-  CHECK_FUNCTION_EXISTS(acl_set HAVE_FACL_SET)
     279-  CHECK_FUNCTION_EXISTS(facl_set HAVE_FACL_SET)
     280 ELSE(ENABLE_ACL)
     281   # If someone runs cmake, then disables ACL support, we need
     282   # to forcibly override the cached values for these.
     283-  SET(HAVE_ACL_CREATE_ENTRY FALSE)
     284-  SET(HAVE_ACL_GET_LINK FALSE)
     285-  SET(HAVE_ACL_GET_LINK_NP FALSE)
     286-  SET(HAVE_ACL_GET_PERM FALSE)
     287-  SET(HAVE_ACL_GET_PERM_NP FALSE)
     288-  SET(HAVE_ACL_INIT FALSE)
     289-  SET(HAVE_ACL_LIB FALSE)
     290-  SET(HAVE_ACL_PERMSET_T FALSE)
     291-  SET(HAVE_ACL_SET_FD FALSE)
     292-  SET(HAVE_ACL_SET_FD_NP FALSE)
     293-  SET(HAVE_ACL_SET_FILE FALSE)
     294-  SET(HAVE_ACL_TYPE_NFS4 FALSE)
     295-  SET(HAVE_ACL_USER FALSE)
     296-  SET(HAVE_ACL_TYPE_EXTENDED FALSE)
     297-  SET(HAVE_ACL_GET FALSE)
     298-  SET(HAVE_ACLENT_T FALSE)
     299-  SET(HAVE_ACE_T FALSE)
     300-  SET(HAVE_FACL_GET FALSE)
     301-  SET(HAVE_ACL_SET FALSE)
     302-  SET(HAVE_FACL_SET FALSE)
     303+  SET(ARCHIVE_ACL_DARWIN FALSE)
     304+  SET(ARCHIVE_ACL_FREEBSD FALSE)
     305+  SET(ARCHIVE_ACL_FREEBSD_NFS4 FALSE)
     306+  SET(ARCHIVE_ACL_LIBACL FALSE)
     307+  SET(ARCHIVE_ACL_SUNOS FALSE)
     308+  SET(ARCHIVE_ACL_SUNOS_NFS4 FALSE)
     309 ENDIF(ENABLE_ACL)
     310 
     311 #
     312--- Makefile.am.orig
     313+++ Makefile.am
     314@@ -23,7 +23,7 @@ TESTS_ENVIRONMENT= $(libarchive_TESTS_ENVIRONMENT) $(bsdtar_TESTS_ENVIRONMENT) $
     315 DISTCHECK_CONFIGURE_FLAGS = --enable-bsdtar --enable-bsdcpio
     316 # The next line is commented out by default in shipping libarchive releases.
     317 # It is uncommented by default in trunk.
     318-# DEV_CFLAGS=-Werror -Wextra -Wunused -Wshadow -Wmissing-prototypes -Wcast-qual -g
     319+DEV_CFLAGS=-Werror -Wextra -Wunused -Wshadow -Wmissing-prototypes -Wcast-qual -g
     320 AM_CFLAGS=$(DEV_CFLAGS)
     321 PLATFORMCPPFLAGS = @PLATFORMCPPFLAGS@
     322 AM_CPPFLAGS=$(PLATFORMCPPFLAGS)
     323@@ -127,6 +127,7 @@ libarchive_la_SOURCES= \
     324        libarchive/archive_pathmatch.c \
     325        libarchive/archive_pathmatch.h \
     326        libarchive/archive_platform.h \
     327+       libarchive/archive_platform_acl.h \
     328        libarchive/archive_ppmd_private.h \
     329        libarchive/archive_ppmd7.c \
     330        libarchive/archive_ppmd7_private.h \
     331@@ -186,9 +187,9 @@ libarchive_la_SOURCES= \
     332        libarchive/archive_string_composition.h \
     333        libarchive/archive_string_sprintf.c \
     334        libarchive/archive_util.c \
     335+       libarchive/archive_version_details.c \
     336        libarchive/archive_virtual.c \
     337        libarchive/archive_write.c \
     338-       libarchive/archive_write_disk_acl.c \
     339        libarchive/archive_write_disk_posix.c \
     340        libarchive/archive_write_disk_private.h \
     341        libarchive/archive_write_disk_set_standard_lookup.c \
     342@@ -247,6 +248,38 @@ libarchive_la_SOURCES+= \
     343        libarchive/filter_fork_windows.c
     344 endif
     345 
     346+if INC_LINUX_ACL
     347+libarchive_la_SOURCES+= \
     348+       libarchive/archive_acl_maps.h \
     349+       libarchive/archive_acl_maps_linux.c \
     350+       libarchive/archive_read_disk_acl_linux.c \
     351+       libarchive/archive_write_disk_acl_linux.c
     352+else
     353+if INC_SUNOS_ACL
     354+libarchive_la_SOURCES+= \
     355+       libarchive/archive_acl_maps.h \
     356+       libarchive/archive_acl_maps_sunos.c \
     357+       libarchive/archive_read_disk_acl_sunos.c \
     358+       libarchive/archive_write_disk_acl_sunos.c
     359+else
     360+if INC_DARWIN_ACL
     361+libarchive_la_SOURCES+= \
     362+       libarchive/archive_acl_maps.h \
     363+       libarchive/archive_acl_maps_darwin.c \
     364+       libarchive/archive_read_disk_acl_darwin.c \
     365+       libarchive/archive_write_disk_acl_darwin.c
     366+else
     367+if INC_FREEBSD_ACL
     368+libarchive_la_SOURCES+= \
     369+       libarchive/archive_acl_maps.h \
     370+       libarchive/archive_acl_maps_freebsd.c \
     371+       libarchive/archive_read_disk_acl_freebsd.c \
     372+       libarchive/archive_write_disk_acl_freebsd.c
     373+endif
     374+endif
     375+endif
     376+endif
     377+
     378 # -no-undefined marks that libarchive doesn't rely on symbols
     379 # defined in the application.  This is mandatory for cygwin.
     380 libarchive_la_LDFLAGS= -no-undefined -version-info $(ARCHIVE_LIBTOOL_VERSION)
     381@@ -951,10 +984,12 @@ bsdtar_test_SOURCES= \
     382        tar/test/test_option_T_upper.c \
     383        tar/test/test_option_U_upper.c \
     384        tar/test/test_option_X_upper.c \
     385+       tar/test/test_option_acls.c \
     386        tar/test/test_option_a.c \
     387        tar/test/test_option_b.c \
     388        tar/test/test_option_b64encode.c \
     389        tar/test/test_option_exclude.c \
     390+       tar/test/test_option_fflags.c \
     391        tar/test/test_option_gid_gname.c \
     392        tar/test/test_option_grzip.c \
     393        tar/test/test_option_j.c \
     394--- NEWS.orig
     395+++ NEWS
     396@@ -1,3 +1,5 @@
     397+Mar 16, 2017: NFSv4 ACL support for Linux (librichacl)
     398+
     399 Feb 26, 2017: libarchive 3.3.1 released
     400     Security & Feature release
     401 
     402@@ -293,7 +295,7 @@ May 04, 2008: libarchive 2.5.3b released
     403        * libarchive: Mark which entry strings are set; be accurate about
     404          distinguishing empty strings ("") from unset ones (NULL)
     405        * tar: Don't crash reading entries with empty filenames
     406-       * libarchive_test, bsdtar_test, bsdcpio_test:  Better detaults:
     407+       * libarchive_test, bsdtar_test, bsdcpio_test:  Better defaults:
     408          run all tests, delete temp dirs, summarize repeated failures
     409        * -no-undefined to libtool for Cygwin
     410        * libarchive_test: Skip large file tests on systems with 32-bit off_t
     411--- build/cmake/config.h.in.orig
     412+++ build/cmake/config.h.in
     413@@ -179,6 +179,27 @@ typedef uint64_t uintmax_t;
     414 /* Define ZLIB_WINAPI if zlib was built on Visual Studio. */
     415 #cmakedefine ZLIB_WINAPI 1
     416 
     417+/* Darwin ACL support */
     418+#cmakedefine ARCHIVE_ACL_DARWIN 1
     419+
     420+/* FreeBSD ACL support */
     421+#cmakedefine ARCHIVE_ACL_FREEBSD 1
     422+
     423+/* FreeBSD NFSv4 ACL support */
     424+#cmakedefine ARCHIVE_ACL_FREEBSD_NFS4 1
     425+
     426+/* Linux POSIX.1e ACL support via libacl */
     427+#cmakedefine ARCHIVE_ACL_LIBACL 1
     428+
     429+/* Linux NFSv4 ACL support via librichacl */
     430+#cmakedefine ARCHIVE_ACL_LIBRICHACL 1
     431+
     432+/* Solaris ACL support */
     433+#cmakedefine ARCHIVE_ACL_SUNOS 1
     434+
     435+/* Solaris NFSv4 ACL support */
     436+#cmakedefine ARCHIVE_ACL_SUNOS_NFS4 1
     437+
     438 /* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */
     439 #cmakedefine ARCHIVE_CRYPTO_MD5_LIBC 1
     440 
     441@@ -326,15 +347,6 @@ typedef uint64_t uintmax_t;
     442 /* Define to 1 if you have the `acl_set_file' function. */
     443 #cmakedefine HAVE_ACL_SET_FILE 1
     444 
     445-/* True for FreeBSD with NFSv4 ACL support */
     446-#cmakedefine HAVE_ACL_TYPE_NFS4 1
     447-
     448-/* True for MacOS ACL support */
     449-#cmakedefine HAVE_ACL_TYPE_EXTENDED 1
     450-
     451-/* True for systems with POSIX ACL support */
     452-#cmakedefine HAVE_ACL_USER 1
     453-
     454 /* Define to 1 if you have the `arc4random_buf' function. */
     455 #cmakedefine HAVE_ARC4RANDOM_BUF 1
     456 
     457@@ -371,6 +383,34 @@ typedef uint64_t uintmax_t;
     458 /* Define to 1 if you have the `cygwin_conv_path' function. */
     459 #cmakedefine HAVE_CYGWIN_CONV_PATH 1
     460 
     461+/* Define to 1 if you have the declaration of `ACE_GETACL', and to 0 if you
     462+   don't. */
     463+#cmakedefine HAVE_DECL_ACE_GETACL 1
     464+
     465+/* Define to 1 if you have the declaration of `ACE_GETACLCNT', and to 0 if you
     466+   don't. */
     467+#cmakedefine HAVE_DECL_ACE_GETACLCNT 1
     468+
     469+/* Define to 1 if you have the declaration of `ACE_SETACL', and to 0 if you
     470+   don't. */
     471+#cmakedefine HAVE_DECL_ACE_SETACL 1
     472+
     473+/* Define to 1 if you have the declaration of `ACL_SYNCHRONIZE', and to 0 if
     474+   you don't. */
     475+#cmakedefine HAVE_DECL_ACL_SYNCHRONIZE 1
     476+
     477+/* Define to 1 if you have the declaration of `ACL_TYPE_EXTENDED', and to 0 if
     478+   you don't. */
     479+#cmakedefine HAVE_DECL_ACL_TYPE_EXTENDED 1
     480+
     481+/* Define to 1 if you have the declaration of `ACL_TYPE_NFS4', and to 0 if you
     482+   don't. */
     483+#cmakedefine HAVE_DECL_ACL_TYPE_NFS4 1
     484+
     485+/* Define to 1 if you have the declaration of `ACL_USER', and to 0 if you
     486+   don't. */
     487+#cmakedefine HAVE_DECL_ACL_USER 1
     488+
     489 /* Define to 1 if you have the declaration of `INT32_MAX', and to 0 if you
     490    don't. */
     491 #cmakedefine HAVE_DECL_INT32_MAX 1
     492@@ -395,6 +435,10 @@ typedef uint64_t uintmax_t;
     493    don't. */
     494 #cmakedefine HAVE_DECL_INTMAX_MIN 1
     495 
     496+/* Define to 1 if you have the declaration of `SETACL', and to 0 if you don't.
     497+   */
     498+#cmakedefine HAVE_DECL_SETACL 1
     499+
     500 /* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
     501    don't. */
     502 #cmakedefine HAVE_DECL_SIZE_MAX 1
     503@@ -468,6 +512,14 @@ typedef uint64_t uintmax_t;
     504 /* Define to 1 if EXTATTR_NAMESPACE_USER is defined in sys/extattr.h. */
     505 #cmakedefine HAVE_DECL_EXTATTR_NAMESPACE_USER 1
     506 
     507+/* Define to 1 if you have the declaration of `GETACL', and to 0 if you don't.
     508+   */
     509+#cmakedefine HAVE_DECL_GETACL 1
     510+
     511+/* Define to 1 if you have the declaration of `GETACLCNT', and to 0 if you
     512+   don't. */
     513+#cmakedefine HAVE_DECL_GETACLCNT 1
     514+
     515 /* Define to 1 if you have the `fchdir' function. */
     516 #cmakedefine HAVE_FCHDIR 1
     517 
     518@@ -742,6 +794,9 @@ typedef uint64_t uintmax_t;
     519 /* Define to 1 if you have the `mbrtowc' function. */
     520 #cmakedefine HAVE_MBRTOWC 1
     521 
     522+/* Define to 1 if you have the <membership.h> header file. */
     523+#cmakedefine HAVE_MEMBERSHIP_H 1
     524+
     525 /* Define to 1 if you have the `memmove' function. */
     526 #cmakedefine HAVE_MEMMOVE 1
     527 
     528@@ -979,6 +1034,9 @@ typedef uint64_t uintmax_t;
     529 /* Define to 1 if you have the <sys/poll.h> header file. */
     530 #cmakedefine HAVE_SYS_POLL_H 1
     531 
     532+/* Define to 1 if you have the <sys/richacl.h> header file. */
     533+#cmakedefine HAVE_SYS_RICHACL_H 1
     534+
     535 /* Define to 1 if you have the <sys/select.h> header file. */
     536 #cmakedefine HAVE_SYS_SELECT_H 1
     537 
     538--- build/version.orig
     539+++ build/version
     540@@ -1 +1 @@
     541-3003001
     542+3003002dev
     543--- cat/test/CMakeLists.txt.orig
     544+++ cat/test/CMakeLists.txt
     545@@ -29,6 +29,16 @@ IF(ENABLE_CAT AND ENABLE_TEST)
     546   # Register target
     547   #
     548   ADD_EXECUTABLE(bsdcat_test ${bsdcat_test_SOURCES})
     549+  IF(ENABLE_ACL)
     550+    SET(TEST_ACL_LIBS "")
     551+    IF(HAVE_LIBACL)
     552+      LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY})
     553+    ENDIF(HAVE_LIBACL)
     554+    IF(HAVE_LIBRICHACL)
     555+      LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY})
     556+    ENDIF(HAVE_LIBRICHACL)
     557+    TARGET_LINK_LIBRARIES(bsdcat_test ${TEST_ACL_LIBS})
     558+  ENDIF(ENABLE_ACL)
     559   SET_PROPERTY(TARGET bsdcat_test PROPERTY COMPILE_DEFINITIONS LIST_H)
     560 
     561   #
     562--- configure.ac.orig
     563+++ configure.ac
     564@@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front.
     565 dnl In particular, this allows the version macro to be used in AC_INIT
     566 
     567 dnl These first two version numbers are updated automatically on each release.
     568-m4_define([LIBARCHIVE_VERSION_S],[3.3.1])
     569-m4_define([LIBARCHIVE_VERSION_N],[3003001])
     570+m4_define([LIBARCHIVE_VERSION_S],[3.3.2dev])
     571+m4_define([LIBARCHIVE_VERSION_N],[3003002])
     572 
     573 dnl bsdtar and bsdcpio versioning tracks libarchive
     574 m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
     575@@ -253,6 +253,7 @@ esac
     576 # Checks for header files.
     577 AC_HEADER_DIRENT
     578 AC_HEADER_SYS_WAIT
     579+AC_CHECK_HEADERS([acl/libacl.h])
     580 AC_CHECK_HEADERS([copyfile.h ctype.h])
     581 AC_CHECK_HEADERS([errno.h ext2fs/ext2_fs.h fcntl.h grp.h])
     582 
     583@@ -283,16 +284,16 @@ AS_VAR_IF([ac_cv_have_decl_FS_IOC_GETFLAGS], [yes],
     584     [AC_DEFINE_UNQUOTED([HAVE_WORKING_FS_IOC_GETFLAGS], [1],
     585                     [Define to 1 if you have a working FS_IOC_GETFLAGS])])
     586 
     587-AC_CHECK_HEADERS([locale.h paths.h poll.h pthread.h pwd.h])
     588+AC_CHECK_HEADERS([locale.h membership.h paths.h poll.h pthread.h pwd.h])
     589 AC_CHECK_HEADERS([readpassphrase.h signal.h spawn.h])
     590 AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h])
     591-AC_CHECK_HEADERS([sys/cdefs.h sys/extattr.h])
     592+AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h])
     593 AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h])
     594-AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/statfs.h sys/statvfs.h])
     595+AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/richacl.h])
     596+AC_CHECK_HEADERS([sys/select.h sys/statfs.h sys/statvfs.h])
     597 AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h])
     598 AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h])
     599 AC_CHECK_HEADERS([windows.h])
     600-AC_CHECK_HEADERS([Bcrypt.h])
     601 # check windows.h first; the other headers require it.
     602 AC_CHECK_HEADERS([wincrypt.h winioctl.h],[],[],
     603 [[#ifdef HAVE_WINDOWS_H
     604@@ -399,6 +400,9 @@ if test "x$with_lzo2" = "xyes"; then
     605   AC_CHECK_LIB(lzo2,lzo1x_decompress_safe)
     606 fi
     607 
     608+AC_ARG_WITH([cng],
     609+  AS_HELP_STRING([--without-cng], [Don't build support of CNG(Crypto Next Generation)]))
     610+
     611 AC_ARG_WITH([nettle],
     612   AS_HELP_STRING([--without-nettle], [Don't build with crypto support from Nettle]))
     613 AC_ARG_WITH([openssl],
     614@@ -697,72 +701,211 @@ AC_ARG_ENABLE([acl],
     615                [Disable ACL support (default: check)]))
     616 
     617 if test "x$enable_acl" != "xno"; then
     618-   AC_CHECK_HEADERS([acl/libacl.h])
     619-   AC_CHECK_HEADERS([sys/acl.h])
     620-   AC_CHECK_LIB([acl],[acl_get_file])
     621-   AC_CHECK_FUNCS([acl_create_entry acl_get_fd_np])
     622-   AC_CHECK_FUNCS([acl_init acl_set_fd acl_set_fd_np acl_set_file])
     623+    # Libacl
     624+    AC_CHECK_LIB([acl], [acl_get_file])
     625+
     626+    AC_CHECK_TYPES([acl_t, acl_entry_t, acl_permset_t, acl_tag_t], [], [], [
     627+      #if HAVE_SYS_TYPES_H
     628+      #include <sys/types.h>
     629+      #endif
     630+      #if HAVE_SYS_ACL_H
     631+      #include <sys/acl.h>
     632+      #endif
     633+    ])
     634+
     635+    AC_CHECK_LIB([richacl], [richacl_get_file])
     636+
     637+    AC_CHECK_TYPES([[struct richace], [struct richacl]], [], [], [
     638+      #if HAVE_SYS_RICHACL_H
     639+      #include <sys/richacl.h>
     640+      #endif
     641+    ])
     642 
     643-   AC_CHECK_TYPES(acl_permset_t,,,
     644-       [#if HAVE_SYS_TYPES_H
     645-       #include <sys/types.h>
     646-       #endif
     647-       #if HAVE_SYS_ACL_H
     648-       #include <sys/acl.h>
     649-       #endif
     650-       ])
     651-
     652-    # The "acl_get_perm()" function was omitted from the POSIX draft.
     653-    # (It's a pretty obvious oversight; otherwise, there's no way to
     654-    # test for specific permissions in a permset.)  Linux uses the obvious
     655-    # name, FreeBSD adds _np to mark it as "non-Posix extension."
     656-    # Test for both as a double-check that we really have POSIX-style ACL
     657-    # support.
     658-    AC_CHECK_FUNCS(acl_get_perm_np acl_get_perm acl_get_link acl_get_link_np,,,
     659-       [#if HAVE_SYS_TYPES_H
     660-       #include <sys/types.h>
     661-       #endif
     662-       #if HAVE_SYS_ACL_H
     663-       #include <sys/acl.h>
     664-       #endif
     665-       ])
     666+    # Solaris and derivates ACLs
     667+    AC_CHECK_FUNCS(acl facl)
     668+
     669+    if test "x$ac_cv_lib_richacl_richacl_get_file" = "xyes" \
     670+        -a "x$ac_cv_type_struct_richace" = "xyes" \
     671+        -a "x$ac_cv_type_struct_richacl" = "xyes"; then
     672+       AC_CACHE_VAL([ac_cv_archive_acl_librichacl],
     673+         [AC_CHECK_FUNCS(richacl_alloc \
     674+                         richacl_equiv_mode \
     675+                         richacl_free \
     676+                         richacl_get_fd \
     677+                         richacl_get_file \
     678+                         richacl_set_fd \
     679+                         richacl_set_file,
     680+         [ac_cv_archive_acl_librichacl=yes], [ac_cv_archive_acl_librichacl=no],          [#include <sys/richacl.h>])])
     681+    fi
     682 
     683-    # Check for acl_is_trivial_np on FreeBSD
     684-    AC_CHECK_FUNCS(acl_is_trivial_np,,,
     685-       [#if HAVE_SYS_TYPES_H
     686-       #include <sys/types.h>
     687-       #endif
     688-       #if HAVE_SYS_ACL_H
     689-       #include <sys/acl.h>
     690-       #endif
     691+    if test "x$ac_cv_func_acl" = "xyes" \
     692+        -a "x$ac_cv_func_facl" = "xyes"; then
     693+       AC_CHECK_TYPES([aclent_t], [], [], [[#include <sys/acl.h>]])
     694+       if test "x$ac_cv_type_aclent_t" = "xyes"; then
     695+           AC_CACHE_VAL([ac_cv_archive_acl_sunos],
     696+             [AC_CHECK_DECLS([GETACL, SETACL, GETACLCNT],
     697+             [ac_cv_archive_acl_sunos=yes], [ac_cv_archive_acl_sunos=no],
     698+             [#include <sys/acl.h>])])
     699+           AC_CHECK_TYPES([ace_t], [], [], [[#include <sys/acl.h>]])
     700+           if test "x$ac_cv_type_ace_t" = "xyes"; then
     701+               AC_CACHE_VAL([ac_cv_archive_acl_sunos_nfs4],
     702+                 [AC_CHECK_DECLS([ACE_GETACL, ACE_SETACL, ACE_GETACLCNT],
     703+                 [ac_cv_archive_acl_sunos_nfs4=yes],
     704+                 [ac_cv_archive_acl_sonos_nfs4=no],
     705+                 [#include <sys/acl.h>])])
     706+           fi
     707+       fi
     708+    elif test "x$ac_cv_type_acl_t" = "xyes" \
     709+        -a "x$ac_cv_type_acl_entry_t" = "xyes" \
     710+        -a "x$ac_cv_type_acl_permset_t" = "xyes" \
     711+        -a "x$ac_cv_type_acl_tag_t" = "xyes"; then
     712+       # POSIX.1e ACL functions
     713+       AC_CACHE_VAL([ac_cv_posix_acl_funcs],
     714+         [AC_CHECK_FUNCS(acl_add_perm \
     715+                         acl_clear_perms \
     716+                         acl_create_entry \
     717+                         acl_delete_def_file \
     718+                         acl_free \
     719+                         acl_get_entry \
     720+                         acl_get_fd \
     721+                         acl_get_file \
     722+                         acl_get_permset \
     723+                         acl_get_qualifier \
     724+                         acl_get_tag_type \
     725+                         acl_init \
     726+                         acl_set_fd \
     727+                         acl_set_file \
     728+                         acl_set_qualifier \
     729+                         acl_set_tag_type,
     730+         [ac_cv_posix_acl_funcs=yes], [ac_cv_posix_acl_funcs=no],
     731+         [#if HAVE_SYS_TYPES_H
     732+          #include <sys/types.h>
     733+          #endif
     734+          #if HAVE_SYS_ACL_H
     735+          #include <sys/acl.h>
     736+          #endif
     737+         ])
     738        ])
     739 
     740-    # Check for ACL_TYPE_NFS4
     741-    AC_CHECK_DECL([ACL_TYPE_NFS4],
     742-               [AC_DEFINE(HAVE_ACL_TYPE_NFS4, 1, [True for FreeBSD with NFSv4 ACL support])],
     743-               [],
     744-               [#include <sys/acl.h>])
     745+       AC_CHECK_FUNCS(acl_get_perm)
     746 
     747-    # MacOS has an acl.h that isn't POSIX.  It can be detected by
     748-    # checking for ACL_USER
     749-    AC_CHECK_DECL([ACL_USER],
     750-               [AC_DEFINE(HAVE_ACL_USER, 1, [True for systems with POSIX ACL support])],
     751-               [],
     752-               [#include <sys/acl.h>])
     753+       if test "x$ac_cv_posix_acl_funcs" = "xyes" \
     754+            -a "x$ac_cv_header_acl_libacl_h" = "xyes" \
     755+            -a "x$ac_cv_lib_acl_acl_get_file" = "xyes" \
     756+            -a "x$ac_cv_func_acl_get_perm"; then
     757+           AC_CACHE_VAL([ac_cv_archive_acl_libacl],
     758+             [ac_cv_archive_acl_libacl=yes])
     759+           AC_DEFINE([ARCHIVE_ACL_LIBACL], [1],
     760+             [POSIX.1e ACL support via libacl])
     761+       else
     762+            # FreeBSD/Darwin
     763+            AC_CHECK_FUNCS(acl_add_flag_np \
     764+                           acl_clear_flags_np \
     765+                           acl_get_brand_np \
     766+                           acl_get_entry_type_np \
     767+                           acl_get_flag_np \
     768+                           acl_get_flagset_np \
     769+                           acl_get_fd_np \
     770+                           acl_get_link_np \
     771+                           acl_get_perm_np \
     772+                           acl_is_trivial_np \
     773+                           acl_set_entry_type_np \
     774+                           acl_set_fd_np \
     775+                           acl_set_link_np,,,
     776+             [#include <sys/types.h>
     777+              #include <sys/acl.h>])
     778+
     779+           AC_CHECK_FUNCS(mbr_uid_to_uuid \
     780+                          mbr_uuid_to_id \
     781+                          mbr_gid_to_uuid,,,
     782+             [#include <membership.h>])
     783+
     784+           AC_CHECK_DECLS([ACL_TYPE_EXTENDED, ACL_TYPE_NFS4, ACL_USER,
     785+             ACL_SYNCHRONIZE], [], [],
     786+             [#include <sys/types.h>
     787+              #include <sys/acl.h>])
     788+           if test "x$ac_cv_posix_acl_funcs" = "xyes" \
     789+                -a "x$ac_cv_func_acl_get_fd_np" = "xyes" \
     790+                 -a "x$ac_cv_func_acl_get_perm" != "xyes" \
     791+                -a "x$ac_cv_func_acl_get_perm_np" = "xyes" \
     792+                -a "x$ac_cv_func_acl_set_fd_np" = "xyes"; then
     793+               if test "x$ac_cv_have_decl_ACL_USER" = "xyes"; then
     794+                   AC_CACHE_VAL([ac_cv_archive_acl_freebsd],
     795+                     [ac_cv_archive_acl_freebsd=yes])
     796+                   if test "x$ac_cv_have_decl_ACL_TYPE_NFS4" = "xyes" \
     797+                        -a "x$ac_cv_func_acl_add_flag_np" = "xyes" \
     798+                        -a "x$ac_cv_func_acl_get_brand_np" = "xyes" \
     799+                        -a "x$ac_cv_func_acl_get_entry_type_np" = "xyes" \
     800+                        -a "x$ac_cv_func_acl_get_flagset_np" = "xyes" \
     801+                        -a "x$ac_cv_func_acl_set_entry_type_np" = "xyes"; then
     802+                       AC_CACHE_VAL([ac_cv_archive_acl_freebsd_nfs4],
     803+                         [ac_cv_archive_acl_freebsd_nfs4=yes])
     804+                   fi
     805+               elif test "x$ac_cv_have_decl_ACL_TYPE_EXTENDED" = "xyes" \
     806+                      -a "x$ac_cv_func_acl_add_flag_np" = "xyes" \
     807+                      -a "x$ac_cv_func_acl_get_flagset_np" = "xyes" \
     808+                      -a "x$ac_cv_func_acl_get_link_np" = "xyes" \
     809+                      -a "x$ac_cv_func_acl_set_link_np" = "xyes" \
     810+                      -a "x$ac_cv_func_mbr_uid_to_uuid" = "xyes" \
     811+                      -a "x$ac_cv_func_mbr_uuid_to_id" = "xyes" \
     812+                      -a "x$ac_cv_func_mbr_gid_to_uuid" = "xyes"; then
     813+                   AC_CACHE_VAL([ac_cv_archive_acl_darwin],
     814+                     [ac_cv_archive_acl_darwin=yes])
     815+               fi
     816+           fi
     817+       fi
     818+    fi
     819+    AC_MSG_CHECKING([for ACL support])
     820+    if test "x$ac_cv_archive_acl_libacl" = "xyes" \
     821+        -a "x$ac_cv_archive_acl_librichacl" = "xyes"; then
     822+       AC_MSG_RESULT([libacl (POSIX.1e) + librichacl (NFSv4)])
     823+       AC_DEFINE([ARCHIVE_ACL_LIBACL], [1],
     824+         [Linux POSIX.1e ACL support via libacl])
     825+       AC_DEFINE([ARCHIVE_ACL_LIBRICHACL], [1],
     826+         [Linux NFSv4 ACL support via librichacl])
     827+    elif test "x$ac_cv_archive_acl_libacl" = "xyes"; then
     828+       AC_MSG_RESULT([libacl (POSIX.1e)])
     829+       AC_DEFINE([ARCHIVE_ACL_LIBACL], [1],
     830+         [Linux POSIX.1e ACL support via libacl])
     831+    elif test "x$ac_cv_archive_acl_librichacl" = "xyes"; then
     832+       AC_MSG_RESULT([librichacl (NFSv4)])
     833+       AC_DEFINE([ARCHIVE_ACL_LIBRICHACL], [1],
     834+         [Linux NFSv4 ACL support via librichacl])
     835+    elif test "x$ac_cv_archive_acl_darwin" = "xyes"; then
     836+       AC_DEFINE([ARCHIVE_ACL_DARWIN], [1], [Darwin ACL support])
     837+       AC_MSG_RESULT([Darwin (limited NFSv4)])
     838+    elif test "x$ac_cv_archive_acl_sunos" = "xyes"; then
     839+       AC_DEFINE([ARCHIVE_ACL_SUNOS], [1], [Solaris ACL support])
     840+       if test "x$ac_cv_archive_acl_sunos_nfs4" = "xyes"; then
     841+           AC_DEFINE([ARCHIVE_ACL_SUNOS_NFS4], [1],
     842+             [Solaris NFSv4 ACL support])
     843+           AC_MSG_RESULT([Solaris (POSIX.1e and NFSv4)])
     844+       else
     845+           AC_MSG_RESULT([Solaris (POSIX.1e)])
     846+       fi
     847+    elif test "x$ac_cv_archive_acl_freebsd" = "xyes"; then
     848+       AC_DEFINE([ARCHIVE_ACL_FREEBSD], [1], [FreeBSD ACL support])
     849+       if test "x$ac_cv_archive_acl_freebsd_nfs4" = "xyes"; then
     850+           AC_DEFINE([ARCHIVE_ACL_FREEBSD_NFS4], [1],
     851+             [FreeBSD NFSv4 ACL support])
     852+           AC_MSG_RESULT([FreeBSD (POSIX.1e and NFSv4)])
     853+       else
     854+           AC_MSG_RESULT([FreeBSD (POSIX.1e)])
     855+       fi
     856+    else
     857+       AC_MSG_RESULT([none])
     858+    fi
     859+fi
     860 
     861-    # MacOS has ACL_TYPE_EXTENDED instead
     862-    AC_CHECK_DECL([ACL_TYPE_EXTENDED],
     863-               [AC_DEFINE(HAVE_ACL_TYPE_EXTENDED, 1, [True for MacOS ACL support])],
     864-               [],
     865-               [#include <sys/types.h>
     866-               #include <sys/acl.h>])
     867 
     868-    # Solaris and derivates ACLs
     869-    AC_CHECK_LIB([sec], [acl_get])
     870-    AC_CHECK_TYPES([aclent_t], [], [], [[#include <sys/acl.h>]])
     871-    AC_CHECK_TYPES([ace_t], [], [], [[#include <sys/acl.h>]])
     872-    AC_CHECK_FUNCS(acl_get facl_get acl_set facl_set)
     873-fi
     874+AM_CONDITIONAL([INC_LINUX_ACL],
     875+  [test "x$ac_cv_archive_acl_libacl" = "xyes" \
     876+     -o "x$ac_cv_archive_acl_librichacl" = "xyes"])
     877+AM_CONDITIONAL([INC_SUNOS_ACL], [test "x$ac_cv_archive_acl_sunos" = "xyes"])
     878+AM_CONDITIONAL([INC_DARWIN_ACL],
     879+         [test "x$ac_cv_archive_acl_darwin" = "xyes"])
     880+AM_CONDITIONAL([INC_FREEBSD_ACL],
     881+         [test "x$ac_cv_archive_acl_freebsd" = "xyes"])
     882 
     883 # Additional requirements
     884 AC_SYS_LARGEFILE
     885@@ -852,6 +995,16 @@ case "$host_os" in
     886        ;;
     887 esac
     888 
     889+if test "x$with_cng" != "xno"; then
     890+    AC_CHECK_HEADERS([bcrypt.h],[
     891+        LIBS="$LIBS -lbcrypt"
     892+    ],[],
     893+    [[#ifdef HAVE_WINDOWS_H
     894+    # include <windows.h>
     895+    #endif
     896+    ]])
     897+fi
     898+
     899 if test "x$with_nettle" != "xno"; then
     900     AC_CHECK_HEADERS([nettle/md5.h nettle/ripemd160.h nettle/sha.h])
     901     AC_CHECK_HEADERS([nettle/pbkdf2.h nettle/aes.h nettle/hmac.h])
     902--- cpio/cpio.c.orig
     903+++ cpio/cpio.c
     904@@ -108,22 +108,22 @@ static int        entry_to_archive(struct cpio *, struct archive_entry *);
     905 static int     file_to_archive(struct cpio *, const char *);
     906 static void    free_cache(struct name_cache *cache);
     907 static void    list_item_verbose(struct cpio *, struct archive_entry *);
     908-static void    long_help(void);
     909+static void    long_help(void) __LA_DEAD;
     910 static const char *lookup_gname(struct cpio *, gid_t gid);
     911 static int     lookup_gname_helper(struct cpio *,
     912                    const char **name, id_t gid);
     913 static const char *lookup_uname(struct cpio *, uid_t uid);
     914 static int     lookup_uname_helper(struct cpio *,
     915                    const char **name, id_t uid);
     916-static void    mode_in(struct cpio *);
     917-static void    mode_list(struct cpio *);
     918+static void    mode_in(struct cpio *) __LA_DEAD;
     919+static void    mode_list(struct cpio *) __LA_DEAD;
     920 static void    mode_out(struct cpio *);
     921 static void    mode_pass(struct cpio *, const char *);
     922 static const char *remove_leading_slash(const char *);
     923 static int     restore_time(struct cpio *, struct archive_entry *,
     924                    const char *, int fd);
     925-static void    usage(void);
     926-static void    version(void);
     927+static void    usage(void) __LA_DEAD;
     928+static void    version(void) __LA_DEAD;
     929 static const char * passphrase_callback(struct archive *, void *);
     930 static void    passphrase_free(char *);
     931 
     932@@ -1344,23 +1344,23 @@ lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable,
     933                cache->cache[slot].name = NULL;
     934        }
     935 
     936-       if (lookup_fn(cpio, &name, id) == 0) {
     937-               if (name == NULL || name[0] == '\0') {
     938-                       /* If lookup failed, format it as a number. */
     939-                       snprintf(asnum, sizeof(asnum), "%u", (unsigned)id);
     940-                       name = asnum;
     941-               }
     942-               cache->cache[slot].name = strdup(name);
     943-               if (cache->cache[slot].name != NULL) {
     944-                       cache->cache[slot].id = id;
     945-                       return (cache->cache[slot].name);
     946-               }
     947-               /*
     948-                * Conveniently, NULL marks an empty slot, so
     949-                * if the strdup() fails, we've just failed to
     950-                * cache it.  No recovery necessary.
     951-                */
     952+       if (lookup_fn(cpio, &name, id)) {
     953+               /* If lookup failed, format it as a number. */
     954+               snprintf(asnum, sizeof(asnum), "%u", (unsigned)id);
     955+               name = asnum;
     956+       }
     957+
     958+       cache->cache[slot].name = strdup(name);
     959+       if (cache->cache[slot].name != NULL) {
     960+               cache->cache[slot].id = id;
     961+               return (cache->cache[slot].name);
     962        }
     963+
     964+       /*
     965+        * Conveniently, NULL marks an empty slot, so
     966+        * if the strdup() fails, we've just failed to
     967+        * cache it.  No recovery necessary.
     968+        */
     969        return (NULL);
     970 }
     971 
     972@@ -1381,15 +1381,14 @@ lookup_uname_helper(struct cpio *cpio, const char **name, id_t id)
     973        errno = 0;
     974        pwent = getpwuid((uid_t)id);
     975        if (pwent == NULL) {
     976-               *name = NULL;
     977-               if (errno != 0 && errno != ENOENT)
     978+               if (errno && errno != ENOENT)
     979                        lafe_warnc(errno, "getpwuid(%s) failed",
     980                            cpio_i64toa((int64_t)id));
     981-               return (errno);
     982+               return 1;
     983        }
     984 
     985        *name = pwent->pw_name;
     986-       return (0);
     987+       return 0;
     988 }
     989 
     990 static const char *
     991@@ -1409,15 +1408,14 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
     992        errno = 0;
     993        grent = getgrgid((gid_t)id);
     994        if (grent == NULL) {
     995-               *name = NULL;
     996-               if (errno != 0)
     997+               if (errno && errno != ENOENT)
     998                        lafe_warnc(errno, "getgrgid(%s) failed",
     999                            cpio_i64toa((int64_t)id));
     1000-               return (errno);
     1001+               return 1;
     1002        }
     1003 
     1004        *name = grent->gr_name;
     1005-       return (0);
     1006+       return 0;
     1007 }
     1008 
     1009 /*
     1010--- cpio/test/CMakeLists.txt.orig
     1011+++ cpio/test/CMakeLists.txt
     1012@@ -62,6 +62,16 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
     1013   # Register target
     1014   #
     1015   ADD_EXECUTABLE(bsdcpio_test ${bsdcpio_test_SOURCES})
     1016+  IF(ENABLE_ACL)
     1017+    SET(TEST_ACL_LIBS "")
     1018+    IF(HAVE_LIBACL)
     1019+      LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY})
     1020+    ENDIF(HAVE_LIBACL)
     1021+    IF(HAVE_LIBRICHACL)
     1022+      LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY})
     1023+    ENDIF(HAVE_LIBRICHACL)
     1024+    TARGET_LINK_LIBRARIES(bsdcpio_test ${TEST_ACL_LIBS})
     1025+  ENDIF(ENABLE_ACL)
     1026   SET_PROPERTY(TARGET bsdcpio_test PROPERTY COMPILE_DEFINITIONS LIST_H)
     1027 
     1028   #
     1029--- libarchive/CMakeLists.txt.orig
     1030+++ libarchive/CMakeLists.txt
     1031@@ -14,6 +14,7 @@ SET(include_HEADERS
     1032 # Sources and private headers
     1033 SET(libarchive_SOURCES
     1034   archive_acl.c
     1035+  archive_acl_private.h
     1036   archive_check_magic.c
     1037   archive_cmdline.c
     1038   archive_cmdline_private.h
     1039@@ -47,6 +48,7 @@ SET(libarchive_SOURCES
     1040   archive_pathmatch.c
     1041   archive_pathmatch.h
     1042   archive_platform.h
     1043+  archive_platform_acl.h
     1044   archive_ppmd_private.h
     1045   archive_ppmd7.c
     1046   archive_ppmd7_private.h
     1047@@ -106,9 +108,9 @@ SET(libarchive_SOURCES
     1048   archive_string_composition.h
     1049   archive_string_sprintf.c
     1050   archive_util.c
     1051+  archive_version_details.c
     1052   archive_virtual.c
     1053   archive_write.c
     1054-  archive_write_disk_acl.c
     1055   archive_write_disk_posix.c
     1056   archive_write_disk_private.h
     1057   archive_write_disk_set_standard_lookup.c
     1058@@ -210,6 +212,28 @@ IF(WIN32 AND NOT CYGWIN)
     1059   LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
     1060 ENDIF(WIN32 AND NOT CYGWIN)
     1061 
     1062+IF(ARCHIVE_ACL_DARWIN)
     1063+  LIST(APPEND libarchive_SOURCES archive_acl_maps.h)
     1064+  LIST(APPEND libarchive_SOURCES archive_acl_maps_darwin.c)
     1065+  LIST(APPEND libarchive_SOURCES archive_read_disk_acl_darwin.c)
     1066+  LIST(APPEND libarchive_SOURCES archive_write_disk_acl_darwin.c)
     1067+ELSEIF(ARCHIVE_ACL_FREEBSD)
     1068+  LIST(APPEND libarchive_SOURCES archive_acl_maps.h)
     1069+  LIST(APPEND libarchive_SOURCES archive_acl_maps_freebsd.c)
     1070+  LIST(APPEND libarchive_SOURCES archive_read_disk_acl_freebsd.c)
     1071+  LIST(APPEND libarchive_SOURCES archive_write_disk_acl_freebsd.c)
     1072+ELSEIF(ARCHIVE_ACL_LIBACL)
     1073+  LIST(APPEND libarchive_SOURCES archive_acl_maps.h)
     1074+  LIST(APPEND libarchive_SOURCES archive_acl_maps_linux.c)
     1075+  LIST(APPEND libarchive_SOURCES archive_read_disk_acl_linux.c)
     1076+  LIST(APPEND libarchive_SOURCES archive_write_disk_acl_linux.c)
     1077+ELSEIF(ARCHIVE_ACL_SUNOS)
     1078+  LIST(APPEND libarchive_SOURCES archive_acl_maps.h)
     1079+  LIST(APPEND libarchive_SOURCES archive_acl_maps_sunos.c)
     1080+  LIST(APPEND libarchive_SOURCES archive_read_disk_acl_sunos.c)
     1081+  LIST(APPEND libarchive_SOURCES archive_write_disk_acl_sunos.c)
     1082+ENDIF()
     1083+
     1084 # Libarchive is a shared library
     1085 ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
     1086 TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
     1087--- libarchive/archive.h.orig
     1088+++ libarchive/archive.h
     1089@@ -36,7 +36,7 @@
     1090  * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
     1091  */
     1092 /* Note: Compiler will complain if this does not match archive_entry.h! */
     1093-#define        ARCHIVE_VERSION_NUMBER 3003001
     1094+#define        ARCHIVE_VERSION_NUMBER 3003002
     1095 
     1096 #include <sys/stat.h>
     1097 #include <stddef.h>  /* for wchar_t */
     1098@@ -155,7 +155,7 @@ __LA_DECL int               archive_version_number(void);
     1099 /*
     1100  * Textual name/version of the library, useful for version displays.
     1101  */
     1102-#define        ARCHIVE_VERSION_ONLY_STRING "3.3.1"
     1103+#define        ARCHIVE_VERSION_ONLY_STRING "3.3.2dev"
     1104 #define        ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
     1105 __LA_DECL const char * archive_version_string(void);
     1106 
     1107--- /dev/null
     1108+++ libarchive/archive_acl_maps.h
     1109@@ -0,0 +1,52 @@
     1110+/*-
     1111+ * Copyright (c) 2017 Martin Matuska
     1112+ * All rights reserved.
     1113+ *
     1114+ * Redistribution and use in source and binary forms, with or without
     1115+ * modification, are permitted provided that the following conditions
     1116+ * are met:
     1117+ * 1. Redistributions of source code must retain the above copyright
     1118+ *    notice, this list of conditions and the following disclaimer.
     1119+ * 2. Redistributions in binary form must reproduce the above copyright
     1120+ *    notice, this list of conditions and the following disclaimer in the
     1121+ *    documentation and/or other materials provided with the distribution.
     1122+ *
     1123+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     1124+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     1125+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     1126+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     1127+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     1128+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     1129+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     1130+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     1131+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     1132+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     1133+ */
     1134+
     1135+#ifndef __LIBARCHIVE_BUILD
     1136+#error This header is only to be used internally to libarchive.
     1137+#endif
     1138+
     1139+#ifndef ARCHIVE_ACL_MAPS_H_INCLUDED
     1140+#define ARCHIVE_ACL_MAPS_H_INCLUDED
     1141+
     1142+#include "archive_platform_acl.h"
     1143+
     1144+typedef struct {
     1145+       const int a_perm;       /* Libarchive permission or flag */
     1146+       const int p_perm;       /* Platform permission or flag */
     1147+} acl_perm_map_t;
     1148+
     1149+#ifndef _ARCHIVE_ACL_MAPS_DEFS
     1150+#if ARCHIVE_ACL_POSIX1E
     1151+extern const acl_perm_map_t acl_posix_perm_map[];
     1152+extern const int acl_posix_perm_map_size;
     1153+#endif
     1154+#if ARCHIVE_ACL_NFS4
     1155+extern const acl_perm_map_t acl_nfs4_perm_map[];
     1156+extern const int acl_nfs4_perm_map_size;
     1157+extern const acl_perm_map_t acl_nfs4_flag_map[];
     1158+extern const int acl_nfs4_flag_map_size;
     1159+#endif
     1160+#endif /* !_ARCHIVE_ACL_MAPS_DEFS */
     1161+#endif /* ARCHIVE_ACL_MAPS_H_INCLUDED */
     1162--- /dev/null
     1163+++ libarchive/archive_acl_maps_darwin.c
     1164@@ -0,0 +1,76 @@
     1165+/*-
     1166+ * Copyright (c) 2017 Martin Matuska
     1167+ * All rights reserved.
     1168+ *
     1169+ * Redistribution and use in source and binary forms, with or without
     1170+ * modification, are permitted provided that the following conditions
     1171+ * are met:
     1172+ * 1. Redistributions of source code must retain the above copyright
     1173+ *    notice, this list of conditions and the following disclaimer.
     1174+ * 2. Redistributions in binary form must reproduce the above copyright
     1175+ *    notice, this list of conditions and the following disclaimer in the
     1176+ *    documentation and/or other materials provided with the distribution.
     1177+ *
     1178+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     1179+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     1180+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     1181+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     1182+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     1183+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     1184+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     1185+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     1186+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     1187+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     1188+ */
     1189+
     1190+#include "archive_platform.h"
     1191+
     1192+#ifdef HAVE_SYS_TYPES_H
     1193+#include <sys/types.h>
     1194+#endif
     1195+#ifdef HAVE_SYS_ACL_H
     1196+#define _ACL_PRIVATE /* For debugging */
     1197+#include <sys/acl.h>
     1198+#endif
     1199+
     1200+#include "archive_entry.h"
     1201+#include "archive_private.h"
     1202+#include "archive_read_disk_private.h"
     1203+#define _ARCHIVE_ACL_MAPS_DEFS
     1204+#include "archive_acl_maps.h"
     1205+
     1206+const acl_perm_map_t acl_nfs4_perm_map[] = {
     1207+       {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
     1208+       {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
     1209+       {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
     1210+       {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
     1211+       {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
     1212+       {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
     1213+       {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
     1214+       {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
     1215+       {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
     1216+       {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
     1217+       {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
     1218+       {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
     1219+       {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
     1220+       {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
     1221+       {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
     1222+       {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
     1223+#if HAVE_DECL_ACL_SYNCHRONIZE
     1224+       {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
     1225+#endif
     1226+};
     1227+
     1228+const int acl_nfs4_perm_map_size =
     1229+    (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
     1230+
     1231+const acl_perm_map_t acl_nfs4_flag_map[] = {
     1232+       {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
     1233+       {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
     1234+       {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
     1235+       {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
     1236+       {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
     1237+};
     1238+
     1239+const int acl_nfs4_flag_map_size =
     1240+    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
     1241--- /dev/null
     1242+++ libarchive/archive_acl_maps_freebsd.c
     1243@@ -0,0 +1,87 @@
     1244+/*-
     1245+ * Copyright (c) 2017 Martin Matuska
     1246+ * All rights reserved.
     1247+ *
     1248+ * Redistribution and use in source and binary forms, with or without
     1249+ * modification, are permitted provided that the following conditions
     1250+ * are met:
     1251+ * 1. Redistributions of source code must retain the above copyright
     1252+ *    notice, this list of conditions and the following disclaimer.
     1253+ * 2. Redistributions in binary form must reproduce the above copyright
     1254+ *    notice, this list of conditions and the following disclaimer in the
     1255+ *    documentation and/or other materials provided with the distribution.
     1256+ *
     1257+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     1258+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     1259+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     1260+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     1261+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     1262+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     1263+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     1264+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     1265+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     1266+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     1267+ */
     1268+
     1269+#include "archive_platform.h"
     1270+
     1271+#ifdef HAVE_SYS_TYPES_H
     1272+#include <sys/types.h>
     1273+#endif
     1274+#ifdef HAVE_SYS_ACL_H
     1275+#define _ACL_PRIVATE /* For debugging */
     1276+#include <sys/acl.h>
     1277+#endif
     1278+
     1279+#include "archive_entry.h"
     1280+#include "archive_private.h"
     1281+#include "archive_read_disk_private.h"
     1282+#define _ARCHIVE_ACL_MAPS_DEFS
     1283+#include "archive_acl_maps.h"
     1284+
     1285+const acl_perm_map_t acl_posix_perm_map[] = {
     1286+       {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
     1287+       {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
     1288+       {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
     1289+};
     1290+
     1291+const int acl_posix_perm_map_size =
     1292+    (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
     1293+
     1294+#if ARCHIVE_ACL_FREEBSD_NFS4
     1295+const acl_perm_map_t acl_nfs4_perm_map[] = {
     1296+       {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
     1297+       {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
     1298+       {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
     1299+       {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
     1300+       {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
     1301+       {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
     1302+       {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
     1303+       {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
     1304+       {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
     1305+       {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
     1306+       {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
     1307+       {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
     1308+       {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
     1309+       {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
     1310+       {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
     1311+       {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
     1312+       {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
     1313+};
     1314+
     1315+const int acl_nfs4_perm_map_size =
     1316+    (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
     1317+
     1318+const acl_perm_map_t acl_nfs4_flag_map[] = {
     1319+       {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
     1320+       {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
     1321+       {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
     1322+       {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
     1323+       {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
     1324+       {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
     1325+       {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
     1326+};
     1327+
     1328+const int acl_nfs4_flag_map_size =
     1329+    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
     1330+#endif /* ARCHIVE_ACL_FREEBSD_NFS4 */
     1331--- /dev/null
     1332+++ libarchive/archive_acl_maps_linux.c
     1333@@ -0,0 +1,90 @@
     1334+/*-
     1335+ * Copyright (c) 2017 Martin Matuska
     1336+ * All rights reserved.
     1337+ *
     1338+ * Redistribution and use in source and binary forms, with or without
     1339+ * modification, are permitted provided that the following conditions
     1340+ * are met:
     1341+ * 1. Redistributions of source code must retain the above copyright
     1342+ *    notice, this list of conditions and the following disclaimer.
     1343+ * 2. Redistributions in binary form must reproduce the above copyright
     1344+ *    notice, this list of conditions and the following disclaimer in the
     1345+ *    documentation and/or other materials provided with the distribution.
     1346+ *
     1347+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     1348+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     1349+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     1350+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     1351+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     1352+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     1353+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     1354+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     1355+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     1356+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     1357+ */
     1358+
     1359+#include "archive_platform.h"
     1360+
     1361+#ifdef HAVE_SYS_TYPES_H
     1362+#include <sys/types.h>
     1363+#endif
     1364+#ifdef HAVE_SYS_ACL_H
     1365+#define _ACL_PRIVATE /* For debugging */
     1366+#include <sys/acl.h>
     1367+#endif
     1368+#ifdef HAVE_SYS_RICHACL_H
     1369+#include <sys/richacl.h>
     1370+#endif
     1371+
     1372+#include "archive_entry.h"
     1373+#include "archive_private.h"
     1374+#include "archive_read_disk_private.h"
     1375+#define _ARCHIVE_ACL_MAPS_DEFS
     1376+#include "archive_acl_maps.h"
     1377+
     1378+#if ARCHIVE_ACL_LIBACL
     1379+const acl_perm_map_t acl_posix_perm_map[] = {
     1380+       {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
     1381+       {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
     1382+       {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
     1383+};
     1384+
     1385+const int acl_posix_perm_map_size =
     1386+    (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
     1387+#endif /* ARCHIVE_ACL_LIBACL */
     1388+
     1389+#if ARCHIVE_ACL_LIBRICHACL
     1390+const acl_perm_map_t acl_nfs4_perm_map[] = {
     1391+       {ARCHIVE_ENTRY_ACL_EXECUTE, RICHACE_EXECUTE},
     1392+       {ARCHIVE_ENTRY_ACL_READ_DATA, RICHACE_READ_DATA},
     1393+       {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, RICHACE_LIST_DIRECTORY},
     1394+       {ARCHIVE_ENTRY_ACL_WRITE_DATA, RICHACE_WRITE_DATA},
     1395+       {ARCHIVE_ENTRY_ACL_ADD_FILE, RICHACE_ADD_FILE},
     1396+       {ARCHIVE_ENTRY_ACL_APPEND_DATA, RICHACE_APPEND_DATA},
     1397+       {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, RICHACE_ADD_SUBDIRECTORY},
     1398+       {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, RICHACE_READ_NAMED_ATTRS},
     1399+       {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, RICHACE_WRITE_NAMED_ATTRS},
     1400+       {ARCHIVE_ENTRY_ACL_DELETE_CHILD, RICHACE_DELETE_CHILD},
     1401+       {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, RICHACE_READ_ATTRIBUTES},
     1402+       {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, RICHACE_WRITE_ATTRIBUTES},
     1403+       {ARCHIVE_ENTRY_ACL_DELETE, RICHACE_DELETE},
     1404+       {ARCHIVE_ENTRY_ACL_READ_ACL, RICHACE_READ_ACL},
     1405+       {ARCHIVE_ENTRY_ACL_WRITE_ACL, RICHACE_WRITE_ACL},
     1406+       {ARCHIVE_ENTRY_ACL_WRITE_OWNER, RICHACE_WRITE_OWNER},
     1407+       {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, RICHACE_SYNCHRONIZE}
     1408+};
     1409+
     1410+const int acl_nfs4_perm_map_size =
     1411+    (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
     1412+
     1413+const acl_perm_map_t acl_nfs4_flag_map[] = {
     1414+       {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, RICHACE_FILE_INHERIT_ACE},
     1415+       {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, RICHACE_DIRECTORY_INHERIT_ACE},
     1416+       {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, RICHACE_NO_PROPAGATE_INHERIT_ACE},
     1417+       {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE},
     1418+       {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE}
     1419+};
     1420+
     1421+const int acl_nfs4_flag_map_size =
     1422+    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
     1423+#endif /* ARCHIVE_ACL_LIBRICHACL */
     1424--- /dev/null
     1425+++ libarchive/archive_acl_maps_sunos.c
     1426@@ -0,0 +1,90 @@
     1427+/*-
     1428+ * Copyright (c) 2017 Martin Matuska
     1429+ * All rights reserved.
     1430+ *
     1431+ * Redistribution and use in source and binary forms, with or without
     1432+ * modification, are permitted provided that the following conditions
     1433+ * are met:
     1434+ * 1. Redistributions of source code must retain the above copyright
     1435+ *    notice, this list of conditions and the following disclaimer.
     1436+ * 2. Redistributions in binary form must reproduce the above copyright
     1437+ *    notice, this list of conditions and the following disclaimer in the
     1438+ *    documentation and/or other materials provided with the distribution.
     1439+ *
     1440+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     1441+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     1442+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     1443+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     1444+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     1445+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     1446+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     1447+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     1448+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     1449+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     1450+ */
     1451+
     1452+#include "archive_platform.h"
     1453+
     1454+#ifdef HAVE_SYS_TYPES_H
     1455+#include <sys/types.h>
     1456+#endif
     1457+#ifdef HAVE_SYS_ACL_H
     1458+#define _ACL_PRIVATE /* For debugging */
     1459+#include <sys/acl.h>
     1460+#endif
     1461+
     1462+#include "archive_entry.h"
     1463+#include "archive_private.h"
     1464+#include "archive_read_disk_private.h"
     1465+#define _ARCHIVE_ACL_MAPS_DEFS
     1466+#include "archive_acl_maps.h"
     1467+
     1468+const acl_perm_map_t acl_posix_perm_map[] = {
     1469+       {ARCHIVE_ENTRY_ACL_EXECUTE, S_IXOTH },
     1470+       {ARCHIVE_ENTRY_ACL_WRITE, S_IWOTH },
     1471+       {ARCHIVE_ENTRY_ACL_READ, S_IROTH }
     1472+};
     1473+
     1474+const int acl_posix_perm_map_size =
     1475+    (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
     1476+
     1477+#if ARCHIVE_ACL_SUNOS_NFS4
     1478+const acl_perm_map_t acl_nfs4_perm_map[] = {
     1479+       {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
     1480+       {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
     1481+       {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
     1482+       {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
     1483+       {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
     1484+       {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
     1485+       {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
     1486+       {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
     1487+       {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
     1488+       {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
     1489+       {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
     1490+       {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
     1491+       {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
     1492+       {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
     1493+       {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
     1494+       {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
     1495+       {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
     1496+};
     1497+
     1498+const int acl_nfs4_perm_map_size =
     1499+    (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
     1500+
     1501+const acl_perm_map_t acl_nfs4_flag_map[] = {
     1502+       {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
     1503+       {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
     1504+       {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
     1505+       {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
     1506+       {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
     1507+       {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
     1508+#ifdef ACE_INHERITED_ACE
     1509+       {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
     1510+#endif
     1511+};
     1512+
     1513+const int acl_nfs4_flag_map_size =
     1514+    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
     1515+
     1516+#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
     1517--- libarchive/archive_check_magic.c.orig
     1518+++ libarchive/archive_check_magic.c
     1519@@ -62,7 +62,7 @@ errmsg(const char *m)
     1520        }
     1521 }
     1522 
     1523-static void
     1524+static __LA_DEAD void
     1525 diediedie(void)
     1526 {
     1527 #if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
     1528--- libarchive/archive_entry.3.orig
     1529+++ libarchive/archive_entry.3
     1530@@ -25,7 +25,7 @@
     1531 .\"
     1532 .\" $FreeBSD$
     1533 .\"
     1534-.Dd Feburary 2, 2012
     1535+.Dd February 2, 2012
     1536 .Dt ARCHIVE_ENTRY 3
     1537 .Os
     1538 .Sh NAME
     1539--- libarchive/archive_entry.c.orig
     1540+++ libarchive/archive_entry.c
     1541@@ -401,7 +401,7 @@ archive_entry_fflags_text(struct archive_entry *entry)
     1542        return (NULL);
     1543 }
     1544 
     1545-int64_t
     1546+la_int64_t
     1547 archive_entry_gid(struct archive_entry *entry)
     1548 {
     1549        return (entry->ae_stat.aest_gid);
     1550@@ -502,7 +502,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
     1551        return (archive_mstring_get_mbs_l(&entry->ae_hardlink, p, len, sc));
     1552 }
     1553 
     1554-int64_t
     1555+la_int64_t
     1556 archive_entry_ino(struct archive_entry *entry)
     1557 {
     1558        return (entry->ae_stat.aest_ino);
     1559@@ -514,7 +514,7 @@ archive_entry_ino_is_set(struct archive_entry *entry)
     1560        return (entry->ae_set & AE_SET_INO);
     1561 }
     1562 
     1563-int64_t
     1564+la_int64_t
     1565 archive_entry_ino64(struct archive_entry *entry)
     1566 {
     1567        return (entry->ae_stat.aest_ino);
     1568@@ -627,7 +627,7 @@ archive_entry_rdevminor(struct archive_entry *entry)
     1569                return minor(entry->ae_stat.aest_rdev);
     1570 }
     1571 
     1572-int64_t
     1573+la_int64_t
     1574 archive_entry_size(struct archive_entry *entry)
     1575 {
     1576        return (entry->ae_stat.aest_size);
     1577@@ -715,7 +715,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
     1578        return (archive_mstring_get_mbs_l( &entry->ae_symlink, p, len, sc));
     1579 }
     1580 
     1581-int64_t
     1582+la_int64_t
     1583 archive_entry_uid(struct archive_entry *entry)
     1584 {
     1585        return (entry->ae_stat.aest_uid);
     1586@@ -819,7 +819,7 @@ archive_entry_copy_fflags_text_w(struct archive_entry *entry,
     1587 }
     1588 
     1589 void
     1590-archive_entry_set_gid(struct archive_entry *entry, int64_t g)
     1591+archive_entry_set_gid(struct archive_entry *entry, la_int64_t g)
     1592 {
     1593        entry->stat_valid = 0;
     1594        entry->ae_stat.aest_gid = g;
     1595@@ -868,7 +868,7 @@ _archive_entry_copy_gname_l(struct archive_entry *entry,
     1596 }
     1597 
     1598 void
     1599-archive_entry_set_ino(struct archive_entry *entry, int64_t ino)
     1600+archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino)
     1601 {
     1602        entry->stat_valid = 0;
     1603        entry->ae_set |= AE_SET_INO;
     1604@@ -876,7 +876,7 @@ archive_entry_set_ino(struct archive_entry *entry, int64_t ino)
     1605 }
     1606 
     1607 void
     1608-archive_entry_set_ino64(struct archive_entry *entry, int64_t ino)
     1609+archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino)
     1610 {
     1611        entry->stat_valid = 0;
     1612        entry->ae_set |= AE_SET_INO;
     1613@@ -1209,7 +1209,7 @@ archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
     1614 }
     1615 
     1616 void
     1617-archive_entry_set_size(struct archive_entry *entry, int64_t s)
     1618+archive_entry_set_size(struct archive_entry *entry, la_int64_t s)
     1619 {
     1620        entry->stat_valid = 0;
     1621        entry->ae_stat.aest_size = s;
     1622@@ -1306,7 +1306,7 @@ _archive_entry_copy_symlink_l(struct archive_entry *entry,
     1623 }
     1624 
     1625 void
     1626-archive_entry_set_uid(struct archive_entry *entry, int64_t u)
     1627+archive_entry_set_uid(struct archive_entry *entry, la_int64_t u)
     1628 {
     1629        entry->stat_valid = 0;
     1630        entry->ae_stat.aest_uid = u;
     1631--- libarchive/archive_entry.h.orig
     1632+++ libarchive/archive_entry.h
     1633@@ -30,7 +30,7 @@
     1634 #define        ARCHIVE_ENTRY_H_INCLUDED
     1635 
     1636 /* Note: Compiler will complain if this does not match archive.h! */
     1637-#define        ARCHIVE_VERSION_NUMBER 3003001
     1638+#define        ARCHIVE_VERSION_NUMBER 3003002
     1639 
     1640 /*
     1641  * Note: archive_entry.h is for use outside of libarchive; the
     1642--- libarchive/archive_entry_acl.3.orig
     1643+++ libarchive/archive_entry_acl.3
     1644@@ -32,7 +32,7 @@
     1645 .Nm archive_entry_acl_clear ,
     1646 .Nm archive_entry_acl_count ,
     1647 .Nm archive_entry_acl_from_text ,
     1648-.Nm archive_entry_acl_from_text_w,
     1649+.Nm archive_entry_acl_from_text_w ,
     1650 .Nm archive_entry_acl_next ,
     1651 .Nm archive_entry_acl_next_w ,
     1652 .Nm archive_entry_acl_reset ,
     1653@@ -267,7 +267,7 @@ Only inherit, do not apply the permission on the directory itself.
     1654 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT ( Sy n )
     1655 Do not propagate inherit flags. Only first-level entries inherit ACLs.
     1656 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS ( Sy S )
     1657-Trigger alarm or audit on succesful access.
     1658+Trigger alarm or audit on successful access.
     1659 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS ( Sy F )
     1660 Trigger alarm or audit on failed access.
     1661 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERITED ( Sy I )
     1662@@ -279,7 +279,7 @@ and
     1663 .Fn archive_entry_acl_add_entry_w
     1664 add a single ACL entry.
     1665 For the access ACL and non-extended principals, the classic Unix permissions
     1666-are updated. An archive enry cannot contain both POSIX.1e and NFSv4 ACL
     1667+are updated. An archive entry cannot contain both POSIX.1e and NFSv4 ACL
     1668 entries.
     1669 .Pp
     1670 .Fn archive_entry_acl_clear
     1671@@ -303,7 +303,7 @@ for POSIX.1e ACLs and
     1672 for NFSv4 ACLs. For POSIX.1e ACLs if
     1673 .Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
     1674 is included and at least one extended ACL entry is found,
     1675-the three non-extened ACLs are added.
     1676+the three non-extended ACLs are added.
     1677 .Pp
     1678 .Fn archive_entry_acl_from_text
     1679 and
     1680@@ -367,7 +367,7 @@ and
     1681 .Fn archive_entry_acl_to_text_w
     1682 convert the ACL entries for the given type into a
     1683 .Pq wide
     1684-string of ACL entries separated by newline. If the the pointer
     1685+string of ACL entries separated by newline. If the pointer
     1686 .Fa len_p
     1687 is not NULL, then the function shall return the length of the string
     1688 .Pq not including the NULL terminator
     1689--- libarchive/archive_entry_paths.3.orig
     1690+++ libarchive/archive_entry_paths.3
     1691@@ -31,25 +31,25 @@
     1692 .Nm archive_entry_set_hardlink ,
     1693 .Nm archive_entry_copy_hardlink ,
     1694 .Nm archive_entry_copy_hardlink_w ,
     1695-.Nm archve_entry_update_hardlink_utf8 ,
     1696+.Nm archive_entry_update_hardlink_utf8 ,
     1697 .Nm archive_entry_set_link ,
     1698 .Nm archive_entry_copy_link ,
     1699 .Nm archive_entry_copy_link_w ,
     1700-.Nm archve_entry_update_link_utf8 ,
     1701+.Nm archive_entry_update_link_utf8 ,
     1702 .Nm archive_entry_pathname ,
     1703 .Nm archive_entry_pathname_w ,
     1704 .Nm archive_entry_set_pathname ,
     1705 .Nm archive_entry_copy_pathname ,
     1706 .Nm archive_entry_copy_pathname_w ,
     1707-.Nm archve_entry_update_pathname_utf8 ,
     1708+.Nm archive_entry_update_pathname_utf8 ,
     1709 .Nm archive_entry_sourcepath ,
     1710 .Nm archive_entry_copy_sourcepath ,
     1711-.Nm archive_entry_symlink,
     1712-.Nm archive_entry_symlink_w,
     1713+.Nm archive_entry_symlink ,
     1714+.Nm archive_entry_symlink_w ,
     1715 .Nm archive_entry_set_symlink ,
     1716 .Nm archive_entry_copy_symlink ,
     1717 .Nm archive_entry_copy_symlink_w ,
     1718-.Nm archve_entry_update_symlink_utf8
     1719+.Nm archive_entry_update_symlink_utf8
     1720 .Nd functions for manipulating path names in archive entry descriptions
     1721 .Sh LIBRARY
     1722 Streaming Archive Library (libarchive, -larchive)
     1723--- libarchive/archive_entry_perms.3.orig
     1724+++ libarchive/archive_entry_perms.3
     1725@@ -34,8 +34,8 @@
     1726 .Nm archive_entry_perm ,
     1727 .Nm archive_entry_set_perm ,
     1728 .Nm archive_entry_strmode ,
     1729-.Nm archive_entry_uname
     1730-.Nm archive_entry_uname_w
     1731+.Nm archive_entry_uname ,
     1732+.Nm archive_entry_uname_w ,
     1733 .Nm archive_entry_set_uname ,
     1734 .Nm archive_entry_copy_uname ,
     1735 .Nm archive_entry_copy_uname_w ,
     1736--- libarchive/archive_platform.h.orig
     1737+++ libarchive/archive_platform.h
     1738@@ -143,32 +143,6 @@
     1739 #endif
     1740 
     1741 /*
     1742- * If this platform has <sys/acl.h>, acl_create(), acl_init(),
     1743- * acl_set_file(), and ACL_USER, we assume it has the rest of the
     1744- * POSIX.1e draft functions used in archive_read_extract.c.
     1745- */
     1746-#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
     1747-#if HAVE_ACL_USER
     1748-#define        HAVE_POSIX_ACL  1
     1749-#elif HAVE_ACL_TYPE_EXTENDED
     1750-#define HAVE_DARWIN_ACL 1
     1751-#endif
     1752-#endif
     1753-
     1754-/*
     1755- * If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
     1756- * facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
     1757- */
     1758-#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
     1759-#define        HAVE_SUN_ACL    1
     1760-#endif
     1761-
     1762-/* Define if platform supports NFSv4 ACLs */
     1763-#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
     1764-#define HAVE_NFS4_ACL  1
     1765-#endif
     1766-
     1767-/*
     1768  * If we can't restore metadata using a file descriptor, then
     1769  * for compatibility's sake, close files before trying to restore metadata.
     1770  */
     1771--- /dev/null
     1772+++ libarchive/archive_platform_acl.h
     1773@@ -0,0 +1,49 @@
     1774+/*-
     1775+ * Copyright (c) 2017 Martin Matuska
     1776+ * All rights reserved.
     1777+ *
     1778+ * Redistribution and use in source and binary forms, with or without
     1779+ * modification, are permitted provided that the following conditions
     1780+ * are met:
     1781+ * 1. Redistributions of source code must retain the above copyright
     1782+ *    notice, this list of conditions and the following disclaimer.
     1783+ * 2. Redistributions in binary form must reproduce the above copyright
     1784+ *    notice, this list of conditions and the following disclaimer in the
     1785+ *    documentation and/or other materials provided with the distribution.
     1786+ *
     1787+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     1788+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     1789+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     1790+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     1791+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     1792+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     1793+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     1794+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     1795+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     1796+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     1797+ *
     1798+ * $FreeBSD$
     1799+ */
     1800+
     1801+/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
     1802+
     1803+#ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED
     1804+#define ARCHIVE_PLATFORM_ACL_H_INCLUDED
     1805+
     1806+/*
     1807+ * Determine what ACL types are supported
     1808+ */
     1809+#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_SUNOS || ARCHIVE_ACL_LIBACL
     1810+#define ARCHIVE_ACL_POSIX1E     1
     1811+#endif
     1812+
     1813+#if ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_SUNOS_NFS4 || \
     1814+    ARCHIVE_ACL_DARWIN  || ARCHIVE_ACL_LIBRICHACL
     1815+#define ARCHIVE_ACL_NFS4        1
     1816+#endif
     1817+
     1818+#if ARCHIVE_ACL_POSIX1E || ARCHIVE_ACL_NFS4
     1819+#define ARCHIVE_ACL_SUPPORT     1
     1820+#endif
     1821+
     1822+#endif /* ARCHIVE_PLATFORM_ACL_H_INCLUDED */
     1823--- libarchive/archive_read_disk.3.orig
     1824+++ libarchive/archive_read_disk.3
     1825@@ -37,10 +37,7 @@
     1826 .Nm archive_read_disk_uname ,
     1827 .Nm archive_read_disk_set_uname_lookup ,
     1828 .Nm archive_read_disk_set_gname_lookup ,
     1829-.Nm archive_read_disk_set_standard_lookup ,
     1830-.Nm archive_read_close ,
     1831-.Nm archive_read_finish ,
     1832-.Nm archive_read_free
     1833+.Nm archive_read_disk_set_standard_lookup
     1834 .Nd functions for reading objects from disk
     1835 .Sh LIBRARY
     1836 Streaming Archive Library (libarchive, -larchive)
     1837@@ -81,12 +78,6 @@ Streaming Archive Library (libarchive, -larchive)
     1838 .Fa "int fd"
     1839 .Fa "const struct stat *"
     1840 .Fc
     1841-.Ft int
     1842-.Fn archive_read_close "struct archive *"
     1843-.Ft int
     1844-.Fn archive_read_finish "struct archive *"
     1845-.Ft int
     1846-.Fn archive_read_free "struct archive *"
     1847 .Sh DESCRIPTION
     1848 These functions provide an API for reading information about
     1849 objects on disk.
     1850@@ -181,17 +172,6 @@ using the currently registered lookup functions above.
     1851 This affects the file ownership fields and ACL values in the
     1852 .Tn struct archive_entry
     1853 object.
     1854-.It Fn archive_read_close
     1855-Does nothing for
     1856-.Tn archive_read_disk
     1857-handles.
     1858-.It Fn archive_read_finish
     1859-This is a deprecated synonym for
     1860-.Fn archive_read_free .
     1861-.It Fn archive_read_free
     1862-Invokes
     1863-.Fn archive_read_close
     1864-if it was not invoked manually, then releases all resources.
     1865 .El
     1866 More information about the
     1867 .Va struct archive
     1868--- /dev/null
     1869+++ libarchive/archive_read_disk_acl_darwin.c
     1870@@ -0,0 +1,337 @@
     1871+/*-
     1872+ * Copyright (c) 2017 Martin Matuska
     1873+ * All rights reserved.
     1874+ *
     1875+ * Redistribution and use in source and binary forms, with or without
     1876+ * modification, are permitted provided that the following conditions
     1877+ * are met:
     1878+ * 1. Redistributions of source code must retain the above copyright
     1879+ *    notice, this list of conditions and the following disclaimer.
     1880+ * 2. Redistributions in binary form must reproduce the above copyright
     1881+ *    notice, this list of conditions and the following disclaimer in the
     1882+ *    documentation and/or other materials provided with the distribution.
     1883+ *
     1884+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     1885+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     1886+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     1887+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     1888+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     1889+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     1890+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     1891+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     1892+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     1893+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     1894+ */
     1895+
     1896+#include "archive_platform.h"
     1897+
     1898+#ifdef HAVE_FCNTL_H
     1899+#include <fcntl.h>
     1900+#endif
     1901+#if HAVE_ERRNO_H
     1902+#include <errno.h>
     1903+#endif
     1904+#if HAVE_MEMBERSHIP_H
     1905+#include <membership.h>
     1906+#endif
     1907+#ifdef HAVE_SYS_TYPES_H
     1908+#include <sys/types.h>
     1909+#endif
     1910+#ifdef HAVE_SYS_ACL_H
     1911+#define _ACL_PRIVATE /* For debugging */
     1912+#include <sys/acl.h>
     1913+#endif
     1914+
     1915+#include "archive_entry.h"
     1916+#include "archive_private.h"
     1917+#include "archive_read_disk_private.h"
     1918+#include "archive_acl_maps.h"
     1919+
     1920+
     1921+/*
     1922+ * Darwin-specific ACL functions and helper functions
     1923+ *
     1924+ * Exported functions:
     1925+ * none
     1926+ */
     1927+static int translate_guid(struct archive *a, acl_entry_t acl_entry,
     1928+    int *ae_id, int *ae_tag, const char **ae_name)
     1929+{
     1930+       void *q;
     1931+       uid_t ugid;
     1932+       int r, idtype;
     1933+
     1934+       q = acl_get_qualifier(acl_entry);
     1935+       if (q == NULL)
     1936+               return (1);
     1937+       r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
     1938+       if (r != 0) {
     1939+               acl_free(q);
     1940+               return (1);
     1941+       }
     1942+       if (idtype == ID_TYPE_UID) {
     1943+               *ae_tag = ARCHIVE_ENTRY_ACL_USER;
     1944+               *ae_id = ugid;
     1945+               *ae_name = archive_read_disk_uname(a, *ae_id);
     1946+       } else if (idtype == ID_TYPE_GID) {
     1947+               *ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
     1948+               *ae_id = ugid;
     1949+               *ae_name = archive_read_disk_gname(a, *ae_id);
     1950+       } else
     1951+               r = 1;
     1952+
     1953+       acl_free(q);
     1954+       return (r);
     1955+}
     1956+
     1957+/*
     1958+ * Add trivial NFSv4 ACL entries from mode
     1959+ */
     1960+static void
     1961+add_trivial_nfs4_acl(struct archive_entry *entry)
     1962+{
     1963+       mode_t mode;
     1964+       int i;
     1965+       const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA;
     1966+       const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA |
     1967+           ARCHIVE_ENTRY_ACL_APPEND_DATA;
     1968+       const int eperm = ARCHIVE_ENTRY_ACL_EXECUTE;
     1969+       const int pubset = ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
     1970+           ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
     1971+           ARCHIVE_ENTRY_ACL_READ_ACL |
     1972+           ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
     1973+       const int ownset = pubset | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
     1974+           ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
     1975+           ARCHIVE_ENTRY_ACL_WRITE_ACL |
     1976+           ARCHIVE_ENTRY_ACL_WRITE_OWNER;
     1977+
     1978+       struct {
     1979+           const int type;
     1980+           const int tag;
     1981+           int permset;
     1982+       } tacl_entry[] = {
     1983+           {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
     1984+           {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
     1985+           {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0},
     1986+           {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, ownset},
     1987+           {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_GROUP_OBJ, pubset},
     1988+           {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EVERYONE, pubset}
     1989+       };
     1990+
     1991+       mode = archive_entry_mode(entry);
     1992+
     1993+       /* Permissions for everyone@ */
     1994+       if (mode & 0004)
     1995+               tacl_entry[5].permset |= rperm;
     1996+       if (mode & 0002)
     1997+               tacl_entry[5].permset |= wperm;
     1998+       if (mode & 0001)
     1999+               tacl_entry[5].permset |= eperm;
     2000+
     2001+       /* Permissions for group@ */
     2002+       if (mode & 0040)
     2003+               tacl_entry[4].permset |= rperm;
     2004+       else if (mode & 0004)
     2005+               tacl_entry[2].permset |= rperm;
     2006+       if (mode & 0020)
     2007+               tacl_entry[4].permset |= wperm;
     2008+       else if (mode & 0002)
     2009+               tacl_entry[2].permset |= wperm;
     2010+       if (mode & 0010)
     2011+               tacl_entry[4].permset |= eperm;
     2012+       else if (mode & 0001)
     2013+               tacl_entry[2].permset |= eperm;
     2014+
     2015+       /* Permissions for owner@ */
     2016+       if (mode & 0400) {
     2017+               tacl_entry[3].permset |= rperm;
     2018+               if (!(mode & 0040) && (mode & 0004))
     2019+                       tacl_entry[0].permset |= rperm;
     2020+       } else if ((mode & 0040) || (mode & 0004))
     2021+               tacl_entry[1].permset |= rperm;
     2022+       if (mode & 0200) {
     2023+               tacl_entry[3].permset |= wperm;
     2024+               if (!(mode & 0020) && (mode & 0002))
     2025+                       tacl_entry[0].permset |= wperm;
     2026+       } else if ((mode & 0020) || (mode & 0002))
     2027+               tacl_entry[1].permset |= wperm;
     2028+       if (mode & 0100) {
     2029+               tacl_entry[3].permset |= eperm;
     2030+               if (!(mode & 0010) && (mode & 0001))
     2031+                       tacl_entry[0].permset |= eperm;
     2032+       } else if ((mode & 0010) || (mode & 0001))
     2033+               tacl_entry[1].permset |= eperm;
     2034+
     2035+       for (i = 0; i < 6; i++) {
     2036+               if (tacl_entry[i].permset != 0) {
     2037+                       archive_entry_acl_add_entry(entry,
     2038+                           tacl_entry[i].type, tacl_entry[i].permset,
     2039+                           tacl_entry[i].tag, -1, NULL);
     2040+               }
     2041+       }
     2042+
     2043+       return;
     2044+}
     2045+
     2046+static int
     2047+translate_acl(struct archive_read_disk *a,
     2048+    struct archive_entry *entry, acl_t acl)
     2049+{
     2050+       acl_tag_t        acl_tag;
     2051+       acl_flagset_t    acl_flagset;
     2052+       acl_entry_t      acl_entry;
     2053+       acl_permset_t    acl_permset;
     2054+       int              i, entry_acl_type;
     2055+       int              r, s, ae_id, ae_tag, ae_perm;
     2056+       const char      *ae_name;
     2057+
     2058+       s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
     2059+       if (s == -1) {
     2060+               archive_set_error(&a->archive, errno,
     2061+                   "Failed to get first ACL entry");
     2062+               return (ARCHIVE_WARN);
     2063+       }
     2064+
     2065+       while (s == 0) {
     2066+               ae_id = -1;
     2067+               ae_name = NULL;
     2068+               ae_perm = 0;
     2069+
     2070+               if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
     2071+                       archive_set_error(&a->archive, errno,
     2072+                           "Failed to get ACL tag type");
     2073+                       return (ARCHIVE_WARN);
     2074+               }
     2075+               switch (acl_tag) {
     2076+               case ACL_EXTENDED_ALLOW:
     2077+                       entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
     2078+                       r = translate_guid(&a->archive, acl_entry,
     2079+                           &ae_id, &ae_tag, &ae_name);
     2080+                       break;
     2081+               case ACL_EXTENDED_DENY:
     2082+                       entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
     2083+                       r = translate_guid(&a->archive, acl_entry,
     2084+                           &ae_id, &ae_tag, &ae_name);
     2085+                       break;
     2086+               default:
     2087+                       /* Skip types that libarchive can't support. */
     2088+                       s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
     2089+                       continue;
     2090+               }
     2091+
     2092+               /* Skip if translate_guid() above failed */
     2093+               if (r != 0) {
     2094+                       s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
     2095+                       continue;
     2096+               }
     2097+
     2098+               /*
     2099+                * Libarchive stores "flag" (NFSv4 inheritance bits)
     2100+                * in the ae_perm bitmap.
     2101+                *
     2102+                * acl_get_flagset_np() fails with non-NFSv4 ACLs
     2103+                */
     2104+               if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
     2105+                       archive_set_error(&a->archive, errno,
     2106+                           "Failed to get flagset from a NFSv4 ACL entry");
     2107+                       return (ARCHIVE_WARN);
     2108+               }
     2109+               for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
     2110+                       r = acl_get_flag_np(acl_flagset,
     2111+                           acl_nfs4_flag_map[i].p_perm);
     2112+                       if (r == -1) {
     2113+                               archive_set_error(&a->archive, errno,
     2114+                                   "Failed to check flag in a NFSv4 "
     2115+                                   "ACL flagset");
     2116+                               return (ARCHIVE_WARN);
     2117+                       } else if (r)
     2118+                               ae_perm |= acl_nfs4_flag_map[i].a_perm;
     2119+               }
     2120+
     2121+               if (acl_get_permset(acl_entry, &acl_permset) != 0) {
     2122+                       archive_set_error(&a->archive, errno,
     2123+                           "Failed to get ACL permission set");
     2124+                       return (ARCHIVE_WARN);
     2125+               }
     2126+
     2127+               for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
     2128+                       /*
     2129+                        * acl_get_perm() is spelled differently on different
     2130+                        * platforms; see above.
     2131+                        */
     2132+                       r = acl_get_perm_np(acl_permset,
     2133+                           acl_nfs4_perm_map[i].p_perm);
     2134+                       if (r == -1) {
     2135+                               archive_set_error(&a->archive, errno,
     2136+                                   "Failed to check permission in an ACL "
     2137+                                   "permission set");
     2138+                               return (ARCHIVE_WARN);
     2139+                       } else if (r)
     2140+                               ae_perm |= acl_nfs4_perm_map[i].a_perm;
     2141+               }
     2142+
     2143+#if !HAVE_DECL_ACL_SYNCHRONIZE
     2144+               /* On Mac OS X without ACL_SYNCHRONIZE assume it is set */
     2145+               ae_perm |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
     2146+#endif
     2147+
     2148+               archive_entry_acl_add_entry(entry, entry_acl_type,
     2149+                                           ae_perm, ae_tag,
     2150+                                           ae_id, ae_name);
     2151+
     2152+               s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
     2153+       }
     2154+       return (ARCHIVE_OK);
     2155+}
     2156+
     2157+int
     2158+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
     2159+    struct archive_entry *entry, int *fd)
     2160+{
     2161+       const char      *accpath;
     2162+       acl_t           acl;
     2163+       int             r;
     2164+
     2165+       accpath = NULL;
     2166+
     2167+       if (*fd < 0) {
     2168+               accpath = archive_read_disk_entry_setup_path(a, entry, fd);
     2169+               if (accpath == NULL)
     2170+                       return (ARCHIVE_WARN);
     2171+       }
     2172+
     2173+       archive_entry_acl_clear(entry);
     2174+
     2175+       acl = NULL;
     2176+
     2177+       if (*fd >= 0)
     2178+               acl = acl_get_fd_np(*fd, ACL_TYPE_EXTENDED);
     2179+       else if (!a->follow_symlinks)
     2180+               acl = acl_get_link_np(accpath, ACL_TYPE_EXTENDED);
     2181+       else
     2182+               acl = acl_get_file(accpath, ACL_TYPE_EXTENDED);
     2183+
     2184+       if (acl != NULL) {
     2185+               r = translate_acl(a, entry, acl);
     2186+               acl_free(acl);
     2187+               acl = NULL;
     2188+
     2189+               if (r != ARCHIVE_OK) {
     2190+                       archive_set_error(&a->archive, errno,
     2191+                           "Couldn't translate NFSv4 ACLs");
     2192+               }
     2193+
     2194+               /*
     2195+                * Because Mac OS doesn't support owner@, group@ and everyone@
     2196+                * ACLs we need to add NFSv4 ACLs mirroring the file mode to
     2197+                * the archive entry. Otherwise extraction on non-Mac platforms
     2198+                * would lead to an invalid file mode.
     2199+                */
     2200+               if ((archive_entry_acl_types(entry) &
     2201+                   ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0)
     2202+                       add_trivial_nfs4_acl(entry);
     2203+
     2204+               return (r);
     2205+       }
     2206+       return (ARCHIVE_OK);
     2207+}
     2208--- /dev/null
     2209+++ libarchive/archive_read_disk_acl_freebsd.c
     2210@@ -0,0 +1,371 @@
     2211+/*-
     2212+ * Copyright (c) 2003-2009 Tim Kientzle
     2213+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
     2214+ * Copyright (c) 2016-2017 Martin Matuska
     2215+ * All rights reserved.
     2216+ *
     2217+ * Redistribution and use in source and binary forms, with or without
     2218+ * modification, are permitted provided that the following conditions
     2219+ * are met:
     2220+ * 1. Redistributions of source code must retain the above copyright
     2221+ *    notice, this list of conditions and the following disclaimer.
     2222+ * 2. Redistributions in binary form must reproduce the above copyright
     2223+ *    notice, this list of conditions and the following disclaimer in the
     2224+ *    documentation and/or other materials provided with the distribution.
     2225+ *
     2226+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     2227+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     2228+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     2229+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     2230+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     2231+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     2232+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     2233+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     2234+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     2235+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     2236+ */
     2237+
     2238+#include "archive_platform.h"
     2239+
     2240+#ifdef HAVE_ERRNO_H
     2241+#include <errno.h>
     2242+#endif
     2243+#ifdef HAVE_FCNTL_H
     2244+#include <fcntl.h>
     2245+#endif
     2246+#ifdef HAVE_SYS_TYPES_H
     2247+#include <sys/types.h>
     2248+#endif
     2249+#ifdef HAVE_SYS_ACL_H
     2250+#define _ACL_PRIVATE /* For debugging */
     2251+#include <sys/acl.h>
     2252+#endif
     2253+
     2254+#include "archive_entry.h"
     2255+#include "archive_private.h"
     2256+#include "archive_read_disk_private.h"
     2257+#include "archive_acl_maps.h"
     2258+
     2259+/*
     2260+ * Translate FreeBSD ACLs into libarchive internal structure
     2261+ */
     2262+static int
     2263+translate_acl(struct archive_read_disk *a,
     2264+    struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
     2265+{
     2266+#if ARCHIVE_ACL_FREEBSD_NFS4
     2267+       int brand;
     2268+       acl_flagset_t    acl_flagset;
     2269+#endif
     2270+       acl_tag_t        acl_tag;
     2271+       acl_entry_t      acl_entry;
     2272+       acl_permset_t    acl_permset;
     2273+       acl_entry_type_t acl_type;
     2274+       int              i, entry_acl_type, perm_map_size;
     2275+       const acl_perm_map_t    *perm_map;
     2276+       int              r, s, ae_id, ae_tag, ae_perm;
     2277+       void            *q;
     2278+       const char      *ae_name;
     2279+
     2280+#if ARCHIVE_ACL_FREEBSD_NFS4
     2281+       // FreeBSD "brands" ACLs as POSIX.1e or NFSv4
     2282+       // Make sure the "brand" on this ACL is consistent
     2283+       // with the default_entry_acl_type bits provided.
     2284+       if (acl_get_brand_np(acl, &brand) != 0) {
     2285+               archive_set_error(&a->archive, errno,
     2286+                   "Failed to read ACL brand");
     2287+               return (ARCHIVE_WARN);
     2288+       }
     2289+       switch (brand) {
     2290+       case ACL_BRAND_POSIX:
     2291+               switch (default_entry_acl_type) {
     2292+               case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
     2293+               case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
     2294+                       break;
     2295+               default:
     2296+                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     2297+                           "Invalid ACL entry type for POSIX.1e ACL");
     2298+                       return (ARCHIVE_WARN);
     2299+               }
     2300+               break;
     2301+       case ACL_BRAND_NFS4:
     2302+               if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     2303+                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     2304+                           "Invalid ACL entry type for NFSv4 ACL");
     2305+                       return (ARCHIVE_WARN);
     2306+               }
     2307+               break;
     2308+       default:
     2309+               archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     2310+                   "Unknown ACL brand");
     2311+               return (ARCHIVE_WARN);
     2312+       }
     2313+#endif
     2314+
     2315+       s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
     2316+       if (s == -1) {
     2317+               archive_set_error(&a->archive, errno,
     2318+                   "Failed to get first ACL entry");
     2319+               return (ARCHIVE_WARN);
     2320+       }
     2321+
     2322+       while (s == 1) {
     2323+               ae_id = -1;
     2324+               ae_name = NULL;
     2325+               ae_perm = 0;
     2326+
     2327+               if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
     2328+                       archive_set_error(&a->archive, errno,
     2329+                           "Failed to get ACL tag type");
     2330+                       return (ARCHIVE_WARN);
     2331+               }
     2332+               switch (acl_tag) {
     2333+               case ACL_USER:
     2334+                       q = acl_get_qualifier(acl_entry);
     2335+                       if (q != NULL) {
     2336+                               ae_id = (int)*(uid_t *)q;
     2337+                               acl_free(q);
     2338+                               ae_name = archive_read_disk_uname(&a->archive,
     2339+                                   ae_id);
     2340+                       }
     2341+                       ae_tag = ARCHIVE_ENTRY_ACL_USER;
     2342+                       break;
     2343+               case ACL_GROUP:
     2344+                       q = acl_get_qualifier(acl_entry);
     2345+                       if (q != NULL) {
     2346+                               ae_id = (int)*(gid_t *)q;
     2347+                               acl_free(q);
     2348+                               ae_name = archive_read_disk_gname(&a->archive,
     2349+                                   ae_id);
     2350+                       }
     2351+                       ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
     2352+                       break;
     2353+               case ACL_MASK:
     2354+                       ae_tag = ARCHIVE_ENTRY_ACL_MASK;
     2355+                       break;
     2356+               case ACL_USER_OBJ:
     2357+                       ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
     2358+                       break;
     2359+               case ACL_GROUP_OBJ:
     2360+                       ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
     2361+                       break;
     2362+               case ACL_OTHER:
     2363+                       ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
     2364+                       break;
     2365+#if ARCHIVE_ACL_FREEBSD_NFS4
     2366+               case ACL_EVERYONE:
     2367+                       ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
     2368+                       break;
     2369+#endif
     2370+               default:
     2371+                       /* Skip types that libarchive can't support. */
     2372+                       s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
     2373+                       continue;
     2374+               }
     2375+
     2376+               // XXX acl_type maps to allow/deny/audit/YYYY bits
     2377+               entry_acl_type = default_entry_acl_type;
     2378+
     2379+#if ARCHIVE_ACL_FREEBSD_NFS4
     2380+               if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     2381+                       /*
     2382+                        * acl_get_entry_type_np() fails with non-NFSv4 ACLs
     2383+                        */
     2384+                       if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) {
     2385+                               archive_set_error(&a->archive, errno, "Failed "
     2386+                                   "to get ACL type from a NFSv4 ACL entry");
     2387+                               return (ARCHIVE_WARN);
     2388+                       }
     2389+                       switch (acl_type) {
     2390+                       case ACL_ENTRY_TYPE_ALLOW:
     2391+                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
     2392+                               break;
     2393+                       case ACL_ENTRY_TYPE_DENY:
     2394+                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
     2395+                               break;
     2396+                       case ACL_ENTRY_TYPE_AUDIT:
     2397+                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
     2398+                               break;
     2399+                       case ACL_ENTRY_TYPE_ALARM:
     2400+                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
     2401+                               break;
     2402+                       default:
     2403+                               archive_set_error(&a->archive, errno,
     2404+                                   "Invalid NFSv4 ACL entry type");
     2405+                               return (ARCHIVE_WARN);
     2406+                       }
     2407+
     2408+                       /*
     2409+                        * Libarchive stores "flag" (NFSv4 inheritance bits)
     2410+                        * in the ae_perm bitmap.
     2411+                        *
     2412+                        * acl_get_flagset_np() fails with non-NFSv4 ACLs
     2413+                        */
     2414+                       if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
     2415+                               archive_set_error(&a->archive, errno,
     2416+                                   "Failed to get flagset from a NFSv4 "
     2417+                                   "ACL entry");
     2418+                               return (ARCHIVE_WARN);
     2419+                       }
     2420+                       for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
     2421+                               r = acl_get_flag_np(acl_flagset,
     2422+                                   acl_nfs4_flag_map[i].p_perm);
     2423+                               if (r == -1) {
     2424+                                       archive_set_error(&a->archive, errno,
     2425+                                           "Failed to check flag in a NFSv4 "
     2426+                                           "ACL flagset");
     2427+                                       return (ARCHIVE_WARN);
     2428+                               } else if (r)
     2429+                                       ae_perm |= acl_nfs4_flag_map[i].a_perm;
     2430+                       }
     2431+               }
     2432+#endif
     2433+
     2434+               if (acl_get_permset(acl_entry, &acl_permset) != 0) {
     2435+                       archive_set_error(&a->archive, errno,
     2436+                           "Failed to get ACL permission set");
     2437+                       return (ARCHIVE_WARN);
     2438+               }
     2439+
     2440+#if ARCHIVE_ACL_FREEBSD_NFS4
     2441+               if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     2442+                       perm_map_size = acl_nfs4_perm_map_size;
     2443+                       perm_map = acl_nfs4_perm_map;
     2444+               } else {
     2445+#endif
     2446+                       perm_map_size = acl_posix_perm_map_size;
     2447+                       perm_map = acl_posix_perm_map;
     2448+#if ARCHIVE_ACL_FREEBSD_NFS4
     2449+               }
     2450+#endif
     2451+
     2452+               for (i = 0; i < perm_map_size; ++i) {
     2453+                       r = acl_get_perm_np(acl_permset, perm_map[i].p_perm);
     2454+                       if (r == -1) {
     2455+                               archive_set_error(&a->archive, errno,
     2456+                                   "Failed to check permission in an ACL "
     2457+                                   "permission set");
     2458+                               return (ARCHIVE_WARN);
     2459+                       } else if (r)
     2460+                               ae_perm |= perm_map[i].a_perm;
     2461+               }
     2462+
     2463+               archive_entry_acl_add_entry(entry, entry_acl_type,
     2464+                                           ae_perm, ae_tag,
     2465+                                           ae_id, ae_name);
     2466+
     2467+               s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
     2468+               if (s == -1) {
     2469+                       archive_set_error(&a->archive, errno,
     2470+                           "Failed to get next ACL entry");
     2471+                       return (ARCHIVE_WARN);
     2472+               }
     2473+       }
     2474+       return (ARCHIVE_OK);
     2475+}
     2476+
     2477+int
     2478+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
     2479+    struct archive_entry *entry, int *fd)
     2480+{
     2481+       const char      *accpath;
     2482+       acl_t           acl;
     2483+       int             r;
     2484+
     2485+       accpath = NULL;
     2486+
     2487+       if (*fd < 0) {
     2488+               accpath = archive_read_disk_entry_setup_path(a, entry, fd);
     2489+               if (accpath == NULL)
     2490+                       return (ARCHIVE_WARN);
     2491+       }
     2492+
     2493+       archive_entry_acl_clear(entry);
     2494+
     2495+       acl = NULL;
     2496+
     2497+#if ARCHIVE_ACL_FREEBSD_NFS4
     2498+       /* Try NFSv4 ACL first. */
     2499+       if (*fd >= 0)
     2500+               acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4);
     2501+       else if (!a->follow_symlinks)
     2502+               acl = acl_get_link_np(accpath, ACL_TYPE_NFS4);
     2503+       else
     2504+               acl = acl_get_file(accpath, ACL_TYPE_NFS4);
     2505+
     2506+       /* Ignore "trivial" ACLs that just mirror the file mode. */
     2507+       if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
     2508+               acl_free(acl);
     2509+               acl = NULL;
     2510+               return (ARCHIVE_OK);
     2511+       }
     2512+
     2513+       if (acl != NULL) {
     2514+               r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
     2515+               acl_free(acl);
     2516+               acl = NULL;
     2517+
     2518+               if (r != ARCHIVE_OK) {
     2519+                       archive_set_error(&a->archive, errno,
     2520+                           "Couldn't translate NFSv4 ACLs");
     2521+               }
     2522+
     2523+               return (r);
     2524+       }
     2525+#endif
     2526+
     2527+       /* Retrieve access ACL from file. */
     2528+       if (*fd >= 0)
     2529+               acl = acl_get_fd_np(*fd, ACL_TYPE_ACCESS);
     2530+#if HAVE_ACL_GET_LINK_NP
     2531+       else if (!a->follow_symlinks)
     2532+               acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
     2533+#else
     2534+       else if ((!a->follow_symlinks)
     2535+           && (archive_entry_filetype(entry) == AE_IFLNK))
     2536+               /* We can't get the ACL of a symlink, so we assume it can't
     2537+                  have one. */
     2538+               acl = NULL;
     2539+#endif
     2540+       else
     2541+               acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
     2542+
     2543+#if HAVE_ACL_IS_TRIVIAL_NP
     2544+       /* Ignore "trivial" ACLs that just mirror the file mode. */
     2545+       if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
     2546+               acl_free(acl);
     2547+               acl = NULL;
     2548+       }
     2549+#endif
     2550+
     2551+       if (acl != NULL) {
     2552+               r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
     2553+               acl_free(acl);
     2554+               acl = NULL;
     2555+
     2556+               if (r != ARCHIVE_OK) {
     2557+                       archive_set_error(&a->archive, errno,
     2558+                           "Couldn't translate access ACLs");
     2559+                       return (r);
     2560+               }
     2561+       }
     2562+
     2563+       /* Only directories can have default ACLs. */
     2564+       if (S_ISDIR(archive_entry_mode(entry))) {
     2565+               if (*fd >= 0)
     2566+                       acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT);
     2567+               else
     2568+                       acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
     2569+               if (acl != NULL) {
     2570+                       r = translate_acl(a, entry, acl,
     2571+                           ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
     2572+                       acl_free(acl);
     2573+                       if (r != ARCHIVE_OK) {
     2574+                               archive_set_error(&a->archive, errno,
     2575+                                   "Couldn't translate default ACLs");
     2576+                               return (r);
     2577+                       }
     2578+               }
     2579+       }
     2580+       return (ARCHIVE_OK);
     2581+}
     2582--- /dev/null
     2583+++ libarchive/archive_read_disk_acl_linux.c
     2584@@ -0,0 +1,352 @@
     2585+/*-
     2586+ * Copyright (c) 2003-2009 Tim Kientzle
     2587+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
     2588+ * Copyright (c) 2016-2017 Martin Matuska
     2589+ * All rights reserved.
     2590+ *
     2591+ * Redistribution and use in source and binary forms, with or without
     2592+ * modification, are permitted provided that the following conditions
     2593+ * are met:
     2594+ * 1. Redistributions of source code must retain the above copyright
     2595+ *    notice, this list of conditions and the following disclaimer.
     2596+ * 2. Redistributions in binary form must reproduce the above copyright
     2597+ *    notice, this list of conditions and the following disclaimer in the
     2598+ *    documentation and/or other materials provided with the distribution.
     2599+ *
     2600+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     2601+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     2602+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     2603+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     2604+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     2605+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     2606+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     2607+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     2608+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     2609+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     2610+ */
     2611+
     2612+#include "archive_platform.h"
     2613+
     2614+#ifdef HAVE_ERRNO_H
     2615+#include <errno.h>
     2616+#endif
     2617+#ifdef HAVE_FCNTL_H
     2618+#include <fcntl.h>
     2619+#endif
     2620+#if HAVE_ACL_LIBACL_H
     2621+#include <acl/libacl.h>
     2622+#endif
     2623+#ifdef HAVE_SYS_ACL_H
     2624+#include <sys/acl.h>
     2625+#endif
     2626+#if HAVE_SYS_RICHACL_H
     2627+#include <sys/richacl.h>
     2628+#endif
     2629+
     2630+#include "archive_entry.h"
     2631+#include "archive_private.h"
     2632+#include "archive_read_disk_private.h"
     2633+#include "archive_acl_maps.h"
     2634+
     2635+#if HAVE_LIBACL
     2636+#include <acl/libacl.h>
     2637+#endif
     2638+
     2639+#if ARCHIVE_ACL_LIBACL
     2640+/*
     2641+ * Translate POSIX.1e ACLs into libarchive internal structure
     2642+ */
     2643+static int
     2644+translate_acl(struct archive_read_disk *a,
     2645+    struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
     2646+{
     2647+       acl_tag_t        acl_tag;
     2648+       acl_entry_t      acl_entry;
     2649+       acl_permset_t    acl_permset;
     2650+       int              i, entry_acl_type;
     2651+       int              r, s, ae_id, ae_tag, ae_perm;
     2652+       void            *q;
     2653+       const char      *ae_name;
     2654+
     2655+       s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
     2656+       if (s == -1) {
     2657+               archive_set_error(&a->archive, errno,
     2658+                   "Failed to get first ACL entry");
     2659+               return (ARCHIVE_WARN);
     2660+       }
     2661+
     2662+       while (s == 1) {
     2663+               ae_id = -1;
     2664+               ae_name = NULL;
     2665+               ae_perm = 0;
     2666+
     2667+               if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
     2668+                       archive_set_error(&a->archive, errno,
     2669+                           "Failed to get ACL tag type");
     2670+                       return (ARCHIVE_WARN);
     2671+               }
     2672+               switch (acl_tag) {
     2673+               case ACL_USER:
     2674+                       q = acl_get_qualifier(acl_entry);
     2675+                       if (q != NULL) {
     2676+                               ae_id = (int)*(uid_t *)q;
     2677+                               acl_free(q);
     2678+                               ae_name = archive_read_disk_uname(&a->archive,
     2679+                                   ae_id);
     2680+                       }
     2681+                       ae_tag = ARCHIVE_ENTRY_ACL_USER;
     2682+                       break;
     2683+               case ACL_GROUP:
     2684+                       q = acl_get_qualifier(acl_entry);
     2685+                       if (q != NULL) {
     2686+                               ae_id = (int)*(gid_t *)q;
     2687+                               acl_free(q);
     2688+                               ae_name = archive_read_disk_gname(&a->archive,
     2689+                                   ae_id);
     2690+                       }
     2691+                       ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
     2692+                       break;
     2693+               case ACL_MASK:
     2694+                       ae_tag = ARCHIVE_ENTRY_ACL_MASK;
     2695+                       break;
     2696+               case ACL_USER_OBJ:
     2697+                       ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
     2698+                       break;
     2699+               case ACL_GROUP_OBJ:
     2700+                       ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
     2701+                       break;
     2702+               case ACL_OTHER:
     2703+                       ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
     2704+                       break;
     2705+               default:
     2706+                       /* Skip types that libarchive can't support. */
     2707+                       s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
     2708+                       continue;
     2709+               }
     2710+
     2711+               // XXX acl_type maps to allow/deny/audit/YYYY bits
     2712+               entry_acl_type = default_entry_acl_type;
     2713+
     2714+               if (acl_get_permset(acl_entry, &acl_permset) != 0) {
     2715+                       archive_set_error(&a->archive, errno,
     2716+                           "Failed to get ACL permission set");
     2717+                       return (ARCHIVE_WARN);
     2718+               }
     2719+
     2720+               for (i = 0; i < acl_posix_perm_map_size; ++i) {
     2721+                       r = acl_get_perm(acl_permset,
     2722+                           acl_posix_perm_map[i].p_perm);
     2723+                       if (r == -1) {
     2724+                               archive_set_error(&a->archive, errno,
     2725+                                   "Failed to check permission in an ACL "
     2726+                                   "permission set");
     2727+                               return (ARCHIVE_WARN);
     2728+                       } else if (r)
     2729+                               ae_perm |= acl_posix_perm_map[i].a_perm;
     2730+               }
     2731+
     2732+               archive_entry_acl_add_entry(entry, entry_acl_type,
     2733+                                           ae_perm, ae_tag,
     2734+                                           ae_id, ae_name);
     2735+
     2736+               s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
     2737+               if (s == -1) {
     2738+                       archive_set_error(&a->archive, errno,
     2739+                           "Failed to get next ACL entry");
     2740+                       return (ARCHIVE_WARN);
     2741+               }
     2742+       }
     2743+       return (ARCHIVE_OK);
     2744+}
     2745+#endif /* ARCHIVE_ACL_LIBACL */
     2746+
     2747+#if ARCHIVE_ACL_LIBRICHACL
     2748+/*
     2749+ * Translate RichACL into libarchive internal ACL
     2750+ */
     2751+static int
     2752+translate_richacl(struct archive_read_disk *a, struct archive_entry *entry,
     2753+    struct richacl *richacl)
     2754+{
     2755+       int ae_id, ae_tag, ae_perm;
     2756+       int entry_acl_type, i;
     2757+       const char *ae_name;
     2758+
     2759+       struct richace *richace;
     2760+
     2761+       richacl_for_each_entry(richace, richacl) {
     2762+               ae_name = NULL;
     2763+               ae_tag = 0;
     2764+               ae_perm = 0;
     2765+               ae_id = -1;
     2766+
     2767+               switch (richace->e_type) {
     2768+               case RICHACE_ACCESS_ALLOWED_ACE_TYPE:
     2769+                       entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
     2770+                       break;
     2771+               case RICHACE_ACCESS_DENIED_ACE_TYPE:
     2772+                       entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
     2773+                       break;
     2774+               default: /* Unknown entry type, skip */
     2775+                       continue;
     2776+               }
     2777+
     2778+               /* Unsupported */
     2779+               if (richace->e_flags & RICHACE_UNMAPPED_WHO)
     2780+                       continue;
     2781+
     2782+               if (richace->e_flags & RICHACE_SPECIAL_WHO) {
     2783+                       switch (richace->e_id) {
     2784+                       case RICHACE_OWNER_SPECIAL_ID:
     2785+                               ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
     2786+                               break;
     2787+                       case RICHACE_GROUP_SPECIAL_ID:
     2788+                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
     2789+                               break;
     2790+                       case RICHACE_EVERYONE_SPECIAL_ID:
     2791+                               ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
     2792+                               break;
     2793+                       default: /* Unknown special ID type */
     2794+                               continue;
     2795+                       }
     2796+               } else {
     2797+                       ae_id = richace->e_id;
     2798+                       if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) {
     2799+                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
     2800+                               ae_name = archive_read_disk_gname(&a->archive,
     2801+                                   (gid_t)(richace->e_id));
     2802+                       } else {
     2803+                               ae_tag = ARCHIVE_ENTRY_ACL_USER;
     2804+                               ae_name = archive_read_disk_uname(&a->archive,
     2805+                                   (uid_t)(richace->e_id));
     2806+                       }
     2807+               }
     2808+               for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
     2809+                       if ((richace->e_flags &
     2810+                           acl_nfs4_flag_map[i].p_perm) != 0)
     2811+                               ae_perm |= acl_nfs4_flag_map[i].a_perm;
     2812+               }
     2813+               for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
     2814+                       if ((richace->e_mask &
     2815+                           acl_nfs4_perm_map[i].p_perm) != 0)
     2816+                               ae_perm |=
     2817+                                   acl_nfs4_perm_map[i].a_perm;
     2818+               }
     2819+
     2820+               archive_entry_acl_add_entry(entry, entry_acl_type,
     2821+                   ae_perm, ae_tag, ae_id, ae_name);
     2822+       }
     2823+       return (ARCHIVE_OK);
     2824+}
     2825+#endif /* ARCHIVE_ACL_LIBRICHACL */
     2826+
     2827+int
     2828+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
     2829+    struct archive_entry *entry, int *fd)
     2830+{
     2831+       const char      *accpath;
     2832+       int             r;
     2833+#if ARCHIVE_ACL_LIBACL
     2834+       acl_t           acl;
     2835+#endif
     2836+#if ARCHIVE_ACL_LIBRICHACL
     2837+       struct richacl *richacl;
     2838+       mode_t          mode;
     2839+#endif
     2840+
     2841+       accpath = NULL;
     2842+       r = ARCHIVE_OK;
     2843+
     2844+       /* For default ACLs we need reachable accpath */
     2845+       if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) {
     2846+               accpath = archive_read_disk_entry_setup_path(a, entry, fd);
     2847+               if (accpath == NULL)
     2848+                       return (ARCHIVE_WARN);
     2849+       }
     2850+
     2851+       archive_entry_acl_clear(entry);
     2852+
     2853+#if ARCHIVE_ACL_LIBACL
     2854+       acl = NULL;
     2855+#endif
     2856+#if ARCHIVE_ACL_LIBRICHACL
     2857+       richacl = NULL;
     2858+#endif
     2859+
     2860+#if ARCHIVE_ACL_LIBRICHACL
     2861+       /* Try NFSv4 ACL first. */
     2862+       if (*fd >= 0)
     2863+               richacl = richacl_get_fd(*fd);
     2864+       else if ((!a->follow_symlinks)
     2865+           && (archive_entry_filetype(entry) == AE_IFLNK))
     2866+               /* We can't get the ACL of a symlink, so we assume it can't
     2867+                  have one */
     2868+               richacl = NULL;
     2869+       else
     2870+               richacl = richacl_get_file(accpath);
     2871+
     2872+       /* Ignore "trivial" ACLs that just mirror the file mode. */
     2873+       if (richacl != NULL) {
     2874+               mode = archive_entry_mode(entry);
     2875+               if (richacl_equiv_mode(richacl, &mode) == 0) {
     2876+                       richacl_free(richacl);
     2877+                       richacl = NULL;
     2878+                       return (ARCHIVE_OK);
     2879+               }
     2880+       }
     2881+
     2882+       if (richacl != NULL) {
     2883+               r = translate_richacl(a, entry, richacl);
     2884+               richacl_free(richacl);
     2885+               richacl = NULL;
     2886+
     2887+               if (r != ARCHIVE_OK) {
     2888+                       archive_set_error(&a->archive, errno,
     2889+                       "Couldn't translate NFSv4 ACLs");
     2890+               }
     2891+
     2892+               return (r);
     2893+       }
     2894+#endif /* ARCHIVE_ACL_LIBRICHACL */
     2895+
     2896+#if ARCHIVE_ACL_LIBACL
     2897+       /* Retrieve access ACL from file. */
     2898+       if (*fd >= 0)
     2899+               acl = acl_get_fd(*fd);
     2900+       else if ((!a->follow_symlinks)
     2901+           && (archive_entry_filetype(entry) == AE_IFLNK))
     2902+               /* We can't get the ACL of a symlink, so we assume it can't
     2903+                  have one. */
     2904+               acl = NULL;
     2905+       else
     2906+               acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
     2907+
     2908+       if (acl != NULL) {
     2909+               r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
     2910+               acl_free(acl);
     2911+               acl = NULL;
     2912+
     2913+               if (r != ARCHIVE_OK) {
     2914+                       archive_set_error(&a->archive, errno,
     2915+                           "Couldn't translate access ACLs");
     2916+                       return (r);
     2917+               }
     2918+       }
     2919+
     2920+       /* Only directories can have default ACLs. */
     2921+       if (S_ISDIR(archive_entry_mode(entry))) {
     2922+               acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
     2923+               if (acl != NULL) {
     2924+                       r = translate_acl(a, entry, acl,
     2925+                           ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
     2926+                       acl_free(acl);
     2927+                       if (r != ARCHIVE_OK) {
     2928+                               archive_set_error(&a->archive, errno,
     2929+                                   "Couldn't translate default ACLs");
     2930+                               return (r);
     2931+                       }
     2932+               }
     2933+       }
     2934+#endif /* ARCHIVE_ACL_LIBACL */
     2935+       return (r);
     2936+}
     2937--- /dev/null
     2938+++ libarchive/archive_read_disk_acl_sunos.c
     2939@@ -0,0 +1,482 @@
     2940+/*-
     2941+ * Copyright (c) 2017 Martin Matuska
     2942+ * All rights reserved.
     2943+ *
     2944+ * Redistribution and use in source and binary forms, with or without
     2945+ * modification, are permitted provided that the following conditions
     2946+ * are met:
     2947+ * 1. Redistributions of source code must retain the above copyright
     2948+ *    notice, this list of conditions and the following disclaimer.
     2949+ * 2. Redistributions in binary form must reproduce the above copyright
     2950+ *    notice, this list of conditions and the following disclaimer in the
     2951+ *    documentation and/or other materials provided with the distribution.
     2952+ *
     2953+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     2954+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     2955+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     2956+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     2957+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     2958+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     2959+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     2960+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     2961+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     2962+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     2963+ */
     2964+
     2965+#include "archive_platform.h"
     2966+
     2967+#ifdef HAVE_ERRNO_H
     2968+#include <errno.h>
     2969+#endif
     2970+#ifdef HAVE_FCNTL_H
     2971+#include <fcntl.h>
     2972+#endif
     2973+#ifdef HAVE_SYS_TYPES_H
     2974+#include <sys/types.h>
     2975+#endif
     2976+#ifdef HAVE_SYS_ACL_H
     2977+#include <sys/acl.h>
     2978+#endif
     2979+
     2980+#include "archive_entry.h"
     2981+#include "archive_private.h"
     2982+#include "archive_read_disk_private.h"
     2983+#include "archive_acl_maps.h"
     2984+
     2985+/*
     2986+ * Solaris-specific ACL functions and helper functions
     2987+ *
     2988+ * Exported functions:
     2989+ * translate_acl()
     2990+ */
     2991+static void *
     2992+sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
     2993+{
     2994+       int cnt, cntcmd;
     2995+       size_t size;
     2996+       void *aclp;
     2997+
     2998+       if (cmd == GETACL) {
     2999+               cntcmd = GETACLCNT;
     3000+               size = sizeof(aclent_t);
     3001+       }
     3002+#if ARCHIVE_ACL_SUNOS_NFS4
     3003+       else if (cmd == ACE_GETACL) {
     3004+               cntcmd = ACE_GETACLCNT;
     3005+               size = sizeof(ace_t);
     3006+       }
     3007+#endif
     3008+       else {
     3009+               errno = EINVAL;
     3010+               *aclcnt = -1;
     3011+               return (NULL);
     3012+       }
     3013+
     3014+       aclp = NULL;
     3015+       cnt = -2;
     3016+
     3017+       while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
     3018+               if (path != NULL)
     3019+                       cnt = acl(path, cntcmd, 0, NULL);
     3020+               else
     3021+                       cnt = facl(fd, cntcmd, 0, NULL);
     3022+
     3023+               if (cnt > 0) {
     3024+                       if (aclp == NULL)
     3025+                               aclp = malloc(cnt * size);
     3026+                       else
     3027+                               aclp = realloc(NULL, cnt * size);
     3028+                       if (aclp != NULL) {
     3029+                               if (path != NULL)
     3030+                                       cnt = acl(path, cmd, cnt, aclp);
     3031+                               else
     3032+                                       cnt = facl(fd, cmd, cnt, aclp);
     3033+                       }
     3034+               } else {
     3035+                       if (aclp != NULL) {
     3036+                               free(aclp);
     3037+                               aclp = NULL;
     3038+                       }
     3039+                       break;
     3040+               }
     3041+       }
     3042+
     3043+       *aclcnt = cnt;
     3044+       return (aclp);
     3045+}
     3046+
     3047+/*
     3048+ * Check if acl is trivial
     3049+ * This is a FreeBSD acl_is_trivial_np() implementation for Solaris
     3050+ */
     3051+static int
     3052+sun_acl_is_trivial(void *aclp, int aclcnt, mode_t mode, int is_nfs4,
     3053+    int is_dir, int *trivialp)
     3054+{
     3055+#if ARCHIVE_ACL_SUNOS_NFS4
     3056+       int i, p;
     3057+       const uint32_t rperm = ACE_READ_DATA;
     3058+       const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
     3059+       const uint32_t eperm = ACE_EXECUTE;
     3060+       const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
     3061+           ACE_READ_ACL | ACE_SYNCHRONIZE;
     3062+       const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES |
     3063+           ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER;
     3064+
     3065+       ace_t *ace;
     3066+       ace_t tace[6];
     3067+#endif
     3068+
     3069+       if (aclp == NULL || trivialp == NULL)
     3070+               return (-1);
     3071+
     3072+       *trivialp = 0;
     3073+
     3074+       /*
     3075+        * POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
     3076+        * FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
     3077+        * including mask.
     3078+        */
     3079+       if (!is_nfs4) {
     3080+               if (aclcnt == 4)
     3081+                       *trivialp = 1;
     3082+               return (0);
     3083+       }
     3084+
     3085+#if ARCHIVE_ACL_SUNOS_NFS4
     3086+       /*
     3087+        * Continue with checking NFSv4 ACLs
     3088+        *
     3089+        * Create list of trivial ace's to be compared
     3090+        */
     3091+
     3092+       /* owner@ allow pre */
     3093+       tace[0].a_flags = ACE_OWNER;
     3094+       tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
     3095+       tace[0].a_access_mask = 0;
     3096+
     3097+       /* owner@ deny */
     3098+       tace[1].a_flags = ACE_OWNER;
     3099+       tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
     3100+       tace[1].a_access_mask = 0;
     3101+
     3102+       /* group@ deny */
     3103+       tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
     3104+       tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
     3105+       tace[2].a_access_mask = 0;
     3106+
     3107+       /* owner@ allow */
     3108+       tace[3].a_flags = ACE_OWNER;
     3109+       tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
     3110+       tace[3].a_access_mask = ownset;
     3111+
     3112+       /* group@ allow */
     3113+       tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
     3114+       tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
     3115+       tace[4].a_access_mask = pubset;
     3116+
     3117+       /* everyone@ allow */
     3118+       tace[5].a_flags = ACE_EVERYONE;
     3119+       tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
     3120+       tace[5].a_access_mask = pubset;
     3121+
     3122+       /* Permissions for everyone@ */
     3123+       if (mode & 0004)
     3124+               tace[5].a_access_mask |= rperm;
     3125+       if (mode & 0002)
     3126+               tace[5].a_access_mask |= wperm;
     3127+       if (mode & 0001)
     3128+               tace[5].a_access_mask |= eperm;
     3129+
     3130+       /* Permissions for group@ */
     3131+       if (mode & 0040)
     3132+               tace[4].a_access_mask |= rperm;
     3133+       else if (mode & 0004)
     3134+               tace[2].a_access_mask |= rperm;
     3135+       if (mode & 0020)
     3136+               tace[4].a_access_mask |= wperm;
     3137+       else if (mode & 0002)
     3138+               tace[2].a_access_mask |= wperm;
     3139+       if (mode & 0010)
     3140+               tace[4].a_access_mask |= eperm;
     3141+       else if (mode & 0001)
     3142+               tace[2].a_access_mask |= eperm;
     3143+
     3144+       /* Permissions for owner@ */
     3145+       if (mode & 0400) {
     3146+               tace[3].a_access_mask |= rperm;
     3147+               if (!(mode & 0040) && (mode & 0004))
     3148+                       tace[0].a_access_mask |= rperm;
     3149+       } else if ((mode & 0040) || (mode & 0004))
     3150+               tace[1].a_access_mask |= rperm;
     3151+       if (mode & 0200) {
     3152+               tace[3].a_access_mask |= wperm;
     3153+               if (!(mode & 0020) && (mode & 0002))
     3154+                       tace[0].a_access_mask |= wperm;
     3155+       } else if ((mode & 0020) || (mode & 0002))
     3156+               tace[1].a_access_mask |= wperm;
     3157+       if (mode & 0100) {
     3158+               tace[3].a_access_mask |= eperm;
     3159+               if (!(mode & 0010) && (mode & 0001))
     3160+                       tace[0].a_access_mask |= eperm;
     3161+       } else if ((mode & 0010) || (mode & 0001))
     3162+               tace[1].a_access_mask |= eperm;
     3163+
     3164+       /* Check if the acl count matches */
     3165+       p = 3;
     3166+       for (i = 0; i < 3; i++) {
     3167+               if (tace[i].a_access_mask != 0)
     3168+                       p++;
     3169+       }
     3170+       if (aclcnt != p)
     3171+               return (0);
     3172+
     3173+       p = 0;
     3174+       for (i = 0; i < 6; i++) {
     3175+               if (tace[i].a_access_mask != 0) {
     3176+                       ace = &((ace_t *)aclp)[p];
     3177+                       /*
     3178+                        * Illumos added ACE_DELETE_CHILD to write perms for
     3179+                        * directories. We have to check against that, too.
     3180+                        */
     3181+                       if (ace->a_flags != tace[i].a_flags ||
     3182+                           ace->a_type != tace[i].a_type ||
     3183+                           (ace->a_access_mask != tace[i].a_access_mask &&
     3184+                           (!is_dir || (tace[i].a_access_mask & wperm) == 0 ||
     3185+                           ace->a_access_mask !=
     3186+                           (tace[i].a_access_mask | ACE_DELETE_CHILD))))
     3187+                               return (0);
     3188+                       p++;
     3189+               }
     3190+       }
     3191+
     3192+       *trivialp = 1;
     3193+#else  /* !ARCHIVE_ACL_SUNOS_NFS4 */
     3194+       (void)is_dir;   /* UNUSED */
     3195+       (void)aclp;     /* UNUSED */
     3196+#endif /* !ARCHIVE_ACL_SUNOS_NFS4 */
     3197+       return (0);
     3198+}
     3199+
     3200+/*
     3201+ * Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL
     3202+ */
     3203+static int
     3204+translate_acl(struct archive_read_disk *a,
     3205+    struct archive_entry *entry, void *aclp, int aclcnt,
     3206+    int default_entry_acl_type)
     3207+{
     3208+       int e, i;
     3209+       int ae_id, ae_tag, ae_perm;
     3210+       int entry_acl_type;
     3211+       const char *ae_name;
     3212+       aclent_t *aclent;
     3213+#if ARCHIVE_ACL_SUNOS_NFS4
     3214+       ace_t *ace;
     3215+#endif
     3216+
     3217+       if (aclcnt <= 0)
     3218+               return (ARCHIVE_OK);
     3219+
     3220+       for (e = 0; e < aclcnt; e++) {
     3221+               ae_name = NULL;
     3222+               ae_tag = 0;
     3223+               ae_perm = 0;
     3224+
     3225+#if ARCHIVE_ACL_SUNOS_NFS4
     3226+               if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     3227+                       ace = &((ace_t *)aclp)[e];
     3228+                       ae_id = ace->a_who;
     3229+
     3230+                       switch(ace->a_type) {
     3231+                       case ACE_ACCESS_ALLOWED_ACE_TYPE:
     3232+                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
     3233+                               break;
     3234+                       case ACE_ACCESS_DENIED_ACE_TYPE:
     3235+                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
     3236+                               break;
     3237+                       case ACE_SYSTEM_AUDIT_ACE_TYPE:
     3238+                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
     3239+                               break;
     3240+                       case ACE_SYSTEM_ALARM_ACE_TYPE:
     3241+                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
     3242+                               break;
     3243+                       default:
     3244+                               /* Unknown entry type, skip */
     3245+                               continue;
     3246+                       }
     3247+
     3248+                       if ((ace->a_flags & ACE_OWNER) != 0)
     3249+                               ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
     3250+                       else if ((ace->a_flags & ACE_GROUP) != 0)
     3251+                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
     3252+                       else if ((ace->a_flags & ACE_EVERYONE) != 0)
     3253+                               ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
     3254+                       else if ((ace->a_flags & ACE_IDENTIFIER_GROUP) != 0) {
     3255+                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
     3256+                               ae_name = archive_read_disk_gname(&a->archive,
     3257+                                   ae_id);
     3258+                       } else {
     3259+                               ae_tag = ARCHIVE_ENTRY_ACL_USER;
     3260+                               ae_name = archive_read_disk_uname(&a->archive,
     3261+                                   ae_id);
     3262+                       }
     3263+
     3264+                       for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
     3265+                               if ((ace->a_flags &
     3266+                                   acl_nfs4_flag_map[i].p_perm) != 0)
     3267+                                       ae_perm |= acl_nfs4_flag_map[i].a_perm;
     3268+                       }
     3269+
     3270+                       for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
     3271+                               if ((ace->a_access_mask &
     3272+                                   acl_nfs4_perm_map[i].p_perm) != 0)
     3273+                                       ae_perm |= acl_nfs4_perm_map[i].a_perm;
     3274+                       }
     3275+               } else
     3276+#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
     3277+               if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
     3278+                       aclent = &((aclent_t *)aclp)[e];
     3279+                       if ((aclent->a_type & ACL_DEFAULT) != 0)
     3280+                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
     3281+                       else
     3282+                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
     3283+                       ae_id = aclent->a_id;
     3284+
     3285+                       switch(aclent->a_type) {
     3286+                       case DEF_USER:
     3287+                       case USER:
     3288+                               ae_name = archive_read_disk_uname(&a->archive,
     3289+                                   ae_id);
     3290+                               ae_tag = ARCHIVE_ENTRY_ACL_USER;
     3291+                               break;
     3292+                       case DEF_GROUP:
     3293+                       case GROUP:
     3294+                               ae_name = archive_read_disk_gname(&a->archive,
     3295+                                   ae_id);
     3296+                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
     3297+                               break;
     3298+                       case DEF_CLASS_OBJ:
     3299+                       case CLASS_OBJ:
     3300+                               ae_tag = ARCHIVE_ENTRY_ACL_MASK;
     3301+                               break;
     3302+                       case DEF_USER_OBJ:
     3303+                       case USER_OBJ:
     3304+                               ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
     3305+                               break;
     3306+                       case DEF_GROUP_OBJ:
     3307+                       case GROUP_OBJ:
     3308+                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
     3309+                               break;
     3310+                       case DEF_OTHER_OBJ:
     3311+                       case OTHER_OBJ:
     3312+                               ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
     3313+                               break;
     3314+                       default:
     3315+                               /* Unknown tag type, skip */
     3316+                               continue;
     3317+                       }
     3318+
     3319+                       for (i = 0; i < acl_posix_perm_map_size; ++i) {
     3320+                               if ((aclent->a_perm &
     3321+                                   acl_posix_perm_map[i].p_perm) != 0)
     3322+                                       ae_perm |= acl_posix_perm_map[i].a_perm;
     3323+                       }
     3324+               } else
     3325+                       return (ARCHIVE_WARN);
     3326+
     3327+               archive_entry_acl_add_entry(entry, entry_acl_type,
     3328+                   ae_perm, ae_tag, ae_id, ae_name);
     3329+       }
     3330+       return (ARCHIVE_OK);
     3331+}
     3332+
     3333+int
     3334+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
     3335+    struct archive_entry *entry, int *fd)
     3336+{
     3337+       const char      *accpath;
     3338+       void            *aclp;
     3339+       int             aclcnt;
     3340+       int             r;
     3341+
     3342+       accpath = NULL;
     3343+
     3344+       if (*fd < 0) {
     3345+               accpath = archive_read_disk_entry_setup_path(a, entry, fd);
     3346+               if (accpath == NULL)
     3347+                       return (ARCHIVE_WARN);
     3348+       }
     3349+
     3350+       archive_entry_acl_clear(entry);
     3351+
     3352+       aclp = NULL;
     3353+
     3354+#if ARCHIVE_ACL_SUNOS_NFS4
     3355+       if (*fd >= 0)
     3356+               aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL);
     3357+       else if ((!a->follow_symlinks)
     3358+           && (archive_entry_filetype(entry) == AE_IFLNK))
     3359+               /* We can't get the ACL of a symlink, so we assume it can't
     3360+                  have one. */
     3361+               aclp = NULL;
     3362+       else
     3363+               aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath);
     3364+
     3365+       if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
     3366+           archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)),
     3367+           &r) == 0 && r == 1) {
     3368+               free(aclp);
     3369+               aclp = NULL;
     3370+               return (ARCHIVE_OK);
     3371+       }
     3372+
     3373+       if (aclp != NULL) {
     3374+               r = translate_acl(a, entry, aclp, aclcnt,
     3375+                   ARCHIVE_ENTRY_ACL_TYPE_NFS4);
     3376+               free(aclp);
     3377+               aclp = NULL;
     3378+
     3379+               if (r != ARCHIVE_OK) {
     3380+                       archive_set_error(&a->archive, errno,
     3381+                           "Couldn't translate NFSv4 ACLs");
     3382+               }
     3383+               return (r);
     3384+       }
     3385+#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
     3386+
     3387+       /* Retrieve POSIX.1e ACLs from file. */
     3388+       if (*fd >= 0)
     3389+               aclp = sunacl_get(GETACL, &aclcnt, *fd, NULL);
     3390+       else if ((!a->follow_symlinks)
     3391+           && (archive_entry_filetype(entry) == AE_IFLNK))
     3392+               /* We can't get the ACL of a symlink, so we assume it can't
     3393+                  have one. */
     3394+               aclp = NULL;
     3395+       else
     3396+               aclp = sunacl_get(GETACL, &aclcnt, 0, accpath);
     3397+
     3398+       /* Ignore "trivial" ACLs that just mirror the file mode. */
     3399+       if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
     3400+           archive_entry_mode(entry), 0, S_ISDIR(archive_entry_mode(entry)),
     3401+           &r) == 0 && r == 1) {
     3402+               free(aclp);
     3403+               aclp = NULL;
     3404+       }
     3405+
     3406+       if (aclp != NULL)
     3407+       {
     3408+               r = translate_acl(a, entry, aclp, aclcnt,
     3409+                   ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
     3410+               free(aclp);
     3411+               aclp = NULL;
     3412+
     3413+               if (r != ARCHIVE_OK) {
     3414+                       archive_set_error(&a->archive, errno,
     3415+                           "Couldn't translate access ACLs");
     3416+                       return (r);
     3417+               }
     3418+       }
     3419+
     3420+       return (ARCHIVE_OK);
     3421+}
     3422--- libarchive/archive_read_disk_entry_from_file.c.orig
     3423+++ libarchive/archive_read_disk_entry_from_file.c
     3424@@ -26,23 +26,14 @@
     3425  */
     3426 
     3427 #include "archive_platform.h"
     3428-__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 201084 2009-12-28 02:14:09Z kientzle $");
     3429+__FBSDID("$FreeBSD");
     3430 
     3431 /* This is the tree-walking code for POSIX systems. */
     3432 #if !defined(_WIN32) || defined(__CYGWIN__)
     3433 
     3434 #ifdef HAVE_SYS_TYPES_H
     3435-/* Mac OSX requires sys/types.h before sys/acl.h. */
     3436 #include <sys/types.h>
     3437 #endif
     3438-#ifdef HAVE_SYS_ACL_H
     3439-#include <sys/acl.h>
     3440-#endif
     3441-#ifdef HAVE_DARWIN_ACL
     3442-#include <membership.h>
     3443-#include <grp.h>
     3444-#include <pwd.h>
     3445-#endif
     3446 #ifdef HAVE_SYS_EXTATTR_H
     3447 #include <sys/extattr.h>
     3448 #endif
     3449@@ -63,9 +54,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
     3450 #ifdef HAVE_SYS_EA_H
     3451 #include <sys/ea.h>
     3452 #endif
     3453-#ifdef HAVE_ACL_LIBACL_H
     3454-#include <acl/libacl.h>
     3455-#endif
     3456 #ifdef HAVE_COPYFILE_H
     3457 #include <copyfile.h>
     3458 #endif
     3459@@ -113,27 +101,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
     3460 #define O_CLOEXEC      0
     3461 #endif
     3462 
     3463-/*
     3464- * Linux and FreeBSD plug this obvious hole in POSIX.1e in
     3465- * different ways.
     3466- */
     3467-#if HAVE_ACL_GET_PERM
     3468-#define        ACL_GET_PERM acl_get_perm
     3469-#elif HAVE_ACL_GET_PERM_NP
     3470-#define        ACL_GET_PERM acl_get_perm_np
     3471-#endif
     3472-
     3473-/* NFSv4 platform ACL type */
     3474-#if HAVE_SUN_ACL
     3475-#define        ARCHIVE_PLATFORM_ACL_TYPE_NFS4  ACE_T
     3476-#elif HAVE_DARWIN_ACL
     3477-#define        ARCHIVE_PLATFORM_ACL_TYPE_NFS4  ACL_TYPE_EXTENDED
     3478-#elif HAVE_ACL_TYPE_NFS4
     3479-#define        ARCHIVE_PLATFORM_ACL_TYPE_NFS4  ACL_TYPE_NFS4
     3480-#endif
     3481-
     3482-static int setup_acls(struct archive_read_disk *,
     3483-    struct archive_entry *, int *fd);
     3484 static int setup_mac_metadata(struct archive_read_disk *,
     3485     struct archive_entry *, int *fd);
     3486 static int setup_xattrs(struct archive_read_disk *,
     3487@@ -145,6 +112,45 @@ static int setup_sparse_fiemap(struct archive_read_disk *,
     3488     struct archive_entry *, int *fd);
     3489 #endif
     3490 
     3491+#if !ARCHIVE_ACL_SUPPORT
     3492+int
     3493+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
     3494+    struct archive_entry *entry, int *fd)
     3495+{
     3496+       (void)a;      /* UNUSED */
     3497+       (void)entry;  /* UNUSED */
     3498+       (void)fd;     /* UNUSED */
     3499+       return (ARCHIVE_OK);
     3500+}
     3501+#endif
     3502+
     3503+/*
     3504+ * Enter working directory and return working pathname of archive_entry.
     3505+ * If a pointer to an integer is provided and its value is below zero
     3506+ * open a file descriptor on this pahtname.
     3507+ */
     3508+const char *
     3509+archive_read_disk_entry_setup_path(struct archive_read_disk *a,
     3510+    struct archive_entry *entry, int *fd)
     3511+{
     3512+       const char *path;
     3513+
     3514+       path = archive_entry_sourcepath(entry);
     3515+
     3516+       if (path == NULL || (a->tree != NULL &&
     3517+           a->tree_enter_working_dir(a->tree) != 0))
     3518+               path = archive_entry_pathname(entry);
     3519+       if (path == NULL) {
     3520+               archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     3521+                  "Couldn't determine path");
     3522+       } else if (fd != NULL && *fd < 0 && a->tree != NULL &&
     3523+           (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)) {
     3524+               *fd = a->open_on_current_dir(a->tree, path,
     3525+                   O_RDONLY | O_NONBLOCK);
     3526+       }
     3527+       return (path);
     3528+}
     3529+
     3530 int
     3531 archive_read_disk_entry_from_file(struct archive *_a,
     3532     struct archive_entry *entry,
     3533@@ -279,7 +285,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
     3534 
     3535        r = 0;
     3536        if ((a->flags & ARCHIVE_READDISK_NO_ACL) == 0)
     3537-               r = setup_acls(a, entry, &fd);
     3538+               r = archive_read_disk_entry_setup_acls(a, entry, &fd);
     3539        if ((a->flags & ARCHIVE_READDISK_NO_XATTR) == 0) {
     3540                r1 = setup_xattrs(a, entry, &fd);
     3541                if (r1 < r)
     3542@@ -328,19 +334,10 @@ setup_mac_metadata(struct archive_read_disk *a,
     3543        struct archive_string tempfile;
     3544 
     3545        (void)fd; /* UNUSED */
     3546-       name = archive_entry_sourcepath(entry);
     3547+
     3548+       name = archive_read_disk_entry_setup_path(a, entry, NULL);
     3549        if (name == NULL)
     3550-               name = archive_entry_pathname(entry);
     3551-       else if (a->tree != NULL && a->tree_enter_working_dir(a->tree) != 0) {
     3552-               archive_set_error(&a->archive, errno,
     3553-                           "Can't change dir to read extended attributes");
     3554-                       return (ARCHIVE_FAILED);
     3555-       }
     3556-       if (name == NULL) {
     3557-               archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     3558-                   "Can't open file to read extended attributes: No name");
     3559                return (ARCHIVE_WARN);
     3560-       }
     3561 
     3562        /* Short-circuit if there's nothing to do. */
     3563        have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
     3564@@ -426,990 +423,6 @@ setup_mac_metadata(struct archive_read_disk *a,
     3565 }
     3566 #endif
     3567 
     3568-#if HAVE_DARWIN_ACL
     3569-static int translate_guid(struct archive *, acl_entry_t,
     3570-    int *, int *, const char **);
     3571-
     3572-static void add_trivial_nfs4_acl(struct archive_entry *);
     3573-#endif
     3574-
     3575-#if HAVE_SUN_ACL
     3576-static int
     3577-sun_acl_is_trivial(acl_t *, mode_t, int *trivialp);
     3578-#endif
     3579-
     3580-#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
     3581-static int translate_acl(struct archive_read_disk *a,
     3582-    struct archive_entry *entry,
     3583-#if HAVE_SUN_ACL
     3584-    acl_t *acl,
     3585-#else
     3586-    acl_t acl,
     3587-#endif
     3588-    int archive_entry_acl_type);
     3589-
     3590-static int
     3591-setup_acls(struct archive_read_disk *a,
     3592-    struct archive_entry *entry, int *fd)
     3593-{
     3594-       const char      *accpath;
     3595-#if HAVE_SUN_ACL
     3596-       acl_t           *acl;
     3597-#else
     3598-       acl_t           acl;
     3599-#endif
     3600-       int             r;
     3601-
     3602-       accpath = NULL;
     3603-
     3604-#if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_ACL_GET_FD_NP
     3605-       if (*fd < 0)
     3606-#else
     3607-       /* For default ACLs on Linux we need reachable accpath */
     3608-       if (*fd < 0 || S_ISDIR(archive_entry_mode(entry)))
     3609-#endif
     3610-       {
     3611-               accpath = archive_entry_sourcepath(entry);
     3612-               if (accpath == NULL || (a->tree != NULL &&
     3613-                   a->tree_enter_working_dir(a->tree) != 0))
     3614-                       accpath = archive_entry_pathname(entry);
     3615-               if (accpath == NULL) {
     3616-                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     3617-                           "Couldn't determine file path to read ACLs");
     3618-                       return (ARCHIVE_WARN);
     3619-               }
     3620-               if (a->tree != NULL &&
     3621-#if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_ACL_GET_FD_NP
     3622-                   *fd < 0 &&
     3623-#endif
     3624-                   (a->follow_symlinks ||
     3625-                   archive_entry_filetype(entry) != AE_IFLNK)) {
     3626-                       *fd = a->open_on_current_dir(a->tree,
     3627-                           accpath, O_RDONLY | O_NONBLOCK);
     3628-               }
     3629-       }
     3630-
     3631-       archive_entry_acl_clear(entry);
     3632-
     3633-       acl = NULL;
     3634-
     3635-#if HAVE_NFS4_ACL
     3636-       /* Try NFSv4 ACL first. */
     3637-       if (*fd >= 0)
     3638-#if HAVE_SUN_ACL
     3639-               /* Solaris reads both POSIX.1e and NFSv4 ACL here */
     3640-               facl_get(*fd, 0, &acl);
     3641-#elif HAVE_ACL_GET_FD_NP
     3642-               acl = acl_get_fd_np(*fd, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
     3643-#else
     3644-               acl = acl_get_fd(*fd);
     3645-#endif
     3646-#if HAVE_ACL_GET_LINK_NP
     3647-       else if (!a->follow_symlinks)
     3648-               acl = acl_get_link_np(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
     3649-#else
     3650-       else if ((!a->follow_symlinks)
     3651-           && (archive_entry_filetype(entry) == AE_IFLNK))
     3652-               /* We can't get the ACL of a symlink, so we assume it can't
     3653-                  have one. */
     3654-               acl = NULL;
     3655-#endif
     3656-       else
     3657-#if HAVE_SUN_ACL
     3658-               /* Solaris reads both POSIX.1e and NFSv4 ACLs here */
     3659-               acl_get(accpath, 0, &acl);
     3660-#else
     3661-               acl = acl_get_file(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
     3662-#endif
     3663-
     3664-
     3665-#if HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL
     3666-       /* Ignore "trivial" ACLs that just mirror the file mode. */
     3667-       if (acl != NULL) {
     3668-#if HAVE_SUN_ACL
     3669-               if (sun_acl_is_trivial(acl, archive_entry_mode(entry),
     3670-                   &r) == 0 && r == 1)
     3671-#elif HAVE_ACL_IS_TRIVIAL_NP
     3672-               if (acl_is_trivial_np(acl, &r) == 0 && r == 1)
     3673-#endif
     3674-               {
     3675-                       acl_free(acl);
     3676-                       acl = NULL;
     3677-                       /*
     3678-                        * Simultaneous NFSv4 and POSIX.1e ACLs for the same
     3679-                        * entry are not allowed, so we should return here
     3680-                        */
     3681-                       return (ARCHIVE_OK);
     3682-               }
     3683-       }
     3684-#endif /* HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL */
     3685-       if (acl != NULL) {
     3686-               r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
     3687-               acl_free(acl);
     3688-               if (r != ARCHIVE_OK) {
     3689-                       archive_set_error(&a->archive, errno,
     3690-                           "Couldn't translate "
     3691-#if !HAVE_SUN_ACL
     3692-                           "NFSv4 "
     3693-#endif
     3694-                           "ACLs");
     3695-               }
     3696-#if HAVE_DARWIN_ACL
     3697-               /*
     3698-                * Because Mac OS doesn't support owner@, group@ and everyone@
     3699-                * ACLs we need to add NFSv4 ACLs mirroring the file mode to
     3700-                * the archive entry. Otherwise extraction on non-Mac platforms
     3701-                * would lead to an invalid file mode.
     3702-                */
     3703-               if ((archive_entry_acl_types(entry) &
     3704-                   ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0)
     3705-                       add_trivial_nfs4_acl(entry);
     3706-#endif
     3707-               return (r);
     3708-       }
     3709-#endif /* HAVE_NFS4_ACL */
     3710-
     3711-#if HAVE_POSIX_ACL
     3712-       /* This code path is skipped on MacOS and Solaris */
     3713-
     3714-       /* Retrieve access ACL from file. */
     3715-       if (*fd >= 0)
     3716-               acl = acl_get_fd(*fd);
     3717-#if HAVE_ACL_GET_LINK_NP
     3718-       else if (!a->follow_symlinks)
     3719-               acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
     3720-#else
     3721-       else if ((!a->follow_symlinks)
     3722-           && (archive_entry_filetype(entry) == AE_IFLNK))
     3723-               /* We can't get the ACL of a symlink, so we assume it can't
     3724-                  have one. */
     3725-               acl = NULL;
     3726-#endif
     3727-       else
     3728-               acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
     3729-
     3730-#if HAVE_ACL_IS_TRIVIAL_NP
     3731-       /* Ignore "trivial" ACLs that just mirror the file mode. */
     3732-       if (acl != NULL && acl_is_trivial_np(acl, &r) == 0) {
     3733-               if (r) {
     3734-                       acl_free(acl);
     3735-                       acl = NULL;
     3736-               }
     3737-       }
     3738-#endif
     3739-
     3740-       if (acl != NULL) {
     3741-               r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
     3742-               acl_free(acl);
     3743-               acl = NULL;
     3744-               if (r != ARCHIVE_OK) {
     3745-                       archive_set_error(&a->archive, errno,
     3746-                           "Couldn't translate access ACLs");
     3747-                       return (r);
     3748-               }
     3749-       }
     3750-
     3751-       /* Only directories can have default ACLs. */
     3752-       if (S_ISDIR(archive_entry_mode(entry))) {
     3753-#if HAVE_ACL_GET_FD_NP
     3754-               if (*fd >= 0)
     3755-                       acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT);
     3756-               else
     3757-#endif
     3758-               acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
     3759-               if (acl != NULL) {
     3760-                       r = translate_acl(a, entry, acl,
     3761-                           ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
     3762-                       acl_free(acl);
     3763-                       if (r != ARCHIVE_OK) {
     3764-                               archive_set_error(&a->archive, errno,
     3765-                                   "Couldn't translate default ACLs");
     3766-                               return (r);
     3767-                       }
     3768-               }
     3769-       }
     3770-#endif /* HAVE_POSIX_ACL */
     3771-       return (ARCHIVE_OK);
     3772-}
     3773-
     3774-/*
     3775- * Translate system ACL permissions into libarchive internal structure
     3776- */
     3777-static const struct {
     3778-       const int archive_perm;
     3779-       const int platform_perm;
     3780-} acl_perm_map[] = {
     3781-#if HAVE_SUN_ACL       /* Solaris NFSv4 ACL permissions */
     3782-       {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
     3783-       {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
     3784-       {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
     3785-       {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
     3786-       {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
     3787-       {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
     3788-       {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
     3789-       {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
     3790-       {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
     3791-       {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
     3792-       {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
     3793-       {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
     3794-       {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
     3795-       {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
     3796-       {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
     3797-       {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
     3798-       {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
     3799-#elif HAVE_DARWIN_ACL  /* MacOS ACL permissions */
     3800-       {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
     3801-       {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
     3802-       {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
     3803-       {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
     3804-       {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
     3805-       {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
     3806-       {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
     3807-       {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
     3808-       {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
     3809-       {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
     3810-       {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
     3811-       {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
     3812-       {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
     3813-       {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
     3814-       {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
     3815-       {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
     3816-       {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
     3817-#else  /* POSIX.1e ACL permissions */
     3818-       {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
     3819-       {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
     3820-       {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
     3821-#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
     3822-       {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
     3823-       {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
     3824-       {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
     3825-       {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
     3826-       {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
     3827-       {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
     3828-       {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
     3829-       {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
     3830-       {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
     3831-       {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
     3832-       {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
     3833-       {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
     3834-       {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
     3835-       {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
     3836-       {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
     3837-       {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
     3838-#endif
     3839-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
     3840-};
     3841-
     3842-#if HAVE_NFS4_ACL
     3843-/*
     3844- * Translate system NFSv4 inheritance flags into libarchive internal structure
     3845- */
     3846-static const struct {
     3847-       const int archive_inherit;
     3848-       const int platform_inherit;
     3849-} acl_inherit_map[] = {
     3850-#if HAVE_SUN_ACL       /* Solaris ACL inheritance flags */
     3851-       {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
     3852-       {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
     3853-       {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
     3854-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
     3855-       {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
     3856-       {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
     3857-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
     3858-#elif HAVE_DARWIN_ACL  /* MacOS NFSv4 inheritance flags */
     3859-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
     3860-       {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
     3861-       {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
     3862-       {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
     3863-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
     3864-#else  /* FreeBSD NFSv4 ACL inheritance flags */
     3865-       {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
     3866-       {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
     3867-       {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
     3868-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
     3869-       {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
     3870-       {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
     3871-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
     3872-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
     3873-};
     3874-#endif /* HAVE_NFS4_ACL */
     3875-
     3876-#if HAVE_DARWIN_ACL
     3877-static int translate_guid(struct archive *a, acl_entry_t acl_entry,
     3878-    int *ae_id, int *ae_tag, const char **ae_name)
     3879-{
     3880-       void *q;
     3881-       uid_t ugid;
     3882-       int r, idtype;
     3883-       struct passwd *pwd;
     3884-       struct group *grp;
     3885-
     3886-       q = acl_get_qualifier(acl_entry);
     3887-       if (q == NULL)
     3888-               return (1);
     3889-       r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
     3890-       if (r != 0) {
     3891-               acl_free(q);
     3892-               return (1);
     3893-       }
     3894-       if (idtype == ID_TYPE_UID) {
     3895-               *ae_tag = ARCHIVE_ENTRY_ACL_USER;
     3896-               pwd = getpwuuid(q);
     3897-               if (pwd == NULL) {
     3898-                       *ae_id = ugid;
     3899-                       *ae_name = NULL;
     3900-               } else {
     3901-                       *ae_id = pwd->pw_uid;
     3902-                       *ae_name = archive_read_disk_uname(a, *ae_id);
     3903-               }
     3904-       } else if (idtype == ID_TYPE_GID) {
     3905-               *ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
     3906-               grp = getgruuid(q);
     3907-               if (grp == NULL) {
     3908-                       *ae_id = ugid;
     3909-                       *ae_name = NULL;
     3910-               } else {
     3911-                       *ae_id = grp->gr_gid;
     3912-                       *ae_name = archive_read_disk_gname(a, *ae_id);
     3913-               }
     3914-       } else
     3915-               r = 1;
     3916-
     3917-       acl_free(q);
     3918-       return (r);
     3919-}
     3920-
     3921-/*
     3922- * Add trivial NFSv4 ACL entries from mode
     3923- */
     3924-static void
     3925-add_trivial_nfs4_acl(struct archive_entry *entry)
     3926-{
     3927-       mode_t mode;
     3928-       int i;
     3929-       const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA;
     3930-       const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA |
     3931-           ARCHIVE_ENTRY_ACL_APPEND_DATA;
     3932-       const int eperm = ARCHIVE_ENTRY_ACL_EXECUTE;
     3933-       const int pubset = ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
     3934-           ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
     3935-           ARCHIVE_ENTRY_ACL_READ_ACL |
     3936-           ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
     3937-       const int ownset = pubset | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
     3938-           ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
     3939-           ARCHIVE_ENTRY_ACL_WRITE_ACL |
     3940-           ARCHIVE_ENTRY_ACL_WRITE_OWNER;
     3941-
     3942-       struct {
     3943-           const int type;
     3944-           const int tag;
     3945-           int permset;
     3946-       } tacl_entry[] = {
     3947-           {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
     3948-           {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
     3949-           {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0},
     3950-           {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, ownset},
     3951-           {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_GROUP_OBJ, pubset},
     3952-           {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EVERYONE, pubset}
     3953-       };
     3954-
     3955-       mode = archive_entry_mode(entry);
     3956-
     3957-       /* Permissions for everyone@ */
     3958-       if (mode & 0004)
     3959-               tacl_entry[5].permset |= rperm;
     3960-       if (mode & 0002)
     3961-               tacl_entry[5].permset |= wperm;
     3962-       if (mode & 0001)
     3963-               tacl_entry[5].permset |= eperm;
     3964-
     3965-       /* Permissions for group@ */
     3966-       if (mode & 0040)
     3967-               tacl_entry[4].permset |= rperm;
     3968-       else if (mode & 0004)
     3969-               tacl_entry[2].permset |= rperm;
     3970-       if (mode & 0020)
     3971-               tacl_entry[4].permset |= wperm;
     3972-       else if (mode & 0002)
     3973-               tacl_entry[2].permset |= wperm;
     3974-       if (mode & 0010)
     3975-               tacl_entry[4].permset |= eperm;
     3976-       else if (mode & 0001)
     3977-               tacl_entry[2].permset |= eperm;
     3978-
     3979-       /* Permissions for owner@ */
     3980-       if (mode & 0400) {
     3981-               tacl_entry[3].permset |= rperm;
     3982-               if (!(mode & 0040) && (mode & 0004))
     3983-                       tacl_entry[0].permset |= rperm;
     3984-       } else if ((mode & 0040) || (mode & 0004))
     3985-               tacl_entry[1].permset |= rperm;
     3986-       if (mode & 0200) {
     3987-               tacl_entry[3].permset |= wperm;
     3988-               if (!(mode & 0020) && (mode & 0002))
     3989-                       tacl_entry[0].permset |= wperm;
     3990-       } else if ((mode & 0020) || (mode & 0002))
     3991-               tacl_entry[1].permset |= wperm;
     3992-       if (mode & 0100) {
     3993-               tacl_entry[3].permset |= eperm;
     3994-               if (!(mode & 0010) && (mode & 0001))
     3995-                       tacl_entry[0].permset |= eperm;
     3996-       } else if ((mode & 0010) || (mode & 0001))
     3997-               tacl_entry[1].permset |= eperm;
     3998-
     3999-       for (i = 0; i < 6; i++) {
     4000-               if (tacl_entry[i].permset != 0) {
     4001-                       archive_entry_acl_add_entry(entry,
     4002-                           tacl_entry[i].type, tacl_entry[i].permset,
     4003-                           tacl_entry[i].tag, -1, NULL);
     4004-               }
     4005-       }
     4006-
     4007-       return;
     4008-}
     4009-#elif HAVE_SUN_ACL
     4010-/*
     4011- * Check if acl is trivial
     4012- * This is a FreeBSD acl_is_trivial_np() implementation for Solaris
     4013- */
     4014-static int
     4015-sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
     4016-{
     4017-       int i, p;
     4018-       const uint32_t rperm = ACE_READ_DATA;
     4019-       const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
     4020-       const uint32_t eperm = ACE_EXECUTE;
     4021-       const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
     4022-           ACE_READ_ACL | ACE_SYNCHRONIZE;
     4023-       const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES |
     4024-           ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER;
     4025-
     4026-       ace_t *ace;
     4027-       ace_t tace[6];
     4028-
     4029-       if (acl == NULL || trivialp == NULL)
     4030-               return (-1);
     4031-
     4032-       *trivialp = 0;
     4033-
     4034-       /* ACL_IS_TRIVIAL flag must be set for both POSIX.1e and NFSv4 ACLs */
     4035-       if ((acl->acl_flags & ACL_IS_TRIVIAL) == 0)
     4036-               return (0);
     4037-
     4038-       /*
     4039-        * POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
     4040-        * FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
     4041-        * including mask.
     4042-        */
     4043-       if (acl->acl_type == ACLENT_T) {
     4044-               if (acl->acl_cnt == 4)
     4045-                       *trivialp = 1;
     4046-               return (0);
     4047-       }
     4048-
     4049-       if (acl->acl_type != ACE_T || acl->acl_entry_size != sizeof(ace_t))
     4050-               return (-1);
     4051-
     4052-       /*
     4053-        * Continue with checking NFSv4 ACLs
     4054-        *
     4055-        * Create list of trivial ace's to be compared
     4056-        */
     4057-
     4058-       /* owner@ allow pre */
     4059-       tace[0].a_flags = ACE_OWNER;
     4060-       tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
     4061-       tace[0].a_access_mask = 0;
     4062-
     4063-       /* owner@ deny */
     4064-       tace[1].a_flags = ACE_OWNER;
     4065-       tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
     4066-       tace[1].a_access_mask = 0;
     4067-
     4068-       /* group@ deny */
     4069-       tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
     4070-       tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
     4071-       tace[2].a_access_mask = 0;
     4072-
     4073-       /* owner@ allow */
     4074-       tace[3].a_flags = ACE_OWNER;
     4075-       tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
     4076-       tace[3].a_access_mask = ownset;
     4077-
     4078-       /* group@ allow */
     4079-       tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
     4080-       tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
     4081-       tace[4].a_access_mask = pubset;
     4082-
     4083-       /* everyone@ allow */
     4084-       tace[5].a_flags = ACE_EVERYONE;
     4085-       tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
     4086-       tace[5].a_access_mask = pubset;
     4087-
     4088-       /* Permissions for everyone@ */
     4089-       if (mode & 0004)
     4090-               tace[5].a_access_mask |= rperm;
     4091-       if (mode & 0002)
     4092-               tace[5].a_access_mask |= wperm;
     4093-       if (mode & 0001)
     4094-               tace[5].a_access_mask |= eperm;
     4095-
     4096-       /* Permissions for group@ */
     4097-       if (mode & 0040)
     4098-               tace[4].a_access_mask |= rperm;
     4099-       else if (mode & 0004)
     4100-               tace[2].a_access_mask |= rperm;
     4101-       if (mode & 0020)
     4102-               tace[4].a_access_mask |= wperm;
     4103-       else if (mode & 0002)
     4104-               tace[2].a_access_mask |= wperm;
     4105-       if (mode & 0010)
     4106-               tace[4].a_access_mask |= eperm;
     4107-       else if (mode & 0001)
     4108-               tace[2].a_access_mask |= eperm;
     4109-
     4110-       /* Permissions for owner@ */
     4111-       if (mode & 0400) {
     4112-               tace[3].a_access_mask |= rperm;
     4113-               if (!(mode & 0040) && (mode & 0004))
     4114-                       tace[0].a_access_mask |= rperm;
     4115-       } else if ((mode & 0040) || (mode & 0004))
     4116-               tace[1].a_access_mask |= rperm;
     4117-       if (mode & 0200) {
     4118-               tace[3].a_access_mask |= wperm;
     4119-               if (!(mode & 0020) && (mode & 0002))
     4120-                       tace[0].a_access_mask |= wperm;
     4121-       } else if ((mode & 0020) || (mode & 0002))
     4122-               tace[1].a_access_mask |= wperm;
     4123-       if (mode & 0100) {
     4124-               tace[3].a_access_mask |= eperm;
     4125-               if (!(mode & 0010) && (mode & 0001))
     4126-                       tace[0].a_access_mask |= eperm;
     4127-       } else if ((mode & 0010) || (mode & 0001))
     4128-               tace[1].a_access_mask |= eperm;
     4129-
     4130-       /* Check if the acl count matches */
     4131-       p = 3;
     4132-       for (i = 0; i < 3; i++) {
     4133-               if (tace[i].a_access_mask != 0)
     4134-                       p++;
     4135-       }
     4136-       if (acl->acl_cnt != p)
     4137-               return (0);
     4138-
     4139-       p = 0;
     4140-       for (i = 0; i < 6; i++) {
     4141-               if (tace[i].a_access_mask != 0) {
     4142-                       ace = &((ace_t *)acl->acl_aclp)[p];
     4143-                       /*
     4144-                        * Illumos added ACE_DELETE_CHILD to write perms for
     4145-                        * directories. We have to check against that, too.
     4146-                        */
     4147-                       if (ace->a_flags != tace[i].a_flags ||
     4148-                           ace->a_type != tace[i].a_type ||
     4149-                           (ace->a_access_mask != tace[i].a_access_mask &&
     4150-                           ((acl->acl_flags & ACL_IS_DIR) == 0 ||
     4151-                           (tace[i].a_access_mask & wperm) == 0 ||
     4152-                           ace->a_access_mask !=
     4153-                           (tace[i].a_access_mask | ACE_DELETE_CHILD))))
     4154-                               return (0);
     4155-                       p++;
     4156-               }
     4157-       }
     4158-
     4159-       *trivialp = 1;
     4160-       return (0);
     4161-}
     4162-#endif /* HAVE_SUN_ACL */
     4163-
     4164-#if HAVE_SUN_ACL
     4165-/*
     4166- * Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL
     4167- */
     4168-static int
     4169-translate_acl(struct archive_read_disk *a,
     4170-    struct archive_entry *entry, acl_t *acl, int default_entry_acl_type)
     4171-{
     4172-       int e, i;
     4173-       int ae_id, ae_tag, ae_perm;
     4174-       int entry_acl_type;
     4175-       const char *ae_name;
     4176-       aclent_t *aclent;
     4177-       ace_t *ace;
     4178-
     4179-       (void)default_entry_acl_type;
     4180-
     4181-       if (acl->acl_cnt <= 0)
     4182-               return (ARCHIVE_OK);
     4183-
     4184-       for (e = 0; e < acl->acl_cnt; e++) {
     4185-               ae_name = NULL;
     4186-               ae_tag = 0;
     4187-               ae_perm = 0;
     4188-
     4189-               if (acl->acl_type == ACE_T) {
     4190-                       ace = &((ace_t *)acl->acl_aclp)[e];
     4191-                       ae_id = ace->a_who;
     4192-
     4193-                       switch(ace->a_type) {
     4194-                       case ACE_ACCESS_ALLOWED_ACE_TYPE:
     4195-                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
     4196-                               break;
     4197-                       case ACE_ACCESS_DENIED_ACE_TYPE:
     4198-                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
     4199-                               break;
     4200-                       case ACE_SYSTEM_AUDIT_ACE_TYPE:
     4201-                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
     4202-                               break;
     4203-                       case ACE_SYSTEM_ALARM_ACE_TYPE:
     4204-                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
     4205-                               break;
     4206-                       default:
     4207-                               /* Unknown entry type, skip */
     4208-                               continue;
     4209-                       }
     4210-
     4211-                       if ((ace->a_flags & ACE_OWNER) != 0)
     4212-                               ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
     4213-                       else if ((ace->a_flags & ACE_GROUP) != 0)
     4214-                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
     4215-                       else if ((ace->a_flags & ACE_EVERYONE) != 0)
     4216-                               ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
     4217-                       else if ((ace->a_flags & ACE_IDENTIFIER_GROUP) != 0) {
     4218-                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
     4219-                               ae_name = archive_read_disk_gname(&a->archive,
     4220-                                   ae_id);
     4221-                       } else {
     4222-                               ae_tag = ARCHIVE_ENTRY_ACL_USER;
     4223-                               ae_name = archive_read_disk_uname(&a->archive,
     4224-                                   ae_id);
     4225-                       }
     4226-
     4227-                       for (i = 0; i < (int)(sizeof(acl_inherit_map) /
     4228-                           sizeof(acl_inherit_map[0])); ++i) {
     4229-                               if ((ace->a_flags &
     4230-                                   acl_inherit_map[i].platform_inherit) != 0)
     4231-                                       ae_perm |=
     4232-                                           acl_inherit_map[i].archive_inherit;
     4233-                       }
     4234-
     4235-                       for (i = 0; i < (int)(sizeof(acl_perm_map) /
     4236-                           sizeof(acl_perm_map[0])); ++i) {
     4237-                               if ((ace->a_access_mask &
     4238-                                   acl_perm_map[i].platform_perm) != 0)
     4239-                                       ae_perm |=
     4240-                                           acl_perm_map[i].archive_perm;
     4241-                       }
     4242-               } else {
     4243-                       aclent = &((aclent_t *)acl->acl_aclp)[e];
     4244-                       if ((aclent->a_type & ACL_DEFAULT) != 0)
     4245-                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
     4246-                       else
     4247-                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
     4248-                       ae_id = aclent->a_id;
     4249-
     4250-                       switch(aclent->a_type) {
     4251-                       case DEF_USER:
     4252-                       case USER:
     4253-                               ae_name = archive_read_disk_uname(&a->archive,
     4254-                                   ae_id);
     4255-                               ae_tag = ARCHIVE_ENTRY_ACL_USER;
     4256-                               break;
     4257-                       case DEF_GROUP:
     4258-                       case GROUP:
     4259-                               ae_name = archive_read_disk_gname(&a->archive,
     4260-                                   ae_id);
     4261-                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
     4262-                               break;
     4263-                       case DEF_CLASS_OBJ:
     4264-                       case CLASS_OBJ:
     4265-                               ae_tag = ARCHIVE_ENTRY_ACL_MASK;
     4266-                               break;
     4267-                       case DEF_USER_OBJ:
     4268-                       case USER_OBJ:
     4269-                               ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
     4270-                               break;
     4271-                       case DEF_GROUP_OBJ:
     4272-                       case GROUP_OBJ:
     4273-                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
     4274-                               break;
     4275-                       case DEF_OTHER_OBJ:
     4276-                       case OTHER_OBJ:
     4277-                               ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
     4278-                               break;
     4279-                       default:
     4280-                               /* Unknown tag type, skip */
     4281-                               continue;
     4282-                       }
     4283-
     4284-                       if ((aclent->a_perm & 1) != 0)
     4285-                               ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE;
     4286-                       if ((aclent->a_perm & 2) != 0)
     4287-                               ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;
     4288-                       if ((aclent->a_perm & 4) != 0)
     4289-                               ae_perm |= ARCHIVE_ENTRY_ACL_READ;
     4290-               } /* default_entry_acl_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4 */
     4291-
     4292-               archive_entry_acl_add_entry(entry, entry_acl_type,
     4293-                   ae_perm, ae_tag, ae_id, ae_name);
     4294-       }
     4295-       return (ARCHIVE_OK);
     4296-}
     4297-#else  /* !HAVE_SUN_ACL */
     4298-/*
     4299- * Translate POSIX.1e (Linux), FreeBSD (both POSIX.1e and NFSv4) and
     4300- * MacOS (NFSv4 only) ACLs into libarchive internal structure
     4301- */
     4302-static int
     4303-translate_acl(struct archive_read_disk *a,
     4304-    struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
     4305-{
     4306-       acl_tag_t        acl_tag;
     4307-#if HAVE_ACL_TYPE_NFS4
     4308-       acl_entry_type_t acl_type;
     4309-       int brand;
     4310-#endif
     4311-#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
     4312-       acl_flagset_t    acl_flagset;
     4313-#endif
     4314-       acl_entry_t      acl_entry;
     4315-       acl_permset_t    acl_permset;
     4316-       int              i, entry_acl_type;
     4317-       int              r, s, ae_id, ae_tag, ae_perm;
     4318-#if !HAVE_DARWIN_ACL
     4319-       void            *q;
     4320-#endif
     4321-       const char      *ae_name;
     4322-
     4323-#if HAVE_ACL_TYPE_NFS4
     4324-       // FreeBSD "brands" ACLs as POSIX.1e or NFSv4
     4325-       // Make sure the "brand" on this ACL is consistent
     4326-       // with the default_entry_acl_type bits provided.
     4327-       if (acl_get_brand_np(acl, &brand) != 0) {
     4328-               archive_set_error(&a->archive, errno,
     4329-                   "Failed to read ACL brand");
     4330-               return (ARCHIVE_WARN);
     4331-       }
     4332-       switch (brand) {
     4333-       case ACL_BRAND_POSIX:
     4334-               switch (default_entry_acl_type) {
     4335-               case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
     4336-               case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
     4337-                       break;
     4338-               default:
     4339-                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     4340-                           "Invalid ACL entry type for POSIX.1e ACL");
     4341-                       return (ARCHIVE_WARN);
     4342-               }
     4343-               break;
     4344-       case ACL_BRAND_NFS4:
     4345-               if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     4346-                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     4347-                           "Invalid ACL entry type for NFSv4 ACL");
     4348-                       return (ARCHIVE_WARN);
     4349-               }
     4350-               break;
     4351-       default:
     4352-               archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     4353-                   "Unknown ACL brand");
     4354-               return (ARCHIVE_WARN);
     4355-       }
     4356-#endif
     4357-
     4358-       s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
     4359-       if (s == -1) {
     4360-               archive_set_error(&a->archive, errno,
     4361-                   "Failed to get first ACL entry");
     4362-               return (ARCHIVE_WARN);
     4363-       }
     4364-
     4365-#if HAVE_DARWIN_ACL
     4366-       while (s == 0)
     4367-#else  /* FreeBSD, Linux */
     4368-       while (s == 1)
     4369-#endif
     4370-       {
     4371-               ae_id = -1;
     4372-               ae_name = NULL;
     4373-               ae_perm = 0;
     4374-
     4375-               if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
     4376-                       archive_set_error(&a->archive, errno,
     4377-                           "Failed to get ACL tag type");
     4378-                       return (ARCHIVE_WARN);
     4379-               }
     4380-               switch (acl_tag) {
     4381-#if !HAVE_DARWIN_ACL   /* FreeBSD, Linux */
     4382-               case ACL_USER:
     4383-                       q = acl_get_qualifier(acl_entry);
     4384-                       if (q != NULL) {
     4385-                               ae_id = (int)*(uid_t *)q;
     4386-                               acl_free(q);
     4387-                               ae_name = archive_read_disk_uname(&a->archive,
     4388-                                   ae_id);
     4389-                       }
     4390-                       ae_tag = ARCHIVE_ENTRY_ACL_USER;
     4391-                       break;
     4392-               case ACL_GROUP:
     4393-                       q = acl_get_qualifier(acl_entry);
     4394-                       if (q != NULL) {
     4395-                               ae_id = (int)*(gid_t *)q;
     4396-                               acl_free(q);
     4397-                               ae_name = archive_read_disk_gname(&a->archive,
     4398-                                   ae_id);
     4399-                       }
     4400-                       ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
     4401-                       break;
     4402-               case ACL_MASK:
     4403-                       ae_tag = ARCHIVE_ENTRY_ACL_MASK;
     4404-                       break;
     4405-               case ACL_USER_OBJ:
     4406-                       ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
     4407-                       break;
     4408-               case ACL_GROUP_OBJ:
     4409-                       ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
     4410-                       break;
     4411-               case ACL_OTHER:
     4412-                       ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
     4413-                       break;
     4414-#if HAVE_ACL_TYPE_NFS4
     4415-               case ACL_EVERYONE:
     4416-                       ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
     4417-                       break;
     4418-#endif
     4419-#else  /* HAVE_DARWIN_ACL */
     4420-               case ACL_EXTENDED_ALLOW:
     4421-                       entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
     4422-                       r = translate_guid(&a->archive, acl_entry, &ae_id,
     4423-                           &ae_tag, &ae_name);
     4424-                       break;
     4425-               case ACL_EXTENDED_DENY:
     4426-                       entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
     4427-                       r = translate_guid(&a->archive, acl_entry, &ae_id,
     4428-                           &ae_tag, &ae_name);
     4429-                       break;
     4430-#endif /* HAVE_DARWIN_ACL */
     4431-               default:
     4432-                       /* Skip types that libarchive can't support. */
     4433-                       s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
     4434-                       continue;
     4435-               }
     4436-
     4437-#if HAVE_DARWIN_ACL
     4438-               /* Skip if translate_guid() above failed */
     4439-               if (r != 0) {
     4440-                       s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
     4441-                       continue;
     4442-               }
     4443-#endif
     4444-
     4445-#if !HAVE_DARWIN_ACL
     4446-               // XXX acl_type maps to allow/deny/audit/YYYY bits
     4447-               entry_acl_type = default_entry_acl_type;
     4448-#endif
     4449-#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
     4450-               if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     4451-#if HAVE_ACL_TYPE_NFS4
     4452-                       /*
     4453-                        * acl_get_entry_type_np() fails with non-NFSv4 ACLs
     4454-                        */
     4455-                       if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) {
     4456-                               archive_set_error(&a->archive, errno, "Failed "
     4457-                                   "to get ACL type from a NFSv4 ACL entry");
     4458-                               return (ARCHIVE_WARN);
     4459-                       }
     4460-                       switch (acl_type) {
     4461-                       case ACL_ENTRY_TYPE_ALLOW:
     4462-                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
     4463-                               break;
     4464-                       case ACL_ENTRY_TYPE_DENY:
     4465-                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
     4466-                               break;
     4467-                       case ACL_ENTRY_TYPE_AUDIT:
     4468-                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
     4469-                               break;
     4470-                       case ACL_ENTRY_TYPE_ALARM:
     4471-                               entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
     4472-                               break;
     4473-                       default:
     4474-                               archive_set_error(&a->archive, errno,
     4475-                                   "Invalid NFSv4 ACL entry type");
     4476-                               return (ARCHIVE_WARN);
     4477-                       }
     4478-#endif /* HAVE_ACL_TYPE_NFS4 */
     4479-
     4480-                       /*
     4481-                        * Libarchive stores "flag" (NFSv4 inheritance bits)
     4482-                        * in the ae_perm bitmap.
     4483-                        *
     4484-                        * acl_get_flagset_np() fails with non-NFSv4 ACLs
     4485-                        */
     4486-                       if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
     4487-                               archive_set_error(&a->archive, errno,
     4488-                                   "Failed to get flagset from a NFSv4 ACL entry");
     4489-                               return (ARCHIVE_WARN);
     4490-                       }
     4491-                       for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
     4492-                               r = acl_get_flag_np(acl_flagset,
     4493-                                   acl_inherit_map[i].platform_inherit);
     4494-                               if (r == -1) {
     4495-                                       archive_set_error(&a->archive, errno,
     4496-                                           "Failed to check flag in a NFSv4 "
     4497-                                           "ACL flagset");
     4498-                                       return (ARCHIVE_WARN);
     4499-                               } else if (r)
     4500-                                       ae_perm |= acl_inherit_map[i].archive_inherit;
     4501-                       }
     4502-               }
     4503-#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL */
     4504-
     4505-               if (acl_get_permset(acl_entry, &acl_permset) != 0) {
     4506-                       archive_set_error(&a->archive, errno,
     4507-                           "Failed to get ACL permission set");
     4508-                       return (ARCHIVE_WARN);
     4509-               }
     4510-               for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
     4511-                       /*
     4512-                        * acl_get_perm() is spelled differently on different
     4513-                        * platforms; see above.
     4514-                        */
     4515-                       r = ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm);
     4516-                       if (r == -1) {
     4517-                               archive_set_error(&a->archive, errno,
     4518-                                   "Failed to check permission in an ACL permission set");
     4519-                               return (ARCHIVE_WARN);
     4520-                       } else if (r)
     4521-                               ae_perm |= acl_perm_map[i].archive_perm;
     4522-               }
     4523-
     4524-               archive_entry_acl_add_entry(entry, entry_acl_type,
     4525-                                           ae_perm, ae_tag,
     4526-                                           ae_id, ae_name);
     4527-
     4528-               s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
     4529-#if !HAVE_DARWIN_ACL
     4530-               if (s == -1) {
     4531-                       archive_set_error(&a->archive, errno,
     4532-                           "Failed to get next ACL entry");
     4533-                       return (ARCHIVE_WARN);
     4534-               }
     4535-#endif
     4536-       }
     4537-       return (ARCHIVE_OK);
     4538-}
     4539-#endif /* !HAVE_SUN_ACL */
     4540-#else  /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */
     4541-static int
     4542-setup_acls(struct archive_read_disk *a,
     4543-    struct archive_entry *entry, int *fd)
     4544-{
     4545-       (void)a;      /* UNUSED */
     4546-       (void)entry;  /* UNUSED */
     4547-       (void)fd;     /* UNUSED */
     4548-       return (ARCHIVE_OK);
     4549-}
     4550-#endif /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */
     4551-
     4552 #if (HAVE_FGETXATTR && HAVE_FLISTXATTR && HAVE_LISTXATTR && \
     4553     HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR) || \
     4554     (HAVE_FGETEA && HAVE_FLISTEA && HAVE_LISTEA)
     4555@@ -1499,21 +512,9 @@ setup_xattrs(struct archive_read_disk *a,
     4556        path = NULL;
     4557 
     4558        if (*fd < 0) {
     4559-               path = archive_entry_sourcepath(entry);
     4560-               if (path == NULL || (a->tree != NULL &&
     4561-                   a->tree_enter_working_dir(a->tree) != 0))
     4562-                       path = archive_entry_pathname(entry);
     4563-               if (path == NULL) {
     4564-                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     4565-                           "Couldn't determine file path to read "
     4566-                           "extended attributes");
     4567+               path = archive_read_disk_entry_setup_path(a, entry, fd);
     4568+               if (path == NULL)
     4569                        return (ARCHIVE_WARN);
     4570-               }
     4571-               if (a->tree != NULL && (a->follow_symlinks ||
     4572-                   archive_entry_filetype(entry) != AE_IFLNK)) {
     4573-                       *fd = a->open_on_current_dir(a->tree,
     4574-                           path, O_RDONLY | O_NONBLOCK);
     4575-               }
     4576        }
     4577 
     4578 #if HAVE_FLISTXATTR
     4579@@ -1658,21 +659,9 @@ setup_xattrs(struct archive_read_disk *a,
     4580        path = NULL;
     4581 
     4582        if (*fd < 0) {
     4583-               path = archive_entry_sourcepath(entry);
     4584-               if (path == NULL || (a->tree != NULL &&
     4585-                   a->tree_enter_working_dir(a->tree) != 0))
     4586-                       path = archive_entry_pathname(entry);
     4587-               if (path == NULL) {
     4588-                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
     4589-                           "Couldn't determine file path to read "
     4590-                           "extended attributes");
     4591+               path = archive_read_disk_entry_setup_path(a, entry, fd);
     4592+               if (path == NULL)
     4593                        return (ARCHIVE_WARN);
     4594-               }
     4595-               if (a->tree != NULL && (a->follow_symlinks ||
     4596-                   archive_entry_filetype(entry) != AE_IFLNK)) {
     4597-                       *fd = a->open_on_current_dir(a->tree,
     4598-                           path, O_RDONLY | O_NONBLOCK);
     4599-               }
     4600        }
     4601 
     4602        if (*fd >= 0)
     4603@@ -1773,6 +762,7 @@ setup_sparse_fiemap(struct archive_read_disk *a,
     4604        int64_t size;
     4605        int count, do_fiemap, iters;
     4606        int exit_sts = ARCHIVE_OK;
     4607+       const char *path;
     4608 
     4609        if (archive_entry_filetype(entry) != AE_IFREG
     4610            || archive_entry_size(entry) <= 0
     4611@@ -1780,11 +770,10 @@ setup_sparse_fiemap(struct archive_read_disk *a,
     4612                return (ARCHIVE_OK);
     4613 
     4614        if (*fd < 0) {
     4615-               const char *path;
     4616-
     4617-               path = archive_entry_sourcepath(entry);
     4618+               path = archive_read_disk_entry_setup_path(a, entry, NULL);
     4619                if (path == NULL)
     4620-                       path = archive_entry_pathname(entry);
     4621+                       return (ARCHIVE_FAILED);
     4622+
     4623                if (a->tree != NULL)
     4624                        *fd = a->open_on_current_dir(a->tree, path,
     4625                                O_RDONLY | O_NONBLOCK | O_CLOEXEC);
     4626@@ -1880,6 +869,7 @@ setup_sparse(struct archive_read_disk *a,
     4627        off_t off_s, off_e;
     4628        int exit_sts = ARCHIVE_OK;
     4629        int check_fully_sparse = 0;
     4630+       const char *path;
     4631 
     4632        if (archive_entry_filetype(entry) != AE_IFREG
     4633            || archive_entry_size(entry) <= 0
     4634@@ -1887,19 +877,10 @@ setup_sparse(struct archive_read_disk *a,
     4635                return (ARCHIVE_OK);
     4636 
     4637        /* Does filesystem support the reporting of hole ? */
     4638-       if (*fd < 0 && a->tree != NULL) {
     4639-               const char *path;
     4640-
     4641-               path = archive_entry_sourcepath(entry);
     4642+       if (*fd < 0) {
     4643+               path = archive_read_disk_entry_setup_path(a, entry, fd);
     4644                if (path == NULL)
     4645-                       path = archive_entry_pathname(entry);
     4646-               *fd = a->open_on_current_dir(a->tree, path,
     4647-                               O_RDONLY | O_NONBLOCK);
     4648-               if (*fd < 0) {
     4649-                       archive_set_error(&a->archive, errno,
     4650-                           "Can't open `%s'", path);
     4651                        return (ARCHIVE_FAILED);
     4652-               }
     4653        }
     4654 
     4655        if (*fd >= 0) {
     4656@@ -1911,12 +892,6 @@ setup_sparse(struct archive_read_disk *a,
     4657                if (initial_off != 0)
     4658                        lseek(*fd, 0, SEEK_SET);
     4659        } else {
     4660-               const char *path;
     4661-
     4662-               path = archive_entry_sourcepath(entry);
     4663-               if (path == NULL)
     4664-                       path = archive_entry_pathname(entry);
     4665-                       
     4666 #ifdef _PC_MIN_HOLE_SIZE
     4667                if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
     4668                        return (ARCHIVE_OK);
     4669--- libarchive/archive_read_disk_private.h.orig
     4670+++ libarchive/archive_read_disk_private.h
     4671@@ -33,6 +33,8 @@
     4672 #ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
     4673 #define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
     4674 
     4675+#include "archive_platform_acl.h"
     4676+
     4677 struct tree;
     4678 struct archive_entry;
     4679 
     4680@@ -86,4 +88,11 @@ struct archive_read_disk {
     4681        void    *excluded_cb_data;
     4682 };
     4683 
     4684+const char *
     4685+archive_read_disk_entry_setup_path(struct archive_read_disk *,
     4686+    struct archive_entry *, int *);
     4687+
     4688+int
     4689+archive_read_disk_entry_setup_acls(struct archive_read_disk *,
     4690+    struct archive_entry *, int *);
     4691 #endif
     4692--- libarchive/archive_read_format.3.orig
     4693+++ libarchive/archive_read_format.3
     4694@@ -37,9 +37,9 @@
     4695 .Nm archive_read_support_format_empty ,
     4696 .Nm archive_read_support_format_iso9660 ,
     4697 .Nm archive_read_support_format_lha ,
     4698-.Nm archive_read_support_format_mtree,
     4699-.Nm archive_read_support_format_rar,
     4700-.Nm archive_read_support_format_raw,
     4701+.Nm archive_read_support_format_mtree ,
     4702+.Nm archive_read_support_format_rar ,
     4703+.Nm archive_read_support_format_raw ,
     4704 .Nm archive_read_support_format_tar ,
     4705 .Nm archive_read_support_format_xar ,
     4706 .Nm archive_read_support_format_zip
     4707--- libarchive/archive_read_open.3.orig
     4708+++ libarchive/archive_read_open.3
     4709@@ -33,7 +33,7 @@
     4710 .Nm archive_read_open_fd ,
     4711 .Nm archive_read_open_FILE ,
     4712 .Nm archive_read_open_filename ,
     4713-.Nm archive_read_open_memory ,
     4714+.Nm archive_read_open_memory
     4715 .Nd functions for reading streaming archives
     4716 .Sh LIBRARY
     4717 Streaming Archive Library (libarchive, -larchive)
     4718--- libarchive/archive_read_support_format_mtree.c.orifg
     4719+++ libarchive/archive_read_support_format_mtree.c
     4720@@ -1857,33 +1857,38 @@ mtree_atol8(char **p)
     4721  * Note that this implementation does not (and should not!) obey
     4722  * locale settings; you cannot simply substitute strtol here, since
     4723  * it does obey locale.
     4724+ *
     4725+ * Convert the number pointed to by 'p' into a 64-bit signed integer.
     4726+ * On return, 'p' points to the first non-digit following the number.
     4727+ * On overflow, the function returns INT64_MIN or INT64_MAX.
     4728  */
     4729 static int64_t
     4730 mtree_atol10(char **p)
     4731 {
     4732-       int64_t l, limit, last_digit_limit;
     4733-       int base, digit, sign;
     4734-
     4735-       base = 10;
     4736+       const int base = 10;
     4737+       const int64_t limit = INT64_MAX / base;
     4738+       const int64_t last_digit_limit = INT64_MAX % base;
     4739+       int64_t l;
     4740+       int sign;
     4741 
     4742        if (**p == '-') {
     4743                sign = -1;
     4744-               limit = ((uint64_t)(INT64_MAX) + 1) / base;
     4745-               last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
     4746                ++(*p);
     4747        } else {
     4748                sign = 1;
     4749-               limit = INT64_MAX / base;
     4750-               last_digit_limit = INT64_MAX % base;
     4751        }
     4752 
     4753        l = 0;
     4754-       digit = **p - '0';
     4755-       while (digit >= 0 && digit < base) {
     4756-               if (l > limit || (l == limit && digit > last_digit_limit))
     4757+       while (**p >= '0' && **p < '0' + base) {
     4758+               int digit = **p - '0';
     4759+               if (l > limit || (l == limit && digit > last_digit_limit)) {
     4760+                       while (**p >= '0' && **p < '0' + base) {
     4761+                               ++(*p);
     4762+                       }
     4763                        return (sign < 0) ? INT64_MIN : INT64_MAX;
     4764+               }
     4765                l = (l * base) + digit;
     4766-               digit = *++(*p) - '0';
     4767+               ++(*p);
     4768        }
     4769        return (sign < 0) ? -l : l;
     4770 }
     4771--- libarchive/archive_read_support_format_tar.c.orig
     4772+++ libarchive/archive_read_support_format_tar.c
     4773@@ -155,6 +155,7 @@ struct tar {
     4774        int                      compat_2x;
     4775        int                      process_mac_extensions;
     4776        int                      read_concatenated_archives;
     4777+       int                      realsize_override;
     4778 };
     4779 
     4780 static int     archive_block_is_null(const char *p);
     4781@@ -527,6 +528,7 @@ archive_read_format_tar_read_header(struct archive_read *a,
     4782        tar->entry_offset = 0;
     4783        gnu_clear_sparse_list(tar);
     4784        tar->realsize = -1; /* Mark this as "unset" */
     4785+       tar->realsize_override = 0;
     4786 
     4787        /* Setup default string conversion. */
     4788        tar->sconv = tar->opt_sconv;
     4789@@ -1894,6 +1896,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
     4790                if (strcmp(key, "GNU.sparse.size") == 0) {
     4791                        tar->realsize = tar_atol10(value, strlen(value));
     4792                        archive_entry_set_size(entry, tar->realsize);
     4793+                       tar->realsize_override = 1;
     4794                }
     4795 
     4796                /* GNU "0.1" sparse pax format. */
     4797@@ -1925,6 +1928,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
     4798                if (strcmp(key, "GNU.sparse.realsize") == 0) {
     4799                        tar->realsize = tar_atol10(value, strlen(value));
     4800                        archive_entry_set_size(entry, tar->realsize);
     4801+                       tar->realsize_override = 1;
     4802                }
     4803                break;
     4804        case 'L':
     4805@@ -1977,6 +1981,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
     4806                            tar_atol10(value, strlen(value)));
     4807                } else if (strcmp(key, "SCHILY.realsize") == 0) {
     4808                        tar->realsize = tar_atol10(value, strlen(value));
     4809+                       tar->realsize_override = 1;
     4810                        archive_entry_set_size(entry, tar->realsize);
     4811                } else if (strncmp(key, "SCHILY.xattr.", 13) == 0) {
     4812                        pax_attribute_schily_xattr(entry, key, value,
     4813@@ -2055,14 +2060,12 @@ pax_attribute(struct archive_read *a, struct tar *tar,
     4814                        tar->entry_bytes_remaining
     4815                            = tar_atol10(value, strlen(value));
     4816                        /*
     4817-                        * But, "size" is not necessarily the size of
     4818-                        * the file on disk; if this is a sparse file,
     4819-                        * the disk size may have already been set from
     4820-                        * GNU.sparse.realsize or GNU.sparse.size or
     4821-                        * an old GNU header field or SCHILY.realsize
     4822-                        * or ....
     4823+                        * The "size" pax header keyword always overrides the
     4824+                        * "size" field in the tar header.
     4825+                        * GNU.sparse.realsize, GNU.sparse.size and
     4826+                        * SCHILY.realsize override this value.
     4827                         */
     4828-                       if (tar->realsize < 0) {
     4829+                       if (!tar->realsize_override) {
     4830                                archive_entry_set_size(entry,
     4831                                    tar->entry_bytes_remaining);
     4832                                tar->realsize
     4833@@ -2206,6 +2209,7 @@ header_gnutar(struct archive_read *a, struct tar *tar,
     4834                tar->realsize
     4835                    = tar_atol(header->realsize, sizeof(header->realsize));
     4836                archive_entry_set_size(entry, tar->realsize);
     4837+               tar->realsize_override = 1;
     4838        }
     4839 
     4840        if (header->sparse[0].offset[0] != 0) {
     4841--- libarchive/archive_read_support_format_warc.c.orig
     4842+++ libarchive/archive_read_support_format_warc.c
     4843@@ -600,9 +600,10 @@ _warc_rdver(const char *buf, size_t bsz)
     4844        /* looks good so far, read the version number for a laugh */
     4845        buf += sizeof(magic) - 1U;
     4846 
     4847-       if (isdigit(buf[0U]) && (buf[1U] == '.') && isdigit(buf[2U])) {
     4848+       if (isdigit((unsigned char)buf[0U]) && (buf[1U] == '.') &&
     4849+           isdigit((unsigned char)buf[2U])) {
     4850                /* we support a maximum of 2 digits in the minor version */
     4851-               if (isdigit(buf[3U]))
     4852+               if (isdigit((unsigned char)buf[3U]))
     4853                        end = 1U;
     4854                /* set up major version */
     4855                ver = (buf[0U] - '0') * 10000U;
     4856@@ -686,7 +687,7 @@ _warc_rduri(const char *buf, size_t bsz)
     4857 
     4858        /* spaces inside uri are not allowed, CRLF should follow */
     4859        for (p = val; p < eol; p++) {
     4860-               if (isspace(*p))
     4861+               if (isspace((unsigned char)*p))
     4862                        return res;
     4863        }
     4864 
     4865@@ -736,7 +737,7 @@ _warc_rdlen(const char *buf, size_t bsz)
     4866        while (val < eol && (*val == ' ' || *val == '\t'))
     4867                val++;
     4868        /* there must be at least one digit */
     4869-       if (!isdigit(*val))
     4870+       if (!isdigit((unsigned char)*val))
     4871                return -1;
     4872        len = strtol(val, &on, 10);
     4873        if (on != eol) {
     4874--- libarchive/archive_read_support_format_zip.c.orig
     4875+++ libarchive/archive_read_support_format_zip.c
     4876@@ -2407,7 +2407,7 @@ read_eocd(struct zip *zip, const char *p, int64_t current_offset)
     4877  * Examine Zip64 EOCD locator:  If it's valid, store the information
     4878  * from it.
     4879  */
     4880-static void
     4881+static int
     4882 read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
     4883 {
     4884        int64_t eocd64_offset;
     4885@@ -2417,35 +2417,37 @@ read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
     4886 
     4887        /* Central dir must be on first volume. */
     4888        if (archive_le32dec(p + 4) != 0)
     4889-               return;
     4890+               return 0;
     4891        /* Must be only a single volume. */
     4892        if (archive_le32dec(p + 16) != 1)
     4893-               return;
     4894+               return 0;
     4895 
     4896        /* Find the Zip64 EOCD record. */
     4897        eocd64_offset = archive_le64dec(p + 8);
     4898        if (__archive_read_seek(a, eocd64_offset, SEEK_SET) < 0)
     4899-               return;
     4900+               return 0;
     4901        if ((p = __archive_read_ahead(a, 56, NULL)) == NULL)
     4902-               return;
     4903+               return 0;
     4904        /* Make sure we can read all of it. */
     4905        eocd64_size = archive_le64dec(p + 4) + 12;
     4906        if (eocd64_size < 56 || eocd64_size > 16384)
     4907-               return;
     4908+               return 0;
     4909        if ((p = __archive_read_ahead(a, (size_t)eocd64_size, NULL)) == NULL)
     4910-               return;
     4911+               return 0;
     4912 
     4913        /* Sanity-check the EOCD64 */
     4914        if (archive_le32dec(p + 16) != 0) /* Must be disk #0 */
     4915-               return;
     4916+               return 0;
     4917        if (archive_le32dec(p + 20) != 0) /* CD must be on disk #0 */
     4918-               return;
     4919+               return 0;
     4920        /* CD can't be split. */
     4921        if (archive_le64dec(p + 24) != archive_le64dec(p + 32))
     4922-               return;
     4923+               return 0;
     4924 
     4925        /* Save the central directory offset for later use. */
     4926        zip->central_directory_offset = archive_le64dec(p + 48);
     4927+
     4928+       return 32;
     4929 }
     4930 
     4931 static int
     4932@@ -2483,15 +2485,14 @@ archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
     4933                        if (memcmp(p + i, "PK\005\006", 4) == 0) {
     4934                                int ret = read_eocd(zip, p + i,
     4935                                    current_offset + i);
     4936-                               if (ret > 0) {
     4937-                                       /* Zip64 EOCD locator precedes
     4938-                                        * regular EOCD if present. */
     4939-                                       if (i >= 20
     4940-                                           && memcmp(p + i - 20, "PK\006\007", 4) == 0) {
     4941-                                               read_zip64_eocd(a, zip, p + i - 20);
     4942-                                       }
     4943-                                       return (ret);
     4944+                               /* Zip64 EOCD locator precedes
     4945+                                * regular EOCD if present. */
     4946+                               if (i >= 20 && memcmp(p + i - 20, "PK\006\007", 4) == 0) {
     4947+                                       int ret_zip64 = read_zip64_eocd(a, zip, p + i - 20);
     4948+                                       if (ret_zip64 > ret)
     4949+                                               ret = ret_zip64;
     4950                                }
     4951+                               return (ret);
     4952                        }
     4953                        i -= 4;
     4954                        break;
     4955--- libarchive/archive_util.c.orig
     4956+++ libarchive/archive_util.c
     4957@@ -89,88 +89,6 @@ archive_version_string(void)
     4958        return (ARCHIVE_VERSION_STRING);
     4959 }
     4960 
     4961-const char *
     4962-archive_version_details(void)
     4963-{
     4964-       static struct archive_string str;
     4965-       static int init = 0;
     4966-       const char *zlib = archive_zlib_version();
     4967-       const char *liblzma = archive_liblzma_version();
     4968-       const char *bzlib = archive_bzlib_version();
     4969-       const char *liblz4 = archive_liblz4_version();
     4970-
     4971-       if (!init) {
     4972-               archive_string_init(&str);
     4973-
     4974-               archive_strcat(&str, ARCHIVE_VERSION_STRING);
     4975-               if (zlib != NULL) {
     4976-                       archive_strcat(&str, " zlib/");
     4977-                       archive_strcat(&str, zlib);
     4978-               }
     4979-               if (liblzma) {
     4980-                       archive_strcat(&str, " liblzma/");
     4981-                       archive_strcat(&str, liblzma);
     4982-               }
     4983-               if (bzlib) {
     4984-                       const char *p = bzlib;
     4985-                       const char *sep = strchr(p, ',');
     4986-                       if (sep == NULL)
     4987-                               sep = p + strlen(p);
     4988-                       archive_strcat(&str, " bz2lib/");
     4989-                       archive_strncat(&str, p, sep - p);
     4990-               }
     4991-               if (liblz4) {
     4992-                       archive_strcat(&str, " liblz4/");
     4993-                       archive_strcat(&str, liblz4);
     4994-               }
     4995-       }
     4996-       return str.s;
     4997-}
     4998-
     4999-const char *
     5000-archive_zlib_version(void)
     5001-{
     5002-#ifdef HAVE_ZLIB_H
     5003-       return ZLIB_VERSION;
     5004-#else
     5005-       return NULL;
     5006-#endif
     5007-}
     5008-
     5009-const char *
     5010-archive_liblzma_version(void)
     5011-{
     5012-#ifdef HAVE_LZMA_H
     5013-       return LZMA_VERSION_STRING;
     5014-#else
     5015-       return NULL;
     5016-#endif
     5017-}
     5018-
     5019-const char *
     5020-archive_bzlib_version(void)
     5021-{
     5022-#ifdef HAVE_BZLIB_H
     5023-       return BZ2_bzlibVersion();
     5024-#else
     5025-       return NULL;
     5026-#endif
     5027-}
     5028-
     5029-const char *
     5030-archive_liblz4_version(void)
     5031-{
     5032-#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
     5033-#define str(s) #s
     5034-#define NUMBER(x) str(x)
     5035-       return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
     5036-#undef NUMBER
     5037-#undef str
     5038-#else
     5039-       return NULL;
     5040-#endif
     5041-}
     5042-
     5043 int
     5044 archive_errno(struct archive *a)
     5045 {
     5046--- /dev/null
     5047+++ libarchive/archive_version_details.c
     5048@@ -0,0 +1,133 @@
     5049+/*-
     5050+ * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA
     5051+ * Copyright (c) 2003-2007 Tim Kientzle
     5052+ * All rights reserved.
     5053+ *
     5054+ * Redistribution and use in source and binary forms, with or without
     5055+ * modification, are permitted provided that the following conditions
     5056+ * are met:
     5057+ * 1. Redistributions of source code must retain the above copyright
     5058+ *    notice, this list of conditions and the following disclaimer.
     5059+ * 2. Redistributions in binary form must reproduce the above copyright
     5060+ *    notice, this list of conditions and the following disclaimer in the
     5061+ *    documentation and/or other materials provided with the distribution.
     5062+ *
     5063+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     5064+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     5065+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     5066+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     5067+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     5068+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     5069+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     5070+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     5071+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     5072+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     5073+ */
     5074+
     5075+#include "archive_platform.h"
     5076+__FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
     5077+
     5078+#ifdef HAVE_STDLIB_H
     5079+#include <stdlib.h>
     5080+#endif
     5081+#ifdef HAVE_STRING_H
     5082+#include <string.h>
     5083+#endif
     5084+#ifdef HAVE_ZLIB_H
     5085+#include <zlib.h>
     5086+#endif
     5087+#ifdef HAVE_LZMA_H
     5088+#include <lzma.h>
     5089+#endif
     5090+#ifdef HAVE_BZLIB_H
     5091+#include <bzlib.h>
     5092+#endif
     5093+#ifdef HAVE_LZ4_H
     5094+#include <lz4.h>
     5095+#endif
     5096+
     5097+#include "archive.h"
     5098+#include "archive_private.h"
     5099+#include "archive_string.h"
     5100+
     5101+const char *
     5102+archive_version_details(void)
     5103+{
     5104+       static struct archive_string str;
     5105+       static int init = 0;
     5106+       const char *zlib = archive_zlib_version();
     5107+       const char *liblzma = archive_liblzma_version();
     5108+       const char *bzlib = archive_bzlib_version();
     5109+       const char *liblz4 = archive_liblz4_version();
     5110+
     5111+       if (!init) {
     5112+               archive_string_init(&str);
     5113+
     5114+               archive_strcat(&str, ARCHIVE_VERSION_STRING);
     5115+               if (zlib != NULL) {
     5116+                       archive_strcat(&str, " zlib/");
     5117+                       archive_strcat(&str, zlib);
     5118+               }
     5119+               if (liblzma) {
     5120+                       archive_strcat(&str, " liblzma/");
     5121+                       archive_strcat(&str, liblzma);
     5122+               }
     5123+               if (bzlib) {
     5124+                       const char *p = bzlib;
     5125+                       const char *sep = strchr(p, ',');
     5126+                       if (sep == NULL)
     5127+                               sep = p + strlen(p);
     5128+                       archive_strcat(&str, " bz2lib/");
     5129+                       archive_strncat(&str, p, sep - p);
     5130+               }
     5131+               if (liblz4) {
     5132+                       archive_strcat(&str, " liblz4/");
     5133+                       archive_strcat(&str, liblz4);
     5134+               }
     5135+       }
     5136+       return str.s;
     5137+}
     5138+
     5139+const char *
     5140+archive_zlib_version(void)
     5141+{
     5142+#ifdef HAVE_ZLIB_H
     5143+       return ZLIB_VERSION;
     5144+#else
     5145+       return NULL;
     5146+#endif
     5147+}
     5148+
     5149+const char *
     5150+archive_liblzma_version(void)
     5151+{
     5152+#ifdef HAVE_LZMA_H
     5153+       return LZMA_VERSION_STRING;
     5154+#else
     5155+       return NULL;
     5156+#endif
     5157+}
     5158+
     5159+const char *
     5160+archive_bzlib_version(void)
     5161+{
     5162+#ifdef HAVE_BZLIB_H
     5163+       return BZ2_bzlibVersion();
     5164+#else
     5165+       return NULL;
     5166+#endif
     5167+}
     5168+
     5169+const char *
     5170+archive_liblz4_version(void)
     5171+{
     5172+#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
     5173+#define str(s) #s
     5174+#define NUMBER(x) str(x)
     5175+       return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
     5176+#undef NUMBER
     5177+#undef str
     5178+#else
     5179+       return NULL;
     5180+#endif
     5181+}
     5182--- libarchive/archive_write_data.3.orig
     5183+++ libarchive/archive_write_data.3
     5184@@ -24,11 +24,12 @@
     5185 .\"
     5186 .\" $FreeBSD$
     5187 .\"
     5188-.Dd February 2, 2012
     5189+.Dd February 28, 2017
     5190 .Dt ARCHIVE_WRITE_DATA 3
     5191 .Os
     5192 .Sh NAME
     5193-.Nm archive_write_data
     5194+.Nm archive_write_data ,
     5195+.Nm archive_write_data_block
     5196 .Nd functions for creating archives
     5197 .Sh LIBRARY
     5198 Streaming Archive Library (libarchive, -larchive)
     5199@@ -36,8 +37,27 @@ Streaming Archive Library (libarchive, -larchive)
     5200 .In archive.h
     5201 .Ft la_ssize_t
     5202 .Fn archive_write_data "struct archive *" "const void *" "size_t"
     5203+.Ft la_ssize_t
     5204+.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset"
     5205 .Sh DESCRIPTION
     5206+.Bl -tag -width indent
     5207+.It Fn archive_write_data
     5208+Write data corresponding to the header just written.
     5209+.It Fn archive_write_data_block
     5210 Write data corresponding to the header just written.
     5211+This is like
     5212+.Fn archive_write_data
     5213+except that it performs a seek on the file being
     5214+written to the specified offset before writing the data.
     5215+This is useful when restoring sparse files from archive
     5216+formats that support sparse files.
     5217+Returns number of bytes written or -1 on error.
     5218+(Note: This is currently not supported for
     5219+.Tn archive_write
     5220+handles, only for
     5221+.Tn archive_write_disk
     5222+handles.
     5223+.El
     5224 .\" .Sh EXAMPLE
     5225 .\"
     5226 .Sh RETURN VALUES
     5227--- libarchive/archive_write_disk.3.orig
     5228+++ libarchive/archive_write_disk.3
     5229@@ -24,7 +24,7 @@
     5230 .\"
     5231 .\" $FreeBSD$
     5232 .\"
     5233-.Dd February 2, 2012
     5234+.Dd February 28, 2017
     5235 .Dt ARCHIVE_WRITE_DISK 3
     5236 .Os
     5237 .Sh NAME
     5238@@ -33,14 +33,7 @@
     5239 .Nm archive_write_disk_set_skip_file ,
     5240 .Nm archive_write_disk_set_group_lookup ,
     5241 .Nm archive_write_disk_set_standard_lookup ,
     5242-.Nm archive_write_disk_set_user_lookup ,
     5243-.Nm archive_write_header ,
     5244-.Nm archive_write_data ,
     5245-.Nm archive_write_data_block ,
     5246-.Nm archive_write_finish_entry ,
     5247-.Nm archive_write_close ,
     5248-.Nm archive_write_finish
     5249-.Nm archive_write_free
     5250+.Nm archive_write_disk_set_user_lookup
     5251 .Nd functions for creating objects on disk
     5252 .Sh LIBRARY
     5253 Streaming Archive Library (libarchive, -larchive)
     5254@@ -68,20 +61,6 @@ Streaming Archive Library (libarchive, -larchive)
     5255 .Fa "uid_t (*)(void *, const char *uname, uid_t uid)"
     5256 .Fa "void (*cleanup)(void *)"
     5257 .Fc
     5258-.Ft int
     5259-.Fn archive_write_header "struct archive *" "struct archive_entry *"
     5260-.Ft la_ssize_t
     5261-.Fn archive_write_data "struct archive *" "const void *" "size_t"
     5262-.Ft la_ssize_t
     5263-.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset"
     5264-.Ft int
     5265-.Fn archive_write_finish_entry "struct archive *"
     5266-.Ft int
     5267-.Fn archive_write_close "struct archive *"
     5268-.Ft int
     5269-.Fn archive_write_finish "struct archive *"
     5270-.Ft int
     5271-.Fn archive_write_free "struct archive *"
     5272 .Sh DESCRIPTION
     5273 These functions provide a complete API for creating objects on
     5274 disk from
     5275@@ -223,60 +202,6 @@ the number of calls to
     5276 .Xr getpwnam 3
     5277 and
     5278 .Xr getgrnam 3 .
     5279-.It Fn archive_write_header
     5280-Build and write a header using the data in the provided
     5281-.Tn struct archive_entry
     5282-structure.
     5283-See
     5284-.Xr archive_entry 3
     5285-for information on creating and populating
     5286-.Tn struct archive_entry
     5287-objects.
     5288-.It Fn archive_write_data
     5289-Write data corresponding to the header just written.
     5290-Returns number of bytes written or -1 on error.
     5291-.It Fn archive_write_data_block
     5292-Write data corresponding to the header just written.
     5293-This is like
     5294-.Fn archive_write_data
     5295-except that it performs a seek on the file being
     5296-written to the specified offset before writing the data.
     5297-This is useful when restoring sparse files from archive
     5298-formats that support sparse files.
     5299-Returns number of bytes written or -1 on error.
     5300-(Note: This is currently not supported for
     5301-.Tn archive_write
     5302-handles, only for
     5303-.Tn archive_write_disk
     5304-handles.)
     5305-.It Fn archive_write_finish_entry
     5306-Close out the entry just written.
     5307-Ordinarily, clients never need to call this, as it
     5308-is called automatically by
     5309-.Fn archive_write_next_header
     5310-and
     5311-.Fn archive_write_close
     5312-as needed.
     5313-However, some file attributes are written to disk only
     5314-after the file is closed, so this can be necessary
     5315-if you need to work with the file on disk right away.
     5316-.It Fn archive_write_close
     5317-Set any attributes that could not be set during the initial restore.
     5318-For example, directory timestamps are not restored initially because
     5319-restoring a subsequent file would alter that timestamp.
     5320-Similarly, non-writable directories are initially created with
     5321-write permissions (so that their contents can be restored).
     5322-The
     5323-.Nm
     5324-library maintains a list of all such deferred attributes and
     5325-sets them when this function is invoked.
     5326-.It Fn archive_write_finish
     5327-This is a deprecated synonym for
     5328-.Fn archive_write_free .
     5329-.It Fn archive_write_free
     5330-Invokes
     5331-.Fn archive_write_close
     5332-if it was not invoked manually, then releases all resources.
     5333 .El
     5334 More information about the
     5335 .Va struct archive
     5336--- libarchive/archive_write_disk_acl.c
     5337+++ /dev/null
     5338@@ -1,654 +0,0 @@
     5339-/*-
     5340- * Copyright (c) 2003-2010 Tim Kientzle
     5341- * All rights reserved.
     5342- *
     5343- * Redistribution and use in source and binary forms, with or without
     5344- * modification, are permitted provided that the following conditions
     5345- * are met:
     5346- * 1. Redistributions of source code must retain the above copyright
     5347- *    notice, this list of conditions and the following disclaimer
     5348- *    in this position and unchanged.
     5349- * 2. Redistributions in binary form must reproduce the above copyright
     5350- *    notice, this list of conditions and the following disclaimer in the
     5351- *    documentation and/or other materials provided with the distribution.
     5352- *
     5353- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     5354- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     5355- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     5356- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     5357- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     5358- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     5359- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     5360- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     5361- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     5362- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     5363- */
     5364-
     5365-#include "archive_platform.h"
     5366-__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 05:35:40Z kientzle $");
     5367-
     5368-#ifdef HAVE_SYS_TYPES_H
     5369-#include <sys/types.h>
     5370-#endif
     5371-#ifdef HAVE_SYS_ACL_H
     5372-#define _ACL_PRIVATE /* For debugging */
     5373-#include <sys/acl.h>
     5374-#endif
     5375-#if HAVE_DARWIN_ACL
     5376-#include <membership.h>
     5377-#endif
     5378-#ifdef HAVE_ERRNO_H
     5379-#include <errno.h>
     5380-#endif
     5381-
     5382-#include "archive.h"
     5383-#include "archive_entry.h"
     5384-#include "archive_acl_private.h"
     5385-#include "archive_write_disk_private.h"
     5386-
     5387-#if !HAVE_POSIX_ACL && !HAVE_NFS4_ACL
     5388-/* Default empty function body to satisfy mainline code. */
     5389-int
     5390-archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
     5391-        struct archive_acl *abstract_acl)
     5392-{
     5393-       (void)a; /* UNUSED */
     5394-       (void)fd; /* UNUSED */
     5395-       (void)name; /* UNUSED */
     5396-       (void)abstract_acl; /* UNUSED */
     5397-       return (ARCHIVE_OK);
     5398-}
     5399-
     5400-#else /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
     5401-
     5402-#if HAVE_SUN_ACL
     5403-#define        ARCHIVE_PLATFORM_ACL_TYPE_NFS4  ACE_T
     5404-#elif HAVE_DARWIN_ACL
     5405-#define        ARCHIVE_PLATFORM_ACL_TYPE_NFS4  ACL_TYPE_EXTENDED
     5406-#elif HAVE_ACL_TYPE_NFS4
     5407-#define        ARCHIVE_PLATFORM_ACL_TYPE_NFS4  ACL_TYPE_NFS4
     5408-#endif
     5409-
     5410-static int     set_acl(struct archive *, int fd, const char *,
     5411-                       struct archive_acl *,
     5412-                       acl_type_t, int archive_entry_acl_type, const char *tn);
     5413-
     5414-int
     5415-archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
     5416-        struct archive_acl *abstract_acl)
     5417-{
     5418-       int             ret = ARCHIVE_OK;
     5419-
     5420-#if !HAVE_DARWIN_ACL
     5421-       if ((archive_acl_types(abstract_acl)
     5422-           & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
     5423-#if HAVE_SUN_ACL
     5424-               /* Solaris writes POSIX.1e access and default ACLs together */
     5425-               ret = set_acl(a, fd, name, abstract_acl, ACLENT_T,
     5426-                   ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
     5427-#else  /* HAVE_POSIX_ACL */
     5428-               if ((archive_acl_types(abstract_acl)
     5429-                   & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
     5430-                       ret = set_acl(a, fd, name, abstract_acl,
     5431-                           ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
     5432-                           "access");
     5433-                       if (ret != ARCHIVE_OK)
     5434-                               return (ret);
     5435-               }
     5436-               if ((archive_acl_types(abstract_acl)
     5437-                   & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
     5438-                       ret = set_acl(a, fd, name, abstract_acl,
     5439-                           ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
     5440-                           "default");
     5441-#endif /* !HAVE_SUN_ACL */
     5442-               /* Simultaneous POSIX.1e and NFSv4 is not supported */
     5443-               return (ret);
     5444-       }
     5445-#endif /* !HAVE_DARWIN_ACL */
     5446-#if HAVE_NFS4_ACL
     5447-       if ((archive_acl_types(abstract_acl) &
     5448-           ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
     5449-               ret = set_acl(a, fd, name, abstract_acl,
     5450-                   ARCHIVE_PLATFORM_ACL_TYPE_NFS4,
     5451-                   ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
     5452-       }
     5453-#endif /* HAVE_NFS4_ACL */
     5454-       return (ret);
     5455-}
     5456-
     5457-/*
     5458- * Translate system ACL permissions into libarchive internal structure
     5459- */
     5460-static const struct {
     5461-       const int archive_perm;
     5462-       const int platform_perm;
     5463-} acl_perm_map[] = {
     5464-#if HAVE_SUN_ACL       /* Solaris NFSv4 ACL permissions */
     5465-       {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
     5466-       {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
     5467-       {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
     5468-       {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
     5469-       {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
     5470-       {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
     5471-       {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
     5472-       {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
     5473-       {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
     5474-       {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
     5475-       {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
     5476-       {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
     5477-       {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
     5478-       {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
     5479-       {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
     5480-       {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
     5481-       {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
     5482-#elif HAVE_DARWIN_ACL  /* MacOS ACL permissions */
     5483-       {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
     5484-       {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
     5485-       {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
     5486-       {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
     5487-       {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
     5488-       {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
     5489-       {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
     5490-       {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
     5491-       {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
     5492-       {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
     5493-       {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
     5494-       {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
     5495-       {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
     5496-       {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
     5497-       {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
     5498-       {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
     5499-       {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
     5500-#else  /* POSIX.1e ACL permissions */
     5501-       {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
     5502-       {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
     5503-       {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
     5504-#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
     5505-       {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
     5506-       {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
     5507-       {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
     5508-       {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
     5509-       {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
     5510-       {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
     5511-       {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
     5512-       {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
     5513-       {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
     5514-       {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
     5515-       {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
     5516-       {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
     5517-       {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
     5518-       {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
     5519-       {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
     5520-       {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
     5521-#endif
     5522-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
     5523-};
     5524-
     5525-#if HAVE_NFS4_ACL
     5526-/*
     5527- * Translate system NFSv4 inheritance flags into libarchive internal structure
     5528- */
     5529-static const struct {
     5530-       const int archive_inherit;
     5531-       const int platform_inherit;
     5532-} acl_inherit_map[] = {
     5533-#if HAVE_SUN_ACL       /* Solaris NFSv4 inheritance flags */
     5534-       {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
     5535-       {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
     5536-       {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
     5537-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
     5538-       {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
     5539-       {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
     5540-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
     5541-#elif HAVE_DARWIN_ACL  /* MacOS NFSv4 inheritance flags */
     5542-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
     5543-       {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
     5544-       {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
     5545-       {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
     5546-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
     5547-#else  /* FreeBSD NFSv4 ACL inheritance flags */
     5548-       {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
     5549-       {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
     5550-       {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
     5551-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
     5552-       {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
     5553-       {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
     5554-       {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
     5555-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
     5556-};
     5557-#endif /* HAVE_NFS4_ACL */
     5558-
     5559-static int
     5560-set_acl(struct archive *a, int fd, const char *name,
     5561-    struct archive_acl *abstract_acl,
     5562-    acl_type_t acl_type, int ae_requested_type, const char *tname)
     5563-{
     5564-#if HAVE_SUN_ACL
     5565-       aclent_t         *aclent;
     5566-       ace_t            *ace;
     5567-       int              e, r;
     5568-       acl_t            *acl;
     5569-#else
     5570-       acl_t            acl;
     5571-       acl_entry_t      acl_entry;
     5572-       acl_permset_t    acl_permset;
     5573-#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
     5574-       acl_flagset_t    acl_flagset;
     5575-#endif
     5576-#endif /* HAVE_SUN_ACL */
     5577-#if HAVE_ACL_TYPE_NFS4
     5578-       int             r;
     5579-#endif
     5580-       int              ret;
     5581-       int              ae_type, ae_permset, ae_tag, ae_id;
     5582-#if HAVE_DARWIN_ACL
     5583-       uuid_t          ae_uuid;
     5584-#endif
     5585-       uid_t            ae_uid;
     5586-       gid_t            ae_gid;
     5587-       const char      *ae_name;
     5588-       int              entries;
     5589-       int              i;
     5590-
     5591-       ret = ARCHIVE_OK;
     5592-       entries = archive_acl_reset(abstract_acl, ae_requested_type);
     5593-       if (entries == 0)
     5594-               return (ARCHIVE_OK);
     5595-
     5596-#if HAVE_SUN_ACL
     5597-       acl = NULL;
     5598-       acl = malloc(sizeof(acl_t));
     5599-       if (acl == NULL) {
     5600-               archive_set_error(a, ARCHIVE_ERRNO_MISC,
     5601-                       "Invalid ACL type");
     5602-               return (ARCHIVE_FAILED);
     5603-       }
     5604-       if (acl_type == ACE_T)
     5605-               acl->acl_entry_size = sizeof(ace_t);
     5606-       else if (acl_type == ACLENT_T)
     5607-               acl->acl_entry_size = sizeof(aclent_t);
     5608-       else {
     5609-               archive_set_error(a, ARCHIVE_ERRNO_MISC,
     5610-                       "Invalid ACL type");
     5611-               acl_free(acl);
     5612-               return (ARCHIVE_FAILED);
     5613-       }
     5614-       acl->acl_type = acl_type;
     5615-       acl->acl_cnt = entries;
     5616-
     5617-       acl->acl_aclp = malloc(entries * acl->acl_entry_size);
     5618-       if (acl->acl_aclp == NULL) {
     5619-               archive_set_error(a, errno,
     5620-                   "Can't allocate memory for acl buffer");
     5621-               acl_free(acl);
     5622-               return (ARCHIVE_FAILED);
     5623-       }
     5624-#else  /* !HAVE_SUN_ACL */
     5625-       acl = acl_init(entries);
     5626-       if (acl == (acl_t)NULL) {
     5627-               archive_set_error(a, errno,
     5628-                   "Failed to initialize ACL working storage");
     5629-               return (ARCHIVE_FAILED);
     5630-       }
     5631-#endif /* !HAVE_SUN_ACL */
     5632-#if HAVE_SUN_ACL
     5633-       e = 0;
     5634-#endif
     5635-       while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
     5636-                  &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
     5637-#if HAVE_SUN_ACL
     5638-               ace = NULL;
     5639-               aclent = NULL;
     5640-               if (acl->acl_type == ACE_T)  {
     5641-                       ace = &((ace_t *)acl->acl_aclp)[e];
     5642-                       ace->a_who = -1;
     5643-                       ace->a_access_mask = 0;
     5644-                       ace->a_flags = 0;
     5645-               } else {
     5646-                       aclent = &((aclent_t *)acl->acl_aclp)[e];
     5647-                       aclent->a_id = -1;
     5648-                       aclent->a_type = 0;
     5649-                       aclent->a_perm = 0;
     5650-               }
     5651-#else  /* !HAVE_SUN_ACL  */
     5652-#if HAVE_DARWIN_ACL
     5653-               /*
     5654-                * Mac OS doesn't support NFSv4 ACLs for
     5655-                * owner@, group@ and everyone@.
     5656-                * We skip any of these ACLs found.
     5657-                */
     5658-               if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
     5659-                   ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
     5660-                   ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
     5661-                       continue;
     5662-#endif
     5663-               if (acl_create_entry(&acl, &acl_entry) != 0) {
     5664-                       archive_set_error(a, errno,
     5665-                           "Failed to create a new ACL entry");
     5666-                       ret = ARCHIVE_FAILED;
     5667-                       goto exit_free;
     5668-               }
     5669-#endif /* !HAVE_SUN_ACL */
     5670-#if HAVE_DARWIN_ACL
     5671-               switch (ae_type) {
     5672-               case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
     5673-                       acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
     5674-                       break;
     5675-               case ARCHIVE_ENTRY_ACL_TYPE_DENY:
     5676-                       acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
     5677-                       break;
     5678-               default:
     5679-                       /* We don't support any other types on MacOS */
     5680-                       continue;
     5681-               }
     5682-#endif
     5683-               switch (ae_tag) {
     5684-#if HAVE_SUN_ACL
     5685-               case ARCHIVE_ENTRY_ACL_USER:
     5686-                       ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
     5687-                       if (acl->acl_type == ACE_T)
     5688-                               ace->a_who = ae_uid;
     5689-                       else {
     5690-                               aclent->a_id = ae_uid;
     5691-                               aclent->a_type |= USER;
     5692-                       }
     5693-                       break;
     5694-               case ARCHIVE_ENTRY_ACL_GROUP:
     5695-                       ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
     5696-                       if (acl->acl_type == ACE_T) {
     5697-                               ace->a_who = ae_gid;
     5698-                               ace->a_flags |= ACE_IDENTIFIER_GROUP;
     5699-                       } else {
     5700-                               aclent->a_id = ae_gid;
     5701-                               aclent->a_type |= GROUP;
     5702-                       }
     5703-                       break;
     5704-               case ARCHIVE_ENTRY_ACL_USER_OBJ:
     5705-                       if (acl->acl_type == ACE_T)
     5706-                               ace->a_flags |= ACE_OWNER;
     5707-                       else
     5708-                               aclent->a_type |= USER_OBJ;
     5709-                       break;
     5710-               case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
     5711-                       if (acl->acl_type == ACE_T) {
     5712-                               ace->a_flags |= ACE_GROUP;
     5713-                               ace->a_flags |= ACE_IDENTIFIER_GROUP;
     5714-                       } else
     5715-                               aclent->a_type |= GROUP_OBJ;
     5716-                       break;
     5717-               case ARCHIVE_ENTRY_ACL_MASK:
     5718-                       aclent->a_type |= CLASS_OBJ;
     5719-                       break;
     5720-               case ARCHIVE_ENTRY_ACL_OTHER:
     5721-                       aclent->a_type |= OTHER_OBJ;
     5722-                       break;
     5723-               case ARCHIVE_ENTRY_ACL_EVERYONE:
     5724-                       ace->a_flags |= ACE_EVERYONE;
     5725-                       break;
     5726-#else  /* !HAVE_SUN_ACL */
     5727-               case ARCHIVE_ENTRY_ACL_USER:
     5728-                       ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
     5729-#if !HAVE_DARWIN_ACL   /* FreeBSD, Linux */
     5730-                       acl_set_tag_type(acl_entry, ACL_USER);
     5731-                       acl_set_qualifier(acl_entry, &ae_uid);
     5732-#else  /* MacOS */
     5733-                       if (mbr_identifier_to_uuid(ID_TYPE_UID, &ae_uid,
     5734-                           sizeof(uid_t), ae_uuid) != 0)
     5735-                               continue;
     5736-                       if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
     5737-                               continue;
     5738-#endif /* HAVE_DARWIN_ACL */
     5739-                       break;
     5740-               case ARCHIVE_ENTRY_ACL_GROUP:
     5741-                       ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
     5742-#if !HAVE_DARWIN_ACL   /* FreeBSD, Linux */
     5743-                       acl_set_tag_type(acl_entry, ACL_GROUP);
     5744-                       acl_set_qualifier(acl_entry, &ae_gid);
     5745-#else  /* MacOS */
     5746-                       if (mbr_identifier_to_uuid(ID_TYPE_GID, &ae_gid,
     5747-                           sizeof(gid_t), ae_uuid) != 0)
     5748-                               continue;
     5749-                       if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
     5750-                               continue;
     5751-#endif /* HAVE_DARWIN_ACL */
     5752-                       break;
     5753-#if !HAVE_DARWIN_ACL   /* FreeBSD, Linux */
     5754-               case ARCHIVE_ENTRY_ACL_USER_OBJ:
     5755-                       acl_set_tag_type(acl_entry, ACL_USER_OBJ);
     5756-                       break;
     5757-               case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
     5758-                       acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
     5759-                       break;
     5760-               case ARCHIVE_ENTRY_ACL_MASK:
     5761-                       acl_set_tag_type(acl_entry, ACL_MASK);
     5762-                       break;
     5763-               case ARCHIVE_ENTRY_ACL_OTHER:
     5764-                       acl_set_tag_type(acl_entry, ACL_OTHER);
     5765-                       break;
     5766-#if HAVE_ACL_TYPE_NFS4 /* FreeBSD only */
     5767-               case ARCHIVE_ENTRY_ACL_EVERYONE:
     5768-                       acl_set_tag_type(acl_entry, ACL_EVERYONE);
     5769-                       break;
     5770-#endif
     5771-#endif /* !HAVE_DARWIN_ACL */
     5772-#endif /* !HAVE_SUN_ACL */
     5773-               default:
     5774-                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
     5775-                           "Unknown ACL tag");
     5776-                       ret = ARCHIVE_FAILED;
     5777-                       goto exit_free;
     5778-               }
     5779-
     5780-#if HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL
     5781-               r = 0;
     5782-               switch (ae_type) {
     5783-#if HAVE_SUN_ACL
     5784-               case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
     5785-                       if (ace != NULL)
     5786-                               ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
     5787-                       else
     5788-                               r = -1;
     5789-                       break;
     5790-               case ARCHIVE_ENTRY_ACL_TYPE_DENY:
     5791-                       if (ace != NULL)
     5792-                               ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
     5793-                       else
     5794-                               r = -1;
     5795-                       break;
     5796-               case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
     5797-                       if (ace != NULL)
     5798-                               ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
     5799-                       else
     5800-                               r = -1;
     5801-                       break;
     5802-               case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
     5803-                       if (ace != NULL)
     5804-                               ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
     5805-                       else
     5806-                               r = -1;
     5807-                       break;
     5808-               case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
     5809-                       if (aclent == NULL)
     5810-                               r = -1;
     5811-                       break;
     5812-               case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
     5813-                       if (aclent != NULL)
     5814-                               aclent->a_type |= ACL_DEFAULT;
     5815-                       else
     5816-                               r = -1;
     5817-                       break;
     5818-#else  /* !HAVE_SUN_ACL */
     5819-               case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
     5820-                       r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
     5821-                       break;
     5822-               case ARCHIVE_ENTRY_ACL_TYPE_DENY:
     5823-                       r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY);
     5824-                       break;
     5825-               case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
     5826-                       r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT);
     5827-                       break;
     5828-               case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
     5829-                       r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM);
     5830-                       break;
     5831-               case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
     5832-               case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
     5833-                       // These don't translate directly into the system ACL.
     5834-                       break;
     5835-#endif /* !HAVE_SUN_ACL */
     5836-               default:
     5837-                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
     5838-                           "Unknown ACL entry type");
     5839-                       ret = ARCHIVE_FAILED;
     5840-                       goto exit_free;
     5841-               }
     5842-
     5843-               if (r != 0) {
     5844-#if HAVE_SUN_ACL
     5845-                       errno = EINVAL;
     5846-#endif
     5847-                       archive_set_error(a, errno,
     5848-                           "Failed to set ACL entry type");
     5849-                       ret = ARCHIVE_FAILED;
     5850-                       goto exit_free;
     5851-               }
     5852-#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL */
     5853-
     5854-#if HAVE_SUN_ACL
     5855-               if (acl->acl_type == ACLENT_T) {
     5856-                       if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
     5857-                               aclent->a_perm |= 1;
     5858-                       if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
     5859-                               aclent->a_perm |= 2;
     5860-                       if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
     5861-                               aclent->a_perm |= 4;
     5862-               } else
     5863-#else
     5864-               if (acl_get_permset(acl_entry, &acl_permset) != 0) {
     5865-                       archive_set_error(a, errno,
     5866-                           "Failed to get ACL permission set");
     5867-                       ret = ARCHIVE_FAILED;
     5868-                       goto exit_free;
     5869-               }
     5870-               if (acl_clear_perms(acl_permset) != 0) {
     5871-                       archive_set_error(a, errno,
     5872-                           "Failed to clear ACL permissions");
     5873-                       ret = ARCHIVE_FAILED;
     5874-                       goto exit_free;
     5875-               }
     5876-#endif /* !HAVE_SUN_ACL */
     5877-               for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
     5878-                       if (ae_permset & acl_perm_map[i].archive_perm) {
     5879-#if HAVE_SUN_ACL
     5880-                               ace->a_access_mask |=
     5881-                                   acl_perm_map[i].platform_perm;
     5882-#else
     5883-                               if (acl_add_perm(acl_permset,
     5884-                                   acl_perm_map[i].platform_perm) != 0) {
     5885-                                       archive_set_error(a, errno,
     5886-                                           "Failed to add ACL permission");
     5887-                                       ret = ARCHIVE_FAILED;
     5888-                                       goto exit_free;
     5889-                               }
     5890-#endif
     5891-                       }
     5892-               }
     5893-
     5894-#if HAVE_NFS4_ACL
     5895-#if HAVE_SUN_ACL
     5896-               if (acl_type == ACE_T)
     5897-#elif HAVE_DARWIN_ACL
     5898-               if (acl_type == ACL_TYPE_EXTENDED)
     5899-#else  /* FreeBSD */
     5900-               if (acl_type == ACL_TYPE_NFS4)
     5901-#endif
     5902-               {
     5903-#if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
     5904-                       /*
     5905-                        * acl_get_flagset_np() fails with non-NFSv4 ACLs
     5906-                        */
     5907-                       if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
     5908-                               archive_set_error(a, errno,
     5909-                                   "Failed to get flagset from an NFSv4 ACL entry");
     5910-                               ret = ARCHIVE_FAILED;
     5911-                               goto exit_free;
     5912-                       }
     5913-                       if (acl_clear_flags_np(acl_flagset) != 0) {
     5914-                               archive_set_error(a, errno,
     5915-                                   "Failed to clear flags from an NFSv4 ACL flagset");
     5916-                               ret = ARCHIVE_FAILED;
     5917-                               goto exit_free;
     5918-                       }
     5919-#endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
     5920-                       for (i = 0; i < (int)(sizeof(acl_inherit_map) /sizeof(acl_inherit_map[0])); ++i) {
     5921-                               if (ae_permset & acl_inherit_map[i].archive_inherit) {
     5922-#if HAVE_SUN_ACL
     5923-                                       ace->a_flags |=
     5924-                                           acl_inherit_map[i].platform_inherit;
     5925-#else  /* !HAVE_SUN_ACL */
     5926-                                       if (acl_add_flag_np(acl_flagset,
     5927-                                                       acl_inherit_map[i].platform_inherit) != 0) {
     5928-                                               archive_set_error(a, errno,
     5929-                                                   "Failed to add flag to NFSv4 ACL flagset");
     5930-                                               ret = ARCHIVE_FAILED;
     5931-                                               goto exit_free;
     5932-                                       }
     5933-#endif /* HAVE_SUN_ACL */
     5934-                               }
     5935-                       }
     5936-               }
     5937-#endif /* HAVE_NFS4_ACL */
     5938-#if HAVE_SUN_ACL
     5939-       e++;
     5940-#endif
     5941-       }
     5942-
     5943-#if HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL
     5944-       /* Try restoring the ACL through 'fd' if we can. */
     5945-#if HAVE_SUN_ACL || HAVE_ACL_SET_FD_NP
     5946-       if (fd >= 0)
     5947-#else  /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
     5948-       if (fd >= 0 && acl_type == ACL_TYPE_ACCESS)
     5949-#endif
     5950-       {
     5951-#if HAVE_SUN_ACL
     5952-               if (facl_set(fd, acl) == 0)
     5953-#elif HAVE_ACL_SET_FD_NP
     5954-               if (acl_set_fd_np(fd, acl, acl_type) == 0)
     5955-#else  /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
     5956-               if (acl_set_fd(fd, acl) == 0)
     5957-#endif
     5958-                       ret = ARCHIVE_OK;
     5959-               else {
     5960-                       if (errno == EOPNOTSUPP) {
     5961-                               /* Filesystem doesn't support ACLs */
     5962-                               ret = ARCHIVE_OK;
     5963-                       } else {
     5964-                               archive_set_error(a, errno,
     5965-                                   "Failed to set %s acl on fd", tname);
     5966-                       }
     5967-               }
     5968-       } else
     5969-#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */
     5970-#if HAVE_SUN_ACL
     5971-       if (acl_set(name, acl) != 0)
     5972-#elif HAVE_ACL_SET_LINK_NP
     5973-       if (acl_set_link_np(name, acl_type, acl) != 0)
     5974-#else
     5975-       /* TODO: Skip this if 'name' is a symlink. */
     5976-       if (acl_set_file(name, acl_type, acl) != 0)
     5977-#endif
     5978-       {
     5979-               if (errno == EOPNOTSUPP) {
     5980-                       /* Filesystem doesn't support ACLs */
     5981-                       ret = ARCHIVE_OK;
     5982-               } else {
     5983-                       archive_set_error(a, errno, "Failed to set %s acl",
     5984-                           tname);
     5985-                       ret = ARCHIVE_WARN;
     5986-               }
     5987-       }
     5988-exit_free:
     5989-       acl_free(acl);
     5990-       return (ret);
     5991-}
     5992-#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
     5993--- /dev/null
     5994+++ libarchive/archive_write_disk_acl_darwin.c
     5995@@ -0,0 +1,234 @@
     5996+/*-
     5997+ * Copyright (c) 2017 Martin Matuska
     5998+ * All rights reserved.
     5999+ *
     6000+ * Redistribution and use in source and binary forms, with or without
     6001+ * modification, are permitted provided that the following conditions
     6002+ * are met:
     6003+ * 1. Redistributions of source code must retain the above copyright
     6004+ *    notice, this list of conditions and the following disclaimer
     6005+ *    in this position and unchanged.
     6006+ * 2. Redistributions in binary form must reproduce the above copyright
     6007+ *    notice, this list of conditions and the following disclaimer in the
     6008+ *    documentation and/or other materials provided with the distribution.
     6009+ *
     6010+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     6011+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     6012+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     6013+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     6014+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     6015+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     6016+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     6017+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     6018+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     6019+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     6020+ */
     6021+
     6022+#include "archive_platform.h"
     6023+
     6024+#ifdef HAVE_SYS_TYPES_H
     6025+#include <sys/types.h>
     6026+#endif
     6027+#if HAVE_MEMBERSHIP_H
     6028+#include <membership.h>
     6029+#endif
     6030+#ifdef HAVE_ERRNO_H
     6031+#include <errno.h>
     6032+#endif
     6033+#ifdef HAVE_SYS_ACL_H
     6034+#define _ACL_PRIVATE /* For debugging */
     6035+#include <sys/acl.h>
     6036+#endif
     6037+
     6038+#include "archive.h"
     6039+#include "archive_entry.h"
     6040+#include "archive_write_disk_private.h"
     6041+#include "archive_acl_maps.h"
     6042+
     6043+static int
     6044+set_acl(struct archive *a, int fd, const char *name,
     6045+    struct archive_acl *abstract_acl,
     6046+    int ae_requested_type, const char *tname)
     6047+{
     6048+       acl_t            acl;
     6049+       acl_entry_t      acl_entry;
     6050+       acl_permset_t    acl_permset;
     6051+       acl_flagset_t    acl_flagset;
     6052+       int              ret;
     6053+       int              ae_type, ae_permset, ae_tag, ae_id;
     6054+       uuid_t           ae_uuid;
     6055+       uid_t            ae_uid;
     6056+       gid_t            ae_gid;
     6057+       const char      *ae_name;
     6058+       int              entries;
     6059+       int              i;
     6060+
     6061+       ret = ARCHIVE_OK;
     6062+       entries = archive_acl_reset(abstract_acl, ae_requested_type);
     6063+       if (entries == 0)
     6064+               return (ARCHIVE_OK);
     6065+
     6066+       if (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     6067+               errno = ENOENT;
     6068+               archive_set_error(a, errno, "Unsupported ACL type");
     6069+               return (ARCHIVE_FAILED);
     6070+       }
     6071+
     6072+       acl = acl_init(entries);
     6073+       if (acl == (acl_t)NULL) {
     6074+               archive_set_error(a, errno,
     6075+                   "Failed to initialize ACL working storage");
     6076+               return (ARCHIVE_FAILED);
     6077+       }
     6078+
     6079+       while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
     6080+                  &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
     6081+               /*
     6082+                * Mac OS doesn't support NFSv4 ACLs for
     6083+                * owner@, group@ and everyone@.
     6084+                * We skip any of these ACLs found.
     6085+                */
     6086+               if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
     6087+                   ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
     6088+                   ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
     6089+                       continue;
     6090+
     6091+               if (acl_create_entry(&acl, &acl_entry) != 0) {
     6092+                       archive_set_error(a, errno,
     6093+                           "Failed to create a new ACL entry");
     6094+                       ret = ARCHIVE_FAILED;
     6095+                       goto exit_free;
     6096+               }
     6097+
     6098+               switch (ae_type) {
     6099+               case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
     6100+                       acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
     6101+                       break;
     6102+               case ARCHIVE_ENTRY_ACL_TYPE_DENY:
     6103+                       acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
     6104+                       break;
     6105+               default:
     6106+                       /* We don't support any other types on MacOS */
     6107+                       continue;
     6108+               }
     6109+
     6110+               switch (ae_tag) {
     6111+               case ARCHIVE_ENTRY_ACL_USER:
     6112+                       ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
     6113+                       if (mbr_uid_to_uuid(ae_uid, ae_uuid) != 0)
     6114+                               continue;
     6115+                       if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
     6116+                               continue;
     6117+                       break;
     6118+               case ARCHIVE_ENTRY_ACL_GROUP:
     6119+                       ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
     6120+                       if (mbr_gid_to_uuid(ae_gid, ae_uuid) != 0)
     6121+                               continue;
     6122+                       if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
     6123+                               continue;
     6124+                       break;
     6125+               default:
     6126+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
     6127+                           "Unsupported ACL tag");
     6128+                       ret = ARCHIVE_FAILED;
     6129+                       goto exit_free;
     6130+               }
     6131+
     6132+               if (acl_get_permset(acl_entry, &acl_permset) != 0) {
     6133+                       archive_set_error(a, errno,
     6134+                           "Failed to get ACL permission set");
     6135+                       ret = ARCHIVE_FAILED;
     6136+                       goto exit_free;
     6137+               }
     6138+               if (acl_clear_perms(acl_permset) != 0) {
     6139+                       archive_set_error(a, errno,
     6140+                           "Failed to clear ACL permissions");
     6141+                       ret = ARCHIVE_FAILED;
     6142+                       goto exit_free;
     6143+               }
     6144+
     6145+               for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
     6146+                       if (ae_permset & acl_nfs4_perm_map[i].a_perm) {
     6147+                               if (acl_add_perm(acl_permset,
     6148+                                   acl_nfs4_perm_map[i].p_perm) != 0) {
     6149+                                       archive_set_error(a, errno,
     6150+                                           "Failed to add ACL permission");
     6151+                                       ret = ARCHIVE_FAILED;
     6152+                                       goto exit_free;
     6153+                               }
     6154+                       }
     6155+               }
     6156+
     6157+               /*
     6158+                * acl_get_flagset_np() fails with non-NFSv4 ACLs
     6159+                */
     6160+               if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
     6161+                       archive_set_error(a, errno,
     6162+                           "Failed to get flagset from an NFSv4 ACL entry");
     6163+                       ret = ARCHIVE_FAILED;
     6164+                       goto exit_free;
     6165+               }
     6166+               if (acl_clear_flags_np(acl_flagset) != 0) {
     6167+                       archive_set_error(a, errno,
     6168+                           "Failed to clear flags from an NFSv4 ACL flagset");
     6169+                       ret = ARCHIVE_FAILED;
     6170+                       goto exit_free;
     6171+               }
     6172+
     6173+               for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
     6174+                       if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
     6175+                               if (acl_add_flag_np(acl_flagset,
     6176+                                   acl_nfs4_flag_map[i].p_perm) != 0) {
     6177+                                       archive_set_error(a, errno,
     6178+                                           "Failed to add flag to "
     6179+                                           "NFSv4 ACL flagset");
     6180+                                       ret = ARCHIVE_FAILED;
     6181+                                       goto exit_free;
     6182+                               }
     6183+                       }
     6184+               }
     6185+       }
     6186+
     6187+       if (fd >= 0) {
     6188+               if (acl_set_fd_np(fd, acl, ACL_TYPE_EXTENDED) == 0)
     6189+                       ret = ARCHIVE_OK;
     6190+               else {
     6191+                       if (errno == EOPNOTSUPP) {
     6192+                               /* Filesystem doesn't support ACLs */
     6193+                               ret = ARCHIVE_OK;
     6194+                       } else {
     6195+                               archive_set_error(a, errno,
     6196+                                   "Failed to set acl on fd: %s", tname);
     6197+                               ret = ARCHIVE_WARN;
     6198+                       }
     6199+               }
     6200+       } else if (acl_set_link_np(name, ACL_TYPE_EXTENDED, acl) != 0) {
     6201+               if (errno == EOPNOTSUPP) {
     6202+                       /* Filesystem doesn't support ACLs */
     6203+                       ret = ARCHIVE_OK;
     6204+               } else {
     6205+                       archive_set_error(a, errno, "Failed to set acl: %s",
     6206+                           tname);
     6207+                       ret = ARCHIVE_WARN;
     6208+               }
     6209+       }
     6210+exit_free:
     6211+       acl_free(acl);
     6212+       return (ret);
     6213+}
     6214+
     6215+int
     6216+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
     6217+    struct archive_acl *abstract_acl, __LA_MODE_T mode)
     6218+{
     6219+       int             ret = ARCHIVE_OK;
     6220+
     6221+       (void)mode;     /* UNUSED */
     6222+
     6223+       if ((archive_acl_types(abstract_acl) &
     6224+           ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
     6225+               ret = set_acl(a, fd, name, abstract_acl,
     6226+                   ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
     6227+       }
     6228+       return (ret);
     6229+}
     6230--- /dev/null
     6231+++ libarchive/archive_write_disk_acl_freebsd.c
     6232@@ -0,0 +1,321 @@
     6233+/*-
     6234+ * Copyright (c) 2003-2010 Tim Kientzle
     6235+ * All rights reserved.
     6236+ *
     6237+ * Redistribution and use in source and binary forms, with or without
     6238+ * modification, are permitted provided that the following conditions
     6239+ * are met:
     6240+ * 1. Redistributions of source code must retain the above copyright
     6241+ *    notice, this list of conditions and the following disclaimer
     6242+ *    in this position and unchanged.
     6243+ * 2. Redistributions in binary form must reproduce the above copyright
     6244+ *    notice, this list of conditions and the following disclaimer in the
     6245+ *    documentation and/or other materials provided with the distribution.
     6246+ *
     6247+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     6248+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     6249+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     6250+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     6251+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     6252+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     6253+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     6254+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     6255+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     6256+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     6257+ */
     6258+
     6259+#include "archive_platform.h"
     6260+__FBSDID("$FreeBSD$");
     6261+
     6262+#ifdef HAVE_SYS_TYPES_H
     6263+#include <sys/types.h>
     6264+#endif
     6265+#ifdef HAVE_ERRNO_H
     6266+#include <errno.h>
     6267+#endif
     6268+#ifdef HAVE_SYS_ACL_H
     6269+#define _ACL_PRIVATE /* For debugging */
     6270+#include <sys/acl.h>
     6271+#endif
     6272+
     6273+#include "archive.h"
     6274+#include "archive_entry.h"
     6275+#include "archive_write_disk_private.h"
     6276+#include "archive_acl_maps.h"
     6277+
     6278+static int
     6279+set_acl(struct archive *a, int fd, const char *name,
     6280+    struct archive_acl *abstract_acl,
     6281+    int ae_requested_type, const char *tname)
     6282+{
     6283+       int              acl_type = 0;
     6284+       acl_t            acl;
     6285+       acl_entry_t      acl_entry;
     6286+       acl_permset_t    acl_permset;
     6287+#if ARCHIVE_ACL_FREEBSD_NFS4
     6288+       acl_flagset_t    acl_flagset;
     6289+       int              r;
     6290+#endif
     6291+       int              ret;
     6292+       int              ae_type, ae_permset, ae_tag, ae_id;
     6293+       int              perm_map_size;
     6294+       const acl_perm_map_t    *perm_map;
     6295+       uid_t            ae_uid;
     6296+       gid_t            ae_gid;
     6297+       const char      *ae_name;
     6298+       int              entries;
     6299+       int              i;
     6300+
     6301+       ret = ARCHIVE_OK;
     6302+       entries = archive_acl_reset(abstract_acl, ae_requested_type);
     6303+       if (entries == 0)
     6304+               return (ARCHIVE_OK);
     6305+
     6306+
     6307+       switch (ae_requested_type) {
     6308+       case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
     6309+               acl_type = ACL_TYPE_ACCESS;
     6310+               break;
     6311+       case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
     6312+               acl_type = ACL_TYPE_DEFAULT;
     6313+               break;
     6314+#if ARCHIVE_ACL_FREEBSD_NFS4
     6315+       case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
     6316+               acl_type = ACL_TYPE_NFS4;
     6317+               break;
     6318+#endif
     6319+       default:
     6320+               errno = ENOENT;
     6321+               archive_set_error(a, errno, "Unsupported ACL type");
     6322+               return (ARCHIVE_FAILED);
     6323+       }
     6324+
     6325+       acl = acl_init(entries);
     6326+       if (acl == (acl_t)NULL) {
     6327+               archive_set_error(a, errno,
     6328+                   "Failed to initialize ACL working storage");
     6329+               return (ARCHIVE_FAILED);
     6330+       }
     6331+
     6332+       while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
     6333+                  &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
     6334+               if (acl_create_entry(&acl, &acl_entry) != 0) {
     6335+                       archive_set_error(a, errno,
     6336+                           "Failed to create a new ACL entry");
     6337+                       ret = ARCHIVE_FAILED;
     6338+                       goto exit_free;
     6339+               }
     6340+               switch (ae_tag) {
     6341+               case ARCHIVE_ENTRY_ACL_USER:
     6342+                       ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
     6343+                       acl_set_tag_type(acl_entry, ACL_USER);
     6344+                       acl_set_qualifier(acl_entry, &ae_uid);
     6345+                       break;
     6346+               case ARCHIVE_ENTRY_ACL_GROUP:
     6347+                       ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
     6348+                       acl_set_tag_type(acl_entry, ACL_GROUP);
     6349+                       acl_set_qualifier(acl_entry, &ae_gid);
     6350+                       break;
     6351+               case ARCHIVE_ENTRY_ACL_USER_OBJ:
     6352+                       acl_set_tag_type(acl_entry, ACL_USER_OBJ);
     6353+                       break;
     6354+               case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
     6355+                       acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
     6356+                       break;
     6357+               case ARCHIVE_ENTRY_ACL_MASK:
     6358+                       acl_set_tag_type(acl_entry, ACL_MASK);
     6359+                       break;
     6360+               case ARCHIVE_ENTRY_ACL_OTHER:
     6361+                       acl_set_tag_type(acl_entry, ACL_OTHER);
     6362+                       break;
     6363+#if ARCHIVE_ACL_FREEBSD_NFS4
     6364+               case ARCHIVE_ENTRY_ACL_EVERYONE:
     6365+                       acl_set_tag_type(acl_entry, ACL_EVERYONE);
     6366+                       break;
     6367+#endif
     6368+               default:
     6369+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
     6370+                           "Unsupported ACL tag");
     6371+                       ret = ARCHIVE_FAILED;
     6372+                       goto exit_free;
     6373+               }
     6374+
     6375+#if ARCHIVE_ACL_FREEBSD_NFS4
     6376+               r = 0;
     6377+               switch (ae_type) {
     6378+               case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
     6379+                       r = acl_set_entry_type_np(acl_entry,
     6380+                           ACL_ENTRY_TYPE_ALLOW);
     6381+                       break;
     6382+               case ARCHIVE_ENTRY_ACL_TYPE_DENY:
     6383+                       r = acl_set_entry_type_np(acl_entry,
     6384+                           ACL_ENTRY_TYPE_DENY);
     6385+                       break;
     6386+               case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
     6387+                       r = acl_set_entry_type_np(acl_entry,
     6388+                           ACL_ENTRY_TYPE_AUDIT);
     6389+                       break;
     6390+               case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
     6391+                       r = acl_set_entry_type_np(acl_entry,
     6392+                           ACL_ENTRY_TYPE_ALARM);
     6393+                       break;
     6394+               case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
     6395+               case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
     6396+                       // These don't translate directly into the system ACL.
     6397+                       break;
     6398+               default:
     6399+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
     6400+                           "Unsupported ACL entry type");
     6401+                       ret = ARCHIVE_FAILED;
     6402+                       goto exit_free;
     6403+               }
     6404+
     6405+               if (r != 0) {
     6406+                       archive_set_error(a, errno,
     6407+                           "Failed to set ACL entry type");
     6408+                       ret = ARCHIVE_FAILED;
     6409+                       goto exit_free;
     6410+               }
     6411+#endif
     6412+
     6413+               if (acl_get_permset(acl_entry, &acl_permset) != 0) {
     6414+                       archive_set_error(a, errno,
     6415+                           "Failed to get ACL permission set");
     6416+                       ret = ARCHIVE_FAILED;
     6417+                       goto exit_free;
     6418+               }
     6419+               if (acl_clear_perms(acl_permset) != 0) {
     6420+                       archive_set_error(a, errno,
     6421+                           "Failed to clear ACL permissions");
     6422+                       ret = ARCHIVE_FAILED;
     6423+                       goto exit_free;
     6424+               }
     6425+#if ARCHIVE_ACL_FREEBSD_NFS4
     6426+               if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     6427+                       perm_map_size = acl_nfs4_perm_map_size;
     6428+                       perm_map = acl_nfs4_perm_map;
     6429+               } else {
     6430+#endif
     6431+                       perm_map_size = acl_posix_perm_map_size;
     6432+                       perm_map = acl_posix_perm_map;
     6433+#if ARCHIVE_ACL_FREEBSD_NFS4
     6434+               }
     6435+#endif
     6436+
     6437+               for (i = 0; i < perm_map_size; ++i) {
     6438+                       if (ae_permset & perm_map[i].a_perm) {
     6439+                               if (acl_add_perm(acl_permset,
     6440+                                   perm_map[i].p_perm) != 0) {
     6441+                                       archive_set_error(a, errno,
     6442+                                           "Failed to add ACL permission");
     6443+                                       ret = ARCHIVE_FAILED;
     6444+                                       goto exit_free;
     6445+                               }
     6446+                       }
     6447+               }
     6448+
     6449+#if ARCHIVE_ACL_FREEBSD_NFS4
     6450+               if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     6451+                       /*
     6452+                        * acl_get_flagset_np() fails with non-NFSv4 ACLs
     6453+                        */
     6454+                       if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
     6455+                               archive_set_error(a, errno,
     6456+                                   "Failed to get flagset from an NFSv4 "
     6457+                                   "ACL entry");
     6458+                               ret = ARCHIVE_FAILED;
     6459+                               goto exit_free;
     6460+                       }
     6461+                       if (acl_clear_flags_np(acl_flagset) != 0) {
     6462+                               archive_set_error(a, errno,
     6463+                                   "Failed to clear flags from an NFSv4 "
     6464+                                   "ACL flagset");
     6465+                               ret = ARCHIVE_FAILED;
     6466+                               goto exit_free;
     6467+                       }
     6468+                       for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
     6469+                               if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
     6470+                                       if (acl_add_flag_np(acl_flagset,
     6471+                                           acl_nfs4_flag_map[i].p_perm) != 0) {
     6472+                                               archive_set_error(a, errno,
     6473+                                                   "Failed to add flag to "
     6474+                                                   "NFSv4 ACL flagset");
     6475+                                               ret = ARCHIVE_FAILED;
     6476+                                               goto exit_free;
     6477+                                       }
     6478+                               }
     6479+                       }
     6480+               }
     6481+#endif
     6482+       }
     6483+
     6484+       /* Try restoring the ACL through 'fd' if we can. */
     6485+       if (fd >= 0) {
     6486+               if (acl_set_fd_np(fd, acl, acl_type) == 0)
     6487+                       ret = ARCHIVE_OK;
     6488+               else {
     6489+                       if (errno == EOPNOTSUPP) {
     6490+                               /* Filesystem doesn't support ACLs */
     6491+                               ret = ARCHIVE_OK;
     6492+                       } else {
     6493+                               archive_set_error(a, errno,
     6494+                                   "Failed to set acl on fd: %s", tname);
     6495+                               ret = ARCHIVE_WARN;
     6496+                       }
     6497+               }
     6498+       }
     6499+#if HAVE_ACL_SET_LINK_NP
     6500+       else if (acl_set_link_np(name, acl_type, acl) != 0)
     6501+#else
     6502+       /* FreeBSD older than 8.0 */
     6503+       else if (acl_set_file(name, acl_type, acl) != 0)
     6504+#endif
     6505+       {
     6506+               if (errno == EOPNOTSUPP) {
     6507+                       /* Filesystem doesn't support ACLs */
     6508+                       ret = ARCHIVE_OK;
     6509+               } else {
     6510+                       archive_set_error(a, errno, "Failed to set acl: %s",
     6511+                           tname);
     6512+                       ret = ARCHIVE_WARN;
     6513+               }
     6514+       }
     6515+exit_free:
     6516+       acl_free(acl);
     6517+       return (ret);
     6518+}
     6519+
     6520+int
     6521+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
     6522+    struct archive_acl *abstract_acl, __LA_MODE_T mode)
     6523+{
     6524+       int             ret = ARCHIVE_OK;
     6525+
     6526+       (void)mode;     /* UNUSED */
     6527+
     6528+       if ((archive_acl_types(abstract_acl)
     6529+           & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
     6530+               if ((archive_acl_types(abstract_acl)
     6531+                   & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
     6532+                       ret = set_acl(a, fd, name, abstract_acl,
     6533+                           ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
     6534+                       if (ret != ARCHIVE_OK)
     6535+                               return (ret);
     6536+               }
     6537+               if ((archive_acl_types(abstract_acl)
     6538+                   & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
     6539+                       ret = set_acl(a, fd, name, abstract_acl,
     6540+                           ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
     6541+
     6542+               /* Simultaneous POSIX.1e and NFSv4 is not supported */
     6543+               return (ret);
     6544+       }
     6545+#if ARCHIVE_ACL_FREEBSD_NFS4
     6546+       else if ((archive_acl_types(abstract_acl) &
     6547+           ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
     6548+               ret = set_acl(a, fd, name, abstract_acl,
     6549+                   ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
     6550+       }
     6551+#endif
     6552+       return (ret);
     6553+}
     6554--- /dev/null
     6555+++ libarchive/archive_write_disk_acl_linux.c
     6556@@ -0,0 +1,388 @@
     6557+/*-
     6558+ * Copyright (c) 2003-2010 Tim Kientzle
     6559+ * All rights reserved.
     6560+ *
     6561+ * Redistribution and use in source and binary forms, with or without
     6562+ * modification, are permitted provided that the following conditions
     6563+ * are met:
     6564+ * 1. Redistributions of source code must retain the above copyright
     6565+ *    notice, this list of conditions and the following disclaimer
     6566+ *    in this position and unchanged.
     6567+ * 2. Redistributions in binary form must reproduce the above copyright
     6568+ *    notice, this list of conditions and the following disclaimer in the
     6569+ *    documentation and/or other materials provided with the distribution.
     6570+ *
     6571+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     6572+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     6573+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     6574+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     6575+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     6576+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     6577+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     6578+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     6579+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     6580+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     6581+ */
     6582+
     6583+#include "archive_platform.h"
     6584+
     6585+#ifdef HAVE_ERRNO_H
     6586+#include <errno.h>
     6587+#endif
     6588+#ifdef HAVE_FCNTL_H
     6589+#include <fcntl.h>
     6590+#endif
     6591+#if HAVE_ACL_LIBACL_H
     6592+#include <acl/libacl.h>
     6593+#endif
     6594+#ifdef HAVE_SYS_ACL_H
     6595+#include <sys/acl.h>
     6596+#endif
     6597+#if HAVE_SYS_RICHACL_H
     6598+#include <sys/richacl.h>
     6599+#endif
     6600+
     6601+#include "archive.h"
     6602+#include "archive_entry.h"
     6603+#include "archive_write_disk_private.h"
     6604+#include "archive_acl_maps.h"
     6605+
     6606+#if ARCHIVE_ACL_LIBRICHACL
     6607+static int
     6608+_richacl_mode_to_mask(short mode)
     6609+{
     6610+       int mask = 0;
     6611+
     6612+       if (mode & S_IROTH)
     6613+               mask |= RICHACE_POSIX_MODE_READ;
     6614+       if (mode & S_IWOTH)
     6615+               mask |= RICHACE_POSIX_MODE_WRITE;
     6616+       if (mode & S_IXOTH)
     6617+               mask |= RICHACE_POSIX_MODE_EXEC;
     6618+
     6619+       return (mask);
     6620+}
     6621+
     6622+static void
     6623+_richacl_mode_to_masks(struct richacl *richacl, __LA_MODE_T mode)
     6624+{
     6625+       richacl->a_owner_mask = _richacl_mode_to_mask((mode & 0700) >> 6);
     6626+       richacl->a_group_mask = _richacl_mode_to_mask((mode & 0070) >> 3);
     6627+       richacl->a_other_mask = _richacl_mode_to_mask(mode & 0007);
     6628+}
     6629+#endif /* ARCHIVE_ACL_LIBRICHACL */
     6630+
     6631+#if ARCHIVE_ACL_LIBRICHACL
     6632+static int
     6633+set_richacl(struct archive *a, int fd, const char *name,
     6634+    struct archive_acl *abstract_acl, __LA_MODE_T mode,
     6635+    int ae_requested_type, const char *tname)
     6636+{
     6637+       int              ae_type, ae_permset, ae_tag, ae_id;
     6638+       uid_t            ae_uid;
     6639+       gid_t            ae_gid;
     6640+       const char      *ae_name;
     6641+       int              entries;
     6642+       int              i;
     6643+       int              ret;
     6644+       int              e = 0;
     6645+       struct richacl  *richacl = NULL;
     6646+       struct richace  *richace;
     6647+
     6648+       ret = ARCHIVE_OK;
     6649+       entries = archive_acl_reset(abstract_acl, ae_requested_type);
     6650+       if (entries == 0)
     6651+               return (ARCHIVE_OK);
     6652+
     6653+       if (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     6654+               errno = ENOENT;
     6655+               archive_set_error(a, errno, "Unsupported ACL type");
     6656+               return (ARCHIVE_FAILED);
     6657+       }
     6658+
     6659+       richacl = richacl_alloc(entries);
     6660+       if (richacl == NULL) {
     6661+               archive_set_error(a, errno,
     6662+                       "Failed to initialize RichACL working storage");
     6663+               return (ARCHIVE_FAILED);
     6664+       }
     6665+
     6666+       e = 0;
     6667+
     6668+       while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
     6669+                  &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
     6670+               richace = &(richacl->a_entries[e]);
     6671+
     6672+               richace->e_flags = 0;
     6673+               richace->e_mask = 0;
     6674+
     6675+               switch (ae_tag) {
     6676+               case ARCHIVE_ENTRY_ACL_USER:
     6677+                       ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
     6678+                       richace->e_id = ae_uid;
     6679+                       break;
     6680+               case ARCHIVE_ENTRY_ACL_GROUP:
     6681+                       ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
     6682+                       richace->e_id = ae_gid;
     6683+                       richace->e_flags |= RICHACE_IDENTIFIER_GROUP;
     6684+                       break;
     6685+               case ARCHIVE_ENTRY_ACL_USER_OBJ:
     6686+                       richace->e_flags |= RICHACE_SPECIAL_WHO;
     6687+                       richace->e_id = RICHACE_OWNER_SPECIAL_ID;
     6688+                       break;
     6689+               case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
     6690+                       richace->e_flags |= RICHACE_SPECIAL_WHO;
     6691+                       richace->e_id = RICHACE_GROUP_SPECIAL_ID;
     6692+                       break;
     6693+               case ARCHIVE_ENTRY_ACL_EVERYONE:
     6694+                       richace->e_flags |= RICHACE_SPECIAL_WHO;
     6695+                       richace->e_id = RICHACE_EVERYONE_SPECIAL_ID;
     6696+                       break;
     6697+               default:
     6698+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
     6699+                           "Unsupported ACL tag");
     6700+                       ret = ARCHIVE_FAILED;
     6701+                       goto exit_free;
     6702+               }
     6703+
     6704+               switch (ae_type) {
     6705+                       case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
     6706+                               richace->e_type =
     6707+                                   RICHACE_ACCESS_ALLOWED_ACE_TYPE;
     6708+                               break;
     6709+                       case ARCHIVE_ENTRY_ACL_TYPE_DENY:
     6710+                               richace->e_type =
     6711+                                   RICHACE_ACCESS_DENIED_ACE_TYPE;
     6712+                               break;
     6713+                       case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
     6714+                       case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
     6715+                               break;
     6716+               default:
     6717+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
     6718+                           "Unsupported ACL entry type");
     6719+                       ret = ARCHIVE_FAILED;
     6720+                       goto exit_free;
     6721+               }
     6722+
     6723+               for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
     6724+                       if (ae_permset & acl_nfs4_perm_map[i].a_perm)
     6725+                               richace->e_mask |= acl_nfs4_perm_map[i].p_perm;
     6726+               }
     6727+
     6728+               for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
     6729+                       if (ae_permset &
     6730+                           acl_nfs4_flag_map[i].a_perm)
     6731+                               richace->e_flags |= acl_nfs4_flag_map[i].p_perm;
     6732+               }
     6733+       e++;
     6734+       }
     6735+
     6736+       /* Fill RichACL masks */
     6737+       _richacl_mode_to_masks(richacl, mode);
     6738+
     6739+       if (fd >= 0) {
     6740+               if (richacl_set_fd(fd, richacl) == 0)
     6741+                       ret = ARCHIVE_OK;
     6742+               else {
     6743+                       if (errno == EOPNOTSUPP) {
     6744+                               /* Filesystem doesn't support ACLs */
     6745+                               ret = ARCHIVE_OK;
     6746+                       } else {
     6747+                               archive_set_error(a, errno,
     6748+                                   "Failed to set richacl on fd: %s", tname);
     6749+                               ret = ARCHIVE_WARN;
     6750+                       }
     6751+               }
     6752+       } else if (richacl_set_file(name, richacl) != 0) {
     6753+               if (errno == EOPNOTSUPP) {
     6754+                       /* Filesystem doesn't support ACLs */
     6755+                       ret = ARCHIVE_OK;
     6756+               } else {
     6757+                       archive_set_error(a, errno, "Failed to set richacl: %s",
     6758+                           tname);
     6759+                       ret = ARCHIVE_WARN;
     6760+               }
     6761+       }
     6762+exit_free:
     6763+       richacl_free(richacl);
     6764+       return (ret);
     6765+}
     6766+#endif /* ARCHIVE_ACL_RICHACL */
     6767+
     6768+#if ARCHIVE_ACL_LIBACL
     6769+static int
     6770+set_acl(struct archive *a, int fd, const char *name,
     6771+    struct archive_acl *abstract_acl,
     6772+    int ae_requested_type, const char *tname)
     6773+{
     6774+       int              acl_type = 0;
     6775+       int              ae_type, ae_permset, ae_tag, ae_id;
     6776+       uid_t            ae_uid;
     6777+       gid_t            ae_gid;
     6778+       const char      *ae_name;
     6779+       int              entries;
     6780+       int              i;
     6781+       int              ret;
     6782+       acl_t            acl = NULL;
     6783+       acl_entry_t      acl_entry;
     6784+       acl_permset_t    acl_permset;
     6785+
     6786+       ret = ARCHIVE_OK;
     6787+       entries = archive_acl_reset(abstract_acl, ae_requested_type);
     6788+       if (entries == 0)
     6789+               return (ARCHIVE_OK);
     6790+
     6791+       switch (ae_requested_type) {
     6792+       case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
     6793+               acl_type = ACL_TYPE_ACCESS;
     6794+               break;
     6795+       case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
     6796+               acl_type = ACL_TYPE_DEFAULT;
     6797+               break;
     6798+       default:
     6799+               errno = ENOENT;
     6800+               archive_set_error(a, errno, "Unsupported ACL type");
     6801+               return (ARCHIVE_FAILED);
     6802+       }
     6803+
     6804+       acl = acl_init(entries);
     6805+       if (acl == (acl_t)NULL) {
     6806+               archive_set_error(a, errno,
     6807+                   "Failed to initialize ACL working storage");
     6808+               return (ARCHIVE_FAILED);
     6809+       }
     6810+
     6811+       while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
     6812+                  &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
     6813+
     6814+               if (acl_create_entry(&acl, &acl_entry) != 0) {
     6815+                       archive_set_error(a, errno,
     6816+                           "Failed to create a new ACL entry");
     6817+                       ret = ARCHIVE_FAILED;
     6818+                       goto exit_free;
     6819+               }
     6820+
     6821+               switch (ae_tag) {
     6822+               case ARCHIVE_ENTRY_ACL_USER:
     6823+                       ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
     6824+                       acl_set_tag_type(acl_entry, ACL_USER);
     6825+                       acl_set_qualifier(acl_entry, &ae_uid);
     6826+                       break;
     6827+               case ARCHIVE_ENTRY_ACL_GROUP:
     6828+                       ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
     6829+                       acl_set_tag_type(acl_entry, ACL_GROUP);
     6830+                       acl_set_qualifier(acl_entry, &ae_gid);
     6831+                       break;
     6832+               case ARCHIVE_ENTRY_ACL_USER_OBJ:
     6833+                       acl_set_tag_type(acl_entry, ACL_USER_OBJ);
     6834+                       break;
     6835+               case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
     6836+                       acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
     6837+                       break;
     6838+               case ARCHIVE_ENTRY_ACL_MASK:
     6839+                       acl_set_tag_type(acl_entry, ACL_MASK);
     6840+                       break;
     6841+               case ARCHIVE_ENTRY_ACL_OTHER:
     6842+                       acl_set_tag_type(acl_entry, ACL_OTHER);
     6843+                       break;
     6844+               default:
     6845+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
     6846+                           "Unsupported ACL tag");
     6847+                       ret = ARCHIVE_FAILED;
     6848+                       goto exit_free;
     6849+               }
     6850+
     6851+               if (acl_get_permset(acl_entry, &acl_permset) != 0) {
     6852+                       archive_set_error(a, errno,
     6853+                           "Failed to get ACL permission set");
     6854+                       ret = ARCHIVE_FAILED;
     6855+                       goto exit_free;
     6856+               }
     6857+               if (acl_clear_perms(acl_permset) != 0) {
     6858+                       archive_set_error(a, errno,
     6859+                           "Failed to clear ACL permissions");
     6860+                       ret = ARCHIVE_FAILED;
     6861+                       goto exit_free;
     6862+               }
     6863+
     6864+               for (i = 0; i < acl_posix_perm_map_size; ++i) {
     6865+                       if (ae_permset & acl_posix_perm_map[i].a_perm) {
     6866+                               if (acl_add_perm(acl_permset,
     6867+                                   acl_posix_perm_map[i].p_perm) != 0) {
     6868+                                       archive_set_error(a, errno,
     6869+                                           "Failed to add ACL permission");
     6870+                                       ret = ARCHIVE_FAILED;
     6871+                                       goto exit_free;
     6872+                               }
     6873+                       }
     6874+               }
     6875+
     6876+       }
     6877+
     6878+       if (fd >= 0 && ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
     6879+               if (acl_set_fd(fd, acl) == 0)
     6880+                       ret = ARCHIVE_OK;
     6881+               else {
     6882+                       if (errno == EOPNOTSUPP) {
     6883+                               /* Filesystem doesn't support ACLs */
     6884+                               ret = ARCHIVE_OK;
     6885+                       } else {
     6886+                               archive_set_error(a, errno,
     6887+                                   "Failed to set acl on fd: %s", tname);
     6888+                               ret = ARCHIVE_WARN;
     6889+                       }
     6890+               }
     6891+       } else if (acl_set_file(name, acl_type, acl) != 0) {
     6892+               if (errno == EOPNOTSUPP) {
     6893+                       /* Filesystem doesn't support ACLs */
     6894+                       ret = ARCHIVE_OK;
     6895+               } else {
     6896+                       archive_set_error(a, errno, "Failed to set acl: %s",
     6897+                           tname);
     6898+                       ret = ARCHIVE_WARN;
     6899+               }
     6900+       }
     6901+exit_free:
     6902+       acl_free(acl);
     6903+       return (ret);
     6904+}
     6905+#endif /* ARCHIVE_ACL_LIBACL */
     6906+
     6907+int
     6908+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
     6909+    struct archive_acl *abstract_acl, __LA_MODE_T mode)
     6910+{
     6911+       int             ret = ARCHIVE_OK;
     6912+
     6913+#if !ARCHIVE_ACL_LIBRICHACL
     6914+       (void)mode;     /* UNUSED */
     6915+#endif
     6916+
     6917+#if ARCHIVE_ACL_LIBRICHACL
     6918+       if ((archive_acl_types(abstract_acl)
     6919+           & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
     6920+               ret = set_richacl(a, fd, name, abstract_acl, mode,
     6921+                   ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
     6922+       }
     6923+#if ARCHIVE_ACL_LIBACL
     6924+       else
     6925+#endif
     6926+#endif /* ARCHIVE_ACL_LIBRICHACL */
     6927+#if ARCHIVE_ACL_LIBACL
     6928+       if ((archive_acl_types(abstract_acl)
     6929+           & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
     6930+               if ((archive_acl_types(abstract_acl)
     6931+                   & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
     6932+                       ret = set_acl(a, fd, name, abstract_acl,
     6933+                           ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
     6934+                       if (ret != ARCHIVE_OK)
     6935+                               return (ret);
     6936+               }
     6937+               if ((archive_acl_types(abstract_acl)
     6938+                   & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
     6939+                       ret = set_acl(a, fd, name, abstract_acl,
     6940+                           ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
     6941+       }
     6942+#endif /* ARCHIVE_ACL_LIBACL */
     6943+       return (ret);
     6944+}
     6945--- /dev/null
     6946+++ libarchive/archive_write_disk_acl_sunos.c
     6947@@ -0,0 +1,329 @@
     6948+/*-
     6949+ * Copyright (c) 2017 Martin Matuska
     6950+ * All rights reserved.
     6951+ *
     6952+ * Redistribution and use in source and binary forms, with or without
     6953+ * modification, are permitted provided that the following conditions
     6954+ * are met:
     6955+ * 1. Redistributions of source code must retain the above copyright
     6956+ *    notice, this list of conditions and the following disclaimer
     6957+ *    in this position and unchanged.
     6958+ * 2. Redistributions in binary form must reproduce the above copyright
     6959+ *    notice, this list of conditions and the following disclaimer in the
     6960+ *    documentation and/or other materials provided with the distribution.
     6961+ *
     6962+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     6963+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     6964+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     6965+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     6966+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     6967+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     6968+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     6969+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     6970+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     6971+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     6972+ */
     6973+
     6974+#include "archive_platform.h"
     6975+
     6976+#ifdef HAVE_SYS_TYPES_H
     6977+#include <sys/types.h>
     6978+#endif
     6979+#ifdef HAVE_ERRNO_H
     6980+#include <errno.h>
     6981+#endif
     6982+#ifdef HAVE_SYS_ACL_H
     6983+#define _ACL_PRIVATE /* For debugging */
     6984+#include <sys/acl.h>
     6985+#endif
     6986+
     6987+#include "archive.h"
     6988+#include "archive_entry.h"
     6989+#include "archive_write_disk_private.h"
     6990+#include "archive_acl_maps.h"
     6991+
     6992+static int
     6993+set_acl(struct archive *a, int fd, const char *name,
     6994+    struct archive_acl *abstract_acl,
     6995+    int ae_requested_type, const char *tname)
     6996+{
     6997+       aclent_t         *aclent;
     6998+#if ARCHIVE_ACL_SUNOS_NFS4
     6999+       ace_t            *ace;
     7000+#endif
     7001+       int              cmd, e, r;
     7002+       void             *aclp;
     7003+       int              ret;
     7004+       int              ae_type, ae_permset, ae_tag, ae_id;
     7005+       int              perm_map_size;
     7006+       const acl_perm_map_t    *perm_map;
     7007+       uid_t            ae_uid;
     7008+       gid_t            ae_gid;
     7009+       const char      *ae_name;
     7010+       int              entries;
     7011+       int              i;
     7012+
     7013+       ret = ARCHIVE_OK;
     7014+       entries = archive_acl_reset(abstract_acl, ae_requested_type);
     7015+       if (entries == 0)
     7016+               return (ARCHIVE_OK);
     7017+
     7018+
     7019+       switch (ae_requested_type) {
     7020+       case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
     7021+               cmd = SETACL;
     7022+               aclp = malloc(entries * sizeof(aclent_t));
     7023+               break;
     7024+#if ARCHIVE_ACL_SUNOS_NFS4
     7025+       case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
     7026+               cmd = ACE_SETACL;
     7027+               aclp = malloc(entries * sizeof(ace_t));
     7028+
     7029+               break;
     7030+#endif
     7031+       default:
     7032+               errno = ENOENT;
     7033+               archive_set_error(a, errno, "Unsupported ACL type");
     7034+               return (ARCHIVE_FAILED);
     7035+       }
     7036+
     7037+       if (aclp == NULL) {
     7038+               archive_set_error(a, errno,
     7039+                   "Can't allocate memory for acl buffer");
     7040+               return (ARCHIVE_FAILED);
     7041+       }
     7042+
     7043+       e = 0;
     7044+
     7045+       while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
     7046+                  &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
     7047+               aclent = NULL;
     7048+#if ARCHIVE_ACL_SUNOS_NFS4
     7049+               ace = NULL;
     7050+#endif
     7051+               if (cmd == SETACL) {
     7052+                       aclent = &((aclent_t *)aclp)[e];
     7053+                       aclent->a_id = -1;
     7054+                       aclent->a_type = 0;
     7055+                       aclent->a_perm = 0;
     7056+               }
     7057+#if ARCHIVE_ACL_SUNOS_NFS4
     7058+               else {  /* cmd == ACE_SETACL */
     7059+                       ace = &((ace_t *)aclp)[e];
     7060+                       ace->a_who = -1;
     7061+                       ace->a_access_mask = 0;
     7062+                       ace->a_flags = 0;
     7063+               }
     7064+#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
     7065+
     7066+               switch (ae_tag) {
     7067+               case ARCHIVE_ENTRY_ACL_USER:
     7068+                       ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
     7069+                       if (aclent != NULL) {
     7070+                               aclent->a_id = ae_uid;
     7071+                               aclent->a_type |= USER;
     7072+                       }
     7073+#if ARCHIVE_ACL_SUNOS_NFS4
     7074+                       else {
     7075+                               ace->a_who = ae_uid;
     7076+                       }
     7077+#endif
     7078+                       break;
     7079+               case ARCHIVE_ENTRY_ACL_GROUP:
     7080+                       ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
     7081+                       if (aclent != NULL) {
     7082+                               aclent->a_id = ae_gid;
     7083+                               aclent->a_type |= GROUP;
     7084+                       }
     7085+#if ARCHIVE_ACL_SUNOS_NFS4
     7086+                       else {
     7087+                               ace->a_who = ae_gid;
     7088+                               ace->a_flags |= ACE_IDENTIFIER_GROUP;
     7089+                       }
     7090+#endif
     7091+                       break;
     7092+               case ARCHIVE_ENTRY_ACL_USER_OBJ:
     7093+                       if (aclent != NULL)
     7094+                               aclent->a_type |= USER_OBJ;
     7095+#if ARCHIVE_ACL_SUNOS_NFS4
     7096+                       else {
     7097+                               ace->a_flags |= ACE_OWNER;
     7098+                       }
     7099+#endif
     7100+                       break;
     7101+               case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
     7102+                       if (aclent != NULL)
     7103+                               aclent->a_type |= GROUP_OBJ;
     7104+#if ARCHIVE_ACL_SUNOS_NFS4
     7105+                       else {
     7106+                               ace->a_flags |= ACE_GROUP;
     7107+                               ace->a_flags |= ACE_IDENTIFIER_GROUP;
     7108+                       }
     7109+#endif
     7110+                       break;
     7111+               case ARCHIVE_ENTRY_ACL_MASK:
     7112+                       if (aclent != NULL)
     7113+                               aclent->a_type |= CLASS_OBJ;
     7114+                       break;
     7115+               case ARCHIVE_ENTRY_ACL_OTHER:
     7116+                       if (aclent != NULL)
     7117+                               aclent->a_type |= OTHER_OBJ;
     7118+                       break;
     7119+#if ARCHIVE_ACL_SUNOS_NFS4
     7120+               case ARCHIVE_ENTRY_ACL_EVERYONE:
     7121+                       if (ace != NULL)
     7122+                               ace->a_flags |= ACE_EVERYONE;
     7123+                       break;
     7124+#endif
     7125+               default:
     7126+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
     7127+                           "Unsupported ACL tag");
     7128+                       ret = ARCHIVE_FAILED;
     7129+                       goto exit_free;
     7130+               }
     7131+
     7132+               r = 0;
     7133+               switch (ae_type) {
     7134+#if ARCHIVE_ACL_SUNOS_NFS4
     7135+               case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
     7136+                       if (ace != NULL)
     7137+                               ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
     7138+                       else
     7139+                               r = -1;
     7140+                       break;
     7141+               case ARCHIVE_ENTRY_ACL_TYPE_DENY:
     7142+                       if (ace != NULL)
     7143+                               ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
     7144+                       else
     7145+                               r = -1;
     7146+                       break;
     7147+               case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
     7148+                       if (ace != NULL)
     7149+                               ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
     7150+                       else
     7151+                               r = -1;
     7152+                       break;
     7153+               case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
     7154+                       if (ace != NULL)
     7155+                               ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
     7156+                       else
     7157+                               r = -1;
     7158+                       break;
     7159+#endif
     7160+               case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
     7161+                       if (aclent == NULL)
     7162+                               r = -1;
     7163+                       break;
     7164+               case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
     7165+                       if (aclent != NULL)
     7166+                               aclent->a_type |= ACL_DEFAULT;
     7167+                       else
     7168+                               r = -1;
     7169+                       break;
     7170+               default:
     7171+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
     7172+                           "Unsupported ACL entry type");
     7173+                       ret = ARCHIVE_FAILED;
     7174+                       goto exit_free;
     7175+               }
     7176+
     7177+               if (r != 0) {
     7178+                       errno = EINVAL;
     7179+                       archive_set_error(a, errno,
     7180+                           "Failed to set ACL entry type");
     7181+                       ret = ARCHIVE_FAILED;
     7182+                       goto exit_free;
     7183+               }
     7184+
     7185+#if ARCHIVE_ACL_SUNOS_NFS4
     7186+               if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     7187+                       perm_map_size = acl_nfs4_perm_map_size;
     7188+                       perm_map = acl_nfs4_perm_map;
     7189+               } else {
     7190+#endif
     7191+                       perm_map_size = acl_posix_perm_map_size;
     7192+                       perm_map = acl_posix_perm_map;
     7193+#if ARCHIVE_ACL_SUNOS_NFS4
     7194+               }
     7195+#endif
     7196+               for (i = 0; i < perm_map_size; ++i) {
     7197+                       if (ae_permset & perm_map[i].a_perm) {
     7198+#if ARCHIVE_ACL_SUNOS_NFS4
     7199+                               if (ae_requested_type ==
     7200+                                   ARCHIVE_ENTRY_ACL_TYPE_NFS4)
     7201+                                       ace->a_access_mask |=
     7202+                                           perm_map[i].p_perm;
     7203+                               else
     7204+#endif
     7205+                                       aclent->a_perm |= perm_map[i].p_perm;
     7206+                       }
     7207+               }
     7208+
     7209+#if ARCHIVE_ACL_SUNOS_NFS4
     7210+               if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
     7211+                       for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
     7212+                               if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
     7213+                                       ace->a_flags |=
     7214+                                           acl_nfs4_flag_map[i].p_perm;
     7215+                               }
     7216+                       }
     7217+               }
     7218+#endif
     7219+       e++;
     7220+       }
     7221+
     7222+       /* Try restoring the ACL through 'fd' if we can. */
     7223+       if (fd >= 0) {
     7224+               if (facl(fd, cmd, entries, aclp) == 0)
     7225+                       ret = ARCHIVE_OK;
     7226+               else {
     7227+                       if (errno == EOPNOTSUPP) {
     7228+                               /* Filesystem doesn't support ACLs */
     7229+                               ret = ARCHIVE_OK;
     7230+                       } else {
     7231+                               archive_set_error(a, errno,
     7232+                                   "Failed to set acl on fd: %s", tname);
     7233+                               ret = ARCHIVE_WARN;
     7234+                       }
     7235+               }
     7236+       } else if (acl(name, cmd, entries, aclp) != 0) {
     7237+               if (errno == EOPNOTSUPP) {
     7238+                       /* Filesystem doesn't support ACLs */
     7239+                       ret = ARCHIVE_OK;
     7240+               } else {
     7241+                       archive_set_error(a, errno, "Failed to set acl: %s",
     7242+                           tname);
     7243+                       ret = ARCHIVE_WARN;
     7244+               }
     7245+       }
     7246+exit_free:
     7247+       free(aclp);
     7248+       return (ret);
     7249+}
     7250+
     7251+int
     7252+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
     7253+    struct archive_acl *abstract_acl, __LA_MODE_T mode)
     7254+{
     7255+       int             ret = ARCHIVE_OK;
     7256+
     7257+       (void)mode;     /* UNUSED */
     7258+
     7259+       if ((archive_acl_types(abstract_acl)
     7260+           & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
     7261+               /* Solaris writes POSIX.1e access and default ACLs together */
     7262+               ret = set_acl(a, fd, name, abstract_acl,
     7263+                   ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
     7264+
     7265+               /* Simultaneous POSIX.1e and NFSv4 is not supported */
     7266+               return (ret);
     7267+       }
     7268+#if ARCHIVE_ACL_SUNOS_NFS4
     7269+       else if ((archive_acl_types(abstract_acl) &
     7270+           ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
     7271+               ret = set_acl(a, fd, name, abstract_acl,
     7272+                   ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
     7273+       }
     7274+#endif
     7275+       return (ret);
     7276+}
     7277--- libarchive/archive_write_disk_posix.c.orig
     7278+++ libarchive/archive_write_disk_posix.c
     7279@@ -575,10 +575,55 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
     7280        if (a->flags & ARCHIVE_EXTRACT_TIME)
     7281                a->todo |= TODO_TIMES;
     7282        if (a->flags & ARCHIVE_EXTRACT_ACL) {
     7283+#if ARCHIVE_ACL_DARWIN
     7284+               /*
     7285+                * On MacOS, platform ACLs get stored in mac_metadata, too.
     7286+                * If we intend to extract mac_metadata and it is present
     7287+                * we skip extracting libarchive NFSv4 ACLs.
     7288+                */
     7289+               size_t metadata_size;
     7290+
     7291+               if ((a->flags & ARCHIVE_EXTRACT_MAC_METADATA) == 0 ||
     7292+                   archive_entry_mac_metadata(a->entry,
     7293+                   &metadata_size) == NULL || metadata_size == 0)
     7294+#endif
     7295+#if ARCHIVE_ACL_LIBRICHACL
     7296+               /*
     7297+                * RichACLs are stored in an extended attribute.
     7298+                * If we intend to extract extended attributes and have this
     7299+                * attribute we skip extracting libarchive NFSv4 ACLs.
     7300+                */
     7301+               short extract_acls = 1;
     7302+               if (a->flags & ARCHIVE_EXTRACT_XATTR && (
     7303+                   archive_entry_acl_types(a->entry) &
     7304+                   ARCHIVE_ENTRY_ACL_TYPE_NFS4)) {
     7305+                       const char *attr_name;
     7306+                       const void *attr_value;
     7307+                       size_t attr_size;
     7308+                       int i = archive_entry_xattr_reset(a->entry);
     7309+                       while (i--) {
     7310+                               archive_entry_xattr_next(a->entry, &attr_name,
     7311+                                   &attr_value, &attr_size);
     7312+                               if (attr_name != NULL && attr_value != NULL &&
     7313+                                   attr_size > 0 && strcmp(attr_name,
     7314+                                   "trusted.richacl") == 0) {
     7315+                                       extract_acls = 0;
     7316+                                       break;
     7317+                               }
     7318+                       }
     7319+               }
     7320+               if (extract_acls)
     7321+#endif
     7322+#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
     7323+               {
     7324+#endif
     7325                if (archive_entry_filetype(a->entry) == AE_IFDIR)
     7326                        a->deferred |= TODO_ACLS;
     7327                else
     7328                        a->todo |= TODO_ACLS;
     7329+#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
     7330+               }
     7331+#endif
     7332        }
     7333        if (a->flags & ARCHIVE_EXTRACT_MAC_METADATA) {
     7334                if (archive_entry_filetype(a->entry) == AE_IFDIR)
     7335@@ -1703,25 +1748,11 @@ _archive_write_disk_finish_entry(struct archive *_a)
     7336         */
     7337        if (a->todo & TODO_ACLS) {
     7338                int r2;
     7339-#ifdef HAVE_DARWIN_ACL
     7340-               /*
     7341-                * On Mac OS, platform ACLs are stored also in mac_metadata by
     7342-                * the operating system. If mac_metadata is present it takes
     7343-                * precedence and we skip extracting libarchive NFSv4 ACLs
     7344-                */
     7345-               const void *metadata;
     7346-               size_t metadata_size;
     7347-               metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
     7348-               if ((a->todo & TODO_MAC_METADATA) == 0 ||
     7349-                   metadata == NULL || metadata_size == 0) {
     7350-#endif
     7351                r2 = archive_write_disk_set_acls(&a->archive, a->fd,
     7352                    archive_entry_pathname(a->entry),
     7353-                   archive_entry_acl(a->entry));
     7354+                   archive_entry_acl(a->entry),
     7355+                   archive_entry_mode(a->entry));
     7356                if (r2 < ret) ret = r2;
     7357-#ifdef HAVE_DARWIN_ACL
     7358-               }
     7359-#endif
     7360        }
     7361 
     7362 finish_metadata:
     7363@@ -2293,13 +2324,8 @@ _archive_write_disk_close(struct archive *_a)
     7364                if (p->fixup & TODO_MODE_BASE)
     7365                        chmod(p->name, p->mode);
     7366                if (p->fixup & TODO_ACLS)
     7367-#ifdef HAVE_DARWIN_ACL
     7368-                       if ((p->fixup & TODO_MAC_METADATA) == 0 ||
     7369-                           p->mac_metadata == NULL ||
     7370-                           p->mac_metadata_size == 0)
     7371-#endif
     7372-                               archive_write_disk_set_acls(&a->archive,
     7373-                                   -1, p->name, &p->acl);
     7374+                       archive_write_disk_set_acls(&a->archive, -1, p->name,
     7375+                           &p->acl, p->mode);
     7376                if (p->fixup & TODO_FFLAGS)
     7377                        set_fflags_platform(a, -1, p->name,
     7378                            p->mode, p->fflags_set, 0);
     7379@@ -2467,7 +2493,7 @@ fsobj_error(int *a_eno, struct archive_string *a_estr,
     7380        if (a_eno)
     7381                *a_eno = err;
     7382        if (a_estr)
     7383-               archive_string_sprintf(a_estr, errstr, path);
     7384+               archive_string_sprintf(a_estr, "%s%s", errstr, path);
     7385 }
     7386 
     7387 /*
     7388@@ -2573,7 +2599,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
     7389                                 * with the deep-directory editing.
     7390                                 */
     7391                                fsobj_error(a_eno, a_estr, errno,
     7392-                                   "Could not stat %s", path);
     7393+                                   "Could not stat ", path);
     7394                                res = ARCHIVE_FAILED;
     7395                                break;
     7396                        }
     7397@@ -2582,7 +2608,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
     7398                                if (chdir(head) != 0) {
     7399                                        tail[0] = c;
     7400                                        fsobj_error(a_eno, a_estr, errno,
     7401-                                           "Could not chdir %s", path);
     7402+                                           "Could not chdir ", path);
     7403                                        res = (ARCHIVE_FATAL);
     7404                                        break;
     7405                                }
     7406@@ -2599,7 +2625,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
     7407                                if (unlink(head)) {
     7408                                        tail[0] = c;
     7409                                        fsobj_error(a_eno, a_estr, errno,
     7410-                                           "Could not remove symlink %s",
     7411+                                           "Could not remove symlink ",
     7412                                            path);
     7413                                        res = ARCHIVE_FAILED;
     7414                                        break;
     7415@@ -2618,7 +2644,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
     7416                                /*
     7417                                if (!S_ISLNK(path)) {
     7418                                        fsobj_error(a_eno, a_estr, 0,
     7419-                                           "Removing symlink %s", path);
     7420+                                           "Removing symlink ", path);
     7421                                }
     7422                                */
     7423                                /* Symlink gone.  No more problem! */
     7424@@ -2630,7 +2656,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
     7425                                        tail[0] = c;
     7426                                        fsobj_error(a_eno, a_estr, 0,
     7427                                            "Cannot remove intervening "
     7428-                                           "symlink %s", path);
     7429+                                           "symlink ", path);
     7430                                        res = ARCHIVE_FAILED;
     7431                                        break;
     7432                                }
     7433@@ -2652,7 +2678,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
     7434                                        } else {
     7435                                                fsobj_error(a_eno, a_estr,
     7436                                                    errno,
     7437-                                                   "Could not stat %s", path);
     7438+                                                   "Could not stat ", path);
     7439                                                res = (ARCHIVE_FAILED);
     7440                                                break;
     7441                                        }
     7442@@ -2661,7 +2687,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
     7443                                                tail[0] = c;
     7444                                                fsobj_error(a_eno, a_estr,
     7445                                                    errno,
     7446-                                                   "Could not chdir %s", path);
     7447+                                                   "Could not chdir ", path);
     7448                                                res = (ARCHIVE_FATAL);
     7449                                                break;
     7450                                        }
     7451@@ -2674,14 +2700,14 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
     7452                                        tail[0] = c;
     7453                                        fsobj_error(a_eno, a_estr, 0,
     7454                                            "Cannot extract through "
     7455-                                           "symlink %s", path);
     7456+                                           "symlink ", path);
     7457                                        res = ARCHIVE_FAILED;
     7458                                        break;
     7459                                }
     7460                        } else {
     7461                                tail[0] = c;
     7462                                fsobj_error(a_eno, a_estr, 0,
     7463-                                   "Cannot extract through symlink %s", path);
     7464+                                   "Cannot extract through symlink ", path);
     7465                                res = ARCHIVE_FAILED;
     7466                                break;
     7467                        }
     7468@@ -4239,5 +4265,19 @@ older(struct stat *st, struct archive_entry *entry)
     7469        return (0);
     7470 }
     7471 
     7472+#ifndef ARCHIVE_ACL_SUPPORT
     7473+int
     7474+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
     7475+    struct archive_acl *abstract_acl, __LA_MODE_T mode)
     7476+{
     7477+       (void)a; /* UNUSED */
     7478+       (void)fd; /* UNUSED */
     7479+       (void)name; /* UNUSED */
     7480+       (void)abstract_acl; /* UNUSED */
     7481+       (void)mode; /* UNUSED */
     7482+       return (ARCHIVE_OK);
     7483+}
     7484+#endif
     7485+
     7486 #endif /* !_WIN32 || __CYGWIN__ */
     7487 
     7488--- libarchive/archive_write_disk_private.h.orig
     7489+++ libarchive/archive_write_disk_private.h
     7490@@ -33,11 +33,13 @@
     7491 #ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
     7492 #define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
     7493 
     7494+#include "archive_platform_acl.h"
     7495 #include "archive_acl_private.h"
     7496+#include "archive_entry.h"
     7497 
     7498 struct archive_write_disk;
     7499 
     7500-int
     7501-archive_write_disk_set_acls(struct archive *, int /* fd */, const char * /* pathname */, struct archive_acl *);
     7502+int archive_write_disk_set_acls(struct archive *, int, const char *,
     7503+    struct archive_acl *, __LA_MODE_T);
     7504 
     7505 #endif
     7506--- libarchive/archive_write_finish_entry.3.orig
     7507+++ libarchive/archive_write_finish_entry.3
     7508@@ -24,7 +24,7 @@
     7509 .\"
     7510 .\" $FreeBSD$
     7511 .\"
     7512-.Dd February 2, 2012
     7513+.Dd February 28, 2017
     7514 .Dt ARCHIVE_WRITE_FINISH_ENTRY 3
     7515 .Os
     7516 .Sh NAME
     7517@@ -45,6 +45,9 @@ is called automatically by
     7518 and
     7519 .Fn archive_write_close
     7520 as needed.
     7521+For
     7522+.Tn archive_write_disk
     7523+handles, this flushes pending file attribute changes like modification time.
     7524 .\" .Sh EXAMPLE
     7525 .Sh RETURN VALUES
     7526 This function returns
     7527--- libarchive/archive_write_format.3.orig
     7528+++ libarchive/archive_write_format.3
     7529@@ -108,7 +108,6 @@ Streaming Archive Library (libarchive, -larchive)
     7530 These functions set the format that will be used for the archive.
     7531 .Pp
     7532 The library can write a variety of common archive formats.
     7533-
     7534 .Bl -tag -width indent
     7535 .It Fn archive_write_set_format
     7536 Sets the format based on the format code (see
     7537--- libarchive/mtree.5.orig
     7538+++ libarchive/mtree.5
     7539@@ -48,7 +48,7 @@ Leading whitespace is always ignored.
     7540 .Pp
     7541 When encoding file or pathnames, any backslash character or
     7542 character outside of the 95 printable ASCII characters must be
     7543-encoded as a a backslash followed by three
     7544+encoded as a backslash followed by three
     7545 octal digits.
     7546 When reading mtree files, any appearance of a backslash
     7547 followed by three octal digits should be converted into the
     7548--- libarchive/test/test_acl_platform_nfs4.c.orig
     7549+++ libarchive/test/test_acl_platform_nfs4.c
     7550@@ -26,15 +26,18 @@
     7551 #include "test.h"
     7552 __FBSDID("$FreeBSD$");
     7553 
     7554-#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
     7555+#if ARCHIVE_ACL_NFS4
     7556+#if HAVE_SYS_ACL_H
     7557 #define _ACL_PRIVATE
     7558 #include <sys/acl.h>
     7559-#if HAVE_DARWIN_ACL
     7560-#include <membership.h>
     7561 #endif
     7562+#if HAVE_SYS_RICHACL_H
     7563+#include <sys/richacl.h>
     7564+#endif
     7565+#if HAVE_MEMBERSHIP_H
     7566+#include <membership.h>
     7567 #endif
     7568 
     7569-#if HAVE_NFS4_ACL
     7570 struct myacl_t {
     7571        int type;
     7572        int permset;
     7573@@ -44,7 +47,7 @@ struct myacl_t {
     7574 };
     7575 
     7576 static struct myacl_t acls_reg[] = {
     7577-#if !HAVE_DARWIN_ACL
     7578+#if !ARCHIVE_ACL_DARWIN
     7579        /* For this test, we need the file owner to be able to read and write the ACL. */
     7580        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
     7581          ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTRY_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
     7582@@ -91,7 +94,7 @@ static struct myacl_t acls_reg[] = {
     7583 //       ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
     7584        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
     7585          ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" },
     7586-#if !HAVE_DARWIN_ACL
     7587+#if !ARCHIVE_ACL_DARWIN
     7588        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
     7589          ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
     7590        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
     7591@@ -134,7 +137,7 @@ static const int acls_reg_cnt = (int)(sizeof(acls_reg)/sizeof(acls_reg[0]));
     7592 
     7593 static struct myacl_t acls_dir[] = {
     7594        /* For this test, we need to be able to read and write the ACL. */
     7595-#if !HAVE_DARWIN_ACL
     7596+#if !ARCHIVE_ACL_DARWIN
     7597        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL,
     7598          ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
     7599 #endif
     7600@@ -180,13 +183,17 @@ static struct myacl_t acls_dir[] = {
     7601        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
     7602          ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
     7603          ARCHIVE_ENTRY_ACL_USER, 302, "user302" },
     7604-#if 0
     7605        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
     7606-         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT,
     7607+         ARCHIVE_ENTRY_ACL_READ_DATA |
     7608+         ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
     7609+         ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT,
     7610          ARCHIVE_ENTRY_ACL_USER, 303, "user303" },
     7611        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
     7612-         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
     7613+         ARCHIVE_ENTRY_ACL_READ_DATA |
     7614+         ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT |
     7615+         ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
     7616          ARCHIVE_ENTRY_ACL_USER, 304, "user304" },
     7617+#if !defined(ARCHIVE_ACL_SUNOS_NFS4) || defined(ACE_INHERITED_ACE)
     7618        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
     7619          ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
     7620          ARCHIVE_ENTRY_ACL_USER, 305, "user305" },
     7621@@ -207,7 +214,7 @@ static struct myacl_t acls_dir[] = {
     7622          ARCHIVE_ENTRY_ACL_USER, 501, "user501" },
     7623        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
     7624          ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" },
     7625-#if !HAVE_DARWIN_ACL
     7626+#if !ARCHIVE_ACL_DARWIN
     7627        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
     7628          ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
     7629        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
     7630@@ -254,12 +261,14 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
     7631        int i;
     7632 
     7633        archive_entry_acl_clear(ae);
     7634+#if !ARCHIVE_ACL_DARWIN
     7635        if (start > 0) {
     7636                assertEqualInt(ARCHIVE_OK,
     7637                        archive_entry_acl_add_entry(ae,
     7638                            acls[0].type, acls[0].permset, acls[0].tag,
     7639                            acls[0].qual, acls[0].name));
     7640        }
     7641+#endif
     7642        for (i = start; i < end; i++) {
     7643                assertEqualInt(ARCHIVE_OK,
     7644                    archive_entry_acl_add_entry(ae,
     7645@@ -269,76 +278,96 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
     7646 }
     7647 
     7648 static int
     7649-#ifdef HAVE_SUN_ACL
     7650-acl_permset_to_bitmap(uint32_t a_access_mask)
     7651+#if ARCHIVE_ACL_SUNOS_NFS4
     7652+acl_permset_to_bitmap(uint32_t mask)
     7653+#elif ARCHIVE_ACL_LIBRICHACL
     7654+acl_permset_to_bitmap(unsigned int mask)
     7655 #else
     7656 acl_permset_to_bitmap(acl_permset_t opaque_ps)
     7657 #endif
     7658 {
     7659-       static struct { int machine; int portable; } perms[] = {
     7660-#ifdef HAVE_SUN_ACL    /* Solaris NFSv4 ACL permissions */
     7661-               {ACE_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
     7662-               {ACE_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
     7663-               {ACE_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
     7664-               {ACE_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
     7665-               {ACE_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
     7666-               {ACE_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
     7667-               {ACE_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
     7668-               {ACE_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
     7669-               {ACE_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
     7670-               {ACE_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
     7671-               {ACE_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
     7672-               {ACE_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
     7673-               {ACE_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
     7674-               {ACE_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
     7675-               {ACE_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
     7676-               {ACE_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
     7677-               {ACE_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
     7678-#elif HAVE_DARWIN_ACL  /* MacOS NFSv4 ACL permissions */
     7679-               {ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
     7680-               {ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
     7681-               {ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
     7682-               {ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
     7683-               {ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
     7684-               {ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
     7685-               {ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
     7686-               {ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
     7687-               {ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
     7688-               {ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
     7689-               {ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
     7690-               {ACL_READ_EXTATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
     7691-               {ACL_WRITE_EXTATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
     7692-               {ACL_READ_SECURITY, ARCHIVE_ENTRY_ACL_READ_ACL},
     7693-               {ACL_WRITE_SECURITY, ARCHIVE_ENTRY_ACL_WRITE_ACL},
     7694-               {ACL_CHANGE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
     7695-               {ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE},
     7696+       static struct { int portable; int machine; } perms[] = {
     7697+#ifdef ARCHIVE_ACL_SUNOS_NFS4  /* Solaris NFSv4 ACL permissions */
     7698+               {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
     7699+               {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
     7700+               {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
     7701+               {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
     7702+               {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
     7703+               {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
     7704+               {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
     7705+               {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
     7706+               {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
     7707+               {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
     7708+               {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
     7709+               {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
     7710+               {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
     7711+               {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
     7712+               {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
     7713+               {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
     7714+               {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
     7715+#elif ARCHIVE_ACL_DARWIN       /* MacOS NFSv4 ACL permissions */
     7716+               {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
     7717+               {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
     7718+               {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
     7719+               {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
     7720+               {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
     7721+               {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
     7722+               {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
     7723+               {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
     7724+               {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
     7725+               {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
     7726+               {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
     7727+               {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
     7728+               {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
     7729+               {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
     7730+               {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
     7731+               {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
     7732+#if HAVE_DECL_ACL_SYNCHRONIZE
     7733+               {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
     7734+#endif
     7735+#elif ARCHIVE_ACL_LIBRICHACL
     7736+               {ARCHIVE_ENTRY_ACL_EXECUTE, RICHACE_EXECUTE},
     7737+               {ARCHIVE_ENTRY_ACL_READ_DATA, RICHACE_READ_DATA},
     7738+               {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, RICHACE_LIST_DIRECTORY},
     7739+               {ARCHIVE_ENTRY_ACL_WRITE_DATA, RICHACE_WRITE_DATA},
     7740+               {ARCHIVE_ENTRY_ACL_ADD_FILE, RICHACE_ADD_FILE},
     7741+               {ARCHIVE_ENTRY_ACL_APPEND_DATA, RICHACE_APPEND_DATA},
     7742+               {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, RICHACE_ADD_SUBDIRECTORY},
     7743+               {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, RICHACE_READ_NAMED_ATTRS},
     7744+               {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, RICHACE_WRITE_NAMED_ATTRS},
     7745+               {ARCHIVE_ENTRY_ACL_DELETE_CHILD, RICHACE_DELETE_CHILD},
     7746+               {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, RICHACE_READ_ATTRIBUTES},
     7747+               {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, RICHACE_WRITE_ATTRIBUTES},
     7748+               {ARCHIVE_ENTRY_ACL_DELETE, RICHACE_DELETE},
     7749+               {ARCHIVE_ENTRY_ACL_READ_ACL, RICHACE_READ_ACL},
     7750+               {ARCHIVE_ENTRY_ACL_WRITE_ACL, RICHACE_WRITE_ACL},
     7751+               {ARCHIVE_ENTRY_ACL_WRITE_OWNER, RICHACE_WRITE_OWNER},
     7752+               {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, RICHACE_SYNCHRONIZE}
     7753 #else  /* FreeBSD NFSv4 ACL permissions */
     7754-               {ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
     7755-               {ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
     7756-               {ACL_READ, ARCHIVE_ENTRY_ACL_READ},
     7757-               {ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
     7758-               {ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
     7759-               {ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
     7760-               {ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
     7761-               {ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
     7762-               {ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
     7763-               {ACL_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
     7764-               {ACL_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
     7765-               {ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
     7766-               {ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
     7767-               {ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
     7768-               {ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
     7769-               {ACL_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
     7770-               {ACL_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
     7771-               {ACL_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
     7772-               {ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
     7773+               {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
     7774+               {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
     7775+               {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
     7776+               {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
     7777+               {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
     7778+               {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
     7779+               {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
     7780+               {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
     7781+               {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
     7782+               {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
     7783+               {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
     7784+               {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
     7785+               {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
     7786+               {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
     7787+               {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
     7788+               {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
     7789+               {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
     7790 #endif
     7791        };
     7792        int i, permset = 0;
     7793 
     7794        for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
     7795-#if HAVE_SUN_ACL
     7796-               if (a_access_mask & perms[i].machine)
     7797+#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL
     7798+               if (mask & perms[i].machine)
     7799 #else
     7800                if (acl_get_perm_np(opaque_ps, perms[i].machine))
     7801 #endif
     7802@@ -347,88 +376,70 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
     7803 }
     7804 
     7805 static int
     7806-#if HAVE_SUN_ACL
     7807-acl_flagset_to_bitmap(uint16_t a_flags)
     7808+#if ARCHIVE_ACL_SUNOS_NFS4
     7809+acl_flagset_to_bitmap(uint16_t flags)
     7810+#elif ARCHIVE_ACL_LIBRICHACL
     7811+acl_flagset_to_bitmap(int flags)
     7812 #else
     7813 acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
     7814 #endif
     7815 {
     7816-       static struct { int machine; int portable; } flags[] = {
     7817-#if HAVE_SUN_ACL       /* Solaris NFSv4 ACL inheritance flags */
     7818-               {ACE_FILE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
     7819-               {ACE_DIRECTORY_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
     7820-               {ACE_NO_PROPAGATE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
     7821-               {ACE_INHERIT_ONLY_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
     7822-               {ACE_SUCCESSFUL_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
     7823-               {ACE_FAILED_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
     7824-               {ACE_INHERITED_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED}
     7825-#elif HAVE_DARWIN_ACL  /* MacOS NFSv4 ACL inheritance flags */
     7826-               {ACL_ENTRY_INHERITED, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED},
     7827-               {ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
     7828-               {ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
     7829-               {ACL_ENTRY_LIMIT_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
     7830-               {ACL_ENTRY_ONLY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY}
     7831+       static struct { int portable; int machine; } perms[] = {
     7832+#if ARCHIVE_ACL_SUNOS_NFS4     /* Solaris NFSv4 ACL inheritance flags */
     7833+               {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
     7834+               {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
     7835+               {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
     7836+               {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
     7837+               {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
     7838+               {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
     7839+#ifdef ACE_INHERITED_ACE
     7840+               {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
     7841+#endif
     7842+#elif ARCHIVE_ACL_DARWIN       /* MacOS NFSv4 ACL inheritance flags */
     7843+               {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
     7844+               {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
     7845+               {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
     7846+               {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
     7847+               {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
     7848+#elif ARCHIVE_ACL_LIBRICHACL
     7849+               {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, RICHACE_FILE_INHERIT_ACE},
     7850+               {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, RICHACE_DIRECTORY_INHERIT_ACE},
     7851+               {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, RICHACE_NO_PROPAGATE_INHERIT_ACE},
     7852+               {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE},
     7853+               {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE}
     7854 #else  /* FreeBSD NFSv4 ACL inheritance flags */
     7855-               {ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
     7856-               {ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
     7857-               {ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
     7858-               {ACL_ENTRY_SUCCESSFUL_ACCESS, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
     7859-               {ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
     7860-               {ACL_ENTRY_INHERIT_ONLY, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
     7861+               {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
     7862+               {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
     7863+               {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
     7864+               {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
     7865+               {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
     7866+               {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
     7867+               {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
     7868 #endif
     7869        };
     7870        int i, flagset = 0;
     7871 
     7872-       for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
     7873-#if HAVE_SUN_ACL
     7874-               if (a_flags & flags[i].machine)
     7875+       for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
     7876+#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL
     7877+               if (flags & perms[i].machine)
     7878 #else
     7879-               if (acl_get_flag_np(opaque_fs, flags[i].machine))
     7880+               if (acl_get_flag_np(opaque_fs, perms[i].machine))
     7881 #endif
     7882-                       flagset |= flags[i].portable;
     7883+                       flagset |= perms[i].portable;
     7884        return flagset;
     7885 }
     7886 
     7887+#if ARCHIVE_ACL_SUNOS_NFS4
     7888 static int
     7889-#if HAVE_SUN_ACL
     7890 acl_match(ace_t *ace, struct myacl_t *myacl)
     7891-#else
     7892-acl_match(acl_entry_t aclent, struct myacl_t *myacl)
     7893-#endif
     7894 {
     7895-#if !HAVE_SUN_ACL
     7896-#if HAVE_DARWIN_ACL
     7897-       void *q;
     7898-       uid_t ugid;
     7899-       int r, idtype;
     7900-#else
     7901-       gid_t g, *gp;
     7902-       uid_t u, *up;
     7903-       acl_entry_type_t entry_type;
     7904-#endif /* !HAVE_DARWIN_ACL */
     7905-       acl_tag_t tag_type;
     7906-       acl_permset_t opaque_ps;
     7907-       acl_flagset_t opaque_fs;
     7908-#endif /* !HAVE_SUN_ACL */
     7909        int perms;
     7910 
     7911-#if HAVE_SUN_ACL
     7912        perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags);
     7913-#else
     7914-       acl_get_tag_type(aclent, &tag_type);
     7915-#if !HAVE_DARWIN_ACL
     7916-       acl_get_entry_type_np(aclent, &entry_type);
     7917-#endif
     7918 
     7919-       /* translate the silly opaque permset to a bitmap */
     7920-       acl_get_permset(aclent, &opaque_ps);
     7921-       acl_get_flagset_np(aclent, &opaque_fs);
     7922-       perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs);
     7923-#endif
     7924        if (perms != myacl->permset)
     7925                return (0);
     7926 
     7927-#if HAVE_SUN_ACL
     7928        switch (ace->a_type) {
     7929        case ACE_ACCESS_ALLOWED_ACE_TYPE:
     7930                if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
     7931@@ -470,7 +481,85 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
     7932                if ((uid_t)myacl->qual != ace->a_who)
     7933                        return (0);
     7934        }
     7935-#elif HAVE_DARWIN_ACL
     7936+       return (1);
     7937+}
     7938+#elif ARCHIVE_ACL_LIBRICHACL
     7939+static int
     7940+acl_match(struct richace *richace, struct myacl_t *myacl)
     7941+{
     7942+       int perms;
     7943+
     7944+       perms = acl_permset_to_bitmap(richace->e_mask) |
     7945+           acl_flagset_to_bitmap(richace->e_flags);
     7946+
     7947+       if (perms != myacl->permset)
     7948+               return (0);
     7949+
     7950+       switch (richace->e_type) {
     7951+       case RICHACE_ACCESS_ALLOWED_ACE_TYPE:
     7952+               if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
     7953+                       return (0);
     7954+               break;
     7955+       case RICHACE_ACCESS_DENIED_ACE_TYPE:
     7956+               if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
     7957+                       return (0);
     7958+               break;
     7959+       default:
     7960+               return (0);
     7961+       }
     7962+
     7963+       if (richace->e_flags & RICHACE_SPECIAL_WHO) {
     7964+               switch (richace->e_id) {
     7965+               case RICHACE_OWNER_SPECIAL_ID:
     7966+                       if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ)
     7967+                               return (0);
     7968+                       break;
     7969+               case RICHACE_GROUP_SPECIAL_ID:
     7970+                       if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ)
     7971+                               return (0);
     7972+                       break;
     7973+               case RICHACE_EVERYONE_SPECIAL_ID:
     7974+                       if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE)
     7975+                               return (0);
     7976+                       break;
     7977+               default:
     7978+                       /* Invalid e_id */
     7979+                       return (0);
     7980+               }
     7981+       } else if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) {
     7982+               if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
     7983+                       return (0);
     7984+               if ((gid_t)myacl->qual != richace->e_id)
     7985+                       return (0);
     7986+       } else {
     7987+               if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
     7988+                       return (0);
     7989+               if ((uid_t)myacl->qual != richace->e_id)
     7990+                       return (0);
     7991+       }
     7992+       return (1);
     7993+}
     7994+#elif ARCHIVE_ACL_DARWIN
     7995+static int
     7996+acl_match(acl_entry_t aclent, struct myacl_t *myacl)
     7997+{
     7998+       void *q;
     7999+       uid_t ugid;
     8000+       int r, idtype;
     8001+       acl_tag_t tag_type;
     8002+       acl_permset_t opaque_ps;
     8003+       acl_flagset_t opaque_fs;
     8004+       int perms;
     8005+
     8006+       acl_get_tag_type(aclent, &tag_type);
     8007+
     8008+       /* translate the silly opaque permset to a bitmap */
     8009+       acl_get_permset(aclent, &opaque_ps);
     8010+       acl_get_flagset_np(aclent, &opaque_fs);
     8011+       perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs);
     8012+       if (perms != myacl->permset)
     8013+               return (0);
     8014+
     8015        r = 0;
     8016        switch (tag_type) {
     8017        case ACL_EXTENDED_ALLOW:
     8018@@ -507,7 +596,30 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
     8019                default:
     8020                        return (0);
     8021        }
     8022-#else  /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
     8023+       return (1);
     8024+}
     8025+#else /* ARCHIVE_ACL_FREEBSD_NFS4 */
     8026+static int
     8027+acl_match(acl_entry_t aclent, struct myacl_t *myacl)
     8028+{
     8029+       gid_t g, *gp;
     8030+       uid_t u, *up;
     8031+       acl_entry_type_t entry_type;
     8032+       acl_tag_t tag_type;
     8033+       acl_permset_t opaque_ps;
     8034+       acl_flagset_t opaque_fs;
     8035+       int perms;
     8036+
     8037+       acl_get_tag_type(aclent, &tag_type);
     8038+       acl_get_entry_type_np(aclent, &entry_type);
     8039+
     8040+       /* translate the silly opaque permset to a bitmap */
     8041+       acl_get_permset(aclent, &opaque_ps);
     8042+       acl_get_flagset_np(aclent, &opaque_fs);
     8043+       perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs);
     8044+       if (perms != myacl->permset)
     8045+               return (0);
     8046+
     8047        switch (entry_type) {
     8048        case ACL_ENTRY_TYPE_ALLOW:
     8049                if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
     8050@@ -559,14 +671,17 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
     8051                if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
     8052                break;
     8053        }
     8054-#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
     8055        return (1);
     8056 }
     8057+#endif /* various ARCHIVE_ACL_NFS4 implementations */
     8058 
     8059 static void
     8060 compare_acls(
     8061-#if HAVE_SUN_ACL
     8062-    acl_t *acl,
     8063+#if ARCHIVE_ACL_SUNOS_NFS4
     8064+    void *aclp,
     8065+    int aclcnt,
     8066+#elif ARCHIVE_ACL_LIBRICHACL
     8067+    struct richacl *richacl,
     8068 #else
     8069     acl_t acl,
     8070 #endif
     8071@@ -575,38 +690,61 @@ compare_acls(
     8072        int *marker;
     8073        int matched;
     8074        int i, n;
     8075-#if HAVE_SUN_ACL
     8076+#if ARCHIVE_ACL_SUNOS_NFS4
     8077        int e;
     8078        ace_t *acl_entry;
     8079+#elif ARCHIVE_ACL_LIBRICHACL
     8080+       int e;
     8081+       struct richace *acl_entry;
     8082+       int aclcnt;
     8083 #else
     8084        int entry_id = ACL_FIRST_ENTRY;
     8085        acl_entry_t acl_entry;
     8086+#if ARCHIVE_ACL_DARWIN
     8087+       const int acl_get_entry_ret = 0;
     8088+#else
     8089+       const int acl_get_entry_ret = 1;
     8090+#endif
     8091+#endif
     8092+
     8093+#if ARCHIVE_ACL_SUNOS_NFS4
     8094+       if (aclp == NULL)
     8095+               return;
     8096+#elif ARCHIVE_ACL_LIBRICHACL
     8097+       if (richacl == NULL)
     8098+               return;
     8099+       aclcnt = richacl->a_count;
     8100+#else
     8101+       if (acl == NULL)
     8102+               return;
     8103 #endif
     8104 
     8105        n = end - start;
     8106        marker = malloc(sizeof(marker[0]) * (n + 1));
     8107        for (i = 0; i < n; i++)
     8108                marker[i] = i + start;
     8109+#if !ARCHIVE_ACL_DARWIN
     8110        /* Always include the first ACE. */
     8111        if (start > 0) {
     8112          marker[n] = 0;
     8113          ++n;
     8114        }
     8115+#endif
     8116 
     8117        /*
     8118         * Iterate over acls in system acl object, try to match each
     8119         * one with an item in the myacls array.
     8120         */
     8121-#if HAVE_SUN_ACL
     8122-       for (e = 0; e < acl->acl_cnt; e++)
     8123-#elif HAVE_DARWIN_ACL
     8124-       while (0 == acl_get_entry(acl, entry_id, &acl_entry))
     8125+#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL
     8126+       for (e = 0; e < aclcnt; e++)
     8127 #else
     8128-       while (1 == acl_get_entry(acl, entry_id, &acl_entry))
     8129+       while (acl_get_entry_ret == acl_get_entry(acl, entry_id, &acl_entry))
     8130 #endif
     8131        {
     8132-#if HAVE_SUN_ACL
     8133-               acl_entry = &((ace_t *)acl->acl_aclp)[e];
     8134+#if ARCHIVE_ACL_SUNOS_NFS4
     8135+               acl_entry = &((ace_t *)aclp)[e];
     8136+#elif ARCHIVE_ACL_LIBRICHACL
     8137+               acl_entry = &(richacl->a_entries[e]);
     8138 #else
     8139                /* After the first time... */
     8140                entry_id = ACL_NEXT_ENTRY;
     8141@@ -699,7 +837,7 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
     8142        }
     8143        free(marker);
     8144 }
     8145-#endif /* HAVE_NFS4_ACL */
     8146+#endif /* ARCHIVE_ACL_NFS4 */
     8147 
     8148 /*
     8149  * Verify ACL restore-to-disk.  This test is Platform-specific.
     8150@@ -707,101 +845,36 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
     8151 
     8152 DEFINE_TEST(test_acl_platform_nfs4)
     8153 {
     8154-#if !HAVE_NFS4_ACL
     8155+#if !ARCHIVE_ACL_NFS4
     8156        skipping("NFS4 ACLs are not supported on this platform");
     8157-#else
     8158+#else /* ARCHIVE_ACL_NFS4 */
     8159        char buff[64];
     8160+       int i;
     8161        struct stat st;
     8162        struct archive *a;
     8163        struct archive_entry *ae;
     8164-       int i, n;
     8165-       char *func;
     8166-#if HAVE_DARWIN_ACL /* On MacOS we skip trivial ACLs in some tests */
     8167+#if ARCHIVE_ACL_DARWIN /* On MacOS we skip trivial ACLs in some tests */
     8168        const int regcnt = acls_reg_cnt - 4;
     8169        const int dircnt = acls_dir_cnt - 4;
     8170 #else
     8171        const int regcnt = acls_reg_cnt;
     8172        const int dircnt = acls_dir_cnt;
     8173 #endif
     8174-#if HAVE_SUN_ACL
     8175-       acl_t *acl;
     8176-#else  /* !HAVE_SUN_ACL */
     8177-#if HAVE_DARWIN_ACL
     8178-       acl_entry_t aclent;
     8179-       acl_permset_t permset;
     8180-       const uid_t uid = 1000;
     8181-       uuid_t uuid;
     8182-#endif /* HAVE_DARWIN_ACL */
     8183+#if ARCHIVE_ACL_SUNOS_NFS4
     8184+       void *aclp;
     8185+       int aclcnt;
     8186+#elif ARCHIVE_ACL_LIBRICHACL
     8187+       struct richacl *richacl;
     8188+#else  /* !ARCHIVE_ACL_SUNOS_NFS4 */
     8189        acl_t acl;
     8190-#endif /* !HAVE_SUN_ACL */
     8191-
     8192-       /*
     8193-        * First, do a quick manual set/read of ACL data to
     8194-        * verify that the local filesystem does support ACLs.
     8195-        * If it doesn't, we'll simply skip the remaining tests.
     8196-        */
     8197-#if HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4
     8198-       acl = acl_from_text("owner@:rwxp::allow,group@:rwp:f:allow");
     8199-       failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
     8200-       assert((void *)acl != NULL);
     8201-#elif HAVE_DARWIN_ACL
     8202-       acl = acl_init(1);
     8203-       assert((void *)acl != NULL);
     8204-       assertEqualInt(0, acl_create_entry(&acl, &aclent));
     8205-       assertEqualInt(0, acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW));
     8206-       assertEqualInt(0, acl_get_permset(aclent, &permset));
     8207-       assertEqualInt(0, acl_add_perm(permset, ACL_READ_DATA));
     8208-       assertEqualInt(0, acl_add_perm(permset, ACL_WRITE_DATA));
     8209-       assertEqualInt(0, acl_add_perm(permset, ACL_APPEND_DATA));
     8210-       assertEqualInt(0, acl_add_perm(permset, ACL_EXECUTE));
     8211-       assertEqualInt(0, acl_set_permset(aclent, permset));
     8212-       assertEqualInt(0, mbr_identifier_to_uuid(ID_TYPE_UID, &uid,
     8213-           sizeof(uid_t), uuid));
     8214-       assertEqualInt(0, acl_set_qualifier(aclent, uuid));
     8215-#endif
     8216-
     8217-       /* Create a test dir and try to set an ACL on it. */
     8218-       if (!assertMakeDir("pretest", 0755)) {
     8219-#if !HAVE_SUN_ACL
     8220-               acl_free(acl);
     8221 #endif
     8222-               return;
     8223-       }
     8224 
     8225-#if HAVE_SUN_ACL
     8226-       func = "acl_get()";
     8227-       n = acl_get("pretest", 0, &acl);
     8228-#else
     8229-       func = "acl_set_file()";
     8230-#if HAVE_DARWIN_ACL
     8231-       n = acl_set_file("pretest", ACL_TYPE_EXTENDED, acl);
     8232-#else
     8233-       n = acl_set_file("pretest", ACL_TYPE_NFS4, acl);
     8234-#endif
     8235-       acl_free(acl);
     8236-#endif
     8237-       if (n != 0) {
     8238-#if HAVE_SUN_ACL
     8239-               if (errno == ENOSYS)
     8240-#else
     8241-               if (errno == EOPNOTSUPP || errno == EINVAL)
     8242-#endif
     8243-               {
     8244-                       skipping("NFS4 ACL is not supported on this filesystem");
     8245-                       return;
     8246-               }
     8247-       }
     8248-       failure("%s: errno = %d (%s)", func, errno, strerror(errno));
     8249-       assertEqualInt(0, n);
     8250+       assertMakeFile("pretest", 0644, "a");
     8251 
     8252-#if HAVE_SUN_ACL
     8253-       if (acl->acl_type != ACE_T) {
     8254-               acl_free(acl);
     8255-               skipping("NFS4 ACL is not supported on this filesystem");
     8256+       if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_NFS4) {
     8257+               skipping("NFS4 ACLs are not writable on this filesystem");
     8258                return;
     8259        }
     8260-       acl_free(acl);
     8261-#endif
     8262 
     8263        /* Create a write-to-disk object. */
     8264        assert(NULL != (a = archive_write_disk_new()));
     8265@@ -848,63 +921,115 @@ DEFINE_TEST(test_acl_platform_nfs4)
     8266        /* Verify the data on disk. */
     8267        assertEqualInt(0, stat("testall", &st));
     8268        assertEqualInt(st.st_mtime, 123456);
     8269-#if HAVE_SUN_ACL
     8270-       n = acl_get("testall", 0, &acl);
     8271-       failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
     8272-       assertEqualInt(0, n);
     8273+#if ARCHIVE_ACL_SUNOS_NFS4
     8274+       aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "testall");
     8275+       failure("acl(\"%s\"): errno = %d (%s)", "testall", errno,
     8276+           strerror(errno));
     8277+       assert(aclp != NULL);
     8278+#elif ARCHIVE_ACL_LIBRICHACL
     8279+       richacl = richacl_get_file("testall");
     8280+       failure("richacl_get_file(\"%s\"): errno = %d (%s)", "testall", errno,
     8281+           strerror(errno));
     8282+       assert(richacl != NULL);
     8283 #else
     8284-#if HAVE_DARWIN_ACL
     8285+#if ARCHIVE_ACL_DARWIN
     8286        acl = acl_get_file("testall", ACL_TYPE_EXTENDED);
     8287 #else
     8288        acl = acl_get_file("testall", ACL_TYPE_NFS4);
     8289 #endif
     8290-       failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
     8291+       failure("acl_get_file(\"%s\"): errno = %d (%s)", "testall", errno,
     8292+           strerror(errno));
     8293        assert(acl != (acl_t)NULL);
     8294 #endif
     8295+#if ARCHIVE_ACL_SUNOS_NFS4
     8296+       compare_acls(aclp, aclcnt, acls_reg, "testall", 0, regcnt);
     8297+       free(aclp);
     8298+       aclp = NULL;
     8299+#elif ARCHIVE_ACL_LIBRICHACL
     8300+       compare_acls(richacl, acls_reg, "testall", 0, regcnt);
     8301+       richacl_free(richacl);
     8302+#else
     8303        compare_acls(acl, acls_reg, "testall", 0, regcnt);
     8304        acl_free(acl);
     8305+#endif
     8306+
     8307 
     8308        /* Verify single-permission dirs on disk. */
     8309        for (i = 0; i < dircnt; ++i) {
     8310                sprintf(buff, "dir%d", i);
     8311                assertEqualInt(0, stat(buff, &st));
     8312                assertEqualInt(st.st_mtime, 123456 + i);
     8313-#if HAVE_SUN_ACL
     8314-               n = acl_get(buff, 0, &acl);
     8315-               failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
     8316-               assertEqualInt(0, n);
     8317+#if ARCHIVE_ACL_SUNOS_NFS4
     8318+               aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, buff);
     8319+               failure("acl(\"%s\"): errno = %d (%s)", buff, errno,
     8320+                   strerror(errno));
     8321+               assert(aclp != NULL);
     8322+#elif ARCHIVE_ACL_LIBRICHACL
     8323+               richacl = richacl_get_file(buff);
     8324+               /* First and last two dir do not return a richacl */
     8325+               if ((i == 0 || i >= dircnt - 2) && richacl == NULL &&
     8326+                   errno == ENODATA)
     8327+                       continue;
     8328+               failure("richacl_get_file(\"%s\"): errno = %d (%s)", buff,
     8329+                   errno, strerror(errno));
     8330+               assert(richacl != NULL);
     8331 #else
     8332-#if HAVE_DARWIN_ACL
     8333+#if ARCHIVE_ACL_DARWIN
     8334                acl = acl_get_file(buff, ACL_TYPE_EXTENDED);
     8335 #else
     8336                acl = acl_get_file(buff, ACL_TYPE_NFS4);
     8337 #endif
     8338-               failure("acl_get_file(): errno = %d (%s)", errno,
     8339+               failure("acl_get_file(\"%s\"): errno = %d (%s)", buff, errno,
     8340                    strerror(errno));
     8341                assert(acl != (acl_t)NULL);
     8342 #endif
     8343+#if ARCHIVE_ACL_SUNOS_NFS4
     8344+               compare_acls(aclp, aclcnt, acls_dir, buff, i, i + 1);
     8345+               free(aclp);
     8346+               aclp = NULL;
     8347+#elif ARCHIVE_ACL_LIBRICHACL
     8348+               compare_acls(richacl, acls_dir, buff, i, i + 1);
     8349+               richacl_free(richacl);
     8350+#else
     8351                compare_acls(acl, acls_dir, buff, i, i + 1);
     8352                acl_free(acl);
     8353+#endif
     8354        }
     8355 
     8356        /* Verify "dirall" on disk. */
     8357        assertEqualInt(0, stat("dirall", &st));
     8358        assertEqualInt(st.st_mtime, 123456);
     8359-#if HAVE_SUN_ACL
     8360-       n = acl_get("dirall", 0, &acl);
     8361-       failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
     8362-       assertEqualInt(0, n);
     8363+#if ARCHIVE_ACL_SUNOS_NFS4
     8364+       aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "dirall");
     8365+       failure("acl(\"%s\"): errno = %d (%s)", "dirall", errno,
     8366+           strerror(errno));
     8367+       assert(aclp != NULL);
     8368+#elif ARCHIVE_ACL_LIBRICHACL
     8369+       richacl = richacl_get_file("dirall");
     8370+       failure("richacl_get_file(\"%s\"): errno = %d (%s)", "dirall",
     8371+           errno, strerror(errno));
     8372+       assert(richacl != NULL);
     8373 #else
     8374-#if HAVE_DARWIN_ACL
     8375+#if ARCHIVE_ACL_DARWIN
     8376        acl = acl_get_file("dirall", ACL_TYPE_EXTENDED);
     8377 #else
     8378        acl = acl_get_file("dirall", ACL_TYPE_NFS4);
     8379 #endif
     8380-       failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
     8381+       failure("acl_get_file(\"%s\"): errno = %d (%s)", "dirall", errno,
     8382+           strerror(errno));
     8383        assert(acl != (acl_t)NULL);
     8384 #endif
     8385+#if ARCHIVE_ACL_SUNOS_NFS4
     8386+       compare_acls(aclp, aclcnt, acls_dir, "dirall", 0, dircnt);
     8387+       free(aclp);
     8388+       aclp = NULL;
     8389+#elif ARCHIVE_ACL_LIBRICHACL
     8390+       compare_acls(richacl, acls_dir, "dirall", 0, dircnt);
     8391+       richacl_free(richacl);
     8392+#else
     8393        compare_acls(acl, acls_dir, "dirall", 0, dircnt);
     8394        acl_free(acl);
     8395+#endif
     8396 
     8397        /* Read and compare ACL via archive_read_disk */
     8398        a = archive_read_disk_new();
     8399@@ -929,5 +1054,5 @@ DEFINE_TEST(test_acl_platform_nfs4)
     8400        compare_entry_acls(ae, acls_dir, "dirall", 0, acls_dir_cnt);
     8401        archive_entry_free(ae);
     8402        assertEqualInt(ARCHIVE_OK, archive_read_free(a));
     8403-#endif /* HAVE_NFS4_ACL */
     8404+#endif /* ARCHIVE_ACL_NFS4 */
     8405 }
     8406--- libarchive/test/test_acl_platform_posix1e.c.orig
     8407+++ libarchive/test/test_acl_platform_posix1e.c
     8408@@ -26,7 +26,7 @@
     8409 #include "test.h"
     8410 __FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-06 04:21:23Z kientzle $");
     8411 
     8412-#if HAVE_POSIX_ACL || HAVE_SUN_ACL
     8413+#if ARCHIVE_ACL_POSIX1E
     8414 #include <sys/acl.h>
     8415 #if HAVE_ACL_GET_PERM
     8416 #include <acl/libacl.h>
     8417@@ -55,18 +55,18 @@ static struct archive_test_acl_t acls2[] = {
     8418 };
     8419 
     8420 static int
     8421-#if HAVE_SUN_ACL
     8422+#if ARCHIVE_ACL_SUNOS
     8423 acl_entry_get_perm(aclent_t *aclent)
     8424 #else
     8425 acl_entry_get_perm(acl_entry_t aclent)
     8426 #endif
     8427 {
     8428        int permset = 0;
     8429-#if HAVE_POSIX_ACL
     8430+#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL
     8431        acl_permset_t opaque_ps;
     8432 #endif
     8433 
     8434-#if HAVE_SUN_ACL
     8435+#if ARCHIVE_ACL_SUNOS
     8436        if (aclent->a_perm & 1)
     8437                permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
     8438        if (aclent->a_perm & 2)
     8439@@ -127,114 +127,108 @@ acl_get_specific_entry(acl_t acl, acl_tag_t requested_tag_type, int requested_ta
     8440 }
     8441 #endif
     8442 
     8443+#if ARCHIVE_ACL_SUNOS
     8444 static int
     8445-#if HAVE_SUN_ACL
     8446 acl_match(aclent_t *aclent, struct archive_test_acl_t *myacl)
     8447-#else
     8448+{
     8449+
     8450+       if (myacl->permset != acl_entry_get_perm(aclent))
     8451+               return (0);
     8452+
     8453+       switch (aclent->a_type) {
     8454+       case DEF_USER_OBJ:
     8455+       case USER_OBJ:
     8456+               if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
     8457+               break;
     8458+               if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
     8459+                       return (0);
     8460+               if ((uid_t)myacl->qual != aclent->a_id)
     8461+                       return (0);
     8462+               break;
     8463+       case DEF_GROUP_OBJ:
     8464+       case GROUP_OBJ:
     8465+               if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
     8466+               break;
     8467+       case DEF_GROUP:
     8468+       case GROUP:
     8469+               if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
     8470+                       return (0);
     8471+               if ((gid_t)myacl->qual != aclent->a_id)
     8472+                       return (0);
     8473+               break;
     8474+       case DEF_CLASS_OBJ:
     8475+       case CLASS_OBJ:
     8476+               if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0);
     8477+               break;
     8478+       case DEF_OTHER_OBJ:
     8479+       case OTHER_OBJ:
     8480+               if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0);
     8481+               break;
     8482+       }
     8483+       return (1);
     8484+}
     8485+
     8486+#else  /* ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL */
     8487+static int
     8488 acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
     8489-#endif
     8490 {
     8491-#if HAVE_POSIX_ACL
     8492        gid_t g, *gp;
     8493        uid_t u, *up;
     8494        acl_tag_t tag_type;
     8495-#endif
     8496 
     8497        if (myacl->permset != acl_entry_get_perm(aclent))
     8498                return (0);
     8499 
     8500-#if HAVE_SUN_ACL
     8501-       switch (aclent->a_type)
     8502-#else
     8503        acl_get_tag_type(aclent, &tag_type);
     8504-       switch (tag_type)
     8505-#endif
     8506-       {
     8507-#if HAVE_SUN_ACL
     8508-       case DEF_USER_OBJ:
     8509-       case USER_OBJ:
     8510-#else
     8511+       switch (tag_type) {
     8512        case ACL_USER_OBJ:
     8513-#endif
     8514                if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
     8515                break;
     8516-#if HAVE_SUN_ACL
     8517-       case DEF_USER:
     8518-       case USER:
     8519-#else
     8520        case ACL_USER:
     8521-#endif
     8522                if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
     8523                        return (0);
     8524-#if HAVE_SUN_ACL
     8525-               if ((uid_t)myacl->qual != aclent->a_id)
     8526-                       return (0);
     8527-#else
     8528                up = acl_get_qualifier(aclent);
     8529                u = *up;
     8530                acl_free(up);
     8531                if ((uid_t)myacl->qual != u)
     8532                        return (0);
     8533-#endif
     8534                break;
     8535-#if HAVE_SUN_ACL
     8536-       case DEF_GROUP_OBJ:
     8537-       case GROUP_OBJ:
     8538-#else
     8539        case ACL_GROUP_OBJ:
     8540-#endif
     8541                if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
     8542                break;
     8543-#if HAVE_SUN_ACL
     8544-       case DEF_GROUP:
     8545-       case GROUP:
     8546-#else
     8547        case ACL_GROUP:
     8548-#endif
     8549                if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
     8550                        return (0);
     8551-#if HAVE_SUN_ACL
     8552-               if ((gid_t)myacl->qual != aclent->a_id)
     8553-                       return (0);
     8554-#else
     8555                gp = acl_get_qualifier(aclent);
     8556                g = *gp;
     8557                acl_free(gp);
     8558                if ((gid_t)myacl->qual != g)
     8559                        return (0);
     8560-#endif
     8561                break;
     8562-#if HAVE_SUN_ACL
     8563-       case DEF_CLASS_OBJ:
     8564-       case CLASS_OBJ:
     8565-#else
     8566        case ACL_MASK:
     8567-#endif
     8568                if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0);
     8569                break;
     8570-#if HAVE_SUN_ACL
     8571-       case DEF_OTHER_OBJ:
     8572-       case OTHER_OBJ:
     8573-#else
     8574        case ACL_OTHER:
     8575-#endif
     8576                if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0);
     8577                break;
     8578        }
     8579        return (1);
     8580 }
     8581+#endif
     8582 
     8583 static void
     8584-#if HAVE_SUN_ACL
     8585-compare_acls(acl_t *acl, struct archive_test_acl_t *myacls, int n)
     8586+compare_acls(
     8587+#if ARCHIVE_ACL_SUNOS
     8588+    void *aclp, int aclcnt,
     8589 #else
     8590-compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
     8591+    acl_t acl,
     8592 #endif
     8593+    struct archive_test_acl_t *myacls, int n)
     8594 {
     8595        int *marker;
     8596        int matched;
     8597        int i;
     8598-#if HAVE_SUN_ACL
     8599+#if ARCHIVE_ACL_SUNOS
     8600        int e;
     8601        aclent_t *acl_entry;
     8602 #else
     8603@@ -253,9 +247,9 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
     8604         * Iterate over acls in system acl object, try to match each
     8605         * one with an item in the myacls array.
     8606         */
     8607-#if HAVE_SUN_ACL
     8608-       for(e = 0; e < acl->acl_cnt; e++) {
     8609-               acl_entry = &((aclent_t *)acl->acl_aclp)[e];
     8610+#if ARCHIVE_ACL_SUNOS
     8611+       for(e = 0; e < aclcnt; e++) {
     8612+               acl_entry = &((aclent_t *)aclp)[e];
     8613 #else
     8614        while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
     8615                /* After the first time... */
     8616@@ -288,99 +282,33 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
     8617        }
     8618        free(marker);
     8619 }
     8620-
     8621 #endif
     8622 
     8623-
     8624 /*
     8625  * Verify ACL restore-to-disk.  This test is Platform-specific.
     8626  */
     8627 
     8628 DEFINE_TEST(test_acl_platform_posix1e_restore)
     8629 {
     8630-#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
     8631+#if !ARCHIVE_ACL_POSIX1E
     8632        skipping("POSIX.1e ACLs are not supported on this platform");
     8633-#else  /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
     8634+#else  /* ARCHIVE_ACL_POSIX1E */
     8635        struct stat st;
     8636        struct archive *a;
     8637        struct archive_entry *ae;
     8638-       int n, fd;
     8639-       char *func;
     8640-#if HAVE_SUN_ACL
     8641-       acl_t *acl, *acl2;
     8642+#if ARCHIVE_ACL_SUNOS
     8643+       void *aclp;
     8644+       int aclcnt;
     8645 #else
     8646        acl_t acl;
     8647 #endif
     8648 
     8649-       /*
     8650-        * First, do a quick manual set/read of ACL data to
     8651-        * verify that the local filesystem does support ACLs.
     8652-        * If it doesn't, we'll simply skip the remaining tests.
     8653-        */
     8654-#if HAVE_SUN_ACL
     8655-       n = acl_fromtext("user::rwx,user:1:rw-,group::rwx,group:15:r-x,other:rwx,mask:rwx", &acl);
     8656-       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
     8657-       assertEqualInt(0, n);
     8658-#else
     8659-       acl = acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx");
     8660-       failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
     8661-       assert((void *)acl != NULL);
     8662-#endif
     8663-
     8664-       /* Create a test file and try ACL on it. */
     8665-       fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
     8666-       failure("Could not create test file?!");
     8667-       if (!assert(fd >= 0)) {
     8668-               acl_free(acl);
     8669-               return;
     8670-       }
     8671-
     8672-#if HAVE_SUN_ACL
     8673-       n = facl_get(fd, 0, &acl2);
     8674-       if (n != 0) {
     8675-               close(fd);
     8676-               acl_free(acl);
     8677-       }
     8678-       if (errno == ENOSYS) {
     8679-               skipping("POSIX.1e ACLs are not supported on this filesystem");
     8680-               return;
     8681-       }
     8682-       failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
     8683-       assertEqualInt(0, n);
     8684+       assertMakeFile("pretest", 0644, "a");
     8685 
     8686-       if (acl2->acl_type != ACLENT_T) {
     8687-               acl_free(acl2);
     8688-               skipping("POSIX.1e ACLs are not supported on this filesystem");
     8689+       if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_POSIX1E) {
     8690+               skipping("POSIX.1e ACLs are not writable on this filesystem");
     8691                return;
     8692        }
     8693-       acl_free(acl2);
     8694-
     8695-       func = "facl_set()";
     8696-       n = facl_set(fd, acl);
     8697-#else
     8698-       func = "acl_set_fd()";
     8699-       n = acl_set_fd(fd, acl);
     8700-#endif
     8701-       acl_free(acl);
     8702-       if (n != 0) {
     8703-#if HAVE_SUN_ACL
     8704-               if (errno == ENOSYS)
     8705-#else
     8706-               if (errno == EOPNOTSUPP || errno == EINVAL)
     8707-#endif
     8708-               {
     8709-                       close(fd);
     8710-                       skipping("POSIX.1e ACLs are not supported on this filesystem");
     8711-                       return;
     8712-               }
     8713-       }
     8714-       failure("%s: errno = %d (%s)", func, errno, strerror(errno));
     8715-       assertEqualInt(0, n);
     8716-
     8717-#if HAVE_SUN_ACL
     8718-
     8719-#endif
     8720-       close(fd);
     8721 
     8722        /* Create a write-to-disk object. */
     8723        assert(NULL != (a = archive_write_disk_new()));
     8724@@ -404,18 +332,25 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
     8725        /* Verify the data on disk. */
     8726        assertEqualInt(0, stat("test0", &st));
     8727        assertEqualInt(st.st_mtime, 123456);
     8728-#if HAVE_SUN_ACL
     8729-       n = acl_get("test0", 0, &acl);
     8730-       failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
     8731-       assertEqualInt(0, n);
     8732+#if ARCHIVE_ACL_SUNOS
     8733+       aclp = sunacl_get(GETACL, &aclcnt, 0, "test0");
     8734+       failure("acl(): errno = %d (%s)", errno, strerror(errno));
     8735+       assert(aclp != NULL);
     8736 #else
     8737        acl = acl_get_file("test0", ACL_TYPE_ACCESS);
     8738        failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
     8739        assert(acl != (acl_t)NULL);
     8740 #endif
     8741+#if ARCHIVE_ACL_SUNOS
     8742+       compare_acls(aclp, aclcnt, acls2, sizeof(acls2)/sizeof(acls2[0]));
     8743+       free(aclp);
     8744+       aclp = NULL;
     8745+#else
     8746        compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0]));
     8747        acl_free(acl);
     8748-#endif /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
     8749+#endif
     8750+
     8751+#endif /* ARCHIVE_ACL_POSIX1E */
     8752 }
     8753 
     8754 /*
     8755@@ -423,16 +358,17 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
     8756  */
     8757 DEFINE_TEST(test_acl_platform_posix1e_read)
     8758 {
     8759-#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
     8760+#if !ARCHIVE_ACL_POSIX1E
     8761        skipping("POSIX.1e ACLs are not supported on this platform");
     8762-#else
     8763+#else /* ARCHIVE_ACL_POSIX1E */
     8764        struct archive *a;
     8765        struct archive_entry *ae;
     8766        int n, fd, flags, dflags;
     8767        char *func, *acl_text;
     8768        const char *acl1_text, *acl2_text, *acl3_text;
     8769-#if HAVE_SUN_ACL
     8770-       acl_t *acl, *acl1, *acl2, *acl3;
     8771+#if ARCHIVE_ACL_SUNOS
     8772+       void *aclp;
     8773+       int aclcnt;
     8774 #else
     8775        acl_t acl1, acl2, acl3;
     8776 #endif
     8777@@ -444,16 +380,21 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
     8778         */
     8779 
     8780        /* Create a test file f1 with acl1 */
     8781-#if HAVE_SUN_ACL
     8782+#if ARCHIVE_ACL_SUNOS
     8783        acl1_text = "user::rwx,"
     8784            "group::rwx,"
     8785            "other:rwx,"
     8786            "user:1:rw-,"
     8787            "group:15:r-x,"
     8788            "mask:rwx";
     8789-       n = acl_fromtext(acl1_text, &acl1);
     8790-       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
     8791-       assertEqualInt(0, n);
     8792+       aclent_t aclp1[] = {
     8793+           { USER_OBJ, -1, 4 | 2 | 1 },
     8794+           { USER, 1, 4 | 2 },
     8795+           { GROUP_OBJ, -1, 4 | 2 | 1 },
     8796+           { GROUP, 15, 4 | 1 },
     8797+           { CLASS_OBJ, -1, 4 | 2 | 1 },
     8798+           { OTHER_OBJ, -1, 4 | 2 | 1 }
     8799+       };
     8800 #else
     8801        acl1_text = "user::rwx\n"
     8802            "group::rwx\n"
     8803@@ -468,41 +409,36 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
     8804        fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
     8805        failure("Could not create test file?!");
     8806        if (!assert(fd >= 0)) {
     8807+#if !ARCHIVE_ACL_SUNOS
     8808                acl_free(acl1);
     8809+#endif
     8810                return;
     8811        }
     8812-#if HAVE_SUN_ACL
     8813+#if ARCHIVE_ACL_SUNOS
     8814        /* Check if Solaris filesystem supports POSIX.1e ACLs */
     8815-       n = facl_get(fd, 0, &acl);
     8816-       if (n != 0)
     8817+       aclp = sunacl_get(GETACL, &aclcnt, fd, NULL);
     8818+       if (aclp == 0)
     8819                close(fd);
     8820-       if (n != 0 && errno == ENOSYS) {
     8821-               acl_free(acl1);
     8822+       if (errno == ENOSYS || errno == ENOTSUP) {
     8823                skipping("POSIX.1e ACLs are not supported on this filesystem");
     8824                return;
     8825        }
     8826-       failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
     8827-       assertEqualInt(0, n);
     8828+       failure("facl(): errno = %d (%s)", errno, strerror(errno));
     8829+       assert(aclp != NULL);
     8830 
     8831-       if (acl->acl_type != ACLENT_T) {
     8832-               acl_free(acl);
     8833-               acl_free(acl1);
     8834-               close(fd);
     8835-               skipping("POSIX.1e ACLs are not supported on this filesystem");
     8836-               return;
     8837-       }
     8838-
     8839-       func = "facl_set()";
     8840-       n = facl_set(fd, acl1);
     8841+       func = "facl()";
     8842+       n = facl(fd, SETACL, (int)(sizeof(aclp1)/sizeof(aclp1[0])), aclp1);
     8843 #else
     8844        func = "acl_set_fd()";
     8845        n = acl_set_fd(fd, acl1);
     8846 #endif
     8847+#if !ARCHIVE_ACL_SUNOS
     8848        acl_free(acl1);
     8849+#endif
     8850 
     8851        if (n != 0) {
     8852-#if HAVE_SUN_ACL
     8853-               if (errno == ENOSYS)
     8854+#if ARCHIVE_ACL_SUNOS
     8855+               if (errno == ENOSYS || errno == ENOTSUP)
     8856 #else
     8857                if (errno == EOPNOTSUPP || errno == EINVAL)
     8858 #endif
     8859@@ -530,16 +466,21 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
     8860         * to read ACLs, resulting in reading the ACL from a like-named
     8861         * file in the wrong directory.
     8862         */
     8863-#if HAVE_SUN_ACL
     8864+#if ARCHIVE_ACL_SUNOS
     8865        acl2_text = "user::rwx,"
     8866            "group::rwx,"
     8867            "other:---,"
     8868            "user:1:r--,"
     8869            "group:15:r--,"
     8870            "mask:rwx";
     8871-       n = acl_fromtext(acl2_text, &acl2);
     8872-       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
     8873-       assertEqualInt(0, n);
     8874+       aclent_t aclp2[] = {
     8875+           { USER_OBJ, -1, 4 | 2 | 1 },
     8876+           { USER, 1, 4 },
     8877+           { GROUP_OBJ, -1, 4 | 2 | 1},
     8878+           { GROUP, 15, 4 },
     8879+           { CLASS_OBJ, -1, 4 | 2 | 1},
     8880+           { OTHER_OBJ, -1, 0 }
     8881+       };
     8882 #else
     8883        acl2_text = "user::rwx\n"
     8884            "group::rwx\n"
     8885@@ -554,17 +495,19 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
     8886        fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
     8887        failure("Could not create test file?!");
     8888        if (!assert(fd >= 0)) {
     8889+#if !ARCHIVE_ACL_SUNOS
     8890                acl_free(acl2);
     8891+#endif
     8892                return;
     8893        }
     8894-#if HAVE_SUN_ACL
     8895-       func = "facl_set()";
     8896-       n = facl_set(fd, acl2);
     8897+#if ARCHIVE_ACL_SUNOS
     8898+       func = "facl()";
     8899+       n = facl(fd, SETACL, (int)(sizeof(aclp2) / sizeof(aclp2[0])), aclp2);
     8900 #else
     8901        func = "acl_set_fd()";
     8902        n = acl_set_fd(fd, acl2);
     8903-#endif
     8904        acl_free(acl2);
     8905+#endif
     8906        if (n != 0)
     8907                close(fd);
     8908        failure("%s: errno = %d (%s)", func, errno, strerror(errno));
     8909@@ -574,7 +517,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
     8910        /* Create nested directory d2 with default ACLs */
     8911        assertMakeDir("d/d2", 0755);
     8912 
     8913-#if HAVE_SUN_ACL
     8914+#if ARCHIVE_ACL_SUNOS
     8915        acl3_text = "user::rwx,"
     8916            "group::r-x,"
     8917            "other:r-x,"
     8918@@ -587,9 +530,20 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
     8919            "default:group:15:r--,"
     8920            "default:mask:rwx,"
     8921            "default:other:r-x";
     8922-       n = acl_fromtext(acl3_text, &acl3);
     8923-       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
     8924-       assertEqualInt(0, n);
     8925+       aclent_t aclp3[] = {
     8926+           { USER_OBJ, -1, 4 | 2 | 1 },
     8927+           { USER, 2, 4 },
     8928+           { GROUP_OBJ, -1, 4 | 1 },
     8929+           { GROUP, 16, 2 },
     8930+           { CLASS_OBJ, -1, 4 | 2 | 1 },
     8931+           { OTHER_OBJ, -1, 4 | 1 },
     8932+           { USER_OBJ | ACL_DEFAULT, -1, 4 | 2 | 1 },
     8933+           { USER | ACL_DEFAULT, 1, 4 },
     8934+           { GROUP_OBJ | ACL_DEFAULT, -1, 4 | 1 },
     8935+           { GROUP | ACL_DEFAULT, 15, 4 },
     8936+           { CLASS_OBJ | ACL_DEFAULT, -1, 4 | 2 | 1},
     8937+           { OTHER_OBJ | ACL_DEFAULT, -1, 4 | 1 }
     8938+       };
     8939 #else
     8940        acl3_text = "user::rwx\n"
     8941            "user:1:r--\n"
     8942@@ -602,15 +556,14 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
     8943        assert((void *)acl3 != NULL);
     8944 #endif
     8945 
     8946-#if HAVE_SUN_ACL
     8947-       func = "acl_set()";
     8948-       n = acl_set("d/d2", acl3);
     8949+#if ARCHIVE_ACL_SUNOS
     8950+       func = "acl()";
     8951+       n = acl("d/d2", SETACL, (int)(sizeof(aclp3) / sizeof(aclp3[0])), aclp3);
     8952 #else
     8953        func = "acl_set_file()";
     8954        n = acl_set_file("d/d2", ACL_TYPE_DEFAULT, acl3);
     8955-#endif
     8956        acl_free(acl3);
     8957-
     8958+#endif
     8959        failure("%s: errno = %d (%s)", func, errno, strerror(errno));
     8960        assertEqualInt(0, n);
     8961 
     8962@@ -619,7 +572,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
     8963        assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "."));
     8964        assert(NULL != (ae = archive_entry_new()));
     8965 
     8966-#if HAVE_SUN_ACL
     8967+#if ARCHIVE_ACL_SUNOS
     8968        flags = ARCHIVE_ENTRY_ACL_TYPE_POSIX1E
     8969            | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA
     8970            | ARCHIVE_ENTRY_ACL_STYLE_SOLARIS;
     8971@@ -649,5 +602,5 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
     8972 
     8973        archive_entry_free(ae);
     8974        assertEqualInt(ARCHIVE_OK, archive_free(a));
     8975-#endif
     8976+#endif /* ARCHIVE_ACL_POSIX1E */
     8977 }
     8978--- libarchive/test/test_read_disk_directory_traversals.c.orig
     8979+++ libarchive/test/test_read_disk_directory_traversals.c
     8980@@ -1231,8 +1231,8 @@ test_restore_atime(void)
     8981         * Test4: Traversals with ARCHIVE_READDISK_RESTORE_ATIME and
     8982         * ARCHIVE_READDISK_HONOR_NODUMP
     8983         */
     8984-       assertNodump("at/f1");
     8985-       assertNodump("at/f2");
     8986+       assertSetNodump("at/f1");
     8987+       assertSetNodump("at/f2");
     8988        assertUtimes("at/f1", 886600, 0, 886600, 0);
     8989        assertUtimes("at/f2", 886611, 0, 886611, 0);
     8990        assertUtimes("at/fe", 886611, 0, 886611, 0);
     8991@@ -1450,7 +1450,7 @@ test_nodump(void)
     8992        assertMakeFile("nd/f1", 0644, "0123456789");
     8993        assertMakeFile("nd/f2", 0644, "hello world");
     8994        assertMakeFile("nd/fe", 0644, NULL);
     8995-       assertNodump("nd/f2");
     8996+       assertSetNodump("nd/f2");
     8997        assertUtimes("nd/f1", 886600, 0, 886600, 0);
     8998        assertUtimes("nd/f2", 886611, 0, 886611, 0);
     8999        assertUtimes("nd/fe", 886611, 0, 886611, 0);
     9000--- tar/bsdtar.1.orig
     9001+++ tar/bsdtar.1
     9002@@ -25,7 +25,7 @@
     9003 .\"
     9004 .\" $FreeBSD$
     9005 .\"
     9006-.Dd February 24, 2017
     9007+.Dd February 25, 2017
     9008 .Dt TAR 1
     9009 .Os
     9010 .Sh NAME
     9011@@ -450,14 +450,7 @@ This is the reverse of
     9012 .Fl p
     9013 and the default behavior if
     9014 .Nm
     9015-is run as non-root and can be overridden by also specifying
     9016-.Fl Fl acls ,
     9017-.Fl Fl fflags ,
     9018-.Fl Fl mac-metadata,
     9019-.Fl Fl same-owner ,
     9020-.Fl Fl same-permissions
     9021-and
     9022-.Fl Fl xattrs .
     9023+is run as non-root.
     9024 .It Fl Fl no-xattrs
     9025 (c, r, u, x modes only)
     9026 Do not archive or extract extended attributes. This is the reverse of
     9027@@ -647,16 +640,16 @@ This option suppresses these behaviors.
     9028 (x mode only)
     9029 Preserve file permissions.
     9030 Attempt to restore the full permissions, including owner, file modes, ACLs,
     9031-extended atributes and extended file flags, if available, for each item
     9032-extracted from the archive. This is the default, if
     9033+extended attributes and extended file flags, if available, for each item
     9034+extracted from the archive. This is te reverse of
     9035+.Fl Fl no-same-permissions
     9036+and the default if
     9037 .Nm
     9038-is being run by root and can be overridden by also specifying
     9039+is being run by root and can be partially overridden by also specifying
     9040 .Fl Fl no-acls ,
     9041 .Fl Fl no-fflags ,
     9042-.Fl Fl no-mac-metadata,
     9043-.Fl Fl no-same-owner ,
     9044-.Fl Fl no-same-permissions
     9045-and
     9046+.Fl Fl no-mac-metadata
     9047+or
     9048 .Fl Fl no-xattrs .
     9049 .It Fl Fl passphrase Ar passphrase
     9050 The
     9051--- tar/bsdtar.c.orig
     9052+++ tar/bsdtar.c
     9053@@ -118,11 +118,11 @@ need_report(void)
     9054 }
     9055 #endif
     9056 
     9057-static void             long_help(void);
     9058+static void             long_help(void) __LA_DEAD;
     9059 static void             only_mode(struct bsdtar *, const char *opt,
     9060                             const char *valid);
     9061 static void             set_mode(struct bsdtar *, char opt);
     9062-static void             version(void);
     9063+static void             version(void) __LA_DEAD;
     9064 
     9065 /* A basic set of security flags to request from libarchive. */
     9066 #define        SECURITY                                        \
     9067--- tar/bsdtar.h.orig
     9068+++ tar/bsdtar.h
     9069@@ -189,7 +189,7 @@ void        do_chdir(struct bsdtar *);
     9070 int    edit_pathname(struct bsdtar *, struct archive_entry *);
     9071 int    need_report(void);
     9072 int    pathcmp(const char *a, const char *b);
     9073-void   safe_fprintf(FILE *, const char *fmt, ...);
     9074+void   safe_fprintf(FILE *, const char *fmt, ...) __LA_PRINTF(2, 3);
     9075 void   set_chdir(struct bsdtar *, const char *newdir);
     9076 const char *tar_i64toa(int64_t);
     9077 void   tar_mode_c(struct bsdtar *bsdtar);
     9078@@ -197,8 +197,8 @@ void        tar_mode_r(struct bsdtar *bsdtar);
     9079 void   tar_mode_t(struct bsdtar *bsdtar);
     9080 void   tar_mode_u(struct bsdtar *bsdtar);
     9081 void   tar_mode_x(struct bsdtar *bsdtar);
     9082-void   usage(void);
     9083-int    yes(const char *fmt, ...);
     9084+void   usage(void) __LA_DEAD;
     9085+int    yes(const char *fmt, ...) __LA_PRINTF(1, 2);
     9086 
     9087 #if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
     9088 void   add_substitution(struct bsdtar *, const char *);
     9089--- tar/test/CMakeLists.txt.orig
     9090+++ tar/test/CMakeLists.txt
     9091@@ -34,9 +34,11 @@ IF(ENABLE_TAR AND ENABLE_TEST)
     9092     test_option_U_upper.c
     9093     test_option_X_upper.c
     9094     test_option_a.c
     9095+    test_option_acls.c
     9096     test_option_b.c
     9097     test_option_b64encode.c
     9098     test_option_exclude.c
     9099+    test_option_fflags.c
     9100     test_option_gid_gname.c
     9101     test_option_grzip.c
     9102     test_option_j.c
     9103@@ -71,6 +73,16 @@ IF(ENABLE_TAR AND ENABLE_TEST)
     9104   # Register target
     9105   #
     9106   ADD_EXECUTABLE(bsdtar_test ${bsdtar_test_SOURCES})
     9107+  IF(ENABLE_ACL)
     9108+    SET(TEST_ACL_LIBS "")
     9109+    IF(HAVE_LIBACL)
     9110+      LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY})
     9111+    ENDIF(HAVE_LIBACL)
     9112+    IF(HAVE_LIBRICHACL)
     9113+      LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY})
     9114+    ENDIF(HAVE_LIBRICHACL)
     9115+    TARGET_LINK_LIBRARIES(bsdtar_test ${TEST_ACL_LIBS})
     9116+  ENDIF(ENABLE_ACL)
     9117   SET_PROPERTY(TARGET bsdtar_test PROPERTY COMPILE_DEFINITIONS LIST_H)
     9118 
     9119   #
     9120--- /dev/null
     9121+++ tar/test/test_option_acls.c
     9122@@ -0,0 +1,469 @@
     9123+/*-
     9124+ * Copyright (c) 2017 Martin Matuska
     9125+ * All rights reserved.
     9126+ *
     9127+ * Redistribution and use in source and binary forms, with or without
     9128+ * modification, are permitted provided that the following conditions
     9129+ * are met:
     9130+ * 1. Redistributions of source code must retain the above copyright
     9131+ *    notice, this list of conditions and the following disclaimer.
     9132+ * 2. Redistributions in binary form must reproduce the above copyright
     9133+ *    notice, this list of conditions and the following disclaimer in the
     9134+ *    documentation and/or other materials provided with the distribution.
     9135+ *
     9136+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     9137+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     9138+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     9139+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     9140+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     9141+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     9142+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     9143+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     9144+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     9145+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     9146+ */
     9147+#include "test.h"
     9148+__FBSDID("$FreeBSD$");
     9149+
     9150+#if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
     9151+static const acl_perm_t acl_perms[] = {
     9152+#if HAVE_DARWIN_ACL
     9153+    ACL_READ_DATA,
     9154+    ACL_LIST_DIRECTORY,
     9155+    ACL_WRITE_DATA,
     9156+    ACL_ADD_FILE,
     9157+    ACL_EXECUTE,
     9158+    ACL_SEARCH,
     9159+    ACL_DELETE,
     9160+    ACL_APPEND_DATA,
     9161+    ACL_ADD_SUBDIRECTORY,
     9162+    ACL_DELETE_CHILD,
     9163+    ACL_READ_ATTRIBUTES,
     9164+    ACL_WRITE_ATTRIBUTES,
     9165+    ACL_READ_EXTATTRIBUTES,
     9166+    ACL_WRITE_EXTATTRIBUTES,
     9167+    ACL_READ_SECURITY,
     9168+    ACL_WRITE_SECURITY,
     9169+    ACL_CHANGE_OWNER,
     9170+    ACL_SYNCHRONIZE
     9171+#else /* !HAVE_DARWIN_ACL */
     9172+    ACL_EXECUTE,
     9173+    ACL_WRITE,
     9174+    ACL_READ,
     9175+#if HAVE_FREEBSD_NFS4_ACL
     9176+    ACL_READ_DATA,
     9177+    ACL_LIST_DIRECTORY,
     9178+    ACL_WRITE_DATA,
     9179+    ACL_ADD_FILE,
     9180+    ACL_APPEND_DATA,
     9181+    ACL_ADD_SUBDIRECTORY,
     9182+    ACL_READ_NAMED_ATTRS,
     9183+    ACL_WRITE_NAMED_ATTRS,
     9184+    ACL_DELETE_CHILD,
     9185+    ACL_READ_ATTRIBUTES,
     9186+    ACL_WRITE_ATTRIBUTES,
     9187+    ACL_DELETE,
     9188+    ACL_READ_ACL,
     9189+    ACL_WRITE_ACL,
     9190+    ACL_WRITE_OWNER,
     9191+    ACL_SYNCHRONIZE
     9192+#endif /* HAVE_FREEBSD_NFS4_ACL */
     9193+#endif /* !HAVE_DARWIN_ACL */
     9194+};
     9195+#if HAVE_DARWIN_ACL || HAVE_FREEBSD_NFS4_ACL
     9196+static const acl_flag_t acl_flags[] = {
     9197+#if HAVE_DARWIN_ACL
     9198+    ACL_ENTRY_INHERITED,
     9199+    ACL_ENTRY_FILE_INHERIT,
     9200+    ACL_ENTRY_DIRECTORY_INHERIT,
     9201+    ACL_ENTRY_LIMIT_INHERIT,
     9202+    ACL_ENTRY_ONLY_INHERIT
     9203+#else  /* HAVE_FREEBSD_NFS4_ACL */
     9204+    ACL_ENTRY_FILE_INHERIT,
     9205+    ACL_ENTRY_DIRECTORY_INHERIT,
     9206+    ACL_ENTRY_NO_PROPAGATE_INHERIT,
     9207+    ACL_ENTRY_INHERIT_ONLY,
     9208+    ACL_ENTRY_SUCCESSFUL_ACCESS,
     9209+    ACL_ENTRY_FAILED_ACCESS,
     9210+    ACL_ENTRY_INHERITED
     9211+#endif /* HAVE_FREEBSD_NFS4_ACL */
     9212+};
     9213+#endif /* HAVE_DARWIN_ACL || HAVE_FREEBSD_NFS4_ACL */
     9214+
     9215+/*
     9216+ * Compare two ACL entries on FreeBSD or on Mac OS X
     9217+ */
     9218+static int
     9219+compare_acl_entry(acl_entry_t ae_a, acl_entry_t ae_b, int is_nfs4)
     9220+{
     9221+       acl_tag_t tag_a, tag_b;
     9222+       acl_permset_t permset_a, permset_b;
     9223+       int perm_a, perm_b, perm_start, perm_end;
     9224+       void *qual_a, *qual_b;
     9225+#if HAVE_FREEBSD_NFS4_ACL
     9226+       acl_entry_type_t type_a, type_b;
     9227+#endif
     9228+#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
     9229+       acl_flagset_t flagset_a, flagset_b;
     9230+       int flag_a, flag_b;
     9231+#endif
     9232+       int i, r;
     9233+
     9234+
     9235+       /* Compare ACL tag */
     9236+       r = acl_get_tag_type(ae_a, &tag_a);
     9237+       failure("acl_get_tag_type() error: %s", strerror(errno));
     9238+       if (assertEqualInt(r, 0) == 0)
     9239+               return (-1);
     9240+       r = acl_get_tag_type(ae_b, &tag_b);
     9241+       failure("acl_get_tag_type() error: %s", strerror(errno));
     9242+       if (assertEqualInt(r, 0) == 0)
     9243+               return (-1);
     9244+       if (tag_a != tag_b)
     9245+               return (0);
     9246+
     9247+       /* Compare ACL qualifier */
     9248+#if HAVE_DARWIN_ACL
     9249+       if (tag_a == ACL_EXTENDED_ALLOW || tag_b == ACL_EXTENDED_DENY)
     9250+#else
     9251+       if (tag_a == ACL_USER || tag_a == ACL_GROUP)
     9252+#endif
     9253+       {
     9254+               qual_a = acl_get_qualifier(ae_a);
     9255+               failure("acl_get_qualifier() error: %s", strerror(errno));
     9256+               if (assert(qual_a != NULL) == 0)
     9257+                       return (-1);
     9258+               qual_b = acl_get_qualifier(ae_b);
     9259+               failure("acl_get_qualifier() error: %s", strerror(errno));
     9260+               if (assert(qual_b != NULL) == 0) {
     9261+                       acl_free(qual_a);
     9262+                       return (-1);
     9263+               }
     9264+#if HAVE_DARWIN_ACL
     9265+               if (memcmp(((guid_t *)qual_a)->g_guid,
     9266+                   ((guid_t *)qual_b)->g_guid, KAUTH_GUID_SIZE) != 0)
     9267+#else
     9268+               if ((tag_a == ACL_USER &&
     9269+                   (*(uid_t *)qual_a != *(uid_t *)qual_b)) ||
     9270+                   (tag_a == ACL_GROUP &&
     9271+                   (*(gid_t *)qual_a != *(gid_t *)qual_b)))
     9272+#endif
     9273+               {
     9274+                       acl_free(qual_a);
     9275+                       acl_free(qual_b);
     9276+                       return (0);
     9277+               }
     9278+               acl_free(qual_a);
     9279+               acl_free(qual_b);
     9280+       }
     9281+
     9282+#if HAVE_FREEBSD_NFS4_ACL
     9283+       if (is_nfs4) {
     9284+               /* Compare NFS4 ACL type */
     9285+               r = acl_get_entry_type_np(ae_a, &type_a);
     9286+               failure("acl_get_entry_type_np() error: %s", strerror(errno));
     9287+               if (assertEqualInt(r, 0) == 0)
     9288+                       return (-1);
     9289+               r = acl_get_entry_type_np(ae_b, &type_b);
     9290+               failure("acl_get_entry_type_np() error: %s", strerror(errno));
     9291+               if (assertEqualInt(r, 0) == 0)
     9292+                       return (-1);
     9293+               if (type_a != type_b)
     9294+                       return (0);
     9295+       }
     9296+#endif
     9297+
     9298+       /* Compare ACL perms */
     9299+       r = acl_get_permset(ae_a, &permset_a);
     9300+       failure("acl_get_permset() error: %s", strerror(errno));
     9301+       if (assertEqualInt(r, 0) == 0)
     9302+               return (-1);
     9303+       r = acl_get_permset(ae_b, &permset_b);
     9304+       failure("acl_get_permset() error: %s", strerror(errno));
     9305+       if (assertEqualInt(r, 0) == 0)
     9306+               return (-1);
     9307+
     9308+       perm_start = 0;
     9309+       perm_end = (int)(sizeof(acl_perms) / sizeof(acl_perms[0]));
     9310+#if HAVE_FREEBSD_NFS4_ACL
     9311+       if (is_nfs4)
     9312+               perm_start = 3;
     9313+       else
     9314+               perm_end = 3;
     9315+#endif
     9316+       /* Cycle through all perms and compare their value */
     9317+       for (i = perm_start; i < perm_end; i++) {
     9318+#if HAVE_LIBACL
     9319+               perm_a = acl_get_perm(permset_a, acl_perms[i]);
     9320+               perm_b = acl_get_perm(permset_b, acl_perms[i]);
     9321+#else
     9322+               perm_a = acl_get_perm_np(permset_a, acl_perms[i]);
     9323+               perm_b = acl_get_perm_np(permset_b, acl_perms[i]);
     9324+#endif
     9325+               if (perm_a == -1 || perm_b == -1)
     9326+                       return (-1);
     9327+               if (perm_a != perm_b)
     9328+                       return (0);
     9329+       }
     9330+
     9331+#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
     9332+       if (is_nfs4) {
     9333+               r = acl_get_flagset_np(ae_a, &flagset_a);
     9334+               failure("acl_get_flagset_np() error: %s", strerror(errno));
     9335+               if (assertEqualInt(r, 0) == 0)
     9336+                       return (-1);
     9337+               r = acl_get_flagset_np(ae_b, &flagset_b);
     9338+               failure("acl_get_flagset_np() error: %s", strerror(errno));
     9339+               if (assertEqualInt(r, 0) == 0)
     9340+                       return (-1);
     9341+               /* Cycle through all flags and compare their status */
     9342+               for (i = 0; i < (int)(sizeof(acl_flags) / sizeof(acl_flags[0]));
     9343+                   i++) {
     9344+                       flag_a = acl_get_flag_np(flagset_a, acl_flags[i]);
     9345+                       flag_b = acl_get_flag_np(flagset_b, acl_flags[i]);
     9346+                       if (flag_a == -1 || flag_b == -1)
     9347+                               return (-1);
     9348+                       if (flag_a != flag_b)
     9349+                               return (0);
     9350+               }
     9351+       }
     9352+#else  /* HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL*/
     9353+       (void)is_nfs4;  /* UNUSED */
     9354+#endif
     9355+       return (1);
     9356+}
     9357+#endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
     9358+
     9359+#if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL
     9360+/*
     9361+ * Clear default ACLs or inheritance flags
     9362+ */
     9363+static void
     9364+clear_inheritance_flags(const char *path, int type)
     9365+{
     9366+       switch (type) {
     9367+       case ARCHIVE_TEST_ACL_TYPE_POSIX1E:
     9368+#if HAVE_POSIX_ACL
     9369+               acl_delete_def_file(path);
     9370+#else
     9371+               /* Solaris */
     9372+               setTestAcl(path);
     9373+#endif
     9374+               break;
     9375+       case ARCHIVE_TEST_ACL_TYPE_NFS4:
     9376+#if HAVE_NFS4_ACL
     9377+               setTestAcl(path);
     9378+#endif
     9379+               break;
     9380+       default:
     9381+               (void)path;     /* UNUSED */
     9382+               break;
     9383+       }
     9384+}
     9385+
     9386+static int
     9387+compare_acls(const char *path_a, const char *path_b)
     9388+{
     9389+       int ret = 1;
     9390+       int is_nfs4 = 0;
     9391+#if HAVE_SUN_ACL
     9392+       void *acl_a, *acl_b;
     9393+       int aclcnt_a, aclcnt_b;
     9394+        aclent_t *aclent_a, *aclent_b;
     9395+        ace_t *ace_a, *ace_b;
     9396+       int e;
     9397+#else
     9398+       acl_t acl_a, acl_b;
     9399+       acl_entry_t aclent_a, aclent_b;
     9400+       int a, b, r;
     9401+#endif
     9402+
     9403+       acl_a = NULL;
     9404+       acl_b = NULL;
     9405+#if HAVE_SUN_ACL
     9406+       acl_a = sunacl_get(GETACL, &aclcnt_a, 0, path_a);
     9407+       if (acl_a == NULL) {
     9408+#if HAVE_SUN_NFS4_ACL
     9409+               is_nfs4 = 1;
     9410+               acl_a = sunacl_get(ACE_GETACL, &aclcnt_a, 0, path_a);
     9411+#endif
     9412+               failure("acl_get() error: %s", strerror(errno));
     9413+               if (assert(acl_a != NULL) == 0)
     9414+                       return (-1);
     9415+#if HAVE_SUN_NFS4_ACL
     9416+               acl_b = sunacl_get(ACE_GETACL, &aclcnt_b, 0, path_b);
     9417+#endif
     9418+       } else
     9419+               acl_b = sunacl_get(GETACL, &aclcnt_b, 0, path_b);
     9420+       if (acl_b == NULL && (errno == ENOSYS || errno == ENOTSUP)) {
     9421+               free(acl_a);
     9422+               return (0);
     9423+       }
     9424+       failure("acl_get() error: %s", strerror(errno));
     9425+       if (assert(acl_b != NULL) == 0) {
     9426+               free(acl_a);
     9427+               return (-1);
     9428+       }
     9429+
     9430+       if (aclcnt_a != aclcnt_b) {
     9431+               ret = 0;
     9432+               goto exit_free;
     9433+       }
     9434+
     9435+       for (e = 0; e < aclcnt_a; e++) {
     9436+               if (!is_nfs4) {
     9437+                       aclent_a = &((aclent_t *)acl_a)[e];
     9438+                       aclent_b = &((aclent_t *)acl_b)[e];
     9439+                       if (aclent_a->a_type != aclent_b->a_type ||
     9440+                           aclent_a->a_id != aclent_b->a_id ||
     9441+                           aclent_a->a_perm != aclent_b->a_perm) {
     9442+                               ret = 0;
     9443+                               goto exit_free;
     9444+                       }
     9445+               }
     9446+#if HAVE_SUN_NFS4_ACL
     9447+               else {
     9448+                       ace_a = &((ace_t *)acl_a)[e];
     9449+                       ace_b = &((ace_t *)acl_b)[e];
     9450+                       if (ace_a->a_who != ace_b->a_who ||
     9451+                           ace_a->a_access_mask != ace_b->a_access_mask ||
     9452+                           ace_a->a_flags != ace_b->a_flags ||
     9453+                           ace_a->a_type != ace_b->a_type) {
     9454+                               ret = 0;
     9455+                               goto exit_free;
     9456+                       }
     9457+               }
     9458+#endif
     9459+       }
     9460+#else  /* !HAVE_SUN_ACL */
     9461+#if HAVE_DARWIN_ACL
     9462+       is_nfs4 = 1;
     9463+       acl_a = acl_get_file(path_a, ACL_TYPE_EXTENDED);
     9464+#elif HAVE_FREEBSD_NFS4_ACL
     9465+       acl_a = acl_get_file(path_a, ACL_TYPE_NFS4);
     9466+       if (acl_a != NULL)
     9467+               is_nfs4 = 1;
     9468+#endif
     9469+#if !HAVE_DARWIN_ACL
     9470+       if (acl_a == NULL)
     9471+               acl_a = acl_get_file(path_a, ACL_TYPE_ACCESS);
     9472+#endif
     9473+       failure("acl_get_file() error: %s (%s)", path_a, strerror(errno));
     9474+       if (assert(acl_a != NULL) == 0)
     9475+               return (-1);
     9476+#if HAVE_DARWIN_ACL
     9477+       acl_b = acl_get_file(path_b, ACL_TYPE_EXTENDED);
     9478+#elif HAVE_FREEBSD_NFS4_ACL
     9479+       acl_b = acl_get_file(path_b, ACL_TYPE_NFS4);
     9480+#endif
     9481+#if !HAVE_DARWIN_ACL
     9482+       if (acl_b == NULL) {
     9483+#if HAVE_FREEBSD_NFS4_ACL
     9484+               if (is_nfs4) {
     9485+                       acl_free(acl_a);
     9486+                       return (0);
     9487+               }
     9488+#endif
     9489+               acl_b = acl_get_file(path_b, ACL_TYPE_ACCESS);
     9490+       }
     9491+       failure("acl_get_file() error: %s (%s)", path_b, strerror(errno));
     9492+       if (assert(acl_b != NULL) == 0) {
     9493+               acl_free(acl_a);
     9494+               return (-1);
     9495+       }
     9496+#endif
     9497+       a = acl_get_entry(acl_a, ACL_FIRST_ENTRY, &aclent_a);
     9498+       if (a == -1) {
     9499+               ret = 0;
     9500+               goto exit_free;
     9501+       }
     9502+       b = acl_get_entry(acl_b, ACL_FIRST_ENTRY, &aclent_b);
     9503+       if (b == -1) {
     9504+               ret = 0;
     9505+               goto exit_free;
     9506+       }
     9507+#if HAVE_DARWIN_ACL
     9508+       while (a == 0 && b == 0)
     9509+#else  /* FreeBSD, Linux */
     9510+       while (a == 1 && b == 1)
     9511+#endif
     9512+       {
     9513+               r = compare_acl_entry(aclent_a, aclent_b, is_nfs4);
     9514+               if (r != 1) {
     9515+                       ret = r;
     9516+                       goto exit_free;
     9517+               }
     9518+               a = acl_get_entry(acl_a, ACL_NEXT_ENTRY, &aclent_a);
     9519+               b = acl_get_entry(acl_b, ACL_NEXT_ENTRY, &aclent_b);
     9520+       }
     9521+       /* Entry count must match */
     9522+       if (a != b)
     9523+               ret = 0;
     9524+#endif /* !HAVE_SUN_ACL */
     9525+exit_free:
     9526+#if HAVE_SUN_ACL
     9527+       free(acl_a);
     9528+       free(acl_b);
     9529+#else
     9530+       acl_free(acl_a);
     9531+       acl_free(acl_b);
     9532+#endif
     9533+       return (ret);
     9534+}
     9535+#endif /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
     9536+
     9537+DEFINE_TEST(test_option_acls)
     9538+{
     9539+#if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_POSIX_ACL
     9540+        skipping("ACLs are not supported on this platform");
     9541+#else   /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
     9542+       int acltype, r;
     9543+
     9544+       assertMakeFile("f", 0644, "a");
     9545+       acltype = setTestAcl("f");
     9546+       if (acltype == 0) {
     9547+               skipping("Can't write ACLs on the filesystem");
     9548+               return;
     9549+       }
     9550+
     9551+       /* Archive it with acls */
     9552+        r = systemf("%s -c --no-mac-metadata --acls -f acls.tar f >acls.out 2>acls.err", testprog);
     9553+        assertEqualInt(r, 0);
     9554+
     9555+       /* Archive it without acls */
     9556+       r = systemf("%s -c --no-mac-metadata --no-acls -f noacls.tar f >noacls.out 2>noacls.err", testprog);
     9557+       assertEqualInt(r, 0);
     9558+
     9559+       /* Extract acls with acls */
     9560+       assertMakeDir("acls_acls", 0755);
     9561+       clear_inheritance_flags("acls_acls", acltype);
     9562+       r = systemf("%s -x -C acls_acls --no-same-permissions --acls -f acls.tar >acls_acls.out 2>acls_acls.err", testprog);
     9563+       assertEqualInt(r, 0);
     9564+       r = compare_acls("f", "acls_acls/f");
     9565+       assertEqualInt(r, 1);
     9566+
     9567+       /* Extractl acls without acls */
     9568+       assertMakeDir("acls_noacls", 0755);
     9569+       clear_inheritance_flags("acls_noacls", acltype);
     9570+       r = systemf("%s -x -C acls_noacls -p --no-acls -f acls.tar >acls_noacls.out 2>acls_noacls.err", testprog);
     9571+       assertEqualInt(r, 0);
     9572+       r = compare_acls("f", "acls_noacls/f");
     9573+       assertEqualInt(r, 0);
     9574+
     9575+       /* Extract noacls with acls flag */
     9576+       assertMakeDir("noacls_acls", 0755);
     9577+       clear_inheritance_flags("noacls_acls", acltype);
     9578+       r = systemf("%s -x -C noacls_acls --no-same-permissions --acls -f noacls.tar >noacls_acls.out 2>noacls_acls.err", testprog);
     9579+       assertEqualInt(r, 0);
     9580+       r = compare_acls("f", "noacls_acls/f");
     9581+       assertEqualInt(r, 0);
     9582+
     9583+       /* Extract noacls with noacls */
     9584+       assertMakeDir("noacls_noacls", 0755);
     9585+       clear_inheritance_flags("noacls_noacls", acltype);
     9586+       r = systemf("%s -x -C noacls_noacls -p --no-acls -f noacls.tar >noacls_noacls.out 2>noacls_noacls.err", testprog);
     9587+       assertEqualInt(r, 0);
     9588+       r = compare_acls("f", "noacls_noacls/f");
     9589+       assertEqualInt(r, 0);
     9590+#endif /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
     9591+}
     9592--- /dev/null
     9593+++ tar/test/test_option_fflags.c
     9594@@ -0,0 +1,106 @@
     9595+/*-
     9596+ * Copyright (c) 2017 Martin Matuska
     9597+ * All rights reserved.
     9598+ *
     9599+ * Redistribution and use in source and binary forms, with or without
     9600+ * modification, are permitted provided that the following conditions
     9601+ * are met:
     9602+ * 1. Redistributions of source code must retain the above copyright
     9603+ *    notice, this list of conditions and the following disclaimer.
     9604+ * 2. Redistributions in binary form must reproduce the above copyright
     9605+ *    notice, this list of conditions and the following disclaimer in the
     9606+ *    documentation and/or other materials provided with the distribution.
     9607+ *
     9608+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     9609+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     9610+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     9611+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     9612+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     9613+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     9614+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     9615+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     9616+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     9617+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     9618+ */
     9619+#include "test.h"
     9620+__FBSDID("$FreeBSD$");
     9621+
     9622+static void
     9623+clear_fflags(const char *pathname)
     9624+{
     9625+#if defined(HAVE_STRUCT_STAT_ST_FLAGS)
     9626+       chflags(pathname, 0);
     9627+#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
     9628+      (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
     9629+       int fd;
     9630+
     9631+       fd = open(pathname, O_RDONLY | O_NONBLOCK);
     9632+       if (fd < 0)
     9633+               return;
     9634+       ioctl(fd,
     9635+#ifdef FS_IOC_GETFLAGS
     9636+           FS_IOC_GETFLAGS,
     9637+#else
     9638+           EXT2_IOC_GETFLAGS,
     9639+#endif
     9640+           0);
     9641+#else
     9642+       (void)pathname; /* UNUSED */
     9643+#endif
     9644+       return;
     9645+}
     9646+
     9647+DEFINE_TEST(test_option_fflags)
     9648+{
     9649+       int r;
     9650+
     9651+       if (!canNodump()) {
     9652+               skipping("Can't test nodump flag on this filesystem");
     9653+               return;
     9654+       }
     9655+
     9656+       /* Create a file. */
     9657+       assertMakeFile("f", 0644, "a");
     9658+
     9659+       /* Set nodump flag on the file */
     9660+       assertSetNodump("f");
     9661+
     9662+       /* FreeBSD ZFS workaround: ZFS sets uarch on all touched files and dirs */
     9663+       chmod("f", 0644);
     9664+
     9665+       /* Archive it with fflags */
     9666+       r = systemf("%s -c --fflags -f fflags.tar f >fflags.out 2>fflags.err", testprog);
     9667+       assertEqualInt(r, 0);
     9668+
     9669+       /* Archive it without fflags */
     9670+       r = systemf("%s -c --no-fflags -f nofflags.tar f >nofflags.out 2>nofflags.err", testprog);
     9671+       assertEqualInt(r, 0);
     9672+
     9673+       /* Extract fflags with fflags */
     9674+       assertMakeDir("fflags_fflags", 0755);
     9675+       clear_fflags("fflags_fflags");
     9676+       r = systemf("%s -x -C fflags_fflags --no-same-permissions --fflags -f fflags.tar >fflags_fflags.out 2>fflags_fflags.err", testprog);
     9677+       assertEqualInt(r, 0);
     9678+       assertEqualFflags("f", "fflags_fflags/f");
     9679+
     9680+       /* Extract fflags without fflags */
     9681+       assertMakeDir("fflags_nofflags", 0755);
     9682+       clear_fflags("fflags_nofflags");
     9683+       r = systemf("%s -x -C fflags_nofflags -p --no-fflags -f fflags.tar >fflags_nofflags.out 2>fflags_nofflags.err", testprog);
     9684+       assertEqualInt(r, 0);
     9685+       assertUnequalFflags("f", "fflags_nofflags/f");
     9686+
     9687+       /* Extract nofflags with fflags */
     9688+       assertMakeDir("nofflags_fflags", 0755);
     9689+       clear_fflags("nofflags_fflags");
     9690+       r = systemf("%s -x -C nofflags_fflags --no-same-permissions --fflags -f nofflags.tar >nofflags_fflags.out 2>nofflags_fflags.err", testprog);
     9691+       assertEqualInt(r, 0);   
     9692+       assertUnequalFflags("f", "nofflags_fflags/f");
     9693+
     9694+       /* Extract nofflags with nofflags */
     9695+       assertMakeDir("nofflags_nofflags", 0755);
     9696+       clear_fflags("nofflags_nofflags");
     9697+       r = systemf("%s -x -C nofflags_nofflags -p --no-fflags -f nofflags.tar >nofflags_nofflags.out 2>nofflags_nofflags.err", testprog);
     9698+       assertEqualInt(r, 0);
     9699+       assertUnequalFflags("f", "nofflags_nofflags/f");
     9700+}
     9701--- tar/test/test_option_nodump.c.orig
     9702+++ tar/test/test_option_nodump.c
     9703@@ -36,7 +36,7 @@ DEFINE_TEST(test_option_nodump)
     9704        assertMakeFile("file1", 0644, "file1");
     9705        assertMakeFile("file2", 0644, "file2");
     9706        assertMakeFile("file3", 0644, "file3");
     9707-       assertNodump("file2");
     9708+       assertSetNodump("file2");
     9709 
     9710        /* Test 1: Without --nodump */
     9711        assertEqualInt(0, systemf("%s -cf test1.tar file1 file2 file3",
     9712--- test_utils/test_common.h.orig
     9713+++ test_utils/test_common.h
     9714@@ -73,6 +73,12 @@
     9715 #include <unistd.h>
     9716 #endif
     9717 #include <wchar.h>
     9718+#ifdef HAVE_ACL_LIBACL_H
     9719+#include <acl/libacl.h>
     9720+#endif
     9721+#ifdef HAVE_SYS_ACL_H
     9722+#include <sys/acl.h>
     9723+#endif
     9724 #ifdef HAVE_WINDOWS_H
     9725 #include <windows.h>
     9726 #endif
     9727@@ -121,31 +127,10 @@
     9728 #define        O_BINARY 0
     9729 #endif
     9730 
     9731-/*
     9732- * If this platform has <sys/acl.h>, acl_create(), acl_init(),
     9733- * acl_set_file(), and ACL_USER, we assume it has the rest of the
     9734- * POSIX.1e draft functions used in archive_read_extract.c.
     9735- */
     9736-#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
     9737-#if HAVE_ACL_USER
     9738-#define        HAVE_POSIX_ACL  1
     9739-#elif HAVE_ACL_TYPE_EXTENDED
     9740-#define        HAVE_DARWIN_ACL 1
     9741-#endif
     9742-#endif
     9743-
     9744-/*
     9745- * If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
     9746- * facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
     9747- */
     9748-#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
     9749-#define        HAVE_SUN_ACL    1
     9750-#endif
     9751+#include "archive_platform_acl.h"
     9752+#define        ARCHIVE_TEST_ACL_TYPE_POSIX1E   1
     9753+#define        ARCHIVE_TEST_ACL_TYPE_NFS4      2
     9754 
     9755-/* Define if platform supports NFSv4 ACLs */
     9756-#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
     9757-#define        HAVE_NFS4_ACL   1
     9758-#endif
     9759 
     9760 /*
     9761  * Redefine DEFINE_TEST for use in defining the test functions.
     9762@@ -158,6 +143,9 @@
     9763 /* chdir() and error if it fails */
     9764 #define assertChdir(path)  \
     9765   assertion_chdir(__FILE__, __LINE__, path)
     9766+/* Assert two files have the same file flags */
     9767+#define assertEqualFflags(patha, pathb)        \
     9768+  assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 0)
     9769 /* Assert two integers are the same.  Reports value of each one if not. */
     9770 #define assertEqualInt(v1,v2) \
     9771   assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
     9772@@ -239,10 +227,13 @@
     9773   assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
     9774 #define assertMakeSymlink(newfile, linkto)     \
     9775   assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
     9776-#define assertNodump(path)      \
     9777-  assertion_nodump(__FILE__, __LINE__, path)
     9778+#define assertSetNodump(path)  \
     9779+  assertion_set_nodump(__FILE__, __LINE__, path)
     9780 #define assertUmask(mask)      \
     9781   assertion_umask(__FILE__, __LINE__, mask)
     9782+/* Assert that two files have unequal file flags */
     9783+#define assertUnequalFflags(patha, pathb)      \
     9784+  assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 1)
     9785 #define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec)   \
     9786   assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
     9787 #ifndef PROGRAM
     9788@@ -265,6 +256,8 @@
     9789 void failure(const char *fmt, ...);
     9790 int assertion_assert(const char *, int, int, const char *, void *);
     9791 int assertion_chdir(const char *, int, const char *);
     9792+int assertion_compare_fflags(const char *, int, const char *, const char *,
     9793+    int);
     9794 int assertion_empty_file(const char *, int, const char *);
     9795 int assertion_equal_file(const char *, int, const char *, const char *);
     9796 int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
     9797@@ -295,8 +288,8 @@ int assertion_make_dir(const char *, int, const char *, int);
     9798 int assertion_make_file(const char *, int, const char *, int, int, const void *);
     9799 int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
     9800 int assertion_make_symlink(const char *, int, const char *newpath, const char *);
     9801-int assertion_nodump(const char *, int, const char *);
     9802 int assertion_non_empty_file(const char *, int, const char *);
     9803+int assertion_set_nodump(const char *, int, const char *);
     9804 int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
     9805 int assertion_umask(const char *, int, int);
     9806 int assertion_utimes(const char *, int, const char *, long, long, long, long );
     9807@@ -347,9 +340,17 @@ int canXz(void);
     9808 /* Return true if this filesystem can handle nodump flags. */
     9809 int canNodump(void);
     9810 
     9811+/* Set test ACLs */
     9812+int setTestAcl(const char *path);
     9813+
     9814 /* Return true if the file has large i-node number(>0xffffffff). */
     9815 int is_LargeInode(const char *);
     9816 
     9817+#if ARCHIVE_ACL_SUNOS
     9818+/* Fetch ACLs on Solaris using acl() or facl() */
     9819+void *sunacl_get(int cmd, int *aclcnt, int fd, const char *path);
     9820+#endif
     9821+
     9822 /* Suck file into string allocated via malloc(). Call free() when done. */
     9823 /* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
     9824 char *slurpfile(size_t *, const char *fmt, ...);
     9825--- test_utils/test_main.c.orig
     9826+++ test_utils/test_main.c
     9827@@ -56,6 +56,24 @@
     9828 #include <stdarg.h>
     9829 #include <time.h>
     9830 
     9831+#ifdef HAVE_SIGNAL_H
     9832+#endif
     9833+#ifdef HAVE_ACL_LIBACL_H
     9834+#include <acl/libacl.h>
     9835+#endif
     9836+#ifdef HAVE_SYS_TYPES_H
     9837+#include <sys/types.h>
     9838+#endif
     9839+#ifdef HAVE_SYS_ACL_H
     9840+#include <sys/acl.h>
     9841+#endif
     9842+#ifdef HAVE_SYS_RICHACL_H
     9843+#include <sys/richacl.h>
     9844+#endif
     9845+#if HAVE_MEMBERSHIP_H
     9846+#include <membership.h>
     9847+#endif
     9848+
     9849 /*
     9850  *
     9851  * Windows support routines
     9852@@ -1883,9 +1901,103 @@ assertion_utimes(const char *file, int line,
     9853 #endif /* defined(_WIN32) && !defined(__CYGWIN__) */
     9854 }
     9855 
     9856+/* Compare file flags */
     9857+int
     9858+assertion_compare_fflags(const char *file, int line, const char *patha,
     9859+    const char *pathb, int nomatch)
     9860+{
     9861+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
     9862+       struct stat sa, sb;
     9863+
     9864+       assertion_count(file, line);
     9865+
     9866+       if (stat(patha, &sa) < 0)
     9867+               return (0);
     9868+       if (stat(pathb, &sb) < 0)
     9869+               return (0);
     9870+       if (!nomatch && sa.st_flags != sb.st_flags) {
     9871+               failure_start(file, line, "File flags should be identical: "
     9872+                   "%s=%#010x %s=%#010x", patha, sa.st_flags, pathb,
     9873+                   sb.st_flags);
     9874+               failure_finish(NULL);
     9875+               return (0);
     9876+       }
     9877+       if (nomatch && sa.st_flags == sb.st_flags) {
     9878+               failure_start(file, line, "File flags should be different: "
     9879+                   "%s=%#010x %s=%#010x", patha, sa.st_flags, pathb,
     9880+                   sb.st_flags);
     9881+               failure_finish(NULL);
     9882+               return (0);
     9883+       }
     9884+#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) && \
     9885+       defined(FS_NODUMP_FL)) || \
     9886+      (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
     9887+         && defined(EXT2_NODUMP_FL))
     9888+       int fd, r, flagsa, flagsb;
     9889+
     9890+       assertion_count(file, line);
     9891+       fd = open(patha, O_RDONLY | O_NONBLOCK);
     9892+       if (fd < 0) {
     9893+               failure_start(file, line, "Can't open %s\n", patha);
     9894+               failure_finish(NULL);
     9895+               return (0);
     9896+       }
     9897+       r = ioctl(fd,
     9898+#ifdef FS_IOC_GETFLAGS
     9899+           FS_IOC_GETFLAGS,
     9900+#else
     9901+           EXT2_IOC_GETFLAGS,
     9902+#endif
     9903+           &flagsa);
     9904+       close(fd);
     9905+       if (r < 0) {
     9906+               failure_start(file, line, "Can't get flags %s\n", patha);
     9907+               failure_finish(NULL);
     9908+               return (0);
     9909+       }
     9910+       fd = open(pathb, O_RDONLY | O_NONBLOCK);
     9911+       if (fd < 0) {
     9912+               failure_start(file, line, "Can't open %s\n", pathb);
     9913+               failure_finish(NULL);
     9914+               return (0);
     9915+       }
     9916+       r = ioctl(fd,
     9917+#ifdef FS_IOC_GETFLAGS
     9918+           FS_IOC_GETFLAGS,
     9919+#else
     9920+           EXT2_IOC_GETFLAGS,
     9921+#endif
     9922+           &flagsb);
     9923+       close(fd);
     9924+       if (r < 0) {
     9925+               failure_start(file, line, "Can't get flags %s\n", pathb);
     9926+               failure_finish(NULL);
     9927+               return (0);
     9928+       }
     9929+       if (!nomatch && flagsa != flagsb) {
     9930+               failure_start(file, line, "File flags should be identical: "
     9931+                   "%s=%#010x %s=%#010x", patha, flagsa, pathb, flagsb);
     9932+               failure_finish(NULL);
     9933+               return (0);
     9934+       }
     9935+       if (nomatch && flagsa == flagsb) {
     9936+               failure_start(file, line, "File flags should be different: "
     9937+                   "%s=%#010x %s=%#010x", patha, flagsa, pathb, flagsb);
     9938+               failure_finish(NULL);
     9939+               return (0);
     9940+       }
     9941+#else
     9942+       (void)patha; /* UNUSED */
     9943+       (void)pathb; /* UNUSED */
     9944+       (void)nomatch; /* UNUSED */
     9945+       assertion_count(file, line);
     9946+#endif
     9947+       return (1);
     9948+}
     9949+
     9950 /* Set nodump, report failures. */
     9951 int
     9952-assertion_nodump(const char *file, int line, const char *pathname)
     9953+assertion_set_nodump(const char *file, int line, const char *pathname)
     9954 {
     9955 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
     9956        int r;
     9957@@ -2256,11 +2368,10 @@ canXz(void)
     9958 /*
     9959  * Can this filesystem handle nodump flags.
     9960  */
     9961-#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
     9962-
     9963 int
     9964 canNodump(void)
     9965 {
     9966+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
     9967        const char *path = "cannodumptest";
     9968        struct stat sb;
     9969 
     9970@@ -2271,16 +2382,10 @@ canNodump(void)
     9971                return (0);
     9972        if (sb.st_flags & UF_NODUMP)
     9973                return (1);
     9974-       return (0);
     9975-}
     9976-
     9977 #elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) \
     9978         && defined(FS_NODUMP_FL)) || \
     9979       (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \
     9980         && defined(EXT2_NODUMP_FL))
     9981-int
     9982-canNodump(void)
     9983-{
     9984        const char *path = "cannodumptest";
     9985        int fd, r, flags;
     9986 
     9987@@ -2331,18 +2436,250 @@ canNodump(void)
     9988        if (flags & EXT2_NODUMP_FL)
     9989 #endif
     9990                return (1);
     9991+#endif
     9992        return (0);
     9993 }
     9994 
     9995-#else
     9996-
     9997-int
     9998-canNodump()
     9999+#if ARCHIVE_ACL_SUNOS
     10000+/* Fetch ACLs on Solaris using acl() or facl() */
     10001+void *
     10002+sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
     10003 {
     10004-       return (0);
     10005+       int cnt, cntcmd;
     10006+       size_t size;
     10007+       void *aclp;
     10008+
     10009+       if (cmd == GETACL) {
     10010+               cntcmd = GETACLCNT;
     10011+               size = sizeof(aclent_t);
     10012+       }
     10013+#if ARCHIVE_ACL_SUNOS_NFS4
     10014+       else if (cmd == ACE_GETACL) {
     10015+               cntcmd = ACE_GETACLCNT;
     10016+               size = sizeof(ace_t);
     10017+       }
     10018+#endif
     10019+       else {
     10020+               errno = EINVAL;
     10021+               *aclcnt = -1;
     10022+               return (NULL);
     10023+       }
     10024+
     10025+       aclp = NULL;
     10026+       cnt = -2;
     10027+       while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
     10028+               if (path != NULL)
     10029+                       cnt = acl(path, cntcmd, 0, NULL);
     10030+               else
     10031+                       cnt = facl(fd, cntcmd, 0, NULL);
     10032+
     10033+               if (cnt > 0) {
     10034+                       if (aclp == NULL)
     10035+                               aclp = malloc(cnt * size);
     10036+                       else
     10037+                               aclp = realloc(NULL, cnt * size);
     10038+                       if (aclp != NULL) {
     10039+                               if (path != NULL)
     10040+                                       cnt = acl(path, cmd, cnt, aclp);
     10041+                               else
     10042+                                       cnt = facl(fd, cmd, cnt, aclp);
     10043+                       }
     10044+               } else {
     10045+                       if (aclp != NULL) {
     10046+                               free(aclp);
     10047+                               aclp = NULL;
     10048+                       }
     10049+                       break;
     10050+               }
     10051+       }
     10052+
     10053+       *aclcnt = cnt;
     10054+       return (aclp);
     10055 }
     10056+#endif /* ARCHIVE_ACL_SUNOS */
     10057+
     10058+/*
     10059+ * Set test ACLs on a path
     10060+ * Return values:
     10061+ * 0: error setting ACLs
     10062+ * ARCHIVE_TEST_ACL_TYPE_POSIX1E: POSIX.1E ACLs have been set
     10063+ * ARCHIVE_TEST_ACL_TYPE_NFS4: NFSv4 or extended ACLs have been set
     10064+ */
     10065+int
     10066+setTestAcl(const char *path)
     10067+{
     10068+#if ARCHIVE_ACL_SUPPORT
     10069+       int r = 1;
     10070+#if ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_DARWIN
     10071+       acl_t acl;
     10072+#endif
     10073+#if ARCHIVE_ACL_LIBRICHACL
     10074+       struct richacl *richacl;
     10075+#endif
     10076+#if ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_FREEBSD
     10077+       const char *acltext_posix1e = "user:1:rw-,"
     10078+           "group:15:r-x,"
     10079+           "user::rwx,"
     10080+           "group::rwx,"
     10081+           "other::r-x,"
     10082+           "mask::rwx";
     10083+#elif ARCHIVE_ACL_SUNOS /* Solaris POSIX.1e */
     10084+       aclent_t aclp_posix1e[] = {
     10085+           { USER_OBJ, -1, 4 | 2 | 1 },
     10086+           { USER, 1, 4 | 2 },
     10087+           { GROUP_OBJ, -1, 4 | 2 | 1 },
     10088+           { GROUP, 15, 4 | 1 },
     10089+           { CLASS_OBJ, -1, 4 | 2 | 1 },
     10090+           { OTHER_OBJ, -1, 4 | 2 | 1 }
     10091+       };
     10092+#endif
     10093+#if ARCHIVE_ACL_FREEBSD /* FreeBSD NFS4 */
     10094+       const char *acltext_nfs4 = "user:1:rwpaRcs::allow:1,"
     10095+           "group:15:rxaRcs::allow:15,"
     10096+           "owner@:rwpxaARWcCos::allow,"
     10097+           "group@:rwpxaRcs::allow,"
     10098+           "everyone@:rxaRcs::allow";
     10099+#elif ARCHIVE_ACL_LIBRICHACL
     10100+       const char *acltext_nfs4 = "owner:rwpxaARWcCoS::mask,"
     10101+           "group:rwpxaRcS::mask,"
     10102+           "other:rxaRcS::mask,"
     10103+           "user:1:rwpaRcS::allow,"
     10104+           "group:15:rxaRcS::allow,"
     10105+           "owner@:rwpxaARWcCoS::allow,"
     10106+           "group@:rwpxaRcS::allow,"
     10107+           "everyone@:rxaRcS::allow";
     10108+#elif ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFS4 */
     10109+       ace_t aclp_nfs4[] = {
     10110+           { 1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA |
     10111+             ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS | ACE_READ_ACL |
     10112+             ACE_SYNCHRONIZE, 0, ACE_ACCESS_ALLOWED_ACE_TYPE },
     10113+           { 15, ACE_READ_DATA | ACE_EXECUTE | ACE_READ_ATTRIBUTES |
     10114+             ACE_READ_NAMED_ATTRS | ACE_READ_ACL | ACE_SYNCHRONIZE,
     10115+             ACE_IDENTIFIER_GROUP, ACE_ACCESS_ALLOWED_ACE_TYPE },
     10116+           { -1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA |
     10117+             ACE_EXECUTE | ACE_READ_ATTRIBUTES | ACE_WRITE_ATTRIBUTES |
     10118+             ACE_READ_NAMED_ATTRS | ACE_WRITE_NAMED_ATTRS |
     10119+             ACE_READ_ACL | ACE_WRITE_ACL | ACE_WRITE_OWNER | ACE_SYNCHRONIZE,
     10120+             ACE_OWNER, ACE_ACCESS_ALLOWED_ACE_TYPE },
     10121+           { -1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA |
     10122+             ACE_EXECUTE | ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
     10123+             ACE_READ_ACL | ACE_SYNCHRONIZE, ACE_GROUP | ACE_IDENTIFIER_GROUP,
     10124+             ACE_ACCESS_ALLOWED_ACE_TYPE },
     10125+           { -1, ACE_READ_DATA | ACE_EXECUTE | ACE_READ_ATTRIBUTES |
     10126+             ACE_READ_NAMED_ATTRS | ACE_READ_ACL | ACE_SYNCHRONIZE,
     10127+             ACE_EVERYONE, ACE_ACCESS_ALLOWED_ACE_TYPE }
     10128+       };
     10129+#elif ARCHIVE_ACL_DARWIN /* Mac OS X */
     10130+       acl_entry_t aclent;
     10131+       acl_permset_t permset;
     10132+       const uid_t uid = 1;
     10133+       uuid_t uuid;
     10134+       int i;
     10135+       const acl_perm_t acl_perms[] = {
     10136+               ACL_READ_DATA,
     10137+               ACL_WRITE_DATA,
     10138+               ACL_APPEND_DATA,
     10139+               ACL_EXECUTE,
     10140+               ACL_READ_ATTRIBUTES,
     10141+               ACL_READ_EXTATTRIBUTES,
     10142+               ACL_READ_SECURITY,
     10143+#if HAVE_DECL_ACL_SYNCHRONIZE
     10144+               ACL_SYNCHRONIZE
     10145+#endif
     10146+       };
     10147+#endif /* ARCHIVE_ACL_DARWIN */
     10148 
     10149+#if ARCHIVE_ACL_FREEBSD
     10150+       acl = acl_from_text(acltext_nfs4);
     10151+       failure("acl_from_text() error: %s", strerror(errno));
     10152+       if (assert(acl != NULL) == 0)
     10153+               return (0);
     10154+#elif ARCHIVE_ACL_LIBRICHACL
     10155+       richacl = richacl_from_text(acltext_nfs4, NULL, NULL);
     10156+       failure("richacl_from_text() error: %s", strerror(errno));
     10157+       if (assert(richacl != NULL) == 0)
     10158+               return (0);
     10159+#elif ARCHIVE_ACL_DARWIN
     10160+       acl = acl_init(1);
     10161+       failure("acl_init() error: %s", strerror(errno));
     10162+       if (assert(acl != NULL) == 0)
     10163+               return (0);
     10164+       r = acl_create_entry(&acl, &aclent);
     10165+       failure("acl_create_entry() error: %s", strerror(errno));
     10166+       if (assertEqualInt(r, 0) == 0)
     10167+               goto testacl_free;
     10168+       r = acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW);
     10169+       failure("acl_set_tag_type() error: %s", strerror(errno));
     10170+       if (assertEqualInt(r, 0) == 0)
     10171+               goto testacl_free;
     10172+       r = acl_get_permset(aclent, &permset);
     10173+       failure("acl_get_permset() error: %s", strerror(errno));
     10174+       if (assertEqualInt(r, 0) == 0)
     10175+               goto testacl_free;
     10176+       for (i = 0; i < (int)(sizeof(acl_perms) / sizeof(acl_perms[0])); i++) {
     10177+               r = acl_add_perm(permset, acl_perms[i]);
     10178+               failure("acl_add_perm() error: %s", strerror(errno));
     10179+               if (assertEqualInt(r, 0) == 0)
     10180+                       goto testacl_free;
     10181+       }
     10182+       r = acl_set_permset(aclent, permset);
     10183+       failure("acl_set_permset() error: %s", strerror(errno));
     10184+       if (assertEqualInt(r, 0) == 0)
     10185+               goto testacl_free;
     10186+       r = mbr_uid_to_uuid(uid, uuid);
     10187+       failure("mbr_uid_to_uuid() error: %s", strerror(errno));
     10188+       if (assertEqualInt(r, 0) == 0)
     10189+               goto testacl_free;
     10190+       r = acl_set_qualifier(aclent, uuid);
     10191+       failure("acl_set_qualifier() error: %s", strerror(errno));
     10192+       if (assertEqualInt(r, 0) == 0)
     10193+               goto testacl_free;
     10194+#endif /* ARCHIVE_ACL_DARWIN */
     10195+
     10196+#if ARCHIVE_ACL_NFS4
     10197+#if ARCHIVE_ACL_FREEBSD
     10198+       r = acl_set_file(path, ACL_TYPE_NFS4, acl);
     10199+       acl_free(acl);
     10200+#elif ARCHIVE_ACL_LIBRICHACL
     10201+       r = richacl_set_file(path, richacl);
     10202+       richacl_free(richacl);
     10203+#elif ARCHIVE_ACL_SUNOS_NFS4
     10204+       r = acl(path, ACE_SETACL,
     10205+           (int)(sizeof(aclp_nfs4)/sizeof(aclp_nfs4[0])), aclp_nfs4);
     10206+#elif ARCHIVE_ACL_DARWIN
     10207+       r = acl_set_file(path, ACL_TYPE_EXTENDED, acl);
     10208+       acl_free(acl);
     10209+#endif
     10210+       if (r == 0)
     10211+               return (ARCHIVE_TEST_ACL_TYPE_NFS4);
     10212+#endif /* ARCHIVE_ACL_NFS4 */
     10213+
     10214+#if ARCHIVE_ACL_POSIX1E
     10215+#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL
     10216+       acl = acl_from_text(acltext_posix1e);
     10217+       failure("acl_from_text() error: %s", strerror(errno));
     10218+       if (assert(acl != NULL) == 0)
     10219+               return (0);
     10220+
     10221+       r = acl_set_file(path, ACL_TYPE_ACCESS, acl);
     10222+       acl_free(acl);
     10223+#elif ARCHIVE_ACL_SUNOS
     10224+       r = acl(path, SETACL,
     10225+           (int)(sizeof(aclp_posix1e)/sizeof(aclp_posix1e[0])), aclp_posix1e);
     10226 #endif
     10227+       if (r == 0)
     10228+               return (ARCHIVE_TEST_ACL_TYPE_POSIX1E);
     10229+       else
     10230+               return (0);
     10231+#endif /* ARCHIVE_ACL_POSIX1E */
     10232+#if ARCHIVE_ACL_DARWIN
     10233+testacl_free:
     10234+       acl_free(acl);
     10235+#endif
     10236+#endif /* ARCHIVE_ACL_SUPPORT */
     10237+       (void)path;     /* UNUSED */
     10238+       return (0);
     10239+}
     10240 
     10241 /*
     10242  * Sleep as needed; useful for verifying disk timestamp changes by