mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-24 07:08:38 -05:00
Merge topic 'update-libarchive'
d83c9ff24aUtilities: Update hard-coded try_compile results for libarchive 3.7.20ff572370flibarchive: Set build options the way we need for CMakeb281fd471alibarchive: Add cm3p prefixes on includes new to version 3.7.2c4fec0edd6Merge branch 'upstream-LibArchive' into update-libarchive939e164ee5LibArchive 2023-09-12 (6468cd1f)1cc25f22fflibarchive: Update script to get 3.7.2 Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !8890
This commit is contained in:
@@ -287,6 +287,8 @@ else()
|
||||
set(ENABLE_CPIO_SHARED OFF)
|
||||
set(ENABLE_CAT OFF)
|
||||
set(ENABLE_CAT_SHARED OFF)
|
||||
set(ENABLE_UNZIP OFF)
|
||||
set(ENABLE_UNZIP_SHARED OFF)
|
||||
set(ENABLE_XATTR OFF)
|
||||
set(ENABLE_ACL OFF)
|
||||
set(ENABLE_ICONV OFF)
|
||||
|
||||
@@ -8,7 +8,7 @@ readonly name="LibArchive"
|
||||
readonly ownership="LibArchive Upstream <libarchive-discuss@googlegroups.com>"
|
||||
readonly subtree="Utilities/cmlibarchive"
|
||||
readonly repo="https://github.com/libarchive/libarchive.git"
|
||||
readonly tag="v3.6.2"
|
||||
readonly tag="v3.7.2"
|
||||
readonly shortlog=false
|
||||
readonly paths="
|
||||
CMakeLists.txt
|
||||
|
||||
@@ -43,8 +43,8 @@ if(WIN32)
|
||||
set(HAVE_CHROOT 0)
|
||||
set(HAVE_COPYFILE_H 0)
|
||||
set(HAVE_CRYPTO_H 0)
|
||||
set(HAVE__CTIME64_S 1)
|
||||
set(HAVE_CTIME_R 0)
|
||||
set(HAVE_CTIME_S 1)
|
||||
set(HAVE_CYGWIN_CONV_PATH 0)
|
||||
set(HAVE_DES_H 0)
|
||||
set(HAVE_DIRECT_H 1)
|
||||
@@ -64,6 +64,8 @@ if(WIN32)
|
||||
set(HAVE_FCNTL_H 1)
|
||||
set(HAVE_FCNTL_O_NONBLOCK 0)
|
||||
set(HAVE_FDOPENDIR 0)
|
||||
set(HAVE_FNMATCH 0)
|
||||
set(HAVE_FNMATCH_H 0)
|
||||
set(HAVE_FORK 0)
|
||||
set(HAVE_FREEADDRINFO 1)
|
||||
set(HAVE_FREEIFADDRS 0)
|
||||
@@ -82,6 +84,7 @@ if(WIN32)
|
||||
set(HAVE_GETGRGID_R 0)
|
||||
set(HAVE_GETGRNAM_R 0)
|
||||
set(HAVE_GETHOSTBYNAME 1)
|
||||
set(HAVE_GETLINE 0)
|
||||
set(HAVE_GETPAGESIZE 0)
|
||||
set(HAVE_GETPEERNAME 1)
|
||||
set(HAVE_GETPID 1)
|
||||
@@ -94,8 +97,8 @@ if(WIN32)
|
||||
set(HAVE_GETSOCKNAME 1)
|
||||
set(HAVE_GETVFSBYNAME 0)
|
||||
set(HAVE_GLIBC_STRERROR_R 0)
|
||||
set(HAVE__GMTIME64_S 1)
|
||||
set(HAVE_GMTIME_R 0)
|
||||
set(HAVE_GMTIME_S 1)
|
||||
set(HAVE_GRP_H 0)
|
||||
set(HAVE_IDN2_H 0)
|
||||
set(HAVE_IFADDRS_H 0)
|
||||
@@ -126,8 +129,8 @@ if(WIN32)
|
||||
set(HAVE_LINUX_FS_H 0)
|
||||
set(HAVE_LINUX_MAGIC_H 0)
|
||||
set(HAVE_LINUX_TYPES_H 0)
|
||||
set(HAVE__LOCALTIME64_S 1)
|
||||
set(HAVE_LOCALTIME_R 0)
|
||||
set(HAVE_LOCALTIME_S 0)
|
||||
set(HAVE_LSTAT 0)
|
||||
set(HAVE_LUTIMES 0)
|
||||
set(HAVE_MACH_ABSOLUTE_TIME 0)
|
||||
@@ -136,7 +139,7 @@ if(WIN32)
|
||||
set(HAVE_MEMORY_H 1)
|
||||
set(HAVE_MKDIR 1)
|
||||
set(HAVE_MKFIFO 0)
|
||||
set(HAVE__MKGMTIME64 1)
|
||||
set(HAVE__MKGMTIME 1)
|
||||
set(HAVE_MKNOD 0)
|
||||
set(HAVE_MMAP 0)
|
||||
set(HAVE_MSG_NOSIGNAL 0)
|
||||
@@ -216,6 +219,7 @@ if(WIN32)
|
||||
set(HAVE_SYS_MKDEV_H 0)
|
||||
set(HAVE_SYS_MOUNT_H 0)
|
||||
set(HAVE_SYS_POLL_H 0)
|
||||
set(HAVE_SYS_QUEUE_H 0)
|
||||
set(HAVE_SYS_RESOURCE_H 0)
|
||||
set(HAVE_SYS_RICHACL_H 0)
|
||||
set(HAVE_SYS_SELECT_H 0)
|
||||
|
||||
@@ -69,6 +69,7 @@ SET(VERSION "${_major}.${_trimmed_minor}.${_trimmed_revision}
|
||||
SET(BSDCPIO_VERSION_STRING "${VERSION}")
|
||||
SET(BSDTAR_VERSION_STRING "${VERSION}")
|
||||
SET(BSDCAT_VERSION_STRING "${VERSION}")
|
||||
SET(BSDUNZIP_VERSION_STRING "${VERSION}")
|
||||
SET(LIBARCHIVE_VERSION_NUMBER "${_version_number}")
|
||||
SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
|
||||
|
||||
@@ -224,6 +225,8 @@ ENDIF()
|
||||
# Enable CTest/CDash support
|
||||
include(CTest)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||
|
||||
OPTION(ENABLE_MBEDTLS "Enable use of mbed TLS" OFF)
|
||||
OPTION(ENABLE_NETTLE "Enable use of Nettle" OFF)
|
||||
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
|
||||
@@ -248,6 +251,13 @@ OPTION(ENABLE_CPIO "Enable cpio building" ON)
|
||||
OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE)
|
||||
OPTION(ENABLE_CAT "Enable cat building" ON)
|
||||
OPTION(ENABLE_CAT_SHARED "Enable dynamic build of cat" FALSE)
|
||||
IF(WIN32 AND NOT CYGWIN)
|
||||
SET(ENABLE_UNZIP FALSE)
|
||||
SET(ENABLE_UNZIP_SHARED FALSE)
|
||||
ELSE()
|
||||
OPTION(ENABLE_UNZIP "Enable unzip building" ON)
|
||||
OPTION(ENABLE_UNZIP_SHARED "Enable dynamic build of unzip" FALSE)
|
||||
ENDIF()
|
||||
OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
|
||||
OPTION(ENABLE_ACL "Enable ACL support" ON)
|
||||
OPTION(ENABLE_ICONV "Enable iconv support" ON)
|
||||
@@ -324,6 +334,7 @@ ENDIF()
|
||||
|
||||
IF(MINGW)
|
||||
ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO)
|
||||
ADD_DEFINITIONS(-D__MINGW_USE_VC2005_COMPAT)
|
||||
ENDIF()
|
||||
|
||||
#
|
||||
@@ -394,7 +405,11 @@ MACRO (TRY_MACRO_FOR_LIBRARY INCLUDES LIBRARIES
|
||||
IF("${TRY_TYPE}" MATCHES "COMPILES")
|
||||
CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR})
|
||||
ELSEIF("${TRY_TYPE}" MATCHES "RUNS")
|
||||
CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
|
||||
IF(CMAKE_CROSSCOMPILING)
|
||||
MESSAGE(WARNING "Cannot test run \"${VAR}\" when cross-compiling")
|
||||
ELSE(CMAKE_CROSSCOMPILING)
|
||||
CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
|
||||
ENDIF(CMAKE_CROSSCOMPILING)
|
||||
ELSE("${TRY_TYPE}" MATCHES "COMPILES")
|
||||
MESSAGE(FATAL_ERROR "UNKNOWN KEYWORD \"${TRY_TYPE}\" FOR TRY_TYPE")
|
||||
ENDIF("${TRY_TYPE}" MATCHES "COMPILES")
|
||||
@@ -533,15 +548,19 @@ IF(LIBLZMA_FOUND)
|
||||
COMPILES
|
||||
"#include <lzma.h>\nint main() {return (int)lzma_version_number(); }"
|
||||
"WITHOUT_LZMA_API_STATIC;LZMA_API_STATIC")
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
"#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
|
||||
HAVE_LZMA_STREAM_ENCODER_MT)
|
||||
IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
|
||||
ADD_DEFINITIONS(-DLZMA_API_STATIC)
|
||||
ENDIF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
ADD_DEFINITIONS(-DLZMA_API_STATIC)
|
||||
ENDIF()
|
||||
CMAKE_POP_CHECK_STATE()
|
||||
ELSE(LIBLZMA_FOUND)
|
||||
# LZMA not found and will not be used.
|
||||
SET(HAVE_LZMA_STREAM_ENCODER_MT 0)
|
||||
ENDIF(LIBLZMA_FOUND)
|
||||
#
|
||||
# Find LZO2
|
||||
@@ -590,6 +609,7 @@ IF(LIBB2_FOUND)
|
||||
SET(HAVE_BLAKE2_H 1)
|
||||
SET(ARCHIVE_BLAKE2 FALSE)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${LIBB2_LIBRARY})
|
||||
INCLUDE_DIRECTORIES(${LIBB2_INCLUDE_DIR})
|
||||
CMAKE_PUSH_CHECK_STATE()
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${LIBB2_LIBRARY})
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${LIBB2_INCLUDE_DIR})
|
||||
@@ -708,6 +728,7 @@ CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
|
||||
int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
|
||||
|
||||
LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H)
|
||||
LA_CHECK_INCLUDE_FILE("fnmatch.h" HAVE_FNMATCH_H)
|
||||
LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H)
|
||||
LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
|
||||
LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H)
|
||||
@@ -745,6 +766,7 @@ LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/queue.h" HAVE_SYS_QUEUE_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/richacl.h" HAVE_SYS_RICHACL_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
|
||||
@@ -764,9 +786,9 @@ LA_CHECK_INCLUDE_FILE("wchar.h" HAVE_WCHAR_H)
|
||||
LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
|
||||
LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
|
||||
IF(ENABLE_CNG)
|
||||
LA_CHECK_INCLUDE_FILE("Bcrypt.h" HAVE_BCRYPT_H)
|
||||
LA_CHECK_INCLUDE_FILE("bcrypt.h" HAVE_BCRYPT_H)
|
||||
IF(HAVE_BCRYPT_H)
|
||||
LIST(APPEND ADDITIONAL_LIBS "Bcrypt")
|
||||
LIST(APPEND ADDITIONAL_LIBS "bcrypt")
|
||||
ENDIF(HAVE_BCRYPT_H)
|
||||
ELSE(ENABLE_CNG)
|
||||
UNSET(HAVE_BCRYPT_H CACHE)
|
||||
@@ -842,6 +864,10 @@ IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
IF(OPENSSL_FOUND)
|
||||
SET(HAVE_LIBCRYPTO 1)
|
||||
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
LA_CHECK_INCLUDE_FILE("openssl/evp.h" HAVE_OPENSSL_EVP_H)
|
||||
CHECK_FUNCTION_EXISTS(PKCS5_PBKDF2_HMAC_SHA1 HAVE_PKCS5_PBKDF2_HMAC_SHA1)
|
||||
ENDIF(OPENSSL_FOUND)
|
||||
ELSE()
|
||||
SET(OPENSSL_FOUND FALSE) # Override cached value
|
||||
@@ -1379,6 +1405,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(fchmod HAVE_FCHMOD)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fchown HAVE_FCHOWN)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fcntl HAVE_FCNTL)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fdopendir HAVE_FDOPENDIR)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fnmatch HAVE_FNMATCH)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fork HAVE_FORK)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fstat HAVE_FSTAT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(fstatat HAVE_FSTATAT)
|
||||
@@ -1391,6 +1418,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getline HAVE_GETLINE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
|
||||
@@ -1443,12 +1471,12 @@ CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(_gmtime64_s HAVE__GMTIME64_S)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64)
|
||||
CHECK_SYMBOL_EXISTS(ctime_s "time.h" HAVE_CTIME_S)
|
||||
CHECK_SYMBOL_EXISTS(gmtime_s "time.h" HAVE_GMTIME_S)
|
||||
CHECK_SYMBOL_EXISTS(localtime_s "time.h" HAVE_LOCALTIME_S)
|
||||
CHECK_SYMBOL_EXISTS(_mkgmtime "time.h" HAVE__MKGMTIME)
|
||||
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "")
|
||||
CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH)
|
||||
@@ -1491,7 +1519,6 @@ CHECK_C_SOURCE_COMPILES(
|
||||
"#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
|
||||
HAVE_READLINKAT)
|
||||
|
||||
|
||||
# To verify major(), we need to both include the header
|
||||
# of interest and verify that the result can be linked.
|
||||
# CHECK_FUNCTION_EXISTS doesn't accept a header argument,
|
||||
@@ -1503,20 +1530,6 @@ CHECK_C_SOURCE_COMPILES(
|
||||
"#include <sys/sysmacros.h>\nint main() { return major(256); }"
|
||||
MAJOR_IN_SYSMACROS)
|
||||
|
||||
IF(ENABLE_LZMA)
|
||||
CMAKE_PUSH_CHECK_STATE()
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES})
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR})
|
||||
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
"#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
|
||||
HAVE_LZMA_STREAM_ENCODER_MT)
|
||||
|
||||
CMAKE_POP_CHECK_STATE()
|
||||
ELSE()
|
||||
SET(HAVE_LZMA_STREAM_ENCODER_MT 0)
|
||||
ENDIF(ENABLE_LZMA)
|
||||
|
||||
IF(HAVE_STRERROR_R)
|
||||
SET(HAVE_DECL_STRERROR_R 1)
|
||||
ENDIF(HAVE_STRERROR_R)
|
||||
@@ -1578,7 +1591,7 @@ ENDIF()
|
||||
#
|
||||
#
|
||||
CHECK_STRUCT_HAS_MEMBER("struct tm" tm_sec
|
||||
"sys/types.h;sys/time.h;time.h" TIME_WITH_SYS_TIME)
|
||||
"sys/types.h;sys/time.h;time.h" HAVE_SYS_TIME_H)
|
||||
|
||||
CHECK_TYPE_SIZE(dev_t DEV_T)
|
||||
IF(NOT HAVE_DEV_T)
|
||||
@@ -2076,6 +2089,7 @@ IF(0) # CMake does not build libarchive's command-line tools.
|
||||
add_subdirectory(cat)
|
||||
add_subdirectory(tar)
|
||||
add_subdirectory(cpio)
|
||||
add_subdirectory(unzip)
|
||||
ENDIF()
|
||||
|
||||
install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmlibarchive)
|
||||
|
||||
@@ -7,7 +7,7 @@ find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
|
||||
set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(MBEDTLS DEFAULT_MSG
|
||||
find_package_handle_standard_args(MbedTLS DEFAULT_MSG
|
||||
MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
|
||||
|
||||
mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
/* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1
|
||||
|
||||
/* MD5 via ARCHIVE_CRYPTO_MD5_MBEDTLS supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_MD5_MBEDTLS 1
|
||||
|
||||
/* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_MD5_NETTLE 1
|
||||
|
||||
@@ -53,6 +56,9 @@
|
||||
/* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_RMD160_NETTLE 1
|
||||
|
||||
/* RMD160 via ARCHIVE_CRYPTO_RMD160_MBEDTLS supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_RMD160_MBEDTLS 1
|
||||
|
||||
/* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_RMD160_OPENSSL 1
|
||||
|
||||
@@ -62,6 +68,9 @@
|
||||
/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1
|
||||
|
||||
/* SHA1 via ARCHIVE_CRYPTO_SHA1_MBEDTLS supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA1_MBEDTLS 1
|
||||
|
||||
/* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA1_NETTLE 1
|
||||
|
||||
@@ -83,6 +92,9 @@
|
||||
/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1
|
||||
|
||||
/* SHA256 via ARCHIVE_CRYPTO_SHA256_MBEDTLS supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA256_MBEDTLS 1
|
||||
|
||||
/* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA256_NETTLE 1
|
||||
|
||||
@@ -104,6 +116,9 @@
|
||||
/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1
|
||||
|
||||
/* SHA384 via ARCHIVE_CRYPTO_SHA384_MBEDTLS supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA384_MBEDTLS 1
|
||||
|
||||
/* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA384_NETTLE 1
|
||||
|
||||
@@ -125,6 +140,9 @@
|
||||
/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1
|
||||
|
||||
/* SHA512 via ARCHIVE_CRYPTO_SHA512_MBEDTLS supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA512_MBEDTLS 1
|
||||
|
||||
/* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_SHA512_NETTLE 1
|
||||
|
||||
@@ -155,6 +173,9 @@
|
||||
/* Version number of bsdcat */
|
||||
#cmakedefine BSDCAT_VERSION_STRING "@BSDCAT_VERSION_STRING@"
|
||||
|
||||
/* Version number of bsdunzip */
|
||||
#cmakedefine BSDUNZIP_VERSION_STRING "@BSDUNZIP_VERSION_STRING@"
|
||||
|
||||
/* Define to 1 if you have the `acl_create_entry' function. */
|
||||
#cmakedefine HAVE_ACL_CREATE_ENTRY 1
|
||||
|
||||
@@ -197,7 +218,7 @@
|
||||
/* Define to 1 if you have the <attr/xattr.h> header file. */
|
||||
#cmakedefine HAVE_ATTR_XATTR_H 1
|
||||
|
||||
/* Define to 1 if you have the <Bcrypt.h> header file. */
|
||||
/* Define to 1 if you have the <bcrypt.h> header file. */
|
||||
#cmakedefine HAVE_BCRYPT_H 1
|
||||
|
||||
/* Define to 1 if you have the <bsdxml.h> header file. */
|
||||
@@ -357,6 +378,12 @@
|
||||
/* Define to 1 if you have the `flistxattr' function. */
|
||||
#cmakedefine HAVE_FLISTXATTR 1
|
||||
|
||||
/* Define to 1 if you have the `fnmatch' function. */
|
||||
#cmakedefine HAVE_FNMATCH 1
|
||||
|
||||
/* Define to 1 if you have the <fnmatch.h> header file. */
|
||||
#cmakedefine HAVE_FNMATCH_H 1
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#cmakedefine HAVE_FORK 1
|
||||
|
||||
@@ -405,6 +432,9 @@
|
||||
/* Define to 1 if you have the `getgrnam_r' function. */
|
||||
#cmakedefine HAVE_GETGRNAM_R 1
|
||||
|
||||
/* Define to 1 if you have the `getline' function. */
|
||||
#cmakedefine HAVE_GETLINE 1
|
||||
|
||||
/* Define to 1 if you have the `getpid' function. */
|
||||
#cmakedefine HAVE_GETPID 1
|
||||
|
||||
@@ -611,6 +641,15 @@
|
||||
/* 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 <mbedtls/aes.h> header file. */
|
||||
#cmakedefine HAVE_MBEDTLS_AES_H 1
|
||||
|
||||
/* Define to 1 if you have the <mbedtls/md.h> header file. */
|
||||
#cmakedefine HAVE_MBEDTLS_MD_H 1
|
||||
|
||||
/* Define to 1 if you have the <mbedtls/pkcs5.h> header file. */
|
||||
#cmakedefine HAVE_MBEDTLS_PKCS5_H 1
|
||||
|
||||
/* Define to 1 if you have the `mbrtowc' function. */
|
||||
#cmakedefine HAVE_MBRTOWC 1
|
||||
|
||||
@@ -662,6 +701,9 @@
|
||||
/* Define to 1 if you have the `openat' function. */
|
||||
#cmakedefine HAVE_OPENAT 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/evp.h> header file. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_H 1
|
||||
|
||||
/* Define to 1 if you have the <paths.h> header file. */
|
||||
#cmakedefine HAVE_PATHS_H 1
|
||||
|
||||
@@ -771,6 +813,12 @@
|
||||
/* Define to 1 if you have the `strrchr' function. */
|
||||
#cmakedefine HAVE_STRRCHR 1
|
||||
|
||||
/* Define to 1 if the system has the type `struct statfs'. */
|
||||
#cmakedefine HAVE_STRUCT_STATFS 1
|
||||
|
||||
/* Define to 1 if `f_iosize' is a member of `struct statfs'. */
|
||||
#cmakedefine HAVE_STRUCT_STATFS_F_IOSIZE 1
|
||||
|
||||
/* Define to 1 if `f_namemax' is a member of `struct statfs'. */
|
||||
#cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1
|
||||
|
||||
@@ -854,6 +902,9 @@
|
||||
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||
#cmakedefine HAVE_SYS_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/queue.h> header file. */
|
||||
#cmakedefine HAVE_SYS_QUEUE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/richacl.h> header file. */
|
||||
#cmakedefine HAVE_SYS_RICHACL_H 1
|
||||
|
||||
@@ -993,8 +1044,8 @@
|
||||
/* Define to 1 if you have the <zstd.h> header file. */
|
||||
#cmakedefine HAVE_ZSTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `_ctime64_s' function. */
|
||||
#cmakedefine HAVE__CTIME64_S 1
|
||||
/* Define to 1 if you have the `ctime_s' function. */
|
||||
#cmakedefine HAVE_CTIME_S 1
|
||||
|
||||
/* Define to 1 if you have the `_fseeki64' function. */
|
||||
#cmakedefine HAVE__FSEEKI64 1
|
||||
@@ -1002,14 +1053,14 @@
|
||||
/* Define to 1 if you have the `_get_timezone' function. */
|
||||
#cmakedefine HAVE__GET_TIMEZONE 1
|
||||
|
||||
/* Define to 1 if you have the `_gmtime64_s' function. */
|
||||
#cmakedefine HAVE__GMTIME64_S 1
|
||||
/* Define to 1 if you have the `gmtime_s' function. */
|
||||
#cmakedefine HAVE_GMTIME_S 1
|
||||
|
||||
/* Define to 1 if you have the `_localtime64_s' function. */
|
||||
#cmakedefine HAVE__LOCALTIME64_S 1
|
||||
/* Define to 1 if you have the `localtime_s' function. */
|
||||
#cmakedefine HAVE_LOCALTIME_S 1
|
||||
|
||||
/* Define to 1 if you have the `_mkgmtime64' function. */
|
||||
#cmakedefine HAVE__MKGMTIME64 1
|
||||
/* Define to 1 if you have the `_mkgmtime' function. */
|
||||
#cmakedefine HAVE__MKGMTIME 1
|
||||
|
||||
/* Define as const if the declaration of iconv() needs const. */
|
||||
#define ICONV_CONST @ICONV_CONST@
|
||||
|
||||
@@ -1 +1 @@
|
||||
3006002
|
||||
3007002
|
||||
|
||||
@@ -252,10 +252,12 @@ endif()
|
||||
|
||||
IF(0) # CMake does not build libarchive's full package.
|
||||
# Libarchive is a shared library
|
||||
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
|
||||
TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
|
||||
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
|
||||
SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
|
||||
IF(BUILD_SHARED_LIBS)
|
||||
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
|
||||
TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
|
||||
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
|
||||
SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
|
||||
ENDIF(BUILD_SHARED_LIBS)
|
||||
|
||||
# archive_static is a static library
|
||||
ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS})
|
||||
@@ -263,13 +265,19 @@ TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS})
|
||||
SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
|
||||
LIBARCHIVE_STATIC)
|
||||
# On Posix systems, libarchive.so and libarchive.a can co-exist.
|
||||
IF(NOT WIN32 OR CYGWIN)
|
||||
IF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
|
||||
SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
|
||||
ENDIF(NOT WIN32 OR CYGWIN)
|
||||
ENDIF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
|
||||
|
||||
IF(ENABLE_INSTALL)
|
||||
# How to install the libraries
|
||||
INSTALL(TARGETS archive archive_static
|
||||
IF(BUILD_SHARED_LIBS)
|
||||
INSTALL(TARGETS archive
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib)
|
||||
ENDIF(BUILD_SHARED_LIBS)
|
||||
INSTALL(TARGETS archive_static
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||
*/
|
||||
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3006002
|
||||
#define ARCHIVE_VERSION_NUMBER 3007002
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h> /* for wchar_t */
|
||||
@@ -154,7 +154,7 @@ __LA_DECL int archive_version_number(void);
|
||||
/*
|
||||
* Textual name/version of the library, useful for version displays.
|
||||
*/
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.6.2"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.7.2"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
#error Cannot use both OpenSSL and libmd.
|
||||
#endif
|
||||
|
||||
/* Common in other bcrypt implementations, but missing from VS2008. */
|
||||
#ifndef BCRYPT_SUCCESS
|
||||
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Message digest functions for Windows platform.
|
||||
*/
|
||||
@@ -48,6 +53,26 @@
|
||||
/*
|
||||
* Initialize a Message digest.
|
||||
*/
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
static int
|
||||
win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ctx->valid = 0;
|
||||
|
||||
status = BCryptOpenAlgorithmProvider(&ctx->hAlg, algo, NULL, 0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
return (ARCHIVE_FAILED);
|
||||
status = BCryptCreateHash(ctx->hAlg, &ctx->hHash, NULL, 0, NULL, 0, 0);
|
||||
if (!BCRYPT_SUCCESS(status)) {
|
||||
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
ctx->valid = 1;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
|
||||
{
|
||||
@@ -70,6 +95,7 @@ win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
|
||||
ctx->valid = 1;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update a Message digest.
|
||||
@@ -81,23 +107,37 @@ win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
|
||||
if (!ctx->valid)
|
||||
return (ARCHIVE_FAILED);
|
||||
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
BCryptHashData(ctx->hHash,
|
||||
(PUCHAR)(uintptr_t)buf,
|
||||
(ULONG)len, 0);
|
||||
#else
|
||||
CryptHashData(ctx->hash,
|
||||
(unsigned char *)(uintptr_t)buf,
|
||||
(DWORD)len, 0);
|
||||
#endif
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
|
||||
{
|
||||
#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
|
||||
DWORD siglen = (DWORD)bufsize;
|
||||
#endif
|
||||
|
||||
if (!ctx->valid)
|
||||
return (ARCHIVE_FAILED);
|
||||
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0);
|
||||
BCryptDestroyHash(ctx->hHash);
|
||||
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
|
||||
#else
|
||||
CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
|
||||
CryptDestroyHash(ctx->hash);
|
||||
CryptReleaseContext(ctx->cryptProv, 0);
|
||||
#endif
|
||||
ctx->valid = 0;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
@@ -276,7 +316,11 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
|
||||
static int
|
||||
__archive_md5init(archive_md5_ctx *ctx)
|
||||
{
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
|
||||
#else
|
||||
return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -659,7 +703,11 @@ __archive_sha1final(archive_sha1_ctx *ctx, void *md)
|
||||
static int
|
||||
__archive_sha1init(archive_sha1_ctx *ctx)
|
||||
{
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
|
||||
#else
|
||||
return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -919,7 +967,11 @@ __archive_sha256final(archive_sha256_ctx *ctx, void *md)
|
||||
static int
|
||||
__archive_sha256init(archive_sha256_ctx *ctx)
|
||||
{
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
|
||||
#else
|
||||
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1155,7 +1207,11 @@ __archive_sha384final(archive_sha384_ctx *ctx, void *md)
|
||||
static int
|
||||
__archive_sha384init(archive_sha384_ctx *ctx)
|
||||
{
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
|
||||
#else
|
||||
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1415,7 +1471,11 @@ __archive_sha512final(archive_sha512_ctx *ctx, void *md)
|
||||
static int
|
||||
__archive_sha512init(archive_sha512_ctx *ctx)
|
||||
{
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
|
||||
#else
|
||||
return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -164,6 +164,15 @@
|
||||
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_WIN)
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
/* don't use bcrypt when XP needs to be supported */
|
||||
#include <bcrypt.h>
|
||||
typedef struct {
|
||||
int valid;
|
||||
BCRYPT_ALG_HANDLE hAlg;
|
||||
BCRYPT_HASH_HANDLE hHash;
|
||||
} Digest_CTX;
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
typedef struct {
|
||||
@@ -172,6 +181,7 @@ typedef struct {
|
||||
HCRYPTHASH hash;
|
||||
} Digest_CTX;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* typedefs */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3006002
|
||||
#define ARCHIVE_VERSION_NUMBER 3007002
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
|
||||
@@ -700,13 +700,9 @@ Convert(time_t Month, time_t Day, time_t Year,
|
||||
time_t Julian;
|
||||
int i;
|
||||
struct tm *ltime;
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
|
||||
struct tm tmbuf;
|
||||
#endif
|
||||
#if defined(HAVE__LOCALTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
if (Year < 69)
|
||||
Year += 2000;
|
||||
@@ -733,15 +729,10 @@ Convert(time_t Month, time_t Day, time_t Year,
|
||||
Julian *= DAY;
|
||||
Julian += Timezone;
|
||||
Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
|
||||
#if defined(HAVE_LOCALTIME_R)
|
||||
#if defined(HAVE_LOCALTIME_S)
|
||||
ltime = localtime_s(&tmbuf, &Julian) ? NULL : &tmbuf;
|
||||
#elif defined(HAVE_LOCALTIME_R)
|
||||
ltime = localtime_r(&Julian, &tmbuf);
|
||||
#elif defined(HAVE__LOCALTIME64_S)
|
||||
tmptime = Julian;
|
||||
terr = _localtime64_s(&tmbuf, &tmptime);
|
||||
if (terr)
|
||||
ltime = NULL;
|
||||
else
|
||||
ltime = &tmbuf;
|
||||
#else
|
||||
ltime = localtime(&Julian);
|
||||
#endif
|
||||
@@ -757,36 +748,21 @@ DSTcorrect(time_t Start, time_t Future)
|
||||
time_t StartDay;
|
||||
time_t FutureDay;
|
||||
struct tm *ltime;
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
|
||||
struct tm tmbuf;
|
||||
#endif
|
||||
#if defined(HAVE__LOCALTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LOCALTIME_R)
|
||||
#if defined(HAVE_LOCALTIME_S)
|
||||
ltime = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
|
||||
#elif defined(HAVE_LOCALTIME_R)
|
||||
ltime = localtime_r(&Start, &tmbuf);
|
||||
#elif defined(HAVE__LOCALTIME64_S)
|
||||
tmptime = Start;
|
||||
terr = _localtime64_s(&tmbuf, &tmptime);
|
||||
if (terr)
|
||||
ltime = NULL;
|
||||
else
|
||||
ltime = &tmbuf;
|
||||
#else
|
||||
ltime = localtime(&Start);
|
||||
#endif
|
||||
StartDay = (ltime->tm_hour + 1) % 24;
|
||||
#if defined(HAVE_LOCALTIME_R)
|
||||
#if defined(HAVE_LOCALTIME_S)
|
||||
ltime = localtime_s(&tmbuf, &Future) ? NULL : &tmbuf;
|
||||
#elif defined(HAVE_LOCALTIME_R)
|
||||
ltime = localtime_r(&Future, &tmbuf);
|
||||
#elif defined(HAVE__LOCALTIME64_S)
|
||||
tmptime = Future;
|
||||
terr = _localtime64_s(&tmbuf, &tmptime);
|
||||
if (terr)
|
||||
ltime = NULL;
|
||||
else
|
||||
ltime = &tmbuf;
|
||||
#else
|
||||
ltime = localtime(&Future);
|
||||
#endif
|
||||
@@ -801,24 +777,15 @@ RelativeDate(time_t Start, time_t zone, int dstmode,
|
||||
{
|
||||
struct tm *tm;
|
||||
time_t t, now;
|
||||
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
|
||||
#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
|
||||
struct tm tmbuf;
|
||||
#endif
|
||||
#if defined(HAVE__GMTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
t = Start - zone;
|
||||
#if defined(HAVE_GMTIME_R)
|
||||
#if defined(HAVE_GMTIME_S)
|
||||
tm = gmtime_s(&tmbuf, &t) ? NULL : &tmbuf;
|
||||
#elif defined(HAVE_GMTIME_R)
|
||||
tm = gmtime_r(&t, &tmbuf);
|
||||
#elif defined(HAVE__GMTIME64_S)
|
||||
tmptime = t;
|
||||
terr = _gmtime64_s(&tmbuf, &tmptime);
|
||||
if (terr)
|
||||
tm = NULL;
|
||||
else
|
||||
tm = &tmbuf;
|
||||
#else
|
||||
tm = gmtime(&t);
|
||||
#endif
|
||||
@@ -837,25 +804,16 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
|
||||
struct tm *tm;
|
||||
time_t Month;
|
||||
time_t Year;
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
|
||||
struct tm tmbuf;
|
||||
#endif
|
||||
#if defined(HAVE__LOCALTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
if (RelMonth == 0)
|
||||
return 0;
|
||||
#if defined(HAVE_LOCALTIME_R)
|
||||
#if defined(HAVE_LOCALTIME_S)
|
||||
tm = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf;
|
||||
#elif defined(HAVE_LOCALTIME_R)
|
||||
tm = localtime_r(&Start, &tmbuf);
|
||||
#elif defined(HAVE__LOCALTIME64_S)
|
||||
tmptime = Start;
|
||||
terr = _localtime64_s(&tmbuf, &tmptime);
|
||||
if (terr)
|
||||
tm = NULL;
|
||||
else
|
||||
tm = &tmbuf;
|
||||
#else
|
||||
tm = localtime(&Start);
|
||||
#endif
|
||||
@@ -995,10 +953,6 @@ __archive_get_date(time_t now, const char *p)
|
||||
time_t Start;
|
||||
time_t tod;
|
||||
long tzone;
|
||||
#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
/* Clear out the parsed token array. */
|
||||
memset(tokens, 0, sizeof(tokens));
|
||||
@@ -1007,36 +961,26 @@ __archive_get_date(time_t now, const char *p)
|
||||
gds = &_gds;
|
||||
|
||||
/* Look up the current time. */
|
||||
#if defined(HAVE_LOCALTIME_R)
|
||||
#if defined(HAVE_LOCALTIME_S)
|
||||
tm = localtime_s(&local, &now) ? NULL : &local;
|
||||
#elif defined(HAVE_LOCALTIME_R)
|
||||
tm = localtime_r(&now, &local);
|
||||
#elif defined(HAVE__LOCALTIME64_S)
|
||||
tmptime = now;
|
||||
terr = _localtime64_s(&local, &tmptime);
|
||||
if (terr)
|
||||
tm = NULL;
|
||||
else
|
||||
tm = &local;
|
||||
#else
|
||||
memset(&local, 0, sizeof(local));
|
||||
tm = localtime(&now);
|
||||
#endif
|
||||
if (tm == NULL)
|
||||
return -1;
|
||||
#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S)
|
||||
#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S)
|
||||
local = *tm;
|
||||
#endif
|
||||
|
||||
/* Look up UTC if we can and use that to determine the current
|
||||
* timezone offset. */
|
||||
#if defined(HAVE_GMTIME_R)
|
||||
#if defined(HAVE_GMTIME_S)
|
||||
gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
|
||||
#elif defined(HAVE_GMTIME_R)
|
||||
gmt_ptr = gmtime_r(&now, &gmt);
|
||||
#elif defined(HAVE__GMTIME64_S)
|
||||
tmptime = now;
|
||||
terr = _gmtime64_s(&gmt, &tmptime);
|
||||
if (terr)
|
||||
gmt_ptr = NULL;
|
||||
else
|
||||
gmt_ptr = &gmt;
|
||||
#else
|
||||
memset(&gmt, 0, sizeof(gmt));
|
||||
gmt_ptr = gmtime(&now);
|
||||
@@ -1078,15 +1022,10 @@ __archive_get_date(time_t now, const char *p)
|
||||
* time components instead of the local timezone. */
|
||||
if (gds->HaveZone && gmt_ptr != NULL) {
|
||||
now -= gds->Timezone;
|
||||
#if defined(HAVE_GMTIME_R)
|
||||
#if defined(HAVE_GMTIME_S)
|
||||
gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt;
|
||||
#elif defined(HAVE_GMTIME_R)
|
||||
gmt_ptr = gmtime_r(&now, &gmt);
|
||||
#elif defined(HAVE__GMTIME64_S)
|
||||
tmptime = now;
|
||||
terr = _gmtime64_s(&gmt, &tmptime);
|
||||
if (terr)
|
||||
gmt_ptr = NULL;
|
||||
else
|
||||
gmt_ptr = &gmt;
|
||||
#else
|
||||
gmt_ptr = gmtime(&now);
|
||||
#endif
|
||||
|
||||
@@ -231,15 +231,20 @@ static int
|
||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
OSSL_PARAM params[2];
|
||||
EVP_MAC *mac;
|
||||
|
||||
EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
|
||||
char sha1[] = "SHA1";
|
||||
OSSL_PARAM params[] = {
|
||||
OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
|
||||
*ctx = EVP_MAC_CTX_new(mac);
|
||||
EVP_MAC_free(mac);
|
||||
if (*ctx == NULL)
|
||||
return -1;
|
||||
EVP_MAC_free(mac);
|
||||
params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0);
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
EVP_MAC_init(*ctx, key, key_len, params);
|
||||
#else
|
||||
*ctx = HMAC_CTX_new();
|
||||
|
||||
@@ -77,6 +77,8 @@ typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/hmac.h>
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#include <openssl/params.h>
|
||||
|
||||
typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
|
||||
|
||||
#else
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* memset */
|
||||
static inline EVP_MD_CTX *EVP_MD_CTX_new(void)
|
||||
|
||||
@@ -51,16 +51,27 @@ __FBSDID("$FreeBSD$");
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
static void arc4random_buf(void *, size_t);
|
||||
static void la_arc4random_buf(void *, size_t);
|
||||
|
||||
#endif /* HAVE_ARC4RANDOM_BUF */
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_random_private.h"
|
||||
|
||||
#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
/* don't use bcrypt when XP needs to be supported */
|
||||
#include <bcrypt.h>
|
||||
|
||||
/* Common in other bcrypt implementations, but missing from VS2008. */
|
||||
#ifndef BCRYPT_SUCCESS
|
||||
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
|
||||
#endif
|
||||
|
||||
#elif defined(HAVE_WINCRYPT_H)
|
||||
#include <wincrypt.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
@@ -75,6 +86,20 @@ int
|
||||
archive_random(void *buf, size_t nbytes)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
NTSTATUS status;
|
||||
BCRYPT_ALG_HANDLE hAlg;
|
||||
|
||||
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, NULL, 0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
return ARCHIVE_FAILED;
|
||||
status = BCryptGenRandom(hAlg, buf, (ULONG)nbytes, 0);
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
return ARCHIVE_FAILED;
|
||||
|
||||
return ARCHIVE_OK;
|
||||
# else
|
||||
HCRYPTPROV hProv;
|
||||
BOOL success;
|
||||
|
||||
@@ -92,6 +117,10 @@ archive_random(void *buf, size_t nbytes)
|
||||
}
|
||||
/* TODO: Does this case really happen? */
|
||||
return ARCHIVE_FAILED;
|
||||
# endif
|
||||
#elif !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
|
||||
la_arc4random_buf(buf, nbytes);
|
||||
return ARCHIVE_OK;
|
||||
#else
|
||||
arc4random_buf(buf, nbytes);
|
||||
return ARCHIVE_OK;
|
||||
@@ -256,7 +285,7 @@ arc4_getbyte(void)
|
||||
}
|
||||
|
||||
static void
|
||||
arc4random_buf(void *_buf, size_t n)
|
||||
la_arc4random_buf(void *_buf, size_t n)
|
||||
{
|
||||
uint8_t *buf = (uint8_t *)_buf;
|
||||
_ARC4_LOCK();
|
||||
|
||||
@@ -95,8 +95,13 @@ archive_read_data_into_fd(struct archive *a, int fd)
|
||||
"archive_read_data_into_fd");
|
||||
|
||||
can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
|
||||
if (!can_lseek)
|
||||
if (!can_lseek) {
|
||||
nulls = calloc(1, nulls_size);
|
||||
if (!nulls) {
|
||||
r = ARCHIVE_FATAL;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
|
||||
ARCHIVE_OK) {
|
||||
|
||||
@@ -1678,6 +1678,11 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
else
|
||||
t->current_filesystem->name_max = nm;
|
||||
#endif
|
||||
if (t->current_filesystem->name_max == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Cannot determine name_max");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif /* USE_READDIR_R */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
@@ -1868,7 +1873,16 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
|
||||
#if defined(USE_READDIR_R)
|
||||
/* Set maximum filename length. */
|
||||
#if defined(HAVE_STATVFS)
|
||||
t->current_filesystem->name_max = svfs.f_namemax;
|
||||
#else
|
||||
t->current_filesystem->name_max = sfs.f_namelen;
|
||||
#endif
|
||||
if (t->current_filesystem->name_max == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Cannot determine name_max");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
@@ -1950,6 +1964,11 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
#if defined(USE_READDIR_R)
|
||||
/* Set maximum filename length. */
|
||||
t->current_filesystem->name_max = svfs.f_namemax;
|
||||
if (t->current_filesystem->name_max == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Cannot determine name_max");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
@@ -2004,6 +2023,11 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
else
|
||||
t->current_filesystem->name_max = nm;
|
||||
# endif /* _PC_NAME_MAX */
|
||||
if (t->current_filesystem->name_max == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Cannot determine name_max");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif /* USE_READDIR_R */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
@@ -2554,7 +2578,11 @@ tree_current_lstat(struct tree *t)
|
||||
#else
|
||||
if (tree_enter_working_dir(t) != 0)
|
||||
return NULL;
|
||||
#ifdef HAVE_LSTAT
|
||||
if (lstat(tree_current_access_path(t), &t->lst) != 0)
|
||||
#else
|
||||
if (la_stat(tree_current_access_path(t), &t->lst) != 0)
|
||||
#endif
|
||||
#endif
|
||||
return NULL;
|
||||
t->flags |= hasLstat;
|
||||
|
||||
@@ -418,9 +418,19 @@ la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype)
|
||||
FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
int ret;
|
||||
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileFlags = flag;
|
||||
h = CreateFile2(path, 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
OPEN_EXISTING, &createExParams);
|
||||
#else
|
||||
h = CreateFileW(path, 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
|
||||
OPEN_EXISTING, flag, NULL);
|
||||
#endif
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
return (-1);
|
||||
@@ -1067,16 +1077,29 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
||||
if (archive_entry_filetype(entry) == AE_IFREG &&
|
||||
archive_entry_size(entry) > 0) {
|
||||
DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
#endif
|
||||
if (t->async_io)
|
||||
flags |= FILE_FLAG_OVERLAPPED;
|
||||
if (t->direct_io)
|
||||
flags |= FILE_FLAG_NO_BUFFERING;
|
||||
else
|
||||
flags |= FILE_FLAG_SEQUENTIAL_SCAN;
|
||||
#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileFlags = flags;
|
||||
t->entry_fh = CreateFile2(tree_current_access_path(t),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
OPEN_EXISTING, &createExParams);
|
||||
#else
|
||||
t->entry_fh = CreateFileW(tree_current_access_path(t),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL, OPEN_EXISTING, flags, NULL);
|
||||
#endif
|
||||
if (t->entry_fh == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
archive_set_error(&a->archive, errno,
|
||||
@@ -1547,6 +1570,9 @@ close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
|
||||
{
|
||||
HANDLE handle;
|
||||
int r = 0;
|
||||
#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
#endif
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
|
||||
return (0);
|
||||
@@ -1560,8 +1586,16 @@ close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
|
||||
if ((t->flags & needsRestoreTimes) == 0)
|
||||
return (r);
|
||||
|
||||
#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
handle = CreateFile2(rt->full_path, FILE_WRITE_ATTRIBUTES,
|
||||
0, OPEN_EXISTING, &createExParams);
|
||||
#else
|
||||
handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
|
||||
0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
#endif
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
@@ -2046,12 +2080,24 @@ tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
|
||||
HANDLE h;
|
||||
int r;
|
||||
DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
#endif
|
||||
|
||||
if (sim_lstat && tree_current_is_physical_link(t))
|
||||
flag |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileFlags = flag;
|
||||
h = CreateFile2(tree_current_access_path(t), 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
OPEN_EXISTING, &createExParams);
|
||||
#else
|
||||
h = CreateFileW(tree_current_access_path(t), 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
|
||||
OPEN_EXISTING, flag, NULL);
|
||||
#endif
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
t->tree_errno = errno;
|
||||
@@ -2257,7 +2303,10 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
} else {
|
||||
WIN32_FIND_DATAW findData;
|
||||
DWORD flag, desiredAccess;
|
||||
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
#endif
|
||||
|
||||
h = FindFirstFileW(path, &findData);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
@@ -2279,9 +2328,18 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
} else
|
||||
desiredAccess = GENERIC_READ;
|
||||
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileFlags = flag;
|
||||
h = CreateFile2(path, desiredAccess,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
OPEN_EXISTING, &createExParams);
|
||||
#else
|
||||
h = CreateFileW(path, desiredAccess,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
|
||||
OPEN_EXISTING, flag, NULL);
|
||||
#endif
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
archive_set_error(&a->archive, errno,
|
||||
@@ -2342,9 +2400,19 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
if (fd >= 0) {
|
||||
h = (HANDLE)_get_osfhandle(fd);
|
||||
} else {
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
h = CreateFile2(path, GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
OPEN_EXISTING, &createExParams);
|
||||
#else
|
||||
h = CreateFileW(path, GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
|
||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
#endif
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
archive_set_error(&a->archive, errno,
|
||||
|
||||
@@ -154,10 +154,10 @@ file_skip(struct archive *a, void *client_data, int64_t request)
|
||||
#ifdef __ANDROID__
|
||||
/* fileno() isn't safe on all platforms ... see above. */
|
||||
if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
|
||||
#elif HAVE_FSEEKO
|
||||
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
|
||||
#elif HAVE__FSEEKI64
|
||||
if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
|
||||
#elif HAVE_FSEEKO
|
||||
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
|
||||
#else
|
||||
if (fseek(mine->f, skip, SEEK_CUR) != 0)
|
||||
#endif
|
||||
|
||||
@@ -255,6 +255,27 @@ have been concatenated together.
|
||||
Without this option, only the contents of
|
||||
the first concatenated archive would be read.
|
||||
.El
|
||||
.It Format zip
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm compat-2x
|
||||
Libarchive 2.x incorrectly encoded Unicode filenames on
|
||||
some platforms.
|
||||
This option mimics the libarchive 2.x filename handling
|
||||
so that such archives can be read correctly.
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating file names.
|
||||
.It Cm ignorecrc32
|
||||
Skip the CRC32 check.
|
||||
Mostly used for testing.
|
||||
.It Cm mac-ext
|
||||
Support Mac OS metadata extension that records data in special
|
||||
files beginning with a period and underscore.
|
||||
Defaults to enabled on Mac OS, disabled on other platforms.
|
||||
Use
|
||||
.Cm !mac-ext
|
||||
to disable.
|
||||
.El
|
||||
.El
|
||||
.\"
|
||||
.Sh ERRORS
|
||||
|
||||
@@ -230,7 +230,7 @@ bzip2_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 = (uint32_t)state->out_block_size;
|
||||
|
||||
/* Try to fill the output buffer. */
|
||||
for (;;) {
|
||||
@@ -288,7 +288,7 @@ bzip2_filter_read(struct archive_read_filter *self, const void **p)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
state->stream.next_in = (char *)(uintptr_t)read_buf;
|
||||
state->stream.avail_in = ret;
|
||||
state->stream.avail_in = (uint32_t)ret;
|
||||
/* There is no more data, return whatever we have. */
|
||||
if (ret == 0) {
|
||||
state->eof = 1;
|
||||
|
||||
@@ -584,7 +584,7 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
|
||||
state->out_block + prefix64k, (int)compressed_size,
|
||||
state->flags.block_maximum_size,
|
||||
state->out_block,
|
||||
prefix64k);
|
||||
(int)prefix64k);
|
||||
#else
|
||||
uncompressed_size = LZ4_decompress_safe_withPrefix64k(
|
||||
read_buf + 4,
|
||||
|
||||
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
@@ -61,12 +62,17 @@ struct uudecode {
|
||||
#define ST_UUEND 2
|
||||
#define ST_READ_BASE64 3
|
||||
#define ST_IGNORE 4
|
||||
mode_t mode;
|
||||
int mode_set;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static int uudecode_bidder_bid(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *filter);
|
||||
static int uudecode_bidder_init(struct archive_read_filter *);
|
||||
|
||||
static int uudecode_read_header(struct archive_read_filter *,
|
||||
struct archive_entry *entry);
|
||||
static ssize_t uudecode_filter_read(struct archive_read_filter *,
|
||||
const void **);
|
||||
static int uudecode_filter_close(struct archive_read_filter *);
|
||||
@@ -359,6 +365,7 @@ static const struct archive_read_filter_vtable
|
||||
uudecode_reader_vtable = {
|
||||
.read = uudecode_filter_read,
|
||||
.close = uudecode_filter_close,
|
||||
.read_header = uudecode_read_header
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -389,6 +396,8 @@ uudecode_bidder_init(struct archive_read_filter *self)
|
||||
uudecode->in_allocated = IN_BUFF_SIZE;
|
||||
uudecode->out_buff = out_buff;
|
||||
uudecode->state = ST_FIND_HEAD;
|
||||
uudecode->mode_set = 0;
|
||||
uudecode->name = NULL;
|
||||
self->vtable = &uudecode_reader_vtable;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
@@ -434,6 +443,22 @@ ensure_in_buff_size(struct archive_read_filter *self,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
uudecode_read_header(struct archive_read_filter *self, struct archive_entry *entry)
|
||||
{
|
||||
|
||||
struct uudecode *uudecode;
|
||||
uudecode = (struct uudecode *)self->data;
|
||||
|
||||
if (uudecode->mode_set != 0)
|
||||
archive_entry_set_mode(entry, S_IFREG | uudecode->mode);
|
||||
|
||||
if (uudecode->name != NULL)
|
||||
archive_entry_set_pathname(entry, uudecode->name);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
uudecode_filter_read(struct archive_read_filter *self, const void **buff)
|
||||
{
|
||||
@@ -443,7 +468,7 @@ uudecode_filter_read(struct archive_read_filter *self, const void **buff)
|
||||
ssize_t avail_in, ravail;
|
||||
ssize_t used;
|
||||
ssize_t total;
|
||||
ssize_t len, llen, nl;
|
||||
ssize_t len, llen, nl, namelen;
|
||||
|
||||
uudecode = (struct uudecode *)self->data;
|
||||
|
||||
@@ -551,6 +576,28 @@ read_more:
|
||||
uudecode->state = ST_READ_UU;
|
||||
else
|
||||
uudecode->state = ST_READ_BASE64;
|
||||
uudecode->mode = (mode_t)(
|
||||
((int)(b[l] - '0') * 64) +
|
||||
((int)(b[l+1] - '0') * 8) +
|
||||
(int)(b[l+2] - '0'));
|
||||
uudecode->mode_set = 1;
|
||||
namelen = len - nl - 4 - l;
|
||||
if (namelen > 1) {
|
||||
if (uudecode->name != NULL)
|
||||
free(uudecode->name);
|
||||
uudecode->name = malloc(namelen + 1);
|
||||
if (uudecode->name == NULL) {
|
||||
archive_set_error(
|
||||
&self->archive->archive,
|
||||
ENOMEM,
|
||||
"Can't allocate data for uudecode");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
strncpy(uudecode->name,
|
||||
(const char *)(b + l + 4),
|
||||
namelen);
|
||||
uudecode->name[namelen] = '\0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ST_READ_UU:
|
||||
@@ -683,6 +730,7 @@ uudecode_filter_close(struct archive_read_filter *self)
|
||||
uudecode = (struct uudecode *)self->data;
|
||||
free(uudecode->in_buff);
|
||||
free(uudecode->out_buff);
|
||||
free(uudecode->name);
|
||||
free(uudecode);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
@@ -115,9 +115,9 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
unsigned prefix;
|
||||
|
||||
/* Zstd frame magic values */
|
||||
const unsigned zstd_magic = 0xFD2FB528U;
|
||||
const unsigned zstd_magic_skippable_start = 0x184D2A50U;
|
||||
const unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
|
||||
unsigned zstd_magic = 0xFD2FB528U;
|
||||
unsigned zstd_magic_skippable_start = 0x184D2A50U;
|
||||
unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
|
||||
|
||||
(void) self; /* UNUSED */
|
||||
|
||||
@@ -170,7 +170,7 @@ static int
|
||||
zstd_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
struct private_data *state;
|
||||
const size_t out_block_size = ZSTD_DStreamOutSize();
|
||||
size_t out_block_size = ZSTD_DStreamOutSize();
|
||||
void *out_block;
|
||||
ZSTD_DStream *dstream;
|
||||
|
||||
@@ -211,6 +211,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
|
||||
ssize_t avail_in;
|
||||
ZSTD_outBuffer out;
|
||||
ZSTD_inBuffer in;
|
||||
size_t ret;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
|
||||
@@ -219,7 +220,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
|
||||
/* Try to fill the output buffer. */
|
||||
while (out.pos < out.size && !state->eof) {
|
||||
if (!state->in_frame) {
|
||||
const size_t ret = ZSTD_initDStream(state->dstream);
|
||||
ret = ZSTD_initDStream(state->dstream);
|
||||
if (ZSTD_isError(ret)) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
@@ -249,8 +250,7 @@ zstd_filter_read(struct archive_read_filter *self, const void **p)
|
||||
in.pos = 0;
|
||||
|
||||
{
|
||||
const size_t ret =
|
||||
ZSTD_decompressStream(state->dstream, &out, &in);
|
||||
ret = ZSTD_decompressStream(state->dstream, &out, &in);
|
||||
|
||||
if (ZSTD_isError(ret)) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
|
||||
@@ -41,6 +41,9 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef HAVE_ZLIB_H
|
||||
#include <cm3p/zlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_ZSTD_H
|
||||
#include <cm3p/zstd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __clang_analyzer__
|
||||
#include <assert.h>
|
||||
@@ -84,8 +87,11 @@ __FBSDID("$FreeBSD$");
|
||||
#define _7Z_IA64 0x03030401
|
||||
#define _7Z_ARM 0x03030501
|
||||
#define _7Z_ARMTHUMB 0x03030701
|
||||
#define _7Z_ARM64 0xa
|
||||
#define _7Z_SPARC 0x03030805
|
||||
|
||||
#define _7Z_ZSTD 0x4F71101 /* Copied from https://github.com/mcmilk/7-Zip-zstd.git */
|
||||
|
||||
/*
|
||||
* 7-Zip header property IDs.
|
||||
*/
|
||||
@@ -114,6 +120,30 @@ __FBSDID("$FreeBSD$");
|
||||
#define kEncodedHeader 0x17
|
||||
#define kDummy 0x19
|
||||
|
||||
// Check that some windows file attribute constants are defined.
|
||||
// Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
|
||||
#ifndef FILE_ATTRIBUTE_READONLY
|
||||
#define FILE_ATTRIBUTE_READONLY 0x00000001
|
||||
#endif
|
||||
|
||||
#ifndef FILE_ATTRIBUTE_HIDDEN
|
||||
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
|
||||
#endif
|
||||
|
||||
#ifndef FILE_ATTRIBUTE_SYSTEM
|
||||
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
|
||||
#endif
|
||||
|
||||
#ifndef FILE_ATTRIBUTE_DIRECTORY
|
||||
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
||||
#endif
|
||||
|
||||
// This value is defined in 7zip with the comment "trick for Unix".
|
||||
//
|
||||
// 7z archives created on unix have this bit set in the high 16 bits of
|
||||
// the attr field along with the unix permissions.
|
||||
#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000
|
||||
|
||||
struct _7z_digests {
|
||||
unsigned char *defineds;
|
||||
uint32_t *digests;
|
||||
@@ -281,6 +311,11 @@ struct _7zip {
|
||||
#ifdef HAVE_ZLIB_H
|
||||
z_stream stream;
|
||||
int stream_valid;
|
||||
#endif
|
||||
/* Decoding Zstandard data. */
|
||||
#if HAVE_ZSTD_H
|
||||
ZSTD_DStream *zstd_dstream;
|
||||
int zstdstream_valid;
|
||||
#endif
|
||||
/* Decoding PPMd data. */
|
||||
int ppmd7_stat;
|
||||
@@ -401,6 +436,9 @@ static int setup_decode_folder(struct archive_read *, struct _7z_folder *,
|
||||
int);
|
||||
static void x86_Init(struct _7zip *);
|
||||
static size_t x86_Convert(struct _7zip *, uint8_t *, size_t);
|
||||
static void arm_Init(struct _7zip *);
|
||||
static size_t arm_Convert(struct _7zip *, uint8_t *, size_t);
|
||||
static size_t arm64_Convert(struct _7zip *, uint8_t *, size_t);
|
||||
static ssize_t Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
|
||||
|
||||
|
||||
@@ -729,6 +767,37 @@ archive_read_format_7zip_read_header(struct archive_read *a,
|
||||
archive_entry_set_size(entry, 0);
|
||||
}
|
||||
|
||||
// These attributes are supported by the windows implementation of archive_write_disk.
|
||||
const int supported_attrs = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
|
||||
|
||||
if (zip_entry->attr & supported_attrs) {
|
||||
char *fflags_text, *ptr;
|
||||
/* allocate for "rdonly,hidden,system," */
|
||||
fflags_text = malloc(22 * sizeof(char));
|
||||
if (fflags_text != NULL) {
|
||||
ptr = fflags_text;
|
||||
if (zip_entry->attr & FILE_ATTRIBUTE_READONLY) {
|
||||
strcpy(ptr, "rdonly,");
|
||||
ptr = ptr + 7;
|
||||
}
|
||||
if (zip_entry->attr & FILE_ATTRIBUTE_HIDDEN) {
|
||||
strcpy(ptr, "hidden,");
|
||||
ptr = ptr + 7;
|
||||
}
|
||||
if (zip_entry->attr & FILE_ATTRIBUTE_SYSTEM) {
|
||||
strcpy(ptr, "system,");
|
||||
ptr = ptr + 7;
|
||||
}
|
||||
if (ptr > fflags_text) {
|
||||
/* Delete trailing comma */
|
||||
*(ptr - 1) = '\0';
|
||||
archive_entry_copy_fflags_text(entry,
|
||||
fflags_text);
|
||||
}
|
||||
free(fflags_text);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's no body, force read_data() to return EOF immediately. */
|
||||
if (zip->entry_bytes_remaining < 1)
|
||||
zip->end_of_entry = 1;
|
||||
@@ -1034,10 +1103,13 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||
case _7Z_COPY:
|
||||
case _7Z_BZ2:
|
||||
case _7Z_DEFLATE:
|
||||
case _7Z_ZSTD:
|
||||
case _7Z_PPMD:
|
||||
if (coder2 != NULL) {
|
||||
if (coder2->codec != _7Z_X86 &&
|
||||
coder2->codec != _7Z_X86_BCJ2) {
|
||||
coder2->codec != _7Z_X86_BCJ2 &&
|
||||
coder2->codec != _7Z_ARM &&
|
||||
coder2->codec != _7Z_ARM64) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported filter %lx for %lx",
|
||||
@@ -1048,6 +1120,8 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||
zip->bcj_state = 0;
|
||||
if (coder2->codec == _7Z_X86)
|
||||
x86_Init(zip);
|
||||
else if (coder2->codec == _7Z_ARM)
|
||||
arm_Init(zip);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1144,6 +1218,12 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||
filters[fi].id = LZMA_FILTER_ARMTHUMB;
|
||||
fi++;
|
||||
break;
|
||||
#ifdef LZMA_FILTER_ARM64
|
||||
case _7Z_ARM64:
|
||||
filters[fi].id = LZMA_FILTER_ARM64;
|
||||
fi++;
|
||||
break;
|
||||
#endif
|
||||
case _7Z_SPARC:
|
||||
filters[fi].id = LZMA_FILTER_SPARC;
|
||||
fi++;
|
||||
@@ -1229,6 +1309,22 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||
"BZ2 codec is unsupported");
|
||||
return (ARCHIVE_FAILED);
|
||||
#endif
|
||||
case _7Z_ZSTD:
|
||||
{
|
||||
#if defined(HAVE_ZSTD_H)
|
||||
if (zip->zstdstream_valid) {
|
||||
ZSTD_freeDStream(zip->zstd_dstream);
|
||||
zip->zstdstream_valid = 0;
|
||||
}
|
||||
zip->zstd_dstream = ZSTD_createDStream();
|
||||
zip->zstdstream_valid = 1;
|
||||
break;
|
||||
#else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"ZSTD codec is unsupported");
|
||||
return (ARCHIVE_FAILED);
|
||||
#endif
|
||||
}
|
||||
case _7Z_DEFLATE:
|
||||
#ifdef HAVE_ZLIB_H
|
||||
if (zip->stream_valid)
|
||||
@@ -1299,6 +1395,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||
case _7Z_IA64:
|
||||
case _7Z_ARM:
|
||||
case _7Z_ARMTHUMB:
|
||||
case _7Z_ARM64:
|
||||
case _7Z_SPARC:
|
||||
case _7Z_DELTA:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
@@ -1443,9 +1540,9 @@ decompress(struct archive_read *a, struct _7zip *zip,
|
||||
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
|
||||
case _7Z_BZ2:
|
||||
zip->bzstream.next_in = (char *)(uintptr_t)t_next_in;
|
||||
zip->bzstream.avail_in = t_avail_in;
|
||||
zip->bzstream.avail_in = (uint32_t)t_avail_in;
|
||||
zip->bzstream.next_out = (char *)(uintptr_t)t_next_out;
|
||||
zip->bzstream.avail_out = t_avail_out;
|
||||
zip->bzstream.avail_out = (uint32_t)t_avail_out;
|
||||
r = BZ2_bzDecompress(&(zip->bzstream));
|
||||
switch (r) {
|
||||
case BZ_STREAM_END: /* Found end of stream. */
|
||||
@@ -1494,6 +1591,22 @@ decompress(struct archive_read *a, struct _7zip *zip,
|
||||
t_avail_in = zip->stream.avail_in;
|
||||
t_avail_out = zip->stream.avail_out;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_ZSTD_H
|
||||
case _7Z_ZSTD:
|
||||
{
|
||||
ZSTD_inBuffer input = { t_next_in, t_avail_in, 0 }; // src, size, pos
|
||||
ZSTD_outBuffer output = { t_next_out, t_avail_out, 0 }; // dst, size, pos
|
||||
|
||||
size_t const zret = ZSTD_decompressStream(zip->zstd_dstream, &output, &input);
|
||||
if (ZSTD_isError(zret)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Zstd decompression failed: %s", ZSTD_getErrorName(zret));
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
t_avail_in -= input.pos;
|
||||
t_avail_out -= output.pos;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case _7Z_PPMD:
|
||||
{
|
||||
@@ -1579,16 +1692,23 @@ decompress(struct archive_read *a, struct _7zip *zip,
|
||||
/*
|
||||
* Decord BCJ.
|
||||
*/
|
||||
if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
|
||||
size_t l = x86_Convert(zip, buff, *outbytes);
|
||||
zip->odd_bcj_size = *outbytes - l;
|
||||
if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
|
||||
o_avail_in && ret != ARCHIVE_EOF) {
|
||||
memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
|
||||
zip->odd_bcj_size);
|
||||
*outbytes = l;
|
||||
} else
|
||||
zip->odd_bcj_size = 0;
|
||||
if (zip->codec != _7Z_LZMA2) {
|
||||
if (zip->codec2 == _7Z_X86) {
|
||||
size_t l = x86_Convert(zip, buff, *outbytes);
|
||||
|
||||
zip->odd_bcj_size = *outbytes - l;
|
||||
if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
|
||||
o_avail_in && ret != ARCHIVE_EOF) {
|
||||
memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
|
||||
zip->odd_bcj_size);
|
||||
*outbytes = l;
|
||||
} else
|
||||
zip->odd_bcj_size = 0;
|
||||
} else if (zip->codec2 == _7Z_ARM) {
|
||||
*outbytes = arm_Convert(zip, buff, *outbytes);
|
||||
} else if (zip->codec2 == _7Z_ARM64) {
|
||||
*outbytes = arm64_Convert(zip, buff, *outbytes);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2612,6 +2732,28 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
|
||||
entries[i].flg |= HAS_STREAM;
|
||||
/* The high 16 bits of attributes is a posix file mode. */
|
||||
entries[i].mode = entries[i].attr >> 16;
|
||||
|
||||
if (!(entries[i].attr & FILE_ATTRIBUTE_UNIX_EXTENSION)) {
|
||||
// Only windows permissions specified for this entry. Translate to
|
||||
// reasonable corresponding unix permissions.
|
||||
|
||||
if (entries[i].attr & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
if (entries[i].attr & FILE_ATTRIBUTE_READONLY) {
|
||||
// Read-only directory.
|
||||
entries[i].mode = AE_IFDIR | 0555;
|
||||
} else {
|
||||
// Read-write directory.
|
||||
entries[i].mode = AE_IFDIR | 0755;
|
||||
}
|
||||
} else if (entries[i].attr & FILE_ATTRIBUTE_READONLY) {
|
||||
// Readonly file.
|
||||
entries[i].mode = AE_IFREG | 0444;
|
||||
} else {
|
||||
// Assume read-write file.
|
||||
entries[i].mode = AE_IFREG | 0644;
|
||||
}
|
||||
}
|
||||
|
||||
if (entries[i].flg & HAS_STREAM) {
|
||||
if ((size_t)sindex >= si->ss.unpack_streams)
|
||||
return (-1);
|
||||
@@ -2652,7 +2794,7 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
|
||||
}
|
||||
entries[i].ssIndex = -1;
|
||||
}
|
||||
if (entries[i].attr & 0x01)
|
||||
if (entries[i].attr & FILE_ATTRIBUTE_READONLY)
|
||||
entries[i].mode &= ~0222;/* Read only. */
|
||||
|
||||
if ((entries[i].flg & HAS_STREAM) == 0 && indexInFolder == 0) {
|
||||
@@ -3737,6 +3879,116 @@ x86_Convert(struct _7zip *zip, uint8_t *data, size_t size)
|
||||
return (bufferPos);
|
||||
}
|
||||
|
||||
static void
|
||||
arm_Init(struct _7zip *zip)
|
||||
{
|
||||
zip->bcj_ip = 8;
|
||||
}
|
||||
|
||||
static size_t
|
||||
arm_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
|
||||
{
|
||||
// This function was adapted from
|
||||
// static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
||||
// in https://git.tukaani.org/xz-embedded.git
|
||||
|
||||
/*
|
||||
* Branch/Call/Jump (BCJ) filter decoders
|
||||
*
|
||||
* Authors: Lasse Collin <lasse.collin@tukaani.org>
|
||||
* Igor Pavlov <https://7-zip.org/>
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
size_t i;
|
||||
uint32_t addr;
|
||||
|
||||
for (i = 0; i + 4 <= size; i += 4) {
|
||||
if (buf[i + 3] == 0xEB) {
|
||||
// Calculate the transformed addr.
|
||||
addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
|
||||
| ((uint32_t)buf[i + 2] << 16);
|
||||
addr <<= 2;
|
||||
addr -= zip->bcj_ip + (uint32_t)i;
|
||||
addr >>= 2;
|
||||
|
||||
// Store the transformed addr in buf.
|
||||
buf[i] = (uint8_t)addr;
|
||||
buf[i + 1] = (uint8_t)(addr >> 8);
|
||||
buf[i + 2] = (uint8_t)(addr >> 16);
|
||||
}
|
||||
}
|
||||
|
||||
zip->bcj_ip += (uint32_t)i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static size_t
|
||||
arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size)
|
||||
{
|
||||
// This function was adapted from
|
||||
// static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
||||
// in https://git.tukaani.org/xz-embedded.git
|
||||
|
||||
/*
|
||||
* Branch/Call/Jump (BCJ) filter decoders
|
||||
*
|
||||
* Authors: Lasse Collin <lasse.collin@tukaani.org>
|
||||
* Igor Pavlov <https://7-zip.org/>
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
size_t i;
|
||||
uint32_t instr;
|
||||
uint32_t addr;
|
||||
|
||||
for (i = 0; i + 4 <= size; i += 4) {
|
||||
instr = (uint32_t)buf[i]
|
||||
| ((uint32_t)buf[i+1] << 8)
|
||||
| ((uint32_t)buf[i+2] << 16)
|
||||
| ((uint32_t)buf[i+3] << 24);
|
||||
|
||||
if ((instr >> 26) == 0x25) {
|
||||
/* BL instruction */
|
||||
addr = instr - ((zip->bcj_ip + (uint32_t)i) >> 2);
|
||||
instr = 0x94000000 | (addr & 0x03FFFFFF);
|
||||
|
||||
buf[i] = (uint8_t)instr;
|
||||
buf[i+1] = (uint8_t)(instr >> 8);
|
||||
buf[i+2] = (uint8_t)(instr >> 16);
|
||||
buf[i+3] = (uint8_t)(instr >> 24);
|
||||
} else if ((instr & 0x9F000000) == 0x90000000) {
|
||||
/* ADRP instruction */
|
||||
addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC);
|
||||
|
||||
/* Only convert values in the range +/-512 MiB. */
|
||||
if ((addr + 0x020000) & 0x1C0000)
|
||||
continue;
|
||||
|
||||
addr -= (zip->bcj_ip + (uint32_t)i) >> 12;
|
||||
|
||||
instr &= 0x9000001F;
|
||||
instr |= (addr & 3) << 29;
|
||||
instr |= (addr & 0x03FFFC) << 3;
|
||||
instr |= (0U - (addr & 0x020000)) & 0xE00000;
|
||||
|
||||
buf[i] = (uint8_t)instr;
|
||||
buf[i+1] = (uint8_t)(instr >> 8);
|
||||
buf[i+2] = (uint8_t)(instr >> 16);
|
||||
buf[i+3] = (uint8_t)(instr >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
zip->bcj_ip += (uint32_t)i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Brought from LZMA SDK.
|
||||
*
|
||||
|
||||
@@ -2294,10 +2294,10 @@ lzx_br_fillup(struct lzx_stream *strm, struct lzx_br *br)
|
||||
(br->cache_buffer << 48) |
|
||||
((uint64_t)strm->next_in[1]) << 40 |
|
||||
((uint64_t)strm->next_in[0]) << 32 |
|
||||
((uint32_t)strm->next_in[3]) << 24 |
|
||||
((uint32_t)strm->next_in[2]) << 16 |
|
||||
((uint32_t)strm->next_in[5]) << 8 |
|
||||
(uint32_t)strm->next_in[4];
|
||||
((uint64_t)strm->next_in[3]) << 24 |
|
||||
((uint64_t)strm->next_in[2]) << 16 |
|
||||
((uint64_t)strm->next_in[5]) << 8 |
|
||||
(uint64_t)strm->next_in[4];
|
||||
strm->next_in += 6;
|
||||
strm->avail_in -= 6;
|
||||
br->cache_avail += 6 * 8;
|
||||
|
||||
@@ -441,7 +441,7 @@ archive_read_format_cpio_read_header(struct archive_read *a,
|
||||
|
||||
/* Compare name to "TRAILER!!!" to test for end-of-archive. */
|
||||
if (namelength == 11 && strncmp((const char *)h, "TRAILER!!!",
|
||||
11) == 0) {
|
||||
10) == 0) {
|
||||
/* TODO: Store file location of start of block. */
|
||||
archive_clear_error(&a->archive);
|
||||
return (ARCHIVE_EOF);
|
||||
@@ -985,14 +985,14 @@ archive_read_format_cpio_cleanup(struct archive_read *a)
|
||||
static int64_t
|
||||
le4(const unsigned char *p)
|
||||
{
|
||||
return ((p[0] << 16) + (((int64_t)p[1]) << 24) + (p[2] << 0) + (p[3] << 8));
|
||||
return ((p[0] << 16) | (((int64_t)p[1]) << 24) | (p[2] << 0) | (p[3] << 8));
|
||||
}
|
||||
|
||||
|
||||
static int64_t
|
||||
be4(const unsigned char *p)
|
||||
{
|
||||
return ((((int64_t)p[0]) << 24) + (p[1] << 16) + (p[2] << 8) + (p[3]));
|
||||
return ((((int64_t)p[0]) << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1901,7 +1901,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
* NUMBER of RRIP "PX" extension.
|
||||
* Note: Old mkisofs did not record that FILE SERIAL NUMBER
|
||||
* in ISO images.
|
||||
* Note2: xorriso set 0 to the location of a symlink file.
|
||||
* Note2: xorriso set 0 to the location of a symlink file.
|
||||
*/
|
||||
if (file->size == 0 && location >= 0) {
|
||||
/* If file->size is zero, its location points wrong place,
|
||||
@@ -1955,7 +1955,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
* made by makefs is not zero and its location is
|
||||
* the same as those of next regular file. That is
|
||||
* the same as hard like file and it causes unexpected
|
||||
* error.
|
||||
* error.
|
||||
*/
|
||||
if (file->size > 0 &&
|
||||
(file->mode & AE_IFMT) == AE_IFLNK) {
|
||||
@@ -2747,7 +2747,7 @@ next_cache_entry(struct archive_read *a, struct iso9660 *iso9660,
|
||||
* If directory entries all which are descendant of
|
||||
* rr_moved are still remaining, expose their.
|
||||
*/
|
||||
if (iso9660->re_files.first != NULL &&
|
||||
if (iso9660->re_files.first != NULL &&
|
||||
iso9660->rr_moved != NULL &&
|
||||
iso9660->rr_moved->rr_moved_has_re_only)
|
||||
/* Expose "rr_moved" entry. */
|
||||
@@ -3182,11 +3182,11 @@ isodate17(const unsigned char *v)
|
||||
static time_t
|
||||
time_from_tm(struct tm *t)
|
||||
{
|
||||
#if HAVE_TIMEGM
|
||||
#if HAVE__MKGMTIME
|
||||
return _mkgmtime(t);
|
||||
#elif HAVE_TIMEGM
|
||||
/* Use platform timegm() if available. */
|
||||
return (timegm(t));
|
||||
#elif HAVE__MKGMTIME64
|
||||
return (_mkgmtime64(t));
|
||||
#else
|
||||
/* Else use direct calculation using POSIX assumptions. */
|
||||
/* First, fix up tm_yday based on the year/month/day. */
|
||||
|
||||
@@ -1819,7 +1819,7 @@ lha_crc16(uint16_t crc, const void *pp, size_t len)
|
||||
* remove the statement which will not be executed. */
|
||||
#undef bswap16
|
||||
#ifndef __has_builtin
|
||||
# define __has_builtin(x) 0
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400 /* Visual Studio */
|
||||
# define bswap16(x) _byteswap_ushort(x)
|
||||
@@ -1827,7 +1827,7 @@ lha_crc16(uint16_t crc, const void *pp, size_t len)
|
||||
/* GCC 4.8 and later has __builtin_bswap16() */
|
||||
# define bswap16(x) __builtin_bswap16(x)
|
||||
#elif defined(__clang__) && __has_builtin(__builtin_bswap16)
|
||||
/* All clang versions have __builtin_bswap16() */
|
||||
/* Newer clang versions have __builtin_bswap16() */
|
||||
# define bswap16(x) __builtin_bswap16(x)
|
||||
#else
|
||||
# define bswap16(x) ((((x) >> 8) & 0xff) | ((x) << 8))
|
||||
@@ -2012,10 +2012,10 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
|
||||
((uint64_t)strm->next_in[0]) << 48 |
|
||||
((uint64_t)strm->next_in[1]) << 40 |
|
||||
((uint64_t)strm->next_in[2]) << 32 |
|
||||
((uint32_t)strm->next_in[3]) << 24 |
|
||||
((uint32_t)strm->next_in[4]) << 16 |
|
||||
((uint32_t)strm->next_in[5]) << 8 |
|
||||
(uint32_t)strm->next_in[6];
|
||||
((uint64_t)strm->next_in[3]) << 24 |
|
||||
((uint64_t)strm->next_in[4]) << 16 |
|
||||
((uint64_t)strm->next_in[5]) << 8 |
|
||||
(uint64_t)strm->next_in[6];
|
||||
strm->next_in += 7;
|
||||
strm->avail_in -= 7;
|
||||
br->cache_avail += 7 * 8;
|
||||
@@ -2025,10 +2025,10 @@ lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br)
|
||||
(br->cache_buffer << 48) |
|
||||
((uint64_t)strm->next_in[0]) << 40 |
|
||||
((uint64_t)strm->next_in[1]) << 32 |
|
||||
((uint32_t)strm->next_in[2]) << 24 |
|
||||
((uint32_t)strm->next_in[3]) << 16 |
|
||||
((uint32_t)strm->next_in[4]) << 8 |
|
||||
(uint32_t)strm->next_in[5];
|
||||
((uint64_t)strm->next_in[2]) << 24 |
|
||||
((uint64_t)strm->next_in[3]) << 16 |
|
||||
((uint64_t)strm->next_in[4]) << 8 |
|
||||
(uint64_t)strm->next_in[5];
|
||||
strm->next_in += 6;
|
||||
strm->avail_in -= 6;
|
||||
br->cache_avail += 6 * 8;
|
||||
|
||||
@@ -1280,7 +1280,13 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
|
||||
mtree->fd = -1;
|
||||
st = NULL;
|
||||
}
|
||||
} else if (lstat(path, st) == -1) {
|
||||
}
|
||||
#ifdef HAVE_LSTAT
|
||||
else if (lstat(path, st) == -1)
|
||||
#else
|
||||
else if (la_stat(path, st) == -1)
|
||||
#endif
|
||||
{
|
||||
st = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1064,7 +1064,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
p = h;
|
||||
crc32_val = crc32(crc32_val, (const unsigned char *)p, to_read);
|
||||
crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned int)to_read);
|
||||
__archive_read_consume(a, to_read);
|
||||
skip -= to_read;
|
||||
}
|
||||
@@ -1832,13 +1832,9 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
|
||||
struct tm *tm;
|
||||
time_t t;
|
||||
long nsec;
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
|
||||
struct tm tmbuf;
|
||||
#endif
|
||||
#if defined(HAVE__LOCALTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
if (p + 2 > endp)
|
||||
return (-1);
|
||||
@@ -1870,15 +1866,10 @@ read_exttime(const char *p, struct rar *rar, const char *endp)
|
||||
rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
|
||||
p++;
|
||||
}
|
||||
#if defined(HAVE_LOCALTIME_R)
|
||||
#if defined(HAVE_LOCALTIME_S)
|
||||
tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf;
|
||||
#elif defined(HAVE_LOCALTIME_R)
|
||||
tm = localtime_r(&t, &tmbuf);
|
||||
#elif defined(HAVE__LOCALTIME64_S)
|
||||
tmptime = t;
|
||||
terr = _localtime64_s(&tmbuf, &tmptime);
|
||||
if (terr)
|
||||
tm = NULL;
|
||||
else
|
||||
tm = &tmbuf;
|
||||
#else
|
||||
tm = localtime(&t);
|
||||
#endif
|
||||
@@ -3451,7 +3442,7 @@ compile_program(const uint8_t *bytes, size_t length)
|
||||
prog = calloc(1, sizeof(*prog));
|
||||
if (!prog)
|
||||
return NULL;
|
||||
prog->fingerprint = crc32(0, bytes, length) | ((uint64_t)length << 32);
|
||||
prog->fingerprint = crc32(0, bytes, (unsigned int)length) | ((uint64_t)length << 32);
|
||||
|
||||
if (membr_bits(&br, 1))
|
||||
{
|
||||
|
||||
@@ -2475,7 +2475,7 @@ static void update_crc(struct rar5* rar, const uint8_t* p, size_t to_read) {
|
||||
* `stored_crc32` info filled in. */
|
||||
if(rar->file.stored_crc32 > 0) {
|
||||
rar->file.calculated_crc32 =
|
||||
crc32(rar->file.calculated_crc32, p, to_read);
|
||||
crc32(rar->file.calculated_crc32, p, (unsigned int)to_read);
|
||||
}
|
||||
|
||||
/* Check if the file uses an optional BLAKE2sp checksum
|
||||
|
||||
@@ -530,11 +530,11 @@ strtoi_lim(const char *str, const char **ep, int llim, int ulim)
|
||||
static time_t
|
||||
time_from_tm(struct tm *t)
|
||||
{
|
||||
#if HAVE_TIMEGM
|
||||
#if HAVE__MKGMTIME
|
||||
return _mkgmtime(t);
|
||||
#elif HAVE_TIMEGM
|
||||
/* Use platform timegm() if available. */
|
||||
return (timegm(t));
|
||||
#elif HAVE__MKGMTIME64
|
||||
return (_mkgmtime64(t));
|
||||
#else
|
||||
/* Else use direct calculation using POSIX assumptions. */
|
||||
/* First, fix up tm_yday based on the year/month/day. */
|
||||
|
||||
@@ -1127,7 +1127,7 @@ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
|
||||
x |= p[1] - '0';
|
||||
else
|
||||
return (-1);
|
||||
|
||||
|
||||
*b++ = x;
|
||||
bsize--;
|
||||
p += 2;
|
||||
@@ -1139,11 +1139,11 @@ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
|
||||
static time_t
|
||||
time_from_tm(struct tm *t)
|
||||
{
|
||||
#if HAVE_TIMEGM
|
||||
#if HAVE__MKGMTIME
|
||||
return _mkgmtime(t);
|
||||
#elif HAVE_TIMEGM
|
||||
/* Use platform timegm() if available. */
|
||||
return (timegm(t));
|
||||
#elif HAVE__MKGMTIME64
|
||||
return (_mkgmtime64(t));
|
||||
#else
|
||||
/* Else use direct calculation using POSIX assumptions. */
|
||||
/* First, fix up tm_yday based on the year/month/day. */
|
||||
|
||||
@@ -2186,11 +2186,11 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
|
||||
|
||||
/* Setup buffer boundaries. */
|
||||
zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff;
|
||||
zip->bzstream.avail_in = in_bytes;
|
||||
zip->bzstream.avail_in = (uint32_t)in_bytes;
|
||||
zip->bzstream.total_in_hi32 = 0;
|
||||
zip->bzstream.total_in_lo32 = 0;
|
||||
zip->bzstream.next_out = (char*) zip->uncompressed_buffer;
|
||||
zip->bzstream.avail_out = zip->uncompressed_buffer_size;
|
||||
zip->bzstream.avail_out = (uint32_t)zip->uncompressed_buffer_size;
|
||||
zip->bzstream.total_out_hi32 = 0;
|
||||
zip->bzstream.total_out_lo32 = 0;
|
||||
|
||||
@@ -2227,7 +2227,7 @@ zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
|
||||
to_consume = zip->bzstream.total_in_lo32;
|
||||
__archive_read_consume(a, to_consume);
|
||||
|
||||
total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) +
|
||||
total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) |
|
||||
zip->bzstream.total_out_lo32;
|
||||
|
||||
zip->entry_bytes_remaining -= to_consume;
|
||||
|
||||
@@ -1324,6 +1324,10 @@ free_sconv_object(struct archive_string_conv *sc)
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# if defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
# define GetOEMCP() CP_OEMCP
|
||||
# endif
|
||||
|
||||
static unsigned
|
||||
my_atoi(const char *p)
|
||||
{
|
||||
|
||||
@@ -42,9 +42,20 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
/* don't use bcrypt when XP needs to be supported */
|
||||
#include <bcrypt.h>
|
||||
|
||||
/* Common in other bcrypt implementations, but missing from VS2008. */
|
||||
#ifndef BCRYPT_SUCCESS
|
||||
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
|
||||
#endif
|
||||
|
||||
#elif defined(HAVE_WINCRYPT_H)
|
||||
#include <wincrypt.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_ZLIB_H
|
||||
#include <cm3p/zlib.h>
|
||||
#endif
|
||||
@@ -233,14 +244,16 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
|
||||
L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
|
||||
L'u', L'v', L'w', L'x', L'y', L'z'
|
||||
};
|
||||
HCRYPTPROV hProv;
|
||||
struct archive_wstring temp_name;
|
||||
wchar_t *ws;
|
||||
DWORD attr;
|
||||
wchar_t *xp, *ep;
|
||||
int fd;
|
||||
|
||||
hProv = (HCRYPTPROV)NULL;
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
BCRYPT_ALG_HANDLE hAlg = NULL;
|
||||
#else
|
||||
HCRYPTPROV hProv = (HCRYPTPROV)NULL;
|
||||
#endif
|
||||
fd = -1;
|
||||
ws = NULL;
|
||||
|
||||
@@ -314,23 +327,42 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
|
||||
abort();
|
||||
}
|
||||
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM,
|
||||
NULL, 0))) {
|
||||
la_dosmaperr(GetLastError());
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
#else
|
||||
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT)) {
|
||||
la_dosmaperr(GetLastError());
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
wchar_t *p;
|
||||
HANDLE h;
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
#endif
|
||||
|
||||
/* Generate a random file name through CryptGenRandom(). */
|
||||
p = xp;
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, (PUCHAR)p,
|
||||
(DWORD)(ep - p)*sizeof(wchar_t), 0))) {
|
||||
la_dosmaperr(GetLastError());
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
#else
|
||||
if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
|
||||
(BYTE*)p)) {
|
||||
la_dosmaperr(GetLastError());
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
#endif
|
||||
for (; p < ep; p++)
|
||||
*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
|
||||
|
||||
@@ -347,6 +379,17 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
|
||||
/* mkstemp */
|
||||
attr = FILE_ATTRIBUTE_NORMAL;
|
||||
}
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileAttributes = attr & 0xFFFF;
|
||||
createExParams.dwFileFlags = attr & 0xFFF00000;
|
||||
h = CreateFile2(ws,
|
||||
GENERIC_READ | GENERIC_WRITE | DELETE,
|
||||
0,/* Not share */
|
||||
CREATE_NEW,
|
||||
&createExParams);
|
||||
#else
|
||||
h = CreateFileW(ws,
|
||||
GENERIC_READ | GENERIC_WRITE | DELETE,
|
||||
0,/* Not share */
|
||||
@@ -354,6 +397,7 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
|
||||
CREATE_NEW,/* Create a new file only */
|
||||
attr,
|
||||
NULL);
|
||||
#endif
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
/* The same file already exists. retry with
|
||||
* a new filename. */
|
||||
@@ -372,8 +416,13 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
|
||||
break;/* success! */
|
||||
}
|
||||
exit_tmpfile:
|
||||
#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
if (hAlg != NULL)
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
#else
|
||||
if (hProv != (HCRYPTPROV)NULL)
|
||||
CryptReleaseContext(hProv, 0);
|
||||
#endif
|
||||
free(ws);
|
||||
if (template == temp_name.s)
|
||||
archive_wstring_free(&temp_name);
|
||||
|
||||
@@ -234,7 +234,11 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
|
||||
{
|
||||
wchar_t *wpath;
|
||||
HANDLE handle;
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
#endif
|
||||
|
||||
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
|
||||
handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
|
||||
lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
|
||||
hTemplateFile);
|
||||
@@ -242,12 +246,25 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
|
||||
return (handle);
|
||||
if (GetLastError() != ERROR_PATH_NOT_FOUND)
|
||||
return (handle);
|
||||
#endif
|
||||
wpath = __la_win_permissive_name(path);
|
||||
if (wpath == NULL)
|
||||
return (handle);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF;
|
||||
createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000;
|
||||
createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F00000;
|
||||
createExParams.lpSecurityAttributes = lpSecurityAttributes;
|
||||
createExParams.hTemplateFile = hTemplateFile;
|
||||
handle = CreateFile2(wpath, dwDesiredAccess, dwShareMode,
|
||||
dwCreationDisposition, &createExParams);
|
||||
#else /* !WINAPI_PARTITION_DESKTOP */
|
||||
handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
|
||||
lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
|
||||
hTemplateFile);
|
||||
#endif /* !WINAPI_PARTITION_DESKTOP */
|
||||
free(wpath);
|
||||
return (handle);
|
||||
}
|
||||
@@ -305,7 +322,10 @@ __la_open(const char *path, int flags, ...)
|
||||
* "Permission denied" error.
|
||||
*/
|
||||
attr = GetFileAttributesA(path);
|
||||
if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
|
||||
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
|
||||
if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND)
|
||||
#endif
|
||||
{
|
||||
ws = __la_win_permissive_name(path);
|
||||
if (ws == NULL) {
|
||||
errno = EINVAL;
|
||||
@@ -320,7 +340,7 @@ __la_open(const char *path, int flags, ...)
|
||||
}
|
||||
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
HANDLE handle;
|
||||
|
||||
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
|
||||
if (ws != NULL)
|
||||
handle = CreateFileW(ws, 0, 0, NULL,
|
||||
OPEN_EXISTING,
|
||||
@@ -333,6 +353,15 @@ __la_open(const char *path, int flags, ...)
|
||||
FILE_FLAG_BACKUP_SEMANTICS |
|
||||
FILE_ATTRIBUTE_READONLY,
|
||||
NULL);
|
||||
#else /* !WINAPI_PARTITION_DESKTOP */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
|
||||
createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
handle = CreateFile2(ws, 0, 0,
|
||||
OPEN_EXISTING, &createExParams);
|
||||
#endif /* !WINAPI_PARTITION_DESKTOP */
|
||||
free(ws);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
|
||||
@@ -310,6 +310,25 @@ __archive_write_output(struct archive_write *a, const void *buff, size_t length)
|
||||
return (__archive_write_filter(a->filter_first, buff, length));
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_write_filters_flush(struct archive_write *a)
|
||||
{
|
||||
struct archive_write_filter *f;
|
||||
int ret, ret1;
|
||||
|
||||
ret = ARCHIVE_OK;
|
||||
for (f = a->filter_first; f != NULL; f = f->next_filter) {
|
||||
if (f->flush != NULL && f->bytes_written > 0) {
|
||||
ret1 = (f->flush)(f);
|
||||
if (ret1 < ret)
|
||||
ret = ret1;
|
||||
if (ret1 < ARCHIVE_WARN)
|
||||
f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
__archive_write_nulls(struct archive_write *a, size_t length)
|
||||
{
|
||||
@@ -740,6 +759,18 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
/* Flush filters at boundary. */
|
||||
r2 = __archive_write_filters_flush(a);
|
||||
if (r2 == ARCHIVE_FAILED) {
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (r2 == ARCHIVE_FATAL) {
|
||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (r2 < ret)
|
||||
ret = r2;
|
||||
|
||||
/* Format and write header. */
|
||||
r2 = ((a->format_write_header)(a, entry));
|
||||
if (r2 == ARCHIVE_FAILED) {
|
||||
|
||||
@@ -190,7 +190,7 @@ archive_compressor_bzip2_open(struct archive_write_filter *f)
|
||||
|
||||
memset(&data->stream, 0, sizeof(data->stream));
|
||||
data->stream.next_out = data->compressed;
|
||||
data->stream.avail_out = data->compressed_buffer_size;
|
||||
data->stream.avail_out = (uint32_t)data->compressed_buffer_size;
|
||||
f->write = archive_compressor_bzip2_write;
|
||||
|
||||
/* Initialize compression library */
|
||||
@@ -244,7 +244,7 @@ archive_compressor_bzip2_write(struct archive_write_filter *f,
|
||||
|
||||
/* Compress input data to output buffer */
|
||||
SET_NEXT_IN(data, buff);
|
||||
data->stream.avail_in = length;
|
||||
data->stream.avail_in = (uint32_t)length;
|
||||
if (drive_compressor(f, data, 0))
|
||||
return (ARCHIVE_FATAL);
|
||||
return (ARCHIVE_OK);
|
||||
@@ -313,7 +313,7 @@ drive_compressor(struct archive_write_filter *f,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
data->stream.next_out = data->compressed;
|
||||
data->stream.avail_out = data->compressed_buffer_size;
|
||||
data->stream.avail_out = (uint32_t)data->compressed_buffer_size;
|
||||
}
|
||||
|
||||
/* If there's nothing to do, we're done. */
|
||||
|
||||
@@ -352,7 +352,7 @@ archive_compressor_compress_write(struct archive_write_filter *f,
|
||||
while (length--) {
|
||||
c = *bp++;
|
||||
state->in_count++;
|
||||
state->cur_fcode = (c << 16) + state->cur_code;
|
||||
state->cur_fcode = (c << 16) | state->cur_code;
|
||||
i = ((c << HSHIFT) ^ state->cur_code); /* Xor hashing. */
|
||||
|
||||
if (state->hashtab[i] == state->cur_fcode) {
|
||||
|
||||
@@ -518,10 +518,10 @@ drive_compressor_independence(struct archive_write_filter *f, const char *p,
|
||||
} else {
|
||||
/* The buffer is not compressed. The compressed size was
|
||||
* bigger than its uncompressed size. */
|
||||
archive_le32enc(data->out, length | 0x80000000);
|
||||
archive_le32enc(data->out, (uint32_t)(length | 0x80000000));
|
||||
data->out += 4;
|
||||
memcpy(data->out, p, length);
|
||||
outsize = length;
|
||||
outsize = (uint32_t)length;
|
||||
}
|
||||
data->out += outsize;
|
||||
if (data->block_checksum) {
|
||||
@@ -603,10 +603,10 @@ drive_compressor_dependence(struct archive_write_filter *f, const char *p,
|
||||
} else {
|
||||
/* The buffer is not compressed. The compressed size was
|
||||
* bigger than its uncompressed size. */
|
||||
archive_le32enc(data->out, length | 0x80000000);
|
||||
archive_le32enc(data->out, (uint32_t)(length | 0x80000000));
|
||||
data->out += 4;
|
||||
memcpy(data->out, p, length);
|
||||
outsize = length;
|
||||
outsize = (uint32_t)length;
|
||||
}
|
||||
data->out += outsize;
|
||||
if (data->block_checksum) {
|
||||
|
||||
@@ -31,6 +31,9 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
@@ -50,10 +53,22 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
struct private_data {
|
||||
int compression_level;
|
||||
int threads;
|
||||
int threads;
|
||||
int long_distance;
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
|
||||
enum {
|
||||
running,
|
||||
finishing,
|
||||
resetting,
|
||||
} state;
|
||||
int frame_per_file;
|
||||
size_t min_frame_size;
|
||||
size_t max_frame_size;
|
||||
size_t cur_frame;
|
||||
size_t cur_frame_in;
|
||||
size_t cur_frame_out;
|
||||
size_t total_in;
|
||||
ZSTD_CStream *cstream;
|
||||
int64_t total_in;
|
||||
ZSTD_outBuffer out;
|
||||
#else
|
||||
struct archive_write_program_data *pdata;
|
||||
@@ -67,14 +82,18 @@ struct private_data {
|
||||
#define CLEVEL_STD_MAX 19 /* without using --ultra */
|
||||
#define CLEVEL_MAX 22
|
||||
|
||||
#define LONG_STD 27
|
||||
|
||||
#define MINVER_NEGCLEVEL 10304
|
||||
#define MINVER_MINCLEVEL 10306
|
||||
#define MINVER_LONG 10302
|
||||
|
||||
static int archive_compressor_zstd_options(struct archive_write_filter *,
|
||||
const char *, const char *);
|
||||
static int archive_compressor_zstd_open(struct archive_write_filter *);
|
||||
static int archive_compressor_zstd_write(struct archive_write_filter *,
|
||||
const void *, size_t);
|
||||
static int archive_compressor_zstd_flush(struct archive_write_filter *);
|
||||
static int archive_compressor_zstd_close(struct archive_write_filter *);
|
||||
static int archive_compressor_zstd_free(struct archive_write_filter *);
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
|
||||
@@ -103,13 +122,20 @@ archive_write_add_filter_zstd(struct archive *_a)
|
||||
f->data = data;
|
||||
f->open = &archive_compressor_zstd_open;
|
||||
f->options = &archive_compressor_zstd_options;
|
||||
f->flush = &archive_compressor_zstd_flush;
|
||||
f->close = &archive_compressor_zstd_close;
|
||||
f->free = &archive_compressor_zstd_free;
|
||||
f->code = ARCHIVE_FILTER_ZSTD;
|
||||
f->name = "zstd";
|
||||
data->compression_level = CLEVEL_DEFAULT;
|
||||
data->threads = 0;
|
||||
data->long_distance = 0;
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
|
||||
data->frame_per_file = 0;
|
||||
data->min_frame_size = 0;
|
||||
data->max_frame_size = SIZE_MAX;
|
||||
data->cur_frame_in = 0;
|
||||
data->cur_frame_out = 0;
|
||||
data->cstream = ZSTD_createCStream();
|
||||
if (data->cstream == NULL) {
|
||||
free(data);
|
||||
@@ -147,29 +173,18 @@ archive_compressor_zstd_free(struct archive_write_filter *f)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int string_is_numeric (const char* value)
|
||||
static int string_to_number(const char *string, intmax_t *numberp)
|
||||
{
|
||||
size_t len = strlen(value);
|
||||
size_t i;
|
||||
char *end;
|
||||
|
||||
if (len == 0) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
else if (len == 1 && !(value[0] >= '0' && value[0] <= '9')) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
else if (!(value[0] >= '0' && value[0] <= '9') &&
|
||||
value[0] != '-' && value[0] != '+') {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
for (i = 1; i < len; i++) {
|
||||
if (!(value[i] >= '0' && value[i] <= '9')) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
if (string == NULL || *string == '\0')
|
||||
return (ARCHIVE_WARN);
|
||||
*numberp = strtoimax(string, &end, 10);
|
||||
if (end == string || *end != '\0' || errno == EOVERFLOW) {
|
||||
*numberp = 0;
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -182,13 +197,13 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
|
||||
if (strcmp(key, "compression-level") == 0) {
|
||||
int level = atoi(value);
|
||||
intmax_t level;
|
||||
if (string_to_number(value, &level) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
/* If we don't have the library, hard-code the max level */
|
||||
int minimum = CLEVEL_MIN;
|
||||
int maximum = CLEVEL_MAX;
|
||||
if (string_is_numeric(value) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
|
||||
maximum = ZSTD_maxCLevel();
|
||||
#if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL
|
||||
@@ -204,21 +219,65 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
|
||||
if (level < minimum || level > maximum) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
data->compression_level = level;
|
||||
data->compression_level = (int)level;
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "threads") == 0) {
|
||||
int threads = atoi(value);
|
||||
if (string_is_numeric(value) != ARCHIVE_OK) {
|
||||
intmax_t threads;
|
||||
if (string_to_number(value, &threads) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
int minimum = 0;
|
||||
|
||||
if (threads < minimum) {
|
||||
if (threads < 0) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
data->threads = threads;
|
||||
data->threads = (int)threads;
|
||||
return (ARCHIVE_OK);
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
|
||||
} else if (strcmp(key, "frame-per-file") == 0) {
|
||||
data->frame_per_file = 1;
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "min-frame-size") == 0) {
|
||||
intmax_t min_frame_size;
|
||||
if (string_to_number(value, &min_frame_size) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
if (min_frame_size < 0) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
data->min_frame_size = min_frame_size;
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "max-frame-size") == 0) {
|
||||
intmax_t max_frame_size;
|
||||
if (string_to_number(value, &max_frame_size) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
if (max_frame_size < 1024) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
data->max_frame_size = max_frame_size;
|
||||
return (ARCHIVE_OK);
|
||||
#endif
|
||||
}
|
||||
else if (strcmp(key, "long") == 0) {
|
||||
intmax_t long_distance;
|
||||
if (string_to_number(value, &long_distance) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR && ZSTD_VERSION_NUMBER >= MINVER_LONG
|
||||
ZSTD_bounds bounds = ZSTD_cParam_getBounds(ZSTD_c_windowLog);
|
||||
if (ZSTD_isError(bounds.error)) {
|
||||
int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
|
||||
if (((int)long_distance) < 10 || (int)long_distance > max_distance)
|
||||
return (ARCHIVE_WARN);
|
||||
} else {
|
||||
if ((int)long_distance < bounds.lowerBound || (int)long_distance > bounds.upperBound)
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
#else
|
||||
int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
|
||||
if (((int)long_distance) < 10 || (int)long_distance > max_distance)
|
||||
return (ARCHIVE_WARN);
|
||||
#endif
|
||||
data->long_distance = (int)long_distance;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@@ -270,6 +329,10 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
|
||||
|
||||
ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads);
|
||||
|
||||
#if ZSTD_VERSION_NUMBER >= MINVER_LONG
|
||||
ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_windowLog, data->long_distance);
|
||||
#endif
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@@ -281,15 +344,22 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
|
||||
size_t length)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
int ret;
|
||||
|
||||
/* Update statistics */
|
||||
data->total_in += length;
|
||||
return (drive_compressor(f, data, 0, buff, length));
|
||||
}
|
||||
|
||||
if ((ret = drive_compressor(f, data, 0, buff, length)) != ARCHIVE_OK)
|
||||
return (ret);
|
||||
/*
|
||||
* Flush the compressed stream.
|
||||
*/
|
||||
static int
|
||||
archive_compressor_zstd_flush(struct archive_write_filter *f)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
if (data->frame_per_file && data->state == running &&
|
||||
data->cur_frame_out > data->min_frame_size)
|
||||
data->state = finishing;
|
||||
return (drive_compressor(f, data, 1, NULL, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -300,57 +370,72 @@ archive_compressor_zstd_close(struct archive_write_filter *f)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
|
||||
/* Finish zstd frame */
|
||||
return drive_compressor(f, data, 1, NULL, 0);
|
||||
if (data->state == running)
|
||||
data->state = finishing;
|
||||
return (drive_compressor(f, data, 1, NULL, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function to push input data through compressor,
|
||||
* writing full output blocks as necessary.
|
||||
*
|
||||
* Note that this handles both the regular write case (finishing ==
|
||||
* false) and the end-of-archive case (finishing == true).
|
||||
*/
|
||||
static int
|
||||
drive_compressor(struct archive_write_filter *f,
|
||||
struct private_data *data, int finishing, const void *src, size_t length)
|
||||
struct private_data *data, int flush, const void *src, size_t length)
|
||||
{
|
||||
ZSTD_inBuffer in = (ZSTD_inBuffer) { src, length, 0 };
|
||||
ZSTD_inBuffer in = { .src = src, .size = length, .pos = 0 };
|
||||
size_t ipos, opos, zstdret = 0;
|
||||
int ret;
|
||||
|
||||
for (;;) {
|
||||
if (data->out.pos == data->out.size) {
|
||||
const int ret = __archive_write_filter(f->next_filter,
|
||||
data->out.dst, data->out.size);
|
||||
ipos = in.pos;
|
||||
opos = data->out.pos;
|
||||
switch (data->state) {
|
||||
case running:
|
||||
if (in.pos == in.size)
|
||||
return (ARCHIVE_OK);
|
||||
zstdret = ZSTD_compressStream(data->cstream,
|
||||
&data->out, &in);
|
||||
if (ZSTD_isError(zstdret))
|
||||
goto zstd_fatal;
|
||||
break;
|
||||
case finishing:
|
||||
zstdret = ZSTD_endStream(data->cstream, &data->out);
|
||||
if (ZSTD_isError(zstdret))
|
||||
goto zstd_fatal;
|
||||
if (zstdret == 0)
|
||||
data->state = resetting;
|
||||
break;
|
||||
case resetting:
|
||||
ZSTD_CCtx_reset(data->cstream, ZSTD_reset_session_only);
|
||||
data->cur_frame++;
|
||||
data->cur_frame_in = 0;
|
||||
data->cur_frame_out = 0;
|
||||
data->state = running;
|
||||
break;
|
||||
}
|
||||
data->total_in += in.pos - ipos;
|
||||
data->cur_frame_in += in.pos - ipos;
|
||||
data->cur_frame_out += data->out.pos - opos;
|
||||
if (data->state == running &&
|
||||
data->cur_frame_in >= data->max_frame_size) {
|
||||
data->state = finishing;
|
||||
}
|
||||
if (data->out.pos == data->out.size ||
|
||||
(flush && data->out.pos > 0)) {
|
||||
ret = __archive_write_filter(f->next_filter,
|
||||
data->out.dst, data->out.pos);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
goto fatal;
|
||||
data->out.pos = 0;
|
||||
}
|
||||
|
||||
/* If there's nothing to do, we're done. */
|
||||
if (!finishing && in.pos == in.size)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
{
|
||||
const size_t zstdret = !finishing ?
|
||||
ZSTD_compressStream(data->cstream, &data->out, &in)
|
||||
: ZSTD_endStream(data->cstream, &data->out);
|
||||
|
||||
if (ZSTD_isError(zstdret)) {
|
||||
archive_set_error(f->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Zstd compression failed: %s",
|
||||
ZSTD_getErrorName(zstdret));
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* If we're finishing, 0 means nothing left to flush */
|
||||
if (finishing && zstdret == 0) {
|
||||
const int ret = __archive_write_filter(f->next_filter,
|
||||
data->out.dst, data->out.pos);
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
zstd_fatal:
|
||||
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Zstd compression failed: %s",
|
||||
ZSTD_getErrorName(zstdret));
|
||||
fatal:
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
#else /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */
|
||||
@@ -367,17 +452,9 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
|
||||
archive_strcpy(&as, "zstd --no-check");
|
||||
|
||||
if (data->compression_level < CLEVEL_STD_MIN) {
|
||||
struct archive_string as2;
|
||||
archive_string_init(&as2);
|
||||
archive_string_sprintf(&as2, " --fast=%d", -data->compression_level);
|
||||
archive_string_concat(&as, &as2);
|
||||
archive_string_free(&as2);
|
||||
archive_string_sprintf(&as, " --fast=%d", -data->compression_level);
|
||||
} else {
|
||||
struct archive_string as2;
|
||||
archive_string_init(&as2);
|
||||
archive_string_sprintf(&as2, " -%d", data->compression_level);
|
||||
archive_string_concat(&as, &as2);
|
||||
archive_string_free(&as2);
|
||||
archive_string_sprintf(&as, " -%d", data->compression_level);
|
||||
}
|
||||
|
||||
if (data->compression_level > CLEVEL_STD_MAX) {
|
||||
@@ -385,11 +462,11 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
|
||||
}
|
||||
|
||||
if (data->threads != 0) {
|
||||
struct archive_string as2;
|
||||
archive_string_init(&as2);
|
||||
archive_string_sprintf(&as2, " --threads=%d", data->threads);
|
||||
archive_string_concat(&as, &as2);
|
||||
archive_string_free(&as2);
|
||||
archive_string_sprintf(&as, " --threads=%d", data->threads);
|
||||
}
|
||||
|
||||
if (data->long_distance != 0) {
|
||||
archive_string_sprintf(&as, " --long=%d", data->long_distance);
|
||||
}
|
||||
|
||||
f->write = archive_compressor_zstd_write;
|
||||
@@ -407,6 +484,14 @@ archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
|
||||
return __archive_write_program_write(f, data->pdata, buff, length);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_compressor_zstd_flush(struct archive_write_filter *f)
|
||||
{
|
||||
(void)f; /* UNUSED */
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_compressor_zstd_close(struct archive_write_filter *f)
|
||||
{
|
||||
|
||||
@@ -397,6 +397,7 @@ static int set_times_from_entry(struct archive_write_disk *);
|
||||
static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
|
||||
static ssize_t write_data_block(struct archive_write_disk *,
|
||||
const char *, size_t);
|
||||
static void close_file_descriptor(struct archive_write_disk *);
|
||||
|
||||
static int _archive_write_disk_close(struct archive *);
|
||||
static int _archive_write_disk_free(struct archive *);
|
||||
@@ -514,7 +515,12 @@ lazy_stat(struct archive_write_disk *a)
|
||||
* XXX At this point, symlinks should not be hit, otherwise
|
||||
* XXX a race occurred. Do we want to check explicitly for that?
|
||||
*/
|
||||
if (lstat(a->name, &a->st) == 0) {
|
||||
#ifdef HAVE_LSTAT
|
||||
if (lstat(a->name, &a->st) == 0)
|
||||
#else
|
||||
if (la_stat(a->name, &a->st) == 0)
|
||||
#endif
|
||||
{
|
||||
a->pst = &a->st;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
@@ -1605,12 +1611,12 @@ hfs_write_data_block(struct archive_write_disk *a, const char *buff,
|
||||
"Seek failed");
|
||||
return (ARCHIVE_FATAL);
|
||||
} else if (a->offset > a->fd_offset) {
|
||||
int64_t skip = a->offset - a->fd_offset;
|
||||
uint64_t skip = a->offset - a->fd_offset;
|
||||
char nullblock[1024];
|
||||
|
||||
memset(nullblock, 0, sizeof(nullblock));
|
||||
while (skip > 0) {
|
||||
if (skip > (int64_t)sizeof(nullblock))
|
||||
if (skip > sizeof(nullblock))
|
||||
bytes_written = hfs_write_decmpfs_block(
|
||||
a, nullblock, sizeof(nullblock));
|
||||
else
|
||||
@@ -1725,8 +1731,10 @@ _archive_write_disk_finish_entry(struct archive *_a)
|
||||
else
|
||||
r = hfs_write_data_block(
|
||||
a, null_d, a->file_remaining_bytes);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
close_file_descriptor(a);
|
||||
return ((int)r);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
@@ -1735,6 +1743,7 @@ _archive_write_disk_finish_entry(struct archive *_a)
|
||||
a->filesize == 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"File size could not be restored");
|
||||
close_file_descriptor(a);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif
|
||||
@@ -1744,8 +1753,10 @@ _archive_write_disk_finish_entry(struct archive *_a)
|
||||
* to see what happened.
|
||||
*/
|
||||
a->pst = NULL;
|
||||
if ((ret = lazy_stat(a)) != ARCHIVE_OK)
|
||||
return (ret);
|
||||
if ((ret = lazy_stat(a)) != ARCHIVE_OK) {
|
||||
close_file_descriptor(a);
|
||||
return (ret);
|
||||
}
|
||||
/* We can use lseek()/write() to extend the file if
|
||||
* ftruncate didn't work or isn't available. */
|
||||
if (a->st.st_size < a->filesize) {
|
||||
@@ -1753,11 +1764,13 @@ _archive_write_disk_finish_entry(struct archive *_a)
|
||||
if (lseek(a->fd, a->filesize - 1, SEEK_SET) < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Seek failed");
|
||||
close_file_descriptor(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (write(a->fd, &nul, 1) < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Write to restore size failed");
|
||||
close_file_descriptor(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
a->pst = NULL;
|
||||
@@ -2154,7 +2167,11 @@ restore_entry(struct archive_write_disk *a)
|
||||
* then don't follow it.
|
||||
*/
|
||||
if (r != 0 || !S_ISDIR(a->mode))
|
||||
#ifdef HAVE_LSTAT
|
||||
r = lstat(a->name, &a->st);
|
||||
#else
|
||||
r = la_stat(a->name, &a->st);
|
||||
#endif
|
||||
if (r != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Can't stat existing object");
|
||||
@@ -2550,7 +2567,12 @@ _archive_write_disk_close(struct archive *_a)
|
||||
goto skip_fixup_entry;
|
||||
} else
|
||||
#endif
|
||||
if (lstat(p->name, &st) != 0 ||
|
||||
if (
|
||||
#ifdef HAVE_LSTAT
|
||||
lstat(p->name, &st) != 0 ||
|
||||
#else
|
||||
la_stat(p->name, &st) != 0 ||
|
||||
#endif
|
||||
la_verify_filetype(st.st_mode,
|
||||
p->filetype) == 0) {
|
||||
goto skip_fixup_entry;
|
||||
@@ -2565,7 +2587,12 @@ _archive_write_disk_close(struct archive *_a)
|
||||
goto skip_fixup_entry;
|
||||
} else
|
||||
#endif
|
||||
if (lstat(p->name, &st) != 0 ||
|
||||
if (
|
||||
#ifdef HAVE_LSTAT
|
||||
lstat(p->name, &st) != 0 ||
|
||||
#else
|
||||
la_stat(p->name, &st) != 0 ||
|
||||
#endif
|
||||
la_verify_filetype(st.st_mode,
|
||||
p->filetype) == 0) {
|
||||
goto skip_fixup_entry;
|
||||
@@ -2785,8 +2812,8 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
|
||||
!(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT))
|
||||
/* Platform doesn't have lstat, so we can't look for symlinks. */
|
||||
(void)path; /* UNUSED */
|
||||
(void)error_number; /* UNUSED */
|
||||
(void)error_string; /* UNUSED */
|
||||
(void)a_eno; /* UNUSED */
|
||||
(void)a_estr; /* UNUSED */
|
||||
(void)flags; /* UNUSED */
|
||||
(void)checking_linkname; /* UNUSED */
|
||||
return (ARCHIVE_OK);
|
||||
@@ -2859,8 +2886,10 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
|
||||
/* Check that we haven't hit a symlink. */
|
||||
#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
|
||||
r = fstatat(chdir_fd, head, &st, AT_SYMLINK_NOFOLLOW);
|
||||
#else
|
||||
#elif defined(HAVE_LSTAT)
|
||||
r = lstat(head, &st);
|
||||
#else
|
||||
r = la_stat(head, &st);
|
||||
#endif
|
||||
if (r != 0) {
|
||||
tail[0] = c;
|
||||
@@ -3558,7 +3587,9 @@ set_time(int fd, int mode, const char *name,
|
||||
(void)fd; /* UNUSED */
|
||||
(void)mode; /* UNUSED */
|
||||
(void)name; /* UNUSED */
|
||||
(void)atime; /* UNUSED */
|
||||
(void)atime_nsec; /* UNUSED */
|
||||
(void)mtime; /* UNUSED */
|
||||
(void)mtime_nsec; /* UNUSED */
|
||||
return (ARCHIVE_WARN);
|
||||
#endif
|
||||
@@ -4391,7 +4422,12 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname)
|
||||
*/
|
||||
archive_strncpy(&datafork, pathname, p - pathname);
|
||||
archive_strcat(&datafork, p + 2);
|
||||
if (lstat(datafork.s, &st) == -1 ||
|
||||
if (
|
||||
#ifdef HAVE_LSTAT
|
||||
lstat(datafork.s, &st) == -1 ||
|
||||
#else
|
||||
la_stat(datafork.s, &st) == -1 ||
|
||||
#endif
|
||||
(st.st_mode & AE_IFMT) != AE_IFREG)
|
||||
goto skip_appledouble;
|
||||
|
||||
@@ -4707,5 +4743,17 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Close the file descriptor if one is open.
|
||||
*/
|
||||
static void close_file_descriptor(struct archive_write_disk* a)
|
||||
{
|
||||
if (a->fd >= 0) {
|
||||
close(a->fd);
|
||||
a->fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* !_WIN32 || __CYGWIN__ */
|
||||
|
||||
|
||||
@@ -254,9 +254,9 @@ static ssize_t _archive_write_disk_data_block(struct archive *, const void *,
|
||||
* which is high-16-bits of nFileIndexHigh. */
|
||||
#define bhfi_ino(bhfi) \
|
||||
((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
|
||||
+ (bhfi)->nFileIndexLow)
|
||||
| (bhfi)->nFileIndexLow)
|
||||
#define bhfi_size(bhfi) \
|
||||
((((int64_t)(bhfi)->nFileSizeHigh) << 32) + (bhfi)->nFileSizeLow)
|
||||
((((int64_t)(bhfi)->nFileSizeHigh) << 32) | (bhfi)->nFileSizeLow)
|
||||
|
||||
static int
|
||||
file_information(struct archive_write_disk *a, wchar_t *path,
|
||||
@@ -266,6 +266,9 @@ file_information(struct archive_write_disk *a, wchar_t *path,
|
||||
int r;
|
||||
DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
WIN32_FIND_DATAW findData;
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
#endif
|
||||
|
||||
if (sim_lstat || mode != NULL) {
|
||||
h = FindFirstFileW(path, &findData);
|
||||
@@ -290,14 +293,27 @@ file_information(struct archive_write_disk *a, wchar_t *path,
|
||||
(findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
|
||||
flag |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileFlags = flag;
|
||||
h = CreateFile2(a->name, 0, 0,
|
||||
OPEN_EXISTING, &createExParams);
|
||||
#else
|
||||
h = CreateFileW(a->name, 0, 0, NULL,
|
||||
OPEN_EXISTING, flag, NULL);
|
||||
#endif
|
||||
if (h == INVALID_HANDLE_VALUE &&
|
||||
GetLastError() == ERROR_INVALID_NAME) {
|
||||
wchar_t *full;
|
||||
full = __la_win_permissive_name_w(path);
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
h = CreateFile2(full, 0, 0,
|
||||
OPEN_EXISTING, &createExParams);
|
||||
#else
|
||||
h = CreateFileW(full, 0, 0, NULL,
|
||||
OPEN_EXISTING, flag, NULL);
|
||||
#endif
|
||||
free(full);
|
||||
}
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
@@ -559,6 +575,7 @@ la_mktemp(struct archive_write_disk *a)
|
||||
return (fd);
|
||||
}
|
||||
|
||||
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
|
||||
static void *
|
||||
la_GetFunctionKernel32(const char *name)
|
||||
{
|
||||
@@ -574,18 +591,24 @@ la_GetFunctionKernel32(const char *name)
|
||||
}
|
||||
return (void *)GetProcAddress(lib, name);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
|
||||
{
|
||||
static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
|
||||
static int set;
|
||||
static BOOL (WINAPI *f)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
|
||||
BOOL ret;
|
||||
|
||||
#if _WIN32_WINNT < _WIN32_WINNT_XP
|
||||
static int set;
|
||||
/* CreateHardLinkW is available since XP and always loaded */
|
||||
if (!set) {
|
||||
set = 1;
|
||||
f = la_GetFunctionKernel32("CreateHardLinkW");
|
||||
}
|
||||
#else
|
||||
f = CreateHardLinkW;
|
||||
#endif
|
||||
if (!f) {
|
||||
errno = ENOTSUP;
|
||||
return (0);
|
||||
@@ -624,7 +647,6 @@ static int
|
||||
la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
|
||||
int linktype) {
|
||||
static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD);
|
||||
static int set;
|
||||
wchar_t *ttarget, *p;
|
||||
size_t len;
|
||||
DWORD attrs = 0;
|
||||
@@ -632,10 +654,20 @@ la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
|
||||
DWORD newflags = 0;
|
||||
BOOL ret = 0;
|
||||
|
||||
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
|
||||
/* CreateSymbolicLinkW is available since Vista and always loaded */
|
||||
static int set;
|
||||
if (!set) {
|
||||
set = 1;
|
||||
f = la_GetFunctionKernel32("CreateSymbolicLinkW");
|
||||
}
|
||||
#else
|
||||
# if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
f = CreateSymbolicLinkW;
|
||||
# else
|
||||
f = NULL;
|
||||
# endif
|
||||
#endif
|
||||
if (!f)
|
||||
return (0);
|
||||
|
||||
@@ -1185,6 +1217,8 @@ _archive_write_disk_finish_entry(struct archive *_a)
|
||||
if (la_ftruncate(a->fh, a->filesize) == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"File size could not be restored");
|
||||
CloseHandle(a->fh);
|
||||
a->fh = INVALID_HANDLE_VALUE;
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
}
|
||||
@@ -1656,6 +1690,9 @@ create_filesystem_object(struct archive_write_disk *a)
|
||||
mode_t final_mode, mode;
|
||||
int r;
|
||||
DWORD attrs = 0;
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
#endif
|
||||
|
||||
/* We identify hard/symlinks according to the link names. */
|
||||
/* Since link(2) and symlink(2) don't handle modes, we're done here. */
|
||||
@@ -1719,8 +1756,16 @@ create_filesystem_object(struct archive_write_disk *a)
|
||||
a->todo = 0;
|
||||
a->deferred = 0;
|
||||
} else if (r == 0 && a->filesize > 0) {
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||
a->fh = CreateFile2(namefull, GENERIC_WRITE, 0,
|
||||
TRUNCATE_EXISTING, &createExParams);
|
||||
#else
|
||||
a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
|
||||
TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#endif
|
||||
if (a->fh == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
r = errno;
|
||||
@@ -1783,14 +1828,27 @@ create_filesystem_object(struct archive_write_disk *a)
|
||||
a->tmpname = NULL;
|
||||
fullname = a->name;
|
||||
/* O_WRONLY | O_CREAT | O_EXCL */
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||
a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
|
||||
CREATE_NEW, &createExParams);
|
||||
#else
|
||||
a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
|
||||
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#endif
|
||||
if (a->fh == INVALID_HANDLE_VALUE &&
|
||||
GetLastError() == ERROR_INVALID_NAME &&
|
||||
fullname == a->name) {
|
||||
fullname = __la_win_permissive_name_w(a->name);
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
a->fh = CreateFile2(fullname, GENERIC_WRITE, 0,
|
||||
CREATE_NEW, &createExParams);
|
||||
#else
|
||||
a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
|
||||
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#endif
|
||||
}
|
||||
if (a->fh == INVALID_HANDLE_VALUE) {
|
||||
if (GetLastError() == ERROR_ACCESS_DENIED) {
|
||||
@@ -2551,14 +2609,25 @@ set_times(struct archive_write_disk *a,
|
||||
hw = NULL;
|
||||
} else {
|
||||
wchar_t *ws;
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
CREATEFILE2_EXTENDED_PARAMETERS createExParams;
|
||||
#endif
|
||||
|
||||
if (S_ISLNK(mode))
|
||||
return (ARCHIVE_OK);
|
||||
ws = __la_win_permissive_name_w(name);
|
||||
if (ws == NULL)
|
||||
goto settimes_failed;
|
||||
# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
|
||||
ZeroMemory(&createExParams, sizeof(createExParams));
|
||||
createExParams.dwSize = sizeof(createExParams);
|
||||
createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
hw = CreateFile2(ws, FILE_WRITE_ATTRIBUTES, 0,
|
||||
OPEN_EXISTING, &createExParams);
|
||||
#else
|
||||
hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
|
||||
0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
#endif
|
||||
free(ws);
|
||||
if (hw == INVALID_HANDLE_VALUE)
|
||||
goto settimes_failed;
|
||||
|
||||
@@ -53,6 +53,7 @@ struct archive_write_filter {
|
||||
const char *key, const char *value);
|
||||
int (*open)(struct archive_write_filter *);
|
||||
int (*write)(struct archive_write_filter *, const void *, size_t);
|
||||
int (*flush)(struct archive_write_filter *);
|
||||
int (*close)(struct archive_write_filter *);
|
||||
int (*free)(struct archive_write_filter *);
|
||||
void *data;
|
||||
|
||||
@@ -91,6 +91,26 @@ __FBSDID("$FreeBSD$");
|
||||
#define kAttributes 0x15
|
||||
#define kEncodedHeader 0x17
|
||||
|
||||
// Check that some windows file attribute constants are defined.
|
||||
// Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
|
||||
#ifndef FILE_ATTRIBUTE_READONLY
|
||||
#define FILE_ATTRIBUTE_READONLY 0x00000001
|
||||
#endif
|
||||
|
||||
#ifndef FILE_ATTRIBUTE_DIRECTORY
|
||||
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
||||
#endif
|
||||
|
||||
#ifndef FILE_ATTRIBUTE_ARCHIVE
|
||||
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
|
||||
#endif
|
||||
|
||||
// This value is defined in 7zip with the comment "trick for Unix".
|
||||
//
|
||||
// 7z archives created on unix have this bit set in the high 16 bits of
|
||||
// the attr field along with the unix permissions.
|
||||
#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000
|
||||
|
||||
enum la_zaction {
|
||||
ARCHIVE_Z_FINISH,
|
||||
ARCHIVE_Z_RUN
|
||||
@@ -165,7 +185,7 @@ struct file {
|
||||
mode_t mode;
|
||||
uint32_t crc32;
|
||||
|
||||
signed int dir:1;
|
||||
unsigned dir:1;
|
||||
};
|
||||
|
||||
struct _7zip {
|
||||
@@ -1424,14 +1444,19 @@ make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size,
|
||||
* High 16bits is unix mode.
|
||||
* Low 16bits is Windows attributes.
|
||||
*/
|
||||
uint32_t encattr, attr;
|
||||
uint32_t encattr, attr = 0;
|
||||
|
||||
if (file->dir)
|
||||
attr = 0x8010;
|
||||
attr |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
else
|
||||
attr = 0x8020;
|
||||
attr |= FILE_ATTRIBUTE_ARCHIVE;
|
||||
|
||||
if ((file->mode & 0222) == 0)
|
||||
attr |= 1;/* Read Only. */
|
||||
attr |= FILE_ATTRIBUTE_READONLY;
|
||||
|
||||
attr |= FILE_ATTRIBUTE_UNIX_EXTENSION;
|
||||
attr |= ((uint32_t)file->mode) << 16;
|
||||
|
||||
archive_le32enc(&encattr, attr);
|
||||
r = (int)compress_out(a, &encattr, 4, ARCHIVE_Z_RUN);
|
||||
if (r < 0)
|
||||
@@ -1809,11 +1834,11 @@ compression_init_encoder_bzip2(struct archive *a,
|
||||
* of ugly hackery to convert a const * pointer to
|
||||
* a non-const pointer. */
|
||||
strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
|
||||
strm->avail_in = lastrm->avail_in;
|
||||
strm->avail_in = (uint32_t)lastrm->avail_in;
|
||||
strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
|
||||
strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
|
||||
strm->next_out = (char *)lastrm->next_out;
|
||||
strm->avail_out = lastrm->avail_out;
|
||||
strm->avail_out = (uint32_t)lastrm->avail_out;
|
||||
strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
|
||||
strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
|
||||
if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
|
||||
@@ -1842,11 +1867,11 @@ compression_code_bzip2(struct archive *a,
|
||||
* of ugly hackery to convert a const * pointer to
|
||||
* a non-const pointer. */
|
||||
strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
|
||||
strm->avail_in = lastrm->avail_in;
|
||||
strm->avail_in = (uint32_t)lastrm->avail_in;
|
||||
strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
|
||||
strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
|
||||
strm->next_out = (char *)lastrm->next_out;
|
||||
strm->avail_out = lastrm->avail_out;
|
||||
strm->avail_out = (uint32_t)lastrm->avail_out;
|
||||
strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
|
||||
strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
|
||||
r = BZ2_bzCompress(strm,
|
||||
|
||||
@@ -293,12 +293,12 @@ struct isoent {
|
||||
struct extr_rec *current;
|
||||
} extr_rec_list;
|
||||
|
||||
signed int virtual:1;
|
||||
unsigned int virtual:1;
|
||||
/* If set to one, this file type is a directory.
|
||||
* A convenience flag to be used as
|
||||
* "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
|
||||
*/
|
||||
signed int dir:1;
|
||||
unsigned int dir:1;
|
||||
};
|
||||
|
||||
struct hardlink {
|
||||
@@ -656,7 +656,7 @@ struct iso_option {
|
||||
#define VOLUME_IDENTIFIER_SIZE 32
|
||||
|
||||
/*
|
||||
* Usage : !zisofs [DEFAULT]
|
||||
* Usage : !zisofs [DEFAULT]
|
||||
* : Disable to generate RRIP 'ZF' extension.
|
||||
* : zisofs
|
||||
* : Make files zisofs file and generate RRIP 'ZF'
|
||||
@@ -693,7 +693,7 @@ struct iso9660 {
|
||||
uint64_t bytes_remaining;
|
||||
int need_multi_extent;
|
||||
|
||||
/* Temporary string buffer for Joliet extension. */
|
||||
/* Temporary string buffer for Joliet extension. */
|
||||
struct archive_string utf16be;
|
||||
struct archive_string mbs;
|
||||
|
||||
@@ -759,9 +759,9 @@ struct iso9660 {
|
||||
|
||||
/* Used for making zisofs. */
|
||||
struct {
|
||||
signed int detect_magic:1;
|
||||
signed int making:1;
|
||||
signed int allzero:1;
|
||||
unsigned int detect_magic:1;
|
||||
unsigned int making:1;
|
||||
unsigned int allzero:1;
|
||||
unsigned char magic_buffer[64];
|
||||
int magic_cnt;
|
||||
|
||||
@@ -2525,12 +2525,11 @@ get_gmoffset(struct tm *tm)
|
||||
static void
|
||||
get_tmfromtime(struct tm *tm, time_t *t)
|
||||
{
|
||||
#if HAVE_LOCALTIME_R
|
||||
#if HAVE_LOCALTIME_S
|
||||
localtime_s(tm, t);
|
||||
#elif HAVE_LOCALTIME_R
|
||||
tzset();
|
||||
localtime_r(t, tm);
|
||||
#elif HAVE__LOCALTIME64_S
|
||||
__time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
|
||||
_localtime64_s(tm, &tmp_t);
|
||||
#else
|
||||
memcpy(tm, localtime(t), sizeof(*tm));
|
||||
#endif
|
||||
@@ -4078,11 +4077,8 @@ write_information_block(struct archive_write *a)
|
||||
}
|
||||
memset(info.s, 0, info_size);
|
||||
opt = 0;
|
||||
#if defined(HAVE__CTIME64_S)
|
||||
{
|
||||
__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
|
||||
_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
|
||||
}
|
||||
#if defined(HAVE_CTIME_S)
|
||||
ctime_s(buf, sizeof(buf), &(iso9660->birth_time));
|
||||
#elif defined(HAVE_CTIME_R)
|
||||
ctime_r(&(iso9660->birth_time), buf);
|
||||
#else
|
||||
@@ -7811,8 +7807,8 @@ struct zisofs_extract {
|
||||
uint64_t pz_uncompressed_size;
|
||||
size_t uncompressed_buffer_size;
|
||||
|
||||
signed int initialized:1;
|
||||
signed int header_passed:1;
|
||||
unsigned int initialized:1;
|
||||
unsigned int header_passed:1;
|
||||
|
||||
uint32_t pz_offset;
|
||||
unsigned char *block_pointers;
|
||||
|
||||
@@ -100,6 +100,7 @@ static int has_non_ASCII(const char *);
|
||||
static void sparse_list_clear(struct pax *);
|
||||
static int sparse_list_add(struct pax *, int64_t, int64_t);
|
||||
static char *url_encode(const char *in);
|
||||
static time_t get_ustar_max_mtime(void);
|
||||
|
||||
/*
|
||||
* Set output format to 'restricted pax' format.
|
||||
@@ -367,10 +368,12 @@ archive_write_pax_header_xattr(struct pax *pax, const char *encoded_name,
|
||||
struct archive_string s;
|
||||
char *encoded_value;
|
||||
|
||||
if (encoded_name == NULL)
|
||||
return;
|
||||
|
||||
if (pax->flags & WRITE_LIBARCHIVE_XATTR) {
|
||||
encoded_value = base64_encode((const char *)value, value_len);
|
||||
|
||||
if (encoded_name != NULL && encoded_value != NULL) {
|
||||
if (encoded_value != NULL) {
|
||||
archive_string_init(&s);
|
||||
archive_strcpy(&s, "LIBARCHIVE.xattr.");
|
||||
archive_strcat(&s, encoded_name);
|
||||
@@ -403,17 +406,22 @@ archive_write_pax_header_xattrs(struct archive_write *a,
|
||||
|
||||
archive_entry_xattr_next(entry, &name, &value, &size);
|
||||
url_encoded_name = url_encode(name);
|
||||
if (url_encoded_name != NULL) {
|
||||
if (url_encoded_name == NULL)
|
||||
goto malloc_error;
|
||||
else {
|
||||
/* Convert narrow-character to UTF-8. */
|
||||
r = archive_strcpy_l(&(pax->l_url_encoded_name),
|
||||
url_encoded_name, pax->sconv_utf8);
|
||||
free(url_encoded_name); /* Done with this. */
|
||||
if (r == 0)
|
||||
encoded_name = pax->l_url_encoded_name.s;
|
||||
else if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Linkname");
|
||||
return (ARCHIVE_FATAL);
|
||||
else if (r == -1)
|
||||
goto malloc_error;
|
||||
else {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Error encoding pax extended attribute");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,6 +430,9 @@ archive_write_pax_header_xattrs(struct archive_write *a,
|
||||
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
malloc_error:
|
||||
archive_set_error(&a->archive, ENOMEM, "Can't allocate memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -595,6 +606,8 @@ archive_write_pax_header(struct archive_write *a,
|
||||
need_extension = 0;
|
||||
pax = (struct pax *)a->format_data;
|
||||
|
||||
const time_t ustar_max_mtime = get_ustar_max_mtime();
|
||||
|
||||
/* Sanity check. */
|
||||
if (archive_entry_pathname(entry_original) == NULL) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
@@ -1116,16 +1129,13 @@ archive_write_pax_header(struct archive_write *a,
|
||||
}
|
||||
|
||||
/*
|
||||
* Technically, the mtime field in the ustar header can
|
||||
* support 33 bits, but many platforms use signed 32-bit time
|
||||
* values. The cutoff of 0x7fffffff here is a compromise.
|
||||
* Yes, this check is duplicated just below; this helps to
|
||||
* avoid writing an mtime attribute just to handle a
|
||||
* high-resolution timestamp in "restricted pax" mode.
|
||||
*/
|
||||
if (!need_extension &&
|
||||
((archive_entry_mtime(entry_main) < 0)
|
||||
|| (archive_entry_mtime(entry_main) >= 0x7fffffff)))
|
||||
|| (archive_entry_mtime(entry_main) >= ustar_max_mtime)))
|
||||
need_extension = 1;
|
||||
|
||||
/* I use a star-compatible file flag attribute. */
|
||||
@@ -1190,7 +1200,7 @@ archive_write_pax_header(struct archive_write *a,
|
||||
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
|
||||
need_extension) {
|
||||
if (archive_entry_mtime(entry_main) < 0 ||
|
||||
archive_entry_mtime(entry_main) >= 0x7fffffff ||
|
||||
archive_entry_mtime(entry_main) >= ustar_max_mtime ||
|
||||
archive_entry_mtime_nsec(entry_main) != 0)
|
||||
add_pax_attr_time(&(pax->pax_header), "mtime",
|
||||
archive_entry_mtime(entry_main),
|
||||
@@ -1428,7 +1438,7 @@ archive_write_pax_header(struct archive_write *a,
|
||||
/* Copy mtime, but clip to ustar limits. */
|
||||
s = archive_entry_mtime(entry_main);
|
||||
if (s < 0) { s = 0; }
|
||||
if (s >= 0x7fffffff) { s = 0x7fffffff; }
|
||||
if (s > ustar_max_mtime) { s = ustar_max_mtime; }
|
||||
archive_entry_set_mtime(pax_attr_entry, s, 0);
|
||||
|
||||
/* Standard ustar doesn't support atime. */
|
||||
@@ -1904,14 +1914,19 @@ url_encode(const char *in)
|
||||
{
|
||||
const char *s;
|
||||
char *d;
|
||||
int out_len = 0;
|
||||
size_t out_len = 0;
|
||||
char *out;
|
||||
|
||||
for (s = in; *s != '\0'; s++) {
|
||||
if (*s < 33 || *s > 126 || *s == '%' || *s == '=')
|
||||
if (*s < 33 || *s > 126 || *s == '%' || *s == '=') {
|
||||
if (SIZE_MAX - out_len < 4)
|
||||
return (NULL);
|
||||
out_len += 3;
|
||||
else
|
||||
} else {
|
||||
if (SIZE_MAX - out_len < 2)
|
||||
return (NULL);
|
||||
out_len++;
|
||||
}
|
||||
}
|
||||
|
||||
out = (char *)malloc(out_len + 1);
|
||||
@@ -2046,3 +2061,18 @@ sparse_list_add(struct pax *pax, int64_t offset, int64_t length)
|
||||
return (_sparse_list_add_block(pax, offset, length, 0));
|
||||
}
|
||||
|
||||
static time_t
|
||||
get_ustar_max_mtime(void)
|
||||
{
|
||||
/*
|
||||
* Technically, the mtime field in the ustar header can
|
||||
* support 33 bits. We are using all of them to keep
|
||||
* tar/test/test_option_C_mtree.c simple and passing after 2038.
|
||||
* For platforms that use signed 32-bit time values we
|
||||
* use the 32-bit maximum.
|
||||
*/
|
||||
if (sizeof(time_t) > sizeof(int32_t))
|
||||
return (time_t)0x1ffffffff;
|
||||
else
|
||||
return (time_t)0x7fffffff;
|
||||
}
|
||||
|
||||
@@ -329,30 +329,21 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t)
|
||||
{
|
||||
/** like strftime(3) but for time_t objects */
|
||||
struct tm *rt;
|
||||
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
|
||||
#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S)
|
||||
struct tm timeHere;
|
||||
#endif
|
||||
#if defined(HAVE__GMTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
char strtime[100];
|
||||
size_t len;
|
||||
|
||||
#ifdef HAVE_GMTIME_R
|
||||
if ((rt = gmtime_r(&t, &timeHere)) == NULL)
|
||||
return;
|
||||
#elif defined(HAVE__GMTIME64_S)
|
||||
tmptime = t;
|
||||
terr = _gmtime64_s(&timeHere, &tmptime);
|
||||
if (terr)
|
||||
rt = NULL;
|
||||
else
|
||||
rt = &timeHere;
|
||||
#if defined(HAVE_GMTIME_S)
|
||||
rt = gmtime_s(&timeHere, &t) ? NULL : &timeHere;
|
||||
#elif defined(HAVE_GMTIME_R)
|
||||
rt = gmtime_r(&t, &timeHere);
|
||||
#else
|
||||
if ((rt = gmtime(&t)) == NULL)
|
||||
return;
|
||||
rt = gmtime(&t);
|
||||
#endif
|
||||
if (!rt)
|
||||
return;
|
||||
/* leave the hard yacker to our role model strftime() */
|
||||
len = strftime(strtime, sizeof(strtime)-1, fmt, rt);
|
||||
archive_strncat(as, strtime, len);
|
||||
|
||||
@@ -212,8 +212,8 @@ struct file {
|
||||
struct heap_data data;
|
||||
struct archive_string script;
|
||||
|
||||
signed int virtual:1;
|
||||
signed int dir:1;
|
||||
unsigned int virtual:1;
|
||||
unsigned int dir:1;
|
||||
};
|
||||
|
||||
struct hardlink {
|
||||
@@ -906,15 +906,11 @@ xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
|
||||
{
|
||||
char timestr[100];
|
||||
struct tm tm;
|
||||
#if defined(HAVE__GMTIME64_S)
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GMTIME_R)
|
||||
#if defined(HAVE_GMTIME_S)
|
||||
gmtime_s(&tm, &t);
|
||||
#elif defined(HAVE_GMTIME_R)
|
||||
gmtime_r(&t, &tm);
|
||||
#elif defined(HAVE__GMTIME64_S)
|
||||
tmptime = t;
|
||||
_gmtime64_s(&tm, &tmptime);
|
||||
#else
|
||||
memcpy(&tm, gmtime(&t), sizeof(tm));
|
||||
#endif
|
||||
|
||||
@@ -1382,25 +1382,14 @@ dos_time(const time_t unix_time)
|
||||
{
|
||||
struct tm *t;
|
||||
unsigned int dt;
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S)
|
||||
struct tm tmbuf;
|
||||
#endif
|
||||
#if defined(HAVE__LOCALTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
/* This will not preserve time when creating/extracting the archive
|
||||
* on two systems with different time zones. */
|
||||
#if defined(HAVE_LOCALTIME_R)
|
||||
#if defined(HAVE_LOCALTIME_S)
|
||||
t = localtime_s(&tmbuf, &unix_time) ? NULL : &tmbuf;
|
||||
#elif defined(HAVE_LOCALTIME_R)
|
||||
t = localtime_r(&unix_time, &tmbuf);
|
||||
#elif defined(HAVE__LOCALTIME64_S)
|
||||
tmptime = unix_time;
|
||||
terr = _localtime64_s(&tmbuf, &tmptime);
|
||||
if (terr)
|
||||
t = NULL;
|
||||
else
|
||||
t = &tmbuf;
|
||||
#else
|
||||
t = localtime(&unix_time);
|
||||
#endif
|
||||
|
||||
@@ -257,6 +257,15 @@ If supported, the default value is read from
|
||||
The value is interpreted as a decimal integer specifying the
|
||||
compression level. Supported values depend on the library version,
|
||||
common values are from 1 to 22.
|
||||
.It Cm long
|
||||
Enables long distance matching. The value is interpreted as a
|
||||
decimal integer specifying log2 window size in bytes. Values from
|
||||
10 to 30 for 32 bit, or 31 for 64 bit, are supported.
|
||||
.It Cm threads
|
||||
The value is interpreted as a decimal integer specifying the
|
||||
number of threads for multi-threaded zstd compression.
|
||||
If set to 0, zstd will attempt to detect and use the number
|
||||
of physical CPU cores.
|
||||
.El
|
||||
.It Format 7zip
|
||||
.Bl -tag -compact -width indent
|
||||
|
||||
@@ -111,6 +111,8 @@
|
||||
#define HAVE_FCNTL 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_FDOPENDIR 1
|
||||
#define HAVE_FNMATCH 1
|
||||
#define HAVE_FNMATCH_H 1
|
||||
#define HAVE_FORK 1
|
||||
#define HAVE_FSEEKO 1
|
||||
#define HAVE_FSTAT 1
|
||||
@@ -123,6 +125,8 @@
|
||||
#define HAVE_GETEUID 1
|
||||
#define HAVE_GETGRGID_R 1
|
||||
#define HAVE_GETGRNAM_R 1
|
||||
#define HAVE_GETLINE 1
|
||||
#define HAVE_GETOPT_OPTRESET 1
|
||||
#define HAVE_GETPID 1
|
||||
#define HAVE_GETPWNAM_R 1
|
||||
#define HAVE_GETPWUID_R 1
|
||||
@@ -201,6 +205,7 @@
|
||||
#define HAVE_SYS_MOUNT_H 1
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
#define HAVE_SYS_POLL_H 1
|
||||
#define HAVE_SYS_QUEUE_H 1
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
#define HAVE_SYS_STATVFS_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
@@ -234,7 +239,7 @@
|
||||
#define HAVE_WMEMCPY 1
|
||||
#define HAVE_WMEMMOVE 1
|
||||
#define HAVE_ZLIB_H 1
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
#if __FreeBSD_version >= 800505
|
||||
#define HAVE_LIBLZMA 1
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "filter_fork.h"
|
||||
|
||||
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
/* There are some editions of Windows ("nano server," for example) that
|
||||
* do not host user32.dll. If we want to keep running on those editions,
|
||||
* we need to delay-load WaitForInputIdle. */
|
||||
@@ -224,6 +225,14 @@ fail:
|
||||
__archive_cmdline_free(acmd);
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
#else /* !WINAPI_PARTITION_DESKTOP */
|
||||
int
|
||||
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, HANDLE *out_child)
|
||||
{
|
||||
(void)cmd; (void)child_stdin; (void) child_stdout; (void) out_child;
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
#endif /* !WINAPI_PARTITION_DESKTOP */
|
||||
|
||||
void
|
||||
__archive_check_child(int in, int out)
|
||||
|
||||
@@ -149,6 +149,10 @@ typedef struct _U32_S { U32 v; } _PACKED U32_S;
|
||||
|
||||
#if GCC_VERSION >= 409
|
||||
__attribute__((__no_sanitize_undefined__))
|
||||
#else
|
||||
# if defined(__clang__)
|
||||
__attribute__((no_sanitize("undefined")))
|
||||
# endif
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
static __inline U32 A32(const void * x)
|
||||
|
||||
Reference in New Issue
Block a user