mirror of
https://github.com/reactos/CMake.git
synced 2024-11-23 19:49:51 +00:00
LibArchive 2020-02-11 (3288ebb0)
Code extracted from: https://github.com/libarchive/libarchive.git at commit 3288ebb0353beb51dfb09d444dedbe9235ead53d (v3.4.2).
This commit is contained in:
parent
2aaed7a050
commit
8cce62295a
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
* -whitespace
|
135
CMakeLists.txt
135
CMakeLists.txt
@ -1,5 +1,8 @@
|
||||
#
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
|
||||
if(POLICY CMP0074)
|
||||
cmake_policy(SET CMP0074 NEW) #3.12.0 `find_package()`` uses ``<PackageName>_ROOT`` variables.
|
||||
endif()
|
||||
#
|
||||
PROJECT(libarchive C)
|
||||
#
|
||||
@ -84,6 +87,11 @@ SET(CMAKE_REQUIRED_DEFINITIONS)
|
||||
SET(CMAKE_REQUIRED_INCLUDES)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES)
|
||||
SET(CMAKE_REQUIRED_FLAGS)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
OPTION(ENABLE_WERROR "Treat warnings as errors - default is ON for Debug, OFF otherwise." ON)
|
||||
else ()
|
||||
OPTION(ENABLE_WERROR "Treat warnings as errors - default is ON for Debug, OFF otherwise." OFF)
|
||||
endif ()
|
||||
|
||||
# Especially for early development, we want to be a little
|
||||
# aggressive about diagnosing build problems; this can get
|
||||
@ -93,10 +101,12 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$")
|
||||
#################################################################
|
||||
# Set compile flags for all build types.
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security")
|
||||
if (ENABLE_WERROR)
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
||||
endif ()
|
||||
#################################################################
|
||||
# Set compile flags for debug build.
|
||||
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wextra")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wunused")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow")
|
||||
@ -108,11 +118,13 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^Clang$")
|
||||
#################################################################
|
||||
# Set compile flags for all build types.
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security")
|
||||
if (ENABLE_WERROR)
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
||||
endif ()
|
||||
#################################################################
|
||||
# Set compile flags for debug build.
|
||||
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wextra")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wunused")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow")
|
||||
@ -125,21 +137,27 @@ IF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
|
||||
#################################################################
|
||||
# Set compile flags for all build types.
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qflag=e:e -qformat=sec")
|
||||
if (ENABLE_WERROR)
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qhalt=w")
|
||||
endif ()
|
||||
#################################################################
|
||||
# Set compile flags for debug build.
|
||||
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qhalt=w")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qflag=w:w")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qinfo=pro:use")
|
||||
ENDIF(CMAKE_C_COMPILER_ID MATCHES "^XL$")
|
||||
IF (MSVC)
|
||||
if (ENABLE_WERROR)
|
||||
# /WX option is the same as gcc's -Werror option.
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
|
||||
endif ()
|
||||
#################################################################
|
||||
# Set compile flags for debug build.
|
||||
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
|
||||
# Enable level 4 C4061: The enumerate has no associated handler in a switch
|
||||
# statement.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4061")
|
||||
# Enable level 4 C4062: The enumerate has no associated handler in a switch
|
||||
# statement and there is no default that can catch it.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4062")
|
||||
# Enable level 4 C4254: A larger bit field was assigned to a smaller bit
|
||||
# field.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4254")
|
||||
@ -165,8 +183,6 @@ IF (MSVC)
|
||||
# Enable level 4 C4706: The test value in a conditional expression was the
|
||||
# result of an assignment.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4706")
|
||||
# /WX option is the same as gcc's -Werror option.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /WX")
|
||||
# /Oi option enables built-in functions.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Oi")
|
||||
#################################################################
|
||||
@ -177,11 +193,14 @@ ENDIF (MSVC)
|
||||
# Enable CTest/CDash support
|
||||
include(CTest)
|
||||
|
||||
OPTION(ENABLE_NETTLE "Enable use of Nettle" 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)
|
||||
OPTION(ENABLE_LIBB2 "Enable the use of the system LIBB2 library if found" ON)
|
||||
OPTION(ENABLE_LZ4 "Enable the use of the system LZ4 library if found" ON)
|
||||
OPTION(ENABLE_LZO "Enable the use of the system LZO library if found" OFF)
|
||||
OPTION(ENABLE_LZMA "Enable the use of the system LZMA library if found" ON)
|
||||
OPTION(ENABLE_ZSTD "Enable the use of the system zstd library if found" ON)
|
||||
|
||||
OPTION(ENABLE_ZLIB "Enable the use of the system ZLIB library if found" ON)
|
||||
OPTION(ENABLE_BZip2 "Enable the use of the system BZip2 library if found" ON)
|
||||
@ -268,6 +287,10 @@ IF("${CMAKE_C_PLATFORM_ID}" MATCHES "^(HP-UX)$")
|
||||
ADD_DEFINITIONS(-D_XOPEN_SOURCE=500) # Ask wchar.h for mbstate_t
|
||||
ENDIF()
|
||||
|
||||
IF(MINGW)
|
||||
ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO)
|
||||
ENDIF()
|
||||
|
||||
#
|
||||
INCLUDE(CheckCSourceCompiles)
|
||||
INCLUDE(CheckCSourceRuns)
|
||||
@ -457,12 +480,13 @@ MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARIES)
|
||||
IF(ENABLE_LZMA)
|
||||
FIND_PACKAGE(LibLZMA)
|
||||
ELSE()
|
||||
SET(LIBZMA_FOUND FALSE) # Override cached value
|
||||
SET(LIBLZMA_FOUND FALSE) # Override cached value
|
||||
ENDIF()
|
||||
|
||||
IF(LIBLZMA_FOUND)
|
||||
SET(HAVE_LIBLZMA 1)
|
||||
SET(HAVE_LZMA_H 1)
|
||||
CMAKE_PUSH_CHECK_STATE()
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR})
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES})
|
||||
INCLUDE_DIRECTORIES(${LIBLZMA_INCLUDE_DIRS})
|
||||
@ -476,9 +500,13 @@ IF(LIBLZMA_FOUND)
|
||||
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)
|
||||
CMAKE_POP_CHECK_STATE()
|
||||
ELSE(LIBLZMA_FOUND)
|
||||
# LZMA not found and will not be used.
|
||||
ENDIF(LIBLZMA_FOUND)
|
||||
MARK_AS_ADVANCED(CLEAR LIBLZMA_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(CLEAR LIBLZMA_LIBRARY)
|
||||
|
||||
#
|
||||
# Find LZO2
|
||||
#
|
||||
@ -508,6 +536,35 @@ ENDIF(LZO2_FOUND)
|
||||
MARK_AS_ADVANCED(CLEAR LZO2_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(CLEAR LZO2_LIBRARY)
|
||||
#
|
||||
# Find libb2
|
||||
#
|
||||
IF(ENABLE_LIBB2)
|
||||
IF (LIBB2_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
SET(LIBB2_FIND_QUIETLY TRUE)
|
||||
ENDIF (LIBB2_INCLUDE_DIR)
|
||||
|
||||
FIND_PATH(LIBB2_INCLUDE_DIR blake2.h)
|
||||
FIND_LIBRARY(LIBB2_LIBRARY NAMES b2 libb2)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBB2 DEFAULT_MSG LIBB2_LIBRARY LIBB2_INCLUDE_DIR)
|
||||
ELSE(ENABLE_LIBB2)
|
||||
SET(LIBB2_FOUND FALSE) # Override cached value
|
||||
ENDIF(ENABLE_LIBB2)
|
||||
IF(LIBB2_FOUND)
|
||||
SET(HAVE_LIBB2 1)
|
||||
SET(HAVE_BLAKE2_H 1)
|
||||
SET(ARCHIVE_BLAKE2 FALSE)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${LIBB2_LIBRARY})
|
||||
CMAKE_PUSH_CHECK_STATE()
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${LIBB2_LIBRARY})
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${LIBB2_INCLUDE_DIR})
|
||||
CHECK_FUNCTION_EXISTS(blake2sp_init HAVE_LIBB2)
|
||||
CMAKE_POP_CHECK_STATE()
|
||||
ELSE(LIBB2_FOUND)
|
||||
SET(ARCHIVE_BLAKE2 TRUE)
|
||||
ENDIF(LIBB2_FOUND)
|
||||
#
|
||||
# Find LZ4
|
||||
#
|
||||
IF(ENABLE_LZ4)
|
||||
@ -541,29 +598,36 @@ MARK_AS_ADVANCED(CLEAR LZ4_LIBRARY)
|
||||
#
|
||||
# Find Zstd
|
||||
#
|
||||
IF (ZSTD_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
SET(ZSTD_FIND_QUIETLY TRUE)
|
||||
ENDIF (ZSTD_INCLUDE_DIR)
|
||||
IF(ENABLE_ZSTD)
|
||||
IF (ZSTD_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
SET(ZSTD_FIND_QUIETLY TRUE)
|
||||
ENDIF (ZSTD_INCLUDE_DIR)
|
||||
|
||||
FIND_PATH(ZSTD_INCLUDE_DIR zstd.h)
|
||||
FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
|
||||
FIND_PATH(ZSTD_INCLUDE_DIR zstd.h)
|
||||
FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
|
||||
ELSE(ENABLE_ZSTD)
|
||||
SET(ZSTD_FOUND FALSE) # Override cached value
|
||||
ENDIF(ENABLE_ZSTD)
|
||||
IF(ZSTD_FOUND)
|
||||
SET(HAVE_ZSTD_H 1)
|
||||
INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIR})
|
||||
LIST(APPEND ADDITIONAL_LIBS ${ZSTD_LIBRARY})
|
||||
CMAKE_PUSH_CHECK_STATE()
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${ZSTD_LIBRARY})
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${ZSTD_INCLUDE_DIR})
|
||||
CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_LIBZSTD)
|
||||
#
|
||||
# TODO: test for static library.
|
||||
#
|
||||
CMAKE_POP_CHECK_STATE()
|
||||
ENDIF(ZSTD_FOUND)
|
||||
MARK_AS_ADVANCED(CLEAR ZSTD_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(CLEAR ZSTD_LIBRARY)
|
||||
|
||||
|
||||
#
|
||||
# Check headers
|
||||
#
|
||||
@ -679,6 +743,26 @@ CHECK_C_SOURCE_COMPILES(
|
||||
int main() { return 0;}"
|
||||
SAFE_TO_DEFINE_EXTENSIONS)
|
||||
|
||||
#
|
||||
# Find mbed TLS
|
||||
#
|
||||
IF(ENABLE_MBEDTLS)
|
||||
FIND_PACKAGE(MbedTLS)
|
||||
IF(MBEDTLS_FOUND)
|
||||
SET(HAVE_LIBMBEDCRYPTO 1)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${MBEDCRYPTO_LIBRARY})
|
||||
INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIRS})
|
||||
|
||||
LIST(APPEND CMAKE_REQUIRED_INCLUDES ${MBEDTLS_INCLUDE_DIRS})
|
||||
LA_CHECK_INCLUDE_FILE("mbedtls/aes.h" HAVE_MBEDTLS_AES_H)
|
||||
LA_CHECK_INCLUDE_FILE("mbedtls/md.h" HAVE_MBEDTLS_MD_H)
|
||||
LA_CHECK_INCLUDE_FILE("mbedtls/pkcs5.h" HAVE_MBEDTLS_PKCS5_H)
|
||||
|
||||
ENDIF(MBEDTLS_FOUND)
|
||||
MARK_AS_ADVANCED(CLEAR MBEDTLS_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(CLEAR MBEDCRYPTO_LIBRARY)
|
||||
ENDIF(ENABLE_MBEDTLS)
|
||||
|
||||
#
|
||||
# Find Nettle
|
||||
#
|
||||
@ -741,6 +825,8 @@ MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
|
||||
STRING(TOUPPER "${ALGORITHM}" algorithm)
|
||||
IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
|
||||
SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
|
||||
ELSEIF("${IMPLEMENTATION}" MATCHES "^MBEDTLS$" AND NOT MBEDTLS_FOUND)
|
||||
SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
|
||||
ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NOT NETTLE_FOUND)
|
||||
SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
|
||||
ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
|
||||
@ -756,6 +842,11 @@ MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
|
||||
"${TRY_CRYPTO_REQUIRED_INCLUDES};${OPENSSL_INCLUDE_DIR}")
|
||||
SET(TRY_CRYPTO_REQUIRED_LIBS
|
||||
"-DLINK_LIBRARIES:STRING=${OPENSSL_LIBRARIES}")
|
||||
ELSEIF("${IMPLEMENTATION}" MATCHES "^MBEDTLS$" AND MBEDTLS_FOUND)
|
||||
SET(TRY_CRYPTO_REQUIRED_INCLUDES
|
||||
"${TRY_CRYPTO_REQUIRED_INCLUDES};${MBEDTLS_INCLUDE_DIRS}")
|
||||
SET(TRY_CRYPTO_REQUIRED_LIBS
|
||||
"-DLINK_LIBRARIES:STRING=${MBEDCRYPTO_LIBRARY}")
|
||||
ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NETTLE_FOUND)
|
||||
SET(TRY_CRYPTO_REQUIRED_INCLUDES
|
||||
"${TRY_CRYPTO_REQUIRED_INCLUDES};${NETTLE_INCLUDE_DIR}")
|
||||
@ -1291,6 +1382,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(unlinkat HAVE_UNLINKAT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(unsetenv HAVE_UNSETENV)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(utime HAVE_UTIME)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(utimes HAVE_UTIMES)
|
||||
@ -1304,6 +1396,7 @@ 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)
|
||||
|
||||
@ -1572,6 +1665,11 @@ IF(ENABLE_XATTR)
|
||||
CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_LIBATTR)
|
||||
IF(HAVE_LIBATTR)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "attr")
|
||||
ELSE()
|
||||
CHECK_LIBRARY_EXISTS(gnu "setxattr" "" HAVE_LIBATTR_GNU)
|
||||
IF(HAVE_LIBATTR_GNU)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "gnu")
|
||||
ENDIF()
|
||||
ENDIF(HAVE_LIBATTR)
|
||||
CHECK_SYMBOL_EXISTS(EXTATTR_NAMESPACE_USER "sys/types.h;sys/extattr.h" HAVE_DECL_EXTATTR_NAMESPACE_USER)
|
||||
CHECK_SYMBOL_EXISTS(XATTR_NOFOLLOW "sys/xattr.h" HAVE_DECL_XATTR_NOFOLLOW)
|
||||
@ -1895,6 +1993,7 @@ CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" LIBC)
|
||||
CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC2)
|
||||
CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC3)
|
||||
CHECK_CRYPTO("MD5;SHA1;SHA256;SHA384;SHA512" LIBSYSTEM)
|
||||
CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" MBEDTLS)
|
||||
CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" NETTLE)
|
||||
CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" OPENSSL)
|
||||
|
||||
|
9
COPYING
9
COPYING
@ -23,6 +23,13 @@ the actual statements in the files are controlling.
|
||||
* The following source files are in the public domain:
|
||||
libarchive/archive_getdate.c
|
||||
|
||||
* The following source files are triple-licensed with the ability to choose
|
||||
from CC0 1.0 Universal, OpenSSL or Apache 2.0 licenses:
|
||||
libarchive/archive_blake2.h
|
||||
libarchive/archive_blake2_impl.h
|
||||
libarchive/archive_blake2s_ref.c
|
||||
libarchive/archive_blake2sp_ref.c
|
||||
|
||||
* The build files---including Makefiles, configure scripts,
|
||||
and auxiliary scripts used as part of the compile process---have
|
||||
widely varying licensing terms. Please check individual files before
|
||||
@ -34,7 +41,7 @@ do use the license below. The varying licensing of the build scripts
|
||||
seems to be an unavoidable mess.
|
||||
|
||||
|
||||
Copyright (c) 2003-2009 <author(s)>
|
||||
Copyright (c) 2003-2018 <author(s)>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
13
build/cmake/FindMbedTLS.cmake
Normal file
13
build/cmake/FindMbedTLS.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
|
||||
|
||||
find_library(MBEDTLS_LIBRARY mbedtls)
|
||||
find_library(MBEDX509_LIBRARY mbedx509)
|
||||
find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
|
||||
|
||||
set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
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)
|
@ -680,6 +680,12 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the `bz2' library (-lbz2). */
|
||||
#cmakedefine HAVE_LIBBZ2 1
|
||||
|
||||
/* Define to 1 if you have the `b2' library (-lb2). */
|
||||
#cmakedefine HAVE_LIBB2 1
|
||||
|
||||
/* Define to 1 if you have the <blake2.h> header file. */
|
||||
#cmakedefine HAVE_BLAKE2_H 1
|
||||
|
||||
/* Define to 1 if you have the `charset' library (-lcharset). */
|
||||
#cmakedefine HAVE_LIBCHARSET 1
|
||||
|
||||
@ -704,6 +710,9 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the `lzo2' library (-llzo2). */
|
||||
#cmakedefine HAVE_LIBLZO2 1
|
||||
|
||||
/* Define to 1 if you have the `mbedcrypto' library (-lmbedcrypto). */
|
||||
#cmakedefine HAVE_LIBMBEDCRYPTO 1
|
||||
|
||||
/* Define to 1 if you have the `nettle' library (-lnettle). */
|
||||
#cmakedefine HAVE_LIBNETTLE 1
|
||||
|
||||
@ -1105,6 +1114,9 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#cmakedefine HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `unlinkat' function. */
|
||||
#cmakedefine HAVE_UNLINKAT 1
|
||||
|
||||
/* Define to 1 if you have the `unsetenv' function. */
|
||||
#cmakedefine HAVE_UNSETENV 1
|
||||
|
||||
@ -1198,6 +1210,9 @@ typedef uint64_t uintmax_t;
|
||||
/* 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 `_localtime64_s' function. */
|
||||
#cmakedefine HAVE__LOCALTIME64_S 1
|
||||
|
||||
|
@ -1 +1 @@
|
||||
3003003
|
||||
3004002
|
||||
|
@ -51,6 +51,8 @@ SET(libarchive_SOURCES
|
||||
archive_platform_acl.h
|
||||
archive_platform_xattr.h
|
||||
archive_ppmd_private.h
|
||||
archive_ppmd8.c
|
||||
archive_ppmd8_private.h
|
||||
archive_ppmd7.c
|
||||
archive_ppmd7_private.h
|
||||
archive_private.h
|
||||
@ -100,6 +102,7 @@ SET(libarchive_SOURCES
|
||||
archive_read_support_format_lha.c
|
||||
archive_read_support_format_mtree.c
|
||||
archive_read_support_format_rar.c
|
||||
archive_read_support_format_rar5.c
|
||||
archive_read_support_format_raw.c
|
||||
archive_read_support_format_tar.c
|
||||
archive_read_support_format_warc.c
|
||||
@ -147,6 +150,7 @@ SET(libarchive_SOURCES
|
||||
archive_write_set_format_iso9660.c
|
||||
archive_write_set_format_mtree.c
|
||||
archive_write_set_format_pax.c
|
||||
archive_write_set_format_private.h
|
||||
archive_write_set_format_raw.c
|
||||
archive_write_set_format_shar.c
|
||||
archive_write_set_format_ustar.c
|
||||
@ -167,6 +171,7 @@ SET(libarchive_MANS
|
||||
archive_entry.3
|
||||
archive_entry_acl.3
|
||||
archive_entry_linkify.3
|
||||
archive_entry_misc.3
|
||||
archive_entry_paths.3
|
||||
archive_entry_perms.3
|
||||
archive_entry_stat.3
|
||||
@ -215,6 +220,11 @@ IF(WIN32 AND NOT CYGWIN)
|
||||
LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
|
||||
ENDIF(WIN32 AND NOT CYGWIN)
|
||||
|
||||
IF(ARCHIVE_BLAKE2)
|
||||
LIST(APPEND libarchive_SOURCES archive_blake2sp_ref.c)
|
||||
LIST(APPEND libarchive_SOURCES archive_blake2s_ref.c)
|
||||
ENDIF(ARCHIVE_BLAKE2)
|
||||
|
||||
IF(ARCHIVE_ACL_DARWIN)
|
||||
LIST(APPEND libarchive_SOURCES archive_disk_acl_darwin.c)
|
||||
ELSEIF(ARCHIVE_ACL_FREEBSD)
|
||||
@ -227,6 +237,7 @@ ENDIF()
|
||||
|
||||
# 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})
|
||||
|
||||
|
@ -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 3003003
|
||||
#define ARCHIVE_VERSION_NUMBER 3004002
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h> /* for wchar_t */
|
||||
@ -52,7 +52,7 @@
|
||||
*/
|
||||
#if defined(__BORLANDC__) && __BORLANDC__ >= 0x560
|
||||
# include <stdint.h>
|
||||
#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS) && !defined(__osf__)
|
||||
#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS) && !defined(__osf__) && !defined(__CLANG_INTTYPES_H)
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
|
||||
/*
|
||||
* Textual name/version of the library, useful for version displays.
|
||||
*/
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.3.3"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.4.2"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
@ -340,6 +340,7 @@ typedef const char *archive_passphrase_callback(struct archive *,
|
||||
#define ARCHIVE_FORMAT_RAR 0xD0000
|
||||
#define ARCHIVE_FORMAT_7ZIP 0xE0000
|
||||
#define ARCHIVE_FORMAT_WARC 0xF0000
|
||||
#define ARCHIVE_FORMAT_RAR_V5 0x100000
|
||||
|
||||
/*
|
||||
* Codes returned by archive_read_format_capabilities().
|
||||
@ -449,6 +450,7 @@ __LA_DECL int archive_read_support_format_iso9660(struct archive *);
|
||||
__LA_DECL int archive_read_support_format_lha(struct archive *);
|
||||
__LA_DECL int archive_read_support_format_mtree(struct archive *);
|
||||
__LA_DECL int archive_read_support_format_rar(struct archive *);
|
||||
__LA_DECL int archive_read_support_format_rar5(struct archive *);
|
||||
__LA_DECL int archive_read_support_format_raw(struct archive *);
|
||||
__LA_DECL int archive_read_support_format_tar(struct archive *);
|
||||
__LA_DECL int archive_read_support_format_warc(struct archive *);
|
||||
@ -691,6 +693,8 @@ __LA_DECL int archive_read_set_passphrase_callback(struct archive *,
|
||||
#define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000)
|
||||
/* Default: Do not clear no-change flags when unlinking object */
|
||||
#define ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS (0x20000)
|
||||
/* Default: Do not extract atomically (using rename) */
|
||||
#define ARCHIVE_EXTRACT_SAFE_WRITES (0x40000)
|
||||
|
||||
__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
|
||||
int flags);
|
||||
@ -1093,6 +1097,8 @@ __LA_DECL int archive_match_excluded(struct archive *,
|
||||
*/
|
||||
__LA_DECL int archive_match_path_excluded(struct archive *,
|
||||
struct archive_entry *);
|
||||
/* Control recursive inclusion of directory content when directory is included. Default on. */
|
||||
__LA_DECL int archive_match_set_inclusion_recursion(struct archive *, int);
|
||||
/* Add exclusion pathname pattern. */
|
||||
__LA_DECL int archive_match_exclude_pattern(struct archive *, const char *);
|
||||
__LA_DECL int archive_match_exclude_pattern_w(struct archive *,
|
||||
|
@ -138,14 +138,10 @@ archive_acl_clear(struct archive_acl *acl)
|
||||
free(acl->acl_head);
|
||||
acl->acl_head = ap;
|
||||
}
|
||||
if (acl->acl_text_w != NULL) {
|
||||
free(acl->acl_text_w);
|
||||
acl->acl_text_w = NULL;
|
||||
}
|
||||
if (acl->acl_text != NULL) {
|
||||
free(acl->acl_text);
|
||||
acl->acl_text = NULL;
|
||||
}
|
||||
free(acl->acl_text_w);
|
||||
acl->acl_text_w = NULL;
|
||||
free(acl->acl_text);
|
||||
acl->acl_text = NULL;
|
||||
acl->acl_p = NULL;
|
||||
acl->acl_types = 0;
|
||||
acl->acl_state = 0; /* Not counting. */
|
||||
@ -324,14 +320,10 @@ acl_new_entry(struct archive_acl *acl,
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (acl->acl_text_w != NULL) {
|
||||
free(acl->acl_text_w);
|
||||
acl->acl_text_w = NULL;
|
||||
}
|
||||
if (acl->acl_text != NULL) {
|
||||
free(acl->acl_text);
|
||||
acl->acl_text = NULL;
|
||||
}
|
||||
free(acl->acl_text_w);
|
||||
acl->acl_text_w = NULL;
|
||||
free(acl->acl_text);
|
||||
acl->acl_text = NULL;
|
||||
|
||||
/*
|
||||
* If there's a matching entry already in the list, overwrite it.
|
||||
@ -753,8 +745,10 @@ archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
append_entry_w(&wp, prefix, ap->type, ap->tag, flags,
|
||||
wname, ap->permset, id);
|
||||
count++;
|
||||
} else if (r < 0 && errno == ENOMEM)
|
||||
} else if (r < 0 && errno == ENOMEM) {
|
||||
free(ws);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add terminating character */
|
||||
@ -975,8 +969,10 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
prefix = NULL;
|
||||
r = archive_mstring_get_mbs_l(
|
||||
&ap->name, &name, &len, sc);
|
||||
if (r != 0)
|
||||
if (r != 0) {
|
||||
free(s);
|
||||
return (NULL);
|
||||
}
|
||||
if (count > 0)
|
||||
*p++ = separator;
|
||||
if (name == NULL ||
|
||||
@ -1581,17 +1577,29 @@ next_field_w(const wchar_t **wp, const wchar_t **start,
|
||||
|
||||
/* Scan for the separator. */
|
||||
while (**wp != L'\0' && **wp != L',' && **wp != L':' &&
|
||||
**wp != L'\n') {
|
||||
**wp != L'\n' && **wp != L'#') {
|
||||
(*wp)++;
|
||||
}
|
||||
*sep = **wp;
|
||||
|
||||
/* Trim trailing whitespace to locate end of field. */
|
||||
*end = *wp - 1;
|
||||
while (**end == L' ' || **end == L'\t' || **end == L'\n') {
|
||||
(*end)--;
|
||||
/* Locate end of field, trim trailing whitespace if necessary */
|
||||
if (*wp == *start) {
|
||||
*end = *wp;
|
||||
} else {
|
||||
*end = *wp - 1;
|
||||
while (**end == L' ' || **end == L'\t' || **end == L'\n') {
|
||||
(*end)--;
|
||||
}
|
||||
(*end)++;
|
||||
}
|
||||
|
||||
/* Handle in-field comments */
|
||||
if (*sep == L'#') {
|
||||
while (**wp != L'\0' && **wp != L',' && **wp != L'\n') {
|
||||
(*wp)++;
|
||||
}
|
||||
*sep = **wp;
|
||||
}
|
||||
(*end)++;
|
||||
|
||||
/* Adjust scanner location. */
|
||||
if (**wp != L'\0')
|
||||
@ -1642,7 +1650,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
ret = ARCHIVE_OK;
|
||||
types = 0;
|
||||
|
||||
while (text != NULL && *text != '\0') {
|
||||
while (text != NULL && *text != '\0') {
|
||||
/*
|
||||
* Parse the fields out of the next entry,
|
||||
* advance 'text' to start of next entry.
|
||||
@ -1707,6 +1715,11 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
st = field[n].start + 1;
|
||||
len = field[n].end - field[n].start;
|
||||
|
||||
if (len == 0) {
|
||||
ret = ARCHIVE_WARN;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (*s) {
|
||||
case 'u':
|
||||
if (len == 1 || (len == 4
|
||||
@ -2053,17 +2066,30 @@ next_field(const char **p, const char **start,
|
||||
*start = *p;
|
||||
|
||||
/* Scan for the separator. */
|
||||
while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n') {
|
||||
while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' &&
|
||||
**p != '#') {
|
||||
(*p)++;
|
||||
}
|
||||
*sep = **p;
|
||||
|
||||
/* Trim trailing whitespace to locate end of field. */
|
||||
*end = *p - 1;
|
||||
while (**end == ' ' || **end == '\t' || **end == '\n') {
|
||||
(*end)--;
|
||||
/* Locate end of field, trim trailing whitespace if necessary */
|
||||
if (*p == *start) {
|
||||
*end = *p;
|
||||
} else {
|
||||
*end = *p - 1;
|
||||
while (**end == ' ' || **end == '\t' || **end == '\n') {
|
||||
(*end)--;
|
||||
}
|
||||
(*end)++;
|
||||
}
|
||||
|
||||
/* Handle in-field comments */
|
||||
if (*sep == '#') {
|
||||
while (**p != '\0' && **p != ',' && **p != '\n') {
|
||||
(*p)++;
|
||||
}
|
||||
*sep = **p;
|
||||
}
|
||||
(*end)++;
|
||||
|
||||
/* Adjust scanner location. */
|
||||
if (**p != '\0')
|
||||
|
@ -25,13 +25,13 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive_string.h"
|
||||
|
||||
struct archive_acl_entry {
|
||||
|
195
libarchive/archive_blake2.h
Normal file
195
libarchive/archive_blake2.h
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_BLAKE2_H
|
||||
#define ARCHIVE_BLAKE2_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
|
||||
#else
|
||||
#define BLAKE2_PACKED(x) x __attribute__((packed))
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum blake2s_constant
|
||||
{
|
||||
BLAKE2S_BLOCKBYTES = 64,
|
||||
BLAKE2S_OUTBYTES = 32,
|
||||
BLAKE2S_KEYBYTES = 32,
|
||||
BLAKE2S_SALTBYTES = 8,
|
||||
BLAKE2S_PERSONALBYTES = 8
|
||||
};
|
||||
|
||||
enum blake2b_constant
|
||||
{
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_OUTBYTES = 64,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
BLAKE2B_SALTBYTES = 16,
|
||||
BLAKE2B_PERSONALBYTES = 16
|
||||
};
|
||||
|
||||
typedef struct blake2s_state__
|
||||
{
|
||||
uint32_t h[8];
|
||||
uint32_t t[2];
|
||||
uint32_t f[2];
|
||||
uint8_t buf[BLAKE2S_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
size_t outlen;
|
||||
uint8_t last_node;
|
||||
} blake2s_state;
|
||||
|
||||
typedef struct blake2b_state__
|
||||
{
|
||||
uint64_t h[8];
|
||||
uint64_t t[2];
|
||||
uint64_t f[2];
|
||||
uint8_t buf[BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
size_t outlen;
|
||||
uint8_t last_node;
|
||||
} blake2b_state;
|
||||
|
||||
typedef struct blake2sp_state__
|
||||
{
|
||||
blake2s_state S[8][1];
|
||||
blake2s_state R[1];
|
||||
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
size_t outlen;
|
||||
} blake2sp_state;
|
||||
|
||||
typedef struct blake2bp_state__
|
||||
{
|
||||
blake2b_state S[4][1];
|
||||
blake2b_state R[1];
|
||||
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
size_t outlen;
|
||||
} blake2bp_state;
|
||||
|
||||
BLAKE2_PACKED(struct blake2s_param__
|
||||
{
|
||||
uint8_t digest_length; /* 1 */
|
||||
uint8_t key_length; /* 2 */
|
||||
uint8_t fanout; /* 3 */
|
||||
uint8_t depth; /* 4 */
|
||||
uint32_t leaf_length; /* 8 */
|
||||
uint32_t node_offset; /* 12 */
|
||||
uint16_t xof_length; /* 14 */
|
||||
uint8_t node_depth; /* 15 */
|
||||
uint8_t inner_length; /* 16 */
|
||||
/* uint8_t reserved[0]; */
|
||||
uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */
|
||||
uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */
|
||||
});
|
||||
|
||||
typedef struct blake2s_param__ blake2s_param;
|
||||
|
||||
BLAKE2_PACKED(struct blake2b_param__
|
||||
{
|
||||
uint8_t digest_length; /* 1 */
|
||||
uint8_t key_length; /* 2 */
|
||||
uint8_t fanout; /* 3 */
|
||||
uint8_t depth; /* 4 */
|
||||
uint32_t leaf_length; /* 8 */
|
||||
uint32_t node_offset; /* 12 */
|
||||
uint32_t xof_length; /* 16 */
|
||||
uint8_t node_depth; /* 17 */
|
||||
uint8_t inner_length; /* 18 */
|
||||
uint8_t reserved[14]; /* 32 */
|
||||
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
|
||||
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
|
||||
});
|
||||
|
||||
typedef struct blake2b_param__ blake2b_param;
|
||||
|
||||
typedef struct blake2xs_state__
|
||||
{
|
||||
blake2s_state S[1];
|
||||
blake2s_param P[1];
|
||||
} blake2xs_state;
|
||||
|
||||
typedef struct blake2xb_state__
|
||||
{
|
||||
blake2b_state S[1];
|
||||
blake2b_param P[1];
|
||||
} blake2xb_state;
|
||||
|
||||
/* Padded structs result in a compile-time error */
|
||||
enum {
|
||||
BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES),
|
||||
BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES)
|
||||
};
|
||||
|
||||
/* Streaming API */
|
||||
int blake2s_init( blake2s_state *S, size_t outlen );
|
||||
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
|
||||
int blake2s_update( blake2s_state *S, const void *in, size_t inlen );
|
||||
int blake2s_final( blake2s_state *S, void *out, size_t outlen );
|
||||
|
||||
int blake2b_init( blake2b_state *S, size_t outlen );
|
||||
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
|
||||
int blake2b_update( blake2b_state *S, const void *in, size_t inlen );
|
||||
int blake2b_final( blake2b_state *S, void *out, size_t outlen );
|
||||
|
||||
int blake2sp_init( blake2sp_state *S, size_t outlen );
|
||||
int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );
|
||||
int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen );
|
||||
int blake2sp_final( blake2sp_state *S, void *out, size_t outlen );
|
||||
|
||||
int blake2bp_init( blake2bp_state *S, size_t outlen );
|
||||
int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );
|
||||
int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen );
|
||||
int blake2bp_final( blake2bp_state *S, void *out, size_t outlen );
|
||||
|
||||
/* Variable output length API */
|
||||
int blake2xs_init( blake2xs_state *S, const size_t outlen );
|
||||
int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen );
|
||||
int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen );
|
||||
int blake2xs_final(blake2xs_state *S, void *out, size_t outlen);
|
||||
|
||||
int blake2xb_init( blake2xb_state *S, const size_t outlen );
|
||||
int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen );
|
||||
int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen );
|
||||
int blake2xb_final(blake2xb_state *S, void *out, size_t outlen);
|
||||
|
||||
/* Simple API */
|
||||
int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
|
||||
int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
|
||||
int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
|
||||
/* This is simply an alias for blake2b */
|
||||
int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
161
libarchive/archive_blake2_impl.h
Normal file
161
libarchive/archive_blake2_impl.h
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_BLAKE2_IMPL_H
|
||||
#define ARCHIVE_BLAKE2_IMPL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
|
||||
#if defined(_MSC_VER)
|
||||
#define BLAKE2_INLINE __inline
|
||||
#elif defined(__GNUC__)
|
||||
#define BLAKE2_INLINE __inline__
|
||||
#else
|
||||
#define BLAKE2_INLINE
|
||||
#endif
|
||||
#else
|
||||
#define BLAKE2_INLINE inline
|
||||
#endif
|
||||
|
||||
static BLAKE2_INLINE uint32_t load32( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint32_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
return (( uint32_t )( p[0] ) << 0) |
|
||||
(( uint32_t )( p[1] ) << 8) |
|
||||
(( uint32_t )( p[2] ) << 16) |
|
||||
(( uint32_t )( p[3] ) << 24) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint64_t load64( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint64_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
return (( uint64_t )( p[0] ) << 0) |
|
||||
(( uint64_t )( p[1] ) << 8) |
|
||||
(( uint64_t )( p[2] ) << 16) |
|
||||
(( uint64_t )( p[3] ) << 24) |
|
||||
(( uint64_t )( p[4] ) << 32) |
|
||||
(( uint64_t )( p[5] ) << 40) |
|
||||
(( uint64_t )( p[6] ) << 48) |
|
||||
(( uint64_t )( p[7] ) << 56) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint16_t load16( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint16_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
return ( uint16_t )((( uint32_t )( p[0] ) << 0) |
|
||||
(( uint32_t )( p[1] ) << 8));
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store16( void *dst, uint16_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store32( void *dst, uint32_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
p[0] = (uint8_t)(w >> 0);
|
||||
p[1] = (uint8_t)(w >> 8);
|
||||
p[2] = (uint8_t)(w >> 16);
|
||||
p[3] = (uint8_t)(w >> 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store64( void *dst, uint64_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
p[0] = (uint8_t)(w >> 0);
|
||||
p[1] = (uint8_t)(w >> 8);
|
||||
p[2] = (uint8_t)(w >> 16);
|
||||
p[3] = (uint8_t)(w >> 24);
|
||||
p[4] = (uint8_t)(w >> 32);
|
||||
p[5] = (uint8_t)(w >> 40);
|
||||
p[6] = (uint8_t)(w >> 48);
|
||||
p[7] = (uint8_t)(w >> 56);
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint64_t load48( const void *src )
|
||||
{
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
return (( uint64_t )( p[0] ) << 0) |
|
||||
(( uint64_t )( p[1] ) << 8) |
|
||||
(( uint64_t )( p[2] ) << 16) |
|
||||
(( uint64_t )( p[3] ) << 24) |
|
||||
(( uint64_t )( p[4] ) << 32) |
|
||||
(( uint64_t )( p[5] ) << 40) ;
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store48( void *dst, uint64_t w )
|
||||
{
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
p[0] = (uint8_t)(w >> 0);
|
||||
p[1] = (uint8_t)(w >> 8);
|
||||
p[2] = (uint8_t)(w >> 16);
|
||||
p[3] = (uint8_t)(w >> 24);
|
||||
p[4] = (uint8_t)(w >> 32);
|
||||
p[5] = (uint8_t)(w >> 40);
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 32 - c ) );
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 64 - c ) );
|
||||
}
|
||||
|
||||
/* prevents compiler optimizing out memset() */
|
||||
static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
|
||||
{
|
||||
static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
|
||||
memset_v(v, 0, n);
|
||||
}
|
||||
|
||||
#endif
|
367
libarchive/archive_blake2s_ref.c
Normal file
367
libarchive/archive_blake2s_ref.c
Normal file
@ -0,0 +1,367 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "archive_blake2.h"
|
||||
#include "archive_blake2_impl.h"
|
||||
|
||||
static const uint32_t blake2s_IV[8] =
|
||||
{
|
||||
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
||||
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||
};
|
||||
|
||||
static const uint8_t blake2s_sigma[10][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
};
|
||||
|
||||
static void blake2s_set_lastnode( blake2s_state *S )
|
||||
{
|
||||
S->f[1] = (uint32_t)-1;
|
||||
}
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
static int blake2s_is_lastblock( const blake2s_state *S )
|
||||
{
|
||||
return S->f[0] != 0;
|
||||
}
|
||||
|
||||
static void blake2s_set_lastblock( blake2s_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2s_set_lastnode( S );
|
||||
|
||||
S->f[0] = (uint32_t)-1;
|
||||
}
|
||||
|
||||
static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
|
||||
{
|
||||
S->t[0] += inc;
|
||||
S->t[1] += ( S->t[0] < inc );
|
||||
}
|
||||
|
||||
static void blake2s_init0( blake2s_state *S )
|
||||
{
|
||||
size_t i;
|
||||
memset( S, 0, sizeof( blake2s_state ) );
|
||||
|
||||
for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
|
||||
}
|
||||
|
||||
/* init2 xors IV with input parameter block */
|
||||
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
|
||||
{
|
||||
const unsigned char *p = ( const unsigned char * )( P );
|
||||
size_t i;
|
||||
|
||||
blake2s_init0( S );
|
||||
|
||||
/* IV XOR ParamBlock */
|
||||
for( i = 0; i < 8; ++i )
|
||||
S->h[i] ^= load32( &p[i * 4] );
|
||||
|
||||
S->outlen = P->digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Sequential blake2s initialization */
|
||||
int blake2s_init( blake2s_state *S, size_t outlen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
|
||||
/* Move interval verification here? */
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||
|
||||
P->digest_length = (uint8_t)outlen;
|
||||
P->key_length = 0;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store32( &P->node_offset, 0 );
|
||||
store16( &P->xof_length, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
/* memset(P->reserved, 0, sizeof(P->reserved) ); */
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2s_init_param( S, P );
|
||||
}
|
||||
|
||||
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||
|
||||
if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
P->digest_length = (uint8_t)outlen;
|
||||
P->key_length = (uint8_t)keylen;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store32( &P->node_offset, 0 );
|
||||
store16( &P->xof_length, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
/* memset(P->reserved, 0, sizeof(P->reserved) ); */
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
|
||||
if( blake2s_init_param( S, P ) < 0 ) return -1;
|
||||
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define G(r,i,a,b,c,d) \
|
||||
do { \
|
||||
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
|
||||
d = rotr32(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr32(b ^ c, 12); \
|
||||
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
|
||||
d = rotr32(d ^ a, 8); \
|
||||
c = c + d; \
|
||||
b = rotr32(b ^ c, 7); \
|
||||
} while(0)
|
||||
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
||||
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
||||
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
||||
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
||||
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
||||
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
||||
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
||||
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
||||
} while(0)
|
||||
|
||||
static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] )
|
||||
{
|
||||
uint32_t m[16];
|
||||
uint32_t v[16];
|
||||
size_t i;
|
||||
|
||||
for( i = 0; i < 16; ++i ) {
|
||||
m[i] = load32( in + i * sizeof( m[i] ) );
|
||||
}
|
||||
|
||||
for( i = 0; i < 8; ++i ) {
|
||||
v[i] = S->h[i];
|
||||
}
|
||||
|
||||
v[ 8] = blake2s_IV[0];
|
||||
v[ 9] = blake2s_IV[1];
|
||||
v[10] = blake2s_IV[2];
|
||||
v[11] = blake2s_IV[3];
|
||||
v[12] = S->t[0] ^ blake2s_IV[4];
|
||||
v[13] = S->t[1] ^ blake2s_IV[5];
|
||||
v[14] = S->f[0] ^ blake2s_IV[6];
|
||||
v[15] = S->f[1] ^ blake2s_IV[7];
|
||||
|
||||
ROUND( 0 );
|
||||
ROUND( 1 );
|
||||
ROUND( 2 );
|
||||
ROUND( 3 );
|
||||
ROUND( 4 );
|
||||
ROUND( 5 );
|
||||
ROUND( 6 );
|
||||
ROUND( 7 );
|
||||
ROUND( 8 );
|
||||
ROUND( 9 );
|
||||
|
||||
for( i = 0; i < 8; ++i ) {
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
}
|
||||
}
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
|
||||
int blake2s_update( blake2s_state *S, const void *pin, size_t inlen )
|
||||
{
|
||||
const unsigned char * in = (const unsigned char *)pin;
|
||||
if( inlen > 0 )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = BLAKE2S_BLOCKBYTES - left;
|
||||
if( inlen > fill )
|
||||
{
|
||||
S->buflen = 0;
|
||||
memcpy( S->buf + left, in, fill ); /* Fill buffer */
|
||||
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||
blake2s_compress( S, S->buf ); /* Compress */
|
||||
in += fill; inlen -= fill;
|
||||
while(inlen > BLAKE2S_BLOCKBYTES) {
|
||||
blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
|
||||
blake2s_compress( S, in );
|
||||
in += BLAKE2S_BLOCKBYTES;
|
||||
inlen -= BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
memcpy( S->buf + S->buflen, in, inlen );
|
||||
S->buflen += inlen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2s_final( blake2s_state *S, void *out, size_t outlen )
|
||||
{
|
||||
uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
|
||||
size_t i;
|
||||
|
||||
if( out == NULL || outlen < S->outlen )
|
||||
return -1;
|
||||
|
||||
if( blake2s_is_lastblock( S ) )
|
||||
return -1;
|
||||
|
||||
blake2s_increment_counter( S, ( uint32_t )S->buflen );
|
||||
blake2s_set_lastblock( S );
|
||||
memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
|
||||
blake2s_compress( S, S->buf );
|
||||
|
||||
for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
|
||||
store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
|
||||
|
||||
memcpy( out, buffer, outlen );
|
||||
secure_zero_memory(buffer, sizeof(buffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
|
||||
{
|
||||
blake2s_state S[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in && inlen > 0 ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if ( NULL == key && keylen > 0) return -1;
|
||||
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
if( keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( blake2s_init( S, outlen ) < 0 ) return -1;
|
||||
}
|
||||
|
||||
blake2s_update( S, ( const uint8_t * )in, inlen );
|
||||
blake2s_final( S, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(SUPERCOP)
|
||||
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
|
||||
{
|
||||
return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BLAKE2S_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( void )
|
||||
{
|
||||
uint8_t key[BLAKE2S_KEYBYTES];
|
||||
uint8_t buf[BLAKE2_KAT_LENGTH];
|
||||
size_t i, step;
|
||||
|
||||
for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
/* Test simple API */
|
||||
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test streaming API */
|
||||
for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {
|
||||
for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2s_state S;
|
||||
uint8_t * p = buf;
|
||||
size_t mlen = i;
|
||||
int err = 0;
|
||||
|
||||
if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
while (mlen >= step) {
|
||||
if ( (err = blake2s_update(&S, p, step)) < 0 ) {
|
||||
goto fail;
|
||||
}
|
||||
mlen -= step;
|
||||
p += step;
|
||||
}
|
||||
if ( (err = blake2s_update(&S, p, mlen)) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
fail:
|
||||
puts("error");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
359
libarchive/archive_blake2sp_ref.c
Normal file
359
libarchive/archive_blake2sp_ref.c
Normal file
@ -0,0 +1,359 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "archive_blake2.h"
|
||||
#include "archive_blake2_impl.h"
|
||||
|
||||
#define PARALLELISM_DEGREE 8
|
||||
|
||||
/*
|
||||
blake2sp_init_param defaults to setting the expecting output length
|
||||
from the digest_length parameter block field.
|
||||
|
||||
In some cases, however, we do not want this, as the output length
|
||||
of these instances is given by inner_length instead.
|
||||
*/
|
||||
static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P )
|
||||
{
|
||||
int err = blake2s_init_param(S, P);
|
||||
S->outlen = P->inner_length;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint32_t offset )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
P->digest_length = (uint8_t)outlen;
|
||||
P->key_length = (uint8_t)keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store32( &P->node_offset, offset );
|
||||
store16( &P->xof_length, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = BLAKE2S_OUTBYTES;
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2sp_init_leaf_param( S, P );
|
||||
}
|
||||
|
||||
static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
P->digest_length = (uint8_t)outlen;
|
||||
P->key_length = (uint8_t)keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store32( &P->node_offset, 0 );
|
||||
store16( &P->xof_length, 0 );
|
||||
P->node_depth = 1;
|
||||
P->inner_length = BLAKE2S_OUTBYTES;
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2s_init_param( S, P );
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_init( blake2sp_state *S, size_t outlen )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
S->outlen = outlen;
|
||||
|
||||
if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S->S[i], outlen, 0, (uint32_t)i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
S->outlen = outlen;
|
||||
|
||||
if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S->S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen )
|
||||
{
|
||||
const unsigned char * in = (const unsigned char *)pin;
|
||||
size_t left = S->buflen;
|
||||
size_t fill = sizeof( S->buf ) - left;
|
||||
size_t i;
|
||||
|
||||
if( left && inlen >= fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill );
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t i = omp_get_thread_num();
|
||||
#endif
|
||||
size_t inlen__ = inlen;
|
||||
const unsigned char *in__ = ( const unsigned char * )in;
|
||||
in__ += i * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
|
||||
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
|
||||
inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
if( inlen > 0 )
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
|
||||
S->buflen = left + inlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_final( blake2sp_state *S, void *out, size_t outlen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||
size_t i;
|
||||
|
||||
if(out == NULL || outlen < S->outlen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
{
|
||||
if( S->buflen > i * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;
|
||||
|
||||
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
|
||||
}
|
||||
|
||||
blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );
|
||||
}
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
|
||||
|
||||
return blake2s_final( S->R, out, S->outlen );
|
||||
}
|
||||
|
||||
|
||||
int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||
blake2s_state S[PARALLELISM_DEGREE][1];
|
||||
blake2s_state FS[1];
|
||||
size_t i;
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in && inlen > 0 ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if ( NULL == key && keylen > 0) return -1;
|
||||
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
if( keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1;
|
||||
|
||||
S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t i = omp_get_thread_num();
|
||||
#endif
|
||||
size_t inlen__ = inlen;
|
||||
const unsigned char *in__ = ( const unsigned char * )in;
|
||||
in__ += i * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
|
||||
if( inlen__ > i * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES;
|
||||
const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
|
||||
blake2s_update( S[i], in__, len );
|
||||
}
|
||||
|
||||
blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES );
|
||||
}
|
||||
|
||||
if( blake2sp_init_root( FS, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
FS->last_node = 1;
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );
|
||||
|
||||
return blake2s_final( FS, out, outlen );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(BLAKE2SP_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( void )
|
||||
{
|
||||
uint8_t key[BLAKE2S_KEYBYTES];
|
||||
uint8_t buf[BLAKE2_KAT_LENGTH];
|
||||
size_t i, step;
|
||||
|
||||
for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
/* Test simple API */
|
||||
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test streaming API */
|
||||
for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {
|
||||
for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2sp_state S;
|
||||
uint8_t * p = buf;
|
||||
size_t mlen = i;
|
||||
int err = 0;
|
||||
|
||||
if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
while (mlen >= step) {
|
||||
if ( (err = blake2sp_update(&S, p, step)) < 0 ) {
|
||||
goto fail;
|
||||
}
|
||||
mlen -= step;
|
||||
p += step;
|
||||
}
|
||||
if ( (err = blake2sp_update(&S, p, mlen)) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
fail:
|
||||
puts("error");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
@ -25,15 +25,15 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_CMDLINE_PRIVATE_H
|
||||
#define ARCHIVE_CMDLINE_PRIVATE_H
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_CMDLINE_PRIVATE_H
|
||||
#define ARCHIVE_CMDLINE_PRIVATE_H
|
||||
|
||||
struct archive_cmdline {
|
||||
char *path;
|
||||
char **argv;
|
||||
|
@ -25,6 +25,9 @@
|
||||
* $FreeBSD: head/lib/libarchive/archive_crc32.h 201102 2009-12-28 03:11:36Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_CRC32_H
|
||||
#define ARCHIVE_CRC32_H
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
@ -76,3 +79,5 @@ crc32(unsigned long crc, const void *_p, size_t len)
|
||||
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
return (crc ^ 0xffffffffUL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -85,6 +85,35 @@ pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
|
||||
return (BCRYPT_SUCCESS(status)) ? 0: -1;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_PKCS5_H)
|
||||
|
||||
static int
|
||||
pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
|
||||
size_t salt_len, unsigned rounds, uint8_t *derived_key,
|
||||
size_t derived_key_len)
|
||||
{
|
||||
mbedtls_md_context_t ctx;
|
||||
const mbedtls_md_info_t *info;
|
||||
int ret;
|
||||
|
||||
mbedtls_md_init(&ctx);
|
||||
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
||||
if (info == NULL) {
|
||||
mbedtls_md_free(&ctx);
|
||||
return (-1);
|
||||
}
|
||||
ret = mbedtls_md_setup(&ctx, info, 1);
|
||||
if (ret != 0) {
|
||||
mbedtls_md_free(&ctx);
|
||||
return (-1);
|
||||
}
|
||||
ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char *)pw,
|
||||
pw_len, salt, salt_len, rounds, derived_key_len, derived_key);
|
||||
|
||||
mbedtls_md_free(&ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H)
|
||||
|
||||
static int
|
||||
@ -269,6 +298,39 @@ aes_ctr_release(archive_crypto_ctx *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H)
|
||||
|
||||
static int
|
||||
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
mbedtls_aes_init(&ctx->ctx);
|
||||
ctx->key_len = key_len;
|
||||
memcpy(ctx->key, key, key_len);
|
||||
memset(ctx->nonce, 0, sizeof(ctx->nonce));
|
||||
ctx->encr_pos = AES_BLOCK_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
if (mbedtls_aes_setkey_enc(&ctx->ctx, ctx->key,
|
||||
ctx->key_len * 8) != 0)
|
||||
return (-1);
|
||||
if (mbedtls_aes_crypt_ecb(&ctx->ctx, MBEDTLS_AES_ENCRYPT, ctx->nonce,
|
||||
ctx->encr_buf) != 0)
|
||||
return (-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_release(archive_crypto_ctx *ctx)
|
||||
{
|
||||
mbedtls_aes_free(&ctx->ctx);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
|
||||
|
||||
static int
|
||||
@ -316,7 +378,14 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
memcpy(ctx->key, key, key_len);
|
||||
memset(ctx->nonce, 0, sizeof(ctx->nonce));
|
||||
ctx->encr_pos = AES_BLOCK_SIZE;
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
if (!EVP_CIPHER_CTX_reset(ctx->ctx)) {
|
||||
EVP_CIPHER_CTX_free(ctx->ctx);
|
||||
ctx->ctx = NULL;
|
||||
}
|
||||
#else
|
||||
EVP_CIPHER_CTX_init(ctx->ctx);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -23,13 +23,12 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
/*
|
||||
* On systems that do not support any recognized crypto libraries,
|
||||
* the archive_cryptor.c file will normally define no usable symbols.
|
||||
@ -83,6 +82,23 @@ typedef struct {
|
||||
unsigned encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H)
|
||||
#include <mbedtls/aes.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/pkcs5.h>
|
||||
|
||||
#define AES_MAX_KEY_SIZE 32
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
typedef struct {
|
||||
mbedtls_aes_context ctx;
|
||||
uint8_t key[AES_MAX_KEY_SIZE];
|
||||
unsigned key_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
uint8_t encr_buf[AES_BLOCK_SIZE];
|
||||
unsigned encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
|
||||
#if defined(HAVE_NETTLE_PBKDF2_H)
|
||||
#include <nettle/pbkdf2.h>
|
||||
|
@ -178,6 +178,40 @@ __archive_libsystem_md5final(archive_md5_ctx *ctx, void *md)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
|
||||
|
||||
static int
|
||||
__archive_mbedtls_md5init(archive_md5_ctx *ctx)
|
||||
{
|
||||
mbedtls_md5_init(ctx);
|
||||
if (mbedtls_md5_starts_ret(ctx) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_md5update(archive_md5_ctx *ctx, const void *indata,
|
||||
size_t insize)
|
||||
{
|
||||
if (mbedtls_md5_update_ret(ctx, indata, insize) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_md5final(archive_md5_ctx *ctx, void *md)
|
||||
{
|
||||
if (mbedtls_md5_finish_ret(ctx, md) == 0) {
|
||||
mbedtls_md5_free(ctx);
|
||||
return (ARCHIVE_OK);
|
||||
} else {
|
||||
mbedtls_md5_free(ctx);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
|
||||
|
||||
static int
|
||||
@ -335,6 +369,40 @@ __archive_libmd_ripemd160final(archive_rmd160_ctx *ctx, void *md)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
|
||||
|
||||
static int
|
||||
__archive_mbedtls_ripemd160init(archive_rmd160_ctx *ctx)
|
||||
{
|
||||
mbedtls_ripemd160_init(ctx);
|
||||
if (mbedtls_ripemd160_starts_ret(ctx) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
|
||||
size_t insize)
|
||||
{
|
||||
if (mbedtls_ripemd160_update_ret(ctx, indata, insize) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_ripemd160final(archive_rmd160_ctx *ctx, void *md)
|
||||
{
|
||||
if (mbedtls_ripemd160_finish_ret(ctx, md) == 0) {
|
||||
mbedtls_ripemd160_free(ctx);
|
||||
return (ARCHIVE_OK);
|
||||
} else {
|
||||
mbedtls_ripemd160_free(ctx);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
|
||||
|
||||
static int
|
||||
@ -491,6 +559,40 @@ __archive_libsystem_sha1final(archive_sha1_ctx *ctx, void *md)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha1init(archive_sha1_ctx *ctx)
|
||||
{
|
||||
mbedtls_sha1_init(ctx);
|
||||
if (mbedtls_sha1_starts_ret(ctx) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha1update(archive_sha1_ctx *ctx, const void *indata,
|
||||
size_t insize)
|
||||
{
|
||||
if (mbedtls_sha1_update_ret(ctx, indata, insize) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha1final(archive_sha1_ctx *ctx, void *md)
|
||||
{
|
||||
if (mbedtls_sha1_finish_ret(ctx, md) == 0) {
|
||||
mbedtls_sha1_free(ctx);
|
||||
return (ARCHIVE_OK);
|
||||
} else {
|
||||
mbedtls_sha1_free(ctx);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
|
||||
|
||||
static int
|
||||
@ -720,6 +822,40 @@ __archive_libsystem_sha256final(archive_sha256_ctx *ctx, void *md)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha256init(archive_sha256_ctx *ctx)
|
||||
{
|
||||
mbedtls_sha256_init(ctx);
|
||||
if (mbedtls_sha256_starts_ret(ctx, 0) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha256update(archive_sha256_ctx *ctx, const void *indata,
|
||||
size_t insize)
|
||||
{
|
||||
if (mbedtls_sha256_update_ret(ctx, indata, insize) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha256final(archive_sha256_ctx *ctx, void *md)
|
||||
{
|
||||
if (mbedtls_sha256_finish_ret(ctx, md) == 0) {
|
||||
mbedtls_sha256_free(ctx);
|
||||
return (ARCHIVE_OK);
|
||||
} else {
|
||||
mbedtls_sha256_free(ctx);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
|
||||
|
||||
static int
|
||||
@ -921,6 +1057,40 @@ __archive_libsystem_sha384final(archive_sha384_ctx *ctx, void *md)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha384init(archive_sha384_ctx *ctx)
|
||||
{
|
||||
mbedtls_sha512_init(ctx);
|
||||
if (mbedtls_sha512_starts_ret(ctx, 1) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha384update(archive_sha384_ctx *ctx, const void *indata,
|
||||
size_t insize)
|
||||
{
|
||||
if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha384final(archive_sha384_ctx *ctx, void *md)
|
||||
{
|
||||
if (mbedtls_sha512_finish_ret(ctx, md) == 0) {
|
||||
mbedtls_sha512_free(ctx);
|
||||
return (ARCHIVE_OK);
|
||||
} else {
|
||||
mbedtls_sha512_free(ctx);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
|
||||
|
||||
static int
|
||||
@ -1146,6 +1316,40 @@ __archive_libsystem_sha512final(archive_sha512_ctx *ctx, void *md)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha512init(archive_sha512_ctx *ctx)
|
||||
{
|
||||
mbedtls_sha512_init(ctx);
|
||||
if (mbedtls_sha512_starts_ret(ctx, 0) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha512update(archive_sha512_ctx *ctx, const void *indata,
|
||||
size_t insize)
|
||||
{
|
||||
if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
__archive_mbedtls_sha512final(archive_sha512_ctx *ctx, void *md)
|
||||
{
|
||||
if (mbedtls_sha512_finish_ret(ctx, md) == 0) {
|
||||
mbedtls_sha512_free(ctx);
|
||||
return (ARCHIVE_OK);
|
||||
} else {
|
||||
mbedtls_sha512_free(ctx);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
|
||||
|
||||
static int
|
||||
@ -1276,6 +1480,10 @@ const struct archive_digest __archive_digest =
|
||||
&__archive_libsystem_md5init,
|
||||
&__archive_libsystem_md5update,
|
||||
&__archive_libsystem_md5final,
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
|
||||
&__archive_mbedtls_md5init,
|
||||
&__archive_mbedtls_md5update,
|
||||
&__archive_mbedtls_md5final,
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
|
||||
&__archive_nettle_md5init,
|
||||
&__archive_nettle_md5update,
|
||||
@ -1303,6 +1511,10 @@ const struct archive_digest __archive_digest =
|
||||
&__archive_libmd_ripemd160init,
|
||||
&__archive_libmd_ripemd160update,
|
||||
&__archive_libmd_ripemd160final,
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
|
||||
&__archive_mbedtls_ripemd160init,
|
||||
&__archive_mbedtls_ripemd160update,
|
||||
&__archive_mbedtls_ripemd160final,
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
|
||||
&__archive_nettle_ripemd160init,
|
||||
&__archive_nettle_ripemd160update,
|
||||
@ -1330,6 +1542,10 @@ const struct archive_digest __archive_digest =
|
||||
&__archive_libsystem_sha1init,
|
||||
&__archive_libsystem_sha1update,
|
||||
&__archive_libsystem_sha1final,
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
|
||||
&__archive_mbedtls_sha1init,
|
||||
&__archive_mbedtls_sha1update,
|
||||
&__archive_mbedtls_sha1final,
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
|
||||
&__archive_nettle_sha1init,
|
||||
&__archive_nettle_sha1update,
|
||||
@ -1369,6 +1585,10 @@ const struct archive_digest __archive_digest =
|
||||
&__archive_libsystem_sha256init,
|
||||
&__archive_libsystem_sha256update,
|
||||
&__archive_libsystem_sha256final,
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
|
||||
&__archive_mbedtls_sha256init,
|
||||
&__archive_mbedtls_sha256update,
|
||||
&__archive_mbedtls_sha256final,
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
|
||||
&__archive_nettle_sha256init,
|
||||
&__archive_nettle_sha256update,
|
||||
@ -1404,6 +1624,10 @@ const struct archive_digest __archive_digest =
|
||||
&__archive_libsystem_sha384init,
|
||||
&__archive_libsystem_sha384update,
|
||||
&__archive_libsystem_sha384final,
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
|
||||
&__archive_mbedtls_sha384init,
|
||||
&__archive_mbedtls_sha384update,
|
||||
&__archive_mbedtls_sha384final,
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
|
||||
&__archive_nettle_sha384init,
|
||||
&__archive_nettle_sha384update,
|
||||
@ -1443,6 +1667,10 @@ const struct archive_digest __archive_digest =
|
||||
&__archive_libsystem_sha512init,
|
||||
&__archive_libsystem_sha512update,
|
||||
&__archive_libsystem_sha512final
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
|
||||
&__archive_mbedtls_sha512init,
|
||||
&__archive_mbedtls_sha512update,
|
||||
&__archive_mbedtls_sha512final
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
|
||||
&__archive_nettle_sha512init,
|
||||
&__archive_nettle_sha512update,
|
||||
|
@ -24,13 +24,12 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_DIGEST_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_DIGEST_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
|
||||
|
||||
/*
|
||||
* Crypto support in various Operating Systems:
|
||||
*
|
||||
@ -112,6 +111,24 @@
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#endif
|
||||
|
||||
/* mbed TLS crypto headers */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
|
||||
#include <mbedtls/md5.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
|
||||
#include <mbedtls/ripemd160.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
|
||||
#include <mbedtls/sha1.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
|
||||
#include <mbedtls/sha256.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
|
||||
#include <mbedtls/sha512.h>
|
||||
#endif
|
||||
|
||||
/* Nettle crypto headers */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_NETTLE)
|
||||
#include <nettle/md5.h>
|
||||
@ -159,6 +176,8 @@ typedef MD5_CTX archive_md5_ctx;
|
||||
typedef MD5_CTX archive_md5_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
|
||||
typedef CC_MD5_CTX archive_md5_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
|
||||
typedef mbedtls_md5_context archive_md5_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
|
||||
typedef struct md5_ctx archive_md5_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
|
||||
@ -173,6 +192,8 @@ typedef unsigned char archive_md5_ctx;
|
||||
typedef RMD160_CTX archive_rmd160_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
|
||||
typedef RIPEMD160_CTX archive_rmd160_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
|
||||
typedef mbedtls_ripemd160_context archive_rmd160_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
|
||||
typedef struct ripemd160_ctx archive_rmd160_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
|
||||
@ -187,6 +208,8 @@ typedef SHA1_CTX archive_sha1_ctx;
|
||||
typedef SHA1_CTX archive_sha1_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
|
||||
typedef CC_SHA1_CTX archive_sha1_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
|
||||
typedef mbedtls_sha1_context archive_sha1_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
|
||||
typedef struct sha1_ctx archive_sha1_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
|
||||
@ -207,6 +230,8 @@ typedef SHA2_CTX archive_sha256_ctx;
|
||||
typedef SHA256_CTX archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
|
||||
typedef CC_SHA256_CTX archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
|
||||
typedef mbedtls_sha256_context archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
|
||||
typedef struct sha256_ctx archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
|
||||
@ -225,6 +250,8 @@ typedef SHA384_CTX archive_sha384_ctx;
|
||||
typedef SHA2_CTX archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
|
||||
typedef CC_SHA512_CTX archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
|
||||
typedef mbedtls_sha512_context archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
|
||||
typedef struct sha384_ctx archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
|
||||
@ -245,6 +272,8 @@ typedef SHA2_CTX archive_sha512_ctx;
|
||||
typedef SHA512_CTX archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
|
||||
typedef CC_SHA512_CTX archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
|
||||
typedef mbedtls_sha512_context archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
|
||||
typedef struct sha512_ctx archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
|
||||
@ -259,6 +288,7 @@ typedef unsigned char archive_sha512_ctx;
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \
|
||||
defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_MD5_WIN)
|
||||
@ -272,6 +302,7 @@ typedef unsigned char archive_sha512_ctx;
|
||||
__archive_digest.md5update(ctx, buf, n)
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
|
||||
#define ARCHIVE_HAS_RMD160
|
||||
@ -286,6 +317,7 @@ typedef unsigned char archive_sha512_ctx;
|
||||
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \
|
||||
defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_WIN)
|
||||
@ -303,6 +335,7 @@ typedef unsigned char archive_sha512_ctx;
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_WIN)
|
||||
@ -319,6 +352,7 @@ typedef unsigned char archive_sha512_ctx;
|
||||
defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_WIN)
|
||||
@ -336,6 +370,7 @@ typedef unsigned char archive_sha512_ctx;
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_WIN)
|
||||
|
@ -145,10 +145,8 @@ sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
|
||||
cnt = facl(fd, cmd, cnt, aclp);
|
||||
}
|
||||
} else {
|
||||
if (aclp != NULL) {
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
}
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -28,16 +28,15 @@
|
||||
* Borrowed from FreeBSD's <sys/endian.h>
|
||||
*/
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#ifndef ARCHIVE_ENDIAN_H_INCLUDED
|
||||
#define ARCHIVE_ENDIAN_H_INCLUDED
|
||||
|
||||
/* Note: This is a purely internal header! */
|
||||
/* Do not use this outside of libarchive internal code! */
|
||||
|
||||
#ifndef ARCHIVE_ENDIAN_H_INCLUDED
|
||||
#define ARCHIVE_ENDIAN_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Disabling inline keyword for compilers known to choke on it:
|
||||
|
@ -32,7 +32,7 @@
|
||||
.Nm archive_entry_clear ,
|
||||
.Nm archive_entry_clone ,
|
||||
.Nm archive_entry_free ,
|
||||
.Nm archive_entry_new ,
|
||||
.Nm archive_entry_new
|
||||
.Nd functions for managing archive entry descriptions
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
@ -126,7 +126,6 @@ using the current locale.
|
||||
Similarly, if you store a wide string and then store a
|
||||
narrow string for the same data, the previously-set wide string will
|
||||
be discarded in favor of the new data.
|
||||
.Pp
|
||||
.\" .Sh EXAMPLE
|
||||
.\" .Sh RETURN VALUES
|
||||
.\" .Sh ERRORS
|
||||
@ -134,8 +133,8 @@ be discarded in favor of the new data.
|
||||
.Xr archive_entry_acl 3 ,
|
||||
.Xr archive_entry_paths 3 ,
|
||||
.Xr archive_entry_perms 3 ,
|
||||
.Xr archive_entry_time 3
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_entry_time 3 ,
|
||||
.Xr libarchive 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm libarchive
|
||||
|
@ -168,6 +168,7 @@ archive_entry_clear(struct archive_entry *entry)
|
||||
archive_entry_xattr_clear(entry);
|
||||
archive_entry_sparse_clear(entry);
|
||||
free(entry->stat);
|
||||
entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED;
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
return entry;
|
||||
}
|
||||
@ -202,6 +203,9 @@ archive_entry_clone(struct archive_entry *entry)
|
||||
entry2->ae_set = entry->ae_set;
|
||||
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
|
||||
|
||||
/* Copy symlink type */
|
||||
entry2->ae_symlink_type = entry->ae_symlink_type;
|
||||
|
||||
/* Copy encryption status */
|
||||
entry2->encryption = entry->encryption;
|
||||
|
||||
@ -253,6 +257,7 @@ archive_entry_new2(struct archive *a)
|
||||
if (entry == NULL)
|
||||
return (NULL);
|
||||
entry->archive = a;
|
||||
entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED;
|
||||
return (entry);
|
||||
}
|
||||
|
||||
@ -675,6 +680,12 @@ archive_entry_symlink(struct archive_entry *entry)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_symlink_type(struct archive_entry *entry)
|
||||
{
|
||||
return (entry->ae_symlink_type);
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_entry_symlink_utf8(struct archive_entry *entry)
|
||||
{
|
||||
@ -1245,6 +1256,12 @@ archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
|
||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_symlink_type(struct archive_entry *entry, int type)
|
||||
{
|
||||
entry->ae_symlink_type = type;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
|
||||
{
|
||||
@ -1560,10 +1577,8 @@ archive_entry_acl_text_compat(int *flags)
|
||||
const wchar_t *
|
||||
archive_entry_acl_text_w(struct archive_entry *entry, int flags)
|
||||
{
|
||||
if (entry->acl.acl_text_w != NULL) {
|
||||
free(entry->acl.acl_text_w);
|
||||
entry->acl.acl_text_w = NULL;
|
||||
}
|
||||
free(entry->acl.acl_text_w);
|
||||
entry->acl.acl_text_w = NULL;
|
||||
if (archive_entry_acl_text_compat(&flags) == 0)
|
||||
entry->acl.acl_text_w = archive_acl_to_text_w(&entry->acl,
|
||||
NULL, flags, entry->archive);
|
||||
@ -1574,10 +1589,8 @@ archive_entry_acl_text_w(struct archive_entry *entry, int flags)
|
||||
const char *
|
||||
archive_entry_acl_text(struct archive_entry *entry, int flags)
|
||||
{
|
||||
if (entry->acl.acl_text != NULL) {
|
||||
free(entry->acl.acl_text);
|
||||
entry->acl.acl_text = NULL;
|
||||
}
|
||||
free(entry->acl.acl_text);
|
||||
entry->acl.acl_text = NULL;
|
||||
if (archive_entry_acl_text_compat(&flags) == 0)
|
||||
entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, NULL,
|
||||
flags, NULL);
|
||||
@ -1590,10 +1603,8 @@ int
|
||||
_archive_entry_acl_text_l(struct archive_entry *entry, int flags,
|
||||
const char **acl_text, size_t *len, struct archive_string_conv *sc)
|
||||
{
|
||||
if (entry->acl.acl_text != NULL) {
|
||||
free(entry->acl.acl_text);
|
||||
entry->acl.acl_text = NULL;
|
||||
}
|
||||
free(entry->acl.acl_text);
|
||||
entry->acl.acl_text = NULL;
|
||||
|
||||
if (archive_entry_acl_text_compat(&flags) == 0)
|
||||
entry->acl.acl_text = archive_acl_to_text_l(&entry->acl,
|
||||
@ -1638,198 +1649,215 @@ _archive_entry_acl_text_l(struct archive_entry *entry, int flags,
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Supported file flags on FreeBSD and Mac OS:
|
||||
* sappnd,sappend SF_APPEND
|
||||
* arch,archived SF_ARCHIVED
|
||||
* schg,schange,simmutable SF_IMMUTABLE
|
||||
* sunlnk,sunlink SF_NOUNLINK (FreeBSD only)
|
||||
* uappnd,uappend UF_APPEND
|
||||
* compressed UF_COMPRESSED (Mac OS only)
|
||||
* hidden,uhidden UF_HIDDEN
|
||||
* uchg,uchange,uimmutable UF_IMMUTABLE
|
||||
* nodump UF_NODUMP
|
||||
* uunlnk,uunlink UF_NOUNLINK (FreeBSD only)
|
||||
* offline,uoffline UF_OFFLINE (FreeBSD only)
|
||||
* opaque UF_OPAQUE
|
||||
* rdonly,urdonly,readonly UF_READONLY (FreeBSD only)
|
||||
* reparse,ureparse UF_REPARSE (FreeBSD only)
|
||||
* sparse,usparse UF_SPARSE (FreeBSD only)
|
||||
* system,usystem UF_SYSTEM (FreeBSD only)
|
||||
*
|
||||
* See chflags(2) for more information
|
||||
*
|
||||
* Supported file attributes on Linux:
|
||||
* a append only FS_APPEND_FL sappnd
|
||||
* A no atime updates FS_NOATIME_FL atime
|
||||
* c compress FS_COMPR_FL compress
|
||||
* C no copy on write FS_NOCOW_FL cow
|
||||
* d no dump FS_NODUMP_FL dump
|
||||
* D synchronous directory updates FS_DIRSYNC_FL dirsync
|
||||
* i immutable FS_IMMUTABLE_FL schg
|
||||
* j data journalling FS_JOURNAL_DATA_FL journal
|
||||
* P project hierarchy FS_PROJINHERIT_FL projinherit
|
||||
* s secure deletion FS_SECRM_FL securedeletion
|
||||
* S synchronous updates FS_SYNC_FL sync
|
||||
* t no tail-merging FS_NOTAIL_FL tail
|
||||
* T top of directory hierarchy FS_TOPDIR_FL topdir
|
||||
* u undeletable FS_UNRM_FL undel
|
||||
*
|
||||
* See ioctl_iflags(2) for more information
|
||||
*
|
||||
* Equivalent file flags supported on FreeBSD / Mac OS and Linux:
|
||||
* SF_APPEND FS_APPEND_FL sappnd
|
||||
* SF_IMMUTABLE FS_IMMUTABLE_FL schg
|
||||
* UF_NODUMP FS_NODUMP_FL nodump
|
||||
*/
|
||||
|
||||
static const struct flag {
|
||||
const char *name;
|
||||
const wchar_t *wname;
|
||||
unsigned long set;
|
||||
unsigned long clear;
|
||||
} flags[] = {
|
||||
} fileflags[] = {
|
||||
/* Preferred (shorter) names per flag first, all prefixed by "no" */
|
||||
#ifdef SF_APPEND
|
||||
{ "nosappnd", L"nosappnd", SF_APPEND, 0 },
|
||||
{ "nosappend", L"nosappend", SF_APPEND, 0 },
|
||||
{ "nosappnd", L"nosappnd", SF_APPEND, 0},
|
||||
{ "nosappend", L"nosappend", SF_APPEND, 0},
|
||||
#endif
|
||||
#if defined(FS_APPEND_FL) /* 'a' */
|
||||
{ "nosappnd", L"nosappnd", FS_APPEND_FL, 0 },
|
||||
{ "nosappend", L"nosappend", FS_APPEND_FL, 0 },
|
||||
{ "nosappnd", L"nosappnd", FS_APPEND_FL, 0},
|
||||
{ "nosappend", L"nosappend", FS_APPEND_FL, 0},
|
||||
#elif defined(EXT2_APPEND_FL) /* 'a' */
|
||||
{ "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0 },
|
||||
{ "nosappend", L"nosappend", EXT2_APPEND_FL, 0 },
|
||||
{ "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0},
|
||||
{ "nosappend", L"nosappend", EXT2_APPEND_FL, 0},
|
||||
#endif
|
||||
#ifdef SF_ARCHIVED
|
||||
{ "noarch", L"noarch", SF_ARCHIVED, 0 },
|
||||
{ "noarchived", L"noarchived", SF_ARCHIVED, 0 },
|
||||
{ "noarch", L"noarch", SF_ARCHIVED, 0},
|
||||
{ "noarchived", L"noarchived", SF_ARCHIVED, 0},
|
||||
#endif
|
||||
#ifdef SF_IMMUTABLE
|
||||
{ "noschg", L"noschg", SF_IMMUTABLE, 0 },
|
||||
{ "noschange", L"noschange", SF_IMMUTABLE, 0 },
|
||||
{ "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0 },
|
||||
{ "noschg", L"noschg", SF_IMMUTABLE, 0},
|
||||
{ "noschange", L"noschange", SF_IMMUTABLE, 0},
|
||||
{ "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0},
|
||||
#endif
|
||||
#if defined(FS_IMMUTABLE_FL) /* 'i' */
|
||||
{ "noschg", L"noschg", FS_IMMUTABLE_FL, 0 },
|
||||
{ "noschange", L"noschange", FS_IMMUTABLE_FL, 0 },
|
||||
{ "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0 },
|
||||
{ "noschg", L"noschg", FS_IMMUTABLE_FL, 0},
|
||||
{ "noschange", L"noschange", FS_IMMUTABLE_FL, 0},
|
||||
{ "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0},
|
||||
#elif defined(EXT2_IMMUTABLE_FL) /* 'i' */
|
||||
{ "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0 },
|
||||
{ "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0 },
|
||||
{ "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0 },
|
||||
{ "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0},
|
||||
{ "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0},
|
||||
{ "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0},
|
||||
#endif
|
||||
#ifdef SF_NOUNLINK
|
||||
{ "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0 },
|
||||
{ "nosunlink", L"nosunlink", SF_NOUNLINK, 0 },
|
||||
#endif
|
||||
#ifdef SF_SNAPSHOT
|
||||
{ "nosnapshot", L"nosnapshot", SF_SNAPSHOT, 0 },
|
||||
{ "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0},
|
||||
{ "nosunlink", L"nosunlink", SF_NOUNLINK, 0},
|
||||
#endif
|
||||
#ifdef UF_APPEND
|
||||
{ "nouappnd", L"nouappnd", UF_APPEND, 0 },
|
||||
{ "nouappend", L"nouappend", UF_APPEND, 0 },
|
||||
{ "nouappnd", L"nouappnd", UF_APPEND, 0},
|
||||
{ "nouappend", L"nouappend", UF_APPEND, 0},
|
||||
#endif
|
||||
#ifdef UF_IMMUTABLE
|
||||
{ "nouchg", L"nouchg", UF_IMMUTABLE, 0 },
|
||||
{ "nouchange", L"nouchange", UF_IMMUTABLE, 0 },
|
||||
{ "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0 },
|
||||
{ "nouchg", L"nouchg", UF_IMMUTABLE, 0},
|
||||
{ "nouchange", L"nouchange", UF_IMMUTABLE, 0},
|
||||
{ "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0},
|
||||
#endif
|
||||
#ifdef UF_NODUMP
|
||||
{ "nodump", L"nodump", 0, UF_NODUMP},
|
||||
#endif
|
||||
#if defined(FS_NODUMP_FL) /* 'd' */
|
||||
{ "nodump", L"nodump", 0, FS_NODUMP_FL},
|
||||
#elif defined(EXT2_NODUMP_FL) /* 'd' */
|
||||
#elif defined(EXT2_NODUMP_FL)
|
||||
{ "nodump", L"nodump", 0, EXT2_NODUMP_FL},
|
||||
#endif
|
||||
#ifdef UF_OPAQUE
|
||||
{ "noopaque", L"noopaque", UF_OPAQUE, 0 },
|
||||
{ "noopaque", L"noopaque", UF_OPAQUE, 0},
|
||||
#endif
|
||||
#ifdef UF_NOUNLINK
|
||||
{ "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0 },
|
||||
{ "nouunlink", L"nouunlink", UF_NOUNLINK, 0 },
|
||||
{ "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0},
|
||||
{ "nouunlink", L"nouunlink", UF_NOUNLINK, 0},
|
||||
#endif
|
||||
#ifdef UF_COMPRESSED
|
||||
{ "nocompressed",L"nocompressed", UF_COMPRESSED, 0 },
|
||||
/* Mac OS */
|
||||
{ "nocompressed", L"nocompressed", UF_COMPRESSED, 0},
|
||||
#endif
|
||||
#ifdef UF_HIDDEN
|
||||
{ "nohidden", L"nohidden", UF_HIDDEN, 0 },
|
||||
{ "nohidden", L"nohidden", UF_HIDDEN, 0},
|
||||
{ "nouhidden", L"nouhidden", UF_HIDDEN, 0},
|
||||
#endif
|
||||
#if defined(FS_UNRM_FL)
|
||||
{ "nouunlink", L"nouunlink", FS_UNRM_FL, 0},
|
||||
#ifdef FILE_ATTRIBUTE_HIDDEN
|
||||
{ "nohidden", L"nohidden", FILE_ATTRIBUTE_HIDDEN, 0},
|
||||
{ "nouhidden", L"nouhidden", FILE_ATTRIBUTE_HIDDEN, 0},
|
||||
#endif
|
||||
#ifdef UF_OFFLINE
|
||||
{ "nooffline", L"nooffline", UF_OFFLINE, 0},
|
||||
{ "nouoffline", L"nouoffline", UF_OFFLINE, 0},
|
||||
#endif
|
||||
#ifdef UF_READONLY
|
||||
{ "nordonly", L"nordonly", UF_READONLY, 0},
|
||||
{ "nourdonly", L"nourdonly", UF_READONLY, 0},
|
||||
{ "noreadonly", L"noreadonly", UF_READONLY, 0},
|
||||
#endif
|
||||
#ifdef FILE_ATTRIBUTE_READONLY
|
||||
{ "nordonly", L"nordonly", FILE_ATTRIBUTE_READONLY, 0},
|
||||
{ "nourdonly", L"nourdonly", FILE_ATTRIBUTE_READONLY, 0},
|
||||
{ "noreadonly", L"noreadonly", FILE_ATTRIBUTE_READONLY, 0},
|
||||
#endif
|
||||
#ifdef UF_SPARSE
|
||||
{ "nosparse", L"nosparse", UF_SPARSE, 0},
|
||||
{ "nousparse", L"nousparse", UF_SPARSE, 0},
|
||||
#endif
|
||||
#ifdef UF_REPARSE
|
||||
{ "noreparse", L"noreparse", UF_REPARSE, 0},
|
||||
{ "noureparse", L"noureparse", UF_REPARSE, 0},
|
||||
#endif
|
||||
#ifdef UF_SYSTEM
|
||||
{ "nosystem", L"nosystem", UF_SYSTEM, 0},
|
||||
{ "nousystem", L"nousystem", UF_SYSTEM, 0},
|
||||
#endif
|
||||
#ifdef FILE_ATTRIBUTE_SYSTEM
|
||||
{ "nosystem", L"nosystem", FILE_ATTRIBUTE_SYSTEM, 0},
|
||||
{ "nousystem", L"nousystem", FILE_ATTRIBUTE_SYSTEM, 0},
|
||||
#endif
|
||||
#if defined(FS_UNRM_FL) /* 'u' */
|
||||
{ "noundel", L"noundel", FS_UNRM_FL, 0},
|
||||
#elif defined(EXT2_UNRM_FL)
|
||||
{ "nouunlink", L"nouunlink", EXT2_UNRM_FL, 0},
|
||||
{ "noundel", L"noundel", EXT2_UNRM_FL, 0},
|
||||
#endif
|
||||
|
||||
#if defined(FS_BTREE_FL)
|
||||
{ "nobtree", L"nobtree", FS_BTREE_FL, 0 },
|
||||
#elif defined(EXT2_BTREE_FL)
|
||||
{ "nobtree", L"nobtree", EXT2_BTREE_FL, 0 },
|
||||
#if defined(FS_COMPR_FL) /* 'c' */
|
||||
{ "nocompress", L"nocompress", FS_COMPR_FL, 0},
|
||||
#elif defined(EXT2_COMPR_FL)
|
||||
{ "nocompress", L"nocompress", EXT2_COMPR_FL, 0},
|
||||
#endif
|
||||
|
||||
#if defined(FS_ECOMPR_FL)
|
||||
{ "nocomperr", L"nocomperr", FS_ECOMPR_FL, 0 },
|
||||
#elif defined(EXT2_ECOMPR_FL)
|
||||
{ "nocomperr", L"nocomperr", EXT2_ECOMPR_FL, 0 },
|
||||
#if defined(FS_NOATIME_FL) /* 'A' */
|
||||
{ "noatime", L"noatime", 0, FS_NOATIME_FL},
|
||||
#elif defined(EXT2_NOATIME_FL)
|
||||
{ "noatime", L"noatime", 0, EXT2_NOATIME_FL},
|
||||
#endif
|
||||
|
||||
#if defined(FS_COMPR_FL) /* 'c' */
|
||||
{ "nocompress", L"nocompress", FS_COMPR_FL, 0 },
|
||||
#elif defined(EXT2_COMPR_FL) /* 'c' */
|
||||
{ "nocompress", L"nocompress", EXT2_COMPR_FL, 0 },
|
||||
#endif
|
||||
|
||||
#if defined(FS_NOATIME_FL) /* 'A' */
|
||||
{ "noatime", L"noatime", 0, FS_NOATIME_FL},
|
||||
#elif defined(EXT2_NOATIME_FL) /* 'A' */
|
||||
{ "noatime", L"noatime", 0, EXT2_NOATIME_FL},
|
||||
#endif
|
||||
|
||||
#if defined(FS_DIRTY_FL)
|
||||
{ "nocompdirty",L"nocompdirty", FS_DIRTY_FL, 0},
|
||||
#elif defined(EXT2_DIRTY_FL)
|
||||
{ "nocompdirty",L"nocompdirty", EXT2_DIRTY_FL, 0},
|
||||
#endif
|
||||
|
||||
#if defined(FS_COMPRBLK_FL)
|
||||
#if defined(FS_NOCOMPR_FL)
|
||||
{ "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, FS_NOCOMPR_FL},
|
||||
#else
|
||||
{ "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, 0},
|
||||
#endif
|
||||
#elif defined(EXT2_COMPRBLK_FL)
|
||||
#if defined(EXT2_NOCOMPR_FL)
|
||||
{ "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, EXT2_NOCOMPR_FL},
|
||||
#else
|
||||
{ "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, 0},
|
||||
#endif
|
||||
#endif
|
||||
#if defined(FS_DIRSYNC_FL)
|
||||
{ "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0},
|
||||
#if defined(FS_DIRSYNC_FL) /* 'D' */
|
||||
{ "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0},
|
||||
#elif defined(EXT2_DIRSYNC_FL)
|
||||
{ "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0},
|
||||
{ "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0},
|
||||
#endif
|
||||
#if defined(FS_INDEX_FL)
|
||||
{ "nohashidx", L"nohashidx", FS_INDEX_FL, 0},
|
||||
#elif defined(EXT2_INDEX_FL)
|
||||
{ "nohashidx", L"nohashidx", EXT2_INDEX_FL, 0},
|
||||
#endif
|
||||
#if defined(FS_IMAGIC_FL)
|
||||
{ "noimagic", L"noimagic", FS_IMAGIC_FL, 0},
|
||||
#elif defined(EXT2_IMAGIC_FL)
|
||||
{ "noimagic", L"noimagic", EXT2_IMAGIC_FL, 0},
|
||||
#endif
|
||||
#if defined(FS_JOURNAL_DATA_FL)
|
||||
{ "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0},
|
||||
#if defined(FS_JOURNAL_DATA_FL) /* 'j' */
|
||||
{ "nojournal-data",L"nojournal-data", FS_JOURNAL_DATA_FL, 0},
|
||||
{ "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0},
|
||||
#elif defined(EXT3_JOURNAL_DATA_FL)
|
||||
{ "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0},
|
||||
{ "nojournal-data",L"nojournal-data", EXT3_JOURNAL_DATA_FL, 0},
|
||||
{ "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0},
|
||||
#endif
|
||||
#if defined(FS_SECRM_FL)
|
||||
{ "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0},
|
||||
#if defined(FS_SECRM_FL) /* 's' */
|
||||
{ "nosecdel", L"nosecdel", FS_SECRM_FL, 0},
|
||||
{ "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0},
|
||||
#elif defined(EXT2_SECRM_FL)
|
||||
{ "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0},
|
||||
{ "nosecdel", L"nosecdel", EXT2_SECRM_FL, 0},
|
||||
{ "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0},
|
||||
#endif
|
||||
#if defined(FS_SYNC_FL)
|
||||
{ "nosync", L"nosync", FS_SYNC_FL, 0},
|
||||
#if defined(FS_SYNC_FL) /* 'S' */
|
||||
{ "nosync", L"nosync", FS_SYNC_FL, 0},
|
||||
#elif defined(EXT2_SYNC_FL)
|
||||
{ "nosync", L"nosync", EXT2_SYNC_FL, 0},
|
||||
{ "nosync", L"nosync", EXT2_SYNC_FL, 0},
|
||||
#endif
|
||||
#if defined(FS_NOTAIL_FL)
|
||||
{ "notail", L"notail", 0, FS_NOTAIL_FL},
|
||||
#if defined(FS_NOTAIL_FL) /* 't' */
|
||||
{ "notail", L"notail", 0, FS_NOTAIL_FL},
|
||||
#elif defined(EXT2_NOTAIL_FL)
|
||||
{ "notail", L"notail", 0, EXT2_NOTAIL_FL},
|
||||
{ "notail", L"notail", 0, EXT2_NOTAIL_FL},
|
||||
#endif
|
||||
#if defined(FS_TOPDIR_FL)
|
||||
{ "notopdir", L"notopdir", FS_TOPDIR_FL, 0},
|
||||
#if defined(FS_TOPDIR_FL) /* 'T' */
|
||||
{ "notopdir", L"notopdir", FS_TOPDIR_FL, 0},
|
||||
#elif defined(EXT2_TOPDIR_FL)
|
||||
{ "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0},
|
||||
{ "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0},
|
||||
#endif
|
||||
#ifdef FS_ENCRYPT_FL
|
||||
{ "noencrypt", L"noencrypt", FS_ENCRYPT_FL, 0},
|
||||
#ifdef FS_NOCOW_FL /* 'C' */
|
||||
{ "nocow", L"nocow", 0, FS_NOCOW_FL},
|
||||
#endif
|
||||
#ifdef FS_HUGE_FILE_FL
|
||||
{ "nohugefile", L"nohugefile", FS_HUGE_FILE_FL, 0},
|
||||
#ifdef FS_PROJINHERIT_FL /* 'P' */
|
||||
{ "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0},
|
||||
#endif
|
||||
#ifdef FS_EXTENT_FL
|
||||
{ "noextent", L"noextent", FS_EXTENT_FL, 0},
|
||||
#endif
|
||||
#ifdef FS_EA_INODE_FL
|
||||
{ "noeainode", L"noeainode", FS_EA_INODE_FL, 0},
|
||||
#endif
|
||||
#ifdef FS_EOFBLOCKS_FL
|
||||
{ "noeofblocks",L"noeofblocks", FS_EOFBLOCKS_FL, 0},
|
||||
#endif
|
||||
#ifdef FS_NOCOW_FL
|
||||
{ "nocow", L"nocow", FS_NOCOW_FL, 0},
|
||||
#endif
|
||||
#ifdef FS_INLINE_DATA_FL
|
||||
{ "noinlinedata",L"noinlinedata", FS_INLINE_DATA_FL, 0},
|
||||
#endif
|
||||
#ifdef FS_PROJINHERIT_FL
|
||||
{ "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0},
|
||||
#endif
|
||||
#if defined(FS_RESERVED_FL)
|
||||
{ "noreserved", L"noreserved", FS_RESERVED_FL, 0},
|
||||
#elif defined(EXT2_RESERVED_FL)
|
||||
{ "noreserved", L"noreserved", EXT2_RESERVED_FL, 0},
|
||||
#endif
|
||||
{ NULL, NULL, 0, 0 }
|
||||
{ NULL, NULL, 0, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1848,7 +1876,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
|
||||
|
||||
bits = bitset | bitclear;
|
||||
length = 0;
|
||||
for (flag = flags; flag->name != NULL; flag++)
|
||||
for (flag = fileflags; flag->name != NULL; flag++)
|
||||
if (bits & (flag->set | flag->clear)) {
|
||||
length += strlen(flag->name) + 1;
|
||||
bits &= ~(flag->set | flag->clear);
|
||||
@ -1861,7 +1889,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
|
||||
return (NULL);
|
||||
|
||||
dp = string;
|
||||
for (flag = flags; flag->name != NULL; flag++) {
|
||||
for (flag = fileflags; flag->name != NULL; flag++) {
|
||||
if (bitset & flag->set || bitclear & flag->clear) {
|
||||
sp = flag->name + 2;
|
||||
} else if (bitset & flag->clear || bitclear & flag->set) {
|
||||
@ -1913,7 +1941,7 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
|
||||
*end != ' ' && *end != ',')
|
||||
end++;
|
||||
length = end - start;
|
||||
for (flag = flags; flag->name != NULL; flag++) {
|
||||
for (flag = fileflags; flag->name != NULL; flag++) {
|
||||
size_t flag_length = strlen(flag->name);
|
||||
if (length == flag_length
|
||||
&& memcmp(start, flag->name, length) == 0) {
|
||||
@ -1981,7 +2009,7 @@ ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp)
|
||||
*end != L' ' && *end != L',')
|
||||
end++;
|
||||
length = end - start;
|
||||
for (flag = flags; flag->wname != NULL; flag++) {
|
||||
for (flag = fileflags; flag->wname != NULL; flag++) {
|
||||
size_t flag_length = wcslen(flag->wname);
|
||||
if (length == flag_length
|
||||
&& wmemcmp(start, flag->wname, length) == 0) {
|
||||
|
@ -30,7 +30,7 @@
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3003003
|
||||
#define ARCHIVE_VERSION_NUMBER 3004002
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
@ -190,6 +190,13 @@ struct archive_entry;
|
||||
#define AE_IFDIR ((__LA_MODE_T)0040000)
|
||||
#define AE_IFIFO ((__LA_MODE_T)0010000)
|
||||
|
||||
/*
|
||||
* Symlink types
|
||||
*/
|
||||
#define AE_SYMLINK_TYPE_UNDEFINED 0
|
||||
#define AE_SYMLINK_TYPE_FILE 1
|
||||
#define AE_SYMLINK_TYPE_DIRECTORY 2
|
||||
|
||||
/*
|
||||
* Basic object manipulation
|
||||
*/
|
||||
@ -275,6 +282,7 @@ __LA_DECL int archive_entry_size_is_set(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_symlink_type(struct archive_entry *);
|
||||
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
|
||||
__LA_DECL la_int64_t archive_entry_uid(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
|
||||
@ -350,6 +358,7 @@ __LA_DECL void archive_entry_unset_size(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
|
||||
__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_symlink_type(struct archive_entry *, int);
|
||||
__LA_DECL void archive_entry_set_symlink_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
|
||||
@ -515,9 +524,6 @@ __LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type
|
||||
__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
|
||||
int * /* type */, int * /* permset */, int * /* tag */,
|
||||
int * /* qual */, const char ** /* name */);
|
||||
__LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type */,
|
||||
int * /* type */, int * /* permset */, int * /* tag */,
|
||||
int * /* qual */, const wchar_t ** /* name */);
|
||||
|
||||
/*
|
||||
* Construct a text-format ACL. The flags argument is a bitmask that
|
||||
@ -692,7 +698,6 @@ __LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
|
||||
struct archive_entry **, struct archive_entry **);
|
||||
__LA_DECL struct archive_entry *archive_entry_partial_links(
|
||||
struct archive_entry_linkresolver *res, unsigned int *links);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -34,7 +34,6 @@
|
||||
.Nm archive_entry_acl_from_text ,
|
||||
.Nm archive_entry_acl_from_text_w ,
|
||||
.Nm archive_entry_acl_next ,
|
||||
.Nm archive_entry_acl_next_w ,
|
||||
.Nm archive_entry_acl_reset ,
|
||||
.Nm archive_entry_acl_to_text ,
|
||||
.Nm archive_entry_acl_to_text_w ,
|
||||
@ -89,16 +88,6 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Fa "const char **ret_name"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_entry_acl_next_w
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "int type"
|
||||
.Fa "int *ret_type"
|
||||
.Fa "int *ret_permset"
|
||||
.Fa "int *ret_tag"
|
||||
.Fa "int *ret_qual"
|
||||
.Fa "const wchar_t **ret_name"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_entry_acl_reset "struct archive_entry *a" "int type"
|
||||
.Ft char *
|
||||
.Fo archive_entry_acl_to_text
|
||||
@ -118,15 +107,16 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Dq Access Control Lists (ACLs)
|
||||
extend the standard Unix perssion model.
|
||||
extend the standard Unix permission model.
|
||||
The ACL interface of
|
||||
.Nm libarchive
|
||||
supports both POSIX.1e and NFSv4 style ACLs. Use of ACLs is restricted by
|
||||
supports both POSIX.1e and NFSv4 style ACLs.
|
||||
Use of ACLs is restricted by
|
||||
various levels of ACL support in operating systems, file systems and archive
|
||||
formats.
|
||||
.Ss POSIX.1e Access Control Lists
|
||||
A POSIX.1e ACL consists of a number of independent entries.
|
||||
Each entry specifies the permission set as bitmask of basic permissions.
|
||||
Each entry specifies the permission set as a bitmask of basic permissions.
|
||||
Valid permissions in the
|
||||
.Fa permset
|
||||
are:
|
||||
@ -147,13 +137,13 @@ The user specified by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
|
||||
The owner of the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_GROUP
|
||||
The group specied by the name field.
|
||||
The group specified by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
|
||||
The group who owns the file.
|
||||
The group which owns the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_MASK
|
||||
The maximum permissions to be obtained via group permissions.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_OTHER
|
||||
Any principal who is not file owner or a member of the owning group.
|
||||
Any principal who is not the file owner or a member of the owning group.
|
||||
.El
|
||||
.Pp
|
||||
The principals
|
||||
@ -164,12 +154,12 @@ and
|
||||
are equivalent to user, group and other in the classic Unix permission
|
||||
model and specify non-extended ACL entries.
|
||||
.Pp
|
||||
All files with have an access ACL
|
||||
All files have an access ACL
|
||||
.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS .
|
||||
This specifies the permissions required for access to the file itself.
|
||||
Directories have an additional ACL
|
||||
.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT ,
|
||||
which controls the initial access ACL for newly created directory entries.
|
||||
which controls the initial access ACL for newly-created directory entries.
|
||||
.Ss NFSv4 Access Control Lists
|
||||
A NFSv4 ACL consists of multiple individual entries called Access Control
|
||||
Entries (ACEs).
|
||||
@ -197,11 +187,11 @@ The user specified by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
|
||||
The owner of the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_GROUP
|
||||
The group specied by the name field.
|
||||
The group specified by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
|
||||
The group who owns the file.
|
||||
The group which owns the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_EVERYONE
|
||||
Any principal who is not file owner or a member of the owning group.
|
||||
Any principal who is not the file owner or a member of the owning group.
|
||||
.El
|
||||
.Pp
|
||||
Entries with the
|
||||
@ -216,9 +206,10 @@ integer.
|
||||
.Pp
|
||||
NFSv4 ACE permissions and flags are stored in the same
|
||||
.Fa permset
|
||||
bitfield. Some permissions share the same constant and permission character but
|
||||
have different effect on directories than on files. The following ACE
|
||||
permissions are supported:
|
||||
bitfield.
|
||||
Some permissions share the same constant and permission character
|
||||
but have different effect on directories than on files.
|
||||
The following ACE permissions are supported:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ_DATA ( Sy r )
|
||||
Read data (file).
|
||||
@ -265,7 +256,8 @@ Inherit parent directory ACE to subdirectories.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY ( Sy i )
|
||||
Only inherit, do not apply the permission on the directory itself.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT ( Sy n )
|
||||
Do not propagate inherit flags. Only first-level entries inherit ACLs.
|
||||
Do not propagate inherit flags.
|
||||
Only first-level entries inherit ACLs.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS ( Sy S )
|
||||
Trigger alarm or audit on successful access.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS ( Sy F )
|
||||
@ -279,8 +271,8 @@ and
|
||||
.Fn archive_entry_acl_add_entry_w
|
||||
add a single ACL entry.
|
||||
For the access ACL and non-extended principals, the classic Unix permissions
|
||||
are updated. An archive entry cannot contain both POSIX.1e and NFSv4 ACL
|
||||
entries.
|
||||
are updated.
|
||||
An archive entry cannot contain both POSIX.1e and NFSv4 ACL entries.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_clear
|
||||
removes all ACL entries and resets the enumeration pointer.
|
||||
@ -300,7 +292,8 @@ for POSIX.1e ACLs and
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_AUDIT
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALARM
|
||||
.El
|
||||
for NFSv4 ACLs. For POSIX.1e ACLs if
|
||||
for NFSv4 ACLs.
|
||||
For POSIX.1e ACLs if
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
is included and at least one extended ACL entry is found,
|
||||
the three non-extended ACLs are added.
|
||||
@ -312,7 +305,8 @@ add new
|
||||
.Pq or merge with existing
|
||||
ACL entries from
|
||||
.Pq wide
|
||||
text. The argument
|
||||
text.
|
||||
The argument
|
||||
.Fa type
|
||||
may take one of the following values:
|
||||
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_DEFAULT"
|
||||
@ -322,11 +316,13 @@ may take one of the following values:
|
||||
.El
|
||||
Supports all formats that can be created with
|
||||
.Fn archive_entry_acl_to_text
|
||||
or respective
|
||||
or respectively
|
||||
.Fn archive_entry_acl_to_text_w .
|
||||
Existing ACL entries are preserved. To get a clean new ACL from text
|
||||
Existing ACL entries are preserved.
|
||||
To get a clean new ACL from text
|
||||
.Fn archive_entry_acl_clear
|
||||
must be called first. Entries prefixed with
|
||||
must be called first.
|
||||
Entries prefixed with
|
||||
.Dq default:
|
||||
are treated as
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
@ -342,8 +338,6 @@ character
|
||||
are skipped.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_next
|
||||
and
|
||||
.Fn archive_entry_acl_next_w
|
||||
return the next entry of the ACL list.
|
||||
This functions may only be called after
|
||||
.Fn archive_entry_acl_reset
|
||||
@ -351,10 +345,8 @@ has indicated the presence of extended ACL entries.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_reset
|
||||
prepare reading the list of ACL entries with
|
||||
.Fn archive_entry_acl_next
|
||||
or
|
||||
.Fn archive_entry_acl_next_w .
|
||||
The function returns either 0, if no non-extended ACLs are found.
|
||||
.Fn archive_entry_acl_next .
|
||||
The function returns 0 if no non-extended ACLs are found.
|
||||
In this case, the access permissions should be obtained by
|
||||
.Xr archive_entry_mode 3
|
||||
or set using
|
||||
@ -367,7 +359,8 @@ and
|
||||
.Fn archive_entry_acl_to_text_w
|
||||
convert the ACL entries for the given type into a
|
||||
.Pq wide
|
||||
string of ACL entries separated by newline. If the pointer
|
||||
string of ACL entries separated by newline.
|
||||
If the pointer
|
||||
.Fa len_p
|
||||
is not NULL, then the function shall return the length of the string
|
||||
.Pq not including the NULL terminator
|
||||
@ -415,7 +408,8 @@ are prefixed with
|
||||
.Dq default: .
|
||||
.Pp
|
||||
.Fn archive_entry_acl_types
|
||||
get ACL entry types contained in an archive entry's ACL. As POSIX.1e and NFSv4
|
||||
get ACL entry types contained in an archive entry's ACL.
|
||||
As POSIX.1e and NFSv4
|
||||
ACL entries cannot be mixed, this function is a very efficient way to detect if
|
||||
an ACL already contains POSIX.1e or NFSv4 ACL entries.
|
||||
.Sh RETURN VALUES
|
||||
@ -438,9 +432,7 @@ if all entries were successfully parsed and
|
||||
if one or more entries were invalid or non-parseable.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_next
|
||||
and
|
||||
.Fn archive_entry_acl_next_w
|
||||
return
|
||||
returns
|
||||
.Dv ARCHIVE_OK
|
||||
on success,
|
||||
.Dv ARCHIVE_EOF
|
||||
|
@ -25,13 +25,13 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
|
||||
#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
|
||||
#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
|
||||
|
||||
struct archive_entry;
|
||||
struct archive_string_conv;
|
||||
|
||||
|
63
libarchive/archive_entry_misc.3
Normal file
63
libarchive/archive_entry_misc.3
Normal file
@ -0,0 +1,63 @@
|
||||
.\" Copyright (c) 2019 Martin Matuska
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd April 15, 2019
|
||||
.Dt ARCHIVE_ENTRY_MISC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_entry_symlink_type ,
|
||||
.Nm archive_entry_set_symlink_type
|
||||
.Nd miscellaneous functions for manipulating properties of archive_entry
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive_entry.h
|
||||
.Ft int
|
||||
.Fn archive_entry_symlink_type "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_symlink_type "struct archive_entry *a" "int"
|
||||
.Sh DESCRIPTION
|
||||
The function
|
||||
.Fn archive_entry_symlink_type
|
||||
returns and the function
|
||||
.Fn archive_entry_set_symlink_type
|
||||
sets the type of the symbolic link stored in an archive entry.
|
||||
These functions
|
||||
have special meaning on operating systems that support multiple symbolic link
|
||||
types (e.g. Microsoft Windows).
|
||||
.Pp
|
||||
Supported values are:
|
||||
.Bl -tag -width "AE_SYMLINK_TYPE_DIRECTORY" -compact
|
||||
.It AE_SYMLINK_TYPE_UNDEFINED
|
||||
Symbolic link target type is not defined (default on unix systems)
|
||||
.It AE_SYMLINK_TYPE_FILE
|
||||
Symbolic link points to a file
|
||||
.It AE_SYMLINK_TYPE_DIRECTORY
|
||||
Symbolic link points to a directory
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr archive_entry_paths 3 ,
|
||||
.Xr archive_entry_stat 3 ,
|
||||
.Xr libarchive 3
|
@ -133,7 +133,7 @@ The accessor functions are named
|
||||
.Fn XXX_w .
|
||||
.It UTF-8
|
||||
Unicode strings encoded as UTF-8.
|
||||
This are convience functions to update both the multibyte and wide
|
||||
These are convenience functions to update both the multibyte and wide
|
||||
character strings at the same time.
|
||||
.El
|
||||
.Pp
|
||||
@ -141,13 +141,13 @@ The sourcepath is a pure filesystem concept and never stored in an
|
||||
archive directly.
|
||||
.Pp
|
||||
For that reason, it is only available as multibyte string.
|
||||
The link path is a convience function for conditionally setting
|
||||
The link path is a convenience function for conditionally setting
|
||||
hardlink or symlink destination.
|
||||
It doesn't have a corresponding get accessor function.
|
||||
.Pp
|
||||
.Fn archive_entry_set_XXX
|
||||
is an alias for
|
||||
is an alias for
|
||||
.Fn archive_entry_copy_XXX .
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr libarchive 3
|
||||
|
@ -126,7 +126,7 @@ The corresponding functions
|
||||
and
|
||||
.Fn archive_entry_set_perm
|
||||
store the given user id, group id and permission in the entry.
|
||||
The permission is also set as side effect of calling
|
||||
The permission is also set as a side effect of calling
|
||||
.Fn archive_entry_set_mode .
|
||||
.Pp
|
||||
.Fn archive_entry_strmode
|
||||
@ -143,12 +143,12 @@ The accessor functions are named
|
||||
.Fn XXX_w .
|
||||
.It UTF-8
|
||||
Unicode strings encoded as UTF-8.
|
||||
This are convience functions to update both the multibyte and wide
|
||||
These are convenience functions to update both the multibyte and wide
|
||||
character strings at the same time.
|
||||
.El
|
||||
.Pp
|
||||
.Fn archive_entry_set_XXX
|
||||
is an alias for
|
||||
is an alias for
|
||||
.Fn archive_entry_copy_XXX .
|
||||
.Ss File Flags
|
||||
File flags are transparently converted between a bitmap
|
||||
@ -182,7 +182,7 @@ The
|
||||
.Fn archive_entry_copy_fflags_text
|
||||
and
|
||||
.Fn archive_entry_copy_fflags_text_w
|
||||
functions parse the provided text and sets the internal bitmap values.
|
||||
functions parse the provided text and set the internal bitmap values.
|
||||
This is a platform-specific operation; names that are not meaningful
|
||||
on the current platform will be ignored.
|
||||
The function returns a pointer to the start of the first name that was not
|
||||
@ -197,8 +197,8 @@ which stops parsing at the first unrecognized name.)
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr archive_entry_acl 3 ,
|
||||
.Xr archive_read_disk 3 ,
|
||||
.Xr archive_write_disk 3
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_write_disk 3 ,
|
||||
.Xr libarchive 3
|
||||
.Sh BUGS
|
||||
The platform types
|
||||
.Vt uid_t
|
||||
|
@ -25,13 +25,13 @@
|
||||
* $FreeBSD: head/lib/libarchive/archive_entry_private.h 201096 2009-12-28 02:41:27Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive_acl_private.h"
|
||||
#include "archive_string.h"
|
||||
|
||||
@ -176,6 +176,9 @@ struct archive_entry {
|
||||
|
||||
/* Miscellaneous. */
|
||||
char strmode[12];
|
||||
|
||||
/* Symlink type support */
|
||||
int ae_symlink_type;
|
||||
};
|
||||
|
||||
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
|
||||
|
@ -54,7 +54,7 @@
|
||||
.Nm archive_entry_rdevmajor ,
|
||||
.Nm archive_entry_set_rdevmajor ,
|
||||
.Nm archive_entry_rdevminor ,
|
||||
.Nm archive_entry_set_rdevminor ,
|
||||
.Nm archive_entry_set_rdevminor
|
||||
.Nd accessor functions for manipulating archive entry descriptions
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
@ -267,8 +267,8 @@ platforms.
|
||||
Some archive formats use the combined form, while other formats use
|
||||
the split form.
|
||||
.Sh SEE ALSO
|
||||
.Xr stat 2 ,
|
||||
.Xr archive_entry_acl 3 ,
|
||||
.Xr archive_entry_perms 3 ,
|
||||
.Xr archive_entry_time 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr stat 2
|
||||
.Xr libarchive 3
|
||||
|
@ -48,7 +48,7 @@
|
||||
.Nm archive_entry_mtime_nsec ,
|
||||
.Nm archive_entry_mtime_is_set ,
|
||||
.Nm archive_entry_set_mtime ,
|
||||
.Nm archive_entry_unset_mtime ,
|
||||
.Nm archive_entry_unset_mtime
|
||||
.Nd functions for manipulating times in archive entry descriptions
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
@ -113,8 +113,8 @@ The current state can be queried using
|
||||
.Fn XXX_is_set .
|
||||
Unset time fields have a second and nanosecond field of 0.
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr libarchive 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm libarchive
|
||||
|
@ -27,6 +27,7 @@
|
||||
** This code is in the public domain and has no copyright.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
@ -694,8 +695,16 @@ Convert(time_t Month, time_t Day, time_t Year,
|
||||
signed char DaysInMonth[12] = {
|
||||
31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||
};
|
||||
time_t Julian;
|
||||
int i;
|
||||
time_t Julian;
|
||||
int i;
|
||||
struct tm *ltime;
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
|
||||
struct tm tmbuf;
|
||||
#endif
|
||||
#if defined(HAVE__LOCALTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
if (Year < 69)
|
||||
Year += 2000;
|
||||
@ -722,21 +731,64 @@ 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)
|
||||
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
|
||||
if (DSTmode == DSTon
|
||||
|| (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
|
||||
|| (DSTmode == DSTmaybe && ltime->tm_isdst))
|
||||
Julian -= HOUR;
|
||||
return Julian;
|
||||
}
|
||||
|
||||
|
||||
static time_t
|
||||
DSTcorrect(time_t Start, time_t Future)
|
||||
{
|
||||
time_t StartDay;
|
||||
time_t FutureDay;
|
||||
time_t StartDay;
|
||||
time_t FutureDay;
|
||||
struct tm *ltime;
|
||||
#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
|
||||
struct tm tmbuf;
|
||||
#endif
|
||||
#if defined(HAVE__LOCALTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
StartDay = (localtime(&Start)->tm_hour + 1) % 24;
|
||||
FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
|
||||
#if 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)
|
||||
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
|
||||
FutureDay = (ltime->tm_hour + 1) % 24;
|
||||
return (Future - Start) + (StartDay - FutureDay) * HOUR;
|
||||
}
|
||||
|
||||
@ -747,9 +799,27 @@ 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)
|
||||
struct tm tmbuf;
|
||||
#endif
|
||||
#if defined(HAVE__GMTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
t = Start - zone;
|
||||
#if 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
|
||||
now = Start;
|
||||
now += DAY * ((DayNumber - tm->tm_wday + 7) % 7);
|
||||
now += 7 * DAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
|
||||
@ -765,10 +835,28 @@ 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)
|
||||
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)
|
||||
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
|
||||
Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
|
||||
Year = Month / 12;
|
||||
Month = Month % 12 + 1;
|
||||
@ -905,6 +993,10 @@ __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));
|
||||
@ -913,20 +1005,44 @@ __archive_get_date(time_t now, const char *p)
|
||||
gds = &_gds;
|
||||
|
||||
/* Look up the current time. */
|
||||
#if 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);
|
||||
tm = localtime(&now);
|
||||
#endif
|
||||
if (tm == NULL)
|
||||
return -1;
|
||||
#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S)
|
||||
local = *tm;
|
||||
#endif
|
||||
|
||||
/* Look up UTC if we can and use that to determine the current
|
||||
* timezone offset. */
|
||||
#if 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);
|
||||
gmt_ptr = gmtime(&now);
|
||||
if (gmt_ptr != NULL) {
|
||||
/* Copy, in case localtime and gmtime use the same buffer. */
|
||||
gmt = *gmt_ptr;
|
||||
}
|
||||
#endif
|
||||
if (gmt_ptr != NULL)
|
||||
tzone = difftm (&gmt, &local);
|
||||
else
|
||||
@ -960,7 +1076,18 @@ __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;
|
||||
gmt_ptr = gmtime (&now);
|
||||
#if 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
|
||||
if (gmt_ptr != NULL)
|
||||
local = *gmt_ptr;
|
||||
now += gds->Timezone;
|
||||
|
@ -25,13 +25,13 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_GETDATE_H_INCLUDED
|
||||
#define ARCHIVE_GETDATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_GETDATE_H_INCLUDED
|
||||
#define ARCHIVE_GETDATE_H_INCLUDED
|
||||
|
||||
#include <time.h>
|
||||
|
||||
time_t __archive_get_date(time_t now, const char *);
|
||||
|
@ -83,6 +83,9 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||
static int
|
||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
#endif
|
||||
BCRYPT_ALG_HANDLE hAlg;
|
||||
BCRYPT_HASH_HANDLE hHash;
|
||||
DWORD hash_len;
|
||||
@ -147,6 +150,53 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H)
|
||||
|
||||
static int
|
||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
const mbedtls_md_info_t *info;
|
||||
int ret;
|
||||
|
||||
mbedtls_md_init(ctx);
|
||||
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
||||
if (info == NULL) {
|
||||
mbedtls_md_free(ctx);
|
||||
return (-1);
|
||||
}
|
||||
ret = mbedtls_md_setup(ctx, info, 1);
|
||||
if (ret != 0) {
|
||||
mbedtls_md_free(ctx);
|
||||
return (-1);
|
||||
}
|
||||
ret = mbedtls_md_hmac_starts(ctx, key, key_len);
|
||||
if (ret != 0) {
|
||||
mbedtls_md_free(ctx);
|
||||
return (-1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
|
||||
size_t data_len)
|
||||
{
|
||||
mbedtls_md_hmac_update(ctx, data, data_len);
|
||||
}
|
||||
|
||||
static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
|
||||
{
|
||||
(void)out_len; /* UNUSED */
|
||||
|
||||
mbedtls_md_hmac_finish(ctx, out);
|
||||
}
|
||||
|
||||
static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||
{
|
||||
mbedtls_md_free(ctx);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
|
||||
|
||||
static int
|
||||
@ -198,6 +248,7 @@ static void
|
||||
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
|
||||
{
|
||||
unsigned int len = (unsigned int)*out_len;
|
||||
|
||||
HMAC_Final(*ctx, out, &len);
|
||||
*out_len = len;
|
||||
}
|
||||
|
@ -23,13 +23,12 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_HMAC_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
/*
|
||||
* On systems that do not support any recognized crypto libraries,
|
||||
* the archive_hmac.c file is expected to define no usable symbols.
|
||||
@ -64,6 +63,11 @@ typedef struct {
|
||||
|
||||
} archive_hmac_sha1_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H)
|
||||
#include <mbedtls/md.h>
|
||||
|
||||
typedef mbedtls_md_context_t archive_hmac_sha1_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
|
||||
#include <nettle/hmac.h>
|
||||
|
||||
|
@ -93,6 +93,9 @@ struct archive_match {
|
||||
/* exclusion/inclusion set flag. */
|
||||
int setflag;
|
||||
|
||||
/* Recursively include directory content? */
|
||||
int recursive_include;
|
||||
|
||||
/*
|
||||
* Matching filename patterns.
|
||||
*/
|
||||
@ -223,6 +226,7 @@ archive_match_new(void)
|
||||
return (NULL);
|
||||
a->archive.magic = ARCHIVE_MATCH_MAGIC;
|
||||
a->archive.state = ARCHIVE_STATE_NEW;
|
||||
a->recursive_include = 1;
|
||||
match_list_init(&(a->inclusions));
|
||||
match_list_init(&(a->exclusions));
|
||||
__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
|
||||
@ -470,6 +474,28 @@ archive_match_path_excluded(struct archive *_a,
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* When recursive inclusion of directory content is enabled,
|
||||
* an inclusion pattern that matches a directory will also
|
||||
* include everything beneath that directory. Enabled by default.
|
||||
*
|
||||
* For compatibility with GNU tar, exclusion patterns always
|
||||
* match if a subset of the full patch matches (i.e., they are
|
||||
* are not rooted at the beginning of the path) and thus there
|
||||
* is no corresponding non-recursive exclusion mode.
|
||||
*/
|
||||
int
|
||||
archive_match_set_inclusion_recursion(struct archive *_a, int enabled)
|
||||
{
|
||||
struct archive_match *a;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_match_set_inclusion_recursion");
|
||||
a = (struct archive_match *)_a;
|
||||
a->recursive_include = enabled;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility functions to get statistic information for inclusion patterns.
|
||||
*/
|
||||
@ -781,7 +807,10 @@ static int
|
||||
match_path_inclusion(struct archive_match *a, struct match *m,
|
||||
int mbs, const void *pn)
|
||||
{
|
||||
int flag = PATHMATCH_NO_ANCHOR_END;
|
||||
/* Recursive operation requires only a prefix match. */
|
||||
int flag = a->recursive_include ?
|
||||
PATHMATCH_NO_ANCHOR_END :
|
||||
0;
|
||||
int r;
|
||||
|
||||
if (mbs) {
|
||||
@ -1232,7 +1261,7 @@ set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
|
||||
archive_set_error(&(a->archive), EINVAL, "pathname is empty");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (stat(path, &st) != 0) {
|
||||
if (la_stat(path, &st) != 0) {
|
||||
archive_set_error(&(a->archive), errno, "Failed to stat()");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
@ -22,9 +22,14 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
|
@ -22,9 +22,14 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
|
@ -23,6 +23,9 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
@ -45,3 +48,4 @@ _archive_set_either_option(struct archive *a,
|
||||
const char *m, const char *o, const char *v,
|
||||
option_handler use_format_option, option_handler use_filter_option);
|
||||
|
||||
#endif
|
||||
|
@ -57,8 +57,12 @@ __RCSID("$NetBSD$");
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SYSMACROS_H
|
||||
#if MAJOR_IN_MKDEV
|
||||
#include <sys/mkdev.h>
|
||||
#define HAVE_MAJOR
|
||||
#elif MAJOR_IN_SYSMACROS
|
||||
#include <sys/sysmacros.h>
|
||||
#define HAVE_MAJOR
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
|
@ -31,8 +31,8 @@
|
||||
|
||||
/* Originally from NetBSD's mknod(8) source. */
|
||||
|
||||
#ifndef _PACK_DEV_H
|
||||
#define _PACK_DEV_H
|
||||
#ifndef ARCHIVE_PACK_DEV_H
|
||||
#define ARCHIVE_PACK_DEV_H
|
||||
|
||||
typedef dev_t pack_t(int, unsigned long [], const char **);
|
||||
|
||||
@ -46,4 +46,4 @@ pack_t pack_native;
|
||||
(((y) << 12) & 0xfff00000) | \
|
||||
(((y) << 0) & 0x000000ff)))
|
||||
|
||||
#endif /* _PACK_DEV_H */
|
||||
#endif /* ARCHIVE_PACK_DEV_H */
|
||||
|
@ -26,15 +26,15 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_PATHMATCH_H
|
||||
#define ARCHIVE_PATHMATCH_H
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_PATHMATCH_H
|
||||
#define ARCHIVE_PATHMATCH_H
|
||||
|
||||
/* Don't anchor at beginning unless the pattern starts with "^" */
|
||||
#define PATHMATCH_NO_ANCHOR_START 1
|
||||
/* Don't anchor at end unless the pattern ends with "$" */
|
||||
|
@ -69,6 +69,8 @@
|
||||
* either Windows or Posix APIs. */
|
||||
#if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
|
||||
#include "archive_windows.h"
|
||||
#else
|
||||
#define la_stat(path,stref) stat(path,stref)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -30,6 +30,12 @@
|
||||
#ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED
|
||||
#define ARCHIVE_PLATFORM_ACL_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST_COMMON
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Determine what ACL types are supported
|
||||
*/
|
||||
|
@ -30,6 +30,12 @@
|
||||
#ifndef ARCHIVE_PLATFORM_XATTR_H_INCLUDED
|
||||
#define ARCHIVE_PLATFORM_XATTR_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST_COMMON
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Determine if we support extended attributes
|
||||
*/
|
||||
|
@ -1000,7 +1000,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
|
||||
|
||||
static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
|
||||
{
|
||||
p->Low += start * (p->Range /= total);
|
||||
p->Low += (UInt64)start * (UInt64)(p->Range /= total);
|
||||
p->Range *= size;
|
||||
while (p->Range < kTopValue)
|
||||
{
|
||||
|
@ -6,13 +6,13 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
|
||||
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
|
||||
|
||||
#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive_ppmd_private.h"
|
||||
|
||||
#define PPMD7_MIN_ORDER 2
|
||||
|
1287
libarchive/archive_ppmd8.c
Normal file
1287
libarchive/archive_ppmd8.c
Normal file
File diff suppressed because it is too large
Load Diff
148
libarchive/archive_ppmd8_private.h
Normal file
148
libarchive/archive_ppmd8_private.h
Normal file
@ -0,0 +1,148 @@
|
||||
/* Ppmd8.h -- PPMdI codec
|
||||
2011-01-27 : Igor Pavlov : Public domain
|
||||
This code is based on:
|
||||
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
||||
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||
|
||||
#ifndef ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive_ppmd_private.h"
|
||||
|
||||
#define PPMD8_MIN_ORDER 2
|
||||
#define PPMD8_MAX_ORDER 16
|
||||
|
||||
struct CPpmd8_Context_;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
struct CPpmd8_Context_ *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd8_Context_Ref;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct CPpmd8_Context_
|
||||
{
|
||||
Byte NumStats;
|
||||
Byte Flags;
|
||||
UInt16 SummFreq;
|
||||
CPpmd_State_Ref Stats;
|
||||
CPpmd8_Context_Ref Suffix;
|
||||
} CPpmd8_Context;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
|
||||
|
||||
/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
|
||||
code is not compatible with original code for some files compressed
|
||||
in FREEZE mode. So we disable FREEZE mode support. */
|
||||
|
||||
enum
|
||||
{
|
||||
PPMD8_RESTORE_METHOD_RESTART,
|
||||
PPMD8_RESTORE_METHOD_CUT_OFF
|
||||
#ifdef PPMD8_FREEZE_SUPPORT
|
||||
, PPMD8_RESTORE_METHOD_FREEZE
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CPpmd8_Context *MinContext, *MaxContext;
|
||||
CPpmd_State *FoundState;
|
||||
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder;
|
||||
Int32 RunLength, InitRL; /* must be 32-bit at least */
|
||||
|
||||
UInt32 Size;
|
||||
UInt32 GlueCount;
|
||||
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
|
||||
UInt32 AlignOffset;
|
||||
unsigned RestoreMethod;
|
||||
|
||||
/* Range Coder */
|
||||
UInt32 Range;
|
||||
UInt32 Code;
|
||||
UInt32 Low;
|
||||
union
|
||||
{
|
||||
IByteIn *In;
|
||||
IByteOut *Out;
|
||||
} Stream;
|
||||
|
||||
Byte Indx2Units[PPMD_NUM_INDEXES];
|
||||
Byte Units2Indx[128];
|
||||
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
|
||||
UInt32 Stamps[PPMD_NUM_INDEXES];
|
||||
|
||||
Byte NS2BSIndx[256], NS2Indx[260];
|
||||
CPpmd_See DummySee, See[24][32];
|
||||
UInt16 BinSumm[25][64];
|
||||
} CPpmd8;
|
||||
|
||||
void Ppmd8_Construct(CPpmd8 *p);
|
||||
Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size);
|
||||
void Ppmd8_Free(CPpmd8 *p);
|
||||
void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
|
||||
#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
|
||||
|
||||
|
||||
/* ---------- Internal Functions ---------- */
|
||||
|
||||
extern const Byte PPMD8_kExpEscape[16];
|
||||
|
||||
#ifdef PPMD_32BIT
|
||||
#define Ppmd8_GetPtr(p, ptr) (ptr)
|
||||
#define Ppmd8_GetContext(p, ptr) (ptr)
|
||||
#define Ppmd8_GetStats(p, ctx) ((ctx)->Stats)
|
||||
#else
|
||||
#define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
|
||||
#define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs)))
|
||||
#define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats)))
|
||||
#endif
|
||||
|
||||
void Ppmd8_Update1(CPpmd8 *p);
|
||||
void Ppmd8_Update1_0(CPpmd8 *p);
|
||||
void Ppmd8_Update2(CPpmd8 *p);
|
||||
void Ppmd8_UpdateBin(CPpmd8 *p);
|
||||
|
||||
#define Ppmd8_GetBinSumm(p) \
|
||||
&p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
|
||||
p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
|
||||
p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
|
||||
|
||||
CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
|
||||
|
||||
|
||||
/* ---------- Decode ---------- */
|
||||
|
||||
Bool Ppmd8_RangeDec_Init(CPpmd8 *p);
|
||||
#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
||||
int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */
|
||||
|
||||
/* ---------- Encode ---------- */
|
||||
|
||||
#define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
|
||||
void Ppmd8_RangeEnc_FlushData(CPpmd8 *p);
|
||||
void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Base Functions */
|
||||
void (*Ppmd8_Construct)(CPpmd8 *p);
|
||||
Bool (*Ppmd8_Alloc)(CPpmd8 *p, UInt32 size);
|
||||
void (*Ppmd8_Free)(CPpmd8 *p);
|
||||
void (*Ppmd8_Init)(CPpmd8 *p, unsigned max_order, unsigned restore_method);
|
||||
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
||||
|
||||
/* Decode Functions */
|
||||
int (*Ppmd8_RangeDec_Init)(CPpmd8 *p);
|
||||
int (*Ppmd8_DecodeSymbol)(CPpmd8 *p);
|
||||
} IPpmd8;
|
||||
|
||||
extern const IPpmd8 __archive_ppmd8_functions;
|
||||
|
||||
#endif
|
@ -2,13 +2,13 @@
|
||||
2010-03-12 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "archive_read_private.h"
|
||||
|
@ -25,13 +25,13 @@
|
||||
* $FreeBSD: head/lib/libarchive/archive_private.h 201098 2009-12-28 02:58:14Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PRIVATE_H_INCLUDED
|
||||
|
||||
#if HAVE_ICONV_H
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
@ -153,6 +153,11 @@ void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
|
||||
|
||||
void __archive_ensure_cloexec_flag(int fd);
|
||||
int __archive_mktemp(const char *tmpdir);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
int __archive_mkstemp(wchar_t *template);
|
||||
#else
|
||||
int __archive_mkstemp(char *template);
|
||||
#endif
|
||||
|
||||
int __archive_clean(struct archive *);
|
||||
|
||||
|
@ -23,13 +23,13 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
|
||||
|
||||
/* Random number generator. */
|
||||
int archive_random(void *buf, size_t nbytes);
|
||||
|
||||
|
@ -28,8 +28,9 @@
|
||||
*
|
||||
* Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp
|
||||
*/
|
||||
#ifndef ARCHIVE_RB_H_
|
||||
#define ARCHIVE_RB_H_
|
||||
|
||||
#ifndef ARCHIVE_RB_H_INCLUDED
|
||||
#define ARCHIVE_RB_H_INCLUDED
|
||||
|
||||
struct archive_rb_node {
|
||||
struct archive_rb_node *rb_nodes[2];
|
||||
@ -48,12 +49,24 @@ struct archive_rb_node {
|
||||
__archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT)
|
||||
#define ARCHIVE_RB_TREE_MAX(T) \
|
||||
__archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT)
|
||||
#define ARCHIVE_RB_TREE_NEXT(T, N) \
|
||||
__archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT)
|
||||
#define ARCHIVE_RB_TREE_PREV(T, N) \
|
||||
__archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT)
|
||||
#define ARCHIVE_RB_TREE_FOREACH(N, T) \
|
||||
for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \
|
||||
(N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT))
|
||||
(N) = ARCHIVE_RB_TREE_NEXT((T), (N)))
|
||||
#define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \
|
||||
for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \
|
||||
(N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT))
|
||||
(N) = ARCHIVE_RB_TREE_PREV((T), (N)))
|
||||
#define ARCHIVE_RB_TREE_FOREACH_SAFE(N, T, S) \
|
||||
for ((N) = ARCHIVE_RB_TREE_MIN(T); \
|
||||
(N) && ((S) = ARCHIVE_RB_TREE_NEXT((T), (N)), 1); \
|
||||
(N) = (S))
|
||||
#define ARCHIVE_RB_TREE_FOREACH_REVERSE_SAFE(N, T, S) \
|
||||
for ((N) = ARCHIVE_RB_TREE_MAX(T); \
|
||||
(N) && ((S) = ARCHIVE_RB_TREE_PREV((T), (N)), 1); \
|
||||
(N) = (S))
|
||||
|
||||
/*
|
||||
* archive_rbto_compare_nodes_fn:
|
||||
|
@ -155,7 +155,7 @@ to close the archive, then call
|
||||
.Fn archive_read_free
|
||||
to release all resources, including all memory allocated by the library.
|
||||
.\"
|
||||
.Sh EXAMPLE
|
||||
.Sh EXAMPLES
|
||||
The following illustrates basic usage of the library.
|
||||
In this example,
|
||||
the callback functions are simply wrappers around the standard
|
||||
@ -217,16 +217,16 @@ myclose(struct archive *a, void *client_data)
|
||||
.\" .Sh ERRORS
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read_new 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_extract 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_header 3 ,
|
||||
.Xr archive_read_new 3 ,
|
||||
.Xr archive_read_open 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
||||
.Sh HISTORY
|
||||
The
|
||||
|
@ -433,7 +433,7 @@ archive_read_add_callback_data(struct archive *_a, void *client_data,
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
a->client.dataset = (struct archive_read_data_node *)p;
|
||||
for (i = a->client.nodes - 1; i > iindex && i > 0; i--) {
|
||||
for (i = a->client.nodes - 1; i > iindex; i--) {
|
||||
a->client.dataset[i].data = a->client.dataset[i-1].data;
|
||||
a->client.dataset[i].begin_position = -1;
|
||||
a->client.dataset[i].total_size = -1;
|
||||
@ -611,6 +611,15 @@ choose_filters(struct archive_read *a)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
int
|
||||
__archive_read_header(struct archive_read *a, struct archive_entry *entry)
|
||||
{
|
||||
if (a->filter->read_header)
|
||||
return a->filter->read_header(a->filter, entry);
|
||||
else
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read header of next entry.
|
||||
*/
|
||||
@ -835,7 +844,8 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
|
||||
dest = (char *)buff;
|
||||
|
||||
while (s > 0) {
|
||||
if (a->read_data_remaining == 0) {
|
||||
if (a->read_data_offset == a->read_data_output_offset &&
|
||||
a->read_data_remaining == 0) {
|
||||
read_buf = a->read_data_block;
|
||||
a->read_data_is_posix_read = 1;
|
||||
a->read_data_requested = s;
|
||||
|
@ -59,16 +59,16 @@ or empty, this function will do nothing and
|
||||
will be returned.
|
||||
Otherwise,
|
||||
.Cm ARCHIVE_OK
|
||||
will be returned.
|
||||
will be returned.
|
||||
.It Fn archive_read_set_passphrase_callback
|
||||
Register callback function that will be invoked to get a passphrase
|
||||
for decrption after trying all passphrases registered by the
|
||||
Register a callback function that will be invoked to get a passphrase
|
||||
for decryption after trying all the passphrases registered by the
|
||||
.Fn archive_read_add_passphrase
|
||||
function failed.
|
||||
.El
|
||||
.\" .Sh ERRORS
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_set_options 3
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr libarchive 3
|
||||
|
@ -28,7 +28,7 @@
|
||||
.Dt ARCHIVE_READ_DATA 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_data
|
||||
.Nm archive_read_data ,
|
||||
.Nm archive_read_data_block ,
|
||||
.Nm archive_read_data_skip ,
|
||||
.Nm archive_read_data_into_fd
|
||||
@ -118,7 +118,6 @@ functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_extract 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
@ -127,4 +126,5 @@ functions.
|
||||
.Xr archive_read_open 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
||||
|
@ -99,9 +99,10 @@ following values:
|
||||
.Bl -tag -compact -width "indent"
|
||||
.It Cm ARCHIVE_READDISK_HONOR_NODUMP
|
||||
Skip files and directories with the nodump file attribute (file flag) set.
|
||||
By default, the nodump file atrribute is ignored.
|
||||
By default, the nodump file attribute is ignored.
|
||||
.It Cm ARCHIVE_READDISK_MAC_COPYFILE
|
||||
Mac OS X specific. Read metadata (ACLs and extended attributes) with
|
||||
Mac OS X specific.
|
||||
Read metadata (ACLs and extended attributes) with
|
||||
.Xr copyfile 3 .
|
||||
By default, metadata is read using
|
||||
.Xr copyfile 3 .
|
||||
@ -120,7 +121,7 @@ or
|
||||
for more information on file attributes.
|
||||
.It Cm ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS
|
||||
Do not traverse mount points.
|
||||
By defaut, moint points are traversed.
|
||||
By default, mount points are traversed.
|
||||
.It Cm ARCHIVE_READDISK_NO_XATTR
|
||||
Do not read extended file attributes (xattrs).
|
||||
By default, extended file attributes are read from disk.
|
||||
@ -216,7 +217,7 @@ of some other operation.
|
||||
(For example, directory traversal libraries often provide this information.)
|
||||
.Pp
|
||||
Where necessary, user and group ids are converted to user and group names
|
||||
using the currently registered lookup functions above.
|
||||
using the currently-registered lookup functions above.
|
||||
This affects the file ownership fields and ACL values in the
|
||||
.Tn struct archive_entry
|
||||
object.
|
||||
@ -226,7 +227,7 @@ More information about the
|
||||
object and the overall design of the library can be found in the
|
||||
.Xr libarchive 3
|
||||
overview.
|
||||
.Sh EXAMPLE
|
||||
.Sh EXAMPLES
|
||||
The following illustrates basic usage of the library by
|
||||
showing how to use it to copy an item on disk into an archive.
|
||||
.Bd -literal -offset indent
|
||||
@ -291,11 +292,11 @@ and
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr archive_write 3 ,
|
||||
.Xr archive_write_disk 3 ,
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
|
@ -163,6 +163,9 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
int initial_fd = fd;
|
||||
int r, r1;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
|
||||
"archive_read_disk_entry_from_file");
|
||||
|
||||
archive_clear_error(_a);
|
||||
path = archive_entry_sourcepath(entry);
|
||||
if (path == NULL)
|
||||
@ -188,7 +191,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (stat(path, &s) != 0) {
|
||||
if (la_stat(path, &s) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Can't stat %s", path);
|
||||
return (ARCHIVE_FAILED);
|
||||
@ -246,11 +249,11 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
|
||||
#if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
|
||||
if (S_ISLNK(st->st_mode)) {
|
||||
size_t linkbuffer_len = st->st_size + 1;
|
||||
size_t linkbuffer_len = st->st_size;
|
||||
char *linkbuffer;
|
||||
int lnklen;
|
||||
|
||||
linkbuffer = malloc(linkbuffer_len);
|
||||
linkbuffer = malloc(linkbuffer_len + 1);
|
||||
if (linkbuffer == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Couldn't read link data");
|
||||
@ -277,7 +280,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
free(linkbuffer);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
linkbuffer[lnklen] = 0;
|
||||
linkbuffer[lnklen] = '\0';
|
||||
archive_entry_set_symlink(entry, linkbuffer);
|
||||
free(linkbuffer);
|
||||
}
|
||||
|
@ -694,6 +694,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||
struct tree *t = a->tree;
|
||||
int r;
|
||||
ssize_t bytes;
|
||||
int64_t sparse_bytes;
|
||||
size_t buffbytes;
|
||||
int empty_sparse_region = 0;
|
||||
|
||||
@ -728,27 +729,23 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||
if ((t->flags & needsRestoreTimes) != 0 &&
|
||||
t->restore_time.noatime == 0)
|
||||
flags |= O_NOATIME;
|
||||
do {
|
||||
#endif
|
||||
t->entry_fd = open_on_current_dir(t,
|
||||
tree_current_access_path(t), flags);
|
||||
__archive_ensure_cloexec_flag(t->entry_fd);
|
||||
t->entry_fd = open_on_current_dir(t,
|
||||
tree_current_access_path(t), flags);
|
||||
__archive_ensure_cloexec_flag(t->entry_fd);
|
||||
#if defined(O_NOATIME)
|
||||
/*
|
||||
* When we did open the file with O_NOATIME flag,
|
||||
* if successful, set 1 to t->restore_time.noatime
|
||||
* not to restore an atime of the file later.
|
||||
* if failed by EPERM, retry it without O_NOATIME flag.
|
||||
*/
|
||||
if (flags & O_NOATIME) {
|
||||
if (t->entry_fd >= 0)
|
||||
t->restore_time.noatime = 1;
|
||||
else if (errno == EPERM) {
|
||||
flags &= ~O_NOATIME;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
/*
|
||||
* When we did open the file with O_NOATIME flag,
|
||||
* if successful, set 1 to t->restore_time.noatime
|
||||
* not to restore an atime of the file later.
|
||||
* if failed by EPERM, retry it without O_NOATIME flag.
|
||||
*/
|
||||
if (flags & O_NOATIME) {
|
||||
if (t->entry_fd >= 0)
|
||||
t->restore_time.noatime = 1;
|
||||
else if (errno == EPERM)
|
||||
flags &= ~O_NOATIME;
|
||||
}
|
||||
#endif
|
||||
if (t->entry_fd < 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
@ -792,9 +789,9 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||
goto abort_read_data;
|
||||
}
|
||||
bytes = t->current_sparse->offset - t->entry_total;
|
||||
t->entry_remaining_bytes -= bytes;
|
||||
t->entry_total += bytes;
|
||||
sparse_bytes = t->current_sparse->offset - t->entry_total;
|
||||
t->entry_remaining_bytes -= sparse_bytes;
|
||||
t->entry_total += sparse_bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -856,7 +853,12 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
||||
const struct stat *st; /* info to use for this entry */
|
||||
const struct stat *lst;/* lstat() information */
|
||||
const char *name;
|
||||
int descend, r;
|
||||
int delayed, delayed_errno, descend, r;
|
||||
struct archive_string delayed_str;
|
||||
|
||||
delayed = ARCHIVE_OK;
|
||||
delayed_errno = 0;
|
||||
archive_string_init(&delayed_str);
|
||||
|
||||
st = NULL;
|
||||
lst = NULL;
|
||||
@ -885,14 +887,26 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
||||
case TREE_REGULAR:
|
||||
lst = tree_current_lstat(t);
|
||||
if (lst == NULL) {
|
||||
if (errno == ENOENT && t->depth > 0) {
|
||||
delayed = ARCHIVE_WARN;
|
||||
delayed_errno = errno;
|
||||
if (delayed_str.length == 0) {
|
||||
archive_string_sprintf(&delayed_str,
|
||||
"%s", tree_current_path(t));
|
||||
} else {
|
||||
archive_string_sprintf(&delayed_str,
|
||||
" %s", tree_current_path(t));
|
||||
}
|
||||
} else {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"%s: Cannot stat",
|
||||
tree_current_path(t));
|
||||
tree_enter_initial_dir(t);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (lst == NULL);
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -1083,6 +1097,17 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
||||
r = archive_read_disk_entry_from_file(&(a->archive), entry,
|
||||
t->entry_fd, st);
|
||||
|
||||
if (r == ARCHIVE_OK) {
|
||||
r = delayed;
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_string_sprintf(&delayed_str, ": %s",
|
||||
"File removed before we read it");
|
||||
archive_set_error(&(a->archive), delayed_errno,
|
||||
"%s", delayed_str.s);
|
||||
}
|
||||
}
|
||||
archive_string_free(&delayed_str);
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
@ -1114,6 +1139,8 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
|
||||
t->entry_fd = -1;
|
||||
}
|
||||
|
||||
archive_entry_clear(entry);
|
||||
|
||||
for (;;) {
|
||||
r = next_entry(a, t, entry);
|
||||
if (t->entry_fd >= 0) {
|
||||
@ -1266,10 +1293,23 @@ archive_read_disk_descend(struct archive *_a)
|
||||
if (t->visit_type != TREE_REGULAR || !t->descend)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
/*
|
||||
* We must not treat the initial specified path as a physical dir,
|
||||
* because if we do then we will try and ascend out of it by opening
|
||||
* ".." which is (a) wrong and (b) causes spurious permissions errors
|
||||
* if ".." is not readable by us. Instead, treat it as if it were a
|
||||
* symlink. (This uses an extra fd, but it can only happen once at the
|
||||
* top level of a traverse.) But we can't necessarily assume t->st is
|
||||
* valid here (though t->lst is), which complicates the logic a
|
||||
* little.
|
||||
*/
|
||||
if (tree_current_is_physical_dir(t)) {
|
||||
tree_push(t, t->basename, t->current_filesystem_id,
|
||||
t->lst.st_dev, t->lst.st_ino, &t->restore_time);
|
||||
t->stack->flags |= isDir;
|
||||
if (t->stack->parent->parent != NULL)
|
||||
t->stack->flags |= isDir;
|
||||
else
|
||||
t->stack->flags |= isDirLink;
|
||||
} else if (tree_current_is_dir(t)) {
|
||||
tree_push(t, t->basename, t->current_filesystem_id,
|
||||
t->st.st_dev, t->st.st_ino, &t->restore_time);
|
||||
@ -2122,6 +2162,17 @@ tree_open(const char *path, int symlink_mode, int restore_time)
|
||||
static struct tree *
|
||||
tree_reopen(struct tree *t, const char *path, int restore_time)
|
||||
{
|
||||
#if defined(O_PATH)
|
||||
/* Linux */
|
||||
const int o_flag = O_PATH;
|
||||
#elif defined(O_SEARCH)
|
||||
/* SunOS */
|
||||
const int o_flag = O_SEARCH;
|
||||
#elif defined(__FreeBSD__) && defined(O_EXEC)
|
||||
/* FreeBSD */
|
||||
const int o_flag = O_EXEC;
|
||||
#endif
|
||||
|
||||
t->flags = (restore_time != 0)?needsRestoreTimes:0;
|
||||
t->flags |= onInitialDir;
|
||||
t->visit_type = 0;
|
||||
@ -2143,6 +2194,16 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
|
||||
t->stack->flags = needsFirstVisit;
|
||||
t->maxOpenCount = t->openCount = 1;
|
||||
t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC);
|
||||
#if defined(O_PATH) || defined(O_SEARCH) || \
|
||||
(defined(__FreeBSD__) && defined(O_EXEC))
|
||||
/*
|
||||
* Most likely reason to fail opening "." is that it's not readable,
|
||||
* so try again for execute. The consequences of not opening this are
|
||||
* unhelpful and unnecessary errors later.
|
||||
*/
|
||||
if (t->initial_dir_fd < 0)
|
||||
t->initial_dir_fd = open(".", o_flag | O_CLOEXEC);
|
||||
#endif
|
||||
__archive_ensure_cloexec_flag(t->initial_dir_fd);
|
||||
t->working_dir_fd = tree_dup(t->initial_dir_fd);
|
||||
return (t);
|
||||
@ -2450,7 +2511,7 @@ tree_current_stat(struct tree *t)
|
||||
#else
|
||||
if (tree_enter_working_dir(t) != 0)
|
||||
return NULL;
|
||||
if (stat(tree_current_access_path(t), &t->st) != 0)
|
||||
if (la_stat(tree_current_access_path(t), &t->st) != 0)
|
||||
#endif
|
||||
return NULL;
|
||||
t->flags |= hasStat;
|
||||
|
@ -26,13 +26,13 @@
|
||||
* $FreeBSD: head/lib/libarchive/archive_read_disk_private.h 201105 2009-12-28 03:20:54Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive_platform_acl.h"
|
||||
|
||||
struct tree;
|
||||
|
@ -299,8 +299,155 @@ static int close_and_restore_time(HANDLE, struct tree *,
|
||||
struct restore_time *);
|
||||
static int setup_sparse_from_disk(struct archive_read_disk *,
|
||||
struct archive_entry *, HANDLE);
|
||||
static int la_linkname_from_handle(HANDLE, wchar_t **, int *);
|
||||
static int la_linkname_from_pathw(const wchar_t *, wchar_t **, int *);
|
||||
static void entry_symlink_from_pathw(struct archive_entry *,
|
||||
const wchar_t *path);
|
||||
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG ReparseTag;
|
||||
USHORT ReparseDataLength;
|
||||
USHORT Reserved;
|
||||
union {
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
ULONG Flags;
|
||||
WCHAR PathBuffer[1];
|
||||
} SymbolicLinkReparseBuffer;
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
WCHAR PathBuffer[1];
|
||||
} MountPointReparseBuffer;
|
||||
struct {
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
} DUMMYUNIONNAME;
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
|
||||
/*
|
||||
* Reads the target of a symbolic link
|
||||
*
|
||||
* Returns 0 on success and -1 on failure
|
||||
* outbuf is allocated in the function
|
||||
*/
|
||||
static int
|
||||
la_linkname_from_handle(HANDLE h, wchar_t **linkname, int *linktype)
|
||||
{
|
||||
DWORD inbytes;
|
||||
REPARSE_DATA_BUFFER *buf;
|
||||
BY_HANDLE_FILE_INFORMATION st;
|
||||
size_t len;
|
||||
BOOL ret;
|
||||
BYTE *indata;
|
||||
wchar_t *tbuf;
|
||||
|
||||
ret = GetFileInformationByHandle(h, &st);
|
||||
if (ret == 0 ||
|
||||
(st.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
indata = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
|
||||
ret = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, indata,
|
||||
1024, &inbytes, NULL);
|
||||
if (ret == 0) {
|
||||
la_dosmaperr(GetLastError());
|
||||
free(indata);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
buf = (REPARSE_DATA_BUFFER *) indata;
|
||||
if (buf->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
|
||||
free(indata);
|
||||
/* File is not a symbolic link */
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
len = buf->SymbolicLinkReparseBuffer.SubstituteNameLength;
|
||||
if (len <= 0) {
|
||||
free(indata);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
tbuf = malloc(len + 1 * sizeof(wchar_t));
|
||||
if (tbuf == NULL) {
|
||||
free(indata);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
memcpy(tbuf, &((BYTE *)buf->SymbolicLinkReparseBuffer.PathBuffer)
|
||||
[buf->SymbolicLinkReparseBuffer.SubstituteNameOffset], len);
|
||||
free(indata);
|
||||
|
||||
tbuf[len / sizeof(wchar_t)] = L'\0';
|
||||
|
||||
*linkname = tbuf;
|
||||
|
||||
/*
|
||||
* Translate backslashes to slashes for libarchive internal use
|
||||
*/
|
||||
while(*tbuf != L'\0') {
|
||||
if (*tbuf == L'\\')
|
||||
*tbuf = L'/';
|
||||
tbuf++;
|
||||
}
|
||||
|
||||
if ((st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
||||
*linktype = AE_SYMLINK_TYPE_FILE;
|
||||
else
|
||||
*linktype = AE_SYMLINK_TYPE_DIRECTORY;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns AE_SYMLINK_TYPE_FILE, AE_SYMLINK_TYPE_DIRECTORY or -1 on error
|
||||
*/
|
||||
static int
|
||||
la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype)
|
||||
{
|
||||
HANDLE h;
|
||||
const DWORD flag = FILE_FLAG_BACKUP_SEMANTICS |
|
||||
FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
int ret;
|
||||
|
||||
h = CreateFileW(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, flag,
|
||||
NULL);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ret = la_linkname_from_handle(h, outbuf, linktype);
|
||||
CloseHandle(h);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
entry_symlink_from_pathw(struct archive_entry *entry, const wchar_t *path)
|
||||
{
|
||||
wchar_t *linkname = NULL;
|
||||
int ret, linktype;
|
||||
|
||||
ret = la_linkname_from_pathw(path, &linkname, &linktype);
|
||||
if (ret != 0)
|
||||
return;
|
||||
if (linktype >= 0) {
|
||||
archive_entry_copy_symlink_w(entry, linkname);
|
||||
archive_entry_set_symlink_type(entry, linktype);
|
||||
}
|
||||
free(linkname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static struct archive_vtable *
|
||||
archive_read_disk_vtable(void)
|
||||
@ -899,6 +1046,19 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* File attributes
|
||||
*/
|
||||
if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0) {
|
||||
const int supported_attrs =
|
||||
FILE_ATTRIBUTE_READONLY |
|
||||
FILE_ATTRIBUTE_HIDDEN |
|
||||
FILE_ATTRIBUTE_SYSTEM;
|
||||
DWORD file_attrs = st->dwFileAttributes & supported_attrs;
|
||||
if (file_attrs != 0)
|
||||
archive_entry_set_fflags(entry, file_attrs, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke a meta data filter callback.
|
||||
*/
|
||||
@ -966,6 +1126,8 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
|
||||
t->entry_fh = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
archive_entry_clear(entry);
|
||||
|
||||
while ((r = next_entry(a, t, entry)) == ARCHIVE_RETRY)
|
||||
archive_entry_clear(entry);
|
||||
|
||||
@ -1838,9 +2000,10 @@ entry_copy_bhfi(struct archive_entry *entry, const wchar_t *path,
|
||||
mode |= S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
|
||||
findData != NULL &&
|
||||
findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK)
|
||||
findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
|
||||
mode |= S_IFLNK;
|
||||
else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
entry_symlink_from_pathw(entry, path);
|
||||
} else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||
else {
|
||||
const wchar_t *p;
|
||||
@ -2139,6 +2302,8 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
fileAttributes = bhfi.dwFileAttributes;
|
||||
} else {
|
||||
archive_entry_copy_stat(entry, st);
|
||||
if (st->st_mode & S_IFLNK)
|
||||
entry_symlink_from_pathw(entry, path);
|
||||
h = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
@ -2150,6 +2315,19 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
||||
if (name != NULL)
|
||||
archive_entry_copy_gname(entry, name);
|
||||
|
||||
/*
|
||||
* File attributes
|
||||
*/
|
||||
if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0) {
|
||||
const int supported_attrs =
|
||||
FILE_ATTRIBUTE_READONLY |
|
||||
FILE_ATTRIBUTE_HIDDEN |
|
||||
FILE_ATTRIBUTE_SYSTEM;
|
||||
DWORD file_attrs = fileAttributes & supported_attrs;
|
||||
if (file_attrs != 0)
|
||||
archive_entry_set_fflags(entry, file_attrs, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this file be sparse file ?
|
||||
*/
|
||||
|
@ -126,7 +126,6 @@ and
|
||||
functions.
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
@ -134,4 +133,5 @@ functions.
|
||||
.Xr archive_read_open 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
||||
|
@ -147,8 +147,8 @@ and
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_format 3
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr libarchive 3
|
||||
|
@ -102,7 +102,7 @@ For example,
|
||||
.Fn archive_read_support_format_tar
|
||||
enables support for a variety of standard tar formats, old-style tar,
|
||||
ustar, pax interchange format, and many common variants.
|
||||
.It Fn archive_read_support_format_all
|
||||
.It Fn archive_read_support_format_all
|
||||
Enables support for all available formats except the
|
||||
.Dq raw
|
||||
format (see below).
|
||||
@ -125,7 +125,7 @@ it is not possible to accurately determine a format for
|
||||
an empty file based purely on contents.
|
||||
So empty files are treated by libarchive as a distinct
|
||||
format.
|
||||
.It Fn archive_read_support_format_raw
|
||||
.It Fn archive_read_support_format_raw
|
||||
The
|
||||
.Dq raw
|
||||
format handler allows libarchive to be used to read arbitrary data.
|
||||
@ -153,11 +153,11 @@ functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
||||
.Sh BUGS
|
||||
Many traditional archiver programs treat
|
||||
|
@ -83,11 +83,11 @@ and
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read_new 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_new 3 ,
|
||||
.Xr archive_read_open 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3
|
||||
|
@ -79,7 +79,6 @@ functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_extract 3 ,
|
||||
@ -88,4 +87,5 @@ functions.
|
||||
.Xr archive_read_open 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
||||
|
@ -50,10 +50,10 @@ object can be found in the overview manual page for
|
||||
.\" .Sh ERRORS
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
||||
|
@ -205,7 +205,7 @@ On failure, the callback should invoke
|
||||
.Fn archive_set_error
|
||||
to register an error code and message and
|
||||
return
|
||||
.Cm ARCHIVE_FATAL.
|
||||
.Cm ARCHIVE_FATAL .
|
||||
.\" .Sh EXAMPLE
|
||||
.\"
|
||||
.Sh RETURN VALUES
|
||||
@ -223,11 +223,11 @@ functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
||||
|
@ -174,8 +174,7 @@ file_close(struct archive *a, void *client_data)
|
||||
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
if (mine->buffer != NULL)
|
||||
free(mine->buffer);
|
||||
free(mine->buffer);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
@ -25,15 +25,15 @@
|
||||
* $FreeBSD: head/lib/libarchive/archive_read_private.h 201088 2009-12-28 02:18:55Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_READ_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_READ_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_string.h"
|
||||
#include "archive_private.h"
|
||||
@ -98,6 +98,8 @@ struct archive_read_filter {
|
||||
int (*close)(struct archive_read_filter *self);
|
||||
/* Function that handles switching from reading one block to the next/prev */
|
||||
int (*sswitch)(struct archive_read_filter *self, unsigned int iindex);
|
||||
/* Read any header metadata if available. */
|
||||
int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry);
|
||||
/* My private data. */
|
||||
void *data;
|
||||
|
||||
@ -250,6 +252,7 @@ int64_t __archive_read_seek(struct archive_read*, int64_t, int);
|
||||
int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
|
||||
int64_t __archive_read_consume(struct archive_read *, int64_t);
|
||||
int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
|
||||
int __archive_read_header(struct archive_read *, struct archive_entry *);
|
||||
int __archive_read_program(struct archive_read_filter *, const char *);
|
||||
void __archive_read_free_filters(struct archive_read *);
|
||||
struct archive_read_extract *__archive_read_get_extract(struct archive_read *);
|
||||
|
@ -73,6 +73,9 @@ archive_read_set_format(struct archive *_a, int code)
|
||||
case ARCHIVE_FORMAT_RAR:
|
||||
strcpy(str, "rar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAR_V5:
|
||||
strcpy(str, "rar5");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
strcpy(str, "tar");
|
||||
break;
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dd January 31, 2020
|
||||
.Dt ARCHIVE_READ_OPTIONS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -180,6 +180,18 @@ only to modules whose name matches
|
||||
.\"
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -compact -width indent
|
||||
.It Format cab
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating file names.
|
||||
.El
|
||||
.It Format cpio
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating file names.
|
||||
.El
|
||||
.It Format iso9660
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm joliet
|
||||
@ -193,6 +205,24 @@ Defaults to enabled, use
|
||||
.Cm !rockridge
|
||||
to disable.
|
||||
.El
|
||||
.It Format lha
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating file names.
|
||||
.El
|
||||
.It Format mtree
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm checkfs
|
||||
Allow reading information missing from the mtree from the file system.
|
||||
Disabled by default.
|
||||
.El
|
||||
.It Format rar
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating file names.
|
||||
.El
|
||||
.It Format tar
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm compat-2x
|
||||
@ -202,7 +232,7 @@ This option mimics the libarchive 2.x filename handling
|
||||
so that such archives can be read correctly.
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating filenames.
|
||||
used when translating file names.
|
||||
.It Cm mac-ext
|
||||
Support Mac OS metadata extension that records data in special
|
||||
files beginning with a period and underscore.
|
||||
@ -212,7 +242,8 @@ Use
|
||||
to disable.
|
||||
.It Cm read_concatenated_archives
|
||||
Ignore zeroed blocks in the archive, which occurs when multiple tar archives
|
||||
have been concatenated together. Without this option, only the contents of
|
||||
have been concatenated together.
|
||||
Without this option, only the contents of
|
||||
the first concatenated archive would be read.
|
||||
.El
|
||||
.El
|
||||
@ -226,6 +257,6 @@ functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_write_set_options 3 ,
|
||||
.Xr archive_read 3
|
||||
.Xr libarchive 3
|
||||
|
@ -37,6 +37,9 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@ -45,6 +48,8 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_endian.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
@ -56,6 +61,8 @@ struct private_data {
|
||||
size_t out_block_size;
|
||||
int64_t total_out;
|
||||
unsigned long crc;
|
||||
uint32_t mtime;
|
||||
char *name;
|
||||
char eof; /* True = found end of compressed data. */
|
||||
};
|
||||
|
||||
@ -123,12 +130,21 @@ archive_read_support_filter_gzip(struct archive *_a)
|
||||
* count of bits verified, suitable for use by bidder.
|
||||
*/
|
||||
static ssize_t
|
||||
peek_at_header(struct archive_read_filter *filter, int *pbits)
|
||||
peek_at_header(struct archive_read_filter *filter, int *pbits,
|
||||
#ifdef HAVE_ZLIB_H
|
||||
struct private_data *state
|
||||
#else
|
||||
void *state
|
||||
#endif
|
||||
)
|
||||
{
|
||||
const unsigned char *p;
|
||||
ssize_t avail, len;
|
||||
int bits = 0;
|
||||
int header_flags;
|
||||
#ifndef HAVE_ZLIB_H
|
||||
(void)state; /* UNUSED */
|
||||
#endif
|
||||
|
||||
/* Start by looking at the first ten bytes of the header, which
|
||||
* is all fixed layout. */
|
||||
@ -144,7 +160,11 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
|
||||
return (0);
|
||||
bits += 3;
|
||||
header_flags = p[3];
|
||||
/* Bytes 4-7 are mod time. */
|
||||
/* Bytes 4-7 are mod time in little endian. */
|
||||
#ifdef HAVE_ZLIB_H
|
||||
if (state)
|
||||
state->mtime = archive_le32dec(p + 4);
|
||||
#endif
|
||||
/* Byte 8 is deflate flags. */
|
||||
/* XXXX TODO: return deflate flags back to consume_header for use
|
||||
in initializing the decompressor. */
|
||||
@ -161,6 +181,9 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
|
||||
|
||||
/* Null-terminated optional filename. */
|
||||
if (header_flags & 8) {
|
||||
#ifdef HAVE_ZLIB_H
|
||||
ssize_t file_start = len;
|
||||
#endif
|
||||
do {
|
||||
++len;
|
||||
if (avail < len)
|
||||
@ -169,6 +192,14 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
|
||||
if (p == NULL)
|
||||
return (0);
|
||||
} while (p[len - 1] != 0);
|
||||
|
||||
#ifdef HAVE_ZLIB_H
|
||||
if (state) {
|
||||
/* Reset the name in case of repeat header reads. */
|
||||
free(state->name);
|
||||
state->name = strdup((const char *)&p[file_start]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Null-terminated optional comment. */
|
||||
@ -214,12 +245,11 @@ gzip_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
|
||||
(void)self; /* UNUSED */
|
||||
|
||||
if (peek_at_header(filter, &bits_checked))
|
||||
if (peek_at_header(filter, &bits_checked, NULL))
|
||||
return (bits_checked);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_ZLIB_H
|
||||
|
||||
/*
|
||||
@ -243,6 +273,24 @@ gzip_bidder_init(struct archive_read_filter *self)
|
||||
|
||||
#else
|
||||
|
||||
static int
|
||||
gzip_read_header(struct archive_read_filter *self, struct archive_entry *entry)
|
||||
{
|
||||
struct private_data *state;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
|
||||
/* A mtime of 0 is considered invalid/missing. */
|
||||
if (state->mtime != 0)
|
||||
archive_entry_set_mtime(entry, state->mtime, 0);
|
||||
|
||||
/* If the name is available, extract it. */
|
||||
if (state->name)
|
||||
archive_entry_set_pathname(entry, state->name);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the filter object.
|
||||
*/
|
||||
@ -272,6 +320,9 @@ gzip_bidder_init(struct archive_read_filter *self)
|
||||
self->read = gzip_filter_read;
|
||||
self->skip = NULL; /* not supported */
|
||||
self->close = gzip_filter_close;
|
||||
#ifdef HAVE_ZLIB_H
|
||||
self->read_header = gzip_read_header;
|
||||
#endif
|
||||
|
||||
state->in_stream = 0; /* We're not actually within a stream yet. */
|
||||
|
||||
@ -289,7 +340,7 @@ consume_header(struct archive_read_filter *self)
|
||||
state = (struct private_data *)self->data;
|
||||
|
||||
/* If this is a real header, consume it. */
|
||||
len = peek_at_header(self->upstream, NULL);
|
||||
len = peek_at_header(self->upstream, NULL, state);
|
||||
if (len == 0)
|
||||
return (ARCHIVE_EOF);
|
||||
__archive_read_filter_consume(self->upstream, len);
|
||||
@ -374,7 +425,7 @@ gzip_filter_read(struct archive_read_filter *self, const void **p)
|
||||
{
|
||||
struct private_data *state;
|
||||
size_t decompressed;
|
||||
ssize_t avail_in;
|
||||
ssize_t avail_in, max_in;
|
||||
int ret;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
@ -408,6 +459,12 @@ gzip_filter_read(struct archive_read_filter *self, const void **p)
|
||||
"truncated gzip input");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (UINT_MAX >= SSIZE_MAX)
|
||||
max_in = SSIZE_MAX;
|
||||
else
|
||||
max_in = UINT_MAX;
|
||||
if (avail_in > max_in)
|
||||
avail_in = max_in;
|
||||
state->stream.avail_in = (uInt)avail_in;
|
||||
|
||||
/* Decompress and consume some of that data. */
|
||||
@ -469,6 +526,7 @@ gzip_filter_close(struct archive_read_filter *self)
|
||||
}
|
||||
}
|
||||
|
||||
free(state->name);
|
||||
free(state->out_block);
|
||||
free(state);
|
||||
return (ret);
|
||||
|
@ -460,7 +460,7 @@ lz4_filter_read_descriptor(struct archive_read_filter *self)
|
||||
|
||||
__archive_read_filter_consume(self->upstream, descriptor_bytes);
|
||||
|
||||
/* Make sure we have an enough buffer for uncompressed data. */
|
||||
/* Make sure we have a large enough buffer for uncompressed data. */
|
||||
if (lz4_allocate_out_block(self) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (state->flags.stream_checksum)
|
||||
@ -520,7 +520,7 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
|
||||
if (read_buf == NULL)
|
||||
goto truncated_error;
|
||||
|
||||
/* Optional process, checking a block sum. */
|
||||
/* Optional processing, checking a block sum. */
|
||||
if (checksum_size) {
|
||||
unsigned int chsum = __archive_xxhash.XXH32(
|
||||
read_buf + 4, (int)compressed_size, 0);
|
||||
@ -640,7 +640,7 @@ lz4_filter_read_default_stream(struct archive_read_filter *self, const void **p)
|
||||
if (ret == 0 && *p == NULL)
|
||||
state->stage = SELECT_STREAM;
|
||||
|
||||
/* Optional process, checking a stream sum. */
|
||||
/* Optional processing, checking a stream sum. */
|
||||
if (state->flags.stream_checksum) {
|
||||
if (state->stage == SELECT_STREAM) {
|
||||
unsigned int checksum;
|
||||
@ -660,7 +660,7 @@ lz4_filter_read_default_stream(struct archive_read_filter *self, const void **p)
|
||||
if (checksum != checksum_stream) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"lz4 stream cheksum error");
|
||||
"lz4 stream checksum error");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
} else if (ret > 0)
|
||||
@ -674,7 +674,7 @@ static ssize_t
|
||||
lz4_filter_read_legacy_stream(struct archive_read_filter *self, const void **p)
|
||||
{
|
||||
struct private_data *state = (struct private_data *)self->data;
|
||||
int compressed;
|
||||
uint32_t compressed;
|
||||
const char *read_buf;
|
||||
ssize_t ret;
|
||||
|
||||
|
@ -574,14 +574,13 @@ read_more:
|
||||
while (l > 0) {
|
||||
int n = 0;
|
||||
|
||||
if (l > 0) {
|
||||
if (!uuchar[b[0]] || !uuchar[b[1]])
|
||||
break;
|
||||
n = UUDECODE(*b++) << 18;
|
||||
n |= UUDECODE(*b++) << 12;
|
||||
*out++ = n >> 16; total++;
|
||||
--l;
|
||||
}
|
||||
if (!uuchar[b[0]] || !uuchar[b[1]])
|
||||
break;
|
||||
n = UUDECODE(*b++) << 18;
|
||||
n |= UUDECODE(*b++) << 12;
|
||||
*out++ = n >> 16; total++;
|
||||
--l;
|
||||
|
||||
if (l > 0) {
|
||||
if (!uuchar[b[0]])
|
||||
break;
|
||||
@ -626,14 +625,13 @@ read_more:
|
||||
while (l > 0) {
|
||||
int n = 0;
|
||||
|
||||
if (l > 0) {
|
||||
if (!base64[b[0]] || !base64[b[1]])
|
||||
break;
|
||||
n = base64num[*b++] << 18;
|
||||
n |= base64num[*b++] << 12;
|
||||
*out++ = n >> 16; total++;
|
||||
l -= 2;
|
||||
}
|
||||
if (!base64[b[0]] || !base64[b[1]])
|
||||
break;
|
||||
n = base64num[*b++] << 18;
|
||||
n |= base64num[*b++] << 12;
|
||||
*out++ = n >> 16; total++;
|
||||
l -= 2;
|
||||
|
||||
if (l > 0) {
|
||||
if (*b == '=')
|
||||
break;
|
||||
|
@ -1086,10 +1086,17 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
|
||||
zip->bcj_state = 0;
|
||||
break;
|
||||
case _7Z_DELTA:
|
||||
if (coder2->propertiesSize != 1) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Delta parameter");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
filters[fi].id = LZMA_FILTER_DELTA;
|
||||
memset(&delta_opt, 0, sizeof(delta_opt));
|
||||
delta_opt.type = LZMA_DELTA_TYPE_BYTE;
|
||||
delta_opt.dist = 1;
|
||||
delta_opt.dist =
|
||||
(uint32_t)coder2->properties[0] + 1;
|
||||
filters[fi].options = &delta_opt;
|
||||
fi++;
|
||||
break;
|
||||
@ -1787,7 +1794,7 @@ read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (*p != kSize)
|
||||
if (*p != kCRC)
|
||||
return (-1);
|
||||
|
||||
if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0)
|
||||
@ -2964,13 +2971,7 @@ get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
|
||||
if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) {
|
||||
/* Copy mode. */
|
||||
|
||||
/*
|
||||
* Note: '1' here is a performance optimization.
|
||||
* Recall that the decompression layer returns a count of
|
||||
* available bytes; asking for more than that forces the
|
||||
* decompressor to combine reads by copying data.
|
||||
*/
|
||||
*buff = __archive_read_ahead(a, 1, &bytes_avail);
|
||||
*buff = __archive_read_ahead(a, minimum, &bytes_avail);
|
||||
if (bytes_avail <= 0) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -3323,8 +3324,7 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
|
||||
* Release the memory which the previous folder used for BCJ2.
|
||||
*/
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (zip->sub_stream_buff[i] != NULL)
|
||||
free(zip->sub_stream_buff[i]);
|
||||
free(zip->sub_stream_buff[i]);
|
||||
zip->sub_stream_buff[i] = NULL;
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,7 @@ archive_read_support_format_all(struct archive *a)
|
||||
archive_read_support_format_7zip(a);
|
||||
archive_read_support_format_cab(a);
|
||||
archive_read_support_format_rar(a);
|
||||
archive_read_support_format_rar5(a);
|
||||
archive_read_support_format_iso9660(a);
|
||||
/* Seek is really bad, since it forces the read-ahead
|
||||
* logic to discard buffered data. */
|
||||
|
@ -138,8 +138,7 @@ archive_read_format_ar_cleanup(struct archive_read *a)
|
||||
struct ar *ar;
|
||||
|
||||
ar = (struct ar *)(a->format->data);
|
||||
if (ar->strtab)
|
||||
free(ar->strtab);
|
||||
free(ar->strtab);
|
||||
free(ar);
|
||||
(a->format->data) = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
@ -388,9 +387,10 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
|
||||
/*
|
||||
* "/" is the SVR4/GNU archive symbol table.
|
||||
* "/SYM64/" is the SVR4/GNU 64-bit variant archive symbol table.
|
||||
*/
|
||||
if (strcmp(filename, "/") == 0) {
|
||||
archive_entry_copy_pathname(entry, "/");
|
||||
if (strcmp(filename, "/") == 0 || strcmp(filename, "/SYM64/") == 0) {
|
||||
archive_entry_copy_pathname(entry, filename);
|
||||
/* Parse the time, owner, mode, size fields. */
|
||||
r = ar_parse_common_header(ar, entry, h);
|
||||
/* Force the file type to a regular file. */
|
||||
@ -459,6 +459,7 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
|
||||
uint64_t n;
|
||||
|
||||
/* Copy remaining header */
|
||||
archive_entry_set_filetype(entry, AE_IFREG);
|
||||
archive_entry_set_mtime(entry,
|
||||
(time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L);
|
||||
archive_entry_set_uid(entry,
|
||||
|
@ -60,6 +60,9 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
|
||||
case ARCHIVE_FORMAT_RAR:
|
||||
return archive_read_support_format_rar(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAR_V5:
|
||||
return archive_read_support_format_rar5(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
return archive_read_support_format_tar(a);
|
||||
break;
|
||||
|
@ -1509,8 +1509,8 @@ cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
|
||||
}
|
||||
if (mszip == 1 && cab->stream.next_in[0] != 0x4b)
|
||||
goto nomszip;
|
||||
else if (cab->stream.next_in[0] != 0x43 ||
|
||||
cab->stream.next_in[1] != 0x4b)
|
||||
else if (mszip == 2 && (cab->stream.next_in[0] != 0x43 ||
|
||||
cab->stream.next_in[1] != 0x4b))
|
||||
goto nomszip;
|
||||
cab->stream.next_in += mszip;
|
||||
cab->stream.avail_in -= mszip;
|
||||
|
@ -955,8 +955,7 @@ archive_read_format_cpio_cleanup(struct archive_read *a)
|
||||
while (cpio->links_head != NULL) {
|
||||
struct links_entry *lp = cpio->links_head->next;
|
||||
|
||||
if (cpio->links_head->name)
|
||||
free(cpio->links_head->name);
|
||||
free(cpio->links_head->name);
|
||||
free(cpio->links_head);
|
||||
cpio->links_head = lp;
|
||||
}
|
||||
|
@ -1724,8 +1724,7 @@ archive_read_format_iso9660_cleanup(struct archive_read *a)
|
||||
free(iso9660->read_ce_req.reqs);
|
||||
archive_string_free(&iso9660->pathname);
|
||||
archive_string_free(&iso9660->previous_pathname);
|
||||
if (iso9660->pending_files.files)
|
||||
free(iso9660->pending_files.files);
|
||||
free(iso9660->pending_files.files);
|
||||
#ifdef HAVE_ZLIB_H
|
||||
free(iso9660->entry_zisofs.uncompressed_buffer);
|
||||
free(iso9660->entry_zisofs.block_pointers);
|
||||
@ -2102,6 +2101,7 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
|
||||
const unsigned char *p, const unsigned char *end)
|
||||
{
|
||||
struct iso9660 *iso9660;
|
||||
int entry_seen = 0;
|
||||
|
||||
iso9660 = (struct iso9660 *)(a->format->data);
|
||||
|
||||
@ -2257,8 +2257,16 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
|
||||
}
|
||||
|
||||
p += p[2];
|
||||
entry_seen = 1;
|
||||
}
|
||||
|
||||
if (entry_seen)
|
||||
return (ARCHIVE_OK);
|
||||
else {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Tried to parse Rockridge extensions, but none found");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -3029,8 +3037,7 @@ heap_add_entry(struct archive_read *a, struct heap_queue *heap,
|
||||
if (heap->allocated)
|
||||
memcpy(new_pending_files, heap->files,
|
||||
heap->allocated * sizeof(new_pending_files[0]));
|
||||
if (heap->files != NULL)
|
||||
free(heap->files);
|
||||
free(heap->files);
|
||||
heap->files = new_pending_files;
|
||||
heap->allocated = new_size;
|
||||
}
|
||||
|
@ -175,7 +175,9 @@ struct lha {
|
||||
struct archive_string gname;
|
||||
uint16_t header_crc;
|
||||
uint16_t crc;
|
||||
struct archive_string_conv *sconv;
|
||||
/* dirname and filename could be in different codepages */
|
||||
struct archive_string_conv *sconv_dir;
|
||||
struct archive_string_conv *sconv_fname;
|
||||
struct archive_string_conv *opt_sconv;
|
||||
|
||||
struct archive_string dirname;
|
||||
@ -232,8 +234,8 @@ static time_t lha_dos_time(const unsigned char *);
|
||||
static time_t lha_win_time(uint64_t, long *);
|
||||
static unsigned char lha_calcsum(unsigned char, const void *,
|
||||
int, size_t);
|
||||
static int lha_parse_linkname(struct archive_string *,
|
||||
struct archive_string *);
|
||||
static int lha_parse_linkname(struct archive_wstring *,
|
||||
struct archive_wstring *);
|
||||
static int lha_read_data_none(struct archive_read *, const void **,
|
||||
size_t *, int64_t *);
|
||||
static int lha_read_data_lzh(struct archive_read *, const void **,
|
||||
@ -473,13 +475,15 @@ static int
|
||||
archive_read_format_lha_read_header(struct archive_read *a,
|
||||
struct archive_entry *entry)
|
||||
{
|
||||
struct archive_string linkname;
|
||||
struct archive_string pathname;
|
||||
struct archive_wstring linkname;
|
||||
struct archive_wstring pathname;
|
||||
struct lha *lha;
|
||||
const unsigned char *p;
|
||||
const char *signature;
|
||||
int err;
|
||||
|
||||
struct archive_mstring conv_buffer;
|
||||
const wchar_t *conv_buffer_p;
|
||||
|
||||
lha_crc16_init();
|
||||
|
||||
a->archive.archive_format = ARCHIVE_FORMAT_LHA;
|
||||
@ -561,10 +565,13 @@ archive_read_format_lha_read_header(struct archive_read *a,
|
||||
archive_string_empty(&lha->dirname);
|
||||
archive_string_empty(&lha->filename);
|
||||
lha->dos_attr = 0;
|
||||
if (lha->opt_sconv != NULL)
|
||||
lha->sconv = lha->opt_sconv;
|
||||
else
|
||||
lha->sconv = NULL;
|
||||
if (lha->opt_sconv != NULL) {
|
||||
lha->sconv_dir = lha->opt_sconv;
|
||||
lha->sconv_fname = lha->opt_sconv;
|
||||
} else {
|
||||
lha->sconv_dir = NULL;
|
||||
lha->sconv_fname = NULL;
|
||||
}
|
||||
|
||||
switch (p[H_LEVEL_OFFSET]) {
|
||||
case 0:
|
||||
@ -594,12 +601,54 @@ archive_read_format_lha_read_header(struct archive_read *a,
|
||||
return (truncated_error(a));
|
||||
|
||||
/*
|
||||
* Make a pathname from a dirname and a filename.
|
||||
*/
|
||||
archive_string_concat(&lha->dirname, &lha->filename);
|
||||
* Make a pathname from a dirname and a filename, after converting to Unicode.
|
||||
* This is because codepages might differ between dirname and filename.
|
||||
*/
|
||||
archive_string_init(&pathname);
|
||||
archive_string_init(&linkname);
|
||||
archive_string_copy(&pathname, &lha->dirname);
|
||||
archive_string_init(&conv_buffer.aes_mbs);
|
||||
archive_string_init(&conv_buffer.aes_mbs_in_locale);
|
||||
archive_string_init(&conv_buffer.aes_utf8);
|
||||
archive_string_init(&conv_buffer.aes_wcs);
|
||||
if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->dirname.s, lha->dirname.length, lha->sconv_dir)) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Pathname cannot be converted "
|
||||
"from %s to Unicode.",
|
||||
archive_string_conversion_charset_name(lha->sconv_dir));
|
||||
err = ARCHIVE_FATAL;
|
||||
} else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
|
||||
err = ARCHIVE_FATAL;
|
||||
if (err == ARCHIVE_FATAL) {
|
||||
archive_mstring_clean(&conv_buffer);
|
||||
archive_wstring_free(&pathname);
|
||||
archive_wstring_free(&linkname);
|
||||
return (err);
|
||||
}
|
||||
archive_wstring_copy(&pathname, &conv_buffer.aes_wcs);
|
||||
|
||||
archive_string_empty(&conv_buffer.aes_mbs);
|
||||
archive_string_empty(&conv_buffer.aes_mbs_in_locale);
|
||||
archive_string_empty(&conv_buffer.aes_utf8);
|
||||
archive_wstring_empty(&conv_buffer.aes_wcs);
|
||||
if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->filename.s, lha->filename.length, lha->sconv_fname)) {
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Pathname cannot be converted "
|
||||
"from %s to Unicode.",
|
||||
archive_string_conversion_charset_name(lha->sconv_fname));
|
||||
err = ARCHIVE_FATAL;
|
||||
}
|
||||
else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
|
||||
err = ARCHIVE_FATAL;
|
||||
if (err == ARCHIVE_FATAL) {
|
||||
archive_mstring_clean(&conv_buffer);
|
||||
archive_wstring_free(&pathname);
|
||||
archive_wstring_free(&linkname);
|
||||
return (err);
|
||||
}
|
||||
archive_wstring_concat(&pathname, &conv_buffer.aes_wcs);
|
||||
archive_mstring_clean(&conv_buffer);
|
||||
|
||||
if ((lha->mode & AE_IFMT) == AE_IFLNK) {
|
||||
/*
|
||||
@ -610,8 +659,8 @@ archive_read_format_lha_read_header(struct archive_read *a,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Unknown symlink-name");
|
||||
archive_string_free(&pathname);
|
||||
archive_string_free(&linkname);
|
||||
archive_wstring_free(&pathname);
|
||||
archive_wstring_free(&linkname);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
} else {
|
||||
@ -629,39 +678,13 @@ archive_read_format_lha_read_header(struct archive_read *a,
|
||||
/*
|
||||
* Set basic file parameters.
|
||||
*/
|
||||
if (archive_entry_copy_pathname_l(entry, pathname.s,
|
||||
pathname.length, lha->sconv) != 0) {
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Pathname");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Pathname cannot be converted "
|
||||
"from %s to current locale.",
|
||||
archive_string_conversion_charset_name(lha->sconv));
|
||||
err = ARCHIVE_WARN;
|
||||
}
|
||||
archive_string_free(&pathname);
|
||||
archive_entry_copy_pathname_w(entry, pathname.s);
|
||||
archive_wstring_free(&pathname);
|
||||
if (archive_strlen(&linkname) > 0) {
|
||||
if (archive_entry_copy_symlink_l(entry, linkname.s,
|
||||
linkname.length, lha->sconv) != 0) {
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Linkname");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Linkname cannot be converted "
|
||||
"from %s to current locale.",
|
||||
archive_string_conversion_charset_name(lha->sconv));
|
||||
err = ARCHIVE_WARN;
|
||||
}
|
||||
archive_entry_copy_symlink_w(entry, linkname.s);
|
||||
} else
|
||||
archive_entry_set_symlink(entry, NULL);
|
||||
archive_string_free(&linkname);
|
||||
archive_wstring_free(&linkname);
|
||||
/*
|
||||
* When a header level is 0, there is a possibility that
|
||||
* a pathname and a symlink has '\' character, a directory
|
||||
@ -1208,6 +1231,27 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
|
||||
archive_strncpy(&lha->filename,
|
||||
(const char *)extdheader, datasize);
|
||||
break;
|
||||
case EXT_UTF16_FILENAME:
|
||||
if (datasize == 0) {
|
||||
/* maybe directory header */
|
||||
archive_string_empty(&lha->filename);
|
||||
break;
|
||||
} else if (datasize & 1) {
|
||||
/* UTF-16 characters take always 2 or 4 bytes */
|
||||
goto invalid;
|
||||
}
|
||||
if (extdheader[0] == '\0')
|
||||
goto invalid;
|
||||
archive_string_empty(&lha->filename);
|
||||
archive_array_append(&lha->filename,
|
||||
(const char *)extdheader, datasize);
|
||||
/* Setup a string conversion for a filename. */
|
||||
lha->sconv_fname =
|
||||
archive_string_conversion_from_charset(&a->archive,
|
||||
"UTF-16LE", 1);
|
||||
if (lha->sconv_fname == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
break;
|
||||
case EXT_DIRECTORY:
|
||||
if (datasize == 0 || extdheader[0] == '\0')
|
||||
/* no directory name data. exit this case. */
|
||||
@ -1228,6 +1272,50 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
|
||||
/* invalid directory data */
|
||||
goto invalid;
|
||||
break;
|
||||
case EXT_UTF16_DIRECTORY:
|
||||
/* UTF-16 characters take always 2 or 4 bytes */
|
||||
if (datasize == 0 || (datasize & 1) ||
|
||||
extdheader[0] == '\0') {
|
||||
/* no directory name data. exit this case. */
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
archive_string_empty(&lha->dirname);
|
||||
archive_array_append(&lha->dirname,
|
||||
(const char *)extdheader, datasize);
|
||||
lha->sconv_dir =
|
||||
archive_string_conversion_from_charset(&a->archive,
|
||||
"UTF-16LE", 1);
|
||||
if (lha->sconv_dir == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
else {
|
||||
/*
|
||||
* Convert directory delimiter from 0xFFFF
|
||||
* to '/' for local system.
|
||||
*/
|
||||
uint16_t dirSep;
|
||||
uint16_t d = 1;
|
||||
if (archive_be16dec(&d) == 1)
|
||||
dirSep = 0x2F00;
|
||||
else
|
||||
dirSep = 0x002F;
|
||||
|
||||
/* UTF-16LE character */
|
||||
uint16_t *utf16name =
|
||||
(uint16_t *)lha->dirname.s;
|
||||
for (i = 0; i < lha->dirname.length / 2; i++) {
|
||||
if (utf16name[i] == 0xFFFF) {
|
||||
utf16name[i] = dirSep;
|
||||
}
|
||||
}
|
||||
/* Is last character directory separator? */
|
||||
if (utf16name[lha->dirname.length / 2 - 1] !=
|
||||
dirSep) {
|
||||
/* invalid directory data */
|
||||
goto invalid;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXT_DOS_ATTR:
|
||||
if (datasize == 2)
|
||||
lha->dos_attr = (unsigned char)
|
||||
@ -1276,11 +1364,16 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
|
||||
charset = cp.s;
|
||||
break;
|
||||
}
|
||||
lha->sconv =
|
||||
lha->sconv_dir =
|
||||
archive_string_conversion_from_charset(
|
||||
&(a->archive), charset, 1);
|
||||
lha->sconv_fname =
|
||||
archive_string_conversion_from_charset(
|
||||
&(a->archive), charset, 1);
|
||||
archive_string_free(&cp);
|
||||
if (lha->sconv == NULL)
|
||||
if (lha->sconv_dir == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (lha->sconv_fname == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
break;
|
||||
@ -1336,8 +1429,7 @@ lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
|
||||
}
|
||||
break;
|
||||
case EXT_TIMEZONE: /* Not supported */
|
||||
case EXT_UTF16_FILENAME: /* Not supported */
|
||||
case EXT_UTF16_DIRECTORY: /* Not supported */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1600,19 +1692,19 @@ archive_read_format_lha_cleanup(struct archive_read *a)
|
||||
* then a archived pathname is 'xxx/bbb|aaa/bb/cc'
|
||||
*/
|
||||
static int
|
||||
lha_parse_linkname(struct archive_string *linkname,
|
||||
struct archive_string *pathname)
|
||||
lha_parse_linkname(struct archive_wstring *linkname,
|
||||
struct archive_wstring *pathname)
|
||||
{
|
||||
char * linkptr;
|
||||
wchar_t * linkptr;
|
||||
size_t symlen;
|
||||
|
||||
linkptr = strchr(pathname->s, '|');
|
||||
linkptr = wcschr(pathname->s, L'|');
|
||||
if (linkptr != NULL) {
|
||||
symlen = strlen(linkptr + 1);
|
||||
archive_strncpy(linkname, linkptr+1, symlen);
|
||||
symlen = wcslen(linkptr + 1);
|
||||
archive_wstrncpy(linkname, linkptr+1, symlen);
|
||||
|
||||
*linkptr = 0;
|
||||
pathname->length = strlen(pathname->s);
|
||||
pathname->length = wcslen(pathname->s);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
@ -45,6 +45,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
@ -255,6 +258,7 @@ archive_read_support_format_mtree(struct archive *_a)
|
||||
"Can't allocate mtree data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
mtree->checkfs = 0;
|
||||
mtree->fd = -1;
|
||||
|
||||
__archive_rb_tree_init(&mtree->rbtree, &rb_ops);
|
||||
@ -1011,7 +1015,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
{
|
||||
ssize_t len;
|
||||
uintmax_t counter;
|
||||
char *p;
|
||||
char *p, *s;
|
||||
struct mtree_option *global;
|
||||
struct mtree_entry *last_entry;
|
||||
int r, is_form_d;
|
||||
@ -1025,6 +1029,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
(void)detect_form(a, &is_form_d);
|
||||
|
||||
for (counter = 1; ; ++counter) {
|
||||
r = ARCHIVE_OK;
|
||||
len = readline(a, mtree, &p, 65536);
|
||||
if (len == 0) {
|
||||
mtree->this_entry = mtree->entries;
|
||||
@ -1045,6 +1050,15 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
continue;
|
||||
if (*p == '\r' || *p == '\n' || *p == '\0')
|
||||
continue;
|
||||
/* Non-printable characters are not allowed */
|
||||
for (s = p;s < p + len - 1; s++) {
|
||||
if (!isprint(*s)) {
|
||||
r = ARCHIVE_FATAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r != ARCHIVE_OK)
|
||||
break;
|
||||
if (*p != '/') {
|
||||
r = process_add_entry(a, mtree, &global, p, len,
|
||||
&last_entry, is_form_d);
|
||||
|
@ -148,6 +148,9 @@
|
||||
#define FILE_ATTRIBUTE_DIRECTORY 0x10
|
||||
#endif
|
||||
|
||||
#undef minimum
|
||||
#define minimum(a, b) ((a)<(b)?(a):(b))
|
||||
|
||||
/* Fields common to all headers */
|
||||
struct rar_header
|
||||
{
|
||||
@ -258,6 +261,7 @@ struct rar
|
||||
struct data_block_offsets *dbo;
|
||||
unsigned int cursor;
|
||||
unsigned int nodes;
|
||||
char filename_must_match;
|
||||
|
||||
/* LZSS members */
|
||||
struct huffman_code maincode;
|
||||
@ -1023,8 +1027,11 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
||||
case COMPRESS_METHOD_GOOD:
|
||||
case COMPRESS_METHOD_BEST:
|
||||
ret = read_data_compressed(a, buff, size, offset);
|
||||
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
|
||||
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
|
||||
rar->start_new_table = 1;
|
||||
rar->ppmd_valid = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1560,6 +1567,12 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else if (rar->filename_must_match)
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Mismatch of file parts split across multi-volume archive");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
rar->filename_save = (char*)realloc(rar->filename_save,
|
||||
filename_size + 1);
|
||||
@ -1712,6 +1725,13 @@ 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)
|
||||
struct tm tmbuf;
|
||||
#endif
|
||||
#if defined(HAVE__LOCALTIME64_S)
|
||||
errno_t terr;
|
||||
__time64_t tmptime;
|
||||
#endif
|
||||
|
||||
if (p + 2 > endp)
|
||||
return (-1);
|
||||
@ -1743,7 +1763,18 @@ 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)
|
||||
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
|
||||
nsec = tm->tm_sec + rem / NS_UNIT;
|
||||
if (rmode & 4)
|
||||
{
|
||||
@ -2300,6 +2331,11 @@ parse_codes(struct archive_read *a)
|
||||
new_size = DICTIONARY_MAX_SIZE;
|
||||
else
|
||||
new_size = rar_fls((unsigned int)rar->unp_size) << 1;
|
||||
if (new_size == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Zero window size is invalid.");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
new_window = realloc(rar->lzss.window, new_size);
|
||||
if (new_window == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
@ -2437,8 +2473,11 @@ create_code(struct archive_read *a, struct huffman_code *code,
|
||||
if (add_value(a, code, j, codebits, i) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
codebits++;
|
||||
if (--symbolsleft <= 0) { break; break; }
|
||||
if (--symbolsleft <= 0)
|
||||
break;
|
||||
}
|
||||
if (symbolsleft <= 0)
|
||||
break;
|
||||
codebits <<= 1;
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
@ -2448,7 +2487,8 @@ static int
|
||||
add_value(struct archive_read *a, struct huffman_code *code, int value,
|
||||
int codebits, int length)
|
||||
{
|
||||
int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode;
|
||||
int lastnode, bitpos, bit;
|
||||
/* int repeatpos, repeatnode, nextnode; */
|
||||
|
||||
free(code->table);
|
||||
code->table = NULL;
|
||||
@ -2458,6 +2498,9 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
|
||||
if(length < code->minlength)
|
||||
code->minlength = length;
|
||||
|
||||
/*
|
||||
* Dead code, repeatpos was is -1
|
||||
*
|
||||
repeatpos = -1;
|
||||
if (repeatpos == 0 || (repeatpos >= 0
|
||||
&& (((codebits >> (repeatpos - 1)) & 3) == 0
|
||||
@ -2467,6 +2510,7 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
|
||||
"Invalid repeat position");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
*/
|
||||
|
||||
lastnode = 0;
|
||||
for (bitpos = length - 1; bitpos >= 0; bitpos--)
|
||||
@ -2482,9 +2526,12 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dead code, repeatpos was -1, bitpos >=0
|
||||
*
|
||||
if (bitpos == repeatpos)
|
||||
{
|
||||
/* Open branch check */
|
||||
* Open branch check *
|
||||
if (!(code->tree[lastnode].branches[bit] < 0))
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -2503,16 +2550,17 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Set branches */
|
||||
* Set branches *
|
||||
code->tree[lastnode].branches[bit] = repeatnode;
|
||||
code->tree[repeatnode].branches[bit] = repeatnode;
|
||||
code->tree[repeatnode].branches[bit^1] = nextnode;
|
||||
lastnode = nextnode;
|
||||
|
||||
bitpos++; /* terminating bit already handled, skip it */
|
||||
bitpos++; * terminating bit already handled, skip it *
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
/* Open branch check */
|
||||
if (code->tree[lastnode].branches[bit] < 0)
|
||||
{
|
||||
@ -2526,7 +2574,7 @@ add_value(struct archive_read *a, struct huffman_code *code, int value,
|
||||
|
||||
/* set to branch */
|
||||
lastnode = code->tree[lastnode].branches[bit];
|
||||
}
|
||||
/* } */
|
||||
}
|
||||
|
||||
if (!(code->tree[lastnode].branches[0] == -1
|
||||
@ -2610,11 +2658,15 @@ make_table_recurse(struct archive_read *a, struct huffman_code *code, int node,
|
||||
table[i].value = code->tree[node].branches[0];
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Dead code, node >= 0
|
||||
*
|
||||
else if (node < 0)
|
||||
{
|
||||
for(i = 0; i < currtablesize; i++)
|
||||
table[i].length = -1;
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
if(depth == maxdepth)
|
||||
@ -2646,6 +2698,10 @@ expand(struct archive_read *a, int64_t end)
|
||||
0, 1, 1, 1, 1, 2, 2,
|
||||
2, 2, 3, 3, 3, 3, 4,
|
||||
4, 4, 4, 5, 5, 5, 5 };
|
||||
static const int lengthb_min = minimum(
|
||||
(int)(sizeof(lengthbases)/sizeof(lengthbases[0])),
|
||||
(int)(sizeof(lengthbits)/sizeof(lengthbits[0]))
|
||||
);
|
||||
static const unsigned int offsetbases[] =
|
||||
{ 0, 1, 2, 3, 4, 6,
|
||||
8, 12, 16, 24, 32, 48,
|
||||
@ -2663,6 +2719,10 @@ expand(struct archive_read *a, int64_t end)
|
||||
11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 };
|
||||
static const int offsetb_min = minimum(
|
||||
(int)(sizeof(offsetbases)/sizeof(offsetbases[0])),
|
||||
(int)(sizeof(offsetbits)/sizeof(offsetbits[0]))
|
||||
);
|
||||
static const unsigned char shortbases[] =
|
||||
{ 0, 4, 8, 16, 32, 64, 128, 192 };
|
||||
static const unsigned char shortbits[] =
|
||||
@ -2742,9 +2802,7 @@ expand(struct archive_read *a, int64_t end)
|
||||
|
||||
if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
|
||||
goto bad_data;
|
||||
if (lensymbol > (int)(sizeof(lengthbases)/sizeof(lengthbases[0])))
|
||||
goto bad_data;
|
||||
if (lensymbol > (int)(sizeof(lengthbits)/sizeof(lengthbits[0])))
|
||||
if (lensymbol > lengthb_min)
|
||||
goto bad_data;
|
||||
len = lengthbases[lensymbol] + 2;
|
||||
if (lengthbits[lensymbol] > 0) {
|
||||
@ -2776,9 +2834,7 @@ expand(struct archive_read *a, int64_t end)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (symbol-271 > (int)(sizeof(lengthbases)/sizeof(lengthbases[0])))
|
||||
goto bad_data;
|
||||
if (symbol-271 > (int)(sizeof(lengthbits)/sizeof(lengthbits[0])))
|
||||
if (symbol-271 > lengthb_min)
|
||||
goto bad_data;
|
||||
len = lengthbases[symbol-271]+3;
|
||||
if(lengthbits[symbol-271] > 0) {
|
||||
@ -2790,9 +2846,7 @@ expand(struct archive_read *a, int64_t end)
|
||||
|
||||
if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
|
||||
goto bad_data;
|
||||
if (offssymbol > (int)(sizeof(offsetbases)/sizeof(offsetbases[0])))
|
||||
goto bad_data;
|
||||
if (offssymbol > (int)(sizeof(offsetbits)/sizeof(offsetbits[0])))
|
||||
if (offssymbol > offsetb_min)
|
||||
goto bad_data;
|
||||
offs = offsetbases[offssymbol]+1;
|
||||
if(offsetbits[offssymbol] > 0)
|
||||
@ -2928,12 +2982,14 @@ rar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
|
||||
else if (*avail == 0 && rar->main_flags & MHD_VOLUME &&
|
||||
rar->file_flags & FHD_SPLIT_AFTER)
|
||||
{
|
||||
rar->filename_must_match = 1;
|
||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
||||
if (ret == (ARCHIVE_EOF))
|
||||
{
|
||||
rar->has_endarc_header = 1;
|
||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
||||
}
|
||||
rar->filename_must_match = 0;
|
||||
if (ret != (ARCHIVE_OK))
|
||||
return NULL;
|
||||
return rar_read_ahead(a, min, avail);
|
||||
|
4103
libarchive/archive_read_support_format_rar5.c
Normal file
4103
libarchive/archive_read_support_format_rar5.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -120,7 +120,9 @@ archive_read_format_raw_read_header(struct archive_read *a,
|
||||
archive_entry_set_filetype(entry, AE_IFREG);
|
||||
archive_entry_set_perm(entry, 0644);
|
||||
/* I'm deliberately leaving most fields unset here. */
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
/* Let the filter fill out any fields it might have. */
|
||||
return __archive_read_header(a, entry);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -694,11 +694,13 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
struct archive_entry *entry, size_t *unconsumed)
|
||||
{
|
||||
ssize_t bytes;
|
||||
int err;
|
||||
int err, eof_vol_header;
|
||||
const char *h;
|
||||
const struct archive_entry_header_ustar *header;
|
||||
const struct archive_entry_header_gnutar *gnuheader;
|
||||
|
||||
eof_vol_header = 0;
|
||||
|
||||
/* Loop until we find a workable header record. */
|
||||
for (;;) {
|
||||
tar_flush_unconsumed(a, unconsumed);
|
||||
@ -788,6 +790,8 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
break;
|
||||
case 'V': /* GNU volume header */
|
||||
err = header_volume(a, tar, entry, h, unconsumed);
|
||||
if (err == ARCHIVE_EOF)
|
||||
eof_vol_header = 1;
|
||||
break;
|
||||
case 'X': /* Used by SUN tar; same as 'x'. */
|
||||
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
||||
@ -862,9 +866,17 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
if (err == ARCHIVE_EOF)
|
||||
/* EOF when recursively reading a header is bad. */
|
||||
archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
|
||||
if (err == ARCHIVE_EOF) {
|
||||
if (!eof_vol_header) {
|
||||
/* EOF when recursively reading a header is bad. */
|
||||
archive_set_error(&a->archive, EINVAL,
|
||||
"Damaged tar archive");
|
||||
} else {
|
||||
/* If we encounter just a GNU volume header treat
|
||||
* this situation as an empty archive */
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
}
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
@ -1942,6 +1954,15 @@ pax_attribute(struct archive_read *a, struct tar *tar,
|
||||
pax_time(value, &s, &n);
|
||||
archive_entry_set_birthtime(entry, s, n);
|
||||
}
|
||||
if (strcmp(key, "LIBARCHIVE.symlinktype") == 0) {
|
||||
if (strcmp(value, "file") == 0) {
|
||||
archive_entry_set_symlink_type(entry,
|
||||
AE_SYMLINK_TYPE_FILE);
|
||||
} else if (strcmp(value, "dir") == 0) {
|
||||
archive_entry_set_symlink_type(entry,
|
||||
AE_SYMLINK_TYPE_DIRECTORY);
|
||||
}
|
||||
}
|
||||
if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
|
||||
pax_attribute_xattr(entry, key, value);
|
||||
break;
|
||||
|
@ -386,6 +386,11 @@ _warc_read(struct archive_read *a, const void **buf, size_t *bsz, int64_t *off)
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
|
||||
if (w->unconsumed) {
|
||||
__archive_read_consume(a, w->unconsumed);
|
||||
w->unconsumed = 0U;
|
||||
}
|
||||
|
||||
rab = __archive_read_ahead(a, 1U, &nrd);
|
||||
if (nrd < 0) {
|
||||
*bsz = 0U;
|
||||
@ -621,7 +626,8 @@ _warc_rdver(const char *buf, size_t bsz)
|
||||
if (ver >= 1200U) {
|
||||
if (memcmp(c, "\r\n", 2U) != 0)
|
||||
ver = 0U;
|
||||
} else if (ver < 1200U) {
|
||||
} else {
|
||||
/* ver < 1200U */
|
||||
if (*c != ' ' && *c != '\t')
|
||||
ver = 0U;
|
||||
}
|
||||
@ -739,8 +745,9 @@ _warc_rdlen(const char *buf, size_t bsz)
|
||||
/* there must be at least one digit */
|
||||
if (!isdigit((unsigned char)*val))
|
||||
return -1;
|
||||
errno = 0;
|
||||
len = strtol(val, &on, 10);
|
||||
if (on != eol) {
|
||||
if (errno != 0 || on != eol) {
|
||||
/* line must end here */
|
||||
return -1;
|
||||
}
|
||||
|
@ -167,6 +167,9 @@ struct xar_file {
|
||||
#define HAS_FFLAGS 0x01000
|
||||
#define HAS_XATTR 0x02000
|
||||
#define HAS_ACL 0x04000
|
||||
#define HAS_CTIME 0x08000
|
||||
#define HAS_MTIME 0x10000
|
||||
#define HAS_ATIME 0x20000
|
||||
|
||||
uint64_t id;
|
||||
uint64_t length;
|
||||
@ -695,9 +698,15 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
|
||||
*/
|
||||
file_free(file);
|
||||
}
|
||||
archive_entry_set_atime(entry, file->atime, 0);
|
||||
archive_entry_set_ctime(entry, file->ctime, 0);
|
||||
archive_entry_set_mtime(entry, file->mtime, 0);
|
||||
if (file->has & HAS_ATIME) {
|
||||
archive_entry_set_atime(entry, file->atime, 0);
|
||||
}
|
||||
if (file->has & HAS_CTIME) {
|
||||
archive_entry_set_ctime(entry, file->ctime, 0);
|
||||
}
|
||||
if (file->has & HAS_MTIME) {
|
||||
archive_entry_set_mtime(entry, file->mtime, 0);
|
||||
}
|
||||
archive_entry_set_gid(entry, file->gid);
|
||||
if (file->gname.length > 0 &&
|
||||
archive_entry_copy_gname_l(entry, file->gname.s,
|
||||
@ -789,7 +798,8 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
|
||||
xattr = file->xattr_list;
|
||||
while (xattr != NULL) {
|
||||
const void *d;
|
||||
size_t outbytes, used;
|
||||
size_t outbytes = 0;
|
||||
size_t used = 0;
|
||||
|
||||
r = move_reading_point(a, xattr->offset);
|
||||
if (r != ARCHIVE_OK)
|
||||
@ -811,8 +821,18 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
|
||||
r = checksum_final(a,
|
||||
xattr->a_sum.val, xattr->a_sum.len,
|
||||
xattr->e_sum.val, xattr->e_sum.len);
|
||||
if (r != ARCHIVE_OK)
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
|
||||
"Xattr checksum error");
|
||||
r = ARCHIVE_WARN;
|
||||
break;
|
||||
}
|
||||
if (xattr->name.s == NULL) {
|
||||
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
|
||||
"Xattr name error");
|
||||
r = ARCHIVE_WARN;
|
||||
break;
|
||||
}
|
||||
archive_entry_xattr_add_entry(entry,
|
||||
xattr->name.s, d, outbytes);
|
||||
xattr = xattr->next;
|
||||
@ -838,7 +858,7 @@ xar_read_data(struct archive_read *a,
|
||||
const void **buff, size_t *size, int64_t *offset)
|
||||
{
|
||||
struct xar *xar;
|
||||
size_t used;
|
||||
size_t used = 0;
|
||||
int r;
|
||||
|
||||
xar = (struct xar *)(a->format->data);
|
||||
@ -967,7 +987,7 @@ move_reading_point(struct archive_read *a, uint64_t offset)
|
||||
return ((int)step);
|
||||
xar->offset += step;
|
||||
} else {
|
||||
int64_t pos = __archive_read_seek(a, offset, SEEK_SET);
|
||||
int64_t pos = __archive_read_seek(a, xar->h_base + offset, SEEK_SET);
|
||||
if (pos == ARCHIVE_FAILED) {
|
||||
archive_set_error(&(a->archive),
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
@ -1220,8 +1240,7 @@ heap_add_entry(struct archive_read *a,
|
||||
}
|
||||
memcpy(new_pending_files, heap->files,
|
||||
heap->allocated * sizeof(new_pending_files[0]));
|
||||
if (heap->files != NULL)
|
||||
free(heap->files);
|
||||
free(heap->files);
|
||||
heap->files = new_pending_files;
|
||||
heap->allocated = new_size;
|
||||
}
|
||||
@ -1767,8 +1786,8 @@ file_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list)
|
||||
}
|
||||
file->parent = xar->file;
|
||||
file->mode = 0777 | AE_IFREG;
|
||||
file->atime = time(NULL);
|
||||
file->mtime = time(NULL);
|
||||
file->atime = 0;
|
||||
file->mtime = 0;
|
||||
xar->file = file;
|
||||
xar->xattr = NULL;
|
||||
for (attr = list->first; attr != NULL; attr = attr->next) {
|
||||
@ -2594,15 +2613,14 @@ strappend_base64(struct xar *xar,
|
||||
while (l > 0) {
|
||||
int n = 0;
|
||||
|
||||
if (l > 0) {
|
||||
if (base64[b[0]] < 0 || base64[b[1]] < 0)
|
||||
break;
|
||||
n = base64[*b++] << 18;
|
||||
n |= base64[*b++] << 12;
|
||||
*out++ = n >> 16;
|
||||
len++;
|
||||
l -= 2;
|
||||
}
|
||||
if (base64[b[0]] < 0 || base64[b[1]] < 0)
|
||||
break;
|
||||
n = base64[*b++] << 18;
|
||||
n |= base64[*b++] << 12;
|
||||
*out++ = n >> 16;
|
||||
len++;
|
||||
l -= 2;
|
||||
|
||||
if (l > 0) {
|
||||
if (base64[*b] < 0)
|
||||
break;
|
||||
@ -2751,15 +2769,15 @@ xml_data(void *userData, const char *s, int len)
|
||||
xar->file->uid = atol10(s, len);
|
||||
break;
|
||||
case FILE_CTIME:
|
||||
xar->file->has |= HAS_TIME;
|
||||
xar->file->has |= HAS_TIME | HAS_CTIME;
|
||||
xar->file->ctime = parse_time(s, len);
|
||||
break;
|
||||
case FILE_MTIME:
|
||||
xar->file->has |= HAS_TIME;
|
||||
xar->file->has |= HAS_TIME | HAS_MTIME;
|
||||
xar->file->mtime = parse_time(s, len);
|
||||
break;
|
||||
case FILE_ATIME:
|
||||
xar->file->has |= HAS_TIME;
|
||||
xar->file->has |= HAS_TIME | HAS_ATIME;
|
||||
xar->file->atime = parse_time(s, len);
|
||||
break;
|
||||
case FILE_DATA_LENGTH:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -75,6 +75,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33
|
||||
#define wmemmove(a,b,i) (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t))
|
||||
#endif
|
||||
|
||||
#undef max
|
||||
#define max(a, b) ((a)>(b)?(a):(b))
|
||||
|
||||
struct archive_string_conv {
|
||||
struct archive_string_conv *next;
|
||||
char *from_charset;
|
||||
@ -458,7 +461,7 @@ archive_wstring_append_from_mbs_in_codepage(struct archive_wstring *dest,
|
||||
|
||||
if (from_cp == CP_C_LOCALE) {
|
||||
/*
|
||||
* "C" locale special process.
|
||||
* "C" locale special processing.
|
||||
*/
|
||||
wchar_t *ws;
|
||||
const unsigned char *mp;
|
||||
@ -591,7 +594,7 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
|
||||
* No single byte will be more than one wide character,
|
||||
* so this length estimate will always be big enough.
|
||||
*/
|
||||
size_t wcs_length = len;
|
||||
// size_t wcs_length = len;
|
||||
size_t mbs_length = len;
|
||||
const char *mbs = p;
|
||||
wchar_t *wcs;
|
||||
@ -600,7 +603,11 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
|
||||
|
||||
memset(&shift_state, 0, sizeof(shift_state));
|
||||
#endif
|
||||
if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
|
||||
/*
|
||||
* As we decided to have wcs_length == mbs_length == len
|
||||
* we can use len here instead of wcs_length
|
||||
*/
|
||||
if (NULL == archive_wstring_ensure(dest, dest->length + len + 1))
|
||||
return (-1);
|
||||
wcs = dest->s + dest->length;
|
||||
/*
|
||||
@ -609,6 +616,12 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
|
||||
* multi bytes.
|
||||
*/
|
||||
while (*mbs && mbs_length > 0) {
|
||||
/*
|
||||
* The buffer we allocated is always big enough.
|
||||
* Keep this code path in a comment if we decide to choose
|
||||
* smaller wcs_length in the future
|
||||
*/
|
||||
/*
|
||||
if (wcs_length == 0) {
|
||||
dest->length = wcs - dest->s;
|
||||
dest->s[dest->length] = L'\0';
|
||||
@ -618,24 +631,20 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
|
||||
return (-1);
|
||||
wcs = dest->s + dest->length;
|
||||
}
|
||||
*/
|
||||
#if HAVE_MBRTOWC
|
||||
r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
|
||||
r = mbrtowc(wcs, mbs, mbs_length, &shift_state);
|
||||
#else
|
||||
r = mbtowc(wcs, mbs, wcs_length);
|
||||
r = mbtowc(wcs, mbs, mbs_length);
|
||||
#endif
|
||||
if (r == (size_t)-1 || r == (size_t)-2) {
|
||||
ret_val = -1;
|
||||
if (errno == EILSEQ) {
|
||||
++mbs;
|
||||
--mbs_length;
|
||||
continue;
|
||||
} else
|
||||
break;
|
||||
break;
|
||||
}
|
||||
if (r == 0 || r > mbs_length)
|
||||
break;
|
||||
wcs++;
|
||||
wcs_length--;
|
||||
// wcs_length--;
|
||||
mbs += r;
|
||||
mbs_length -= r;
|
||||
}
|
||||
@ -680,7 +689,7 @@ archive_string_append_from_wcs_in_codepage(struct archive_string *as,
|
||||
|
||||
if (to_cp == CP_C_LOCALE) {
|
||||
/*
|
||||
* "C" locale special process.
|
||||
* "C" locale special processing.
|
||||
*/
|
||||
const wchar_t *wp = ws;
|
||||
char *p;
|
||||
@ -735,7 +744,8 @@ archive_string_append_from_wcs_in_codepage(struct archive_string *as,
|
||||
else
|
||||
dp = &defchar_used;
|
||||
count = WideCharToMultiByte(to_cp, 0, ws, wslen,
|
||||
as->s + as->length, (int)as->buffer_length-1, NULL, dp);
|
||||
as->s + as->length,
|
||||
(int)as->buffer_length - as->length - 1, NULL, dp);
|
||||
if (count == 0 &&
|
||||
GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
/* Expand the MBS buffer and retry. */
|
||||
@ -798,7 +808,8 @@ archive_string_append_from_wcs(struct archive_string *as,
|
||||
as->s[as->length] = '\0';
|
||||
/* Re-allocate buffer for MBS. */
|
||||
if (archive_string_ensure(as,
|
||||
as->length + len * 2 + 1) == NULL)
|
||||
as->length + max(len * 2,
|
||||
(size_t)MB_CUR_MAX) + 1) == NULL)
|
||||
return (-1);
|
||||
p = as->s + as->length;
|
||||
end = as->s + as->buffer_length - MB_CUR_MAX -1;
|
||||
@ -889,7 +900,7 @@ add_converter(struct archive_string_conv *sc, int (*converter)
|
||||
struct archive_string_conv *))
|
||||
{
|
||||
if (sc == NULL || sc->nconverter >= 2)
|
||||
__archive_errx(1, "Programing error");
|
||||
__archive_errx(1, "Programming error");
|
||||
sc->converter[sc->nconverter++] = converter;
|
||||
}
|
||||
|
||||
@ -1512,8 +1523,10 @@ get_current_codepage(void)
|
||||
p = strrchr(locale, '.');
|
||||
if (p == NULL)
|
||||
return (GetACP());
|
||||
if (strcmp(p+1, "utf8") == 0)
|
||||
return CP_UTF8;
|
||||
cp = my_atoi(p+1);
|
||||
if (cp <= 0)
|
||||
if ((int)cp <= 0)
|
||||
return (GetACP());
|
||||
return (cp);
|
||||
}
|
||||
@ -3438,7 +3451,8 @@ strncat_from_utf8_libarchive2(struct archive_string *as,
|
||||
as->length = p - as->s;
|
||||
/* Re-allocate buffer for MBS. */
|
||||
if (archive_string_ensure(as,
|
||||
as->length + len * 2 + 1) == NULL)
|
||||
as->length + max(len * 2,
|
||||
(size_t)MB_CUR_MAX) + 1) == NULL)
|
||||
return (-1);
|
||||
p = as->s + as->length;
|
||||
end = as->s + as->buffer_length - MB_CUR_MAX -1;
|
||||
@ -4050,6 +4064,7 @@ archive_mstring_copy_utf8(struct archive_mstring *aes, const char *utf8)
|
||||
{
|
||||
if (utf8 == NULL) {
|
||||
aes->aes_set = 0;
|
||||
return (0);
|
||||
}
|
||||
aes->aes_set = AES_SET_UTF8;
|
||||
archive_string_empty(&(aes->aes_mbs));
|
||||
@ -4064,6 +4079,7 @@ archive_mstring_copy_wcs_len(struct archive_mstring *aes, const wchar_t *wcs,
|
||||
{
|
||||
if (wcs == NULL) {
|
||||
aes->aes_set = 0;
|
||||
return (0);
|
||||
}
|
||||
aes->aes_set = AES_SET_WCS; /* Only WCS form set. */
|
||||
archive_string_empty(&(aes->aes_mbs));
|
||||
|
@ -26,15 +26,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_STRING_H_INCLUDED
|
||||
#define ARCHIVE_STRING_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_STRING_H_INCLUDED
|
||||
#define ARCHIVE_STRING_H_INCLUDED
|
||||
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for wchar_t on some systems */
|
||||
|
@ -34,13 +34,13 @@
|
||||
* See also http://unicode.org/report/tr15/
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
|
||||
#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
|
||||
#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
|
||||
|
||||
struct unicode_composition_table {
|
||||
uint32_t cp1;
|
||||
uint32_t cp2;
|
||||
|
@ -92,10 +92,10 @@ Clears any error information left over from a previous call.
|
||||
Not generally used in client code.
|
||||
.It Fn archive_compression
|
||||
Synonym for
|
||||
.Fn archive_filter_code(a, 0) .
|
||||
.Fn archive_filter_code a 0 .
|
||||
.It Fn archive_compression_name
|
||||
Synonym for
|
||||
.Fn archive_filter_name(a, 0) .
|
||||
.Fn archive_filter_name a 0 .
|
||||
.It Fn archive_copy_error
|
||||
Copies error information from one archive to another.
|
||||
.It Fn archive_errno
|
||||
@ -142,13 +142,13 @@ filter 0 is the gunzip filter,
|
||||
filter 1 is the uudecode filter,
|
||||
and filter 2 is the pseudo-filter that wraps the archive read functions.
|
||||
In this case, requesting
|
||||
.Fn archive_position(a, -1)
|
||||
.Fn archive_position a -1
|
||||
would be a synonym for
|
||||
.Fn archive_position(a, 2)
|
||||
.Fn archive_position a 2
|
||||
which would return the number of bytes currently read from the archive, while
|
||||
.Fn archive_position(a, 1)
|
||||
.Fn archive_position a 1
|
||||
would return the number of bytes after uudecoding, and
|
||||
.Fn archive_position(a, 0)
|
||||
.Fn archive_position a 0
|
||||
would return the number of bytes after decompression.
|
||||
.It Fn archive_filter_name
|
||||
Returns a textual name identifying the indicated filter.
|
||||
@ -170,9 +170,9 @@ A textual description of the format of the current entry.
|
||||
.It Fn archive_position
|
||||
Returns the number of bytes read from or written to the indicated filter.
|
||||
In particular,
|
||||
.Fn archive_position(a, 0)
|
||||
.Fn archive_position a 0
|
||||
returns the number of bytes read or written by the format handler, while
|
||||
.Fn archive_position(a, -1)
|
||||
.Fn archive_position a -1
|
||||
returns the number of bytes read or written to the archive.
|
||||
See
|
||||
.Fn archive_filter_count
|
||||
|
@ -218,8 +218,8 @@ __archive_errx(int retvalue, const char *msg)
|
||||
* Also Windows version of mktemp family including _mktemp_s
|
||||
* are not secure.
|
||||
*/
|
||||
int
|
||||
__archive_mktemp(const char *tmpdir)
|
||||
static int
|
||||
__archive_mktempx(const char *tmpdir, wchar_t *template)
|
||||
{
|
||||
static const wchar_t prefix[] = L"libarchive_";
|
||||
static const wchar_t suffix[] = L"XXXXXXXXXX";
|
||||
@ -243,64 +243,76 @@ __archive_mktemp(const char *tmpdir)
|
||||
hProv = (HCRYPTPROV)NULL;
|
||||
fd = -1;
|
||||
ws = NULL;
|
||||
archive_string_init(&temp_name);
|
||||
|
||||
/* Get a temporary directory. */
|
||||
if (tmpdir == NULL) {
|
||||
size_t l;
|
||||
wchar_t *tmp;
|
||||
if (template == NULL) {
|
||||
archive_string_init(&temp_name);
|
||||
|
||||
l = GetTempPathW(0, NULL);
|
||||
if (l == 0) {
|
||||
la_dosmaperr(GetLastError());
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
tmp = malloc(l*sizeof(wchar_t));
|
||||
if (tmp == NULL) {
|
||||
errno = ENOMEM;
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
GetTempPathW((DWORD)l, tmp);
|
||||
archive_wstrcpy(&temp_name, tmp);
|
||||
free(tmp);
|
||||
} else {
|
||||
if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
|
||||
strlen(tmpdir)) < 0)
|
||||
goto exit_tmpfile;
|
||||
if (temp_name.s[temp_name.length-1] != L'/')
|
||||
archive_wstrappend_wchar(&temp_name, L'/');
|
||||
}
|
||||
/* Get a temporary directory. */
|
||||
if (tmpdir == NULL) {
|
||||
size_t l;
|
||||
wchar_t *tmp;
|
||||
|
||||
/* Check if temp_name is a directory. */
|
||||
attr = GetFileAttributesW(temp_name.s);
|
||||
if (attr == (DWORD)-1) {
|
||||
if (GetLastError() != ERROR_FILE_NOT_FOUND) {
|
||||
la_dosmaperr(GetLastError());
|
||||
goto exit_tmpfile;
|
||||
l = GetTempPathW(0, NULL);
|
||||
if (l == 0) {
|
||||
la_dosmaperr(GetLastError());
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
tmp = malloc(l*sizeof(wchar_t));
|
||||
if (tmp == NULL) {
|
||||
errno = ENOMEM;
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
GetTempPathW((DWORD)l, tmp);
|
||||
archive_wstrcpy(&temp_name, tmp);
|
||||
free(tmp);
|
||||
} else {
|
||||
if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
|
||||
strlen(tmpdir)) < 0)
|
||||
goto exit_tmpfile;
|
||||
if (temp_name.s[temp_name.length-1] != L'/')
|
||||
archive_wstrappend_wchar(&temp_name, L'/');
|
||||
}
|
||||
ws = __la_win_permissive_name_w(temp_name.s);
|
||||
if (ws == NULL) {
|
||||
errno = EINVAL;
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
attr = GetFileAttributesW(ws);
|
||||
|
||||
/* Check if temp_name is a directory. */
|
||||
attr = GetFileAttributesW(temp_name.s);
|
||||
if (attr == (DWORD)-1) {
|
||||
la_dosmaperr(GetLastError());
|
||||
if (GetLastError() != ERROR_FILE_NOT_FOUND) {
|
||||
la_dosmaperr(GetLastError());
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
ws = __la_win_permissive_name_w(temp_name.s);
|
||||
if (ws == NULL) {
|
||||
errno = EINVAL;
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
attr = GetFileAttributesW(ws);
|
||||
if (attr == (DWORD)-1) {
|
||||
la_dosmaperr(GetLastError());
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
}
|
||||
if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
errno = ENOTDIR;
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
}
|
||||
if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
errno = ENOTDIR;
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a temporary file.
|
||||
*/
|
||||
archive_wstrcat(&temp_name, prefix);
|
||||
archive_wstrcat(&temp_name, suffix);
|
||||
ep = temp_name.s + archive_strlen(&temp_name);
|
||||
xp = ep - wcslen(suffix);
|
||||
/*
|
||||
* Create a temporary file.
|
||||
*/
|
||||
archive_wstrcat(&temp_name, prefix);
|
||||
archive_wstrcat(&temp_name, suffix);
|
||||
ep = temp_name.s + archive_strlen(&temp_name);
|
||||
xp = ep - wcslen(suffix);
|
||||
template = temp_name.s;
|
||||
} else {
|
||||
xp = wcschr(template, L'X');
|
||||
if (xp == NULL) /* No X, programming error */
|
||||
abort();
|
||||
for (ep = xp; *ep == L'X'; ep++)
|
||||
continue;
|
||||
if (*ep) /* X followed by non X, programming error */
|
||||
abort();
|
||||
}
|
||||
|
||||
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT)) {
|
||||
@ -323,20 +335,24 @@ __archive_mktemp(const char *tmpdir)
|
||||
*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
|
||||
|
||||
free(ws);
|
||||
ws = __la_win_permissive_name_w(temp_name.s);
|
||||
ws = __la_win_permissive_name_w(template);
|
||||
if (ws == NULL) {
|
||||
errno = EINVAL;
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
/* Specifies FILE_FLAG_DELETE_ON_CLOSE flag is to
|
||||
* delete this temporary file immediately when this
|
||||
* file closed. */
|
||||
if (template == temp_name.s) {
|
||||
attr = FILE_ATTRIBUTE_TEMPORARY |
|
||||
FILE_FLAG_DELETE_ON_CLOSE;
|
||||
} else {
|
||||
/* mkstemp */
|
||||
attr = FILE_ATTRIBUTE_NORMAL;
|
||||
}
|
||||
h = CreateFileW(ws,
|
||||
GENERIC_READ | GENERIC_WRITE | DELETE,
|
||||
0,/* Not share */
|
||||
NULL,
|
||||
CREATE_NEW,/* Create a new file only */
|
||||
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
|
||||
attr,
|
||||
NULL);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
/* The same file already exists. retry with
|
||||
@ -358,10 +374,23 @@ exit_tmpfile:
|
||||
if (hProv != (HCRYPTPROV)NULL)
|
||||
CryptReleaseContext(hProv, 0);
|
||||
free(ws);
|
||||
archive_wstring_free(&temp_name);
|
||||
if (template == temp_name.s)
|
||||
archive_wstring_free(&temp_name);
|
||||
return (fd);
|
||||
}
|
||||
|
||||
int
|
||||
__archive_mktemp(const char *tmpdir)
|
||||
{
|
||||
return __archive_mktempx(tmpdir, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
__archive_mkstemp(wchar_t *template)
|
||||
{
|
||||
return __archive_mktempx(NULL, template);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int
|
||||
@ -414,14 +443,24 @@ exit_tmpfile:
|
||||
return (fd);
|
||||
}
|
||||
|
||||
#else
|
||||
int
|
||||
__archive_mkstemp(char *template)
|
||||
{
|
||||
int fd = -1;
|
||||
fd = mkstemp(template);
|
||||
if (fd >= 0)
|
||||
__archive_ensure_cloexec_flag(fd);
|
||||
return (fd);
|
||||
}
|
||||
|
||||
#else /* !HAVE_MKSTEMP */
|
||||
|
||||
/*
|
||||
* We use a private routine.
|
||||
*/
|
||||
|
||||
int
|
||||
__archive_mktemp(const char *tmpdir)
|
||||
static int
|
||||
__archive_mktempx(const char *tmpdir, char *template)
|
||||
{
|
||||
static const char num[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
@ -439,26 +478,37 @@ __archive_mktemp(const char *tmpdir)
|
||||
char *tp, *ep;
|
||||
|
||||
fd = -1;
|
||||
archive_string_init(&temp_name);
|
||||
if (tmpdir == NULL) {
|
||||
if (get_tempdir(&temp_name) != ARCHIVE_OK)
|
||||
if (template == NULL) {
|
||||
archive_string_init(&temp_name);
|
||||
if (tmpdir == NULL) {
|
||||
if (get_tempdir(&temp_name) != ARCHIVE_OK)
|
||||
goto exit_tmpfile;
|
||||
} else
|
||||
archive_strcpy(&temp_name, tmpdir);
|
||||
if (temp_name.s[temp_name.length-1] == '/') {
|
||||
temp_name.s[temp_name.length-1] = '\0';
|
||||
temp_name.length --;
|
||||
}
|
||||
if (la_stat(temp_name.s, &st) < 0)
|
||||
goto exit_tmpfile;
|
||||
} else
|
||||
archive_strcpy(&temp_name, tmpdir);
|
||||
if (temp_name.s[temp_name.length-1] == '/') {
|
||||
temp_name.s[temp_name.length-1] = '\0';
|
||||
temp_name.length --;
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
archive_strcat(&temp_name, "/libarchive_");
|
||||
tp = temp_name.s + archive_strlen(&temp_name);
|
||||
archive_strcat(&temp_name, "XXXXXXXXXX");
|
||||
ep = temp_name.s + archive_strlen(&temp_name);
|
||||
template = temp_name.s;
|
||||
} else {
|
||||
tp = strchr(template, 'X');
|
||||
if (tp == NULL) /* No X, programming error */
|
||||
abort();
|
||||
for (ep = tp; *ep == 'X'; ep++)
|
||||
continue;
|
||||
if (*ep) /* X followed by non X, programming error */
|
||||
abort();
|
||||
}
|
||||
if (stat(temp_name.s, &st) < 0)
|
||||
goto exit_tmpfile;
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
goto exit_tmpfile;
|
||||
}
|
||||
archive_strcat(&temp_name, "/libarchive_");
|
||||
tp = temp_name.s + archive_strlen(&temp_name);
|
||||
archive_strcat(&temp_name, "XXXXXXXXXX");
|
||||
ep = temp_name.s + archive_strlen(&temp_name);
|
||||
|
||||
do {
|
||||
char *p;
|
||||
@ -469,19 +519,33 @@ __archive_mktemp(const char *tmpdir)
|
||||
int d = *((unsigned char *)p) % sizeof(num);
|
||||
*p++ = num[d];
|
||||
}
|
||||
fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
|
||||
fd = open(template, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
|
||||
0600);
|
||||
} while (fd < 0 && errno == EEXIST);
|
||||
if (fd < 0)
|
||||
goto exit_tmpfile;
|
||||
__archive_ensure_cloexec_flag(fd);
|
||||
unlink(temp_name.s);
|
||||
if (template == temp_name.s)
|
||||
unlink(temp_name.s);
|
||||
exit_tmpfile:
|
||||
archive_string_free(&temp_name);
|
||||
if (template == temp_name.s)
|
||||
archive_string_free(&temp_name);
|
||||
return (fd);
|
||||
}
|
||||
|
||||
#endif /* HAVE_MKSTEMP */
|
||||
int
|
||||
__archive_mktemp(const char *tmpdir)
|
||||
{
|
||||
return __archive_mktempx(tmpdir, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
__archive_mkstemp(char *template)
|
||||
{
|
||||
return __archive_mktempx(NULL, template);
|
||||
}
|
||||
|
||||
#endif /* !HAVE_MKSTEMP */
|
||||
#endif /* !_WIN32 || __CYGWIN__ */
|
||||
|
||||
/*
|
||||
|
@ -445,7 +445,8 @@ fileTimeToUTC(const FILETIME *filetime, time_t *t, long *ns)
|
||||
* Windows' stat() does not accept the path added "\\?\" especially "?"
|
||||
* character.
|
||||
* It means we cannot access the long name path longer than MAX_PATH.
|
||||
* So I've implemented simular Windows' stat() to access the long name path.
|
||||
* So I've implemented a function similar to Windows' stat() to access the
|
||||
* long name path.
|
||||
* And I've added some feature.
|
||||
* 1. set st_ino by nFileIndexHigh and nFileIndexLow of
|
||||
* BY_HANDLE_FILE_INFORMATION.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user