1
0
Эх сурвалжийг харах

Merge topic 'update-libarchive'

5a58efaa libarchive: Avoid using name 'u_long'
e2b02823 Update libarchive configuration within CMake
80883321 libarchive: Do not require includers to have windows.h
dfb0458e libarchive: Convert literal LL suffix to ARCHIVE_LITERAL_LL
b0a9807f libarchive: Update archive_util.c to use CMake zlib and bzip2 headers
debe4dec libarchive: Drop options not present in reduced version
66b0c4fa libarchive: Do not generate a pkg-config file
8092e759 libarchive: Update README-CMake.txt for new snapshot
2f197863 Merge branch 'libarchive-upstream' into update-libarchive
23e4666c libarchive: Disable more whitespace checks in third-party code
64713ae3 libarchive 3.1.2-218-g00f4bd83 (reduced)
Brad King 11 жил өмнө
parent
commit
11a6b3d59a
57 өөрчлөгдсөн 2775 нэмэгдсэн , 1263 устгасан
  1. 6 0
      CMakeLists.txt
  2. 1 2
      Utilities/cmlibarchive/.gitattributes
  3. 34 23
      Utilities/cmlibarchive/CMakeLists.txt
  4. 4 4
      Utilities/cmlibarchive/README-CMake.txt
  5. 31 0
      Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake
  6. 68 0
      Utilities/cmlibarchive/build/cmake/LibarchiveCodeCoverage.cmake
  7. 5 0
      Utilities/cmlibarchive/build/cmake/config.h.in
  8. 3 0
      Utilities/cmlibarchive/libarchive/CMakeLists.txt
  9. 72 0
      Utilities/cmlibarchive/libarchive/archive.h
  10. 41 0
      Utilities/cmlibarchive/libarchive/archive_entry.c
  11. 6 5
      Utilities/cmlibarchive/libarchive/archive_entry.h
  12. 5 0
      Utilities/cmlibarchive/libarchive/archive_entry_private.h
  13. 1 1
      Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
  14. 5 4
      Utilities/cmlibarchive/libarchive/archive_getdate.c
  15. 1 1
      Utilities/cmlibarchive/libarchive/archive_match.c
  16. 329 0
      Utilities/cmlibarchive/libarchive/archive_pack_dev.c
  17. 49 0
      Utilities/cmlibarchive/libarchive/archive_pack_dev.h
  18. 5 2
      Utilities/cmlibarchive/libarchive/archive_platform.h
  19. 61 5
      Utilities/cmlibarchive/libarchive/archive_read.c
  20. 18 4
      Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
  21. 1 1
      Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
  22. 4 4
      Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
  23. 13 9
      Utilities/cmlibarchive/libarchive/archive_read_private.h
  24. 22 0
      Utilities/cmlibarchive/libarchive/archive_read_set_options.3
  25. 16 16
      Utilities/cmlibarchive/libarchive/archive_read_set_options.c
  26. 5 4
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
  27. 1 1
      Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
  28. 138 24
      Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
  29. 3 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
  30. 3 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
  31. 3 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
  32. 2 0
      Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
  33. 3 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
  34. 3 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
  35. 258 158
      Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
  36. 70 9
      Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
  37. 3 1
      Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
  38. 71 33
      Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
  39. 11 5
      Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
  40. 526 584
      Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
  41. 109 0
      Utilities/cmlibarchive/libarchive/archive_util.c
  42. 10 6
      Utilities/cmlibarchive/libarchive/archive_virtual.c
  43. 5 5
      Utilities/cmlibarchive/libarchive/archive_windows.c
  44. 7 5
      Utilities/cmlibarchive/libarchive/archive_windows.h
  45. 13 3
      Utilities/cmlibarchive/libarchive/archive_write.c
  46. 6 1
      Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c
  47. 15 1
      Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c
  48. 1 1
      Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
  49. 4 1
      Utilities/cmlibarchive/libarchive/archive_write_format.3
  50. 2 1
      Utilities/cmlibarchive/libarchive/archive_write_set_format.c
  51. 1 0
      Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
  52. 31 6
      Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
  53. 125 0
      Utilities/cmlibarchive/libarchive/archive_write_set_format_raw.c
  54. 1 0
      Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
  55. 466 326
      Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
  56. 1 1
      Utilities/cmlibarchive/libarchive/filter_fork_windows.c
  57. 77 1
      Utilities/cmlibarchive/libarchive/mtree.5

+ 6 - 0
CMakeLists.txt

@@ -321,6 +321,12 @@ macro (CMAKE_BUILD_UTILITIES)
     add_definitions(-DLIBARCHIVE_STATIC)
     add_definitions(-DLIBARCHIVE_STATIC)
     set(ENABLE_NETTLE OFF CACHE INTERNAL "Enable use of Nettle")
     set(ENABLE_NETTLE OFF CACHE INTERNAL "Enable use of Nettle")
     set(ENABLE_OPENSSL ${CMAKE_USE_OPENSSL} CACHE INTERNAL "Enable use of OpenSSL")
     set(ENABLE_OPENSSL ${CMAKE_USE_OPENSSL} CACHE INTERNAL "Enable use of OpenSSL")
+    set(ENABLE_LZMA OFF CACHE INTERNAL "Enable the use of the system found LZMA library if found")
+    set(ENABLE_ZLIB ON CACHE INTERNAL "Enable the use of the system found ZLIB library if found")
+    set(ENABLE_BZip2 ON CACHE INTERNAL "Enable the use of the system found BZip2 library if found")
+    set(ENABLE_EXPAT OFF CACHE INTERNAL "Enable the use of the system found EXPAT library if found")
+    set(ENABLE_PCREPOSIX OFF CACHE INTERNAL "Enable the use of the system found PCREPOSIX library if found")
+    set(ENABLE_LibGCC OFF CACHE INTERNAL "Enable the use of the system found LibGCC library if found")
     set(ENABLE_XATTR OFF CACHE INTERNAL "Enable extended attribute support")
     set(ENABLE_XATTR OFF CACHE INTERNAL "Enable extended attribute support")
     set(ENABLE_ACL OFF CACHE INTERNAL "Enable ACL support")
     set(ENABLE_ACL OFF CACHE INTERNAL "Enable ACL support")
     set(ENABLE_ICONV OFF CACHE INTERNAL "Enable iconv support")
     set(ENABLE_ICONV OFF CACHE INTERNAL "Enable iconv support")

+ 1 - 2
Utilities/cmlibarchive/.gitattributes

@@ -1,2 +1 @@
-*.h              whitespace=indent-with-non-tab,-blank-at-eol
-*.c              whitespace=indent-with-non-tab,-blank-at-eol
+* whitespace=-indent-with-non-tab,-tab-in-indent,-blank-at-eol,-blank-at-eof

+ 34 - 23
Utilities/cmlibarchive/CMakeLists.txt

@@ -32,7 +32,7 @@ SET(LIBARCHIVE_VERSION_NUMBER  "${_version_number}")
 SET(LIBARCHIVE_VERSION_STRING  "${VERSION}")
 SET(LIBARCHIVE_VERSION_STRING  "${VERSION}")
 
 
 # INTERFACE_VERSION increments with every release
 # INTERFACE_VERSION increments with every release
-# libarchive 2.7 == interface version 9 = 2 + 7 
+# libarchive 2.7 == interface version 9 = 2 + 7
 # libarchive 2.8 == interface version 10 = 2 + 8
 # libarchive 2.8 == interface version 10 = 2 + 8
 # libarchive 2.9 == interface version 11 = 2 + 9
 # libarchive 2.9 == interface version 11 = 2 + 9
 # libarchive 3.0 == interface version 12
 # libarchive 3.0 == interface version 12
@@ -69,6 +69,13 @@ include(CTest)
 
 
 OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
 OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
 OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
 OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
+OPTION(ENABLE_LZMA "Enable the use of the system found LZMA library if found" ON)
+OPTION(ENABLE_ZLIB "Enable the use of the system found ZLIB library if found" ON)
+OPTION(ENABLE_BZip2 "Enable the use of the system found BZip2 library if found" ON)
+OPTION(ENABLE_EXPAT "Enable the use of the system found EXPAT library if found" ON)
+OPTION(ENABLE_PCREPOSIX "Enable the use of the system found PCREPOSIX library if found" ON)
+OPTION(ENABLE_LibGCC "Enable the use of the system found LibGCC library if found" ON)
+
 OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
 OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
 OPTION(ENABLE_ACL "Enable ACL support" ON)
 OPTION(ENABLE_ACL "Enable ACL support" ON)
 OPTION(ENABLE_ICONV "Enable iconv support" ON)
 OPTION(ENABLE_ICONV "Enable iconv support" ON)
@@ -190,7 +197,7 @@ IF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
   #--- zconf.h.orig	2005-07-21 00:40:26.000000000
   #--- zconf.h.orig	2005-07-21 00:40:26.000000000
   #+++ zconf.h	2009-01-19 11:39:10.093750000
   #+++ zconf.h	2009-01-19 11:39:10.093750000
   #@@ -286,7 +286,7 @@
   #@@ -286,7 +286,7 @@
-  # 
+  #
   # #if 1           /* HAVE_UNISTD_H -- this line is updated by ./configure */
   # #if 1           /* HAVE_UNISTD_H -- this line is updated by ./configure */
   # #  include <sys/types.h> /* for off_t */
   # #  include <sys/types.h> /* for off_t */
   #-#  include <unistd.h>    /* for SEEK_* and off_t */
   #-#  include <unistd.h>    /* for SEEK_* and off_t */
@@ -204,7 +211,11 @@ SET(ADDITIONAL_LIBS "")
 #
 #
 # Find ZLIB
 # Find ZLIB
 #
 #
-FIND_PACKAGE(ZLIB)
+IF(ENABLE_ZLIB)
+  FIND_PACKAGE(ZLIB)
+ELSE()
+  SET(ZLIB_FOUND FALSE) # Override cached value
+ENDIF()
 IF(ZLIB_FOUND)
 IF(ZLIB_FOUND)
   SET(HAVE_LIBZ 1)
   SET(HAVE_LIBZ 1)
   SET(HAVE_ZLIB_H 1)
   SET(HAVE_ZLIB_H 1)
@@ -239,7 +250,11 @@ ENDIF(ZLIB_FOUND)
 #
 #
 # Find BZip2
 # Find BZip2
 #
 #
-FIND_PACKAGE(BZip2)
+IF(ENABLE_BZip2)
+  FIND_PACKAGE(BZip2)
+ELSE()
+  SET(BZIP2_FOUND FALSE) # Override cached value
+ENDIF()
 IF(BZIP2_FOUND)
 IF(BZIP2_FOUND)
   SET(HAVE_LIBBZ2 1)
   SET(HAVE_LIBBZ2 1)
   SET(HAVE_BZLIB_H 1)
   SET(HAVE_BZLIB_H 1)
@@ -263,7 +278,13 @@ IF(0) # CMake does not need LZMA or LZO2 support in libarchive
 #
 #
 # Find LZMA
 # Find LZMA
 #
 #
-FIND_PACKAGE(LZMA)
+IF(ENABLE_LZMA)
+  FIND_PACKAGE(LZMA)
+ELSE()
+  SET(LZMA_FOUND FALSE) # Override cached value
+  SET(LZMADEC_FOUND FALSE) # Override cached value
+ENDIF()
+
 IF(LZMA_FOUND)
 IF(LZMA_FOUND)
   SET(HAVE_LIBLZMA 1)
   SET(HAVE_LIBLZMA 1)
   SET(HAVE_LZMA_H 1)
   SET(HAVE_LZMA_H 1)
@@ -283,6 +304,8 @@ ELSEIF(LZMADEC_FOUND)
   SET(HAVE_LZMADEC_H 1)
   SET(HAVE_LZMADEC_H 1)
   INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
   INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
   LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
   LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
+ELSE(LZMA_FOUND)
+# LZMA not found and will not be used.
 ENDIF(LZMA_FOUND)
 ENDIF(LZMA_FOUND)
 #
 #
 # Find LZO2
 # Find LZO2
@@ -510,16 +533,10 @@ main(int argc, char **argv)
 	FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}")
 	FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}")
 	MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}")
 	MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}")
 
 
-    IF(CMAKE_REQUIRED_LINKER_FLAGS)
-      SET(CHECK_CRYPTO_ADD_LINKER_FLAGS
-        "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
-    ELSE(CMAKE_REQUIRED_LINKER_FLAGS)
-      SET(CHECK_CRYPTO_ADD_LINKER_FLAGS)
-    ENDIF(CMAKE_REQUIRED_LINKER_FLAGS)
 	TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}
 	TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}
 	  ${CMAKE_BINARY_DIR}
 	  ${CMAKE_BINARY_DIR}
 	  ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c
 	  ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c
-	  CMAKE_FLAGS ${CHECK_CRYPTO_ADD_LINKER_FLAGS}
+	  CMAKE_FLAGS
 	   "${TRY_CRYPTO_REQUIRED_LIBS}"
 	   "${TRY_CRYPTO_REQUIRED_LIBS}"
 	   "${TRY_CRYPTO_REQUIRED_INCLUDES}"
 	   "${TRY_CRYPTO_REQUIRED_INCLUDES}"
 	  OUTPUT_VARIABLE OUTPUT)
 	  OUTPUT_VARIABLE OUTPUT)
@@ -604,16 +621,10 @@ main(int argc, char **argv)
 	FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
 	FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
 	MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
 	MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
 
 
-    IF(CMAKE_REQUIRED_LINKER_FLAGS)
-      SET(CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS
-        "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
-    ELSE(CMAKE_REQUIRED_LINKER_FLAGS)
-      SET(CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS)
-    ENDIF(CMAKE_REQUIRED_LINKER_FLAGS)
 	TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
 	TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
 	  ${CMAKE_BINARY_DIR}
 	  ${CMAKE_BINARY_DIR}
 	  ${SOURCE_FILE}
 	  ${SOURCE_FILE}
-	  CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive" ${CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS}
+	  CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive"
 	  OUTPUT_VARIABLE OUTPUT)
 	  OUTPUT_VARIABLE OUTPUT)
 
 
 	IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
 	IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
@@ -1030,13 +1041,13 @@ CHECK_TYPE_SIZE("unsigned long long" SIZE_OF_UNSIGNED_LONG_LONG)
 CHECK_TYPE_SIZE("__int64" __INT64)
 CHECK_TYPE_SIZE("__int64" __INT64)
 CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
 CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
 
 
-CHECK_TYPE_SIZE(int16_t INT16_T) 
+CHECK_TYPE_SIZE(int16_t INT16_T)
 CHECK_TYPE_SIZE(int32_t INT32_T)
 CHECK_TYPE_SIZE(int32_t INT32_T)
 CHECK_TYPE_SIZE(int64_t INT64_T)
 CHECK_TYPE_SIZE(int64_t INT64_T)
 CHECK_TYPE_SIZE(intmax_t INTMAX_T)
 CHECK_TYPE_SIZE(intmax_t INTMAX_T)
-CHECK_TYPE_SIZE(uint8_t UINT8_T) 
-CHECK_TYPE_SIZE(uint16_t UINT16_T) 
-CHECK_TYPE_SIZE(uint32_t UINT32_T) 
+CHECK_TYPE_SIZE(uint8_t UINT8_T)
+CHECK_TYPE_SIZE(uint16_t UINT16_T)
+CHECK_TYPE_SIZE(uint32_t UINT32_T)
 CHECK_TYPE_SIZE(uint64_t UINT64_T)
 CHECK_TYPE_SIZE(uint64_t UINT64_T)
 CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
 CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
 
 

+ 4 - 4
Utilities/cmlibarchive/README-CMake.txt

@@ -11,7 +11,7 @@ branch, but it is merged into our history.
 Update libarchive from upstream as follows.  Create a local branch to
 Update libarchive from upstream as follows.  Create a local branch to
 explicitly reference the upstream snapshot branch head:
 explicitly reference the upstream snapshot branch head:
 
 
- git branch libarchive-upstream 35df7c8b
+ git branch libarchive-upstream 64713ae3
 
 
 Use a temporary directory to checkout the branch:
 Use a temporary directory to checkout the branch:
 
 
@@ -24,7 +24,7 @@ Use a temporary directory to checkout the branch:
 Now place the (reduced) libarchive content in this directory.  See
 Now place the (reduced) libarchive content in this directory.  See
 instructions shown by
 instructions shown by
 
 
- git log 35df7c8b
+ git log 64713ae3
 
 
 for help extracting the content from the upstream svn repo.  Then run
 for help extracting the content from the upstream svn repo.  Then run
 the following commands to commit the new version.  Substitute the
 the following commands to commit the new version.  Substitute the
@@ -34,8 +34,8 @@ appropriate date and version number:
 
 
  GIT_AUTHOR_NAME='LibArchive Upstream' \
  GIT_AUTHOR_NAME='LibArchive Upstream' \
  GIT_AUTHOR_EMAIL='[email protected]' \
  GIT_AUTHOR_EMAIL='[email protected]' \
- GIT_AUTHOR_DATE='2013-02-09 12:17:57 -0500' \
- git commit -m 'libarchive 3.1.2 (reduced)' &&
+ GIT_AUTHOR_DATE='Mon Mar 17 20:43:07 2014 -0700' \
+ git commit -m 'libarchive 3.1.2-218-g00f4bd83 (reduced)' &&
  git commit --amend
  git commit --amend
 
 
 Edit the commit message to describe the procedure used to obtain the
 Edit the commit message to describe the procedure used to obtain the

+ 31 - 0
Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake

@@ -0,0 +1,31 @@
+# - Generate a libarchive.pc like autotools for pkg-config
+#
+
+# Set the required variables (we use the same input file as autotools)
+SET(prefix ${CMAKE_INSTALL_PREFIX})
+SET(exec_prefix \${prefix})
+SET(libdir \${exec_prefix}/lib)
+SET(includedir \${prefix}/include)
+# Now, this is not particularly pretty, nor is it terribly accurate...
+# Loop over all our additional libs
+FOREACH(mylib ${ADDITIONAL_LIBS})
+	# Extract the filename from the absolute path
+	GET_FILENAME_COMPONENT(mylib_name ${mylib} NAME_WE)
+	# Strip the lib prefix
+	STRING(REGEX REPLACE "^lib" "" mylib_name ${mylib_name})
+	# Append it to our LIBS string
+	SET(LIBS "${LIBS} -l${mylib_name}")
+ENDFOREACH()
+# libxml2 is easier, since it's already using pkg-config
+FOREACH(mylib ${PC_LIBXML_STATIC_LDFLAGS})
+	SET(LIBS "${LIBS} ${mylib}")
+ENDFOREACH()
+# FIXME: The order of the libraries doesn't take dependencies into account,
+#	 thus there's a good chance it'll make some binutils versions unhappy...
+#	 This only affects Libs.private (looked up for static builds) though.
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc.in
+		${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc
+		@ONLY)
+# And install it, of course ;).
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc
+	DESTINATION "lib/pkgconfig")

+ 68 - 0
Utilities/cmlibarchive/build/cmake/LibarchiveCodeCoverage.cmake

@@ -0,0 +1,68 @@
+#################################################################
+# Adds a build target called "coverage" for code coverage.
+#
+# This compiles the code using special GCC flags, run the tests,
+# and then generates a nice HTML output. This new "coverage" make
+# target will only be available if you build using GCC in Debug
+# mode. If any of the required programs (lcov and genhtml) were
+# not found, a FATAL_ERROR message is printed.
+#
+# If not already done, this code will set ENABLE_TEST to ON.
+#
+# To build the code coverage and open it in your browser do this:
+#
+#    mkdir debug
+#    cd debug
+#    cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON ..
+#    make -j4
+#    make coverage
+#    xdg-open coverage/index.html
+#################################################################
+
+# Find programs we need 
+FIND_PROGRAM(LCOV_EXECUTABLE lcov DOC "Full path to lcov executable")
+FIND_PROGRAM(GENHTML_EXECUTABLE genhtml DOC "Full path to genhtml executable")
+MARK_AS_ADVANCED(LCOV_EXECUTABLE GENHTML_EXECUTABLE)
+
+# Check, compiler, build types and programs are available
+IF(NOT CMAKE_COMPILER_IS_GNUCC)
+MESSAGE(FATAL_ERROR "Coverage can only be built on GCC")
+ELSEIF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
+MESSAGE(FATAL_ERROR "Coverage can only be built in Debug mode")
+ELSEIF(NOT LCOV_EXECUTABLE)
+MESSAGE(FATAL_ERROR "lcov executable not found")
+ELSEIF(NOT GENHTML_EXECUTABLE)
+MESSAGE(FATAL_ERROR "genhtml executable not found")
+ENDIF(NOT CMAKE_COMPILER_IS_GNUCC)
+
+# Enable testing if not already done
+SET(ENABLE_TEST ON)
+
+#################################################################
+# Set special compiler and linker flags for test coverage
+#################################################################
+# 0. Enable debug: -g
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
+# 1. Disable optimizations: -O0
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
+# 2. Enable all kind of warnings:
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W")
+# 3. Enable special coverage flag (HINT: --coverage is a synonym for -fprofile-arcs -ftest-coverage)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage")
+SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
+#################################################################
+
+ADD_CUSTOM_TARGET(coverage
+COMMAND ${CMAKE_COMMAND} -E echo "Beginning test coverage. Output is written to coverage.log."
+COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-1/5: Reset all execution counts to zero"
+COMMAND ${LCOV_EXECUTABLE} --directory . --zerocounters > coverage.log 2>&1
+COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-2/5: Run testrunner"
+COMMAND ${CMAKE_CTEST_COMMAND} >> coverage.log 2>&1
+COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-3/5: Collect coverage data"
+COMMAND ${LCOV_EXECUTABLE} --capture --directory . --output-file "./coverage.info" >> coverage.log 2>&1
+COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-4/5: Generate HTML from coverage data"
+COMMAND ${GENHTML_EXECUTABLE} "coverage.info" --title="libarchive-${LIBARCHIVE_VERSION_STRING}" --show-details --legend --output-directory "./coverage"  >> coverage.log 2>&1
+COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-5/5: Open test coverage HTML output in browser: xdg-open ./coverage/index.html"
+COMMENT "Runs testrunner and generates coverage output (formats: .info and .html)")
+

+ 5 - 0
Utilities/cmlibarchive/build/cmake/config.h.in

@@ -1112,8 +1112,13 @@ typedef uint64_t uintmax_t;
 #cmakedefine _LARGE_FILES ${_LARGE_FILES}
 #cmakedefine _LARGE_FILES ${_LARGE_FILES}
 
 
 /* Define for Windows to use Windows 2000+ APIs. */
 /* Define for Windows to use Windows 2000+ APIs. */
+#ifndef _WIN32_WINNT
 #cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
 #cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
+#endif // _WIN32_WINNT
+
+#ifndef WINVER
 #cmakedefine WINVER ${WINVER}
 #cmakedefine WINVER ${WINVER}
+#endif // WINVER
 
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* Define to empty if `const' does not conform to ANSI C. */
 #cmakedefine const ${const}
 #cmakedefine const ${const}

+ 3 - 0
Utilities/cmlibarchive/libarchive/CMakeLists.txt

@@ -35,6 +35,8 @@ SET(libarchive_SOURCES
   archive_match.c
   archive_match.c
   archive_options.c
   archive_options.c
   archive_options_private.h
   archive_options_private.h
+  archive_pack_dev.h
+  archive_pack_dev.c
   archive_pathmatch.c
   archive_pathmatch.c
   archive_pathmatch.h
   archive_pathmatch.h
   archive_platform.h
   archive_platform.h
@@ -125,6 +127,7 @@ SET(libarchive_SOURCES
   archive_write_set_format_iso9660.c
   archive_write_set_format_iso9660.c
   archive_write_set_format_mtree.c
   archive_write_set_format_mtree.c
   archive_write_set_format_pax.c
   archive_write_set_format_pax.c
+  archive_write_set_format_raw.c
   archive_write_set_format_shar.c
   archive_write_set_format_shar.c
   archive_write_set_format_ustar.c
   archive_write_set_format_ustar.c
   archive_write_set_format_v7tar.c
   archive_write_set_format_v7tar.c

+ 72 - 0
Utilities/cmlibarchive/libarchive/archive.h

@@ -137,6 +137,11 @@ __LA_DECL int		archive_version_number(void);
 #define	ARCHIVE_VERSION_STRING "libarchive 3.1.2"
 #define	ARCHIVE_VERSION_STRING "libarchive 3.1.2"
 __LA_DECL const char *	archive_version_string(void);
 __LA_DECL const char *	archive_version_string(void);
 
 
+/*
+ * Detailed textual name/version of the library and its dependencies.
+ */
+__LA_DECL const char *	archive_version_details(void);
+
 /* Declare our basic types. */
 /* Declare our basic types. */
 struct archive;
 struct archive;
 struct archive_entry;
 struct archive_entry;
@@ -289,6 +294,30 @@ typedef int archive_switch_callback(struct archive *, void *_client_data1,
 #define	ARCHIVE_FORMAT_RAR			0xD0000
 #define	ARCHIVE_FORMAT_RAR			0xD0000
 #define	ARCHIVE_FORMAT_7ZIP			0xE0000
 #define	ARCHIVE_FORMAT_7ZIP			0xE0000
 
 
+/*
+ * Codes returned by archive_read_format_capabilities().
+ *
+ * This list can be extended with values between 0 and 0xffff.
+ * The original purpose of this list was to let different archive
+ * format readers expose their general capabilities in terms of
+ * encryption.
+ */
+#define ARCHIVE_READ_FORMAT_CAPS_NONE (0) /* no special capabilities */
+#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA (1<<0)  /* reader can detect encrypted data */
+#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA (1<<1)  /* reader can detect encryptable metadata (pathname, mtime, etc.) */
+
+/*
+ * Codes returned by archive_read_has_encrypted_entries().
+ *
+ * In case the archive does not support encryption detection at all
+ * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned. If the reader
+ * for some other reason (e.g. not enough bytes read) cannot say if
+ * there are encrypted entries, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW
+ * is returned.
+ */
+#define ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED -2
+#define ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW -1
+
 /*-
 /*-
  * Basic outline for reading an archive:
  * Basic outline for reading an archive:
  *   1) Ask archive_read_new for an archive reader object.
  *   1) Ask archive_read_new for an archive reader object.
@@ -374,7 +403,15 @@ __LA_DECL int archive_read_support_format_rar(struct archive *);
 __LA_DECL int archive_read_support_format_raw(struct archive *);
 __LA_DECL int archive_read_support_format_raw(struct archive *);
 __LA_DECL int archive_read_support_format_tar(struct archive *);
 __LA_DECL int archive_read_support_format_tar(struct archive *);
 __LA_DECL int archive_read_support_format_xar(struct archive *);
 __LA_DECL int archive_read_support_format_xar(struct archive *);
+/* archive_read_support_format_zip() enables both streamable and seekable
+ * zip readers. */
 __LA_DECL int archive_read_support_format_zip(struct archive *);
 __LA_DECL int archive_read_support_format_zip(struct archive *);
+/* Reads Zip archives as stream from beginning to end.  Doesn't
+ * correctly handle SFX ZIP files or ZIP archives that have been modified
+ * in-place. */
+__LA_DECL int archive_read_support_format_zip_streamable(struct archive *);
+/* Reads starting from central directory; requires seekable input. */
+__LA_DECL int archive_read_support_format_zip_seekable(struct archive *);
 
 
 /* Functions to manually set the format and filters to be used. This is
 /* Functions to manually set the format and filters to be used. This is
  * useful to bypass the bidding process when the format and filters to use
  * useful to bypass the bidding process when the format and filters to use
@@ -470,6 +507,32 @@ __LA_DECL int archive_read_next_header2(struct archive *,
  */
  */
 __LA_DECL __LA_INT64_T		 archive_read_header_position(struct archive *);
 __LA_DECL __LA_INT64_T		 archive_read_header_position(struct archive *);
 
 
+/*
+ * Returns 1 if the archive contains at least one encrypted entry.
+ * If the archive format not support encryption at all
+ * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
+ * If for any other reason (e.g. not enough data read so far)
+ * we cannot say whether there are encrypted entries, then
+ * ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
+ * In general, this function will return values below zero when the
+ * reader is uncertain or totally uncapable of encryption support.
+ * When this function returns 0 you can be sure that the reader
+ * supports encryption detection but no encrypted entries have
+ * been found yet.
+ *
+ * NOTE: If the metadata/header of an archive is also encrypted, you
+ * cannot rely on the number of encrypted entries. That is why this
+ * function does not return the number of encrypted entries but#
+ * just shows that there are some.
+ */
+__LA_DECL int	archive_read_has_encrypted_entries(struct archive *);
+
+/*
+ * Returns a bitmask of capabilities that are supported by the archive format reader.
+ * If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
+ */
+__LA_DECL int		 archive_read_format_capabilities(struct archive *);
+
 /* Read data from the body of an entry.  Similar to read(2). */
 /* Read data from the body of an entry.  Similar to read(2). */
 __LA_DECL __LA_SSIZE_T		 archive_read_data(struct archive *,
 __LA_DECL __LA_SSIZE_T		 archive_read_data(struct archive *,
 				    void *, size_t);
 				    void *, size_t);
@@ -674,6 +737,7 @@ __LA_DECL int archive_write_set_format_mtree_classic(struct archive *);
 /* TODO: int archive_write_set_format_old_tar(struct archive *); */
 /* TODO: int archive_write_set_format_old_tar(struct archive *); */
 __LA_DECL int archive_write_set_format_pax(struct archive *);
 __LA_DECL int archive_write_set_format_pax(struct archive *);
 __LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
 __LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
+__LA_DECL int archive_write_set_format_raw(struct archive *);
 __LA_DECL int archive_write_set_format_shar(struct archive *);
 __LA_DECL int archive_write_set_format_shar(struct archive *);
 __LA_DECL int archive_write_set_format_shar_dump(struct archive *);
 __LA_DECL int archive_write_set_format_shar_dump(struct archive *);
 __LA_DECL int archive_write_set_format_ustar(struct archive *);
 __LA_DECL int archive_write_set_format_ustar(struct archive *);
@@ -883,6 +947,10 @@ __LA_DECL int	archive_read_disk_set_metadata_filter_callback(struct archive *,
 		    int (*_metadata_filter_func)(struct archive *, void *,
 		    int (*_metadata_filter_func)(struct archive *, void *,
 		    	struct archive_entry *), void *_client_data);
 		    	struct archive_entry *), void *_client_data);
 
 
+/* Simplified cleanup interface;
+ * This calls archive_read_free() or archive_write_free() as needed. */
+__LA_DECL int	archive_free(struct archive *);
+
 /*
 /*
  * Accessor functions to read/set various information in
  * Accessor functions to read/set various information in
  * the struct archive object:
  * the struct archive object:
@@ -1029,6 +1097,10 @@ __LA_DECL int	archive_match_include_gname(struct archive *, const char *);
 __LA_DECL int	archive_match_include_gname_w(struct archive *,
 __LA_DECL int	archive_match_include_gname_w(struct archive *,
 		    const wchar_t *);
 		    const wchar_t *);
 
 
+/* Utility functions */
+/* Convenience function to sort a NULL terminated list of strings */
+__LA_DECL int archive_utility_string_sort(char **);
+
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 41 - 0
Utilities/cmlibarchive/libarchive/archive_entry.c

@@ -201,6 +201,9 @@ archive_entry_clone(struct archive_entry *entry)
 	entry2->ae_set = entry->ae_set;
 	entry2->ae_set = entry->ae_set;
 	archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
 	archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
 
 
+	/* Copy encryption status */
+	entry2->encryption = entry->encryption;
+	
 	/* Copy ACL data over. */
 	/* Copy ACL data over. */
 	archive_acl_copy(&entry2->acl, &entry->acl);
 	archive_acl_copy(&entry2->acl, &entry->acl);
 
 
@@ -695,6 +698,24 @@ _archive_entry_uname_l(struct archive_entry *entry,
 	return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
 	return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
 }
 }
 
 
+int
+archive_entry_is_data_encrypted(struct archive_entry *entry)
+{
+	return ((entry->encryption & AE_ENCRYPTION_DATA) == AE_ENCRYPTION_DATA);
+}
+
+int
+archive_entry_is_metadata_encrypted(struct archive_entry *entry)
+{
+	return ((entry->encryption & AE_ENCRYPTION_METADATA) == AE_ENCRYPTION_METADATA);
+}
+
+int
+archive_entry_is_encrypted(struct archive_entry *entry)
+{
+	return (entry->encryption & (AE_ENCRYPTION_DATA|AE_ENCRYPTION_METADATA));
+}
+
 /*
 /*
  * Functions to set archive_entry properties.
  * Functions to set archive_entry properties.
  */
  */
@@ -1216,6 +1237,26 @@ archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
 	return (0);
 	return (0);
 }
 }
 
 
+void
+archive_entry_set_is_data_encrypted(struct archive_entry *entry, char is_encrypted)
+{
+	if (is_encrypted) {
+		entry->encryption |= AE_ENCRYPTION_DATA;
+	} else {
+		entry->encryption &= ~AE_ENCRYPTION_DATA;
+	}
+}
+
+void
+archive_entry_set_is_metadata_encrypted(struct archive_entry *entry, char is_encrypted)
+{
+	if (is_encrypted) {
+		entry->encryption |= AE_ENCRYPTION_METADATA;
+	} else {
+		entry->encryption &= ~AE_ENCRYPTION_METADATA;
+	}
+}
+
 int
 int
 _archive_entry_copy_uname_l(struct archive_entry *entry,
 _archive_entry_copy_uname_l(struct archive_entry *entry,
     const char *name, size_t len, struct archive_string_conv *sc)
     const char *name, size_t len, struct archive_string_conv *sc)

+ 6 - 5
Utilities/cmlibarchive/libarchive/archive_entry.h

@@ -43,10 +43,6 @@
 #include <stddef.h>  /* for wchar_t */
 #include <stddef.h>  /* for wchar_t */
 #include <time.h>
 #include <time.h>
 
 
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <windows.h>
-#endif
-
 /* Get a suitable 64-bit integer type. */
 /* Get a suitable 64-bit integer type. */
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
 # define	__LA_INT64_T	__int64
 # define	__LA_INT64_T	__int64
@@ -235,6 +231,9 @@ __LA_DECL const wchar_t	*archive_entry_symlink_w(struct archive_entry *);
 __LA_DECL __LA_INT64_T	 archive_entry_uid(struct archive_entry *);
 __LA_DECL __LA_INT64_T	 archive_entry_uid(struct archive_entry *);
 __LA_DECL const char	*archive_entry_uname(struct archive_entry *);
 __LA_DECL const char	*archive_entry_uname(struct archive_entry *);
 __LA_DECL const wchar_t	*archive_entry_uname_w(struct archive_entry *);
 __LA_DECL const wchar_t	*archive_entry_uname_w(struct archive_entry *);
+__LA_DECL int archive_entry_is_data_encrypted(struct archive_entry *);
+__LA_DECL int archive_entry_is_metadata_encrypted(struct archive_entry *);
+__LA_DECL int archive_entry_is_encrypted(struct archive_entry *);
 
 
 /*
 /*
  * Set fields in an archive_entry.
  * Set fields in an archive_entry.
@@ -248,7 +247,7 @@ __LA_DECL const wchar_t	*archive_entry_uname_w(struct archive_entry *);
 __LA_DECL void	archive_entry_set_atime(struct archive_entry *, time_t, long);
 __LA_DECL void	archive_entry_set_atime(struct archive_entry *, time_t, long);
 __LA_DECL void  archive_entry_unset_atime(struct archive_entry *);
 __LA_DECL void  archive_entry_unset_atime(struct archive_entry *);
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #if defined(_WIN32) && !defined(__CYGWIN__)
-__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *);
+__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, struct _BY_HANDLE_FILE_INFORMATION *);
 #endif
 #endif
 __LA_DECL void	archive_entry_set_birthtime(struct archive_entry *, time_t, long);
 __LA_DECL void	archive_entry_set_birthtime(struct archive_entry *, time_t, long);
 __LA_DECL void  archive_entry_unset_birthtime(struct archive_entry *);
 __LA_DECL void  archive_entry_unset_birthtime(struct archive_entry *);
@@ -306,6 +305,8 @@ __LA_DECL void	archive_entry_set_uname(struct archive_entry *, const char *);
 __LA_DECL void	archive_entry_copy_uname(struct archive_entry *, const char *);
 __LA_DECL void	archive_entry_copy_uname(struct archive_entry *, const char *);
 __LA_DECL void	archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
 __LA_DECL void	archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
 __LA_DECL int	archive_entry_update_uname_utf8(struct archive_entry *, const char *);
 __LA_DECL int	archive_entry_update_uname_utf8(struct archive_entry *, const char *);
+__LA_DECL void	archive_entry_set_is_data_encrypted(struct archive_entry *, char is_encrypted);
+__LA_DECL void	archive_entry_set_is_metadata_encrypted(struct archive_entry *, char is_encrypted);
 /*
 /*
  * Routines to bulk copy fields to/from a platform-native "struct
  * Routines to bulk copy fields to/from a platform-native "struct
  * stat."  Libarchive used to just store a struct stat inside of each
  * stat."  Libarchive used to just store a struct stat inside of each

+ 5 - 0
Utilities/cmlibarchive/libarchive/archive_entry_private.h

@@ -154,6 +154,11 @@ struct archive_entry {
 	/* Not used within libarchive; useful for some clients. */
 	/* Not used within libarchive; useful for some clients. */
 	struct archive_mstring ae_sourcepath;	/* Path this entry is sourced from. */
 	struct archive_mstring ae_sourcepath;	/* Path this entry is sourced from. */
 
 
+#define AE_ENCRYPTION_NONE 0
+#define AE_ENCRYPTION_DATA 1
+#define AE_ENCRYPTION_METADATA 2
+	char encryption;
+	
 	void *mac_metadata;
 	void *mac_metadata;
 	size_t mac_metadata_size;
 	size_t mac_metadata_size;
 
 

+ 1 - 1
Utilities/cmlibarchive/libarchive/archive_entry_sparse.c

@@ -58,7 +58,7 @@ archive_entry_sparse_add_entry(struct archive_entry *entry,
 	if (offset < 0 || length < 0)
 	if (offset < 0 || length < 0)
 		/* Invalid value */
 		/* Invalid value */
 		return;
 		return;
-	if (offset + length < 0 ||
+	if (offset > INT64_MAX - length ||
 	    offset + length > archive_entry_size(entry))
 	    offset + length > archive_entry_size(entry))
 		/* A value of "length" parameter is too large. */
 		/* A value of "length" parameter is too large. */
 		return;
 		return;

+ 5 - 4
Utilities/cmlibarchive/libarchive/archive_getdate.c

@@ -369,8 +369,8 @@ relunitphrase(struct gdstate *gds)
 	    && gds->tokenp[1].token == tSEC_UNIT) {
 	    && gds->tokenp[1].token == tSEC_UNIT) {
 		/* "1 day" */
 		/* "1 day" */
 		gds->HaveRel++;
 		gds->HaveRel++;
-		gds->RelSeconds += gds->tokenp[1].value * gds->tokenp[2].value;
-		gds->tokenp += 3;
+		gds->RelSeconds += gds->tokenp[0].value * gds->tokenp[1].value;
+		gds->tokenp += 2;
 		return 1;
 		return 1;
 	}
 	}
 	if (gds->tokenp[0].token == '-'
 	if (gds->tokenp[0].token == '-'
@@ -403,7 +403,7 @@ relunitphrase(struct gdstate *gds)
 		/* "now", "tomorrow" */
 		/* "now", "tomorrow" */
 		gds->HaveRel++;
 		gds->HaveRel++;
 		gds->RelSeconds += gds->tokenp[0].value;
 		gds->RelSeconds += gds->tokenp[0].value;
-		++gds->tokenp;
+		gds->tokenp += 1;
 		return 1;
 		return 1;
 	}
 	}
 	if (gds->tokenp[0].token == tMONTH_UNIT) {
 	if (gds->tokenp[0].token == tMONTH_UNIT) {
@@ -1022,10 +1022,11 @@ int
 main(int argc, char **argv)
 main(int argc, char **argv)
 {
 {
     time_t	d;
     time_t	d;
+    time_t	now = time(NULL);
 
 
     while (*++argv != NULL) {
     while (*++argv != NULL) {
 	    (void)printf("Input: %s\n", *argv);
 	    (void)printf("Input: %s\n", *argv);
-	    d = get_date(*argv);
+	    d = get_date(now, *argv);
 	    if (d == -1)
 	    if (d == -1)
 		    (void)printf("Bad format - couldn't convert.\n");
 		    (void)printf("Bad format - couldn't convert.\n");
 	    else
 	    else

+ 1 - 1
Utilities/cmlibarchive/libarchive/archive_match.c

@@ -1152,7 +1152,7 @@ set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
 {
 {
 	/* NOTE: stat() on Windows cannot handle nano seconds. */
 	/* NOTE: stat() on Windows cannot handle nano seconds. */
 	HANDLE h;
 	HANDLE h;
-	WIN32_FIND_DATA d;
+	WIN32_FIND_DATAA d;
 
 
 	if (path == NULL || *path == '\0') {
 	if (path == NULL || *path == '\0') {
 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");

+ 329 - 0
Utilities/cmlibarchive/libarchive/archive_pack_dev.c

@@ -0,0 +1,329 @@
+/*	$NetBSD: pack_dev.c,v 1.12 2013/06/14 16:28:20 tsutsui Exp $	*/
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Originally from NetBSD's mknod(8) source. */
+
+#include "archive_platform.h"
+
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+#if !defined(lint)
+__RCSID("$NetBSD$");
+#endif /* not lint */
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive_pack_dev.h"
+
+static	pack_t	pack_netbsd;
+static	pack_t	pack_freebsd;
+static	pack_t	pack_8_8;
+static	pack_t	pack_12_20;
+static	pack_t	pack_14_18;
+static	pack_t	pack_8_24;
+static	pack_t	pack_bsdos;
+static	int	compare_format(const void *, const void *);
+
+static const char iMajorError[] = "invalid major number";
+static const char iMinorError[] = "invalid minor number";
+static const char tooManyFields[] = "too many fields for format";
+
+/* This is blatantly stolen from libarchive/archive_entry.c,
+ * in an attempt to get this to play nice on MinGW... */
+#if !defined(HAVE_MAJOR) && !defined(major)
+/* Replacement for major/minor/makedev. */
+#define major(x) ((int)(0x00ff & ((x) >> 8)))
+#define minor(x) ((int)(0xffff00ff & (x)))
+#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min)))
+#endif
+
+/* Play games to come up with a suitable makedev() definition. */
+#ifdef __QNXNTO__
+/* QNX.  <sigh> */
+#include <sys/netmgr.h>
+#define apd_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min))
+#elif defined makedev
+/* There's a "makedev" macro. */
+#define apd_makedev(maj, min) makedev((maj), (min))
+#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__))
+/* Windows. <sigh> */
+#define apd_makedev(maj, min) mkdev((maj), (min))
+#else
+/* There's a "makedev" function. */
+#define apd_makedev(maj, min) makedev((maj), (min))
+#endif
+
+/* exported */
+dev_t
+pack_native(int n, unsigned long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = apd_makedev(numbers[0], numbers[1]);
+		if ((unsigned long)major(dev) != numbers[0])
+			*error = iMajorError;
+		else if ((unsigned long)minor(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+static dev_t
+pack_netbsd(int n, unsigned long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_netbsd(numbers[0], numbers[1]);
+		if ((unsigned long)major_netbsd(dev) != numbers[0])
+			*error = iMajorError;
+		else if ((unsigned long)minor_netbsd(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_freebsd(x)	((int32_t)(((x) & 0x0000ff00) >> 8))
+#define	minor_freebsd(x)	((int32_t)(((x) & 0xffff00ff) >> 0))
+#define	makedev_freebsd(x,y)	((dev_t)((((x) << 8) & 0x0000ff00) | \
+					 (((y) << 0) & 0xffff00ff)))
+
+static dev_t
+pack_freebsd(int n, unsigned long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_freebsd(numbers[0], numbers[1]);
+		if ((unsigned long)major_freebsd(dev) != numbers[0])
+			*error = iMajorError;
+		if ((unsigned long)minor_freebsd(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_8_8(x)		((int32_t)(((x) & 0x0000ff00) >> 8))
+#define	minor_8_8(x)		((int32_t)(((x) & 0x000000ff) >> 0))
+#define	makedev_8_8(x,y)	((dev_t)((((x) << 8) & 0x0000ff00) | \
+					 (((y) << 0) & 0x000000ff)))
+
+static dev_t
+pack_8_8(int n, unsigned long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_8_8(numbers[0], numbers[1]);
+		if ((unsigned long)major_8_8(dev) != numbers[0])
+			*error = iMajorError;
+		if ((unsigned long)minor_8_8(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_12_20(x)		((int32_t)(((x) & 0xfff00000) >> 20))
+#define	minor_12_20(x)		((int32_t)(((x) & 0x000fffff) >>  0))
+#define	makedev_12_20(x,y)	((dev_t)((((x) << 20) & 0xfff00000) | \
+					 (((y) <<  0) & 0x000fffff)))
+
+static dev_t
+pack_12_20(int n, unsigned long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_12_20(numbers[0], numbers[1]);
+		if ((unsigned long)major_12_20(dev) != numbers[0])
+			*error = iMajorError;
+		if ((unsigned long)minor_12_20(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_14_18(x)		((int32_t)(((x) & 0xfffc0000) >> 18))
+#define	minor_14_18(x)		((int32_t)(((x) & 0x0003ffff) >>  0))
+#define	makedev_14_18(x,y)	((dev_t)((((x) << 18) & 0xfffc0000) | \
+					 (((y) <<  0) & 0x0003ffff)))
+
+static dev_t
+pack_14_18(int n, unsigned long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_14_18(numbers[0], numbers[1]);
+		if ((unsigned long)major_14_18(dev) != numbers[0])
+			*error = iMajorError;
+		if ((unsigned long)minor_14_18(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_8_24(x)		((int32_t)(((x) & 0xff000000) >> 24))
+#define	minor_8_24(x)		((int32_t)(((x) & 0x00ffffff) >>  0))
+#define	makedev_8_24(x,y)	((dev_t)((((x) << 24) & 0xff000000) | \
+					 (((y) <<  0) & 0x00ffffff)))
+
+static dev_t
+pack_8_24(int n, unsigned long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_8_24(numbers[0], numbers[1]);
+		if ((unsigned long)major_8_24(dev) != numbers[0])
+			*error = iMajorError;
+		if ((unsigned long)minor_8_24(dev) != numbers[1])
+			*error = iMinorError;
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+#define	major_12_12_8(x)	((int32_t)(((x) & 0xfff00000) >> 20))
+#define	unit_12_12_8(x)		((int32_t)(((x) & 0x000fff00) >>  8))
+#define	subunit_12_12_8(x)	((int32_t)(((x) & 0x000000ff) >>  0))
+#define	makedev_12_12_8(x,y,z)	((dev_t)((((x) << 20) & 0xfff00000) | \
+					 (((y) <<  8) & 0x000fff00) | \
+					 (((z) <<  0) & 0x000000ff)))
+
+static dev_t
+pack_bsdos(int n, unsigned long numbers[], const char **error)
+{
+	dev_t dev = 0;
+
+	if (n == 2) {
+		dev = makedev_12_20(numbers[0], numbers[1]);
+		if ((unsigned long)major_12_20(dev) != numbers[0])
+			*error = iMajorError;
+		if ((unsigned long)minor_12_20(dev) != numbers[1])
+			*error = iMinorError;
+	} else if (n == 3) {
+		dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]);
+		if ((unsigned long)major_12_12_8(dev) != numbers[0])
+			*error = iMajorError;
+		if ((unsigned long)unit_12_12_8(dev) != numbers[1])
+			*error = "invalid unit number";
+		if ((unsigned long)subunit_12_12_8(dev) != numbers[2])
+			*error = "invalid subunit number";
+	} else
+		*error = tooManyFields;
+	return (dev);
+}
+
+
+		/* list of formats and pack functions */
+		/* this list must be sorted lexically */
+static struct format {
+	const char	*name;
+	pack_t		*pack;
+} formats[] = {
+	{"386bsd",  pack_8_8},
+	{"4bsd",    pack_8_8},
+	{"bsdos",   pack_bsdos},
+	{"freebsd", pack_freebsd},
+	{"hpux",    pack_8_24},
+	{"isc",     pack_8_8},
+	{"linux",   pack_8_8},
+	{"native",  pack_native},
+	{"netbsd",  pack_netbsd},
+	{"osf1",    pack_12_20},
+	{"sco",     pack_8_8},
+	{"solaris", pack_14_18},
+	{"sunos",   pack_8_8},
+	{"svr3",    pack_8_8},
+	{"svr4",    pack_14_18},
+	{"ultrix",  pack_8_8},
+};
+
+static int
+compare_format(const void *key, const void *element)
+{
+	const char		*name;
+	const struct format	*format;
+
+	name = key;
+	format = element;
+
+	return (strcmp(name, format->name));
+}
+
+
+pack_t *
+pack_find(const char *name)
+{
+	struct format	*format;
+
+	format = bsearch(name, formats,
+	    sizeof(formats)/sizeof(formats[0]),
+	    sizeof(formats[0]), compare_format);
+	if (format == 0)
+		return (NULL);
+	return (format->pack);
+}

+ 49 - 0
Utilities/cmlibarchive/libarchive/archive_pack_dev.h

@@ -0,0 +1,49 @@
+/*	$NetBSD: pack_dev.h,v 1.8 2013/06/14 16:28:20 tsutsui Exp $	*/
+
+/*-
+ * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Originally from NetBSD's mknod(8) source. */
+
+#ifndef	_PACK_DEV_H
+#define	_PACK_DEV_H
+
+typedef	dev_t pack_t(int, unsigned long [], const char **);
+
+pack_t	*pack_find(const char *);
+pack_t	 pack_native;
+
+#define	major_netbsd(x)		((int32_t)((((x) & 0x000fff00) >>  8)))
+#define	minor_netbsd(x)		((int32_t)((((x) & 0xfff00000) >> 12) | \
+					   (((x) & 0x000000ff) >>  0)))
+#define	makedev_netbsd(x,y)	((dev_t)((((x) <<  8) & 0x000fff00) | \
+					 (((y) << 12) & 0xfff00000) | \
+					 (((y) <<  0) & 0x000000ff)))
+
+#endif	/* _PACK_DEV_H */

+ 5 - 2
Utilities/cmlibarchive/libarchive/archive_platform.h

@@ -66,15 +66,18 @@
  * headers as required.
  * headers as required.
  */
  */
 
 
-/* Get a real definition for __FBSDID if we can */
+/* Get a real definition for __FBSDID or __RCSID if we can */
 #if HAVE_SYS_CDEFS_H
 #if HAVE_SYS_CDEFS_H
 #include <sys/cdefs.h>
 #include <sys/cdefs.h>
 #endif
 #endif
 
 
-/* If not, define it so as to avoid dangling semicolons. */
+/* If not, define them so as to avoid dangling semicolons. */
 #ifndef __FBSDID
 #ifndef __FBSDID
 #define	__FBSDID(a)     struct _undefined_hack
 #define	__FBSDID(a)     struct _undefined_hack
 #endif
 #endif
+#ifndef __RCSID
+#define	__RCSID(a)     struct _undefined_hack
+#endif
 
 
 /* Old glibc mbsnrtowcs fails assertions in our use case.  */
 /* Old glibc mbsnrtowcs fails assertions in our use case.  */
 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 1
 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 1

+ 61 - 5
Utilities/cmlibarchive/libarchive/archive_read.c

@@ -746,6 +746,59 @@ archive_read_header_position(struct archive *_a)
 	return (a->header_position);
 	return (a->header_position);
 }
 }
 
 
+/*
+ * Returns 1 if the archive contains at least one encrypted entry.
+ * If the archive format not support encryption at all
+ * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
+ * If for any other reason (e.g. not enough data read so far)
+ * we cannot say whether there are encrypted entries, then
+ * ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
+ * In general, this function will return values below zero when the
+ * reader is uncertain or totally uncapable of encryption support.
+ * When this function returns 0 you can be sure that the reader
+ * supports encryption detection but no encrypted entries have
+ * been found yet.
+ *
+ * NOTE: If the metadata/header of an archive is also encrypted, you
+ * cannot rely on the number of encrypted entries. That is why this
+ * function does not return the number of encrypted entries but#
+ * just shows that there are some.
+ */
+int
+archive_read_has_encrypted_entries(struct archive *_a)
+{
+	struct archive_read *a = (struct archive_read *)_a;
+	int format_supports_encryption = archive_read_format_capabilities(_a)
+			& (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
+
+	if (!_a || !format_supports_encryption) {
+		/* Format in general doesn't support encryption */
+		return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED;
+	}
+
+	/* A reader potentially has read enough data now. */
+	if (a->format && a->format->has_encrypted_entries) {
+		return (a->format->has_encrypted_entries)(a);
+	}
+
+	/* For any other reason we cannot say how many entries are there. */
+	return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+}
+
+/*
+ * Returns a bitmask of capabilities that are supported by the archive format reader.
+ * If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
+ */
+int
+archive_read_format_capabilities(struct archive *_a)
+{
+	struct archive_read *a = (struct archive_read *)_a;
+	if (a && a->format && a->format->format_capabilties) {
+		return (a->format->format_capabilties)(a);
+	}
+	return ARCHIVE_READ_FORMAT_CAPS_NONE;
+}
+
 /*
 /*
  * Read data from an archive entry, using a read(2)-style interface.
  * Read data from an archive entry, using a read(2)-style interface.
  * This is a convenience routine that just calls
  * This is a convenience routine that just calls
@@ -1094,7 +1147,9 @@ __archive_read_register_format(struct archive_read *a,
     int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
     int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
     int (*read_data_skip)(struct archive_read *),
     int (*read_data_skip)(struct archive_read *),
     int64_t (*seek_data)(struct archive_read *, int64_t, int),
     int64_t (*seek_data)(struct archive_read *, int64_t, int),
-    int (*cleanup)(struct archive_read *))
+    int (*cleanup)(struct archive_read *),
+    int (*format_capabilities)(struct archive_read *),
+    int (*has_encrypted_entries)(struct archive_read *))
 {
 {
 	int i, number_slots;
 	int i, number_slots;
 
 
@@ -1117,6 +1172,8 @@ __archive_read_register_format(struct archive_read *a,
 			a->formats[i].cleanup = cleanup;
 			a->formats[i].cleanup = cleanup;
 			a->formats[i].data = format_data;
 			a->formats[i].data = format_data;
 			a->formats[i].name = name;
 			a->formats[i].name = name;
+			a->formats[i].format_capabilties = format_capabilities;
+			a->formats[i].has_encrypted_entries = has_encrypted_entries;
 			return (ARCHIVE_OK);
 			return (ARCHIVE_OK);
 		}
 		}
 	}
 	}
@@ -1557,10 +1614,9 @@ __archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset,
 			client->dataset[++cursor].begin_position = r;
 			client->dataset[++cursor].begin_position = r;
 		}
 		}
 		offset -= client->dataset[cursor].begin_position;
 		offset -= client->dataset[cursor].begin_position;
-		if (offset < 0)
-			offset = 0;
-		else if (offset > client->dataset[cursor].total_size - 1)
-			offset = client->dataset[cursor].total_size - 1;
+		if (offset < 0
+		    || offset > client->dataset[cursor].total_size)
+			return ARCHIVE_FATAL;
 		if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0)
 		if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0)
 			return r;
 			return r;
 		break;
 		break;

+ 18 - 4
Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c

@@ -399,7 +399,7 @@ setup_mac_metadata(struct archive_read_disk *a,
 #endif
 #endif
 
 
 
 
-#if defined(HAVE_POSIX_ACL) && defined(ACL_TYPE_NFS4)
+#ifdef HAVE_POSIX_ACL
 static int translate_acl(struct archive_read_disk *a,
 static int translate_acl(struct archive_read_disk *a,
     struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
     struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
 
 
@@ -419,6 +419,7 @@ setup_acls(struct archive_read_disk *a,
 
 
 	archive_entry_acl_clear(entry);
 	archive_entry_acl_clear(entry);
 
 
+#ifdef ACL_TYPE_NFS4
 	/* Try NFS4 ACL first. */
 	/* Try NFS4 ACL first. */
 	if (*fd >= 0)
 	if (*fd >= 0)
 		acl = acl_get_fd(*fd);
 		acl = acl_get_fd(*fd);
@@ -447,6 +448,7 @@ setup_acls(struct archive_read_disk *a,
 		acl_free(acl);
 		acl_free(acl);
 		return (ARCHIVE_OK);
 		return (ARCHIVE_OK);
 	}
 	}
+#endif
 
 
 	/* Retrieve access ACL from file. */
 	/* Retrieve access ACL from file. */
 	if (*fd >= 0)
 	if (*fd >= 0)
@@ -492,6 +494,7 @@ static struct {
         {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
         {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
         {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
         {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
         {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
         {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+#ifdef ACL_TYPE_NFS4
         {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
         {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
         {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
         {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
         {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
         {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
@@ -508,8 +511,10 @@ static struct {
         {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
         {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
         {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
         {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
         {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
         {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+#endif
 };
 };
 
 
+#ifdef ACL_TYPE_NFS4
 static struct {
 static struct {
         int archive_inherit;
         int archive_inherit;
         int platform_inherit;
         int platform_inherit;
@@ -519,21 +524,25 @@ static struct {
 	{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
 	{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
 	{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
 	{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
 };
 };
-
+#endif
 static int
 static int
 translate_acl(struct archive_read_disk *a,
 translate_acl(struct archive_read_disk *a,
     struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
     struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
 {
 {
 	acl_tag_t	 acl_tag;
 	acl_tag_t	 acl_tag;
+#ifdef ACL_TYPE_NFS4
 	acl_entry_type_t acl_type;
 	acl_entry_type_t acl_type;
 	acl_flagset_t	 acl_flagset;
 	acl_flagset_t	 acl_flagset;
+	int brand, r;
+#endif
 	acl_entry_t	 acl_entry;
 	acl_entry_t	 acl_entry;
 	acl_permset_t	 acl_permset;
 	acl_permset_t	 acl_permset;
-	int		 brand, i, r, entry_acl_type;
+	int		 i, entry_acl_type;
 	int		 s, ae_id, ae_tag, ae_perm;
 	int		 s, ae_id, ae_tag, ae_perm;
 	const char	*ae_name;
 	const char	*ae_name;
 
 
 
 
+#ifdef ACL_TYPE_NFS4
 	// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
 	// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
 	// Make sure the "brand" on this ACL is consistent
 	// Make sure the "brand" on this ACL is consistent
 	// with the default_entry_acl_type bits provided.
 	// with the default_entry_acl_type bits provided.
@@ -560,6 +569,7 @@ translate_acl(struct archive_read_disk *a,
 		return ARCHIVE_FAILED;
 		return ARCHIVE_FAILED;
 		break;
 		break;
 	}
 	}
+#endif
 
 
 
 
 	s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
 	s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
@@ -592,9 +602,11 @@ translate_acl(struct archive_read_disk *a,
 		case ACL_OTHER:
 		case ACL_OTHER:
 			ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
 			ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
 			break;
 			break;
+#ifdef ACL_TYPE_NFS4
 		case ACL_EVERYONE:
 		case ACL_EVERYONE:
 			ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
 			ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
 			break;
 			break;
+#endif
 		default:
 		default:
 			/* Skip types that libarchive can't support. */
 			/* Skip types that libarchive can't support. */
 			s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
 			s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
@@ -605,6 +617,7 @@ translate_acl(struct archive_read_disk *a,
 		// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
 		// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
 		// non-NFSv4 ACLs
 		// non-NFSv4 ACLs
 		entry_acl_type = default_entry_acl_type;
 		entry_acl_type = default_entry_acl_type;
+#ifdef ACL_TYPE_NFS4
 		r = acl_get_entry_type_np(acl_entry, &acl_type);
 		r = acl_get_entry_type_np(acl_entry, &acl_type);
 		if (r == 0) {
 		if (r == 0) {
 			switch (acl_type) {
 			switch (acl_type) {
@@ -634,9 +647,10 @@ translate_acl(struct archive_read_disk *a,
 				ae_perm |= acl_inherit_map[i].archive_inherit;
 				ae_perm |= acl_inherit_map[i].archive_inherit;
 
 
                 }
                 }
+#endif
 
 
 		acl_get_permset(acl_entry, &acl_permset);
 		acl_get_permset(acl_entry, &acl_permset);
-                for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
+		for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
 			/*
 			/*
 			 * acl_get_perm() is spelled differently on different
 			 * acl_get_perm() is spelled differently on different
 			 * platforms; see above.
 			 * platforms; see above.

+ 1 - 1
Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c

@@ -1973,7 +1973,7 @@ tree_dup(int fd)
 	static volatile int can_dupfd_cloexec = 1;
 	static volatile int can_dupfd_cloexec = 1;
 
 
 	if (can_dupfd_cloexec) {
 	if (can_dupfd_cloexec) {
-		new_fd = fcntl(fd, F_DUPFD_CLOEXEC);
+		new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
 		if (new_fd != -1)
 		if (new_fd != -1)
 			return (new_fd);
 			return (new_fd);
 		/* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,
 		/* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,

+ 4 - 4
Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c

@@ -929,7 +929,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
 		else
 		else
 			flags |= FILE_FLAG_SEQUENTIAL_SCAN;
 			flags |= FILE_FLAG_SEQUENTIAL_SCAN;
 		t->entry_fh = CreateFileW(tree_current_access_path(t),
 		t->entry_fh = CreateFileW(tree_current_access_path(t),
-		    GENERIC_READ, 0, NULL, OPEN_EXISTING, flags, NULL);
+		    GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);
 		if (t->entry_fh == INVALID_HANDLE_VALUE) {
 		if (t->entry_fh == INVALID_HANDLE_VALUE) {
 			archive_set_error(&a->archive, errno,
 			archive_set_error(&a->archive, errno,
 			    "Couldn't open %ls", tree_current_path(a->tree));
 			    "Couldn't open %ls", tree_current_path(a->tree));
@@ -1886,7 +1886,7 @@ tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
 	
 	
 	if (sim_lstat && tree_current_is_physical_link(t))
 	if (sim_lstat && tree_current_is_physical_link(t))
 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
 		flag |= FILE_FLAG_OPEN_REPARSE_POINT;
-	h = CreateFileW(tree_current_access_path(t), 0, 0, NULL,
+	h = CreateFileW(tree_current_access_path(t), 0, FILE_SHARE_READ, NULL,
 	    OPEN_EXISTING, flag, NULL);
 	    OPEN_EXISTING, flag, NULL);
 	if (h == INVALID_HANDLE_VALUE) {
 	if (h == INVALID_HANDLE_VALUE) {
 		la_dosmaperr(GetLastError());
 		la_dosmaperr(GetLastError());
@@ -2115,7 +2115,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
 			} else
 			} else
 				desiredAccess = GENERIC_READ;
 				desiredAccess = GENERIC_READ;
 
 
-			h = CreateFileW(path, desiredAccess, 0, NULL,
+			h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL,
 			    OPEN_EXISTING, flag, NULL);
 			    OPEN_EXISTING, flag, NULL);
 			if (h == INVALID_HANDLE_VALUE) {
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
 				la_dosmaperr(GetLastError());
@@ -2162,7 +2162,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
 		if (fd >= 0) {
 		if (fd >= 0) {
 			h = (HANDLE)_get_osfhandle(fd);
 			h = (HANDLE)_get_osfhandle(fd);
 		} else {
 		} else {
-			h = CreateFileW(path, GENERIC_READ, 0, NULL,
+			h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
 			    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
 			    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
 			if (h == INVALID_HANDLE_VALUE) {
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
 				la_dosmaperr(GetLastError());

+ 13 - 9
Utilities/cmlibarchive/libarchive/archive_read_private.h

@@ -207,6 +207,8 @@ struct archive_read {
 		int	(*read_data_skip)(struct archive_read *);
 		int	(*read_data_skip)(struct archive_read *);
 		int64_t	(*seek_data)(struct archive_read *, int64_t, int);
 		int64_t	(*seek_data)(struct archive_read *, int64_t, int);
 		int	(*cleanup)(struct archive_read *);
 		int	(*cleanup)(struct archive_read *);
+		int	(*format_capabilties)(struct archive_read *);
+		int	(*has_encrypted_entries)(struct archive_read *);
 	}	formats[16];
 	}	formats[16];
 	struct archive_format_descriptor	*format; /* Active format. */
 	struct archive_format_descriptor	*format; /* Active format. */
 
 
@@ -218,15 +220,17 @@ struct archive_read {
 };
 };
 
 
 int	__archive_read_register_format(struct archive_read *a,
 int	__archive_read_register_format(struct archive_read *a,
-	    void *format_data,
-	    const char *name,
-	    int (*bid)(struct archive_read *, int),
-	    int (*options)(struct archive_read *, const char *, const char *),
-	    int (*read_header)(struct archive_read *, struct archive_entry *),
-	    int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
-	    int (*read_data_skip)(struct archive_read *),
-	    int64_t (*seek_data)(struct archive_read *, int64_t, int),
-	    int (*cleanup)(struct archive_read *));
+		void *format_data,
+		const char *name,
+		int (*bid)(struct archive_read *, int),
+		int (*options)(struct archive_read *, const char *, const char *),
+		int (*read_header)(struct archive_read *, struct archive_entry *),
+		int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
+		int (*read_data_skip)(struct archive_read *),
+		int64_t (*seek_data)(struct archive_read *, int64_t, int),
+		int (*cleanup)(struct archive_read *),
+		int (*format_capabilities)(struct archive_read *),
+		int (*has_encrypted_entries)(struct archive_read *));
 
 
 int __archive_read_get_bidder(struct archive_read *a,
 int __archive_read_get_bidder(struct archive_read *a,
     struct archive_read_filter_bidder **bidder);
     struct archive_read_filter_bidder **bidder);

+ 22 - 0
Utilities/cmlibarchive/libarchive/archive_read_set_options.3

@@ -193,6 +193,28 @@ Defaults to enabled, use
 .Cm !rockridge
 .Cm !rockridge
 to disable.
 to disable.
 .El
 .El
+.It Format tar
+.Bl -tag -compact -width indent
+.It Cm compat-2x
+Libarchive 2.x incorrectly encoded Unicode filenames on
+some platforms.
+This option mimics the libarchive 2.x filename handling
+so that such archives can be read correctly.
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating filenames.
+.It Cm mac-ext
+Support Mac OS metadata extension that records data in special
+files beginning with a period and underscore.
+Defaults to enabled on Mac OS, disabled on other platforms.
+Use
+.Cm !mac-ext
+to disable.
+.It Cm read_concatenated_archives
+Ignore zeroed blocks in the archive, which occurs when multiple tar archives
+have been concatenated together.  Without this option, only the contents of
+the first concatenated archive would be read.
+.El
 .El
 .El
 .\"
 .\"
 .Sh ERRORS
 .Sh ERRORS

+ 16 - 16
Utilities/cmlibarchive/libarchive/archive_read_set_options.c

@@ -78,7 +78,7 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
 	struct archive_read *a = (struct archive_read *)_a;
 	struct archive_read *a = (struct archive_read *)_a;
 	struct archive_format_descriptor *format;
 	struct archive_format_descriptor *format;
 	size_t i;
 	size_t i;
-	int r, rv = ARCHIVE_WARN;
+	int r, rv = ARCHIVE_WARN, matched_modules = 0;
 
 
 	for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
 	for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
 		format = &a->formats[i];
 		format = &a->formats[i];
@@ -86,8 +86,11 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
 		    format->name == NULL)
 		    format->name == NULL)
 			/* This format does not support option. */
 			/* This format does not support option. */
 			continue;
 			continue;
-		if (m != NULL && strcmp(format->name, m) != 0)
-			continue;
+		if (m != NULL) {
+			if (strcmp(format->name, m) != 0)
+				continue;
+			++matched_modules;
+		}
 
 
 		a->format = format;
 		a->format = format;
 		r = format->options(a, o, v);
 		r = format->options(a, o, v);
@@ -96,16 +99,13 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
 		if (r == ARCHIVE_FATAL)
 		if (r == ARCHIVE_FATAL)
 			return (ARCHIVE_FATAL);
 			return (ARCHIVE_FATAL);
 
 
-		if (m != NULL)
-			return (r);
-
 		if (r == ARCHIVE_OK)
 		if (r == ARCHIVE_OK)
 			rv = ARCHIVE_OK;
 			rv = ARCHIVE_OK;
 	}
 	}
 	/* If the format name didn't match, return a special code for
 	/* If the format name didn't match, return a special code for
 	 * _archive_set_option[s]. */
 	 * _archive_set_option[s]. */
-	if (rv == ARCHIVE_WARN && m != NULL)
-		rv = ARCHIVE_WARN - 1;
+	if (m != NULL && matched_modules == 0)
+		return ARCHIVE_WARN - 1;
 	return (rv);
 	return (rv);
 }
 }
 
 
@@ -116,7 +116,7 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
 	struct archive_read *a = (struct archive_read *)_a;
 	struct archive_read *a = (struct archive_read *)_a;
 	struct archive_read_filter *filter;
 	struct archive_read_filter *filter;
 	struct archive_read_filter_bidder *bidder;
 	struct archive_read_filter_bidder *bidder;
-	int r, rv = ARCHIVE_WARN;
+	int r, rv = ARCHIVE_WARN, matched_modules = 0;
 
 
 	for (filter = a->filter; filter != NULL; filter = filter->upstream) {
 	for (filter = a->filter; filter != NULL; filter = filter->upstream) {
 		bidder = filter->bidder;
 		bidder = filter->bidder;
@@ -125,24 +125,24 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
 		if (bidder->options == NULL)
 		if (bidder->options == NULL)
 			/* This bidder does not support option */
 			/* This bidder does not support option */
 			continue;
 			continue;
-		if (m != NULL && strcmp(filter->name, m) != 0)
-			continue;
+		if (m != NULL) {
+			if (strcmp(filter->name, m) != 0)
+				continue;
+			++matched_modules;
+		}
 
 
 		r = bidder->options(bidder, o, v);
 		r = bidder->options(bidder, o, v);
 
 
 		if (r == ARCHIVE_FATAL)
 		if (r == ARCHIVE_FATAL)
 			return (ARCHIVE_FATAL);
 			return (ARCHIVE_FATAL);
 
 
-		if (m != NULL)
-			return (r);
-
 		if (r == ARCHIVE_OK)
 		if (r == ARCHIVE_OK)
 			rv = ARCHIVE_OK;
 			rv = ARCHIVE_OK;
 	}
 	}
 	/* If the filter name didn't match, return a special code for
 	/* If the filter name didn't match, return a special code for
 	 * _archive_set_option[s]. */
 	 * _archive_set_option[s]. */
-	if (rv == ARCHIVE_WARN && m != NULL)
-		rv = ARCHIVE_WARN - 1;
+	if (m != NULL && matched_modules == 0)
+		return ARCHIVE_WARN - 1;
 	return (rv);
 	return (rv);
 }
 }
 
 

+ 5 - 4
Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c

@@ -242,10 +242,11 @@ consume_header(struct archive_read_filter *self)
 
 
 	if (version >= 0x940) {
 	if (version >= 0x940) {
 		unsigned level = *p++;
 		unsigned level = *p++;
-		if (method == 1 && level == 0) level = 3;
-		if (method == 2 && level == 0) level = 1;
-		if (method == 3 && level == 0) level = 9;
-		if (level < 1 && level > 9) {
+		unsigned default_level[] = {0, 3, 1, 9};
+		if (level == 0)
+			/* Method is 1..3 here due to check above. */
+			level = default_level[method];
+		else if (level > 9) {
 			archive_set_error(&self->archive->archive,
 			archive_set_error(&self->archive->archive,
 			    ARCHIVE_ERRNO_MISC, "Invalid level");
 			    ARCHIVE_ERRNO_MISC, "Invalid level");
 			return (ARCHIVE_FAILED);
 			return (ARCHIVE_FAILED);

+ 1 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c

@@ -601,7 +601,7 @@ lzip_init(struct archive_read_filter *self)
 		return (ARCHIVE_FATAL);
 		return (ARCHIVE_FATAL);
 	}
 	}
 	ret = lzma_raw_decoder(&(state->stream), filters);
 	ret = lzma_raw_decoder(&(state->stream), filters);
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
 	free(filters[0].options);
 	free(filters[0].options);
 #endif
 #endif
 	if (ret != LZMA_OK) {
 	if (ret != LZMA_OK) {

+ 138 - 24
Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c

@@ -69,7 +69,11 @@ __FBSDID("$FreeBSD$");
 #define _7Z_BZ2		0x040202
 #define _7Z_BZ2		0x040202
 #define _7Z_PPMD	0x030401
 #define _7Z_PPMD	0x030401
 #define _7Z_DELTA	0x03
 #define _7Z_DELTA	0x03
-#define _7Z_CRYPTO	0x06F10701
+#define _7Z_CRYPTO_MAIN_ZIP			0x06F10101 /* Main Zip crypto algo */
+#define _7Z_CRYPTO_RAR_29			0x06F10303 /* Rar29 AES-128 + (modified SHA-1) */
+#define _7Z_CRYPTO_AES_256_SHA_256	0x06F10701 /* AES-256 + SHA-256 */
+
+
 #define _7Z_X86		0x03030103
 #define _7Z_X86		0x03030103
 #define _7Z_X86_BCJ2	0x0303011B
 #define _7Z_X86_BCJ2	0x0303011B
 #define _7Z_POWERPC	0x03030205
 #define _7Z_POWERPC	0x03030205
@@ -322,8 +326,13 @@ struct _7zip {
 	struct archive_string_conv *sconv;
 	struct archive_string_conv *sconv;
 
 
 	char			 format_name[64];
 	char			 format_name[64];
+
+	/* Custom value that is non-zero if this archive contains encrypted entries. */
+	int			 has_encrypted_entries;
 };
 };
 
 
+static int	archive_read_format_7zip_has_encrypted_entries(struct archive_read *);
+static int	archive_read_support_format_7zip_capabilities(struct archive_read *a);
 static int	archive_read_format_7zip_bid(struct archive_read *, int);
 static int	archive_read_format_7zip_bid(struct archive_read *, int);
 static int	archive_read_format_7zip_cleanup(struct archive_read *);
 static int	archive_read_format_7zip_cleanup(struct archive_read *);
 static int	archive_read_format_7zip_read_data(struct archive_read *,
 static int	archive_read_format_7zip_read_data(struct archive_read *,
@@ -401,6 +410,13 @@ archive_read_support_format_7zip(struct archive *_a)
 		return (ARCHIVE_FATAL);
 		return (ARCHIVE_FATAL);
 	}
 	}
 
 
+	/*
+	 * Until enough data has been read, we cannot tell about
+	 * any encrypted entries yet.
+	 */
+	zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+
+
 	r = __archive_read_register_format(a,
 	r = __archive_read_register_format(a,
 	    zip,
 	    zip,
 	    "7zip",
 	    "7zip",
@@ -410,13 +426,36 @@ archive_read_support_format_7zip(struct archive *_a)
 	    archive_read_format_7zip_read_data,
 	    archive_read_format_7zip_read_data,
 	    archive_read_format_7zip_read_data_skip,
 	    archive_read_format_7zip_read_data_skip,
 	    NULL,
 	    NULL,
-	    archive_read_format_7zip_cleanup);
+	    archive_read_format_7zip_cleanup,
+	    archive_read_support_format_7zip_capabilities,
+	    archive_read_format_7zip_has_encrypted_entries);
 
 
 	if (r != ARCHIVE_OK)
 	if (r != ARCHIVE_OK)
 		free(zip);
 		free(zip);
 	return (ARCHIVE_OK);
 	return (ARCHIVE_OK);
 }
 }
 
 
+static int
+archive_read_support_format_7zip_capabilities(struct archive_read * a)
+{
+	(void)a; /* UNUSED */
+	return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
+			ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
+}
+
+
+static int
+archive_read_format_7zip_has_encrypted_entries(struct archive_read *_a)
+{
+	if (_a && _a->format) {
+		struct _7zip * zip = (struct _7zip *)_a->format->data;
+		if (zip) {
+			return zip->has_encrypted_entries;
+		}
+	}
+	return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+}
+
 static int
 static int
 archive_read_format_7zip_bid(struct archive_read *a, int best_bid)
 archive_read_format_7zip_bid(struct archive_read *a, int best_bid)
 {
 {
@@ -476,7 +515,7 @@ check_7zip_header_in_sfx(const char *p)
 	switch ((unsigned char)p[5]) {
 	switch ((unsigned char)p[5]) {
 	case 0x1C:
 	case 0x1C:
 		if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0)
 		if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0)
-			return (6); 
+			return (6);
 		/*
 		/*
 		 * Test the CRC because its extraction code has 7-Zip
 		 * Test the CRC because its extraction code has 7-Zip
 		 * Magic Code, so we should do this in order not to
 		 * Magic Code, so we should do this in order not to
@@ -484,15 +523,15 @@ check_7zip_header_in_sfx(const char *p)
 		 */
 		 */
 		if (crc32(0, (const unsigned char *)p + 12, 20)
 		if (crc32(0, (const unsigned char *)p + 12, 20)
 			!= archive_le32dec(p + 8))
 			!= archive_le32dec(p + 8))
-			return (6); 
+			return (6);
 		/* Hit the header! */
 		/* Hit the header! */
 		return (0);
 		return (0);
-	case 0x37: return (5); 
-	case 0x7A: return (4); 
-	case 0xBC: return (3); 
-	case 0xAF: return (2); 
-	case 0x27: return (1); 
-	default: return (6); 
+	case 0x37: return (5);
+	case 0x7A: return (4);
+	case 0xBC: return (3);
+	case 0xAF: return (2);
+	case 0x27: return (1);
+	default: return (6);
 	}
 	}
 }
 }
 
 
@@ -568,6 +607,19 @@ archive_read_format_7zip_read_header(struct archive_read *a,
 	struct _7zip *zip = (struct _7zip *)a->format->data;
 	struct _7zip *zip = (struct _7zip *)a->format->data;
 	struct _7zip_entry *zip_entry;
 	struct _7zip_entry *zip_entry;
 	int r, ret = ARCHIVE_OK;
 	int r, ret = ARCHIVE_OK;
+	struct _7z_folder *folder = 0;
+	uint64_t fidx = 0;
+
+	/*
+	 * It should be sufficient to call archive_read_next_header() for
+	 * a reader to determine if an entry is encrypted or not. If the
+	 * encryption of an entry is only detectable when calling
+	 * archive_read_data(), so be it. We'll do the same check there
+	 * as well.
+	 */
+	if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+		zip->has_encrypted_entries = 0;
+	}
 
 
 	a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
 	a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
 	if (a->archive.archive_format_name == NULL)
 	if (a->archive.archive_format_name == NULL)
@@ -604,6 +656,32 @@ archive_read_format_7zip_read_header(struct archive_read *a,
 			return (ARCHIVE_FATAL);
 			return (ARCHIVE_FATAL);
 	}
 	}
 
 
+	/* Figure out if the entry is encrypted by looking at the folder
+	   that is associated to the current 7zip entry. If the folder
+	   has a coder with a _7Z_CRYPTO codec then the folder is encrypted.
+	   Hence the entry must also be encrypted. */
+	if (zip_entry && zip_entry->folderIndex < zip->si.ci.numFolders) {
+		folder = &(zip->si.ci.folders[zip_entry->folderIndex]);
+		for (fidx=0; folder && fidx<folder->numCoders; fidx++) {
+			switch(folder->coders[fidx].codec) {
+				case _7Z_CRYPTO_MAIN_ZIP:
+				case _7Z_CRYPTO_RAR_29:
+				case _7Z_CRYPTO_AES_256_SHA_256: {
+					archive_entry_set_is_data_encrypted(entry, 1);
+					zip->has_encrypted_entries = 1;
+					break;
+				}
+			}
+		}
+	}
+
+	/* Now that we've checked for encryption, if there were still no
+	 * encrypted entries found we can say for sure that there are none.
+	 */
+	if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+		zip->has_encrypted_entries = 0;
+	}
+
 	if (archive_entry_copy_pathname_l(entry,
 	if (archive_entry_copy_pathname_l(entry,
 	    (const char *)zip_entry->utf16name,
 	    (const char *)zip_entry->utf16name,
 	    zip_entry->name_len, zip->sconv) != 0) {
 	    zip_entry->name_len, zip->sconv) != 0) {
@@ -707,6 +785,10 @@ archive_read_format_7zip_read_data(struct archive_read *a,
 
 
 	zip = (struct _7zip *)(a->format->data);
 	zip = (struct _7zip *)(a->format->data);
 
 
+	if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+		zip->has_encrypted_entries = 0;
+	}
+
 	if (zip->pack_stream_bytes_unconsumed)
 	if (zip->pack_stream_bytes_unconsumed)
 		read_consume(a);
 		read_consume(a);
 
 
@@ -969,7 +1051,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 	{
 	{
 		lzma_options_delta delta_opt;
 		lzma_options_delta delta_opt;
 		lzma_filter filters[LZMA_FILTERS_MAX];
 		lzma_filter filters[LZMA_FILTERS_MAX];
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
 		lzma_filter *ff;
 		lzma_filter *ff;
 #endif
 #endif
 		int fi = 0;
 		int fi = 0;
@@ -994,7 +1076,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 		 * for BCJ+LZMA. If we were able to tell the uncompressed
 		 * for BCJ+LZMA. If we were able to tell the uncompressed
 		 * size to liblzma when using lzma_raw_decoder() liblzma
 		 * size to liblzma when using lzma_raw_decoder() liblzma
 		 * could correctly deal with BCJ+LZMA. But unfortunately
 		 * could correctly deal with BCJ+LZMA. But unfortunately
-		 * there is no way to do that. 
+		 * there is no way to do that.
 		 * Discussion about this can be found at XZ Utils forum.
 		 * Discussion about this can be found at XZ Utils forum.
 		 */
 		 */
 		if (coder2 != NULL) {
 		if (coder2 != NULL) {
@@ -1056,7 +1138,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 		else
 		else
 			filters[fi].id = LZMA_FILTER_LZMA1;
 			filters[fi].id = LZMA_FILTER_LZMA1;
 		filters[fi].options = NULL;
 		filters[fi].options = NULL;
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
 		ff = &filters[fi];
 		ff = &filters[fi];
 #endif
 #endif
 		r = lzma_properties_decode(&filters[fi], NULL,
 		r = lzma_properties_decode(&filters[fi], NULL,
@@ -1070,7 +1152,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 		filters[fi].id = LZMA_VLI_UNKNOWN;
 		filters[fi].id = LZMA_VLI_UNKNOWN;
 		filters[fi].options = NULL;
 		filters[fi].options = NULL;
 		r = lzma_raw_decoder(&(zip->lzstream), filters);
 		r = lzma_raw_decoder(&(zip->lzstream), filters);
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
 		free(ff->options);
 		free(ff->options);
 #endif
 #endif
 		if (r != LZMA_OK) {
 		if (r != LZMA_OK) {
@@ -1203,6 +1285,17 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 		    "Unexpected codec ID: %lX", zip->codec);
 		    "Unexpected codec ID: %lX", zip->codec);
 		return (ARCHIVE_FAILED);
 		return (ARCHIVE_FAILED);
+	case _7Z_CRYPTO_MAIN_ZIP:
+	case _7Z_CRYPTO_RAR_29:
+	case _7Z_CRYPTO_AES_256_SHA_256:
+		if (a->entry) {
+			archive_entry_set_is_metadata_encrypted(a->entry, 1);
+			archive_entry_set_is_data_encrypted(a->entry, 1);
+			zip->has_encrypted_entries = 1;
+		}
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Crypto codec not supported yet (ID: 0x%lX)", zip->codec);
+		return (ARCHIVE_FAILED);
 	default:
 	default:
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 		    "Unknown codec ID: %lX", zip->codec);
 		    "Unknown codec ID: %lX", zip->codec);
@@ -1426,7 +1519,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
 
 
 		do {
 		do {
 			int sym;
 			int sym;
-			
+
 			sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
 			sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
 				&(zip->ppmd7_context), &(zip->range_dec.p));
 				&(zip->ppmd7_context), &(zip->range_dec.p));
 			if (sym < 0) {
 			if (sym < 0) {
@@ -2755,6 +2848,7 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
 	zip->header_crc32 = 0;
 	zip->header_crc32 = 0;
 	zip->header_is_encoded = 0;
 	zip->header_is_encoded = 0;
 	zip->header_is_being_read = 1;
 	zip->header_is_being_read = 1;
+	zip->has_encrypted_entries = 0;
 	check_header_crc = 1;
 	check_header_crc = 1;
 
 
 	if ((p = header_bytes(a, 1)) == NULL) {
 	if ((p = header_bytes(a, 1)) == NULL) {
@@ -3170,7 +3264,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
 		return (r);
 		return (r);
 
 
 	/*
 	/*
-	 * Skip the bytes we alrady has skipped in skip_stream(). 
+	 * Skip the bytes we alrady has skipped in skip_stream().
 	 */
 	 */
 	while (skip_bytes) {
 	while (skip_bytes) {
 		ssize_t skipped;
 		ssize_t skipped;
@@ -3235,16 +3329,36 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
 	 * Check coder types.
 	 * Check coder types.
 	 */
 	 */
 	for (i = 0; i < folder->numCoders; i++) {
 	for (i = 0; i < folder->numCoders; i++) {
-		if (folder->coders[i].codec == _7Z_CRYPTO) {
-			archive_set_error(&(a->archive),
-			    ARCHIVE_ERRNO_MISC,
-			    "The %s is encrypted, "
-			    "but currently not supported", cname);
-			return (ARCHIVE_FATAL);
+		switch(folder->coders[i].codec) {
+			case _7Z_CRYPTO_MAIN_ZIP:
+			case _7Z_CRYPTO_RAR_29:
+			case _7Z_CRYPTO_AES_256_SHA_256: {
+				/* For entry that is associated with this folder, mark
+				   it as encrypted (data+metadata). */
+				zip->has_encrypted_entries = 1;
+				if (a->entry) {
+					archive_entry_set_is_data_encrypted(a->entry, 1);
+					archive_entry_set_is_metadata_encrypted(a->entry, 1);
+				}
+				archive_set_error(&(a->archive),
+					ARCHIVE_ERRNO_MISC,
+					"The %s is encrypted, "
+					"but currently not supported", cname);
+				return (ARCHIVE_FATAL);
+			}
+			case _7Z_X86_BCJ2: {
+				found_bcj2++;
+				break;
+			}
 		}
 		}
-		if (folder->coders[i].codec == _7Z_X86_BCJ2)
-			found_bcj2++;
 	}
 	}
+	/* Now that we've checked for encryption, if there were still no
+	 * encrypted entries found we can say for sure that there are none.
+	 */
+	if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+		zip->has_encrypted_entries = 0;
+	}
+
 	if ((folder->numCoders > 2 && !found_bcj2) || found_bcj2 > 1) {
 	if ((folder->numCoders > 2 && !found_bcj2) || found_bcj2 > 1) {
 		archive_set_error(&(a->archive),
 		archive_set_error(&(a->archive),
 		    ARCHIVE_ERRNO_MISC,
 		    ARCHIVE_ERRNO_MISC,

+ 3 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c

@@ -122,7 +122,9 @@ archive_read_support_format_ar(struct archive *_a)
 	    archive_read_format_ar_read_data,
 	    archive_read_format_ar_read_data,
 	    archive_read_format_ar_skip,
 	    archive_read_format_ar_skip,
 	    NULL,
 	    NULL,
-	    archive_read_format_ar_cleanup);
+	    archive_read_format_ar_cleanup,
+	    NULL,
+	    NULL);
 
 
 	if (r != ARCHIVE_OK) {
 	if (r != ARCHIVE_OK) {
 		free(ar);
 		free(ar);

+ 3 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c

@@ -383,7 +383,9 @@ archive_read_support_format_cab(struct archive *_a)
 	    archive_read_format_cab_read_data,
 	    archive_read_format_cab_read_data,
 	    archive_read_format_cab_read_data_skip,
 	    archive_read_format_cab_read_data_skip,
 	    NULL,
 	    NULL,
-	    archive_read_format_cab_cleanup);
+	    archive_read_format_cab_cleanup,
+	    NULL,
+	    NULL);
 
 
 	if (r != ARCHIVE_OK)
 	if (r != ARCHIVE_OK)
 		free(cab);
 		free(cab);

+ 3 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c

@@ -243,7 +243,9 @@ archive_read_support_format_cpio(struct archive *_a)
 	    archive_read_format_cpio_read_data,
 	    archive_read_format_cpio_read_data,
 	    archive_read_format_cpio_skip,
 	    archive_read_format_cpio_skip,
 	    NULL,
 	    NULL,
-	    archive_read_format_cpio_cleanup);
+	    archive_read_format_cpio_cleanup,
+	    NULL,
+	    NULL);
 
 
 	if (r != ARCHIVE_OK)
 	if (r != ARCHIVE_OK)
 		free(cpio);
 		free(cpio);

+ 2 - 0
Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c

@@ -54,6 +54,8 @@ archive_read_support_format_empty(struct archive *_a)
 	    archive_read_format_empty_read_data,
 	    archive_read_format_empty_read_data,
 	    NULL,
 	    NULL,
 	    NULL,
 	    NULL,
+	    NULL,
+	    NULL,
 	    NULL);
 	    NULL);
 
 
 	return (r);
 	return (r);

+ 3 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c

@@ -478,7 +478,9 @@ archive_read_support_format_iso9660(struct archive *_a)
 	    archive_read_format_iso9660_read_data,
 	    archive_read_format_iso9660_read_data,
 	    archive_read_format_iso9660_read_data_skip,
 	    archive_read_format_iso9660_read_data_skip,
 	    NULL,
 	    NULL,
-	    archive_read_format_iso9660_cleanup);
+	    archive_read_format_iso9660_cleanup,
+	    NULL,
+	    NULL);
 
 
 	if (r != ARCHIVE_OK) {
 	if (r != ARCHIVE_OK) {
 		free(iso9660);
 		free(iso9660);

+ 3 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c

@@ -320,7 +320,9 @@ archive_read_support_format_lha(struct archive *_a)
 	    archive_read_format_lha_read_data,
 	    archive_read_format_lha_read_data,
 	    archive_read_format_lha_read_data_skip,
 	    archive_read_format_lha_read_data_skip,
 	    NULL,
 	    NULL,
-	    archive_read_format_lha_cleanup);
+	    archive_read_format_lha_cleanup,
+	    NULL,
+	    NULL);
 
 
 	if (r != ARCHIVE_OK)
 	if (r != ARCHIVE_OK)
 		free(lha);
 		free(lha);

+ 258 - 158
Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c

@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
 #include "archive_private.h"
 #include "archive_private.h"
 #include "archive_read_private.h"
 #include "archive_read_private.h"
 #include "archive_string.h"
 #include "archive_string.h"
+#include "archive_pack_dev.h"
 
 
 #ifndef O_BINARY
 #ifndef O_BINARY
 #define	O_BINARY 0
 #define	O_BINARY 0
@@ -103,6 +104,7 @@ struct mtree {
 	struct archive_entry_linkresolver *resolver;
 	struct archive_entry_linkresolver *resolver;
 
 
 	int64_t			 cur_size;
 	int64_t			 cur_size;
+	char checkfs;
 };
 };
 
 
 static int	bid_keycmp(const char *, const char *, ssize_t);
 static int	bid_keycmp(const char *, const char *, ssize_t);
@@ -173,6 +175,29 @@ get_time_t_min(void)
 #endif
 #endif
 }
 }
 
 
+static int
+archive_read_format_mtree_options(struct archive_read *a,
+    const char *key, const char *val)
+{
+	struct mtree *mtree;
+
+	mtree = (struct mtree *)(a->format->data);
+	if (strcmp(key, "checkfs")  == 0) {
+		/* Allows to read information missing from the mtree from the file system */
+		if (val == NULL || val[0] == 0) {
+			mtree->checkfs = 0;
+		} else {
+			mtree->checkfs = 1;
+		}
+		return (ARCHIVE_OK);
+	}
+
+	/* Note: The "warn" return is just to inform the options
+	 * supervisor that we didn't handle it.  It will generate
+	 * a suitable error if no one used this option. */
+	return (ARCHIVE_WARN);
+}
+
 static void
 static void
 free_options(struct mtree_option *head)
 free_options(struct mtree_option *head)
 {
 {
@@ -205,7 +230,7 @@ archive_read_support_format_mtree(struct archive *_a)
 	mtree->fd = -1;
 	mtree->fd = -1;
 
 
 	r = __archive_read_register_format(a, mtree, "mtree",
 	r = __archive_read_register_format(a, mtree, "mtree",
-	    mtree_bid, NULL, read_header, read_data, skip, NULL, cleanup);
+           mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup, NULL, NULL);
 
 
 	if (r != ARCHIVE_OK)
 	if (r != ARCHIVE_OK)
 		free(mtree);
 		free(mtree);
@@ -367,7 +392,7 @@ bid_keyword(const char *p,  ssize_t len)
 		"gid", "gname", NULL
 		"gid", "gname", NULL
 	};
 	};
 	static const char *keys_il[] = {
 	static const char *keys_il[] = {
-		"ignore", "link", NULL
+		"ignore", "inode", "link", NULL
 	};
 	};
 	static const char *keys_m[] = {
 	static const char *keys_m[] = {
 		"md5", "md5digest", "mode", NULL
 		"md5", "md5digest", "mode", NULL
@@ -376,7 +401,7 @@ bid_keyword(const char *p,  ssize_t len)
 		"nlink", "nochange", "optional", NULL
 		"nlink", "nochange", "optional", NULL
 	};
 	};
 	static const char *keys_r[] = {
 	static const char *keys_r[] = {
-		"rmd160", "rmd160digest", NULL
+		"resdevice", "rmd160", "rmd160digest", NULL
 	};
 	};
 	static const char *keys_s[] = {
 	static const char *keys_s[] = {
 		"sha1", "sha1digest",
 		"sha1", "sha1digest",
@@ -1103,162 +1128,164 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
 			mtree->current_dir.length = n;
 			mtree->current_dir.length = n;
 	}
 	}
 
 
-	/*
-	 * Try to open and stat the file to get the real size
-	 * and other file info.  It would be nice to avoid
-	 * this here so that getting a listing of an mtree
-	 * wouldn't require opening every referenced contents
-	 * file.  But then we wouldn't know the actual
-	 * contents size, so I don't see a really viable way
-	 * around this.  (Also, we may want to someday pull
-	 * other unspecified info from the contents file on
-	 * disk.)
-	 */
-	mtree->fd = -1;
-	if (archive_strlen(&mtree->contents_name) > 0)
-		path = mtree->contents_name.s;
-	else
-		path = archive_entry_pathname(entry);
-
-	if (archive_entry_filetype(entry) == AE_IFREG ||
-	    archive_entry_filetype(entry) == AE_IFDIR) {
-		mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
-		__archive_ensure_cloexec_flag(mtree->fd);
-		if (mtree->fd == -1 &&
-		    (errno != ENOENT ||
-		     archive_strlen(&mtree->contents_name) > 0)) {
-			archive_set_error(&a->archive, errno,
-			    "Can't open %s", path);
-			r = ARCHIVE_WARN;
+	if (mtree->checkfs) {
+		/*
+		 * Try to open and stat the file to get the real size
+		 * and other file info.  It would be nice to avoid
+		 * this here so that getting a listing of an mtree
+		 * wouldn't require opening every referenced contents
+		 * file.  But then we wouldn't know the actual
+		 * contents size, so I don't see a really viable way
+		 * around this.  (Also, we may want to someday pull
+		 * other unspecified info from the contents file on
+		 * disk.)
+		 */
+		mtree->fd = -1;
+		if (archive_strlen(&mtree->contents_name) > 0)
+			path = mtree->contents_name.s;
+		else
+			path = archive_entry_pathname(entry);
+
+		if (archive_entry_filetype(entry) == AE_IFREG ||
+				archive_entry_filetype(entry) == AE_IFDIR) {
+			mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
+			__archive_ensure_cloexec_flag(mtree->fd);
+			if (mtree->fd == -1 &&
+					(errno != ENOENT ||
+					 archive_strlen(&mtree->contents_name) > 0)) {
+				archive_set_error(&a->archive, errno,
+						"Can't open %s", path);
+				r = ARCHIVE_WARN;
+			}
 		}
 		}
-	}
 
 
-	st = &st_storage;
-	if (mtree->fd >= 0) {
-		if (fstat(mtree->fd, st) == -1) {
-			archive_set_error(&a->archive, errno,
-			    "Could not fstat %s", path);
-			r = ARCHIVE_WARN;
-			/* If we can't stat it, don't keep it open. */
-			close(mtree->fd);
-			mtree->fd = -1;
+		st = &st_storage;
+		if (mtree->fd >= 0) {
+			if (fstat(mtree->fd, st) == -1) {
+				archive_set_error(&a->archive, errno,
+						"Could not fstat %s", path);
+				r = ARCHIVE_WARN;
+				/* If we can't stat it, don't keep it open. */
+				close(mtree->fd);
+				mtree->fd = -1;
+				st = NULL;
+			}
+		} else if (lstat(path, st) == -1) {
 			st = NULL;
 			st = NULL;
 		}
 		}
-	} else if (lstat(path, st) == -1) {
-		st = NULL;
-	}
 
 
-	/*
-	 * Check for a mismatch between the type in the specification and
-	 * the type of the contents object on disk.
-	 */
-	if (st != NULL) {
-		if (
-		    ((st->st_mode & S_IFMT) == S_IFREG &&
-		     archive_entry_filetype(entry) == AE_IFREG)
+		/*
+		 * Check for a mismatch between the type in the specification and
+		 * the type of the contents object on disk.
+		 */
+		if (st != NULL) {
+			if (
+					((st->st_mode & S_IFMT) == S_IFREG &&
+					 archive_entry_filetype(entry) == AE_IFREG)
 #ifdef S_IFLNK
 #ifdef S_IFLNK
-		    || ((st->st_mode & S_IFMT) == S_IFLNK &&
-			archive_entry_filetype(entry) == AE_IFLNK)
+					|| ((st->st_mode & S_IFMT) == S_IFLNK &&
+						archive_entry_filetype(entry) == AE_IFLNK)
 #endif
 #endif
 #ifdef S_IFSOCK
 #ifdef S_IFSOCK
-		    || ((st->st_mode & S_IFSOCK) == S_IFSOCK &&
-			archive_entry_filetype(entry) == AE_IFSOCK)
+					|| ((st->st_mode & S_IFSOCK) == S_IFSOCK &&
+						archive_entry_filetype(entry) == AE_IFSOCK)
 #endif
 #endif
 #ifdef S_IFCHR
 #ifdef S_IFCHR
-		    || ((st->st_mode & S_IFMT) == S_IFCHR &&
-			archive_entry_filetype(entry) == AE_IFCHR)
+					|| ((st->st_mode & S_IFMT) == S_IFCHR &&
+						archive_entry_filetype(entry) == AE_IFCHR)
 #endif
 #endif
 #ifdef S_IFBLK
 #ifdef S_IFBLK
-		    || ((st->st_mode & S_IFMT) == S_IFBLK &&
-			archive_entry_filetype(entry) == AE_IFBLK)
+					|| ((st->st_mode & S_IFMT) == S_IFBLK &&
+						archive_entry_filetype(entry) == AE_IFBLK)
 #endif
 #endif
-		    || ((st->st_mode & S_IFMT) == S_IFDIR &&
-			archive_entry_filetype(entry) == AE_IFDIR)
+					|| ((st->st_mode & S_IFMT) == S_IFDIR &&
+						archive_entry_filetype(entry) == AE_IFDIR)
 #ifdef S_IFIFO
 #ifdef S_IFIFO
-		    || ((st->st_mode & S_IFMT) == S_IFIFO &&
-			archive_entry_filetype(entry) == AE_IFIFO)
+					|| ((st->st_mode & S_IFMT) == S_IFIFO &&
+							archive_entry_filetype(entry) == AE_IFIFO)
 #endif
 #endif
-		    ) {
-			/* Types match. */
-		} else {
-			/* Types don't match; bail out gracefully. */
-			if (mtree->fd >= 0)
-				close(mtree->fd);
-			mtree->fd = -1;
-			if (parsed_kws & MTREE_HAS_OPTIONAL) {
-				/* It's not an error for an optional entry
-				   to not match disk. */
-				*use_next = 1;
-			} else if (r == ARCHIVE_OK) {
-				archive_set_error(&a->archive,
-				    ARCHIVE_ERRNO_MISC,
-				    "mtree specification has different type for %s",
-				    archive_entry_pathname(entry));
-				r = ARCHIVE_WARN;
-			}
-			return r;
+					) {
+						/* Types match. */
+					} else {
+						/* Types don't match; bail out gracefully. */
+						if (mtree->fd >= 0)
+							close(mtree->fd);
+						mtree->fd = -1;
+						if (parsed_kws & MTREE_HAS_OPTIONAL) {
+							/* It's not an error for an optional entry
+							   to not match disk. */
+							*use_next = 1;
+						} else if (r == ARCHIVE_OK) {
+							archive_set_error(&a->archive,
+									ARCHIVE_ERRNO_MISC,
+									"mtree specification has different type for %s",
+									archive_entry_pathname(entry));
+							r = ARCHIVE_WARN;
+						}
+						return r;
+					}
 		}
 		}
-	}
 
 
-	/*
-	 * If there is a contents file on disk, pick some of the metadata
-	 * from that file.  For most of these, we only set it from the contents
-	 * if it wasn't already parsed from the specification.
-	 */
-	if (st != NULL) {
-		if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
-		     (parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
-		    (archive_entry_filetype(entry) == AE_IFCHR ||
-		     archive_entry_filetype(entry) == AE_IFBLK))
-			archive_entry_set_rdev(entry, st->st_rdev);
-		if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME)) == 0 ||
-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
-			archive_entry_set_gid(entry, st->st_gid);
-		if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME)) == 0 ||
-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
-			archive_entry_set_uid(entry, st->st_uid);
-		if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
+		/*
+		 * If there is a contents file on disk, pick some of the metadata
+		 * from that file.  For most of these, we only set it from the contents
+		 * if it wasn't already parsed from the specification.
+		 */
+		if (st != NULL) {
+			if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
+						(parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
+					(archive_entry_filetype(entry) == AE_IFCHR ||
+					 archive_entry_filetype(entry) == AE_IFBLK))
+				archive_entry_set_rdev(entry, st->st_rdev);
+			if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME)) == 0 ||
+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+				archive_entry_set_gid(entry, st->st_gid);
+			if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME)) == 0 ||
+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+				archive_entry_set_uid(entry, st->st_uid);
+			if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
 #if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
 #if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
-			archive_entry_set_mtime(entry, st->st_mtime,
-			    st->st_mtimespec.tv_nsec);
+				archive_entry_set_mtime(entry, st->st_mtime,
+						st->st_mtimespec.tv_nsec);
 #elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
 #elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
-			archive_entry_set_mtime(entry, st->st_mtime,
-			    st->st_mtim.tv_nsec);
+				archive_entry_set_mtime(entry, st->st_mtime,
+						st->st_mtim.tv_nsec);
 #elif HAVE_STRUCT_STAT_ST_MTIME_N
 #elif HAVE_STRUCT_STAT_ST_MTIME_N
-			archive_entry_set_mtime(entry, st->st_mtime,
-			    st->st_mtime_n);
+				archive_entry_set_mtime(entry, st->st_mtime,
+						st->st_mtime_n);
 #elif HAVE_STRUCT_STAT_ST_UMTIME
 #elif HAVE_STRUCT_STAT_ST_UMTIME
-			archive_entry_set_mtime(entry, st->st_mtime,
-			    st->st_umtime*1000);
+				archive_entry_set_mtime(entry, st->st_mtime,
+						st->st_umtime*1000);
 #elif HAVE_STRUCT_STAT_ST_MTIME_USEC
 #elif HAVE_STRUCT_STAT_ST_MTIME_USEC
-			archive_entry_set_mtime(entry, st->st_mtime,
-			    st->st_mtime_usec*1000);
+				archive_entry_set_mtime(entry, st->st_mtime,
+						st->st_mtime_usec*1000);
 #else
 #else
-			archive_entry_set_mtime(entry, st->st_mtime, 0);
+				archive_entry_set_mtime(entry, st->st_mtime, 0);
 #endif
 #endif
+			}
+			if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+				archive_entry_set_nlink(entry, st->st_nlink);
+			if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+				archive_entry_set_perm(entry, st->st_mode);
+			if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
+					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+				archive_entry_set_size(entry, st->st_size);
+			archive_entry_set_ino(entry, st->st_ino);
+			archive_entry_set_dev(entry, st->st_dev);
+
+			archive_entry_linkify(mtree->resolver, &entry, &sparse_entry);
+		} else if (parsed_kws & MTREE_HAS_OPTIONAL) {
+			/*
+			 * Couldn't open the entry, stat it or the on-disk type
+			 * didn't match.  If this entry is optional, just ignore it
+			 * and read the next header entry.
+			 */
+			*use_next = 1;
+			return ARCHIVE_OK;
 		}
 		}
-		if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
-			archive_entry_set_nlink(entry, st->st_nlink);
-		if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
-			archive_entry_set_perm(entry, st->st_mode);
-		if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
-			archive_entry_set_size(entry, st->st_size);
-		archive_entry_set_ino(entry, st->st_ino);
-		archive_entry_set_dev(entry, st->st_dev);
-
-		archive_entry_linkify(mtree->resolver, &entry, &sparse_entry);
-	} else if (parsed_kws & MTREE_HAS_OPTIONAL) {
-		/*
-		 * Couldn't open the entry, stat it or the on-disk type
-		 * didn't match.  If this entry is optional, just ignore it
-		 * and read the next header entry.
-		 */
-		*use_next = 1;
-		return ARCHIVE_OK;
 	}
 	}
 
 
 	mtree->cur_size = archive_entry_size(entry);
 	mtree->cur_size = archive_entry_size(entry);
@@ -1292,33 +1319,82 @@ parse_line(struct archive_read *a, struct archive_entry *entry,
 
 
 /*
 /*
  * Device entries have one of the following forms:
  * Device entries have one of the following forms:
- * raw dev_t
- * format,major,minor[,subdevice]
- *
- * Just use major and minor, no translation etc is done
- * between formats.
+ *  - raw dev_t
+ *  - format,major,minor[,subdevice]
+ * When parsing succeeded, `pdev' will contain the appropriate dev_t value.
  */
  */
-static int
-parse_device(struct archive *a, struct archive_entry *entry, char *val)
+
+/* strsep() is not in C90, but strcspn() is. */
+/* Taken from http://unixpapa.com/incnote/string.html */
+static char *
+la_strsep(char **sp, char *sep)
 {
 {
-	char *comma1, *comma2;
+	char *p, *s;
+	if (sp == NULL || *sp == NULL || **sp == '\0')
+		return(NULL);
+	s = *sp;
+	p = s + strcspn(s, sep);
+	if (*p != '\0')
+		*p++ = '\0';
+	*sp = p;
+	return(s);
+}
 
 
-	comma1 = strchr(val, ',');
-	if (comma1 == NULL) {
-		archive_entry_set_dev(entry, (dev_t)mtree_atol10(&val));
-		return (ARCHIVE_OK);
-	}
-	++comma1;
-	comma2 = strchr(comma1, ',');
-	if (comma2 == NULL) {
-		archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
-		    "Malformed device attribute");
-		return (ARCHIVE_WARN);
+static int
+parse_device(dev_t *pdev, struct archive *a, char *val)
+{
+#define MAX_PACK_ARGS 3
+	unsigned long numbers[MAX_PACK_ARGS];
+	char *p, *dev;
+	int argc;
+	pack_t *pack;
+	dev_t result;
+	const char *error = NULL;
+
+	memset(pdev, 0, sizeof(*pdev));
+	if ((dev = strchr(val, ',')) != NULL) {
+		/*
+		 * Device's major/minor are given in a specified format.
+		 * Decode and pack it accordingly.
+		 */
+		*dev++ = '\0';
+		if ((pack = pack_find(val)) == NULL) {
+			archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Unknown format `%s'", val);
+			return ARCHIVE_WARN;
+		}
+		argc = 0;
+		while ((p = la_strsep(&dev, ",")) != NULL) {
+			if (*p == '\0') {
+				archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Missing number");
+				return ARCHIVE_WARN;
+			}
+			numbers[argc++] = mtree_atol(&p);
+			if (argc > MAX_PACK_ARGS) {
+				archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Too many arguments");
+				return ARCHIVE_WARN;
+			}
+		}
+		if (argc < 2) {
+			archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Not enough arguments");
+			return ARCHIVE_WARN;
+		}
+		result = (*pack)(argc, numbers, &error);
+		if (error != NULL) {
+			archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+			    "%s", error);
+			return ARCHIVE_WARN;
+		}
+	} else {
+		/* file system raw value. */
+		result = (dev_t)mtree_atol(&val);
 	}
 	}
-	++comma2;
-	archive_entry_set_rdevmajor(entry, (dev_t)mtree_atol(&comma1));
-	archive_entry_set_rdevminor(entry, (dev_t)mtree_atol(&comma2));
-	return (ARCHIVE_OK);
+	*pdev = result;
+	return ARCHIVE_OK;
+#undef MAX_PACK_ARGS
 }
 }
 
 
 /*
 /*
@@ -1374,8 +1450,16 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 			break;
 			break;
 	case 'd':
 	case 'd':
 		if (strcmp(key, "device") == 0) {
 		if (strcmp(key, "device") == 0) {
+			/* stat(2) st_rdev field, e.g. the major/minor IDs
+			 * of a char/block special file */
+			int r;
+			dev_t dev;
+
 			*parsed_kws |= MTREE_HAS_DEVICE;
 			*parsed_kws |= MTREE_HAS_DEVICE;
-			return parse_device(&a->archive, entry, val);
+			r = parse_device(&dev, &a->archive, val);
+			if (r == ARCHIVE_OK)
+				archive_entry_set_rdev(entry, dev);
+			return r;
 		}
 		}
 	case 'f':
 	case 'f':
 		if (strcmp(key, "flags") == 0) {
 		if (strcmp(key, "flags") == 0) {
@@ -1394,6 +1478,11 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 			archive_entry_copy_gname(entry, val);
 			archive_entry_copy_gname(entry, val);
 			break;
 			break;
 		}
 		}
+	case 'i':
+		if (strcmp(key, "inode") == 0) {
+			archive_entry_set_ino(entry, mtree_atol10(&val));
+			break;
+		}
 	case 'l':
 	case 'l':
 		if (strcmp(key, "link") == 0) {
 		if (strcmp(key, "link") == 0) {
 			archive_entry_copy_symlink(entry, val);
 			archive_entry_copy_symlink(entry, val);
@@ -1423,6 +1512,17 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 			break;
 			break;
 		}
 		}
 	case 'r':
 	case 'r':
+		if (strcmp(key, "resdevice") == 0) {
+			/* stat(2) st_dev field, e.g. the device ID where the
+			 * inode resides */
+			int r;
+			dev_t dev;
+
+			r = parse_device(&dev, &a->archive, val);
+			if (r == ARCHIVE_OK)
+				archive_entry_set_dev(entry, dev);
+			return r;
+		}
 		if (strcmp(key, "rmd160") == 0 ||
 		if (strcmp(key, "rmd160") == 0 ||
 		    strcmp(key, "rmd160digest") == 0)
 		    strcmp(key, "rmd160digest") == 0)
 			break;
 			break;

+ 70 - 9
Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c

@@ -304,8 +304,15 @@ struct rar
     ssize_t		 avail_in;
     ssize_t		 avail_in;
     const unsigned char *next_in;
     const unsigned char *next_in;
   } br;
   } br;
+
+  /*
+   * Custom field to denote that this archive contains encrypted entries
+   */
+  int has_encrypted_entries;
 };
 };
 
 
+static int archive_read_support_format_rar_capabilities(struct archive_read *);
+static int archive_read_format_rar_has_encrypted_entries(struct archive_read *);
 static int archive_read_format_rar_bid(struct archive_read *, int);
 static int archive_read_format_rar_bid(struct archive_read *, int);
 static int archive_read_format_rar_options(struct archive_read *,
 static int archive_read_format_rar_options(struct archive_read *,
     const char *, const char *);
     const char *, const char *);
@@ -646,6 +653,12 @@ archive_read_support_format_rar(struct archive *_a)
   }
   }
   memset(rar, 0, sizeof(*rar));
   memset(rar, 0, sizeof(*rar));
 
 
+	/*
+	 * Until enough data has been read, we cannot tell about
+	 * any encrypted entries yet.
+	 */
+	rar->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+
   r = __archive_read_register_format(a,
   r = __archive_read_register_format(a,
                                      rar,
                                      rar,
                                      "rar",
                                      "rar",
@@ -655,13 +668,36 @@ archive_read_support_format_rar(struct archive *_a)
                                      archive_read_format_rar_read_data,
                                      archive_read_format_rar_read_data,
                                      archive_read_format_rar_read_data_skip,
                                      archive_read_format_rar_read_data_skip,
                                      archive_read_format_rar_seek_data,
                                      archive_read_format_rar_seek_data,
-                                     archive_read_format_rar_cleanup);
+                                     archive_read_format_rar_cleanup,
+                                     archive_read_support_format_rar_capabilities,
+                                     archive_read_format_rar_has_encrypted_entries);
 
 
   if (r != ARCHIVE_OK)
   if (r != ARCHIVE_OK)
     free(rar);
     free(rar);
   return (r);
   return (r);
 }
 }
 
 
+static int
+archive_read_support_format_rar_capabilities(struct archive_read * a)
+{
+	(void)a; /* UNUSED */
+	return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA
+			| ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
+}
+
+static int
+archive_read_format_rar_has_encrypted_entries(struct archive_read *_a)
+{
+	if (_a && _a->format) {
+		struct rar * rar = (struct rar *)_a->format->data;
+		if (rar) {
+			return rar->has_encrypted_entries;
+		}
+	}
+	return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
+}
+
+
 static int
 static int
 archive_read_format_rar_bid(struct archive_read *a, int best_bid)
 archive_read_format_rar_bid(struct archive_read *a, int best_bid)
 {
 {
@@ -755,7 +791,7 @@ archive_read_format_rar_options(struct archive_read *a,
 {
 {
   struct rar *rar;
   struct rar *rar;
   int ret = ARCHIVE_FAILED;
   int ret = ARCHIVE_FAILED;
-        
+
   rar = (struct rar *)(a->format->data);
   rar = (struct rar *)(a->format->data);
   if (strcmp(key, "hdrcharset")  == 0) {
   if (strcmp(key, "hdrcharset")  == 0) {
     if (val == NULL || val[0] == 0)
     if (val == NULL || val[0] == 0)
@@ -797,6 +833,17 @@ archive_read_format_rar_read_header(struct archive_read *a,
 
 
   rar = (struct rar *)(a->format->data);
   rar = (struct rar *)(a->format->data);
 
 
+  /*
+   * It should be sufficient to call archive_read_next_header() for
+   * a reader to determine if an entry is encrypted or not. If the
+   * encryption of an entry is only detectable when calling
+   * archive_read_data(), so be it. We'll do the same check there
+   * as well.
+   */
+  if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+	  rar->has_encrypted_entries = 0;
+  }
+
   /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if
   /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if
   * this fails.
   * this fails.
   */
   */
@@ -857,9 +904,14 @@ archive_read_format_rar_read_header(struct archive_read *a,
                             sizeof(rar->reserved2));
                             sizeof(rar->reserved2));
       }
       }
 
 
+      /* Main header is password encrytped, so we cannot read any
+         file names or any other info about files from the header. */
       if (rar->main_flags & MHD_PASSWORD)
       if (rar->main_flags & MHD_PASSWORD)
       {
       {
-        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+        archive_entry_set_is_metadata_encrypted(entry, 1);
+        archive_entry_set_is_data_encrypted(entry, 1);
+        rar->has_encrypted_entries = 1;
+         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                           "RAR encryption support unavailable.");
                           "RAR encryption support unavailable.");
         return (ARCHIVE_FATAL);
         return (ARCHIVE_FATAL);
       }
       }
@@ -938,6 +990,10 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
   struct rar *rar = (struct rar *)(a->format->data);
   struct rar *rar = (struct rar *)(a->format->data);
   int ret;
   int ret;
 
 
+  if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+	  rar->has_encrypted_entries = 0;
+  }
+
   if (rar->bytes_unconsumed > 0) {
   if (rar->bytes_unconsumed > 0) {
       /* Consume as much as the decompressor actually used. */
       /* Consume as much as the decompressor actually used. */
       __archive_read_consume(a, rar->bytes_unconsumed);
       __archive_read_consume(a, rar->bytes_unconsumed);
@@ -957,7 +1013,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
   {
   {
   case COMPRESS_METHOD_STORE:
   case COMPRESS_METHOD_STORE:
     ret = read_data_stored(a, buff, size, offset);
     ret = read_data_stored(a, buff, size, offset);
-    break; 
+    break;
 
 
   case COMPRESS_METHOD_FASTEST:
   case COMPRESS_METHOD_FASTEST:
   case COMPRESS_METHOD_FAST:
   case COMPRESS_METHOD_FAST:
@@ -967,13 +1023,13 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
     ret = read_data_compressed(a, buff, size, offset);
     ret = read_data_compressed(a, buff, size, offset);
     if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
     if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
       __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
       __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
-    break; 
+    break;
 
 
   default:
   default:
     archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
     archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                       "Unsupported compression method for RAR file.");
                       "Unsupported compression method for RAR file.");
     ret = ARCHIVE_FATAL;
     ret = ARCHIVE_FATAL;
-    break; 
+    break;
   }
   }
   return (ret);
   return (ret);
 }
 }
@@ -1290,9 +1346,14 @@ read_header(struct archive_read *a, struct archive_entry *entry,
 
 
   if (rar->file_flags & FHD_PASSWORD)
   if (rar->file_flags & FHD_PASSWORD)
   {
   {
+	archive_entry_set_is_data_encrypted(entry, 1);
+	rar->has_encrypted_entries = 1;
     archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
     archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                       "RAR encryption support unavailable.");
                       "RAR encryption support unavailable.");
-    return (ARCHIVE_FATAL);
+    /* Since it is only the data part itself that is encrypted we can at least
+       extract information about the currently processed entry and don't need
+       to return ARCHIVE_FATAL here. */
+    /*return (ARCHIVE_FATAL);*/
   }
   }
 
 
   if (rar->file_flags & FHD_LARGE)
   if (rar->file_flags & FHD_LARGE)
@@ -1377,7 +1438,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
           flagbyte = *(p + offset++);
           flagbyte = *(p + offset++);
           flagbits = 8;
           flagbits = 8;
         }
         }
-	
+
         flagbits -= 2;
         flagbits -= 2;
         switch((flagbyte >> flagbits) & 3)
         switch((flagbyte >> flagbits) & 3)
         {
         {
@@ -2611,7 +2672,7 @@ expand(struct archive_read *a, int64_t end)
     if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
     if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
       return (ARCHIVE_FATAL);
       return (ARCHIVE_FATAL);
     rar->output_last_match = 0;
     rar->output_last_match = 0;
-    
+
     if (symbol < 256)
     if (symbol < 256)
     {
     {
       lzss_emit_literal(rar, symbol);
       lzss_emit_literal(rar, symbol);

+ 3 - 1
Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c

@@ -78,7 +78,9 @@ archive_read_support_format_raw(struct archive *_a)
 	    archive_read_format_raw_read_data,
 	    archive_read_format_raw_read_data,
 	    archive_read_format_raw_read_data_skip,
 	    archive_read_format_raw_read_data_skip,
 	    NULL,
 	    NULL,
-	    archive_read_format_raw_cleanup);
+	    archive_read_format_raw_cleanup,
+	    NULL,
+	    NULL);
 	if (r != ARCHIVE_OK)
 	if (r != ARCHIVE_OK)
 		free(info);
 		free(info);
 	return (r);
 	return (r);

+ 71 - 33
Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c

@@ -151,6 +151,8 @@ struct tar {
 	struct archive_string_conv *sconv_default;
 	struct archive_string_conv *sconv_default;
 	int			 init_default_conversion;
 	int			 init_default_conversion;
 	int			 compat_2x;
 	int			 compat_2x;
+	int			 process_mac_extensions;
+	int			 read_concatenated_archives;
 };
 };
 
 
 static int	archive_block_is_null(const char *p);
 static int	archive_block_is_null(const char *p);
@@ -241,6 +243,10 @@ archive_read_support_format_tar(struct archive *_a)
 	    ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
 	    ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
 
 
 	tar = (struct tar *)calloc(1, sizeof(*tar));
 	tar = (struct tar *)calloc(1, sizeof(*tar));
+#ifdef HAVE_COPYFILE_H
+	/* Set this by default on Mac OS. */
+	tar->process_mac_extensions = 1;
+#endif
 	if (tar == NULL) {
 	if (tar == NULL) {
 		archive_set_error(&a->archive, ENOMEM,
 		archive_set_error(&a->archive, ENOMEM,
 		    "Can't allocate tar data");
 		    "Can't allocate tar data");
@@ -254,7 +260,9 @@ archive_read_support_format_tar(struct archive *_a)
 	    archive_read_format_tar_read_data,
 	    archive_read_format_tar_read_data,
 	    archive_read_format_tar_skip,
 	    archive_read_format_tar_skip,
 	    NULL,
 	    NULL,
-	    archive_read_format_tar_cleanup);
+	    archive_read_format_tar_cleanup,
+	    NULL,
+	    NULL);
 
 
 	if (r != ARCHIVE_OK)
 	if (r != ARCHIVE_OK)
 		free(tar);
 		free(tar);
@@ -368,7 +376,7 @@ archive_read_format_tar_options(struct archive_read *a,
 	tar = (struct tar *)(a->format->data);
 	tar = (struct tar *)(a->format->data);
 	if (strcmp(key, "compat-2x")  == 0) {
 	if (strcmp(key, "compat-2x")  == 0) {
 		/* Handle UTF-8 filnames as libarchive 2.x */
 		/* Handle UTF-8 filnames as libarchive 2.x */
-		tar->compat_2x = (val != NULL)?1:0;
+		tar->compat_2x = (val != NULL && val[0] != 0);
 		tar->init_default_conversion = tar->compat_2x;
 		tar->init_default_conversion = tar->compat_2x;
 		return (ARCHIVE_OK);
 		return (ARCHIVE_OK);
 	} else if (strcmp(key, "hdrcharset")  == 0) {
 	} else if (strcmp(key, "hdrcharset")  == 0) {
@@ -385,6 +393,12 @@ archive_read_format_tar_options(struct archive_read *a,
 				ret = ARCHIVE_FATAL;
 				ret = ARCHIVE_FATAL;
 		}
 		}
 		return (ret);
 		return (ret);
+	} else if (strcmp(key, "mac-ext") == 0) {
+		tar->process_mac_extensions = (val != NULL && val[0] != 0);
+		return (ARCHIVE_OK);
+	} else if (strcmp(key, "read_concatenated_archives") == 0) {
+		tar->read_concatenated_archives = (val != NULL && val[0] != 0);
+		return (ARCHIVE_OK);
 	}
 	}
 
 
 	/* Note: The "warn" return is just to inform the options
 	/* Note: The "warn" return is just to inform the options
@@ -397,7 +411,7 @@ archive_read_format_tar_options(struct archive_read *a,
  * how much unconsumed data we have floating around, and to consume
  * how much unconsumed data we have floating around, and to consume
  * anything outstanding since we're going to do read_aheads
  * anything outstanding since we're going to do read_aheads
  */
  */
-static void 
+static void
 tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed)
 tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed)
 {
 {
 	if (*unconsumed) {
 	if (*unconsumed) {
@@ -590,7 +604,7 @@ archive_read_format_tar_skip(struct archive_read *a)
 	tar = (struct tar *)(a->format->data);
 	tar = (struct tar *)(a->format->data);
 
 
 	bytes_skipped = __archive_read_consume(a,
 	bytes_skipped = __archive_read_consume(a,
-	    tar->entry_bytes_remaining + tar->entry_padding + 
+	    tar->entry_bytes_remaining + tar->entry_padding +
 	    tar->entry_bytes_unconsumed);
 	    tar->entry_bytes_unconsumed);
 	if (bytes_skipped < 0)
 	if (bytes_skipped < 0)
 		return (ARCHIVE_FATAL);
 		return (ARCHIVE_FATAL);
@@ -619,36 +633,50 @@ tar_read_header(struct archive_read *a, struct tar *tar,
 	const struct archive_entry_header_ustar *header;
 	const struct archive_entry_header_ustar *header;
 	const struct archive_entry_header_gnutar *gnuheader;
 	const struct archive_entry_header_gnutar *gnuheader;
 
 
-	tar_flush_unconsumed(a, unconsumed);
+	/* Loop until we find a workable header record. */
+	for (;;) {
+		tar_flush_unconsumed(a, unconsumed);
 
 
-	/* Read 512-byte header record */
-	h = __archive_read_ahead(a, 512, &bytes);
-	if (bytes < 0)
-		return ((int)bytes);
-	if (bytes == 0) { /* EOF at a block boundary. */
-		/* Some writers do omit the block of nulls. <sigh> */
-		return (ARCHIVE_EOF);
-	}
-	if (bytes < 512) {  /* Short block at EOF; this is bad. */
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-		    "Truncated tar archive");
-		return (ARCHIVE_FATAL);
-	}
-	*unconsumed = 512;
+		/* Read 512-byte header record */
+		h = __archive_read_ahead(a, 512, &bytes);
+		if (bytes < 0)
+			return ((int)bytes);
+		if (bytes == 0) { /* EOF at a block boundary. */
+			/* Some writers do omit the block of nulls. <sigh> */
+			return (ARCHIVE_EOF);
+		}
+		if (bytes < 512) {  /* Short block at EOF; this is bad. */
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Truncated tar archive");
+			return (ARCHIVE_FATAL);
+		}
+		*unconsumed = 512;
 
 
-	/* Check for end-of-archive mark. */
-	if (h[0] == 0 && archive_block_is_null(h)) {
-		/* Try to consume a second all-null record, as well. */
-		tar_flush_unconsumed(a, unconsumed);
-		h = __archive_read_ahead(a, 512, NULL);
-		if (h != NULL)
-			__archive_read_consume(a, 512);
-		archive_clear_error(&a->archive);
+		/* Header is workable if it's not an end-of-archive mark. */
+		if (h[0] != 0 || !archive_block_is_null(h))
+			break;
+
+		/* Ensure format is set for archives with only null blocks. */
 		if (a->archive.archive_format_name == NULL) {
 		if (a->archive.archive_format_name == NULL) {
 			a->archive.archive_format = ARCHIVE_FORMAT_TAR;
 			a->archive.archive_format = ARCHIVE_FORMAT_TAR;
 			a->archive.archive_format_name = "tar";
 			a->archive.archive_format_name = "tar";
 		}
 		}
-		return (ARCHIVE_EOF);
+
+		if (!tar->read_concatenated_archives) {
+			/* Try to consume a second all-null record, as well. */
+			tar_flush_unconsumed(a, unconsumed);
+			h = __archive_read_ahead(a, 512, NULL);
+			if (h != NULL && h[0] == 0 && archive_block_is_null(h))
+				__archive_read_consume(a, 512);
+			archive_clear_error(&a->archive);
+			return (ARCHIVE_EOF);
+		}
+
+		/*
+		 * We're reading concatenated archives, ignore this block and
+		 * loop to get the next.
+		 */
 	}
 	}
 
 
 	/*
 	/*
@@ -683,6 +711,8 @@ tar_read_header(struct archive_read *a, struct tar *tar,
 		a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
 		a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
 		a->archive.archive_format_name = "POSIX pax interchange format";
 		a->archive.archive_format_name = "POSIX pax interchange format";
 		err = header_pax_global(a, tar, entry, h, unconsumed);
 		err = header_pax_global(a, tar, entry, h, unconsumed);
+		if (err == ARCHIVE_EOF)
+			return (err);
 		break;
 		break;
 	case 'K': /* Long link name (GNU tar, others) */
 	case 'K': /* Long link name (GNU tar, others) */
 		err = header_longlink(a, tar, entry, h, unconsumed);
 		err = header_longlink(a, tar, entry, h, unconsumed);
@@ -735,9 +765,9 @@ tar_read_header(struct archive_read *a, struct tar *tar,
 	 * extensions for both the AppleDouble extension entry and the
 	 * extensions for both the AppleDouble extension entry and the
 	 * regular entry.
 	 * regular entry.
 	 */
 	 */
-	/* TODO: Should this be disabled on non-Mac platforms? */
 	if ((err == ARCHIVE_WARN || err == ARCHIVE_OK) &&
 	if ((err == ARCHIVE_WARN || err == ARCHIVE_OK) &&
-	    tar->header_recursion_depth == 0) {
+	    tar->header_recursion_depth == 0 &&
+	    tar->process_mac_extensions) {
 		int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed);
 		int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed);
 		if (err2 < err)
 		if (err2 < err)
 			err = err2;
 			err = err2;
@@ -780,12 +810,20 @@ checksum(struct archive_read *a, const void *h)
 {
 {
 	const unsigned char *bytes;
 	const unsigned char *bytes;
 	const struct archive_entry_header_ustar	*header;
 	const struct archive_entry_header_ustar	*header;
-	int check, i, sum;
+	int check, sum;
+	size_t i;
 
 
 	(void)a; /* UNUSED */
 	(void)a; /* UNUSED */
 	bytes = (const unsigned char *)h;
 	bytes = (const unsigned char *)h;
 	header = (const struct archive_entry_header_ustar *)h;
 	header = (const struct archive_entry_header_ustar *)h;
 
 
+	/* Checksum field must hold an octal number */
+	for (i = 0; i < sizeof(header->checksum); ++i) {
+		char c = header->checksum[i];
+		if (c != ' ' && c != '\0' && (c < '0' || c > '7'))
+			return 0;
+	}
+
 	/*
 	/*
 	 * Test the checksum.  Note that POSIX specifies _unsigned_
 	 * Test the checksum.  Note that POSIX specifies _unsigned_
 	 * bytes for this calculation.
 	 * bytes for this calculation.
@@ -1277,7 +1315,7 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
 			if (wp[0] == '/' && wp[1] != L'\0')
 			if (wp[0] == '/' && wp[1] != L'\0')
 				wname = wp + 1;
 				wname = wp + 1;
 		}
 		}
-		/* 
+		/*
 		 * If last path element starts with "._", then
 		 * If last path element starts with "._", then
 		 * this is a Mac extension.
 		 * this is a Mac extension.
 		 */
 		 */
@@ -1292,7 +1330,7 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
 			if (p[0] == '/' && p[1] != '\0')
 			if (p[0] == '/' && p[1] != '\0')
 				name = p + 1;
 				name = p + 1;
 		}
 		}
-		/* 
+		/*
 		 * If last path element starts with "._", then
 		 * If last path element starts with "._", then
 		 * this is a Mac extension.
 		 * this is a Mac extension.
 		 */
 		 */

+ 11 - 5
Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c

@@ -468,7 +468,9 @@ archive_read_support_format_xar(struct archive *_a)
 	    xar_read_data,
 	    xar_read_data,
 	    xar_read_data_skip,
 	    xar_read_data_skip,
 	    NULL,
 	    NULL,
-	    xar_cleanup);
+	    xar_cleanup,
+	    NULL,
+	    NULL);
 	if (r != ARCHIVE_OK)
 	if (r != ARCHIVE_OK)
 		free(xar);
 		free(xar);
 	return (r);
 	return (r);
@@ -967,10 +969,14 @@ move_reading_point(struct archive_read *a, uint64_t offset)
 				return ((int)step);
 				return ((int)step);
 			xar->offset += step;
 			xar->offset += step;
 		} else {
 		} else {
-			archive_set_error(&(a->archive),
-			    ARCHIVE_ERRNO_MISC,
-			    "Cannot seek.");
-			return (ARCHIVE_FAILED);
+			int64_t pos = __archive_read_seek(a, offset, SEEK_SET);
+			if (pos == ARCHIVE_FAILED) {
+				archive_set_error(&(a->archive),
+				    ARCHIVE_ERRNO_MISC,
+				    "Cannot seek.");
+				return (ARCHIVE_FAILED);
+			}
+			xar->offset = pos;
 		}
 		}
 	}
 	}
 	return (ARCHIVE_OK);
 	return (ARCHIVE_OK);

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 526 - 584
Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c


+ 109 - 0
Utilities/cmlibarchive/libarchive/archive_util.c

@@ -45,6 +45,15 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
 #if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
 #if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
 #include <wincrypt.h>
 #include <wincrypt.h>
 #endif
 #endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <cm_bzlib.h>
+#endif
 
 
 #include "archive.h"
 #include "archive.h"
 #include "archive_private.h"
 #include "archive_private.h"
@@ -54,6 +63,8 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
 #define O_CLOEXEC	0
 #define O_CLOEXEC	0
 #endif
 #endif
 
 
+static int archive_utility_string_sort_helper(char **, unsigned int);
+
 /* Generic initialization of 'struct archive' objects. */
 /* Generic initialization of 'struct archive' objects. */
 int
 int
 __archive_clean(struct archive *a)
 __archive_clean(struct archive *a)
@@ -74,6 +85,38 @@ archive_version_string(void)
 	return (ARCHIVE_VERSION_STRING);
 	return (ARCHIVE_VERSION_STRING);
 }
 }
 
 
+const char *
+archive_version_details(void)
+{
+	static struct archive_string str;
+	static int init = 0;
+
+	if (!init) {
+		archive_string_init(&str);
+
+		archive_strcat(&str, ARCHIVE_VERSION_STRING);
+#ifdef HAVE_ZLIB_H
+		archive_strcat(&str, " zlib/");
+		archive_strcat(&str, ZLIB_VERSION);
+#endif
+#ifdef HAVE_LZMA_H
+		archive_strcat(&str, " liblzma/");
+		archive_strcat(&str, LZMA_VERSION_STRING);
+#endif
+#ifdef HAVE_BZLIB_H
+		{
+			const char *p = BZ2_bzlibVersion();
+			const char *sep = strchr(p, ',');
+			if (sep == NULL)
+				sep = p + strlen(p);
+			archive_strcat(&str, " bz2lib/");
+			archive_strncat(&str, p, sep - p);
+		}
+#endif
+	    }
+	return str.s;
+}
+
 int
 int
 archive_errno(struct archive *a)
 archive_errno(struct archive *a)
 {
 {
@@ -499,3 +542,69 @@ __archive_ensure_cloexec_flag(int fd)
 	}
 	}
 #endif
 #endif
 }
 }
+
+/*
+ * Utility function to sort a group of strings using quicksort.
+ */
+static int
+archive_utility_string_sort_helper(char **strings, unsigned int n)
+{
+  unsigned int i, lesser_count, greater_count;
+  char **lesser, **greater, **tmp, *pivot;
+  int retval1, retval2;
+
+  /* A list of 0 or 1 elements is already sorted */
+  if (n <= 1)
+    return (ARCHIVE_OK);
+
+  lesser_count = greater_count = 0;
+  lesser = greater = NULL;
+  pivot = strings[0];
+  for (i = 1; i < n; i++)
+  {
+    if (strcmp(strings[i], pivot) < 0)
+    {
+      lesser_count++;
+      tmp = (char **)realloc(lesser, lesser_count * sizeof(char *));
+      if (!tmp)
+        return (ARCHIVE_FATAL);
+      lesser = tmp;
+      lesser[lesser_count - 1] = strings[i];
+    }
+    else
+    {
+      greater_count++;
+      tmp = (char **)realloc(greater, greater_count * sizeof(char *));
+      if (!tmp)
+        return (ARCHIVE_FATAL);
+      greater = tmp;
+      greater[greater_count - 1] = strings[i];
+    }
+  }
+
+  /* quicksort(lesser) */
+  retval1 = archive_utility_string_sort_helper(lesser, lesser_count);
+  for (i = 0; i < lesser_count; i++)
+    strings[i] = lesser[i];
+  free(lesser);
+
+  /* pivot */
+  strings[lesser_count] = pivot;
+
+  /* quicksort(greater) */
+  retval2 = archive_utility_string_sort_helper(greater, greater_count);
+  for (i = 0; i < greater_count; i++)
+    strings[lesser_count + 1 + i] = greater[i];
+  free(greater);
+
+  return (retval1 < retval2) ? retval1 : retval2;
+}
+
+int
+archive_utility_string_sort(char **strings)
+{
+  unsigned int size = 0;
+  while (strings[size] != NULL)
+    size++;
+  return archive_utility_string_sort_helper(strings, size);
+}

+ 10 - 6
Utilities/cmlibarchive/libarchive/archive_virtual.c

@@ -54,6 +54,14 @@ archive_filter_bytes(struct archive *a, int n)
 	return ((a->vtable->archive_filter_bytes)(a, n));
 	return ((a->vtable->archive_filter_bytes)(a, n));
 }
 }
 
 
+int
+archive_free(struct archive *a)
+{
+	if (a == NULL)
+		return (ARCHIVE_OK);
+	return ((a->vtable->archive_free)(a));
+}
+
 int
 int
 archive_write_close(struct archive *a)
 archive_write_close(struct archive *a)
 {
 {
@@ -76,9 +84,7 @@ archive_write_fail(struct archive *a)
 int
 int
 archive_write_free(struct archive *a)
 archive_write_free(struct archive *a)
 {
 {
-	if (a == NULL)
-		return (ARCHIVE_OK);
-	return ((a->vtable->archive_free)(a));
+	return archive_free(a);
 }
 }
 
 
 #if ARCHIVE_VERSION_NUMBER < 4000000
 #if ARCHIVE_VERSION_NUMBER < 4000000
@@ -93,9 +99,7 @@ archive_write_finish(struct archive *a)
 int
 int
 archive_read_free(struct archive *a)
 archive_read_free(struct archive *a)
 {
 {
-	if (a == NULL)
-		return (ARCHIVE_OK);
-	return ((a->vtable->archive_free)(a));
+	return archive_free(a);
 }
 }
 
 
 #if ARCHIVE_VERSION_NUMBER < 4000000
 #if ARCHIVE_VERSION_NUMBER < 4000000

+ 5 - 5
Utilities/cmlibarchive/libarchive/archive_windows.c

@@ -301,7 +301,7 @@ __la_open(const char *path, int flags, ...)
 	ws = NULL;
 	ws = NULL;
 	if ((flags & ~O_BINARY) == O_RDONLY) {
 	if ((flags & ~O_BINARY) == O_RDONLY) {
 		/*
 		/*
-		 * When we open a directory, _open function returns 
+		 * When we open a directory, _open function returns
 		 * "Permission denied" error.
 		 * "Permission denied" error.
 		 */
 		 */
 		attr = GetFileAttributesA(path);
 		attr = GetFileAttributesA(path);
@@ -515,9 +515,9 @@ __hstat(HANDLE handle, struct ustat *st)
 	else
 	else
 		mode |= S_IFREG;
 		mode |= S_IFREG;
 	st->st_mode = mode;
 	st->st_mode = mode;
-	
+
 	fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
 	fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
-	st->st_atime = t; 
+	st->st_atime = t;
 	st->st_atime_nsec = ns;
 	st->st_atime_nsec = ns;
 	fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
 	fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
 	st->st_mtime = t;
 	st->st_mtime = t;
@@ -525,7 +525,7 @@ __hstat(HANDLE handle, struct ustat *st)
 	fileTimeToUTC(&info.ftCreationTime, &t, &ns);
 	fileTimeToUTC(&info.ftCreationTime, &t, &ns);
 	st->st_ctime = t;
 	st->st_ctime = t;
 	st->st_ctime_nsec = ns;
 	st->st_ctime_nsec = ns;
-	st->st_size = 
+	st->st_size =
 	    ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
 	    ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
 		+ (int64_t)(info.nFileSizeLow);
 		+ (int64_t)(info.nFileSizeLow);
 #ifdef SIMULATE_WIN_STAT
 #ifdef SIMULATE_WIN_STAT
@@ -599,7 +599,7 @@ __la_stat(const char *path, struct stat *st)
 	struct ustat u;
 	struct ustat u;
 	int ret;
 	int ret;
 
 
-	handle = la_CreateFile(path, 0, 0, NULL, OPEN_EXISTING,
+	handle = la_CreateFile(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
 		FILE_FLAG_BACKUP_SEMANTICS,
 		FILE_FLAG_BACKUP_SEMANTICS,
 		NULL);
 		NULL);
 	if (handle == INVALID_HANDLE_VALUE) {
 	if (handle == INVALID_HANDLE_VALUE) {

+ 7 - 5
Utilities/cmlibarchive/libarchive/archive_windows.h

@@ -93,7 +93,7 @@
 
 
 /* Alias the Windows _function to the POSIX equivalent. */
 /* Alias the Windows _function to the POSIX equivalent. */
 #define	close		_close
 #define	close		_close
-#define	fcntl(fd, cmd, flg)	/* No operation. */		
+#define	fcntl(fd, cmd, flg)	/* No operation. */
 #ifndef fileno
 #ifndef fileno
 #define	fileno		_fileno
 #define	fileno		_fileno
 #endif
 #endif
@@ -113,13 +113,14 @@
 #define	lstat		__la_stat
 #define	lstat		__la_stat
 #define	open		__la_open
 #define	open		__la_open
 #define	read		__la_read
 #define	read		__la_read
-#if !defined(__BORLANDC__)
+#if !defined(__BORLANDC__) && !defined(__WATCOMC__)
 #define setmode		_setmode
 #define setmode		_setmode
 #endif
 #endif
 #ifdef stat
 #ifdef stat
 #undef stat
 #undef stat
 #endif
 #endif
 #define	stat(path,stref)		__la_stat(path,stref)
 #define	stat(path,stref)		__la_stat(path,stref)
+#if !defined(__WATCOMC__)
 #if !defined(__BORLANDC__)
 #if !defined(__BORLANDC__)
 #define	strdup		_strdup
 #define	strdup		_strdup
 #endif
 #endif
@@ -127,9 +128,12 @@
 #if !defined(__BORLANDC__)
 #if !defined(__BORLANDC__)
 #define	umask		_umask
 #define	umask		_umask
 #endif
 #endif
+#endif
 #define	waitpid		__la_waitpid
 #define	waitpid		__la_waitpid
 #define	write		__la_write
 #define	write		__la_write
 
 
+#if !defined(__WATCOMC__)
+
 #ifndef O_RDONLY
 #ifndef O_RDONLY
 #define	O_RDONLY	_O_RDONLY
 #define	O_RDONLY	_O_RDONLY
 #define	O_WRONLY	_O_WRONLY
 #define	O_WRONLY	_O_WRONLY
@@ -189,8 +193,6 @@
 #define	S_ISREG(m)	(((m) & S_IFMT) == S_IFREG)	/* regular file */
 #define	S_ISREG(m)	(((m) & S_IFMT) == S_IFREG)	/* regular file */
 #endif
 #endif
 
 
-#if !defined(__WATCOMC__) 
-
 #define	S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK) /* Symbolic link */
 #define	S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK) /* Symbolic link */
 #define	S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) /* Socket */
 #define	S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) /* Socket */
 
 
@@ -210,7 +212,7 @@
 #define	_S_IXGRP        (_S_IXUSR >> 3) /* read permission, group */
 #define	_S_IXGRP        (_S_IXUSR >> 3) /* read permission, group */
 #define	_S_IWGRP        (_S_IWUSR >> 3) /* write permission, group */
 #define	_S_IWGRP        (_S_IWUSR >> 3) /* write permission, group */
 #define	_S_IRGRP        (_S_IRUSR >> 3) /* execute/search permission, group */
 #define	_S_IRGRP        (_S_IRUSR >> 3) /* execute/search permission, group */
-#define	_S_IRWXO        (_S_IRWXG >> 3) 
+#define	_S_IRWXO        (_S_IRWXG >> 3)
 #define	_S_IXOTH        (_S_IXGRP >> 3) /* read permission, other */
 #define	_S_IXOTH        (_S_IXGRP >> 3) /* read permission, other */
 #define	_S_IWOTH        (_S_IWGRP >> 3) /* write permission, other */
 #define	_S_IWOTH        (_S_IWGRP >> 3) /* write permission, other */
 #define	_S_IROTH        (_S_IRGRP  >> 3) /* execute/search permission, other */
 #define	_S_IROTH        (_S_IRGRP  >> 3) /* execute/search permission, other */

+ 13 - 3
Utilities/cmlibarchive/libarchive/archive_write.c

@@ -503,8 +503,9 @@ _archive_write_close(struct archive *_a)
 
 
 	archive_clear_error(&a->archive);
 	archive_clear_error(&a->archive);
 
 
-	/* Finish the last entry. */
-	if (a->archive.state == ARCHIVE_STATE_DATA)
+	/* Finish the last entry if a finish callback is specified */
+	if (a->archive.state == ARCHIVE_STATE_DATA
+	    && a->format_finish_entry != NULL)
 		r = ((a->format_finish_entry)(a));
 		r = ((a->format_finish_entry)(a));
 
 
 	/* Finish off the archive. */
 	/* Finish off the archive. */
@@ -638,6 +639,9 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
 
 
 	/* Format and write header. */
 	/* Format and write header. */
 	r2 = ((a->format_write_header)(a, entry));
 	r2 = ((a->format_write_header)(a, entry));
+	if (r2 == ARCHIVE_FAILED) {
+		return (ARCHIVE_FAILED);
+	}
 	if (r2 == ARCHIVE_FATAL) {
 	if (r2 == ARCHIVE_FATAL) {
 		a->archive.state = ARCHIVE_STATE_FATAL;
 		a->archive.state = ARCHIVE_STATE_FATAL;
 		return (ARCHIVE_FATAL);
 		return (ARCHIVE_FATAL);
@@ -658,7 +662,8 @@ _archive_write_finish_entry(struct archive *_a)
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
 	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
 	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
 	    "archive_write_finish_entry");
 	    "archive_write_finish_entry");
-	if (a->archive.state & ARCHIVE_STATE_DATA)
+	if (a->archive.state & ARCHIVE_STATE_DATA
+	    && a->format_finish_entry != NULL)
 		ret = (a->format_finish_entry)(a);
 		ret = (a->format_finish_entry)(a);
 	a->archive.state = ARCHIVE_STATE_HEADER;
 	a->archive.state = ARCHIVE_STATE_HEADER;
 	return (ret);
 	return (ret);
@@ -671,8 +676,13 @@ static ssize_t
 _archive_write_data(struct archive *_a, const void *buff, size_t s)
 _archive_write_data(struct archive *_a, const void *buff, size_t s)
 {
 {
 	struct archive_write *a = (struct archive_write *)_a;
 	struct archive_write *a = (struct archive_write *)_a;
+	const size_t max_write = INT_MAX;
+
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
 	    ARCHIVE_STATE_DATA, "archive_write_data");
 	    ARCHIVE_STATE_DATA, "archive_write_data");
+	/* In particular, this catches attempts to pass negative values. */
+	if (s > max_write)
+		s = max_write;
 	archive_clear_error(&a->archive);
 	archive_clear_error(&a->archive);
 	return ((a->format_write_data)(a, buff, s));
 	return ((a->format_write_data)(a, buff, s));
 }
 }

+ 6 - 1
Utilities/cmlibarchive/libarchive/archive_write_add_filter_lrzip.c

@@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
 struct write_lrzip {
 struct write_lrzip {
 	struct archive_write_program_data *pdata;
 	struct archive_write_program_data *pdata;
 	int	compression_level;
 	int	compression_level;
-	enum { lzma = 0, bzip2, gzip, lzo, zpaq } compression;
+	enum { lzma = 0, bzip2, gzip, lzo, none, zpaq } compression;
 };
 };
 
 
 static int archive_write_lrzip_open(struct archive_write_filter *);
 static int archive_write_lrzip_open(struct archive_write_filter *);
@@ -107,6 +107,8 @@ archive_write_lrzip_options(struct archive_write_filter *f, const char *key,
 			data->compression = gzip;
 			data->compression = gzip;
 		else if (strcmp(value, "lzo") == 0)
 		else if (strcmp(value, "lzo") == 0)
 			data->compression = lzo;
 			data->compression = lzo;
+		else if (strcmp(value, "none") == 0)
+			data->compression = none;
 		else if (strcmp(value, "zpaq") == 0)
 		else if (strcmp(value, "zpaq") == 0)
 			data->compression = zpaq;
 			data->compression = zpaq;
 		else
 		else
@@ -148,6 +150,9 @@ archive_write_lrzip_open(struct archive_write_filter *f)
 	case lzo:
 	case lzo:
 		archive_strcat(&as, " -l");
 		archive_strcat(&as, " -l");
 		break;
 		break;
+	case none:
+		archive_strcat(&as, " -n");
+		break;
 	case zpaq:
 	case zpaq:
 		archive_strcat(&as, " -z");
 		archive_strcat(&as, " -z");
 		break;
 		break;

+ 15 - 1
Utilities/cmlibarchive/libarchive/archive_write_disk_acl.c

@@ -43,7 +43,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
 #include "archive_acl_private.h"
 #include "archive_acl_private.h"
 #include "archive_write_disk_private.h"
 #include "archive_write_disk_private.h"
 
 
-#if !defined(HAVE_POSIX_ACL) || !defined(ACL_TYPE_NFS4)
+#ifndef HAVE_POSIX_ACL
 /* Default empty function body to satisfy mainline code. */
 /* Default empty function body to satisfy mainline code. */
 int
 int
 archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
 archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
@@ -79,10 +79,12 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
 		ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
 		ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
 		    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
 		    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
 		return (ret);
 		return (ret);
+#ifdef ACL_TYPE_NFS4
 	} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0) {
 	} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0) {
 		ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
 		ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
 		    ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
 		    ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
 		return (ret);
 		return (ret);
+#endif
 	} else
 	} else
 		return ARCHIVE_OK;
 		return ARCHIVE_OK;
 }
 }
@@ -94,6 +96,7 @@ static struct {
 	{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
 	{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
 	{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
 	{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
 	{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
 	{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+#ifdef ACL_TYPE_NFS4
 	{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
 	{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
 	{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
 	{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
 	{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
 	{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
@@ -110,8 +113,10 @@ static struct {
 	{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
 	{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
 	{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
 	{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
 	{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
 	{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+#endif
 };
 };
 
 
+#ifdef ACL_TYPE_NFS4
 static struct {
 static struct {
 	int archive_inherit;
 	int archive_inherit;
 	int platform_inherit;
 	int platform_inherit;
@@ -121,6 +126,7 @@ static struct {
 	{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
 	{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
 	{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
 	{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
 };
 };
+#endif
 
 
 static int
 static int
 set_acl(struct archive *a, int fd, const char *name,
 set_acl(struct archive *a, int fd, const char *name,
@@ -130,7 +136,9 @@ set_acl(struct archive *a, int fd, const char *name,
 	acl_t		 acl;
 	acl_t		 acl;
 	acl_entry_t	 acl_entry;
 	acl_entry_t	 acl_entry;
 	acl_permset_t	 acl_permset;
 	acl_permset_t	 acl_permset;
+#ifdef ACL_TYPE_NFS4
 	acl_flagset_t	 acl_flagset;
 	acl_flagset_t	 acl_flagset;
+#endif
 	int		 ret;
 	int		 ret;
 	int		 ae_type, ae_permset, ae_tag, ae_id;
 	int		 ae_type, ae_permset, ae_tag, ae_id;
 	uid_t		 ae_uid;
 	uid_t		 ae_uid;
@@ -171,14 +179,17 @@ set_acl(struct archive *a, int fd, const char *name,
 		case ARCHIVE_ENTRY_ACL_OTHER:
 		case ARCHIVE_ENTRY_ACL_OTHER:
 			acl_set_tag_type(acl_entry, ACL_OTHER);
 			acl_set_tag_type(acl_entry, ACL_OTHER);
 			break;
 			break;
+#ifdef ACL_TYPE_NFS4
 		case ARCHIVE_ENTRY_ACL_EVERYONE:
 		case ARCHIVE_ENTRY_ACL_EVERYONE:
 			acl_set_tag_type(acl_entry, ACL_EVERYONE);
 			acl_set_tag_type(acl_entry, ACL_EVERYONE);
 			break;
 			break;
+#endif
 		default:
 		default:
 			/* XXX */
 			/* XXX */
 			break;
 			break;
 		}
 		}
 
 
+#ifdef ACL_TYPE_NFS4
 		switch (ae_type) {
 		switch (ae_type) {
 		case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
 		case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
 			acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
 			acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
@@ -200,6 +211,7 @@ set_acl(struct archive *a, int fd, const char *name,
 			// XXX error handling here.
 			// XXX error handling here.
 			break;
 			break;
 		}
 		}
+#endif
 
 
 		acl_get_permset(acl_entry, &acl_permset);
 		acl_get_permset(acl_entry, &acl_permset);
 		acl_clear_perms(acl_permset);
 		acl_clear_perms(acl_permset);
@@ -210,6 +222,7 @@ set_acl(struct archive *a, int fd, const char *name,
 					     acl_perm_map[i].platform_perm);
 					     acl_perm_map[i].platform_perm);
 		}
 		}
 
 
+#ifdef ACL_TYPE_NFS4
 		acl_get_flagset_np(acl_entry, &acl_flagset);
 		acl_get_flagset_np(acl_entry, &acl_flagset);
 		acl_clear_flags_np(acl_flagset);
 		acl_clear_flags_np(acl_flagset);
 		for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
 		for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
@@ -217,6 +230,7 @@ set_acl(struct archive *a, int fd, const char *name,
 				acl_add_flag_np(acl_flagset,
 				acl_add_flag_np(acl_flagset,
 						acl_inherit_map[i].platform_inherit);
 						acl_inherit_map[i].platform_inherit);
 		}
 		}
+#endif
 	}
 	}
 
 
 	/* Try restoring the ACL through 'fd' if we can. */
 	/* Try restoring the ACL through 'fd' if we can. */

+ 1 - 1
Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c

@@ -525,7 +525,7 @@ la_GetFunctionKernel32(const char *name)
 	static int set;
 	static int set;
 	if (!set) {
 	if (!set) {
 		set = 1;
 		set = 1;
-		lib = LoadLibrary("kernel32.dll");
+		lib = LoadLibrary(TEXT("kernel32.dll"));
 	}
 	}
 	if (lib == NULL) {
 	if (lib == NULL) {
 		fprintf(stderr, "Can't load kernel32.dll?!\n");
 		fprintf(stderr, "Can't load kernel32.dll?!\n");

+ 4 - 1
Utilities/cmlibarchive/libarchive/archive_write_format.3

@@ -24,13 +24,14 @@
 .\"
 .\"
 .\" $FreeBSD$
 .\" $FreeBSD$
 .\"
 .\"
-.Dd February 2, 2012
+.Dd February 14, 2013
 .Dt ARCHIVE_WRITE_FORMAT 3
 .Dt ARCHIVE_WRITE_FORMAT 3
 .Os
 .Os
 .Sh NAME
 .Sh NAME
 .Nm archive_write_set_format_cpio ,
 .Nm archive_write_set_format_cpio ,
 .Nm archive_write_set_format_pax ,
 .Nm archive_write_set_format_pax ,
 .Nm archive_write_set_format_pax_restricted ,
 .Nm archive_write_set_format_pax_restricted ,
+.Nm archive_write_set_format_raw ,
 .Nm archive_write_set_format_shar ,
 .Nm archive_write_set_format_shar ,
 .Nm archive_write_set_format_shar_dump ,
 .Nm archive_write_set_format_shar_dump ,
 .Nm archive_write_set_format_ustar
 .Nm archive_write_set_format_ustar
@@ -46,6 +47,8 @@ Streaming Archive Library (libarchive, -larchive)
 .Ft int
 .Ft int
 .Fn archive_write_set_format_pax_restricted "struct archive *"
 .Fn archive_write_set_format_pax_restricted "struct archive *"
 .Ft int
 .Ft int
+.Fn archive_write_set_format_raw "struct archive *"
+.Ft int
 .Fn archive_write_set_format_shar "struct archive *"
 .Fn archive_write_set_format_shar "struct archive *"
 .Ft int
 .Ft int
 .Fn archive_write_set_format_shar_dump "struct archive *"
 .Fn archive_write_set_format_shar_dump "struct archive *"

+ 2 - 1
Utilities/cmlibarchive/libarchive/archive_write_set_format.c

@@ -47,6 +47,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
 	{ ARCHIVE_FORMAT_CPIO_SVR4_NOCRC,	archive_write_set_format_cpio_newc },
 	{ ARCHIVE_FORMAT_CPIO_SVR4_NOCRC,	archive_write_set_format_cpio_newc },
 	{ ARCHIVE_FORMAT_ISO9660,	archive_write_set_format_iso9660 },
 	{ ARCHIVE_FORMAT_ISO9660,	archive_write_set_format_iso9660 },
 	{ ARCHIVE_FORMAT_MTREE,		archive_write_set_format_mtree },
 	{ ARCHIVE_FORMAT_MTREE,		archive_write_set_format_mtree },
+	{ ARCHIVE_FORMAT_RAW,		archive_write_set_format_raw },
 	{ ARCHIVE_FORMAT_SHAR,		archive_write_set_format_shar },
 	{ ARCHIVE_FORMAT_SHAR,		archive_write_set_format_shar },
 	{ ARCHIVE_FORMAT_SHAR_BASE,	archive_write_set_format_shar },
 	{ ARCHIVE_FORMAT_SHAR_BASE,	archive_write_set_format_shar },
 	{ ARCHIVE_FORMAT_SHAR_DUMP,	archive_write_set_format_shar_dump },
 	{ ARCHIVE_FORMAT_SHAR_DUMP,	archive_write_set_format_shar_dump },
@@ -57,7 +58,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
 				archive_write_set_format_pax_restricted },
 				archive_write_set_format_pax_restricted },
 	{ ARCHIVE_FORMAT_TAR_USTAR,	archive_write_set_format_ustar },
 	{ ARCHIVE_FORMAT_TAR_USTAR,	archive_write_set_format_ustar },
 	{ ARCHIVE_FORMAT_XAR,		archive_write_set_format_xar },
 	{ ARCHIVE_FORMAT_XAR,		archive_write_set_format_xar },
-	{ ARCHIVE_FORMAT_ZIP,	archive_write_set_format_zip },
+	{ ARCHIVE_FORMAT_ZIP,		archive_write_set_format_zip },
 	{ 0,		NULL }
 	{ 0,		NULL }
 };
 };
 
 

+ 1 - 0
Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c

@@ -63,6 +63,7 @@ struct { const char *name; int (*setter)(struct archive *); } names[] =
 	{ "pax",	archive_write_set_format_pax },
 	{ "pax",	archive_write_set_format_pax },
 	{ "paxr",	archive_write_set_format_pax_restricted },
 	{ "paxr",	archive_write_set_format_pax_restricted },
 	{ "posix",	archive_write_set_format_pax },
 	{ "posix",	archive_write_set_format_pax },
+	{ "raw",	archive_write_set_format_raw },
 	{ "rpax",	archive_write_set_format_pax_restricted },
 	{ "rpax",	archive_write_set_format_pax_restricted },
 	{ "shar",	archive_write_set_format_shar },
 	{ "shar",	archive_write_set_format_shar },
 	{ "shardump",	archive_write_set_format_shar_dump },
 	{ "shardump",	archive_write_set_format_shar_dump },

+ 31 - 6
Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c

@@ -128,6 +128,9 @@ struct mtree_entry {
 	unsigned long fflags_clear;
 	unsigned long fflags_clear;
 	dev_t rdevmajor;
 	dev_t rdevmajor;
 	dev_t rdevminor;
 	dev_t rdevminor;
+	dev_t devmajor;
+	dev_t devminor;
+	int64_t ino;
 };
 };
 
 
 struct mtree_writer {
 struct mtree_writer {
@@ -210,6 +213,9 @@ struct mtree_writer {
 #define	F_SHA256	0x00800000		/* SHA-256 digest */
 #define	F_SHA256	0x00800000		/* SHA-256 digest */
 #define	F_SHA384	0x01000000		/* SHA-384 digest */
 #define	F_SHA384	0x01000000		/* SHA-384 digest */
 #define	F_SHA512	0x02000000		/* SHA-512 digest */
 #define	F_SHA512	0x02000000		/* SHA-512 digest */
+#define	F_INO		0x04000000		/* inode number */
+#define	F_RESDEV	0x08000000		/* device ID on which the
+						 * entry resides */
 
 
 	/* Options */
 	/* Options */
 	int dironly;		/* If it is set, ignore all files except
 	int dironly;		/* If it is set, ignore all files except
@@ -823,8 +829,11 @@ mtree_entry_new(struct archive_write *a, struct archive_entry *entry,
 	archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
 	archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
 	me->mtime = archive_entry_mtime(entry);
 	me->mtime = archive_entry_mtime(entry);
 	me->mtime_nsec = archive_entry_mtime_nsec(entry);
 	me->mtime_nsec = archive_entry_mtime_nsec(entry);
-	me->rdevmajor =	archive_entry_rdevmajor(entry);
+	me->rdevmajor = archive_entry_rdevmajor(entry);
 	me->rdevminor = archive_entry_rdevminor(entry);
 	me->rdevminor = archive_entry_rdevminor(entry);
+	me->devmajor = archive_entry_devmajor(entry);
+	me->devminor = archive_entry_devminor(entry);
+	me->ino = archive_entry_ino(entry);
 	me->size = archive_entry_size(entry);
 	me->size = archive_entry_size(entry);
 	if (me->filetype == AE_IFDIR) {
 	if (me->filetype == AE_IFDIR) {
 		me->dir_info = calloc(1, sizeof(*me->dir_info));
 		me->dir_info = calloc(1, sizeof(*me->dir_info));
@@ -882,7 +891,7 @@ archive_write_mtree_header(struct archive_write *a,
 		mtree->first = 0;
 		mtree->first = 0;
 		archive_strcat(&mtree->buf, "#mtree\n");
 		archive_strcat(&mtree->buf, "#mtree\n");
 		if ((mtree->keys & SET_KEYS) == 0)
 		if ((mtree->keys & SET_KEYS) == 0)
-			mtree->output_global_set = 0;/* Disalbed. */
+			mtree->output_global_set = 0;/* Disabled. */
 	}
 	}
 
 
 	mtree->entry_bytes_remaining = archive_entry_size(entry);
 	mtree->entry_bytes_remaining = archive_entry_size(entry);
@@ -983,6 +992,15 @@ write_mtree_entry(struct archive_write *a, struct mtree_entry *me)
 	if ((keys & F_UID) != 0)
 	if ((keys & F_UID) != 0)
 		archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
 		archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
 
 
+	if ((keys & F_INO) != 0)
+		archive_string_sprintf(str, " inode=%jd", (intmax_t)me->ino);
+	if ((keys & F_RESDEV) != 0) {
+		archive_string_sprintf(str,
+		    " resdevice=native,%ju,%ju",
+		    (uintmax_t)me->devmajor,
+		    (uintmax_t)me->devminor);
+	}
+
 	switch (me->filetype) {
 	switch (me->filetype) {
 	case AE_IFLNK:
 	case AE_IFLNK:
 		if ((keys & F_TYPE) != 0)
 		if ((keys & F_TYPE) != 0)
@@ -1117,7 +1135,7 @@ write_mtree_entry_tree(struct archive_write *a)
 		} else {
 		} else {
 			/* Whenever output_global_set is enabled
 			/* Whenever output_global_set is enabled
 			 * output global value(/set keywords)
 			 * output global value(/set keywords)
-			 * even if the directory entry is not allowd
+			 * even if the directory entry is not allowed
 			 * to be written because the global values
 			 * to be written because the global values
 			 * can be used for the children. */
 			 * can be used for the children. */
 			if (mtree->output_global_set)
 			if (mtree->output_global_set)
@@ -1296,6 +1314,8 @@ archive_write_mtree_options(struct archive_write *a, const char *key,
 		if (strcmp(key, "indent") == 0) {
 		if (strcmp(key, "indent") == 0) {
 			mtree->indent = (value != NULL)? 1: 0;
 			mtree->indent = (value != NULL)? 1: 0;
 			return (ARCHIVE_OK);
 			return (ARCHIVE_OK);
+		} else if (strcmp(key, "inode") == 0) {
+			keybit = F_INO;
 		}
 		}
 		break;
 		break;
 	case 'l':
 	case 'l':
@@ -1314,7 +1334,9 @@ archive_write_mtree_options(struct archive_write *a, const char *key,
 			keybit = F_NLINK;
 			keybit = F_NLINK;
 		break;
 		break;
 	case 'r':
 	case 'r':
-		if (strcmp(key, "ripemd160digest") == 0 ||
+		if (strcmp(key, "resdevice") == 0) {
+			keybit = F_RESDEV;
+		} else if (strcmp(key, "ripemd160digest") == 0 ||
 		    strcmp(key, "rmd160") == 0 ||
 		    strcmp(key, "rmd160") == 0 ||
 		    strcmp(key, "rmd160digest") == 0)
 		    strcmp(key, "rmd160digest") == 0)
 			keybit = F_RMD160;
 			keybit = F_RMD160;
@@ -1855,9 +1877,9 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
 		return (ret);
 		return (ret);
 	}
 	}
 
 
-	/* Make a basename from dirname and slash */
+	/* Make a basename from file->parentdir.s and slash */
 	*slash  = '\0';
 	*slash  = '\0';
-	file->parentdir.length = slash - dirname;
+	file->parentdir.length = slash - file->parentdir.s;
 	archive_strcpy(&(file->basename),  slash + 1);
 	archive_strcpy(&(file->basename),  slash + 1);
 	return (ret);
 	return (ret);
 }
 }
@@ -2198,6 +2220,9 @@ mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np,
 	np->mtime_nsec = file->mtime_nsec;
 	np->mtime_nsec = file->mtime_nsec;
 	np->rdevmajor = file->rdevmajor;
 	np->rdevmajor = file->rdevmajor;
 	np->rdevminor = file->rdevminor;
 	np->rdevminor = file->rdevminor;
+	np->devmajor = file->devmajor;
+	np->devminor = file->devminor;
+	np->ino = file->ino;
 
 
 	return (ARCHIVE_WARN);
 	return (ARCHIVE_WARN);
 }
 }

+ 125 - 0
Utilities/cmlibarchive/libarchive/archive_write_set_format_raw.c

@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 2013 Marek Kubica
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "archive_entry.h"
+#include "archive_write_private.h"
+
+static ssize_t	archive_write_raw_data(struct archive_write *,
+		    const void *buff, size_t s);
+static int	archive_write_raw_free(struct archive_write *);
+static int	archive_write_raw_header(struct archive_write *,
+		    struct archive_entry *);
+
+struct raw {
+        int entries_written;
+};
+
+/*
+ * Set output format to 'raw' format.
+ */
+int
+archive_write_set_format_raw(struct archive *_a)
+{
+	struct archive_write *a = (struct archive_write *)_a;
+	struct raw *raw;
+
+	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_write_set_format_raw");
+
+	/* If someone else was already registered, unregister them. */
+	if (a->format_free != NULL)
+		(a->format_free)(a);
+
+	raw = (struct raw *)calloc(1, sizeof(*raw));
+	if (raw == NULL) {
+		archive_set_error(&a->archive, ENOMEM, "Can't allocate raw data");
+		return (ARCHIVE_FATAL);
+	}
+	raw->entries_written = 0;
+	a->format_data = raw;
+	a->format_name = "raw";
+        /* no options exist for this format */
+	a->format_options = NULL;
+	a->format_write_header = archive_write_raw_header;
+	a->format_write_data = archive_write_raw_data;
+	a->format_finish_entry = NULL;
+        /* nothing needs to be done on closing */
+	a->format_close = NULL;
+	a->format_free = archive_write_raw_free;
+	a->archive.archive_format = ARCHIVE_FORMAT_RAW;
+	a->archive.archive_format_name = "RAW";
+	return (ARCHIVE_OK);
+}
+
+static int
+archive_write_raw_header(struct archive_write *a, struct archive_entry *entry)
+{
+	struct raw *raw = (struct raw *)a->format_data;
+
+	if (archive_entry_filetype(entry) != AE_IFREG) {
+		archive_set_error(&a->archive, ERANGE,
+		    "Raw format only supports filetype AE_IFREG");
+		return (ARCHIVE_FATAL);
+	}
+
+
+	if (raw->entries_written > 0) {
+		archive_set_error(&a->archive, ERANGE,
+		    "Raw format only supports one entry per archive");
+		return (ARCHIVE_FATAL);
+	}
+	raw->entries_written++;
+
+	return (ARCHIVE_OK);
+}
+
+static ssize_t
+archive_write_raw_data(struct archive_write *a, const void *buff, size_t s)
+{
+	int ret;
+
+	ret = __archive_write_output(a, buff, s);
+	if (ret >= 0)
+		return (s);
+	else
+		return (ret);
+}
+
+static int
+archive_write_raw_free(struct archive_write *a)
+{
+	struct raw *raw;
+
+	raw = (struct raw *)a->format_data;
+	free(raw);
+	a->format_data = NULL;
+	return (ARCHIVE_OK);
+}

+ 1 - 0
Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c

@@ -548,6 +548,7 @@ archive_write_shar_finish_entry(struct archive_write *a)
 				archive_strcat(&shar->work, ":");
 				archive_strcat(&shar->work, ":");
 				shar_quote(&shar->work, g, 1);
 				shar_quote(&shar->work, g, 1);
 			}
 			}
+			archive_strcat(&shar->work, " ");
 			shar_quote(&shar->work,
 			shar_quote(&shar->work,
 			    archive_entry_pathname(shar->entry), 1);
 			    archive_entry_pathname(shar->entry), 1);
 			archive_strcat(&shar->work, "\n");
 			archive_strcat(&shar->work, "\n");

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 466 - 326
Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c


+ 1 - 1
Utilities/cmlibarchive/libarchive/filter_fork_windows.c

@@ -36,7 +36,7 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
 {
 {
 	HANDLE childStdout[2], childStdin[2],childStderr;
 	HANDLE childStdout[2], childStdin[2],childStderr;
 	SECURITY_ATTRIBUTES secAtts;
 	SECURITY_ATTRIBUTES secAtts;
-	STARTUPINFO staInfo;
+	STARTUPINFOA staInfo;
 	PROCESS_INFORMATION childInfo;
 	PROCESS_INFORMATION childInfo;
 	struct archive_string cmdline;
 	struct archive_string cmdline;
 	struct archive_string fullpath;
 	struct archive_string fullpath;

+ 77 - 1
Utilities/cmlibarchive/libarchive/mtree.5

@@ -28,7 +28,7 @@
 .\"     From: @(#)mtree.8       8.2 (Berkeley) 12/11/93
 .\"     From: @(#)mtree.8       8.2 (Berkeley) 12/11/93
 .\" $FreeBSD$
 .\" $FreeBSD$
 .\"
 .\"
-.Dd May 6, 2008
+.Dd September 4, 2013
 .Dt MTREE 5
 .Dt MTREE 5
 .Os
 .Os
 .Sh NAME
 .Sh NAME
@@ -134,6 +134,52 @@ The checksum of the file using the default algorithm specified by
 the
 the
 .Xr cksum 1
 .Xr cksum 1
 utility.
 utility.
+.It Cm device
+The device number for
+.Sy block
+or
+.Sy char
+file types.
+The value must be one of the following forms:
+.Pp
+.Bl -tag -width 4n
+.It Ar format , Ns Ar major , Ns Ar minor Ns Bo , Ns Ar subunit Bc
+A device with
+.Ar major , minor
+and optional
+.Ar subunit
+fields.
+Their meaning is specified by the operating's system
+.Ar format .
+See below for valid formats.
+.It Ar number
+Opaque number (as stored on the file system).
+.El
+.Pp
+The following values for
+.Ar format
+are recognized:
+.Sy native ,
+.Sy 386bsd ,
+.Sy 4bsd ,
+.Sy bsdos ,
+.Sy freebsd ,
+.Sy hpux ,
+.Sy isc ,
+.Sy linux ,
+.Sy netbsd ,
+.Sy osf1 ,
+.Sy sco ,
+.Sy solaris ,
+.Sy sunos ,
+.Sy svr3 ,
+.Sy svr4 ,  
+and 
+.Sy ultrix .
+.Pp
+See
+.Xr mknod 8
+for more details.
 .It Cm contents
 .It Cm contents
 The full pathname of a file that holds the contents of this file.
 The full pathname of a file that holds the contents of this file.
 .It Cm flags
 .It Cm flags
@@ -150,6 +196,8 @@ The file group as a numeric value.
 The file group as a symbolic name.
 The file group as a symbolic name.
 .It Cm ignore
 .It Cm ignore
 Ignore any file hierarchy below this file.
 Ignore any file hierarchy below this file.
+.It Cm inode
+The inode number.
 .It Cm link
 .It Cm link
 The target of the symbolic link when type=link.
 The target of the symbolic link when type=link.
 .It Cm md5
 .It Cm md5
@@ -164,6 +212,16 @@ value.
 The number of hard links the file is expected to have.
 The number of hard links the file is expected to have.
 .It Cm nochange
 .It Cm nochange
 Make sure this file or directory exists but otherwise ignore all attributes.
 Make sure this file or directory exists but otherwise ignore all attributes.
+.It Cm optional
+The file is optional; do not complain about the file if it is not in
+the file hierarchy.
+.It Cm resdevice
+The
+.Dq resident
+device number of the file, e.g. the ID of the device that
+contains the file.
+Its format is the same as the one for
+.Cm device .
 .It Cm ripemd160digest
 .It Cm ripemd160digest
 The
 The
 .Tn RIPEMD160
 .Tn RIPEMD160
@@ -192,6 +250,24 @@ message digest of the file.
 .It Cm sha256digest
 .It Cm sha256digest
 A synonym for
 A synonym for
 .Cm sha256 .
 .Cm sha256 .
+.It Cm sha384
+The
+.Tn FIPS
+180-2
+.Pq Dq Tn SHA-384
+message digest of the file.
+.It Cm sha384digest
+A synonym for
+.Cm sha384 .
+.It Cm sha512
+The
+.Tn FIPS
+180-2
+.Pq Dq Tn SHA-512
+message digest of the file.
+.It Cm sha512digest
+A synonym for
+.Cm sha512 .
 .It Cm size
 .It Cm size
 The size, in bytes, of the file.
 The size, in bytes, of the file.
 .It Cm time
 .It Cm time

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно