libarchive 3.1.2-218-g00f4bd83 (reduced)
Extract upstream libarchive using the following shell code. url=git://github.com/libarchive/libarchive.git && v=3.1.2-218-g00f4bd83 && r=00f4bd83 && paths=" CMakeLists.txt COPYING CTestConfig.cmake build/cmake build/pkgconfig build/utils build/version libarchive/*.* " && mkdir libarchive-$v-g$r-reduced && git clone $url libarchive-git && date=$(cd libarchive-git && git log -n 1 --format='%cd' $r) && (cd libarchive-git && git archive --format=tar $r -- $paths) | (cd libarchive-$v-g$r-reduced && tar xv) && fromdos libarchive-$v-g$r-reduced/build/cmake/Find*.cmake && echo "g$r date: $date"
This commit is contained in:
parent
35df7c8ba8
commit
64713ae3ff
122
CMakeLists.txt
122
CMakeLists.txt
|
@ -59,7 +59,7 @@ SET(LIBARCHIVE_VERSION_NUMBER "${_version_number}")
|
||||||
SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
|
SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
|
||||||
|
|
||||||
# INTERFACE_VERSION increments with every release
|
# INTERFACE_VERSION increments with every release
|
||||||
# libarchive 2.7 == interface version 9 = 2 + 7
|
# libarchive 2.7 == interface version 9 = 2 + 7
|
||||||
# libarchive 2.8 == interface version 10 = 2 + 8
|
# libarchive 2.8 == interface version 10 = 2 + 8
|
||||||
# libarchive 2.9 == interface version 11 = 2 + 9
|
# libarchive 2.9 == interface version 11 = 2 + 9
|
||||||
# libarchive 3.0 == interface version 12
|
# libarchive 3.0 == interface version 12
|
||||||
|
@ -97,6 +97,20 @@ IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
|
||||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wmissing-prototypes")
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wmissing-prototypes")
|
||||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wcast-qual")
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wcast-qual")
|
||||||
ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
|
ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
|
||||||
|
IF ("CMAKE_C_COMPILER_ID" MATCHES "^Clang$")
|
||||||
|
SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security")
|
||||||
|
#################################################################
|
||||||
|
# Set compile flags for all build types.
|
||||||
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security")
|
||||||
|
#################################################################
|
||||||
|
# Set compile flags for debug build.
|
||||||
|
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror -Wextra -Wunused")
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow")
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wmissing-prototypes")
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wcast-qual")
|
||||||
|
ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^Clang$")
|
||||||
IF (MSVC)
|
IF (MSVC)
|
||||||
#################################################################
|
#################################################################
|
||||||
# Set compile flags for debug build.
|
# Set compile flags for debug build.
|
||||||
|
@ -143,6 +157,13 @@ include(CTest)
|
||||||
|
|
||||||
OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
|
OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
|
||||||
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
|
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
|
||||||
|
OPTION(ENABLE_LZMA "Enable the use of the system found LZMA library if found" ON)
|
||||||
|
OPTION(ENABLE_ZLIB "Enable the use of the system found ZLIB library if found" ON)
|
||||||
|
OPTION(ENABLE_BZip2 "Enable the use of the system found BZip2 library if found" ON)
|
||||||
|
OPTION(ENABLE_EXPAT "Enable the use of the system found EXPAT library if found" ON)
|
||||||
|
OPTION(ENABLE_PCREPOSIX "Enable the use of the system found PCREPOSIX library if found" ON)
|
||||||
|
OPTION(ENABLE_LibGCC "Enable the use of the system found LibGCC library if found" ON)
|
||||||
|
|
||||||
OPTION(ENABLE_TAR "Enable tar building" ON)
|
OPTION(ENABLE_TAR "Enable tar building" ON)
|
||||||
OPTION(ENABLE_TAR_SHARED "Enable dynamic build of tar" FALSE)
|
OPTION(ENABLE_TAR_SHARED "Enable dynamic build of tar" FALSE)
|
||||||
OPTION(ENABLE_CPIO "Enable cpio building" ON)
|
OPTION(ENABLE_CPIO "Enable cpio building" ON)
|
||||||
|
@ -151,10 +172,16 @@ OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
|
||||||
OPTION(ENABLE_ACL "Enable ACL support" ON)
|
OPTION(ENABLE_ACL "Enable ACL support" ON)
|
||||||
OPTION(ENABLE_ICONV "Enable iconv support" ON)
|
OPTION(ENABLE_ICONV "Enable iconv support" ON)
|
||||||
OPTION(ENABLE_TEST "Enable unit and regression tests" ON)
|
OPTION(ENABLE_TEST "Enable unit and regression tests" ON)
|
||||||
|
OPTION(ENABLE_COVERAGE "Enable code coverage (GCC only, automatically sets ENABLE_TEST to ON)" FALSE)
|
||||||
|
|
||||||
SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support")
|
SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support")
|
||||||
SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)")
|
SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)")
|
||||||
SET(WINDOWS_VERSION "" CACHE STRING "Set Windows version to use (Windows only)")
|
SET(WINDOWS_VERSION "" CACHE STRING "Set Windows version to use (Windows only)")
|
||||||
|
|
||||||
|
IF(ENABLE_COVERAGE)
|
||||||
|
include(LibarchiveCodeCoverage)
|
||||||
|
ENDIF(ENABLE_COVERAGE)
|
||||||
|
|
||||||
IF(ENABLE_TEST)
|
IF(ENABLE_TEST)
|
||||||
ENABLE_TESTING()
|
ENABLE_TESTING()
|
||||||
ENDIF(ENABLE_TEST)
|
ENDIF(ENABLE_TEST)
|
||||||
|
@ -184,12 +211,12 @@ IF(MSVC)
|
||||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH")
|
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH")
|
||||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH")
|
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH")
|
||||||
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH")
|
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH")
|
||||||
SET(CMAKE_REQUIRED_LINKER_FLAGS "/SAFESEH")
|
SET(ENV{LDFLAGS} "$ENV{LDFLAGS} /SAFESEH")
|
||||||
ELSEIF(ENABLE_SAFESEH STREQUAL "NO")
|
ELSEIF(ENABLE_SAFESEH STREQUAL "NO")
|
||||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
|
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
|
||||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
|
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
|
||||||
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO")
|
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO")
|
||||||
SET(CMAKE_REQUIRED_LINKER_FLAGS "/SAFESEH:NO")
|
SET(ENV{LDFLAGS} "$ENV{LDFLAGS} /SAFESEH:NO")
|
||||||
ENDIF(ENABLE_SAFESEH STREQUAL "YES")
|
ENDIF(ENABLE_SAFESEH STREQUAL "YES")
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
|
|
||||||
|
@ -198,8 +225,8 @@ IF("${CMAKE_C_PLATFORM_ID}" MATCHES "^(HP-UX)$")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
#
|
#
|
||||||
INCLUDE(LibarchiveCheckCSourceCompiles)
|
INCLUDE(CheckCSourceCompiles)
|
||||||
INCLUDE(LibarchiveCheckCSourceRuns)
|
INCLUDE(CheckCSourceRuns)
|
||||||
INCLUDE(CheckFileOffsetBits)
|
INCLUDE(CheckFileOffsetBits)
|
||||||
INCLUDE(CheckFuncs)
|
INCLUDE(CheckFuncs)
|
||||||
INCLUDE(CheckHeaderDirent)
|
INCLUDE(CheckHeaderDirent)
|
||||||
|
@ -263,9 +290,9 @@ MACRO (TRY_MACRO_FOR_LIBRARY INCLUDES LIBRARIES
|
||||||
ENDIF(NOT "${PREV_VAR_WITH_LIB}" STREQUAL "${LIBRARIES}")
|
ENDIF(NOT "${PREV_VAR_WITH_LIB}" STREQUAL "${LIBRARIES}")
|
||||||
# Check if the library can be used with the macro.
|
# Check if the library can be used with the macro.
|
||||||
IF("${TRY_TYPE}" MATCHES "COMPILES")
|
IF("${TRY_TYPE}" MATCHES "COMPILES")
|
||||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR})
|
CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR})
|
||||||
ELSEIF("${TRY_TYPE}" MATCHES "RUNS")
|
ELSEIF("${TRY_TYPE}" MATCHES "RUNS")
|
||||||
LIBARCHIVE_CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
|
CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
|
||||||
ELSE("${TRY_TYPE}" MATCHES "COMPILES")
|
ELSE("${TRY_TYPE}" MATCHES "COMPILES")
|
||||||
MESSAGE(FATAL_ERROR "UNKNOWN KEYWORD \"${TRY_TYPE}\" FOR TRY_TYPE")
|
MESSAGE(FATAL_ERROR "UNKNOWN KEYWORD \"${TRY_TYPE}\" FOR TRY_TYPE")
|
||||||
ENDIF("${TRY_TYPE}" MATCHES "COMPILES")
|
ENDIF("${TRY_TYPE}" MATCHES "COMPILES")
|
||||||
|
@ -301,7 +328,7 @@ IF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
|
||||||
#--- zconf.h.orig 2005-07-21 00:40:26.000000000
|
#--- zconf.h.orig 2005-07-21 00:40:26.000000000
|
||||||
#+++ zconf.h 2009-01-19 11:39:10.093750000
|
#+++ zconf.h 2009-01-19 11:39:10.093750000
|
||||||
#@@ -286,7 +286,7 @@
|
#@@ -286,7 +286,7 @@
|
||||||
#
|
#
|
||||||
# #if 1 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
# #if 1 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||||
# # include <sys/types.h> /* for off_t */
|
# # include <sys/types.h> /* for off_t */
|
||||||
#-# include <unistd.h> /* for SEEK_* and off_t */
|
#-# include <unistd.h> /* for SEEK_* and off_t */
|
||||||
|
@ -315,7 +342,11 @@ SET(ADDITIONAL_LIBS "")
|
||||||
#
|
#
|
||||||
# Find ZLIB
|
# Find ZLIB
|
||||||
#
|
#
|
||||||
FIND_PACKAGE(ZLIB)
|
IF(ENABLE_ZLIB)
|
||||||
|
FIND_PACKAGE(ZLIB)
|
||||||
|
ELSE()
|
||||||
|
SET(ZLIB_FOUND FALSE) # Override cached value
|
||||||
|
ENDIF()
|
||||||
IF(ZLIB_FOUND)
|
IF(ZLIB_FOUND)
|
||||||
SET(HAVE_LIBZ 1)
|
SET(HAVE_LIBZ 1)
|
||||||
SET(HAVE_ZLIB_H 1)
|
SET(HAVE_ZLIB_H 1)
|
||||||
|
@ -350,7 +381,11 @@ MARK_AS_ADVANCED(CLEAR ZLIB_LIBRARY)
|
||||||
#
|
#
|
||||||
# Find BZip2
|
# Find BZip2
|
||||||
#
|
#
|
||||||
FIND_PACKAGE(BZip2)
|
IF(ENABLE_BZip2)
|
||||||
|
FIND_PACKAGE(BZip2)
|
||||||
|
ELSE()
|
||||||
|
SET(BZIP2_FOUND FALSE) # Override cached value
|
||||||
|
ENDIF()
|
||||||
IF(BZIP2_FOUND)
|
IF(BZIP2_FOUND)
|
||||||
SET(HAVE_LIBBZ2 1)
|
SET(HAVE_LIBBZ2 1)
|
||||||
SET(HAVE_BZLIB_H 1)
|
SET(HAVE_BZLIB_H 1)
|
||||||
|
@ -370,10 +405,18 @@ IF(BZIP2_FOUND)
|
||||||
ENDIF(BZIP2_FOUND)
|
ENDIF(BZIP2_FOUND)
|
||||||
MARK_AS_ADVANCED(CLEAR BZIP2_INCLUDE_DIR)
|
MARK_AS_ADVANCED(CLEAR BZIP2_INCLUDE_DIR)
|
||||||
MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARIES)
|
MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARIES)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Find LZMA
|
# Find LZMA
|
||||||
#
|
#
|
||||||
FIND_PACKAGE(LZMA)
|
IF(ENABLE_LZMA)
|
||||||
|
FIND_PACKAGE(LZMA)
|
||||||
|
ELSE()
|
||||||
|
SET(LZMA_FOUND FALSE) # Override cached value
|
||||||
|
SET(LZMADEC_FOUND FALSE) # Override cached value
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(LZMA_FOUND)
|
IF(LZMA_FOUND)
|
||||||
SET(HAVE_LIBLZMA 1)
|
SET(HAVE_LIBLZMA 1)
|
||||||
SET(HAVE_LZMA_H 1)
|
SET(HAVE_LZMA_H 1)
|
||||||
|
@ -393,6 +436,8 @@ ELSEIF(LZMADEC_FOUND)
|
||||||
SET(HAVE_LZMADEC_H 1)
|
SET(HAVE_LZMADEC_H 1)
|
||||||
INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
|
INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
|
||||||
LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
|
LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
|
||||||
|
ELSE(LZMA_FOUND)
|
||||||
|
# LZMA not found and will not be used.
|
||||||
ENDIF(LZMA_FOUND)
|
ENDIF(LZMA_FOUND)
|
||||||
#
|
#
|
||||||
# Find LZO2
|
# Find LZO2
|
||||||
|
@ -444,7 +489,7 @@ LA_CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLFCN_H)
|
||||||
LA_CHECK_INCLUDE_FILE("errno.h" HAVE_ERRNO_H)
|
LA_CHECK_INCLUDE_FILE("errno.h" HAVE_ERRNO_H)
|
||||||
LA_CHECK_INCLUDE_FILE("ext2fs/ext2_fs.h" HAVE_EXT2FS_EXT2_FS_H)
|
LA_CHECK_INCLUDE_FILE("ext2fs/ext2_fs.h" HAVE_EXT2FS_EXT2_FS_H)
|
||||||
|
|
||||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
|
CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
|
||||||
#include <ext2fs/ext2_fs.h>
|
#include <ext2fs/ext2_fs.h>
|
||||||
int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
|
int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
|
||||||
|
|
||||||
|
@ -507,7 +552,7 @@ FOREACH (it ${_HEADER})
|
||||||
SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
|
SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
|
||||||
ENDFOREACH (it)
|
ENDFOREACH (it)
|
||||||
|
|
||||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
CHECK_C_SOURCE_COMPILES(
|
||||||
"#define __EXTENSIONS__ 1
|
"#define __EXTENSIONS__ 1
|
||||||
${_INCLUDE_FILES}
|
${_INCLUDE_FILES}
|
||||||
int main() { return 0;}"
|
int main() { return 0;}"
|
||||||
|
@ -619,16 +664,10 @@ main(int argc, char **argv)
|
||||||
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}")
|
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}")
|
||||||
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}")
|
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}")
|
||||||
|
|
||||||
IF(CMAKE_REQUIRED_LINKER_FLAGS)
|
|
||||||
SET(CHECK_CRYPTO_ADD_LINKER_FLAGS
|
|
||||||
"-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
|
|
||||||
ELSE(CMAKE_REQUIRED_LINKER_FLAGS)
|
|
||||||
SET(CHECK_CRYPTO_ADD_LINKER_FLAGS)
|
|
||||||
ENDIF(CMAKE_REQUIRED_LINKER_FLAGS)
|
|
||||||
TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}
|
TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}
|
||||||
${CMAKE_BINARY_DIR}
|
${CMAKE_BINARY_DIR}
|
||||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c
|
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c
|
||||||
CMAKE_FLAGS ${CHECK_CRYPTO_ADD_LINKER_FLAGS}
|
CMAKE_FLAGS
|
||||||
"${TRY_CRYPTO_REQUIRED_LIBS}"
|
"${TRY_CRYPTO_REQUIRED_LIBS}"
|
||||||
"${TRY_CRYPTO_REQUIRED_INCLUDES}"
|
"${TRY_CRYPTO_REQUIRED_INCLUDES}"
|
||||||
OUTPUT_VARIABLE OUTPUT)
|
OUTPUT_VARIABLE OUTPUT)
|
||||||
|
@ -713,16 +752,10 @@ main(int argc, char **argv)
|
||||||
FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
|
FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
|
||||||
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
|
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
|
||||||
|
|
||||||
IF(CMAKE_REQUIRED_LINKER_FLAGS)
|
|
||||||
SET(CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS
|
|
||||||
"-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
|
|
||||||
ELSE(CMAKE_REQUIRED_LINKER_FLAGS)
|
|
||||||
SET(CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS)
|
|
||||||
ENDIF(CMAKE_REQUIRED_LINKER_FLAGS)
|
|
||||||
TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
|
TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
|
||||||
${CMAKE_BINARY_DIR}
|
${CMAKE_BINARY_DIR}
|
||||||
${SOURCE_FILE}
|
${SOURCE_FILE}
|
||||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive" ${CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS}
|
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive"
|
||||||
OUTPUT_VARIABLE OUTPUT)
|
OUTPUT_VARIABLE OUTPUT)
|
||||||
|
|
||||||
IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
|
IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
|
||||||
|
@ -768,7 +801,7 @@ MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
|
||||||
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /WX")
|
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /WX")
|
||||||
ENDIF (MSVC)
|
ENDIF (MSVC)
|
||||||
#
|
#
|
||||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
CHECK_C_SOURCE_COMPILES(
|
||||||
"#include <stdlib.h>
|
"#include <stdlib.h>
|
||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -883,8 +916,8 @@ ENDIF(ENABLE_ICONV)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Find Libxml2
|
# Find Libxml2
|
||||||
#
|
|
||||||
FIND_PACKAGE(LibXml2)
|
FIND_PACKAGE(LibXml2)
|
||||||
|
#
|
||||||
IF(LIBXML2_FOUND)
|
IF(LIBXML2_FOUND)
|
||||||
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
|
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
|
||||||
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
|
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
|
||||||
|
@ -979,8 +1012,16 @@ IF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$"
|
||||||
#
|
#
|
||||||
# If requested, try finding library for PCREPOSIX
|
# If requested, try finding library for PCREPOSIX
|
||||||
#
|
#
|
||||||
FIND_PACKAGE(LibGCC)
|
IF(ENABLE_LibGCC)
|
||||||
FIND_PACKAGE(PCREPOSIX)
|
FIND_PACKAGE(LibGCC)
|
||||||
|
ELSE()
|
||||||
|
SET(LIBGCC_FOUND FALSE) # Override cached value
|
||||||
|
ENDIF()
|
||||||
|
IF(ENABLE_PCREPOSIX)
|
||||||
|
FIND_PACKAGE(PCREPOSIX)
|
||||||
|
ELSE()
|
||||||
|
SET(PCREPOSIX_FOUND FALSE) # Override cached value
|
||||||
|
ENDIF()
|
||||||
IF(PCREPOSIX_FOUND)
|
IF(PCREPOSIX_FOUND)
|
||||||
INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIR})
|
INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIR})
|
||||||
LIST(APPEND ADDITIONAL_LIBS ${PCREPOSIX_LIBRARIES})
|
LIST(APPEND ADDITIONAL_LIBS ${PCREPOSIX_LIBRARIES})
|
||||||
|
@ -1131,14 +1172,14 @@ CMAKE_POP_CHECK_STATE() # Restore the state of the variables
|
||||||
|
|
||||||
# Make sure we have the POSIX version of readdir_r, not the
|
# Make sure we have the POSIX version of readdir_r, not the
|
||||||
# older 2-argument version.
|
# older 2-argument version.
|
||||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
CHECK_C_SOURCE_COMPILES(
|
||||||
"#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}"
|
"#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}"
|
||||||
HAVE_READDIR_R)
|
HAVE_READDIR_R)
|
||||||
|
|
||||||
|
|
||||||
# Only detect readlinkat() if we also have AT_FDCWD in unistd.h.
|
# Only detect readlinkat() if we also have AT_FDCWD in unistd.h.
|
||||||
# NOTE: linux requires fcntl.h for AT_FDCWD.
|
# NOTE: linux requires fcntl.h for AT_FDCWD.
|
||||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
CHECK_C_SOURCE_COMPILES(
|
||||||
"#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
|
"#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
|
||||||
HAVE_READLINKAT)
|
HAVE_READLINKAT)
|
||||||
|
|
||||||
|
@ -1147,10 +1188,10 @@ LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
||||||
# of interest and verify that the result can be linked.
|
# of interest and verify that the result can be linked.
|
||||||
# CHECK_FUNCTION_EXISTS doesn't accept a header argument,
|
# CHECK_FUNCTION_EXISTS doesn't accept a header argument,
|
||||||
# CHECK_SYMBOL_EXISTS doesn't test linkage.
|
# CHECK_SYMBOL_EXISTS doesn't test linkage.
|
||||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
CHECK_C_SOURCE_COMPILES(
|
||||||
"#include <sys/mkdev.h>\nint main() { return major(256); }"
|
"#include <sys/mkdev.h>\nint main() { return major(256); }"
|
||||||
MAJOR_IN_MKDEV)
|
MAJOR_IN_MKDEV)
|
||||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
CHECK_C_SOURCE_COMPILES(
|
||||||
"#include <sys/sysmacros.h>\nint main() { return major(256); }"
|
"#include <sys/sysmacros.h>\nint main() { return major(256); }"
|
||||||
MAJOR_IN_SYSMACROS)
|
MAJOR_IN_SYSMACROS)
|
||||||
|
|
||||||
|
@ -1242,13 +1283,13 @@ CHECK_TYPE_SIZE("unsigned long long" SIZE_OF_UNSIGNED_LONG_LONG)
|
||||||
CHECK_TYPE_SIZE("__int64" __INT64)
|
CHECK_TYPE_SIZE("__int64" __INT64)
|
||||||
CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
|
CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
|
||||||
|
|
||||||
CHECK_TYPE_SIZE(int16_t INT16_T)
|
CHECK_TYPE_SIZE(int16_t INT16_T)
|
||||||
CHECK_TYPE_SIZE(int32_t INT32_T)
|
CHECK_TYPE_SIZE(int32_t INT32_T)
|
||||||
CHECK_TYPE_SIZE(int64_t INT64_T)
|
CHECK_TYPE_SIZE(int64_t INT64_T)
|
||||||
CHECK_TYPE_SIZE(intmax_t INTMAX_T)
|
CHECK_TYPE_SIZE(intmax_t INTMAX_T)
|
||||||
CHECK_TYPE_SIZE(uint8_t UINT8_T)
|
CHECK_TYPE_SIZE(uint8_t UINT8_T)
|
||||||
CHECK_TYPE_SIZE(uint16_t UINT16_T)
|
CHECK_TYPE_SIZE(uint16_t UINT16_T)
|
||||||
CHECK_TYPE_SIZE(uint32_t UINT32_T)
|
CHECK_TYPE_SIZE(uint32_t UINT32_T)
|
||||||
CHECK_TYPE_SIZE(uint64_t UINT64_T)
|
CHECK_TYPE_SIZE(uint64_t UINT64_T)
|
||||||
CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
|
CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
|
||||||
|
|
||||||
|
@ -1491,6 +1532,9 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
|
||||||
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
|
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
ADD_DEFINITIONS(-DHAVE_CONFIG_H)
|
ADD_DEFINITIONS(-DHAVE_CONFIG_H)
|
||||||
|
|
||||||
|
# Handle generation of the libarchive.pc file for pkg-config
|
||||||
|
INCLUDE(CreatePkgConfigFile)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Register installation of PDF documents.
|
# Register installation of PDF documents.
|
||||||
#
|
#
|
||||||
|
|
|
@ -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")
|
|
@ -1,106 +0,0 @@
|
||||||
# - Check if given C source compiles and links into an executable
|
|
||||||
# CHECK_C_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>])
|
|
||||||
# <code> - source code to try to compile, must define 'main'
|
|
||||||
# <var> - variable to store whether the source code compiled
|
|
||||||
# <fail-regex> - fail if test output matches this regex
|
|
||||||
# The following variables may be set before calling this macro to
|
|
||||||
# modify the way the check is run:
|
|
||||||
#
|
|
||||||
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
|
|
||||||
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
|
|
||||||
# CMAKE_REQUIRED_INCLUDES = list of include directories
|
|
||||||
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Copyright 2005-2009 Kitware, Inc.
|
|
||||||
#
|
|
||||||
# Distributed under the OSI-approved BSD License (the "License");
|
|
||||||
# see accompanying file Copyright.txt for details.
|
|
||||||
#
|
|
||||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
|
||||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the License for more information.
|
|
||||||
#=============================================================================
|
|
||||||
# (To distribute this file outside of CMake, substitute the full
|
|
||||||
# License text for the above reference.)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Extra arguments added by libarchive
|
|
||||||
# CMAKE_REQUIRED_LINKER_FLAGS = string of linker command line flags
|
|
||||||
#
|
|
||||||
|
|
||||||
include(CMakeExpandImportedTargets)
|
|
||||||
|
|
||||||
|
|
||||||
macro(LIBARCHIVE_CHECK_C_SOURCE_COMPILES SOURCE VAR)
|
|
||||||
if("${VAR}" MATCHES "^${VAR}$")
|
|
||||||
set(_FAIL_REGEX)
|
|
||||||
set(_key)
|
|
||||||
foreach(arg ${ARGN})
|
|
||||||
if("${arg}" MATCHES "^(FAIL_REGEX)$")
|
|
||||||
set(_key "${arg}")
|
|
||||||
elseif(_key)
|
|
||||||
list(APPEND _${_key} "${arg}")
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
|
||||||
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
|
|
||||||
if(CMAKE_REQUIRED_LIBRARIES)
|
|
||||||
# this one translates potentially used imported library targets to their files on disk
|
|
||||||
CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
|
|
||||||
"-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
|
|
||||||
else()
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
|
|
||||||
endif()
|
|
||||||
if(CMAKE_REQUIRED_INCLUDES)
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
|
|
||||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
|
||||||
else()
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
|
|
||||||
endif()
|
|
||||||
if(CMAKE_REQUIRED_LINKER_FLAGS)
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_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()
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS)
|
|
||||||
endif()
|
|
||||||
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
|
|
||||||
"${SOURCE}\n")
|
|
||||||
|
|
||||||
message(STATUS "Performing Test ${VAR}")
|
|
||||||
try_compile(${VAR}
|
|
||||||
${CMAKE_BINARY_DIR}
|
|
||||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
|
|
||||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
|
|
||||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} ${CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS}
|
|
||||||
"${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
|
|
||||||
"${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
|
|
||||||
OUTPUT_VARIABLE OUTPUT)
|
|
||||||
|
|
||||||
foreach(_regex ${_FAIL_REGEX})
|
|
||||||
if("${OUTPUT}" MATCHES "${_regex}")
|
|
||||||
set(${VAR} 0)
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
if(${VAR})
|
|
||||||
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
|
|
||||||
message(STATUS "Performing Test ${VAR} - Success")
|
|
||||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
|
||||||
"Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
|
|
||||||
"${OUTPUT}\n"
|
|
||||||
"Source file was:\n${SOURCE}\n")
|
|
||||||
else()
|
|
||||||
message(STATUS "Performing Test ${VAR} - Failed")
|
|
||||||
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
|
|
||||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
|
||||||
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
|
|
||||||
"${OUTPUT}\n"
|
|
||||||
"Source file was:\n${SOURCE}\n")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
# - Check if the given C source code compiles and runs.
|
|
||||||
# CHECK_C_SOURCE_RUNS(<code> <var>)
|
|
||||||
# <code> - source code to try to compile
|
|
||||||
# <var> - variable to store the result
|
|
||||||
# (1 for success, empty for failure)
|
|
||||||
# The following variables may be set before calling this macro to
|
|
||||||
# modify the way the check is run:
|
|
||||||
#
|
|
||||||
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
|
|
||||||
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
|
|
||||||
# CMAKE_REQUIRED_INCLUDES = list of include directories
|
|
||||||
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Copyright 2006-2009 Kitware, Inc.
|
|
||||||
#
|
|
||||||
# Distributed under the OSI-approved BSD License (the "License");
|
|
||||||
# see accompanying file Copyright.txt for details.
|
|
||||||
#
|
|
||||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
|
||||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the License for more information.
|
|
||||||
#=============================================================================
|
|
||||||
# (To distribute this file outside of CMake, substitute the full
|
|
||||||
# License text for the above reference.)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Extra arguments added by libarchive
|
|
||||||
# CMAKE_REQUIRED_LINKER_FLAGS = string of linker command line flags
|
|
||||||
#
|
|
||||||
|
|
||||||
include(CMakeExpandImportedTargets)
|
|
||||||
|
|
||||||
|
|
||||||
macro(LIBARCHIVE_CHECK_C_SOURCE_RUNS SOURCE VAR)
|
|
||||||
if("${VAR}" MATCHES "^${VAR}$")
|
|
||||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
|
||||||
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
|
|
||||||
if(CMAKE_REQUIRED_LIBRARIES)
|
|
||||||
# this one translates potentially used imported library targets to their files on disk
|
|
||||||
CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
|
|
||||||
"-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
|
|
||||||
else()
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
|
|
||||||
endif()
|
|
||||||
if(CMAKE_REQUIRED_INCLUDES)
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
|
|
||||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
|
||||||
else()
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
|
|
||||||
endif()
|
|
||||||
if(CMAKE_REQUIRED_LINKER_FLAGS)
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_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()
|
|
||||||
set(CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS)
|
|
||||||
endif()
|
|
||||||
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
|
|
||||||
"${SOURCE}\n")
|
|
||||||
|
|
||||||
message(STATUS "Performing Test ${VAR}")
|
|
||||||
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
|
|
||||||
${CMAKE_BINARY_DIR}
|
|
||||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
|
|
||||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
|
|
||||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} ${CHECK_C_SOURCE_COMPILES_ADD_LINKER_FLAGS}
|
|
||||||
-DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
|
|
||||||
"${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
|
|
||||||
"${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
|
|
||||||
COMPILE_OUTPUT_VARIABLE OUTPUT)
|
|
||||||
# if it did not compile make the return value fail code of 1
|
|
||||||
if(NOT ${VAR}_COMPILED)
|
|
||||||
set(${VAR}_EXITCODE 1)
|
|
||||||
endif()
|
|
||||||
# if the return value was 0 then it worked
|
|
||||||
if("${${VAR}_EXITCODE}" EQUAL 0)
|
|
||||||
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
|
|
||||||
message(STATUS "Performing Test ${VAR} - Success")
|
|
||||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
|
||||||
"Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
|
|
||||||
"${OUTPUT}\n"
|
|
||||||
"Return value: ${${VAR}}\n"
|
|
||||||
"Source file was:\n${SOURCE}\n")
|
|
||||||
else()
|
|
||||||
if(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
|
|
||||||
set(${VAR} "${${VAR}_EXITCODE}")
|
|
||||||
else()
|
|
||||||
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "Performing Test ${VAR} - Failed")
|
|
||||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
|
||||||
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
|
|
||||||
"${OUTPUT}\n"
|
|
||||||
"Return value: ${${VAR}_EXITCODE}\n"
|
|
||||||
"Source file was:\n${SOURCE}\n")
|
|
||||||
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
|
@ -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)")
|
||||||
|
|
|
@ -1106,8 +1106,13 @@ typedef uint64_t uintmax_t;
|
||||||
#cmakedefine _LARGE_FILES ${_LARGE_FILES}
|
#cmakedefine _LARGE_FILES ${_LARGE_FILES}
|
||||||
|
|
||||||
/* Define for Windows to use Windows 2000+ APIs. */
|
/* Define for Windows to use Windows 2000+ APIs. */
|
||||||
|
#ifndef _WIN32_WINNT
|
||||||
#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
|
#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
|
||||||
|
#endif // _WIN32_WINNT
|
||||||
|
|
||||||
|
#ifndef WINVER
|
||||||
#cmakedefine WINVER ${WINVER}
|
#cmakedefine WINVER ${WINVER}
|
||||||
|
#endif // WINVER
|
||||||
|
|
||||||
/* Define to empty if `const' does not conform to ANSI C. */
|
/* Define to empty if `const' does not conform to ANSI C. */
|
||||||
#cmakedefine const ${const}
|
#cmakedefine const ${const}
|
||||||
|
|
|
@ -35,6 +35,8 @@ SET(libarchive_SOURCES
|
||||||
archive_match.c
|
archive_match.c
|
||||||
archive_options.c
|
archive_options.c
|
||||||
archive_options_private.h
|
archive_options_private.h
|
||||||
|
archive_pack_dev.h
|
||||||
|
archive_pack_dev.c
|
||||||
archive_pathmatch.c
|
archive_pathmatch.c
|
||||||
archive_pathmatch.h
|
archive_pathmatch.h
|
||||||
archive_platform.h
|
archive_platform.h
|
||||||
|
@ -125,6 +127,7 @@ SET(libarchive_SOURCES
|
||||||
archive_write_set_format_iso9660.c
|
archive_write_set_format_iso9660.c
|
||||||
archive_write_set_format_mtree.c
|
archive_write_set_format_mtree.c
|
||||||
archive_write_set_format_pax.c
|
archive_write_set_format_pax.c
|
||||||
|
archive_write_set_format_raw.c
|
||||||
archive_write_set_format_shar.c
|
archive_write_set_format_shar.c
|
||||||
archive_write_set_format_ustar.c
|
archive_write_set_format_ustar.c
|
||||||
archive_write_set_format_v7tar.c
|
archive_write_set_format_v7tar.c
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
/* Get appropriate definitions of standard POSIX-style types. */
|
/* Get appropriate definitions of standard POSIX-style types. */
|
||||||
/* These should match the types used in 'struct stat' */
|
/* These should match the types used in 'struct stat' */
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
|
||||||
# define __LA_INT64_T __int64
|
# define __LA_INT64_T __int64
|
||||||
# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
|
# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
|
||||||
# define __LA_SSIZE_T ssize_t
|
# define __LA_SSIZE_T ssize_t
|
||||||
|
@ -133,6 +133,11 @@ __LA_DECL int archive_version_number(void);
|
||||||
#define ARCHIVE_VERSION_STRING "libarchive 3.1.2"
|
#define ARCHIVE_VERSION_STRING "libarchive 3.1.2"
|
||||||
__LA_DECL const char * archive_version_string(void);
|
__LA_DECL const char * archive_version_string(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Detailed textual name/version of the library and its dependencies.
|
||||||
|
*/
|
||||||
|
__LA_DECL const char * archive_version_details(void);
|
||||||
|
|
||||||
/* Declare our basic types. */
|
/* Declare our basic types. */
|
||||||
struct archive;
|
struct archive;
|
||||||
struct archive_entry;
|
struct archive_entry;
|
||||||
|
@ -285,6 +290,30 @@ typedef int archive_switch_callback(struct archive *, void *_client_data1,
|
||||||
#define ARCHIVE_FORMAT_RAR 0xD0000
|
#define ARCHIVE_FORMAT_RAR 0xD0000
|
||||||
#define ARCHIVE_FORMAT_7ZIP 0xE0000
|
#define ARCHIVE_FORMAT_7ZIP 0xE0000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Codes returned by archive_read_format_capabilities().
|
||||||
|
*
|
||||||
|
* This list can be extended with values between 0 and 0xffff.
|
||||||
|
* The original purpose of this list was to let different archive
|
||||||
|
* format readers expose their general capabilities in terms of
|
||||||
|
* encryption.
|
||||||
|
*/
|
||||||
|
#define ARCHIVE_READ_FORMAT_CAPS_NONE (0) /* no special capabilities */
|
||||||
|
#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA (1<<0) /* reader can detect encrypted data */
|
||||||
|
#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA (1<<1) /* reader can detect encryptable metadata (pathname, mtime, etc.) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Codes returned by archive_read_has_encrypted_entries().
|
||||||
|
*
|
||||||
|
* In case the archive does not support encryption detection at all
|
||||||
|
* ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned. If the reader
|
||||||
|
* for some other reason (e.g. not enough bytes read) cannot say if
|
||||||
|
* there are encrypted entries, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW
|
||||||
|
* is returned.
|
||||||
|
*/
|
||||||
|
#define ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED -2
|
||||||
|
#define ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW -1
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Basic outline for reading an archive:
|
* Basic outline for reading an archive:
|
||||||
* 1) Ask archive_read_new for an archive reader object.
|
* 1) Ask archive_read_new for an archive reader object.
|
||||||
|
@ -370,7 +399,15 @@ __LA_DECL int archive_read_support_format_rar(struct archive *);
|
||||||
__LA_DECL int archive_read_support_format_raw(struct archive *);
|
__LA_DECL int archive_read_support_format_raw(struct archive *);
|
||||||
__LA_DECL int archive_read_support_format_tar(struct archive *);
|
__LA_DECL int archive_read_support_format_tar(struct archive *);
|
||||||
__LA_DECL int archive_read_support_format_xar(struct archive *);
|
__LA_DECL int archive_read_support_format_xar(struct archive *);
|
||||||
|
/* archive_read_support_format_zip() enables both streamable and seekable
|
||||||
|
* zip readers. */
|
||||||
__LA_DECL int archive_read_support_format_zip(struct archive *);
|
__LA_DECL int archive_read_support_format_zip(struct archive *);
|
||||||
|
/* Reads Zip archives as stream from beginning to end. Doesn't
|
||||||
|
* correctly handle SFX ZIP files or ZIP archives that have been modified
|
||||||
|
* in-place. */
|
||||||
|
__LA_DECL int archive_read_support_format_zip_streamable(struct archive *);
|
||||||
|
/* Reads starting from central directory; requires seekable input. */
|
||||||
|
__LA_DECL int archive_read_support_format_zip_seekable(struct archive *);
|
||||||
|
|
||||||
/* Functions to manually set the format and filters to be used. This is
|
/* Functions to manually set the format and filters to be used. This is
|
||||||
* useful to bypass the bidding process when the format and filters to use
|
* useful to bypass the bidding process when the format and filters to use
|
||||||
|
@ -466,6 +503,32 @@ __LA_DECL int archive_read_next_header2(struct archive *,
|
||||||
*/
|
*/
|
||||||
__LA_DECL __LA_INT64_T archive_read_header_position(struct archive *);
|
__LA_DECL __LA_INT64_T archive_read_header_position(struct archive *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if the archive contains at least one encrypted entry.
|
||||||
|
* If the archive format not support encryption at all
|
||||||
|
* ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
|
||||||
|
* If for any other reason (e.g. not enough data read so far)
|
||||||
|
* we cannot say whether there are encrypted entries, then
|
||||||
|
* ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
|
||||||
|
* In general, this function will return values below zero when the
|
||||||
|
* reader is uncertain or totally uncapable of encryption support.
|
||||||
|
* When this function returns 0 you can be sure that the reader
|
||||||
|
* supports encryption detection but no encrypted entries have
|
||||||
|
* been found yet.
|
||||||
|
*
|
||||||
|
* NOTE: If the metadata/header of an archive is also encrypted, you
|
||||||
|
* cannot rely on the number of encrypted entries. That is why this
|
||||||
|
* function does not return the number of encrypted entries but#
|
||||||
|
* just shows that there are some.
|
||||||
|
*/
|
||||||
|
__LA_DECL int archive_read_has_encrypted_entries(struct archive *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a bitmask of capabilities that are supported by the archive format reader.
|
||||||
|
* If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
|
||||||
|
*/
|
||||||
|
__LA_DECL int archive_read_format_capabilities(struct archive *);
|
||||||
|
|
||||||
/* Read data from the body of an entry. Similar to read(2). */
|
/* Read data from the body of an entry. Similar to read(2). */
|
||||||
__LA_DECL __LA_SSIZE_T archive_read_data(struct archive *,
|
__LA_DECL __LA_SSIZE_T archive_read_data(struct archive *,
|
||||||
void *, size_t);
|
void *, size_t);
|
||||||
|
@ -670,6 +733,7 @@ __LA_DECL int archive_write_set_format_mtree_classic(struct archive *);
|
||||||
/* TODO: int archive_write_set_format_old_tar(struct archive *); */
|
/* TODO: int archive_write_set_format_old_tar(struct archive *); */
|
||||||
__LA_DECL int archive_write_set_format_pax(struct archive *);
|
__LA_DECL int archive_write_set_format_pax(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
|
__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
|
||||||
|
__LA_DECL int archive_write_set_format_raw(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_shar(struct archive *);
|
__LA_DECL int archive_write_set_format_shar(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_shar_dump(struct archive *);
|
__LA_DECL int archive_write_set_format_shar_dump(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_ustar(struct archive *);
|
__LA_DECL int archive_write_set_format_ustar(struct archive *);
|
||||||
|
@ -879,6 +943,10 @@ __LA_DECL int archive_read_disk_set_metadata_filter_callback(struct archive *,
|
||||||
int (*_metadata_filter_func)(struct archive *, void *,
|
int (*_metadata_filter_func)(struct archive *, void *,
|
||||||
struct archive_entry *), void *_client_data);
|
struct archive_entry *), void *_client_data);
|
||||||
|
|
||||||
|
/* Simplified cleanup interface;
|
||||||
|
* This calls archive_read_free() or archive_write_free() as needed. */
|
||||||
|
__LA_DECL int archive_free(struct archive *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accessor functions to read/set various information in
|
* Accessor functions to read/set various information in
|
||||||
* the struct archive object:
|
* the struct archive object:
|
||||||
|
@ -1025,6 +1093,10 @@ __LA_DECL int archive_match_include_gname(struct archive *, const char *);
|
||||||
__LA_DECL int archive_match_include_gname_w(struct archive *,
|
__LA_DECL int archive_match_include_gname_w(struct archive *,
|
||||||
const wchar_t *);
|
const wchar_t *);
|
||||||
|
|
||||||
|
/* Utility functions */
|
||||||
|
/* Convenience function to sort a NULL terminated list of strings */
|
||||||
|
__LA_DECL int archive_utility_string_sort(char **);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -58,7 +58,13 @@ archive_be16dec(const void *pp)
|
||||||
{
|
{
|
||||||
unsigned char const *p = (unsigned char const *)pp;
|
unsigned char const *p = (unsigned char const *)pp;
|
||||||
|
|
||||||
return ((p[0] << 8) | p[1]);
|
/* Store into unsigned temporaries before left shifting, to avoid
|
||||||
|
promotion to signed int and then left shifting into the sign bit,
|
||||||
|
which is undefined behaviour. */
|
||||||
|
unsigned int p1 = p[1];
|
||||||
|
unsigned int p0 = p[0];
|
||||||
|
|
||||||
|
return ((p0 << 8) | p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
|
@ -66,7 +72,15 @@ archive_be32dec(const void *pp)
|
||||||
{
|
{
|
||||||
unsigned char const *p = (unsigned char const *)pp;
|
unsigned char const *p = (unsigned char const *)pp;
|
||||||
|
|
||||||
return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
|
/* Store into unsigned temporaries before left shifting, to avoid
|
||||||
|
promotion to signed int and then left shifting into the sign bit,
|
||||||
|
which is undefined behaviour. */
|
||||||
|
unsigned int p3 = p[3];
|
||||||
|
unsigned int p2 = p[2];
|
||||||
|
unsigned int p1 = p[1];
|
||||||
|
unsigned int p0 = p[0];
|
||||||
|
|
||||||
|
return ((p0 << 24) | (p1 << 16) | (p2 << 8) | p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t
|
static inline uint64_t
|
||||||
|
@ -82,7 +96,13 @@ archive_le16dec(const void *pp)
|
||||||
{
|
{
|
||||||
unsigned char const *p = (unsigned char const *)pp;
|
unsigned char const *p = (unsigned char const *)pp;
|
||||||
|
|
||||||
return ((p[1] << 8) | p[0]);
|
/* Store into unsigned temporaries before left shifting, to avoid
|
||||||
|
promotion to signed int and then left shifting into the sign bit,
|
||||||
|
which is undefined behaviour. */
|
||||||
|
unsigned int p1 = p[1];
|
||||||
|
unsigned int p0 = p[0];
|
||||||
|
|
||||||
|
return ((p1 << 8) | p0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
|
@ -90,7 +110,15 @@ archive_le32dec(const void *pp)
|
||||||
{
|
{
|
||||||
unsigned char const *p = (unsigned char const *)pp;
|
unsigned char const *p = (unsigned char const *)pp;
|
||||||
|
|
||||||
return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
|
/* Store into unsigned temporaries before left shifting, to avoid
|
||||||
|
promotion to signed int and then left shifting into the sign bit,
|
||||||
|
which is undefined behaviour. */
|
||||||
|
unsigned int p3 = p[3];
|
||||||
|
unsigned int p2 = p[2];
|
||||||
|
unsigned int p1 = p[1];
|
||||||
|
unsigned int p0 = p[0];
|
||||||
|
|
||||||
|
return ((p3 << 24) | (p2 << 16) | (p1 << 8) | p0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t
|
static inline uint64_t
|
||||||
|
|
|
@ -201,6 +201,9 @@ archive_entry_clone(struct archive_entry *entry)
|
||||||
entry2->ae_set = entry->ae_set;
|
entry2->ae_set = entry->ae_set;
|
||||||
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
|
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
|
||||||
|
|
||||||
|
/* Copy encryption status */
|
||||||
|
entry2->encryption = entry->encryption;
|
||||||
|
|
||||||
/* Copy ACL data over. */
|
/* Copy ACL data over. */
|
||||||
archive_acl_copy(&entry2->acl, &entry->acl);
|
archive_acl_copy(&entry2->acl, &entry->acl);
|
||||||
|
|
||||||
|
@ -695,6 +698,24 @@ _archive_entry_uname_l(struct archive_entry *entry,
|
||||||
return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
|
return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
archive_entry_is_data_encrypted(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
return ((entry->encryption & AE_ENCRYPTION_DATA) == AE_ENCRYPTION_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
archive_entry_is_metadata_encrypted(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
return ((entry->encryption & AE_ENCRYPTION_METADATA) == AE_ENCRYPTION_METADATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
archive_entry_is_encrypted(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
return (entry->encryption & (AE_ENCRYPTION_DATA|AE_ENCRYPTION_METADATA));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions to set archive_entry properties.
|
* Functions to set archive_entry properties.
|
||||||
*/
|
*/
|
||||||
|
@ -1216,6 +1237,26 @@ archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
archive_entry_set_is_data_encrypted(struct archive_entry *entry, char is_encrypted)
|
||||||
|
{
|
||||||
|
if (is_encrypted) {
|
||||||
|
entry->encryption |= AE_ENCRYPTION_DATA;
|
||||||
|
} else {
|
||||||
|
entry->encryption &= ~AE_ENCRYPTION_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
archive_entry_set_is_metadata_encrypted(struct archive_entry *entry, char is_encrypted)
|
||||||
|
{
|
||||||
|
if (is_encrypted) {
|
||||||
|
entry->encryption |= AE_ENCRYPTION_METADATA;
|
||||||
|
} else {
|
||||||
|
entry->encryption &= ~AE_ENCRYPTION_METADATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_archive_entry_copy_uname_l(struct archive_entry *entry,
|
_archive_entry_copy_uname_l(struct archive_entry *entry,
|
||||||
const char *name, size_t len, struct archive_string_conv *sc)
|
const char *name, size_t len, struct archive_string_conv *sc)
|
||||||
|
|
|
@ -43,12 +43,8 @@
|
||||||
#include <stddef.h> /* for wchar_t */
|
#include <stddef.h> /* for wchar_t */
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get a suitable 64-bit integer type. */
|
/* Get a suitable 64-bit integer type. */
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
|
||||||
# define __LA_INT64_T __int64
|
# define __LA_INT64_T __int64
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -63,7 +59,7 @@
|
||||||
#if ARCHIVE_VERSION_NUMBER >= 3999000
|
#if ARCHIVE_VERSION_NUMBER >= 3999000
|
||||||
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
|
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
|
||||||
# define __LA_MODE_T int
|
# define __LA_MODE_T int
|
||||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__)
|
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
|
||||||
# define __LA_MODE_T unsigned short
|
# define __LA_MODE_T unsigned short
|
||||||
#else
|
#else
|
||||||
# define __LA_MODE_T mode_t
|
# define __LA_MODE_T mode_t
|
||||||
|
@ -235,6 +231,9 @@ __LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
|
||||||
__LA_DECL __LA_INT64_T archive_entry_uid(struct archive_entry *);
|
__LA_DECL __LA_INT64_T archive_entry_uid(struct archive_entry *);
|
||||||
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
|
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
|
||||||
__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
|
__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
|
||||||
|
__LA_DECL int archive_entry_is_data_encrypted(struct archive_entry *);
|
||||||
|
__LA_DECL int archive_entry_is_metadata_encrypted(struct archive_entry *);
|
||||||
|
__LA_DECL int archive_entry_is_encrypted(struct archive_entry *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set fields in an archive_entry.
|
* Set fields in an archive_entry.
|
||||||
|
@ -306,6 +305,8 @@ __LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
|
||||||
__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
|
__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
|
||||||
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
|
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
|
||||||
__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *);
|
__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *);
|
||||||
|
__LA_DECL void archive_entry_set_is_data_encrypted(struct archive_entry *, char is_encrypted);
|
||||||
|
__LA_DECL void archive_entry_set_is_metadata_encrypted(struct archive_entry *, char is_encrypted);
|
||||||
/*
|
/*
|
||||||
* Routines to bulk copy fields to/from a platform-native "struct
|
* Routines to bulk copy fields to/from a platform-native "struct
|
||||||
* stat." Libarchive used to just store a struct stat inside of each
|
* stat." Libarchive used to just store a struct stat inside of each
|
||||||
|
|
|
@ -154,6 +154,11 @@ struct archive_entry {
|
||||||
/* Not used within libarchive; useful for some clients. */
|
/* Not used within libarchive; useful for some clients. */
|
||||||
struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */
|
struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */
|
||||||
|
|
||||||
|
#define AE_ENCRYPTION_NONE 0
|
||||||
|
#define AE_ENCRYPTION_DATA 1
|
||||||
|
#define AE_ENCRYPTION_METADATA 2
|
||||||
|
char encryption;
|
||||||
|
|
||||||
void *mac_metadata;
|
void *mac_metadata;
|
||||||
size_t mac_metadata_size;
|
size_t mac_metadata_size;
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ archive_entry_sparse_add_entry(struct archive_entry *entry,
|
||||||
if (offset < 0 || length < 0)
|
if (offset < 0 || length < 0)
|
||||||
/* Invalid value */
|
/* Invalid value */
|
||||||
return;
|
return;
|
||||||
if (offset + length < 0 ||
|
if (offset > INT64_MAX - length ||
|
||||||
offset + length > archive_entry_size(entry))
|
offset + length > archive_entry_size(entry))
|
||||||
/* A value of "length" parameter is too large. */
|
/* A value of "length" parameter is too large. */
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -369,8 +369,8 @@ relunitphrase(struct gdstate *gds)
|
||||||
&& gds->tokenp[1].token == tSEC_UNIT) {
|
&& gds->tokenp[1].token == tSEC_UNIT) {
|
||||||
/* "1 day" */
|
/* "1 day" */
|
||||||
gds->HaveRel++;
|
gds->HaveRel++;
|
||||||
gds->RelSeconds += gds->tokenp[1].value * gds->tokenp[2].value;
|
gds->RelSeconds += gds->tokenp[0].value * gds->tokenp[1].value;
|
||||||
gds->tokenp += 3;
|
gds->tokenp += 2;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (gds->tokenp[0].token == '-'
|
if (gds->tokenp[0].token == '-'
|
||||||
|
@ -403,7 +403,7 @@ relunitphrase(struct gdstate *gds)
|
||||||
/* "now", "tomorrow" */
|
/* "now", "tomorrow" */
|
||||||
gds->HaveRel++;
|
gds->HaveRel++;
|
||||||
gds->RelSeconds += gds->tokenp[0].value;
|
gds->RelSeconds += gds->tokenp[0].value;
|
||||||
++gds->tokenp;
|
gds->tokenp += 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (gds->tokenp[0].token == tMONTH_UNIT) {
|
if (gds->tokenp[0].token == tMONTH_UNIT) {
|
||||||
|
@ -1022,10 +1022,11 @@ int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
time_t d;
|
time_t d;
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
while (*++argv != NULL) {
|
while (*++argv != NULL) {
|
||||||
(void)printf("Input: %s\n", *argv);
|
(void)printf("Input: %s\n", *argv);
|
||||||
d = get_date(*argv);
|
d = get_date(now, *argv);
|
||||||
if (d == -1)
|
if (d == -1)
|
||||||
(void)printf("Bad format - couldn't convert.\n");
|
(void)printf("Bad format - couldn't convert.\n");
|
||||||
else
|
else
|
||||||
|
|
|
@ -1152,7 +1152,7 @@ set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
|
||||||
{
|
{
|
||||||
/* NOTE: stat() on Windows cannot handle nano seconds. */
|
/* NOTE: stat() on Windows cannot handle nano seconds. */
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
WIN32_FIND_DATA d;
|
WIN32_FIND_DATAA d;
|
||||||
|
|
||||||
if (path == NULL || *path == '\0') {
|
if (path == NULL || *path == '\0') {
|
||||||
archive_set_error(&(a->archive), EINVAL, "pathname is empty");
|
archive_set_error(&(a->archive), EINVAL, "pathname is empty");
|
||||||
|
|
|
@ -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, u_long numbers[], const char **error)
|
||||||
|
{
|
||||||
|
dev_t dev = 0;
|
||||||
|
|
||||||
|
if (n == 2) {
|
||||||
|
dev = apd_makedev(numbers[0], numbers[1]);
|
||||||
|
if ((u_long)major(dev) != numbers[0])
|
||||||
|
*error = iMajorError;
|
||||||
|
else if ((u_long)minor(dev) != numbers[1])
|
||||||
|
*error = iMinorError;
|
||||||
|
} else
|
||||||
|
*error = tooManyFields;
|
||||||
|
return (dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static dev_t
|
||||||
|
pack_netbsd(int n, u_long numbers[], const char **error)
|
||||||
|
{
|
||||||
|
dev_t dev = 0;
|
||||||
|
|
||||||
|
if (n == 2) {
|
||||||
|
dev = makedev_netbsd(numbers[0], numbers[1]);
|
||||||
|
if ((u_long)major_netbsd(dev) != numbers[0])
|
||||||
|
*error = iMajorError;
|
||||||
|
else if ((u_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, u_long numbers[], const char **error)
|
||||||
|
{
|
||||||
|
dev_t dev = 0;
|
||||||
|
|
||||||
|
if (n == 2) {
|
||||||
|
dev = makedev_freebsd(numbers[0], numbers[1]);
|
||||||
|
if ((u_long)major_freebsd(dev) != numbers[0])
|
||||||
|
*error = iMajorError;
|
||||||
|
if ((u_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, u_long numbers[], const char **error)
|
||||||
|
{
|
||||||
|
dev_t dev = 0;
|
||||||
|
|
||||||
|
if (n == 2) {
|
||||||
|
dev = makedev_8_8(numbers[0], numbers[1]);
|
||||||
|
if ((u_long)major_8_8(dev) != numbers[0])
|
||||||
|
*error = iMajorError;
|
||||||
|
if ((u_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, u_long numbers[], const char **error)
|
||||||
|
{
|
||||||
|
dev_t dev = 0;
|
||||||
|
|
||||||
|
if (n == 2) {
|
||||||
|
dev = makedev_12_20(numbers[0], numbers[1]);
|
||||||
|
if ((u_long)major_12_20(dev) != numbers[0])
|
||||||
|
*error = iMajorError;
|
||||||
|
if ((u_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, u_long numbers[], const char **error)
|
||||||
|
{
|
||||||
|
dev_t dev = 0;
|
||||||
|
|
||||||
|
if (n == 2) {
|
||||||
|
dev = makedev_14_18(numbers[0], numbers[1]);
|
||||||
|
if ((u_long)major_14_18(dev) != numbers[0])
|
||||||
|
*error = iMajorError;
|
||||||
|
if ((u_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, u_long numbers[], const char **error)
|
||||||
|
{
|
||||||
|
dev_t dev = 0;
|
||||||
|
|
||||||
|
if (n == 2) {
|
||||||
|
dev = makedev_8_24(numbers[0], numbers[1]);
|
||||||
|
if ((u_long)major_8_24(dev) != numbers[0])
|
||||||
|
*error = iMajorError;
|
||||||
|
if ((u_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, u_long numbers[], const char **error)
|
||||||
|
{
|
||||||
|
dev_t dev = 0;
|
||||||
|
|
||||||
|
if (n == 2) {
|
||||||
|
dev = makedev_12_20(numbers[0], numbers[1]);
|
||||||
|
if ((u_long)major_12_20(dev) != numbers[0])
|
||||||
|
*error = iMajorError;
|
||||||
|
if ((u_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 ((u_long)major_12_12_8(dev) != numbers[0])
|
||||||
|
*error = iMajorError;
|
||||||
|
if ((u_long)unit_12_12_8(dev) != numbers[1])
|
||||||
|
*error = "invalid unit number";
|
||||||
|
if ((u_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);
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/* $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, u_long [], const char **);
|
||||||
|
typedef unsigned long u_long;
|
||||||
|
|
||||||
|
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 */
|
|
@ -66,15 +66,18 @@
|
||||||
* headers as required.
|
* headers as required.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Get a real definition for __FBSDID if we can */
|
/* Get a real definition for __FBSDID or __RCSID if we can */
|
||||||
#if HAVE_SYS_CDEFS_H
|
#if HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If not, define it so as to avoid dangling semicolons. */
|
/* If not, define them so as to avoid dangling semicolons. */
|
||||||
#ifndef __FBSDID
|
#ifndef __FBSDID
|
||||||
#define __FBSDID(a) struct _undefined_hack
|
#define __FBSDID(a) struct _undefined_hack
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef __RCSID
|
||||||
|
#define __RCSID(a) struct _undefined_hack
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Try to get standard C99-style integer type definitions. */
|
/* Try to get standard C99-style integer type definitions. */
|
||||||
#if HAVE_INTTYPES_H
|
#if HAVE_INTTYPES_H
|
||||||
|
|
|
@ -746,6 +746,59 @@ archive_read_header_position(struct archive *_a)
|
||||||
return (a->header_position);
|
return (a->header_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if the archive contains at least one encrypted entry.
|
||||||
|
* If the archive format not support encryption at all
|
||||||
|
* ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
|
||||||
|
* If for any other reason (e.g. not enough data read so far)
|
||||||
|
* we cannot say whether there are encrypted entries, then
|
||||||
|
* ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
|
||||||
|
* In general, this function will return values below zero when the
|
||||||
|
* reader is uncertain or totally uncapable of encryption support.
|
||||||
|
* When this function returns 0 you can be sure that the reader
|
||||||
|
* supports encryption detection but no encrypted entries have
|
||||||
|
* been found yet.
|
||||||
|
*
|
||||||
|
* NOTE: If the metadata/header of an archive is also encrypted, you
|
||||||
|
* cannot rely on the number of encrypted entries. That is why this
|
||||||
|
* function does not return the number of encrypted entries but#
|
||||||
|
* just shows that there are some.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
archive_read_has_encrypted_entries(struct archive *_a)
|
||||||
|
{
|
||||||
|
struct archive_read *a = (struct archive_read *)_a;
|
||||||
|
int format_supports_encryption = archive_read_format_capabilities(_a)
|
||||||
|
& (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
|
||||||
|
|
||||||
|
if (!_a || !format_supports_encryption) {
|
||||||
|
/* Format in general doesn't support encryption */
|
||||||
|
return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A reader potentially has read enough data now. */
|
||||||
|
if (a->format && a->format->has_encrypted_entries) {
|
||||||
|
return (a->format->has_encrypted_entries)(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For any other reason we cannot say how many entries are there. */
|
||||||
|
return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a bitmask of capabilities that are supported by the archive format reader.
|
||||||
|
* If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
archive_read_format_capabilities(struct archive *_a)
|
||||||
|
{
|
||||||
|
struct archive_read *a = (struct archive_read *)_a;
|
||||||
|
if (a && a->format && a->format->format_capabilties) {
|
||||||
|
return (a->format->format_capabilties)(a);
|
||||||
|
}
|
||||||
|
return ARCHIVE_READ_FORMAT_CAPS_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read data from an archive entry, using a read(2)-style interface.
|
* Read data from an archive entry, using a read(2)-style interface.
|
||||||
* This is a convenience routine that just calls
|
* This is a convenience routine that just calls
|
||||||
|
@ -1094,7 +1147,9 @@ __archive_read_register_format(struct archive_read *a,
|
||||||
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
|
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
|
||||||
int (*read_data_skip)(struct archive_read *),
|
int (*read_data_skip)(struct archive_read *),
|
||||||
int64_t (*seek_data)(struct archive_read *, int64_t, int),
|
int64_t (*seek_data)(struct archive_read *, int64_t, int),
|
||||||
int (*cleanup)(struct archive_read *))
|
int (*cleanup)(struct archive_read *),
|
||||||
|
int (*format_capabilities)(struct archive_read *),
|
||||||
|
int (*has_encrypted_entries)(struct archive_read *))
|
||||||
{
|
{
|
||||||
int i, number_slots;
|
int i, number_slots;
|
||||||
|
|
||||||
|
@ -1117,6 +1172,8 @@ __archive_read_register_format(struct archive_read *a,
|
||||||
a->formats[i].cleanup = cleanup;
|
a->formats[i].cleanup = cleanup;
|
||||||
a->formats[i].data = format_data;
|
a->formats[i].data = format_data;
|
||||||
a->formats[i].name = name;
|
a->formats[i].name = name;
|
||||||
|
a->formats[i].format_capabilties = format_capabilities;
|
||||||
|
a->formats[i].has_encrypted_entries = has_encrypted_entries;
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1557,10 +1614,9 @@ __archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset,
|
||||||
client->dataset[++cursor].begin_position = r;
|
client->dataset[++cursor].begin_position = r;
|
||||||
}
|
}
|
||||||
offset -= client->dataset[cursor].begin_position;
|
offset -= client->dataset[cursor].begin_position;
|
||||||
if (offset < 0)
|
if (offset < 0
|
||||||
offset = 0;
|
|| offset > client->dataset[cursor].total_size)
|
||||||
else if (offset > client->dataset[cursor].total_size - 1)
|
return ARCHIVE_FATAL;
|
||||||
offset = client->dataset[cursor].total_size - 1;
|
|
||||||
if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0)
|
if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -399,7 +399,7 @@ setup_mac_metadata(struct archive_read_disk *a,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_POSIX_ACL) && defined(ACL_TYPE_NFS4)
|
#ifdef HAVE_POSIX_ACL
|
||||||
static int translate_acl(struct archive_read_disk *a,
|
static int translate_acl(struct archive_read_disk *a,
|
||||||
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
|
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
|
||||||
|
|
||||||
|
@ -419,6 +419,7 @@ setup_acls(struct archive_read_disk *a,
|
||||||
|
|
||||||
archive_entry_acl_clear(entry);
|
archive_entry_acl_clear(entry);
|
||||||
|
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
/* Try NFS4 ACL first. */
|
/* Try NFS4 ACL first. */
|
||||||
if (*fd >= 0)
|
if (*fd >= 0)
|
||||||
acl = acl_get_fd(*fd);
|
acl = acl_get_fd(*fd);
|
||||||
|
@ -447,6 +448,7 @@ setup_acls(struct archive_read_disk *a,
|
||||||
acl_free(acl);
|
acl_free(acl);
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Retrieve access ACL from file. */
|
/* Retrieve access ACL from file. */
|
||||||
if (*fd >= 0)
|
if (*fd >= 0)
|
||||||
|
@ -492,6 +494,7 @@ static struct {
|
||||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||||
|
@ -508,8 +511,10 @@ static struct {
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
static struct {
|
static struct {
|
||||||
int archive_inherit;
|
int archive_inherit;
|
||||||
int platform_inherit;
|
int platform_inherit;
|
||||||
|
@ -519,21 +524,25 @@ static struct {
|
||||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
|
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
static int
|
static int
|
||||||
translate_acl(struct archive_read_disk *a,
|
translate_acl(struct archive_read_disk *a,
|
||||||
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
|
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
|
||||||
{
|
{
|
||||||
acl_tag_t acl_tag;
|
acl_tag_t acl_tag;
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
acl_entry_type_t acl_type;
|
acl_entry_type_t acl_type;
|
||||||
acl_flagset_t acl_flagset;
|
acl_flagset_t acl_flagset;
|
||||||
|
int brand, r;
|
||||||
|
#endif
|
||||||
acl_entry_t acl_entry;
|
acl_entry_t acl_entry;
|
||||||
acl_permset_t acl_permset;
|
acl_permset_t acl_permset;
|
||||||
int brand, i, r, entry_acl_type;
|
int i, entry_acl_type;
|
||||||
int s, ae_id, ae_tag, ae_perm;
|
int s, ae_id, ae_tag, ae_perm;
|
||||||
const char *ae_name;
|
const char *ae_name;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
|
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
|
||||||
// Make sure the "brand" on this ACL is consistent
|
// Make sure the "brand" on this ACL is consistent
|
||||||
// with the default_entry_acl_type bits provided.
|
// with the default_entry_acl_type bits provided.
|
||||||
|
@ -560,6 +569,7 @@ translate_acl(struct archive_read_disk *a,
|
||||||
return ARCHIVE_FAILED;
|
return ARCHIVE_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
||||||
|
@ -592,9 +602,11 @@ translate_acl(struct archive_read_disk *a,
|
||||||
case ACL_OTHER:
|
case ACL_OTHER:
|
||||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||||
break;
|
break;
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
case ACL_EVERYONE:
|
case ACL_EVERYONE:
|
||||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
/* Skip types that libarchive can't support. */
|
/* Skip types that libarchive can't support. */
|
||||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||||
|
@ -605,6 +617,7 @@ translate_acl(struct archive_read_disk *a,
|
||||||
// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
|
// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
|
||||||
// non-NFSv4 ACLs
|
// non-NFSv4 ACLs
|
||||||
entry_acl_type = default_entry_acl_type;
|
entry_acl_type = default_entry_acl_type;
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
r = acl_get_entry_type_np(acl_entry, &acl_type);
|
r = acl_get_entry_type_np(acl_entry, &acl_type);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
switch (acl_type) {
|
switch (acl_type) {
|
||||||
|
@ -634,9 +647,10 @@ translate_acl(struct archive_read_disk *a,
|
||||||
ae_perm |= acl_inherit_map[i].archive_inherit;
|
ae_perm |= acl_inherit_map[i].archive_inherit;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
acl_get_permset(acl_entry, &acl_permset);
|
acl_get_permset(acl_entry, &acl_permset);
|
||||||
for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
|
for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
|
||||||
/*
|
/*
|
||||||
* acl_get_perm() is spelled differently on different
|
* acl_get_perm() is spelled differently on different
|
||||||
* platforms; see above.
|
* platforms; see above.
|
||||||
|
|
|
@ -1973,7 +1973,7 @@ tree_dup(int fd)
|
||||||
static volatile int can_dupfd_cloexec = 1;
|
static volatile int can_dupfd_cloexec = 1;
|
||||||
|
|
||||||
if (can_dupfd_cloexec) {
|
if (can_dupfd_cloexec) {
|
||||||
new_fd = fcntl(fd, F_DUPFD_CLOEXEC);
|
new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
|
||||||
if (new_fd != -1)
|
if (new_fd != -1)
|
||||||
return (new_fd);
|
return (new_fd);
|
||||||
/* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,
|
/* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,
|
||||||
|
|
|
@ -929,7 +929,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
||||||
else
|
else
|
||||||
flags |= FILE_FLAG_SEQUENTIAL_SCAN;
|
flags |= FILE_FLAG_SEQUENTIAL_SCAN;
|
||||||
t->entry_fh = CreateFileW(tree_current_access_path(t),
|
t->entry_fh = CreateFileW(tree_current_access_path(t),
|
||||||
GENERIC_READ, 0, NULL, OPEN_EXISTING, flags, NULL);
|
GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);
|
||||||
if (t->entry_fh == INVALID_HANDLE_VALUE) {
|
if (t->entry_fh == INVALID_HANDLE_VALUE) {
|
||||||
archive_set_error(&a->archive, errno,
|
archive_set_error(&a->archive, errno,
|
||||||
"Couldn't open %ls", tree_current_path(a->tree));
|
"Couldn't open %ls", tree_current_path(a->tree));
|
||||||
|
@ -1886,7 +1886,7 @@ tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
|
||||||
|
|
||||||
if (sim_lstat && tree_current_is_physical_link(t))
|
if (sim_lstat && tree_current_is_physical_link(t))
|
||||||
flag |= FILE_FLAG_OPEN_REPARSE_POINT;
|
flag |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||||
h = CreateFileW(tree_current_access_path(t), 0, 0, NULL,
|
h = CreateFileW(tree_current_access_path(t), 0, FILE_SHARE_READ, NULL,
|
||||||
OPEN_EXISTING, flag, NULL);
|
OPEN_EXISTING, flag, NULL);
|
||||||
if (h == INVALID_HANDLE_VALUE) {
|
if (h == INVALID_HANDLE_VALUE) {
|
||||||
la_dosmaperr(GetLastError());
|
la_dosmaperr(GetLastError());
|
||||||
|
@ -2115,7 +2115,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||||
} else
|
} else
|
||||||
desiredAccess = GENERIC_READ;
|
desiredAccess = GENERIC_READ;
|
||||||
|
|
||||||
h = CreateFileW(path, desiredAccess, 0, NULL,
|
h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL,
|
||||||
OPEN_EXISTING, flag, NULL);
|
OPEN_EXISTING, flag, NULL);
|
||||||
if (h == INVALID_HANDLE_VALUE) {
|
if (h == INVALID_HANDLE_VALUE) {
|
||||||
la_dosmaperr(GetLastError());
|
la_dosmaperr(GetLastError());
|
||||||
|
@ -2162,7 +2162,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
h = (HANDLE)_get_osfhandle(fd);
|
h = (HANDLE)_get_osfhandle(fd);
|
||||||
} else {
|
} else {
|
||||||
h = CreateFileW(path, GENERIC_READ, 0, NULL,
|
h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||||
if (h == INVALID_HANDLE_VALUE) {
|
if (h == INVALID_HANDLE_VALUE) {
|
||||||
la_dosmaperr(GetLastError());
|
la_dosmaperr(GetLastError());
|
||||||
|
|
|
@ -103,7 +103,9 @@ int
|
||||||
archive_read_open_filename(struct archive *a, const char *filename,
|
archive_read_open_filename(struct archive *a, const char *filename,
|
||||||
size_t block_size)
|
size_t block_size)
|
||||||
{
|
{
|
||||||
const char *filenames[2] = { filename, NULL };
|
const char *filenames[2];
|
||||||
|
filenames[0] = filename;
|
||||||
|
filenames[1] = NULL;
|
||||||
return archive_read_open_filenames(a, filenames, block_size);
|
return archive_read_open_filenames(a, filenames, block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,8 @@ struct archive_read {
|
||||||
int (*read_data_skip)(struct archive_read *);
|
int (*read_data_skip)(struct archive_read *);
|
||||||
int64_t (*seek_data)(struct archive_read *, int64_t, int);
|
int64_t (*seek_data)(struct archive_read *, int64_t, int);
|
||||||
int (*cleanup)(struct archive_read *);
|
int (*cleanup)(struct archive_read *);
|
||||||
|
int (*format_capabilties)(struct archive_read *);
|
||||||
|
int (*has_encrypted_entries)(struct archive_read *);
|
||||||
} formats[16];
|
} formats[16];
|
||||||
struct archive_format_descriptor *format; /* Active format. */
|
struct archive_format_descriptor *format; /* Active format. */
|
||||||
|
|
||||||
|
@ -218,15 +220,17 @@ struct archive_read {
|
||||||
};
|
};
|
||||||
|
|
||||||
int __archive_read_register_format(struct archive_read *a,
|
int __archive_read_register_format(struct archive_read *a,
|
||||||
void *format_data,
|
void *format_data,
|
||||||
const char *name,
|
const char *name,
|
||||||
int (*bid)(struct archive_read *, int),
|
int (*bid)(struct archive_read *, int),
|
||||||
int (*options)(struct archive_read *, const char *, const char *),
|
int (*options)(struct archive_read *, const char *, const char *),
|
||||||
int (*read_header)(struct archive_read *, struct archive_entry *),
|
int (*read_header)(struct archive_read *, struct archive_entry *),
|
||||||
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
|
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
|
||||||
int (*read_data_skip)(struct archive_read *),
|
int (*read_data_skip)(struct archive_read *),
|
||||||
int64_t (*seek_data)(struct archive_read *, int64_t, int),
|
int64_t (*seek_data)(struct archive_read *, int64_t, int),
|
||||||
int (*cleanup)(struct archive_read *));
|
int (*cleanup)(struct archive_read *),
|
||||||
|
int (*format_capabilities)(struct archive_read *),
|
||||||
|
int (*has_encrypted_entries)(struct archive_read *));
|
||||||
|
|
||||||
int __archive_read_get_bidder(struct archive_read *a,
|
int __archive_read_get_bidder(struct archive_read *a,
|
||||||
struct archive_read_filter_bidder **bidder);
|
struct archive_read_filter_bidder **bidder);
|
||||||
|
|
|
@ -193,6 +193,28 @@ Defaults to enabled, use
|
||||||
.Cm !rockridge
|
.Cm !rockridge
|
||||||
to disable.
|
to disable.
|
||||||
.El
|
.El
|
||||||
|
.It Format tar
|
||||||
|
.Bl -tag -compact -width indent
|
||||||
|
.It Cm compat-2x
|
||||||
|
Libarchive 2.x incorrectly encoded Unicode filenames on
|
||||||
|
some platforms.
|
||||||
|
This option mimics the libarchive 2.x filename handling
|
||||||
|
so that such archives can be read correctly.
|
||||||
|
.It Cm hdrcharset
|
||||||
|
The value is used as a character set name that will be
|
||||||
|
used when translating filenames.
|
||||||
|
.It Cm mac-ext
|
||||||
|
Support Mac OS metadata extension that records data in special
|
||||||
|
files beginning with a period and underscore.
|
||||||
|
Defaults to enabled on Mac OS, disabled on other platforms.
|
||||||
|
Use
|
||||||
|
.Cm !mac-ext
|
||||||
|
to disable.
|
||||||
|
.It Cm read_concatenated_archives
|
||||||
|
Ignore zeroed blocks in the archive, which occurs when multiple tar archives
|
||||||
|
have been concatenated together. Without this option, only the contents of
|
||||||
|
the first concatenated archive would be read.
|
||||||
|
.El
|
||||||
.El
|
.El
|
||||||
.\"
|
.\"
|
||||||
.Sh ERRORS
|
.Sh ERRORS
|
||||||
|
|
|
@ -78,7 +78,7 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
|
||||||
struct archive_read *a = (struct archive_read *)_a;
|
struct archive_read *a = (struct archive_read *)_a;
|
||||||
struct archive_format_descriptor *format;
|
struct archive_format_descriptor *format;
|
||||||
size_t i;
|
size_t i;
|
||||||
int r, rv = ARCHIVE_WARN;
|
int r, rv = ARCHIVE_WARN, matched_modules = 0;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
|
for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
|
||||||
format = &a->formats[i];
|
format = &a->formats[i];
|
||||||
|
@ -86,8 +86,11 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
|
||||||
format->name == NULL)
|
format->name == NULL)
|
||||||
/* This format does not support option. */
|
/* This format does not support option. */
|
||||||
continue;
|
continue;
|
||||||
if (m != NULL && strcmp(format->name, m) != 0)
|
if (m != NULL) {
|
||||||
continue;
|
if (strcmp(format->name, m) != 0)
|
||||||
|
continue;
|
||||||
|
++matched_modules;
|
||||||
|
}
|
||||||
|
|
||||||
a->format = format;
|
a->format = format;
|
||||||
r = format->options(a, o, v);
|
r = format->options(a, o, v);
|
||||||
|
@ -96,16 +99,13 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
|
||||||
if (r == ARCHIVE_FATAL)
|
if (r == ARCHIVE_FATAL)
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
|
|
||||||
if (m != NULL)
|
|
||||||
return (r);
|
|
||||||
|
|
||||||
if (r == ARCHIVE_OK)
|
if (r == ARCHIVE_OK)
|
||||||
rv = ARCHIVE_OK;
|
rv = ARCHIVE_OK;
|
||||||
}
|
}
|
||||||
/* If the format name didn't match, return a special code for
|
/* If the format name didn't match, return a special code for
|
||||||
* _archive_set_option[s]. */
|
* _archive_set_option[s]. */
|
||||||
if (rv == ARCHIVE_WARN && m != NULL)
|
if (m != NULL && matched_modules == 0)
|
||||||
rv = ARCHIVE_WARN - 1;
|
return ARCHIVE_WARN - 1;
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
|
||||||
struct archive_read *a = (struct archive_read *)_a;
|
struct archive_read *a = (struct archive_read *)_a;
|
||||||
struct archive_read_filter *filter;
|
struct archive_read_filter *filter;
|
||||||
struct archive_read_filter_bidder *bidder;
|
struct archive_read_filter_bidder *bidder;
|
||||||
int r, rv = ARCHIVE_WARN;
|
int r, rv = ARCHIVE_WARN, matched_modules = 0;
|
||||||
|
|
||||||
for (filter = a->filter; filter != NULL; filter = filter->upstream) {
|
for (filter = a->filter; filter != NULL; filter = filter->upstream) {
|
||||||
bidder = filter->bidder;
|
bidder = filter->bidder;
|
||||||
|
@ -125,24 +125,24 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
|
||||||
if (bidder->options == NULL)
|
if (bidder->options == NULL)
|
||||||
/* This bidder does not support option */
|
/* This bidder does not support option */
|
||||||
continue;
|
continue;
|
||||||
if (m != NULL && strcmp(filter->name, m) != 0)
|
if (m != NULL) {
|
||||||
continue;
|
if (strcmp(filter->name, m) != 0)
|
||||||
|
continue;
|
||||||
|
++matched_modules;
|
||||||
|
}
|
||||||
|
|
||||||
r = bidder->options(bidder, o, v);
|
r = bidder->options(bidder, o, v);
|
||||||
|
|
||||||
if (r == ARCHIVE_FATAL)
|
if (r == ARCHIVE_FATAL)
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
|
|
||||||
if (m != NULL)
|
|
||||||
return (r);
|
|
||||||
|
|
||||||
if (r == ARCHIVE_OK)
|
if (r == ARCHIVE_OK)
|
||||||
rv = ARCHIVE_OK;
|
rv = ARCHIVE_OK;
|
||||||
}
|
}
|
||||||
/* If the filter name didn't match, return a special code for
|
/* If the filter name didn't match, return a special code for
|
||||||
* _archive_set_option[s]. */
|
* _archive_set_option[s]. */
|
||||||
if (rv == ARCHIVE_WARN && m != NULL)
|
if (m != NULL && matched_modules == 0)
|
||||||
rv = ARCHIVE_WARN - 1;
|
return ARCHIVE_WARN - 1;
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -242,10 +242,11 @@ consume_header(struct archive_read_filter *self)
|
||||||
|
|
||||||
if (version >= 0x940) {
|
if (version >= 0x940) {
|
||||||
unsigned level = *p++;
|
unsigned level = *p++;
|
||||||
if (method == 1 && level == 0) level = 3;
|
unsigned default_level[] = {0, 3, 1, 9};
|
||||||
if (method == 2 && level == 0) level = 1;
|
if (level == 0)
|
||||||
if (method == 3 && level == 0) level = 9;
|
/* Method is 1..3 here due to check above. */
|
||||||
if (level < 1 && level > 9) {
|
level = default_level[method];
|
||||||
|
else if (level > 9) {
|
||||||
archive_set_error(&self->archive->archive,
|
archive_set_error(&self->archive->archive,
|
||||||
ARCHIVE_ERRNO_MISC, "Invalid level");
|
ARCHIVE_ERRNO_MISC, "Invalid level");
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
|
|
|
@ -601,7 +601,7 @@ lzip_init(struct archive_read_filter *self)
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
ret = lzma_raw_decoder(&(state->stream), filters);
|
ret = lzma_raw_decoder(&(state->stream), filters);
|
||||||
#if LZMA_VERSION < 50000030
|
#if LZMA_VERSION < 50010000
|
||||||
free(filters[0].options);
|
free(filters[0].options);
|
||||||
#endif
|
#endif
|
||||||
if (ret != LZMA_OK) {
|
if (ret != LZMA_OK) {
|
||||||
|
|
|
@ -69,7 +69,11 @@ __FBSDID("$FreeBSD$");
|
||||||
#define _7Z_BZ2 0x040202
|
#define _7Z_BZ2 0x040202
|
||||||
#define _7Z_PPMD 0x030401
|
#define _7Z_PPMD 0x030401
|
||||||
#define _7Z_DELTA 0x03
|
#define _7Z_DELTA 0x03
|
||||||
#define _7Z_CRYPTO 0x06F10701
|
#define _7Z_CRYPTO_MAIN_ZIP 0x06F10101 /* Main Zip crypto algo */
|
||||||
|
#define _7Z_CRYPTO_RAR_29 0x06F10303 /* Rar29 AES-128 + (modified SHA-1) */
|
||||||
|
#define _7Z_CRYPTO_AES_256_SHA_256 0x06F10701 /* AES-256 + SHA-256 */
|
||||||
|
|
||||||
|
|
||||||
#define _7Z_X86 0x03030103
|
#define _7Z_X86 0x03030103
|
||||||
#define _7Z_X86_BCJ2 0x0303011B
|
#define _7Z_X86_BCJ2 0x0303011B
|
||||||
#define _7Z_POWERPC 0x03030205
|
#define _7Z_POWERPC 0x03030205
|
||||||
|
@ -322,8 +326,13 @@ struct _7zip {
|
||||||
struct archive_string_conv *sconv;
|
struct archive_string_conv *sconv;
|
||||||
|
|
||||||
char format_name[64];
|
char format_name[64];
|
||||||
|
|
||||||
|
/* Custom value that is non-zero if this archive contains encrypted entries. */
|
||||||
|
int has_encrypted_entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int archive_read_format_7zip_has_encrypted_entries(struct archive_read *);
|
||||||
|
static int archive_read_support_format_7zip_capabilities(struct archive_read *a);
|
||||||
static int archive_read_format_7zip_bid(struct archive_read *, int);
|
static int archive_read_format_7zip_bid(struct archive_read *, int);
|
||||||
static int archive_read_format_7zip_cleanup(struct archive_read *);
|
static int archive_read_format_7zip_cleanup(struct archive_read *);
|
||||||
static int archive_read_format_7zip_read_data(struct archive_read *,
|
static int archive_read_format_7zip_read_data(struct archive_read *,
|
||||||
|
@ -401,6 +410,13 @@ archive_read_support_format_7zip(struct archive *_a)
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Until enough data has been read, we cannot tell about
|
||||||
|
* any encrypted entries yet.
|
||||||
|
*/
|
||||||
|
zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
|
||||||
|
|
||||||
|
|
||||||
r = __archive_read_register_format(a,
|
r = __archive_read_register_format(a,
|
||||||
zip,
|
zip,
|
||||||
"7zip",
|
"7zip",
|
||||||
|
@ -410,13 +426,36 @@ archive_read_support_format_7zip(struct archive *_a)
|
||||||
archive_read_format_7zip_read_data,
|
archive_read_format_7zip_read_data,
|
||||||
archive_read_format_7zip_read_data_skip,
|
archive_read_format_7zip_read_data_skip,
|
||||||
NULL,
|
NULL,
|
||||||
archive_read_format_7zip_cleanup);
|
archive_read_format_7zip_cleanup,
|
||||||
|
archive_read_support_format_7zip_capabilities,
|
||||||
|
archive_read_format_7zip_has_encrypted_entries);
|
||||||
|
|
||||||
if (r != ARCHIVE_OK)
|
if (r != ARCHIVE_OK)
|
||||||
free(zip);
|
free(zip);
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
archive_read_support_format_7zip_capabilities(struct archive_read * a)
|
||||||
|
{
|
||||||
|
(void)a; /* UNUSED */
|
||||||
|
return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
|
||||||
|
ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
archive_read_format_7zip_has_encrypted_entries(struct archive_read *_a)
|
||||||
|
{
|
||||||
|
if (_a && _a->format) {
|
||||||
|
struct _7zip * zip = (struct _7zip *)_a->format->data;
|
||||||
|
if (zip) {
|
||||||
|
return zip->has_encrypted_entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
archive_read_format_7zip_bid(struct archive_read *a, int best_bid)
|
archive_read_format_7zip_bid(struct archive_read *a, int best_bid)
|
||||||
{
|
{
|
||||||
|
@ -476,7 +515,7 @@ check_7zip_header_in_sfx(const char *p)
|
||||||
switch ((unsigned char)p[5]) {
|
switch ((unsigned char)p[5]) {
|
||||||
case 0x1C:
|
case 0x1C:
|
||||||
if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0)
|
if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0)
|
||||||
return (6);
|
return (6);
|
||||||
/*
|
/*
|
||||||
* Test the CRC because its extraction code has 7-Zip
|
* Test the CRC because its extraction code has 7-Zip
|
||||||
* Magic Code, so we should do this in order not to
|
* Magic Code, so we should do this in order not to
|
||||||
|
@ -484,15 +523,15 @@ check_7zip_header_in_sfx(const char *p)
|
||||||
*/
|
*/
|
||||||
if (crc32(0, (const unsigned char *)p + 12, 20)
|
if (crc32(0, (const unsigned char *)p + 12, 20)
|
||||||
!= archive_le32dec(p + 8))
|
!= archive_le32dec(p + 8))
|
||||||
return (6);
|
return (6);
|
||||||
/* Hit the header! */
|
/* Hit the header! */
|
||||||
return (0);
|
return (0);
|
||||||
case 0x37: return (5);
|
case 0x37: return (5);
|
||||||
case 0x7A: return (4);
|
case 0x7A: return (4);
|
||||||
case 0xBC: return (3);
|
case 0xBC: return (3);
|
||||||
case 0xAF: return (2);
|
case 0xAF: return (2);
|
||||||
case 0x27: return (1);
|
case 0x27: return (1);
|
||||||
default: return (6);
|
default: return (6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,6 +607,19 @@ archive_read_format_7zip_read_header(struct archive_read *a,
|
||||||
struct _7zip *zip = (struct _7zip *)a->format->data;
|
struct _7zip *zip = (struct _7zip *)a->format->data;
|
||||||
struct _7zip_entry *zip_entry;
|
struct _7zip_entry *zip_entry;
|
||||||
int r, ret = ARCHIVE_OK;
|
int r, ret = ARCHIVE_OK;
|
||||||
|
struct _7z_folder *folder = 0;
|
||||||
|
uint64_t fidx = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It should be sufficient to call archive_read_next_header() for
|
||||||
|
* a reader to determine if an entry is encrypted or not. If the
|
||||||
|
* encryption of an entry is only detectable when calling
|
||||||
|
* archive_read_data(), so be it. We'll do the same check there
|
||||||
|
* as well.
|
||||||
|
*/
|
||||||
|
if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
|
||||||
|
zip->has_encrypted_entries = 0;
|
||||||
|
}
|
||||||
|
|
||||||
a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
|
a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
|
||||||
if (a->archive.archive_format_name == NULL)
|
if (a->archive.archive_format_name == NULL)
|
||||||
|
@ -604,6 +656,32 @@ archive_read_format_7zip_read_header(struct archive_read *a,
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Figure out if the entry is encrypted by looking at the folder
|
||||||
|
that is associated to the current 7zip entry. If the folder
|
||||||
|
has a coder with a _7Z_CRYPTO codec then the folder is encrypted.
|
||||||
|
Hence the entry must also be encrypted. */
|
||||||
|
if (zip_entry && zip_entry->folderIndex < zip->si.ci.numFolders) {
|
||||||
|
folder = &(zip->si.ci.folders[zip_entry->folderIndex]);
|
||||||
|
for (fidx=0; folder && fidx<folder->numCoders; fidx++) {
|
||||||
|
switch(folder->coders[fidx].codec) {
|
||||||
|
case _7Z_CRYPTO_MAIN_ZIP:
|
||||||
|
case _7Z_CRYPTO_RAR_29:
|
||||||
|
case _7Z_CRYPTO_AES_256_SHA_256: {
|
||||||
|
archive_entry_set_is_data_encrypted(entry, 1);
|
||||||
|
zip->has_encrypted_entries = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now that we've checked for encryption, if there were still no
|
||||||
|
* encrypted entries found we can say for sure that there are none.
|
||||||
|
*/
|
||||||
|
if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
|
||||||
|
zip->has_encrypted_entries = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (archive_entry_copy_pathname_l(entry,
|
if (archive_entry_copy_pathname_l(entry,
|
||||||
(const char *)zip_entry->utf16name,
|
(const char *)zip_entry->utf16name,
|
||||||
zip_entry->name_len, zip->sconv) != 0) {
|
zip_entry->name_len, zip->sconv) != 0) {
|
||||||
|
@ -707,6 +785,10 @@ archive_read_format_7zip_read_data(struct archive_read *a,
|
||||||
|
|
||||||
zip = (struct _7zip *)(a->format->data);
|
zip = (struct _7zip *)(a->format->data);
|
||||||
|
|
||||||
|
if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
|
||||||
|
zip->has_encrypted_entries = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (zip->pack_stream_bytes_unconsumed)
|
if (zip->pack_stream_bytes_unconsumed)
|
||||||
read_consume(a);
|
read_consume(a);
|
||||||
|
|
||||||
|
@ -969,7 +1051,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||||
{
|
{
|
||||||
lzma_options_delta delta_opt;
|
lzma_options_delta delta_opt;
|
||||||
lzma_filter filters[LZMA_FILTERS_MAX];
|
lzma_filter filters[LZMA_FILTERS_MAX];
|
||||||
#if LZMA_VERSION < 50000030
|
#if LZMA_VERSION < 50010000
|
||||||
lzma_filter *ff;
|
lzma_filter *ff;
|
||||||
#endif
|
#endif
|
||||||
int fi = 0;
|
int fi = 0;
|
||||||
|
@ -994,7 +1076,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||||
* for BCJ+LZMA. If we were able to tell the uncompressed
|
* for BCJ+LZMA. If we were able to tell the uncompressed
|
||||||
* size to liblzma when using lzma_raw_decoder() liblzma
|
* size to liblzma when using lzma_raw_decoder() liblzma
|
||||||
* could correctly deal with BCJ+LZMA. But unfortunately
|
* could correctly deal with BCJ+LZMA. But unfortunately
|
||||||
* there is no way to do that.
|
* there is no way to do that.
|
||||||
* Discussion about this can be found at XZ Utils forum.
|
* Discussion about this can be found at XZ Utils forum.
|
||||||
*/
|
*/
|
||||||
if (coder2 != NULL) {
|
if (coder2 != NULL) {
|
||||||
|
@ -1056,7 +1138,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||||
else
|
else
|
||||||
filters[fi].id = LZMA_FILTER_LZMA1;
|
filters[fi].id = LZMA_FILTER_LZMA1;
|
||||||
filters[fi].options = NULL;
|
filters[fi].options = NULL;
|
||||||
#if LZMA_VERSION < 50000030
|
#if LZMA_VERSION < 50010000
|
||||||
ff = &filters[fi];
|
ff = &filters[fi];
|
||||||
#endif
|
#endif
|
||||||
r = lzma_properties_decode(&filters[fi], NULL,
|
r = lzma_properties_decode(&filters[fi], NULL,
|
||||||
|
@ -1070,7 +1152,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||||
filters[fi].id = LZMA_VLI_UNKNOWN;
|
filters[fi].id = LZMA_VLI_UNKNOWN;
|
||||||
filters[fi].options = NULL;
|
filters[fi].options = NULL;
|
||||||
r = lzma_raw_decoder(&(zip->lzstream), filters);
|
r = lzma_raw_decoder(&(zip->lzstream), filters);
|
||||||
#if LZMA_VERSION < 50000030
|
#if LZMA_VERSION < 50010000
|
||||||
free(ff->options);
|
free(ff->options);
|
||||||
#endif
|
#endif
|
||||||
if (r != LZMA_OK) {
|
if (r != LZMA_OK) {
|
||||||
|
@ -1203,6 +1285,17 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||||
"Unexpected codec ID: %lX", zip->codec);
|
"Unexpected codec ID: %lX", zip->codec);
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
|
case _7Z_CRYPTO_MAIN_ZIP:
|
||||||
|
case _7Z_CRYPTO_RAR_29:
|
||||||
|
case _7Z_CRYPTO_AES_256_SHA_256:
|
||||||
|
if (a->entry) {
|
||||||
|
archive_entry_set_is_metadata_encrypted(a->entry, 1);
|
||||||
|
archive_entry_set_is_data_encrypted(a->entry, 1);
|
||||||
|
zip->has_encrypted_entries = 1;
|
||||||
|
}
|
||||||
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||||
|
"Crypto codec not supported yet (ID: 0x%lX)", zip->codec);
|
||||||
|
return (ARCHIVE_FAILED);
|
||||||
default:
|
default:
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||||
"Unknown codec ID: %lX", zip->codec);
|
"Unknown codec ID: %lX", zip->codec);
|
||||||
|
@ -1426,7 +1519,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int sym;
|
int sym;
|
||||||
|
|
||||||
sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
|
sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
|
||||||
&(zip->ppmd7_context), &(zip->range_dec.p));
|
&(zip->ppmd7_context), &(zip->range_dec.p));
|
||||||
if (sym < 0) {
|
if (sym < 0) {
|
||||||
|
@ -2755,6 +2848,7 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
|
||||||
zip->header_crc32 = 0;
|
zip->header_crc32 = 0;
|
||||||
zip->header_is_encoded = 0;
|
zip->header_is_encoded = 0;
|
||||||
zip->header_is_being_read = 1;
|
zip->header_is_being_read = 1;
|
||||||
|
zip->has_encrypted_entries = 0;
|
||||||
check_header_crc = 1;
|
check_header_crc = 1;
|
||||||
|
|
||||||
if ((p = header_bytes(a, 1)) == NULL) {
|
if ((p = header_bytes(a, 1)) == NULL) {
|
||||||
|
@ -3170,7 +3264,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
|
||||||
return (r);
|
return (r);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip the bytes we alrady has skipped in skip_stream().
|
* Skip the bytes we alrady has skipped in skip_stream().
|
||||||
*/
|
*/
|
||||||
while (skip_bytes) {
|
while (skip_bytes) {
|
||||||
ssize_t skipped;
|
ssize_t skipped;
|
||||||
|
@ -3235,16 +3329,36 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
|
||||||
* Check coder types.
|
* Check coder types.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < folder->numCoders; i++) {
|
for (i = 0; i < folder->numCoders; i++) {
|
||||||
if (folder->coders[i].codec == _7Z_CRYPTO) {
|
switch(folder->coders[i].codec) {
|
||||||
archive_set_error(&(a->archive),
|
case _7Z_CRYPTO_MAIN_ZIP:
|
||||||
ARCHIVE_ERRNO_MISC,
|
case _7Z_CRYPTO_RAR_29:
|
||||||
"The %s is encrypted, "
|
case _7Z_CRYPTO_AES_256_SHA_256: {
|
||||||
"but currently not supported", cname);
|
/* For entry that is associated with this folder, mark
|
||||||
return (ARCHIVE_FATAL);
|
it as encrypted (data+metadata). */
|
||||||
|
zip->has_encrypted_entries = 1;
|
||||||
|
if (a->entry) {
|
||||||
|
archive_entry_set_is_data_encrypted(a->entry, 1);
|
||||||
|
archive_entry_set_is_metadata_encrypted(a->entry, 1);
|
||||||
|
}
|
||||||
|
archive_set_error(&(a->archive),
|
||||||
|
ARCHIVE_ERRNO_MISC,
|
||||||
|
"The %s is encrypted, "
|
||||||
|
"but currently not supported", cname);
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
}
|
||||||
|
case _7Z_X86_BCJ2: {
|
||||||
|
found_bcj2++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (folder->coders[i].codec == _7Z_X86_BCJ2)
|
|
||||||
found_bcj2++;
|
|
||||||
}
|
}
|
||||||
|
/* Now that we've checked for encryption, if there were still no
|
||||||
|
* encrypted entries found we can say for sure that there are none.
|
||||||
|
*/
|
||||||
|
if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
|
||||||
|
zip->has_encrypted_entries = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((folder->numCoders > 2 && !found_bcj2) || found_bcj2 > 1) {
|
if ((folder->numCoders > 2 && !found_bcj2) || found_bcj2 > 1) {
|
||||||
archive_set_error(&(a->archive),
|
archive_set_error(&(a->archive),
|
||||||
ARCHIVE_ERRNO_MISC,
|
ARCHIVE_ERRNO_MISC,
|
||||||
|
|
|
@ -122,7 +122,9 @@ archive_read_support_format_ar(struct archive *_a)
|
||||||
archive_read_format_ar_read_data,
|
archive_read_format_ar_read_data,
|
||||||
archive_read_format_ar_skip,
|
archive_read_format_ar_skip,
|
||||||
NULL,
|
NULL,
|
||||||
archive_read_format_ar_cleanup);
|
archive_read_format_ar_cleanup,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (r != ARCHIVE_OK) {
|
if (r != ARCHIVE_OK) {
|
||||||
free(ar);
|
free(ar);
|
||||||
|
|
|
@ -383,7 +383,9 @@ archive_read_support_format_cab(struct archive *_a)
|
||||||
archive_read_format_cab_read_data,
|
archive_read_format_cab_read_data,
|
||||||
archive_read_format_cab_read_data_skip,
|
archive_read_format_cab_read_data_skip,
|
||||||
NULL,
|
NULL,
|
||||||
archive_read_format_cab_cleanup);
|
archive_read_format_cab_cleanup,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (r != ARCHIVE_OK)
|
if (r != ARCHIVE_OK)
|
||||||
free(cab);
|
free(cab);
|
||||||
|
|
|
@ -243,7 +243,9 @@ archive_read_support_format_cpio(struct archive *_a)
|
||||||
archive_read_format_cpio_read_data,
|
archive_read_format_cpio_read_data,
|
||||||
archive_read_format_cpio_skip,
|
archive_read_format_cpio_skip,
|
||||||
NULL,
|
NULL,
|
||||||
archive_read_format_cpio_cleanup);
|
archive_read_format_cpio_cleanup,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (r != ARCHIVE_OK)
|
if (r != ARCHIVE_OK)
|
||||||
free(cpio);
|
free(cpio);
|
||||||
|
|
|
@ -54,6 +54,8 @@ archive_read_support_format_empty(struct archive *_a)
|
||||||
archive_read_format_empty_read_data,
|
archive_read_format_empty_read_data,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
return (r);
|
return (r);
|
||||||
|
|
|
@ -478,7 +478,9 @@ archive_read_support_format_iso9660(struct archive *_a)
|
||||||
archive_read_format_iso9660_read_data,
|
archive_read_format_iso9660_read_data,
|
||||||
archive_read_format_iso9660_read_data_skip,
|
archive_read_format_iso9660_read_data_skip,
|
||||||
NULL,
|
NULL,
|
||||||
archive_read_format_iso9660_cleanup);
|
archive_read_format_iso9660_cleanup,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (r != ARCHIVE_OK) {
|
if (r != ARCHIVE_OK) {
|
||||||
free(iso9660);
|
free(iso9660);
|
||||||
|
|
|
@ -320,7 +320,9 @@ archive_read_support_format_lha(struct archive *_a)
|
||||||
archive_read_format_lha_read_data,
|
archive_read_format_lha_read_data,
|
||||||
archive_read_format_lha_read_data_skip,
|
archive_read_format_lha_read_data_skip,
|
||||||
NULL,
|
NULL,
|
||||||
archive_read_format_lha_cleanup);
|
archive_read_format_lha_cleanup,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (r != ARCHIVE_OK)
|
if (r != ARCHIVE_OK)
|
||||||
free(lha);
|
free(lha);
|
||||||
|
|
|
@ -51,6 +51,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
|
||||||
#include "archive_private.h"
|
#include "archive_private.h"
|
||||||
#include "archive_read_private.h"
|
#include "archive_read_private.h"
|
||||||
#include "archive_string.h"
|
#include "archive_string.h"
|
||||||
|
#include "archive_pack_dev.h"
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
|
@ -103,6 +104,7 @@ struct mtree {
|
||||||
struct archive_entry_linkresolver *resolver;
|
struct archive_entry_linkresolver *resolver;
|
||||||
|
|
||||||
int64_t cur_size;
|
int64_t cur_size;
|
||||||
|
char checkfs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int bid_keycmp(const char *, const char *, ssize_t);
|
static int bid_keycmp(const char *, const char *, ssize_t);
|
||||||
|
@ -173,6 +175,29 @@ get_time_t_min(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
archive_read_format_mtree_options(struct archive_read *a,
|
||||||
|
const char *key, const char *val)
|
||||||
|
{
|
||||||
|
struct mtree *mtree;
|
||||||
|
|
||||||
|
mtree = (struct mtree *)(a->format->data);
|
||||||
|
if (strcmp(key, "checkfs") == 0) {
|
||||||
|
/* Allows to read information missing from the mtree from the file system */
|
||||||
|
if (val == NULL || val[0] == 0) {
|
||||||
|
mtree->checkfs = 0;
|
||||||
|
} else {
|
||||||
|
mtree->checkfs = 1;
|
||||||
|
}
|
||||||
|
return (ARCHIVE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: The "warn" return is just to inform the options
|
||||||
|
* supervisor that we didn't handle it. It will generate
|
||||||
|
* a suitable error if no one used this option. */
|
||||||
|
return (ARCHIVE_WARN);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_options(struct mtree_option *head)
|
free_options(struct mtree_option *head)
|
||||||
{
|
{
|
||||||
|
@ -205,7 +230,7 @@ archive_read_support_format_mtree(struct archive *_a)
|
||||||
mtree->fd = -1;
|
mtree->fd = -1;
|
||||||
|
|
||||||
r = __archive_read_register_format(a, mtree, "mtree",
|
r = __archive_read_register_format(a, mtree, "mtree",
|
||||||
mtree_bid, NULL, read_header, read_data, skip, NULL, cleanup);
|
mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup, NULL, NULL);
|
||||||
|
|
||||||
if (r != ARCHIVE_OK)
|
if (r != ARCHIVE_OK)
|
||||||
free(mtree);
|
free(mtree);
|
||||||
|
@ -367,7 +392,7 @@ bid_keyword(const char *p, ssize_t len)
|
||||||
"gid", "gname", NULL
|
"gid", "gname", NULL
|
||||||
};
|
};
|
||||||
static const char *keys_il[] = {
|
static const char *keys_il[] = {
|
||||||
"ignore", "link", NULL
|
"ignore", "inode", "link", NULL
|
||||||
};
|
};
|
||||||
static const char *keys_m[] = {
|
static const char *keys_m[] = {
|
||||||
"md5", "md5digest", "mode", NULL
|
"md5", "md5digest", "mode", NULL
|
||||||
|
@ -376,7 +401,7 @@ bid_keyword(const char *p, ssize_t len)
|
||||||
"nlink", "nochange", "optional", NULL
|
"nlink", "nochange", "optional", NULL
|
||||||
};
|
};
|
||||||
static const char *keys_r[] = {
|
static const char *keys_r[] = {
|
||||||
"rmd160", "rmd160digest", NULL
|
"resdevice", "rmd160", "rmd160digest", NULL
|
||||||
};
|
};
|
||||||
static const char *keys_s[] = {
|
static const char *keys_s[] = {
|
||||||
"sha1", "sha1digest",
|
"sha1", "sha1digest",
|
||||||
|
@ -1103,162 +1128,164 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
|
||||||
mtree->current_dir.length = n;
|
mtree->current_dir.length = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
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
|
* Try to open and stat the file to get the real size
|
||||||
* this here so that getting a listing of an mtree
|
* and other file info. It would be nice to avoid
|
||||||
* wouldn't require opening every referenced contents
|
* this here so that getting a listing of an mtree
|
||||||
* file. But then we wouldn't know the actual
|
* wouldn't require opening every referenced contents
|
||||||
* contents size, so I don't see a really viable way
|
* file. But then we wouldn't know the actual
|
||||||
* around this. (Also, we may want to someday pull
|
* contents size, so I don't see a really viable way
|
||||||
* other unspecified info from the contents file on
|
* around this. (Also, we may want to someday pull
|
||||||
* disk.)
|
* other unspecified info from the contents file on
|
||||||
*/
|
* disk.)
|
||||||
mtree->fd = -1;
|
*/
|
||||||
if (archive_strlen(&mtree->contents_name) > 0)
|
mtree->fd = -1;
|
||||||
path = mtree->contents_name.s;
|
if (archive_strlen(&mtree->contents_name) > 0)
|
||||||
else
|
path = mtree->contents_name.s;
|
||||||
path = archive_entry_pathname(entry);
|
else
|
||||||
|
path = archive_entry_pathname(entry);
|
||||||
|
|
||||||
if (archive_entry_filetype(entry) == AE_IFREG ||
|
if (archive_entry_filetype(entry) == AE_IFREG ||
|
||||||
archive_entry_filetype(entry) == AE_IFDIR) {
|
archive_entry_filetype(entry) == AE_IFDIR) {
|
||||||
mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
|
mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
|
||||||
__archive_ensure_cloexec_flag(mtree->fd);
|
__archive_ensure_cloexec_flag(mtree->fd);
|
||||||
if (mtree->fd == -1 &&
|
if (mtree->fd == -1 &&
|
||||||
(errno != ENOENT ||
|
(errno != ENOENT ||
|
||||||
archive_strlen(&mtree->contents_name) > 0)) {
|
archive_strlen(&mtree->contents_name) > 0)) {
|
||||||
archive_set_error(&a->archive, errno,
|
archive_set_error(&a->archive, errno,
|
||||||
"Can't open %s", path);
|
"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 = 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)
|
|
||||||
#ifdef S_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)
|
|
||||||
#endif
|
|
||||||
#ifdef S_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)
|
|
||||||
#endif
|
|
||||||
|| ((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)
|
|
||||||
#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;
|
r = ARCHIVE_WARN;
|
||||||
}
|
}
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
st = &st_storage;
|
||||||
* If there is a contents file on disk, pick some of the metadata
|
if (mtree->fd >= 0) {
|
||||||
* from that file. For most of these, we only set it from the contents
|
if (fstat(mtree->fd, st) == -1) {
|
||||||
* if it wasn't already parsed from the specification.
|
archive_set_error(&a->archive, errno,
|
||||||
*/
|
"Could not fstat %s", path);
|
||||||
if (st != NULL) {
|
r = ARCHIVE_WARN;
|
||||||
if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
|
/* If we can't stat it, don't keep it open. */
|
||||||
(parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
|
close(mtree->fd);
|
||||||
(archive_entry_filetype(entry) == AE_IFCHR ||
|
mtree->fd = -1;
|
||||||
archive_entry_filetype(entry) == AE_IFBLK))
|
st = NULL;
|
||||||
archive_entry_set_rdev(entry, st->st_rdev);
|
}
|
||||||
if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME)) == 0 ||
|
} else if (lstat(path, st) == -1) {
|
||||||
(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
|
st = NULL;
|
||||||
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);
|
|
||||||
#elif HAVE_STRUCT_STAT_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);
|
|
||||||
#elif HAVE_STRUCT_STAT_ST_UMTIME
|
|
||||||
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);
|
|
||||||
#else
|
|
||||||
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
|
* Check for a mismatch between the type in the specification and
|
||||||
* didn't match. If this entry is optional, just ignore it
|
* the type of the contents object on disk.
|
||||||
* and read the next header entry.
|
|
||||||
*/
|
*/
|
||||||
*use_next = 1;
|
if (st != NULL) {
|
||||||
return ARCHIVE_OK;
|
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)
|
||||||
|
#endif
|
||||||
|
#ifdef S_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)
|
||||||
|
#endif
|
||||||
|
#ifdef S_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)
|
||||||
|
#ifdef S_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
#elif HAVE_STRUCT_STAT_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);
|
||||||
|
#elif HAVE_STRUCT_STAT_ST_UMTIME
|
||||||
|
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);
|
||||||
|
#else
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mtree->cur_size = archive_entry_size(entry);
|
mtree->cur_size = archive_entry_size(entry);
|
||||||
|
@ -1292,33 +1319,82 @@ parse_line(struct archive_read *a, struct archive_entry *entry,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Device entries have one of the following forms:
|
* Device entries have one of the following forms:
|
||||||
* raw dev_t
|
* - raw dev_t
|
||||||
* format,major,minor[,subdevice]
|
* - format,major,minor[,subdevice]
|
||||||
*
|
* When parsing succeeded, `pdev' will contain the appropriate dev_t value.
|
||||||
* Just use major and minor, no translation etc is done
|
|
||||||
* between formats.
|
|
||||||
*/
|
*/
|
||||||
static int
|
|
||||||
parse_device(struct archive *a, struct archive_entry *entry, char *val)
|
|
||||||
{
|
|
||||||
char *comma1, *comma2;
|
|
||||||
|
|
||||||
comma1 = strchr(val, ',');
|
/* strsep() is not in C90, but strcspn() is. */
|
||||||
if (comma1 == NULL) {
|
/* Taken from http://unixpapa.com/incnote/string.html */
|
||||||
archive_entry_set_dev(entry, (dev_t)mtree_atol10(&val));
|
static char *
|
||||||
return (ARCHIVE_OK);
|
la_strsep(char **sp, char *sep)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
++comma1;
|
*pdev = result;
|
||||||
comma2 = strchr(comma1, ',');
|
return ARCHIVE_OK;
|
||||||
if (comma2 == NULL) {
|
#undef MAX_PACK_ARGS
|
||||||
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
||||||
"Malformed device attribute");
|
|
||||||
return (ARCHIVE_WARN);
|
|
||||||
}
|
|
||||||
++comma2;
|
|
||||||
archive_entry_set_rdevmajor(entry, (dev_t)mtree_atol(&comma1));
|
|
||||||
archive_entry_set_rdevminor(entry, (dev_t)mtree_atol(&comma2));
|
|
||||||
return (ARCHIVE_OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1374,8 +1450,16 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
if (strcmp(key, "device") == 0) {
|
if (strcmp(key, "device") == 0) {
|
||||||
|
/* stat(2) st_rdev field, e.g. the major/minor IDs
|
||||||
|
* of a char/block special file */
|
||||||
|
int r;
|
||||||
|
dev_t dev;
|
||||||
|
|
||||||
*parsed_kws |= MTREE_HAS_DEVICE;
|
*parsed_kws |= MTREE_HAS_DEVICE;
|
||||||
return parse_device(&a->archive, entry, val);
|
r = parse_device(&dev, &a->archive, val);
|
||||||
|
if (r == ARCHIVE_OK)
|
||||||
|
archive_entry_set_rdev(entry, dev);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
case 'f':
|
case 'f':
|
||||||
if (strcmp(key, "flags") == 0) {
|
if (strcmp(key, "flags") == 0) {
|
||||||
|
@ -1394,6 +1478,11 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||||
archive_entry_copy_gname(entry, val);
|
archive_entry_copy_gname(entry, val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'i':
|
||||||
|
if (strcmp(key, "inode") == 0) {
|
||||||
|
archive_entry_set_ino(entry, mtree_atol10(&val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'l':
|
case 'l':
|
||||||
if (strcmp(key, "link") == 0) {
|
if (strcmp(key, "link") == 0) {
|
||||||
archive_entry_copy_symlink(entry, val);
|
archive_entry_copy_symlink(entry, val);
|
||||||
|
@ -1423,6 +1512,17 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'r':
|
case 'r':
|
||||||
|
if (strcmp(key, "resdevice") == 0) {
|
||||||
|
/* stat(2) st_dev field, e.g. the device ID where the
|
||||||
|
* inode resides */
|
||||||
|
int r;
|
||||||
|
dev_t dev;
|
||||||
|
|
||||||
|
r = parse_device(&dev, &a->archive, val);
|
||||||
|
if (r == ARCHIVE_OK)
|
||||||
|
archive_entry_set_dev(entry, dev);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
if (strcmp(key, "rmd160") == 0 ||
|
if (strcmp(key, "rmd160") == 0 ||
|
||||||
strcmp(key, "rmd160digest") == 0)
|
strcmp(key, "rmd160digest") == 0)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -304,8 +304,15 @@ struct rar
|
||||||
ssize_t avail_in;
|
ssize_t avail_in;
|
||||||
const unsigned char *next_in;
|
const unsigned char *next_in;
|
||||||
} br;
|
} br;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Custom field to denote that this archive contains encrypted entries
|
||||||
|
*/
|
||||||
|
int has_encrypted_entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int archive_read_support_format_rar_capabilities(struct archive_read *);
|
||||||
|
static int archive_read_format_rar_has_encrypted_entries(struct archive_read *);
|
||||||
static int archive_read_format_rar_bid(struct archive_read *, int);
|
static int archive_read_format_rar_bid(struct archive_read *, int);
|
||||||
static int archive_read_format_rar_options(struct archive_read *,
|
static int archive_read_format_rar_options(struct archive_read *,
|
||||||
const char *, const char *);
|
const char *, const char *);
|
||||||
|
@ -646,6 +653,12 @@ archive_read_support_format_rar(struct archive *_a)
|
||||||
}
|
}
|
||||||
memset(rar, 0, sizeof(*rar));
|
memset(rar, 0, sizeof(*rar));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Until enough data has been read, we cannot tell about
|
||||||
|
* any encrypted entries yet.
|
||||||
|
*/
|
||||||
|
rar->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
|
||||||
|
|
||||||
r = __archive_read_register_format(a,
|
r = __archive_read_register_format(a,
|
||||||
rar,
|
rar,
|
||||||
"rar",
|
"rar",
|
||||||
|
@ -655,13 +668,36 @@ archive_read_support_format_rar(struct archive *_a)
|
||||||
archive_read_format_rar_read_data,
|
archive_read_format_rar_read_data,
|
||||||
archive_read_format_rar_read_data_skip,
|
archive_read_format_rar_read_data_skip,
|
||||||
archive_read_format_rar_seek_data,
|
archive_read_format_rar_seek_data,
|
||||||
archive_read_format_rar_cleanup);
|
archive_read_format_rar_cleanup,
|
||||||
|
archive_read_support_format_rar_capabilities,
|
||||||
|
archive_read_format_rar_has_encrypted_entries);
|
||||||
|
|
||||||
if (r != ARCHIVE_OK)
|
if (r != ARCHIVE_OK)
|
||||||
free(rar);
|
free(rar);
|
||||||
return (r);
|
return (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
archive_read_support_format_rar_capabilities(struct archive_read * a)
|
||||||
|
{
|
||||||
|
(void)a; /* UNUSED */
|
||||||
|
return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA
|
||||||
|
| ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
archive_read_format_rar_has_encrypted_entries(struct archive_read *_a)
|
||||||
|
{
|
||||||
|
if (_a && _a->format) {
|
||||||
|
struct rar * rar = (struct rar *)_a->format->data;
|
||||||
|
if (rar) {
|
||||||
|
return rar->has_encrypted_entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
archive_read_format_rar_bid(struct archive_read *a, int best_bid)
|
archive_read_format_rar_bid(struct archive_read *a, int best_bid)
|
||||||
{
|
{
|
||||||
|
@ -755,7 +791,7 @@ archive_read_format_rar_options(struct archive_read *a,
|
||||||
{
|
{
|
||||||
struct rar *rar;
|
struct rar *rar;
|
||||||
int ret = ARCHIVE_FAILED;
|
int ret = ARCHIVE_FAILED;
|
||||||
|
|
||||||
rar = (struct rar *)(a->format->data);
|
rar = (struct rar *)(a->format->data);
|
||||||
if (strcmp(key, "hdrcharset") == 0) {
|
if (strcmp(key, "hdrcharset") == 0) {
|
||||||
if (val == NULL || val[0] == 0)
|
if (val == NULL || val[0] == 0)
|
||||||
|
@ -797,6 +833,17 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
||||||
|
|
||||||
rar = (struct rar *)(a->format->data);
|
rar = (struct rar *)(a->format->data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It should be sufficient to call archive_read_next_header() for
|
||||||
|
* a reader to determine if an entry is encrypted or not. If the
|
||||||
|
* encryption of an entry is only detectable when calling
|
||||||
|
* archive_read_data(), so be it. We'll do the same check there
|
||||||
|
* as well.
|
||||||
|
*/
|
||||||
|
if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
|
||||||
|
rar->has_encrypted_entries = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if
|
/* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if
|
||||||
* this fails.
|
* this fails.
|
||||||
*/
|
*/
|
||||||
|
@ -857,9 +904,14 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
||||||
sizeof(rar->reserved2));
|
sizeof(rar->reserved2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Main header is password encrytped, so we cannot read any
|
||||||
|
file names or any other info about files from the header. */
|
||||||
if (rar->main_flags & MHD_PASSWORD)
|
if (rar->main_flags & MHD_PASSWORD)
|
||||||
{
|
{
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
archive_entry_set_is_metadata_encrypted(entry, 1);
|
||||||
|
archive_entry_set_is_data_encrypted(entry, 1);
|
||||||
|
rar->has_encrypted_entries = 1;
|
||||||
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
"RAR encryption support unavailable.");
|
"RAR encryption support unavailable.");
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
|
@ -938,6 +990,10 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
||||||
struct rar *rar = (struct rar *)(a->format->data);
|
struct rar *rar = (struct rar *)(a->format->data);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
|
||||||
|
rar->has_encrypted_entries = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (rar->bytes_unconsumed > 0) {
|
if (rar->bytes_unconsumed > 0) {
|
||||||
/* Consume as much as the decompressor actually used. */
|
/* Consume as much as the decompressor actually used. */
|
||||||
__archive_read_consume(a, rar->bytes_unconsumed);
|
__archive_read_consume(a, rar->bytes_unconsumed);
|
||||||
|
@ -957,7 +1013,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
||||||
{
|
{
|
||||||
case COMPRESS_METHOD_STORE:
|
case COMPRESS_METHOD_STORE:
|
||||||
ret = read_data_stored(a, buff, size, offset);
|
ret = read_data_stored(a, buff, size, offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMPRESS_METHOD_FASTEST:
|
case COMPRESS_METHOD_FASTEST:
|
||||||
case COMPRESS_METHOD_FAST:
|
case COMPRESS_METHOD_FAST:
|
||||||
|
@ -967,13 +1023,13 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
||||||
ret = read_data_compressed(a, buff, size, offset);
|
ret = read_data_compressed(a, buff, size, offset);
|
||||||
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
|
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
|
||||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
|
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
"Unsupported compression method for RAR file.");
|
"Unsupported compression method for RAR file.");
|
||||||
ret = ARCHIVE_FATAL;
|
ret = ARCHIVE_FATAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -1290,9 +1346,14 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||||
|
|
||||||
if (rar->file_flags & FHD_PASSWORD)
|
if (rar->file_flags & FHD_PASSWORD)
|
||||||
{
|
{
|
||||||
|
archive_entry_set_is_data_encrypted(entry, 1);
|
||||||
|
rar->has_encrypted_entries = 1;
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
"RAR encryption support unavailable.");
|
"RAR encryption support unavailable.");
|
||||||
return (ARCHIVE_FATAL);
|
/* Since it is only the data part itself that is encrypted we can at least
|
||||||
|
extract information about the currently processed entry and don't need
|
||||||
|
to return ARCHIVE_FATAL here. */
|
||||||
|
/*return (ARCHIVE_FATAL);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rar->file_flags & FHD_LARGE)
|
if (rar->file_flags & FHD_LARGE)
|
||||||
|
@ -1377,7 +1438,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||||
flagbyte = *(p + offset++);
|
flagbyte = *(p + offset++);
|
||||||
flagbits = 8;
|
flagbits = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
flagbits -= 2;
|
flagbits -= 2;
|
||||||
switch((flagbyte >> flagbits) & 3)
|
switch((flagbyte >> flagbits) & 3)
|
||||||
{
|
{
|
||||||
|
@ -2611,7 +2672,7 @@ expand(struct archive_read *a, int64_t end)
|
||||||
if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
|
if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
rar->output_last_match = 0;
|
rar->output_last_match = 0;
|
||||||
|
|
||||||
if (symbol < 256)
|
if (symbol < 256)
|
||||||
{
|
{
|
||||||
lzss_emit_literal(rar, symbol);
|
lzss_emit_literal(rar, symbol);
|
||||||
|
|
|
@ -78,7 +78,9 @@ archive_read_support_format_raw(struct archive *_a)
|
||||||
archive_read_format_raw_read_data,
|
archive_read_format_raw_read_data,
|
||||||
archive_read_format_raw_read_data_skip,
|
archive_read_format_raw_read_data_skip,
|
||||||
NULL,
|
NULL,
|
||||||
archive_read_format_raw_cleanup);
|
archive_read_format_raw_cleanup,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
if (r != ARCHIVE_OK)
|
if (r != ARCHIVE_OK)
|
||||||
free(info);
|
free(info);
|
||||||
return (r);
|
return (r);
|
||||||
|
|
|
@ -151,6 +151,8 @@ struct tar {
|
||||||
struct archive_string_conv *sconv_default;
|
struct archive_string_conv *sconv_default;
|
||||||
int init_default_conversion;
|
int init_default_conversion;
|
||||||
int compat_2x;
|
int compat_2x;
|
||||||
|
int process_mac_extensions;
|
||||||
|
int read_concatenated_archives;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int archive_block_is_null(const char *p);
|
static int archive_block_is_null(const char *p);
|
||||||
|
@ -241,6 +243,10 @@ archive_read_support_format_tar(struct archive *_a)
|
||||||
ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
|
ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
|
||||||
|
|
||||||
tar = (struct tar *)calloc(1, sizeof(*tar));
|
tar = (struct tar *)calloc(1, sizeof(*tar));
|
||||||
|
#ifdef HAVE_COPYFILE_H
|
||||||
|
/* Set this by default on Mac OS. */
|
||||||
|
tar->process_mac_extensions = 1;
|
||||||
|
#endif
|
||||||
if (tar == NULL) {
|
if (tar == NULL) {
|
||||||
archive_set_error(&a->archive, ENOMEM,
|
archive_set_error(&a->archive, ENOMEM,
|
||||||
"Can't allocate tar data");
|
"Can't allocate tar data");
|
||||||
|
@ -254,7 +260,9 @@ archive_read_support_format_tar(struct archive *_a)
|
||||||
archive_read_format_tar_read_data,
|
archive_read_format_tar_read_data,
|
||||||
archive_read_format_tar_skip,
|
archive_read_format_tar_skip,
|
||||||
NULL,
|
NULL,
|
||||||
archive_read_format_tar_cleanup);
|
archive_read_format_tar_cleanup,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (r != ARCHIVE_OK)
|
if (r != ARCHIVE_OK)
|
||||||
free(tar);
|
free(tar);
|
||||||
|
@ -368,7 +376,7 @@ archive_read_format_tar_options(struct archive_read *a,
|
||||||
tar = (struct tar *)(a->format->data);
|
tar = (struct tar *)(a->format->data);
|
||||||
if (strcmp(key, "compat-2x") == 0) {
|
if (strcmp(key, "compat-2x") == 0) {
|
||||||
/* Handle UTF-8 filnames as libarchive 2.x */
|
/* Handle UTF-8 filnames as libarchive 2.x */
|
||||||
tar->compat_2x = (val != NULL)?1:0;
|
tar->compat_2x = (val != NULL && val[0] != 0);
|
||||||
tar->init_default_conversion = tar->compat_2x;
|
tar->init_default_conversion = tar->compat_2x;
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
} else if (strcmp(key, "hdrcharset") == 0) {
|
} else if (strcmp(key, "hdrcharset") == 0) {
|
||||||
|
@ -385,6 +393,12 @@ archive_read_format_tar_options(struct archive_read *a,
|
||||||
ret = ARCHIVE_FATAL;
|
ret = ARCHIVE_FATAL;
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
|
} else if (strcmp(key, "mac-ext") == 0) {
|
||||||
|
tar->process_mac_extensions = (val != NULL && val[0] != 0);
|
||||||
|
return (ARCHIVE_OK);
|
||||||
|
} else if (strcmp(key, "read_concatenated_archives") == 0) {
|
||||||
|
tar->read_concatenated_archives = (val != NULL && val[0] != 0);
|
||||||
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: The "warn" return is just to inform the options
|
/* Note: The "warn" return is just to inform the options
|
||||||
|
@ -397,7 +411,7 @@ archive_read_format_tar_options(struct archive_read *a,
|
||||||
* how much unconsumed data we have floating around, and to consume
|
* how much unconsumed data we have floating around, and to consume
|
||||||
* anything outstanding since we're going to do read_aheads
|
* anything outstanding since we're going to do read_aheads
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed)
|
tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed)
|
||||||
{
|
{
|
||||||
if (*unconsumed) {
|
if (*unconsumed) {
|
||||||
|
@ -590,7 +604,7 @@ archive_read_format_tar_skip(struct archive_read *a)
|
||||||
tar = (struct tar *)(a->format->data);
|
tar = (struct tar *)(a->format->data);
|
||||||
|
|
||||||
bytes_skipped = __archive_read_consume(a,
|
bytes_skipped = __archive_read_consume(a,
|
||||||
tar->entry_bytes_remaining + tar->entry_padding +
|
tar->entry_bytes_remaining + tar->entry_padding +
|
||||||
tar->entry_bytes_unconsumed);
|
tar->entry_bytes_unconsumed);
|
||||||
if (bytes_skipped < 0)
|
if (bytes_skipped < 0)
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
|
@ -619,36 +633,50 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||||
const struct archive_entry_header_ustar *header;
|
const struct archive_entry_header_ustar *header;
|
||||||
const struct archive_entry_header_gnutar *gnuheader;
|
const struct archive_entry_header_gnutar *gnuheader;
|
||||||
|
|
||||||
tar_flush_unconsumed(a, unconsumed);
|
/* Loop until we find a workable header record. */
|
||||||
|
for (;;) {
|
||||||
/* 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);
|
tar_flush_unconsumed(a, unconsumed);
|
||||||
h = __archive_read_ahead(a, 512, NULL);
|
|
||||||
if (h != NULL)
|
/* Read 512-byte header record */
|
||||||
__archive_read_consume(a, 512);
|
h = __archive_read_ahead(a, 512, &bytes);
|
||||||
archive_clear_error(&a->archive);
|
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;
|
||||||
|
|
||||||
|
/* Header is workable if it's not an end-of-archive mark. */
|
||||||
|
if (h[0] != 0 || !archive_block_is_null(h))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Ensure format is set for archives with only null blocks. */
|
||||||
if (a->archive.archive_format_name == NULL) {
|
if (a->archive.archive_format_name == NULL) {
|
||||||
a->archive.archive_format = ARCHIVE_FORMAT_TAR;
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR;
|
||||||
a->archive.archive_format_name = "tar";
|
a->archive.archive_format_name = "tar";
|
||||||
}
|
}
|
||||||
return (ARCHIVE_EOF);
|
|
||||||
|
if (!tar->read_concatenated_archives) {
|
||||||
|
/* Try to consume a second all-null record, as well. */
|
||||||
|
tar_flush_unconsumed(a, unconsumed);
|
||||||
|
h = __archive_read_ahead(a, 512, NULL);
|
||||||
|
if (h != NULL && h[0] == 0 && archive_block_is_null(h))
|
||||||
|
__archive_read_consume(a, 512);
|
||||||
|
archive_clear_error(&a->archive);
|
||||||
|
return (ARCHIVE_EOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're reading concatenated archives, ignore this block and
|
||||||
|
* loop to get the next.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -683,6 +711,8 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||||
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
||||||
a->archive.archive_format_name = "POSIX pax interchange format";
|
a->archive.archive_format_name = "POSIX pax interchange format";
|
||||||
err = header_pax_global(a, tar, entry, h, unconsumed);
|
err = header_pax_global(a, tar, entry, h, unconsumed);
|
||||||
|
if (err == ARCHIVE_EOF)
|
||||||
|
return (err);
|
||||||
break;
|
break;
|
||||||
case 'K': /* Long link name (GNU tar, others) */
|
case 'K': /* Long link name (GNU tar, others) */
|
||||||
err = header_longlink(a, tar, entry, h, unconsumed);
|
err = header_longlink(a, tar, entry, h, unconsumed);
|
||||||
|
@ -735,9 +765,9 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||||
* extensions for both the AppleDouble extension entry and the
|
* extensions for both the AppleDouble extension entry and the
|
||||||
* regular entry.
|
* regular entry.
|
||||||
*/
|
*/
|
||||||
/* TODO: Should this be disabled on non-Mac platforms? */
|
|
||||||
if ((err == ARCHIVE_WARN || err == ARCHIVE_OK) &&
|
if ((err == ARCHIVE_WARN || err == ARCHIVE_OK) &&
|
||||||
tar->header_recursion_depth == 0) {
|
tar->header_recursion_depth == 0 &&
|
||||||
|
tar->process_mac_extensions) {
|
||||||
int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed);
|
int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed);
|
||||||
if (err2 < err)
|
if (err2 < err)
|
||||||
err = err2;
|
err = err2;
|
||||||
|
@ -780,12 +810,20 @@ checksum(struct archive_read *a, const void *h)
|
||||||
{
|
{
|
||||||
const unsigned char *bytes;
|
const unsigned char *bytes;
|
||||||
const struct archive_entry_header_ustar *header;
|
const struct archive_entry_header_ustar *header;
|
||||||
int check, i, sum;
|
int check, sum;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
(void)a; /* UNUSED */
|
(void)a; /* UNUSED */
|
||||||
bytes = (const unsigned char *)h;
|
bytes = (const unsigned char *)h;
|
||||||
header = (const struct archive_entry_header_ustar *)h;
|
header = (const struct archive_entry_header_ustar *)h;
|
||||||
|
|
||||||
|
/* Checksum field must hold an octal number */
|
||||||
|
for (i = 0; i < sizeof(header->checksum); ++i) {
|
||||||
|
char c = header->checksum[i];
|
||||||
|
if (c != ' ' && c != '\0' && (c < '0' || c > '7'))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test the checksum. Note that POSIX specifies _unsigned_
|
* Test the checksum. Note that POSIX specifies _unsigned_
|
||||||
* bytes for this calculation.
|
* bytes for this calculation.
|
||||||
|
@ -1277,7 +1315,7 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
|
||||||
if (wp[0] == '/' && wp[1] != L'\0')
|
if (wp[0] == '/' && wp[1] != L'\0')
|
||||||
wname = wp + 1;
|
wname = wp + 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* If last path element starts with "._", then
|
* If last path element starts with "._", then
|
||||||
* this is a Mac extension.
|
* this is a Mac extension.
|
||||||
*/
|
*/
|
||||||
|
@ -1292,7 +1330,7 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
|
||||||
if (p[0] == '/' && p[1] != '\0')
|
if (p[0] == '/' && p[1] != '\0')
|
||||||
name = p + 1;
|
name = p + 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* If last path element starts with "._", then
|
* If last path element starts with "._", then
|
||||||
* this is a Mac extension.
|
* this is a Mac extension.
|
||||||
*/
|
*/
|
||||||
|
@ -2412,9 +2450,10 @@ tar_atol(const char *p, size_t char_cnt)
|
||||||
static int64_t
|
static int64_t
|
||||||
tar_atol_base_n(const char *p, size_t char_cnt, int base)
|
tar_atol_base_n(const char *p, size_t char_cnt, int base)
|
||||||
{
|
{
|
||||||
int64_t l, limit, last_digit_limit;
|
int64_t l, maxval, limit, last_digit_limit;
|
||||||
int digit, sign;
|
int digit, sign;
|
||||||
|
|
||||||
|
maxval = INT64_MAX;
|
||||||
limit = INT64_MAX / base;
|
limit = INT64_MAX / base;
|
||||||
last_digit_limit = INT64_MAX % base;
|
last_digit_limit = INT64_MAX % base;
|
||||||
|
|
||||||
|
@ -2431,6 +2470,10 @@ tar_atol_base_n(const char *p, size_t char_cnt, int base)
|
||||||
sign = -1;
|
sign = -1;
|
||||||
p++;
|
p++;
|
||||||
char_cnt--;
|
char_cnt--;
|
||||||
|
|
||||||
|
maxval = INT64_MIN;
|
||||||
|
limit = -(INT64_MIN / base);
|
||||||
|
last_digit_limit = INT64_MIN % base;
|
||||||
}
|
}
|
||||||
|
|
||||||
l = 0;
|
l = 0;
|
||||||
|
@ -2438,8 +2481,7 @@ tar_atol_base_n(const char *p, size_t char_cnt, int base)
|
||||||
digit = *p - '0';
|
digit = *p - '0';
|
||||||
while (digit >= 0 && digit < base && char_cnt != 0) {
|
while (digit >= 0 && digit < base && char_cnt != 0) {
|
||||||
if (l>limit || (l == limit && digit > last_digit_limit)) {
|
if (l>limit || (l == limit && digit > last_digit_limit)) {
|
||||||
l = INT64_MAX; /* Truncate on overflow. */
|
return maxval; /* Truncate on overflow. */
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
l = (l * base) + digit;
|
l = (l * base) + digit;
|
||||||
digit = *++p - '0';
|
digit = *++p - '0';
|
||||||
|
@ -2462,36 +2504,56 @@ tar_atol10(const char *p, size_t char_cnt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse a base-256 integer. This is just a straight signed binary
|
* Parse a base-256 integer. This is just a variable-length
|
||||||
* value in big-endian order, except that the high-order bit is
|
* twos-complement signed binary value in big-endian order, except
|
||||||
* ignored.
|
* that the high-order bit is ignored. The values here can be up to
|
||||||
|
* 12 bytes, so we need to be careful about overflowing 64-bit
|
||||||
|
* (8-byte) integers.
|
||||||
|
*
|
||||||
|
* This code unashamedly assumes that the local machine uses 8-bit
|
||||||
|
* bytes and twos-complement arithmetic.
|
||||||
*/
|
*/
|
||||||
static int64_t
|
static int64_t
|
||||||
tar_atol256(const char *_p, size_t char_cnt)
|
tar_atol256(const char *_p, size_t char_cnt)
|
||||||
{
|
{
|
||||||
int64_t l, upper_limit, lower_limit;
|
uint64_t l;
|
||||||
const unsigned char *p = (const unsigned char *)_p;
|
const unsigned char *p = (const unsigned char *)_p;
|
||||||
|
unsigned char c, neg;
|
||||||
|
|
||||||
upper_limit = INT64_MAX / 256;
|
/* Extend 7-bit 2s-comp to 8-bit 2s-comp, decide sign. */
|
||||||
lower_limit = INT64_MIN / 256;
|
c = *p;
|
||||||
|
if (c & 0x40) {
|
||||||
/* Pad with 1 or 0 bits, depending on sign. */
|
neg = 0xff;
|
||||||
if ((0x40 & *p) == 0x40)
|
c |= 0x80;
|
||||||
l = (int64_t)-1;
|
l = ~ARCHIVE_LITERAL_ULL(0);
|
||||||
else
|
} else {
|
||||||
|
neg = 0;
|
||||||
|
c &= 0x7f;
|
||||||
l = 0;
|
l = 0;
|
||||||
l = (l << 6) | (0x3f & *p++);
|
|
||||||
while (--char_cnt > 0) {
|
|
||||||
if (l > upper_limit) {
|
|
||||||
l = INT64_MAX; /* Truncate on overflow */
|
|
||||||
break;
|
|
||||||
} else if (l < lower_limit) {
|
|
||||||
l = INT64_MIN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
l = (l << 8) | (0xff & (int64_t)*p++);
|
|
||||||
}
|
}
|
||||||
return (l);
|
|
||||||
|
/* If more than 8 bytes, check that we can ignore
|
||||||
|
* high-order bits without overflow. */
|
||||||
|
while (char_cnt > sizeof(int64_t)) {
|
||||||
|
--char_cnt;
|
||||||
|
if (c != neg)
|
||||||
|
return neg ? INT64_MIN : INT64_MAX;
|
||||||
|
c = *++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* c is first byte that fits; if sign mismatch, return overflow */
|
||||||
|
if ((c ^ neg) & 0x80) {
|
||||||
|
return neg ? INT64_MIN : INT64_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accumulate remaining bytes. */
|
||||||
|
while (--char_cnt > 0) {
|
||||||
|
l = (l << 8) | c;
|
||||||
|
c = *++p;
|
||||||
|
}
|
||||||
|
l = (l << 8) | c;
|
||||||
|
/* Return signed twos-complement value. */
|
||||||
|
return (int64_t)(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -468,7 +468,9 @@ archive_read_support_format_xar(struct archive *_a)
|
||||||
xar_read_data,
|
xar_read_data,
|
||||||
xar_read_data_skip,
|
xar_read_data_skip,
|
||||||
NULL,
|
NULL,
|
||||||
xar_cleanup);
|
xar_cleanup,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
if (r != ARCHIVE_OK)
|
if (r != ARCHIVE_OK)
|
||||||
free(xar);
|
free(xar);
|
||||||
return (r);
|
return (r);
|
||||||
|
@ -967,10 +969,14 @@ move_reading_point(struct archive_read *a, uint64_t offset)
|
||||||
return ((int)step);
|
return ((int)step);
|
||||||
xar->offset += step;
|
xar->offset += step;
|
||||||
} else {
|
} else {
|
||||||
archive_set_error(&(a->archive),
|
int64_t pos = __archive_read_seek(a, offset, SEEK_SET);
|
||||||
ARCHIVE_ERRNO_MISC,
|
if (pos == ARCHIVE_FAILED) {
|
||||||
"Cannot seek.");
|
archive_set_error(&(a->archive),
|
||||||
return (ARCHIVE_FAILED);
|
ARCHIVE_ERRNO_MISC,
|
||||||
|
"Cannot seek.");
|
||||||
|
return (ARCHIVE_FAILED);
|
||||||
|
}
|
||||||
|
xar->offset = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -45,6 +45,15 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
|
||||||
#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
|
#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
|
||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_LZMA_H
|
||||||
|
#include <lzma.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_BZLIB_H
|
||||||
|
#include <bzlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
#include "archive_private.h"
|
#include "archive_private.h"
|
||||||
|
@ -54,6 +63,8 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
|
||||||
#define O_CLOEXEC 0
|
#define O_CLOEXEC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int archive_utility_string_sort_helper(char **, unsigned int);
|
||||||
|
|
||||||
/* Generic initialization of 'struct archive' objects. */
|
/* Generic initialization of 'struct archive' objects. */
|
||||||
int
|
int
|
||||||
__archive_clean(struct archive *a)
|
__archive_clean(struct archive *a)
|
||||||
|
@ -74,6 +85,38 @@ archive_version_string(void)
|
||||||
return (ARCHIVE_VERSION_STRING);
|
return (ARCHIVE_VERSION_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
archive_version_details(void)
|
||||||
|
{
|
||||||
|
static struct archive_string str;
|
||||||
|
static int init = 0;
|
||||||
|
|
||||||
|
if (!init) {
|
||||||
|
archive_string_init(&str);
|
||||||
|
|
||||||
|
archive_strcat(&str, ARCHIVE_VERSION_STRING);
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
archive_strcat(&str, " zlib/");
|
||||||
|
archive_strcat(&str, ZLIB_VERSION);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_LZMA_H
|
||||||
|
archive_strcat(&str, " liblzma/");
|
||||||
|
archive_strcat(&str, LZMA_VERSION_STRING);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_BZLIB_H
|
||||||
|
{
|
||||||
|
const char *p = BZ2_bzlibVersion();
|
||||||
|
const char *sep = strchr(p, ',');
|
||||||
|
if (sep == NULL)
|
||||||
|
sep = p + strlen(p);
|
||||||
|
archive_strcat(&str, " bz2lib/");
|
||||||
|
archive_strncat(&str, p, sep - p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return str.s;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
archive_errno(struct archive *a)
|
archive_errno(struct archive *a)
|
||||||
{
|
{
|
||||||
|
@ -499,3 +542,69 @@ __archive_ensure_cloexec_flag(int fd)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility function to sort a group of strings using quicksort.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
archive_utility_string_sort_helper(char **strings, unsigned int n)
|
||||||
|
{
|
||||||
|
unsigned int i, lesser_count, greater_count;
|
||||||
|
char **lesser, **greater, **tmp, *pivot;
|
||||||
|
int retval1, retval2;
|
||||||
|
|
||||||
|
/* A list of 0 or 1 elements is already sorted */
|
||||||
|
if (n <= 1)
|
||||||
|
return (ARCHIVE_OK);
|
||||||
|
|
||||||
|
lesser_count = greater_count = 0;
|
||||||
|
lesser = greater = NULL;
|
||||||
|
pivot = strings[0];
|
||||||
|
for (i = 1; i < n; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(strings[i], pivot) < 0)
|
||||||
|
{
|
||||||
|
lesser_count++;
|
||||||
|
tmp = (char **)realloc(lesser, lesser_count * sizeof(char *));
|
||||||
|
if (!tmp)
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
lesser = tmp;
|
||||||
|
lesser[lesser_count - 1] = strings[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
greater_count++;
|
||||||
|
tmp = (char **)realloc(greater, greater_count * sizeof(char *));
|
||||||
|
if (!tmp)
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
greater = tmp;
|
||||||
|
greater[greater_count - 1] = strings[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* quicksort(lesser) */
|
||||||
|
retval1 = archive_utility_string_sort_helper(lesser, lesser_count);
|
||||||
|
for (i = 0; i < lesser_count; i++)
|
||||||
|
strings[i] = lesser[i];
|
||||||
|
free(lesser);
|
||||||
|
|
||||||
|
/* pivot */
|
||||||
|
strings[lesser_count] = pivot;
|
||||||
|
|
||||||
|
/* quicksort(greater) */
|
||||||
|
retval2 = archive_utility_string_sort_helper(greater, greater_count);
|
||||||
|
for (i = 0; i < greater_count; i++)
|
||||||
|
strings[lesser_count + 1 + i] = greater[i];
|
||||||
|
free(greater);
|
||||||
|
|
||||||
|
return (retval1 < retval2) ? retval1 : retval2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
archive_utility_string_sort(char **strings)
|
||||||
|
{
|
||||||
|
unsigned int size = 0;
|
||||||
|
while (strings[size] != NULL)
|
||||||
|
size++;
|
||||||
|
return archive_utility_string_sort_helper(strings, size);
|
||||||
|
}
|
||||||
|
|
|
@ -54,6 +54,14 @@ archive_filter_bytes(struct archive *a, int n)
|
||||||
return ((a->vtable->archive_filter_bytes)(a, n));
|
return ((a->vtable->archive_filter_bytes)(a, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
archive_free(struct archive *a)
|
||||||
|
{
|
||||||
|
if (a == NULL)
|
||||||
|
return (ARCHIVE_OK);
|
||||||
|
return ((a->vtable->archive_free)(a));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
archive_write_close(struct archive *a)
|
archive_write_close(struct archive *a)
|
||||||
{
|
{
|
||||||
|
@ -76,9 +84,7 @@ archive_write_fail(struct archive *a)
|
||||||
int
|
int
|
||||||
archive_write_free(struct archive *a)
|
archive_write_free(struct archive *a)
|
||||||
{
|
{
|
||||||
if (a == NULL)
|
return archive_free(a);
|
||||||
return (ARCHIVE_OK);
|
|
||||||
return ((a->vtable->archive_free)(a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||||
|
@ -93,9 +99,7 @@ archive_write_finish(struct archive *a)
|
||||||
int
|
int
|
||||||
archive_read_free(struct archive *a)
|
archive_read_free(struct archive *a)
|
||||||
{
|
{
|
||||||
if (a == NULL)
|
return archive_free(a);
|
||||||
return (ARCHIVE_OK);
|
|
||||||
return ((a->vtable->archive_free)(a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||||
|
|
|
@ -301,7 +301,7 @@ __la_open(const char *path, int flags, ...)
|
||||||
ws = NULL;
|
ws = NULL;
|
||||||
if ((flags & ~O_BINARY) == O_RDONLY) {
|
if ((flags & ~O_BINARY) == O_RDONLY) {
|
||||||
/*
|
/*
|
||||||
* When we open a directory, _open function returns
|
* When we open a directory, _open function returns
|
||||||
* "Permission denied" error.
|
* "Permission denied" error.
|
||||||
*/
|
*/
|
||||||
attr = GetFileAttributesA(path);
|
attr = GetFileAttributesA(path);
|
||||||
|
@ -515,9 +515,9 @@ __hstat(HANDLE handle, struct ustat *st)
|
||||||
else
|
else
|
||||||
mode |= S_IFREG;
|
mode |= S_IFREG;
|
||||||
st->st_mode = mode;
|
st->st_mode = mode;
|
||||||
|
|
||||||
fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
|
fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
|
||||||
st->st_atime = t;
|
st->st_atime = t;
|
||||||
st->st_atime_nsec = ns;
|
st->st_atime_nsec = ns;
|
||||||
fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
|
fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
|
||||||
st->st_mtime = t;
|
st->st_mtime = t;
|
||||||
|
@ -525,7 +525,7 @@ __hstat(HANDLE handle, struct ustat *st)
|
||||||
fileTimeToUTC(&info.ftCreationTime, &t, &ns);
|
fileTimeToUTC(&info.ftCreationTime, &t, &ns);
|
||||||
st->st_ctime = t;
|
st->st_ctime = t;
|
||||||
st->st_ctime_nsec = ns;
|
st->st_ctime_nsec = ns;
|
||||||
st->st_size =
|
st->st_size =
|
||||||
((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
|
((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
|
||||||
+ (int64_t)(info.nFileSizeLow);
|
+ (int64_t)(info.nFileSizeLow);
|
||||||
#ifdef SIMULATE_WIN_STAT
|
#ifdef SIMULATE_WIN_STAT
|
||||||
|
@ -599,7 +599,7 @@ __la_stat(const char *path, struct stat *st)
|
||||||
struct ustat u;
|
struct ustat u;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
handle = la_CreateFile(path, 0, 0, NULL, OPEN_EXISTING,
|
handle = la_CreateFile(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||||
FILE_FLAG_BACKUP_SEMANTICS,
|
FILE_FLAG_BACKUP_SEMANTICS,
|
||||||
NULL);
|
NULL);
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
|
|
||||||
/* Alias the Windows _function to the POSIX equivalent. */
|
/* Alias the Windows _function to the POSIX equivalent. */
|
||||||
#define close _close
|
#define close _close
|
||||||
#define fcntl(fd, cmd, flg) /* No operation. */
|
#define fcntl(fd, cmd, flg) /* No operation. */
|
||||||
#ifndef fileno
|
#ifndef fileno
|
||||||
#define fileno _fileno
|
#define fileno _fileno
|
||||||
#endif
|
#endif
|
||||||
|
@ -109,13 +109,14 @@
|
||||||
#define lstat __la_stat
|
#define lstat __la_stat
|
||||||
#define open __la_open
|
#define open __la_open
|
||||||
#define read __la_read
|
#define read __la_read
|
||||||
#if !defined(__BORLANDC__)
|
#if !defined(__BORLANDC__) && !defined(__WATCOMC__)
|
||||||
#define setmode _setmode
|
#define setmode _setmode
|
||||||
#endif
|
#endif
|
||||||
#ifdef stat
|
#ifdef stat
|
||||||
#undef stat
|
#undef stat
|
||||||
#endif
|
#endif
|
||||||
#define stat(path,stref) __la_stat(path,stref)
|
#define stat(path,stref) __la_stat(path,stref)
|
||||||
|
#if !defined(__WATCOMC__)
|
||||||
#if !defined(__BORLANDC__)
|
#if !defined(__BORLANDC__)
|
||||||
#define strdup _strdup
|
#define strdup _strdup
|
||||||
#endif
|
#endif
|
||||||
|
@ -123,9 +124,12 @@
|
||||||
#if !defined(__BORLANDC__)
|
#if !defined(__BORLANDC__)
|
||||||
#define umask _umask
|
#define umask _umask
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#define waitpid __la_waitpid
|
#define waitpid __la_waitpid
|
||||||
#define write __la_write
|
#define write __la_write
|
||||||
|
|
||||||
|
#if !defined(__WATCOMC__)
|
||||||
|
|
||||||
#ifndef O_RDONLY
|
#ifndef O_RDONLY
|
||||||
#define O_RDONLY _O_RDONLY
|
#define O_RDONLY _O_RDONLY
|
||||||
#define O_WRONLY _O_WRONLY
|
#define O_WRONLY _O_WRONLY
|
||||||
|
@ -203,7 +207,7 @@
|
||||||
#define _S_IXGRP (_S_IXUSR >> 3) /* read permission, group */
|
#define _S_IXGRP (_S_IXUSR >> 3) /* read permission, group */
|
||||||
#define _S_IWGRP (_S_IWUSR >> 3) /* write permission, group */
|
#define _S_IWGRP (_S_IWUSR >> 3) /* write permission, group */
|
||||||
#define _S_IRGRP (_S_IRUSR >> 3) /* execute/search permission, group */
|
#define _S_IRGRP (_S_IRUSR >> 3) /* execute/search permission, group */
|
||||||
#define _S_IRWXO (_S_IRWXG >> 3)
|
#define _S_IRWXO (_S_IRWXG >> 3)
|
||||||
#define _S_IXOTH (_S_IXGRP >> 3) /* read permission, other */
|
#define _S_IXOTH (_S_IXGRP >> 3) /* read permission, other */
|
||||||
#define _S_IWOTH (_S_IWGRP >> 3) /* write permission, other */
|
#define _S_IWOTH (_S_IWGRP >> 3) /* write permission, other */
|
||||||
#define _S_IROTH (_S_IRGRP >> 3) /* execute/search permission, other */
|
#define _S_IROTH (_S_IRGRP >> 3) /* execute/search permission, other */
|
||||||
|
@ -223,6 +227,8 @@
|
||||||
#define S_IWOTH _S_IWOTH
|
#define S_IWOTH _S_IWOTH
|
||||||
#define S_IROTH _S_IROTH
|
#define S_IROTH _S_IROTH
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#define F_DUPFD 0 /* Duplicate file descriptor. */
|
#define F_DUPFD 0 /* Duplicate file descriptor. */
|
||||||
#define F_GETFD 1 /* Get file descriptor flags. */
|
#define F_GETFD 1 /* Get file descriptor flags. */
|
||||||
#define F_SETFD 2 /* Set file descriptor flags. */
|
#define F_SETFD 2 /* Set file descriptor flags. */
|
||||||
|
|
|
@ -503,8 +503,9 @@ _archive_write_close(struct archive *_a)
|
||||||
|
|
||||||
archive_clear_error(&a->archive);
|
archive_clear_error(&a->archive);
|
||||||
|
|
||||||
/* Finish the last entry. */
|
/* Finish the last entry if a finish callback is specified */
|
||||||
if (a->archive.state == ARCHIVE_STATE_DATA)
|
if (a->archive.state == ARCHIVE_STATE_DATA
|
||||||
|
&& a->format_finish_entry != NULL)
|
||||||
r = ((a->format_finish_entry)(a));
|
r = ((a->format_finish_entry)(a));
|
||||||
|
|
||||||
/* Finish off the archive. */
|
/* Finish off the archive. */
|
||||||
|
@ -638,6 +639,9 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
|
||||||
|
|
||||||
/* Format and write header. */
|
/* Format and write header. */
|
||||||
r2 = ((a->format_write_header)(a, entry));
|
r2 = ((a->format_write_header)(a, entry));
|
||||||
|
if (r2 == ARCHIVE_FAILED) {
|
||||||
|
return (ARCHIVE_FAILED);
|
||||||
|
}
|
||||||
if (r2 == ARCHIVE_FATAL) {
|
if (r2 == ARCHIVE_FATAL) {
|
||||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
|
@ -658,7 +662,8 @@ _archive_write_finish_entry(struct archive *_a)
|
||||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
||||||
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
|
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
|
||||||
"archive_write_finish_entry");
|
"archive_write_finish_entry");
|
||||||
if (a->archive.state & ARCHIVE_STATE_DATA)
|
if (a->archive.state & ARCHIVE_STATE_DATA
|
||||||
|
&& a->format_finish_entry != NULL)
|
||||||
ret = (a->format_finish_entry)(a);
|
ret = (a->format_finish_entry)(a);
|
||||||
a->archive.state = ARCHIVE_STATE_HEADER;
|
a->archive.state = ARCHIVE_STATE_HEADER;
|
||||||
return (ret);
|
return (ret);
|
||||||
|
@ -671,8 +676,13 @@ static ssize_t
|
||||||
_archive_write_data(struct archive *_a, const void *buff, size_t s)
|
_archive_write_data(struct archive *_a, const void *buff, size_t s)
|
||||||
{
|
{
|
||||||
struct archive_write *a = (struct archive_write *)_a;
|
struct archive_write *a = (struct archive_write *)_a;
|
||||||
|
const size_t max_write = INT_MAX;
|
||||||
|
|
||||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
||||||
ARCHIVE_STATE_DATA, "archive_write_data");
|
ARCHIVE_STATE_DATA, "archive_write_data");
|
||||||
|
/* In particular, this catches attempts to pass negative values. */
|
||||||
|
if (s > max_write)
|
||||||
|
s = max_write;
|
||||||
archive_clear_error(&a->archive);
|
archive_clear_error(&a->archive);
|
||||||
return ((a->format_write_data)(a, buff, s));
|
return ((a->format_write_data)(a, buff, s));
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
|
||||||
struct write_lrzip {
|
struct write_lrzip {
|
||||||
struct archive_write_program_data *pdata;
|
struct archive_write_program_data *pdata;
|
||||||
int compression_level;
|
int compression_level;
|
||||||
enum { lzma = 0, bzip2, gzip, lzo, zpaq } compression;
|
enum { lzma = 0, bzip2, gzip, lzo, none, zpaq } compression;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int archive_write_lrzip_open(struct archive_write_filter *);
|
static int archive_write_lrzip_open(struct archive_write_filter *);
|
||||||
|
@ -107,6 +107,8 @@ archive_write_lrzip_options(struct archive_write_filter *f, const char *key,
|
||||||
data->compression = gzip;
|
data->compression = gzip;
|
||||||
else if (strcmp(value, "lzo") == 0)
|
else if (strcmp(value, "lzo") == 0)
|
||||||
data->compression = lzo;
|
data->compression = lzo;
|
||||||
|
else if (strcmp(value, "none") == 0)
|
||||||
|
data->compression = none;
|
||||||
else if (strcmp(value, "zpaq") == 0)
|
else if (strcmp(value, "zpaq") == 0)
|
||||||
data->compression = zpaq;
|
data->compression = zpaq;
|
||||||
else
|
else
|
||||||
|
@ -148,6 +150,9 @@ archive_write_lrzip_open(struct archive_write_filter *f)
|
||||||
case lzo:
|
case lzo:
|
||||||
archive_strcat(&as, " -l");
|
archive_strcat(&as, " -l");
|
||||||
break;
|
break;
|
||||||
|
case none:
|
||||||
|
archive_strcat(&as, " -n");
|
||||||
|
break;
|
||||||
case zpaq:
|
case zpaq:
|
||||||
archive_strcat(&as, " -z");
|
archive_strcat(&as, " -z");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -43,7 +43,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
|
||||||
#include "archive_acl_private.h"
|
#include "archive_acl_private.h"
|
||||||
#include "archive_write_disk_private.h"
|
#include "archive_write_disk_private.h"
|
||||||
|
|
||||||
#if !defined(HAVE_POSIX_ACL) || !defined(ACL_TYPE_NFS4)
|
#ifndef HAVE_POSIX_ACL
|
||||||
/* Default empty function body to satisfy mainline code. */
|
/* Default empty function body to satisfy mainline code. */
|
||||||
int
|
int
|
||||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||||
|
@ -79,10 +79,12 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||||
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
|
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
|
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
|
||||||
return (ret);
|
return (ret);
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0) {
|
} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0) {
|
||||||
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
|
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||||
return (ret);
|
return (ret);
|
||||||
|
#endif
|
||||||
} else
|
} else
|
||||||
return ARCHIVE_OK;
|
return ARCHIVE_OK;
|
||||||
}
|
}
|
||||||
|
@ -94,6 +96,7 @@ static struct {
|
||||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||||
|
@ -110,8 +113,10 @@ static struct {
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
static struct {
|
static struct {
|
||||||
int archive_inherit;
|
int archive_inherit;
|
||||||
int platform_inherit;
|
int platform_inherit;
|
||||||
|
@ -121,6 +126,7 @@ static struct {
|
||||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
|
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
set_acl(struct archive *a, int fd, const char *name,
|
set_acl(struct archive *a, int fd, const char *name,
|
||||||
|
@ -130,7 +136,9 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||||
acl_t acl;
|
acl_t acl;
|
||||||
acl_entry_t acl_entry;
|
acl_entry_t acl_entry;
|
||||||
acl_permset_t acl_permset;
|
acl_permset_t acl_permset;
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
acl_flagset_t acl_flagset;
|
acl_flagset_t acl_flagset;
|
||||||
|
#endif
|
||||||
int ret;
|
int ret;
|
||||||
int ae_type, ae_permset, ae_tag, ae_id;
|
int ae_type, ae_permset, ae_tag, ae_id;
|
||||||
uid_t ae_uid;
|
uid_t ae_uid;
|
||||||
|
@ -171,14 +179,17 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||||
acl_set_tag_type(acl_entry, ACL_OTHER);
|
acl_set_tag_type(acl_entry, ACL_OTHER);
|
||||||
break;
|
break;
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||||
acl_set_tag_type(acl_entry, ACL_EVERYONE);
|
acl_set_tag_type(acl_entry, ACL_EVERYONE);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
/* XXX */
|
/* XXX */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
switch (ae_type) {
|
switch (ae_type) {
|
||||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||||
acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
|
acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
|
||||||
|
@ -200,6 +211,7 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||||
// XXX error handling here.
|
// XXX error handling here.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
acl_get_permset(acl_entry, &acl_permset);
|
acl_get_permset(acl_entry, &acl_permset);
|
||||||
acl_clear_perms(acl_permset);
|
acl_clear_perms(acl_permset);
|
||||||
|
@ -210,6 +222,7 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||||
acl_perm_map[i].platform_perm);
|
acl_perm_map[i].platform_perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
acl_get_flagset_np(acl_entry, &acl_flagset);
|
acl_get_flagset_np(acl_entry, &acl_flagset);
|
||||||
acl_clear_flags_np(acl_flagset);
|
acl_clear_flags_np(acl_flagset);
|
||||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
|
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
|
||||||
|
@ -217,6 +230,7 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||||
acl_add_flag_np(acl_flagset,
|
acl_add_flag_np(acl_flagset,
|
||||||
acl_inherit_map[i].platform_inherit);
|
acl_inherit_map[i].platform_inherit);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try restoring the ACL through 'fd' if we can. */
|
/* Try restoring the ACL through 'fd' if we can. */
|
||||||
|
|
|
@ -525,7 +525,7 @@ la_GetFunctionKernel32(const char *name)
|
||||||
static int set;
|
static int set;
|
||||||
if (!set) {
|
if (!set) {
|
||||||
set = 1;
|
set = 1;
|
||||||
lib = LoadLibrary("kernel32.dll");
|
lib = LoadLibrary(TEXT("kernel32.dll"));
|
||||||
}
|
}
|
||||||
if (lib == NULL) {
|
if (lib == NULL) {
|
||||||
fprintf(stderr, "Can't load kernel32.dll?!\n");
|
fprintf(stderr, "Can't load kernel32.dll?!\n");
|
||||||
|
|
|
@ -24,13 +24,14 @@
|
||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd February 2, 2012
|
.Dd February 14, 2013
|
||||||
.Dt ARCHIVE_WRITE_FORMAT 3
|
.Dt ARCHIVE_WRITE_FORMAT 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm archive_write_set_format_cpio ,
|
.Nm archive_write_set_format_cpio ,
|
||||||
.Nm archive_write_set_format_pax ,
|
.Nm archive_write_set_format_pax ,
|
||||||
.Nm archive_write_set_format_pax_restricted ,
|
.Nm archive_write_set_format_pax_restricted ,
|
||||||
|
.Nm archive_write_set_format_raw ,
|
||||||
.Nm archive_write_set_format_shar ,
|
.Nm archive_write_set_format_shar ,
|
||||||
.Nm archive_write_set_format_shar_dump ,
|
.Nm archive_write_set_format_shar_dump ,
|
||||||
.Nm archive_write_set_format_ustar
|
.Nm archive_write_set_format_ustar
|
||||||
|
@ -46,6 +47,8 @@ Streaming Archive Library (libarchive, -larchive)
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_write_set_format_pax_restricted "struct archive *"
|
.Fn archive_write_set_format_pax_restricted "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_raw "struct archive *"
|
||||||
|
.Ft int
|
||||||
.Fn archive_write_set_format_shar "struct archive *"
|
.Fn archive_write_set_format_shar "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_write_set_format_shar_dump "struct archive *"
|
.Fn archive_write_set_format_shar_dump "struct archive *"
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
|
||||||
{ ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc },
|
{ ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc },
|
||||||
{ ARCHIVE_FORMAT_ISO9660, archive_write_set_format_iso9660 },
|
{ ARCHIVE_FORMAT_ISO9660, archive_write_set_format_iso9660 },
|
||||||
{ ARCHIVE_FORMAT_MTREE, archive_write_set_format_mtree },
|
{ ARCHIVE_FORMAT_MTREE, archive_write_set_format_mtree },
|
||||||
|
{ ARCHIVE_FORMAT_RAW, archive_write_set_format_raw },
|
||||||
{ ARCHIVE_FORMAT_SHAR, archive_write_set_format_shar },
|
{ ARCHIVE_FORMAT_SHAR, archive_write_set_format_shar },
|
||||||
{ ARCHIVE_FORMAT_SHAR_BASE, archive_write_set_format_shar },
|
{ ARCHIVE_FORMAT_SHAR_BASE, archive_write_set_format_shar },
|
||||||
{ ARCHIVE_FORMAT_SHAR_DUMP, archive_write_set_format_shar_dump },
|
{ ARCHIVE_FORMAT_SHAR_DUMP, archive_write_set_format_shar_dump },
|
||||||
|
@ -57,7 +58,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
|
||||||
archive_write_set_format_pax_restricted },
|
archive_write_set_format_pax_restricted },
|
||||||
{ ARCHIVE_FORMAT_TAR_USTAR, archive_write_set_format_ustar },
|
{ ARCHIVE_FORMAT_TAR_USTAR, archive_write_set_format_ustar },
|
||||||
{ ARCHIVE_FORMAT_XAR, archive_write_set_format_xar },
|
{ ARCHIVE_FORMAT_XAR, archive_write_set_format_xar },
|
||||||
{ ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip },
|
{ ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip },
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ struct { const char *name; int (*setter)(struct archive *); } names[] =
|
||||||
{ "pax", archive_write_set_format_pax },
|
{ "pax", archive_write_set_format_pax },
|
||||||
{ "paxr", archive_write_set_format_pax_restricted },
|
{ "paxr", archive_write_set_format_pax_restricted },
|
||||||
{ "posix", archive_write_set_format_pax },
|
{ "posix", archive_write_set_format_pax },
|
||||||
|
{ "raw", archive_write_set_format_raw },
|
||||||
{ "rpax", archive_write_set_format_pax_restricted },
|
{ "rpax", archive_write_set_format_pax_restricted },
|
||||||
{ "shar", archive_write_set_format_shar },
|
{ "shar", archive_write_set_format_shar },
|
||||||
{ "shardump", archive_write_set_format_shar_dump },
|
{ "shardump", archive_write_set_format_shar_dump },
|
||||||
|
|
|
@ -128,6 +128,9 @@ struct mtree_entry {
|
||||||
unsigned long fflags_clear;
|
unsigned long fflags_clear;
|
||||||
dev_t rdevmajor;
|
dev_t rdevmajor;
|
||||||
dev_t rdevminor;
|
dev_t rdevminor;
|
||||||
|
dev_t devmajor;
|
||||||
|
dev_t devminor;
|
||||||
|
int64_t ino;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mtree_writer {
|
struct mtree_writer {
|
||||||
|
@ -210,6 +213,9 @@ struct mtree_writer {
|
||||||
#define F_SHA256 0x00800000 /* SHA-256 digest */
|
#define F_SHA256 0x00800000 /* SHA-256 digest */
|
||||||
#define F_SHA384 0x01000000 /* SHA-384 digest */
|
#define F_SHA384 0x01000000 /* SHA-384 digest */
|
||||||
#define F_SHA512 0x02000000 /* SHA-512 digest */
|
#define F_SHA512 0x02000000 /* SHA-512 digest */
|
||||||
|
#define F_INO 0x04000000 /* inode number */
|
||||||
|
#define F_RESDEV 0x08000000 /* device ID on which the
|
||||||
|
* entry resides */
|
||||||
|
|
||||||
/* Options */
|
/* Options */
|
||||||
int dironly; /* If it is set, ignore all files except
|
int dironly; /* If it is set, ignore all files except
|
||||||
|
@ -823,8 +829,11 @@ mtree_entry_new(struct archive_write *a, struct archive_entry *entry,
|
||||||
archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
|
archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
|
||||||
me->mtime = archive_entry_mtime(entry);
|
me->mtime = archive_entry_mtime(entry);
|
||||||
me->mtime_nsec = archive_entry_mtime_nsec(entry);
|
me->mtime_nsec = archive_entry_mtime_nsec(entry);
|
||||||
me->rdevmajor = archive_entry_rdevmajor(entry);
|
me->rdevmajor = archive_entry_rdevmajor(entry);
|
||||||
me->rdevminor = archive_entry_rdevminor(entry);
|
me->rdevminor = archive_entry_rdevminor(entry);
|
||||||
|
me->devmajor = archive_entry_devmajor(entry);
|
||||||
|
me->devminor = archive_entry_devminor(entry);
|
||||||
|
me->ino = archive_entry_ino(entry);
|
||||||
me->size = archive_entry_size(entry);
|
me->size = archive_entry_size(entry);
|
||||||
if (me->filetype == AE_IFDIR) {
|
if (me->filetype == AE_IFDIR) {
|
||||||
me->dir_info = calloc(1, sizeof(*me->dir_info));
|
me->dir_info = calloc(1, sizeof(*me->dir_info));
|
||||||
|
@ -882,7 +891,7 @@ archive_write_mtree_header(struct archive_write *a,
|
||||||
mtree->first = 0;
|
mtree->first = 0;
|
||||||
archive_strcat(&mtree->buf, "#mtree\n");
|
archive_strcat(&mtree->buf, "#mtree\n");
|
||||||
if ((mtree->keys & SET_KEYS) == 0)
|
if ((mtree->keys & SET_KEYS) == 0)
|
||||||
mtree->output_global_set = 0;/* Disalbed. */
|
mtree->output_global_set = 0;/* Disabled. */
|
||||||
}
|
}
|
||||||
|
|
||||||
mtree->entry_bytes_remaining = archive_entry_size(entry);
|
mtree->entry_bytes_remaining = archive_entry_size(entry);
|
||||||
|
@ -983,6 +992,15 @@ write_mtree_entry(struct archive_write *a, struct mtree_entry *me)
|
||||||
if ((keys & F_UID) != 0)
|
if ((keys & F_UID) != 0)
|
||||||
archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
|
archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
|
||||||
|
|
||||||
|
if ((keys & F_INO) != 0)
|
||||||
|
archive_string_sprintf(str, " inode=%jd", (intmax_t)me->ino);
|
||||||
|
if ((keys & F_RESDEV) != 0) {
|
||||||
|
archive_string_sprintf(str,
|
||||||
|
" resdevice=native,%ju,%ju",
|
||||||
|
(uintmax_t)me->devmajor,
|
||||||
|
(uintmax_t)me->devminor);
|
||||||
|
}
|
||||||
|
|
||||||
switch (me->filetype) {
|
switch (me->filetype) {
|
||||||
case AE_IFLNK:
|
case AE_IFLNK:
|
||||||
if ((keys & F_TYPE) != 0)
|
if ((keys & F_TYPE) != 0)
|
||||||
|
@ -1117,7 +1135,7 @@ write_mtree_entry_tree(struct archive_write *a)
|
||||||
} else {
|
} else {
|
||||||
/* Whenever output_global_set is enabled
|
/* Whenever output_global_set is enabled
|
||||||
* output global value(/set keywords)
|
* output global value(/set keywords)
|
||||||
* even if the directory entry is not allowd
|
* even if the directory entry is not allowed
|
||||||
* to be written because the global values
|
* to be written because the global values
|
||||||
* can be used for the children. */
|
* can be used for the children. */
|
||||||
if (mtree->output_global_set)
|
if (mtree->output_global_set)
|
||||||
|
@ -1296,6 +1314,8 @@ archive_write_mtree_options(struct archive_write *a, const char *key,
|
||||||
if (strcmp(key, "indent") == 0) {
|
if (strcmp(key, "indent") == 0) {
|
||||||
mtree->indent = (value != NULL)? 1: 0;
|
mtree->indent = (value != NULL)? 1: 0;
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
|
} else if (strcmp(key, "inode") == 0) {
|
||||||
|
keybit = F_INO;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
|
@ -1314,7 +1334,9 @@ archive_write_mtree_options(struct archive_write *a, const char *key,
|
||||||
keybit = F_NLINK;
|
keybit = F_NLINK;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
if (strcmp(key, "ripemd160digest") == 0 ||
|
if (strcmp(key, "resdevice") == 0) {
|
||||||
|
keybit = F_RESDEV;
|
||||||
|
} else if (strcmp(key, "ripemd160digest") == 0 ||
|
||||||
strcmp(key, "rmd160") == 0 ||
|
strcmp(key, "rmd160") == 0 ||
|
||||||
strcmp(key, "rmd160digest") == 0)
|
strcmp(key, "rmd160digest") == 0)
|
||||||
keybit = F_RMD160;
|
keybit = F_RMD160;
|
||||||
|
@ -1855,9 +1877,9 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a basename from dirname and slash */
|
/* Make a basename from file->parentdir.s and slash */
|
||||||
*slash = '\0';
|
*slash = '\0';
|
||||||
file->parentdir.length = slash - dirname;
|
file->parentdir.length = slash - file->parentdir.s;
|
||||||
archive_strcpy(&(file->basename), slash + 1);
|
archive_strcpy(&(file->basename), slash + 1);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -2198,6 +2220,9 @@ mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np,
|
||||||
np->mtime_nsec = file->mtime_nsec;
|
np->mtime_nsec = file->mtime_nsec;
|
||||||
np->rdevmajor = file->rdevmajor;
|
np->rdevmajor = file->rdevmajor;
|
||||||
np->rdevminor = file->rdevminor;
|
np->rdevminor = file->rdevminor;
|
||||||
|
np->devmajor = file->devmajor;
|
||||||
|
np->devminor = file->devminor;
|
||||||
|
np->ino = file->ino;
|
||||||
|
|
||||||
return (ARCHIVE_WARN);
|
return (ARCHIVE_WARN);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -548,6 +548,7 @@ archive_write_shar_finish_entry(struct archive_write *a)
|
||||||
archive_strcat(&shar->work, ":");
|
archive_strcat(&shar->work, ":");
|
||||||
shar_quote(&shar->work, g, 1);
|
shar_quote(&shar->work, g, 1);
|
||||||
}
|
}
|
||||||
|
archive_strcat(&shar->work, " ");
|
||||||
shar_quote(&shar->work,
|
shar_quote(&shar->work,
|
||||||
archive_entry_pathname(shar->entry), 1);
|
archive_entry_pathname(shar->entry), 1);
|
||||||
archive_strcat(&shar->work, "\n");
|
archive_strcat(&shar->work, "\n");
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -36,7 +36,7 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
|
||||||
{
|
{
|
||||||
HANDLE childStdout[2], childStdin[2],childStderr;
|
HANDLE childStdout[2], childStdin[2],childStderr;
|
||||||
SECURITY_ATTRIBUTES secAtts;
|
SECURITY_ATTRIBUTES secAtts;
|
||||||
STARTUPINFO staInfo;
|
STARTUPINFOA staInfo;
|
||||||
PROCESS_INFORMATION childInfo;
|
PROCESS_INFORMATION childInfo;
|
||||||
struct archive_string cmdline;
|
struct archive_string cmdline;
|
||||||
struct archive_string fullpath;
|
struct archive_string fullpath;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
.\" From: @(#)mtree.8 8.2 (Berkeley) 12/11/93
|
.\" From: @(#)mtree.8 8.2 (Berkeley) 12/11/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd May 6, 2008
|
.Dd September 4, 2013
|
||||||
.Dt MTREE 5
|
.Dt MTREE 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -134,6 +134,52 @@ The checksum of the file using the default algorithm specified by
|
||||||
the
|
the
|
||||||
.Xr cksum 1
|
.Xr cksum 1
|
||||||
utility.
|
utility.
|
||||||
|
.It Cm device
|
||||||
|
The device number for
|
||||||
|
.Sy block
|
||||||
|
or
|
||||||
|
.Sy char
|
||||||
|
file types.
|
||||||
|
The value must be one of the following forms:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width 4n
|
||||||
|
.It Ar format , Ns Ar major , Ns Ar minor Ns Bo , Ns Ar subunit Bc
|
||||||
|
A device with
|
||||||
|
.Ar major , minor
|
||||||
|
and optional
|
||||||
|
.Ar subunit
|
||||||
|
fields.
|
||||||
|
Their meaning is specified by the operating's system
|
||||||
|
.Ar format .
|
||||||
|
See below for valid formats.
|
||||||
|
.It Ar number
|
||||||
|
Opaque number (as stored on the file system).
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The following values for
|
||||||
|
.Ar format
|
||||||
|
are recognized:
|
||||||
|
.Sy native ,
|
||||||
|
.Sy 386bsd ,
|
||||||
|
.Sy 4bsd ,
|
||||||
|
.Sy bsdos ,
|
||||||
|
.Sy freebsd ,
|
||||||
|
.Sy hpux ,
|
||||||
|
.Sy isc ,
|
||||||
|
.Sy linux ,
|
||||||
|
.Sy netbsd ,
|
||||||
|
.Sy osf1 ,
|
||||||
|
.Sy sco ,
|
||||||
|
.Sy solaris ,
|
||||||
|
.Sy sunos ,
|
||||||
|
.Sy svr3 ,
|
||||||
|
.Sy svr4 ,
|
||||||
|
and
|
||||||
|
.Sy ultrix .
|
||||||
|
.Pp
|
||||||
|
See
|
||||||
|
.Xr mknod 8
|
||||||
|
for more details.
|
||||||
.It Cm contents
|
.It Cm contents
|
||||||
The full pathname of a file that holds the contents of this file.
|
The full pathname of a file that holds the contents of this file.
|
||||||
.It Cm flags
|
.It Cm flags
|
||||||
|
@ -150,6 +196,8 @@ The file group as a numeric value.
|
||||||
The file group as a symbolic name.
|
The file group as a symbolic name.
|
||||||
.It Cm ignore
|
.It Cm ignore
|
||||||
Ignore any file hierarchy below this file.
|
Ignore any file hierarchy below this file.
|
||||||
|
.It Cm inode
|
||||||
|
The inode number.
|
||||||
.It Cm link
|
.It Cm link
|
||||||
The target of the symbolic link when type=link.
|
The target of the symbolic link when type=link.
|
||||||
.It Cm md5
|
.It Cm md5
|
||||||
|
@ -164,6 +212,16 @@ value.
|
||||||
The number of hard links the file is expected to have.
|
The number of hard links the file is expected to have.
|
||||||
.It Cm nochange
|
.It Cm nochange
|
||||||
Make sure this file or directory exists but otherwise ignore all attributes.
|
Make sure this file or directory exists but otherwise ignore all attributes.
|
||||||
|
.It Cm optional
|
||||||
|
The file is optional; do not complain about the file if it is not in
|
||||||
|
the file hierarchy.
|
||||||
|
.It Cm resdevice
|
||||||
|
The
|
||||||
|
.Dq resident
|
||||||
|
device number of the file, e.g. the ID of the device that
|
||||||
|
contains the file.
|
||||||
|
Its format is the same as the one for
|
||||||
|
.Cm device .
|
||||||
.It Cm ripemd160digest
|
.It Cm ripemd160digest
|
||||||
The
|
The
|
||||||
.Tn RIPEMD160
|
.Tn RIPEMD160
|
||||||
|
@ -192,6 +250,24 @@ message digest of the file.
|
||||||
.It Cm sha256digest
|
.It Cm sha256digest
|
||||||
A synonym for
|
A synonym for
|
||||||
.Cm sha256 .
|
.Cm sha256 .
|
||||||
|
.It Cm sha384
|
||||||
|
The
|
||||||
|
.Tn FIPS
|
||||||
|
180-2
|
||||||
|
.Pq Dq Tn SHA-384
|
||||||
|
message digest of the file.
|
||||||
|
.It Cm sha384digest
|
||||||
|
A synonym for
|
||||||
|
.Cm sha384 .
|
||||||
|
.It Cm sha512
|
||||||
|
The
|
||||||
|
.Tn FIPS
|
||||||
|
180-2
|
||||||
|
.Pq Dq Tn SHA-512
|
||||||
|
message digest of the file.
|
||||||
|
.It Cm sha512digest
|
||||||
|
A synonym for
|
||||||
|
.Cm sha512 .
|
||||||
.It Cm size
|
.It Cm size
|
||||||
The size, in bytes, of the file.
|
The size, in bytes, of the file.
|
||||||
.It Cm time
|
.It Cm time
|
||||||
|
|
Loading…
Reference in New Issue