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:
LibArchive Upstream 2020-02-11 22:49:11 +01:00 committed by Brad King
parent 2aaed7a050
commit 8cce62295a
153 changed files with 11290 additions and 1330 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* -whitespace

View File

@ -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)

View File

@ -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

View 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)

View File

@ -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

View File

@ -1 +1 @@
3003003
3004002

View File

@ -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})

View File

@ -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 *,

View File

@ -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')

View File

@ -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
View 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

View 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

View 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

View 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

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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>

View File

@ -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,

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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:

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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;

View 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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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>

View File

@ -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);
}

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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 */

View File

@ -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 "$" */

View File

@ -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
/*

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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)
{

View File

@ -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

File diff suppressed because it is too large Load Diff

View 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

View File

@ -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"

View File

@ -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 *);

View File

@ -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);

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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 ?
*/

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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 *);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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. */

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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));

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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__ */
/*

View File

@ -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