Update libarchive's vendor dist to version 3.1.2 from release branch.
Git branch: release Git commit: 19f23e191f9d3e1dd2a518735046100419965804 Obtained from: https://github.com/libarchive/libarchive.git
This commit is contained in:
parent
81418b36c0
commit
6a316f322a
317
CMakeLists.txt
317
CMakeLists.txt
@ -63,8 +63,8 @@ SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
|
||||
# libarchive 2.8 == interface version 10 = 2 + 8
|
||||
# libarchive 2.9 == interface version 11 = 2 + 9
|
||||
# libarchive 3.0 == interface version 12
|
||||
# libarchive 3.x == interface version 12 + x
|
||||
math(EXPR INTERFACE_VERSION "12 + ${_minor}")
|
||||
# libarchive 3.1 == interface version 13
|
||||
math(EXPR INTERFACE_VERSION "13 + ${_minor}")
|
||||
|
||||
# Set SOVERSION == Interface version
|
||||
# ?? Should there be more here ??
|
||||
@ -151,27 +151,55 @@ OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
|
||||
OPTION(ENABLE_ACL "Enable ACL support" ON)
|
||||
OPTION(ENABLE_ICONV "Enable iconv support" ON)
|
||||
OPTION(ENABLE_TEST "Enable unit and regression tests" ON)
|
||||
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(WINDOWS_VERSION "" CACHE STRING "Set Windows version to use (Windows only)")
|
||||
|
||||
IF(ENABLE_TEST)
|
||||
ENABLE_TESTING()
|
||||
ENDIF(ENABLE_TEST)
|
||||
|
||||
IF(WIN32)
|
||||
IF(MSVC60)
|
||||
SET(WINVER 0x0400)
|
||||
ELSE()
|
||||
IF(WINDOWS_VERSION STREQUAL "WIN8")
|
||||
SET(WINVER 0x0602)
|
||||
ELSEIF(WINDOWS_VERSION STREQUAL "WIN7")
|
||||
SET(WINVER 0x0601)
|
||||
ELSEIF(WINDOWS_VERSION STREQUAL "WS08")
|
||||
SET(WINVER 0x0600)
|
||||
ELSEIF(WINDOWS_VERSION STREQUAL "VISTA")
|
||||
SET(WINVER 0x0600)
|
||||
ELSEIF(WINDOWS_VERSION STREQUAL "WS03")
|
||||
SET(WINVER 0x0502)
|
||||
ELSEIF(WINDOWS_VERSION STREQUAL "WINXP")
|
||||
SET(WINVER 0x0501)
|
||||
ELSE(WINDOWS_VERSION STREQUAL "WIN8")
|
||||
# The default is to use Windows 2000 API.
|
||||
SET(WINVER 0x0500)
|
||||
ENDIF()
|
||||
ENDIF(WINDOWS_VERSION STREQUAL "WIN8")
|
||||
SET(_WIN32_WINNT ${WINVER})
|
||||
ENDIF(WIN32)
|
||||
|
||||
IF(MSVC)
|
||||
IF(ENABLE_SAFESEH STREQUAL "YES")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_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_REQUIRED_LINKER_FLAGS "/SAFESEH")
|
||||
ELSEIF(ENABLE_SAFESEH STREQUAL "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_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO")
|
||||
SET(CMAKE_REQUIRED_LINKER_FLAGS "/SAFESEH:NO")
|
||||
ENDIF(ENABLE_SAFESEH STREQUAL "YES")
|
||||
ENDIF(MSVC)
|
||||
|
||||
IF("${CMAKE_C_PLATFORM_ID}" MATCHES "^(HP-UX)$")
|
||||
ADD_DEFINITIONS(-D_XOPEN_SOURCE=500) # Ask wchar.h for mbstate_t
|
||||
ENDIF()
|
||||
|
||||
#
|
||||
INCLUDE(CheckCSourceCompiles)
|
||||
INCLUDE(CheckCSourceRuns)
|
||||
INCLUDE(LibarchiveCheckCSourceCompiles)
|
||||
INCLUDE(LibarchiveCheckCSourceRuns)
|
||||
INCLUDE(CheckFileOffsetBits)
|
||||
INCLUDE(CheckFuncs)
|
||||
INCLUDE(CheckHeaderDirent)
|
||||
@ -235,9 +263,9 @@ MACRO (TRY_MACRO_FOR_LIBRARY INCLUDES LIBRARIES
|
||||
ENDIF(NOT "${PREV_VAR_WITH_LIB}" STREQUAL "${LIBRARIES}")
|
||||
# Check if the library can be used with the macro.
|
||||
IF("${TRY_TYPE}" MATCHES "COMPILES")
|
||||
CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR})
|
||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR})
|
||||
ELSEIF("${TRY_TYPE}" MATCHES "RUNS")
|
||||
CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
|
||||
LIBARCHIVE_CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
|
||||
ELSE("${TRY_TYPE}" MATCHES "COMPILES")
|
||||
MESSAGE(FATAL_ERROR "UNKNOWN KEYWORD \"${TRY_TYPE}\" FOR TRY_TYPE")
|
||||
ENDIF("${TRY_TYPE}" MATCHES "COMPILES")
|
||||
@ -366,6 +394,30 @@ ELSEIF(LZMADEC_FOUND)
|
||||
INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
|
||||
LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
|
||||
ENDIF(LZMA_FOUND)
|
||||
#
|
||||
# Find LZO2
|
||||
#
|
||||
IF (LZO2_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
SET(LZO2_FIND_QUIETLY TRUE)
|
||||
ENDIF (LZO2_INCLUDE_DIR)
|
||||
|
||||
FIND_PATH(LZO2_INCLUDE_DIR lzo/lzoconf.h)
|
||||
FIND_LIBRARY(LZO2_LIBRARY NAMES lzo2 liblzo2)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZO2 DEFAULT_MSG LZO2_LIBRARY LZO2_INCLUDE_DIR)
|
||||
IF(LZO2_FOUND)
|
||||
SET(HAVE_LIBLZO2 1)
|
||||
SET(HAVE_LZO_LZOCONF_H 1)
|
||||
SET(HAVE_LZO_LZO1X_H 1)
|
||||
INCLUDE_DIRECTORIES(${LZO2_INCLUDE_DIR})
|
||||
LIST(APPEND ADDITIONAL_LIBS ${LZO2_LIBRARY})
|
||||
#
|
||||
# TODO: test for static library.
|
||||
#
|
||||
ENDIF(LZO2_FOUND)
|
||||
MARK_AS_ADVANCED(CLEAR LZO2_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(CLEAR LZO2_LIBRARY)
|
||||
|
||||
#
|
||||
# Check headers
|
||||
@ -392,7 +444,7 @@ LA_CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLFCN_H)
|
||||
LA_CHECK_INCLUDE_FILE("errno.h" HAVE_ERRNO_H)
|
||||
LA_CHECK_INCLUDE_FILE("ext2fs/ext2_fs.h" HAVE_EXT2FS_EXT2_FS_H)
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
|
||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
|
||||
#include <ext2fs/ext2_fs.h>
|
||||
int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
|
||||
|
||||
@ -414,6 +466,7 @@ LA_CHECK_INCLUDE_FILE("process.h" HAVE_PROCESS_H)
|
||||
LA_CHECK_INCLUDE_FILE("pwd.h" HAVE_PWD_H)
|
||||
LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
|
||||
LA_CHECK_INCLUDE_FILE("signal.h" HAVE_SIGNAL_H)
|
||||
LA_CHECK_INCLUDE_FILE("spawn.h" HAVE_SPAWN_H)
|
||||
LA_CHECK_INCLUDE_FILE("stdarg.h" HAVE_STDARG_H)
|
||||
LA_CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H)
|
||||
LA_CHECK_INCLUDE_FILE("stdlib.h" HAVE_STDLIB_H)
|
||||
@ -454,7 +507,7 @@ FOREACH (it ${_HEADER})
|
||||
SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
|
||||
ENDFOREACH (it)
|
||||
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
||||
"#define __EXTENSIONS__ 1
|
||||
${_INCLUDE_FILES}
|
||||
int main() { return 0;}"
|
||||
@ -464,16 +517,17 @@ CHECK_C_SOURCE_COMPILES(
|
||||
# Find Nettle
|
||||
#
|
||||
IF(ENABLE_NETTLE)
|
||||
CHECK_LIBRARY_EXISTS(nettle "nettle_sha1_digest" "" NETTLE_FOUND)
|
||||
FIND_PACKAGE(Nettle)
|
||||
IF(NETTLE_FOUND)
|
||||
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "nettle")
|
||||
FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARY})
|
||||
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
|
||||
ELSE(NETTLE_FOUND)
|
||||
SET(ENABLE_NETTLE OFF)
|
||||
SET(HAVE_LIBNETTLE 1)
|
||||
SET(HAVE_NETTLE_MD5_H 1)
|
||||
SET(HAVE_NETTLE_RIPEMD160_H 1)
|
||||
SET(HAVE_NETTLE_SHA_H 1)
|
||||
INCLUDE_DIRECTORIES(${NETTLE_INCLUDE_DIR})
|
||||
LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARIES})
|
||||
ENDIF(NETTLE_FOUND)
|
||||
MARK_AS_ADVANCED(CLEAR NETTLE_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(CLEAR NETTLE_LIBRARIES)
|
||||
ENDIF(ENABLE_NETTLE)
|
||||
|
||||
#
|
||||
@ -487,14 +541,16 @@ ELSE()
|
||||
ENDIF()
|
||||
|
||||
# FreeBSD libmd
|
||||
CHECK_LIBRARY_EXISTS(md "MD5Init" "" LIBMD_FOUND)
|
||||
IF(LIBMD_FOUND)
|
||||
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "md")
|
||||
FIND_LIBRARY(LIBMD_LIBRARY NAMES md)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${LIBMD_LIBRARY})
|
||||
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
|
||||
ENDIF(LIBMD_FOUND)
|
||||
IF(NOT OPENSSL_FOUND)
|
||||
CHECK_LIBRARY_EXISTS(md "MD5Init" "" LIBMD_FOUND)
|
||||
IF(LIBMD_FOUND)
|
||||
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "md")
|
||||
FIND_LIBRARY(LIBMD_LIBRARY NAMES md)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${LIBMD_LIBRARY})
|
||||
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
|
||||
ENDIF(LIBMD_FOUND)
|
||||
ENDIF(NOT OPENSSL_FOUND)
|
||||
|
||||
#
|
||||
# How to prove that CRYPTO functions, which have several names on various
|
||||
@ -502,13 +558,8 @@ ENDIF(LIBMD_FOUND)
|
||||
# required libraries.
|
||||
#
|
||||
MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
|
||||
IF(HAVE_SYS_TYPES_H)
|
||||
SET(CRYPTO_HEADER_CONFIG "#define HAVE_SYS_TYPES_H 1\n")
|
||||
ELSE(HAVE_SYS_TYPES_H)
|
||||
SET(CRYPTO_HEADER_CONFIG "")
|
||||
ENDIF(HAVE_SYS_TYPES_H)
|
||||
|
||||
FOREACH(ALGORITHM ${ALGORITHMS})
|
||||
IF(NOT ARCHIVE_CRYPTO_${ALGORITHM})
|
||||
STRING(TOLOWER "${ALGORITHM}" lower_algorithm)
|
||||
STRING(TOUPPER "${ALGORITHM}" algorithm)
|
||||
IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
|
||||
@ -521,7 +572,7 @@ MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
|
||||
# Probe the local implementation for whether this
|
||||
# crypto implementation is available on this platform.
|
||||
SET(TRY_CRYPTO_REQUIRED_INCLUDES
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_CURRENT_SOURCE_DIR}/libarchive;${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp")
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive;${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp")
|
||||
SET(TRY_CRYPTO_REQUIRED_LIBS)
|
||||
IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
|
||||
SET(TRY_CRYPTO_REQUIRED_INCLUDES
|
||||
@ -529,6 +580,8 @@ MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
|
||||
SET(TRY_CRYPTO_REQUIRED_LIBS
|
||||
"-DLINK_LIBRARIES:STRING=${OPENSSL_LIBRARIES}")
|
||||
ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NETTLE_FOUND)
|
||||
SET(TRY_CRYPTO_REQUIRED_INCLUDES
|
||||
"${TRY_CRYPTO_REQUIRED_INCLUDES};${NETTLE_INCLUDE_DIR}")
|
||||
SET(TRY_CRYPTO_REQUIRED_LIBS
|
||||
"-DLINK_LIBRARIES:STRING=${NETTLE_LIBRARY}")
|
||||
ELSEIF("${IMPLEMENTATION}" MATCHES "^LIBMD$" AND LIBMD_FOUND)
|
||||
@ -536,10 +589,15 @@ MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
|
||||
"-DLINK_LIBRARIES:STRING=${LIBMD_LIBRARY}")
|
||||
ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
|
||||
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
|
||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h)
|
||||
FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h"
|
||||
CONFDEFS_H)
|
||||
FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/libarchive/archive_crypto.c"
|
||||
ARCHIVE_CRYPTO_C)
|
||||
|
||||
SET(SOURCE "
|
||||
SET(SOURCE "${CONFDEFS_H}
|
||||
|
||||
#define ARCHIVE_${algorithm}_COMPILE_TEST
|
||||
#define ARCHIVE_CRYPTO_${algorithm}_${IMPLEMENTATION}
|
||||
#define PLATFORM_CONFIG_H \"check_crypto_md.h\"
|
||||
@ -561,10 +619,16 @@ main(int argc, char **argv)
|
||||
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}")
|
||||
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}")
|
||||
|
||||
IF(CMAKE_REQUIRED_LINKER_FLAGS)
|
||||
SET(CHECK_CRYPTO_ADD_LINKER_FLAGS
|
||||
"-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
|
||||
ELSE(CMAKE_REQUIRED_LINKER_FLAGS)
|
||||
SET(CHECK_CRYPTO_ADD_LINKER_FLAGS)
|
||||
ENDIF(CMAKE_REQUIRED_LINKER_FLAGS)
|
||||
TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c
|
||||
CMAKE_FLAGS
|
||||
CMAKE_FLAGS ${CHECK_CRYPTO_ADD_LINKER_FLAGS}
|
||||
"${TRY_CRYPTO_REQUIRED_LIBS}"
|
||||
"${TRY_CRYPTO_REQUIRED_INCLUDES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
@ -572,6 +636,7 @@ main(int argc, char **argv)
|
||||
# Inform user whether or not we found it; if not, log why we didn't.
|
||||
IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
|
||||
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- found")
|
||||
SET(ARCHIVE_CRYPTO_${ALGORITHM} 1)
|
||||
ELSE (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
|
||||
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- not found")
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
@ -590,6 +655,7 @@ main(int argc, char **argv)
|
||||
LIST(REMOVE_DUPLICATES ADDITIONAL_LIBS)
|
||||
ENDIF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
|
||||
ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
|
||||
ENDIF(NOT ARCHIVE_CRYPTO_${ALGORITHM})
|
||||
ENDFOREACH(ALGORITHM ${ALGORITHMS})
|
||||
ENDMACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
|
||||
|
||||
@ -605,6 +671,7 @@ ENDMACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
|
||||
MACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
|
||||
IF(WIN32 AND NOT CYGWIN)
|
||||
FOREACH(CRYPTO ${CRYPTO_LIST})
|
||||
IF(NOT ARCHIVE_CRYPTO_${CRYPTO})
|
||||
IF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
|
||||
STRING(TOUPPER "${CRYPTO}" crypto)
|
||||
SET(ALGID "")
|
||||
@ -624,9 +691,14 @@ MACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
|
||||
SET(ALGID "CALG_SHA_512")
|
||||
ENDIF ("${CRYPTO}" MATCHES "^SHA512$")
|
||||
|
||||
SET(SOURCE "#define ${crypto}_COMPILE_TEST
|
||||
#define _WIN32_WINNT ${_WIN32_WINNT}
|
||||
#define WINVER ${WINVER}
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
|
||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h)
|
||||
FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h"
|
||||
CONFDEFS_H)
|
||||
|
||||
SET(SOURCE "${CONFDEFS_H}
|
||||
|
||||
#define ${crypto}_COMPILE_TEST
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
@ -641,15 +713,22 @@ main(int argc, char **argv)
|
||||
FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
|
||||
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
|
||||
|
||||
IF(CMAKE_REQUIRED_LINKER_FLAGS)
|
||||
SET(CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS
|
||||
"-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_REQUIRED_LINKER_FLAGS}")
|
||||
ELSE(CMAKE_REQUIRED_LINKER_FLAGS)
|
||||
SET(CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS)
|
||||
ENDIF(CMAKE_REQUIRED_LINKER_FLAGS)
|
||||
TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
|
||||
${CMAKE_BINARY_DIR}
|
||||
${SOURCE_FILE}
|
||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_CURRENT_SOURCE_DIR}/libarchive"
|
||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive" ${CHECK_CRYPTO_WIN_ADD_LINKER_FLAGS}
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
|
||||
IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
|
||||
MESSAGE(STATUS
|
||||
"Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- found")
|
||||
SET(ARCHIVE_CRYPTO_${CRYPTO} 1)
|
||||
ELSE (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
|
||||
MESSAGE(STATUS
|
||||
"Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- not found")
|
||||
@ -661,6 +740,7 @@ main(int argc, char **argv)
|
||||
ENDIF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
|
||||
|
||||
ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
|
||||
ENDIF(NOT ARCHIVE_CRYPTO_${CRYPTO})
|
||||
ENDFOREACH(CRYPTO)
|
||||
ENDIF(WIN32 AND NOT CYGWIN)
|
||||
ENDMACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
|
||||
@ -688,7 +768,7 @@ MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
|
||||
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /WX")
|
||||
ENDIF (MSVC)
|
||||
#
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
||||
"#include <stdlib.h>
|
||||
#include <iconv.h>
|
||||
int main() {
|
||||
@ -841,49 +921,112 @@ ELSE(LIBXML2_FOUND)
|
||||
ENDIF(LIBXML2_FOUND)
|
||||
MARK_AS_ADVANCED(CLEAR LIBXML2_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(CLEAR LIBXML2_LIBRARIES)
|
||||
|
||||
#
|
||||
# Find Libregex
|
||||
# POSIX Regular Expression support
|
||||
#
|
||||
FIND_PATH(REGEX_INCLUDE_DIR regex.h)
|
||||
IF(REGEX_INCLUDE_DIR)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBC)
|
||||
IF(POSIX_REGEX_LIB MATCHES "^(AUTO|LIBC|LIBREGEX)$")
|
||||
#
|
||||
# If libc does not provide regex, find libregex.
|
||||
# If PCREPOSIX is not found or not requested, try using regex
|
||||
# from libc or libregex
|
||||
#
|
||||
IF(NOT HAVE_REGCOMP_LIBC)
|
||||
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
|
||||
FIND_LIBRARY(REGEX_LIBRARY regex)
|
||||
IF(REGEX_LIBRARY)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${REGEX_LIBRARY})
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBREGEX)
|
||||
IF(HAVE_REGCOMP_LIBREGEX)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${REGEX_LIBRARY})
|
||||
#
|
||||
# If regex.h is not found, retry looking for regex.h at
|
||||
# REGEX_INCLUDE_DIR
|
||||
#
|
||||
IF(NOT HAVE_REGEX_H)
|
||||
UNSET(HAVE_REGEX_H CACHE)
|
||||
INCLUDE_DIRECTORIES(${REGEX_INCLUDE_DIR})
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${REGEX_INCLUDE_DIR})
|
||||
LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
|
||||
ENDIF(NOT HAVE_REGEX_H)
|
||||
# Test if a macro is needed for the library.
|
||||
TRY_MACRO_FOR_LIBRARY(
|
||||
"${REGEX_INCLUDE_DIR}" "${REGEX_LIBRARY}"
|
||||
COMPILES
|
||||
"#include <stddef.h>\n#include <regex.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
|
||||
"USE_REGEX_DLL;USE_REGEX_STATIC")
|
||||
IF(USE_REGEX_DLL)
|
||||
ADD_DEFINITIONS(-DUSE_REGEX_DLL)
|
||||
ELSEIF(USE_REGEX_STATIC)
|
||||
ADD_DEFINITIONS(-DUSE_REGEX_STATIC)
|
||||
ENDIF(USE_REGEX_DLL)
|
||||
ENDIF(HAVE_REGCOMP_LIBREGEX)
|
||||
ENDIF(REGEX_LIBRARY)
|
||||
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
|
||||
ENDIF(NOT HAVE_REGCOMP_LIBC)
|
||||
ENDIF(REGEX_INCLUDE_DIR)
|
||||
FIND_PATH(REGEX_INCLUDE_DIR regex.h)
|
||||
IF(REGEX_INCLUDE_DIR)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBC)
|
||||
#
|
||||
# If libc does not provide regex, find libregex.
|
||||
#
|
||||
IF(NOT HAVE_REGCOMP_LIBC)
|
||||
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
|
||||
FIND_LIBRARY(REGEX_LIBRARY regex)
|
||||
IF(REGEX_LIBRARY)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${REGEX_LIBRARY})
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBREGEX)
|
||||
IF(HAVE_REGCOMP_LIBREGEX)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${REGEX_LIBRARY})
|
||||
#
|
||||
# If regex.h is not found, retry looking for regex.h at
|
||||
# REGEX_INCLUDE_DIR
|
||||
#
|
||||
IF(NOT HAVE_REGEX_H)
|
||||
UNSET(HAVE_REGEX_H CACHE)
|
||||
INCLUDE_DIRECTORIES(${REGEX_INCLUDE_DIR})
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${REGEX_INCLUDE_DIR})
|
||||
LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
|
||||
ENDIF(NOT HAVE_REGEX_H)
|
||||
# Test if a macro is needed for the library.
|
||||
TRY_MACRO_FOR_LIBRARY(
|
||||
"${REGEX_INCLUDE_DIR}" "${REGEX_LIBRARY}"
|
||||
COMPILES
|
||||
"#include <stddef.h>\n#include <regex.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
|
||||
"USE_REGEX_DLL;USE_REGEX_STATIC")
|
||||
IF(USE_REGEX_DLL)
|
||||
ADD_DEFINITIONS(-DUSE_REGEX_DLL)
|
||||
ELSEIF(USE_REGEX_STATIC)
|
||||
ADD_DEFINITIONS(-DUSE_REGEX_STATIC)
|
||||
ENDIF(USE_REGEX_DLL)
|
||||
ENDIF(HAVE_REGCOMP_LIBREGEX)
|
||||
ENDIF(REGEX_LIBRARY)
|
||||
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
|
||||
ENDIF(NOT HAVE_REGCOMP_LIBC)
|
||||
ENDIF(REGEX_INCLUDE_DIR)
|
||||
IF(HAVE_REGCOMP_LIBC OR HAVE_REGCOMP_LIBREGEX)
|
||||
SET(FOUND_POSIX_REGEX_LIB 1)
|
||||
ENDIF(HAVE_REGCOMP_LIBC OR HAVE_REGCOMP_LIBREGEX)
|
||||
ENDIF(POSIX_REGEX_LIB MATCHES "^(AUTO|LIBC|LIBREGEX)$")
|
||||
|
||||
IF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$")
|
||||
#
|
||||
# If requested, try finding library for PCREPOSIX
|
||||
#
|
||||
FIND_PACKAGE(LibGCC)
|
||||
FIND_PACKAGE(PCREPOSIX)
|
||||
IF(PCREPOSIX_FOUND)
|
||||
INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIR})
|
||||
LIST(APPEND ADDITIONAL_LIBS ${PCREPOSIX_LIBRARIES})
|
||||
# Test if a macro is needed for the library.
|
||||
TRY_MACRO_FOR_LIBRARY(
|
||||
"${PCRE_INCLUDE_DIR}" "${PCREPOSIX_LIBRARIES}"
|
||||
COMPILES
|
||||
"#include <pcreposix.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
|
||||
"WITHOUT_PCRE_STATIC;PCRE_STATIC")
|
||||
IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
|
||||
ADD_DEFINITIONS(-DPCRE_STATIC)
|
||||
ELSEIF(NOT WITHOUT_PCRE_STATIC AND NOT PCRE_STATIC AND PCRE_FOUND)
|
||||
# Determine if pcre static libraries are to be used.
|
||||
LIST(APPEND ADDITIONAL_LIBS ${PCRE_LIBRARIES})
|
||||
SET(TMP_LIBRARIES ${PCREPOSIX_LIBRARIES} ${PCRE_LIBRARIES})
|
||||
MESSAGE(STATUS "trying again with -lpcre included")
|
||||
TRY_MACRO_FOR_LIBRARY(
|
||||
"${PCRE_INCLUDE_DIR}" "${TMP_LIBRARIES}"
|
||||
COMPILES
|
||||
"#include <pcreposix.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
|
||||
"WITHOUT_PCRE_STATIC;PCRE_STATIC")
|
||||
IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
|
||||
ADD_DEFINITIONS(-DPCRE_STATIC)
|
||||
ELSEIF(NOT WITHOUT_PCRE_STATIC AND NOT PCRE_STATIC AND MSVC AND LIBGCC_FOUND)
|
||||
# When doing a Visual Studio build using pcre static libraries
|
||||
# built using the mingw toolchain, -lgcc is needed to resolve
|
||||
# ___chkstk_ms.
|
||||
MESSAGE(STATUS "Visual Studio build detected, trying again with -lgcc included")
|
||||
LIST(APPEND ADDITIONAL_LIBS ${LIBGCC_LIBRARIES})
|
||||
SET(TMP_LIBRARIES ${PCREPOSIX_LIBRARIES} ${PCRE_LIBRARIES} ${LIBGCC_LIBRARIES})
|
||||
TRY_MACRO_FOR_LIBRARY(
|
||||
"${PCRE_INCLUDE_DIR}" "${TMP_LIBRARIES}"
|
||||
COMPILES
|
||||
"#include <pcreposix.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
|
||||
"WITHOUT_PCRE_STATIC;PCRE_STATIC")
|
||||
IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
|
||||
ADD_DEFINITIONS(-DPCRE_STATIC)
|
||||
ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
|
||||
ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
|
||||
ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
|
||||
ENDIF(PCREPOSIX_FOUND)
|
||||
MARK_AS_ADVANCED(CLEAR PCRE_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(CLEAR PCREPOSIX_LIBRARIES)
|
||||
MARK_AS_ADVANCED(CLEAR PCRE_LIBRARIES)
|
||||
MARK_AS_ADVANCED(CLEAR LIBGCC_LIBRARIES)
|
||||
ENDIF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$")
|
||||
|
||||
#
|
||||
# Check functions
|
||||
@ -902,6 +1045,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(ctime_r HAVE_CTIME_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(dirfd HAVE_DIRFD)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fchdir HAVE_FCHDIR)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fchflags HAVE_FCHFLAGS)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fchmod HAVE_FCHMOD)
|
||||
@ -942,6 +1086,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(nl_langinfo HAVE_NL_LANGINFO)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(openat HAVE_OPENAT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(pipe HAVE_PIPE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(poll HAVE_POLL)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(posix_spawnp HAVE_POSIX_SPAWNP)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(readlink HAVE_READLINK)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(select HAVE_SELECT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(setenv HAVE_SETENV)
|
||||
@ -986,14 +1131,14 @@ CMAKE_POP_CHECK_STATE() # Restore the state of the variables
|
||||
|
||||
# Make sure we have the POSIX version of readdir_r, not the
|
||||
# older 2-argument version.
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
||||
"#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}"
|
||||
HAVE_READDIR_R)
|
||||
|
||||
|
||||
# Only detect readlinkat() if we also have AT_FDCWD in unistd.h.
|
||||
# NOTE: linux requires fcntl.h for AT_FDCWD.
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
||||
"#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
|
||||
HAVE_READLINKAT)
|
||||
|
||||
@ -1002,10 +1147,10 @@ CHECK_C_SOURCE_COMPILES(
|
||||
# of interest and verify that the result can be linked.
|
||||
# CHECK_FUNCTION_EXISTS doesn't accept a header argument,
|
||||
# CHECK_SYMBOL_EXISTS doesn't test linkage.
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
||||
"#include <sys/mkdev.h>\nint main() { return major(256); }"
|
||||
MAJOR_IN_MKDEV)
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
LIBARCHIVE_CHECK_C_SOURCE_COMPILES(
|
||||
"#include <sys/sysmacros.h>\nint main() { return major(256); }"
|
||||
MAJOR_IN_SYSMACROS)
|
||||
|
||||
@ -1301,6 +1446,8 @@ IF(ENABLE_ACL)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_link HAVE_ACL_GET_LINK)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_is_trivial_np HAVE_ACL_IS_TRIVIAL_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_set_link_np HAVE_ACL_SET_LINK_NP)
|
||||
|
||||
# MacOS has an acl.h that isn't POSIX. It can be detected by
|
||||
# checking for ACL_USER
|
||||
|
215
Makefile.am
215
Makefile.am
@ -90,6 +90,8 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_acl.c \
|
||||
libarchive/archive_acl_private.h \
|
||||
libarchive/archive_check_magic.c \
|
||||
libarchive/archive_cmdline.c \
|
||||
libarchive/archive_cmdline_private.h \
|
||||
libarchive/archive_crc32.h \
|
||||
libarchive/archive_crypto.c \
|
||||
libarchive/archive_crypto_private.h \
|
||||
@ -118,6 +120,7 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_rb.c \
|
||||
libarchive/archive_rb.h \
|
||||
libarchive/archive_read.c \
|
||||
libarchive/archive_read_append_filter.c \
|
||||
libarchive/archive_read_data_into_fd.c \
|
||||
libarchive/archive_read_disk_entry_from_file.c \
|
||||
libarchive/archive_read_disk_posix.c \
|
||||
@ -129,11 +132,15 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_read_open_filename.c \
|
||||
libarchive/archive_read_open_memory.c \
|
||||
libarchive/archive_read_private.h \
|
||||
libarchive/archive_read_set_format.c \
|
||||
libarchive/archive_read_set_options.c \
|
||||
libarchive/archive_read_support_filter_all.c \
|
||||
libarchive/archive_read_support_filter_bzip2.c \
|
||||
libarchive/archive_read_support_filter_compress.c \
|
||||
libarchive/archive_read_support_filter_grzip.c \
|
||||
libarchive/archive_read_support_filter_gzip.c \
|
||||
libarchive/archive_read_support_filter_lrzip.c \
|
||||
libarchive/archive_read_support_filter_lzop.c \
|
||||
libarchive/archive_read_support_filter_none.c \
|
||||
libarchive/archive_read_support_filter_program.c \
|
||||
libarchive/archive_read_support_filter_rpm.c \
|
||||
@ -161,6 +168,7 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_util.c \
|
||||
libarchive/archive_virtual.c \
|
||||
libarchive/archive_write.c \
|
||||
libarchive/archive_write_disk_acl.c \
|
||||
libarchive/archive_write_disk_posix.c \
|
||||
libarchive/archive_write_disk_private.h \
|
||||
libarchive/archive_write_disk_set_standard_lookup.c \
|
||||
@ -170,11 +178,17 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_write_open_memory.c \
|
||||
libarchive/archive_write_private.h \
|
||||
libarchive/archive_write_add_filter.c \
|
||||
libarchive/archive_write_add_filter_bzip2.c \
|
||||
libarchive/archive_write_add_filter_compress.c \
|
||||
libarchive/archive_write_add_filter_b64encode.c \
|
||||
libarchive/archive_write_add_filter_by_name.c \
|
||||
libarchive/archive_write_add_filter_bzip2.c \
|
||||
libarchive/archive_write_add_filter_compress.c \
|
||||
libarchive/archive_write_add_filter_grzip.c \
|
||||
libarchive/archive_write_add_filter_gzip.c \
|
||||
libarchive/archive_write_add_filter_lrzip.c \
|
||||
libarchive/archive_write_add_filter_lzop.c \
|
||||
libarchive/archive_write_add_filter_none.c \
|
||||
libarchive/archive_write_add_filter_program.c \
|
||||
libarchive/archive_write_add_filter_program.c \
|
||||
libarchive/archive_write_add_filter_uuencode.c \
|
||||
libarchive/archive_write_add_filter_xz.c \
|
||||
libarchive/archive_write_set_format.c \
|
||||
libarchive/archive_write_set_format_7zip.c \
|
||||
@ -187,12 +201,13 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_write_set_format_pax.c \
|
||||
libarchive/archive_write_set_format_shar.c \
|
||||
libarchive/archive_write_set_format_ustar.c \
|
||||
libarchive/archive_write_set_format_v7tar.c \
|
||||
libarchive/archive_write_set_format_gnutar.c \
|
||||
libarchive/archive_write_set_format_xar.c \
|
||||
libarchive/archive_write_set_format_zip.c \
|
||||
libarchive/archive_write_set_options.c \
|
||||
libarchive/config_freebsd.h \
|
||||
libarchive/filter_fork.c \
|
||||
libarchive/filter_fork_posix.c \
|
||||
libarchive/filter_fork.h
|
||||
|
||||
if INC_WINDOWS_FILES
|
||||
@ -220,14 +235,32 @@ libarchive_man_MANS= \
|
||||
libarchive/archive_entry_stat.3 \
|
||||
libarchive/archive_entry_time.3 \
|
||||
libarchive/archive_read.3 \
|
||||
libarchive/archive_read_data.3 \
|
||||
libarchive/archive_read_disk.3 \
|
||||
libarchive/archive_read_extract.3 \
|
||||
libarchive/archive_read_filter.3 \
|
||||
libarchive/archive_read_format.3 \
|
||||
libarchive/archive_read_free.3 \
|
||||
libarchive/archive_read_header.3 \
|
||||
libarchive/archive_read_new.3 \
|
||||
libarchive/archive_read_open.3 \
|
||||
libarchive/archive_read_set_options.3 \
|
||||
libarchive/archive_util.3 \
|
||||
libarchive/archive_write.3 \
|
||||
libarchive/archive_write_blocksize.3 \
|
||||
libarchive/archive_write_data.3 \
|
||||
libarchive/archive_write_disk.3 \
|
||||
libarchive/archive_write_filter.3 \
|
||||
libarchive/archive_write_finish_entry.3 \
|
||||
libarchive/archive_write_format.3 \
|
||||
libarchive/archive_write_free.3 \
|
||||
libarchive/archive_write_header.3 \
|
||||
libarchive/archive_write_new.3 \
|
||||
libarchive/archive_write_open.3 \
|
||||
libarchive/archive_write_set_options.3 \
|
||||
libarchive/cpio.5 \
|
||||
libarchive/libarchive.3 \
|
||||
libarchive/libarchive_changes.3 \
|
||||
libarchive/libarchive_internals.3 \
|
||||
libarchive/libarchive-formats.5 \
|
||||
libarchive/mtree.5 \
|
||||
@ -245,6 +278,11 @@ libarchive_EXTRA_DIST= \
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = build/pkgconfig/libarchive.pc
|
||||
|
||||
# Sources needed by all test programs
|
||||
test_utils_SOURCES= \
|
||||
test_utils/test_utils.c \
|
||||
test_utils/test_utils.h
|
||||
|
||||
#
|
||||
#
|
||||
# libarchive_test program
|
||||
@ -252,15 +290,18 @@ pkgconfig_DATA = build/pkgconfig/libarchive.pc
|
||||
#
|
||||
libarchive_test_SOURCES= \
|
||||
$(libarchive_la_SOURCES) \
|
||||
$(test_utils_SOURCES) \
|
||||
libarchive/test/main.c \
|
||||
libarchive/test/read_open_memory.c \
|
||||
libarchive/test/test.h \
|
||||
libarchive/test/test_acl_freebsd.c \
|
||||
libarchive/test/test_acl_freebsd_posix1e.c \
|
||||
libarchive/test/test_acl_freebsd_nfs4.c \
|
||||
libarchive/test/test_acl_nfs4.c \
|
||||
libarchive/test/test_acl_pax.c \
|
||||
libarchive/test/test_acl_posix1e.c \
|
||||
libarchive/test/test_archive_api_feature.c \
|
||||
libarchive/test/test_archive_clear_error.c \
|
||||
libarchive/test/test_archive_cmdline.c \
|
||||
libarchive/test/test_archive_crypto.c \
|
||||
libarchive/test/test_archive_getdate.c \
|
||||
libarchive/test/test_archive_match_owner.c \
|
||||
@ -270,6 +311,7 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_archive_read_close_twice.c \
|
||||
libarchive/test/test_archive_read_close_twice_open_fd.c \
|
||||
libarchive/test/test_archive_read_close_twice_open_filename.c \
|
||||
libarchive/test/test_archive_read_multiple_data_objects.c \
|
||||
libarchive/test/test_archive_read_next_header_empty.c \
|
||||
libarchive/test/test_archive_read_next_header_raw.c \
|
||||
libarchive/test/test_archive_read_open2.c \
|
||||
@ -281,7 +323,9 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_archive_set_error.c \
|
||||
libarchive/test/test_archive_string.c \
|
||||
libarchive/test/test_archive_string_conversion.c \
|
||||
libarchive/test/test_archive_write_add_filter_by_name.c \
|
||||
libarchive/test/test_archive_write_set_filter_option.c \
|
||||
libarchive/test/test_archive_write_set_format_by_name.c \
|
||||
libarchive/test/test_archive_write_set_format_option.c \
|
||||
libarchive/test/test_archive_write_set_option.c \
|
||||
libarchive/test/test_archive_write_set_options.c \
|
||||
@ -292,11 +336,13 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_compat_gzip.c \
|
||||
libarchive/test/test_compat_lzip.c \
|
||||
libarchive/test/test_compat_lzma.c \
|
||||
libarchive/test/test_compat_lzop.c \
|
||||
libarchive/test/test_compat_mac.c \
|
||||
libarchive/test/test_compat_pax_libarchive_2x.c \
|
||||
libarchive/test/test_compat_solaris_tar_acl.c \
|
||||
libarchive/test/test_compat_solaris_pax_sparse.c \
|
||||
libarchive/test/test_compat_tar_hardlink.c \
|
||||
libarchive/test/test_compat_uudecode.c \
|
||||
libarchive/test/test_compat_xz.c \
|
||||
libarchive/test/test_compat_zip.c \
|
||||
libarchive/test/test_empty_write.c \
|
||||
@ -312,13 +358,19 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_open_file.c \
|
||||
libarchive/test/test_open_filename.c \
|
||||
libarchive/test/test_pax_filename_encoding.c \
|
||||
libarchive/test/test_read_compress_program.c \
|
||||
libarchive/test/test_read_data_large.c \
|
||||
libarchive/test/test_read_disk.c \
|
||||
libarchive/test/test_read_disk_directory_traversals.c \
|
||||
libarchive/test/test_read_disk_entry_from_file.c \
|
||||
libarchive/test/test_read_extract.c \
|
||||
libarchive/test/test_read_file_nonexistent.c \
|
||||
libarchive/test/test_read_filter_grzip.c \
|
||||
libarchive/test/test_read_filter_lrzip.c \
|
||||
libarchive/test/test_read_filter_lzop.c \
|
||||
libarchive/test/test_read_filter_lzop_multiple_parts.c \
|
||||
libarchive/test/test_read_filter_program.c \
|
||||
libarchive/test/test_read_filter_program_signature.c \
|
||||
libarchive/test/test_read_filter_uudecode.c \
|
||||
libarchive/test/test_read_format_7zip.c \
|
||||
libarchive/test/test_read_format_ar.c \
|
||||
libarchive/test/test_read_format_cab.c \
|
||||
@ -372,35 +424,49 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_read_format_ustar_filename.c \
|
||||
libarchive/test/test_read_format_xar.c \
|
||||
libarchive/test/test_read_format_zip.c \
|
||||
libarchive/test/test_read_format_zip_comment_stored.c \
|
||||
libarchive/test/test_read_format_zip_filename.c \
|
||||
libarchive/test/test_read_format_zip_mac_metadata.c \
|
||||
libarchive/test/test_read_format_zip_sfx.c \
|
||||
libarchive/test/test_read_large.c \
|
||||
libarchive/test/test_read_pax_truncated.c \
|
||||
libarchive/test/test_read_position.c \
|
||||
libarchive/test/test_read_set_format.c \
|
||||
libarchive/test/test_read_truncated.c \
|
||||
libarchive/test/test_read_truncated_filter.c \
|
||||
libarchive/test/test_read_uu.c \
|
||||
libarchive/test/test_sparse_basic.c \
|
||||
libarchive/test/test_tar_filenames.c \
|
||||
libarchive/test/test_tar_large.c \
|
||||
libarchive/test/test_ustar_filenames.c \
|
||||
libarchive/test/test_ustar_filename_encoding.c \
|
||||
libarchive/test/test_write_compress.c \
|
||||
libarchive/test/test_write_compress_bzip2.c \
|
||||
libarchive/test/test_write_compress_gzip.c \
|
||||
libarchive/test/test_write_compress_lzip.c \
|
||||
libarchive/test/test_write_compress_lzma.c \
|
||||
libarchive/test/test_write_compress_program.c \
|
||||
libarchive/test/test_write_compress_xz.c \
|
||||
libarchive/test/test_write_disk.c \
|
||||
libarchive/test/test_write_disk_appledouble.c \
|
||||
libarchive/test/test_write_disk_failures.c \
|
||||
libarchive/test/test_write_disk_hardlink.c \
|
||||
libarchive/test/test_write_disk_hfs_compression.c \
|
||||
libarchive/test/test_write_disk_lookup.c \
|
||||
libarchive/test/test_write_disk_mac_metadata.c \
|
||||
libarchive/test/test_write_disk_no_hfs_compression.c \
|
||||
libarchive/test/test_write_disk_perms.c \
|
||||
libarchive/test/test_write_disk_secure.c \
|
||||
libarchive/test/test_write_disk_sparse.c \
|
||||
libarchive/test/test_write_disk_symlink.c \
|
||||
libarchive/test/test_write_disk_times.c \
|
||||
libarchive/test/test_write_filter_b64encode.c \
|
||||
libarchive/test/test_write_filter_bzip2.c \
|
||||
libarchive/test/test_write_filter_compress.c \
|
||||
libarchive/test/test_write_filter_gzip.c \
|
||||
libarchive/test/test_write_filter_gzip_timestamp.c \
|
||||
libarchive/test/test_write_filter_lrzip.c \
|
||||
libarchive/test/test_write_filter_lzip.c \
|
||||
libarchive/test/test_write_filter_lzma.c \
|
||||
libarchive/test/test_write_filter_lzop.c \
|
||||
libarchive/test/test_write_filter_program.c \
|
||||
libarchive/test/test_write_filter_uuencode.c \
|
||||
libarchive/test/test_write_filter_xz.c \
|
||||
libarchive/test/test_write_format_7zip.c \
|
||||
libarchive/test/test_write_format_7zip_empty.c \
|
||||
libarchive/test/test_write_format_7zip_large.c \
|
||||
libarchive/test/test_write_format_ar.c \
|
||||
libarchive/test/test_write_format_cpio.c \
|
||||
libarchive/test/test_write_format_cpio_empty.c \
|
||||
@ -413,22 +479,29 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_write_format_iso9660_filename.c \
|
||||
libarchive/test/test_write_format_iso9660_zisofs.c \
|
||||
libarchive/test/test_write_format_mtree.c \
|
||||
libarchive/test/test_write_format_mtree_absolute_path.c \
|
||||
libarchive/test/test_write_format_mtree_classic.c \
|
||||
libarchive/test/test_write_format_mtree_classic_indent.c\
|
||||
libarchive/test/test_write_format_mtree_fflags.c \
|
||||
libarchive/test/test_write_format_mtree_no_separator.c \
|
||||
libarchive/test/test_write_format_mtree_quoted_filename.c\
|
||||
libarchive/test/test_write_format_pax.c \
|
||||
libarchive/test/test_write_format_shar_empty.c \
|
||||
libarchive/test/test_write_format_tar.c \
|
||||
libarchive/test/test_write_format_tar_empty.c \
|
||||
libarchive/test/test_write_format_tar_sparse.c \
|
||||
libarchive/test/test_write_format_tar_ustar.c \
|
||||
libarchive/test/test_write_format_tar_v7tar.c \
|
||||
libarchive/test/test_write_format_xar.c \
|
||||
libarchive/test/test_write_format_xar_empty.c \
|
||||
libarchive/test/test_write_format_zip.c \
|
||||
libarchive/test/test_write_format_zip_empty.c \
|
||||
libarchive/test/test_write_format_zip_no_compression.c \
|
||||
libarchive/test/test_write_open_memory.c \
|
||||
libarchive/test/test_write_zip_set_compression_store.c \
|
||||
libarchive/test/test_zip_filename_encoding.c
|
||||
|
||||
libarchive_test_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_builddir)/libarchive/test -DLIBARCHIVE_STATIC $(PLATFORMCPPFLAGS)
|
||||
libarchive_test_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/test_utils -I$(top_builddir)/libarchive/test -DLIBARCHIVE_STATIC $(PLATFORMCPPFLAGS)
|
||||
libarchive_test_LDADD= $(LTLIBICONV)
|
||||
|
||||
# The "list.h" file just lists all of the tests defined in all of the sources.
|
||||
@ -437,7 +510,7 @@ libarchive_test_LDADD= $(LTLIBICONV)
|
||||
libarchive/test/list.h: Makefile
|
||||
cat $(top_srcdir)/libarchive/test/test_*.c | grep DEFINE_TEST > libarchive/test/list.h
|
||||
|
||||
libarchive_TESTS_ENVIRONMENT= LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/libarchive/test
|
||||
libarchive_TESTS_ENVIRONMENT= LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/libarchive/test LRZIP=NOCONFIG
|
||||
|
||||
libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/list.h \
|
||||
@ -454,6 +527,9 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_compat_lzma_1.tlz.uu \
|
||||
libarchive/test/test_compat_lzma_2.tlz.uu \
|
||||
libarchive/test/test_compat_lzma_3.tlz.uu \
|
||||
libarchive/test/test_compat_lzop_1.tar.lzo.uu \
|
||||
libarchive/test/test_compat_lzop_2.tar.lzo.uu \
|
||||
libarchive/test/test_compat_lzop_3.tar.lzo.uu \
|
||||
libarchive/test/test_compat_mac-1.tar.Z.uu \
|
||||
libarchive/test/test_compat_mac-2.tar.Z.uu \
|
||||
libarchive/test/test_compat_pax_libarchive_2x.tar.Z.uu \
|
||||
@ -473,6 +549,29 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_fuzz.cab.uu \
|
||||
libarchive/test/test_fuzz.lzh.uu \
|
||||
libarchive/test/test_pax_filename_encoding.tar.uu \
|
||||
libarchive/test/test_rar_multivolume_multiple_files.part1.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_multiple_files.part2.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_multiple_files.part3.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_multiple_files.part4.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_multiple_files.part5.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_multiple_files.part6.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_single_file.part1.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_single_file.part2.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_single_file.part3.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_uncompressed_files.part01.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_uncompressed_files.part02.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_uncompressed_files.part03.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_uncompressed_files.part04.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_uncompressed_files.part05.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_uncompressed_files.part06.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_uncompressed_files.part07.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_uncompressed_files.part08.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_uncompressed_files.part09.rar.uu \
|
||||
libarchive/test/test_rar_multivolume_uncompressed_files.part10.rar.uu \
|
||||
libarchive/test/test_read_filter_grzip.tar.grz.uu \
|
||||
libarchive/test/test_read_filter_lrzip.tar.lrz.uu \
|
||||
libarchive/test/test_read_filter_lzop.tar.lzo.uu \
|
||||
libarchive/test/test_read_filter_lzop_multiple_parts.tar.lzo.uu \
|
||||
libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu \
|
||||
libarchive/test/test_read_format_7zip_bcj_copy.7z.uu \
|
||||
libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu \
|
||||
@ -547,11 +646,17 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_format_lha_withjunk.lzh.uu \
|
||||
libarchive/test/test_read_format_mtree.mtree.uu \
|
||||
libarchive/test/test_read_format_mtree_nomagic.mtree.uu \
|
||||
libarchive/test/test_read_format_mtree_nomagic2.mtree.uu \
|
||||
libarchive/test/test_read_format_mtree_nomagic3.mtree.uu \
|
||||
libarchive/test/test_read_format_rar.rar.uu \
|
||||
libarchive/test/test_read_format_rar_binary_data.rar.uu \
|
||||
libarchive/test/test_read_format_rar_compress_best.rar.uu \
|
||||
libarchive/test/test_read_format_rar_compress_normal.rar.uu \
|
||||
libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu \
|
||||
libarchive/test/test_read_format_rar_multivolume.part0001.rar.uu\
|
||||
libarchive/test/test_read_format_rar_multivolume.part0002.rar.uu\
|
||||
libarchive/test/test_read_format_rar_multivolume.part0003.rar.uu\
|
||||
libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu\
|
||||
libarchive/test/test_read_format_rar_noeof.rar.uu \
|
||||
libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu\
|
||||
libarchive/test/test_read_format_rar_sfx.exe.uu \
|
||||
@ -566,6 +671,8 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \
|
||||
libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
|
||||
libarchive/test/test_read_format_zip.zip.uu \
|
||||
libarchive/test/test_read_format_zip_comment_stored_1.zip.uu \
|
||||
libarchive/test/test_read_format_zip_comment_stored_2.zip.uu \
|
||||
libarchive/test/test_read_format_zip_filename_cp866.zip.uu \
|
||||
libarchive/test/test_read_format_zip_filename_cp932.zip.uu \
|
||||
libarchive/test/test_read_format_zip_filename_koi8r.zip.uu \
|
||||
@ -573,8 +680,26 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu \
|
||||
libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu \
|
||||
libarchive/test/test_read_format_zip_length_at_end.zip.uu \
|
||||
libarchive/test/test_read_format_zip_mac_metadata.zip.uu \
|
||||
libarchive/test/test_read_format_zip_sfx.uu \
|
||||
libarchive/test/test_read_format_zip_symlink.zip.uu \
|
||||
libarchive/test/test_read_format_zip_ux.zip.uu \
|
||||
libarchive/test/test_read_large_splitted_rar_aa.uu \
|
||||
libarchive/test/test_read_large_splitted_rar_ab.uu \
|
||||
libarchive/test/test_read_large_splitted_rar_ac.uu \
|
||||
libarchive/test/test_read_large_splitted_rar_ad.uu \
|
||||
libarchive/test/test_read_large_splitted_rar_ae.uu \
|
||||
libarchive/test/test_read_splitted_rar_aa.uu \
|
||||
libarchive/test/test_read_splitted_rar_ab.uu \
|
||||
libarchive/test/test_read_splitted_rar_ac.uu \
|
||||
libarchive/test/test_read_splitted_rar_ad.uu \
|
||||
libarchive/test/test_splitted_rar_seek_support_aa.uu \
|
||||
libarchive/test/test_splitted_rar_seek_support_ab.uu \
|
||||
libarchive/test/test_splitted_rar_seek_support_ac.uu \
|
||||
libarchive/test/test_write_disk_appledouble.cpio.gz.uu \
|
||||
libarchive/test/test_write_disk_hfs_compression.tgz.uu \
|
||||
libarchive/test/test_write_disk_mac_metadata.tar.gz.uu \
|
||||
libarchive/test/test_write_disk_no_hfs_compression.tgz.uu \
|
||||
libarchive/test/CMakeLists.txt \
|
||||
libarchive/test/README
|
||||
|
||||
@ -600,6 +725,7 @@ bsdtar_SOURCES= \
|
||||
tar/bsdtar.h \
|
||||
tar/bsdtar_platform.h \
|
||||
tar/cmdline.c \
|
||||
tar/creation_set.c \
|
||||
tar/read.c \
|
||||
tar/subst.c \
|
||||
tar/util.c \
|
||||
@ -646,12 +772,22 @@ endif
|
||||
#
|
||||
|
||||
bsdtar_test_SOURCES= \
|
||||
$(test_utils_SOURCES) \
|
||||
tar/test/main.c \
|
||||
tar/test/test.h \
|
||||
tar/test/test_0.c \
|
||||
tar/test/test_basic.c \
|
||||
tar/test/test_copy.c \
|
||||
tar/test/test_empty_mtree.c \
|
||||
tar/test/test_extract_tar_Z.c \
|
||||
tar/test/test_extract_tar_bz2.c \
|
||||
tar/test/test_extract_tar_grz.c \
|
||||
tar/test/test_extract_tar_gz.c \
|
||||
tar/test/test_extract_tar_lrz.c \
|
||||
tar/test/test_extract_tar_lz.c \
|
||||
tar/test/test_extract_tar_lzma.c \
|
||||
tar/test/test_extract_tar_lzo.c \
|
||||
tar/test/test_extract_tar_xz.c \
|
||||
tar/test/test_format_newc.c \
|
||||
tar/test/test_help.c \
|
||||
tar/test/test_option_C_upper.c \
|
||||
@ -661,18 +797,29 @@ bsdtar_test_SOURCES= \
|
||||
tar/test/test_option_T_upper.c \
|
||||
tar/test/test_option_U_upper.c \
|
||||
tar/test/test_option_X_upper.c \
|
||||
tar/test/test_option_a.c \
|
||||
tar/test/test_option_b.c \
|
||||
tar/test/test_option_b64encode.c \
|
||||
tar/test/test_option_exclude.c \
|
||||
tar/test/test_option_gid_gname.c \
|
||||
tar/test/test_option_grzip.c \
|
||||
tar/test/test_option_j.c \
|
||||
tar/test/test_option_k.c \
|
||||
tar/test/test_option_keep_newer_files.c \
|
||||
tar/test/test_option_lrzip.c \
|
||||
tar/test/test_option_lzma.c \
|
||||
tar/test/test_option_lzop.c \
|
||||
tar/test/test_option_n.c \
|
||||
tar/test/test_option_newer_than.c \
|
||||
tar/test/test_option_nodump.c \
|
||||
tar/test/test_option_older_than.c \
|
||||
tar/test/test_option_q.c \
|
||||
tar/test/test_option_r.c \
|
||||
tar/test/test_option_s.c \
|
||||
tar/test/test_option_uid_uname.c \
|
||||
tar/test/test_option_uuencode.c \
|
||||
tar/test/test_option_xz.c \
|
||||
tar/test/test_option_z.c \
|
||||
tar/test/test_patterns.c \
|
||||
tar/test/test_print_longpath.c \
|
||||
tar/test/test_stdio.c \
|
||||
@ -683,6 +830,7 @@ bsdtar_test_SOURCES= \
|
||||
|
||||
bsdtar_test_CPPFLAGS=\
|
||||
-I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \
|
||||
-I$(top_srcdir)/test_utils \
|
||||
-I$(top_srcdir)/tar -I$(top_builddir)/tar/test \
|
||||
$(PLATFORMCPPFLAGS)
|
||||
|
||||
@ -699,6 +847,15 @@ endif
|
||||
|
||||
bsdtar_test_EXTRA_DIST= \
|
||||
tar/test/list.h \
|
||||
tar/test/test_extract.tar.Z.uu \
|
||||
tar/test/test_extract.tar.bz2.uu \
|
||||
tar/test/test_extract.tar.grz.uu \
|
||||
tar/test/test_extract.tar.gz.uu \
|
||||
tar/test/test_extract.tar.lrz.uu \
|
||||
tar/test/test_extract.tar.lz.uu \
|
||||
tar/test/test_extract.tar.lzma.uu \
|
||||
tar/test/test_extract.tar.lzo.uu \
|
||||
tar/test/test_extract.tar.xz.uu \
|
||||
tar/test/test_option_keep_newer_files.tar.Z.uu \
|
||||
tar/test/test_option_s.tar.Z.uu \
|
||||
tar/test/test_patterns_2.tar.uu \
|
||||
@ -763,12 +920,22 @@ endif
|
||||
#
|
||||
|
||||
bsdcpio_test_SOURCES= \
|
||||
$(test_utils_SOURCES) \
|
||||
cpio/cmdline.c \
|
||||
cpio/test/main.c \
|
||||
cpio/test/test.h \
|
||||
cpio/test/test_0.c \
|
||||
cpio/test/test_basic.c \
|
||||
cpio/test/test_cmdline.c \
|
||||
cpio/test/test_extract_cpio_Z.c \
|
||||
cpio/test/test_extract_cpio_bz2.c \
|
||||
cpio/test/test_extract_cpio_grz.c \
|
||||
cpio/test/test_extract_cpio_gz.c \
|
||||
cpio/test/test_extract_cpio_lrz.c \
|
||||
cpio/test/test_extract_cpio_lz.c \
|
||||
cpio/test/test_extract_cpio_lzma.c \
|
||||
cpio/test/test_extract_cpio_lzo.c \
|
||||
cpio/test/test_extract_cpio_xz.c \
|
||||
cpio/test/test_format_newc.c \
|
||||
cpio/test/test_gcpio_compat.c \
|
||||
cpio/test/test_option_0.c \
|
||||
@ -778,16 +945,22 @@ bsdcpio_test_SOURCES= \
|
||||
cpio/test/test_option_L_upper.c \
|
||||
cpio/test/test_option_Z_upper.c \
|
||||
cpio/test/test_option_a.c \
|
||||
cpio/test/test_option_b64encode.c \
|
||||
cpio/test/test_option_c.c \
|
||||
cpio/test/test_option_d.c \
|
||||
cpio/test/test_option_f.c \
|
||||
cpio/test/test_option_grzip.c \
|
||||
cpio/test/test_option_help.c \
|
||||
cpio/test/test_option_l.c \
|
||||
cpio/test/test_option_lrzip.c \
|
||||
cpio/test/test_option_lzma.c \
|
||||
cpio/test/test_option_lzop.c \
|
||||
cpio/test/test_option_m.c \
|
||||
cpio/test/test_option_t.c \
|
||||
cpio/test/test_option_u.c \
|
||||
cpio/test/test_option_uuencode.c \
|
||||
cpio/test/test_option_version.c \
|
||||
cpio/test/test_option_xz.c \
|
||||
cpio/test/test_option_y.c \
|
||||
cpio/test/test_option_z.c \
|
||||
cpio/test/test_owner_parse.c \
|
||||
@ -796,6 +969,7 @@ bsdcpio_test_SOURCES= \
|
||||
|
||||
bsdcpio_test_CPPFLAGS= \
|
||||
-I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \
|
||||
-I$(top_srcdir)/test_utils \
|
||||
-I$(top_srcdir)/cpio -I$(top_builddir)/cpio/test \
|
||||
$(PLATFORMCPPFLAGS)
|
||||
bsdcpio_test_LDADD=libarchive_fe.la
|
||||
@ -813,6 +987,15 @@ endif
|
||||
|
||||
bsdcpio_test_EXTRA_DIST= \
|
||||
cpio/test/list.h \
|
||||
cpio/test/test_extract.cpio.Z.uu \
|
||||
cpio/test/test_extract.cpio.bz2.uu \
|
||||
cpio/test/test_extract.cpio.grz.uu \
|
||||
cpio/test/test_extract.cpio.gz.uu \
|
||||
cpio/test/test_extract.cpio.lrz.uu \
|
||||
cpio/test/test_extract.cpio.lz.uu \
|
||||
cpio/test/test_extract.cpio.lzma.uu \
|
||||
cpio/test/test_extract.cpio.lzo.uu \
|
||||
cpio/test/test_extract.cpio.xz.uu \
|
||||
cpio/test/test_gcpio_compat_ref.bin.uu \
|
||||
cpio/test/test_gcpio_compat_ref.crc.uu \
|
||||
cpio/test/test_gcpio_compat_ref.newc.uu \
|
||||
|
27
NEWS
27
NEWS
@ -1,3 +1,30 @@
|
||||
Feb 09, 2013: libarchive 3.1.2 released
|
||||
|
||||
Jan 28, 2013: libarchive's new website moved to http://www.libarchive.org.
|
||||
|
||||
Jan 13, 2013: libarchive 3.1.1 released
|
||||
|
||||
Jan 13, 2013: libarchive 3.1.0 released
|
||||
|
||||
Dec 07, 2012: Implement functions to manually set the format and filters used.
|
||||
|
||||
Nov 11, 2012: Add support for __MACOSX directory in Zip archives, which resource
|
||||
forks are stored in.
|
||||
|
||||
Oct 20, 2012: Add support for writing v7 tar format.
|
||||
|
||||
Oct 09, 2012: Add support for grzip compression.
|
||||
|
||||
Oct 07, 2012: Introduce b64encode filter.
|
||||
Oct 07, 2012: Introduce uuencode filter.
|
||||
|
||||
Oct 06, 2012: Add support for lzop.
|
||||
|
||||
Sep 27, 2012: Implement function used to seek within data blocks.
|
||||
(Currently only supported for uncompressed RAR archives).
|
||||
|
||||
Apr 22, 2012: Add basic archive read and write filter support for lrzip.
|
||||
|
||||
Mar 27, 2012: libarchive 3.0.4 released
|
||||
|
||||
Feb 05, 2012: libarchive development now hosted at GitHub.
|
||||
|
2
README
2
README
@ -1,7 +1,7 @@
|
||||
README for libarchive bundle.
|
||||
|
||||
Questions? Issues?
|
||||
* http://libarchive.github.com/ is the home for ongoing
|
||||
* http://www.libarchive.org is the home for ongoing
|
||||
libarchive development, including documentation, and
|
||||
links to the libarchive mailing lists.
|
||||
* To report an issue, use the issue tracker at
|
||||
|
35
build/README.txt
Normal file
35
build/README.txt
Normal file
@ -0,0 +1,35 @@
|
||||
Notes on making a new release of libarchive
|
||||
===========================================
|
||||
|
||||
The following serves as a guide for libarchive developers on the general
|
||||
process to be followed when making a new release of libarchive.
|
||||
|
||||
* Update build/version with the version number of the release to be made.
|
||||
* If the library's ABI has changed, the library's soname major version *MUST*
|
||||
be updated. Update configure.ac and CMakeLists.txt appropriately.
|
||||
- For configure.ac, the variable ARCHIVE_INTERFACE needs to be updated.
|
||||
- For CMakeLists.txt, the variable INTERFACE_VERSION needs to be updated.
|
||||
* Update the entries in the NEWS file accordingly.
|
||||
* Run `build/makerelease.sh` from the top source directory. Running this script
|
||||
will do the following.
|
||||
- Removes all Makefile.am development build specific CFLAGS from
|
||||
Makefile.am.
|
||||
- Update configure scripts and header files with the appropriate version
|
||||
number from build/version.
|
||||
- Rebuild the documentation directory.
|
||||
- Runs a full cmake build and test.
|
||||
- Runs a full autotools build and test.
|
||||
- Builds the .tar.gz and .zip distribution files.
|
||||
* Commit all changed files into git.
|
||||
- This should be build/version, NEWS, and the files edited by running
|
||||
build/makerelease.sh.
|
||||
* Tag the release appropriately. The tag should also have an appropriate
|
||||
message.
|
||||
- The git command is as follows:
|
||||
$ git tag -m "Libarchive <version>" v<version>
|
||||
Replace <version> with the version to be released.
|
||||
* Copy all the generated wiki files and commit them into the libarchive.wiki
|
||||
repository. Overwrite any preexisting files with the same name (these files
|
||||
are always autogenerated from the libarchive release after every release).
|
||||
* Update the libarchive.org website accordingly.
|
||||
* Make an announcement to the libarchive-announce mailing list.
|
@ -48,6 +48,11 @@ perl -p -i -e "s/^(#define\tARCHIVE_VERSION_STRING).*/\$1 \"libarchive $VS\"/" l
|
||||
perl -p -i -e 's/(m4_define\(\[LIBARCHIVE_VERSION_S\]),.*\)/$1,['"$VS"'])/' configure.ac
|
||||
perl -p -i -e 's/(m4_define\(\[LIBARCHIVE_VERSION_N\]),.*\)/$1,['"$VN"'])/' configure.ac
|
||||
|
||||
# Remove developer CFLAGS if a release build is being made
|
||||
if [ -n "${MAKE_LIBARCHIVE_RELEASE}" ]; then
|
||||
perl -p -i -e "s/^(DEV_CFLAGS.*)/# \$1/" Makefile.am
|
||||
fi
|
||||
|
||||
set -xe
|
||||
aclocal -I build/autoconf
|
||||
|
||||
|
@ -31,6 +31,6 @@ echo $ANNOUNCE
|
||||
# Add a version notice to NEWS
|
||||
mv NEWS NEWS.bak
|
||||
chmod +w NEWS.bak
|
||||
echo > NEWS
|
||||
echo $ANNOUNCE >> NEWS
|
||||
echo >> NEWS
|
||||
cat NEWS.bak >> NEWS
|
||||
|
22
build/cmake/FindLibGCC.cmake
Normal file
22
build/cmake/FindLibGCC.cmake
Normal file
@ -0,0 +1,22 @@
|
||||
# - Find libgcc
|
||||
# Find the libgcc library.
|
||||
#
|
||||
# LIBGCC_LIBRARIES - List of libraries when using libgcc
|
||||
# LIBGCC_FOUND - True if libgcc found.
|
||||
|
||||
IF (LIBGCC_LIBRARY)
|
||||
# Already in cache, be silent
|
||||
SET(LIBGCC_FIND_QUIETLY TRUE)
|
||||
ENDIF (LIBGCC_LIBRARY)
|
||||
|
||||
FIND_LIBRARY(LIBGCC_LIBRARY NAMES gcc libgcc)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set LIBGCC_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGCC DEFAULT_MSG LIBGCC_LIBRARY)
|
||||
|
||||
IF(LIBGCC_FOUND)
|
||||
SET(LIBGCC_LIBRARIES ${LIBGCC_LIBRARY})
|
||||
SET(HAVE_LIBGCC 1)
|
||||
ENDIF(LIBGCC_FOUND)
|
23
build/cmake/FindNettle.cmake
Normal file
23
build/cmake/FindNettle.cmake
Normal file
@ -0,0 +1,23 @@
|
||||
# - Find Nettle
|
||||
# Find the Nettle include directory and library
|
||||
#
|
||||
# NETTLE_INCLUDE_DIR - where to find <nettle/sha.h>, etc.
|
||||
# NETTLE_LIBRARIES - List of libraries when using libnettle.
|
||||
# NETTLE_FOUND - True if libnettle found.
|
||||
|
||||
IF (NETTLE_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
SET(NETTLE_FIND_QUIETLY TRUE)
|
||||
ENDIF (NETTLE_INCLUDE_DIR)
|
||||
|
||||
FIND_PATH(NETTLE_INCLUDE_DIR nettle/md5.h nettle/ripemd160.h nettle/sha.h)
|
||||
FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle libnettle)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set NETTLE_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(NETTLE DEFAULT_MSG NETTLE_LIBRARY NETTLE_INCLUDE_DIR)
|
||||
|
||||
IF(NETTLE_FOUND)
|
||||
SET(NETTLE_LIBRARIES ${NETTLE_LIBRARY})
|
||||
ENDIF(NETTLE_FOUND)
|
34
build/cmake/FindPCREPOSIX.cmake
Normal file
34
build/cmake/FindPCREPOSIX.cmake
Normal file
@ -0,0 +1,34 @@
|
||||
# - Find pcreposix
|
||||
# Find the native PCRE and PCREPOSIX include and libraries
|
||||
#
|
||||
# PCRE_INCLUDE_DIR - where to find pcreposix.h, etc.
|
||||
# PCREPOSIX_LIBRARIES - List of libraries when using libpcreposix.
|
||||
# PCRE_LIBRARIES - List of libraries when using libpcre.
|
||||
# PCREPOSIX_FOUND - True if libpcreposix found.
|
||||
# PCRE_FOUND - True if libpcre found.
|
||||
|
||||
IF (PCRE_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
SET(PCRE_FIND_QUIETLY TRUE)
|
||||
ENDIF (PCRE_INCLUDE_DIR)
|
||||
|
||||
FIND_PATH(PCRE_INCLUDE_DIR pcreposix.h)
|
||||
FIND_LIBRARY(PCREPOSIX_LIBRARY NAMES pcreposix libpcreposix)
|
||||
FIND_LIBRARY(PCRE_LIBRARY NAMES pcre libpcre)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set PCREPOSIX_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCREPOSIX DEFAULT_MSG PCREPOSIX_LIBRARY PCRE_INCLUDE_DIR)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY)
|
||||
|
||||
IF(PCREPOSIX_FOUND)
|
||||
SET(PCREPOSIX_LIBRARIES ${PCREPOSIX_LIBRARY})
|
||||
SET(HAVE_LIBPCREPOSIX 1)
|
||||
SET(HAVE_PCREPOSIX_H 1)
|
||||
ENDIF(PCREPOSIX_FOUND)
|
||||
|
||||
IF(PCRE_FOUND)
|
||||
SET(PCRE_LIBRARIES ${PCRE_LIBRARY})
|
||||
SET(HAVE_LIBPCRE 1)
|
||||
ENDIF(PCRE_FOUND)
|
106
build/cmake/LibarchiveCheckCSourceCompiles.cmake
Normal file
106
build/cmake/LibarchiveCheckCSourceCompiles.cmake
Normal file
@ -0,0 +1,106 @@
|
||||
# - 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()
|
||||
|
102
build/cmake/LibarchiveCheckCSourceRuns.cmake
Normal file
102
build/cmake/LibarchiveCheckCSourceRuns.cmake
Normal file
@ -0,0 +1,102 @@
|
||||
# - 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()
|
||||
|
@ -390,6 +390,9 @@ typedef uint64_t uintmax_t;
|
||||
*/
|
||||
#cmakedefine HAVE_DIRENT_H 1
|
||||
|
||||
/* Define to 1 if you have the `dirfd' function. */
|
||||
#cmakedefine HAVE_DIRFD 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#cmakedefine HAVE_DLFCN_H 1
|
||||
|
||||
@ -576,12 +579,27 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the `expat' library (-lexpat). */
|
||||
#cmakedefine HAVE_LIBEXPAT 1
|
||||
|
||||
/* Define to 1 if you have the `gcc' library (-lgcc). */
|
||||
#cmakedefine HAVE_LIBGCC 1
|
||||
|
||||
/* Define to 1 if you have the `lzma' library (-llzma). */
|
||||
#cmakedefine HAVE_LIBLZMA 1
|
||||
|
||||
/* Define to 1 if you have the `lzmadec' library (-llzmadec). */
|
||||
#cmakedefine HAVE_LIBLZMADEC 1
|
||||
|
||||
/* Define to 1 if you have the `lzo2' library (-llzo2). */
|
||||
#cmakedefine HAVE_LIBLZO2 1
|
||||
|
||||
/* Define to 1 if you have the `nettle' library (-lnettle). */
|
||||
#cmakedefine HAVE_LIBNETTLE 1
|
||||
|
||||
/* Define to 1 if you have the `pcre' library (-lpcre). */
|
||||
#cmakedefine HAVE_LIBPCRE 1
|
||||
|
||||
/* Define to 1 if you have the `pcreposix' library (-lpcreposix). */
|
||||
#cmakedefine HAVE_LIBPCREPOSIX 1
|
||||
|
||||
/* Define to 1 if you have the `xml2' library (-lxml2). */
|
||||
#cmakedefine HAVE_LIBXML2 1
|
||||
|
||||
@ -661,6 +679,12 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the <lzma.h> header file. */
|
||||
#cmakedefine HAVE_LZMA_H 1
|
||||
|
||||
/* Define to 1 if you have the <lzo/lzo1x.h> header file. */
|
||||
#cmakedefine HAVE_LZO_LZO1X_H 1
|
||||
|
||||
/* Define to 1 if you have the <lzo/lzoconf.h> header file. */
|
||||
#cmakedefine HAVE_LZO_LZOCONF_H 1
|
||||
|
||||
/* Define to 1 if you have the `mbrtowc' function. */
|
||||
#cmakedefine HAVE_MBRTOWC 1
|
||||
|
||||
@ -685,6 +709,15 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
#cmakedefine HAVE_NDIR_H 1
|
||||
|
||||
/* Define to 1 if you have the <nettle/md5.h> header file. */
|
||||
#cmakedefine HAVE_NETTLE_MD5_H 1
|
||||
|
||||
/* Define to 1 if you have the <nettle/ripemd160.h> header file. */
|
||||
#cmakedefine HAVE_NETTLE_RIPEMD160_H 1
|
||||
|
||||
/* Define to 1 if you have the <nettle/sha.h> header file. */
|
||||
#cmakedefine HAVE_NETTLE_SHA_H 1
|
||||
|
||||
/* Define to 1 if you have the `nl_langinfo' function. */
|
||||
#cmakedefine HAVE_NL_LANGINFO 1
|
||||
|
||||
@ -694,6 +727,9 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the <paths.h> header file. */
|
||||
#cmakedefine HAVE_PATHS_H 1
|
||||
|
||||
/* Define to 1 if you have the <pcreposix.h> header file. */
|
||||
#cmakedefine HAVE_PCREPOSIX_H 1
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
#cmakedefine HAVE_PIPE 1
|
||||
|
||||
@ -703,6 +739,9 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#cmakedefine HAVE_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the `posix_spawnp' function. */
|
||||
#cmakedefine HAVE_POSIX_SPAWNP 1
|
||||
|
||||
/* Define to 1 if you have the <process.h> header file. */
|
||||
#cmakedefine HAVE_PROCESS_H 1
|
||||
|
||||
@ -736,6 +775,9 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the <signal.h> header file. */
|
||||
#cmakedefine HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define to 1 if you have the <spawn.h> header file. */
|
||||
#cmakedefine HAVE_SPAWN_H 1
|
||||
|
||||
/* Define to 1 if you have the `statfs' function. */
|
||||
#cmakedefine HAVE_STATFS 1
|
||||
|
||||
|
@ -46,6 +46,7 @@ rm -rf _cmtest
|
||||
#
|
||||
# Construct and verify the autoconf build system
|
||||
#
|
||||
export MAKE_LIBARCHIVE_RELEASE="1"
|
||||
/bin/sh build/autogen.sh
|
||||
|
||||
# Get the newest config.guess/config.sub from savannah.gnu.org
|
||||
|
@ -1 +1 @@
|
||||
3000004
|
||||
3001002
|
||||
|
264
configure.ac
264
configure.ac
@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front.
|
||||
dnl In particular, this allows the version macro to be used in AC_INIT
|
||||
|
||||
dnl These first two version numbers are updated automatically on each release.
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.0.4])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3000004])
|
||||
m4_define([LIBARCHIVE_VERSION_S],[3.1.2])
|
||||
m4_define([LIBARCHIVE_VERSION_N],[3001002])
|
||||
|
||||
dnl bsdtar and bsdcpio versioning tracks libarchive
|
||||
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
|
||||
@ -26,6 +26,7 @@ AC_CONFIG_AUX_DIR([build/autoconf])
|
||||
AC_CONFIG_MACRO_DIR([build/autoconf])
|
||||
# Must follow AC_CONFIG macros above...
|
||||
AM_INIT_AUTOMAKE()
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
# Libtool's "interface version" can be computed from the libarchive version.
|
||||
|
||||
@ -36,8 +37,8 @@ ARCHIVE_MINOR=$(( (LIBARCHIVE_VERSION_N() / 1000) % 1000 ))
|
||||
# Libarchive 2.8 == libtool interface 10 = 2 + 8
|
||||
# Libarchive 2.9 == libtool interface 11 = 2 + 8
|
||||
# Libarchive 3.0 == libtool interface 12
|
||||
# Libarchive 3.x == libtool interface 12 + x
|
||||
ARCHIVE_INTERFACE=`echo $((12 + ${ARCHIVE_MINOR}))`
|
||||
# Libarchive 3.1 == libtool interface 13
|
||||
ARCHIVE_INTERFACE=`echo $((13 + ${ARCHIVE_MINOR}))`
|
||||
# Libarchive revision is bumped on any source change === libtool revision
|
||||
ARCHIVE_REVISION=$(( LIBARCHIVE_VERSION_N() % 1000 ))
|
||||
# Libarchive minor is bumped on any interface addition === libtool age
|
||||
@ -217,10 +218,10 @@ AS_VAR_IF([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes],
|
||||
|
||||
AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h])
|
||||
AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h linux/types.h])
|
||||
AC_CHECK_HEADERS([locale.h paths.h poll.h pwd.h regex.h signal.h stdarg.h])
|
||||
AC_CHECK_HEADERS([stdint.h stdlib.h string.h])
|
||||
AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h sys/ioctl.h])
|
||||
AC_CHECK_HEADERS([sys/mkdev.h sys/mount.h])
|
||||
AC_CHECK_HEADERS([locale.h paths.h poll.h pwd.h signal.h spawn.h])
|
||||
AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h])
|
||||
AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h])
|
||||
AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h])
|
||||
AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/statfs.h sys/statvfs.h])
|
||||
AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h])
|
||||
AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h])
|
||||
@ -246,7 +247,29 @@ AC_ARG_WITH([bz2lib],
|
||||
|
||||
if test "x$with_bz2lib" != "xno"; then
|
||||
AC_CHECK_HEADERS([bzlib.h])
|
||||
AC_CHECK_LIB(bz2,BZ2_bzDecompressInit)
|
||||
case "$host_os" in
|
||||
*mingw* | *cygwin*)
|
||||
dnl AC_CHECK_LIB cannot be used on the Windows port of libbz2, therefore
|
||||
dnl use AC_LINK_IFELSE.
|
||||
AC_MSG_CHECKING([for BZ2_bzDecompressInit in -lbz2])
|
||||
old_LIBS="$LIBS"
|
||||
LIBS="-lbz2 $LIBS"
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_SOURCE(#include <bzlib.h>
|
||||
int main() { return BZ2_bzDecompressInit(NULL, 0, 0); })],
|
||||
[ac_cv_lib_bz2_BZ2_bzDecompressInit=yes],
|
||||
[ac_cv_lib_bz2_BZ2_bzDecompressInit=no])
|
||||
LIBS="$old_LIBS"
|
||||
AC_MSG_RESULT($ac_cv_lib_bz2_BZ2_bzDecompressInit)
|
||||
if test "x$ac_cv_lib_bz2_BZ2_bzDecompressInit" = xyes; then
|
||||
AC_DEFINE([HAVE_LIBBZ2], [1], [Define to 1 if you have the `bz2' library (-lbz2).])
|
||||
LIBS="-lbz2 $LIBS"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_LIB(bz2,BZ2_bzDecompressInit)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([lzmadec],
|
||||
@ -284,6 +307,14 @@ if test "x$with_lzma" != "xno"; then
|
||||
AC_CHECK_LIB(lzma,lzma_stream_decoder)
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([lzo2],
|
||||
AS_HELP_STRING([--without-lzo2], [Don't build support for lzop through liblzo2]))
|
||||
|
||||
if test "x$with_lzo2" != "xno"; then
|
||||
AC_CHECK_HEADERS([lzo/lzoconf.h lzo/lzo1x.h])
|
||||
AC_CHECK_LIB(lzo2,lzo1x_decompress_safe)
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([nettle],
|
||||
AS_HELP_STRING([--without-nettle], [Don't build with crypto support from Nettle]))
|
||||
AC_ARG_WITH([openssl],
|
||||
@ -315,12 +346,61 @@ if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([libregex],
|
||||
AS_HELP_STRING([--without-libregex], [Don't build support for regex through libregex]))
|
||||
AC_ARG_ENABLE([posix-regex-lib],
|
||||
[AS_HELP_STRING([--enable-posix-regex-lib],
|
||||
[choose what library to use for POSIX regular expression support (default: auto)])
|
||||
AS_HELP_STRING([--enable-posix-regex-lib=libc], [use libc POSIX regular expression support])
|
||||
AS_HELP_STRING([--enable-posix-regex-lib=libregex], [use libregex POSIX regular expression support])
|
||||
AS_HELP_STRING([--enable-posix-regex-lib=libpcreposix], [use libpcreposix POSIX regular expression support])
|
||||
AS_HELP_STRING([--disable-posix-regex-lib], [don't enable POSIX regular expression support])],
|
||||
[], [enable_posix_regex_lib=auto])
|
||||
|
||||
if test "x$with_libregex" != "xno"; then
|
||||
posix_regex_lib_found=
|
||||
if test "$enable_posix_regex_lib" = "auto" || test "$enable_posix_regex_lib" = "libc" || test "$enable_posix_regex_lib" = "libregex"; then
|
||||
AC_CHECK_HEADERS([regex.h])
|
||||
if test "x$ac_cv_header_regex_h" != "xno"; then
|
||||
AC_CHECK_FUNC(regcomp, , [AC_CHECK_LIB(regex,regcomp)])
|
||||
AC_CHECK_FUNC(regcomp)
|
||||
if test "x$ac_cv_func_regcomp" = xyes; then
|
||||
posix_regex_lib_found=1
|
||||
else
|
||||
AC_CHECK_LIB(regex,regcomp)
|
||||
if test "x$ac_cv_lib_regex_regcomp" = xyes; then
|
||||
posix_regex_lib_found=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test -z $posix_regex_lib_found && (test "$enable_posix_regex_lib" = "auto" || test "$enable_posix_regex_lib" = "libpcreposix"); then
|
||||
AC_CHECK_HEADERS([pcreposix.h])
|
||||
AC_CHECK_LIB(pcreposix,regcomp)
|
||||
if test "x$ac_cv_lib_pcreposix_regcomp" != xyes; then
|
||||
AC_MSG_NOTICE(trying libpcreposix check again with libpcre)
|
||||
unset ac_cv_lib_pcreposix_regcomp
|
||||
AC_CHECK_LIB(pcre,pcre_exec)
|
||||
AC_CHECK_LIB(pcreposix,regcomp)
|
||||
if test "x$ac_cv_lib_pcre_pcre_exec" = xyes && test "x$ac_cv_lib_pcreposix_regcomp" = xyes; then
|
||||
AC_MSG_CHECKING(if PCRE_STATIC needs to be defined)
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_SOURCE(#include <pcreposix.h>
|
||||
int main() { return regcomp(NULL, NULL, 0); })],
|
||||
[without_pcre_static=yes],
|
||||
[without_pcre_static=no])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_SOURCE(#define PCRE_STATIC
|
||||
#include <pcreposix.h>
|
||||
int main() { return regcomp(NULL, NULL, 0); })],
|
||||
[with_pcre_static=yes],
|
||||
[with_pcre_static=no])
|
||||
if test "x$without_pcre_static" != xyes && test "x$with_pcre_static" = xyes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([PCRE_STATIC], [1], [Define to 1 if PCRE_STATIC needs to be defined.])
|
||||
elif test "x$without_pcre_static" = xyes || test "x$with_pcre_static" = xyes; then
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
posix_regex_lib_found=1
|
||||
fi
|
||||
else
|
||||
posix_regex_lib_found=1
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -432,7 +512,7 @@ AC_FUNC_VPRINTF
|
||||
# To avoid necessity for including windows.h or special forward declaration
|
||||
# workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *'
|
||||
AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *])
|
||||
AC_CHECK_FUNCS([chflags chown chroot ctime_r])
|
||||
AC_CHECK_FUNCS([chflags chown chroot ctime_r dirfd])
|
||||
AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fork])
|
||||
AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate])
|
||||
AC_CHECK_FUNCS([futimens futimes futimesat])
|
||||
@ -441,7 +521,7 @@ AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r])
|
||||
AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat lutimes])
|
||||
AC_CHECK_FUNCS([mbrtowc memmove memset])
|
||||
AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp])
|
||||
AC_CHECK_FUNCS([nl_langinfo openat pipe poll readlink readlinkat])
|
||||
AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawnp readlink readlinkat])
|
||||
AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs])
|
||||
AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm])
|
||||
AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork])
|
||||
@ -553,10 +633,8 @@ AC_SYS_LARGEFILE
|
||||
dnl NOTE: Crypto checks must run last.
|
||||
AC_DEFUN([CRYPTO_CHECK], [
|
||||
if test "$found_$1" != yes; then
|
||||
saved_LIBS="$LIBS"
|
||||
saved_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive"
|
||||
LIBS="$LIBS $mdLIBS $4"
|
||||
touch "check_crypto_md.h"
|
||||
AC_MSG_CHECKING([support for ARCHIVE_CRYPTO_$1_$2])
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
@ -578,63 +656,133 @@ main(int argc, char **argv)
|
||||
])],
|
||||
[ AC_MSG_RESULT([yes])
|
||||
found_$1=yes
|
||||
if [[ -n "$4" ]]; then
|
||||
# The .$4 avoids -e, which doesn't work on Solaris 10
|
||||
# The _$mdLIBS allows .$4 to match at beginning of string <sigh>
|
||||
test -n "$(echo _$mdLIBS | $GREP .$4)" || mdLIBS="$mdLIBS $4"
|
||||
fi
|
||||
found_$2=yes
|
||||
AC_DEFINE(ARCHIVE_CRYPTO_$1_$2, 1, [ $1 via ARCHIVE_CRYPTO_$1_$2 supported.])
|
||||
],
|
||||
[ AC_MSG_RESULT([no])])
|
||||
LIBS="$saved_LIBS"
|
||||
CPPFLAGS="$saved_CPPFLAGS"
|
||||
rm "check_crypto_md.h"
|
||||
fi
|
||||
])
|
||||
|
||||
CRYPTO_CHECK(MD5, LIBC, md5)
|
||||
CRYPTO_CHECK(MD5, LIBSYSTEM, md5)
|
||||
CRYPTO_CHECK(RMD160, LIBC, rmd160)
|
||||
CRYPTO_CHECK(SHA1, LIBC, sha1)
|
||||
CRYPTO_CHECK(SHA1, LIBSYSTEM, sha1)
|
||||
CRYPTO_CHECK(SHA256, LIBC, sha256)
|
||||
CRYPTO_CHECK(SHA256, LIBC2, sha256)
|
||||
CRYPTO_CHECK(SHA256, LIBC3, sha256)
|
||||
CRYPTO_CHECK(SHA256, LIBSYSTEM, sha256)
|
||||
CRYPTO_CHECK(SHA384, LIBC, sha384)
|
||||
CRYPTO_CHECK(SHA384, LIBC2, sha384)
|
||||
CRYPTO_CHECK(SHA384, LIBC3, sha384)
|
||||
CRYPTO_CHECK(SHA384, LIBSYSTEM, sha384)
|
||||
CRYPTO_CHECK(SHA512, LIBC, sha512)
|
||||
CRYPTO_CHECK(SHA512, LIBC2, sha512)
|
||||
CRYPTO_CHECK(SHA512, LIBC3, sha512)
|
||||
CRYPTO_CHECK(SHA512, LIBSYSTEM, sha512)
|
||||
AC_DEFUN([CRYPTO_CHECK_WIN], [
|
||||
if test "$found_$1" != yes; then
|
||||
AC_MSG_CHECKING([support for ARCHIVE_CRYPTO_$1_WIN])
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||
#define ARCHIVE_$1_COMPILE_TEST
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
return ($2);
|
||||
}
|
||||
])],
|
||||
[ AC_MSG_RESULT([yes])
|
||||
found_$1=yes
|
||||
found_WIN=yes
|
||||
AC_DEFINE(ARCHIVE_CRYPTO_$1_WIN, 1, [ $1 via ARCHIVE_CRYPTO_$1_WIN supported.])
|
||||
],
|
||||
[ AC_MSG_RESULT([no])])
|
||||
fi
|
||||
])
|
||||
|
||||
case "$host_os" in
|
||||
*mingw* | *cygwin*)
|
||||
;;
|
||||
*)
|
||||
CRYPTO_CHECK(MD5, LIBC, md5)
|
||||
CRYPTO_CHECK(MD5, LIBSYSTEM, md5)
|
||||
CRYPTO_CHECK(RMD160, LIBC, rmd160)
|
||||
CRYPTO_CHECK(SHA1, LIBC, sha1)
|
||||
CRYPTO_CHECK(SHA1, LIBSYSTEM, sha1)
|
||||
CRYPTO_CHECK(SHA256, LIBC, sha256)
|
||||
CRYPTO_CHECK(SHA256, LIBC2, sha256)
|
||||
CRYPTO_CHECK(SHA256, LIBC3, sha256)
|
||||
CRYPTO_CHECK(SHA256, LIBSYSTEM, sha256)
|
||||
CRYPTO_CHECK(SHA384, LIBC, sha384)
|
||||
CRYPTO_CHECK(SHA384, LIBC2, sha384)
|
||||
CRYPTO_CHECK(SHA384, LIBC3, sha384)
|
||||
CRYPTO_CHECK(SHA384, LIBSYSTEM, sha384)
|
||||
CRYPTO_CHECK(SHA512, LIBC, sha512)
|
||||
CRYPTO_CHECK(SHA512, LIBC2, sha512)
|
||||
CRYPTO_CHECK(SHA512, LIBC3, sha512)
|
||||
CRYPTO_CHECK(SHA512, LIBSYSTEM, sha512)
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "x$with_nettle" != "xno"; then
|
||||
CRYPTO_CHECK(MD5, NETTLE, md5, -lnettle)
|
||||
CRYPTO_CHECK(RMD160, NETTLE, rmd160, -lnettle)
|
||||
CRYPTO_CHECK(SHA1, NETTLE, sha1, -lnettle)
|
||||
CRYPTO_CHECK(SHA256, NETTLE, sha256, -lnettle)
|
||||
CRYPTO_CHECK(SHA384, NETTLE, sha384, -lnettle)
|
||||
CRYPTO_CHECK(SHA512, NETTLE, sha512, -lnettle)
|
||||
AC_CHECK_HEADERS([nettle/md5.h nettle/ripemd160.h nettle/sha.h])
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_LIB(nettle,main)
|
||||
CRYPTO_CHECK(MD5, NETTLE, md5)
|
||||
CRYPTO_CHECK(RMD160, NETTLE, rmd160)
|
||||
CRYPTO_CHECK(SHA1, NETTLE, sha1)
|
||||
CRYPTO_CHECK(SHA256, NETTLE, sha256)
|
||||
CRYPTO_CHECK(SHA384, NETTLE, sha384)
|
||||
CRYPTO_CHECK(SHA512, NETTLE, sha512)
|
||||
if test "x$found_NETTLE" != "xyes"; then
|
||||
LIBS=$saved_LIBS
|
||||
fi
|
||||
fi
|
||||
if test "x$with_openssl" != "xno"; then
|
||||
CRYPTO_CHECK(MD5, OPENSSL, md5, -lcrypto)
|
||||
CRYPTO_CHECK(RMD160, OPENSSL, rmd160, -lcrypto)
|
||||
CRYPTO_CHECK(SHA1, OPENSSL, sha1, -lcrypto)
|
||||
CRYPTO_CHECK(SHA256, OPENSSL, sha256, -lcrypto)
|
||||
CRYPTO_CHECK(SHA384, OPENSSL, sha384, -lcrypto)
|
||||
CRYPTO_CHECK(SHA512, OPENSSL, sha512, -lcrypto)
|
||||
AC_CHECK_HEADERS([openssl/evp.h])
|
||||
saved_LIBS=$LIBS
|
||||
case "$host_os" in
|
||||
*mingw* | *cygwin*)
|
||||
case "$host_cpu" in
|
||||
x86_64)
|
||||
AC_CHECK_LIB(eay64,main)
|
||||
if test "x$ac_cv_lib_eay64_main" != "xyes"; then
|
||||
AC_CHECK_LIB(eay32,main)
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_LIB(eay32,main)
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_LIB(crypto,main)
|
||||
;;
|
||||
esac
|
||||
CRYPTO_CHECK(MD5, OPENSSL, md5)
|
||||
CRYPTO_CHECK(RMD160, OPENSSL, rmd160)
|
||||
CRYPTO_CHECK(SHA1, OPENSSL, sha1)
|
||||
CRYPTO_CHECK(SHA256, OPENSSL, sha256)
|
||||
CRYPTO_CHECK(SHA384, OPENSSL, sha384)
|
||||
CRYPTO_CHECK(SHA512, OPENSSL, sha512)
|
||||
if test "x$found_OPENSSL" != "xyes"; then
|
||||
LIBS=$saved_LIBS
|
||||
fi
|
||||
fi
|
||||
|
||||
# Probe libmd AFTER OpenSSL/libcrypto.
|
||||
# The two are incompatible and OpenSSL is more complete.
|
||||
CRYPTO_CHECK(MD5, LIBMD, md5, -lmd)
|
||||
CRYPTO_CHECK(RMD160, LIBMD, rmd160, -lmd)
|
||||
CRYPTO_CHECK(SHA1, LIBMD, sha1, -lmd)
|
||||
CRYPTO_CHECK(SHA256, LIBMD, sha256, -lmd)
|
||||
CRYPTO_CHECK(SHA512, LIBMD, sha512, -lmd)
|
||||
AC_CHECK_HEADERS([md5.h ripemd.h sha.h sha256.h sha512.h])
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_LIB(md,main)
|
||||
CRYPTO_CHECK(MD5, LIBMD, md5)
|
||||
CRYPTO_CHECK(RMD160, LIBMD, rmd160)
|
||||
CRYPTO_CHECK(SHA1, LIBMD, sha1)
|
||||
CRYPTO_CHECK(SHA256, LIBMD, sha256)
|
||||
CRYPTO_CHECK(SHA512, LIBMD, sha512)
|
||||
if test "x$found_LIBMD" != "xyes"; then
|
||||
LIBS=$saved_LIBS
|
||||
fi
|
||||
|
||||
LIBS="$LIBS $mdLIBS"
|
||||
case "$host_os" in
|
||||
*mingw* | *cygwin*)
|
||||
CRYPTO_CHECK_WIN(MD5, CALG_MD5)
|
||||
CRYPTO_CHECK_WIN(SHA1, CALG_SHA1)
|
||||
CRYPTO_CHECK_WIN(SHA256, CALG_SHA_256)
|
||||
CRYPTO_CHECK_WIN(SHA384, CALG_SHA_384)
|
||||
CRYPTO_CHECK_WIN(SHA512, CALG_SHA_512)
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_OUTPUT
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 24, 2011
|
||||
.Dd October 7, 2012
|
||||
.Dt CPIO 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -176,11 +176,21 @@ With this option, the target of the link will be archived or copied instead.
|
||||
(p mode only)
|
||||
Create links from the target directory to the original files,
|
||||
instead of copying.
|
||||
.It Fl Fl lrzip
|
||||
(o mode only)
|
||||
Compress the resulting archive with
|
||||
.Xr lrzip 1 .
|
||||
In input mode, this option is ignored.
|
||||
.It Fl Fl lzma
|
||||
(o mode only)
|
||||
Compress the file with lzma-compatible compression before writing it.
|
||||
In input mode, this option is ignored; lzma compression is recognized
|
||||
automatically on input.
|
||||
.It Fl Fl lzop
|
||||
(o mode only)
|
||||
Compress the resulting archive with
|
||||
.Xr lzop 1 .
|
||||
In input mode, this option is ignored.
|
||||
.It Fl m , Fl Fl preserve-modification-time
|
||||
(i and p modes)
|
||||
Set file modification time on created files to match
|
||||
|
@ -61,16 +61,20 @@ static const struct option {
|
||||
int required; /* 1 if this option requires an argument */
|
||||
int equivalent; /* Equivalent short option. */
|
||||
} cpio_longopts[] = {
|
||||
{ "b64encode", 0, OPTION_B64ENCODE },
|
||||
{ "create", 0, 'o' },
|
||||
{ "dot", 0, 'V' },
|
||||
{ "extract", 0, 'i' },
|
||||
{ "file", 1, 'F' },
|
||||
{ "format", 1, 'H' },
|
||||
{ "grzip", 0, OPTION_GRZIP },
|
||||
{ "help", 0, 'h' },
|
||||
{ "insecure", 0, OPTION_INSECURE },
|
||||
{ "link", 0, 'l' },
|
||||
{ "list", 0, 't' },
|
||||
{ "lrzip", 0, OPTION_LRZIP },
|
||||
{ "lzma", 0, OPTION_LZMA },
|
||||
{ "lzop", 0, OPTION_LZOP },
|
||||
{ "make-directories", 0, 'd' },
|
||||
{ "no-preserve-owner", 0, OPTION_NO_PRESERVE_OWNER },
|
||||
{ "null", 0, '0' },
|
||||
@ -81,6 +85,7 @@ static const struct option {
|
||||
{ "preserve-owner", 0, OPTION_PRESERVE_OWNER },
|
||||
{ "quiet", 0, OPTION_QUIET },
|
||||
{ "unconditional", 0, 'u' },
|
||||
{ "uuencode", 0, OPTION_UUENCODE },
|
||||
{ "verbose", 0, 'v' },
|
||||
{ "version", 0, OPTION_VERSION },
|
||||
{ "xz", 0, 'J' },
|
||||
|
79
cpio/cpio.c
79
cpio/cpio.c
@ -207,6 +207,9 @@ main(int argc, char *argv[])
|
||||
case 'B': /* POSIX 1997 */
|
||||
cpio->bytes_per_block = 5120;
|
||||
break;
|
||||
case OPTION_B64ENCODE:
|
||||
cpio->add_filter = opt;
|
||||
break;
|
||||
case 'C': /* NetBSD/OpenBSD */
|
||||
cpio->bytes_per_block = atoi(cpio->argument);
|
||||
if (cpio->bytes_per_block <= 0)
|
||||
@ -234,6 +237,9 @@ main(int argc, char *argv[])
|
||||
lafe_errc(1, 0, "Error : %s",
|
||||
archive_error_string(cpio->matching));
|
||||
break;
|
||||
case OPTION_GRZIP:
|
||||
cpio->compress = opt;
|
||||
break;
|
||||
case 'H': /* GNU cpio (also --format) */
|
||||
cpio->format = cpio->argument;
|
||||
break;
|
||||
@ -265,7 +271,9 @@ main(int argc, char *argv[])
|
||||
case 'l': /* POSIX 1997 */
|
||||
cpio->option_link = 1;
|
||||
break;
|
||||
case OPTION_LRZIP:
|
||||
case OPTION_LZMA: /* GNU tar, others */
|
||||
case OPTION_LZOP: /* GNU tar, others */
|
||||
cpio->compress = opt;
|
||||
break;
|
||||
case 'm': /* POSIX 1997 */
|
||||
@ -326,6 +334,9 @@ main(int argc, char *argv[])
|
||||
cpio->extract_flags
|
||||
&= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
|
||||
break;
|
||||
case OPTION_UUENCODE:
|
||||
cpio->add_filter = opt;
|
||||
break;
|
||||
case 'v': /* POSIX 1997 */
|
||||
cpio->verbose++;
|
||||
break;
|
||||
@ -417,6 +428,7 @@ main(int argc, char *argv[])
|
||||
archive_match_free(cpio->matching);
|
||||
free_cache(cpio->gname_cache);
|
||||
free_cache(cpio->uname_cache);
|
||||
free(cpio->destdir);
|
||||
return (cpio->return_value);
|
||||
}
|
||||
|
||||
@ -516,27 +528,49 @@ mode_out(struct cpio *cpio)
|
||||
if (cpio->archive == NULL)
|
||||
lafe_errc(1, 0, "Failed to allocate archive object");
|
||||
switch (cpio->compress) {
|
||||
case OPTION_GRZIP:
|
||||
r = archive_write_add_filter_grzip(cpio->archive);
|
||||
break;
|
||||
case 'J':
|
||||
r = archive_write_set_compression_xz(cpio->archive);
|
||||
r = archive_write_add_filter_xz(cpio->archive);
|
||||
break;
|
||||
case OPTION_LRZIP:
|
||||
r = archive_write_add_filter_lrzip(cpio->archive);
|
||||
break;
|
||||
case OPTION_LZMA:
|
||||
r = archive_write_set_compression_lzma(cpio->archive);
|
||||
r = archive_write_add_filter_lzma(cpio->archive);
|
||||
break;
|
||||
case OPTION_LZOP:
|
||||
r = archive_write_add_filter_lzop(cpio->archive);
|
||||
break;
|
||||
case 'j': case 'y':
|
||||
r = archive_write_set_compression_bzip2(cpio->archive);
|
||||
r = archive_write_add_filter_bzip2(cpio->archive);
|
||||
break;
|
||||
case 'z':
|
||||
r = archive_write_set_compression_gzip(cpio->archive);
|
||||
r = archive_write_add_filter_gzip(cpio->archive);
|
||||
break;
|
||||
case 'Z':
|
||||
r = archive_write_set_compression_compress(cpio->archive);
|
||||
r = archive_write_add_filter_compress(cpio->archive);
|
||||
break;
|
||||
default:
|
||||
r = archive_write_set_compression_none(cpio->archive);
|
||||
r = archive_write_add_filter_none(cpio->archive);
|
||||
break;
|
||||
}
|
||||
if (r < ARCHIVE_WARN)
|
||||
lafe_errc(1, 0, "Requested compression not available");
|
||||
switch (cpio->add_filter) {
|
||||
case 0:
|
||||
r = ARCHIVE_OK;
|
||||
break;
|
||||
case OPTION_B64ENCODE:
|
||||
r = archive_write_add_filter_b64encode(cpio->archive);
|
||||
break;
|
||||
case OPTION_UUENCODE:
|
||||
r = archive_write_add_filter_uuencode(cpio->archive);
|
||||
break;
|
||||
}
|
||||
if (r < ARCHIVE_WARN)
|
||||
lafe_errc(1, 0, "Requested filter not available");
|
||||
r = archive_write_set_format_by_name(cpio->archive, cpio->format);
|
||||
if (r != ARCHIVE_OK)
|
||||
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
@ -548,7 +582,7 @@ mode_out(struct cpio *cpio)
|
||||
/*
|
||||
* The main loop: Copy each file into the output archive.
|
||||
*/
|
||||
r = archive_write_open_file(cpio->archive, cpio->filename);
|
||||
r = archive_write_open_filename(cpio->archive, cpio->filename);
|
||||
if (r != ARCHIVE_OK)
|
||||
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||
lr = lafe_line_reader("-", cpio->option_null);
|
||||
@ -577,7 +611,7 @@ mode_out(struct cpio *cpio)
|
||||
|
||||
if (!cpio->quiet) {
|
||||
int64_t blocks =
|
||||
(archive_position_uncompressed(cpio->archive) + 511)
|
||||
(archive_filter_bytes(cpio->archive, 0) + 511)
|
||||
/ 512;
|
||||
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
|
||||
blocks == 1 ? "block" : "blocks");
|
||||
@ -806,18 +840,21 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
|
||||
exit(1);
|
||||
|
||||
if (r >= ARCHIVE_WARN && archive_entry_size(entry) > 0 && fd >= 0) {
|
||||
bytes_read = read(fd, cpio->buff, cpio->buff_size);
|
||||
bytes_read = read(fd, cpio->buff, (unsigned)cpio->buff_size);
|
||||
while (bytes_read > 0) {
|
||||
r = archive_write_data(cpio->archive,
|
||||
ssize_t bytes_write;
|
||||
bytes_write = archive_write_data(cpio->archive,
|
||||
cpio->buff, bytes_read);
|
||||
if (r < 0)
|
||||
if (bytes_write < 0)
|
||||
lafe_errc(1, archive_errno(cpio->archive),
|
||||
"%s", archive_error_string(cpio->archive));
|
||||
if (r < bytes_read) {
|
||||
if (bytes_write < bytes_read) {
|
||||
lafe_warnc(0,
|
||||
"Truncated write; file may have grown while being archived.");
|
||||
"Truncated write; file may have "
|
||||
"grown while being archived.");
|
||||
}
|
||||
bytes_read = read(fd, cpio->buff, cpio->buff_size);
|
||||
bytes_read = read(fd, cpio->buff,
|
||||
(unsigned)cpio->buff_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -908,7 +945,8 @@ mode_in(struct cpio *cpio)
|
||||
archive_read_support_filter_all(a);
|
||||
archive_read_support_format_all(a);
|
||||
|
||||
if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
|
||||
if (archive_read_open_filename(a, cpio->filename,
|
||||
cpio->bytes_per_block))
|
||||
lafe_errc(1, archive_errno(a),
|
||||
"%s", archive_error_string(a));
|
||||
for (;;) {
|
||||
@ -957,7 +995,7 @@ mode_in(struct cpio *cpio)
|
||||
if (r != ARCHIVE_OK)
|
||||
lafe_errc(1, 0, "%s", archive_error_string(ext));
|
||||
if (!cpio->quiet) {
|
||||
int64_t blocks = (archive_position_uncompressed(a) + 511)
|
||||
int64_t blocks = (archive_filter_bytes(a, 0) + 511)
|
||||
/ 512;
|
||||
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
|
||||
blocks == 1 ? "block" : "blocks");
|
||||
@ -988,7 +1026,7 @@ extract_data(struct archive *ar, struct archive *aw)
|
||||
"%s", archive_error_string(ar));
|
||||
exit(1);
|
||||
}
|
||||
r = archive_write_data_block(aw, block, size, offset);
|
||||
r = (int)archive_write_data_block(aw, block, size, offset);
|
||||
if (r != ARCHIVE_OK) {
|
||||
lafe_warnc(archive_errno(aw),
|
||||
"%s", archive_error_string(aw));
|
||||
@ -1010,7 +1048,8 @@ mode_list(struct cpio *cpio)
|
||||
archive_read_support_filter_all(a);
|
||||
archive_read_support_format_all(a);
|
||||
|
||||
if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
|
||||
if (archive_read_open_filename(a, cpio->filename,
|
||||
cpio->bytes_per_block))
|
||||
lafe_errc(1, archive_errno(a),
|
||||
"%s", archive_error_string(a));
|
||||
for (;;) {
|
||||
@ -1032,7 +1071,7 @@ mode_list(struct cpio *cpio)
|
||||
if (r != ARCHIVE_OK)
|
||||
lafe_errc(1, 0, "%s", archive_error_string(a));
|
||||
if (!cpio->quiet) {
|
||||
int64_t blocks = (archive_position_uncompressed(a) + 511)
|
||||
int64_t blocks = (archive_filter_bytes(a, 0) + 511)
|
||||
/ 512;
|
||||
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
|
||||
blocks == 1 ? "block" : "blocks");
|
||||
@ -1167,7 +1206,7 @@ mode_pass(struct cpio *cpio, const char *destdir)
|
||||
|
||||
if (!cpio->quiet) {
|
||||
int64_t blocks =
|
||||
(archive_position_uncompressed(cpio->archive) + 511)
|
||||
(archive_filter_bytes(cpio->archive, 0) + 511)
|
||||
/ 512;
|
||||
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
|
||||
blocks == 1 ? "block" : "blocks");
|
||||
|
@ -44,6 +44,7 @@ struct cpio {
|
||||
const char *argument;
|
||||
|
||||
/* Options */
|
||||
int add_filter; /* --uuencode */
|
||||
const char *filename;
|
||||
int mode; /* -i -o -p */
|
||||
int compress; /* -j, -y, or -z */
|
||||
@ -96,11 +97,16 @@ const char *owner_parse(const char *, int *, int *);
|
||||
|
||||
/* Fake short equivalents for long options that otherwise lack them. */
|
||||
enum {
|
||||
OPTION_INSECURE = 1,
|
||||
OPTION_B64ENCODE = 1,
|
||||
OPTION_GRZIP,
|
||||
OPTION_INSECURE,
|
||||
OPTION_LRZIP,
|
||||
OPTION_LZMA,
|
||||
OPTION_LZOP,
|
||||
OPTION_NO_PRESERVE_OWNER,
|
||||
OPTION_PRESERVE_OWNER,
|
||||
OPTION_QUIET,
|
||||
OPTION_UUENCODE,
|
||||
OPTION_VERSION
|
||||
};
|
||||
|
||||
|
@ -7,11 +7,21 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
|
||||
SET(bsdcpio_test_SOURCES
|
||||
../cmdline.c
|
||||
../../libarchive_fe/err.c
|
||||
../../test_utils/test_utils.c
|
||||
main.c
|
||||
test.h
|
||||
test_0.c
|
||||
test_basic.c
|
||||
test_cmdline.c
|
||||
test_extract_cpio_Z
|
||||
test_extract_cpio_bz2
|
||||
test_extract_cpio_grz
|
||||
test_extract_cpio_gz
|
||||
test_extract_cpio_lrz
|
||||
test_extract_cpio_lz
|
||||
test_extract_cpio_lzma
|
||||
test_extract_cpio_lzo
|
||||
test_extract_cpio_xz
|
||||
test_format_newc.c
|
||||
test_gcpio_compat.c
|
||||
test_option_0.c
|
||||
@ -21,16 +31,22 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
|
||||
test_option_L_upper.c
|
||||
test_option_Z_upper.c
|
||||
test_option_a.c
|
||||
test_option_b64encode.c
|
||||
test_option_c.c
|
||||
test_option_d.c
|
||||
test_option_f.c
|
||||
test_option_grzip.c
|
||||
test_option_help.c
|
||||
test_option_l.c
|
||||
test_option_lrzip.c
|
||||
test_option_lzma.c
|
||||
test_option_lzop.c
|
||||
test_option_m.c
|
||||
test_option_t.c
|
||||
test_option_u.c
|
||||
test_option_uuencode.c
|
||||
test_option_version.c
|
||||
test_option_xz.c
|
||||
test_option_y.c
|
||||
test_option_z.c
|
||||
test_owner_parse.c
|
||||
@ -65,6 +81,8 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
|
||||
ENDMACRO (DEFINE_TEST _testname)
|
||||
|
||||
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/test_utils)
|
||||
|
||||
# Experimental new test handling
|
||||
ADD_CUSTOM_TARGET(run_bsdcpio_test
|
||||
|
245
cpio/test/main.c
245
cpio/test/main.c
@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
#include "test_utils.h"
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
@ -91,6 +92,7 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/test/main.c,v 1.3 2008/08/24 04:58:22 kient
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#ifndef F_OK
|
||||
#define F_OK (0)
|
||||
@ -389,7 +391,6 @@ failure_finish(void *extra)
|
||||
fprintf(stderr,
|
||||
" *** forcing core dump so failure can be debugged ***\n");
|
||||
abort();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -622,8 +623,8 @@ assertion_equal_string(const char *file, int line,
|
||||
if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0))
|
||||
return (1);
|
||||
failure_start(file, line, "%s != %s", e1, e2);
|
||||
l1 = strlen(e1);
|
||||
l2 = strlen(e2);
|
||||
l1 = (int)strlen(e1);
|
||||
l2 = (int)strlen(e2);
|
||||
if (l1 < l2)
|
||||
l1 = l2;
|
||||
strdump(e1, v1, l1, utf8);
|
||||
@ -746,6 +747,8 @@ assertion_equal_mem(const char *file, int line,
|
||||
assertion_count(file, line);
|
||||
if (v1 == v2 || (v1 != NULL && v2 != NULL && memcmp(v1, v2, l) == 0))
|
||||
return (1);
|
||||
if (v1 == NULL || v2 == NULL)
|
||||
return (0);
|
||||
|
||||
failure_start(file, line, "%s != %s", e1, e2);
|
||||
logprintf(" size %s = %d\n", ld, (int)l);
|
||||
@ -839,9 +842,14 @@ assertion_equal_file(const char *filename, int line, const char *fn1, const char
|
||||
|
||||
f1 = fopen(fn1, "rb");
|
||||
f2 = fopen(fn2, "rb");
|
||||
if (f1 == NULL || f2 == NULL) {
|
||||
if (f1) fclose(f1);
|
||||
if (f2) fclose(f2);
|
||||
return (0);
|
||||
}
|
||||
for (;;) {
|
||||
n1 = fread(buff1, 1, sizeof(buff1), f1);
|
||||
n2 = fread(buff2, 1, sizeof(buff2), f2);
|
||||
n1 = (int)fread(buff1, 1, sizeof(buff1), f1);
|
||||
n2 = (int)fread(buff2, 1, sizeof(buff2), f2);
|
||||
if (n1 != n2)
|
||||
break;
|
||||
if (n1 == 0 && n2 == 0) {
|
||||
@ -915,7 +923,7 @@ assertion_file_contents(const char *filename, int line, const void *buff, int s,
|
||||
return (0);
|
||||
}
|
||||
contents = malloc(s * 2);
|
||||
n = fread(contents, 1, s * 2, f);
|
||||
n = (int)fread(contents, 1, s * 2, f);
|
||||
fclose(f);
|
||||
if (n == s && memcmp(buff, contents, s) == 0) {
|
||||
free(contents);
|
||||
@ -951,9 +959,9 @@ assertion_text_file_contents(const char *filename, int line, const char *buff, c
|
||||
failure_finish(NULL);
|
||||
return (0);
|
||||
}
|
||||
s = strlen(buff);
|
||||
s = (int)strlen(buff);
|
||||
contents = malloc(s * 2 + 128);
|
||||
n = fread(contents, 1, s * 2 + 128 - 1, f);
|
||||
n = (int)fread(contents, 1, s * 2 + 128 - 1, f);
|
||||
if (n >= 0)
|
||||
contents[n] = '\0';
|
||||
fclose(f);
|
||||
@ -1004,8 +1012,8 @@ assertion_file_contains_lines_any_order(const char *file, int line,
|
||||
char *buff;
|
||||
size_t buff_size;
|
||||
size_t expected_count, actual_count, i, j;
|
||||
char **expected;
|
||||
char *p, **actual;
|
||||
char **expected = NULL;
|
||||
char *p, **actual = NULL;
|
||||
char c;
|
||||
int expected_failure = 0, actual_failure = 0;
|
||||
|
||||
@ -1018,14 +1026,21 @@ assertion_file_contains_lines_any_order(const char *file, int line,
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Make a copy of the provided lines and count up the expected file size. */
|
||||
expected_count = 0;
|
||||
/* Make a copy of the provided lines and count up the expected
|
||||
* file size. */
|
||||
for (i = 0; lines[i] != NULL; ++i) {
|
||||
}
|
||||
expected_count = i;
|
||||
expected = malloc(sizeof(char *) * expected_count);
|
||||
for (i = 0; lines[i] != NULL; ++i) {
|
||||
expected[i] = strdup(lines[i]);
|
||||
if (expected_count) {
|
||||
expected = malloc(sizeof(char *) * expected_count);
|
||||
if (expected == NULL) {
|
||||
failure_start(pathname, line, "Can't allocate memory");
|
||||
failure_finish(NULL);
|
||||
return (0);
|
||||
}
|
||||
for (i = 0; lines[i] != NULL; ++i) {
|
||||
expected[i] = strdup(lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Break the file into lines */
|
||||
@ -1037,11 +1052,19 @@ assertion_file_contains_lines_any_order(const char *file, int line,
|
||||
++actual_count;
|
||||
c = *p;
|
||||
}
|
||||
actual = malloc(sizeof(char *) * actual_count);
|
||||
for (j = 0, p = buff; p < buff + buff_size; p += 1 + strlen(p)) {
|
||||
if (*p != '\0') {
|
||||
actual[j] = p;
|
||||
++j;
|
||||
if (actual_count) {
|
||||
actual = calloc(sizeof(char *), actual_count);
|
||||
if (actual == NULL) {
|
||||
failure_start(pathname, line, "Can't allocate memory");
|
||||
failure_finish(NULL);
|
||||
free(expected);
|
||||
return (0);
|
||||
}
|
||||
for (j = 0, p = buff; p < buff + buff_size; p += 1 + strlen(p)) {
|
||||
if (*p != '\0') {
|
||||
actual[j] = p;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1176,11 +1199,11 @@ assertion_file_time(const char *file, int line,
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#define EPOC_TIME (116444736000000000ULL)
|
||||
FILETIME ftime, fbirthtime, fatime, fmtime;
|
||||
FILETIME fxtime, fbirthtime, fatime, fmtime;
|
||||
ULARGE_INTEGER wintm;
|
||||
HANDLE h;
|
||||
ftime.dwLowDateTime = 0;
|
||||
ftime.dwHighDateTime = 0;
|
||||
fxtime.dwLowDateTime = 0;
|
||||
fxtime.dwHighDateTime = 0;
|
||||
|
||||
assertion_count(file, line);
|
||||
/* Note: FILE_FLAG_BACKUP_SEMANTICS applies to open
|
||||
@ -1195,9 +1218,9 @@ assertion_file_time(const char *file, int line,
|
||||
}
|
||||
r = GetFileTime(h, &fbirthtime, &fatime, &fmtime);
|
||||
switch (type) {
|
||||
case 'a': ftime = fatime; break;
|
||||
case 'b': ftime = fbirthtime; break;
|
||||
case 'm': ftime = fmtime; break;
|
||||
case 'a': fxtime = fatime; break;
|
||||
case 'b': fxtime = fbirthtime; break;
|
||||
case 'm': fxtime = fmtime; break;
|
||||
}
|
||||
CloseHandle(h);
|
||||
if (r == 0) {
|
||||
@ -1205,8 +1228,8 @@ assertion_file_time(const char *file, int line,
|
||||
failure_finish(NULL);
|
||||
return (0);
|
||||
}
|
||||
wintm.LowPart = ftime.dwLowDateTime;
|
||||
wintm.HighPart = ftime.dwHighDateTime;
|
||||
wintm.LowPart = fxtime.dwLowDateTime;
|
||||
wintm.HighPart = fxtime.dwHighDateTime;
|
||||
filet = (wintm.QuadPart - EPOC_TIME) / 10000000;
|
||||
filet_nsec = ((wintm.QuadPart - EPOC_TIME) % 10000000) * 100;
|
||||
nsec = (nsec / 100) * 100; /* Round the request */
|
||||
@ -1834,15 +1857,45 @@ canSymlink(void)
|
||||
return (value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this platform run the gzip program?
|
||||
*/
|
||||
/* Platform-dependent options for hiding the output of a subcommand. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
static const char *redirectArgs = ">NUL 2>NUL"; /* Win32 cmd.exe */
|
||||
#else
|
||||
static const char *redirectArgs = ">/dev/null 2>/dev/null"; /* POSIX 'sh' */
|
||||
#endif
|
||||
/*
|
||||
* Can this platform run the bzip2 program?
|
||||
*/
|
||||
int
|
||||
canBzip2(void)
|
||||
{
|
||||
static int tested = 0, value = 0;
|
||||
if (!tested) {
|
||||
tested = 1;
|
||||
if (systemf("bzip2 -d -V %s", redirectArgs) == 0)
|
||||
value = 1;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this platform run the grzip program?
|
||||
*/
|
||||
int
|
||||
canGrzip(void)
|
||||
{
|
||||
static int tested = 0, value = 0;
|
||||
if (!tested) {
|
||||
tested = 1;
|
||||
if (systemf("grzip -V %s", redirectArgs) == 0)
|
||||
value = 1;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this platform run the gzip program?
|
||||
*/
|
||||
int
|
||||
canGzip(void)
|
||||
{
|
||||
@ -1856,15 +1909,75 @@ canGzip(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this platform run the gunzip program?
|
||||
* Can this platform run the lrzip program?
|
||||
*/
|
||||
int
|
||||
canGunzip(void)
|
||||
canLrzip(void)
|
||||
{
|
||||
static int tested = 0, value = 0;
|
||||
if (!tested) {
|
||||
tested = 1;
|
||||
if (systemf("gunzip -V %s", redirectArgs) == 0)
|
||||
if (systemf("lrzip -V %s", redirectArgs) == 0)
|
||||
value = 1;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this platform run the lzip program?
|
||||
*/
|
||||
int
|
||||
canLzip(void)
|
||||
{
|
||||
static int tested = 0, value = 0;
|
||||
if (!tested) {
|
||||
tested = 1;
|
||||
if (systemf("lzip -V %s", redirectArgs) == 0)
|
||||
value = 1;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this platform run the lzma program?
|
||||
*/
|
||||
int
|
||||
canLzma(void)
|
||||
{
|
||||
static int tested = 0, value = 0;
|
||||
if (!tested) {
|
||||
tested = 1;
|
||||
if (systemf("lzma -V %s", redirectArgs) == 0)
|
||||
value = 1;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this platform run the lzop program?
|
||||
*/
|
||||
int
|
||||
canLzop(void)
|
||||
{
|
||||
static int tested = 0, value = 0;
|
||||
if (!tested) {
|
||||
tested = 1;
|
||||
if (systemf("lzop -V %s", redirectArgs) == 0)
|
||||
value = 1;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this platform run the xz program?
|
||||
*/
|
||||
int
|
||||
canXz(void)
|
||||
{
|
||||
static int tested = 0, value = 0;
|
||||
if (!tested) {
|
||||
tested = 1;
|
||||
if (systemf("xz -V %s", redirectArgs) == 0)
|
||||
value = 1;
|
||||
}
|
||||
return (value);
|
||||
@ -2124,7 +2237,7 @@ is_LargeInode(const char *file)
|
||||
/* Use "list.h" to create a list of all tests (functions and names). */
|
||||
#undef DEFINE_TEST
|
||||
#define DEFINE_TEST(n) { n, #n, 0 },
|
||||
struct { void (*func)(void); const char *name; int failures; } tests[] = {
|
||||
struct test_list_t tests[] = {
|
||||
#include "list.h"
|
||||
};
|
||||
|
||||
@ -2377,65 +2490,6 @@ get_refdir(const char *d)
|
||||
return strdup(buff);
|
||||
}
|
||||
|
||||
static int
|
||||
get_test_set(int *test_set, int limit, const char *test)
|
||||
{
|
||||
int start, end;
|
||||
int idx = 0;
|
||||
|
||||
if (test == NULL) {
|
||||
/* Default: Run all tests. */
|
||||
for (;idx < limit; idx++)
|
||||
test_set[idx] = idx;
|
||||
return (limit);
|
||||
}
|
||||
if (*test >= '0' && *test <= '9') {
|
||||
const char *vp = test;
|
||||
start = 0;
|
||||
while (*vp >= '0' && *vp <= '9') {
|
||||
start *= 10;
|
||||
start += *vp - '0';
|
||||
++vp;
|
||||
}
|
||||
if (*vp == '\0') {
|
||||
end = start;
|
||||
} else if (*vp == '-') {
|
||||
++vp;
|
||||
if (*vp == '\0') {
|
||||
end = limit - 1;
|
||||
} else {
|
||||
end = 0;
|
||||
while (*vp >= '0' && *vp <= '9') {
|
||||
end *= 10;
|
||||
end += *vp - '0';
|
||||
++vp;
|
||||
}
|
||||
}
|
||||
} else
|
||||
return (-1);
|
||||
if (start < 0 || end >= limit || start > end)
|
||||
return (-1);
|
||||
while (start <= end)
|
||||
test_set[idx++] = start++;
|
||||
} else {
|
||||
size_t len = strlen(test);
|
||||
for (start = 0; start < limit; ++start) {
|
||||
const char *name = tests[start].name;
|
||||
const char *p;
|
||||
|
||||
while ((p = strchr(name, test[0])) != NULL) {
|
||||
if (strncmp(p, test, len) == 0) {
|
||||
test_set[idx++] = start;
|
||||
break;
|
||||
} else
|
||||
name = p + 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return ((idx == 0)?-1:idx);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -2720,10 +2774,11 @@ main(int argc, char **argv)
|
||||
do {
|
||||
int test_num;
|
||||
|
||||
test_num = get_test_set(test_set, limit, *argv);
|
||||
test_num = get_test_set(test_set, limit, *argv, tests);
|
||||
if (test_num < 0) {
|
||||
printf("*** INVALID Test %s\n", *argv);
|
||||
free(refdir_alloc);
|
||||
free(testprogdir);
|
||||
usage(progname);
|
||||
return (1);
|
||||
}
|
||||
|
@ -266,11 +266,29 @@ void sleepUntilAfter(time_t);
|
||||
/* Return true if this platform can create symlinks. */
|
||||
int canSymlink(void);
|
||||
|
||||
/* Return true if this platform can run the "bzip2" program. */
|
||||
int canBzip2(void);
|
||||
|
||||
/* Return true if this platform can run the "grzip" program. */
|
||||
int canGrzip(void);
|
||||
|
||||
/* Return true if this platform can run the "gzip" program. */
|
||||
int canGzip(void);
|
||||
|
||||
/* Return true if this platform can run the "gunzip" program. */
|
||||
int canGunzip(void);
|
||||
/* Return true if this platform can run the "lrzip" program. */
|
||||
int canLrzip(void);
|
||||
|
||||
/* Return true if this platform can run the "lzip" program. */
|
||||
int canLzip(void);
|
||||
|
||||
/* Return true if this platform can run the "lzma" program. */
|
||||
int canLzma(void);
|
||||
|
||||
/* Return true if this platform can run the "lzop" program. */
|
||||
int canLzop(void);
|
||||
|
||||
/* Return true if this platform can run the "xz" program. */
|
||||
int canXz(void);
|
||||
|
||||
/* Return true if this filesystem can handle nodump flags. */
|
||||
int canNodump(void);
|
||||
|
@ -148,7 +148,7 @@ DEFINE_TEST(test_basic)
|
||||
strncat(result,
|
||||
"bsdcpio: file: large inode number truncated: "
|
||||
"Numerical result out of range\n",
|
||||
sizeof(result) - strlen(result));
|
||||
sizeof(result) - strlen(result) -1);
|
||||
|
||||
/* hardlink to above file. */
|
||||
assertMakeHardlink("linkfile", "file");
|
||||
@ -157,7 +157,7 @@ DEFINE_TEST(test_basic)
|
||||
strncat(result,
|
||||
"bsdcpio: linkfile: large inode number truncated: "
|
||||
"Numerical result out of range\n",
|
||||
sizeof(result) - strlen(result));
|
||||
sizeof(result) - strlen(result) -1);
|
||||
|
||||
/* Symlink to above file. */
|
||||
if (canSymlink()) {
|
||||
@ -167,7 +167,7 @@ DEFINE_TEST(test_basic)
|
||||
strncat(result,
|
||||
"bsdcpio: symlink: large inode number truncated: "
|
||||
"Numerical result out of range\n",
|
||||
sizeof(result) - strlen(result));
|
||||
sizeof(result) - strlen(result) -1);
|
||||
}
|
||||
|
||||
/* Another file with different permissions. */
|
||||
@ -177,7 +177,7 @@ DEFINE_TEST(test_basic)
|
||||
strncat(result,
|
||||
"bsdcpio: file2: large inode number truncated: "
|
||||
"Numerical result out of range\n",
|
||||
sizeof(result) - strlen(result));
|
||||
sizeof(result) - strlen(result) -1);
|
||||
|
||||
/* Directory. */
|
||||
assertMakeDir("dir", 0775);
|
||||
@ -186,8 +186,8 @@ DEFINE_TEST(test_basic)
|
||||
strncat(result,
|
||||
"bsdcpio: dir: large inode number truncated: "
|
||||
"Numerical result out of range\n",
|
||||
sizeof(result) - strlen(result));
|
||||
strncat(result, "2 blocks\n", sizeof(result) - strlen(result));
|
||||
sizeof(result) - strlen(result) -1);
|
||||
strncat(result, "2 blocks\n", sizeof(result) - strlen(result) -1);
|
||||
|
||||
/* All done. */
|
||||
fclose(filelist);
|
||||
|
7
cpio/test/test_extract.cpio.Z.uu
Normal file
7
cpio/test/test_extract.cpio.Z.uu
Normal file
@ -0,0 +1,7 @@
|
||||
begin 664 test_extract.cpio.Z
|
||||
M'YV0,&X$'`B#!@P8,0XJC)$0A@T;!A'>J+%PHL*%%P_&D`%CAHP;!F7,B*C0
|
||||
M1L:+(LVD85,F!H`Q;]S0*2-S#H@W9D"H9!G#A8*!`@46U)A11L.'$6-8U+CT
|
||||
M8D.G'#V"A"&#!L6+)D\>3+FRC(R7,6?6O)ESIU>?0`EJ7<N6[=.V:V/,@$M%
|
||||
A2I`D3(I("<$7@-^_@`,+'DRXL.'#B!,K7LRXL>/'D!4#
|
||||
`
|
||||
end
|
7
cpio/test/test_extract.cpio.bz2.uu
Normal file
7
cpio/test/test_extract.cpio.bz2.uu
Normal file
@ -0,0 +1,7 @@
|
||||
begin 664 test_extract.cpio.bz2
|
||||
M0EIH.3%!629365?=.4@``#G_@G*0(`#@`7^`(B04``LEC```!"``E`E(>I,H
|
||||
M::'J&@_4C3:@E$AD#0&@&@%"E;V/1!XIP>#C9T[41`4PQ1A`@S*4F&BD@B0T
|
||||
MBA$$-:\/@BQGNKU1G@%#`G+N0R%$JTHG(XBRB%1$V8F4#F_IWT=S4+ERVL(?
|
||||
40V!'@1L4+AO_B[DBG"A(*^Z<I```
|
||||
`
|
||||
end
|
7
cpio/test/test_extract.cpio.grz.uu
Normal file
7
cpio/test/test_extract.cpio.grz.uu
Normal file
@ -0,0 +1,7 @@
|
||||
begin 644 test_extract.cpio.grz
|
||||
M1U)::7!)20`"!#HI``(``*P-```&`0``"````&X````B%2.02C`PK`#__..F
|
||||
MI;8=99?N!6`:IQJ:XU/T"`W`B"?N/D9-0K6VN/D\.2>0,#J&)3G"\^YE?X_'
|
||||
M_K._F':0[`DL%IQ=<,Z-JH>V$S,?.[`&42C7]J^XQ@9OY!Z$!$^JLQPKZU[:
|
||||
/!M,+.$MY:Y(HS<<]U`&`
|
||||
`
|
||||
end
|
7
cpio/test/test_extract.cpio.gz.uu
Normal file
7
cpio/test/test_extract.cpio.gz.uu
Normal file
@ -0,0 +1,7 @@
|
||||
begin 664 test_extract.cpio.gz
|
||||
M'XL("`5X<E```W1E<W1?97AT<F%C="YC<&EO`#,P-P!!`Q,#`T,#$#`$4F9F
|
||||
M(*ZYJ0&,-(#)&A@:&1@;F9L8&!F;@/EF!C!@9)R6F9-JR)"<GU>2FE=2K)"?
|
||||
MI@`6T>,R0+?$B$A+3$RQ6F*$88D1PA*"P!"[J#$2)R3(T=/'-4A149%AF`,`
|
||||
(305ZBP`"````
|
||||
`
|
||||
end
|
8
cpio/test/test_extract.cpio.lrz.uu
Normal file
8
cpio/test/test_extract.cpio.lrz.uu
Normal file
@ -0,0 +1,8 @@
|
||||
begin 664 test_extract.cpio.lrz
|
||||
M3%):20`&``(``````````%T````!`0```@$`$`,`````#@`#`````"\``QH`
|
||||
M&@````!W``$G`&4``#,``2(``0``#0$````U<-`Y!F$`MP$````8#=\$8#<1
|
||||
MR/BL39$D4M>["H7&@4%L/4*_(*VGB*YU>?RX.9]HL86'.A)H@Y;Z\^$?M^8_
|
||||
M!/-;62G.*7*A&A!_ENZ8$7]O-M7_.FTRC%BCGC95:6'9ZH3)QSCR4RX42P!`
|
||||
/-E>/7"L[:OY"/A924S4$
|
||||
`
|
||||
end
|
6
cpio/test/test_extract.cpio.lz.uu
Normal file
6
cpio/test/test_extract.cpio.lz.uu
Normal file
@ -0,0 +1,6 @@
|
||||
begin 664 test_extract.cpio.lz
|
||||
M3%I)4`$,`!@-WP1@-Q'(^*Q-D212U[L*A<:!06P]0K\@K:>(KG5Y_+@YGVBQ
|
||||
MA8<Z$FB#EOKSX1^WYC\$\UM9*<XI<J$:$'^B>;_>8N3MLP="$0SJ#QKYB?@8
|
||||
G]@'$$7\&W^T*+9?6B=?__M$G@$T%>HL``@```````($`````````
|
||||
`
|
||||
end
|
6
cpio/test/test_extract.cpio.lzma.uu
Normal file
6
cpio/test/test_extract.cpio.lzma.uu
Normal file
@ -0,0 +1,6 @@
|
||||
begin 664 test_extract.cpio.lzma
|
||||
M70``@`#__________P`8#=\$8#<1R/BL39$D4M>["H7&@4%L/4*_(*VGB*YU
|
||||
M>?RX.9]HL86'.A)H@Y;Z\^$?M^8_!/-;62G.*7*A&A!_HGF_WF+D[;.+!OW3
|
||||
:T_2I)V(;K[FNL#'W%T+L;ATS`A*3__[1Z```
|
||||
`
|
||||
end
|
9
cpio/test/test_extract.cpio.lzo.uu
Normal file
9
cpio/test/test_extract.cpio.lzo.uu
Normal file
@ -0,0 +1,9 @@
|
||||
begin 664 test_extract.cpio.lzo
|
||||
MB4Q:3P`-"AH*$#`@8`E``04#```!``"!M%!R>-T`````$71E<W1?97AT<F%C
|
||||
M="YC<&EOOH$+9````@````"DIR,^[`HP-S`W,#<P,#0P,#$P8``#,3$P,#8V
|
||||
M>`$#-S4P,#`QE`!@`7`#"C`P,3(P,S(W-#`R,S2!`C:4`'````(R,V9I;&4Q
|
||||
M`&-O;G1E;G1S(&]F((8"+@HOD0$R(`:1`31J$#`P+I$!,B^1`3(HD`%L$3L,
|
||||
M`+P<+HH`,3,I1``(5%)!24Q%4B$A(0`@JP````$`````````````````````
|
||||
*````$0``````````
|
||||
`
|
||||
end
|
7
cpio/test/test_extract.cpio.xz.uu
Normal file
7
cpio/test/test_extract.cpio.xz.uu
Normal file
@ -0,0 +1,7 @@
|
||||
begin 664 test_extract.cpio.xz
|
||||
M_3=Z6%H```3FUK1&`@`A`18```!T+^6CX`'_`&%=`!@-WP1@-Q'(^*Q-D212
|
||||
MU[L*A<:!06P]0K\@K:>(KG5Y_+@YGVBQA8<Z$FB#EOKSX1^WYC\$\UM9*<XI
|
||||
M<J$:$'^B>;_>8N3MLXL&_=/3]*DG8ANON:ZP,?<70NQN'3"CP@``````J9FA
|
||||
=#1$]4L<``7V`!`````?M;4JQQ&?[`@`````$65H`
|
||||
`
|
||||
end
|
42
cpio/test/test_extract_cpio_Z.c
Normal file
42
cpio/test/test_extract_cpio_Z.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_extract_cpio_Z)
|
||||
{
|
||||
const char *reffile = "test_extract.cpio.Z";
|
||||
|
||||
extract_reference_file(reffile);
|
||||
assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
|
||||
testprog, reffile));
|
||||
|
||||
assertFileExists("file1");
|
||||
assertTextFileContents("contents of file1.\n", "file1");
|
||||
assertFileExists("file2");
|
||||
assertTextFileContents("contents of file2.\n", "file2");
|
||||
assertEmptyFile("test.out");
|
||||
assertTextFileContents("1 block\n", "test.err");
|
||||
}
|
48
cpio/test/test_extract_cpio_bz2.c
Normal file
48
cpio/test/test_extract_cpio_bz2.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_extract_cpio_bz2)
|
||||
{
|
||||
const char *reffile = "test_extract.cpio.bz2";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canBzip2()) {
|
||||
assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
|
||||
testprog, reffile));
|
||||
|
||||
assertFileExists("file1");
|
||||
assertTextFileContents("contents of file1.\n", "file1");
|
||||
assertFileExists("file2");
|
||||
assertTextFileContents("contents of file2.\n", "file2");
|
||||
assertEmptyFile("test.out");
|
||||
assertTextFileContents("1 block\n", "test.err");
|
||||
} else {
|
||||
skipping("It seems bzip2 is not supported on this platform");
|
||||
}
|
||||
}
|
48
cpio/test/test_extract_cpio_grz.c
Normal file
48
cpio/test/test_extract_cpio_grz.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_extract_cpio_grz)
|
||||
{
|
||||
const char *reffile = "test_extract.cpio.grz";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canGrzip()) {
|
||||
assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
|
||||
testprog, reffile));
|
||||
|
||||
assertFileExists("file1");
|
||||
assertTextFileContents("contents of file1.\n", "file1");
|
||||
assertFileExists("file2");
|
||||
assertTextFileContents("contents of file2.\n", "file2");
|
||||
assertEmptyFile("test.out");
|
||||
assertTextFileContents("1 block\n", "test.err");
|
||||
} else {
|
||||
skipping("It seems grzip is not supported on this platform");
|
||||
}
|
||||
}
|
48
cpio/test/test_extract_cpio_gz.c
Normal file
48
cpio/test/test_extract_cpio_gz.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_extract_cpio_gz)
|
||||
{
|
||||
const char *reffile = "test_extract.cpio.gz";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canGzip()) {
|
||||
assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
|
||||
testprog, reffile));
|
||||
|
||||
assertFileExists("file1");
|
||||
assertTextFileContents("contents of file1.\n", "file1");
|
||||
assertFileExists("file2");
|
||||
assertTextFileContents("contents of file2.\n", "file2");
|
||||
assertEmptyFile("test.out");
|
||||
assertTextFileContents("1 block\n", "test.err");
|
||||
} else {
|
||||
skipping("It seems gzip is not supported on this platform");
|
||||
}
|
||||
}
|
48
cpio/test/test_extract_cpio_lrz.c
Normal file
48
cpio/test/test_extract_cpio_lrz.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_extract_cpio_lrz)
|
||||
{
|
||||
const char *reffile = "test_extract.cpio.lrz";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canLrzip()) {
|
||||
assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
|
||||
testprog, reffile));
|
||||
|
||||
assertFileExists("file1");
|
||||
assertTextFileContents("contents of file1.\n", "file1");
|
||||
assertFileExists("file2");
|
||||
assertTextFileContents("contents of file2.\n", "file2");
|
||||
assertEmptyFile("test.out");
|
||||
assertTextFileContents("1 block\n", "test.err");
|
||||
} else {
|
||||
skipping("It seems lrzip is not supported on this platform");
|
||||
}
|
||||
}
|
48
cpio/test/test_extract_cpio_lz.c
Normal file
48
cpio/test/test_extract_cpio_lz.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_extract_cpio_lz)
|
||||
{
|
||||
const char *reffile = "test_extract.cpio.lz";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canLzip()) {
|
||||
assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
|
||||
testprog, reffile));
|
||||
|
||||
assertFileExists("file1");
|
||||
assertTextFileContents("contents of file1.\n", "file1");
|
||||
assertFileExists("file2");
|
||||
assertTextFileContents("contents of file2.\n", "file2");
|
||||
assertEmptyFile("test.out");
|
||||
assertTextFileContents("1 block\n", "test.err");
|
||||
} else {
|
||||
skipping("It seems lzip is not supported on this platform");
|
||||
}
|
||||
}
|
48
cpio/test/test_extract_cpio_lzma.c
Normal file
48
cpio/test/test_extract_cpio_lzma.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_extract_cpio_lzma)
|
||||
{
|
||||
const char *reffile = "test_extract.cpio.lzma";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canLzma()) {
|
||||
assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
|
||||
testprog, reffile));
|
||||
|
||||
assertFileExists("file1");
|
||||
assertTextFileContents("contents of file1.\n", "file1");
|
||||
assertFileExists("file2");
|
||||
assertTextFileContents("contents of file2.\n", "file2");
|
||||
assertEmptyFile("test.out");
|
||||
assertTextFileContents("1 block\n", "test.err");
|
||||
} else {
|
||||
skipping("It seems lzma is not supported on this platform");
|
||||
}
|
||||
}
|
48
cpio/test/test_extract_cpio_lzo.c
Normal file
48
cpio/test/test_extract_cpio_lzo.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_extract_cpio_lzo)
|
||||
{
|
||||
const char *reffile = "test_extract.cpio.lrz";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canLzop()) {
|
||||
assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
|
||||
testprog, reffile));
|
||||
|
||||
assertFileExists("file1");
|
||||
assertTextFileContents("contents of file1.\n", "file1");
|
||||
assertFileExists("file2");
|
||||
assertTextFileContents("contents of file2.\n", "file2");
|
||||
assertEmptyFile("test.out");
|
||||
assertTextFileContents("1 block\n", "test.err");
|
||||
} else {
|
||||
skipping("It seems lzop is not supported on this platform");
|
||||
}
|
||||
}
|
48
cpio/test/test_extract_cpio_xz.c
Normal file
48
cpio/test/test_extract_cpio_xz.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_extract_cpio_xz)
|
||||
{
|
||||
const char *reffile = "test_extract.cpio.xz";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canXz()) {
|
||||
assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
|
||||
testprog, reffile));
|
||||
|
||||
assertFileExists("file1");
|
||||
assertTextFileContents("contents of file1.\n", "file1");
|
||||
assertFileExists("file2");
|
||||
assertTextFileContents("contents of file2.\n", "file2");
|
||||
assertEmptyFile("test.out");
|
||||
assertTextFileContents("1 block\n", "test.err");
|
||||
} else {
|
||||
skipping("It seems xz is not supported on this platform");
|
||||
}
|
||||
}
|
@ -157,9 +157,9 @@ DEFINE_TEST(test_format_newc)
|
||||
|
||||
/* Verify that nothing went to stderr. */
|
||||
if (canSymlink()) {
|
||||
strncat(result, "2 blocks\n", sizeof(result) - strlen(result));
|
||||
strncat(result, "2 blocks\n", sizeof(result) - strlen(result) -1);
|
||||
} else {
|
||||
strncat(result, "1 block\n", sizeof(result) - strlen(result));
|
||||
strncat(result, "1 block\n", sizeof(result) - strlen(result) -1);
|
||||
}
|
||||
assertTextFileContents(result, "newc.err");
|
||||
|
||||
|
54
cpio/test/test_option_b64encode.c
Normal file
54
cpio/test/test_option_b64encode.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_option_b64encode)
|
||||
{
|
||||
char *p;
|
||||
size_t s;
|
||||
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with compress compression and uuencode. */
|
||||
assertEqualInt(0,
|
||||
systemf("echo f | %s -o -Z --b64encode >archive.out 2>archive.err",
|
||||
testprog));
|
||||
/* Check that the archive file has an uuencode signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "begin-base64 644", 16);
|
||||
|
||||
/* Archive it with uuencode only. */
|
||||
assertEqualInt(0,
|
||||
systemf("echo f | %s -o --b64encode >archive.out 2>archive.err",
|
||||
testprog));
|
||||
/* Check that the archive file has an uuencode signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "begin-base64 644", 16);
|
||||
}
|
52
cpio/test/test_option_grzip.c
Normal file
52
cpio/test/test_option_grzip.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_option_grzip)
|
||||
{
|
||||
char *p;
|
||||
size_t s;
|
||||
|
||||
if (!canGrzip()) {
|
||||
skipping("grzip is not supported on this platform");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with grzip compression. */
|
||||
assertEqualInt(0,
|
||||
systemf("echo f | %s -o --grzip >archive.out 2>archive.err",
|
||||
testprog));
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
/* Check that the archive file has an grzip signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "GRZipII\x00\x02\x04:)", 12);
|
||||
}
|
52
cpio/test/test_option_lrzip.c
Normal file
52
cpio/test/test_option_lrzip.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_option_lrzip)
|
||||
{
|
||||
char *p;
|
||||
size_t s;
|
||||
|
||||
if (!canLrzip()) {
|
||||
skipping("lrzip is not supported on this platform");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with lrzip compression. */
|
||||
assertEqualInt(0,
|
||||
systemf("echo f | %s -o --lrzip >archive.out 2>archive.err",
|
||||
testprog));
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
/* Check that the archive file has an lzma signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "LRZI\x00", 5);
|
||||
}
|
56
cpio/test/test_option_lzop.c
Normal file
56
cpio/test/test_option_lzop.c
Normal file
@ -0,0 +1,56 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_option_lzop)
|
||||
{
|
||||
char *p;
|
||||
int r;
|
||||
size_t s;
|
||||
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with lzop compression. */
|
||||
r = systemf("echo f | %s -o --lzop >archive.out 2>archive.err",
|
||||
testprog);
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (r != 0) {
|
||||
if (!canLzop()) {
|
||||
skipping("lzop is not supported on this platform");
|
||||
return;
|
||||
}
|
||||
failure("--lzop option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
return;
|
||||
}
|
||||
/* Check that the archive file has an lzma signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9);
|
||||
}
|
54
cpio/test/test_option_uuencode.c
Normal file
54
cpio/test/test_option_uuencode.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_option_uuencode)
|
||||
{
|
||||
char *p;
|
||||
size_t s;
|
||||
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with compress compression and uuencode. */
|
||||
assertEqualInt(0,
|
||||
systemf("echo f | %s -o -Z --uuencode >archive.out 2>archive.err",
|
||||
testprog));
|
||||
/* Check that the archive file has an uuencode signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "begin 644", 9);
|
||||
|
||||
/* Archive it with uuencode only. */
|
||||
assertEqualInt(0,
|
||||
systemf("echo f | %s -o --uuencode >archive.out 2>archive.err",
|
||||
testprog));
|
||||
/* Check that the archive file has an uuencode signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "begin 644", 9);
|
||||
}
|
57
cpio/test/test_option_xz.c
Normal file
57
cpio/test/test_option_xz.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_option_xz)
|
||||
{
|
||||
char *p;
|
||||
int r;
|
||||
size_t s;
|
||||
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with xz compression. */
|
||||
r = systemf("echo f | %s -o --xz >archive.out 2>archive.err",
|
||||
testprog);
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (r != 0) {
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without xz support");
|
||||
return;
|
||||
}
|
||||
failure("--xz option is broken");
|
||||
assertEqualInt(r, 0);
|
||||
return;
|
||||
}
|
||||
/* Check that the archive file has an xz signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\xFD\x37\x7A\x58\x5A\x00", 6);
|
||||
}
|
@ -40,9 +40,8 @@ DEFINE_TEST(test_option_y)
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (r != 0) {
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without bzip2 support");
|
||||
if (!canBzip2()) {
|
||||
skipping("bzip2 is not supported on this platform");
|
||||
return;
|
||||
}
|
||||
failure("-y option is broken");
|
||||
|
@ -40,9 +40,8 @@ DEFINE_TEST(test_option_z)
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (r != 0) {
|
||||
if (strstr(p, "compression not available") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without gzip support");
|
||||
if (!canGzip()) {
|
||||
skipping("gzip is not supported on this platform");
|
||||
return;
|
||||
}
|
||||
failure("-z option is broken");
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
#
|
||||
# Simple script to repopulate the 'doc' tree from
|
||||
# the mdoc man pages stored in each project.
|
||||
|
@ -231,27 +231,27 @@ create(const char *filename, int compress, const char **argv)
|
||||
switch (compress) {
|
||||
#ifndef NO_BZIP2_CREATE
|
||||
case 'j': case 'y':
|
||||
archive_write_set_compression_bzip2(a);
|
||||
archive_write_add_filter_bzip2(a);
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_COMPRESS_CREATE
|
||||
case 'Z':
|
||||
archive_write_set_compression_compress(a);
|
||||
archive_write_add_filter_compress(a);
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_GZIP_CREATE
|
||||
case 'z':
|
||||
archive_write_set_compression_gzip(a);
|
||||
archive_write_add_filter_gzip(a);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
archive_write_set_compression_none(a);
|
||||
archive_write_add_filter_none(a);
|
||||
break;
|
||||
}
|
||||
archive_write_set_format_ustar(a);
|
||||
if (strcmp(filename, "-") == 0)
|
||||
filename = NULL;
|
||||
archive_write_open_file(a, filename);
|
||||
archive_write_open_filename(a, filename);
|
||||
|
||||
disk = archive_read_disk_new();
|
||||
#ifndef NO_LOOKUP
|
||||
@ -361,7 +361,7 @@ extract(const char *filename, int do_extract, int flags)
|
||||
#endif
|
||||
if (filename != NULL && strcmp(filename, "-") == 0)
|
||||
filename = NULL;
|
||||
if ((r = archive_read_open_file(a, filename, 10240))) {
|
||||
if ((r = archive_read_open_filename(a, filename, 10240))) {
|
||||
errmsg(archive_error_string(a));
|
||||
errmsg("\n");
|
||||
exit(r);
|
||||
|
@ -158,8 +158,8 @@ extract(const char *filename, int do_extract, int flags)
|
||||
*/
|
||||
if (filename != NULL && strcmp(filename, "-") == 0)
|
||||
filename = NULL;
|
||||
if ((r = archive_read_open_file(a, filename, 10240)))
|
||||
fail("archive_read_open_file()",
|
||||
if ((r = archive_read_open_filename(a, filename, 10240)))
|
||||
fail("archive_read_open_filename()",
|
||||
archive_error_string(a), r);
|
||||
for (;;) {
|
||||
r = archive_read_next_header(a, &entry);
|
||||
|
@ -15,6 +15,9 @@ SET(include_HEADERS
|
||||
SET(libarchive_SOURCES
|
||||
archive_acl.c
|
||||
archive_check_magic.c
|
||||
archive_cmdline.c
|
||||
archive_cmdline_private.h
|
||||
archive_crc32.h
|
||||
archive_crypto.c
|
||||
archive_crypto_private.h
|
||||
archive_endian.h
|
||||
@ -42,6 +45,7 @@ SET(libarchive_SOURCES
|
||||
archive_rb.c
|
||||
archive_rb.h
|
||||
archive_read.c
|
||||
archive_read_append_filter.c
|
||||
archive_read_data_into_fd.c
|
||||
archive_read_disk_entry_from_file.c
|
||||
archive_read_disk_posix.c
|
||||
@ -53,11 +57,15 @@ SET(libarchive_SOURCES
|
||||
archive_read_open_filename.c
|
||||
archive_read_open_memory.c
|
||||
archive_read_private.h
|
||||
archive_read_set_format.c
|
||||
archive_read_set_options.c
|
||||
archive_read_support_filter_all.c
|
||||
archive_read_support_filter_bzip2.c
|
||||
archive_read_support_filter_compress.c
|
||||
archive_read_support_filter_gzip.c
|
||||
archive_read_support_filter_grzip.c
|
||||
archive_read_support_filter_lrzip.c
|
||||
archive_read_support_filter_lzop.c
|
||||
archive_read_support_filter_none.c
|
||||
archive_read_support_filter_program.c
|
||||
archive_read_support_filter_rpm.c
|
||||
@ -85,6 +93,7 @@ SET(libarchive_SOURCES
|
||||
archive_util.c
|
||||
archive_virtual.c
|
||||
archive_write.c
|
||||
archive_write_disk_acl.c
|
||||
archive_write_disk_posix.c
|
||||
archive_write_disk_private.h
|
||||
archive_write_disk_set_standard_lookup.c
|
||||
@ -94,11 +103,17 @@ SET(libarchive_SOURCES
|
||||
archive_write_open_filename.c
|
||||
archive_write_open_memory.c
|
||||
archive_write_add_filter.c
|
||||
archive_write_add_filter_b64encode.c
|
||||
archive_write_add_filter_by_name.c
|
||||
archive_write_add_filter_bzip2.c
|
||||
archive_write_add_filter_compress.c
|
||||
archive_write_add_filter_grzip.c
|
||||
archive_write_add_filter_gzip.c
|
||||
archive_write_add_filter_lrzip.c
|
||||
archive_write_add_filter_lzop.c
|
||||
archive_write_add_filter_none.c
|
||||
archive_write_add_filter_program.c
|
||||
archive_write_add_filter_uuencode.c
|
||||
archive_write_add_filter_xz.c
|
||||
archive_write_set_format.c
|
||||
archive_write_set_format_7zip.c
|
||||
@ -112,10 +127,11 @@ SET(libarchive_SOURCES
|
||||
archive_write_set_format_pax.c
|
||||
archive_write_set_format_shar.c
|
||||
archive_write_set_format_ustar.c
|
||||
archive_write_set_format_v7tar.c
|
||||
archive_write_set_format_xar.c
|
||||
archive_write_set_format_zip.c
|
||||
archive_write_set_options.c
|
||||
filter_fork.c
|
||||
filter_fork_posix.c
|
||||
filter_fork.h
|
||||
)
|
||||
|
||||
|
@ -97,6 +97,12 @@
|
||||
#define __LA_PRINTF(fmtarg, firstvararg) /* nothing */
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ >= 1
|
||||
# define __LA_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
# define __LA_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -118,13 +124,13 @@ extern "C" {
|
||||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||
*/
|
||||
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3000004
|
||||
#define ARCHIVE_VERSION_NUMBER 3001002
|
||||
__LA_DECL int archive_version_number(void);
|
||||
|
||||
/*
|
||||
* Textual name/version of the library, useful for version displays.
|
||||
*/
|
||||
#define ARCHIVE_VERSION_STRING "libarchive 3.0.4"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive 3.1.2"
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
/* Declare our basic types. */
|
||||
@ -194,6 +200,13 @@ typedef int archive_open_callback(struct archive *, void *_client_data);
|
||||
|
||||
typedef int archive_close_callback(struct archive *, void *_client_data);
|
||||
|
||||
/* Switches from one client data object to the next/prev client data object.
|
||||
* This is useful for reading from different data blocks such as a set of files
|
||||
* that make up one large file.
|
||||
*/
|
||||
typedef int archive_switch_callback(struct archive *, void *_client_data1,
|
||||
void *_client_data2);
|
||||
|
||||
/*
|
||||
* Codes to identify various stream filters.
|
||||
*/
|
||||
@ -207,6 +220,9 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
|
||||
#define ARCHIVE_FILTER_UU 7
|
||||
#define ARCHIVE_FILTER_RPM 8
|
||||
#define ARCHIVE_FILTER_LZIP 9
|
||||
#define ARCHIVE_FILTER_LRZIP 10
|
||||
#define ARCHIVE_FILTER_LZOP 11
|
||||
#define ARCHIVE_FILTER_GRZIP 12
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE
|
||||
@ -219,6 +235,7 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
|
||||
#define ARCHIVE_COMPRESSION_UU ARCHIVE_FILTER_UU
|
||||
#define ARCHIVE_COMPRESSION_RPM ARCHIVE_FILTER_RPM
|
||||
#define ARCHIVE_COMPRESSION_LZIP ARCHIVE_FILTER_LZIP
|
||||
#define ARCHIVE_COMPRESSION_LRZIP ARCHIVE_FILTER_LRZIP
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -291,37 +308,49 @@ __LA_DECL struct archive *archive_read_new(void);
|
||||
*/
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
__LA_DECL int archive_read_support_compression_all(struct archive *);
|
||||
__LA_DECL int archive_read_support_compression_bzip2(struct archive *);
|
||||
__LA_DECL int archive_read_support_compression_compress(struct archive *);
|
||||
__LA_DECL int archive_read_support_compression_gzip(struct archive *);
|
||||
__LA_DECL int archive_read_support_compression_lzip(struct archive *);
|
||||
__LA_DECL int archive_read_support_compression_lzma(struct archive *);
|
||||
__LA_DECL int archive_read_support_compression_none(struct archive *);
|
||||
__LA_DECL int archive_read_support_compression_all(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_read_support_compression_bzip2(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_read_support_compression_compress(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_read_support_compression_gzip(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_read_support_compression_lzip(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_read_support_compression_lzma(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_read_support_compression_none(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_read_support_compression_program(struct archive *,
|
||||
const char *command);
|
||||
const char *command) __LA_DEPRECATED;
|
||||
__LA_DECL int archive_read_support_compression_program_signature
|
||||
(struct archive *, const char *,
|
||||
const void * /* match */, size_t);
|
||||
const void * /* match */, size_t) __LA_DEPRECATED;
|
||||
|
||||
__LA_DECL int archive_read_support_compression_rpm(struct archive *);
|
||||
__LA_DECL int archive_read_support_compression_uu(struct archive *);
|
||||
__LA_DECL int archive_read_support_compression_xz(struct archive *);
|
||||
__LA_DECL int archive_read_support_compression_rpm(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_read_support_compression_uu(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_read_support_compression_xz(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
#endif
|
||||
|
||||
__LA_DECL int archive_read_support_filter_all(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_bzip2(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_compress(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_gzip(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_grzip(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_lrzip(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_lzip(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_lzma(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_lzop(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_none(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_program(struct archive *,
|
||||
const char *command);
|
||||
__LA_DECL int archive_read_support_filter_program_signature
|
||||
(struct archive *, const char *,
|
||||
(struct archive *, const char * /* cmd */,
|
||||
const void * /* match */, size_t);
|
||||
|
||||
__LA_DECL int archive_read_support_filter_rpm(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_uu(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_xz(struct archive *);
|
||||
@ -343,6 +372,17 @@ __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_zip(struct archive *);
|
||||
|
||||
/* Functions to manually set the format and filters to be used. This is
|
||||
* useful to bypass the bidding process when the format and filters to use
|
||||
* is known in advance.
|
||||
*/
|
||||
__LA_DECL int archive_read_set_format(struct archive *, int);
|
||||
__LA_DECL int archive_read_append_filter(struct archive *, int);
|
||||
__LA_DECL int archive_read_append_filter_program(struct archive *,
|
||||
const char *);
|
||||
__LA_DECL int archive_read_append_filter_program_signature
|
||||
(struct archive *, const char *, const void * /* match */, size_t);
|
||||
|
||||
/* Set various callbacks. */
|
||||
__LA_DECL int archive_read_set_open_callback(struct archive *,
|
||||
archive_open_callback *);
|
||||
@ -354,8 +394,23 @@ __LA_DECL int archive_read_set_skip_callback(struct archive *,
|
||||
archive_skip_callback *);
|
||||
__LA_DECL int archive_read_set_close_callback(struct archive *,
|
||||
archive_close_callback *);
|
||||
/* The callback data is provided to all of the callbacks above. */
|
||||
/* Callback used to switch between one data object to the next */
|
||||
__LA_DECL int archive_read_set_switch_callback(struct archive *,
|
||||
archive_switch_callback *);
|
||||
|
||||
/* This sets the first data object. */
|
||||
__LA_DECL int archive_read_set_callback_data(struct archive *, void *);
|
||||
/* This sets data object at specified index */
|
||||
__LA_DECL int archive_read_set_callback_data2(struct archive *, void *,
|
||||
unsigned int);
|
||||
/* This adds a data object at the specified index. */
|
||||
__LA_DECL int archive_read_add_callback_data(struct archive *, void *,
|
||||
unsigned int);
|
||||
/* This appends a data object to the end of list */
|
||||
__LA_DECL int archive_read_append_callback_data(struct archive *, void *);
|
||||
/* This prepends a data object to the beginning of list */
|
||||
__LA_DECL int archive_read_prepend_callback_data(struct archive *, void *);
|
||||
|
||||
/* Opening freezes the callbacks. */
|
||||
__LA_DECL int archive_read_open1(struct archive *);
|
||||
|
||||
@ -375,11 +430,15 @@ __LA_DECL int archive_read_open2(struct archive *, void *_client_data,
|
||||
/* Use this if you know the filename. Note: NULL indicates stdin. */
|
||||
__LA_DECL int archive_read_open_filename(struct archive *,
|
||||
const char *_filename, size_t _block_size);
|
||||
/* Use this for reading multivolume files by filenames.
|
||||
* NOTE: Must be NULL terminated. Sorting is NOT done. */
|
||||
__LA_DECL int archive_read_open_filenames(struct archive *,
|
||||
const char **_filenames, size_t _block_size);
|
||||
__LA_DECL int archive_read_open_filename_w(struct archive *,
|
||||
const wchar_t *_filename, size_t _block_size);
|
||||
/* archive_read_open_file() is a deprecated synonym for ..._open_filename(). */
|
||||
__LA_DECL int archive_read_open_file(struct archive *,
|
||||
const char *_filename, size_t _block_size);
|
||||
const char *_filename, size_t _block_size) __LA_DEPRECATED;
|
||||
/* Read an archive that's stored in memory. */
|
||||
__LA_DECL int archive_read_open_memory(struct archive *,
|
||||
void * buff, size_t size);
|
||||
@ -411,6 +470,9 @@ __LA_DECL __LA_INT64_T archive_read_header_position(struct archive *);
|
||||
__LA_DECL __LA_SSIZE_T archive_read_data(struct archive *,
|
||||
void *, size_t);
|
||||
|
||||
/* Seek within the body of an entry. Similar to lseek(2). */
|
||||
__LA_DECL __LA_INT64_T archive_seek_data(struct archive *, __LA_INT64_T, int);
|
||||
|
||||
/*
|
||||
* A zero-copy version of archive_read_data that also exposes the file offset
|
||||
* of each returned block. Note that the client has no way to specify
|
||||
@ -494,6 +556,12 @@ __LA_DECL int archive_read_set_options(struct archive *_a,
|
||||
/* Default: Do not restore Mac extended metadata. */
|
||||
/* This has no effect except on Mac OS. */
|
||||
#define ARCHIVE_EXTRACT_MAC_METADATA (0x2000)
|
||||
/* Default: Use HFS+ compression if it was compressed. */
|
||||
/* This has no effect except on Mac OS v10.6 or later. */
|
||||
#define ARCHIVE_EXTRACT_NO_HFS_COMPRESSION (0x4000)
|
||||
/* Default: Do not use HFS+ compression if it was not compressed. */
|
||||
/* This has no effect except on Mac OS v10.6 or later. */
|
||||
#define ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED (0x8000)
|
||||
|
||||
__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
|
||||
int flags);
|
||||
@ -514,7 +582,7 @@ __LA_DECL int archive_read_close(struct archive *);
|
||||
__LA_DECL int archive_read_free(struct archive *);
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
/* Synonym for archive_read_free() for backwards compatibility. */
|
||||
__LA_DECL int archive_read_finish(struct archive *);
|
||||
__LA_DECL int archive_read_finish(struct archive *) __LA_DEPRECATED;
|
||||
#endif
|
||||
|
||||
/*-
|
||||
@ -547,27 +615,41 @@ __LA_DECL int archive_write_set_skip_file(struct archive *,
|
||||
__LA_INT64_T, __LA_INT64_T);
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
__LA_DECL int archive_write_set_compression_bzip2(struct archive *);
|
||||
__LA_DECL int archive_write_set_compression_compress(struct archive *);
|
||||
__LA_DECL int archive_write_set_compression_gzip(struct archive *);
|
||||
__LA_DECL int archive_write_set_compression_lzip(struct archive *);
|
||||
__LA_DECL int archive_write_set_compression_lzma(struct archive *);
|
||||
__LA_DECL int archive_write_set_compression_none(struct archive *);
|
||||
__LA_DECL int archive_write_set_compression_bzip2(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_write_set_compression_compress(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_write_set_compression_gzip(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_write_set_compression_lzip(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_write_set_compression_lzma(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_write_set_compression_none(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_write_set_compression_program(struct archive *,
|
||||
const char *cmd);
|
||||
__LA_DECL int archive_write_set_compression_xz(struct archive *);
|
||||
const char *cmd) __LA_DEPRECATED;
|
||||
__LA_DECL int archive_write_set_compression_xz(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
#endif
|
||||
|
||||
/* A convenience function to set the filter based on the code. */
|
||||
__LA_DECL int archive_write_add_filter(struct archive *, int filter_code);
|
||||
__LA_DECL int archive_write_add_filter_by_name(struct archive *,
|
||||
const char *name);
|
||||
__LA_DECL int archive_write_add_filter_b64encode(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_bzip2(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_compress(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_grzip(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_gzip(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_lrzip(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_lzip(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_lzma(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_lzop(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_none(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_program(struct archive *,
|
||||
const char *cmd);
|
||||
__LA_DECL int archive_write_add_filter_uuencode(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_xz(struct archive *);
|
||||
|
||||
|
||||
@ -584,14 +666,18 @@ __LA_DECL int archive_write_set_format_cpio_newc(struct archive *);
|
||||
__LA_DECL int archive_write_set_format_gnutar(struct archive *);
|
||||
__LA_DECL int archive_write_set_format_iso9660(struct archive *);
|
||||
__LA_DECL int archive_write_set_format_mtree(struct archive *);
|
||||
__LA_DECL int archive_write_set_format_mtree_classic(struct archive *);
|
||||
/* TODO: int archive_write_set_format_old_tar(struct archive *); */
|
||||
__LA_DECL int archive_write_set_format_pax(struct archive *);
|
||||
__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
|
||||
__LA_DECL int archive_write_set_format_shar(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_v7tar(struct archive *);
|
||||
__LA_DECL int archive_write_set_format_xar(struct archive *);
|
||||
__LA_DECL int archive_write_set_format_zip(struct archive *);
|
||||
__LA_DECL int archive_write_zip_set_compression_deflate(struct archive *);
|
||||
__LA_DECL int archive_write_zip_set_compression_store(struct archive *);
|
||||
__LA_DECL int archive_write_open(struct archive *, void *,
|
||||
archive_open_callback *, archive_write_callback *,
|
||||
archive_close_callback *);
|
||||
@ -600,7 +686,8 @@ __LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
|
||||
__LA_DECL int archive_write_open_filename_w(struct archive *,
|
||||
const wchar_t *_file);
|
||||
/* A deprecated synonym for archive_write_open_filename() */
|
||||
__LA_DECL int archive_write_open_file(struct archive *, const char *_file);
|
||||
__LA_DECL int archive_write_open_file(struct archive *, const char *_file)
|
||||
__LA_DEPRECATED;
|
||||
__LA_DECL int archive_write_open_FILE(struct archive *, FILE *);
|
||||
/* _buffSize is the size of the buffer, _used refers to a variable that
|
||||
* will be updated after each write into the buffer. */
|
||||
@ -622,12 +709,16 @@ __LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *,
|
||||
|
||||
__LA_DECL int archive_write_finish_entry(struct archive *);
|
||||
__LA_DECL int archive_write_close(struct archive *);
|
||||
/* Marks the archive as FATAL so that a subsequent free() operation
|
||||
* won't try to close() cleanly. Provides a fast abort capability
|
||||
* when the client discovers that things have gone wrong. */
|
||||
__LA_DECL int archive_write_fail(struct archive *);
|
||||
/* This can fail if the archive wasn't already closed, in which case
|
||||
* archive_write_free() will implicitly call archive_write_close(). */
|
||||
__LA_DECL int archive_write_free(struct archive *);
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
/* Synonym for archive_write_free() for backwards compatibility. */
|
||||
__LA_DECL int archive_write_finish(struct archive *);
|
||||
__LA_DECL int archive_write_finish(struct archive *) __LA_DEPRECATED;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -806,13 +897,17 @@ __LA_DECL const char * archive_filter_name(struct archive *, int);
|
||||
/* These don't properly handle multiple filters, so are deprecated and
|
||||
* will eventually be removed. */
|
||||
/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, -1); */
|
||||
__LA_DECL __LA_INT64_T archive_position_compressed(struct archive *);
|
||||
__LA_DECL __LA_INT64_T archive_position_compressed(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, 0); */
|
||||
__LA_DECL __LA_INT64_T archive_position_uncompressed(struct archive *);
|
||||
__LA_DECL __LA_INT64_T archive_position_uncompressed(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
/* As of libarchive 3.0, this is an alias for archive_filter_name(a, 0); */
|
||||
__LA_DECL const char *archive_compression_name(struct archive *);
|
||||
__LA_DECL const char *archive_compression_name(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
/* As of libarchive 3.0, this is an alias for archive_filter_code(a, 0); */
|
||||
__LA_DECL int archive_compression(struct archive *);
|
||||
__LA_DECL int archive_compression(struct archive *)
|
||||
__LA_DEPRECATED;
|
||||
#endif
|
||||
|
||||
__LA_DECL int archive_errno(struct archive *);
|
||||
|
227
libarchive/archive_cmdline.c
Normal file
227
libarchive/archive_cmdline.c
Normal file
@ -0,0 +1,227 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* 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"
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_cmdline_private.h"
|
||||
#include "archive_string.h"
|
||||
|
||||
static int cmdline_set_path(struct archive_cmdline *, const char *);
|
||||
static int cmdline_add_arg(struct archive_cmdline *, const char *);
|
||||
|
||||
static ssize_t
|
||||
extract_quotation(struct archive_string *as, const char *p)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
for (s = p + 1; *s;) {
|
||||
if (*s == '\\') {
|
||||
if (s[1] != '\0') {
|
||||
archive_strappend_char(as, s[1]);
|
||||
s += 2;
|
||||
} else
|
||||
s++;
|
||||
} else if (*s == '"')
|
||||
break;
|
||||
else {
|
||||
archive_strappend_char(as, s[0]);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (*s != '"')
|
||||
return (ARCHIVE_FAILED);/* Invalid sequence. */
|
||||
return ((ssize_t)(s + 1 - p));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
get_argument(struct archive_string *as, const char *p)
|
||||
{
|
||||
const char *s = p;
|
||||
|
||||
archive_string_empty(as);
|
||||
|
||||
/* Skip beginning space characters. */
|
||||
while (*s != '\0' && *s == ' ')
|
||||
s++;
|
||||
/* Copy non-space characters. */
|
||||
while (*s != '\0' && *s != ' ') {
|
||||
if (*s == '\\') {
|
||||
if (s[1] != '\0') {
|
||||
archive_strappend_char(as, s[1]);
|
||||
s += 2;
|
||||
} else {
|
||||
s++;/* Ignore this character.*/
|
||||
break;
|
||||
}
|
||||
} else if (*s == '"') {
|
||||
ssize_t q = extract_quotation(as, s);
|
||||
if (q < 0)
|
||||
return (ARCHIVE_FAILED);/* Invalid sequence. */
|
||||
s += q;
|
||||
} else {
|
||||
archive_strappend_char(as, s[0]);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return ((ssize_t)(s - p));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up command line arguments.
|
||||
* Returns ARChIVE_OK if everything okey.
|
||||
* Returns ARChIVE_FAILED if there is a lack of the `"' terminator or an
|
||||
* empty command line.
|
||||
* Returns ARChIVE_FATAL if no memory.
|
||||
*/
|
||||
int
|
||||
__archive_cmdline_parse(struct archive_cmdline *data, const char *cmd)
|
||||
{
|
||||
struct archive_string as;
|
||||
const char *p;
|
||||
ssize_t al;
|
||||
int r;
|
||||
|
||||
archive_string_init(&as);
|
||||
|
||||
/* Get first argument as a command path. */
|
||||
al = get_argument(&as, cmd);
|
||||
if (al < 0) {
|
||||
r = ARCHIVE_FAILED;/* Invalid sequence. */
|
||||
goto exit_function;
|
||||
}
|
||||
if (archive_strlen(&as) == 0) {
|
||||
r = ARCHIVE_FAILED;/* An empty command path. */
|
||||
goto exit_function;
|
||||
}
|
||||
r = cmdline_set_path(data, as.s);
|
||||
if (r != ARCHIVE_OK)
|
||||
goto exit_function;
|
||||
p = strrchr(as.s, '/');
|
||||
if (p == NULL)
|
||||
p = as.s;
|
||||
else
|
||||
p++;
|
||||
r = cmdline_add_arg(data, p);
|
||||
if (r != ARCHIVE_OK)
|
||||
goto exit_function;
|
||||
cmd += al;
|
||||
|
||||
for (;;) {
|
||||
al = get_argument(&as, cmd);
|
||||
if (al < 0) {
|
||||
r = ARCHIVE_FAILED;/* Invalid sequence. */
|
||||
goto exit_function;
|
||||
}
|
||||
if (al == 0)
|
||||
break;
|
||||
cmd += al;
|
||||
if (archive_strlen(&as) == 0 && *cmd == '\0')
|
||||
break;
|
||||
r = cmdline_add_arg(data, as.s);
|
||||
if (r != ARCHIVE_OK)
|
||||
goto exit_function;
|
||||
}
|
||||
r = ARCHIVE_OK;
|
||||
exit_function:
|
||||
archive_string_free(&as);
|
||||
return (r);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the program path.
|
||||
*/
|
||||
static int
|
||||
cmdline_set_path(struct archive_cmdline *data, const char *path)
|
||||
{
|
||||
char *newptr;
|
||||
|
||||
newptr = realloc(data->path, strlen(path) + 1);
|
||||
if (newptr == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
data->path = newptr;
|
||||
strcpy(data->path, path);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a argument for the program.
|
||||
*/
|
||||
static int
|
||||
cmdline_add_arg(struct archive_cmdline *data, const char *arg)
|
||||
{
|
||||
char **newargv;
|
||||
|
||||
if (data->path == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
|
||||
newargv = realloc(data->argv, (data->argc + 2) * sizeof(char *));
|
||||
if (newargv == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
data->argv = newargv;
|
||||
data->argv[data->argc] = strdup(arg);
|
||||
if (data->argv[data->argc] == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
/* Set the terminator of argv. */
|
||||
data->argv[++data->argc] = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
struct archive_cmdline *
|
||||
__archive_cmdline_allocate(void)
|
||||
{
|
||||
return (struct archive_cmdline *)
|
||||
calloc(1, sizeof(struct archive_cmdline));
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the resources.
|
||||
*/
|
||||
int
|
||||
__archive_cmdline_free(struct archive_cmdline *data)
|
||||
{
|
||||
|
||||
if (data) {
|
||||
free(data->path);
|
||||
if (data->argv != NULL) {
|
||||
int i;
|
||||
for (i = 0; data->argv[i] != NULL; i++)
|
||||
free(data->argv[i]);
|
||||
free(data->argv);
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
47
libarchive/archive_cmdline_private.h
Normal file
47
libarchive/archive_cmdline_private.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_CMDLINE_PRIVATE_H
|
||||
#define ARCHIVE_CMDLINE_PRIVATE_H
|
||||
|
||||
struct archive_cmdline {
|
||||
char *path;
|
||||
char **argv;
|
||||
int argc;
|
||||
};
|
||||
|
||||
struct archive_cmdline *__archive_cmdline_allocate(void);
|
||||
int __archive_cmdline_parse(struct archive_cmdline *, const char *);
|
||||
int __archive_cmdline_free(struct archive_cmdline *);
|
||||
|
||||
#endif
|
@ -90,7 +90,7 @@ win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
|
||||
static int
|
||||
win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
|
||||
{
|
||||
DWORD siglen = bufsize;
|
||||
DWORD siglen = (DWORD)bufsize;
|
||||
|
||||
if (!ctx->valid)
|
||||
return (ARCHIVE_FAILED);
|
||||
@ -1222,8 +1222,10 @@ __archive_stub_sha512final(archive_sha512_ctx *ctx, void *md)
|
||||
* 2. libc2
|
||||
* 3. libc3
|
||||
* 4. libSystem
|
||||
* 5. OpenSSL
|
||||
* 6. Windows API
|
||||
* 5. Nettle
|
||||
* 6. OpenSSL
|
||||
* 7. libmd
|
||||
* 8. Windows API
|
||||
*/
|
||||
const struct archive_crypto __archive_crypto =
|
||||
{
|
||||
|
@ -1449,6 +1449,9 @@ static struct flag {
|
||||
{ "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0 },
|
||||
{ "nouunlink", L"nouunlink", UF_NOUNLINK, 0 },
|
||||
#endif
|
||||
#ifdef UF_COMPRESSED
|
||||
{ "nocompressed",L"nocompressed", UF_COMPRESSED, 0 },
|
||||
#endif
|
||||
#ifdef EXT2_UNRM_FL
|
||||
{ "nouunlink", L"nouunlink", EXT2_UNRM_FL, 0},
|
||||
#endif
|
||||
|
@ -29,7 +29,7 @@
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3000004
|
||||
#define ARCHIVE_VERSION_NUMBER 3001002
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
|
@ -244,6 +244,9 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
|
||||
* for future use.
|
||||
*/
|
||||
le = insert_entry(res, *e);
|
||||
if (le == NULL)
|
||||
/* XXX We should return an error code XXX */
|
||||
return;
|
||||
le->entry = *e;
|
||||
*e = NULL;
|
||||
}
|
||||
|
@ -1376,6 +1376,7 @@ add_entry(struct archive_match *a, int flag,
|
||||
archive_mstring_copy_wcs(&(f->pathname), pathname);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_wcs;
|
||||
#else
|
||||
(void)rb_ops_wcs;
|
||||
pathname = archive_entry_pathname(entry);
|
||||
if (pathname == NULL) {
|
||||
free(f);
|
||||
@ -1515,6 +1516,7 @@ time_excluded(struct archive_match *a, struct archive_entry *entry)
|
||||
pathname = archive_entry_pathname_w(entry);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_wcs;
|
||||
#else
|
||||
(void)rb_ops_wcs;
|
||||
pathname = archive_entry_pathname(entry);
|
||||
a->exclusion_tree.rbt_ops = &rb_ops_mbs;
|
||||
#endif
|
||||
@ -1675,13 +1677,16 @@ add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
|
||||
unsigned i;
|
||||
|
||||
if (ids->count + 1 >= ids->size) {
|
||||
void *p;
|
||||
|
||||
if (ids->size == 0)
|
||||
ids->size = 8;
|
||||
else
|
||||
ids->size *= 2;
|
||||
ids->ids = realloc(ids->ids, sizeof(*ids->ids) * ids->size);
|
||||
if (ids->ids == NULL)
|
||||
p = realloc(ids->ids, sizeof(*ids->ids) * ids->size);
|
||||
if (p == NULL)
|
||||
return (error_nomem(a));
|
||||
ids->ids = (int64_t *)p;
|
||||
}
|
||||
|
||||
/* Find an insert point. */
|
||||
@ -1709,7 +1714,7 @@ match_owner_id(struct id_array *ids, int64_t id)
|
||||
unsigned b, m, t;
|
||||
|
||||
t = 0;
|
||||
b = ids->count;
|
||||
b = (unsigned)ids->count;
|
||||
while (t < b) {
|
||||
m = (t + b)>>1;
|
||||
if (ids->ids[m] == id)
|
||||
|
@ -87,6 +87,8 @@ _archive_set_either_option(struct archive *a, const char *m, const char *o, cons
|
||||
if (r2 == ARCHIVE_FATAL)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
if (r2 == ARCHIVE_WARN - 1)
|
||||
return r1;
|
||||
return r1 > r2 ? r1 : r2;
|
||||
}
|
||||
|
||||
@ -94,7 +96,7 @@ int
|
||||
_archive_set_options(struct archive *a, const char *options,
|
||||
int magic, const char *fn, option_handler use_option)
|
||||
{
|
||||
int allok = 1, anyok = 0, r;
|
||||
int allok = 1, anyok = 0, ignore_mod_err = 0, r;
|
||||
char *data;
|
||||
const char *s, *mod, *opt, *val;
|
||||
|
||||
@ -111,6 +113,15 @@ _archive_set_options(struct archive *a, const char *options,
|
||||
mod = opt = val = NULL;
|
||||
|
||||
parse_option(&s, &mod, &opt, &val);
|
||||
if (mod == NULL && opt != NULL &&
|
||||
strcmp("__ignore_wrong_module_name__", opt) == 0) {
|
||||
/* Ignore module name error */
|
||||
if (val != NULL) {
|
||||
ignore_mod_err = 1;
|
||||
anyok = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
r = use_option(a, mod, opt, val);
|
||||
if (r == ARCHIVE_FATAL) {
|
||||
@ -122,6 +133,8 @@ _archive_set_options(struct archive *a, const char *options,
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (r == ARCHIVE_WARN - 1) {
|
||||
if (ignore_mod_err)
|
||||
continue;
|
||||
/* The module name is wrong. */
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unknown module name: `%s'", mod);
|
||||
|
@ -990,7 +990,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
|
||||
p->Cache = (Byte)((UInt32)p->Low >> 24);
|
||||
}
|
||||
p->CacheSize++;
|
||||
p->Low = (UInt32)p->Low << 8;
|
||||
p->Low = ((UInt32)p->Low << 8) & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
|
||||
|
@ -134,6 +134,7 @@ int __archive_check_magic(struct archive *, unsigned int magic,
|
||||
|
||||
void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
|
||||
|
||||
void __archive_ensure_cloexec_flag(int fd);
|
||||
int __archive_mktemp(const char *tmpdir);
|
||||
|
||||
int __archive_clean(struct archive *);
|
||||
|
@ -237,6 +237,8 @@ __archive_rb_tree_reparent_nodes(
|
||||
struct archive_rb_node * const new_father = old_child;
|
||||
struct archive_rb_node * const new_child = old_father;
|
||||
|
||||
if (new_father == NULL)
|
||||
return;
|
||||
/*
|
||||
* Exchange descendant linkages.
|
||||
*/
|
||||
@ -552,6 +554,8 @@ __archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt,
|
||||
unsigned int other = which ^ RB_DIR_OTHER;
|
||||
struct archive_rb_node *brother = parent->rb_nodes[other];
|
||||
|
||||
if (brother == NULL)
|
||||
return;/* The tree may be broken. */
|
||||
/*
|
||||
* For cases 1, 2a, and 2b, our brother's children must
|
||||
* be black and our father must be black
|
||||
@ -573,6 +577,8 @@ __archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt,
|
||||
*/
|
||||
__archive_rb_tree_reparent_nodes(parent, other);
|
||||
brother = parent->rb_nodes[other];
|
||||
if (brother == NULL)
|
||||
return;/* The tree may be broken. */
|
||||
} else {
|
||||
/*
|
||||
* Both our parent and brother are black.
|
||||
@ -656,6 +662,8 @@ __archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt,
|
||||
* If we had two red nephews, then after the swap,
|
||||
* our former father would have a red grandson.
|
||||
*/
|
||||
if (brother->rb_nodes[other] == NULL)
|
||||
return;/* The tree may be broken. */
|
||||
RB_MARK_BLACK(brother->rb_nodes[other]);
|
||||
__archive_rb_tree_reparent_nodes(parent, other);
|
||||
break; /* We're done! */
|
||||
|
@ -57,8 +57,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read.c 201157 2009-12-29 05:30:2
|
||||
|
||||
static int choose_filters(struct archive_read *);
|
||||
static int choose_format(struct archive_read *);
|
||||
static void free_filters(struct archive_read *);
|
||||
static int close_filters(struct archive_read *);
|
||||
static struct archive_vtable *archive_read_vtable(void);
|
||||
static int64_t _archive_filter_bytes(struct archive *, int);
|
||||
static int _archive_filter_code(struct archive *, int);
|
||||
@ -194,8 +192,8 @@ client_skip_proxy(struct archive_read_filter *self, int64_t request)
|
||||
int64_t get, ask = request;
|
||||
if (ask > skip_limit)
|
||||
ask = skip_limit;
|
||||
get = (self->archive->client.skipper)(&self->archive->archive,
|
||||
self->data, ask);
|
||||
get = (self->archive->client.skipper)
|
||||
(&self->archive->archive, self->data, ask);
|
||||
if (get == 0)
|
||||
return (total);
|
||||
request -= get;
|
||||
@ -215,8 +213,8 @@ client_skip_proxy(struct archive_read_filter *self, int64_t request)
|
||||
* only do this for skips of over 64k.
|
||||
*/
|
||||
int64_t before = self->position;
|
||||
int64_t after = (self->archive->client.seeker)(&self->archive->archive,
|
||||
self->data, request, SEEK_CUR);
|
||||
int64_t after = (self->archive->client.seeker)
|
||||
(&self->archive->archive, self->data, request, SEEK_CUR);
|
||||
if (after != before + request)
|
||||
return ARCHIVE_FATAL;
|
||||
return after - before;
|
||||
@ -241,14 +239,64 @@ client_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence)
|
||||
static int
|
||||
client_close_proxy(struct archive_read_filter *self)
|
||||
{
|
||||
int r = ARCHIVE_OK;
|
||||
int r = ARCHIVE_OK, r2;
|
||||
unsigned int i;
|
||||
|
||||
if (self->archive->client.closer != NULL)
|
||||
r = (self->archive->client.closer)((struct archive *)self->archive,
|
||||
self->data);
|
||||
if (self->archive->client.closer == NULL)
|
||||
return (r);
|
||||
for (i = 0; i < self->archive->client.nodes; i++)
|
||||
{
|
||||
r2 = (self->archive->client.closer)
|
||||
((struct archive *)self->archive,
|
||||
self->archive->client.dataset[i].data);
|
||||
if (r > r2)
|
||||
r = r2;
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
|
||||
static int
|
||||
client_open_proxy(struct archive_read_filter *self)
|
||||
{
|
||||
int r = ARCHIVE_OK;
|
||||
if (self->archive->client.opener != NULL)
|
||||
r = (self->archive->client.opener)(
|
||||
(struct archive *)self->archive, self->data);
|
||||
return (r);
|
||||
}
|
||||
|
||||
static int
|
||||
client_switch_proxy(struct archive_read_filter *self, unsigned int iindex)
|
||||
{
|
||||
int r1 = ARCHIVE_OK, r2 = ARCHIVE_OK;
|
||||
void *data2 = NULL;
|
||||
|
||||
/* Don't do anything if already in the specified data node */
|
||||
if (self->archive->client.cursor == iindex)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
self->archive->client.cursor = iindex;
|
||||
data2 = self->archive->client.dataset[self->archive->client.cursor].data;
|
||||
if (self->archive->client.switcher != NULL)
|
||||
{
|
||||
r1 = r2 = (self->archive->client.switcher)
|
||||
((struct archive *)self->archive, self->data, data2);
|
||||
self->data = data2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Attempt to call close and open instead */
|
||||
if (self->archive->client.closer != NULL)
|
||||
r1 = (self->archive->client.closer)
|
||||
((struct archive *)self->archive, self->data);
|
||||
self->data = data2;
|
||||
if (self->archive->client.opener != NULL)
|
||||
r2 = (self->archive->client.opener)
|
||||
((struct archive *)self->archive, self->data);
|
||||
}
|
||||
return (r1 < r2) ? r1 : r2;
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_set_open_callback(struct archive *_a,
|
||||
archive_open_callback *client_opener)
|
||||
@ -305,21 +353,109 @@ archive_read_set_close_callback(struct archive *_a,
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_set_callback_data(struct archive *_a, void *client_data)
|
||||
archive_read_set_switch_callback(struct archive *_a,
|
||||
archive_switch_callback *client_switcher)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_set_callback_data");
|
||||
a->client.data = client_data;
|
||||
"archive_read_set_switch_callback");
|
||||
a->client.switcher = client_switcher;
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_set_callback_data(struct archive *_a, void *client_data)
|
||||
{
|
||||
return archive_read_set_callback_data2(_a, client_data, 0);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_set_callback_data2(struct archive *_a, void *client_data,
|
||||
unsigned int iindex)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_set_callback_data2");
|
||||
|
||||
if (a->client.nodes == 0)
|
||||
{
|
||||
a->client.dataset = (struct archive_read_data_node *)
|
||||
calloc(1, sizeof(*a->client.dataset));
|
||||
if (a->client.dataset == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory.");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
a->client.nodes = 1;
|
||||
}
|
||||
|
||||
if (iindex > a->client.nodes - 1)
|
||||
{
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
"Invalid index specified.");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
a->client.dataset[iindex].data = client_data;
|
||||
a->client.dataset[iindex].begin_position = -1;
|
||||
a->client.dataset[iindex].total_size = -1;
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_add_callback_data(struct archive *_a, void *client_data,
|
||||
unsigned int iindex)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
void *p;
|
||||
unsigned int i;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_add_callback_data");
|
||||
if (iindex > a->client.nodes) {
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
"Invalid index specified.");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
p = realloc(a->client.dataset, sizeof(*a->client.dataset)
|
||||
* (++(a->client.nodes)));
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory.");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
a->client.dataset = (struct archive_read_data_node *)p;
|
||||
for (i = a->client.nodes - 1; i > iindex && i > 0; i--) {
|
||||
a->client.dataset[i].data = a->client.dataset[i-1].data;
|
||||
a->client.dataset[i].begin_position = -1;
|
||||
a->client.dataset[i].total_size = -1;
|
||||
}
|
||||
a->client.dataset[iindex].data = client_data;
|
||||
a->client.dataset[iindex].begin_position = -1;
|
||||
a->client.dataset[iindex].total_size = -1;
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_append_callback_data(struct archive *_a, void *client_data)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
return archive_read_add_callback_data(_a, client_data, a->client.nodes);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_prepend_callback_data(struct archive *_a, void *client_data)
|
||||
{
|
||||
return archive_read_add_callback_data(_a, client_data, 0);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_open1(struct archive *_a)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter *filter;
|
||||
struct archive_read_filter *filter, *tmp;
|
||||
int slot, e;
|
||||
unsigned int i;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_open");
|
||||
@ -334,11 +470,14 @@ archive_read_open1(struct archive *_a)
|
||||
|
||||
/* Open data source. */
|
||||
if (a->client.opener != NULL) {
|
||||
e =(a->client.opener)(&a->archive, a->client.data);
|
||||
e = (a->client.opener)(&a->archive, a->client.dataset[0].data);
|
||||
if (e != 0) {
|
||||
/* If the open failed, call the closer to clean up. */
|
||||
if (a->client.closer)
|
||||
(a->client.closer)(&a->archive, a->client.data);
|
||||
if (a->client.closer) {
|
||||
for (i = 0; i < a->client.nodes; i++)
|
||||
(a->client.closer)(&a->archive,
|
||||
a->client.dataset[i].data);
|
||||
}
|
||||
return (e);
|
||||
}
|
||||
}
|
||||
@ -349,31 +488,51 @@ archive_read_open1(struct archive *_a)
|
||||
filter->bidder = NULL;
|
||||
filter->upstream = NULL;
|
||||
filter->archive = a;
|
||||
filter->data = a->client.data;
|
||||
filter->data = a->client.dataset[0].data;
|
||||
filter->open = client_open_proxy;
|
||||
filter->read = client_read_proxy;
|
||||
filter->skip = client_skip_proxy;
|
||||
filter->seek = client_seek_proxy;
|
||||
filter->close = client_close_proxy;
|
||||
filter->sswitch = client_switch_proxy;
|
||||
filter->name = "none";
|
||||
filter->code = ARCHIVE_COMPRESSION_NONE;
|
||||
a->filter = filter;
|
||||
filter->code = ARCHIVE_FILTER_NONE;
|
||||
|
||||
/* Build out the input pipeline. */
|
||||
e = choose_filters(a);
|
||||
if (e < ARCHIVE_WARN) {
|
||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||
return (ARCHIVE_FATAL);
|
||||
a->client.dataset[0].begin_position = 0;
|
||||
if (!a->filter || !a->bypass_filter_bidding)
|
||||
{
|
||||
a->filter = filter;
|
||||
/* Build out the input pipeline. */
|
||||
e = choose_filters(a);
|
||||
if (e < ARCHIVE_WARN) {
|
||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Need to add "NONE" type filter at the end of the filter chain */
|
||||
tmp = a->filter;
|
||||
while (tmp->upstream)
|
||||
tmp = tmp->upstream;
|
||||
tmp->upstream = filter;
|
||||
}
|
||||
|
||||
slot = choose_format(a);
|
||||
if (slot < 0) {
|
||||
close_filters(a);
|
||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||
return (ARCHIVE_FATAL);
|
||||
if (!a->format)
|
||||
{
|
||||
slot = choose_format(a);
|
||||
if (slot < 0) {
|
||||
__archive_read_close_filters(a);
|
||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
a->format = &(a->formats[slot]);
|
||||
}
|
||||
a->format = &(a->formats[slot]);
|
||||
|
||||
a->archive.state = ARCHIVE_STATE_HEADER;
|
||||
|
||||
/* Ensure libarchive starts from the first node in a multivolume set */
|
||||
client_switch_proxy(a->filter, 0);
|
||||
return (e);
|
||||
}
|
||||
|
||||
@ -413,8 +572,8 @@ choose_filters(struct archive_read *a)
|
||||
/* Verify the filter by asking it for some data. */
|
||||
__archive_read_filter_ahead(a->filter, 1, &avail);
|
||||
if (avail < 0) {
|
||||
close_filters(a);
|
||||
free_filters(a);
|
||||
__archive_read_close_filters(a);
|
||||
__archive_read_free_filters(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
a->archive.compression_name = a->filter->name;
|
||||
@ -432,8 +591,8 @@ choose_filters(struct archive_read *a)
|
||||
a->filter = filter;
|
||||
r = (best_bidder->init)(a->filter);
|
||||
if (r != ARCHIVE_OK) {
|
||||
close_filters(a);
|
||||
free_filters(a);
|
||||
__archive_read_close_filters(a);
|
||||
__archive_read_free_filters(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
@ -501,6 +660,9 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
|
||||
|
||||
a->read_data_output_offset = 0;
|
||||
a->read_data_remaining = 0;
|
||||
a->read_data_is_posix_read = 0;
|
||||
a->read_data_requested = 0;
|
||||
a->data_start_node = a->client.cursor;
|
||||
/* EOF always wins; otherwise return the worst error. */
|
||||
return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1;
|
||||
}
|
||||
@ -611,6 +773,8 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
|
||||
while (s > 0) {
|
||||
if (a->read_data_remaining == 0) {
|
||||
read_buf = a->read_data_block;
|
||||
a->read_data_is_posix_read = 1;
|
||||
a->read_data_requested = s;
|
||||
r = _archive_read_data_block(&a->archive, &read_buf,
|
||||
&a->read_data_remaining, &a->read_data_offset);
|
||||
a->read_data_block = read_buf;
|
||||
@ -664,6 +828,8 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
|
||||
bytes_read += len;
|
||||
}
|
||||
}
|
||||
a->read_data_is_posix_read = 0;
|
||||
a->read_data_requested = 0;
|
||||
return (bytes_read);
|
||||
}
|
||||
|
||||
@ -698,6 +864,23 @@ archive_read_data_skip(struct archive *_a)
|
||||
return (r);
|
||||
}
|
||||
|
||||
int64_t
|
||||
archive_seek_data(struct archive *_a, int64_t offset, int whence)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
|
||||
"archive_seek_data_block");
|
||||
|
||||
if (a->format->seek_data == NULL) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: "
|
||||
"No format_seek_data_block function registered");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
return (a->format->seek_data)(a, offset, whence);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the next block of entry data from the archive.
|
||||
* This is a zero-copy interface; the client receives a pointer,
|
||||
@ -724,8 +907,8 @@ _archive_read_data_block(struct archive *_a,
|
||||
return (a->format->read_data)(a, buff, size, offset);
|
||||
}
|
||||
|
||||
static int
|
||||
close_filters(struct archive_read *a)
|
||||
int
|
||||
__archive_read_close_filters(struct archive_read *a)
|
||||
{
|
||||
struct archive_read_filter *f = a->filter;
|
||||
int r = ARCHIVE_OK;
|
||||
@ -745,8 +928,8 @@ close_filters(struct archive_read *a)
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
free_filters(struct archive_read *a)
|
||||
void
|
||||
__archive_read_free_filters(struct archive_read *a)
|
||||
{
|
||||
while (a->filter != NULL) {
|
||||
struct archive_read_filter *t = a->filter->upstream;
|
||||
@ -790,7 +973,7 @@ _archive_read_close(struct archive *_a)
|
||||
/* TODO: Clean up the formatters. */
|
||||
|
||||
/* Release the filter objects. */
|
||||
r1 = close_filters(a);
|
||||
r1 = __archive_read_close_filters(a);
|
||||
if (r1 < r)
|
||||
r = r1;
|
||||
|
||||
@ -829,7 +1012,7 @@ _archive_read_free(struct archive *_a)
|
||||
}
|
||||
|
||||
/* Free the filters */
|
||||
free_filters(a);
|
||||
__archive_read_free_filters(a);
|
||||
|
||||
/* Release the bidder objects. */
|
||||
n = sizeof(a->bidders)/sizeof(a->bidders[0]);
|
||||
@ -846,6 +1029,7 @@ _archive_read_free(struct archive *_a)
|
||||
archive_entry_free(a->entry);
|
||||
a->archive.magic = 0;
|
||||
__archive_clean(&a->archive);
|
||||
free(a->client.dataset);
|
||||
free(a);
|
||||
return (r);
|
||||
}
|
||||
@ -855,7 +1039,8 @@ get_filter(struct archive *_a, int n)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter *f = a->filter;
|
||||
/* We use n == -1 for 'the last filter', which is always the client proxy. */
|
||||
/* We use n == -1 for 'the last filter', which is always the
|
||||
* client proxy. */
|
||||
if (n == -1 && f != NULL) {
|
||||
struct archive_read_filter *last = f;
|
||||
f = f->upstream;
|
||||
@ -908,6 +1093,7 @@ __archive_read_register_format(struct archive_read *a,
|
||||
int (*read_header)(struct archive_read *, struct archive_entry *),
|
||||
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
|
||||
int (*read_data_skip)(struct archive_read *),
|
||||
int64_t (*seek_data)(struct archive_read *, int64_t, int),
|
||||
int (*cleanup)(struct archive_read *))
|
||||
{
|
||||
int i, number_slots;
|
||||
@ -927,6 +1113,7 @@ __archive_read_register_format(struct archive_read *a,
|
||||
a->formats[i].read_header = read_header;
|
||||
a->formats[i].read_data = read_data;
|
||||
a->formats[i].read_data_skip = read_data_skip;
|
||||
a->formats[i].seek_data = seek_data;
|
||||
a->formats[i].cleanup = cleanup;
|
||||
a->formats[i].data = format_data;
|
||||
a->formats[i].name = name;
|
||||
@ -1073,7 +1260,8 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
|
||||
if (filter->next > filter->buffer &&
|
||||
filter->next + min > filter->buffer + filter->buffer_size) {
|
||||
if (filter->avail > 0)
|
||||
memmove(filter->buffer, filter->next, filter->avail);
|
||||
memmove(filter->buffer, filter->next,
|
||||
filter->avail);
|
||||
filter->next = filter->buffer;
|
||||
}
|
||||
|
||||
@ -1088,15 +1276,26 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
|
||||
&filter->client_buff);
|
||||
if (bytes_read < 0) { /* Read error. */
|
||||
filter->client_total = filter->client_avail = 0;
|
||||
filter->client_next = filter->client_buff = NULL;
|
||||
filter->client_next =
|
||||
filter->client_buff = NULL;
|
||||
filter->fatal = 1;
|
||||
if (avail != NULL)
|
||||
*avail = ARCHIVE_FATAL;
|
||||
return (NULL);
|
||||
}
|
||||
if (bytes_read == 0) { /* Premature end-of-file. */
|
||||
if (bytes_read == 0) {
|
||||
/* Check for another client object first */
|
||||
if (filter->archive->client.cursor !=
|
||||
filter->archive->client.nodes - 1) {
|
||||
if (client_switch_proxy(filter,
|
||||
filter->archive->client.cursor + 1)
|
||||
== ARCHIVE_OK)
|
||||
continue;
|
||||
}
|
||||
/* Premature end-of-file. */
|
||||
filter->client_total = filter->client_avail = 0;
|
||||
filter->client_next = filter->client_buff = NULL;
|
||||
filter->client_next =
|
||||
filter->client_buff = NULL;
|
||||
filter->end_of_file = 1;
|
||||
/* Return whatever we do have. */
|
||||
if (avail != NULL)
|
||||
@ -1106,9 +1305,7 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
|
||||
filter->client_total = bytes_read;
|
||||
filter->client_avail = filter->client_total;
|
||||
filter->client_next = filter->client_buff;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/*
|
||||
* We can't satisfy the request from the copy
|
||||
* buffer or the existing client data, so we
|
||||
@ -1129,9 +1326,10 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
|
||||
t *= 2;
|
||||
if (t <= s) { /* Integer overflow! */
|
||||
archive_set_error(
|
||||
&filter->archive->archive,
|
||||
ENOMEM,
|
||||
"Unable to allocate copy buffer");
|
||||
&filter->archive->archive,
|
||||
ENOMEM,
|
||||
"Unable to allocate copy"
|
||||
" buffer");
|
||||
filter->fatal = 1;
|
||||
if (avail != NULL)
|
||||
*avail = ARCHIVE_FATAL;
|
||||
@ -1170,8 +1368,8 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
|
||||
if (tocopy > filter->client_avail)
|
||||
tocopy = filter->client_avail;
|
||||
|
||||
memcpy(filter->next + filter->avail, filter->client_next,
|
||||
tocopy);
|
||||
memcpy(filter->next + filter->avail,
|
||||
filter->client_next, tocopy);
|
||||
/* Remove this data from client buffer. */
|
||||
filter->client_next += tocopy;
|
||||
filter->client_avail -= tocopy;
|
||||
@ -1274,6 +1472,13 @@ advance_file_pointer(struct archive_read_filter *filter, int64_t request)
|
||||
}
|
||||
|
||||
if (bytes_read == 0) {
|
||||
if (filter->archive->client.cursor !=
|
||||
filter->archive->client.nodes - 1) {
|
||||
if (client_switch_proxy(filter,
|
||||
filter->archive->client.cursor + 1)
|
||||
== ARCHIVE_OK)
|
||||
continue;
|
||||
}
|
||||
filter->client_buff = NULL;
|
||||
filter->end_of_file = 1;
|
||||
return (total_bytes_skipped);
|
||||
@ -1305,15 +1510,109 @@ __archive_read_seek(struct archive_read *a, int64_t offset, int whence)
|
||||
}
|
||||
|
||||
int64_t
|
||||
__archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset, int whence)
|
||||
__archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset,
|
||||
int whence)
|
||||
{
|
||||
struct archive_read_client *client;
|
||||
int64_t r;
|
||||
unsigned int cursor;
|
||||
|
||||
if (filter->closed || filter->fatal)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (filter->seek == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
r = filter->seek(filter, offset, whence);
|
||||
|
||||
client = &(filter->archive->client);
|
||||
switch (whence) {
|
||||
case SEEK_CUR:
|
||||
/* Adjust the offset and use SEEK_SET instead */
|
||||
offset += filter->position;
|
||||
case SEEK_SET:
|
||||
cursor = 0;
|
||||
while (1)
|
||||
{
|
||||
if (client->dataset[cursor].begin_position < 0 ||
|
||||
client->dataset[cursor].total_size < 0 ||
|
||||
client->dataset[cursor].begin_position +
|
||||
client->dataset[cursor].total_size - 1 > offset ||
|
||||
cursor + 1 >= client->nodes)
|
||||
break;
|
||||
r = client->dataset[cursor].begin_position +
|
||||
client->dataset[cursor].total_size;
|
||||
client->dataset[++cursor].begin_position = r;
|
||||
}
|
||||
while (1) {
|
||||
r = client_switch_proxy(filter, cursor);
|
||||
if (r != ARCHIVE_OK)
|
||||
return r;
|
||||
if ((r = client_seek_proxy(filter, 0, SEEK_END)) < 0)
|
||||
return r;
|
||||
client->dataset[cursor].total_size = r;
|
||||
if (client->dataset[cursor].begin_position +
|
||||
client->dataset[cursor].total_size - 1 > offset ||
|
||||
cursor + 1 >= client->nodes)
|
||||
break;
|
||||
r = client->dataset[cursor].begin_position +
|
||||
client->dataset[cursor].total_size;
|
||||
client->dataset[++cursor].begin_position = r;
|
||||
}
|
||||
offset -= client->dataset[cursor].begin_position;
|
||||
if (offset < 0)
|
||||
offset = 0;
|
||||
else if (offset > client->dataset[cursor].total_size - 1)
|
||||
offset = client->dataset[cursor].total_size - 1;
|
||||
if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0)
|
||||
return r;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
cursor = 0;
|
||||
while (1) {
|
||||
if (client->dataset[cursor].begin_position < 0 ||
|
||||
client->dataset[cursor].total_size < 0 ||
|
||||
cursor + 1 >= client->nodes)
|
||||
break;
|
||||
r = client->dataset[cursor].begin_position +
|
||||
client->dataset[cursor].total_size;
|
||||
client->dataset[++cursor].begin_position = r;
|
||||
}
|
||||
while (1) {
|
||||
r = client_switch_proxy(filter, cursor);
|
||||
if (r != ARCHIVE_OK)
|
||||
return r;
|
||||
if ((r = client_seek_proxy(filter, 0, SEEK_END)) < 0)
|
||||
return r;
|
||||
client->dataset[cursor].total_size = r;
|
||||
r = client->dataset[cursor].begin_position +
|
||||
client->dataset[cursor].total_size;
|
||||
if (cursor + 1 >= client->nodes)
|
||||
break;
|
||||
client->dataset[++cursor].begin_position = r;
|
||||
}
|
||||
while (1) {
|
||||
if (r + offset >=
|
||||
client->dataset[cursor].begin_position)
|
||||
break;
|
||||
offset += client->dataset[cursor].total_size;
|
||||
if (cursor == 0)
|
||||
break;
|
||||
cursor--;
|
||||
r = client->dataset[cursor].begin_position +
|
||||
client->dataset[cursor].total_size;
|
||||
}
|
||||
offset = (r + offset) - client->dataset[cursor].begin_position;
|
||||
if ((r = client_switch_proxy(filter, cursor)) != ARCHIVE_OK)
|
||||
return r;
|
||||
r = client_seek_proxy(filter, offset, SEEK_SET);
|
||||
if (r < ARCHIVE_OK)
|
||||
return r;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
r += client->dataset[cursor].begin_position;
|
||||
|
||||
if (r >= 0) {
|
||||
/*
|
||||
* Ouch. Clearing the buffer like this hurts, especially
|
||||
|
198
libarchive/archive_read_append_filter.c
Normal file
198
libarchive/archive_read_append_filter.c
Normal file
@ -0,0 +1,198 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2012 Tim Kientzle
|
||||
* 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"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
int
|
||||
archive_read_append_filter(struct archive *_a, int code)
|
||||
{
|
||||
int r1, r2, number_bidders, i;
|
||||
char str[20];
|
||||
struct archive_read_filter_bidder *bidder;
|
||||
struct archive_read_filter *filter;
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
|
||||
r1 = r2 = (ARCHIVE_OK);
|
||||
switch (code)
|
||||
{
|
||||
case ARCHIVE_FILTER_NONE:
|
||||
/* No filter to add, so do nothing.
|
||||
* NOTE: An initial "NONE" type filter is always set at the end of the
|
||||
* filter chain.
|
||||
*/
|
||||
r1 = (ARCHIVE_OK);
|
||||
break;
|
||||
case ARCHIVE_FILTER_GZIP:
|
||||
strcpy(str, "gzip");
|
||||
r1 = archive_read_support_filter_gzip(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_BZIP2:
|
||||
strcpy(str, "bzip2");
|
||||
r1 = archive_read_support_filter_bzip2(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_COMPRESS:
|
||||
strcpy(str, "compress (.Z)");
|
||||
r1 = archive_read_support_filter_compress(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_PROGRAM:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Cannot append program filter using archive_read_append_filter");
|
||||
return (ARCHIVE_FATAL);
|
||||
case ARCHIVE_FILTER_LZMA:
|
||||
strcpy(str, "lzma");
|
||||
r1 = archive_read_support_filter_lzma(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_XZ:
|
||||
strcpy(str, "xz");
|
||||
r1 = archive_read_support_filter_xz(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_UU:
|
||||
strcpy(str, "uu");
|
||||
r1 = archive_read_support_filter_uu(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_RPM:
|
||||
strcpy(str, "rpm");
|
||||
r1 = archive_read_support_filter_rpm(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZIP:
|
||||
strcpy(str, "lzip");
|
||||
r1 = archive_read_support_filter_lzip(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LRZIP:
|
||||
strcpy(str, "lrzip");
|
||||
r1 = archive_read_support_filter_lrzip(_a);
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Invalid filter code specified");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
if (code != ARCHIVE_FILTER_NONE)
|
||||
{
|
||||
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
|
||||
|
||||
bidder = a->bidders;
|
||||
for (i = 0; i < number_bidders; i++, bidder++)
|
||||
{
|
||||
if (!bidder->name || !strcmp(bidder->name, str))
|
||||
break;
|
||||
}
|
||||
if (!bidder->name || strcmp(bidder->name, str))
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: Unable to append filter");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
filter
|
||||
= (struct archive_read_filter *)calloc(1, sizeof(*filter));
|
||||
if (filter == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
filter->bidder = bidder;
|
||||
filter->archive = a;
|
||||
filter->upstream = a->filter;
|
||||
a->filter = filter;
|
||||
r2 = (bidder->init)(a->filter);
|
||||
if (r2 != ARCHIVE_OK) {
|
||||
__archive_read_close_filters(a);
|
||||
__archive_read_free_filters(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
a->bypass_filter_bidding = 1;
|
||||
return (r1 < r2) ? r1 : r2;
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_append_filter_program(struct archive *_a, const char *cmd)
|
||||
{
|
||||
return (archive_read_append_filter_program_signature(_a, cmd, NULL, 0));
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_append_filter_program_signature(struct archive *_a,
|
||||
const char *cmd, const void *signature, size_t signature_len)
|
||||
{
|
||||
int r, number_bidders, i;
|
||||
struct archive_read_filter_bidder *bidder;
|
||||
struct archive_read_filter *filter;
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
|
||||
if (archive_read_support_filter_program_signature(_a, cmd, signature,
|
||||
signature_len) != (ARCHIVE_OK))
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
|
||||
|
||||
bidder = a->bidders;
|
||||
for (i = 0; i < number_bidders; i++, bidder++)
|
||||
{
|
||||
/* Program bidder name set to filter name after initialization */
|
||||
if (bidder->data && !bidder->name)
|
||||
break;
|
||||
}
|
||||
if (!bidder->data)
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: Unable to append program filter");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
filter
|
||||
= (struct archive_read_filter *)calloc(1, sizeof(*filter));
|
||||
if (filter == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
filter->bidder = bidder;
|
||||
filter->archive = a;
|
||||
filter->upstream = a->filter;
|
||||
a->filter = filter;
|
||||
r = (bidder->init)(a->filter);
|
||||
if (r != ARCHIVE_OK) {
|
||||
__archive_read_close_filters(a);
|
||||
__archive_read_free_filters(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
bidder->name = a->filter->name;
|
||||
|
||||
a->bypass_filter_bidding = 1;
|
||||
return r;
|
||||
}
|
@ -49,8 +49,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_XATTR_H
|
||||
#if defined(HAVE_SYS_XATTR_H)
|
||||
#include <sys/xattr.h>
|
||||
#elif defined(HAVE_ATTR_XATTR_H)
|
||||
#include <attr/xattr.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_EA_H
|
||||
#include <sys/ea.h>
|
||||
@ -58,9 +60,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
|
||||
#ifdef HAVE_ACL_LIBACL_H
|
||||
#include <acl/libacl.h>
|
||||
#endif
|
||||
#ifdef HAVE_ATTR_XATTR_H
|
||||
#include <attr/xattr.h>
|
||||
#endif
|
||||
#ifdef HAVE_COPYFILE_H
|
||||
#include <copyfile.h>
|
||||
#endif
|
||||
@ -104,6 +103,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Linux and FreeBSD plug this obvious hole in POSIX.1e in
|
||||
* different ways.
|
||||
@ -114,7 +117,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
|
||||
#define ACL_GET_PERM acl_get_perm_np
|
||||
#endif
|
||||
|
||||
static int setup_acls_posix1e(struct archive_read_disk *,
|
||||
static int setup_acls(struct archive_read_disk *,
|
||||
struct archive_entry *, int *fd);
|
||||
static int setup_mac_metadata(struct archive_read_disk *,
|
||||
struct archive_entry *, int *fd);
|
||||
@ -168,15 +171,16 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
st = &s;
|
||||
}
|
||||
archive_entry_copy_stat(entry, st);
|
||||
/* Lookup uname/gname */
|
||||
name = archive_read_disk_uname(_a, archive_entry_uid(entry));
|
||||
if (name != NULL)
|
||||
archive_entry_copy_uname(entry, name);
|
||||
name = archive_read_disk_gname(_a, archive_entry_gid(entry));
|
||||
if (name != NULL)
|
||||
archive_entry_copy_gname(entry, name);
|
||||
}
|
||||
|
||||
/* Lookup uname/gname */
|
||||
name = archive_read_disk_uname(_a, archive_entry_uid(entry));
|
||||
if (name != NULL)
|
||||
archive_entry_copy_uname(entry, name);
|
||||
name = archive_read_disk_gname(_a, archive_entry_gid(entry));
|
||||
if (name != NULL)
|
||||
archive_entry_copy_gname(entry, name);
|
||||
|
||||
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
|
||||
/* On FreeBSD, we get flags for free with the stat. */
|
||||
/* TODO: Does this belong in copy_stat()? */
|
||||
@ -192,12 +196,14 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
if (fd < 0) {
|
||||
if (a->tree != NULL)
|
||||
fd = a->open_on_current_dir(a->tree, path,
|
||||
O_RDONLY | O_NONBLOCK);
|
||||
O_RDONLY | O_NONBLOCK | O_CLOEXEC);
|
||||
else
|
||||
fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||
fd = open(path, O_RDONLY | O_NONBLOCK |
|
||||
O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(fd);
|
||||
}
|
||||
if (fd >= 0) {
|
||||
unsigned long stflags;
|
||||
int stflags;
|
||||
r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
|
||||
if (r == 0 && stflags != 0)
|
||||
archive_entry_set_fflags(entry, stflags, 0);
|
||||
@ -244,7 +250,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
}
|
||||
#endif /* HAVE_READLINK || HAVE_READLINKAT */
|
||||
|
||||
r = setup_acls_posix1e(a, entry, &fd);
|
||||
r = setup_acls(a, entry, &fd);
|
||||
r1 = setup_xattrs(a, entry, &fd);
|
||||
if (r1 < r)
|
||||
r = r1;
|
||||
@ -285,9 +291,10 @@ setup_mac_metadata(struct archive_read_disk *a,
|
||||
int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR;
|
||||
struct stat copyfile_stat;
|
||||
int ret = ARCHIVE_OK;
|
||||
void *buff;
|
||||
void *buff = NULL;
|
||||
int have_attrs;
|
||||
const char *name, *tempdir, *tempfile = NULL;
|
||||
const char *name, *tempdir;
|
||||
struct archive_string tempfile;
|
||||
|
||||
(void)fd; /* UNUSED */
|
||||
name = archive_entry_sourcepath(entry);
|
||||
@ -322,25 +329,28 @@ setup_mac_metadata(struct archive_read_disk *a,
|
||||
tempdir = getenv("TMPDIR");
|
||||
if (tempdir == NULL)
|
||||
tempdir = _PATH_TMP;
|
||||
tempfile = tempnam(tempdir, "tar.md.");
|
||||
archive_string_init(&tempfile);
|
||||
archive_strcpy(&tempfile, tempdir);
|
||||
archive_strcat(&tempfile, "tar.md.XXXXXX");
|
||||
tempfd = mkstemp(tempfile.s);
|
||||
if (tempfd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Could not open extended attribute file");
|
||||
ret = ARCHIVE_WARN;
|
||||
goto cleanup;
|
||||
}
|
||||
__archive_ensure_cloexec_flag(tempfd);
|
||||
|
||||
/* XXX I wish copyfile() could pack directly to a memory
|
||||
* buffer; that would avoid the temp file here. For that
|
||||
* matter, it would be nice if fcopyfile() actually worked,
|
||||
* that would reduce the many open/close races here. */
|
||||
if (copyfile(name, tempfile, 0, copyfile_flags | COPYFILE_PACK)) {
|
||||
if (copyfile(name, tempfile.s, 0, copyfile_flags | COPYFILE_PACK)) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Could not pack extended attributes");
|
||||
ret = ARCHIVE_WARN;
|
||||
goto cleanup;
|
||||
}
|
||||
tempfd = open(tempfile, O_RDONLY);
|
||||
if (tempfd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Could not open extended attribute file");
|
||||
ret = ARCHIVE_WARN;
|
||||
goto cleanup;
|
||||
}
|
||||
if (fstat(tempfd, ©file_stat)) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Could not check size of extended attributes");
|
||||
@ -363,10 +373,12 @@ setup_mac_metadata(struct archive_read_disk *a,
|
||||
archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size);
|
||||
|
||||
cleanup:
|
||||
if (tempfd >= 0)
|
||||
if (tempfd >= 0) {
|
||||
close(tempfd);
|
||||
if (tempfile != NULL)
|
||||
unlink(tempfile);
|
||||
unlink(tempfile.s);
|
||||
}
|
||||
archive_string_free(&tempfile);
|
||||
free(buff);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -387,16 +399,19 @@ setup_mac_metadata(struct archive_read_disk *a,
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_POSIX_ACL
|
||||
static void setup_acl_posix1e(struct archive_read_disk *a,
|
||||
#if defined(HAVE_POSIX_ACL) && defined(ACL_TYPE_NFS4)
|
||||
static int translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
|
||||
|
||||
static int
|
||||
setup_acls_posix1e(struct archive_read_disk *a,
|
||||
setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
acl_t acl;
|
||||
#if HAVE_ACL_IS_TRIVIAL_NP
|
||||
int r;
|
||||
#endif
|
||||
|
||||
accpath = archive_entry_sourcepath(entry);
|
||||
if (accpath == NULL)
|
||||
@ -404,15 +419,33 @@ setup_acls_posix1e(struct archive_read_disk *a,
|
||||
|
||||
archive_entry_acl_clear(entry);
|
||||
|
||||
if (*fd < 0 && a->tree != NULL &&
|
||||
(a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)){
|
||||
*fd = a->open_on_current_dir(a->tree, accpath,
|
||||
O_RDONLY | O_NONBLOCK);
|
||||
if (*fd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't access %s", accpath);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
/* Try NFS4 ACL first. */
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd(*fd);
|
||||
#if HAVE_ACL_GET_LINK_NP
|
||||
else if (!a->follow_symlinks)
|
||||
acl = acl_get_link_np(accpath, ACL_TYPE_NFS4);
|
||||
#else
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
/* We can't get the ACL of a symlink, so we assume it can't
|
||||
have one. */
|
||||
acl = NULL;
|
||||
#endif
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_NFS4);
|
||||
#if HAVE_ACL_IS_TRIVIAL_NP
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
acl_is_trivial_np(acl, &r);
|
||||
if (r) {
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
}
|
||||
#endif
|
||||
if (acl != NULL) {
|
||||
translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
|
||||
acl_free(acl);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/* Retrieve access ACL from file. */
|
||||
@ -431,7 +464,7 @@ setup_acls_posix1e(struct archive_read_disk *a,
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
|
||||
if (acl != NULL) {
|
||||
setup_acl_posix1e(a, entry, acl,
|
||||
translate_acl(a, entry, acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
acl_free(acl);
|
||||
}
|
||||
@ -440,7 +473,7 @@ setup_acls_posix1e(struct archive_read_disk *a,
|
||||
if (S_ISDIR(archive_entry_mode(entry))) {
|
||||
acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
|
||||
if (acl != NULL) {
|
||||
setup_acl_posix1e(a, entry, acl,
|
||||
translate_acl(a, entry, acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
|
||||
acl_free(acl);
|
||||
}
|
||||
@ -449,68 +482,180 @@ setup_acls_posix1e(struct archive_read_disk *a,
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate POSIX.1e ACL into libarchive internal structure.
|
||||
* Translate system ACL into libarchive internal structure.
|
||||
*/
|
||||
static void
|
||||
setup_acl_posix1e(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type)
|
||||
|
||||
static struct {
|
||||
int archive_perm;
|
||||
int platform_perm;
|
||||
} acl_perm_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
};
|
||||
|
||||
static struct {
|
||||
int archive_inherit;
|
||||
int platform_inherit;
|
||||
} acl_inherit_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
|
||||
};
|
||||
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
|
||||
{
|
||||
acl_tag_t acl_tag;
|
||||
acl_entry_type_t acl_type;
|
||||
acl_flagset_t acl_flagset;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
int brand, i, r, entry_acl_type;
|
||||
int s, ae_id, ae_tag, ae_perm;
|
||||
const char *ae_name;
|
||||
|
||||
|
||||
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
|
||||
// Make sure the "brand" on this ACL is consistent
|
||||
// with the default_entry_acl_type bits provided.
|
||||
acl_get_brand_np(acl, &brand);
|
||||
switch (brand) {
|
||||
case ACL_BRAND_POSIX:
|
||||
switch (default_entry_acl_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
break;
|
||||
default:
|
||||
// XXX set warning message?
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
break;
|
||||
case ACL_BRAND_NFS4:
|
||||
if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
// XXX set warning message?
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// XXX set warning message?
|
||||
return ARCHIVE_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
||||
while (s == 1) {
|
||||
ae_id = -1;
|
||||
ae_name = NULL;
|
||||
ae_perm = 0;
|
||||
|
||||
acl_get_tag_type(acl_entry, &acl_tag);
|
||||
if (acl_tag == ACL_USER) {
|
||||
switch (acl_tag) {
|
||||
case ACL_USER:
|
||||
ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
|
||||
ae_name = archive_read_disk_uname(&a->archive, ae_id);
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
} else if (acl_tag == ACL_GROUP) {
|
||||
break;
|
||||
case ACL_GROUP:
|
||||
ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);
|
||||
ae_name = archive_read_disk_gname(&a->archive, ae_id);
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
} else if (acl_tag == ACL_MASK) {
|
||||
break;
|
||||
case ACL_MASK:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_MASK;
|
||||
} else if (acl_tag == ACL_USER_OBJ) {
|
||||
break;
|
||||
case ACL_USER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
} else if (acl_tag == ACL_GROUP_OBJ) {
|
||||
break;
|
||||
case ACL_GROUP_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
} else if (acl_tag == ACL_OTHER) {
|
||||
break;
|
||||
case ACL_OTHER:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||
} else {
|
||||
break;
|
||||
case ACL_EVERYONE:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||
break;
|
||||
default:
|
||||
/* Skip types that libarchive can't support. */
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
acl_get_permset(acl_entry, &acl_permset);
|
||||
ae_perm = 0;
|
||||
/*
|
||||
* acl_get_perm() is spelled differently on different
|
||||
* platforms; see above.
|
||||
*/
|
||||
if (ACL_GET_PERM(acl_permset, ACL_EXECUTE))
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
if (ACL_GET_PERM(acl_permset, ACL_READ))
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_READ;
|
||||
if (ACL_GET_PERM(acl_permset, ACL_WRITE))
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;
|
||||
// XXX acl type maps to allow/deny/audit/YYYY bits
|
||||
// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
|
||||
// non-NFSv4 ACLs
|
||||
entry_acl_type = default_entry_acl_type;
|
||||
r = acl_get_entry_type_np(acl_entry, &acl_type);
|
||||
if (r == 0) {
|
||||
switch (acl_type) {
|
||||
case ACL_ENTRY_TYPE_ALLOW:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_DENY:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_AUDIT:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_ALARM:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
archive_entry_acl_add_entry(entry,
|
||||
archive_entry_acl_type, ae_perm, ae_tag,
|
||||
ae_id, ae_name);
|
||||
/*
|
||||
* Libarchive stores "flag" (NFSv4 inheritance bits)
|
||||
* in the ae_perm bitmap.
|
||||
*/
|
||||
acl_get_flagset_np(acl_entry, &acl_flagset);
|
||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
|
||||
if (acl_get_flag_np(acl_flagset,
|
||||
acl_inherit_map[i].platform_inherit))
|
||||
ae_perm |= acl_inherit_map[i].archive_inherit;
|
||||
|
||||
}
|
||||
|
||||
acl_get_permset(acl_entry, &acl_permset);
|
||||
for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
|
||||
/*
|
||||
* acl_get_perm() is spelled differently on different
|
||||
* platforms; see above.
|
||||
*/
|
||||
if (ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm))
|
||||
ae_perm |= acl_perm_map[i].archive_perm;
|
||||
}
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag,
|
||||
ae_id, ae_name);
|
||||
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
setup_acls_posix1e(struct archive_read_disk *a,
|
||||
setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
(void)a; /* UNUSED */
|
||||
@ -901,16 +1046,19 @@ setup_sparse(struct archive_read_disk *a,
|
||||
path = archive_entry_pathname(entry);
|
||||
if (a->tree != NULL)
|
||||
*fd = a->open_on_current_dir(a->tree, path,
|
||||
O_RDONLY | O_NONBLOCK);
|
||||
O_RDONLY | O_NONBLOCK | O_CLOEXEC);
|
||||
else
|
||||
*fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||
*fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
|
||||
if (*fd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Can't open `%s'", path);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
__archive_ensure_cloexec_flag(*fd);
|
||||
}
|
||||
|
||||
/* Initialize buffer to avoid the error valgrind complains about. */
|
||||
memset(buff, 0, sizeof(buff));
|
||||
count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe);
|
||||
fm = (struct fiemap *)buff;
|
||||
fm->fm_start = 0;
|
||||
@ -1012,12 +1160,13 @@ setup_sparse(struct archive_read_disk *a,
|
||||
|
||||
if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
|
||||
return (ARCHIVE_OK);
|
||||
*fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||
*fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
|
||||
if (*fd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Can't open `%s'", path);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
__archive_ensure_cloexec_flag(*fd);
|
||||
initial_off = 0;
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,9 @@ __FBSDID("$FreeBSD$");
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
/*-
|
||||
* This is a new directory-walking system that addresses a number
|
||||
@ -361,6 +364,7 @@ static int setup_sparse(struct archive_read_disk *, struct archive_entry *);
|
||||
static int close_and_restore_time(int fd, struct tree *,
|
||||
struct restore_time *);
|
||||
static int open_on_current_dir(struct tree *, const char *, int);
|
||||
static int tree_dup(int);
|
||||
|
||||
|
||||
static struct archive_vtable *
|
||||
@ -717,7 +721,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||
* Open the current file.
|
||||
*/
|
||||
if (t->entry_fd < 0) {
|
||||
int flags = O_RDONLY | O_BINARY;
|
||||
int flags = O_RDONLY | O_BINARY | O_CLOEXEC;
|
||||
|
||||
/*
|
||||
* Eliminate or reduce cache effects if we can.
|
||||
@ -740,6 +744,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||
#endif
|
||||
t->entry_fd = open_on_current_dir(t,
|
||||
tree_current_access_path(t), flags);
|
||||
__archive_ensure_cloexec_flag(t->entry_fd);
|
||||
#if defined(O_NOATIME)
|
||||
/*
|
||||
* When we did open the file with O_NOATIME flag,
|
||||
@ -984,10 +989,12 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
||||
#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) &&\
|
||||
defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
|
||||
if (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) {
|
||||
unsigned long stflags;
|
||||
int stflags;
|
||||
|
||||
t->entry_fd = open_on_current_dir(t,
|
||||
tree_current_access_path(t), O_RDONLY | O_NONBLOCK);
|
||||
tree_current_access_path(t),
|
||||
O_RDONLY | O_NONBLOCK | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(t->entry_fd);
|
||||
if (t->entry_fd >= 0) {
|
||||
r = ioctl(t->entry_fd, EXT2_IOC_GETFLAGS,
|
||||
&stflags);
|
||||
@ -1359,15 +1366,17 @@ update_current_filesystem(struct archive_read_disk *a, int64_t dev)
|
||||
fid = t->max_filesystem_id++;
|
||||
if (t->max_filesystem_id > t->allocated_filesytem) {
|
||||
size_t s;
|
||||
void *p;
|
||||
|
||||
s = t->max_filesystem_id * 2;
|
||||
t->filesystem_table = realloc(t->filesystem_table,
|
||||
s * sizeof(*t->filesystem_table));
|
||||
if (t->filesystem_table == NULL) {
|
||||
p = realloc(t->filesystem_table,
|
||||
s * sizeof(*t->filesystem_table));
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate tar data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
t->filesystem_table = (struct filesystem *)p;
|
||||
t->allocated_filesytem = s;
|
||||
}
|
||||
t->current_filesystem_id = fid;
|
||||
@ -1482,7 +1491,8 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
* where current is.
|
||||
*/
|
||||
int fd = openat(tree_current_dir_fd(t),
|
||||
tree_current_access_path(t), O_RDONLY);
|
||||
tree_current_access_path(t), O_RDONLY | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(fd);
|
||||
if (fd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"openat failed");
|
||||
@ -1660,7 +1670,8 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
* where current is.
|
||||
*/
|
||||
int fd = openat(tree_current_dir_fd(t),
|
||||
tree_current_access_path(t), O_RDONLY);
|
||||
tree_current_access_path(t), O_RDONLY | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(fd);
|
||||
if (fd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"openat failed");
|
||||
@ -1768,7 +1779,8 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
* where current is.
|
||||
*/
|
||||
int fd = openat(tree_current_dir_fd(t),
|
||||
tree_current_access_path(t), O_RDONLY);
|
||||
tree_current_access_path(t), O_RDONLY | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(fd);
|
||||
if (fd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"openat failed");
|
||||
@ -1889,7 +1901,8 @@ static int
|
||||
close_and_restore_time(int fd, struct tree *t, struct restore_time *rt)
|
||||
{
|
||||
#ifndef HAVE_UTIMES
|
||||
(void)a; /* UNUSED */
|
||||
(void)t; /* UNUSED */
|
||||
(void)rt; /* UNUSED */
|
||||
return (close(fd));
|
||||
#else
|
||||
#if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
|
||||
@ -1952,6 +1965,28 @@ open_on_current_dir(struct tree *t, const char *path, int flags)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
tree_dup(int fd)
|
||||
{
|
||||
int new_fd;
|
||||
#ifdef F_DUPFD_CLOEXEC
|
||||
static volatile int can_dupfd_cloexec = 1;
|
||||
|
||||
if (can_dupfd_cloexec) {
|
||||
new_fd = fcntl(fd, F_DUPFD_CLOEXEC);
|
||||
if (new_fd != -1)
|
||||
return (new_fd);
|
||||
/* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,
|
||||
* but it cannot be used. So we have to try dup(). */
|
||||
/* We won't try F_DUPFD_CLOEXEC. */
|
||||
can_dupfd_cloexec = 0;
|
||||
}
|
||||
#endif /* F_DUPFD_CLOEXEC */
|
||||
new_fd = dup(fd);
|
||||
__archive_ensure_cloexec_flag(new_fd);
|
||||
return (new_fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a directory path to the current stack.
|
||||
*/
|
||||
@ -2052,8 +2087,9 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
|
||||
tree_push(t, path, 0, 0, 0, NULL);
|
||||
t->stack->flags = needsFirstVisit;
|
||||
t->maxOpenCount = t->openCount = 1;
|
||||
t->initial_dir_fd = open(".", O_RDONLY);
|
||||
t->working_dir_fd = dup(t->initial_dir_fd);
|
||||
t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(t->initial_dir_fd);
|
||||
t->working_dir_fd = tree_dup(t->initial_dir_fd);
|
||||
return (t);
|
||||
}
|
||||
|
||||
@ -2063,11 +2099,12 @@ tree_descent(struct tree *t)
|
||||
int flag, new_fd, r = 0;
|
||||
|
||||
t->dirname_length = archive_strlen(&t->path);
|
||||
flag = O_RDONLY;
|
||||
flag = O_RDONLY | O_CLOEXEC;
|
||||
#if defined(O_DIRECTORY)
|
||||
flag |= O_DIRECTORY;
|
||||
#endif
|
||||
new_fd = open_on_current_dir(t, t->stack->name.s, flag);
|
||||
__archive_ensure_cloexec_flag(new_fd);
|
||||
if (new_fd < 0) {
|
||||
t->tree_errno = errno;
|
||||
r = TREE_ERROR_DIR;
|
||||
@ -2101,8 +2138,10 @@ tree_ascend(struct tree *t)
|
||||
prev_dir_fd = t->working_dir_fd;
|
||||
if (te->flags & isDirLink)
|
||||
new_fd = te->symlink_parent_fd;
|
||||
else
|
||||
new_fd = open_on_current_dir(t, "..", O_RDONLY);
|
||||
else {
|
||||
new_fd = open_on_current_dir(t, "..", O_RDONLY | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(new_fd);
|
||||
}
|
||||
if (new_fd < 0) {
|
||||
t->tree_errno = errno;
|
||||
r = TREE_ERROR_FATAL;
|
||||
@ -2265,11 +2304,16 @@ tree_dir_next_posix(struct tree *t)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FDOPENDIR)
|
||||
if ((t->d = fdopendir(dup(t->working_dir_fd))) == NULL) {
|
||||
#else
|
||||
if (tree_enter_working_dir(t) != 0 ||
|
||||
(t->d = opendir(".")) == NULL) {
|
||||
t->d = fdopendir(tree_dup(t->working_dir_fd));
|
||||
#else /* HAVE_FDOPENDIR */
|
||||
if (tree_enter_working_dir(t) == 0) {
|
||||
t->d = opendir(".");
|
||||
#if HAVE_DIRFD || defined(dirfd)
|
||||
__archive_ensure_cloexec_flag(dirfd(t->d));
|
||||
#endif
|
||||
}
|
||||
#endif /* HAVE_FDOPENDIR */
|
||||
if (t->d == NULL) {
|
||||
r = tree_ascend(t); /* Undo "chdir" */
|
||||
tree_pop(t);
|
||||
t->tree_errno = errno;
|
||||
@ -2296,11 +2340,21 @@ tree_dir_next_posix(struct tree *t)
|
||||
#endif /* HAVE_READDIR_R */
|
||||
}
|
||||
for (;;) {
|
||||
errno = 0;
|
||||
#if defined(HAVE_READDIR_R)
|
||||
r = readdir_r(t->d, t->dirent, &t->de);
|
||||
#ifdef _AIX
|
||||
/* Note: According to the man page, return value 9 indicates
|
||||
* that the readdir_r was not successful and the error code
|
||||
* is set to the global errno variable. And then if the end
|
||||
* of directory entries was reached, the return value is 9
|
||||
* and the third parameter is set to NULL and errno is
|
||||
* unchanged. */
|
||||
if (r == 9)
|
||||
r = errno;
|
||||
#endif /* _AIX */
|
||||
if (r != 0 || t->de == NULL) {
|
||||
#else
|
||||
errno = 0;
|
||||
t->de = readdir(t->d);
|
||||
if (t->de == NULL) {
|
||||
r = errno;
|
||||
@ -2391,7 +2445,7 @@ tree_current_is_dir(struct tree *t)
|
||||
return 1;
|
||||
/* Not a dir; might be a link to a dir. */
|
||||
/* If it's not a link, then it's not a link to a dir. */
|
||||
if (!S_ISLNK(tree_current_lstat(t)->st_mode))
|
||||
if (!S_ISLNK(st->st_mode))
|
||||
return 0;
|
||||
/*
|
||||
* It's a link, but we don't know what it's a link to,
|
||||
|
@ -597,7 +597,7 @@ start_next_async_read(struct archive_read_disk *a, struct tree *t)
|
||||
} else
|
||||
ResetEvent(olp->ol.hEvent);
|
||||
|
||||
buffbytes = olp->buff_size;
|
||||
buffbytes = (DWORD)olp->buff_size;
|
||||
if (buffbytes > t->current_sparse->length)
|
||||
buffbytes = (DWORD)t->current_sparse->length;
|
||||
|
||||
@ -669,7 +669,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||
struct tree *t = a->tree;
|
||||
struct la_overlapped *olp;
|
||||
DWORD bytes_transferred;
|
||||
int r;
|
||||
int r = ARCHIVE_FATAL;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
|
||||
"archive_read_data_block");
|
||||
@ -698,7 +698,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||
olp = &(t->ol[t->ol_idx_done]);
|
||||
t->ol_idx_done = (t->ol_idx_done + 1) % MAX_OVERLAPPED;
|
||||
if (olp->bytes_transferred)
|
||||
bytes_transferred = olp->bytes_transferred;
|
||||
bytes_transferred = (DWORD)olp->bytes_transferred;
|
||||
else if (!GetOverlappedResult(t->entry_fh, &(olp->ol),
|
||||
&bytes_transferred, TRUE)) {
|
||||
la_dosmaperr(GetLastError());
|
||||
@ -1208,7 +1208,7 @@ _archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
|
||||
a->tree = tree_open(pathname, a->symlink_mode, a->restore_time);
|
||||
if (a->tree == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate direcotry traversal data");
|
||||
"Can't allocate directory traversal data");
|
||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
@ -1257,16 +1257,18 @@ update_current_filesystem(struct archive_read_disk *a, int64_t dev)
|
||||
fid = t->max_filesystem_id++;
|
||||
if (t->max_filesystem_id > t->allocated_filesytem) {
|
||||
size_t s;
|
||||
void *p;
|
||||
|
||||
s = t->max_filesystem_id * 2;
|
||||
t->filesystem_table = realloc(t->filesystem_table,
|
||||
s * sizeof(*t->filesystem_table));
|
||||
if (t->filesystem_table == NULL) {
|
||||
p = realloc(t->filesystem_table,
|
||||
s * sizeof(*t->filesystem_table));
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate tar data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
t->allocated_filesytem = s;
|
||||
t->filesystem_table = (struct filesystem *)p;
|
||||
t->allocated_filesytem = (int)s;
|
||||
}
|
||||
t->current_filesystem_id = fid;
|
||||
t->current_filesystem = &(t->filesystem_table[fid]);
|
||||
@ -2040,7 +2042,7 @@ tree_free(struct tree *t)
|
||||
free(t->filesystem_table);
|
||||
for (i = 0; i < MAX_OVERLAPPED; i++) {
|
||||
if (t->ol[i].buff)
|
||||
VirtualFree(t->ol[i].buff, t->ol[i].buff_size, MEM_DECOMMIT);
|
||||
VirtualFree(t->ol[i].buff, 0, MEM_RELEASE);
|
||||
CloseHandle(t->ol[i].ol.hEvent);
|
||||
}
|
||||
free(t);
|
||||
@ -2234,7 +2236,7 @@ setup_sparse_from_disk(struct archive_read_disk *a,
|
||||
ret = DeviceIoControl(handle,
|
||||
FSCTL_QUERY_ALLOCATED_RANGES,
|
||||
&range, sizeof(range), outranges,
|
||||
outranges_size, &retbytes, NULL);
|
||||
(DWORD)outranges_size, &retbytes, NULL);
|
||||
if (ret == 0 && GetLastError() == ERROR_MORE_DATA) {
|
||||
free(outranges);
|
||||
outranges_size *= 2;
|
||||
|
@ -154,7 +154,7 @@ copy_data(struct archive *ar, struct archive *aw)
|
||||
return (ARCHIVE_OK);
|
||||
if (r != ARCHIVE_OK)
|
||||
return (r);
|
||||
r = archive_write_data_block(aw, buff, size, offset);
|
||||
r = (int)archive_write_data_block(aw, buff, size, offset);
|
||||
if (r < ARCHIVE_WARN)
|
||||
r = ARCHIVE_WARN;
|
||||
if (r != ARCHIVE_OK) {
|
||||
|
@ -119,7 +119,8 @@ file_read(struct archive *a, void *client_data, const void **buff)
|
||||
if (bytes_read < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
archive_set_error(a, errno, "Error reading fd %d", mine->fd);
|
||||
archive_set_error(a, errno, "Error reading fd %d",
|
||||
mine->fd);
|
||||
}
|
||||
return (bytes_read);
|
||||
}
|
||||
|
@ -108,11 +108,11 @@ static ssize_t
|
||||
file_read(struct archive *a, void *client_data, const void **buff)
|
||||
{
|
||||
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
|
||||
ssize_t bytes_read;
|
||||
size_t bytes_read;
|
||||
|
||||
*buff = mine->buffer;
|
||||
bytes_read = fread(mine->buffer, 1, mine->block_size, mine->f);
|
||||
if (bytes_read < 0) {
|
||||
if (bytes_read < mine->block_size && ferror(mine->f)) {
|
||||
archive_set_error(a, errno, "Error reading file");
|
||||
}
|
||||
return (bytes_read);
|
||||
|
@ -60,11 +60,15 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_filename.c 201093 2009
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_string.h"
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
struct read_file_data {
|
||||
int fd;
|
||||
@ -79,9 +83,10 @@ struct read_file_data {
|
||||
} filename; /* Must be last! */
|
||||
};
|
||||
|
||||
static int file_open(struct archive *, void *);
|
||||
static int file_close(struct archive *, void *);
|
||||
static int file_open_filename(struct archive *, enum fnt_e, const void *,
|
||||
size_t);
|
||||
static int file_close2(struct archive *, void *);
|
||||
static int file_switch(struct archive *, void *, void *);
|
||||
static ssize_t file_read(struct archive *, void *, const void **buff);
|
||||
static int64_t file_seek(struct archive *, void *, int64_t request, int);
|
||||
static int64_t file_skip(struct archive *, void *, int64_t request);
|
||||
@ -98,26 +103,76 @@ int
|
||||
archive_read_open_filename(struct archive *a, const char *filename,
|
||||
size_t block_size)
|
||||
{
|
||||
enum fnt_e filename_type;
|
||||
const char *filenames[2] = { filename, NULL };
|
||||
return archive_read_open_filenames(a, filenames, block_size);
|
||||
}
|
||||
|
||||
if (filename == NULL || filename[0] == '\0') {
|
||||
filename_type = FNT_STDIN;
|
||||
} else
|
||||
filename_type = FNT_MBS;
|
||||
return (file_open_filename(a, filename_type, filename, block_size));
|
||||
int
|
||||
archive_read_open_filenames(struct archive *a, const char **filenames,
|
||||
size_t block_size)
|
||||
{
|
||||
struct read_file_data *mine;
|
||||
const char *filename = NULL;
|
||||
if (filenames)
|
||||
filename = *(filenames++);
|
||||
|
||||
archive_clear_error(a);
|
||||
do
|
||||
{
|
||||
if (filename == NULL)
|
||||
filename = "";
|
||||
mine = (struct read_file_data *)calloc(1,
|
||||
sizeof(*mine) + strlen(filename));
|
||||
if (mine == NULL)
|
||||
goto no_memory;
|
||||
strcpy(mine->filename.m, filename);
|
||||
mine->block_size = block_size;
|
||||
mine->fd = -1;
|
||||
mine->buffer = NULL;
|
||||
mine->st_mode = mine->use_lseek = 0;
|
||||
if (filename == NULL || filename[0] == '\0') {
|
||||
mine->filename_type = FNT_STDIN;
|
||||
} else
|
||||
mine->filename_type = FNT_MBS;
|
||||
if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
|
||||
return (ARCHIVE_FATAL);
|
||||
if (filenames == NULL)
|
||||
break;
|
||||
filename = *(filenames++);
|
||||
} while (filename != NULL && filename[0] != '\0');
|
||||
archive_read_set_open_callback(a, file_open);
|
||||
archive_read_set_read_callback(a, file_read);
|
||||
archive_read_set_skip_callback(a, file_skip);
|
||||
archive_read_set_close_callback(a, file_close);
|
||||
archive_read_set_switch_callback(a, file_switch);
|
||||
archive_read_set_seek_callback(a, file_seek);
|
||||
|
||||
return (archive_read_open1(a));
|
||||
no_memory:
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
|
||||
size_t block_size)
|
||||
{
|
||||
enum fnt_e filename_type;
|
||||
struct read_file_data *mine = (struct read_file_data *)calloc(1,
|
||||
sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
|
||||
if (!mine)
|
||||
{
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
mine->fd = -1;
|
||||
mine->block_size = block_size;
|
||||
|
||||
if (wfilename == NULL || wfilename[0] == L'\0') {
|
||||
filename_type = FNT_STDIN;
|
||||
mine->filename_type = FNT_STDIN;
|
||||
} else {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
filename_type = FNT_WCS;
|
||||
mine->filename_type = FNT_WCS;
|
||||
wcscpy(mine->filename.w, wfilename);
|
||||
#else
|
||||
/*
|
||||
* POSIX system does not support a wchar_t interface for
|
||||
@ -125,7 +180,6 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
|
||||
* filename to multi-byte one and use it.
|
||||
*/
|
||||
struct archive_string fn;
|
||||
int r;
|
||||
|
||||
archive_string_init(&fn);
|
||||
if (archive_string_append_from_wcs(&fn, wfilename,
|
||||
@ -138,22 +192,31 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
|
||||
"Failed to convert a wide-character"
|
||||
" filename to a multi-byte filename");
|
||||
archive_string_free(&fn);
|
||||
free(mine);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
r = file_open_filename(a, FNT_MBS, fn.s, block_size);
|
||||
mine->filename_type = FNT_MBS;
|
||||
strcpy(mine->filename.m, fn.s);
|
||||
archive_string_free(&fn);
|
||||
return (r);
|
||||
#endif
|
||||
}
|
||||
return (file_open_filename(a, filename_type, wfilename, block_size));
|
||||
if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
|
||||
return (ARCHIVE_FATAL);
|
||||
archive_read_set_open_callback(a, file_open);
|
||||
archive_read_set_read_callback(a, file_read);
|
||||
archive_read_set_skip_callback(a, file_skip);
|
||||
archive_read_set_close_callback(a, file_close);
|
||||
archive_read_set_switch_callback(a, file_switch);
|
||||
archive_read_set_seek_callback(a, file_seek);
|
||||
|
||||
return (archive_read_open1(a));
|
||||
}
|
||||
|
||||
static int
|
||||
file_open_filename(struct archive *a, enum fnt_e filename_type,
|
||||
const void *_filename, size_t block_size)
|
||||
file_open(struct archive *a, void *client_data)
|
||||
{
|
||||
struct stat st;
|
||||
struct read_file_data *mine;
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
void *buffer;
|
||||
const char *filename = NULL;
|
||||
const wchar_t *wfilename = NULL;
|
||||
@ -168,7 +231,7 @@ file_open_filename(struct archive *a, enum fnt_e filename_type,
|
||||
#endif
|
||||
|
||||
archive_clear_error(a);
|
||||
if (filename_type == FNT_STDIN) {
|
||||
if (mine->filename_type == FNT_STDIN) {
|
||||
/* We used to delegate stdin support by
|
||||
* directly calling archive_read_open_fd(a,0,block_size)
|
||||
* here, but that doesn't (and shouldn't) handle the
|
||||
@ -183,9 +246,10 @@ file_open_filename(struct archive *a, enum fnt_e filename_type,
|
||||
setmode(0, O_BINARY);
|
||||
#endif
|
||||
filename = "";
|
||||
} else if (filename_type == FNT_MBS) {
|
||||
filename = (const char *)_filename;
|
||||
fd = open(filename, O_RDONLY | O_BINARY);
|
||||
} else if (mine->filename_type == FNT_MBS) {
|
||||
filename = mine->filename.m;
|
||||
fd = open(filename, O_RDONLY | O_BINARY | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(fd);
|
||||
if (fd < 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to open '%s'", filename);
|
||||
@ -193,7 +257,7 @@ file_open_filename(struct archive *a, enum fnt_e filename_type,
|
||||
}
|
||||
} else {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
wfilename = (const wchar_t *)_filename;
|
||||
wfilename = mine->filename.w;
|
||||
fd = _wopen(wfilename, O_RDONLY | O_BINARY);
|
||||
if (fd < 0 && errno == ENOENT) {
|
||||
wchar_t *fullpath;
|
||||
@ -215,7 +279,7 @@ file_open_filename(struct archive *a, enum fnt_e filename_type,
|
||||
#endif
|
||||
}
|
||||
if (fstat(fd, &st) != 0) {
|
||||
if (filename_type == FNT_WCS)
|
||||
if (mine->filename_type == FNT_WCS)
|
||||
archive_set_error(a, errno, "Can't stat '%S'",
|
||||
wfilename);
|
||||
else
|
||||
@ -280,50 +344,32 @@ file_open_filename(struct archive *a, enum fnt_e filename_type,
|
||||
#endif
|
||||
/* TODO: Add an "is_tape_like" variable and appropriate tests. */
|
||||
|
||||
if (filename_type == FNT_WCS)
|
||||
mine = (struct read_file_data *)calloc(1,
|
||||
sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
|
||||
else
|
||||
mine = (struct read_file_data *)calloc(1,
|
||||
sizeof(*mine) + strlen(filename));
|
||||
/* Disk-like devices prefer power-of-two block sizes. */
|
||||
/* Use provided block_size as a guide so users have some control. */
|
||||
if (is_disk_like) {
|
||||
size_t new_block_size = 64 * 1024;
|
||||
while (new_block_size < block_size
|
||||
while (new_block_size < mine->block_size
|
||||
&& new_block_size < 64 * 1024 * 1024)
|
||||
new_block_size *= 2;
|
||||
block_size = new_block_size;
|
||||
mine->block_size = new_block_size;
|
||||
}
|
||||
buffer = malloc(block_size);
|
||||
buffer = malloc(mine->block_size);
|
||||
if (mine == NULL || buffer == NULL) {
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
free(mine);
|
||||
free(buffer);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (filename_type == FNT_WCS)
|
||||
wcscpy(mine->filename.w, wfilename);
|
||||
else
|
||||
strcpy(mine->filename.m, filename);
|
||||
mine->filename_type = filename_type;
|
||||
mine->block_size = block_size;
|
||||
mine->buffer = buffer;
|
||||
mine->fd = fd;
|
||||
/* Remember mode so close can decide whether to flush. */
|
||||
mine->st_mode = st.st_mode;
|
||||
|
||||
/* Disk-like inputs can use lseek(). */
|
||||
if (is_disk_like) {
|
||||
archive_read_set_seek_callback(a, file_seek);
|
||||
if (is_disk_like)
|
||||
mine->use_lseek = 1;
|
||||
}
|
||||
|
||||
archive_read_set_read_callback(a, file_read);
|
||||
archive_read_set_skip_callback(a, file_skip);
|
||||
archive_read_set_close_callback(a, file_close);
|
||||
archive_read_set_callback_data(a, mine);
|
||||
return (archive_read_open1(a));
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@ -401,9 +447,7 @@ file_skip_lseek(struct archive *a, void *client_data, int64_t request)
|
||||
/* TODO: Deal with case where off_t isn't 64 bits.
|
||||
* This shouldn't be a problem on Linux or other POSIX
|
||||
* systems, since the configuration logic for libarchive
|
||||
* tries to obtain a 64-bit off_t. It's still an issue
|
||||
* on Windows, though, so it might suffice to just use
|
||||
* _lseeki64() on Windows.
|
||||
* tries to obtain a 64-bit off_t.
|
||||
*/
|
||||
if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 &&
|
||||
(new_offset = lseek(mine->fd, request, SEEK_CUR)) >= 0)
|
||||
@ -475,7 +519,7 @@ file_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
}
|
||||
|
||||
static int
|
||||
file_close(struct archive *a, void *client_data)
|
||||
file_close2(struct archive *a, void *client_data)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
|
||||
@ -508,6 +552,23 @@ file_close(struct archive *a, void *client_data)
|
||||
close(mine->fd);
|
||||
}
|
||||
free(mine->buffer);
|
||||
mine->buffer = NULL;
|
||||
mine->fd = -1;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
file_close(struct archive *a, void *client_data)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
file_close2(a, client_data);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
file_switch(struct archive *a, void *client_data1, void *client_data2)
|
||||
{
|
||||
file_close2(a, client_data1);
|
||||
return file_open(a, client_data2);
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ struct archive_read_filter;
|
||||
struct archive_read_filter_bidder {
|
||||
/* Configuration data for the bidder. */
|
||||
void *data;
|
||||
/* Name of the filter */
|
||||
const char *name;
|
||||
/* Taste the upstream filter to see if we handle this. */
|
||||
int (*bid)(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
@ -82,6 +84,8 @@ struct archive_read_filter {
|
||||
struct archive_read_filter_bidder *bidder; /* My bidder. */
|
||||
struct archive_read_filter *upstream; /* Who I read from. */
|
||||
struct archive_read *archive; /* Associated archive. */
|
||||
/* Open a block for reading */
|
||||
int (*open)(struct archive_read_filter *self);
|
||||
/* Return next block. */
|
||||
ssize_t (*read)(struct archive_read_filter *, const void **);
|
||||
/* Skip forward this many bytes. */
|
||||
@ -90,6 +94,8 @@ struct archive_read_filter {
|
||||
int64_t (*seek)(struct archive_read_filter *self, int64_t offset, int whence);
|
||||
/* Close (just this filter) and free(self). */
|
||||
int (*close)(struct archive_read_filter *self);
|
||||
/* Function that handles switching from reading one block to the next/prev */
|
||||
int (*sswitch)(struct archive_read_filter *self, unsigned int iindex);
|
||||
/* My private data. */
|
||||
void *data;
|
||||
|
||||
@ -118,13 +124,22 @@ struct archive_read_filter {
|
||||
* transformation filters. This will probably break the API/ABI and
|
||||
* so should be deferred at least until libarchive 3.0.
|
||||
*/
|
||||
struct archive_read_data_node {
|
||||
int64_t begin_position;
|
||||
int64_t total_size;
|
||||
void *data;
|
||||
};
|
||||
struct archive_read_client {
|
||||
archive_open_callback *opener;
|
||||
archive_read_callback *reader;
|
||||
archive_skip_callback *skipper;
|
||||
archive_seek_callback *seeker;
|
||||
archive_close_callback *closer;
|
||||
void *data;
|
||||
archive_switch_callback *switcher;
|
||||
unsigned int nodes;
|
||||
unsigned int cursor;
|
||||
int64_t position;
|
||||
struct archive_read_data_node *dataset;
|
||||
};
|
||||
|
||||
struct archive_read {
|
||||
@ -146,18 +161,33 @@ struct archive_read {
|
||||
int64_t read_data_output_offset;
|
||||
size_t read_data_remaining;
|
||||
|
||||
/* Callbacks to open/read/write/close client archive stream. */
|
||||
/*
|
||||
* Used by formats/filters to determine the amount of data
|
||||
* requested from a call to archive_read_data(). This is only
|
||||
* useful when the format/filter has seek support.
|
||||
*/
|
||||
char read_data_is_posix_read;
|
||||
size_t read_data_requested;
|
||||
|
||||
/* Callbacks to open/read/write/close client archive streams. */
|
||||
struct archive_read_client client;
|
||||
|
||||
/* Registered filter bidders. */
|
||||
struct archive_read_filter_bidder bidders[9];
|
||||
struct archive_read_filter_bidder bidders[14];
|
||||
|
||||
/* Last filter in chain */
|
||||
struct archive_read_filter *filter;
|
||||
|
||||
/* Whether to bypass filter bidding process */
|
||||
int bypass_filter_bidding;
|
||||
|
||||
/* File offset of beginning of most recently-read header. */
|
||||
int64_t header_position;
|
||||
|
||||
/* Nodes and offsets of compressed data block */
|
||||
unsigned int data_start_node;
|
||||
unsigned int data_end_node;
|
||||
|
||||
/*
|
||||
* Format detection is mostly the same as compression
|
||||
* detection, with one significant difference: The bidders
|
||||
@ -175,6 +205,7 @@ struct archive_read {
|
||||
int (*read_header)(struct archive_read *, struct archive_entry *);
|
||||
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *);
|
||||
int (*read_data_skip)(struct archive_read *);
|
||||
int64_t (*seek_data)(struct archive_read *, int64_t, int);
|
||||
int (*cleanup)(struct archive_read *);
|
||||
} formats[16];
|
||||
struct archive_format_descriptor *format; /* Active format. */
|
||||
@ -194,6 +225,7 @@ int __archive_read_register_format(struct archive_read *a,
|
||||
int (*read_header)(struct archive_read *, struct archive_entry *),
|
||||
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
|
||||
int (*read_data_skip)(struct archive_read *),
|
||||
int64_t (*seek_data)(struct archive_read *, int64_t, int),
|
||||
int (*cleanup)(struct archive_read *));
|
||||
|
||||
int __archive_read_get_bidder(struct archive_read *a,
|
||||
@ -207,4 +239,6 @@ int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
|
||||
int64_t __archive_read_consume(struct archive_read *, int64_t);
|
||||
int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
|
||||
int __archive_read_program(struct archive_read_filter *, const char *);
|
||||
void __archive_read_free_filters(struct archive_read *);
|
||||
int __archive_read_close_filters(struct archive_read *);
|
||||
#endif
|
||||
|
105
libarchive/archive_read_set_format.c
Normal file
105
libarchive/archive_read_set_format.c
Normal file
@ -0,0 +1,105 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2012 Tim Kientzle
|
||||
* 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"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
int
|
||||
archive_read_set_format(struct archive *_a, int code)
|
||||
{
|
||||
int r1, r2, slots, i;
|
||||
char str[10];
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
|
||||
if ((r1 = archive_read_support_format_by_code(_a, code)) < (ARCHIVE_OK))
|
||||
return r1;
|
||||
|
||||
r1 = r2 = (ARCHIVE_OK);
|
||||
if (a->format)
|
||||
r2 = (ARCHIVE_WARN);
|
||||
switch (code & ARCHIVE_FORMAT_BASE_MASK)
|
||||
{
|
||||
case ARCHIVE_FORMAT_7ZIP:
|
||||
strcpy(str, "7zip");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_AR:
|
||||
strcpy(str, "ar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_CAB:
|
||||
strcpy(str, "cab");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_CPIO:
|
||||
strcpy(str, "cpio");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ISO9660:
|
||||
strcpy(str, "iso9660");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_LHA:
|
||||
strcpy(str, "lha");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_MTREE:
|
||||
strcpy(str, "mtree");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAR:
|
||||
strcpy(str, "rar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
strcpy(str, "tar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_XAR:
|
||||
strcpy(str, "xar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ZIP:
|
||||
strcpy(str, "zip");
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Invalid format code specified");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
slots = sizeof(a->formats) / sizeof(a->formats[0]);
|
||||
a->format = &(a->formats[0]);
|
||||
for (i = 0; i < slots; i++, a->format++) {
|
||||
if (!a->format->name || !strcmp(a->format->name, str))
|
||||
break;
|
||||
}
|
||||
if (!a->format->name || strcmp(a->format->name, str))
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: Unable to set format");
|
||||
r1 = (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
return (r1 < r2) ? r1 : r2;
|
||||
}
|
@ -48,7 +48,7 @@ archive_read_support_filter_all(struct archive *a)
|
||||
archive_read_support_filter_bzip2(a);
|
||||
/* The decompress code doesn't use an outside library. */
|
||||
archive_read_support_filter_compress(a);
|
||||
/* Gzip decompress falls back to "gunzip" command-line. */
|
||||
/* Gzip decompress falls back to "gzip -d" command-line. */
|
||||
archive_read_support_filter_gzip(a);
|
||||
/* Lzip falls back to "unlzip" command-line program. */
|
||||
archive_read_support_filter_lzip(a);
|
||||
@ -63,6 +63,12 @@ archive_read_support_filter_all(struct archive *a)
|
||||
archive_read_support_filter_uu(a);
|
||||
/* The decode code doesn't use an outside library. */
|
||||
archive_read_support_filter_rpm(a);
|
||||
/* The decode code always uses "lrzip -q -d" command-line. */
|
||||
archive_read_support_filter_lrzip(a);
|
||||
/* Lzop decompress falls back to "lzop -d" command-line. */
|
||||
archive_read_support_filter_lzop(a);
|
||||
/* The decode code always uses "grzip -d" command-line. */
|
||||
archive_read_support_filter_grzip(a);
|
||||
|
||||
/* Note: We always return ARCHIVE_OK here, even if some of the
|
||||
* above return ARCHIVE_WARN. The intent here is to enable
|
||||
|
@ -94,6 +94,7 @@ archive_read_support_filter_bzip2(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
reader->data = NULL;
|
||||
reader->name = "bzip2";
|
||||
reader->bid = bzip2_reader_bid;
|
||||
reader->init = bzip2_reader_init;
|
||||
reader->options = NULL;
|
||||
@ -102,7 +103,7 @@ archive_read_support_filter_bzip2(struct archive *_a)
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external bunzip2 program");
|
||||
"Using external bzip2 program");
|
||||
return (ARCHIVE_WARN);
|
||||
#endif
|
||||
}
|
||||
@ -170,11 +171,11 @@ bzip2_reader_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "bunzip2");
|
||||
r = __archive_read_program(self, "bzip2 -d");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_COMPRESSION_BZIP2;
|
||||
self->code = ARCHIVE_FILTER_BZIP2;
|
||||
self->name = "bzip2";
|
||||
return (r);
|
||||
}
|
||||
@ -192,7 +193,7 @@ bzip2_reader_init(struct archive_read_filter *self)
|
||||
void *out_block;
|
||||
struct private_data *state;
|
||||
|
||||
self->code = ARCHIVE_COMPRESSION_BZIP2;
|
||||
self->code = ARCHIVE_FILTER_BZIP2;
|
||||
self->name = "bzip2";
|
||||
|
||||
state = (struct private_data *)calloc(sizeof(*state), 1);
|
||||
|
@ -163,6 +163,7 @@ archive_read_support_filter_compress(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "compress (.Z)";
|
||||
bidder->bid = compress_bidder_bid;
|
||||
bidder->init = compress_bidder_init;
|
||||
bidder->options = NULL;
|
||||
@ -212,7 +213,7 @@ compress_bidder_init(struct archive_read_filter *self)
|
||||
void *out_block;
|
||||
int code;
|
||||
|
||||
self->code = ARCHIVE_COMPRESSION_COMPRESS;
|
||||
self->code = ARCHIVE_FILTER_COMPRESS;
|
||||
self->name = "compress (.Z)";
|
||||
|
||||
state = (struct private_data *)calloc(sizeof(*state), 1);
|
||||
|
121
libarchive/archive_read_support_filter_grzip.c
Normal file
121
libarchive/archive_read_support_filter_grzip.c
Normal file
@ -0,0 +1,121 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* 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"
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
static const unsigned char grzip_magic[] = {
|
||||
0x47, 0x52, 0x5a, 0x69, 0x70, 0x49, 0x49, 0x00,
|
||||
0x02, 0x04, 0x3a, 0x29 };
|
||||
|
||||
static int grzip_bidder_bid(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
static int grzip_bidder_init(struct archive_read_filter *);
|
||||
|
||||
|
||||
static int
|
||||
grzip_reader_free(struct archive_read_filter_bidder *self)
|
||||
{
|
||||
(void)self; /* UNUSED */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_support_filter_grzip(struct archive *_a)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter_bidder *reader;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_filter_grzip");
|
||||
|
||||
if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
reader->data = NULL;
|
||||
reader->bid = grzip_bidder_bid;
|
||||
reader->init = grzip_bidder_init;
|
||||
reader->options = NULL;
|
||||
reader->free = grzip_reader_free;
|
||||
/* This filter always uses an external program. */
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external grzip program for grzip decompression");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bidder just verifies the header and returns the number of verified bits.
|
||||
*/
|
||||
static int
|
||||
grzip_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
struct archive_read_filter *filter)
|
||||
{
|
||||
const unsigned char *p;
|
||||
ssize_t avail;
|
||||
|
||||
(void)self; /* UNUSED */
|
||||
|
||||
p = __archive_read_filter_ahead(filter, sizeof(grzip_magic), &avail);
|
||||
if (p == NULL || avail == 0)
|
||||
return (0);
|
||||
|
||||
if (memcmp(p, grzip_magic, sizeof(grzip_magic)))
|
||||
return (0);
|
||||
|
||||
return (sizeof(grzip_magic) * 8);
|
||||
}
|
||||
|
||||
static int
|
||||
grzip_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "grzip -d");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_FILTER_GRZIP;
|
||||
self->name = "grzip";
|
||||
return (r);
|
||||
}
|
@ -72,7 +72,7 @@ static int gzip_filter_close(struct archive_read_filter *);
|
||||
*
|
||||
* TODO: If zlib is unavailable, gzip_bidder_init() should
|
||||
* use the compress_program framework to try to fire up an external
|
||||
* gunzip program.
|
||||
* gzip program.
|
||||
*/
|
||||
static int gzip_bidder_bid(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
@ -100,6 +100,7 @@ archive_read_support_filter_gzip(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "gzip";
|
||||
bidder->bid = gzip_bidder_bid;
|
||||
bidder->init = gzip_bidder_init;
|
||||
bidder->options = NULL;
|
||||
@ -109,7 +110,7 @@ archive_read_support_filter_gzip(struct archive *_a)
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external gunzip program");
|
||||
"Using external gzip program");
|
||||
return (ARCHIVE_WARN);
|
||||
#endif
|
||||
}
|
||||
@ -121,7 +122,7 @@ archive_read_support_filter_gzip(struct archive *_a)
|
||||
* number of bytes in header. If pbits is non-NULL, it receives a
|
||||
* count of bits verified, suitable for use by bidder.
|
||||
*/
|
||||
static int
|
||||
static ssize_t
|
||||
peek_at_header(struct archive_read_filter *filter, int *pbits)
|
||||
{
|
||||
const unsigned char *p;
|
||||
@ -223,7 +224,7 @@ gzip_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
|
||||
/*
|
||||
* If we don't have the library on this system, we can't do the
|
||||
* decompression directly. We can, however, try to run gunzip
|
||||
* decompression directly. We can, however, try to run "gzip -d"
|
||||
* in case that's available.
|
||||
*/
|
||||
static int
|
||||
@ -231,11 +232,11 @@ gzip_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "gunzip");
|
||||
r = __archive_read_program(self, "gzip -d");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_COMPRESSION_GZIP;
|
||||
self->code = ARCHIVE_FILTER_GZIP;
|
||||
self->name = "gzip";
|
||||
return (r);
|
||||
}
|
||||
@ -252,7 +253,7 @@ gzip_bidder_init(struct archive_read_filter *self)
|
||||
static const size_t out_block_size = 64 * 1024;
|
||||
void *out_block;
|
||||
|
||||
self->code = ARCHIVE_COMPRESSION_GZIP;
|
||||
self->code = ARCHIVE_FILTER_GZIP;
|
||||
self->name = "gzip";
|
||||
|
||||
state = (struct private_data *)calloc(sizeof(*state), 1);
|
||||
@ -299,7 +300,7 @@ consume_header(struct archive_read_filter *self)
|
||||
/* Initialize compression library. */
|
||||
state->stream.next_in = (unsigned char *)(uintptr_t)
|
||||
__archive_read_filter_ahead(self->upstream, 1, &avail);
|
||||
state->stream.avail_in = avail;
|
||||
state->stream.avail_in = (uInt)avail;
|
||||
ret = inflateInit2(&(state->stream),
|
||||
-15 /* Don't check for zlib header */);
|
||||
|
||||
@ -380,7 +381,7 @@ gzip_filter_read(struct archive_read_filter *self, const void **p)
|
||||
|
||||
/* Empty our output buffer. */
|
||||
state->stream.next_out = state->out_block;
|
||||
state->stream.avail_out = state->out_block_size;
|
||||
state->stream.avail_out = (uInt)state->out_block_size;
|
||||
|
||||
/* Try to fill the output buffer. */
|
||||
while (state->stream.avail_out > 0 && !state->eof) {
|
||||
@ -407,7 +408,7 @@ gzip_filter_read(struct archive_read_filter *self, const void **p)
|
||||
"truncated gzip input");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
state->stream.avail_in = avail_in;
|
||||
state->stream.avail_in = (uInt)avail_in;
|
||||
|
||||
/* Decompress and consume some of that data. */
|
||||
ret = inflate(&(state->stream), 0);
|
||||
|
132
libarchive/archive_read_support_filter_lrzip.c
Normal file
132
libarchive/archive_read_support_filter_lrzip.c
Normal file
@ -0,0 +1,132 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* 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"
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
#define LRZIP_HEADER_MAGIC "LRZI"
|
||||
#define LRZIP_HEADER_MAGIC_LEN 4
|
||||
|
||||
static int lrzip_bidder_bid(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
static int lrzip_bidder_init(struct archive_read_filter *);
|
||||
|
||||
|
||||
static int
|
||||
lrzip_reader_free(struct archive_read_filter_bidder *self)
|
||||
{
|
||||
(void)self; /* UNUSED */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_support_filter_lrzip(struct archive *_a)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter_bidder *reader;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_filter_lrzip");
|
||||
|
||||
if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
reader->data = NULL;
|
||||
reader->name = "lrzip";
|
||||
reader->bid = lrzip_bidder_bid;
|
||||
reader->init = lrzip_bidder_init;
|
||||
reader->options = NULL;
|
||||
reader->free = lrzip_reader_free;
|
||||
/* This filter always uses an external program. */
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external lrzip program for lrzip decompression");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bidder just verifies the header and returns the number of verified bits.
|
||||
*/
|
||||
static int
|
||||
lrzip_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
struct archive_read_filter *filter)
|
||||
{
|
||||
const unsigned char *p;
|
||||
ssize_t avail, len;
|
||||
int i;
|
||||
|
||||
(void)self; /* UNUSED */
|
||||
/* Start by looking at the first six bytes of the header, which
|
||||
* is all fixed layout. */
|
||||
len = 6;
|
||||
p = __archive_read_filter_ahead(filter, len, &avail);
|
||||
if (p == NULL || avail == 0)
|
||||
return (0);
|
||||
|
||||
if (memcmp(p, LRZIP_HEADER_MAGIC, LRZIP_HEADER_MAGIC_LEN))
|
||||
return (0);
|
||||
|
||||
/* current major version is always 0, verify this */
|
||||
if (p[LRZIP_HEADER_MAGIC_LEN])
|
||||
return 0;
|
||||
/* support only v0.6+ lrzip for sanity */
|
||||
i = p[LRZIP_HEADER_MAGIC_LEN + 1];
|
||||
if ((i < 6) || (i > 10))
|
||||
return 0;
|
||||
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
static int
|
||||
lrzip_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "lrzip -d -q");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_FILTER_LRZIP;
|
||||
self->name = "lrzip";
|
||||
return (r);
|
||||
}
|
486
libarchive/archive_read_support_filter_lzop.c
Normal file
486
libarchive/archive_read_support_filter_lzop.c
Normal file
@ -0,0 +1,486 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* 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"
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_LZO_LZOCONF_H
|
||||
#include <lzo/lzoconf.h>
|
||||
#endif
|
||||
#ifdef HAVE_LZO_LZO1X_H
|
||||
#include <lzo/lzo1x.h>
|
||||
#endif
|
||||
#ifdef HAVE_ZLIB_H
|
||||
#include <zlib.h> /* for crc32 and adler32 */
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#if !defined(HAVE_ZLIB_H) &&\
|
||||
defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
|
||||
#include "archive_crc32.h"
|
||||
#endif
|
||||
#include "archive_endian.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
#ifndef HAVE_ZLIB_H
|
||||
#define adler32 lzo_adler32
|
||||
#endif
|
||||
|
||||
#define LZOP_HEADER_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a"
|
||||
#define LZOP_HEADER_MAGIC_LEN 9
|
||||
|
||||
#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
|
||||
struct read_lzop {
|
||||
unsigned char *out_block;
|
||||
size_t out_block_size;
|
||||
int64_t total_out;
|
||||
int flags;
|
||||
uint32_t compressed_cksum;
|
||||
uint32_t uncompressed_cksum;
|
||||
size_t compressed_size;
|
||||
size_t uncompressed_size;
|
||||
size_t unconsumed_bytes;
|
||||
char in_stream;
|
||||
char eof; /* True = found end of compressed data. */
|
||||
};
|
||||
|
||||
#define FILTER 0x0800
|
||||
#define CRC32_HEADER 0x1000
|
||||
#define EXTRA_FIELD 0x0040
|
||||
#define ADLER32_UNCOMPRESSED 0x0001
|
||||
#define ADLER32_COMPRESSED 0x0002
|
||||
#define CRC32_UNCOMPRESSED 0x0100
|
||||
#define CRC32_COMPRESSED 0x0200
|
||||
#define MAX_BLOCK_SIZE (64 * 1024 * 1024)
|
||||
|
||||
static ssize_t lzop_filter_read(struct archive_read_filter *, const void **);
|
||||
static int lzop_filter_close(struct archive_read_filter *);
|
||||
#endif
|
||||
|
||||
static int lzop_bidder_bid(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
static int lzop_bidder_init(struct archive_read_filter *);
|
||||
|
||||
int
|
||||
archive_read_support_filter_lzop(struct archive *_a)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter_bidder *reader;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_filter_lzop");
|
||||
|
||||
if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
reader->data = NULL;
|
||||
reader->bid = lzop_bidder_bid;
|
||||
reader->init = lzop_bidder_init;
|
||||
reader->options = NULL;
|
||||
reader->free = NULL;
|
||||
/* Signal the extent of lzop support with the return value here. */
|
||||
#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
/* Return ARCHIVE_WARN since this always uses an external program. */
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external lzop program for lzop decompression");
|
||||
return (ARCHIVE_WARN);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Bidder just verifies the header and returns the number of verified bits.
|
||||
*/
|
||||
static int
|
||||
lzop_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
struct archive_read_filter *filter)
|
||||
{
|
||||
const unsigned char *p;
|
||||
ssize_t avail;
|
||||
|
||||
(void)self; /* UNUSED */
|
||||
|
||||
p = __archive_read_filter_ahead(filter, LZOP_HEADER_MAGIC_LEN, &avail);
|
||||
if (p == NULL || avail == 0)
|
||||
return (0);
|
||||
|
||||
if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN))
|
||||
return (0);
|
||||
|
||||
return (LZOP_HEADER_MAGIC_LEN * 8);
|
||||
}
|
||||
|
||||
#if !defined(HAVE_LZO_LZOCONF_H) || !defined(HAVE_LZO_LZO1X_H)
|
||||
/*
|
||||
* If we don't have the library on this system, we can't do the
|
||||
* decompression directly. We can, however, try to run "lzop -d"
|
||||
* in case that's available.
|
||||
*/
|
||||
static int
|
||||
lzop_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "lzop -d");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_FILTER_LZOP;
|
||||
self->name = "lzop";
|
||||
return (r);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Initialize the filter object.
|
||||
*/
|
||||
static int
|
||||
lzop_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
struct read_lzop *state;
|
||||
|
||||
self->code = ARCHIVE_FILTER_LZOP;
|
||||
self->name = "lzop";
|
||||
|
||||
state = (struct read_lzop *)calloc(sizeof(*state), 1);
|
||||
if (state == NULL) {
|
||||
archive_set_error(&self->archive->archive, ENOMEM,
|
||||
"Can't allocate data for lzop decompression");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
self->data = state;
|
||||
self->read = lzop_filter_read;
|
||||
self->skip = NULL; /* not supported */
|
||||
self->close = lzop_filter_close;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
consume_header(struct archive_read_filter *self)
|
||||
{
|
||||
struct read_lzop *state = (struct read_lzop *)self->data;
|
||||
const unsigned char *p, *_p;
|
||||
unsigned checksum, flags, len, method, version;
|
||||
|
||||
/*
|
||||
* Check LZOP magic code.
|
||||
*/
|
||||
p = __archive_read_filter_ahead(self->upstream,
|
||||
LZOP_HEADER_MAGIC_LEN, NULL);
|
||||
if (p == NULL)
|
||||
return (ARCHIVE_EOF);
|
||||
|
||||
if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN))
|
||||
return (ARCHIVE_EOF);
|
||||
__archive_read_filter_consume(self->upstream,
|
||||
LZOP_HEADER_MAGIC_LEN);
|
||||
|
||||
p = __archive_read_filter_ahead(self->upstream, 29, NULL);
|
||||
if (p == NULL)
|
||||
goto truncated;
|
||||
_p = p;
|
||||
version = archive_be16dec(p);
|
||||
p += 4;/* version(2 bytes) + library version(2 bytes) */
|
||||
|
||||
if (version >= 0x940) {
|
||||
unsigned reqversion = archive_be16dec(p); p += 2;
|
||||
if (reqversion < 0x900) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC, "Invalid required version");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
method = *p++;
|
||||
if (method < 1 || method > 3) {
|
||||
archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported method");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
if (version >= 0x940) {
|
||||
unsigned level = *p++;
|
||||
if (method == 1 && level == 0) level = 3;
|
||||
if (method == 2 && level == 0) level = 1;
|
||||
if (method == 3 && level == 0) level = 9;
|
||||
if (level < 1 && level > 9) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC, "Invalid level");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
flags = archive_be32dec(p); p += 4;
|
||||
|
||||
if (flags & FILTER)
|
||||
p += 4; /* Skip filter */
|
||||
p += 4; /* Skip mode */
|
||||
if (version >= 0x940)
|
||||
p += 8; /* Skip mtime */
|
||||
else
|
||||
p += 4; /* Skip mtime */
|
||||
len = *p++; /* Read filename length */
|
||||
len += p - _p;
|
||||
/* Make sure we have all bytes we need to calculate checksum. */
|
||||
p = __archive_read_filter_ahead(self->upstream, len + 4, NULL);
|
||||
if (p == NULL)
|
||||
goto truncated;
|
||||
if (flags & CRC32_HEADER)
|
||||
checksum = crc32(crc32(0, NULL, 0), p, len);
|
||||
else
|
||||
checksum = adler32(adler32(0, NULL, 0), p, len);
|
||||
if (archive_be32dec(p + len) != checksum)
|
||||
goto corrupted;
|
||||
__archive_read_filter_consume(self->upstream, len + 4);
|
||||
if (flags & EXTRA_FIELD) {
|
||||
/* Skip extra field */
|
||||
p = __archive_read_filter_ahead(self->upstream, 4, NULL);
|
||||
if (p == NULL)
|
||||
goto truncated;
|
||||
len = archive_be32dec(p);
|
||||
__archive_read_filter_consume(self->upstream, len + 4 + 4);
|
||||
}
|
||||
state->flags = flags;
|
||||
state->in_stream = 1;
|
||||
return (ARCHIVE_OK);
|
||||
truncated:
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data");
|
||||
return (ARCHIVE_FAILED);
|
||||
corrupted:
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT, "Corrupted lzop header");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
static int
|
||||
consume_block_info(struct archive_read_filter *self)
|
||||
{
|
||||
struct read_lzop *state = (struct read_lzop *)self->data;
|
||||
const unsigned char *p;
|
||||
unsigned flags = state->flags;
|
||||
|
||||
p = __archive_read_filter_ahead(self->upstream, 4, NULL);
|
||||
if (p == NULL)
|
||||
goto truncated;
|
||||
state->uncompressed_size = archive_be32dec(p);
|
||||
__archive_read_filter_consume(self->upstream, 4);
|
||||
if (state->uncompressed_size == 0)
|
||||
return (ARCHIVE_EOF);
|
||||
if (state->uncompressed_size > MAX_BLOCK_SIZE)
|
||||
goto corrupted;
|
||||
|
||||
p = __archive_read_filter_ahead(self->upstream, 4, NULL);
|
||||
if (p == NULL)
|
||||
goto truncated;
|
||||
state->compressed_size = archive_be32dec(p);
|
||||
__archive_read_filter_consume(self->upstream, 4);
|
||||
if (state->compressed_size > state->uncompressed_size)
|
||||
goto corrupted;
|
||||
|
||||
if (flags & (CRC32_UNCOMPRESSED | ADLER32_UNCOMPRESSED)) {
|
||||
p = __archive_read_filter_ahead(self->upstream, 4, NULL);
|
||||
if (p == NULL)
|
||||
goto truncated;
|
||||
state->compressed_cksum = state->uncompressed_cksum =
|
||||
archive_be32dec(p);
|
||||
__archive_read_filter_consume(self->upstream, 4);
|
||||
}
|
||||
if ((flags & (CRC32_COMPRESSED | ADLER32_COMPRESSED)) &&
|
||||
state->compressed_size < state->uncompressed_size) {
|
||||
p = __archive_read_filter_ahead(self->upstream, 4, NULL);
|
||||
if (p == NULL)
|
||||
goto truncated;
|
||||
state->compressed_cksum = archive_be32dec(p);
|
||||
__archive_read_filter_consume(self->upstream, 4);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
truncated:
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data");
|
||||
return (ARCHIVE_FAILED);
|
||||
corrupted:
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT, "Corrupted lzop header");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
lzop_filter_read(struct archive_read_filter *self, const void **p)
|
||||
{
|
||||
struct read_lzop *state = (struct read_lzop *)self->data;
|
||||
const void *b;
|
||||
lzo_uint out_size;
|
||||
uint32_t cksum;
|
||||
int ret, r;
|
||||
|
||||
if (state->unconsumed_bytes) {
|
||||
__archive_read_filter_consume(self->upstream,
|
||||
state->unconsumed_bytes);
|
||||
state->unconsumed_bytes = 0;
|
||||
}
|
||||
if (state->eof)
|
||||
return (0);
|
||||
|
||||
for (;;) {
|
||||
if (!state->in_stream) {
|
||||
ret = consume_header(self);
|
||||
if (ret < ARCHIVE_OK)
|
||||
return (ret);
|
||||
if (ret == ARCHIVE_EOF) {
|
||||
state->eof = 1;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
ret = consume_block_info(self);
|
||||
if (ret < ARCHIVE_OK)
|
||||
return (ret);
|
||||
if (ret == ARCHIVE_EOF)
|
||||
state->in_stream = 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (state->out_block == NULL ||
|
||||
state->out_block_size < state->uncompressed_size) {
|
||||
void *new_block;
|
||||
|
||||
new_block = realloc(state->out_block, state->uncompressed_size);
|
||||
if (new_block == NULL) {
|
||||
archive_set_error(&self->archive->archive, ENOMEM,
|
||||
"Can't allocate data for lzop decompression");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
state->out_block = new_block;
|
||||
state->out_block_size = state->uncompressed_size;
|
||||
}
|
||||
|
||||
b = __archive_read_filter_ahead(self->upstream,
|
||||
state->compressed_size, NULL);
|
||||
if (b == NULL) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (state->flags & CRC32_COMPRESSED)
|
||||
cksum = crc32(crc32(0, NULL, 0), b, state->compressed_size);
|
||||
else if (state->flags & ADLER32_COMPRESSED)
|
||||
cksum = adler32(adler32(0, NULL, 0), b, state->compressed_size);
|
||||
else
|
||||
cksum = state->compressed_cksum;
|
||||
if (cksum != state->compressed_cksum) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC, "Corrupted data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the both uncompressed size and compressed size are the same,
|
||||
* we do not decompress this block.
|
||||
*/
|
||||
if (state->uncompressed_size == state->compressed_size) {
|
||||
*p = b;
|
||||
state->total_out += state->compressed_size;
|
||||
state->unconsumed_bytes = state->compressed_size;
|
||||
return ((ssize_t)state->uncompressed_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drive lzo uncompresison.
|
||||
*/
|
||||
out_size = (lzo_uint)state->uncompressed_size;
|
||||
r = lzo1x_decompress_safe(b, (lzo_uint)state->compressed_size,
|
||||
state->out_block, &out_size, NULL);
|
||||
switch (r) {
|
||||
case LZO_E_OK:
|
||||
if (out_size == state->uncompressed_size)
|
||||
break;
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC, "Corrupted data");
|
||||
return (ARCHIVE_FATAL);
|
||||
case LZO_E_OUT_OF_MEMORY:
|
||||
archive_set_error(&self->archive->archive, ENOMEM,
|
||||
"lzop decompression failed: out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
default:
|
||||
archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
|
||||
"lzop decompression failed: %d", r);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
if (state->flags & CRC32_UNCOMPRESSED)
|
||||
cksum = crc32(crc32(0, NULL, 0), state->out_block,
|
||||
state->uncompressed_size);
|
||||
else if (state->flags & ADLER32_UNCOMPRESSED)
|
||||
cksum = adler32(adler32(0, NULL, 0), state->out_block,
|
||||
state->uncompressed_size);
|
||||
else
|
||||
cksum = state->uncompressed_cksum;
|
||||
if (cksum != state->uncompressed_cksum) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC, "Corrupted data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
__archive_read_filter_consume(self->upstream, state->compressed_size);
|
||||
*p = state->out_block;
|
||||
state->total_out += out_size;
|
||||
return ((ssize_t)out_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up the decompressor.
|
||||
*/
|
||||
static int
|
||||
lzop_filter_close(struct archive_read_filter *self)
|
||||
{
|
||||
struct read_lzop *state = (struct read_lzop *)self->data;
|
||||
|
||||
free(state->out_block);
|
||||
free(state);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2007 Joerg Sonnenberger
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -53,7 +54,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_string.h"
|
||||
#include "archive_read_private.h"
|
||||
#include "filter_fork.h"
|
||||
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
@ -79,50 +82,13 @@ archive_read_support_filter_program(struct archive *a, const char *cmd)
|
||||
return (archive_read_support_filter_program_signature(a, cmd, NULL, 0));
|
||||
}
|
||||
|
||||
|
||||
/* This capability is only available on POSIX systems. */
|
||||
#if (!defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \
|
||||
!(defined(HAVE_FORK) || defined(HAVE_VFORK))) && (!defined(_WIN32) || defined(__CYGWIN__))
|
||||
|
||||
/*
|
||||
* On non-Posix systems, allow the program to build, but choke if
|
||||
* this function is actually invoked.
|
||||
*/
|
||||
int
|
||||
archive_read_support_filter_program_signature(struct archive *_a,
|
||||
const char *cmd, const void *signature, size_t signature_len)
|
||||
{
|
||||
(void)_a; /* UNUSED */
|
||||
(void)cmd; /* UNUSED */
|
||||
(void)signature; /* UNUSED */
|
||||
(void)signature_len; /* UNUSED */
|
||||
|
||||
archive_set_error(_a, -1,
|
||||
"External compression programs not supported on this platform");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
int
|
||||
__archive_read_program(struct archive_read_filter *self, const char *cmd)
|
||||
{
|
||||
(void)self; /* UNUSED */
|
||||
(void)cmd; /* UNUSED */
|
||||
|
||||
archive_set_error(&self->archive->archive, -1,
|
||||
"External compression programs not supported on this platform");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "filter_fork.h"
|
||||
|
||||
/*
|
||||
* The bidder object stores the command and the signature to watch for.
|
||||
* The 'inhibit' entry here is used to ensure that unchecked filters never
|
||||
* bid twice in the same pipeline.
|
||||
*/
|
||||
struct program_bidder {
|
||||
char *description;
|
||||
char *cmd;
|
||||
void *signature;
|
||||
size_t signature_len;
|
||||
@ -138,8 +104,12 @@ static int program_bidder_free(struct archive_read_filter_bidder *);
|
||||
* The actual filter needs to track input and output data.
|
||||
*/
|
||||
struct program_filter {
|
||||
char *description;
|
||||
struct archive_string description;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
HANDLE child;
|
||||
#else
|
||||
pid_t child;
|
||||
#endif
|
||||
int exit_status;
|
||||
int waitpid_return;
|
||||
int child_stdin, child_stdout;
|
||||
@ -151,6 +121,29 @@ struct program_filter {
|
||||
static ssize_t program_filter_read(struct archive_read_filter *,
|
||||
const void **);
|
||||
static int program_filter_close(struct archive_read_filter *);
|
||||
static void free_state(struct program_bidder *);
|
||||
|
||||
static int
|
||||
set_bidder_signature(struct archive_read_filter_bidder *bidder,
|
||||
struct program_bidder *state, const void *signature, size_t signature_len)
|
||||
{
|
||||
|
||||
if (signature != NULL && signature_len > 0) {
|
||||
state->signature_len = signature_len;
|
||||
state->signature = malloc(signature_len);
|
||||
memcpy(state->signature, signature, signature_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the bidder object.
|
||||
*/
|
||||
bidder->data = state;
|
||||
bidder->bid = program_bidder_bid;
|
||||
bidder->init = program_bidder_init;
|
||||
bidder->options = NULL;
|
||||
bidder->free = program_bidder_free;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_support_filter_program_signature(struct archive *_a,
|
||||
@ -169,37 +162,40 @@ archive_read_support_filter_program_signature(struct archive *_a,
|
||||
/*
|
||||
* Allocate our private state.
|
||||
*/
|
||||
state = (struct program_bidder *)calloc(sizeof (*state), 1);
|
||||
state = (struct program_bidder *)calloc(1, sizeof (*state));
|
||||
if (state == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
goto memerr;
|
||||
state->cmd = strdup(cmd);
|
||||
if (signature != NULL && signature_len > 0) {
|
||||
state->signature_len = signature_len;
|
||||
state->signature = malloc(signature_len);
|
||||
memcpy(state->signature, signature, signature_len);
|
||||
}
|
||||
if (state->cmd == NULL)
|
||||
goto memerr;
|
||||
|
||||
/*
|
||||
* Fill in the bidder object.
|
||||
*/
|
||||
bidder->data = state;
|
||||
bidder->bid = program_bidder_bid;
|
||||
bidder->init = program_bidder_init;
|
||||
bidder->options = NULL;
|
||||
bidder->free = program_bidder_free;
|
||||
return (ARCHIVE_OK);
|
||||
return set_bidder_signature(bidder, state, signature, signature_len);
|
||||
memerr:
|
||||
free_state(state);
|
||||
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
program_bidder_free(struct archive_read_filter_bidder *self)
|
||||
{
|
||||
struct program_bidder *state = (struct program_bidder *)self->data;
|
||||
free(state->cmd);
|
||||
free(state->signature);
|
||||
free(self->data);
|
||||
|
||||
free_state(state);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
free_state(struct program_bidder *state)
|
||||
{
|
||||
|
||||
if (state) {
|
||||
free(state->cmd);
|
||||
free(state->signature);
|
||||
free(state);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we do have a signature, bid only if that matches.
|
||||
*
|
||||
@ -258,6 +254,9 @@ child_stop(struct archive_read_filter *self, struct program_filter *state)
|
||||
state->waitpid_return
|
||||
= waitpid(state->child, &state->exit_status, 0);
|
||||
} while (state->waitpid_return == -1 && errno == EINTR);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
CloseHandle(state->child);
|
||||
#endif
|
||||
state->child = 0;
|
||||
}
|
||||
|
||||
@ -310,11 +309,35 @@ child_read(struct archive_read_filter *self, char *buf, size_t buf_len)
|
||||
struct program_filter *state = self->data;
|
||||
ssize_t ret, requested, avail;
|
||||
const char *p;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
HANDLE handle = (HANDLE)_get_osfhandle(state->child_stdout);
|
||||
#endif
|
||||
|
||||
requested = buf_len > SSIZE_MAX ? SSIZE_MAX : buf_len;
|
||||
|
||||
for (;;) {
|
||||
do {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Avoid infinity wait.
|
||||
* Note: If there is no data in the pipe, ReadFile()
|
||||
* called in read() never returns and so we won't
|
||||
* write remaining encoded data to the pipe.
|
||||
* Note: This way may cause performance problem.
|
||||
* we are looking forward to great code to resolve
|
||||
* this. */
|
||||
DWORD pipe_avail = -1;
|
||||
int cnt = 2;
|
||||
|
||||
while (PeekNamedPipe(handle, NULL, 0, NULL,
|
||||
&pipe_avail, NULL) != 0 && pipe_avail == 0 &&
|
||||
cnt--)
|
||||
Sleep(5);
|
||||
if (pipe_avail == 0) {
|
||||
ret = -1;
|
||||
errno = EAGAIN;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
ret = read(state->child_stdout, buf, requested);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
@ -376,38 +399,57 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
|
||||
struct program_filter *state;
|
||||
static const size_t out_buf_len = 65536;
|
||||
char *out_buf;
|
||||
char *description;
|
||||
const char *prefix = "Program: ";
|
||||
pid_t child;
|
||||
size_t l;
|
||||
|
||||
l = strlen(prefix) + strlen(cmd) + 1;
|
||||
state = (struct program_filter *)calloc(1, sizeof(*state));
|
||||
out_buf = (char *)malloc(out_buf_len);
|
||||
description = (char *)malloc(strlen(prefix) + strlen(cmd) + 1);
|
||||
if (state == NULL || out_buf == NULL || description == NULL) {
|
||||
if (state == NULL || out_buf == NULL ||
|
||||
archive_string_ensure(&state->description, l) == NULL) {
|
||||
archive_set_error(&self->archive->archive, ENOMEM,
|
||||
"Can't allocate input data");
|
||||
free(state);
|
||||
if (state != NULL) {
|
||||
archive_string_free(&state->description);
|
||||
free(state);
|
||||
}
|
||||
free(out_buf);
|
||||
free(description);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_strcpy(&state->description, prefix);
|
||||
archive_strcat(&state->description, cmd);
|
||||
|
||||
self->code = ARCHIVE_COMPRESSION_PROGRAM;
|
||||
state->description = description;
|
||||
strcpy(state->description, prefix);
|
||||
strcat(state->description, cmd);
|
||||
self->name = state->description;
|
||||
self->code = ARCHIVE_FILTER_PROGRAM;
|
||||
self->name = state->description.s;
|
||||
|
||||
state->out_buf = out_buf;
|
||||
state->out_buf_len = out_buf_len;
|
||||
|
||||
if ((state->child = __archive_create_child(cmd,
|
||||
&state->child_stdin, &state->child_stdout)) == -1) {
|
||||
child = __archive_create_child(cmd, &state->child_stdin,
|
||||
&state->child_stdout);
|
||||
if (child == -1) {
|
||||
free(state->out_buf);
|
||||
free(state);
|
||||
archive_set_error(&self->archive->archive, EINVAL,
|
||||
"Can't initialize filter; unable to run program \"%s\"", cmd);
|
||||
"Can't initialize filter; unable to run program \"%s\"",
|
||||
cmd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
state->child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, child);
|
||||
if (state->child == NULL) {
|
||||
child_stop(self, state);
|
||||
free(state->out_buf);
|
||||
free(state);
|
||||
archive_set_error(&self->archive->archive, EINVAL,
|
||||
"Can't initialize filter; unable to run program \"%s\"",
|
||||
cmd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#else
|
||||
state->child = child;
|
||||
#endif
|
||||
|
||||
self->data = state;
|
||||
self->read = program_filter_read;
|
||||
@ -467,10 +509,8 @@ program_filter_close(struct archive_read_filter *self)
|
||||
|
||||
/* Release our private data. */
|
||||
free(state->out_buf);
|
||||
free(state->description);
|
||||
archive_string_free(&state->description);
|
||||
free(state);
|
||||
|
||||
return (e);
|
||||
}
|
||||
|
||||
#endif /* !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL) */
|
||||
|
@ -85,6 +85,7 @@ archive_read_support_filter_rpm(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "rpm";
|
||||
bidder->bid = rpm_bidder_bid;
|
||||
bidder->init = rpm_bidder_init;
|
||||
bidder->options = NULL;
|
||||
@ -137,7 +138,7 @@ rpm_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
struct rpm *rpm;
|
||||
|
||||
self->code = ARCHIVE_COMPRESSION_RPM;
|
||||
self->code = ARCHIVE_FILTER_RPM;
|
||||
self->name = "rpm";
|
||||
self->read = rpm_filter_read;
|
||||
self->skip = NULL; /* not supported */
|
||||
|
@ -56,6 +56,7 @@ struct uudecode {
|
||||
#define ST_READ_UU 1
|
||||
#define ST_UUEND 2
|
||||
#define ST_READ_BASE64 3
|
||||
#define ST_IGNORE 4
|
||||
};
|
||||
|
||||
static int uudecode_bidder_bid(struct archive_read_filter_bidder *,
|
||||
@ -88,6 +89,7 @@ archive_read_support_filter_uu(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "uu";
|
||||
bidder->bid = uudecode_bidder_bid;
|
||||
bidder->init = uudecode_bidder_init;
|
||||
bidder->options = NULL;
|
||||
@ -377,7 +379,7 @@ uudecode_bidder_init(struct archive_read_filter *self)
|
||||
void *out_buff;
|
||||
void *in_buff;
|
||||
|
||||
self->code = ARCHIVE_COMPRESSION_UU;
|
||||
self->code = ARCHIVE_FILTER_UU;
|
||||
self->name = "uu";
|
||||
self->read = uudecode_filter_read;
|
||||
self->skip = NULL; /* not supported */
|
||||
@ -470,6 +472,10 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
|
||||
total = 0;
|
||||
out = uudecode->out_buff;
|
||||
ravail = avail_in;
|
||||
if (uudecode->state == ST_IGNORE) {
|
||||
used = avail_in;
|
||||
goto finish;
|
||||
}
|
||||
if (uudecode->in_cnt) {
|
||||
/*
|
||||
* If there is remaining data which is saved by
|
||||
@ -485,12 +491,18 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
|
||||
uudecode->in_cnt = 0;
|
||||
}
|
||||
for (;used < avail_in; d += llen, used += llen) {
|
||||
int l, body;
|
||||
int64_t l, body;
|
||||
|
||||
b = d;
|
||||
len = get_line(b, avail_in - used, &nl);
|
||||
if (len < 0) {
|
||||
/* Non-ascii character is found. */
|
||||
if (uudecode->state == ST_FIND_HEAD &&
|
||||
(uudecode->total > 0 || total > 0)) {
|
||||
uudecode->state = ST_IGNORE;
|
||||
used = avail_in;
|
||||
goto finish;
|
||||
}
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Insufficient compressed data");
|
||||
@ -507,7 +519,7 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (uudecode->in_buff != b)
|
||||
memmove(uudecode->in_buff, b, len);
|
||||
uudecode->in_cnt = len;
|
||||
uudecode->in_cnt = (int)len;
|
||||
if (total == 0) {
|
||||
/* Do not return 0; it means end-of-file.
|
||||
* We should try to read bytes more. */
|
||||
@ -545,7 +557,7 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
|
||||
break;
|
||||
case ST_READ_UU:
|
||||
if (total + len * 2 > OUT_BUFF_SIZE)
|
||||
break;
|
||||
goto finish;
|
||||
body = len - nl;
|
||||
if (!uuchar[*b] || body <= 0) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
@ -611,7 +623,7 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
|
||||
break;
|
||||
case ST_READ_BASE64:
|
||||
if (total + len * 2 > OUT_BUFF_SIZE)
|
||||
break;
|
||||
goto finish;
|
||||
l = len - nl;
|
||||
if (l >= 3 && b[0] == '=' && b[1] == '=' &&
|
||||
b[2] == '=') {
|
||||
@ -657,8 +669,10 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__archive_read_filter_consume(self->upstream, ravail);
|
||||
finish:
|
||||
if (ravail < avail_in)
|
||||
used -= avail_in - ravail;
|
||||
__archive_read_filter_consume(self->upstream, used);
|
||||
|
||||
*buff = uudecode->out_buff;
|
||||
uudecode->total += total;
|
||||
|
@ -136,6 +136,7 @@ archive_read_support_filter_xz(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "xz";
|
||||
bidder->bid = xz_bidder_bid;
|
||||
bidder->init = xz_bidder_init;
|
||||
bidder->options = NULL;
|
||||
@ -144,7 +145,7 @@ archive_read_support_filter_xz(struct archive *_a)
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external unxz program for xz decompression");
|
||||
"Using external xz program for xz decompression");
|
||||
return (ARCHIVE_WARN);
|
||||
#endif
|
||||
}
|
||||
@ -170,6 +171,7 @@ archive_read_support_filter_lzma(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "lzma";
|
||||
bidder->bid = lzma_bidder_bid;
|
||||
bidder->init = lzma_bidder_init;
|
||||
bidder->options = NULL;
|
||||
@ -180,7 +182,7 @@ archive_read_support_filter_lzma(struct archive *_a)
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external unlzma program for lzma decompression");
|
||||
"Using external lzma program for lzma decompression");
|
||||
return (ARCHIVE_WARN);
|
||||
#endif
|
||||
}
|
||||
@ -207,6 +209,7 @@ archive_read_support_filter_lzip(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "lzip";
|
||||
bidder->bid = lzip_bidder_bid;
|
||||
bidder->init = lzip_bidder_init;
|
||||
bidder->options = NULL;
|
||||
@ -415,7 +418,7 @@ lzip_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
static int
|
||||
xz_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
self->code = ARCHIVE_COMPRESSION_XZ;
|
||||
self->code = ARCHIVE_FILTER_XZ;
|
||||
self->name = "xz";
|
||||
return (xz_lzma_bidder_init(self));
|
||||
}
|
||||
@ -423,7 +426,7 @@ xz_bidder_init(struct archive_read_filter *self)
|
||||
static int
|
||||
lzma_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
self->code = ARCHIVE_COMPRESSION_LZMA;
|
||||
self->code = ARCHIVE_FILTER_LZMA;
|
||||
self->name = "lzma";
|
||||
return (xz_lzma_bidder_init(self));
|
||||
}
|
||||
@ -431,7 +434,7 @@ lzma_bidder_init(struct archive_read_filter *self)
|
||||
static int
|
||||
lzip_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
self->code = ARCHIVE_COMPRESSION_LZIP;
|
||||
self->code = ARCHIVE_FILTER_LZIP;
|
||||
self->name = "lzip";
|
||||
return (xz_lzma_bidder_init(self));
|
||||
}
|
||||
@ -518,7 +521,7 @@ xz_lzma_bidder_init(struct archive_read_filter *self)
|
||||
state->stream.avail_out = state->out_block_size;
|
||||
|
||||
state->crc32 = 0;
|
||||
if (self->code == ARCHIVE_COMPRESSION_LZIP) {
|
||||
if (self->code == ARCHIVE_FILTER_LZIP) {
|
||||
/*
|
||||
* We have to read a lzip header and use it to initialize
|
||||
* compression library, thus we cannot initialize the
|
||||
@ -530,7 +533,7 @@ xz_lzma_bidder_init(struct archive_read_filter *self)
|
||||
state->in_stream = 1;
|
||||
|
||||
/* Initialize compression library. */
|
||||
if (self->code == ARCHIVE_COMPRESSION_XZ)
|
||||
if (self->code == ARCHIVE_FILTER_XZ)
|
||||
ret = lzma_stream_decoder(&(state->stream),
|
||||
LZMA_MEMLIMIT,/* memlimit */
|
||||
LZMA_CONCATENATED);
|
||||
@ -730,7 +733,7 @@ xz_filter_read(struct archive_read_filter *self, const void **p)
|
||||
*p = NULL;
|
||||
else {
|
||||
*p = state->out_block;
|
||||
if (self->code == ARCHIVE_COMPRESSION_LZIP) {
|
||||
if (self->code == ARCHIVE_FILTER_LZIP) {
|
||||
state->crc32 = lzma_crc32(state->out_block,
|
||||
decompressed, state->crc32);
|
||||
if (state->eof) {
|
||||
@ -778,7 +781,7 @@ lzma_bidder_init(struct archive_read_filter *self)
|
||||
struct private_data *state;
|
||||
ssize_t ret, avail_in;
|
||||
|
||||
self->code = ARCHIVE_COMPRESSION_LZMA;
|
||||
self->code = ARCHIVE_FILTER_LZMA;
|
||||
self->name = "lzma";
|
||||
|
||||
state = (struct private_data *)calloc(sizeof(*state), 1);
|
||||
@ -941,11 +944,11 @@ lzma_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "unlzma");
|
||||
r = __archive_read_program(self, "lzma -d -qq");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_COMPRESSION_LZMA;
|
||||
self->code = ARCHIVE_FILTER_LZMA;
|
||||
self->name = "lzma";
|
||||
return (r);
|
||||
}
|
||||
@ -958,11 +961,11 @@ xz_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "unxz");
|
||||
r = __archive_read_program(self, "xz -d -qq");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_COMPRESSION_XZ;
|
||||
self->code = ARCHIVE_FILTER_XZ;
|
||||
self->name = "xz";
|
||||
return (r);
|
||||
}
|
||||
@ -972,11 +975,11 @@ lzip_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "unlzip");
|
||||
r = __archive_read_program(self, "lzip -d -q");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_COMPRESSION_LZIP;
|
||||
self->code = ARCHIVE_FILTER_LZIP;
|
||||
self->name = "lzip";
|
||||
return (r);
|
||||
}
|
||||
|
@ -409,6 +409,7 @@ archive_read_support_format_7zip(struct archive *_a)
|
||||
archive_read_format_7zip_read_header,
|
||||
archive_read_format_7zip_read_data,
|
||||
archive_read_format_7zip_read_data_skip,
|
||||
NULL,
|
||||
archive_read_format_7zip_cleanup);
|
||||
|
||||
if (r != ARCHIVE_OK)
|
||||
@ -684,8 +685,8 @@ archive_read_format_7zip_read_header(struct archive_read *a,
|
||||
symname[symsize] = '\0';
|
||||
archive_entry_copy_symlink(entry,
|
||||
(const char *)symname);
|
||||
free(symname);
|
||||
}
|
||||
free(symname);
|
||||
archive_entry_set_size(entry, 0);
|
||||
}
|
||||
|
||||
@ -709,16 +710,15 @@ archive_read_format_7zip_read_data(struct archive_read *a,
|
||||
if (zip->pack_stream_bytes_unconsumed)
|
||||
read_consume(a);
|
||||
|
||||
*offset = zip->entry_offset;
|
||||
*size = 0;
|
||||
*buff = NULL;
|
||||
/*
|
||||
* If we hit end-of-entry last time, clean up and return
|
||||
* ARCHIVE_EOF this time.
|
||||
*/
|
||||
if (zip->end_of_entry) {
|
||||
*offset = zip->entry_offset;
|
||||
*size = 0;
|
||||
*buff = NULL;
|
||||
if (zip->end_of_entry)
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
|
||||
bytes = read_stream(a, buff,
|
||||
(size_t)zip->entry_bytes_remaining, 0);
|
||||
@ -736,7 +736,8 @@ archive_read_format_7zip_read_data(struct archive_read *a,
|
||||
|
||||
/* Update checksum */
|
||||
if ((zip->entry->flg & CRC32_IS_SET) && bytes)
|
||||
zip->entry_crc32 = crc32(zip->entry_crc32, *buff, bytes);
|
||||
zip->entry_crc32 = crc32(zip->entry_crc32, *buff,
|
||||
(unsigned)bytes);
|
||||
|
||||
/* If we hit the end, swallow any end-of-data marker. */
|
||||
if (zip->end_of_entry) {
|
||||
@ -1363,9 +1364,9 @@ decompress(struct archive_read *a, struct _7zip *zip,
|
||||
#ifdef HAVE_ZLIB_H
|
||||
case _7Z_DEFLATE:
|
||||
zip->stream.next_in = (Bytef *)(uintptr_t)t_next_in;
|
||||
zip->stream.avail_in = t_avail_in;
|
||||
zip->stream.avail_in = (uInt)t_avail_in;
|
||||
zip->stream.next_out = t_next_out;
|
||||
zip->stream.avail_out = t_avail_out;
|
||||
zip->stream.avail_out = (uInt)t_avail_out;
|
||||
r = inflate(&(zip->stream), 0);
|
||||
switch (r) {
|
||||
case Z_STREAM_END: /* Found end of stream. */
|
||||
@ -1607,9 +1608,10 @@ read_Digests(struct archive_read *a, struct _7z_digests *d, size_t num)
|
||||
const unsigned char *p;
|
||||
unsigned i;
|
||||
|
||||
if (num == 0)
|
||||
return (-1);
|
||||
memset(d, 0, sizeof(*d));
|
||||
|
||||
|
||||
d->defineds = malloc(num);
|
||||
if (d->defineds == NULL)
|
||||
return (-1);
|
||||
@ -2687,7 +2689,7 @@ header_bytes(struct archive_read *a, size_t rbytes)
|
||||
}
|
||||
|
||||
/* Update checksum */
|
||||
zip->header_crc32 = crc32(zip->header_crc32, p, rbytes);
|
||||
zip->header_crc32 = crc32(zip->header_crc32, p, (unsigned)rbytes);
|
||||
return (p);
|
||||
}
|
||||
|
||||
@ -2966,16 +2968,19 @@ extract_pack_stream(struct archive_read *a, size_t minimum)
|
||||
* Expand the uncompressed buffer up to
|
||||
* the minimum size.
|
||||
*/
|
||||
zip->uncompressed_buffer_size = minimum + 1023;
|
||||
zip->uncompressed_buffer_size &= ~0x3ff;
|
||||
zip->uncompressed_buffer =
|
||||
realloc(zip->uncompressed_buffer,
|
||||
zip->uncompressed_buffer_size);
|
||||
if (zip->uncompressed_buffer == NULL) {
|
||||
void *p;
|
||||
size_t new_size;
|
||||
|
||||
new_size = minimum + 1023;
|
||||
new_size &= ~0x3ff;
|
||||
p = realloc(zip->uncompressed_buffer, new_size);
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory for 7-Zip decompression");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
zip->uncompressed_buffer = (unsigned char *)p;
|
||||
zip->uncompressed_buffer_size = new_size;
|
||||
}
|
||||
/*
|
||||
* Move unconsumed bytes to the head.
|
||||
@ -3095,7 +3100,7 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
|
||||
{
|
||||
struct _7zip *zip = (struct _7zip *)a->format->data;
|
||||
uint64_t skip_bytes = 0;
|
||||
int r;
|
||||
ssize_t r;
|
||||
|
||||
if (zip->uncompressed_buffer_bytes_remaining == 0) {
|
||||
if (zip->pack_stream_inbytes_remaining > 0) {
|
||||
@ -3346,8 +3351,10 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
|
||||
for (i = 0; i < 3; i++) {
|
||||
const struct _7z_coder *coder = scoder[i];
|
||||
|
||||
if ((r = seek_pack(a)) < 0)
|
||||
if ((r = seek_pack(a)) < 0) {
|
||||
free(b[0]); free(b[1]); free(b[2]);
|
||||
return (r);
|
||||
}
|
||||
|
||||
if (sunpack[i] == (uint64_t)-1)
|
||||
zip->folder_outbytes_remaining =
|
||||
@ -3356,13 +3363,16 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
|
||||
zip->folder_outbytes_remaining = sunpack[i];
|
||||
|
||||
r = init_decompression(a, zip, coder, NULL);
|
||||
if (r != ARCHIVE_OK)
|
||||
if (r != ARCHIVE_OK) {
|
||||
free(b[0]); free(b[1]); free(b[2]);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Allocate memory for the decorded data of a sub
|
||||
* stream. */
|
||||
b[i] = malloc((size_t)zip->folder_outbytes_remaining);
|
||||
if (b[i] == NULL) {
|
||||
free(b[0]); free(b[1]); free(b[2]);
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory for 7-Zip decompression");
|
||||
return (ARCHIVE_FATAL);
|
||||
@ -3370,14 +3380,18 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
|
||||
|
||||
/* Extract a sub stream. */
|
||||
while (zip->pack_stream_inbytes_remaining > 0) {
|
||||
r = extract_pack_stream(a, 0);
|
||||
if (r < 0)
|
||||
r = (int)extract_pack_stream(a, 0);
|
||||
if (r < 0) {
|
||||
free(b[0]); free(b[1]); free(b[2]);
|
||||
return (r);
|
||||
}
|
||||
bytes = get_uncompressed_data(a, &buff,
|
||||
zip->uncompressed_buffer_bytes_remaining,
|
||||
0);
|
||||
if (bytes < 0)
|
||||
if (bytes < 0) {
|
||||
free(b[0]); free(b[1]); free(b[2]);
|
||||
return ((int)bytes);
|
||||
}
|
||||
memcpy(b[i]+s[i], buff, bytes);
|
||||
s[i] += bytes;
|
||||
if (zip->pack_stream_bytes_unconsumed)
|
||||
@ -3557,7 +3571,7 @@ x86_Convert(struct _7zip *zip, uint8_t *data, size_t size)
|
||||
}
|
||||
zip->bcj_prevPosT = prevPosT;
|
||||
zip->bcj_prevMask = prevMask;
|
||||
zip->bcj_ip += bufferPos;
|
||||
zip->bcj_ip += (uint32_t)bufferPos;
|
||||
return (bufferPos);
|
||||
}
|
||||
|
||||
@ -3701,7 +3715,7 @@ Bcj2_Decode(struct _7zip *zip, uint8_t *outBuf, size_t outSize)
|
||||
((uint32_t)v[1] << 16) |
|
||||
((uint32_t)v[2] << 8) |
|
||||
((uint32_t)v[3])) -
|
||||
((uint32_t)zip->bcj2_outPos + outPos + 4);
|
||||
((uint32_t)zip->bcj2_outPos + (uint32_t)outPos + 4);
|
||||
out[0] = (uint8_t)dest;
|
||||
out[1] = (uint8_t)(dest >> 8);
|
||||
out[2] = (uint8_t)(dest >> 16);
|
||||
@ -3716,7 +3730,7 @@ Bcj2_Decode(struct _7zip *zip, uint8_t *outBuf, size_t outSize)
|
||||
*/
|
||||
zip->odd_bcj_size = 4 -i;
|
||||
for (; i < 4; i++) {
|
||||
j = i - 4 + zip->odd_bcj_size;
|
||||
j = i - 4 + (unsigned)zip->odd_bcj_size;
|
||||
zip->odd_bcj[j] = out[i];
|
||||
}
|
||||
break;
|
||||
|
@ -121,6 +121,7 @@ archive_read_support_format_ar(struct archive *_a)
|
||||
archive_read_format_ar_read_header,
|
||||
archive_read_format_ar_read_data,
|
||||
archive_read_format_ar_skip,
|
||||
NULL,
|
||||
archive_read_format_ar_cleanup);
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
|
@ -382,6 +382,7 @@ archive_read_support_format_cab(struct archive *_a)
|
||||
archive_read_format_cab_read_header,
|
||||
archive_read_format_cab_read_data,
|
||||
archive_read_format_cab_read_data_skip,
|
||||
NULL,
|
||||
archive_read_format_cab_cleanup);
|
||||
|
||||
if (r != ARCHIVE_OK)
|
||||
@ -539,7 +540,7 @@ truncated_error(struct archive_read *a)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
static ssize_t
|
||||
cab_strnlen(const unsigned char *p, size_t maxlen)
|
||||
{
|
||||
size_t i;
|
||||
@ -550,7 +551,7 @@ cab_strnlen(const unsigned char *p, size_t maxlen)
|
||||
}
|
||||
if (i > maxlen)
|
||||
return (-1);/* invalid */
|
||||
return (i);
|
||||
return ((ssize_t)i);
|
||||
}
|
||||
|
||||
/* Read bytes as much as remaining. */
|
||||
@ -626,8 +627,9 @@ cab_read_header(struct archive_read *a)
|
||||
struct cab *cab;
|
||||
struct cfheader *hd;
|
||||
size_t bytes, used;
|
||||
ssize_t len;
|
||||
int64_t skip;
|
||||
int err, i, len;
|
||||
int err, i;
|
||||
int cur_folder, prev_folder;
|
||||
uint32_t offset32;
|
||||
|
||||
@ -1066,13 +1068,13 @@ static uint32_t
|
||||
cab_checksum_cfdata_4(const void *p, size_t bytes, uint32_t seed)
|
||||
{
|
||||
const unsigned char *b;
|
||||
int u32num;
|
||||
unsigned u32num;
|
||||
uint32_t sum;
|
||||
|
||||
u32num = bytes / 4;
|
||||
u32num = (unsigned)bytes / 4;
|
||||
sum = seed;
|
||||
b = p;
|
||||
while (--u32num >= 0) {
|
||||
for (;u32num > 0; --u32num) {
|
||||
sum ^= archive_le32dec(b);
|
||||
b += 4;
|
||||
}
|
||||
@ -1485,7 +1487,7 @@ cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
|
||||
* cast to remove 'const'.
|
||||
*/
|
||||
cab->stream.next_in = (Bytef *)(uintptr_t)d;
|
||||
cab->stream.avail_in = bytes_avail;
|
||||
cab->stream.avail_in = (uInt)bytes_avail;
|
||||
cab->stream.total_in = 0;
|
||||
|
||||
/* Cut out a tow-byte MSZIP signature(0x43, 0x4b). */
|
||||
@ -1506,7 +1508,7 @@ cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
|
||||
*avail = ARCHIVE_FATAL;
|
||||
return (NULL);
|
||||
}
|
||||
mszip -= bytes_avail;
|
||||
mszip -= (int)bytes_avail;
|
||||
continue;
|
||||
}
|
||||
if (mszip == 1 && cab->stream.next_in[0] != 0x4b)
|
||||
@ -1935,7 +1937,7 @@ cab_read_data(struct archive_read *a, const void **buff,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT, "Invalid CFDATA");
|
||||
return (ARCHIVE_FATAL);
|
||||
} else
|
||||
return (bytes_avail);
|
||||
return ((int)bytes_avail);
|
||||
}
|
||||
if (bytes_avail > cab->entry_bytes_remaining)
|
||||
bytes_avail = (ssize_t)cab->entry_bytes_remaining;
|
||||
@ -2001,7 +2003,8 @@ archive_read_format_cab_read_data_skip(struct archive_read *a)
|
||||
|
||||
/* If the compression type is none(uncompressed), we've already
|
||||
* consumed data as much as the current entry size. */
|
||||
if (cab->entry_cffolder->comptype == COMPTYPE_NONE)
|
||||
if (cab->entry_cffolder->comptype == COMPTYPE_NONE &&
|
||||
cab->entry_cfdata != NULL)
|
||||
cab->entry_cfdata->unconsumed = 0;
|
||||
|
||||
/* This entry is finished and done. */
|
||||
@ -2198,7 +2201,7 @@ lzx_translation(struct lzx_stream *strm, void *p, size_t size, uint32_t offset)
|
||||
size_t i = b - (unsigned char *)p;
|
||||
int32_t cp, displacement, value;
|
||||
|
||||
cp = offset + i;
|
||||
cp = (int32_t)(offset + (uint32_t)i);
|
||||
value = archive_le32dec(&b[1]);
|
||||
if (value >= -cp && value < (int32_t)ds->translation_size) {
|
||||
if (value >= 0)
|
||||
@ -2584,7 +2587,7 @@ lzx_read_blocks(struct lzx_stream *strm, int last)
|
||||
goto failed;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
l = ds->block_bytes_avail;
|
||||
l = (int)ds->block_bytes_avail;
|
||||
if (l > ds->w_size - ds->w_pos)
|
||||
l = ds->w_size - ds->w_pos;
|
||||
if (l > strm->avail_out)
|
||||
@ -2746,8 +2749,8 @@ lzx_decode_blocks(struct lzx_stream *strm, int last)
|
||||
struct lzx_br bre = ds->br;
|
||||
struct huffman *at = &(ds->at), *lt = &(ds->lt), *mt = &(ds->mt);
|
||||
const struct lzx_pos_tbl *pos_tbl = ds->pos_tbl;
|
||||
unsigned char *outp = strm->next_out;
|
||||
unsigned char *endp = outp + strm->avail_out;
|
||||
unsigned char *noutp = strm->next_out;
|
||||
unsigned char *endp = noutp + strm->avail_out;
|
||||
unsigned char *w_buff = ds->w_buff;
|
||||
unsigned char *at_bitlen = at->bitlen;
|
||||
unsigned char *lt_bitlen = lt->bitlen;
|
||||
@ -2781,10 +2784,10 @@ lzx_decode_blocks(struct lzx_stream *strm, int last)
|
||||
ds->position_slot = position_slot;
|
||||
ds->r0 = r0; ds->r1 = r1; ds->r2 = r2;
|
||||
ds->w_pos = w_pos;
|
||||
strm->avail_out = endp - outp;
|
||||
strm->avail_out = endp - noutp;
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
if (outp >= endp)
|
||||
if (noutp >= endp)
|
||||
/* Output buffer is empty. */
|
||||
goto next_data;
|
||||
|
||||
@ -2818,7 +2821,7 @@ lzx_decode_blocks(struct lzx_stream *strm, int last)
|
||||
w_buff[w_pos] = c;
|
||||
w_pos = (w_pos + 1) & w_mask;
|
||||
/* Store the decoded code to output buffer. */
|
||||
*outp++ = c;
|
||||
*noutp++ = c;
|
||||
block_bytes_avail--;
|
||||
}
|
||||
/*
|
||||
@ -2963,22 +2966,22 @@ lzx_decode_blocks(struct lzx_stream *strm, int last)
|
||||
if (l > w_size - w_pos)
|
||||
l = w_size - w_pos;
|
||||
}
|
||||
if (outp + l >= endp)
|
||||
l = endp - outp;
|
||||
if (noutp + l >= endp)
|
||||
l = (int)(endp - noutp);
|
||||
s = w_buff + copy_pos;
|
||||
if (l >= 8 && ((copy_pos + l < w_pos)
|
||||
|| (w_pos + l < copy_pos))) {
|
||||
memcpy(w_buff + w_pos, s, l);
|
||||
memcpy(outp, s, l);
|
||||
memcpy(noutp, s, l);
|
||||
} else {
|
||||
unsigned char *d;
|
||||
int li;
|
||||
|
||||
d = w_buff + w_pos;
|
||||
for (li = 0; li < l; li++)
|
||||
outp[li] = d[li] = s[li];
|
||||
noutp[li] = d[li] = s[li];
|
||||
}
|
||||
outp += l;
|
||||
noutp += l;
|
||||
copy_pos = (copy_pos + l) & w_mask;
|
||||
w_pos = (w_pos + l) & w_mask;
|
||||
block_bytes_avail -= l;
|
||||
@ -2986,7 +2989,7 @@ lzx_decode_blocks(struct lzx_stream *strm, int last)
|
||||
/* A copy of current pattern ended. */
|
||||
break;
|
||||
copy_len -= l;
|
||||
if (outp >= endp) {
|
||||
if (noutp >= endp) {
|
||||
/* Output buffer is empty. */
|
||||
state = ST_COPY;
|
||||
goto next_data;
|
||||
@ -3009,7 +3012,7 @@ lzx_decode_blocks(struct lzx_stream *strm, int last)
|
||||
ds->r0 = r0; ds->r1 = r1; ds->r2 = r2;
|
||||
ds->state = state;
|
||||
ds->w_pos = w_pos;
|
||||
strm->avail_out = endp - outp;
|
||||
strm->avail_out = endp - noutp;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -3126,7 +3129,7 @@ lzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
|
||||
hf->bitlen = calloc(len_size, sizeof(hf->bitlen[0]));
|
||||
if (hf->bitlen == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
hf->len_size = len_size;
|
||||
hf->len_size = (int)len_size;
|
||||
} else
|
||||
memset(hf->bitlen, 0, len_size * sizeof(hf->bitlen[0]));
|
||||
if (hf->tbl == NULL) {
|
||||
@ -3134,7 +3137,7 @@ lzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
|
||||
bits = tbl_bits;
|
||||
else
|
||||
bits = HTBL_BITS;
|
||||
hf->tbl = malloc((1 << bits) * sizeof(hf->tbl[0]));
|
||||
hf->tbl = malloc(((size_t)1 << bits) * sizeof(hf->tbl[0]));
|
||||
if (hf->tbl == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
hf->tbl_bits = tbl_bits;
|
||||
|
@ -242,6 +242,7 @@ archive_read_support_format_cpio(struct archive *_a)
|
||||
archive_read_format_cpio_read_header,
|
||||
archive_read_format_cpio_read_data,
|
||||
archive_read_format_cpio_skip,
|
||||
NULL,
|
||||
archive_read_format_cpio_cleanup);
|
||||
|
||||
if (r != ARCHIVE_OK)
|
||||
|
@ -53,6 +53,7 @@ archive_read_support_format_empty(struct archive *_a)
|
||||
archive_read_format_empty_read_header,
|
||||
archive_read_format_empty_read_data,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
return (r);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2009 Andreas Henriksson <andreas@fatal.se>
|
||||
* Copyright (c) 2009-2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2009-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -374,6 +374,8 @@ struct iso9660 {
|
||||
size_t utf16be_path_len;
|
||||
unsigned char *utf16be_previous_path;
|
||||
size_t utf16be_previous_path_len;
|
||||
/* Null buufer used in bidder to improve its performance. */
|
||||
unsigned char null[2048];
|
||||
};
|
||||
|
||||
static int archive_read_format_iso9660_bid(struct archive_read *, int);
|
||||
@ -475,6 +477,7 @@ archive_read_support_format_iso9660(struct archive *_a)
|
||||
archive_read_format_iso9660_read_header,
|
||||
archive_read_format_iso9660_read_data,
|
||||
archive_read_format_iso9660_read_data_skip,
|
||||
NULL,
|
||||
archive_read_format_iso9660_cleanup);
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
@ -587,6 +590,23 @@ archive_read_format_iso9660_options(struct archive_read *a,
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static int
|
||||
isNull(struct iso9660 *iso9660, const unsigned char *h, unsigned offset,
|
||||
unsigned bytes)
|
||||
{
|
||||
|
||||
while (bytes >= sizeof(iso9660->null)) {
|
||||
if (!memcmp(iso9660->null, h + offset, sizeof(iso9660->null)))
|
||||
return (0);
|
||||
offset += sizeof(iso9660->null);
|
||||
bytes -= sizeof(iso9660->null);
|
||||
}
|
||||
if (bytes)
|
||||
return memcmp(iso9660->null, h + offset, bytes) == 0;
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
isBootRecord(struct iso9660 *iso9660, const unsigned char *h)
|
||||
{
|
||||
@ -632,8 +652,6 @@ isVolumePartition(struct iso9660 *iso9660, const unsigned char *h)
|
||||
static int
|
||||
isVDSetTerminator(struct iso9660 *iso9660, const unsigned char *h)
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)iso9660; /* UNUSED */
|
||||
|
||||
/* Type of the Volume Descriptor Set Terminator must be 255. */
|
||||
@ -645,9 +663,8 @@ isVDSetTerminator(struct iso9660 *iso9660, const unsigned char *h)
|
||||
return (0);
|
||||
|
||||
/* Reserved field must be 0. */
|
||||
for (i = 7; i < 2048; ++i)
|
||||
if (h[i] != 0)
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, 7, 2048-7))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
@ -708,7 +725,6 @@ isSVD(struct iso9660 *iso9660, const unsigned char *h)
|
||||
ssize_t logical_block_size;
|
||||
int32_t volume_block;
|
||||
int32_t location;
|
||||
int i;
|
||||
|
||||
(void)iso9660; /* UNUSED */
|
||||
|
||||
@ -717,15 +733,12 @@ isSVD(struct iso9660 *iso9660, const unsigned char *h)
|
||||
return (0);
|
||||
|
||||
/* Reserved field must be 0. */
|
||||
for (i = 0; i < SVD_reserved1_size; ++i)
|
||||
if (h[SVD_reserved1_offset + i] != 0)
|
||||
return (0);
|
||||
for (i = 0; i < SVD_reserved2_size; ++i)
|
||||
if (h[SVD_reserved2_offset + i] != 0)
|
||||
return (0);
|
||||
for (i = 0; i < SVD_reserved3_size; ++i)
|
||||
if (h[SVD_reserved3_offset + i] != 0)
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, SVD_reserved1_offset, SVD_reserved1_size))
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, SVD_reserved2_offset, SVD_reserved2_size))
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, SVD_reserved3_offset, SVD_reserved3_size))
|
||||
return (0);
|
||||
|
||||
/* File structure version must be 1 for ISO9660/ECMA119. */
|
||||
if (h[SVD_file_structure_version_offset] != 1)
|
||||
@ -771,7 +784,6 @@ isEVD(struct iso9660 *iso9660, const unsigned char *h)
|
||||
ssize_t logical_block_size;
|
||||
int32_t volume_block;
|
||||
int32_t location;
|
||||
int i;
|
||||
|
||||
(void)iso9660; /* UNUSED */
|
||||
|
||||
@ -788,14 +800,12 @@ isEVD(struct iso9660 *iso9660, const unsigned char *h)
|
||||
return (0);
|
||||
|
||||
/* Reserved field must be 0. */
|
||||
for (i = 0; i < PVD_reserved2_size; ++i)
|
||||
if (h[PVD_reserved2_offset + i] != 0)
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, PVD_reserved2_offset, PVD_reserved2_size))
|
||||
return (0);
|
||||
|
||||
/* Reserved field must be 0. */
|
||||
for (i = 0; i < PVD_reserved3_size; ++i)
|
||||
if (h[PVD_reserved3_offset + i] != 0)
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, PVD_reserved3_offset, PVD_reserved3_size))
|
||||
return (0);
|
||||
|
||||
/* Logical block size must be > 0. */
|
||||
/* I've looked at Ecma 119 and can't find any stronger
|
||||
@ -830,14 +840,12 @@ isEVD(struct iso9660 *iso9660, const unsigned char *h)
|
||||
return (0);
|
||||
|
||||
/* Reserved field must be 0. */
|
||||
for (i = 0; i < PVD_reserved4_size; ++i)
|
||||
if (h[PVD_reserved4_offset + i] != 0)
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, PVD_reserved4_offset, PVD_reserved4_size))
|
||||
return (0);
|
||||
|
||||
/* Reserved field must be 0. */
|
||||
for (i = 0; i < PVD_reserved5_size; ++i)
|
||||
if (h[PVD_reserved5_offset + i] != 0)
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, PVD_reserved5_offset, PVD_reserved5_size))
|
||||
return (0);
|
||||
|
||||
/* Read Root Directory Record in Volume Descriptor. */
|
||||
p = h + PVD_root_directory_record_offset;
|
||||
@ -869,14 +877,12 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
|
||||
return (0);
|
||||
|
||||
/* Reserved field must be 0. */
|
||||
for (i = 0; i < PVD_reserved2_size; ++i)
|
||||
if (h[PVD_reserved2_offset + i] != 0)
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, PVD_reserved2_offset, PVD_reserved2_size))
|
||||
return (0);
|
||||
|
||||
/* Reserved field must be 0. */
|
||||
for (i = 0; i < PVD_reserved3_size; ++i)
|
||||
if (h[PVD_reserved3_offset + i] != 0)
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, PVD_reserved3_offset, PVD_reserved3_size))
|
||||
return (0);
|
||||
|
||||
/* Logical block size must be > 0. */
|
||||
/* I've looked at Ecma 119 and can't find any stronger
|
||||
@ -919,9 +925,8 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
|
||||
return (0);
|
||||
|
||||
/* Reserved field must be 0. */
|
||||
for (i = 0; i < PVD_reserved5_size; ++i)
|
||||
if (h[PVD_reserved5_offset + i] != 0)
|
||||
return (0);
|
||||
if (!isNull(iso9660, h, PVD_reserved5_offset, PVD_reserved5_size))
|
||||
return (0);
|
||||
|
||||
/* XXX TODO: Check other values for sanity; reject more
|
||||
* malformed PVDs. XXX */
|
||||
@ -934,8 +939,10 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
|
||||
if (!iso9660->primary.location) {
|
||||
iso9660->logical_block_size = logical_block_size;
|
||||
iso9660->volume_block = volume_block;
|
||||
iso9660->volume_size = logical_block_size * (uint64_t)volume_block;
|
||||
iso9660->primary.location = archive_le32dec(p + DR_extent_offset);
|
||||
iso9660->volume_size =
|
||||
logical_block_size * (uint64_t)volume_block;
|
||||
iso9660->primary.location =
|
||||
archive_le32dec(p + DR_extent_offset);
|
||||
iso9660->primary.size = archive_le32dec(p + DR_size_offset);
|
||||
}
|
||||
|
||||
@ -951,6 +958,12 @@ read_children(struct archive_read *a, struct file_info *parent)
|
||||
size_t step, skip_size;
|
||||
|
||||
iso9660 = (struct iso9660 *)(a->format->data);
|
||||
/* flush any remaining bytes from the last round to ensure
|
||||
* we're positioned */
|
||||
if (iso9660->entry_bytes_unconsumed) {
|
||||
__archive_read_consume(a, iso9660->entry_bytes_unconsumed);
|
||||
iso9660->entry_bytes_unconsumed = 0;
|
||||
}
|
||||
if (iso9660->current_position > parent->offset) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Ignoring out-of-order directory (%s) %jd > %jd",
|
||||
@ -1059,6 +1072,94 @@ read_children(struct archive_read *a, struct file_info *parent)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
choose_volume(struct archive_read *a, struct iso9660 *iso9660)
|
||||
{
|
||||
struct file_info *file;
|
||||
int64_t skipsize;
|
||||
struct vd *vd;
|
||||
const void *block;
|
||||
char seenJoliet;
|
||||
|
||||
vd = &(iso9660->primary);
|
||||
if (!iso9660->opt_support_joliet)
|
||||
iso9660->seenJoliet = 0;
|
||||
if (iso9660->seenJoliet &&
|
||||
vd->location > iso9660->joliet.location)
|
||||
/* This condition is unlikely; by way of caution. */
|
||||
vd = &(iso9660->joliet);
|
||||
|
||||
skipsize = LOGICAL_BLOCK_SIZE * vd->location;
|
||||
skipsize = __archive_read_consume(a, skipsize);
|
||||
if (skipsize < 0)
|
||||
return ((int)skipsize);
|
||||
iso9660->current_position = skipsize;
|
||||
|
||||
block = __archive_read_ahead(a, vd->size, NULL);
|
||||
if (block == NULL) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Failed to read full block when scanning "
|
||||
"ISO9660 directory list");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* While reading Root Directory, flag seenJoliet must be zero to
|
||||
* avoid converting special name 0x00(Current Directory) and
|
||||
* next byte to UCS2.
|
||||
*/
|
||||
seenJoliet = iso9660->seenJoliet;/* Save flag. */
|
||||
iso9660->seenJoliet = 0;
|
||||
file = parse_file_info(a, NULL, block);
|
||||
if (file == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
iso9660->seenJoliet = seenJoliet;
|
||||
|
||||
/*
|
||||
* If the iso image has both RockRidge and Joliet, we preferentially
|
||||
* use RockRidge Extensions rather than Joliet ones.
|
||||
*/
|
||||
if (vd == &(iso9660->primary) && iso9660->seenRockridge
|
||||
&& iso9660->seenJoliet)
|
||||
iso9660->seenJoliet = 0;
|
||||
|
||||
if (vd == &(iso9660->primary) && !iso9660->seenRockridge
|
||||
&& iso9660->seenJoliet) {
|
||||
/* Switch reading data from primary to joliet. */
|
||||
vd = &(iso9660->joliet);
|
||||
skipsize = LOGICAL_BLOCK_SIZE * vd->location;
|
||||
skipsize -= iso9660->current_position;
|
||||
skipsize = __archive_read_consume(a, skipsize);
|
||||
if (skipsize < 0)
|
||||
return ((int)skipsize);
|
||||
iso9660->current_position += skipsize;
|
||||
|
||||
block = __archive_read_ahead(a, vd->size, NULL);
|
||||
if (block == NULL) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Failed to read full block when scanning "
|
||||
"ISO9660 directory list");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
iso9660->seenJoliet = 0;
|
||||
file = parse_file_info(a, NULL, block);
|
||||
if (file == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
iso9660->seenJoliet = seenJoliet;
|
||||
}
|
||||
|
||||
/* Store the root directory in the pending list. */
|
||||
if (add_entry(a, iso9660, file) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (iso9660->seenRockridge) {
|
||||
a->archive.archive_format = ARCHIVE_FORMAT_ISO9660_ROCKRIDGE;
|
||||
a->archive.archive_format_name =
|
||||
"ISO9660 with Rockridge extensions";
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_read_format_iso9660_read_header(struct archive_read *a,
|
||||
struct archive_entry *entry)
|
||||
@ -1075,86 +1176,9 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
|
||||
}
|
||||
|
||||
if (iso9660->current_position == 0) {
|
||||
int64_t skipsize;
|
||||
struct vd *vd;
|
||||
const void *block;
|
||||
char seenJoliet;
|
||||
|
||||
vd = &(iso9660->primary);
|
||||
if (!iso9660->opt_support_joliet)
|
||||
iso9660->seenJoliet = 0;
|
||||
if (iso9660->seenJoliet &&
|
||||
vd->location > iso9660->joliet.location)
|
||||
/* This condition is unlikely; by way of caution. */
|
||||
vd = &(iso9660->joliet);
|
||||
|
||||
skipsize = LOGICAL_BLOCK_SIZE * vd->location;
|
||||
skipsize = __archive_read_consume(a, skipsize);
|
||||
if (skipsize < 0)
|
||||
return ((int)skipsize);
|
||||
iso9660->current_position = skipsize;
|
||||
|
||||
block = __archive_read_ahead(a, vd->size, NULL);
|
||||
if (block == NULL) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Failed to read full block when scanning "
|
||||
"ISO9660 directory list");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* While reading Root Directory, flag seenJoliet
|
||||
* must be zero to avoid converting special name
|
||||
* 0x00(Current Directory) and next byte to UCS2.
|
||||
*/
|
||||
seenJoliet = iso9660->seenJoliet;/* Save flag. */
|
||||
iso9660->seenJoliet = 0;
|
||||
file = parse_file_info(a, NULL, block);
|
||||
if (file == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
iso9660->seenJoliet = seenJoliet;
|
||||
if (vd == &(iso9660->primary) && iso9660->seenRockridge
|
||||
&& iso9660->seenJoliet)
|
||||
/*
|
||||
* If iso image has RockRidge and Joliet,
|
||||
* we use RockRidge Extensions.
|
||||
*/
|
||||
iso9660->seenJoliet = 0;
|
||||
if (vd == &(iso9660->primary) && !iso9660->seenRockridge
|
||||
&& iso9660->seenJoliet) {
|
||||
/* Switch reading data from primary to joliet. */
|
||||
vd = &(iso9660->joliet);
|
||||
skipsize = LOGICAL_BLOCK_SIZE * vd->location;
|
||||
skipsize -= iso9660->current_position;
|
||||
skipsize = __archive_read_consume(a, skipsize);
|
||||
if (skipsize < 0)
|
||||
return ((int)skipsize);
|
||||
iso9660->current_position += skipsize;
|
||||
|
||||
block = __archive_read_ahead(a, vd->size, NULL);
|
||||
if (block == NULL) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Failed to read full block when scanning "
|
||||
"ISO9660 directory list");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
iso9660->seenJoliet = 0;
|
||||
file = parse_file_info(a, NULL, block);
|
||||
if (file == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
iso9660->seenJoliet = seenJoliet;
|
||||
}
|
||||
/* Store the root directory in the pending list. */
|
||||
if (add_entry(a, iso9660, file) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (iso9660->seenRockridge) {
|
||||
a->archive.archive_format =
|
||||
ARCHIVE_FORMAT_ISO9660_ROCKRIDGE;
|
||||
a->archive.archive_format_name =
|
||||
"ISO9660 with Rockridge extensions";
|
||||
}
|
||||
r = choose_volume(a, iso9660);
|
||||
if (r != ARCHIVE_OK)
|
||||
return (r);
|
||||
}
|
||||
|
||||
file = NULL;/* Eliminate a warning. */
|
||||
@ -1227,14 +1251,14 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
|
||||
}
|
||||
|
||||
iso9660->entry_bytes_remaining = file->size;
|
||||
iso9660->entry_sparse_offset = 0; /* Offset for sparse-file-aware clients. */
|
||||
/* Offset for sparse-file-aware clients. */
|
||||
iso9660->entry_sparse_offset = 0;
|
||||
|
||||
if (file->offset + file->size > iso9660->volume_size) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"File is beyond end-of-media: %s",
|
||||
archive_entry_pathname(entry));
|
||||
iso9660->entry_bytes_remaining = 0;
|
||||
iso9660->entry_sparse_offset = 0;
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
@ -1286,36 +1310,33 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
|
||||
iso9660->previous_pathname.s);
|
||||
archive_entry_unset_size(entry);
|
||||
iso9660->entry_bytes_remaining = 0;
|
||||
iso9660->entry_sparse_offset = 0;
|
||||
return (rd_r);
|
||||
}
|
||||
|
||||
/* Except for the hardlink case above, if the offset of the
|
||||
* next entry is before our current position, we can't seek
|
||||
* backwards to extract it, so issue a warning. Note that
|
||||
* this can only happen if this entry was added to the heap
|
||||
* after we passed this offset, that is, only if the directory
|
||||
* mentioning this entry is later than the body of the entry.
|
||||
* Such layouts are very unusual; most ISO9660 writers lay out
|
||||
* and record all directory information first, then store
|
||||
* all file bodies. */
|
||||
/* TODO: Someday, libarchive's I/O core will support optional
|
||||
* seeking. When that day comes, this code should attempt to
|
||||
* seek and only return the error if the seek fails. That
|
||||
* will give us support for whacky ISO images that require
|
||||
* seeking while retaining the ability to read almost all ISO
|
||||
* images in a streaming fashion. */
|
||||
if ((file->mode & AE_IFMT) != AE_IFDIR &&
|
||||
file->offset < iso9660->current_position) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Ignoring out-of-order file @%jx (%s) %jd < %jd",
|
||||
(intmax_t)file->number,
|
||||
iso9660->pathname.s,
|
||||
(intmax_t)file->offset,
|
||||
(intmax_t)iso9660->current_position);
|
||||
iso9660->entry_bytes_remaining = 0;
|
||||
iso9660->entry_sparse_offset = 0;
|
||||
return (ARCHIVE_WARN);
|
||||
int64_t r64;
|
||||
|
||||
r64 = __archive_read_seek(a, file->offset, SEEK_SET);
|
||||
if (r64 != (int64_t)file->offset) {
|
||||
/* We can't seek backwards to extract it, so issue
|
||||
* a warning. Note that this can only happen if
|
||||
* this entry was added to the heap after we passed
|
||||
* this offset, that is, only if the directory
|
||||
* mentioning this entry is later than the body of
|
||||
* the entry. Such layouts are very unusual; most
|
||||
* ISO9660 writers lay out and record all directory
|
||||
* information first, then store all file bodies. */
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Ignoring out-of-order file @%jx (%s) %jd < %jd",
|
||||
(intmax_t)file->number,
|
||||
iso9660->pathname.s,
|
||||
(intmax_t)file->offset,
|
||||
(intmax_t)iso9660->current_position);
|
||||
iso9660->entry_bytes_remaining = 0;
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
iso9660->current_position = (uint64_t)r64;
|
||||
}
|
||||
|
||||
/* Initialize zisofs variables. */
|
||||
@ -1356,7 +1377,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
|
||||
archive_entry_set_nlink(entry, 2 + file->subdirs);
|
||||
/* Directory data has been read completely. */
|
||||
iso9660->entry_bytes_remaining = 0;
|
||||
iso9660->entry_sparse_offset = 0;
|
||||
}
|
||||
|
||||
if (rd_r != ARCHIVE_OK)
|
||||
@ -1426,7 +1446,7 @@ zisofs_read_data(struct archive_read *a,
|
||||
zisofs->block_pointers_size = xsize;
|
||||
|
||||
/* Allocate uncompressed data buffer. */
|
||||
xsize = 1UL << zisofs->pz_log2_bs;
|
||||
xsize = (size_t)1UL << zisofs->pz_log2_bs;
|
||||
if (zisofs->uncompressed_buffer_size < xsize) {
|
||||
if (zisofs->uncompressed_buffer != NULL)
|
||||
free(zisofs->uncompressed_buffer);
|
||||
@ -1563,9 +1583,10 @@ zisofs_read_data(struct archive_read *a,
|
||||
if (avail > zisofs->block_avail)
|
||||
zisofs->stream.avail_in = zisofs->block_avail;
|
||||
else
|
||||
zisofs->stream.avail_in = avail;
|
||||
zisofs->stream.avail_in = (uInt)avail;
|
||||
zisofs->stream.next_out = zisofs->uncompressed_buffer;
|
||||
zisofs->stream.avail_out = zisofs->uncompressed_buffer_size;
|
||||
zisofs->stream.avail_out =
|
||||
(uInt)zisofs->uncompressed_buffer_size;
|
||||
|
||||
r = inflate(&zisofs->stream, 0);
|
||||
switch (r) {
|
||||
@ -1580,7 +1601,7 @@ zisofs_read_data(struct archive_read *a,
|
||||
uncompressed_size =
|
||||
zisofs->uncompressed_buffer_size - zisofs->stream.avail_out;
|
||||
avail -= zisofs->stream.next_in - p;
|
||||
zisofs->block_avail -= zisofs->stream.next_in - p;
|
||||
zisofs->block_avail -= (uint32_t)(zisofs->stream.next_in - p);
|
||||
}
|
||||
next_data:
|
||||
bytes_read -= avail;
|
||||
@ -1590,7 +1611,7 @@ zisofs_read_data(struct archive_read *a,
|
||||
iso9660->entry_sparse_offset += uncompressed_size;
|
||||
iso9660->entry_bytes_remaining -= bytes_read;
|
||||
iso9660->current_position += bytes_read;
|
||||
zisofs->pz_offset += bytes_read;
|
||||
zisofs->pz_offset += (uint32_t)bytes_read;
|
||||
iso9660->entry_bytes_unconsumed += bytes_read;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
@ -1873,9 +1894,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
if (iso9660->opt_support_rockridge) {
|
||||
if (parent == NULL && rr_end - rr_start >= 7) {
|
||||
p = rr_start;
|
||||
if (p[0] == 'S' && p[1] == 'P'
|
||||
&& p[2] == 7 && p[3] == 1
|
||||
&& p[4] == 0xBE && p[5] == 0xEF) {
|
||||
if (memcmp(p, "SP\x07\x01\xbe\xef", 6) == 0) {
|
||||
/*
|
||||
* SP extension stores the suspOffset
|
||||
* (Number of bytes to skip between
|
||||
@ -1935,6 +1954,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
if (iso9660->seenRockridge) {
|
||||
if (parent != NULL && parent->parent == NULL &&
|
||||
(flags & 0x02) && iso9660->rr_moved == NULL &&
|
||||
file->name.s &&
|
||||
(strcmp(file->name.s, "rr_moved") == 0 ||
|
||||
strcmp(file->name.s, ".rr_moved") == 0)) {
|
||||
iso9660->rr_moved = file;
|
||||
@ -2067,14 +2087,9 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
|
||||
int data_length = p[2] - 4;
|
||||
int version = p[3];
|
||||
|
||||
/*
|
||||
* Yes, each 'if' here does test p[0] again.
|
||||
* Otherwise, the fall-through handling to catch
|
||||
* unsupported extensions doesn't work.
|
||||
*/
|
||||
switch(p[0]) {
|
||||
case 'C':
|
||||
if (p[0] == 'C' && p[1] == 'E') {
|
||||
if (p[1] == 'E') {
|
||||
if (version == 1 && data_length == 24) {
|
||||
/*
|
||||
* CE extension comprises:
|
||||
@ -2092,53 +2107,42 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
|
||||
!= ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (p[0] == 'C' && p[1] == 'L') {
|
||||
else if (p[1] == 'L') {
|
||||
if (version == 1 && data_length == 8) {
|
||||
file->cl_offset = (uint64_t)
|
||||
iso9660->logical_block_size *
|
||||
(uint64_t)archive_le32dec(data);
|
||||
iso9660->seenRockridge = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
break;
|
||||
case 'N':
|
||||
if (p[0] == 'N' && p[1] == 'M') {
|
||||
if (p[1] == 'M') {
|
||||
if (version == 1) {
|
||||
parse_rockridge_NM1(file,
|
||||
data, data_length);
|
||||
iso9660->seenRockridge = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
break;
|
||||
case 'P':
|
||||
if (p[0] == 'P' && p[1] == 'D') {
|
||||
/*
|
||||
* PD extension is padding;
|
||||
* contents are always ignored.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (p[0] == 'P' && p[1] == 'L') {
|
||||
/*
|
||||
* PL extension won't appear;
|
||||
* contents are always ignored.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (p[0] == 'P' && p[1] == 'N') {
|
||||
/*
|
||||
* PD extension is padding;
|
||||
* contents are always ignored.
|
||||
*
|
||||
* PL extension won't appear;
|
||||
* contents are always ignored.
|
||||
*/
|
||||
if (p[1] == 'N') {
|
||||
if (version == 1 && data_length == 16) {
|
||||
file->rdev = toi(data,4);
|
||||
file->rdev <<= 32;
|
||||
file->rdev |= toi(data + 8, 4);
|
||||
iso9660->seenRockridge = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (p[0] == 'P' && p[1] == 'X') {
|
||||
else if (p[1] == 'X') {
|
||||
/*
|
||||
* PX extension comprises:
|
||||
* 8 bytes for mode,
|
||||
@ -2165,35 +2169,31 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
|
||||
= toi(data + 32, 4);
|
||||
iso9660->seenRockridge = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
break;
|
||||
case 'R':
|
||||
if (p[0] == 'R' && p[1] == 'E' && version == 1) {
|
||||
if (p[1] == 'E' && version == 1) {
|
||||
file->re = 1;
|
||||
iso9660->seenRockridge = 1;
|
||||
break;
|
||||
}
|
||||
if (p[0] == 'R' && p[1] == 'R' && version == 1) {
|
||||
else if (p[1] == 'R' && version == 1) {
|
||||
/*
|
||||
* RR extension comprises:
|
||||
* one byte flag value
|
||||
* This extension is obsolete,
|
||||
* so contents are always ignored.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
break;
|
||||
case 'S':
|
||||
if (p[0] == 'S' && p[1] == 'L') {
|
||||
if (p[1] == 'L') {
|
||||
if (version == 1) {
|
||||
parse_rockridge_SL1(file,
|
||||
data, data_length);
|
||||
iso9660->seenRockridge = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (p[0] == 'S' && p[1] == 'T'
|
||||
else if (p[1] == 'T'
|
||||
&& data_length == 0 && version == 1) {
|
||||
/*
|
||||
* ST extension marks end of this
|
||||
@ -2208,32 +2208,27 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
|
||||
iso9660->seenRockridge = 0;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
if (p[0] == 'T' && p[1] == 'F') {
|
||||
if (p[1] == 'F') {
|
||||
if (version == 1) {
|
||||
parse_rockridge_TF1(file,
|
||||
data, data_length);
|
||||
iso9660->seenRockridge = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
break;
|
||||
case 'Z':
|
||||
if (p[0] == 'Z' && p[1] == 'F') {
|
||||
if (p[1] == 'F') {
|
||||
if (version == 1)
|
||||
parse_rockridge_ZF1(file,
|
||||
data, data_length);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
break;
|
||||
default:
|
||||
/* The FALLTHROUGHs above leave us here for
|
||||
* any unsupported extension. */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
p += p[2];
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
@ -2893,8 +2888,9 @@ next_cache_entry(struct archive_read *a, struct iso9660 *iso9660,
|
||||
|
||||
fatal_rr:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Failed to connect 'CL' pointer to 'RE' rr_moved pointer of"
|
||||
"Rockridge extensions");
|
||||
"Failed to connect 'CL' pointer to 'RE' rr_moved pointer of "
|
||||
"Rockridge extensions: current position = %jd, CL offset = %jd",
|
||||
(intmax_t)iso9660->current_position, (intmax_t)file->cl_offset);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
@ -3226,10 +3222,12 @@ dump_isodirrec(FILE *out, const unsigned char *isodirrec)
|
||||
fprintf(out, " ilv %d,",
|
||||
toi(isodirrec + DR_interleave_offset, DR_interleave_size));
|
||||
fprintf(out, " seq %d,",
|
||||
toi(isodirrec + DR_volume_sequence_number_offset, DR_volume_sequence_number_size));
|
||||
toi(isodirrec + DR_volume_sequence_number_offset,
|
||||
DR_volume_sequence_number_size));
|
||||
fprintf(out, " nl %d:",
|
||||
toi(isodirrec + DR_name_len_offset, DR_name_len_size));
|
||||
fprintf(out, " `%.*s'",
|
||||
toi(isodirrec + DR_name_len_offset, DR_name_len_size), isodirrec + DR_name_offset);
|
||||
toi(isodirrec + DR_name_len_offset, DR_name_len_size),
|
||||
isodirrec + DR_name_offset);
|
||||
}
|
||||
#endif
|
||||
|
@ -272,7 +272,7 @@ static int lha_skip_sfx(struct archive_read *);
|
||||
static time_t lha_dos_time(const unsigned char *);
|
||||
static time_t lha_win_time(uint64_t, long *);
|
||||
static unsigned char lha_calcsum(unsigned char, const void *,
|
||||
int, int);
|
||||
int, size_t);
|
||||
static int lha_parse_linkname(struct archive_string *,
|
||||
struct archive_string *);
|
||||
static int lha_read_data_none(struct archive_read *, const void **,
|
||||
@ -319,6 +319,7 @@ archive_read_support_format_lha(struct archive *_a)
|
||||
archive_read_format_lha_read_header,
|
||||
archive_read_format_lha_read_data,
|
||||
archive_read_format_lha_read_data_skip,
|
||||
NULL,
|
||||
archive_read_format_lha_cleanup);
|
||||
|
||||
if (r != ARCHIVE_OK)
|
||||
@ -1634,7 +1635,7 @@ lha_parse_linkname(struct archive_string *linkname,
|
||||
struct archive_string *pathname)
|
||||
{
|
||||
char * linkptr;
|
||||
int symlen;
|
||||
size_t symlen;
|
||||
|
||||
linkptr = strchr(pathname->s, '|');
|
||||
if (linkptr != NULL) {
|
||||
@ -1689,12 +1690,12 @@ lha_win_time(uint64_t wintime, long *ns)
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
lha_calcsum(unsigned char sum, const void *pp, int offset, int size)
|
||||
lha_calcsum(unsigned char sum, const void *pp, int offset, size_t size)
|
||||
{
|
||||
unsigned char const *p = (unsigned char const *)pp;
|
||||
|
||||
p += offset;
|
||||
while (--size >= 0)
|
||||
for (;size > 0; --size)
|
||||
sum += *p++;
|
||||
return (sum);
|
||||
}
|
||||
@ -2019,7 +2020,7 @@ lzh_copy_from_window(struct lzh_stream *strm, struct lzh_dec *ds)
|
||||
copy_bytes = (size_t)strm->avail_out;
|
||||
memcpy(strm->next_out,
|
||||
ds->w_buff + ds->copy_pos, copy_bytes);
|
||||
ds->copy_pos += copy_bytes;
|
||||
ds->copy_pos += (int)copy_bytes;
|
||||
} else {
|
||||
if (ds->w_remaining <= strm->avail_out)
|
||||
copy_bytes = ds->w_remaining;
|
||||
@ -2027,7 +2028,7 @@ lzh_copy_from_window(struct lzh_stream *strm, struct lzh_dec *ds)
|
||||
copy_bytes = (size_t)strm->avail_out;
|
||||
memcpy(strm->next_out,
|
||||
ds->w_buff + ds->w_size - ds->w_remaining, copy_bytes);
|
||||
ds->w_remaining -= copy_bytes;
|
||||
ds->w_remaining -= (int)copy_bytes;
|
||||
}
|
||||
strm->next_out += copy_bytes;
|
||||
strm->avail_out -= copy_bytes;
|
||||
@ -2481,7 +2482,7 @@ lzh_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
|
||||
bits = tbl_bits;
|
||||
else
|
||||
bits = HTBL_BITS;
|
||||
hf->tbl = malloc((1 << bits) * sizeof(hf->tbl[0]));
|
||||
hf->tbl = malloc(((size_t)1 << bits) * sizeof(hf->tbl[0]));
|
||||
if (hf->tbl == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
@ -2491,7 +2492,7 @@ lzh_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
|
||||
if (hf->tree == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
hf->len_size = len_size;
|
||||
hf->len_size = (int)len_size;
|
||||
hf->tbl_bits = tbl_bits;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2008 Joerg Sonnenberger
|
||||
* Copyright (c) 2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -55,6 +55,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
#define MTREE_HAS_DEVICE 0x0001
|
||||
#define MTREE_HAS_FFLAGS 0x0002
|
||||
@ -69,6 +72,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
|
||||
#define MTREE_HAS_UNAME 0x0400
|
||||
|
||||
#define MTREE_HAS_OPTIONAL 0x0800
|
||||
#define MTREE_HAS_NOCHANGE 0x1000 /* FreeBSD specific */
|
||||
|
||||
struct mtree_option {
|
||||
struct mtree_option *next;
|
||||
@ -103,6 +107,7 @@ struct mtree {
|
||||
|
||||
static int bid_keycmp(const char *, const char *, ssize_t);
|
||||
static int cleanup(struct archive_read *);
|
||||
static int detect_form(struct archive_read *, int *);
|
||||
static int mtree_bid(struct archive_read *, int);
|
||||
static int parse_file(struct archive_read *, struct archive_entry *,
|
||||
struct mtree *, struct mtree_entry *, int *);
|
||||
@ -200,7 +205,7 @@ archive_read_support_format_mtree(struct archive *_a)
|
||||
mtree->fd = -1;
|
||||
|
||||
r = __archive_read_register_format(a, mtree, "mtree",
|
||||
mtree_bid, NULL, read_header, read_data, skip, cleanup);
|
||||
mtree_bid, NULL, read_header, read_data, skip, NULL, cleanup);
|
||||
|
||||
if (r != ARCHIVE_OK)
|
||||
free(mtree);
|
||||
@ -349,7 +354,7 @@ bid_keycmp(const char *p, const char *key, ssize_t len)
|
||||
* Returns the length of a detected keyword.
|
||||
* Returns 0 if any keywords were not found.
|
||||
*/
|
||||
static ssize_t
|
||||
static int
|
||||
bid_keyword(const char *p, ssize_t len)
|
||||
{
|
||||
static const char *keys_c[] = {
|
||||
@ -368,7 +373,7 @@ bid_keyword(const char *p, ssize_t len)
|
||||
"md5", "md5digest", "mode", NULL
|
||||
};
|
||||
static const char *keys_no[] = {
|
||||
"nlink", "optional", NULL
|
||||
"nlink", "nochange", "optional", NULL
|
||||
};
|
||||
static const char *keys_r[] = {
|
||||
"rmd160", "rmd160digest", NULL
|
||||
@ -419,7 +424,7 @@ bid_keyword(const char *p, ssize_t len)
|
||||
* When "unset" is specified, expects a set of "<space characters>keyword".
|
||||
*/
|
||||
static int
|
||||
bid_keyword_list(const char *p, ssize_t len, int unset)
|
||||
bid_keyword_list(const char *p, ssize_t len, int unset, int last_is_path)
|
||||
{
|
||||
int l;
|
||||
int keycnt = 0;
|
||||
@ -437,8 +442,10 @@ bid_keyword_list(const char *p, ssize_t len, int unset)
|
||||
break;
|
||||
if (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r'))
|
||||
break;
|
||||
if (!blank) /* No blank character. */
|
||||
if (!blank && !last_is_path) /* No blank character. */
|
||||
return (-1);
|
||||
if (last_is_path && len == 0)
|
||||
return (keycnt);
|
||||
|
||||
if (unset) {
|
||||
l = bid_keycmp(p, "all", len);
|
||||
@ -473,7 +480,7 @@ bid_keyword_list(const char *p, ssize_t len, int unset)
|
||||
}
|
||||
|
||||
static int
|
||||
bid_entry(const char *p, ssize_t len)
|
||||
bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)
|
||||
{
|
||||
int f = 0;
|
||||
static const unsigned char safe_char[256] = {
|
||||
@ -500,22 +507,60 @@ bid_entry(const char *p, ssize_t len)
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
|
||||
};
|
||||
ssize_t ll = len;
|
||||
const char *pp = p;
|
||||
|
||||
*last_is_path = 0;
|
||||
/*
|
||||
* Skip the path-name which is quoted.
|
||||
*/
|
||||
while (len > 0 && *p != ' ' && *p != '\t') {
|
||||
if (!safe_char[*(const unsigned char *)p])
|
||||
return (-1);
|
||||
++p;
|
||||
--len;
|
||||
while (ll > 0 && *pp != ' ' &&*pp != '\t' && *pp != '\r' &&
|
||||
*pp != '\n') {
|
||||
if (!safe_char[*(const unsigned char *)pp]) {
|
||||
f = 0;
|
||||
break;
|
||||
}
|
||||
++pp;
|
||||
--ll;
|
||||
++f;
|
||||
}
|
||||
/* If a path-name was not found, returns error. */
|
||||
if (f == 0)
|
||||
return (-1);
|
||||
/* If a path-name was not found at the first, try to check
|
||||
* a mtree format ``NetBSD's mtree -D'' creates, which
|
||||
* places the path-name at the last. */
|
||||
if (f == 0) {
|
||||
const char *pb = p + len - nl;
|
||||
int name_len = 0;
|
||||
int slash;
|
||||
|
||||
return (bid_keyword_list(p, len, 0));
|
||||
/* Do not accept multi lines for form D. */
|
||||
if (pb-2 >= p &&
|
||||
pb[-1] == '\\' && (pb[-2] == ' ' || pb[-2] == '\t'))
|
||||
return (-1);
|
||||
if (pb-1 >= p && pb[-1] == '\\')
|
||||
return (-1);
|
||||
|
||||
slash = 0;
|
||||
while (p <= --pb && *pb != ' ' && *pb != '\t') {
|
||||
if (!safe_char[*(const unsigned char *)pb])
|
||||
return (-1);
|
||||
name_len++;
|
||||
/* The pathname should have a slash in this
|
||||
* format. */
|
||||
if (*pb == '/')
|
||||
slash = 1;
|
||||
}
|
||||
if (name_len == 0 || slash == 0)
|
||||
return (-1);
|
||||
/* If '/' is placed at the first in this field, this is not
|
||||
* a valid filename. */
|
||||
if (pb[1] == '/')
|
||||
return (-1);
|
||||
ll = len - nl - name_len;
|
||||
pp = p;
|
||||
*last_is_path = 1;
|
||||
}
|
||||
|
||||
return (bid_keyword_list(pp, ll, 0, *last_is_path));
|
||||
}
|
||||
|
||||
#define MAX_BID_ENTRY 3
|
||||
@ -525,14 +570,11 @@ mtree_bid(struct archive_read *a, int best_bid)
|
||||
{
|
||||
const char *signature = "#mtree";
|
||||
const char *p;
|
||||
ssize_t avail, ravail;
|
||||
ssize_t len, nl;
|
||||
int detected_bytes = 0, entry_cnt = 0, multiline = 0;
|
||||
|
||||
(void)best_bid; /* UNUSED */
|
||||
|
||||
/* Now let's look at the actual header and see if it matches. */
|
||||
p = __archive_read_ahead(a, strlen(signature), &avail);
|
||||
p = __archive_read_ahead(a, strlen(signature), NULL);
|
||||
if (p == NULL)
|
||||
return (-1);
|
||||
|
||||
@ -542,6 +584,24 @@ mtree_bid(struct archive_read *a, int best_bid)
|
||||
/*
|
||||
* There is not a mtree signature. Let's try to detect mtree format.
|
||||
*/
|
||||
return (detect_form(a, NULL));
|
||||
}
|
||||
|
||||
static int
|
||||
detect_form(struct archive_read *a, int *is_form_d)
|
||||
{
|
||||
const char *p;
|
||||
ssize_t avail, ravail;
|
||||
ssize_t detected_bytes = 0, len, nl;
|
||||
int entry_cnt = 0, multiline = 0;
|
||||
int form_D = 0;/* The archive is generated by `NetBSD mtree -D'
|
||||
* (In this source we call it `form D') . */
|
||||
|
||||
if (is_form_d != NULL)
|
||||
*is_form_d = 0;
|
||||
p = __archive_read_ahead(a, 1, &avail);
|
||||
if (p == NULL)
|
||||
return (-1);
|
||||
ravail = avail;
|
||||
for (;;) {
|
||||
len = next_line(a, &p, &avail, &ravail, &nl);
|
||||
@ -566,7 +626,7 @@ mtree_bid(struct archive_read *a, int best_bid)
|
||||
} else {
|
||||
/* A continuance line; the terminal
|
||||
* character of previous line was '\' character. */
|
||||
if (bid_keyword_list(p, len, 0) <= 0)
|
||||
if (bid_keyword_list(p, len, 0, 0) <= 0)
|
||||
break;
|
||||
if (multiline == 1)
|
||||
detected_bytes += len;
|
||||
@ -581,9 +641,25 @@ mtree_bid(struct archive_read *a, int best_bid)
|
||||
continue;
|
||||
}
|
||||
if (p[0] != '/') {
|
||||
if (bid_entry(p, len) >= 0) {
|
||||
int last_is_path, keywords;
|
||||
|
||||
keywords = bid_entry(p, len, nl, &last_is_path);
|
||||
if (keywords >= 0) {
|
||||
detected_bytes += len;
|
||||
if (p[len-nl-1] == '\\')
|
||||
if (form_D == 0) {
|
||||
if (last_is_path)
|
||||
form_D = 1;
|
||||
else if (keywords > 0)
|
||||
/* This line is not `form D'. */
|
||||
form_D = -1;
|
||||
} else if (form_D == 1) {
|
||||
if (!last_is_path && keywords > 0)
|
||||
/* This this is not `form D'
|
||||
* and We cannot accept mixed
|
||||
* format. */
|
||||
break;
|
||||
}
|
||||
if (!last_is_path && p[len-nl-1] == '\\')
|
||||
/* This line continues. */
|
||||
multiline = 1;
|
||||
else {
|
||||
@ -596,13 +672,13 @@ mtree_bid(struct archive_read *a, int best_bid)
|
||||
} else
|
||||
break;
|
||||
} else if (strncmp(p, "/set", 4) == 0) {
|
||||
if (bid_keyword_list(p+4, len-4, 0) <= 0)
|
||||
if (bid_keyword_list(p+4, len-4, 0, 0) <= 0)
|
||||
break;
|
||||
/* This line continues. */
|
||||
if (p[len-nl-1] == '\\')
|
||||
multiline = 2;
|
||||
} else if (strncmp(p, "/unset", 6) == 0) {
|
||||
if (bid_keyword_list(p+6, len-6, 1) <= 0)
|
||||
if (bid_keyword_list(p+6, len-6, 1, 0) <= 0)
|
||||
break;
|
||||
/* This line continues. */
|
||||
if (p[len-nl-1] == '\\')
|
||||
@ -614,8 +690,13 @@ mtree_bid(struct archive_read *a, int best_bid)
|
||||
p += len;
|
||||
avail -= len;
|
||||
}
|
||||
if (entry_cnt >= MAX_BID_ENTRY || (entry_cnt > 0 && len == 0))
|
||||
if (entry_cnt >= MAX_BID_ENTRY || (entry_cnt > 0 && len == 0)) {
|
||||
if (is_form_d != NULL) {
|
||||
if (form_D == 1)
|
||||
*is_form_d = 1;
|
||||
}
|
||||
return (32);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -739,12 +820,12 @@ process_global_unset(struct archive_read *a,
|
||||
|
||||
static int
|
||||
process_add_entry(struct archive_read *a, struct mtree *mtree,
|
||||
struct mtree_option **global, const char *line,
|
||||
struct mtree_entry **last_entry)
|
||||
struct mtree_option **global, const char *line, ssize_t line_len,
|
||||
struct mtree_entry **last_entry, int is_form_d)
|
||||
{
|
||||
struct mtree_entry *entry;
|
||||
struct mtree_option *iter;
|
||||
const char *next, *eq;
|
||||
const char *next, *eq, *name, *end;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
@ -765,17 +846,46 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
|
||||
(*last_entry)->next = entry;
|
||||
*last_entry = entry;
|
||||
|
||||
len = strcspn(line, " \t\r\n");
|
||||
if (is_form_d) {
|
||||
/*
|
||||
* This form places the file name as last parameter.
|
||||
*/
|
||||
name = line + line_len -1;
|
||||
while (line_len > 0) {
|
||||
if (*name != '\r' && *name != '\n' &&
|
||||
*name != '\t' && *name != ' ')
|
||||
break;
|
||||
name--;
|
||||
line_len--;
|
||||
}
|
||||
len = 0;
|
||||
while (line_len > 0) {
|
||||
if (*name == '\r' || *name == '\n' ||
|
||||
*name == '\t' || *name == ' ') {
|
||||
name++;
|
||||
break;
|
||||
}
|
||||
name--;
|
||||
line_len--;
|
||||
len++;
|
||||
}
|
||||
end = name;
|
||||
} else {
|
||||
len = strcspn(line, " \t\r\n");
|
||||
name = line;
|
||||
line += len;
|
||||
end = line + line_len;
|
||||
}
|
||||
|
||||
if ((entry->name = malloc(len + 1)) == NULL) {
|
||||
archive_set_error(&a->archive, errno, "Can't allocate memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
memcpy(entry->name, line, len);
|
||||
memcpy(entry->name, name, len);
|
||||
entry->name[len] = '\0';
|
||||
parse_escapes(entry->name, entry);
|
||||
|
||||
line += len;
|
||||
for (iter = *global; iter != NULL; iter = iter->next) {
|
||||
r = add_option(a, &entry->options, iter->value,
|
||||
strlen(iter->value));
|
||||
@ -787,6 +897,8 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
|
||||
next = line + strspn(line, " \t\r\n");
|
||||
if (*next == '\0')
|
||||
return (ARCHIVE_OK);
|
||||
if (next >= end)
|
||||
return (ARCHIVE_OK);
|
||||
line = next;
|
||||
next = line + strcspn(line, " \t\r\n");
|
||||
eq = strchr(line, '=');
|
||||
@ -811,7 +923,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
char *p;
|
||||
struct mtree_option *global;
|
||||
struct mtree_entry *last_entry;
|
||||
int r;
|
||||
int r, is_form_d;
|
||||
|
||||
mtree->archive_format = ARCHIVE_FORMAT_MTREE;
|
||||
mtree->archive_format_name = "mtree";
|
||||
@ -819,6 +931,8 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
global = NULL;
|
||||
last_entry = NULL;
|
||||
|
||||
(void)detect_form(a, &is_form_d);
|
||||
|
||||
for (counter = 1; ; ++counter) {
|
||||
len = readline(a, mtree, &p, 65536);
|
||||
if (len == 0) {
|
||||
@ -828,7 +942,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
}
|
||||
if (len < 0) {
|
||||
free_options(global);
|
||||
return (len);
|
||||
return ((int)len);
|
||||
}
|
||||
/* Leading whitespace is never significant, ignore it. */
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
@ -841,8 +955,8 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
if (*p == '\r' || *p == '\n' || *p == '\0')
|
||||
continue;
|
||||
if (*p != '/') {
|
||||
r = process_add_entry(a, mtree, &global, p,
|
||||
&last_entry);
|
||||
r = process_add_entry(a, mtree, &global, p, len,
|
||||
&last_entry, is_form_d);
|
||||
} else if (strncmp(p, "/set", 4) == 0) {
|
||||
if (p[4] != ' ' && p[4] != '\t')
|
||||
break;
|
||||
@ -1008,7 +1122,8 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
|
||||
|
||||
if (archive_entry_filetype(entry) == AE_IFREG ||
|
||||
archive_entry_filetype(entry) == AE_IFDIR) {
|
||||
mtree->fd = open(path, O_RDONLY | O_BINARY);
|
||||
mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(mtree->fd);
|
||||
if (mtree->fd == -1 &&
|
||||
(errno != ENOENT ||
|
||||
archive_strlen(&mtree->contents_name) > 0)) {
|
||||
@ -1091,15 +1206,19 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
|
||||
* if it wasn't already parsed from the specification.
|
||||
*/
|
||||
if (st != NULL) {
|
||||
if ((parsed_kws & MTREE_HAS_DEVICE) == 0 &&
|
||||
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)
|
||||
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)
|
||||
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) {
|
||||
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);
|
||||
@ -1119,11 +1238,14 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
|
||||
archive_entry_set_mtime(entry, st->st_mtime, 0);
|
||||
#endif
|
||||
}
|
||||
if ((parsed_kws & MTREE_HAS_NLINK) == 0)
|
||||
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)
|
||||
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)
|
||||
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);
|
||||
@ -1213,6 +1335,10 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
if (*key == '\0')
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
if (strcmp(key, "nochange") == 0) {
|
||||
*parsed_kws |= MTREE_HAS_NOCHANGE;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
if (strcmp(key, "optional") == 0) {
|
||||
*parsed_kws |= MTREE_HAS_OPTIONAL;
|
||||
return (ARCHIVE_OK);
|
||||
|
@ -199,6 +199,13 @@ struct lzss
|
||||
int64_t position;
|
||||
};
|
||||
|
||||
struct data_block_offsets
|
||||
{
|
||||
int64_t header_size;
|
||||
int64_t start_offset;
|
||||
int64_t end_offset;
|
||||
};
|
||||
|
||||
struct rar
|
||||
{
|
||||
/* Entries from main RAR header */
|
||||
@ -217,6 +224,7 @@ struct rar
|
||||
long mnsec;
|
||||
mode_t mode;
|
||||
char *filename;
|
||||
char *filename_save;
|
||||
size_t filename_allocated;
|
||||
|
||||
/* File header optional entries */
|
||||
@ -234,6 +242,7 @@ struct rar
|
||||
int64_t bytes_uncopied;
|
||||
int64_t offset;
|
||||
int64_t offset_outgoing;
|
||||
int64_t offset_seek;
|
||||
char valid;
|
||||
unsigned int unp_offset;
|
||||
unsigned int unp_buffer_size;
|
||||
@ -243,6 +252,10 @@ struct rar
|
||||
char entry_eof;
|
||||
unsigned long crc_calculated;
|
||||
int found_first_header;
|
||||
char has_endarc_header;
|
||||
struct data_block_offsets *dbo;
|
||||
unsigned int cursor;
|
||||
unsigned int nodes;
|
||||
|
||||
/* LZSS members */
|
||||
struct huffman_code maincode;
|
||||
@ -301,6 +314,8 @@ static int archive_read_format_rar_read_header(struct archive_read *,
|
||||
static int archive_read_format_rar_read_data(struct archive_read *,
|
||||
const void **, size_t *, int64_t *);
|
||||
static int archive_read_format_rar_read_data_skip(struct archive_read *a);
|
||||
static int64_t archive_read_format_rar_seek_data(struct archive_read *, int64_t,
|
||||
int);
|
||||
static int archive_read_format_rar_cleanup(struct archive_read *);
|
||||
|
||||
/* Support functions */
|
||||
@ -328,6 +343,7 @@ static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
|
||||
static int64_t expand(struct archive_read *, int64_t);
|
||||
static int copy_from_lzss_window(struct archive_read *, const void **,
|
||||
int64_t, int);
|
||||
static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *);
|
||||
|
||||
/*
|
||||
* Bit stream reader.
|
||||
@ -449,11 +465,9 @@ rar_br_fillup(struct archive_read *a, struct rar_br *br)
|
||||
__archive_read_consume(a, rar->bytes_unconsumed);
|
||||
rar->bytes_unconsumed = 0;
|
||||
}
|
||||
br->next_in = __archive_read_ahead(a, 1, &(br->avail_in));
|
||||
br->next_in = rar_read_ahead(a, 1, &(br->avail_in));
|
||||
if (br->next_in == NULL)
|
||||
return (0);
|
||||
if (br->avail_in > rar->bytes_remaining)
|
||||
br->avail_in = (ssize_t)rar->bytes_remaining;
|
||||
if (br->avail_in == 0)
|
||||
return (0);
|
||||
}
|
||||
@ -473,15 +487,13 @@ rar_br_preparation(struct archive_read *a, struct rar_br *br)
|
||||
struct rar *rar = (struct rar *)(a->format->data);
|
||||
|
||||
if (rar->bytes_remaining > 0) {
|
||||
br->next_in = __archive_read_ahead(a, 1, &(br->avail_in));
|
||||
br->next_in = rar_read_ahead(a, 1, &(br->avail_in));
|
||||
if (br->next_in == NULL) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated RAR file data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (br->avail_in > rar->bytes_remaining)
|
||||
br->avail_in = (ssize_t)rar->bytes_remaining;
|
||||
if (br->cache_avail == 0)
|
||||
(void)rar_br_fillup(a, br);
|
||||
}
|
||||
@ -642,6 +654,7 @@ archive_read_support_format_rar(struct archive *_a)
|
||||
archive_read_format_rar_read_header,
|
||||
archive_read_format_rar_read_data,
|
||||
archive_read_format_rar_read_data_skip,
|
||||
archive_read_format_rar_seek_data,
|
||||
archive_read_format_rar_cleanup);
|
||||
|
||||
if (r != ARCHIVE_OK)
|
||||
@ -844,13 +857,6 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
||||
sizeof(rar->reserved2));
|
||||
}
|
||||
|
||||
if (rar->main_flags & MHD_VOLUME ||
|
||||
rar->main_flags & MHD_FIRSTVOLUME)
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"RAR volume support unavailable.");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (rar->main_flags & MHD_PASSWORD)
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -858,7 +864,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2);
|
||||
crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2);
|
||||
if ((crc32_val & 0xffff) != archive_le16dec(p)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Header CRC error");
|
||||
@ -875,6 +881,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
||||
case SUB_HEAD:
|
||||
case PROTECT_HEAD:
|
||||
case SIGN_HEAD:
|
||||
case ENDARC_HEAD:
|
||||
flags = archive_le16dec(p + 3);
|
||||
skip = archive_le16dec(p + 5);
|
||||
if (skip < 7) {
|
||||
@ -900,13 +907,15 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
||||
p = h;
|
||||
}
|
||||
|
||||
crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2);
|
||||
crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2);
|
||||
if ((crc32_val & 0xffff) != archive_le16dec(p)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Header CRC error");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
__archive_read_consume(a, skip);
|
||||
if (head_type == ENDARC_HEAD)
|
||||
return (ARCHIVE_EOF);
|
||||
break;
|
||||
|
||||
case NEWSUB_HEAD:
|
||||
@ -914,9 +923,6 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
||||
return ret;
|
||||
break;
|
||||
|
||||
case ENDARC_HEAD:
|
||||
return (ARCHIVE_EOF);
|
||||
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Bad RAR file");
|
||||
@ -938,10 +944,12 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
||||
rar->bytes_unconsumed = 0;
|
||||
}
|
||||
|
||||
if (rar->entry_eof) {
|
||||
if (rar->entry_eof || rar->offset_seek >= rar->unp_size) {
|
||||
*buff = NULL;
|
||||
*size = 0;
|
||||
*offset = rar->offset;
|
||||
if (*offset < rar->unp_size)
|
||||
*offset = rar->unp_size;
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
|
||||
@ -975,6 +983,7 @@ archive_read_format_rar_read_data_skip(struct archive_read *a)
|
||||
{
|
||||
struct rar *rar;
|
||||
int64_t bytes_skipped;
|
||||
int ret;
|
||||
|
||||
rar = (struct rar *)(a->format->data);
|
||||
|
||||
@ -989,9 +998,179 @@ archive_read_format_rar_read_data_skip(struct archive_read *a)
|
||||
if (bytes_skipped < 0)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Compressed data to skip must be read from each header in a multivolume
|
||||
* archive.
|
||||
*/
|
||||
if (rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER)
|
||||
{
|
||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
||||
if (ret == (ARCHIVE_EOF))
|
||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
||||
if (ret != (ARCHIVE_OK))
|
||||
return ret;
|
||||
return archive_read_format_rar_read_data_skip(a);
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
archive_read_format_rar_seek_data(struct archive_read *a, int64_t offset,
|
||||
int whence)
|
||||
{
|
||||
int64_t client_offset, ret;
|
||||
unsigned int i;
|
||||
struct rar *rar = (struct rar *)(a->format->data);
|
||||
|
||||
if (rar->compression_method == COMPRESS_METHOD_STORE)
|
||||
{
|
||||
/* Modify the offset for use with SEEK_SET */
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_CUR:
|
||||
client_offset = rar->offset_seek;
|
||||
break;
|
||||
case SEEK_END:
|
||||
client_offset = rar->unp_size;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
default:
|
||||
client_offset = 0;
|
||||
}
|
||||
client_offset += offset;
|
||||
if (client_offset < 0)
|
||||
{
|
||||
/* Can't seek past beginning of data block */
|
||||
return -1;
|
||||
}
|
||||
else if (client_offset > rar->unp_size)
|
||||
{
|
||||
/*
|
||||
* Set the returned offset but only seek to the end of
|
||||
* the data block.
|
||||
*/
|
||||
rar->offset_seek = client_offset;
|
||||
client_offset = rar->unp_size;
|
||||
}
|
||||
|
||||
client_offset += rar->dbo[0].start_offset;
|
||||
i = 0;
|
||||
while (i < rar->cursor)
|
||||
{
|
||||
i++;
|
||||
client_offset += rar->dbo[i].start_offset - rar->dbo[i-1].end_offset;
|
||||
}
|
||||
if (rar->main_flags & MHD_VOLUME)
|
||||
{
|
||||
/* Find the appropriate offset among the multivolume archive */
|
||||
while (1)
|
||||
{
|
||||
if (client_offset < rar->dbo[rar->cursor].start_offset &&
|
||||
rar->file_flags & FHD_SPLIT_BEFORE)
|
||||
{
|
||||
/* Search backwards for the correct data block */
|
||||
if (rar->cursor == 0)
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Attempt to seek past beginning of RAR data block");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
rar->cursor--;
|
||||
client_offset -= rar->dbo[rar->cursor+1].start_offset -
|
||||
rar->dbo[rar->cursor].end_offset;
|
||||
if (client_offset < rar->dbo[rar->cursor].start_offset)
|
||||
continue;
|
||||
ret = __archive_read_seek(a, rar->dbo[rar->cursor].start_offset -
|
||||
rar->dbo[rar->cursor].header_size, SEEK_SET);
|
||||
if (ret < (ARCHIVE_OK))
|
||||
return ret;
|
||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
||||
if (ret != (ARCHIVE_OK))
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Error during seek of RAR file");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
rar->cursor--;
|
||||
break;
|
||||
}
|
||||
else if (client_offset > rar->dbo[rar->cursor].end_offset &&
|
||||
rar->file_flags & FHD_SPLIT_AFTER)
|
||||
{
|
||||
/* Search forward for the correct data block */
|
||||
rar->cursor++;
|
||||
if (rar->cursor < rar->nodes &&
|
||||
client_offset > rar->dbo[rar->cursor].end_offset)
|
||||
{
|
||||
client_offset += rar->dbo[rar->cursor].start_offset -
|
||||
rar->dbo[rar->cursor-1].end_offset;
|
||||
continue;
|
||||
}
|
||||
rar->cursor--;
|
||||
ret = __archive_read_seek(a, rar->dbo[rar->cursor].end_offset,
|
||||
SEEK_SET);
|
||||
if (ret < (ARCHIVE_OK))
|
||||
return ret;
|
||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
||||
if (ret == (ARCHIVE_EOF))
|
||||
{
|
||||
rar->has_endarc_header = 1;
|
||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
||||
}
|
||||
if (ret != (ARCHIVE_OK))
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Error during seek of RAR file");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
client_offset += rar->dbo[rar->cursor].start_offset -
|
||||
rar->dbo[rar->cursor-1].end_offset;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = __archive_read_seek(a, client_offset, SEEK_SET);
|
||||
if (ret < (ARCHIVE_OK))
|
||||
return ret;
|
||||
rar->bytes_remaining = rar->dbo[rar->cursor].end_offset - ret;
|
||||
i = rar->cursor;
|
||||
while (i > 0)
|
||||
{
|
||||
i--;
|
||||
ret -= rar->dbo[i+1].start_offset - rar->dbo[i].end_offset;
|
||||
}
|
||||
ret -= rar->dbo[0].start_offset;
|
||||
|
||||
/* Always restart reading the file after a seek */
|
||||
a->read_data_block = NULL;
|
||||
a->read_data_offset = 0;
|
||||
a->read_data_output_offset = 0;
|
||||
a->read_data_remaining = 0;
|
||||
rar->bytes_unconsumed = 0;
|
||||
rar->offset = 0;
|
||||
|
||||
/*
|
||||
* If a seek past the end of file was requested, return the requested
|
||||
* offset.
|
||||
*/
|
||||
if (ret == rar->unp_size && rar->offset_seek > rar->unp_size)
|
||||
return rar->offset_seek;
|
||||
|
||||
/* Return the new offset */
|
||||
rar->offset_seek = ret;
|
||||
return rar->offset_seek;
|
||||
}
|
||||
else
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Seeking of compressed RAR files is unsupported");
|
||||
}
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_read_format_rar_cleanup(struct archive_read *a)
|
||||
{
|
||||
@ -1000,6 +1179,8 @@ archive_read_format_rar_cleanup(struct archive_read *a)
|
||||
rar = (struct rar *)(a->format->data);
|
||||
free_codes(a);
|
||||
free(rar->filename);
|
||||
free(rar->filename_save);
|
||||
free(rar->dbo);
|
||||
free(rar->unp_buffer);
|
||||
free(rar->lzss.window);
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
|
||||
@ -1138,6 +1319,8 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
rar->bytes_remaining = rar->packed_size;
|
||||
|
||||
/* TODO: RARv3 subblocks contain comments. For now the complete block is
|
||||
* consumed at the end.
|
||||
*/
|
||||
@ -1177,13 +1360,13 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
{
|
||||
if (filename_size != strlen(filename))
|
||||
{
|
||||
unsigned char highbyte, flagbits, flagbyte, offset;
|
||||
unsigned fn_end;
|
||||
unsigned char highbyte, flagbits, flagbyte;
|
||||
unsigned fn_end, offset;
|
||||
|
||||
end = filename_size;
|
||||
fn_end = filename_size * 2;
|
||||
filename_size = 0;
|
||||
offset = strlen(filename) + 1;
|
||||
offset = (unsigned)strlen(filename) + 1;
|
||||
highbyte = *(p + offset++);
|
||||
flagbits = 0;
|
||||
flagbyte = 0;
|
||||
@ -1284,6 +1467,51 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
p += filename_size;
|
||||
}
|
||||
|
||||
/* Split file in multivolume RAR. No more need to process header. */
|
||||
if (rar->filename_save &&
|
||||
!memcmp(rar->filename, rar->filename_save, filename_size + 1))
|
||||
{
|
||||
__archive_read_consume(a, header_size - 7);
|
||||
rar->cursor++;
|
||||
if (rar->cursor >= rar->nodes)
|
||||
{
|
||||
rar->nodes++;
|
||||
if ((rar->dbo =
|
||||
realloc(rar->dbo, sizeof(*rar->dbo) * rar->nodes)) == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
rar->dbo[rar->cursor].header_size = header_size;
|
||||
rar->dbo[rar->cursor].start_offset = -1;
|
||||
rar->dbo[rar->cursor].end_offset = -1;
|
||||
}
|
||||
if (rar->dbo[rar->cursor].start_offset < 0)
|
||||
{
|
||||
rar->dbo[rar->cursor].start_offset = a->filter->position;
|
||||
rar->dbo[rar->cursor].end_offset = rar->dbo[rar->cursor].start_offset +
|
||||
rar->packed_size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
rar->filename_save = (char*)realloc(rar->filename_save,
|
||||
filename_size + 1);
|
||||
memcpy(rar->filename_save, rar->filename, filename_size + 1);
|
||||
|
||||
/* Set info for seeking */
|
||||
free(rar->dbo);
|
||||
if ((rar->dbo = calloc(1, sizeof(*rar->dbo))) == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory.");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
rar->dbo[0].header_size = header_size;
|
||||
rar->dbo[0].start_offset = -1;
|
||||
rar->dbo[0].end_offset = -1;
|
||||
rar->cursor = 0;
|
||||
rar->nodes = 1;
|
||||
|
||||
if (rar->file_flags & FHD_SALT)
|
||||
{
|
||||
if (p + 8 > endp) {
|
||||
@ -1304,6 +1532,8 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
}
|
||||
|
||||
__archive_read_consume(a, header_size - 7);
|
||||
rar->dbo[0].start_offset = a->filter->position;
|
||||
rar->dbo[0].end_offset = rar->dbo[0].start_offset + rar->packed_size;
|
||||
|
||||
switch(file_header.host_os)
|
||||
{
|
||||
@ -1330,9 +1560,9 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
rar->bytes_remaining = rar->packed_size;
|
||||
rar->bytes_uncopied = rar->bytes_unconsumed = 0;
|
||||
rar->lzss.position = rar->offset = 0;
|
||||
rar->offset_seek = 0;
|
||||
rar->dictionary_size = 0;
|
||||
rar->offset_outgoing = 0;
|
||||
rar->br.cache_avail = 0;
|
||||
@ -1488,7 +1718,7 @@ read_symlink_stored(struct archive_read *a, struct archive_entry *entry,
|
||||
int ret = (ARCHIVE_OK);
|
||||
|
||||
rar = (struct rar *)(a->format->data);
|
||||
if ((h = __archive_read_ahead(a, (size_t)rar->packed_size, NULL)) == NULL)
|
||||
if ((h = rar_read_ahead(a, (size_t)rar->packed_size, NULL)) == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
p = h;
|
||||
|
||||
@ -1518,7 +1748,8 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
|
||||
ssize_t bytes_avail;
|
||||
|
||||
rar = (struct rar *)(a->format->data);
|
||||
if (rar->bytes_remaining == 0)
|
||||
if (rar->bytes_remaining == 0 &&
|
||||
!(rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER))
|
||||
{
|
||||
*buff = NULL;
|
||||
*size = 0;
|
||||
@ -1532,23 +1763,23 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
|
||||
*buff = __archive_read_ahead(a, 1, &bytes_avail);
|
||||
*buff = rar_read_ahead(a, 1, &bytes_avail);
|
||||
if (bytes_avail <= 0)
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Truncated RAR file data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (bytes_avail > rar->bytes_remaining)
|
||||
bytes_avail = (ssize_t)rar->bytes_remaining;
|
||||
|
||||
*size = bytes_avail;
|
||||
*offset = rar->offset;
|
||||
rar->offset += bytes_avail;
|
||||
rar->offset_seek += bytes_avail;
|
||||
rar->bytes_remaining -= bytes_avail;
|
||||
rar->bytes_unconsumed = bytes_avail;
|
||||
/* Calculate File CRC. */
|
||||
rar->crc_calculated = crc32(rar->crc_calculated, *buff, bytes_avail);
|
||||
rar->crc_calculated = crc32(rar->crc_calculated, *buff,
|
||||
(unsigned)bytes_avail);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -1578,7 +1809,8 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
*offset = rar->offset_outgoing;
|
||||
rar->offset_outgoing += *size;
|
||||
/* Calculate File CRC. */
|
||||
rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
|
||||
rar->crc_calculated = crc32(rar->crc_calculated, *buff,
|
||||
(unsigned)*size);
|
||||
rar->unp_offset = 0;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
@ -1600,7 +1832,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
bs = rar->unp_buffer_size - rar->unp_offset;
|
||||
else
|
||||
bs = (size_t)rar->bytes_uncopied;
|
||||
ret = copy_from_lzss_window(a, buff, rar->offset, bs);
|
||||
ret = copy_from_lzss_window(a, buff, rar->offset, (int)bs);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
rar->offset += bs;
|
||||
@ -1611,7 +1843,8 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
*offset = rar->offset_outgoing;
|
||||
rar->offset_outgoing += *size;
|
||||
/* Calculate File CRC. */
|
||||
rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
|
||||
rar->crc_calculated = crc32(rar->crc_calculated, *buff,
|
||||
(unsigned)*size);
|
||||
return (ret);
|
||||
}
|
||||
continue;
|
||||
@ -1728,7 +1961,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
bs = rar->unp_buffer_size - rar->unp_offset;
|
||||
else
|
||||
bs = (size_t)rar->bytes_uncopied;
|
||||
ret = copy_from_lzss_window(a, buff, rar->offset, bs);
|
||||
ret = copy_from_lzss_window(a, buff, rar->offset, (int)bs);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
rar->offset += bs;
|
||||
@ -1744,7 +1977,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
*offset = rar->offset_outgoing;
|
||||
rar->offset_outgoing += *size;
|
||||
/* Calculate File CRC. */
|
||||
rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
|
||||
rar->crc_calculated = crc32(rar->crc_calculated, *buff, (unsigned)*size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1987,17 +2220,21 @@ parse_codes(struct archive_read *a)
|
||||
/* Seems as though dictionary sizes are not used. Even so, minimize
|
||||
* memory usage as much as possible.
|
||||
*/
|
||||
void *new_window;
|
||||
unsigned int new_size;
|
||||
|
||||
if (rar->unp_size >= DICTIONARY_MAX_SIZE)
|
||||
rar->dictionary_size = DICTIONARY_MAX_SIZE;
|
||||
new_size = DICTIONARY_MAX_SIZE;
|
||||
else
|
||||
rar->dictionary_size = rar_fls((unsigned int)rar->unp_size) << 1;
|
||||
rar->lzss.window = (unsigned char *)realloc(rar->lzss.window,
|
||||
rar->dictionary_size);
|
||||
if (rar->lzss.window == NULL) {
|
||||
new_size = rar_fls((unsigned int)rar->unp_size) << 1;
|
||||
new_window = realloc(rar->lzss.window, new_size);
|
||||
if (new_window == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Unable to allocate memory for uncompressed data.");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
rar->lzss.window = (unsigned char *)new_window;
|
||||
rar->dictionary_size = new_size;
|
||||
memset(rar->lzss.window, 0, rar->dictionary_size);
|
||||
rar->lzss.mask = rar->dictionary_size - 1;
|
||||
}
|
||||
@ -2235,10 +2472,12 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
|
||||
static int
|
||||
new_node(struct huffman_code *code)
|
||||
{
|
||||
code->tree = (struct huffman_tree_node *)realloc(code->tree,
|
||||
(code->numentries + 1) * sizeof(*code->tree));
|
||||
if (code->tree == NULL)
|
||||
void *new_tree;
|
||||
|
||||
new_tree = realloc(code->tree, (code->numentries + 1) * sizeof(*code->tree));
|
||||
if (new_tree == NULL)
|
||||
return (-1);
|
||||
code->tree = (struct huffman_tree_node *)new_tree;
|
||||
code->tree[code->numentries].branches[0] = -1;
|
||||
code->tree[code->numentries].branches[1] = -2;
|
||||
return 1;
|
||||
@ -2253,8 +2492,8 @@ make_table(struct archive_read *a, struct huffman_code *code)
|
||||
code->tablesize = code->maxlength;
|
||||
|
||||
code->table =
|
||||
(struct huffman_table_entry *)malloc(sizeof(*code->table)
|
||||
* (1 << code->tablesize));
|
||||
(struct huffman_table_entry *)calloc(1, sizeof(*code->table)
|
||||
* ((size_t)1 << code->tablesize));
|
||||
|
||||
return make_table_recurse(a, code, 0, code->table, 0, code->tablesize);
|
||||
}
|
||||
@ -2586,3 +2825,34 @@ copy_from_lzss_window(struct archive_read *a, const void **buffer,
|
||||
*buffer = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static const void *
|
||||
rar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
|
||||
{
|
||||
struct rar *rar = (struct rar *)(a->format->data);
|
||||
const void *h = __archive_read_ahead(a, min, avail);
|
||||
int ret;
|
||||
if (avail)
|
||||
{
|
||||
if (a->read_data_is_posix_read && *avail > (ssize_t)a->read_data_requested)
|
||||
*avail = a->read_data_requested;
|
||||
if (*avail > rar->bytes_remaining)
|
||||
*avail = (ssize_t)rar->bytes_remaining;
|
||||
if (*avail < 0)
|
||||
return NULL;
|
||||
else if (*avail == 0 && rar->main_flags & MHD_VOLUME &&
|
||||
rar->file_flags & FHD_SPLIT_AFTER)
|
||||
{
|
||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
||||
if (ret == (ARCHIVE_EOF))
|
||||
{
|
||||
rar->has_endarc_header = 1;
|
||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
||||
}
|
||||
if (ret != (ARCHIVE_OK))
|
||||
return NULL;
|
||||
return rar_read_ahead(a, min, avail);
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ archive_read_support_format_raw(struct archive *_a)
|
||||
archive_read_format_raw_read_header,
|
||||
archive_read_format_raw_read_data,
|
||||
archive_read_format_raw_read_data_skip,
|
||||
NULL,
|
||||
archive_read_format_raw_cleanup);
|
||||
if (r != ARCHIVE_OK)
|
||||
free(info);
|
||||
@ -157,7 +158,7 @@ archive_read_format_raw_read_data(struct archive_read *a,
|
||||
/* Record and return an error. */
|
||||
*size = 0;
|
||||
*offset = info->offset;
|
||||
return (avail);
|
||||
return ((int)avail);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,10 +210,10 @@ static int read_body_to_string(struct archive_read *, struct tar *,
|
||||
struct archive_string *, const void *h, size_t *);
|
||||
static int solaris_sparse_parse(struct archive_read *, struct tar *,
|
||||
struct archive_entry *, const char *);
|
||||
static int64_t tar_atol(const char *, unsigned);
|
||||
static int64_t tar_atol10(const char *, unsigned);
|
||||
static int64_t tar_atol256(const char *, unsigned);
|
||||
static int64_t tar_atol8(const char *, unsigned);
|
||||
static int64_t tar_atol(const char *, size_t);
|
||||
static int64_t tar_atol10(const char *, size_t);
|
||||
static int64_t tar_atol256(const char *, size_t);
|
||||
static int64_t tar_atol8(const char *, size_t);
|
||||
static int tar_read_header(struct archive_read *, struct tar *,
|
||||
struct archive_entry *, size_t *);
|
||||
static int tohex(int c);
|
||||
@ -253,6 +253,7 @@ archive_read_support_format_tar(struct archive *_a)
|
||||
archive_read_format_tar_read_header,
|
||||
archive_read_format_tar_read_data,
|
||||
archive_read_format_tar_skip,
|
||||
NULL,
|
||||
archive_read_format_tar_cleanup);
|
||||
|
||||
if (r != ARCHIVE_OK)
|
||||
@ -616,13 +617,14 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
int err;
|
||||
const char *h;
|
||||
const struct archive_entry_header_ustar *header;
|
||||
const struct archive_entry_header_gnutar *gnuheader;
|
||||
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
|
||||
/* Read 512-byte header record */
|
||||
h = __archive_read_ahead(a, 512, &bytes);
|
||||
if (bytes < 0)
|
||||
return (bytes);
|
||||
return ((int)bytes);
|
||||
if (bytes == 0) { /* EOF at a block boundary. */
|
||||
/* Some writers do omit the block of nulls. <sigh> */
|
||||
return (ARCHIVE_EOF);
|
||||
@ -703,7 +705,8 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
err = header_pax_extensions(a, tar, entry, h, unconsumed);
|
||||
break;
|
||||
default:
|
||||
if (memcmp(header->magic, "ustar \0", 8) == 0) {
|
||||
gnuheader = (const struct archive_entry_header_gnutar *)h;
|
||||
if (memcmp(gnuheader->magic, "ustar \0", 8) == 0) {
|
||||
a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
|
||||
a->archive.archive_format_name = "GNU tar format";
|
||||
err = header_gnutar(a, tar, entry, h, unconsumed);
|
||||
@ -752,7 +755,7 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
bytes_read = gnu_sparse_10_read(a, tar, unconsumed);
|
||||
tar->entry_bytes_remaining -= bytes_read;
|
||||
if (bytes_read < 0)
|
||||
return (bytes_read);
|
||||
return ((int)bytes_read);
|
||||
} else {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
@ -2390,7 +2393,7 @@ solaris_sparse_parse(struct archive_read *a, struct tar *tar,
|
||||
* On read, this implementation supports both extensions.
|
||||
*/
|
||||
static int64_t
|
||||
tar_atol(const char *p, unsigned char_cnt)
|
||||
tar_atol(const char *p, size_t char_cnt)
|
||||
{
|
||||
/*
|
||||
* Technically, GNU tar considers a field to be in base-256
|
||||
@ -2407,70 +2410,55 @@ tar_atol(const char *p, unsigned char_cnt)
|
||||
* it does obey locale.
|
||||
*/
|
||||
static int64_t
|
||||
tar_atol8(const char *p, unsigned char_cnt)
|
||||
tar_atol_base_n(const char *p, size_t char_cnt, int base)
|
||||
{
|
||||
int64_t l, limit, last_digit_limit;
|
||||
int digit, sign, base;
|
||||
int digit, sign;
|
||||
|
||||
base = 8;
|
||||
limit = INT64_MAX / base;
|
||||
last_digit_limit = INT64_MAX % base;
|
||||
|
||||
while (*p == ' ' || *p == '\t')
|
||||
/* the pointer will not be dereferenced if char_cnt is zero
|
||||
* due to the way the && operator is evaulated.
|
||||
*/
|
||||
while (char_cnt != 0 && (*p == ' ' || *p == '\t')) {
|
||||
p++;
|
||||
if (*p == '-') {
|
||||
char_cnt--;
|
||||
}
|
||||
|
||||
sign = 1;
|
||||
if (char_cnt != 0 && *p == '-') {
|
||||
sign = -1;
|
||||
p++;
|
||||
} else
|
||||
sign = 1;
|
||||
char_cnt--;
|
||||
}
|
||||
|
||||
l = 0;
|
||||
digit = *p - '0';
|
||||
while (digit >= 0 && digit < base && char_cnt-- > 0) {
|
||||
if (l>limit || (l == limit && digit > last_digit_limit)) {
|
||||
l = INT64_MAX; /* Truncate on overflow. */
|
||||
break;
|
||||
if (char_cnt != 0) {
|
||||
digit = *p - '0';
|
||||
while (digit >= 0 && digit < base && char_cnt != 0) {
|
||||
if (l>limit || (l == limit && digit > last_digit_limit)) {
|
||||
l = INT64_MAX; /* Truncate on overflow. */
|
||||
break;
|
||||
}
|
||||
l = (l * base) + digit;
|
||||
digit = *++p - '0';
|
||||
char_cnt--;
|
||||
}
|
||||
l = (l * base) + digit;
|
||||
digit = *++p - '0';
|
||||
}
|
||||
return (sign < 0) ? -l : l;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that this implementation does not (and should not!) obey
|
||||
* locale settings; you cannot simply substitute strtol here, since
|
||||
* it does obey locale.
|
||||
*/
|
||||
static int64_t
|
||||
tar_atol10(const char *p, unsigned char_cnt)
|
||||
tar_atol8(const char *p, size_t char_cnt)
|
||||
{
|
||||
int64_t l, limit, last_digit_limit;
|
||||
int base, digit, sign;
|
||||
return tar_atol_base_n(p, char_cnt, 8);
|
||||
}
|
||||
|
||||
base = 10;
|
||||
limit = INT64_MAX / base;
|
||||
last_digit_limit = INT64_MAX % base;
|
||||
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
if (*p == '-') {
|
||||
sign = -1;
|
||||
p++;
|
||||
} else
|
||||
sign = 1;
|
||||
|
||||
l = 0;
|
||||
digit = *p - '0';
|
||||
while (digit >= 0 && digit < base && char_cnt-- > 0) {
|
||||
if (l > limit || (l == limit && digit > last_digit_limit)) {
|
||||
l = INT64_MAX; /* Truncate on overflow. */
|
||||
break;
|
||||
}
|
||||
l = (l * base) + digit;
|
||||
digit = *++p - '0';
|
||||
}
|
||||
return (sign < 0) ? -l : l;
|
||||
static int64_t
|
||||
tar_atol10(const char *p, size_t char_cnt)
|
||||
{
|
||||
return tar_atol_base_n(p, char_cnt, 10);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2479,7 +2467,7 @@ tar_atol10(const char *p, unsigned char_cnt)
|
||||
* ignored.
|
||||
*/
|
||||
static int64_t
|
||||
tar_atol256(const char *_p, unsigned char_cnt)
|
||||
tar_atol256(const char *_p, size_t char_cnt)
|
||||
{
|
||||
int64_t l, upper_limit, lower_limit;
|
||||
const unsigned char *p = (const unsigned char *)_p;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user