فهرست منبع

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 سال پیش
والد
کامیت
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)
     set(ENABLE_NETTLE OFF CACHE INTERNAL "Enable use of Nettle")
     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_ACL OFF CACHE INTERNAL "Enable ACL 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}")
 
 # 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.9 == interface version 11 = 2 + 9
 # libarchive 3.0 == interface version 12
@@ -69,6 +69,13 @@ include(CTest)
 
 OPTION(ENABLE_NETTLE "Enable use of Nettle" 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_ACL "Enable ACL 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	2009-01-19 11:39:10.093750000
   #@@ -286,7 +286,7 @@
-  # 
+  #
   # #if 1           /* HAVE_UNISTD_H -- this line is updated by ./configure */
   # #  include <sys/types.h> /* for off_t */
   #-#  include <unistd.h>    /* for SEEK_* and off_t */
@@ -204,7 +211,11 @@ SET(ADDITIONAL_LIBS "")
 #
 # Find ZLIB
 #
-FIND_PACKAGE(ZLIB)
+IF(ENABLE_ZLIB)
+  FIND_PACKAGE(ZLIB)
+ELSE()
+  SET(ZLIB_FOUND FALSE) # Override cached value
+ENDIF()
 IF(ZLIB_FOUND)
   SET(HAVE_LIBZ 1)
   SET(HAVE_ZLIB_H 1)
@@ -239,7 +250,11 @@ ENDIF(ZLIB_FOUND)
 #
 # Find BZip2
 #
-FIND_PACKAGE(BZip2)
+IF(ENABLE_BZip2)
+  FIND_PACKAGE(BZip2)
+ELSE()
+  SET(BZIP2_FOUND FALSE) # Override cached value
+ENDIF()
 IF(BZIP2_FOUND)
   SET(HAVE_LIBBZ2 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_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)
   SET(HAVE_LIBLZMA 1)
   SET(HAVE_LZMA_H 1)
@@ -283,6 +304,8 @@ ELSEIF(LZMADEC_FOUND)
   SET(HAVE_LZMADEC_H 1)
   INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
   LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
+ELSE(LZMA_FOUND)
+# LZMA not found and will not be used.
 ENDIF(LZMA_FOUND)
 #
 # 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}")
 	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}
 	  ${CMAKE_BINARY_DIR}
 	  ${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_INCLUDES}"
 	  OUTPUT_VARIABLE OUTPUT)
@@ -604,16 +621,10 @@ main(int argc, char **argv)
 	FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
 	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
 	  ${CMAKE_BINARY_DIR}
 	  ${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)
 
 	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("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(int64_t INT64_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(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
 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:
 
@@ -24,7 +24,7 @@ Use a temporary directory to checkout the branch:
 Now place the (reduced) libarchive content in this directory.  See
 instructions shown by
 
- git log 35df7c8b
+ git log 64713ae3
 
 for help extracting the content from the upstream svn repo.  Then run
 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_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
 
 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}
 
 /* Define for Windows to use Windows 2000+ APIs. */
+#ifndef _WIN32_WINNT
 #cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
+#endif // _WIN32_WINNT
+
+#ifndef WINVER
 #cmakedefine WINVER ${WINVER}
+#endif // WINVER
 
 /* Define to empty if `const' does not conform to ANSI C. */
 #cmakedefine const ${const}

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

@@ -35,6 +35,8 @@ SET(libarchive_SOURCES
   archive_match.c
   archive_options.c
   archive_options_private.h
+  archive_pack_dev.h
+  archive_pack_dev.c
   archive_pathmatch.c
   archive_pathmatch.h
   archive_platform.h
@@ -125,6 +127,7 @@ SET(libarchive_SOURCES
   archive_write_set_format_iso9660.c
   archive_write_set_format_mtree.c
   archive_write_set_format_pax.c
+  archive_write_set_format_raw.c
   archive_write_set_format_shar.c
   archive_write_set_format_ustar.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"
 __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. */
 struct archive;
 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_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:
  *   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_tar(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 *);
+/* 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
  * 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 *);
 
+/*
+ * 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). */
 __LA_DECL __LA_SSIZE_T		 archive_read_data(struct archive *,
 				    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 *); */
 __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_raw(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_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 *,
 		    	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
  * 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 *,
 		    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
 }
 #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;
 	archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
 
+	/* Copy encryption status */
+	entry2->encryption = entry->encryption;
+	
 	/* Copy ACL data over. */
 	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));
 }
 
+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.
  */
@@ -1216,6 +1237,26 @@ archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
 	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
 _archive_entry_copy_uname_l(struct archive_entry *entry,
     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 <time.h>
 
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include <windows.h>
-#endif
-
 /* Get a suitable 64-bit integer type. */
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
 # 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 const char	*archive_entry_uname(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.
@@ -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_unset_atime(struct archive_entry *);
 #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
 __LA_DECL void	archive_entry_set_birthtime(struct archive_entry *, time_t, long);
 __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_w(struct archive_entry *, const wchar_t *);
 __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
  * 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. */
 	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;
 	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)
 		/* Invalid value */
 		return;
-	if (offset + length < 0 ||
+	if (offset > INT64_MAX - length ||
 	    offset + length > archive_entry_size(entry))
 		/* A value of "length" parameter is too large. */
 		return;

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

@@ -369,8 +369,8 @@ relunitphrase(struct gdstate *gds)
 	    && gds->tokenp[1].token == tSEC_UNIT) {
 		/* "1 day" */
 		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;
 	}
 	if (gds->tokenp[0].token == '-'
@@ -403,7 +403,7 @@ relunitphrase(struct gdstate *gds)
 		/* "now", "tomorrow" */
 		gds->HaveRel++;
 		gds->RelSeconds += gds->tokenp[0].value;
-		++gds->tokenp;
+		gds->tokenp += 1;
 		return 1;
 	}
 	if (gds->tokenp[0].token == tMONTH_UNIT) {
@@ -1022,10 +1022,11 @@ int
 main(int argc, char **argv)
 {
     time_t	d;
+    time_t	now = time(NULL);
 
     while (*++argv != NULL) {
 	    (void)printf("Input: %s\n", *argv);
-	    d = get_date(*argv);
+	    d = get_date(now, *argv);
 	    if (d == -1)
 		    (void)printf("Bad format - couldn't convert.\n");
 	    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. */
 	HANDLE h;
-	WIN32_FIND_DATA d;
+	WIN32_FIND_DATAA d;
 
 	if (path == NULL || *path == '\0') {
 		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.
  */
 
-/* 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
 #include <sys/cdefs.h>
 #endif
 
-/* If not, define it so as to avoid dangling semicolons. */
+/* If not, define them so as to avoid dangling semicolons. */
 #ifndef __FBSDID
 #define	__FBSDID(a)     struct _undefined_hack
 #endif
+#ifndef __RCSID
+#define	__RCSID(a)     struct _undefined_hack
+#endif
 
 /* Old glibc mbsnrtowcs fails assertions in our use case.  */
 #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);
 }
 
+/*
+ * 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.
  * 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_skip)(struct archive_read *),
     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;
 
@@ -1117,6 +1172,8 @@ __archive_read_register_format(struct archive_read *a,
 			a->formats[i].cleanup = cleanup;
 			a->formats[i].data = format_data;
 			a->formats[i].name = name;
+			a->formats[i].format_capabilties = format_capabilities;
+			a->formats[i].has_encrypted_entries = has_encrypted_entries;
 			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;
 		}
 		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)
 			return r;
 		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
 
 
-#if defined(HAVE_POSIX_ACL) && defined(ACL_TYPE_NFS4)
+#ifdef HAVE_POSIX_ACL
 static int translate_acl(struct archive_read_disk *a,
     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);
 
+#ifdef ACL_TYPE_NFS4
 	/* Try NFS4 ACL first. */
 	if (*fd >= 0)
 		acl = acl_get_fd(*fd);
@@ -447,6 +448,7 @@ setup_acls(struct archive_read_disk *a,
 		acl_free(acl);
 		return (ARCHIVE_OK);
 	}
+#endif
 
 	/* Retrieve access ACL from file. */
 	if (*fd >= 0)
@@ -492,6 +494,7 @@ static struct {
         {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
         {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
         {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+#ifdef ACL_TYPE_NFS4
         {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
         {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
         {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_OWNER, ACL_WRITE_OWNER},
         {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+#endif
 };
 
+#ifdef ACL_TYPE_NFS4
 static struct {
         int archive_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_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
 };
-
+#endif
 static int
 translate_acl(struct archive_read_disk *a,
     struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
 {
 	acl_tag_t	 acl_tag;
+#ifdef ACL_TYPE_NFS4
 	acl_entry_type_t acl_type;
 	acl_flagset_t	 acl_flagset;
+	int brand, r;
+#endif
 	acl_entry_t	 acl_entry;
 	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;
 	const char	*ae_name;
 
 
+#ifdef ACL_TYPE_NFS4
 	// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
 	// Make sure the "brand" on this ACL is consistent
 	// with the default_entry_acl_type bits provided.
@@ -560,6 +569,7 @@ translate_acl(struct archive_read_disk *a,
 		return ARCHIVE_FAILED;
 		break;
 	}
+#endif
 
 
 	s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
@@ -592,9 +602,11 @@ translate_acl(struct archive_read_disk *a,
 		case ACL_OTHER:
 			ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
 			break;
+#ifdef ACL_TYPE_NFS4
 		case ACL_EVERYONE:
 			ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
 			break;
+#endif
 		default:
 			/* Skip types that libarchive can't support. */
 			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
 		// non-NFSv4 ACLs
 		entry_acl_type = default_entry_acl_type;
+#ifdef ACL_TYPE_NFS4
 		r = acl_get_entry_type_np(acl_entry, &acl_type);
 		if (r == 0) {
 			switch (acl_type) {
@@ -634,9 +647,10 @@ translate_acl(struct archive_read_disk *a,
 				ae_perm |= acl_inherit_map[i].archive_inherit;
 
                 }
+#endif
 
 		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
 			 * 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;
 
 	if (can_dupfd_cloexec) {
-		new_fd = fcntl(fd, F_DUPFD_CLOEXEC);
+		new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
 		if (new_fd != -1)
 			return (new_fd);
 		/* 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
 			flags |= FILE_FLAG_SEQUENTIAL_SCAN;
 		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) {
 			archive_set_error(&a->archive, errno,
 			    "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))
 		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);
 	if (h == INVALID_HANDLE_VALUE) {
 		la_dosmaperr(GetLastError());
@@ -2115,7 +2115,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
 			} else
 				desiredAccess = GENERIC_READ;
 
-			h = CreateFileW(path, desiredAccess, 0, NULL,
+			h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL,
 			    OPEN_EXISTING, flag, NULL);
 			if (h == INVALID_HANDLE_VALUE) {
 				la_dosmaperr(GetLastError());
@@ -2162,7 +2162,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
 		if (fd >= 0) {
 			h = (HANDLE)_get_osfhandle(fd);
 		} else {
-			h = CreateFileW(path, GENERIC_READ, 0, NULL,
+			h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
 			    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
 			if (h == INVALID_HANDLE_VALUE) {
 				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 *);
 		int64_t	(*seek_data)(struct archive_read *, int64_t, int);
 		int	(*cleanup)(struct archive_read *);
+		int	(*format_capabilties)(struct archive_read *);
+		int	(*has_encrypted_entries)(struct archive_read *);
 	}	formats[16];
 	struct archive_format_descriptor	*format; /* Active format. */
 
@@ -218,15 +220,17 @@ struct archive_read {
 };
 
 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,
     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
 to disable.
 .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
 .\"
 .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_format_descriptor *format;
 	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++) {
 		format = &a->formats[i];
@@ -86,8 +86,11 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
 		    format->name == NULL)
 			/* This format does not support option. */
 			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;
 		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)
 			return (ARCHIVE_FATAL);
 
-		if (m != NULL)
-			return (r);
-
 		if (r == ARCHIVE_OK)
 			rv = ARCHIVE_OK;
 	}
 	/* If the format name didn't match, return a special code for
 	 * _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);
 }
 
@@ -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_filter *filter;
 	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) {
 		bidder = filter->bidder;
@@ -125,24 +125,24 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
 		if (bidder->options == NULL)
 			/* This bidder does not support option */
 			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);
 
 		if (r == ARCHIVE_FATAL)
 			return (ARCHIVE_FATAL);
 
-		if (m != NULL)
-			return (r);
-
 		if (r == ARCHIVE_OK)
 			rv = ARCHIVE_OK;
 	}
 	/* If the filter name didn't match, return a special code for
 	 * _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);
 }
 

+ 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) {
 		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_ERRNO_MISC, "Invalid level");
 			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);
 	}
 	ret = lzma_raw_decoder(&(state->stream), filters);
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
 	free(filters[0].options);
 #endif
 	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_PPMD	0x030401
 #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_BCJ2	0x0303011B
 #define _7Z_POWERPC	0x03030205
@@ -322,8 +326,13 @@ struct _7zip {
 	struct archive_string_conv *sconv;
 
 	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_cleanup(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);
 	}
 
+	/*
+	 * 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,
 	    zip,
 	    "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_skip,
 	    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)
 		free(zip);
 	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
 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]) {
 	case 0x1C:
 		if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0)
-			return (6); 
+			return (6);
 		/*
 		 * Test the CRC because its extraction code has 7-Zip
 		 * 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)
 			!= archive_le32dec(p + 8))
-			return (6); 
+			return (6);
 		/* Hit the header! */
 		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_entry *zip_entry;
 	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;
 	if (a->archive.archive_format_name == NULL)
@@ -604,6 +656,32 @@ archive_read_format_7zip_read_header(struct archive_read *a,
 			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,
 	    (const char *)zip_entry->utf16name,
 	    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);
 
+	if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+		zip->has_encrypted_entries = 0;
+	}
+
 	if (zip->pack_stream_bytes_unconsumed)
 		read_consume(a);
 
@@ -969,7 +1051,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 	{
 		lzma_options_delta delta_opt;
 		lzma_filter filters[LZMA_FILTERS_MAX];
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
 		lzma_filter *ff;
 #endif
 		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
 		 * size to liblzma when using lzma_raw_decoder() liblzma
 		 * 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.
 		 */
 		if (coder2 != NULL) {
@@ -1056,7 +1138,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
 		else
 			filters[fi].id = LZMA_FILTER_LZMA1;
 		filters[fi].options = NULL;
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
 		ff = &filters[fi];
 #endif
 		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].options = NULL;
 		r = lzma_raw_decoder(&(zip->lzstream), filters);
-#if LZMA_VERSION < 50000030
+#if LZMA_VERSION < 50010000
 		free(ff->options);
 #endif
 		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,
 		    "Unexpected codec ID: %lX", zip->codec);
 		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:
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 		    "Unknown codec ID: %lX", zip->codec);
@@ -1426,7 +1519,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
 
 		do {
 			int sym;
-			
+
 			sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
 				&(zip->ppmd7_context), &(zip->range_dec.p));
 			if (sym < 0) {
@@ -2755,6 +2848,7 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
 	zip->header_crc32 = 0;
 	zip->header_is_encoded = 0;
 	zip->header_is_being_read = 1;
+	zip->has_encrypted_entries = 0;
 	check_header_crc = 1;
 
 	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);
 
 	/*
-	 * Skip the bytes we alrady has skipped in skip_stream(). 
+	 * Skip the bytes we alrady has skipped in skip_stream().
 	 */
 	while (skip_bytes) {
 		ssize_t skipped;
@@ -3235,16 +3329,36 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
 	 * Check coder types.
 	 */
 	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) {
 		archive_set_error(&(a->archive),
 		    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_skip,
 	    NULL,
-	    archive_read_format_ar_cleanup);
+	    archive_read_format_ar_cleanup,
+	    NULL,
+	    NULL);
 
 	if (r != ARCHIVE_OK) {
 		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_skip,
 	    NULL,
-	    archive_read_format_cab_cleanup);
+	    archive_read_format_cab_cleanup,
+	    NULL,
+	    NULL);
 
 	if (r != ARCHIVE_OK)
 		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_skip,
 	    NULL,
-	    archive_read_format_cpio_cleanup);
+	    archive_read_format_cpio_cleanup,
+	    NULL,
+	    NULL);
 
 	if (r != ARCHIVE_OK)
 		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,
 	    NULL,
 	    NULL,
+	    NULL,
+	    NULL,
 	    NULL);
 
 	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_skip,
 	    NULL,
-	    archive_read_format_iso9660_cleanup);
+	    archive_read_format_iso9660_cleanup,
+	    NULL,
+	    NULL);
 
 	if (r != ARCHIVE_OK) {
 		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_skip,
 	    NULL,
-	    archive_read_format_lha_cleanup);
+	    archive_read_format_lha_cleanup,
+	    NULL,
+	    NULL);
 
 	if (r != ARCHIVE_OK)
 		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_read_private.h"
 #include "archive_string.h"
+#include "archive_pack_dev.h"
 
 #ifndef O_BINARY
 #define	O_BINARY 0
@@ -103,6 +104,7 @@ struct mtree {
 	struct archive_entry_linkresolver *resolver;
 
 	int64_t			 cur_size;
+	char checkfs;
 };
 
 static int	bid_keycmp(const char *, const char *, ssize_t);
@@ -173,6 +175,29 @@ get_time_t_min(void)
 #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
 free_options(struct mtree_option *head)
 {
@@ -205,7 +230,7 @@ archive_read_support_format_mtree(struct archive *_a)
 	mtree->fd = -1;
 
 	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)
 		free(mtree);
@@ -367,7 +392,7 @@ bid_keyword(const char *p,  ssize_t len)
 		"gid", "gname", NULL
 	};
 	static const char *keys_il[] = {
-		"ignore", "link", NULL
+		"ignore", "inode", "link", NULL
 	};
 	static const char *keys_m[] = {
 		"md5", "md5digest", "mode", NULL
@@ -376,7 +401,7 @@ bid_keyword(const char *p,  ssize_t len)
 		"nlink", "nochange", "optional", NULL
 	};
 	static const char *keys_r[] = {
-		"rmd160", "rmd160digest", NULL
+		"resdevice", "rmd160", "rmd160digest", NULL
 	};
 	static const char *keys_s[] = {
 		"sha1", "sha1digest",
@@ -1103,162 +1128,164 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
 			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;
 		}
-	} 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
-		    || ((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
 #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
 #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
 #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
-		    || ((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
-		    || ((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
-		    ) {
-			/* 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
-			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
-			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
-			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
-			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
-			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
-			archive_entry_set_mtime(entry, st->st_mtime, 0);
+				archive_entry_set_mtime(entry, st->st_mtime, 0);
 #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);
@@ -1292,33 +1319,82 @@ parse_line(struct archive_read *a, struct archive_entry *entry,
 
 /*
  * 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;
 	case 'd':
 		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;
-			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':
 		if (strcmp(key, "flags") == 0) {
@@ -1394,6 +1478,11 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 			archive_entry_copy_gname(entry, val);
 			break;
 		}
+	case 'i':
+		if (strcmp(key, "inode") == 0) {
+			archive_entry_set_ino(entry, mtree_atol10(&val));
+			break;
+		}
 	case 'l':
 		if (strcmp(key, "link") == 0) {
 			archive_entry_copy_symlink(entry, val);
@@ -1423,6 +1512,17 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
 			break;
 		}
 	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 ||
 		    strcmp(key, "rmd160digest") == 0)
 			break;

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

@@ -304,8 +304,15 @@ struct rar
     ssize_t		 avail_in;
     const unsigned char *next_in;
   } 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_options(struct archive_read *,
     const char *, const char *);
@@ -646,6 +653,12 @@ archive_read_support_format_rar(struct archive *_a)
   }
   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,
                                      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_skip,
                                      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)
     free(rar);
   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
 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;
   int ret = ARCHIVE_FAILED;
-        
+
   rar = (struct rar *)(a->format->data);
   if (strcmp(key, "hdrcharset")  == 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);
 
+  /*
+   * 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
   * this fails.
   */
@@ -857,9 +904,14 @@ archive_read_format_rar_read_header(struct archive_read *a,
                             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)
       {
-        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.");
         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);
   int ret;
 
+  if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
+	  rar->has_encrypted_entries = 0;
+  }
+
   if (rar->bytes_unconsumed > 0) {
       /* Consume as much as the decompressor actually used. */
       __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:
     ret = read_data_stored(a, buff, size, offset);
-    break; 
+    break;
 
   case COMPRESS_METHOD_FASTEST:
   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);
     if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
       __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
-    break; 
+    break;
 
   default:
     archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                       "Unsupported compression method for RAR file.");
     ret = ARCHIVE_FATAL;
-    break; 
+    break;
   }
   return (ret);
 }
@@ -1290,9 +1346,14 @@ read_header(struct archive_read *a, struct archive_entry *entry,
 
   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,
                       "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)
@@ -1377,7 +1438,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
           flagbyte = *(p + offset++);
           flagbits = 8;
         }
-	
+
         flagbits -= 2;
         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)
       return (ARCHIVE_FATAL);
     rar->output_last_match = 0;
-    
+
     if (symbol < 256)
     {
       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_skip,
 	    NULL,
-	    archive_read_format_raw_cleanup);
+	    archive_read_format_raw_cleanup,
+	    NULL,
+	    NULL);
 	if (r != ARCHIVE_OK)
 		free(info);
 	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;
 	int			 init_default_conversion;
 	int			 compat_2x;
+	int			 process_mac_extensions;
+	int			 read_concatenated_archives;
 };
 
 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");
 
 	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) {
 		archive_set_error(&a->archive, ENOMEM,
 		    "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_skip,
 	    NULL,
-	    archive_read_format_tar_cleanup);
+	    archive_read_format_tar_cleanup,
+	    NULL,
+	    NULL);
 
 	if (r != ARCHIVE_OK)
 		free(tar);
@@ -368,7 +376,7 @@ archive_read_format_tar_options(struct archive_read *a,
 	tar = (struct tar *)(a->format->data);
 	if (strcmp(key, "compat-2x")  == 0) {
 		/* 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;
 		return (ARCHIVE_OK);
 	} else if (strcmp(key, "hdrcharset")  == 0) {
@@ -385,6 +393,12 @@ archive_read_format_tar_options(struct archive_read *a,
 				ret = ARCHIVE_FATAL;
 		}
 		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
@@ -397,7 +411,7 @@ archive_read_format_tar_options(struct archive_read *a,
  * how much unconsumed data we have floating around, and to consume
  * anything outstanding since we're going to do read_aheads
  */
-static void 
+static void
 tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed)
 {
 	if (*unconsumed) {
@@ -590,7 +604,7 @@ archive_read_format_tar_skip(struct archive_read *a)
 	tar = (struct tar *)(a->format->data);
 
 	bytes_skipped = __archive_read_consume(a,
-	    tar->entry_bytes_remaining + tar->entry_padding + 
+	    tar->entry_bytes_remaining + tar->entry_padding +
 	    tar->entry_bytes_unconsumed);
 	if (bytes_skipped < 0)
 		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_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) {
 			a->archive.archive_format = ARCHIVE_FORMAT_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_name = "POSIX pax interchange format";
 		err = header_pax_global(a, tar, entry, h, unconsumed);
+		if (err == ARCHIVE_EOF)
+			return (err);
 		break;
 	case 'K': /* Long link name (GNU tar, others) */
 		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
 	 * regular entry.
 	 */
-	/* TODO: Should this be disabled on non-Mac platforms? */
 	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);
 		if (err2 < err)
 			err = err2;
@@ -780,12 +810,20 @@ checksum(struct archive_read *a, const void *h)
 {
 	const unsigned char *bytes;
 	const struct archive_entry_header_ustar	*header;
-	int check, i, sum;
+	int check, sum;
+	size_t i;
 
 	(void)a; /* UNUSED */
 	bytes = (const unsigned char *)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_
 	 * 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')
 				wname = wp + 1;
 		}
-		/* 
+		/*
 		 * If last path element starts with "._", then
 		 * 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')
 				name = p + 1;
 		}
-		/* 
+		/*
 		 * If last path element starts with "._", then
 		 * 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_skip,
 	    NULL,
-	    xar_cleanup);
+	    xar_cleanup,
+	    NULL,
+	    NULL);
 	if (r != ARCHIVE_OK)
 		free(xar);
 	return (r);
@@ -967,10 +969,14 @@ move_reading_point(struct archive_read *a, uint64_t offset)
 				return ((int)step);
 			xar->offset += step;
 		} 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);

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 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__)
 #include <wincrypt.h>
 #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_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
 #endif
 
+static int archive_utility_string_sort_helper(char **, unsigned int);
+
 /* Generic initialization of 'struct archive' objects. */
 int
 __archive_clean(struct archive *a)
@@ -74,6 +85,38 @@ archive_version_string(void)
 	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
 archive_errno(struct archive *a)
 {
@@ -499,3 +542,69 @@ __archive_ensure_cloexec_flag(int fd)
 	}
 #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));
 }
 
+int
+archive_free(struct archive *a)
+{
+	if (a == NULL)
+		return (ARCHIVE_OK);
+	return ((a->vtable->archive_free)(a));
+}
+
 int
 archive_write_close(struct archive *a)
 {
@@ -76,9 +84,7 @@ archive_write_fail(struct archive *a)
 int
 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
@@ -93,9 +99,7 @@ archive_write_finish(struct archive *a)
 int
 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

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

@@ -301,7 +301,7 @@ __la_open(const char *path, int flags, ...)
 	ws = NULL;
 	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.
 		 */
 		attr = GetFileAttributesA(path);
@@ -515,9 +515,9 @@ __hstat(HANDLE handle, struct ustat *st)
 	else
 		mode |= S_IFREG;
 	st->st_mode = mode;
-	
+
 	fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
-	st->st_atime = t; 
+	st->st_atime = t;
 	st->st_atime_nsec = ns;
 	fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
 	st->st_mtime = t;
@@ -525,7 +525,7 @@ __hstat(HANDLE handle, struct ustat *st)
 	fileTimeToUTC(&info.ftCreationTime, &t, &ns);
 	st->st_ctime = t;
 	st->st_ctime_nsec = ns;
-	st->st_size = 
+	st->st_size =
 	    ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
 		+ (int64_t)(info.nFileSizeLow);
 #ifdef SIMULATE_WIN_STAT
@@ -599,7 +599,7 @@ __la_stat(const char *path, struct stat *st)
 	struct ustat u;
 	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,
 		NULL);
 	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. */
 #define	close		_close
-#define	fcntl(fd, cmd, flg)	/* No operation. */		
+#define	fcntl(fd, cmd, flg)	/* No operation. */
 #ifndef fileno
 #define	fileno		_fileno
 #endif
@@ -113,13 +113,14 @@
 #define	lstat		__la_stat
 #define	open		__la_open
 #define	read		__la_read
-#if !defined(__BORLANDC__)
+#if !defined(__BORLANDC__) && !defined(__WATCOMC__)
 #define setmode		_setmode
 #endif
 #ifdef stat
 #undef stat
 #endif
 #define	stat(path,stref)		__la_stat(path,stref)
+#if !defined(__WATCOMC__)
 #if !defined(__BORLANDC__)
 #define	strdup		_strdup
 #endif
@@ -127,9 +128,12 @@
 #if !defined(__BORLANDC__)
 #define	umask		_umask
 #endif
+#endif
 #define	waitpid		__la_waitpid
 #define	write		__la_write
 
+#if !defined(__WATCOMC__)
+
 #ifndef O_RDONLY
 #define	O_RDONLY	_O_RDONLY
 #define	O_WRONLY	_O_WRONLY
@@ -189,8 +193,6 @@
 #define	S_ISREG(m)	(((m) & S_IFMT) == S_IFREG)	/* regular file */
 #endif
 
-#if !defined(__WATCOMC__) 
-
 #define	S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK) /* Symbolic link */
 #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_IWGRP        (_S_IWUSR >> 3) /* write 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_IWOTH        (_S_IWGRP >> 3) /* write 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);
 
-	/* 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));
 
 	/* Finish off the archive. */
@@ -638,6 +639,9 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
 
 	/* Format and write header. */
 	r2 = ((a->format_write_header)(a, entry));
+	if (r2 == ARCHIVE_FAILED) {
+		return (ARCHIVE_FAILED);
+	}
 	if (r2 == ARCHIVE_FATAL) {
 		a->archive.state = ARCHIVE_STATE_FATAL;
 		return (ARCHIVE_FATAL);
@@ -658,7 +662,8 @@ _archive_write_finish_entry(struct archive *_a)
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
 	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
 	    "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);
 	a->archive.state = ARCHIVE_STATE_HEADER;
 	return (ret);
@@ -671,8 +676,13 @@ static ssize_t
 _archive_write_data(struct archive *_a, const void *buff, size_t s)
 {
 	struct archive_write *a = (struct archive_write *)_a;
+	const size_t max_write = INT_MAX;
+
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
 	    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);
 	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 archive_write_program_data *pdata;
 	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 *);
@@ -107,6 +107,8 @@ archive_write_lrzip_options(struct archive_write_filter *f, const char *key,
 			data->compression = gzip;
 		else if (strcmp(value, "lzo") == 0)
 			data->compression = lzo;
+		else if (strcmp(value, "none") == 0)
+			data->compression = none;
 		else if (strcmp(value, "zpaq") == 0)
 			data->compression = zpaq;
 		else
@@ -148,6 +150,9 @@ archive_write_lrzip_open(struct archive_write_filter *f)
 	case lzo:
 		archive_strcat(&as, " -l");
 		break;
+	case none:
+		archive_strcat(&as, " -n");
+		break;
 	case zpaq:
 		archive_strcat(&as, " -z");
 		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_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. */
 int
 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,
 		    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
 		return (ret);
+#ifdef ACL_TYPE_NFS4
 	} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0) {
 		ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
 		    ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
 		return (ret);
+#endif
 	} else
 		return ARCHIVE_OK;
 }
@@ -94,6 +96,7 @@ static struct {
 	{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
 	{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
 	{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+#ifdef ACL_TYPE_NFS4
 	{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
 	{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
 	{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_OWNER, ACL_WRITE_OWNER},
 	{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
+#endif
 };
 
+#ifdef ACL_TYPE_NFS4
 static struct {
 	int archive_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_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
 };
+#endif
 
 static int
 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_entry_t	 acl_entry;
 	acl_permset_t	 acl_permset;
+#ifdef ACL_TYPE_NFS4
 	acl_flagset_t	 acl_flagset;
+#endif
 	int		 ret;
 	int		 ae_type, ae_permset, ae_tag, ae_id;
 	uid_t		 ae_uid;
@@ -171,14 +179,17 @@ set_acl(struct archive *a, int fd, const char *name,
 		case ARCHIVE_ENTRY_ACL_OTHER:
 			acl_set_tag_type(acl_entry, ACL_OTHER);
 			break;
+#ifdef ACL_TYPE_NFS4
 		case ARCHIVE_ENTRY_ACL_EVERYONE:
 			acl_set_tag_type(acl_entry, ACL_EVERYONE);
 			break;
+#endif
 		default:
 			/* XXX */
 			break;
 		}
 
+#ifdef ACL_TYPE_NFS4
 		switch (ae_type) {
 		case ARCHIVE_ENTRY_ACL_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.
 			break;
 		}
+#endif
 
 		acl_get_permset(acl_entry, &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);
 		}
 
+#ifdef ACL_TYPE_NFS4
 		acl_get_flagset_np(acl_entry, &acl_flagset);
 		acl_clear_flags_np(acl_flagset);
 		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_inherit_map[i].platform_inherit);
 		}
+#endif
 	}
 
 	/* 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;
 	if (!set) {
 		set = 1;
-		lib = LoadLibrary("kernel32.dll");
+		lib = LoadLibrary(TEXT("kernel32.dll"));
 	}
 	if (lib == NULL) {
 		fprintf(stderr, "Can't load kernel32.dll?!\n");

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

@@ -24,13 +24,14 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 2, 2012
+.Dd February 14, 2013
 .Dt ARCHIVE_WRITE_FORMAT 3
 .Os
 .Sh NAME
 .Nm archive_write_set_format_cpio ,
 .Nm archive_write_set_format_pax ,
 .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_dump ,
 .Nm archive_write_set_format_ustar
@@ -46,6 +47,8 @@ Streaming Archive Library (libarchive, -larchive)
 .Ft int
 .Fn archive_write_set_format_pax_restricted "struct archive *"
 .Ft int
+.Fn archive_write_set_format_raw "struct archive *"
+.Ft int
 .Fn archive_write_set_format_shar "struct archive *"
 .Ft int
 .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_ISO9660,	archive_write_set_format_iso9660 },
 	{ 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_BASE,	archive_write_set_format_shar },
 	{ 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_FORMAT_TAR_USTAR,	archive_write_set_format_ustar },
 	{ 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 }
 };
 

+ 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 },
 	{ "paxr",	archive_write_set_format_pax_restricted },
 	{ "posix",	archive_write_set_format_pax },
+	{ "raw",	archive_write_set_format_raw },
 	{ "rpax",	archive_write_set_format_pax_restricted },
 	{ "shar",	archive_write_set_format_shar },
 	{ "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;
 	dev_t rdevmajor;
 	dev_t rdevminor;
+	dev_t devmajor;
+	dev_t devminor;
+	int64_t ino;
 };
 
 struct mtree_writer {
@@ -210,6 +213,9 @@ struct mtree_writer {
 #define	F_SHA256	0x00800000		/* SHA-256 digest */
 #define	F_SHA384	0x01000000		/* SHA-384 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 */
 	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);
 	me->mtime = archive_entry_mtime(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->devmajor = archive_entry_devmajor(entry);
+	me->devminor = archive_entry_devminor(entry);
+	me->ino = archive_entry_ino(entry);
 	me->size = archive_entry_size(entry);
 	if (me->filetype == AE_IFDIR) {
 		me->dir_info = calloc(1, sizeof(*me->dir_info));
@@ -882,7 +891,7 @@ archive_write_mtree_header(struct archive_write *a,
 		mtree->first = 0;
 		archive_strcat(&mtree->buf, "#mtree\n");
 		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);
@@ -983,6 +992,15 @@ write_mtree_entry(struct archive_write *a, struct mtree_entry *me)
 	if ((keys & F_UID) != 0)
 		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) {
 	case AE_IFLNK:
 		if ((keys & F_TYPE) != 0)
@@ -1117,7 +1135,7 @@ write_mtree_entry_tree(struct archive_write *a)
 		} else {
 			/* Whenever output_global_set is enabled
 			 * 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
 			 * can be used for the children. */
 			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) {
 			mtree->indent = (value != NULL)? 1: 0;
 			return (ARCHIVE_OK);
+		} else if (strcmp(key, "inode") == 0) {
+			keybit = F_INO;
 		}
 		break;
 	case 'l':
@@ -1314,7 +1334,9 @@ archive_write_mtree_options(struct archive_write *a, const char *key,
 			keybit = F_NLINK;
 		break;
 	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, "rmd160digest") == 0)
 			keybit = F_RMD160;
@@ -1855,9 +1877,9 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
 		return (ret);
 	}
 
-	/* Make a basename from dirname and slash */
+	/* Make a basename from file->parentdir.s and slash */
 	*slash  = '\0';
-	file->parentdir.length = slash - dirname;
+	file->parentdir.length = slash - file->parentdir.s;
 	archive_strcpy(&(file->basename),  slash + 1);
 	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->rdevmajor = file->rdevmajor;
 	np->rdevminor = file->rdevminor;
+	np->devmajor = file->devmajor;
+	np->devminor = file->devminor;
+	np->ino = file->ino;
 
 	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, ":");
 				shar_quote(&shar->work, g, 1);
 			}
+			archive_strcat(&shar->work, " ");
 			shar_quote(&shar->work,
 			    archive_entry_pathname(shar->entry), 1);
 			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;
 	SECURITY_ATTRIBUTES secAtts;
-	STARTUPINFO staInfo;
+	STARTUPINFOA staInfo;
 	PROCESS_INFORMATION childInfo;
 	struct archive_string cmdline;
 	struct archive_string fullpath;

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

@@ -28,7 +28,7 @@
 .\"     From: @(#)mtree.8       8.2 (Berkeley) 12/11/93
 .\" $FreeBSD$
 .\"
-.Dd May 6, 2008
+.Dd September 4, 2013
 .Dt MTREE 5
 .Os
 .Sh NAME
@@ -134,6 +134,52 @@ The checksum of the file using the default algorithm specified by
 the
 .Xr cksum 1
 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
 The full pathname of a file that holds the contents of this file.
 .It Cm flags
@@ -150,6 +196,8 @@ The file group as a numeric value.
 The file group as a symbolic name.
 .It Cm ignore
 Ignore any file hierarchy below this file.
+.It Cm inode
+The inode number.
 .It Cm link
 The target of the symbolic link when type=link.
 .It Cm md5
@@ -164,6 +212,16 @@ value.
 The number of hard links the file is expected to have.
 .It Cm nochange
 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
 The
 .Tn RIPEMD160
@@ -192,6 +250,24 @@ message digest of the file.
 .It Cm sha256digest
 A synonym for
 .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
 The size, in bytes, of the file.
 .It Cm time

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است