Update libarchive's vendor dist to version 3.0.4 from release branch.

Git branch:	release
Git commit:	8076b31490c90aaf0edccecf760004c30bd95edc

Obtained from:	https://github.com/libarchive/libarchive.git
This commit is contained in:
Martin Matuska 2012-07-27 08:24:12 +00:00
parent 132160f774
commit 81418b36c0
165 changed files with 11322 additions and 4644 deletions

View File

@ -1,13 +1,36 @@
# #
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.6 FATAL_ERROR)
# #
PROJECT(libarchive C) PROJECT(libarchive C)
# #
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake") SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin)
endif() endif()
SET(CMAKE_BUILD_TYPE "Release") #
# Set the Build type for make based generators.
# You can choose following types:
# Debug : Debug build
# Release : Release build
# RelWithDebInfo : Release build with Debug Info
# MinSizeRel : Release Min Size build
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
# Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the
# value type is "UNINITIALIZED".
GET_PROPERTY(cached_type CACHE CMAKE_BUILD_TYPE PROPERTY TYPE)
IF("${cached_type}" STREQUAL "UNINITIALIZED")
SET(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Build Type" FORCE)
ENDIF("${cached_type}" STREQUAL "UNINITIALIZED")
# Check the Build Type.
IF(NOT "${CMAKE_BUILD_TYPE}"
MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$")
MESSAGE(FATAL_ERROR
"Unknown keyword for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n"
"Acceptable keywords: Debug,Release,RelWithDebInfo,MinSizeRel")
ENDIF(NOT "${CMAKE_BUILD_TYPE}"
MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$")
# On MacOS, prefer MacPorts libraries to system libraries. # On MacOS, prefer MacPorts libraries to system libraries.
# I haven't come up with a compelling argument for this to be conditional. # I haven't come up with a compelling argument for this to be conditional.
@ -47,13 +70,73 @@ math(EXPR INTERFACE_VERSION "12 + ${_minor}")
# ?? Should there be more here ?? # ?? Should there be more here ??
SET(SOVERSION "${INTERFACE_VERSION}") SET(SOVERSION "${INTERFACE_VERSION}")
# Enalbe CMAKE_PUSH_CHECK_STATE() and CMAKE_POP_CHECK_STATE() macros
# saving and restoring the state of the variables.
INCLUDE(CMakePushCheckState)
# Initialize the state of the variables. This initialization is not
# necessary but this shows you what value the variables initially have.
SET(CMAKE_REQUIRED_DEFINITIONS)
SET(CMAKE_REQUIRED_INCLUDES)
SET(CMAKE_REQUIRED_LIBRARIES)
SET(CMAKE_REQUIRED_FLAGS)
# Especially for early development, we want to be a little # Especially for early development, we want to be a little
# aggressive about diagnosing build problems; this can get # aggressive about diagnosing build problems; this can get
# relaxed somewhat in final shipping versions. # relaxed somewhat in final shipping versions.
IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$") IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
ADD_DEFINITIONS(-Wall) SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security")
SET(CMAKE_REQUIRED_FLAGS "-Wall") #################################################################
# Set compile flags for all build types.
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security")
#################################################################
# Set compile flags for debug build.
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror -Wextra -Wunused")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wmissing-prototypes")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wcast-qual")
ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$") ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
IF (MSVC)
#################################################################
# 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 C4254: A larger bit field was assigned to a smaller bit
# field.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4254")
# Enable level 4 C4295: An array was initialized but the last character in
# the array is not a null; accessing the array may
# produce unexpected results.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4295")
# Enable level 4 C4296: An unsigned variable was used in a comparison
# operation with zero.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4296")
# Enable level 4 C4389: An operation involved signed and unsigned variables.
# This could result in a loss of data.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4389")
# Enable level 4 C4505: The given function is local and not referenced in
# the body of the module; therefore, the function is
# dead code.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4505")
# Enable level 4 C4514: The optimizer removed an inline function that is not
# called.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4514")
# Enable level 4 C4702: Unreachable code.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4702")
# 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")
#################################################################
# Set compile flags for release build.
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Oi")
ENDIF (MSVC)
# Enable CTest/CDash support # Enable CTest/CDash support
include(CTest) include(CTest)
@ -74,10 +157,18 @@ IF(ENABLE_TEST)
ENDIF(ENABLE_TEST) ENDIF(ENABLE_TEST)
IF(WIN32) IF(WIN32)
SET(_WIN32_WINNT 0x0500 CACHE INTERNAL "Setting _WIN32_WINNT to 0x0500 for Windows 2000 APIs") IF(MSVC60)
SET(WINVER 0x0500 CACHE INTERNAL "Setting WINVER to 0x0500 for Windows 2000 APIs") SET(WINVER 0x0400)
ELSE()
SET(WINVER 0x0500)
ENDIF()
SET(_WIN32_WINNT ${WINVER})
ENDIF(WIN32) ENDIF(WIN32)
IF("${CMAKE_C_PLATFORM_ID}" MATCHES "^(HP-UX)$")
ADD_DEFINITIONS(-D_XOPEN_SOURCE=500) # Ask wchar.h for mbstate_t
ENDIF()
# #
INCLUDE(CheckCSourceCompiles) INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckCSourceRuns) INCLUDE(CheckCSourceRuns)
@ -125,7 +216,38 @@ MACRO (INSTALL_MAN __mans)
INSTALL(FILES ${_man} DESTINATION "share/man/man${_mansect}") INSTALL(FILES ${_man} DESTINATION "share/man/man${_mansect}")
ENDFOREACH (_man) ENDFOREACH (_man)
ENDMACRO (INSTALL_MAN __mans) ENDMACRO (INSTALL_MAN __mans)
#
# Find out what macro is needed to use libraries on Windows.
#
MACRO (TRY_MACRO_FOR_LIBRARY INCLUDES LIBRARIES
TRY_TYPE SAMPLE_SOURCE MACRO_LIST)
IF(WIN32 AND NOT CYGWIN)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
SET(CMAKE_REQUIRED_INCLUDES ${INCLUDES})
SET(CMAKE_REQUIRED_LIBRARIES ${LIBRARIES})
FOREACH(VAR ${MACRO_LIST})
# Clear ${VAR} from CACHE If the libraries which ${VAR} was
# checked with are changed.
SET(VAR_WITH_LIB "${VAR}_WITH_LIB")
GET_PROPERTY(PREV_VAR_WITH_LIB VARIABLE PROPERTY ${VAR_WITH_LIB})
IF(NOT "${PREV_VAR_WITH_LIB}" STREQUAL "${LIBRARIES}")
UNSET(${VAR} CACHE)
ENDIF(NOT "${PREV_VAR_WITH_LIB}" STREQUAL "${LIBRARIES}")
# Check if the library can be used with the macro.
IF("${TRY_TYPE}" MATCHES "COMPILES")
CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR})
ELSEIF("${TRY_TYPE}" MATCHES "RUNS")
CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR})
ELSE("${TRY_TYPE}" MATCHES "COMPILES")
MESSAGE(FATAL_ERROR "UNKNOWN KEYWORD \"${TRY_TYPE}\" FOR TRY_TYPE")
ENDIF("${TRY_TYPE}" MATCHES "COMPILES")
# Save the libraries which ${VAR} is checked with.
SET(${VAR_WITH_LIB} "${LIBRARIES}" CACHE INTERNAL
"Macro ${VAR} is checked with")
ENDFOREACH(VAR)
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
ENDIF(WIN32 AND NOT CYGWIN)
ENDMACRO (TRY_MACRO_FOR_LIBRARY)
# #
# Check compress/decompress libraries # Check compress/decompress libraries
# #
@ -172,11 +294,27 @@ IF(ZLIB_FOUND)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${ZLIB_LIBRARIES}) LIST(APPEND ADDITIONAL_LIBS ${ZLIB_LIBRARIES})
IF(WIN32 AND NOT CYGWIN) IF(WIN32 AND NOT CYGWIN)
SET(CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIR}) #
SET(CMAKE_REQUIRED_LIBRARIES ${ZLIB_LIBRARIES}) # Test if ZLIB_WINAPI macro is needed to use.
CHECK_C_SOURCE_Runs( #
"#ifndef ZLIB_WINAPI\n#define ZLIB_WINAPI\n#endif\n#include <zlib.h>\nint main() {uLong f = zlibCompileFlags(); return (f&(1U<<10))?0:-1; }" TRY_MACRO_FOR_LIBRARY(
"${ZLIB_INCLUDE_DIR}" "${ZLIB_LIBRARIES}"
RUNS
"#include <zlib.h>\nint main() {uLong f = zlibCompileFlags(); return (f&(1U<<10))?0:-1; }"
ZLIB_WINAPI) ZLIB_WINAPI)
IF(ZLIB_WINAPI)
ADD_DEFINITIONS(-DZLIB_WINAPI)
ELSE(ZLIB_WINAPI)
# Test if a macro is needed for the library.
TRY_MACRO_FOR_LIBRARY(
"${ZLIB_INCLUDE_DIR}" "${ZLIB_LIBRARIES}"
COMPILES
"#include <zlib.h>\nint main() {return zlibVersion()?1:0; }"
"ZLIB_DLL;WITHOUT_ZLIB_DLL")
IF(ZLIB_DLL)
ADD_DEFINITIONS(-DZLIB_DLL)
ENDIF(ZLIB_DLL)
ENDIF(ZLIB_WINAPI)
ENDIF(WIN32 AND NOT CYGWIN) ENDIF(WIN32 AND NOT CYGWIN)
ENDIF(ZLIB_FOUND) ENDIF(ZLIB_FOUND)
MARK_AS_ADVANCED(CLEAR ZLIB_INCLUDE_DIR) MARK_AS_ADVANCED(CLEAR ZLIB_INCLUDE_DIR)
@ -190,9 +328,20 @@ IF(BZIP2_FOUND)
SET(HAVE_BZLIB_H 1) SET(HAVE_BZLIB_H 1)
INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${BZIP2_LIBRARIES}) LIST(APPEND ADDITIONAL_LIBS ${BZIP2_LIBRARIES})
# Test if a macro is needed for the library.
TRY_MACRO_FOR_LIBRARY(
"${BZIP2_INCLUDE_DIR}" "${BZIP2_LIBRARIES}"
COMPILES
"#include <bzlib.h>\nint main() {return BZ2_bzlibVersion()?1:0; }"
"USE_BZIP2_DLL;USE_BZIP2_STATIC")
IF(USE_BZIP2_DLL)
ADD_DEFINITIONS(-DUSE_BZIP2_DLL)
ELSEIF(USE_BZIP2_STATIC)
ADD_DEFINITIONS(-DUSE_BZIP2_STATIC)
ENDIF(USE_BZIP2_DLL)
ENDIF(BZIP2_FOUND) ENDIF(BZIP2_FOUND)
MARK_AS_ADVANCED(CLEAR BZIP2_INCLUDE_DIR) MARK_AS_ADVANCED(CLEAR BZIP2_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARY) MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARIES)
# #
# Find LZMA # Find LZMA
# #
@ -202,6 +351,15 @@ IF(LZMA_FOUND)
SET(HAVE_LZMA_H 1) SET(HAVE_LZMA_H 1)
INCLUDE_DIRECTORIES(${LZMA_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${LZMA_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${LZMA_LIBRARIES}) LIST(APPEND ADDITIONAL_LIBS ${LZMA_LIBRARIES})
# Test if a macro is needed for the library.
TRY_MACRO_FOR_LIBRARY(
"${LZMA_INCLUDE_DIR}" "${LZMA_LIBRARIES}"
COMPILES
"#include <lzma.h>\nint main() {return (int)lzma_version_number(); }"
"WITHOUT_LZMA_API_STATIC;LZMA_API_STATIC")
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)
ELSEIF(LZMADEC_FOUND) ELSEIF(LZMADEC_FOUND)
SET(HAVE_LIBLZMADEC 1) SET(HAVE_LIBLZMADEC 1)
SET(HAVE_LZMADEC_H 1) SET(HAVE_LZMADEC_H 1)
@ -244,6 +402,7 @@ LA_CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H)
LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H) LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H) LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H)
LA_CHECK_INCLUDE_FILE("limits.h" HAVE_LIMITS_H) LA_CHECK_INCLUDE_FILE("limits.h" HAVE_LIMITS_H)
LA_CHECK_INCLUDE_FILE("linux/types.h" HAVE_LINUX_TYPES_H)
LA_CHECK_INCLUDE_FILE("linux/fiemap.h" HAVE_LINUX_FIEMAP_H) LA_CHECK_INCLUDE_FILE("linux/fiemap.h" HAVE_LINUX_FIEMAP_H)
LA_CHECK_INCLUDE_FILE("linux/fs.h" HAVE_LINUX_FS_H) LA_CHECK_INCLUDE_FILE("linux/fs.h" HAVE_LINUX_FS_H)
LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H) LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H)
@ -307,9 +466,11 @@ CHECK_C_SOURCE_COMPILES(
IF(ENABLE_NETTLE) IF(ENABLE_NETTLE)
CHECK_LIBRARY_EXISTS(nettle "nettle_sha1_digest" "" NETTLE_FOUND) CHECK_LIBRARY_EXISTS(nettle "nettle_sha1_digest" "" NETTLE_FOUND)
IF(NETTLE_FOUND) IF(NETTLE_FOUND)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
SET(CMAKE_REQUIRED_LIBRARIES "nettle") SET(CMAKE_REQUIRED_LIBRARIES "nettle")
FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle) FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle)
LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARY}) LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARY})
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
ELSE(NETTLE_FOUND) ELSE(NETTLE_FOUND)
SET(ENABLE_NETTLE OFF) SET(ENABLE_NETTLE OFF)
ENDIF(NETTLE_FOUND) ENDIF(NETTLE_FOUND)
@ -328,9 +489,11 @@ ENDIF()
# FreeBSD libmd # FreeBSD libmd
CHECK_LIBRARY_EXISTS(md "MD5Init" "" LIBMD_FOUND) CHECK_LIBRARY_EXISTS(md "MD5Init" "" LIBMD_FOUND)
IF(LIBMD_FOUND) IF(LIBMD_FOUND)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
SET(CMAKE_REQUIRED_LIBRARIES "md") SET(CMAKE_REQUIRED_LIBRARIES "md")
FIND_LIBRARY(LIBMD_LIBRARY NAMES md) FIND_LIBRARY(LIBMD_LIBRARY NAMES md)
LIST(APPEND ADDITIONAL_LIBS ${LIBMD_LIBRARY}) LIST(APPEND ADDITIONAL_LIBS ${LIBMD_LIBRARY})
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
ENDIF(LIBMD_FOUND) ENDIF(LIBMD_FOUND)
# #
@ -386,10 +549,10 @@ ${ARCHIVE_CRYPTO_C}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
archive_${lower_crypto}_ctx ctx; archive_${lower_algorithm}_ctx ctx;
archive_${lower_crypto}_init(&ctx); archive_${lower_algorithm}_init(&ctx);
archive_${lower_crypto}_update(&ctx, *argv, argc); archive_${lower_algorithm}_update(&ctx, *argv, argc);
archive_${lower_crypto}_final(&ctx, NULL); archive_${lower_algorithm}_final(&ctx, NULL);
return 0; return 0;
} }
") ")
@ -511,6 +674,20 @@ ENDMACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
# #
MACRO(CHECK_ICONV LIB TRY_ICONV_CONST) MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
IF(NOT HAVE_ICONV) IF(NOT HAVE_ICONV)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
#
# During checking iconv proto type, we should use -Werror to avoid the
# success of iconv detection with a warnig which success is a miss
# detection. So this needs for all build mode(even it's a release mode).
#
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
IF (MSVC)
# NOTE: /WX option is the same as gcc's -Werror option.
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /WX")
ENDIF (MSVC)
#
CHECK_C_SOURCE_COMPILES( CHECK_C_SOURCE_COMPILES(
"#include <stdlib.h> "#include <stdlib.h>
#include <iconv.h> #include <iconv.h>
@ -526,10 +703,12 @@ MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
SET(HAVE_ICONV true) SET(HAVE_ICONV true)
SET(ICONV_CONST ${TRY_ICONV_CONST}) SET(ICONV_CONST ${TRY_ICONV_CONST})
ENDIF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST}) ENDIF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
ENDIF(NOT HAVE_ICONV) ENDIF(NOT HAVE_ICONV)
ENDMACRO(CHECK_ICONV TRY_ICONV_CONST) ENDMACRO(CHECK_ICONV TRY_ICONV_CONST)
IF(ENABLE_ICONV) IF(ENABLE_ICONV)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
FIND_PATH(ICONV_INCLUDE_DIR iconv.h) FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
IF(ICONV_INCLUDE_DIR) IF(ICONV_INCLUDE_DIR)
#SET(INCLUDES ${INCLUDES} "iconv.h") #SET(INCLUDES ${INCLUDES} "iconv.h")
@ -540,9 +719,30 @@ IF(ENABLE_ICONV)
CHECK_ICONV("libc" "") CHECK_ICONV("libc" "")
# If iconv isn't in libc and we have a libiconv, try that. # If iconv isn't in libc and we have a libiconv, try that.
FIND_LIBRARY(LIBICONV_PATH iconv) FIND_LIBRARY(LIBICONV_PATH NAMES iconv libiconv)
IF(NOT HAVE_ICONV AND LIBICONV_PATH) IF(NOT HAVE_ICONV AND LIBICONV_PATH)
LIST(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBICONV_PATH}) LIST(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBICONV_PATH})
# Test if a macro is needed for the library.
TRY_MACRO_FOR_LIBRARY(
"${ICONV_INCLUDE_DIR}" "${LIBICONV_PATH}"
COMPILES
"#include <iconv.h>\nint main() {return iconv_close((iconv_t)0);}"
"WITHOUT_LIBICONV_STATIC;LIBICONV_STATIC")
IF(NOT WITHOUT_LIBICONV_STATIC AND LIBICONV_STATIC)
ADD_DEFINITIONS(-DLIBICONV_STATIC)
ENDIF(NOT WITHOUT_LIBICONV_STATIC AND LIBICONV_STATIC)
#
# Set up CMAKE_REQUIRED_* for CHECK_ICONV
#
SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
SET(CMAKE_REQUIRED_LIBRARIES ${LIBICONV_PATH})
IF(LIBICONV_STATIC)
# LIBICONV_STATIC is necessary for the success of CHECK_ICONV
# on Windows.
SET(CMAKE_REQUIRED_DEFINITIONS "-DLIBICONV_STATIC")
ELSE(LIBICONV_STATIC)
SET(CMAKE_REQUIRED_DEFINITIONS)
ENDIF(LIBICONV_STATIC)
CHECK_ICONV("libiconv" "const") CHECK_ICONV("libiconv" "const")
CHECK_ICONV("libiconv" "") CHECK_ICONV("libiconv" "")
IF (HAVE_ICONV) IF (HAVE_ICONV)
@ -554,19 +754,36 @@ IF(ENABLE_ICONV)
# Find locale_charset() for libiconv. # Find locale_charset() for libiconv.
# #
IF(LIBICONV_PATH) IF(LIBICONV_PATH)
SET(CMAKE_REQUIRED_DEFINITIONS)
SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
SET(CMAKE_REQUIRED_LIBRARIES)
CHECK_INCLUDE_FILES("localcharset.h" HAVE_LOCALCHARSET_H) CHECK_INCLUDE_FILES("localcharset.h" HAVE_LOCALCHARSET_H)
CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET) FIND_LIBRARY(LIBCHARSET_PATH NAMES charset libcharset)
IF(NOT HAVE_LOCALE_CHARSET) IF(LIBCHARSET_PATH)
FIND_LIBRARY(LIBCHARSET_PATH charset) SET(CMAKE_REQUIRED_LIBRARIES ${LIBCHARSET_PATH})
IF(LIBCHARSET_PATH) IF(WIN32 AND NOT CYGWIN)
SET(CMAKE_REQUIRED_LIBRARIES ${LIBCHARSET_PATH}) # Test if a macro is needed for the library.
TRY_MACRO_FOR_LIBRARY(
"${ICONV_INCLUDE_DIR}" "${LIBCHARSET_PATH}"
COMPILES
"#include <localcharset.h>\nint main() {return locale_charset()?1:0;}"
"WITHOUT_LIBCHARSET_STATIC;LIBCHARSET_STATIC")
IF(NOT WITHOUT_LIBCHARSET_STATIC AND LIBCHARSET_STATIC)
ADD_DEFINITIONS(-DLIBCHARSET_STATIC)
ENDIF(NOT WITHOUT_LIBCHARSET_STATIC AND LIBCHARSET_STATIC)
IF(WITHOUT_LIBCHARSET_STATIC OR LIBCHARSET_STATIC)
SET(HAVE_LOCALE_CHARSET ON CACHE INTERNAL
"Have function locale_charset")
ENDIF(WITHOUT_LIBCHARSET_STATIC OR LIBCHARSET_STATIC)
ELSE(WIN32 AND NOT CYGWIN)
CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET) CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET)
IF(HAVE_LOCALE_CHARSET) ENDIF(WIN32 AND NOT CYGWIN)
LIST(APPEND ADDITIONAL_LIBS ${LIBCHARSET_PATH}) IF(HAVE_LOCALE_CHARSET)
ENDIF(HAVE_LOCALE_CHARSET) LIST(APPEND ADDITIONAL_LIBS ${LIBCHARSET_PATH})
ENDIF(LIBCHARSET_PATH) ENDIF(HAVE_LOCALE_CHARSET)
ENDIF(NOT HAVE_LOCALE_CHARSET) ENDIF(LIBCHARSET_PATH)
ENDIF(LIBICONV_PATH) ENDIF(LIBICONV_PATH)
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
ELSE(ENABLE_ICONV) ELSE(ENABLE_ICONV)
# Make sure ICONV variables are not in CACHE after ENABLE_ICONV disabled # Make sure ICONV variables are not in CACHE after ENABLE_ICONV disabled
# (once enabled). # (once enabled).
@ -578,6 +795,10 @@ ELSE(ENABLE_ICONV)
UNSET(HAVE_ICONV_libiconv_const CACHE) UNSET(HAVE_ICONV_libiconv_const CACHE)
UNSET(ICONV_INCLUDE_DIR CACHE) UNSET(ICONV_INCLUDE_DIR CACHE)
UNSET(LIBICONV_PATH CACHE) UNSET(LIBICONV_PATH CACHE)
UNSET(LIBICONV_DLL CACHE)
UNSET(LIBICONV_STATIC CACHE)
UNSET(LIBCHARSET_DLL CACHE)
UNSET(LIBCHARSET_STATIC CACHE)
ENDIF(ENABLE_ICONV) ENDIF(ENABLE_ICONV)
# #
@ -585,6 +806,7 @@ ENDIF(ENABLE_ICONV)
# #
FIND_PACKAGE(LibXml2) FIND_PACKAGE(LibXml2)
IF(LIBXML2_FOUND) IF(LIBXML2_FOUND)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${LIBXML2_LIBRARIES}) LIST(APPEND ADDITIONAL_LIBS ${LIBXML2_LIBRARIES})
SET(HAVE_LIBXML2 1) SET(HAVE_LIBXML2 1)
@ -592,20 +814,33 @@ IF(LIBXML2_FOUND)
SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR}) SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
CHECK_INCLUDE_FILES("libxml/xmlreader.h" HAVE_LIBXML_XMLREADER_H) CHECK_INCLUDE_FILES("libxml/xmlreader.h" HAVE_LIBXML_XMLREADER_H)
CHECK_INCLUDE_FILES("libxml/xmlwriter.h" HAVE_LIBXML_XMLWRITER_H) CHECK_INCLUDE_FILES("libxml/xmlwriter.h" HAVE_LIBXML_XMLWRITER_H)
SET(CMAKE_REQUIRED_INCLUDES "") # Test if a macro is needed for the library.
TRY_MACRO_FOR_LIBRARY(
"${ICONV_INCLUDE_DIR};${LIBXML2_INCLUDE_DIR}"
"ws2_32.lib;${ZLIB_LIBRARIES};${LIBICONV_PATH};${LIBXML2_LIBRARIES}"
COMPILES
"#include <stddef.h>\n#include <libxml/xmlreader.h>\nint main() {return xmlTextReaderRead((xmlTextReaderPtr)(void *)0);}"
"WITHOUT_LIBXML_STATIC;LIBXML_STATIC")
IF(NOT WITHOUT_LIBXML_STATIC AND LIBXML_STATIC)
ADD_DEFINITIONS(-DLIBXML_STATIC)
ENDIF(NOT WITHOUT_LIBXML_STATIC AND LIBXML_STATIC)
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
ELSE(LIBXML2_FOUND) ELSE(LIBXML2_FOUND)
# #
# Find Expat # Find Expat
# #
FIND_PACKAGE(EXPAT) FIND_PACKAGE(EXPAT)
IF(EXPAT_FOUND) IF(EXPAT_FOUND)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
INCLUDE_DIRECTORIES(${EXPAT_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${EXPAT_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${EXPAT_LIBRARIES}) LIST(APPEND ADDITIONAL_LIBS ${EXPAT_LIBRARIES})
SET(HAVE_LIBEXPAT 1) SET(HAVE_LIBEXPAT 1)
LA_CHECK_INCLUDE_FILE("expat.h" HAVE_EXPAT_H) LA_CHECK_INCLUDE_FILE("expat.h" HAVE_EXPAT_H)
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
ENDIF(EXPAT_FOUND) ENDIF(EXPAT_FOUND)
ENDIF(LIBXML2_FOUND) ENDIF(LIBXML2_FOUND)
MARK_AS_ADVANCED(CLEAR LIBXML2_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR LIBXML2_LIBRARIES)
# #
# Find Libregex # Find Libregex
# #
@ -616,6 +851,7 @@ IF(REGEX_INCLUDE_DIR)
# If libc does not provide regex, find libregex. # If libc does not provide regex, find libregex.
# #
IF(NOT HAVE_REGCOMP_LIBC) IF(NOT HAVE_REGCOMP_LIBC)
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
FIND_LIBRARY(REGEX_LIBRARY regex) FIND_LIBRARY(REGEX_LIBRARY regex)
IF(REGEX_LIBRARY) IF(REGEX_LIBRARY)
SET(CMAKE_REQUIRED_LIBRARIES ${REGEX_LIBRARY}) SET(CMAKE_REQUIRED_LIBRARIES ${REGEX_LIBRARY})
@ -632,21 +868,33 @@ IF(REGEX_INCLUDE_DIR)
SET(CMAKE_REQUIRED_INCLUDES ${REGEX_INCLUDE_DIR}) SET(CMAKE_REQUIRED_INCLUDES ${REGEX_INCLUDE_DIR})
LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H) LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
ENDIF(NOT HAVE_REGEX_H) ENDIF(NOT HAVE_REGEX_H)
# Test if a macro is needed for the library.
TRY_MACRO_FOR_LIBRARY(
"${REGEX_INCLUDE_DIR}" "${REGEX_LIBRARY}"
COMPILES
"#include <stddef.h>\n#include <regex.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
"USE_REGEX_DLL;USE_REGEX_STATIC")
IF(USE_REGEX_DLL)
ADD_DEFINITIONS(-DUSE_REGEX_DLL)
ELSEIF(USE_REGEX_STATIC)
ADD_DEFINITIONS(-DUSE_REGEX_STATIC)
ENDIF(USE_REGEX_DLL)
ENDIF(HAVE_REGCOMP_LIBREGEX) ENDIF(HAVE_REGCOMP_LIBREGEX)
ENDIF(REGEX_LIBRARY) ENDIF(REGEX_LIBRARY)
CMAKE_POP_CHECK_STATE() # Restore the state of the variables
ENDIF(NOT HAVE_REGCOMP_LIBC) ENDIF(NOT HAVE_REGCOMP_LIBC)
ENDIF(REGEX_INCLUDE_DIR) ENDIF(REGEX_INCLUDE_DIR)
# #
# Check functions # Check functions
# #
CMAKE_PUSH_CHECK_STATE() # Save the state of the variables
IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$") IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
# #
# During checking functions, we should use -fno-builtin to avoid the # During checking functions, we should use -fno-builtin to avoid the
# failure of function detection which failure is an error "conflicting # failure of function detection which failure is an error "conflicting
# types for built-in function" caused by using -Werror option. # types for built-in function" caused by using -Werror option.
# #
SET(SAVE_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-builtin") SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-builtin")
ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$") ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
CHECK_SYMBOL_EXISTS(_CrtSetReportMode "crtdbg.h" HAVE__CrtSetReportMode) CHECK_SYMBOL_EXISTS(_CrtSetReportMode "crtdbg.h" HAVE__CrtSetReportMode)
@ -685,7 +933,6 @@ CHECK_FUNCTION_EXISTS_GLIBC(localtime_r HAVE_LOCALTIME_R)
CHECK_FUNCTION_EXISTS_GLIBC(lstat HAVE_LSTAT) CHECK_FUNCTION_EXISTS_GLIBC(lstat HAVE_LSTAT)
CHECK_FUNCTION_EXISTS_GLIBC(lutimes HAVE_LUTIMES) CHECK_FUNCTION_EXISTS_GLIBC(lutimes HAVE_LUTIMES)
CHECK_FUNCTION_EXISTS_GLIBC(mbrtowc HAVE_MBRTOWC) CHECK_FUNCTION_EXISTS_GLIBC(mbrtowc HAVE_MBRTOWC)
CHECK_FUNCTION_EXISTS_GLIBC(mbsnrtowcs HAVE_MBSNRTOWCS)
CHECK_FUNCTION_EXISTS_GLIBC(memmove HAVE_MEMMOVE) CHECK_FUNCTION_EXISTS_GLIBC(memmove HAVE_MEMMOVE)
CHECK_FUNCTION_EXISTS_GLIBC(mkdir HAVE_MKDIR) CHECK_FUNCTION_EXISTS_GLIBC(mkdir HAVE_MKDIR)
CHECK_FUNCTION_EXISTS_GLIBC(mkfifo HAVE_MKFIFO) CHECK_FUNCTION_EXISTS_GLIBC(mkfifo HAVE_MKFIFO)
@ -719,7 +966,6 @@ CHECK_FUNCTION_EXISTS_GLIBC(wcrtomb HAVE_WCRTOMB)
CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP) CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP)
CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY) CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN) CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
CHECK_FUNCTION_EXISTS_GLIBC(wcsnrtombs HAVE_WCSNRTOMBS)
CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB) CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S) CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64) CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
@ -736,10 +982,7 @@ CHECK_FUNCTION_EXISTS(vprintf HAVE_VPRINTF)
CHECK_FUNCTION_EXISTS(wmemcmp HAVE_WMEMCMP) CHECK_FUNCTION_EXISTS(wmemcmp HAVE_WMEMCMP)
CHECK_FUNCTION_EXISTS(wmemcpy HAVE_WMEMCPY) CHECK_FUNCTION_EXISTS(wmemcpy HAVE_WMEMCPY)
# Restore CMAKE_REQUIRED_FLAGS CMAKE_POP_CHECK_STATE() # Restore the state of the variables
IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
SET(CMAKE_REQUIRED_FLAGS ${SAVE_CMAKE_REQUIRED_FLAGS})
ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
# Make sure we have the POSIX version of readdir_r, not the # Make sure we have the POSIX version of readdir_r, not the
# older 2-argument version. # older 2-argument version.
@ -826,6 +1069,12 @@ CHECK_STRUCT_MEMBER("struct stat" st_blksize
# Check for st_flags in struct stat (BSD fflags) # Check for st_flags in struct stat (BSD fflags)
CHECK_STRUCT_MEMBER("struct stat" st_flags CHECK_STRUCT_MEMBER("struct stat" st_flags
"sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_FLAGS) "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_FLAGS)
IF(HAVE_SYS_STATVFS_H)
CHECK_STRUCT_MEMBER("struct statvfs" f_iosize
"sys/types.h;sys/statvfs.h" HAVE_STRUCT_STATVFS_F_IOSIZE)
ENDIF()
# #
# #
CHECK_STRUCT_MEMBER("struct tm" tm_sec CHECK_STRUCT_MEMBER("struct tm" tm_sec
@ -1120,11 +1369,6 @@ IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE) ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
ENDIF(MSVC) ENDIF(MSVC)
# We need CoreServices on Mac OS.
IF(APPLE)
LIST(APPEND ADDITIONAL_LIBS "-framework CoreServices")
ENDIF(APPLE)
IF(ENABLE_TEST) IF(ENABLE_TEST)
ADD_CUSTOM_TARGET(run_all_tests) ADD_CUSTOM_TARGET(run_all_tests)
ENDIF(ENABLE_TEST) ENDIF(ENABLE_TEST)

View File

@ -21,7 +21,11 @@ TESTS= libarchive_test $(bsdtar_test_programs) $(bsdcpio_test_programs)
TESTS_ENVIRONMENT= $(libarchive_TESTS_ENVIRONMENT) $(bsdtar_TESTS_ENVIRONMENT) $(bsdcpio_TESTS_ENVIRONMENT) TESTS_ENVIRONMENT= $(libarchive_TESTS_ENVIRONMENT) $(bsdtar_TESTS_ENVIRONMENT) $(bsdcpio_TESTS_ENVIRONMENT)
# Always build and test both bsdtar and bsdcpio as part of 'distcheck' # Always build and test both bsdtar and bsdcpio as part of 'distcheck'
DISTCHECK_CONFIGURE_FLAGS = --enable-bsdtar --enable-bsdcpio DISTCHECK_CONFIGURE_FLAGS = --enable-bsdtar --enable-bsdcpio
AM_CFLAGS=-Wall COMMON_CFLAGS=-Wall -Wformat -Wformat-security
# The next line is commented out by default in shipping libarchive releases.
# It is uncommented by default in trunk.
# DEV_CFLAGS=-Werror -Wextra -Wunused -Wshadow -Wmissing-prototypes -Wcast-qual
AM_CFLAGS=$(COMMON_CFLAGS) $(DEV_CFLAGS)
PLATFORMCPPFLAGS = @PLATFORMCPPFLAGS@ PLATFORMCPPFLAGS = @PLATFORMCPPFLAGS@
AM_CPPFLAGS=$(PLATFORMCPPFLAGS) AM_CPPFLAGS=$(PLATFORMCPPFLAGS)
@ -100,8 +104,12 @@ libarchive_la_SOURCES= \
libarchive/archive_entry_stat.c \ libarchive/archive_entry_stat.c \
libarchive/archive_entry_strmode.c \ libarchive/archive_entry_strmode.c \
libarchive/archive_entry_xattr.c \ libarchive/archive_entry_xattr.c \
libarchive/archive_getdate.c \
libarchive/archive_match.c \
libarchive/archive_options.c \ libarchive/archive_options.c \
libarchive/archive_options_private.h \ libarchive/archive_options_private.h \
libarchive/archive_pathmatch.c \
libarchive/archive_pathmatch.h \
libarchive/archive_platform.h \ libarchive/archive_platform.h \
libarchive/archive_ppmd_private.h \ libarchive/archive_ppmd_private.h \
libarchive/archive_ppmd7.c \ libarchive/archive_ppmd7.c \
@ -161,6 +169,7 @@ libarchive_la_SOURCES= \
libarchive/archive_write_open_filename.c \ libarchive/archive_write_open_filename.c \
libarchive/archive_write_open_memory.c \ libarchive/archive_write_open_memory.c \
libarchive/archive_write_private.h \ libarchive/archive_write_private.h \
libarchive/archive_write_add_filter.c \
libarchive/archive_write_add_filter_bzip2.c \ libarchive/archive_write_add_filter_bzip2.c \
libarchive/archive_write_add_filter_compress.c \ libarchive/archive_write_add_filter_compress.c \
libarchive/archive_write_add_filter_gzip.c \ libarchive/archive_write_add_filter_gzip.c \
@ -253,6 +262,11 @@ libarchive_test_SOURCES= \
libarchive/test/test_archive_api_feature.c \ libarchive/test/test_archive_api_feature.c \
libarchive/test/test_archive_clear_error.c \ libarchive/test/test_archive_clear_error.c \
libarchive/test/test_archive_crypto.c \ libarchive/test/test_archive_crypto.c \
libarchive/test/test_archive_getdate.c \
libarchive/test/test_archive_match_owner.c \
libarchive/test/test_archive_match_path.c \
libarchive/test/test_archive_match_time.c \
libarchive/test/test_archive_pathmatch.c \
libarchive/test/test_archive_read_close_twice.c \ libarchive/test/test_archive_read_close_twice.c \
libarchive/test/test_archive_read_close_twice_open_fd.c \ libarchive/test/test_archive_read_close_twice_open_fd.c \
libarchive/test/test_archive_read_close_twice_open_filename.c \ libarchive/test/test_archive_read_close_twice_open_filename.c \
@ -572,12 +586,9 @@ libarchive_fe_la_SOURCES= \
libarchive_fe/err.h \ libarchive_fe/err.h \
libarchive_fe/lafe_platform.h \ libarchive_fe/lafe_platform.h \
libarchive_fe/line_reader.c \ libarchive_fe/line_reader.c \
libarchive_fe/line_reader.h \ libarchive_fe/line_reader.h
libarchive_fe/matching.c \
libarchive_fe/matching.h \
libarchive_fe/pathmatch.c \
libarchive_fe/pathmatch.h
libarchive_fe_la_CPPFLAGS= -I$(top_srcdir)/libarchive
# #
# #
# bsdtar source, docs, etc. # bsdtar source, docs, etc.
@ -589,11 +600,8 @@ bsdtar_SOURCES= \
tar/bsdtar.h \ tar/bsdtar.h \
tar/bsdtar_platform.h \ tar/bsdtar_platform.h \
tar/cmdline.c \ tar/cmdline.c \
tar/getdate.c \
tar/read.c \ tar/read.c \
tar/subst.c \ tar/subst.c \
tar/tree.c \
tar/tree.h \
tar/util.c \ tar/util.c \
tar/write.c tar/write.c
@ -638,14 +646,13 @@ endif
# #
bsdtar_test_SOURCES= \ bsdtar_test_SOURCES= \
tar/getdate.c \
tar/test/main.c \ tar/test/main.c \
tar/test/test.h \ tar/test/test.h \
tar/test/test_0.c \ tar/test/test_0.c \
tar/test/test_basic.c \ tar/test/test_basic.c \
tar/test/test_copy.c \ tar/test/test_copy.c \
tar/test/test_empty_mtree.c \ tar/test/test_empty_mtree.c \
tar/test/test_getdate.c \ tar/test/test_format_newc.c \
tar/test/test_help.c \ tar/test/test_help.c \
tar/test/test_option_C_upper.c \ tar/test/test_option_C_upper.c \
tar/test/test_option_H_upper.c \ tar/test/test_option_H_upper.c \
@ -661,6 +668,7 @@ bsdtar_test_SOURCES= \
tar/test/test_option_keep_newer_files.c \ tar/test/test_option_keep_newer_files.c \
tar/test/test_option_n.c \ tar/test/test_option_n.c \
tar/test/test_option_newer_than.c \ tar/test/test_option_newer_than.c \
tar/test/test_option_nodump.c \
tar/test/test_option_q.c \ tar/test/test_option_q.c \
tar/test/test_option_r.c \ tar/test/test_option_r.c \
tar/test/test_option_s.c \ tar/test/test_option_s.c \
@ -784,8 +792,7 @@ bsdcpio_test_SOURCES= \
cpio/test/test_option_z.c \ cpio/test/test_option_z.c \
cpio/test/test_owner_parse.c \ cpio/test/test_owner_parse.c \
cpio/test/test_passthrough_dotdot.c \ cpio/test/test_passthrough_dotdot.c \
cpio/test/test_passthrough_reverse.c \ cpio/test/test_passthrough_reverse.c
cpio/test/test_pathmatch.c
bsdcpio_test_CPPFLAGS= \ bsdcpio_test_CPPFLAGS= \
-I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \ -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \

18
NEWS
View File

@ -1,14 +1,10 @@
Jan 10, 2012: Issue 223: Skip atime tests if atime not supported Mar 27, 2012: libarchive 3.0.4 released
Jan 09, 2012: Issue 222: Errors saving sparse files to pax archives
Jan 09, 2012: Issue 221: allow archive_*_free(NULL) Feb 05, 2012: libarchive development now hosted at GitHub.
Dec 31, 2011: Issue 212: configure script on Solaris http://libarchive.github.com/
Dec 30, 2011: Issue 218: empty contents extracting Zip files with bsdcpio Feb 05, 2012: libarchive's issue tracker remains at Google Code.
Dec 30, 2011: Issue 217: fix compile warning http://code.google.com/p/libarchive/issues/list
Dec 30, 2011: Issue 216: truncated filenames in listings Feb 05, 2012: libarchive's mailing lists remain at Google Groups.
Dec 28, 2011: Issue 210: memory leak on Windows
Dec 28, 2011: Issue 206: fix hardlink tests on Windows 2000
Dec 27, 2011: Issue 208: Don't hang when using external compression
program on Windows
Dec 24, 2011: libarchive 3.0.2 released Dec 24, 2011: libarchive 3.0.2 released
Dec 23, 2011: Various fixes merged from FreeBSD Dec 23, 2011: Various fixes merged from FreeBSD

13
README
View File

@ -1,9 +1,14 @@
README for libarchive bundle. README for libarchive bundle.
Questions? Issues? Questions? Issues?
* http://libarchive.googlecode.com/ is the home for ongoing * http://libarchive.github.com/ is the home for ongoing
libarchive development, including issue tracker, additional libarchive development, including documentation, and
documentation, and links to the libarchive mailing lists. links to the libarchive mailing lists.
* To report an issue, use the issue tracker at
http://code.google.com/p/libarchive/issues/list
* To submit an enhancement to libarchive, please submit
a pull request via GitHub.
https://github.com/libarchive/libarchive/pulls
This distribution bundle includes the following components: This distribution bundle includes the following components:
* libarchive: a library for reading and writing streaming archives * libarchive: a library for reading and writing streaming archives
@ -66,6 +71,7 @@ Currently, the library automatically detects and reads the following fomats:
* ZIP archives (with uncompressed or "deflate" compressed entries) * ZIP archives (with uncompressed or "deflate" compressed entries)
* GNU and BSD 'ar' archives * GNU and BSD 'ar' archives
* 'mtree' format * 'mtree' format
* 7-Zip archives
* Microsoft CAB format * Microsoft CAB format
* LHA and LZH archives * LHA and LZH archives
* RAR archives * RAR archives
@ -92,6 +98,7 @@ The library can create archives in any of the following formats:
* GNU and BSD 'ar' archives * GNU and BSD 'ar' archives
* 'mtree' format * 'mtree' format
* ISO9660 format * ISO9660 format
* 7-Zip archives
* XAR archives * XAR archives
When creating archives, the result can be filtered with any of the following: When creating archives, the result can be filtered with any of the following:

View File

@ -19,7 +19,7 @@ GET_FILENAME_COMPONENT(_selfdir_CheckFileOffsetBits
MACRO (CHECK_FILE_OFFSET_BITS) MACRO (CHECK_FILE_OFFSET_BITS)
IF(NOT DEFINED _FILE_OFFSET_BITS) IF(NOT DEFINED _FILE_OFFSET_BITS)
MESSAGE(STATUS "Cheking _FILE_OFFSET_BITS for large files") MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files")
TRY_COMPILE(__WITHOUT_FILE_OFFSET_BITS_64 TRY_COMPILE(__WITHOUT_FILE_OFFSET_BITS_64
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c ${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
@ -33,10 +33,10 @@ MACRO (CHECK_FILE_OFFSET_BITS)
IF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64) IF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
SET(_FILE_OFFSET_BITS 64 CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files") SET(_FILE_OFFSET_BITS 64 CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
MESSAGE(STATUS "Cheking _FILE_OFFSET_BITS for large files - needed") MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - needed")
ELSE(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64) ELSE(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
SET(_FILE_OFFSET_BITS "" CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files") SET(_FILE_OFFSET_BITS "" CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
MESSAGE(STATUS "Cheking _FILE_OFFSET_BITS for large files - not needed") MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - not needed")
ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64) ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
ENDIF(NOT DEFINED _FILE_OFFSET_BITS) ENDIF(NOT DEFINED _FILE_OFFSET_BITS)

View File

@ -609,6 +609,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the <linux/magic.h> header file. */ /* Define to 1 if you have the <linux/magic.h> header file. */
#cmakedefine HAVE_LINUX_MAGIC_H 1 #cmakedefine HAVE_LINUX_MAGIC_H 1
/* Define to 1 if you have the <linux/types.h> header file. */
#cmakedefine HAVE_LINUX_TYPES_H 1
/* Define to 1 if you have the `listea' function. */ /* Define to 1 if you have the `listea' function. */
#cmakedefine HAVE_LISTEA 1 #cmakedefine HAVE_LISTEA 1
@ -661,9 +664,6 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `mbrtowc' function. */ /* Define to 1 if you have the `mbrtowc' function. */
#cmakedefine HAVE_MBRTOWC 1 #cmakedefine HAVE_MBRTOWC 1
/* Define to 1 if you have the `mbsnrtowcs' function. */
#cmakedefine HAVE_MBSNRTOWCS 1
/* Define to 1 if you have the `memmove' function. */ /* Define to 1 if you have the `memmove' function. */
#cmakedefine HAVE_MEMMOVE 1 #cmakedefine HAVE_MEMMOVE 1
@ -782,6 +782,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if `f_namemax' is a member of `struct statfs'. */ /* Define to 1 if `f_namemax' is a member of `struct statfs'. */
#cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1 #cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1
/* Define to 1 if `f_iosize' is a member of `struct statvfs'. */
#cmakedefine HAVE_STRUCT_STATVFS_F_IOSIZE 1
/* Define to 1 if `st_birthtime' is a member of `struct stat'. */ /* Define to 1 if `st_birthtime' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIME 1 #cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIME 1
@ -943,9 +946,6 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `wcslen' function. */ /* Define to 1 if you have the `wcslen' function. */
#cmakedefine HAVE_WCSLEN 1 #cmakedefine HAVE_WCSLEN 1
/* Define to 1 if you have the `wcsnrtombs' function. */
#cmakedefine HAVE_WCSNRTOMBS 1
/* Define to 1 if you have the `wctomb' function. */ /* Define to 1 if you have the `wctomb' function. */
#cmakedefine HAVE_WCTOMB 1 #cmakedefine HAVE_WCTOMB 1

View File

@ -1,10 +1,13 @@
#!/bin/sh #!/bin/sh
# #
# This needs http://unicode.org/Public/UNIDATA/UnicodeData.txt # This needs http://unicode.org/Public/6.0.0/ucd/UnicodeData.txt
# #
inputfile="$1" # Expect UnicodeData.txt inputfile="$1" # Expect UnicodeData.txt
outfile=archive_string_composition.h outfile=archive_string_composition.h
pickout=/tmp/mk_unicode_composition_tbl$$.awk pickout=/tmp/mk_unicode_composition_tbl$$.awk
pickout2=/tmp/mk_unicode_composition_tbl2$$.awk
#nfdtmp=/tmp/mk_unicode_decomposition_tmp$$.txt
nfdtmp="nfdtmpx"
################################################################################# #################################################################################
# #
# Append the file header of "archive_string_composition.h" # Append the file header of "archive_string_composition.h"
@ -14,7 +17,7 @@ append_copyright()
{ {
cat > ${outfile} <<CR_END cat > ${outfile} <<CR_END
/*- /*-
* Copyright (c) 2011 libarchive Project * Copyright (c) 2011-2012 libarchive Project
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -44,7 +47,7 @@ cat > ${outfile} <<CR_END
/* /*
* ATTENTION! * ATTENTION!
* This file is generated by build/utils/gen_archive_string_composition_h.sh * This file is generated by build/utils/gen_archive_string_composition_h.sh
* from http://unicode.org/Public/UNIDATA/UnicodeData.txt * from http://unicode.org/Public/6.0.0/ucd/UnicodeData.txt
* *
* See also http://unicode.org/report/tr15/ * See also http://unicode.org/report/tr15/
*/ */
@ -76,6 +79,7 @@ BEGIN {
min = ""; min = "";
max = ""; max = "";
cmd="sort | awk -F ' ' '{printf \"\\\\t{ 0x%s , 0x%s , 0x%s },\\\\n\",\$1,\$2,\$3}'" cmd="sort | awk -F ' ' '{printf \"\\\\t{ 0x%s , 0x%s , 0x%s },\\\\n\",\$1,\$2,\$3}'"
nfdtbl="${nfdtmp}"
print "static const struct unicode_composition_table u_composition_table[] = {" print "static const struct unicode_composition_table u_composition_table[] = {"
} }
END { END {
@ -178,7 +182,6 @@ END {
} }
print "};" print "};"
print "" print ""
print "#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */"
} }
# #
# #
@ -241,7 +244,7 @@ function hextoi(hex)
#} #}
# #
# Exclusion code points specified by # Exclusion code points specified by
# http://unicode.org/Public/UNIDATA/CompositionExclusions.txt # http://unicode.org/Public/6.0.0/ucd/CompositionExclusions.txt
## ##
# 1. Script Specifices # 1. Script Specifices
## ##
@ -404,6 +407,35 @@ function hextoi(hex)
print "0"cp[1], "0"cp[2], "0"\$1 | cmd print "0"cp[1], "0"cp[2], "0"\$1 | cmd
else else
print cp[1], cp[2], \$1 | cmd print cp[1], cp[2], \$1 | cmd
# NFC ==> NFD table.
if (length(\$1) == 4)
print "0"\$1, "0"cp[1], "0"cp[2] >>nfdtbl
else
print \$1, cp[1], cp[2] >>nfdtbl
}
AWK_END
#################################################################################
# awk script
#
#################################################################################
cat > ${pickout2} <<AWK_END
#
BEGIN {
FS = " "
print "struct unicode_decomposition_table {"
print "\tuint32_t nfc;"
print "\tuint32_t cp1;"
print "\tuint32_t cp2;"
print "};"
print ""
print "static const struct unicode_decomposition_table u_decomposition_table[] = {"
}
END {
print "};"
print ""
}
{
printf "\t{ 0x%s , 0x%s , 0x%s },\n", \$1, \$2, \$3;
} }
AWK_END AWK_END
################################################################################# #################################################################################
@ -413,6 +445,11 @@ AWK_END
################################################################################# #################################################################################
append_copyright append_copyright
awk -f ${pickout} ${inputfile} >> ${outfile} awk -f ${pickout} ${inputfile} >> ${outfile}
awk -f ${pickout2} ${nfdtmp} >> ${outfile}
echo "#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */" >> ${outfile}
echo "" >> ${outfile}
# #
# Remove awk the script. # Remove awk the script.
rm ${pickout} rm ${pickout}
rm ${pickout2}
rm ${nfdtmp}

View File

@ -1 +1 @@
3000003 3000004

View File

@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front.
dnl In particular, this allows the version macro to be used in AC_INIT dnl In particular, this allows the version macro to be used in AC_INIT
dnl These first two version numbers are updated automatically on each release. dnl These first two version numbers are updated automatically on each release.
m4_define([LIBARCHIVE_VERSION_S],[3.0.3]) m4_define([LIBARCHIVE_VERSION_S],[3.0.4])
m4_define([LIBARCHIVE_VERSION_N],[3000003]) m4_define([LIBARCHIVE_VERSION_N],[3000004])
dnl bsdtar and bsdcpio versioning tracks libarchive dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S()) m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
@ -17,7 +17,7 @@ AC_PREREQ(2.65)
# Now starts the "real" configure script. # Now starts the "real" configure script.
# #
AC_INIT([libarchive],LIBARCHIVE_VERSION_S(),[kientzle@FreeBSD.org]) AC_INIT([libarchive],LIBARCHIVE_VERSION_S(),[libarchive-discuss@googlegroups.com])
# Make sure the srcdir contains "libarchive" directory # Make sure the srcdir contains "libarchive" directory
AC_CONFIG_SRCDIR([libarchive]) AC_CONFIG_SRCDIR([libarchive])
# Use auxiliary subscripts from this subdirectory (cleans up root) # Use auxiliary subscripts from this subdirectory (cleans up root)
@ -197,13 +197,6 @@ case $host in
;; ;;
esac esac
# We need CoreServices on Mac OS.
case $host in
*darwin* )
LIBS="${LIBS} -framework CoreServices"
;;
esac
# Checks for header files. # Checks for header files.
AC_HEADER_DIRENT AC_HEADER_DIRENT
AC_HEADER_SYS_WAIT AC_HEADER_SYS_WAIT
@ -223,7 +216,7 @@ AS_VAR_IF([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes],
[Define to 1 if you have a working EXT2_IOC_GETFLAGS])]) [Define to 1 if you have a working EXT2_IOC_GETFLAGS])])
AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h]) AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h])
AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h]) AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h linux/types.h])
AC_CHECK_HEADERS([locale.h paths.h poll.h pwd.h regex.h signal.h stdarg.h]) AC_CHECK_HEADERS([locale.h paths.h poll.h pwd.h regex.h signal.h stdarg.h])
AC_CHECK_HEADERS([stdint.h stdlib.h string.h]) AC_CHECK_HEADERS([stdint.h stdlib.h string.h])
AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h sys/ioctl.h]) AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h sys/ioctl.h])
@ -268,8 +261,8 @@ AC_ARG_WITH([iconv],
AS_HELP_STRING([--without-iconv], [Don't try to link against iconv])) AS_HELP_STRING([--without-iconv], [Don't try to link against iconv]))
if test "x$with_iconv" != "xno"; then if test "x$with_iconv" != "xno"; then
AC_CHECK_HEADERS([iconv.h],[],[],[#include <stdlib.h>])
AM_ICONV AM_ICONV
AC_CHECK_HEADERS([iconv.h],[],[],[#include <stdlib.h>])
if test "x$am_cv_func_iconv" = "xyes"; then if test "x$am_cv_func_iconv" = "xyes"; then
AC_CHECK_HEADERS([localcharset.h]) AC_CHECK_HEADERS([localcharset.h])
am_save_LIBS="$LIBS" am_save_LIBS="$LIBS"
@ -364,6 +357,12 @@ AC_CHECK_MEMBERS([struct statfs.f_namemax],,,
#include <sys/mount.h> #include <sys/mount.h>
]) ])
# Check for f_iosize in struct statvfs
AC_CHECK_MEMBERS([struct statvfs.f_iosize],,,
[
#include <sys/statvfs.h>
])
# Check for birthtime in struct stat # Check for birthtime in struct stat
AC_CHECK_MEMBERS([struct stat.st_birthtime]) AC_CHECK_MEMBERS([struct stat.st_birthtime])
@ -440,13 +439,13 @@ AC_CHECK_FUNCS([futimens futimes futimesat])
AC_CHECK_FUNCS([geteuid getpid getgrgid_r getgrnam_r]) AC_CHECK_FUNCS([geteuid getpid getgrgid_r getgrnam_r])
AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r]) AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r])
AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat lutimes]) AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat lutimes])
AC_CHECK_FUNCS([mbrtowc mbsnrtowcs memmove memset]) AC_CHECK_FUNCS([mbrtowc memmove memset])
AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp]) AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp])
AC_CHECK_FUNCS([nl_langinfo openat pipe poll readlink readlinkat]) AC_CHECK_FUNCS([nl_langinfo openat pipe poll readlink readlinkat])
AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs]) AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs])
AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm]) AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm])
AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork]) AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork])
AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wcsnrtombs wctomb wmemcmp wmemcpy]) AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy])
AC_CHECK_FUNCS([_ctime64_s _fseeki64]) AC_CHECK_FUNCS([_ctime64_s _fseeki64])
AC_CHECK_FUNCS([_get_timezone _localtime64_s _mkgmtime64]) AC_CHECK_FUNCS([_get_timezone _localtime64_s _mkgmtime64])
# detects cygwin-1.7, as opposed to older versions # detects cygwin-1.7, as opposed to older versions

View File

@ -15,10 +15,6 @@ IF(ENABLE_CPIO)
../libarchive_fe/lafe_platform.h ../libarchive_fe/lafe_platform.h
../libarchive_fe/line_reader.c ../libarchive_fe/line_reader.c
../libarchive_fe/line_reader.h ../libarchive_fe/line_reader.h
../libarchive_fe/matching.c
../libarchive_fe/matching.h
../libarchive_fe/pathmatch.c
../libarchive_fe/pathmatch.h
) )
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
IF(WIN32 AND NOT CYGWIN) IF(WIN32 AND NOT CYGWIN)

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd December 21, 2007 .Dd December 24, 2011
.Dt CPIO 1 .Dt CPIO 1
.Os .Os
.Sh NAME .Sh NAME

View File

@ -346,6 +346,7 @@ owner_parse(const char *spec, int *uid, int *gid)
snprintf(errbuff, sizeof(errbuff), snprintf(errbuff, sizeof(errbuff),
"Couldn't lookup user ``%s''", user); "Couldn't lookup user ``%s''", user);
errbuff[sizeof(errbuff) - 1] = '\0'; errbuff[sizeof(errbuff) - 1] = '\0';
free(user);
return (errbuff); return (errbuff);
} }
} }

View File

@ -82,7 +82,6 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.15 2008/12/06 07:30:40 kientzle
#include "cpio.h" #include "cpio.h"
#include "err.h" #include "err.h"
#include "line_reader.h" #include "line_reader.h"
#include "matching.h"
/* Fixed size of uname/gname caches. */ /* Fixed size of uname/gname caches. */
#define name_cache_size 101 #define name_cache_size 101
@ -190,6 +189,10 @@ main(int argc, char *argv[])
cpio->bytes_per_block = 512; cpio->bytes_per_block = 512;
cpio->filename = NULL; cpio->filename = NULL;
cpio->matching = archive_match_new();
if (cpio->matching == NULL)
lafe_errc(1, 0, "Out of memory");
while ((opt = cpio_getopt(cpio)) != -1) { while ((opt = cpio_getopt(cpio)) != -1) {
switch (opt) { switch (opt) {
case '0': /* GNU convention: --null, -0 */ case '0': /* GNU convention: --null, -0 */
@ -216,14 +219,20 @@ main(int argc, char *argv[])
cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR; cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR;
break; break;
case 'E': /* NetBSD/OpenBSD */ case 'E': /* NetBSD/OpenBSD */
lafe_include_from_file(&cpio->matching, if (archive_match_include_pattern_from_file(
cpio->argument, cpio->option_null); cpio->matching, cpio->argument,
cpio->option_null) != ARCHIVE_OK)
lafe_errc(1, 0, "Error : %s",
archive_error_string(cpio->matching));
break; break;
case 'F': /* NetBSD/OpenBSD/GNU cpio */ case 'F': /* NetBSD/OpenBSD/GNU cpio */
cpio->filename = cpio->argument; cpio->filename = cpio->argument;
break; break;
case 'f': /* POSIX 1997 */ case 'f': /* POSIX 1997 */
lafe_exclude(&cpio->matching, cpio->argument); if (archive_match_exclude_pattern(cpio->matching,
cpio->argument) != ARCHIVE_OK)
lafe_errc(1, 0, "Error : %s",
archive_error_string(cpio->matching));
break; break;
case 'H': /* GNU cpio (also --format) */ case 'H': /* GNU cpio (also --format) */
cpio->format = cpio->argument; cpio->format = cpio->argument;
@ -367,9 +376,6 @@ main(int argc, char *argv[])
if (cpio->option_link && cpio->mode != 'p') if (cpio->option_link && cpio->mode != 'p')
lafe_errc(1, 0, "Option -l requires -p"); lafe_errc(1, 0, "Option -l requires -p");
/* -v overrides -V */ /* -v overrides -V */
if (cpio->dot && cpio->verbose)
cpio->dot = 0;
/* -v overrides -V */
if (cpio->dot && cpio->verbose) if (cpio->dot && cpio->verbose)
cpio->dot = 0; cpio->dot = 0;
/* TODO: Flag other nonsensical combinations. */ /* TODO: Flag other nonsensical combinations. */
@ -385,7 +391,10 @@ main(int argc, char *argv[])
break; break;
case 'i': case 'i':
while (*cpio->argv != NULL) { while (*cpio->argv != NULL) {
lafe_include(&cpio->matching, *cpio->argv); if (archive_match_include_pattern(cpio->matching,
*cpio->argv) != ARCHIVE_OK)
lafe_errc(1, 0, "Error : %s",
archive_error_string(cpio->matching));
--cpio->argc; --cpio->argc;
++cpio->argv; ++cpio->argv;
} }
@ -405,6 +414,7 @@ main(int argc, char *argv[])
"Must specify at least one of -i, -o, or -p"); "Must specify at least one of -i, -o, or -p");
} }
archive_match_free(cpio->matching);
free_cache(cpio->gname_cache); free_cache(cpio->gname_cache);
free_cache(cpio->uname_cache); free_cache(cpio->uname_cache);
return (cpio->return_value); return (cpio->return_value);
@ -909,7 +919,7 @@ mode_in(struct cpio *cpio)
lafe_errc(1, archive_errno(a), lafe_errc(1, archive_errno(a),
"%s", archive_error_string(a)); "%s", archive_error_string(a));
} }
if (lafe_excluded(cpio->matching, archive_entry_pathname(entry))) if (archive_match_path_excluded(cpio->matching, entry))
continue; continue;
if (cpio->option_rename) { if (cpio->option_rename) {
destpath = cpio_rename(archive_entry_pathname(entry)); destpath = cpio_rename(archive_entry_pathname(entry));
@ -1011,7 +1021,7 @@ mode_list(struct cpio *cpio)
lafe_errc(1, archive_errno(a), lafe_errc(1, archive_errno(a),
"%s", archive_error_string(a)); "%s", archive_error_string(a));
} }
if (lafe_excluded(cpio->matching, archive_entry_pathname(entry))) if (archive_match_path_excluded(cpio->matching, entry))
continue; continue;
if (cpio->verbose) if (cpio->verbose)
list_item_verbose(cpio, entry); list_item_verbose(cpio, entry);
@ -1306,7 +1316,8 @@ lookup_uname_helper(struct cpio *cpio, const char **name, id_t id)
if (pwent == NULL) { if (pwent == NULL) {
*name = NULL; *name = NULL;
if (errno != 0 && errno != ENOENT) if (errno != 0 && errno != ENOENT)
lafe_warnc(errno, "getpwuid(%d) failed", id); lafe_warnc(errno, "getpwuid(%s) failed",
cpio_i64toa((int64_t)id));
return (errno); return (errno);
} }
@ -1333,7 +1344,8 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
if (grent == NULL) { if (grent == NULL) {
*name = NULL; *name = NULL;
if (errno != 0) if (errno != 0)
lafe_warnc(errno, "getgrgid(%d) failed", id); lafe_warnc(errno, "getgrgid(%s) failed",
cpio_i64toa((int64_t)id));
return (errno); return (errno);
} }

View File

@ -31,8 +31,6 @@
#include "cpio_platform.h" #include "cpio_platform.h"
#include <stdio.h> #include <stdio.h>
#include "matching.h"
/* /*
* The internal state for the "cpio" program. * The internal state for the "cpio" program.
* *
@ -88,7 +86,7 @@ struct cpio {
struct name_cache *gname_cache; struct name_cache *gname_cache;
/* Work data. */ /* Work data. */
struct lafe_matching *matching; struct archive *matching;
char *buff; char *buff;
size_t buff_size; size_t buff_size;
}; };

View File

@ -324,7 +324,7 @@ cpio_dosmaperr(unsigned long e)
return; return;
} }
for (i = 0; i < sizeof(doserrors); i++) { for (i = 0; i < (int)sizeof(doserrors); i++) {
if (doserrors[i].winerr == e) { if (doserrors[i].winerr == e) {
errno = doserrors[i].doserr; errno = doserrors[i].doserr;
return; return;

View File

@ -7,7 +7,6 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
SET(bsdcpio_test_SOURCES SET(bsdcpio_test_SOURCES
../cmdline.c ../cmdline.c
../../libarchive_fe/err.c ../../libarchive_fe/err.c
../../libarchive_fe/pathmatch.c
main.c main.c
test.h test.h
test_0.c test_0.c
@ -37,7 +36,6 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
test_owner_parse.c test_owner_parse.c
test_passthrough_dotdot.c test_passthrough_dotdot.c
test_passthrough_reverse.c test_passthrough_reverse.c
test_pathmatch.c
) )
# #

View File

@ -24,6 +24,9 @@
*/ */
#include "test.h" #include "test.h"
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@ -31,6 +34,16 @@
#ifdef HAVE_ICONV_H #ifdef HAVE_ICONV_H
#include <iconv.h> #include <iconv.h>
#endif #endif
/*
* Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
* As the include guards don't agree, the order of include is important.
*/
#ifdef HAVE_LINUX_EXT2_FS_H
#include <linux/ext2_fs.h> /* for Linux file flags */
#endif
#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
#include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
#endif
#include <limits.h> #include <limits.h>
#include <locale.h> #include <locale.h>
#ifdef HAVE_SIGNAL_H #ifdef HAVE_SIGNAL_H
@ -116,7 +129,14 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/test/main.c,v 1.3 2008/08/24 04:58:22 kient
#endif #endif
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
void *GetFunctionKernel32(const char *name) static void *GetFunctionKernel32(const char *);
static int my_CreateSymbolicLinkA(const char *, const char *, int);
static int my_CreateHardLinkA(const char *, const char *);
static int my_GetFileInformationByName(const char *,
BY_HANDLE_FILE_INFORMATION *);
static void *
GetFunctionKernel32(const char *name)
{ {
static HINSTANCE lib; static HINSTANCE lib;
static int set; static int set;
@ -155,7 +175,7 @@ my_CreateHardLinkA(const char *linkname, const char *target)
return f == NULL ? 0 : (*f)(linkname, target, NULL); return f == NULL ? 0 : (*f)(linkname, target, NULL);
} }
int static int
my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi) my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
{ {
HANDLE h; HANDLE h;
@ -1507,7 +1527,7 @@ assertion_make_dir(const char *file, int line, const char *dirname, int mode)
/* Create a file with the specified contents and report any failures. */ /* Create a file with the specified contents and report any failures. */
int int
assertion_make_file(const char *file, int line, assertion_make_file(const char *file, int line,
const char *path, int mode, const char *contents) const char *path, int mode, int csize, const void *contents)
{ {
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
/* TODO: Rework this to set file mode as well. */ /* TODO: Rework this to set file mode as well. */
@ -1521,8 +1541,13 @@ assertion_make_file(const char *file, int line,
return (0); return (0);
} }
if (contents != NULL) { if (contents != NULL) {
if (strlen(contents) size_t wsize;
!= fwrite(contents, 1, strlen(contents), f)) {
if (csize < 0)
wsize = strlen(contents);
else
wsize = (size_t)csize;
if (wsize != fwrite(contents, 1, wsize, f)) {
fclose(f); fclose(f);
failure_start(file, line, failure_start(file, line,
"Could not write file %s", path); "Could not write file %s", path);
@ -1542,10 +1567,16 @@ assertion_make_file(const char *file, int line,
return (0); return (0);
} }
if (contents != NULL) { if (contents != NULL) {
if ((ssize_t)strlen(contents) ssize_t wsize;
!= write(fd, contents, strlen(contents))) {
if (csize < 0)
wsize = (ssize_t)strlen(contents);
else
wsize = (ssize_t)csize;
if (wsize != write(fd, contents, wsize)) {
close(fd); close(fd);
failure_start(file, line, "Could not write to %s", path); failure_start(file, line,
"Could not write to %s", path);
failure_finish(NULL); failure_finish(NULL);
return (0); return (0);
} }
@ -1716,6 +1747,52 @@ assertion_utimes(const char *file, int line,
#endif /* defined(_WIN32) && !defined(__CYGWIN__) */ #endif /* defined(_WIN32) && !defined(__CYGWIN__) */
} }
/* Set nodump, report failures. */
int
assertion_nodump(const char *file, int line, const char *pathname)
{
#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
int r;
assertion_count(file, line);
r = chflags(pathname, UF_NODUMP);
if (r < 0) {
failure_start(file, line, "Can't set nodump %s\n", pathname);
failure_finish(NULL);
return (0);
}
#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
&& defined(EXT2_NODUMP_FL)
int fd, r, flags;
assertion_count(file, line);
fd = open(pathname, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
failure_start(file, line, "Can't open %s\n", pathname);
failure_finish(NULL);
return (0);
}
r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
if (r < 0) {
failure_start(file, line, "Can't get flags %s\n", pathname);
failure_finish(NULL);
return (0);
}
flags |= EXT2_NODUMP_FL;
r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
if (r < 0) {
failure_start(file, line, "Can't set nodump %s\n", pathname);
failure_finish(NULL);
return (0);
}
close(fd);
#else
(void)pathname; /* UNUSED */
assertion_count(file, line);
#endif
return (1);
}
/* /*
* *
* UTILITIES for use by tests. * UTILITIES for use by tests.
@ -1744,7 +1821,7 @@ canSymlink(void)
return (value); return (value);
++tested; ++tested;
assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a"); assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, 1, "a");
/* Note: Cygwin has its own symlink() emulation that does not /* Note: Cygwin has its own symlink() emulation that does not
* use the Win32 CreateSymbolicLink() function. */ * use the Win32 CreateSymbolicLink() function. */
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
@ -1793,6 +1870,70 @@ canGunzip(void)
return (value); return (value);
} }
/*
* Can this filesystem handle nodump flags.
*/
#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
int
canNodump(void)
{
const char *path = "cannodumptest";
struct stat sb;
assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
if (chflags(path, UF_NODUMP) < 0)
return (0);
if (stat(path, &sb) < 0)
return (0);
if (sb.st_flags & UF_NODUMP)
return (1);
return (0);
}
#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\
&& defined(EXT2_NODUMP_FL)
int
canNodump(void)
{
const char *path = "cannodumptest";
int fd, r, flags;
assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return (0);
r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
if (r < 0)
return (0);
flags |= EXT2_NODUMP_FL;
r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
if (r < 0)
return (0);
close(fd);
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return (0);
r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
if (r < 0)
return (0);
close(fd);
if (flags & EXT2_NODUMP_FL)
return (1);
return (0);
}
#else
int
canNodump()
{
return (0);
}
#endif
/* /*
* Sleep as needed; useful for verifying disk timestamp changes by * Sleep as needed; useful for verifying disk timestamp changes by
* ensuring that the wall-clock time has actually changed before we * ensuring that the wall-clock time has actually changed before we
@ -2236,17 +2377,77 @@ success:
return strdup(buff); return strdup(buff);
} }
static int
get_test_set(int *test_set, int limit, const char *test)
{
int start, end;
int idx = 0;
if (test == NULL) {
/* Default: Run all tests. */
for (;idx < limit; idx++)
test_set[idx] = idx;
return (limit);
}
if (*test >= '0' && *test <= '9') {
const char *vp = test;
start = 0;
while (*vp >= '0' && *vp <= '9') {
start *= 10;
start += *vp - '0';
++vp;
}
if (*vp == '\0') {
end = start;
} else if (*vp == '-') {
++vp;
if (*vp == '\0') {
end = limit - 1;
} else {
end = 0;
while (*vp >= '0' && *vp <= '9') {
end *= 10;
end += *vp - '0';
++vp;
}
}
} else
return (-1);
if (start < 0 || end >= limit || start > end)
return (-1);
while (start <= end)
test_set[idx++] = start++;
} else {
size_t len = strlen(test);
for (start = 0; start < limit; ++start) {
const char *name = tests[start].name;
const char *p;
while ((p = strchr(name, test[0])) != NULL) {
if (strncmp(p, test, len) == 0) {
test_set[idx++] = start;
break;
} else
name = p + 1;
}
}
}
return ((idx == 0)?-1:idx);
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
static const int limit = sizeof(tests) / sizeof(tests[0]); static const int limit = sizeof(tests) / sizeof(tests[0]);
int i = 0, j = 0, start, end, tests_run = 0, tests_failed = 0, option; int test_set[sizeof(tests) / sizeof(tests[0])];
int i = 0, j = 0, tests_run = 0, tests_failed = 0, option;
time_t now; time_t now;
char *refdir_alloc = NULL; char *refdir_alloc = NULL;
const char *progname; const char *progname;
char **saved_argv; char **saved_argv;
const char *tmp, *option_arg, *p; const char *tmp, *option_arg, *p;
char tmpdir[256], *pwd, *testprogdir, *tmp2 = NULL; char tmpdir[256], *pwd, *testprogdir, *tmp2 = NULL, *vlevel = NULL;
char tmpdir_timestamp[256]; char tmpdir_timestamp[256];
(void)argc; /* UNUSED */ (void)argc; /* UNUSED */
@ -2332,6 +2533,19 @@ main(int argc, char **argv)
if (getenv(ENVBASE "_DEBUG") != NULL) if (getenv(ENVBASE "_DEBUG") != NULL)
dump_on_failure = 1; dump_on_failure = 1;
/* Allow -v to be controlled through the environment. */
if (getenv("_VERBOSITY_LEVEL") != NULL)
{
vlevel = getenv("_VERBOSITY_LEVEL");
verbosity = atoi(vlevel);
if (verbosity < VERBOSITY_SUMMARY_ONLY || verbosity > VERBOSITY_FULL)
{
/* Unsupported verbosity levels are silently ignored */
vlevel = NULL;
verbosity = VERBOSITY_PASSFAIL;
}
}
/* Get the directory holding test files from environment. */ /* Get the directory holding test files from environment. */
refdir = getenv(ENVBASE "_TEST_FILES"); refdir = getenv(ENVBASE "_TEST_FILES");
@ -2379,7 +2593,8 @@ main(int argc, char **argv)
#endif #endif
break; break;
case 'q': case 'q':
verbosity--; if (!vlevel)
verbosity--;
break; break;
case 'r': case 'r':
refdir = option_arg; refdir = option_arg;
@ -2388,7 +2603,8 @@ main(int argc, char **argv)
until_failure++; until_failure++;
break; break;
case 'v': case 'v':
verbosity++; if (!vlevel)
verbosity++;
break; break;
default: default:
fprintf(stderr, "Unrecognized option '%c'\n", fprintf(stderr, "Unrecognized option '%c'\n",
@ -2501,78 +2717,27 @@ main(int argc, char **argv)
saved_argv = argv; saved_argv = argv;
do { do {
argv = saved_argv; argv = saved_argv;
if (*argv == NULL) { do {
/* Default: Run all tests. */ int test_num;
for (i = 0; i < limit; i++) {
test_num = get_test_set(test_set, limit, *argv);
if (test_num < 0) {
printf("*** INVALID Test %s\n", *argv);
free(refdir_alloc);
usage(progname);
return (1);
}
for (i = 0; i < test_num; i++) {
tests_run++; tests_run++;
if (test_run(i, tmpdir)) { if (test_run(test_set[i], tmpdir)) {
tests_failed++; tests_failed++;
if (until_failure) if (until_failure)
goto finish; goto finish;
} }
} }
} else { if (*argv != NULL)
while (*(argv) != NULL) {
if (**argv >= '0' && **argv <= '9') {
char *vp = *argv;
start = 0;
while (*vp >= '0' && *vp <= '9') {
start *= 10;
start += *vp - '0';
++vp;
}
if (*vp == '\0') {
end = start;
} else if (*vp == '-') {
++vp;
if (*vp == '\0') {
end = limit - 1;
} else {
end = 0;
while (*vp >= '0' && *vp <= '9') {
end *= 10;
end += *vp - '0';
++vp;
}
}
} else {
printf("*** INVALID Test %s\n", *argv);
free(refdir_alloc);
usage(progname);
return (1);
}
if (start < 0 || end >= limit || start > end) {
printf("*** INVALID Test %s\n", *argv);
free(refdir_alloc);
usage(progname);
return (1);
}
} else {
for (start = 0; start < limit; ++start) {
if (strcmp(*argv, tests[start].name) == 0)
break;
}
end = start;
if (start >= limit) {
printf("*** INVALID Test ``%s''\n",
*argv);
free(refdir_alloc);
usage(progname);
/* usage() never returns */
}
}
while (start <= end) {
tests_run++;
if (test_run(start, tmpdir)) {
tests_failed++;
if (until_failure)
goto finish;
}
++start;
}
argv++; argv++;
} } while (*argv != NULL);
}
} while (until_failure); } while (until_failure);
finish: finish:

View File

@ -194,11 +194,15 @@
#define assertMakeDir(dirname, mode) \ #define assertMakeDir(dirname, mode) \
assertion_make_dir(__FILE__, __LINE__, dirname, mode) assertion_make_dir(__FILE__, __LINE__, dirname, mode)
#define assertMakeFile(path, mode, contents) \ #define assertMakeFile(path, mode, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, contents) assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
#define assertMakeBinFile(path, mode, csize, contents) \
assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
#define assertMakeHardlink(newfile, oldfile) \ #define assertMakeHardlink(newfile, oldfile) \
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile) assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \ #define assertMakeSymlink(newfile, linkto) \
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto) assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertNodump(path) \
assertion_nodump(__FILE__, __LINE__, path)
#define assertUmask(mask) \ #define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask) assertion_umask(__FILE__, __LINE__, mask)
#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \ #define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
@ -241,9 +245,10 @@ int assertion_is_not_hardlink(const char *, int, const char *, const char *);
int assertion_is_reg(const char *, int, const char *, int); int assertion_is_reg(const char *, int, const char *, int);
int assertion_is_symlink(const char *, int, const char *, const char *); int assertion_is_symlink(const char *, int, const char *, const char *);
int assertion_make_dir(const char *, int, const char *, int); int assertion_make_dir(const char *, int, const char *, int);
int assertion_make_file(const char *, int, const char *, int, const char *); int assertion_make_file(const char *, int, const char *, int, int, const void *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *); int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *); int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_nodump(const char *, int, const char *);
int assertion_non_empty_file(const char *, int, const char *); int assertion_non_empty_file(const char *, int, const char *);
int assertion_text_file_contents(const char *, int, const char *buff, const char *f); int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
int assertion_umask(const char *, int, int); int assertion_umask(const char *, int, int);
@ -267,6 +272,9 @@ int canGzip(void);
/* Return true if this platform can run the "gunzip" program. */ /* Return true if this platform can run the "gunzip" program. */
int canGunzip(void); int canGunzip(void);
/* Return true if this filesystem can handle nodump flags. */
int canNodump(void);
/* Return true if the file has large i-node number(>0xffffffff). */ /* Return true if the file has large i-node number(>0xffffffff). */
int is_LargeInode(const char *); int is_LargeInode(const char *);

View File

@ -1,243 +0,0 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
__FBSDID("$FreeBSD$");
#include "pathmatch.h"
/*
* Verify that the pattern matcher implements the wildcard logic specified
* in SUSv2 for the cpio command. This is essentially the
* shell glob syntax:
* * - matches any sequence of chars, including '/'
* ? - matches any single char, including '/'
* [...] - matches any of a set of chars, '-' specifies a range,
* initial '!' is undefined
*
* The specification in SUSv2 is a bit incomplete, I assume the following:
* Trailing '-' in [...] is not special.
*
* TODO: Figure out if there's a good way to extend this to handle
* Windows paths that use '\' as a path separator. <sigh>
*/
DEFINE_TEST(test_pathmatch)
{
assertEqualInt(1, lafe_pathmatch("a/b/c", "a/b/c", 0));
assertEqualInt(0, lafe_pathmatch("a/b/", "a/b/c", 0));
assertEqualInt(0, lafe_pathmatch("a/b", "a/b/c", 0));
assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b/", 0));
assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b", 0));
/* Empty pattern only matches empty string. */
assertEqualInt(1, lafe_pathmatch("","", 0));
assertEqualInt(0, lafe_pathmatch("","a", 0));
assertEqualInt(1, lafe_pathmatch("*","", 0));
assertEqualInt(1, lafe_pathmatch("*","a", 0));
assertEqualInt(1, lafe_pathmatch("*","abcd", 0));
/* SUSv2: * matches / */
assertEqualInt(1, lafe_pathmatch("*","abcd/efgh/ijkl", 0));
assertEqualInt(1, lafe_pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0));
assertEqualInt(1, lafe_pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0));
assertEqualInt(1, lafe_pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0));
assertEqualInt(0, lafe_pathmatch("?", "", 0));
assertEqualInt(0, lafe_pathmatch("?", "\0", 0));
assertEqualInt(1, lafe_pathmatch("?", "a", 0));
assertEqualInt(0, lafe_pathmatch("?", "ab", 0));
assertEqualInt(1, lafe_pathmatch("?", ".", 0));
assertEqualInt(1, lafe_pathmatch("?", "?", 0));
assertEqualInt(1, lafe_pathmatch("a", "a", 0));
assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
assertEqualInt(1, lafe_pathmatch("a?c", "abc", 0));
/* SUSv2: ? matches / */
assertEqualInt(1, lafe_pathmatch("a?c", "a/c", 0));
assertEqualInt(1, lafe_pathmatch("a?*c*", "a/c", 0));
assertEqualInt(1, lafe_pathmatch("*a*", "a/c", 0));
assertEqualInt(1, lafe_pathmatch("*a*", "/a/c", 0));
assertEqualInt(1, lafe_pathmatch("*a*", "defaaaaaaa", 0));
assertEqualInt(0, lafe_pathmatch("a*", "defghi", 0));
assertEqualInt(0, lafe_pathmatch("*a*", "defghi", 0));
/* Character classes */
assertEqualInt(1, lafe_pathmatch("abc[def", "abc[def", 0));
assertEqualInt(0, lafe_pathmatch("abc[def]", "abc[def", 0));
assertEqualInt(0, lafe_pathmatch("abc[def", "abcd", 0));
assertEqualInt(1, lafe_pathmatch("abc[def]", "abcd", 0));
assertEqualInt(1, lafe_pathmatch("abc[def]", "abce", 0));
assertEqualInt(1, lafe_pathmatch("abc[def]", "abcf", 0));
assertEqualInt(0, lafe_pathmatch("abc[def]", "abcg", 0));
assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abcd", 0));
assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abc*", 0));
assertEqualInt(0, lafe_pathmatch("abc[d*f]", "abcdefghi", 0));
assertEqualInt(0, lafe_pathmatch("abc[d*", "abcdefghi", 0));
assertEqualInt(1, lafe_pathmatch("abc[d*", "abc[defghi", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcd", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abce", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcf", 0));
assertEqualInt(0, lafe_pathmatch("abc[d-f]", "abcg", 0));
assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abca", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcd", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abce", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcf", 0));
assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcg", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abch", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abci", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcj", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abck", 0));
assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcl", 0));
assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abc-", 0));
/* [] matches nothing, [!] is the same as ? */
assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcdefg", 0));
assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcqefg", 0));
assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcefg", 0));
assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcdefg", 0));
assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcqefg", 0));
assertEqualInt(0, lafe_pathmatch("abc[!]efg", "abcefg", 0));
/* I assume: Trailing '-' is non-special. */
assertEqualInt(0, lafe_pathmatch("abc[d-fh-]", "abcl", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abch", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
/* ']' can be backslash-quoted within a character class. */
assertEqualInt(1, lafe_pathmatch("abc[\\]]", "abc]", 0));
assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abc]", 0));
assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abcd", 0));
assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abc]", 0));
assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abcd", 0));
assertEqualInt(1, lafe_pathmatch("abc[d]e]", "abcde]", 0));
assertEqualInt(1, lafe_pathmatch("abc[d\\]e]", "abc]", 0));
assertEqualInt(0, lafe_pathmatch("abc[d\\]e]", "abcd]e", 0));
assertEqualInt(0, lafe_pathmatch("abc[d]e]", "abc]", 0));
/* backslash-quoted chars can appear as either end of a range. */
assertEqualInt(1, lafe_pathmatch("abc[\\d-f]gh", "abcegh", 0));
assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abcggh", 0));
assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abc\\gh", 0));
assertEqualInt(1, lafe_pathmatch("abc[d-\\f]gh", "abcegh", 0));
assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
/* backslash-quoted '-' isn't special. */
assertEqualInt(0, lafe_pathmatch("abc[d\\-f]gh", "abcegh", 0));
assertEqualInt(1, lafe_pathmatch("abc[d\\-f]gh", "abc-gh", 0));
/* Leading '!' negates a character class. */
assertEqualInt(0, lafe_pathmatch("abc[!d]", "abcd", 0));
assertEqualInt(1, lafe_pathmatch("abc[!d]", "abce", 0));
assertEqualInt(1, lafe_pathmatch("abc[!d]", "abcc", 0));
assertEqualInt(0, lafe_pathmatch("abc[!d-z]", "abcq", 0));
assertEqualInt(1, lafe_pathmatch("abc[!d-gi-z]", "abch", 0));
assertEqualInt(1, lafe_pathmatch("abc[!fgijkl]", "abch", 0));
assertEqualInt(0, lafe_pathmatch("abc[!fghijkl]", "abch", 0));
/* Backslash quotes next character. */
assertEqualInt(0, lafe_pathmatch("abc\\[def]", "abc\\d", 0));
assertEqualInt(1, lafe_pathmatch("abc\\[def]", "abc[def]", 0));
assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc[def]", 0));
assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc\\[def]", 0));
assertEqualInt(1, lafe_pathmatch("abc\\\\[def]", "abc\\d", 0));
assertEqualInt(1, lafe_pathmatch("abcd\\", "abcd\\", 0));
assertEqualInt(0, lafe_pathmatch("abcd\\", "abcd\\[", 0));
assertEqualInt(0, lafe_pathmatch("abcd\\", "abcde", 0));
assertEqualInt(0, lafe_pathmatch("abcd\\[", "abcd\\", 0));
/*
* Because '.' and '/' have special meanings, we can
* identify many equivalent paths even if they're expressed
* differently. (But quoting a character with '\\' suppresses
* special meanings!)
*/
assertEqualInt(0, lafe_pathmatch("a/b/", "a/bc", 0));
assertEqualInt(1, lafe_pathmatch("a/./b", "a/b", 0));
assertEqualInt(0, lafe_pathmatch("a\\/./b", "a/b", 0));
assertEqualInt(0, lafe_pathmatch("a/\\./b", "a/b", 0));
assertEqualInt(0, lafe_pathmatch("a/.\\/b", "a/b", 0));
assertEqualInt(0, lafe_pathmatch("a\\/\\.\\/b", "a/b", 0));
assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def/", 0));
assertEqualInt(1, lafe_pathmatch("abc/def", "./././abc/./def", 0));
assertEqualInt(1, lafe_pathmatch("abc/def/././//", "./././abc/./def/", 0));
assertEqualInt(1, lafe_pathmatch(".////abc/.//def", "./././abc/./def", 0));
assertEqualInt(1, lafe_pathmatch("./abc?def/", "abc/def/", 0));
failure("\"?./\" is not the same as \"/./\"");
assertEqualInt(0, lafe_pathmatch("./abc?./def/", "abc/def/", 0));
failure("Trailing '/' should match no trailing '/'");
assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def", 0));
failure("Trailing '/./' is still the same directory.");
assertEqualInt(1, lafe_pathmatch("./abc/./def/./", "abc/def", 0));
failure("Trailing '/.' is still the same directory.");
assertEqualInt(1, lafe_pathmatch("./abc/./def/.", "abc/def", 0));
assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/", 0));
failure("Trailing '/./' is still the same directory.");
assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/./", 0));
failure("Trailing '/.' is still the same directory.");
assertEqualInt(1, lafe_pathmatch("./abc*/./def", "abc/def/.", 0));
/* Matches not anchored at beginning. */
assertEqualInt(0,
lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
assertEqualInt(1,
lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START));
assertEqualInt(0,
lafe_pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
assertEqualInt(1,
lafe_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
assertEqualInt(0,
lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
assertEqualInt(0,
lafe_pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
/* Matches not anchored at end. */
assertEqualInt(0,
lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
lafe_pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
lafe_pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(0,
lafe_pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
lafe_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(0,
lafe_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
lafe_pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
lafe_pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
lafe_pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(0,
lafe_pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
lafe_pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(1,
lafe_pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
assertEqualInt(0,
lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
}

View File

@ -377,9 +377,9 @@ function splitwords(l, dest, n, o, w) {
# TODO: Figure out how to handle this # TODO: Figure out how to handle this
} else if(match(words[w],"^[=]$")) { } else if(match(words[w],"^[=]$")) {
addpunct(words[w]) addpunct(words[w])
} else if(match(words[w],"^[\[{(]$")) { } else if(match(words[w],"^[[{(]$")) {
addopen(words[w]) addopen(words[w])
} else if(match(words[w],"^[\\\])}.,;:]$")) { } else if(match(words[w],"^[\\])}.,;:]$")) {
addclose(words[w]) addclose(words[w])
} else { } else {
add(words[w]) add(words[w])

View File

@ -26,6 +26,10 @@ BEGIN {
sep = "" sep = ""
nextsep = " " nextsep = " "
spaces = " " spaces = " "
NORMAL_STATE = 0
PRETAG_STATE = 1
STATE = NORMAL_STATE
} }
# Add a word with appropriate preceding whitespace # Add a word with appropriate preceding whitespace
@ -63,7 +67,11 @@ function endline() {
addclose(trailer) addclose(trailer)
trailer = "" trailer = ""
if(length(out) > 0) { if(length(out) > 0) {
print out if (STATE == PRETAG_STATE) {
print out
} else {
print out " "
}
out="" out=""
} }
if(displaylines > 0) { if(displaylines > 0) {
@ -87,12 +95,12 @@ function breakline() {
# Start an indented display # Start an indented display
function dispstart() { function dispstart() {
linecmd("{{{") linecmd("```text")
} }
# End an indented display # End an indented display
function dispend() { function dispend() {
linecmd("}}}") linecmd("```")
} }
# Collect rest of input line # Collect rest of input line
@ -159,6 +167,7 @@ function splitwords(l, dest, n, o, w) {
dispstart() dispstart()
displaylines = 1 displaylines = 1
} else if(match(words[w],"^Bd$")) { # Begin display } else if(match(words[w],"^Bd$")) { # Begin display
STATE = PRETAG_STATE
if(match(words[w+1],"-literal")) { if(match(words[w+1],"-literal")) {
dispstart() dispstart()
displaylines=10000 displaylines=10000
@ -167,6 +176,7 @@ function splitwords(l, dest, n, o, w) {
} else if(match(words[w],"^Ed$")) { # End display } else if(match(words[w],"^Ed$")) { # End display
displaylines = 0 displaylines = 0
dispend() dispend()
STATE = NORMAL_STATE
} else if(match(words[w],"^Ns$")) { # Suppress space before next word } else if(match(words[w],"^Ns$")) { # Suppress space before next word
sep="" sep=""
} else if(match(words[w],"^No$")) { # Normal text } else if(match(words[w],"^No$")) { # Normal text
@ -182,18 +192,18 @@ function splitwords(l, dest, n, o, w) {
} else if(match(words[w],"^Dc$")) { } else if(match(words[w],"^Dc$")) {
addclose("\"") addclose("\"")
} else if(match(words[w],"^Oo$")) { } else if(match(words[w],"^Oo$")) {
addopen("`[`") addopen("<nowiki>[</nowiki>")
} else if(match(words[w],"^Oc$")) { } else if(match(words[w],"^Oc$")) {
addclose("`]`") addclose("<nowiki>]</nowiki>")
} else if(match(words[w],"^Ao$")) { } else if(match(words[w],"^Ao$")) {
addopen("`<`") addopen("&lt;")
} else if(match(words[w],"^Ac$")) { } else if(match(words[w],"^Ac$")) {
addclose("`>`") addclose("&gt;")
} else if(match(words[w],"^Dd$")) { } else if(match(words[w],"^Dd$")) {
date=wtail() date=wtail()
next next
} else if(match(words[w],"^Dt$")) { } else if(match(words[w],"^Dt$")) {
id=wtail() id=words[++w] "(" words[++w] ")"
next next
} else if(match(words[w],"^Ox$")) { } else if(match(words[w],"^Ox$")) {
add("OpenBSD") add("OpenBSD")
@ -206,32 +216,32 @@ function splitwords(l, dest, n, o, w) {
} else if(match(words[w],"^St$")) { } else if(match(words[w],"^St$")) {
if (match(words[w+1], "^-p1003.1$")) { if (match(words[w+1], "^-p1003.1$")) {
w++ w++
add("IEEE Std 1003.1 (``POSIX.1'')") add("<nowiki>IEEE Std 1003.1 (``POSIX.1'')</nowiki>")
} else if(match(words[w+1], "^-p1003.1-96$")) { } else if(match(words[w+1], "^-p1003.1-96$")) {
w++ w++
add("ISO/IEC 9945-1:1996 (``POSIX.1'')") add("<nowiki>ISO/IEC 9945-1:1996 (``POSIX.1'')</nowiki>")
} else if(match(words[w+1], "^-p1003.1-88$")) { } else if(match(words[w+1], "^-p1003.1-88$")) {
w++ w++
add("IEEE Std 1003.1-1988 (``POSIX.1'')") add("<nowiki>IEEE Std 1003.1-1988 (``POSIX.1'')</nowiki>")
} else if(match(words[w+1], "^-p1003.1-2001$")) { } else if(match(words[w+1], "^-p1003.1-2001$")) {
w++ w++
add("IEEE Std 1003.1-2001 (``POSIX.1'')") add("<nowiki>IEEE Std 1003.1-2001 (``POSIX.1'')</nowiki>")
} else if(match(words[w+1], "^-susv2$")) { } else if(match(words[w+1], "^-susv2$")) {
w++ w++
add("Version 2 of the Single UNIX Specification (``SUSv2'')") add("<nowiki>Version 2 of the Single UNIX Specification (``SUSv2'')</nowiki>")
} }
} else if(match(words[w],"^Ex$")) { } else if(match(words[w],"^Ex$")) {
if (match(words[w+1], "^-std$")) { if (match(words[w+1], "^-std$")) {
w++ w++
add("The *" name "* utility exits 0 on success, and >0 if an error occurs.") add("The '''" name "''' utility exits 0 on success, and &gt;0 if an error occurs.")
} }
} else if(match(words[w],"^Os$")) { } else if(match(words[w],"^Os$")) {
add("#summary " id " manual page") add(id " manual page")
} else if(match(words[w],"^Sh$")) { } else if(match(words[w],"^Sh$")) {
section=wtail() section=wtail()
linecmd("== " section " ==") linecmd("== " section " ==")
} else if(match(words[w],"^Xr$")) { } else if(match(words[w],"^Xr$")) {
add("*" words[++w] "*(" words[++w] ")" words[++w]) add("'''" words[++w] "'''(" words[++w] ")" words[++w])
} else if(match(words[w],"^Nm$")) { } else if(match(words[w],"^Nm$")) {
if(match(section,"SYNOPSIS")) if(match(section,"SYNOPSIS"))
breakline() breakline()
@ -249,7 +259,7 @@ function splitwords(l, dest, n, o, w) {
if(!length(n)) if(!length(n))
n=name n=name
if (displaylines == 0) if (displaylines == 0)
add("*" n "*") add("'''" n "'''")
else else
add(n) add(n)
} else if(match(words[w],"^Nd$")) { } else if(match(words[w],"^Nd$")) {
@ -258,24 +268,22 @@ function splitwords(l, dest, n, o, w) {
addopen("-") addopen("-")
} else if(match(words[w],"^Ar$")) { } else if(match(words[w],"^Ar$")) {
if(w==nwords) if(w==nwords)
add("_file ..._") add("''file ...''")
else { else {
++w ++w
gsub("<", "`<`", words[w]) gsub("<", "&lt;", words[w])
add("_" words[w] "_") add("''" words[w] "''")
} }
} else if(match(words[w],"^Cm$")) { } else if(match(words[w],"^Cm$")) {
++w ++w
if (displaylines == 0) { if (displaylines == 0) {
gsub("^_", "`_`", words[w]) add("'''" words[w] "'''")
gsub("\\*$", "`*`", words[w])
add("*" words[w] "*")
} else } else
add(words[w]) add(words[w])
} else if(match(words[w],"^Op$")) { } else if(match(words[w],"^Op$")) {
addopen("`[`") addopen("<nowiki>[</nowiki>")
option=1 option=1
trailer="`]`" trailer trailer="<nowiki>]</nowiki>" trailer
} else if(match(words[w],"^Pp$")) { } else if(match(words[w],"^Pp$")) {
++w ++w
endline() endline()
@ -292,15 +300,13 @@ function splitwords(l, dest, n, o, w) {
breakline() breakline()
} }
l = wtail() l = wtail()
gsub("\\*", "`*`", l) add("'''" l "'''")
add("*" l "*")
if (match(section, "SYNOPSIS")) { if (match(section, "SYNOPSIS")) {
breakline() breakline()
} }
} else if(match(words[w],"^Fn$")) { } else if(match(words[w],"^Fn$")) {
++w ++w
F = "*" words[w] "*(" F = "'''" words[w] "'''("
Fsep = "" Fsep = ""
while(w<nwords) { while(w<nwords) {
++w ++w
@ -308,8 +314,7 @@ function splitwords(l, dest, n, o, w) {
--w --w
break break
} }
gsub("\\*", "`*`", words[w]) F = F Fsep "''" words[w] "''"
F = F Fsep "_" words[w] "_"
Fsep = ", " Fsep = ", "
} }
add(F ")") add(F ")")
@ -318,12 +323,11 @@ function splitwords(l, dest, n, o, w) {
} }
} else if(match(words[w],"^Fo$")) { } else if(match(words[w],"^Fo$")) {
w++ w++
F = "*" words[w] "*(" F = "'''" words[w] "'''("
Fsep = "" Fsep = ""
} else if(match(words[w],"^Fa$")) { } else if(match(words[w],"^Fa$")) {
w++ w++
gsub("\\*", "`*`", words[w]) F = F Fsep "''" words[w] "''"
F = F Fsep "_" words[w] "_"
Fsep = ", " Fsep = ", "
} else if(match(words[w],"^Fc$")) { } else if(match(words[w],"^Fc$")) {
add(F ")") add(F ")")
@ -332,16 +336,16 @@ function splitwords(l, dest, n, o, w) {
} }
} else if(match(words[w],"^Va$")) { } else if(match(words[w],"^Va$")) {
w++ w++
add("_" words[w] "_") add("''" words[w] "''")
} else if(match(words[w],"^In$")) { } else if(match(words[w],"^In$")) {
w++ w++
add("*#include <" words[w] ">*") add("'''<nowiki>#include <" words[w] "></nowiki>'''")
} else if(match(words[w],"^Pa$")) { } else if(match(words[w],"^Pa$")) {
w++ w++
# if(match(words[w],"^\\.")) # if(match(words[w],"^\\."))
# add("\\&") # add("\\&")
if (displaylines == 0) if (displaylines == 0)
add("_" words[w] "_") add("''" words[w] "''")
else else
add(words[w]) add(words[w])
} else if(match(words[w],"^Dv$")) { } else if(match(words[w],"^Dv$")) {
@ -352,20 +356,19 @@ function splitwords(l, dest, n, o, w) {
addopen("(") addopen("(")
trailer=")" trailer trailer=")" trailer
} else if(match(words[w],"^Aq$")) { } else if(match(words[w],"^Aq$")) {
addopen(" <") addopen(" &lt;")
trailer=">" trailer trailer="&gt;" trailer
} else if(match(words[w],"^Brq$")) { } else if(match(words[w],"^Brq$")) {
addopen("{") addopen("<nowiki>{</nowiki>")
trailer="}" trailer trailer="<nowiki>}</nowiki>" trailer
} else if(match(words[w],"^S[xy]$")) { } else if(match(words[w],"^S[xy]$")) {
add(".B " wtail()) add(".B " wtail())
} else if(match(words[w],"^Tn$")) { } else if(match(words[w],"^Tn$")) {
n=wtail() n=wtail()
gsub("\\*$", "`*`", n) add("'''" n "'''")
add("*" n "*")
} else if(match(words[w],"^Ic$")) { } else if(match(words[w],"^Ic$")) {
add("\\fB") add("''")
trailer="\\fP" trailer trailer="''" trailer
} else if(match(words[w],"^Bl$")) { } else if(match(words[w],"^Bl$")) {
++listdepth ++listdepth
listnext[listdepth]="" listnext[listdepth]=""
@ -408,9 +411,9 @@ function splitwords(l, dest, n, o, w) {
# Suppress trailer # Suppress trailer
w++ w++
} else if(match(words[w+1],"^Pa$|^Ev$")) { } else if(match(words[w+1],"^Pa$|^Ev$")) {
addopen("*") addopen("'''")
w++ w++
add(words[++w] "*") add(words[++w] "'''")
} else { } else {
trailer = listnext[listdepth] "<dd>" trailer trailer = listnext[listdepth] "<dd>" trailer
listnext[listdepth] = "</dd>" listnext[listdepth] = "</dd>"
@ -421,7 +424,7 @@ function splitwords(l, dest, n, o, w) {
} }
} else if(match(words[w], "^Vt$")) { } else if(match(words[w], "^Vt$")) {
w++ w++
add("_" words[w] "_") add("''" words[w] "''")
} else if(match(words[w],"^Xo$")) { } else if(match(words[w],"^Xo$")) {
# TODO: Figure out how to handle this # TODO: Figure out how to handle this
} else if(match(words[w],"^Xc$")) { } else if(match(words[w],"^Xc$")) {
@ -433,9 +436,9 @@ function splitwords(l, dest, n, o, w) {
} }
} else if(match(words[w],"^[=]$")) { } else if(match(words[w],"^[=]$")) {
addpunct(words[w]) addpunct(words[w])
} else if(match(words[w],"^[\[{(]$")) { } else if(match(words[w],"^[[{(]$")) {
addopen(words[w]) addopen(words[w])
} else if(match(words[w],"^[\\\])}.,;:]$")) { } else if(match(words[w],"^[\\])}.,;:]$")) {
addclose(words[w]) addclose(words[w])
} else { } else {
sub("\\\\&", "", words[w]) sub("\\\\&", "", words[w])

View File

@ -80,7 +80,7 @@ for f in $MANPAGES; do
outname="`basename $f`.html" outname="`basename $f`.html"
echo >> Makefile echo >> Makefile
echo $outname: $f >> Makefile echo $outname: $f >> Makefile
echo " groff -mdoc2html $f > $outname" >> Makefile echo " groff -mdoc -T html $f > $outname" >> Makefile
all="$all $outname" all="$all $outname"
done done
echo $all >>Makefile echo $all >>Makefile
@ -113,5 +113,5 @@ cd ..
(cd pdf && make) (cd pdf && make)
# Format all of the manpages to HTML # Format all of the manpages to HTML
(cd html && make) (cd html && make)
# Format all of the manpages to Google Wiki syntax # Format all of the manpages to wiki syntax
(cd wiki && make) (cd wiki && make)

View File

@ -28,8 +28,12 @@ SET(libarchive_SOURCES
archive_entry_stat.c archive_entry_stat.c
archive_entry_strmode.c archive_entry_strmode.c
archive_entry_xattr.c archive_entry_xattr.c
archive_getdate.c
archive_match.c
archive_options.c archive_options.c
archive_options_private.h archive_options_private.h
archive_pathmatch.c
archive_pathmatch.h
archive_platform.h archive_platform.h
archive_ppmd_private.h archive_ppmd_private.h
archive_ppmd7.c archive_ppmd7.c
@ -89,6 +93,7 @@ SET(libarchive_SOURCES
archive_write_open_file.c archive_write_open_file.c
archive_write_open_filename.c archive_write_open_filename.c
archive_write_open_memory.c archive_write_open_memory.c
archive_write_add_filter.c
archive_write_add_filter_bzip2.c archive_write_add_filter_bzip2.c
archive_write_add_filter_compress.c archive_write_add_filter_compress.c
archive_write_add_filter_gzip.c archive_write_add_filter_gzip.c

View File

@ -56,23 +56,14 @@
# else # else
# define __LA_SSIZE_T long # define __LA_SSIZE_T long
# endif # endif
# if defined(__BORLANDC__)
# define __LA_UID_T uid_t
# define __LA_GID_T gid_t
# else
# define __LA_UID_T short
# define __LA_GID_T short
# endif
#else #else
# include <unistd.h> /* ssize_t, uid_t, and gid_t */ # include <unistd.h> /* ssize_t */
# if defined(_SCO_DS) # if defined(_SCO_DS)
# define __LA_INT64_T long long # define __LA_INT64_T long long
# else # else
# define __LA_INT64_T int64_t # define __LA_INT64_T int64_t
# endif # endif
# define __LA_SSIZE_T ssize_t # define __LA_SSIZE_T ssize_t
# define __LA_UID_T uid_t
# define __LA_GID_T gid_t
#endif #endif
/* /*
@ -127,13 +118,13 @@ extern "C" {
* assert that ARCHIVE_VERSION_NUMBER >= 2012108. * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/ */
/* Note: Compiler will complain if this does not match archive_entry.h! */ /* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3000003 #define ARCHIVE_VERSION_NUMBER 3000004
__LA_DECL int archive_version_number(void); __LA_DECL int archive_version_number(void);
/* /*
* Textual name/version of the library, useful for version displays. * Textual name/version of the library, useful for version displays.
*/ */
#define ARCHIVE_VERSION_STRING "libarchive 3.0.3" #define ARCHIVE_VERSION_STRING "libarchive 3.0.4"
__LA_DECL const char * archive_version_string(void); __LA_DECL const char * archive_version_string(void);
/* Declare our basic types. */ /* Declare our basic types. */
@ -567,6 +558,8 @@ __LA_DECL int archive_write_set_compression_program(struct archive *,
__LA_DECL int archive_write_set_compression_xz(struct archive *); __LA_DECL int archive_write_set_compression_xz(struct archive *);
#endif #endif
/* A convenience function to set the filter based on the code. */
__LA_DECL int archive_write_add_filter(struct archive *, int filter_code);
__LA_DECL int archive_write_add_filter_bzip2(struct archive *); __LA_DECL int archive_write_add_filter_bzip2(struct archive *);
__LA_DECL int archive_write_add_filter_compress(struct archive *); __LA_DECL int archive_write_add_filter_compress(struct archive *);
__LA_DECL int archive_write_add_filter_gzip(struct archive *); __LA_DECL int archive_write_add_filter_gzip(struct archive *);
@ -758,11 +751,42 @@ __LA_DECL int archive_read_disk_open_w(struct archive *, const wchar_t *);
* traversal. * traversal.
*/ */
__LA_DECL int archive_read_disk_descend(struct archive *); __LA_DECL int archive_read_disk_descend(struct archive *);
__LA_DECL int archive_read_disk_can_descend(struct archive *);
__LA_DECL int archive_read_disk_current_filesystem(struct archive *); __LA_DECL int archive_read_disk_current_filesystem(struct archive *);
__LA_DECL int archive_read_disk_current_filesystem_is_synthetic(struct archive *); __LA_DECL int archive_read_disk_current_filesystem_is_synthetic(struct archive *);
__LA_DECL int archive_read_disk_current_filesystem_is_remote(struct archive *); __LA_DECL int archive_read_disk_current_filesystem_is_remote(struct archive *);
/* Request that the access time of the entry visited by travesal be restored. */ /* Request that the access time of the entry visited by travesal be restored. */
__LA_DECL int archive_read_disk_set_atime_restored(struct archive *); __LA_DECL int archive_read_disk_set_atime_restored(struct archive *);
/*
* Set behavior. The "flags" argument selects optional behavior.
*/
/* Request that the access time of the entry visited by travesal be restored.
* This is the same as archive_read_disk_set_atime_restored. */
#define ARCHIVE_READDISK_RESTORE_ATIME (0x0001)
/* Default: Do not skip an entry which has nodump flags. */
#define ARCHIVE_READDISK_HONOR_NODUMP (0x0002)
/* Default: Skip a mac resource fork file whose prefix is "._" because of
* using copyfile. */
#define ARCHIVE_READDISK_MAC_COPYFILE (0x0004)
/* Default: Do not traverse mount points. */
#define ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS (0x0008)
__LA_DECL int archive_read_disk_set_behavior(struct archive *,
int flags);
/*
* Set archive_match object that will be used in archive_read_disk to
* know whether an entry should be skipped. The callback function
* _excluded_func will be invoked when an entry is skipped by the result
* of archive_match.
*/
__LA_DECL int archive_read_disk_set_matching(struct archive *,
struct archive *_matching, void (*_excluded_func)
(struct archive *, void *, struct archive_entry *),
void *_client_data);
__LA_DECL int archive_read_disk_set_metadata_filter_callback(struct archive *,
int (*_metadata_filter_func)(struct archive *, void *,
struct archive_entry *), void *_client_data);
/* /*
* Accessor functions to read/set various information in * Accessor functions to read/set various information in
@ -802,14 +826,116 @@ __LA_DECL void archive_copy_error(struct archive *dest,
struct archive *src); struct archive *src);
__LA_DECL int archive_file_count(struct archive *); __LA_DECL int archive_file_count(struct archive *);
/*
* ARCHIVE_MATCH API
*/
__LA_DECL struct archive *archive_match_new(void);
__LA_DECL int archive_match_free(struct archive *);
/*
* Test if archive_entry is excluded.
* This is a convenience function. This is the same as calling all
* archive_match_path_excluded, archive_match_time_excluded
* and archive_match_owner_excluded.
*/
__LA_DECL int archive_match_excluded(struct archive *,
struct archive_entry *);
/*
* Test if pathname is excluded. The conditions are set by following functions.
*/
__LA_DECL int archive_match_path_excluded(struct archive *,
struct archive_entry *);
/* 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 *,
const wchar_t *);
/* Add exclusion pathname pattern from file. */
__LA_DECL int archive_match_exclude_pattern_from_file(struct archive *,
const char *, int _nullSeparator);
__LA_DECL int archive_match_exclude_pattern_from_file_w(struct archive *,
const wchar_t *, int _nullSeparator);
/* Add inclusion pathname pattern. */
__LA_DECL int archive_match_include_pattern(struct archive *, const char *);
__LA_DECL int archive_match_include_pattern_w(struct archive *,
const wchar_t *);
/* Add inclusion pathname pattern from file. */
__LA_DECL int archive_match_include_pattern_from_file(struct archive *,
const char *, int _nullSeparator);
__LA_DECL int archive_match_include_pattern_from_file_w(struct archive *,
const wchar_t *, int _nullSeparator);
/*
* How to get statistic information for inclusion patterns.
*/
/* Return the amount number of unmatched inclusion patterns. */
__LA_DECL int archive_match_path_unmatched_inclusions(struct archive *);
/* Return the pattern of unmatched inclusion with ARCHIVE_OK.
* Return ARCHIVE_EOF if there is no inclusion pattern. */
__LA_DECL int archive_match_path_unmatched_inclusions_next(
struct archive *, const char **);
__LA_DECL int archive_match_path_unmatched_inclusions_next_w(
struct archive *, const wchar_t **);
/*
* Test if a file is excluded by its time stamp.
* The conditions are set by following functions.
*/
__LA_DECL int archive_match_time_excluded(struct archive *,
struct archive_entry *);
/*
* Flags to tell a matching type of time stamps. These are used for
* following functinos.
*/
/* Time flag: mtime to be tested. */
#define ARCHIVE_MATCH_MTIME (0x0100)
/* Time flag: ctime to be tested. */
#define ARCHIVE_MATCH_CTIME (0x0200)
/* Comparison flag: Match the time if it is newer than. */
#define ARCHIVE_MATCH_NEWER (0x0001)
/* Comparison flag: Match the time if it is older than. */
#define ARCHIVE_MATCH_OLDER (0x0002)
/* Comparison flag: Match the time if it is equal to. */
#define ARCHIVE_MATCH_EQUAL (0x0010)
/* Set inclusion time. */
__LA_DECL int archive_match_include_time(struct archive *, int _flag,
time_t _sec, long _nsec);
/* Set inclusion time by a date string. */
__LA_DECL int archive_match_include_date(struct archive *, int _flag,
const char *_datestr);
__LA_DECL int archive_match_include_date_w(struct archive *, int _flag,
const wchar_t *_datestr);
/* Set inclusion time by a particluar file. */
__LA_DECL int archive_match_include_file_time(struct archive *,
int _flag, const char *_pathname);
__LA_DECL int archive_match_include_file_time_w(struct archive *,
int _flag, const wchar_t *_pathname);
/* Add exclusion entry. */
__LA_DECL int archive_match_exclude_entry(struct archive *,
int _flag, struct archive_entry *);
/*
* Test if a file is excluded by its uid ,gid, uname or gname.
* The conditions are set by following functions.
*/
__LA_DECL int archive_match_owner_excluded(struct archive *,
struct archive_entry *);
/* Add inclusion uid, gid, uname and gname. */
__LA_DECL int archive_match_include_uid(struct archive *, __LA_INT64_T);
__LA_DECL int archive_match_include_gid(struct archive *, __LA_INT64_T);
__LA_DECL int archive_match_include_uname(struct archive *, const char *);
__LA_DECL int archive_match_include_uname_w(struct archive *,
const wchar_t *);
__LA_DECL int archive_match_include_gname(struct archive *, const char *);
__LA_DECL int archive_match_include_gname_w(struct archive *,
const wchar_t *);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* These are meaningless outside of this header. */ /* These are meaningless outside of this header. */
#undef __LA_DECL #undef __LA_DECL
#undef __LA_GID_T
#undef __LA_UID_T
/* These need to remain defined because they're used in the /* These need to remain defined because they're used in the
* callback type definitions. XXX Fix this. This is ugly. XXX */ * callback type definitions. XXX Fix this. This is ugly. XXX */

View File

@ -422,8 +422,11 @@ archive_acl_next(struct archive *a, struct archive_acl *acl, int want_type, int
*permset = acl->acl_p->permset; *permset = acl->acl_p->permset;
*tag = acl->acl_p->tag; *tag = acl->acl_p->tag;
*id = acl->acl_p->id; *id = acl->acl_p->id;
if (archive_mstring_get_mbs(a, &acl->acl_p->name, name) != 0) if (archive_mstring_get_mbs(a, &acl->acl_p->name, name) != 0) {
if (errno == ENOMEM)
return (ARCHIVE_FATAL);
*name = NULL; *name = NULL;
}
acl->acl_p = acl->acl_p->next; acl->acl_p = acl->acl_p->next;
return (ARCHIVE_OK); return (ARCHIVE_OK);
} }
@ -441,7 +444,7 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags)
const wchar_t *prefix; const wchar_t *prefix;
wchar_t separator; wchar_t separator;
struct archive_acl_entry *ap; struct archive_acl_entry *ap;
int id; int id, r;
wchar_t *wp; wchar_t *wp;
if (acl->acl_text_w != NULL) { if (acl->acl_text_w != NULL) {
@ -461,9 +464,11 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags)
length += 8; /* "default:" */ length += 8; /* "default:" */
length += 5; /* tag name */ length += 5; /* tag name */
length += 1; /* colon */ length += 1; /* colon */
if (archive_mstring_get_wcs(a, &ap->name, &wname) == 0 && r = archive_mstring_get_wcs(a, &ap->name, &wname);
wname != NULL) if (r == 0 && wname != NULL)
length += wcslen(wname); length += wcslen(wname);
else if (r < 0 && errno == ENOMEM)
return (NULL);
else else
length += sizeof(uid_t) * 3 + 1; length += sizeof(uid_t) * 3 + 1;
length ++; /* colon */ length ++; /* colon */
@ -487,7 +492,7 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags)
/* Now, allocate the string and actually populate it. */ /* Now, allocate the string and actually populate it. */
wp = acl->acl_text_w = (wchar_t *)malloc(length * sizeof(wchar_t)); wp = acl->acl_text_w = (wchar_t *)malloc(length * sizeof(wchar_t));
if (wp == NULL) if (wp == NULL)
__archive_errx(1, "No memory to generate the text version of the ACL"); return (NULL);
count = 0; count = 0;
if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL, append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,
@ -502,16 +507,19 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags)
ap = acl->acl_head; ap = acl->acl_head;
while (ap != NULL) { while (ap != NULL) {
if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0 && if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
archive_mstring_get_wcs(a, &ap->name, &wname) == 0) { r = archive_mstring_get_wcs(a, &ap->name, &wname);
*wp++ = separator; if (r == 0) {
if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) *wp++ = separator;
id = ap->id; if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
else id = ap->id;
id = -1; else
append_entry_w(&wp, NULL, ap->tag, wname, id = -1;
ap->permset, id); append_entry_w(&wp, NULL, ap->tag, wname,
count++; ap->permset, id);
count++;
} else if (r < 0 && errno == ENOMEM)
return (NULL);
} }
ap = ap->next; ap = ap->next;
} }
@ -526,17 +534,20 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags)
ap = acl->acl_head; ap = acl->acl_head;
count = 0; count = 0;
while (ap != NULL) { while (ap != NULL) {
if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0 && if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
archive_mstring_get_wcs(a, &ap->name, &wname) == 0) { r = archive_mstring_get_wcs(a, &ap->name, &wname);
if (count > 0) if (r == 0) {
*wp++ = separator; if (count > 0)
if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) *wp++ = separator;
id = ap->id; if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
else id = ap->id;
id = -1; else
append_entry_w(&wp, prefix, ap->tag, id = -1;
wname, ap->permset, id); append_entry_w(&wp, prefix, ap->tag,
count ++; wname, ap->permset, id);
count ++;
} else if (r < 0 && errno == ENOMEM)
return (NULL);
} }
ap = ap->next; ap = ap->next;
} }
@ -675,7 +686,7 @@ archive_acl_text_l(struct archive_acl *acl, int flags,
/* Now, allocate the string and actually populate it. */ /* Now, allocate the string and actually populate it. */
p = acl->acl_text = (char *)malloc(length); p = acl->acl_text = (char *)malloc(length);
if (p == NULL) if (p == NULL)
__archive_errx(1, "No memory to generate the text version of the ACL"); return (-1);
count = 0; count = 0;
if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL, append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,

View File

@ -94,6 +94,7 @@ archive_handle_type_name(unsigned m)
case ARCHIVE_READ_MAGIC: return ("archive_read"); case ARCHIVE_READ_MAGIC: return ("archive_read");
case ARCHIVE_WRITE_DISK_MAGIC: return ("archive_write_disk"); case ARCHIVE_WRITE_DISK_MAGIC: return ("archive_write_disk");
case ARCHIVE_READ_DISK_MAGIC: return ("archive_read_disk"); case ARCHIVE_READ_DISK_MAGIC: return ("archive_read_disk");
case ARCHIVE_MATCH_MAGIC: return ("archive_match");
default: return NULL; default: return NULL;
} }
} }

View File

@ -126,8 +126,8 @@ archive_be64enc(void *pp, uint64_t u)
{ {
unsigned char *p = (unsigned char *)pp; unsigned char *p = (unsigned char *)pp;
archive_be32enc(p, u >> 32); archive_be32enc(p, (uint32_t)(u >> 32));
archive_be32enc(p + 4, u & 0xffffffff); archive_be32enc(p + 4, (uint32_t)(u & 0xffffffff));
} }
static inline void static inline void
@ -155,8 +155,8 @@ archive_le64enc(void *pp, uint64_t u)
{ {
unsigned char *p = (unsigned char *)pp; unsigned char *p = (unsigned char *)pp;
archive_le32enc(p, u & 0xffffffff); archive_le32enc(p, (uint32_t)(u & 0xffffffff));
archive_le32enc(p + 4, u >> 32); archive_le32enc(p + 4, (uint32_t)(u >> 32));
} }
#endif #endif

View File

@ -23,9 +23,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $ .\" $FreeBSD$
.\" .\"
.Dd Feburary 22, 2010 .Dd Feburary 2, 2012
.Dt ARCHIVE_ENTRY 3 .Dt ARCHIVE_ENTRY 3
.Os .Os
.Sh NAME .Sh NAME
@ -34,6 +34,8 @@
.Nm archive_entry_free , .Nm archive_entry_free ,
.Nm archive_entry_new , .Nm archive_entry_new ,
.Nd functions for managing archive entry descriptions .Nd functions for managing archive entry descriptions
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive_entry.h .In archive_entry.h
.Ft "struct archive_entry *" .Ft "struct archive_entry *"

View File

@ -375,8 +375,11 @@ archive_entry_fflags_text(struct archive_entry *entry)
char *p; char *p;
if (archive_mstring_get_mbs(entry->archive, if (archive_mstring_get_mbs(entry->archive,
&entry->ae_fflags_text, &f) == 0 && f != NULL) &entry->ae_fflags_text, &f) == 0) {
return (f); if (f != NULL)
return (f);
} else if (errno == ENOMEM)
__archive_errx(1, "No memory");
if (entry->ae_fflags_set == 0 && entry->ae_fflags_clear == 0) if (entry->ae_fflags_set == 0 && entry->ae_fflags_clear == 0)
return (NULL); return (NULL);
@ -390,6 +393,8 @@ archive_entry_fflags_text(struct archive_entry *entry)
if (archive_mstring_get_mbs(entry->archive, if (archive_mstring_get_mbs(entry->archive,
&entry->ae_fflags_text, &f) == 0) &entry->ae_fflags_text, &f) == 0)
return (f); return (f);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -405,6 +410,8 @@ archive_entry_gname(struct archive_entry *entry)
const char *p; const char *p;
if (archive_mstring_get_mbs(entry->archive, &entry->ae_gname, &p) == 0) if (archive_mstring_get_mbs(entry->archive, &entry->ae_gname, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -414,6 +421,8 @@ archive_entry_gname_w(struct archive_entry *entry)
const wchar_t *p; const wchar_t *p;
if (archive_mstring_get_wcs(entry->archive, &entry->ae_gname, &p) == 0) if (archive_mstring_get_wcs(entry->archive, &entry->ae_gname, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -428,9 +437,13 @@ const char *
archive_entry_hardlink(struct archive_entry *entry) archive_entry_hardlink(struct archive_entry *entry)
{ {
const char *p; const char *p;
if ((entry->ae_set & AE_SET_HARDLINK) && archive_mstring_get_mbs( if ((entry->ae_set & AE_SET_HARDLINK) == 0)
return (NULL);
if (archive_mstring_get_mbs(
entry->archive, &entry->ae_hardlink, &p) == 0) entry->archive, &entry->ae_hardlink, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -438,9 +451,13 @@ const wchar_t *
archive_entry_hardlink_w(struct archive_entry *entry) archive_entry_hardlink_w(struct archive_entry *entry)
{ {
const wchar_t *p; const wchar_t *p;
if ((entry->ae_set & AE_SET_HARDLINK) && archive_mstring_get_wcs( if ((entry->ae_set & AE_SET_HARDLINK) == 0)
return (NULL);
if (archive_mstring_get_wcs(
entry->archive, &entry->ae_hardlink, &p) == 0) entry->archive, &entry->ae_hardlink, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -511,6 +528,8 @@ archive_entry_pathname(struct archive_entry *entry)
if (archive_mstring_get_mbs( if (archive_mstring_get_mbs(
entry->archive, &entry->ae_pathname, &p) == 0) entry->archive, &entry->ae_pathname, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -521,6 +540,8 @@ archive_entry_pathname_w(struct archive_entry *entry)
if (archive_mstring_get_wcs( if (archive_mstring_get_wcs(
entry->archive, &entry->ae_pathname, &p) == 0) entry->archive, &entry->ae_pathname, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -584,6 +605,8 @@ archive_entry_sourcepath(struct archive_entry *entry)
if (archive_mstring_get_mbs( if (archive_mstring_get_mbs(
entry->archive, &entry->ae_sourcepath, &p) == 0) entry->archive, &entry->ae_sourcepath, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -601,9 +624,13 @@ const char *
archive_entry_symlink(struct archive_entry *entry) archive_entry_symlink(struct archive_entry *entry)
{ {
const char *p; const char *p;
if ((entry->ae_set & AE_SET_SYMLINK) && archive_mstring_get_mbs( if ((entry->ae_set & AE_SET_SYMLINK) == 0)
return (NULL);
if (archive_mstring_get_mbs(
entry->archive, &entry->ae_symlink, &p) == 0) entry->archive, &entry->ae_symlink, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -611,9 +638,13 @@ const wchar_t *
archive_entry_symlink_w(struct archive_entry *entry) archive_entry_symlink_w(struct archive_entry *entry)
{ {
const wchar_t *p; const wchar_t *p;
if ((entry->ae_set & AE_SET_SYMLINK) && archive_mstring_get_wcs( if ((entry->ae_set & AE_SET_SYMLINK) == 0)
return (NULL);
if (archive_mstring_get_wcs(
entry->archive, &entry->ae_symlink, &p) == 0) entry->archive, &entry->ae_symlink, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -641,6 +672,8 @@ archive_entry_uname(struct archive_entry *entry)
const char *p; const char *p;
if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0) if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -650,6 +683,8 @@ archive_entry_uname_w(struct archive_entry *entry)
const wchar_t *p; const wchar_t *p;
if (archive_mstring_get_wcs(entry->archive, &entry->ae_uname, &p) == 0) if (archive_mstring_get_wcs(entry->archive, &entry->ae_uname, &p) == 0)
return (p); return (p);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL); return (NULL);
} }
@ -730,6 +765,8 @@ archive_entry_update_gname_utf8(struct archive_entry *entry, const char *name)
if (archive_mstring_update_utf8(entry->archive, if (archive_mstring_update_utf8(entry->archive,
&entry->ae_gname, name) == 0) &entry->ae_gname, name) == 0)
return (1); return (1);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (0); return (0);
} }
@ -796,6 +833,8 @@ archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *targ
if (archive_mstring_update_utf8(entry->archive, if (archive_mstring_update_utf8(entry->archive,
&entry->ae_hardlink, target) == 0) &entry->ae_hardlink, target) == 0)
return (1); return (1);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (0); return (0);
} }
@ -932,7 +971,11 @@ archive_entry_update_link_utf8(struct archive_entry *entry, const char *target)
else else
r = archive_mstring_update_utf8(entry->archive, r = archive_mstring_update_utf8(entry->archive,
&entry->ae_hardlink, target); &entry->ae_hardlink, target);
return ((r == 0)? 1: 0); if (r == 0)
return (1);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (0);
} }
int int
@ -1005,6 +1048,8 @@ archive_entry_update_pathname_utf8(struct archive_entry *entry, const char *name
if (archive_mstring_update_utf8(entry->archive, if (archive_mstring_update_utf8(entry->archive,
&entry->ae_pathname, name) == 0) &entry->ae_pathname, name) == 0)
return (1); return (1);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (0); return (0);
} }
@ -1115,6 +1160,8 @@ archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkn
if (archive_mstring_update_utf8(entry->archive, if (archive_mstring_update_utf8(entry->archive,
&entry->ae_symlink, linkname) == 0) &entry->ae_symlink, linkname) == 0)
return (1); return (1);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (0); return (0);
} }
@ -1164,6 +1211,8 @@ archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
if (archive_mstring_update_utf8(entry->archive, if (archive_mstring_update_utf8(entry->archive,
&entry->ae_uname, name) == 0) &entry->ae_uname, name) == 0)
return (1); return (1);
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (0); return (0);
} }
@ -1269,7 +1318,12 @@ int
archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type, archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type,
int *permset, int *tag, int *id, const char **name) int *permset, int *tag, int *id, const char **name)
{ {
return archive_acl_next(entry->archive, &entry->acl, want_type, type, permset, tag, id, name); int r;
r = archive_acl_next(entry->archive, &entry->acl, want_type, type,
permset, tag, id, name);
if (r == ARCHIVE_FATAL && errno == ENOMEM)
__archive_errx(1, "No memory");
return (r);
} }
/* /*
@ -1279,7 +1333,11 @@ archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type,
const wchar_t * const wchar_t *
archive_entry_acl_text_w(struct archive_entry *entry, int flags) archive_entry_acl_text_w(struct archive_entry *entry, int flags)
{ {
return archive_acl_text_w(entry->archive, &entry->acl, flags); const wchar_t *r;
r = archive_acl_text_w(entry->archive, &entry->acl, flags);
if (r == NULL && errno == ENOMEM)
__archive_errx(1, "No memory");
return (r);
} }
const char * const char *
@ -1288,7 +1346,7 @@ archive_entry_acl_text(struct archive_entry *entry, int flags)
const char *p; const char *p;
if (archive_acl_text_l(&entry->acl, flags, &p, NULL, NULL) != 0 if (archive_acl_text_l(&entry->acl, flags, &p, NULL, NULL) != 0
&& errno == ENOMEM) && errno == ENOMEM)
return (NULL); __archive_errx(1, "No memory");
return (p); return (p);
} }

View File

@ -29,7 +29,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED #define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */ /* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3000003 #define ARCHIVE_VERSION_NUMBER 3000004
/* /*
* Note: archive_entry.h is for use outside of libarchive; the * Note: archive_entry.h is for use outside of libarchive; the
@ -47,21 +47,9 @@
#include <windows.h> #include <windows.h>
#endif #endif
/* Get appropriate definitions of standard POSIX-style types. */ /* Get a suitable 64-bit integer type. */
/* These should match the types used in 'struct stat' */
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
#define __LA_INT64_T __int64 # define __LA_INT64_T __int64
# if defined(__BORLANDC__)
# define __LA_UID_T uid_t /* Remove in libarchive 3.2 */
# define __LA_GID_T gid_t /* Remove in libarchive 3.2 */
# define __LA_DEV_T dev_t
# define __LA_MODE_T mode_t
# else
# define __LA_UID_T short /* Remove in libarchive 3.2 */
# define __LA_GID_T short /* Remove in libarchive 3.2 */
# define __LA_DEV_T unsigned int
# define __LA_MODE_T unsigned short
# endif
#else #else
#include <unistd.h> #include <unistd.h>
# if defined(_SCO_DS) # if defined(_SCO_DS)
@ -69,17 +57,17 @@
# else # else
# define __LA_INT64_T int64_t # define __LA_INT64_T int64_t
# endif # endif
# define __LA_UID_T uid_t /* Remove in libarchive 3.2 */
# define __LA_GID_T gid_t /* Remove in libarchive 3.2 */
# define __LA_DEV_T dev_t
# define __LA_MODE_T mode_t
#endif #endif
/* /* Get a suitable definition for mode_t */
* Remove this for libarchive 3.2, since ino_t is no longer used. #if ARCHIVE_VERSION_NUMBER >= 3999000
*/ /* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
#define __LA_INO_T ino_t # define __LA_MODE_T int
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__)
# define __LA_MODE_T unsigned short
#else
# define __LA_MODE_T mode_t
#endif
/* /*
* On Windows, define LIBARCHIVE_STATIC if you're building or using a * On Windows, define LIBARCHIVE_STATIC if you're building or using a
@ -149,14 +137,18 @@ struct archive_entry;
* portable values to platform-native values when entries are read from * portable values to platform-native values when entries are read from
* or written to disk. * or written to disk.
*/ */
#define AE_IFMT 0170000 /*
#define AE_IFREG 0100000 * In libarchive 4.0, we can drop the casts here.
#define AE_IFLNK 0120000 * They're needed to work around Borland C's broken mode_t.
#define AE_IFSOCK 0140000 */
#define AE_IFCHR 0020000 #define AE_IFMT ((__LA_MODE_T)0170000)
#define AE_IFBLK 0060000 #define AE_IFREG ((__LA_MODE_T)0100000)
#define AE_IFDIR 0040000 #define AE_IFLNK ((__LA_MODE_T)0120000)
#define AE_IFIFO 0010000 #define AE_IFSOCK ((__LA_MODE_T)0140000)
#define AE_IFCHR ((__LA_MODE_T)0020000)
#define AE_IFBLK ((__LA_MODE_T)0060000)
#define AE_IFDIR ((__LA_MODE_T)0040000)
#define AE_IFIFO ((__LA_MODE_T)0010000)
/* /*
* Basic object manipulation * Basic object manipulation
@ -321,7 +313,10 @@ __LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char
* manipulate archives on systems different than the ones they were * manipulate archives on systems different than the ones they were
* created on. * created on.
* *
* TODO: On Linux, provide both stat32 and stat64 versions of these functions. * TODO: On Linux and other LFS systems, provide both stat32 and
* stat64 versions of these functions and all of the macro glue so
* that archive_entry_stat is magically defined to
* archive_entry_stat32 or archive_entry_stat64 as appropriate.
*/ */
__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *); __LA_DECL const struct stat *archive_entry_stat(struct archive_entry *);
__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *); __LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *);

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd February 21, 2010 .Dd February 2, 2012
.Dt ARCHIVE_ENTRY_ACL 3 .Dt ARCHIVE_ENTRY_ACL 3
.Os .Os
.Sh NAME .Sh NAME
@ -35,6 +35,8 @@
.Nm archive_entry_acl_reset , .Nm archive_entry_acl_reset ,
.Nm archive_entry_acl_text_w .Nm archive_entry_acl_text_w
.Nd functions for manipulating Access Control Lists in archive entry descriptions .Nd functions for manipulating Access Control Lists in archive entry descriptions
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive_entry.h .In archive_entry.h
.Ft void .Ft void

View File

@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$");
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
__inline static void __inline static void
fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns) fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
{ {
ULARGE_INTEGER utc; ULARGE_INTEGER utc;
@ -42,10 +42,10 @@ fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns)
utc.LowPart = filetime->dwLowDateTime; utc.LowPart = filetime->dwLowDateTime;
if (utc.QuadPart >= EPOC_TIME) { if (utc.QuadPart >= EPOC_TIME) {
utc.QuadPart -= EPOC_TIME; utc.QuadPart -= EPOC_TIME;
*time = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */ *t = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
*ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */ *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
} else { } else {
*time = 0; *t = 0;
*ns = 0; *ns = 0;
} }
} }

View File

@ -362,7 +362,7 @@ insert_entry(struct archive_entry_linkresolver *res,
if (res->number_entries > res->number_buckets * 2) if (res->number_entries > res->number_buckets * 2)
grow_hash(res); grow_hash(res);
hash = archive_entry_dev(entry) ^ archive_entry_ino64(entry); hash = (size_t)(archive_entry_dev(entry) ^ archive_entry_ino64(entry));
bucket = hash & (res->number_buckets - 1); bucket = hash & (res->number_buckets - 1);
/* If we could allocate the entry, record it. */ /* If we could allocate the entry, record it. */

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd February 20, 2010 .Dd February 2, 2012
.Dt ARCHIVE_ENTRY_LINKIFY 3 .Dt ARCHIVE_ENTRY_LINKIFY 3
.Os .Os
.Sh NAME .Sh NAME
@ -33,7 +33,7 @@
.Nm archive_entry_linkify .Nm archive_entry_linkify
.Nd hardlink resolver functions .Nd hardlink resolver functions
.Sh LIBRARY .Sh LIBRARY
.Lb libarchive Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive_entry.h .In archive_entry.h
.Ft struct archive_entry_linkresolver * .Ft struct archive_entry_linkresolver *

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd February 22, 2010 .Dd February 2, 2012
.Dt ARCHIVE_ENTRY_PATHS 3 .Dt ARCHIVE_ENTRY_PATHS 3
.Os .Os
.Sh NAME .Sh NAME
@ -51,6 +51,8 @@
.Nm archive_entry_copy_symlink_w , .Nm archive_entry_copy_symlink_w ,
.Nm archve_entry_update_symlink_utf8 .Nm archve_entry_update_symlink_utf8
.Nd functions for manipulating path names in archive entry descriptions .Nd functions for manipulating path names in archive entry descriptions
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive_entry.h .In archive_entry.h
.Ft const char * .Ft const char *

View File

@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd February 22, 2010 .Dd February 2, 2012
.Dt ARCHIVE_ENTRY_PERMS 3 .Dt ARCHIVE_ENTRY_PERMS 3
.Os .Os
.Sh NAME .Sh NAME
@ -52,6 +52,8 @@
.Nm archive_entry_copy_fflags_text , .Nm archive_entry_copy_fflags_text ,
.Nm archive_entry_copy_fflags_text_w .Nm archive_entry_copy_fflags_text_w
.Nd functions for manipulating ownership and permissions in archive entry descriptions .Nd functions for manipulating ownership and permissions in archive entry descriptions
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive_entry.h .In archive_entry.h
.Ft gid_t .Ft gid_t

View File

@ -22,8 +22,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd May 12, 2008 .Dd February 2, 2012
.Dt ARCHIVE_ENTRY 3 .Dt ARCHIVE_ENTRY_STAT 3
.Os .Os
.Sh NAME .Sh NAME
.Nm archive_entry_stat , .Nm archive_entry_stat ,
@ -56,6 +56,8 @@
.Nm archive_entry_rdevminor , .Nm archive_entry_rdevminor ,
.Nm archive_entry_set_rdevminor , .Nm archive_entry_set_rdevminor ,
.Nd accessor functions for manipulating archive entry descriptions .Nd accessor functions for manipulating archive entry descriptions
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive_entry.h .In archive_entry.h
.Ft const struct stat * .Ft const struct stat *

View File

@ -70,12 +70,12 @@ archive_entry_stat(struct archive_entry *entry)
st->st_ctime = archive_entry_ctime(entry); st->st_ctime = archive_entry_ctime(entry);
st->st_mtime = archive_entry_mtime(entry); st->st_mtime = archive_entry_mtime(entry);
st->st_dev = archive_entry_dev(entry); st->st_dev = archive_entry_dev(entry);
st->st_gid = archive_entry_gid(entry); st->st_gid = (gid_t)archive_entry_gid(entry);
st->st_uid = archive_entry_uid(entry); st->st_uid = (uid_t)archive_entry_uid(entry);
st->st_ino = archive_entry_ino64(entry); st->st_ino = (ino_t)archive_entry_ino64(entry);
st->st_nlink = archive_entry_nlink(entry); st->st_nlink = archive_entry_nlink(entry);
st->st_rdev = archive_entry_rdev(entry); st->st_rdev = archive_entry_rdev(entry);
st->st_size = archive_entry_size(entry); st->st_size = (off_t)archive_entry_size(entry);
st->st_mode = archive_entry_mode(entry); st->st_mode = archive_entry_mode(entry);
/* /*

View File

@ -23,9 +23,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $ .\" $FreeBSD$
.\" .\"
.Dd February 21, 2010 .Dd February 2, 2012
.Dt ARCHIVE_ENTRY_TIME 3 .Dt ARCHIVE_ENTRY_TIME 3
.Os .Os
.Sh NAME .Sh NAME
@ -50,6 +50,8 @@
.Nm archive_entry_set_mtime , .Nm archive_entry_set_mtime ,
.Nm archive_entry_unset_mtime , .Nm archive_entry_unset_mtime ,
.Nd functions for manipulating times in archive entry descriptions .Nd functions for manipulating times in archive entry descriptions
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive_entry.h .In archive_entry.h
.Ft time_t .Ft time_t

View File

@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
#include <time.h> #include <time.h>
/* This file defines a single public function. */ /* This file defines a single public function. */
time_t get_date(time_t now, char *); time_t __archive_get_date(time_t now, char *);
/* Basic time units. */ /* Basic time units. */
#define EPOCH 1970 #define EPOCH 1970
@ -894,7 +894,7 @@ difftm (struct tm *a, struct tm *b)
* TODO: tokens[] array should be dynamically sized. * TODO: tokens[] array should be dynamically sized.
*/ */
time_t time_t
get_date(time_t now, char *p) __archive_get_date(time_t now, char *p)
{ {
struct token tokens[256]; struct token tokens[256];
struct gdstate _gds; struct gdstate _gds;

1836
libarchive/archive_match.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -24,14 +24,17 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "lafe_platform.h" #include "archive_platform.h"
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#ifdef HAVE_STRING_H #ifdef HAVE_STRING_H
#include <string.h> #include <string.h>
#endif #endif
#ifdef HAVE_WCHAR_H
#include <wchar.h>
#endif
#include "pathmatch.h" #include "archive_pathmatch.h"
/* /*
* Check whether a character 'c' is matched by a list specification [...]: * Check whether a character 'c' is matched by a list specification [...]:
@ -96,6 +99,53 @@ pm_list(const char *start, const char *end, const char c, int flags)
return (nomatch); return (nomatch);
} }
static int
pm_list_w(const wchar_t *start, const wchar_t *end, const wchar_t c, int flags)
{
const wchar_t *p = start;
wchar_t rangeStart = L'\0', nextRangeStart;
int match = 1, nomatch = 0;
/* This will be used soon... */
(void)flags; /* UNUSED */
/* If this is a negated class, return success for nomatch. */
if ((*p == L'!' || *p == L'^') && p < end) {
match = 0;
nomatch = 1;
++p;
}
while (p < end) {
nextRangeStart = L'\0';
switch (*p) {
case L'-':
/* Trailing or initial '-' is not special. */
if ((rangeStart == L'\0') || (p == end - 1)) {
if (*p == c)
return (match);
} else {
wchar_t rangeEnd = *++p;
if (rangeEnd == L'\\')
rangeEnd = *++p;
if ((rangeStart <= c) && (c <= rangeEnd))
return (match);
}
break;
case L'\\':
++p;
/* Fall through */
default:
if (*p == c)
return (match);
nextRangeStart = *p; /* Possible start of range. */
}
rangeStart = nextRangeStart;
++p;
}
return (nomatch);
}
/* /*
* If s is pointing to "./", ".//", "./././" or the like, skip it. * If s is pointing to "./", ".//", "./././" or the like, skip it.
*/ */
@ -108,6 +158,15 @@ pm_slashskip(const char *s) {
return (s); return (s);
} }
static const wchar_t *
pm_slashskip_w(const wchar_t *s) {
while ((*s == L'/')
|| (s[0] == L'.' && s[1] == L'/')
|| (s[0] == L'.' && s[1] == L'\0'))
++s;
return (s);
}
static int static int
pm(const char *p, const char *s, int flags) pm(const char *p, const char *s, int flags)
{ {
@ -144,7 +203,7 @@ pm(const char *p, const char *s, int flags)
if (*p == '\0') if (*p == '\0')
return (1); return (1);
while (*s) { while (*s) {
if (lafe_pathmatch(p, s, flags)) if (archive_pathmatch(p, s, flags))
return (1); return (1);
++s; ++s;
} }
@ -213,9 +272,114 @@ pm(const char *p, const char *s, int flags)
} }
} }
static int
pm_w(const wchar_t *p, const wchar_t *s, int flags)
{
const wchar_t *end;
/*
* Ignore leading './', './/', '././', etc.
*/
if (s[0] == L'.' && s[1] == L'/')
s = pm_slashskip_w(s + 1);
if (p[0] == L'.' && p[1] == L'/')
p = pm_slashskip_w(p + 1);
for (;;) {
switch (*p) {
case L'\0':
if (s[0] == L'/') {
if (flags & PATHMATCH_NO_ANCHOR_END)
return (1);
/* "dir" == "dir/" == "dir/." */
s = pm_slashskip_w(s);
}
return (*s == L'\0');
case L'?':
/* ? always succeeds, unless we hit end of 's' */
if (*s == L'\0')
return (0);
break;
case L'*':
/* "*" == "**" == "***" ... */
while (*p == L'*')
++p;
/* Trailing '*' always succeeds. */
if (*p == L'\0')
return (1);
while (*s) {
if (archive_pathmatch_w(p, s, flags))
return (1);
++s;
}
return (0);
case L'[':
/*
* Find the end of the [...] character class,
* ignoring \] that might occur within the class.
*/
end = p + 1;
while (*end != L'\0' && *end != L']') {
if (*end == L'\\' && end[1] != L'\0')
++end;
++end;
}
if (*end == L']') {
/* We found [...], try to match it. */
if (!pm_list_w(p + 1, end, *s, flags))
return (0);
p = end; /* Jump to trailing ']' char. */
break;
} else
/* No final ']', so just match '['. */
if (*p != *s)
return (0);
break;
case L'\\':
/* Trailing '\\' matches itself. */
if (p[1] == L'\0') {
if (*s != L'\\')
return (0);
} else {
++p;
if (*p != *s)
return (0);
}
break;
case L'/':
if (*s != L'/' && *s != L'\0')
return (0);
/* Note: pattern "/\./" won't match "/";
* pm_slashskip() correctly stops at backslash. */
p = pm_slashskip_w(p);
s = pm_slashskip_w(s);
if (*p == L'\0' && (flags & PATHMATCH_NO_ANCHOR_END))
return (1);
--p; /* Counteract the increment below. */
--s;
break;
case L'$':
/* '$' is special only at end of pattern and only
* if PATHMATCH_NO_ANCHOR_END is specified. */
if (p[1] == L'\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
/* "dir" == "dir/" == "dir/." */
return (*pm_slashskip_w(s) == L'\0');
}
/* Otherwise, '$' is not special. */
/* FALL THROUGH */
default:
if (*p != *s)
return (0);
break;
}
++p;
++s;
}
}
/* Main entry point. */ /* Main entry point. */
int int
lafe_pathmatch(const char *p, const char *s, int flags) __archive_pathmatch(const char *p, const char *s, int flags)
{ {
/* Empty pattern only matches the empty string. */ /* Empty pattern only matches the empty string. */
if (p == NULL || *p == '\0') if (p == NULL || *p == '\0')
@ -253,3 +417,43 @@ lafe_pathmatch(const char *p, const char *s, int flags)
/* Default: Match from beginning. */ /* Default: Match from beginning. */
return (pm(p, s, flags)); return (pm(p, s, flags));
} }
int
__archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags)
{
/* Empty pattern only matches the empty string. */
if (p == NULL || *p == L'\0')
return (s == NULL || *s == L'\0');
/* Leading '^' anchors the start of the pattern. */
if (*p == L'^') {
++p;
flags &= ~PATHMATCH_NO_ANCHOR_START;
}
if (*p == L'/' && *s != L'/')
return (0);
/* Certain patterns and file names anchor implicitly. */
if (*p == L'*' || *p == L'/' || *p == L'/') {
while (*p == L'/')
++p;
while (*s == L'/')
++s;
return (pm_w(p, s, flags));
}
/* If start is unanchored, try to match start of each path element. */
if (flags & PATHMATCH_NO_ANCHOR_START) {
for ( ; s != NULL; s = wcschr(s, L'/')) {
if (*s == L'/')
s++;
if (pm_w(p, s, flags))
return (1);
}
return (0);
}
/* Default: Match from beginning. */
return (pm_w(p, s, flags));
}

View File

@ -26,8 +26,14 @@
* $FreeBSD$ * $FreeBSD$
*/ */
#ifndef LAFE_PATHMATCH_H #ifndef __LIBARCHIVE_BUILD
#define LAFE_PATHMATCH_H #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 "^" */ /* Don't anchor at beginning unless the pattern starts with "^" */
#define PATHMATCH_NO_ANCHOR_START 1 #define PATHMATCH_NO_ANCHOR_START 1
@ -37,6 +43,10 @@
/* Note that "^" and "$" are not special unless you set the corresponding /* Note that "^" and "$" are not special unless you set the corresponding
* flag above. */ * flag above. */
int lafe_pathmatch(const char *p, const char *s, int flags); int __archive_pathmatch(const char *p, const char *s, int flags);
int __archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags);
#define archive_pathmatch(p, s, f) __archive_pathmatch(p, s, f)
#define archive_pathmatch_w(p, s, f) __archive_pathmatch_w(p, s, f)
#endif #endif

View File

@ -415,7 +415,7 @@ static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)))); upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
} }
do while (numPs != 0)
{ {
/* Create Child */ /* Create Child */
CTX_PTR c1; /* = AllocContext(p); */ CTX_PTR c1; /* = AllocContext(p); */
@ -435,7 +435,6 @@ static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
SetSuccessor(ps[--numPs], REF(c1)); SetSuccessor(ps[--numPs], REF(c1));
c = c1; c = c1;
} }
while (numPs != 0);
return c; return c;
} }
@ -778,7 +777,7 @@ static void Range_Normalize(CPpmd7z_RangeDec *p)
if(p->Range >= p->Bottom) if(p->Range >= p->Bottom)
break; break;
else else
p->Range = -p->Low & (p->Bottom - 1); p->Range = ((uint32_t)(-(int32_t)p->Low)) & (p->Bottom - 1);
} }
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
p->Range <<= 8; p->Range <<= 8;

View File

@ -50,6 +50,7 @@
#define ARCHIVE_READ_MAGIC (0xdeb0c5U) #define ARCHIVE_READ_MAGIC (0xdeb0c5U)
#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U) #define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U)
#define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U) #define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U)
#define ARCHIVE_MATCH_MAGIC (0xcad11c9U)
#define ARCHIVE_STATE_NEW 1U #define ARCHIVE_STATE_NEW 1U
#define ARCHIVE_STATE_HEADER 2U #define ARCHIVE_STATE_HEADER 2U

View File

@ -22,14 +22,16 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $ .\" $FreeBSD$
.\" .\"
.Dd March 23, 2011 .Dd February 2, 2012
.Dt ARCHIVE_READ 3 .Dt ARCHIVE_READ 3
.Os .Os
.Sh NAME .Sh NAME
.Nm archive_read .Nm archive_read
.Nd functions for reading streaming archives .Nd functions for reading streaming archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Sh DESCRIPTION .Sh DESCRIPTION

View File

@ -201,7 +201,6 @@ client_skip_proxy(struct archive_read_filter *self, int64_t request)
request -= get; request -= get;
total += get; total += get;
} }
return total;
} else if (self->archive->client.seeker != NULL } else if (self->archive->client.seeker != NULL
&& request > 64 * 1024) { && request > 64 * 1024) {
/* If the client provided a seeker but not a skipper, /* If the client provided a seeker but not a skipper,
@ -638,8 +637,8 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
len = s; len = s;
} else if (a->read_data_output_offset < } else if (a->read_data_output_offset <
a->read_data_offset) { a->read_data_offset) {
len = a->read_data_offset - len = (size_t)(a->read_data_offset -
a->read_data_output_offset; a->read_data_output_offset);
} else } else
len = 0; len = 0;
@ -1231,7 +1230,7 @@ advance_file_pointer(struct archive_read_filter *filter, int64_t request)
/* Use up the copy buffer first. */ /* Use up the copy buffer first. */
if (filter->avail > 0) { if (filter->avail > 0) {
min = minimum(request, (int64_t)filter->avail); min = (size_t)minimum(request, (int64_t)filter->avail);
filter->next += min; filter->next += min;
filter->avail -= min; filter->avail -= min;
request -= min; request -= min;
@ -1241,7 +1240,7 @@ advance_file_pointer(struct archive_read_filter *filter, int64_t request)
/* Then use up the client buffer. */ /* Then use up the client buffer. */
if (filter->client_avail > 0) { if (filter->client_avail > 0) {
min = minimum(request, (int64_t)filter->client_avail); min = (size_t)minimum(request, (int64_t)filter->client_avail);
filter->client_next += min; filter->client_next += min;
filter->client_avail -= min; filter->client_avail -= min;
request -= min; request -= min;
@ -1283,7 +1282,7 @@ advance_file_pointer(struct archive_read_filter *filter, int64_t request)
if (bytes_read >= request) { if (bytes_read >= request) {
filter->client_next = filter->client_next =
((const char *)filter->client_buff) + request; ((const char *)filter->client_buff) + request;
filter->client_avail = bytes_read - request; filter->client_avail = (size_t)(bytes_read - request);
filter->client_total = bytes_read; filter->client_total = bytes_read;
total_bytes_skipped += request; total_bytes_skipped += request;
filter->position += request; filter->position += request;

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 22, 2011 .Dd February 2, 2012
.Dt ARCHIVE_READ_DATA 3 .Dt ARCHIVE_READ_DATA 3
.Os .Os
.Sh NAME .Sh NAME
@ -33,6 +33,8 @@
.Nm archive_read_data_skip , .Nm archive_read_data_skip ,
.Nm archive_read_data_into_fd .Nm archive_read_data_into_fd
.Nd functions for reading streaming archives .Nd functions for reading streaming archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft ssize_t .Ft ssize_t

View File

@ -22,9 +22,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: head/lib/libarchive/archive_read_disk.3 190957 2009-04-12 05:04:02Z kientzle $ .\" $FreeBSD$
.\" .\"
.Dd March 10, 2009 .Dd February 2, 2012
.Dt ARCHIVE_READ_DISK 3 .Dt ARCHIVE_READ_DISK 3
.Os .Os
.Sh NAME .Sh NAME
@ -42,6 +42,8 @@
.Nm archive_read_finish , .Nm archive_read_finish ,
.Nm archive_read_free .Nm archive_read_free
.Nd functions for reading objects from disk .Nd functions for reading objects from disk
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft struct archive * .Ft struct archive *

View File

@ -1,6 +1,6 @@
/*- /*-
* Copyright (c) 2003-2009 Tim Kientzle * Copyright (c) 2003-2009 Tim Kientzle
* Copyright (c) 2010 Michihiro NAKAJIMA * Copyright (c) 2010-2012 Michihiro NAKAJIMA
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -73,6 +73,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
#ifdef HAVE_LIMITS_H #ifdef HAVE_LIMITS_H
#include <limits.h> #include <limits.h>
#endif #endif
#ifdef HAVE_LINUX_TYPES_H
#include <linux/types.h>
#endif
#ifdef HAVE_LINUX_FIEMAP_H #ifdef HAVE_LINUX_FIEMAP_H
#include <linux/fiemap.h> #include <linux/fiemap.h>
#endif #endif
@ -112,13 +115,13 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
#endif #endif
static int setup_acls_posix1e(struct archive_read_disk *, static int setup_acls_posix1e(struct archive_read_disk *,
struct archive_entry *, int fd); struct archive_entry *, int *fd);
static int setup_mac_metadata(struct archive_read_disk *, static int setup_mac_metadata(struct archive_read_disk *,
struct archive_entry *, int fd); struct archive_entry *, int *fd);
static int setup_xattrs(struct archive_read_disk *, static int setup_xattrs(struct archive_read_disk *,
struct archive_entry *, int fd); struct archive_entry *, int *fd);
static int setup_sparse(struct archive_read_disk *, static int setup_sparse(struct archive_read_disk *,
struct archive_entry *, int fd); struct archive_entry *, int *fd);
int int
archive_read_disk_entry_from_file(struct archive *_a, archive_read_disk_entry_from_file(struct archive *_a,
@ -165,16 +168,15 @@ archive_read_disk_entry_from_file(struct archive *_a,
st = &s; st = &s;
} }
archive_entry_copy_stat(entry, st); archive_entry_copy_stat(entry, st);
/* Lookup uname/gname */
name = archive_read_disk_uname(_a, archive_entry_uid(entry));
if (name != NULL)
archive_entry_copy_uname(entry, name);
name = archive_read_disk_gname(_a, archive_entry_gid(entry));
if (name != NULL)
archive_entry_copy_gname(entry, name);
} }
/* Lookup uname/gname */
name = archive_read_disk_uname(_a, archive_entry_uid(entry));
if (name != NULL)
archive_entry_copy_uname(entry, name);
name = archive_read_disk_gname(_a, archive_entry_gid(entry));
if (name != NULL)
archive_entry_copy_gname(entry, name);
#ifdef HAVE_STRUCT_STAT_ST_FLAGS #ifdef HAVE_STRUCT_STAT_ST_FLAGS
/* On FreeBSD, we get flags for free with the stat. */ /* On FreeBSD, we get flags for free with the stat. */
/* TODO: Does this belong in copy_stat()? */ /* TODO: Does this belong in copy_stat()? */
@ -187,8 +189,13 @@ archive_read_disk_entry_from_file(struct archive *_a,
* this is an extra step, it has a nice side-effect: We get an * this is an extra step, it has a nice side-effect: We get an
* open file descriptor which we can use in the subsequent lookups. */ * open file descriptor which we can use in the subsequent lookups. */
if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) { if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
if (fd < 0) if (fd < 0) {
fd = open(path, O_RDONLY | O_NONBLOCK); if (a->tree != NULL)
fd = a->open_on_current_dir(a->tree, path,
O_RDONLY | O_NONBLOCK);
else
fd = open(path, O_RDONLY | O_NONBLOCK);
}
if (fd >= 0) { if (fd >= 0) {
unsigned long stflags; unsigned long stflags;
r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags); r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
@ -210,13 +217,21 @@ archive_read_disk_entry_from_file(struct archive *_a,
"Couldn't read link data"); "Couldn't read link data");
return (ARCHIVE_FAILED); return (ARCHIVE_FAILED);
} }
if (a->tree != NULL) {
#ifdef HAVE_READLINKAT #ifdef HAVE_READLINKAT
if (a->entry_wd_fd >= 0) lnklen = readlinkat(a->tree_current_dir_fd(a->tree),
lnklen = readlinkat(a->entry_wd_fd, path, path, linkbuffer, linkbuffer_len);
linkbuffer, linkbuffer_len); #else
else if (a->tree_enter_working_dir(a->tree) != 0) {
archive_set_error(&a->archive, errno,
"Couldn't read link data");
free(linkbuffer);
return (ARCHIVE_FAILED);
}
lnklen = readlink(path, linkbuffer, linkbuffer_len);
#endif /* HAVE_READLINKAT */ #endif /* HAVE_READLINKAT */
lnklen = readlink(path, linkbuffer, linkbuffer_len); } else
lnklen = readlink(path, linkbuffer, linkbuffer_len);
if (lnklen < 0) { if (lnklen < 0) {
archive_set_error(&a->archive, errno, archive_set_error(&a->archive, errno,
"Couldn't read link data"); "Couldn't read link data");
@ -229,14 +244,16 @@ archive_read_disk_entry_from_file(struct archive *_a,
} }
#endif /* HAVE_READLINK || HAVE_READLINKAT */ #endif /* HAVE_READLINK || HAVE_READLINKAT */
r = setup_acls_posix1e(a, entry, fd); r = setup_acls_posix1e(a, entry, &fd);
r1 = setup_xattrs(a, entry, fd); r1 = setup_xattrs(a, entry, &fd);
if (r1 < r) if (r1 < r)
r = r1; r = r1;
r1 = setup_mac_metadata(a, entry, fd); if (a->enable_copyfile) {
if (r1 < r) r1 = setup_mac_metadata(a, entry, &fd);
r = r1; if (r1 < r)
r1 = setup_sparse(a, entry, fd); r = r1;
}
r1 = setup_sparse(a, entry, &fd);
if (r1 < r) if (r1 < r)
r = r1; r = r1;
@ -262,7 +279,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
*/ */
static int static int
setup_mac_metadata(struct archive_read_disk *a, setup_mac_metadata(struct archive_read_disk *a,
struct archive_entry *entry, int fd) struct archive_entry *entry, int *fd)
{ {
int tempfd = -1; int tempfd = -1;
int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR; int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR;
@ -272,6 +289,7 @@ setup_mac_metadata(struct archive_read_disk *a,
int have_attrs; int have_attrs;
const char *name, *tempdir, *tempfile = NULL; const char *name, *tempdir, *tempfile = NULL;
(void)fd; /* UNUSED */
name = archive_entry_sourcepath(entry); name = archive_entry_sourcepath(entry);
if (name == NULL) if (name == NULL)
name = archive_entry_pathname(entry); name = archive_entry_pathname(entry);
@ -281,6 +299,14 @@ setup_mac_metadata(struct archive_read_disk *a,
return (ARCHIVE_WARN); return (ARCHIVE_WARN);
} }
if (a->tree != NULL) {
if (a->tree_enter_working_dir(a->tree) != 0) {
archive_set_error(&a->archive, errno,
"Couldn't change dir");
return (ARCHIVE_FAILED);
}
}
/* Short-circuit if there's nothing to do. */ /* Short-circuit if there's nothing to do. */
have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK); have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
if (have_attrs == -1) { if (have_attrs == -1) {
@ -351,7 +377,7 @@ cleanup:
*/ */
static int static int
setup_mac_metadata(struct archive_read_disk *a, setup_mac_metadata(struct archive_read_disk *a,
struct archive_entry *entry, int fd) struct archive_entry *entry, int *fd)
{ {
(void)a; /* UNUSED */ (void)a; /* UNUSED */
(void)entry; /* UNUSED */ (void)entry; /* UNUSED */
@ -367,7 +393,7 @@ static void setup_acl_posix1e(struct archive_read_disk *a,
static int static int
setup_acls_posix1e(struct archive_read_disk *a, setup_acls_posix1e(struct archive_read_disk *a,
struct archive_entry *entry, int fd) struct archive_entry *entry, int *fd)
{ {
const char *accpath; const char *accpath;
acl_t acl; acl_t acl;
@ -378,9 +404,20 @@ setup_acls_posix1e(struct archive_read_disk *a,
archive_entry_acl_clear(entry); archive_entry_acl_clear(entry);
if (*fd < 0 && a->tree != NULL &&
(a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)){
*fd = a->open_on_current_dir(a->tree, accpath,
O_RDONLY | O_NONBLOCK);
if (*fd < 0) {
archive_set_error(&a->archive, errno,
"Couldn't access %s", accpath);
return (ARCHIVE_FAILED);
}
}
/* Retrieve access ACL from file. */ /* Retrieve access ACL from file. */
if (fd >= 0) if (*fd >= 0)
acl = acl_get_fd(fd); acl = acl_get_fd(*fd);
#if HAVE_ACL_GET_LINK_NP #if HAVE_ACL_GET_LINK_NP
else if (!a->follow_symlinks) else if (!a->follow_symlinks)
acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS); acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
@ -474,7 +511,7 @@ setup_acl_posix1e(struct archive_read_disk *a,
#else #else
static int static int
setup_acls_posix1e(struct archive_read_disk *a, setup_acls_posix1e(struct archive_read_disk *a,
struct archive_entry *entry, int fd) struct archive_entry *entry, int *fd)
{ {
(void)a; /* UNUSED */ (void)a; /* UNUSED */
(void)entry; /* UNUSED */ (void)entry; /* UNUSED */
@ -568,7 +605,7 @@ setup_xattr(struct archive_read_disk *a,
static int static int
setup_xattrs(struct archive_read_disk *a, setup_xattrs(struct archive_read_disk *a,
struct archive_entry *entry, int fd) struct archive_entry *entry, int *fd)
{ {
char *list, *p; char *list, *p;
const char *path; const char *path;
@ -578,16 +615,30 @@ setup_xattrs(struct archive_read_disk *a,
if (path == NULL) if (path == NULL)
path = archive_entry_pathname(entry); path = archive_entry_pathname(entry);
if (*fd < 0 && a->tree != NULL) {
if (a->follow_symlinks ||
archive_entry_filetype(entry) != AE_IFLNK)
*fd = a->open_on_current_dir(a->tree, path,
O_RDONLY | O_NONBLOCK);
if (*fd < 0) {
if (a->tree_enter_working_dir(a->tree) != 0) {
archive_set_error(&a->archive, errno,
"Couldn't access %s", path);
return (ARCHIVE_FAILED);
}
}
}
#if HAVE_FLISTXATTR #if HAVE_FLISTXATTR
if (fd >= 0) if (*fd >= 0)
list_size = flistxattr(fd, NULL, 0); list_size = flistxattr(*fd, NULL, 0);
else if (!a->follow_symlinks) else if (!a->follow_symlinks)
list_size = llistxattr(path, NULL, 0); list_size = llistxattr(path, NULL, 0);
else else
list_size = listxattr(path, NULL, 0); list_size = listxattr(path, NULL, 0);
#elif HAVE_FLISTEA #elif HAVE_FLISTEA
if (fd >= 0) if (*fd >= 0)
list_size = flistea(fd, NULL, 0); list_size = flistea(*fd, NULL, 0);
else if (!a->follow_symlinks) else if (!a->follow_symlinks)
list_size = llistea(path, NULL, 0); list_size = llistea(path, NULL, 0);
else else
@ -611,15 +662,15 @@ setup_xattrs(struct archive_read_disk *a,
} }
#if HAVE_FLISTXATTR #if HAVE_FLISTXATTR
if (fd >= 0) if (*fd >= 0)
list_size = flistxattr(fd, list, list_size); list_size = flistxattr(*fd, list, list_size);
else if (!a->follow_symlinks) else if (!a->follow_symlinks)
list_size = llistxattr(path, list, list_size); list_size = llistxattr(path, list, list_size);
else else
list_size = listxattr(path, list, list_size); list_size = listxattr(path, list, list_size);
#elif HAVE_FLISTEA #elif HAVE_FLISTEA
if (fd >= 0) if (*fd >= 0)
list_size = flistea(fd, list, list_size); list_size = flistea(*fd, list, list_size);
else if (!a->follow_symlinks) else if (!a->follow_symlinks)
list_size = llistea(path, list, list_size); list_size = llistea(path, list, list_size);
else else
@ -637,7 +688,7 @@ setup_xattrs(struct archive_read_disk *a,
if (strncmp(p, "system.", 7) == 0 || if (strncmp(p, "system.", 7) == 0 ||
strncmp(p, "xfsroot.", 8) == 0) strncmp(p, "xfsroot.", 8) == 0)
continue; continue;
setup_xattr(a, entry, p, fd); setup_xattr(a, entry, p, *fd);
} }
free(list); free(list);
@ -698,6 +749,7 @@ setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
size = extattr_get_file(accpath, namespace, name, value, size); size = extattr_get_file(accpath, namespace, name, value, size);
if (size == -1) { if (size == -1) {
free(value);
archive_set_error(&a->archive, errno, archive_set_error(&a->archive, errno,
"Couldn't read extended attribute"); "Couldn't read extended attribute");
return (ARCHIVE_WARN); return (ARCHIVE_WARN);
@ -711,7 +763,7 @@ setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
static int static int
setup_xattrs(struct archive_read_disk *a, setup_xattrs(struct archive_read_disk *a,
struct archive_entry *entry, int fd) struct archive_entry *entry, int *fd)
{ {
char buff[512]; char buff[512];
char *list, *p; char *list, *p;
@ -723,8 +775,22 @@ setup_xattrs(struct archive_read_disk *a,
if (path == NULL) if (path == NULL)
path = archive_entry_pathname(entry); path = archive_entry_pathname(entry);
if (fd >= 0) if (*fd < 0 && a->tree != NULL) {
list_size = extattr_list_fd(fd, namespace, NULL, 0); if (a->follow_symlinks ||
archive_entry_filetype(entry) != AE_IFLNK)
*fd = a->open_on_current_dir(a->tree, path,
O_RDONLY | O_NONBLOCK);
if (*fd < 0) {
if (a->tree_enter_working_dir(a->tree) != 0) {
archive_set_error(&a->archive, errno,
"Couldn't access %s", path);
return (ARCHIVE_FAILED);
}
}
}
if (*fd >= 0)
list_size = extattr_list_fd(*fd, namespace, NULL, 0);
else if (!a->follow_symlinks) else if (!a->follow_symlinks)
list_size = extattr_list_link(path, namespace, NULL, 0); list_size = extattr_list_link(path, namespace, NULL, 0);
else else
@ -746,8 +812,8 @@ setup_xattrs(struct archive_read_disk *a,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if (fd >= 0) if (*fd >= 0)
list_size = extattr_list_fd(fd, namespace, list, list_size); list_size = extattr_list_fd(*fd, namespace, list, list_size);
else if (!a->follow_symlinks) else if (!a->follow_symlinks)
list_size = extattr_list_link(path, namespace, list, list_size); list_size = extattr_list_link(path, namespace, list, list_size);
else else
@ -769,7 +835,7 @@ setup_xattrs(struct archive_read_disk *a,
name = buff + strlen(buff); name = buff + strlen(buff);
memcpy(name, p + 1, len); memcpy(name, p + 1, len);
name[len] = '\0'; name[len] = '\0';
setup_xattr(a, entry, namespace, name, buff, fd); setup_xattr(a, entry, namespace, name, buff, *fd);
p += 1 + len; p += 1 + len;
} }
@ -784,7 +850,7 @@ setup_xattrs(struct archive_read_disk *a,
*/ */
static int static int
setup_xattrs(struct archive_read_disk *a, setup_xattrs(struct archive_read_disk *a,
struct archive_entry *entry, int fd) struct archive_entry *entry, int *fd)
{ {
(void)a; /* UNUSED */ (void)a; /* UNUSED */
(void)entry; /* UNUSED */ (void)entry; /* UNUSED */
@ -813,14 +879,13 @@ setup_xattrs(struct archive_read_disk *a,
static int static int
setup_sparse(struct archive_read_disk *a, setup_sparse(struct archive_read_disk *a,
struct archive_entry *entry, int fd) struct archive_entry *entry, int *fd)
{ {
char buff[4096]; char buff[4096];
struct fiemap *fm; struct fiemap *fm;
struct fiemap_extent *fe; struct fiemap_extent *fe;
int64_t size; int64_t size;
int count, do_fiemap; int count, do_fiemap;
int initial_fd = fd;
int exit_sts = ARCHIVE_OK; int exit_sts = ARCHIVE_OK;
if (archive_entry_filetype(entry) != AE_IFREG if (archive_entry_filetype(entry) != AE_IFREG
@ -828,14 +893,18 @@ setup_sparse(struct archive_read_disk *a,
|| archive_entry_hardlink(entry) != NULL) || archive_entry_hardlink(entry) != NULL)
return (ARCHIVE_OK); return (ARCHIVE_OK);
if (fd < 0) { if (*fd < 0) {
const char *path; const char *path;
path = archive_entry_sourcepath(entry); path = archive_entry_sourcepath(entry);
if (path == NULL) if (path == NULL)
path = archive_entry_pathname(entry); path = archive_entry_pathname(entry);
fd = open(path, O_RDONLY | O_NONBLOCK); if (a->tree != NULL)
if (fd < 0) { *fd = a->open_on_current_dir(a->tree, path,
O_RDONLY | O_NONBLOCK);
else
*fd = open(path, O_RDONLY | O_NONBLOCK);
if (*fd < 0) {
archive_set_error(&a->archive, errno, archive_set_error(&a->archive, errno,
"Can't open `%s'", path); "Can't open `%s'", path);
return (ARCHIVE_FAILED); return (ARCHIVE_FAILED);
@ -853,18 +922,11 @@ setup_sparse(struct archive_read_disk *a,
for (;;) { for (;;) {
int i, r; int i, r;
r = ioctl(fd, FS_IOC_FIEMAP, fm); r = ioctl(*fd, FS_IOC_FIEMAP, fm);
if (r < 0) { if (r < 0) {
/* When errno is ENOTTY, it is better we should /* When something error happens, it is better we
* return ARCHIVE_OK because an earlier version * should return ARCHIVE_OK because an earlier
*(<2.6.28) cannot perfom FS_IOC_FIEMAP. * version(<2.6.28) cannot perfom FS_IOC_FIEMAP. */
* We should also check if errno is EOPNOTSUPP,
* it means "Operation not supported". */
if (errno != ENOTTY && errno != EOPNOTSUPP) {
archive_set_error(&a->archive, errno,
"FIEMAP failed");
exit_sts = ARCHIVE_FAILED;
}
goto exit_setup_sparse; goto exit_setup_sparse;
} }
if (fm->fm_mapped_extents == 0) if (fm->fm_mapped_extents == 0)
@ -896,8 +958,6 @@ setup_sparse(struct archive_read_disk *a,
break; break;
} }
exit_setup_sparse: exit_setup_sparse:
if (initial_fd != fd)
close(fd);
return (exit_sts); return (exit_sts);
} }
@ -909,10 +969,9 @@ exit_setup_sparse:
static int static int
setup_sparse(struct archive_read_disk *a, setup_sparse(struct archive_read_disk *a,
struct archive_entry *entry, int fd) struct archive_entry *entry, int *fd)
{ {
int64_t size; int64_t size;
int initial_fd = fd;
off_t initial_off; /* FreeBSD/Solaris only, so off_t okay here */ off_t initial_off; /* FreeBSD/Solaris only, so off_t okay here */
off_t off_s, off_e; /* FreeBSD/Solaris only, so off_t okay here */ off_t off_s, off_e; /* FreeBSD/Solaris only, so off_t okay here */
int exit_sts = ARCHIVE_OK; int exit_sts = ARCHIVE_OK;
@ -923,22 +982,38 @@ setup_sparse(struct archive_read_disk *a,
return (ARCHIVE_OK); return (ARCHIVE_OK);
/* Does filesystem support the reporting of hole ? */ /* Does filesystem support the reporting of hole ? */
if (fd >= 0) { if (*fd < 0 && a->tree != NULL) {
if (fpathconf(fd, _PC_MIN_HOLE_SIZE) <= 0) const char *path;
path = archive_entry_sourcepath(entry);
if (path == NULL)
path = archive_entry_pathname(entry);
*fd = a->open_on_current_dir(a->tree, path,
O_RDONLY | O_NONBLOCK);
if (*fd < 0) {
archive_set_error(&a->archive, errno,
"Can't open `%s'", path);
return (ARCHIVE_FAILED);
}
}
if (*fd >= 0) {
if (fpathconf(*fd, _PC_MIN_HOLE_SIZE) <= 0)
return (ARCHIVE_OK); return (ARCHIVE_OK);
initial_off = lseek(fd, 0, SEEK_CUR); initial_off = lseek(*fd, 0, SEEK_CUR);
if (initial_off != 0) if (initial_off != 0)
lseek(fd, 0, SEEK_SET); lseek(*fd, 0, SEEK_SET);
} else { } else {
const char *path; const char *path;
path = archive_entry_sourcepath(entry); path = archive_entry_sourcepath(entry);
if (path == NULL) if (path == NULL)
path = archive_entry_pathname(entry); path = archive_entry_pathname(entry);
if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0) if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
return (ARCHIVE_OK); return (ARCHIVE_OK);
fd = open(path, O_RDONLY | O_NONBLOCK); *fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0) { if (*fd < 0) {
archive_set_error(&a->archive, errno, archive_set_error(&a->archive, errno,
"Can't open `%s'", path); "Can't open `%s'", path);
return (ARCHIVE_FAILED); return (ARCHIVE_FAILED);
@ -949,7 +1024,7 @@ setup_sparse(struct archive_read_disk *a,
off_s = 0; off_s = 0;
size = archive_entry_size(entry); size = archive_entry_size(entry);
while (off_s < size) { while (off_s < size) {
off_s = lseek(fd, off_s, SEEK_DATA); off_s = lseek(*fd, off_s, SEEK_DATA);
if (off_s == (off_t)-1) { if (off_s == (off_t)-1) {
if (errno == ENXIO) if (errno == ENXIO)
break;/* no more hole */ break;/* no more hole */
@ -958,10 +1033,10 @@ setup_sparse(struct archive_read_disk *a,
exit_sts = ARCHIVE_FAILED; exit_sts = ARCHIVE_FAILED;
goto exit_setup_sparse; goto exit_setup_sparse;
} }
off_e = lseek(fd, off_s, SEEK_HOLE); off_e = lseek(*fd, off_s, SEEK_HOLE);
if (off_s == (off_t)-1) { if (off_e == (off_t)-1) {
if (errno == ENXIO) { if (errno == ENXIO) {
off_e = lseek(fd, 0, SEEK_END); off_e = lseek(*fd, 0, SEEK_END);
if (off_e != (off_t)-1) if (off_e != (off_t)-1)
break;/* no more data */ break;/* no more data */
} }
@ -977,10 +1052,7 @@ setup_sparse(struct archive_read_disk *a,
off_s = off_e; off_s = off_e;
} }
exit_setup_sparse: exit_setup_sparse:
if (initial_fd != fd) lseek(*fd, initial_off, SEEK_SET);
close(fd);
else
lseek(fd, initial_off, SEEK_SET);
return (exit_sts); return (exit_sts);
} }
@ -991,7 +1063,7 @@ exit_setup_sparse:
*/ */
static int static int
setup_sparse(struct archive_read_disk *a, setup_sparse(struct archive_read_disk *a,
struct archive_entry *entry, int fd) struct archive_entry *entry, int *fd)
{ {
(void)a; /* UNUSED */ (void)a; /* UNUSED */
(void)entry; /* UNUSED */ (void)entry; /* UNUSED */

View File

@ -1,6 +1,6 @@
/*- /*-
* Copyright (c) 2003-2009 Tim Kientzle * Copyright (c) 2003-2009 Tim Kientzle
* Copyright (c) 2010,2011 Michihiro NAKAJIMA * Copyright (c) 2010-2012 Michihiro NAKAJIMA
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -52,6 +52,19 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_LINUX_MAGIC_H #ifdef HAVE_LINUX_MAGIC_H
#include <linux/magic.h> #include <linux/magic.h>
#endif #endif
#ifdef HAVE_LINUX_FS_H
#include <linux/fs.h>
#endif
/*
* Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
* As the include guards don't agree, the order of include is important.
*/
#ifdef HAVE_LINUX_EXT2_FS_H
#include <linux/ext2_fs.h> /* for Linux file flags */
#endif
#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
#include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
#endif
#ifdef HAVE_DIRECT_H #ifdef HAVE_DIRECT_H
#include <direct.h> #include <direct.h>
#endif #endif
@ -76,6 +89,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#include "archive.h" #include "archive.h"
#include "archive_string.h" #include "archive_string.h"
@ -222,6 +238,7 @@ struct tree {
char symlink_mode; char symlink_mode;
struct filesystem *current_filesystem; struct filesystem *current_filesystem;
struct filesystem *filesystem_table; struct filesystem *filesystem_table;
int initial_filesystem_id;
int current_filesystem_id; int current_filesystem_id;
int max_filesystem_id; int max_filesystem_id;
int allocated_filesytem; int allocated_filesytem;
@ -240,6 +257,7 @@ struct tree {
#define onWorkingDir 64 /* We are on the working dir where we are #define onWorkingDir 64 /* We are on the working dir where we are
* reading directory entry at this time. */ * reading directory entry at this time. */
#define needsRestoreTimes 128 #define needsRestoreTimes 128
#define onInitialDir 256 /* We are on the initial dir. */
static int static int
tree_dir_next_posix(struct tree *t); tree_dir_next_posix(struct tree *t);
@ -342,6 +360,7 @@ static const char *trivial_lookup_uname(void *, int64_t uid);
static int setup_sparse(struct archive_read_disk *, struct archive_entry *); static int setup_sparse(struct archive_read_disk *, struct archive_entry *);
static int close_and_restore_time(int fd, struct tree *, static int close_and_restore_time(int fd, struct tree *,
struct restore_time *); struct restore_time *);
static int open_on_current_dir(struct tree *, const char *, int);
static struct archive_vtable * static struct archive_vtable *
@ -430,16 +449,19 @@ archive_read_disk_new(void)
{ {
struct archive_read_disk *a; struct archive_read_disk *a;
a = (struct archive_read_disk *)malloc(sizeof(*a)); a = (struct archive_read_disk *)calloc(1, sizeof(*a));
if (a == NULL) if (a == NULL)
return (NULL); return (NULL);
memset(a, 0, sizeof(*a));
a->archive.magic = ARCHIVE_READ_DISK_MAGIC; a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
a->archive.state = ARCHIVE_STATE_NEW; a->archive.state = ARCHIVE_STATE_NEW;
a->archive.vtable = archive_read_disk_vtable(); a->archive.vtable = archive_read_disk_vtable();
a->lookup_uname = trivial_lookup_uname; a->lookup_uname = trivial_lookup_uname;
a->lookup_gname = trivial_lookup_gname; a->lookup_gname = trivial_lookup_gname;
a->entry_wd_fd = -1; a->enable_copyfile = 1;
a->traverse_mount_points = 1;
a->open_on_current_dir = open_on_current_dir;
a->tree_current_dir_fd = tree_current_dir_fd;
a->tree_enter_working_dir = tree_enter_working_dir;
return (&a->archive); return (&a->archive);
} }
@ -555,6 +577,37 @@ archive_read_disk_set_atime_restored(struct archive *_a)
#endif #endif
} }
int
archive_read_disk_set_behavior(struct archive *_a, int flags)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
int r = ARCHIVE_OK;
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump");
if (flags & ARCHIVE_READDISK_RESTORE_ATIME)
r = archive_read_disk_set_atime_restored(_a);
else {
a->restore_time = 0;
if (a->tree != NULL)
a->tree->flags &= ~needsRestoreTimes;
}
if (flags & ARCHIVE_READDISK_HONOR_NODUMP)
a->honor_nodump = 1;
else
a->honor_nodump = 0;
if (flags & ARCHIVE_READDISK_MAC_COPYFILE)
a->enable_copyfile = 1;
else
a->enable_copyfile = 0;
if (flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS)
a->traverse_mount_points = 0;
else
a->traverse_mount_points = 1;
return (r);
}
/* /*
* Trivial implementations of gname/uname lookup functions. * Trivial implementations of gname/uname lookup functions.
* These are normally overridden by the client, but these stub * These are normally overridden by the client, but these stub
@ -685,13 +738,8 @@ _archive_read_data_block(struct archive *_a, const void **buff,
flags |= O_NOATIME; flags |= O_NOATIME;
do { do {
#endif #endif
#ifdef HAVE_OPENAT t->entry_fd = open_on_current_dir(t,
t->entry_fd = openat(tree_current_dir_fd(t),
tree_current_access_path(t), flags); tree_current_access_path(t), flags);
#else
tree_enter_working_dir(t);
t->entry_fd = open(tree_current_access_path(t), flags);
#endif
#if defined(O_NOATIME) #if defined(O_NOATIME)
/* /*
* When we did open the file with O_NOATIME flag, * When we did open the file with O_NOATIME flag,
@ -802,29 +850,17 @@ abort_read_data:
} }
static int static int
_archive_read_next_header2(struct archive *_a, struct archive_entry *entry) next_entry(struct archive_read_disk *a, struct tree *t,
struct archive_entry *entry)
{ {
struct archive_read_disk *a = (struct archive_read_disk *)_a;
struct tree *t;
const struct stat *st; /* info to use for this entry */ const struct stat *st; /* info to use for this entry */
const struct stat *lst;/* lstat() information */ const struct stat *lst;/* lstat() information */
int descend, fd = -1, r; const char *name;
int descend, r;
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_read_next_header2");
t = a->tree;
if (t->entry_fd >= 0) {
close_and_restore_time(t->entry_fd, t, &t->restore_time);
t->entry_fd = -1;
}
#if !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR))
/* Restore working directory. */
tree_enter_working_dir(t);
#endif
st = NULL; st = NULL;
lst = NULL; lst = NULL;
t->descend = 0;
do { do {
switch (tree_next(t)) { switch (tree_next(t)) {
case TREE_ERROR_FATAL: case TREE_ERROR_FATAL:
@ -859,6 +895,38 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
} }
} while (lst == NULL); } while (lst == NULL);
#ifdef __APPLE__
if (a->enable_copyfile) {
/* If we're using copyfile(), ignore "._XXX" files. */
const char *bname = strrchr(tree_current_path(t), '/');
if (bname == NULL)
bname = tree_current_path(t);
else
++bname;
if (bname[0] == '.' && bname[1] == '_')
return (ARCHIVE_RETRY);
}
#endif
archive_entry_copy_pathname(entry, tree_current_path(t));
/*
* Perform path matching.
*/
if (a->matching) {
r = archive_match_path_excluded(a->matching, entry);
if (r < 0) {
archive_set_error(&(a->archive), errno,
"Faild : %s", archive_error_string(a->matching));
return (r);
}
if (r) {
if (a->excluded_cb_func)
a->excluded_cb_func(&(a->archive),
a->excluded_cb_data, entry);
return (ARCHIVE_RETRY);
}
}
/* /*
* Distinguish 'L'/'P'/'H' symlink following. * Distinguish 'L'/'P'/'H' symlink following.
*/ */
@ -897,13 +965,44 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
tree_enter_initial_dir(t); tree_enter_initial_dir(t);
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if (t->initial_filesystem_id == -1)
t->initial_filesystem_id = t->current_filesystem_id;
if (!a->traverse_mount_points) {
if (t->initial_filesystem_id != t->current_filesystem_id)
return (ARCHIVE_RETRY);
}
t->descend = descend; t->descend = descend;
archive_entry_set_pathname(entry, tree_current_path(t)); /*
archive_entry_copy_sourcepath(entry, tree_current_access_path(t)); * Honor nodump flag.
* If the file is marked with nodump flag, do not return this entry.
*/
if (a->honor_nodump) {
#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
if (st->st_flags & UF_NODUMP)
return (ARCHIVE_RETRY);
#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) &&\
defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
if (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) {
unsigned long stflags;
t->entry_fd = open_on_current_dir(t,
tree_current_access_path(t), O_RDONLY | O_NONBLOCK);
if (t->entry_fd >= 0) {
r = ioctl(t->entry_fd, EXT2_IOC_GETFLAGS,
&stflags);
if (r == 0 && (stflags & EXT2_NODUMP_FL) != 0)
return (ARCHIVE_RETRY);
}
}
#endif
}
archive_entry_copy_stat(entry, st); archive_entry_copy_stat(entry, st);
/* Save the times to be restored. */ /* Save the times to be restored. This must be in before
* calling archive_read_disk_descend() or any chance of it,
* especially, invokng a callback. */
t->restore_time.mtime = archive_entry_mtime(entry); t->restore_time.mtime = archive_entry_mtime(entry);
t->restore_time.mtime_nsec = archive_entry_mtime_nsec(entry); t->restore_time.mtime_nsec = archive_entry_mtime_nsec(entry);
t->restore_time.atime = archive_entry_atime(entry); t->restore_time.atime = archive_entry_atime(entry);
@ -911,39 +1010,102 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
t->restore_time.filetype = archive_entry_filetype(entry); t->restore_time.filetype = archive_entry_filetype(entry);
t->restore_time.noatime = t->current_filesystem->noatime; t->restore_time.noatime = t->current_filesystem->noatime;
#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
/* /*
* Open the current file to freely gather its metadata anywhere in * Perform time matching.
* working directory.
* Note: A symbolic link file cannot be opened with O_NOFOLLOW.
*/ */
if (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK) if (a->matching) {
fd = openat(tree_current_dir_fd(t), tree_current_access_path(t), r = archive_match_time_excluded(a->matching, entry);
O_RDONLY | O_NONBLOCK); if (r < 0) {
/* Restore working directory if openat() operation failed or archive_set_error(&(a->archive), errno,
* the file is a symbolic link. */ "Faild : %s", archive_error_string(a->matching));
if (fd < 0) return (r);
tree_enter_working_dir(t); }
if (r) {
if (a->excluded_cb_func)
a->excluded_cb_func(&(a->archive),
a->excluded_cb_data, entry);
return (ARCHIVE_RETRY);
}
}
/* The current direcotry fd is needed at /* Lookup uname/gname */
* archive_read_disk_entry_from_file() function to read link data name = archive_read_disk_uname(&(a->archive), archive_entry_uid(entry));
* with readlinkat(). */ if (name != NULL)
a->entry_wd_fd = tree_current_dir_fd(t); archive_entry_copy_uname(entry, name);
#endif name = archive_read_disk_gname(&(a->archive), archive_entry_gid(entry));
if (name != NULL)
archive_entry_copy_gname(entry, name);
/*
* Perform owner matching.
*/
if (a->matching) {
r = archive_match_owner_excluded(a->matching, entry);
if (r < 0) {
archive_set_error(&(a->archive), errno,
"Faild : %s", archive_error_string(a->matching));
return (r);
}
if (r) {
if (a->excluded_cb_func)
a->excluded_cb_func(&(a->archive),
a->excluded_cb_data, entry);
return (ARCHIVE_RETRY);
}
}
/*
* Invoke a meta data filter callback.
*/
if (a->metadata_filter_func) {
if (!a->metadata_filter_func(&(a->archive),
a->metadata_filter_data, entry))
return (ARCHIVE_RETRY);
}
/* /*
* Populate the archive_entry with metadata from the disk. * Populate the archive_entry with metadata from the disk.
*/ */
r = archive_read_disk_entry_from_file(&(a->archive), entry, fd, st); archive_entry_copy_sourcepath(entry, tree_current_access_path(t));
r = archive_read_disk_entry_from_file(&(a->archive), entry,
t->entry_fd, st);
/* Close the file descriptor used for reding the current file return (r);
* metadata at archive_read_disk_entry_from_file(). */ }
if (fd >= 0)
close(fd); static int
_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
struct tree *t;
int r;
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_read_next_header2");
t = a->tree;
if (t->entry_fd >= 0) {
close_and_restore_time(t->entry_fd, t, &t->restore_time);
t->entry_fd = -1;
}
for (;;) {
r = next_entry(a, t, entry);
if (t->entry_fd >= 0) {
close(t->entry_fd);
t->entry_fd = -1;
}
if (r == ARCHIVE_RETRY) {
archive_entry_clear(entry);
continue;
}
break;
}
/* Return to the initial directory. */ /* Return to the initial directory. */
tree_enter_initial_dir(t); tree_enter_initial_dir(t);
archive_entry_copy_sourcepath(entry, tree_current_path(t));
/* /*
* EOF and FATAL are persistent at this layer. By * EOF and FATAL are persistent at this layer. By
@ -956,6 +1118,8 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
break; break;
case ARCHIVE_OK: case ARCHIVE_OK:
case ARCHIVE_WARN: case ARCHIVE_WARN:
/* Overwrite the sourcepath based on the initial directory. */
archive_entry_copy_sourcepath(entry, tree_current_path(t));
t->entry_total = 0; t->entry_total = 0;
if (archive_entry_filetype(entry) == AE_IFREG) { if (archive_entry_filetype(entry) == AE_IFREG) {
t->nlink = archive_entry_nlink(entry); t->nlink = archive_entry_nlink(entry);
@ -1018,6 +1182,48 @@ setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
return (ARCHIVE_OK); return (ARCHIVE_OK);
} }
int
archive_read_disk_set_matching(struct archive *_a, struct archive *_ma,
void (*_excluded_func)(struct archive *, void *, struct archive_entry *),
void *_client_data)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_disk_set_matching");
a->matching = _ma;
a->excluded_cb_func = _excluded_func;
a->excluded_cb_data = _client_data;
return (ARCHIVE_OK);
}
int
archive_read_disk_set_metadata_filter_callback(struct archive *_a,
int (*_metadata_filter_func)(struct archive *, void *,
struct archive_entry *), void *_client_data)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
"archive_read_disk_set_metadata_filter_callback");
a->metadata_filter_func = _metadata_filter_func;
a->metadata_filter_data = _client_data;
return (ARCHIVE_OK);
}
int
archive_read_disk_can_descend(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
struct tree *t = a->tree;
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_read_disk_can_descend");
return (t->visit_type == TREE_REGULAR && t->descend);
}
/* /*
* Called by the client to mark the directory just returned from * Called by the client to mark the directory just returned from
* tree_next() as needing to be visited. * tree_next() as needing to be visited.
@ -1028,14 +1234,12 @@ archive_read_disk_descend(struct archive *_a)
struct archive_read_disk *a = (struct archive_read_disk *)_a; struct archive_read_disk *a = (struct archive_read_disk *)_a;
struct tree *t = a->tree; struct tree *t = a->tree;
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_read_disk_descend"); "archive_read_disk_descend");
if (t->visit_type != TREE_REGULAR || !t->descend) { if (t->visit_type != TREE_REGULAR || !t->descend)
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, return (ARCHIVE_OK);
"Ignored the request descending the current object");
return (ARCHIVE_WARN);
}
if (tree_current_is_physical_dir(t)) { if (tree_current_is_physical_dir(t)) {
tree_push(t, t->basename, t->current_filesystem_id, tree_push(t, t->basename, t->current_filesystem_id,
@ -1079,8 +1283,12 @@ archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
archive_string_init(&path); archive_string_init(&path);
if (archive_string_append_from_wcs(&path, pathname, if (archive_string_append_from_wcs(&path, pathname,
wcslen(pathname)) != 0) { wcslen(pathname)) != 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, if (errno == ENOMEM)
"Can't convert a path to a char string"); archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory");
else
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Can't convert a path to a char string");
a->archive.state = ARCHIVE_STATE_FATAL; a->archive.state = ARCHIVE_STATE_FATAL;
ret = ARCHIVE_FATAL; ret = ARCHIVE_FATAL;
} else } else
@ -1268,7 +1476,7 @@ setup_current_filesystem(struct archive_read_disk *a)
t->current_filesystem->synthetic = -1; t->current_filesystem->synthetic = -1;
t->current_filesystem->remote = -1; t->current_filesystem->remote = -1;
if (tree_current_is_symblic_link_target(t)) { if (tree_current_is_symblic_link_target(t)) {
#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) #if defined(HAVE_OPENAT)
/* /*
* Get file system statistics on any directory * Get file system statistics on any directory
* where current is. * where current is.
@ -1285,6 +1493,10 @@ setup_current_filesystem(struct archive_read_disk *a)
xr = get_xfer_size(t, fd, NULL); xr = get_xfer_size(t, fd, NULL);
close(fd); close(fd);
#else #else
if (tree_enter_working_dir(t) != 0) {
archive_set_error(&a->archive, errno, "fchdir failed");
return (ARCHIVE_FAILED);
}
r = statfs(tree_current_access_path(t), &sfs); r = statfs(tree_current_access_path(t), &sfs);
if (r == 0) if (r == 0)
xr = get_xfer_size(t, -1, tree_current_access_path(t)); xr = get_xfer_size(t, -1, tree_current_access_path(t));
@ -1334,9 +1546,13 @@ setup_current_filesystem(struct archive_read_disk *a)
t->current_filesystem->name_max = sfs.f_namemax; t->current_filesystem->name_max = sfs.f_namemax;
#else #else
/* Mac OS X does not have f_namemax in struct statfs. */ /* Mac OS X does not have f_namemax in struct statfs. */
if (tree_current_is_symblic_link_target(t)) if (tree_current_is_symblic_link_target(t)) {
if (tree_enter_working_dir(t) != 0) {
archive_set_error(&a->archive, errno, "fchdir failed");
return (ARCHIVE_FAILED);
}
nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
else } else
nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
if (nm == -1) if (nm == -1)
t->current_filesystem->name_max = NAME_MAX; t->current_filesystem->name_max = NAME_MAX;
@ -1360,6 +1576,10 @@ setup_current_filesystem(struct archive_read_disk *a)
int r, xr = 0; int r, xr = 0;
t->current_filesystem->synthetic = -1; t->current_filesystem->synthetic = -1;
if (tree_enter_working_dir(t) != 0) {
archive_set_error(&a->archive, errno, "fchdir failed");
return (ARCHIVE_FAILED);
}
if (tree_current_is_symblic_link_target(t)) { if (tree_current_is_symblic_link_target(t)) {
r = statvfs(tree_current_access_path(t), &sfs); r = statvfs(tree_current_access_path(t), &sfs);
if (r == 0) if (r == 0)
@ -1384,17 +1604,24 @@ setup_current_filesystem(struct archive_read_disk *a)
* for pathconf() function. */ * for pathconf() function. */
t->current_filesystem->xfer_align = sfs.f_frsize; t->current_filesystem->xfer_align = sfs.f_frsize;
t->current_filesystem->max_xfer_size = -1; t->current_filesystem->max_xfer_size = -1;
#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
t->current_filesystem->min_xfer_size = sfs.f_iosize; t->current_filesystem->min_xfer_size = sfs.f_iosize;
t->current_filesystem->incr_xfer_size = sfs.f_iosize; t->current_filesystem->incr_xfer_size = sfs.f_iosize;
#else
t->current_filesystem->min_xfer_size = sfs.f_bsize;
t->current_filesystem->incr_xfer_size = sfs.f_bsize;
#endif
} }
if (sfs.f_flag & ST_LOCAL) if (sfs.f_flag & ST_LOCAL)
t->current_filesystem->remote = 0; t->current_filesystem->remote = 0;
else else
t->current_filesystem->remote = 1; t->current_filesystem->remote = 1;
#if defined(ST_NOATIME)
if (sfs.f_flag & ST_NOATIME) if (sfs.f_flag & ST_NOATIME)
t->current_filesystem->noatime = 1; t->current_filesystem->noatime = 1;
else else
#endif
t->current_filesystem->noatime = 0; t->current_filesystem->noatime = 0;
/* Set maximum filename length. */ /* Set maximum filename length. */
@ -1427,7 +1654,7 @@ setup_current_filesystem(struct archive_read_disk *a)
int r, vr = 0, xr = 0; int r, vr = 0, xr = 0;
if (tree_current_is_symblic_link_target(t)) { if (tree_current_is_symblic_link_target(t)) {
#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) #if defined(HAVE_OPENAT)
/* /*
* Get file system statistics on any directory * Get file system statistics on any directory
* where current is. * where current is.
@ -1445,6 +1672,10 @@ setup_current_filesystem(struct archive_read_disk *a)
xr = get_xfer_size(t, fd, NULL); xr = get_xfer_size(t, fd, NULL);
close(fd); close(fd);
#else #else
if (tree_enter_working_dir(t) != 0) {
archive_set_error(&a->archive, errno, "fchdir failed");
return (ARCHIVE_FAILED);
}
vr = statvfs(tree_current_access_path(t), &svfs); vr = statvfs(tree_current_access_path(t), &svfs);
r = statfs(tree_current_access_path(t), &sfs); r = statfs(tree_current_access_path(t), &sfs);
if (r == 0) if (r == 0)
@ -1456,9 +1687,11 @@ setup_current_filesystem(struct archive_read_disk *a)
r = fstatfs(tree_current_dir_fd(t), &sfs); r = fstatfs(tree_current_dir_fd(t), &sfs);
if (r == 0) if (r == 0)
xr = get_xfer_size(t, tree_current_dir_fd(t), NULL); xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
#elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
#error "Unexpected case. Please tell us about this error."
#else #else
if (tree_enter_working_dir(t) != 0) {
archive_set_error(&a->archive, errno, "fchdir failed");
return (ARCHIVE_FAILED);
}
vr = statvfs(".", &svfs); vr = statvfs(".", &svfs);
r = statfs(".", &sfs); r = statfs(".", &sfs);
if (r == 0) if (r == 0)
@ -1529,7 +1762,7 @@ setup_current_filesystem(struct archive_read_disk *a)
t->current_filesystem->synthetic = -1;/* Not supported */ t->current_filesystem->synthetic = -1;/* Not supported */
t->current_filesystem->remote = -1;/* Not supported */ t->current_filesystem->remote = -1;/* Not supported */
if (tree_current_is_symblic_link_target(t)) { if (tree_current_is_symblic_link_target(t)) {
#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR) #if defined(HAVE_OPENAT)
/* /*
* Get file system statistics on any directory * Get file system statistics on any directory
* where current is. * where current is.
@ -1546,6 +1779,10 @@ setup_current_filesystem(struct archive_read_disk *a)
xr = get_xfer_size(t, fd, NULL); xr = get_xfer_size(t, fd, NULL);
close(fd); close(fd);
#else #else
if (tree_enter_working_dir(t) != 0) {
archive_set_error(&a->archive, errno, "fchdir failed");
return (ARCHIVE_FAILED);
}
r = statvfs(tree_current_access_path(t), &sfs); r = statvfs(tree_current_access_path(t), &sfs);
if (r == 0) if (r == 0)
xr = get_xfer_size(t, -1, tree_current_access_path(t)); xr = get_xfer_size(t, -1, tree_current_access_path(t));
@ -1555,9 +1792,11 @@ setup_current_filesystem(struct archive_read_disk *a)
r = fstatvfs(tree_current_dir_fd(t), &sfs); r = fstatvfs(tree_current_dir_fd(t), &sfs);
if (r == 0) if (r == 0)
xr = get_xfer_size(t, tree_current_dir_fd(t), NULL); xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
#elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
#error "Unexpected case. Please tell us about this error."
#else #else
if (tree_enter_working_dir(t) != 0) {
archive_set_error(&a->archive, errno, "fchdir failed");
return (ARCHIVE_FAILED);
}
r = statvfs(".", &sfs); r = statvfs(".", &sfs);
if (r == 0) if (r == 0)
xr = get_xfer_size(t, -1, "."); xr = get_xfer_size(t, -1, ".");
@ -1615,9 +1854,13 @@ setup_current_filesystem(struct archive_read_disk *a)
#if defined(HAVE_READDIR_R) #if defined(HAVE_READDIR_R)
/* Set maximum filename length. */ /* Set maximum filename length. */
# if defined(_PC_NAME_MAX) # if defined(_PC_NAME_MAX)
if (tree_current_is_symblic_link_target(t)) if (tree_current_is_symblic_link_target(t)) {
if (tree_enter_working_dir(t) != 0) {
archive_set_error(&a->archive, errno, "fchdir failed");
return (ARCHIVE_FAILED);
}
nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
else } else
nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
if (nm == -1) if (nm == -1)
# endif /* _PC_NAME_MAX */ # endif /* _PC_NAME_MAX */
@ -1697,6 +1940,18 @@ close_and_restore_time(int fd, struct tree *t, struct restore_time *rt)
return (0); return (0);
} }
static int
open_on_current_dir(struct tree *t, const char *path, int flags)
{
#ifdef HAVE_OPENAT
return (openat(tree_current_dir_fd(t), path, flags));
#else
if (tree_enter_working_dir(t) != 0)
return (-1);
return (open(path, flags));
#endif
}
/* /*
* Add a directory path to the current stack. * Add a directory path to the current stack.
*/ */
@ -1778,6 +2033,7 @@ static struct tree *
tree_reopen(struct tree *t, const char *path, int restore_time) tree_reopen(struct tree *t, const char *path, int restore_time)
{ {
t->flags = (restore_time)?needsRestoreTimes:0; t->flags = (restore_time)?needsRestoreTimes:0;
t->flags |= onInitialDir;
t->visit_type = 0; t->visit_type = 0;
t->tree_errno = 0; t->tree_errno = 0;
t->dirname_length = 0; t->dirname_length = 0;
@ -1790,6 +2046,7 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
t->entry_fd = -1; t->entry_fd = -1;
t->entry_eof = 0; t->entry_eof = 0;
t->entry_remaining_bytes = 0; t->entry_remaining_bytes = 0;
t->initial_filesystem_id = -1;
/* First item is set up a lot like a symlink traversal. */ /* First item is set up a lot like a symlink traversal. */
tree_push(t, path, 0, 0, 0, NULL); tree_push(t, path, 0, 0, 0, NULL);
@ -1803,12 +2060,14 @@ tree_reopen(struct tree *t, const char *path, int restore_time)
static int static int
tree_descent(struct tree *t) tree_descent(struct tree *t)
{ {
int r = 0; int flag, new_fd, r = 0;
#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
int new_fd;
t->dirname_length = archive_strlen(&t->path); t->dirname_length = archive_strlen(&t->path);
new_fd = openat(t->working_dir_fd, t->stack->name.s, O_RDONLY); flag = O_RDONLY;
#if defined(O_DIRECTORY)
flag |= O_DIRECTORY;
#endif
new_fd = open_on_current_dir(t, t->stack->name.s, flag);
if (new_fd < 0) { if (new_fd < 0) {
t->tree_errno = errno; t->tree_errno = errno;
r = TREE_ERROR_DIR; r = TREE_ERROR_DIR;
@ -1822,30 +2081,10 @@ tree_descent(struct tree *t)
t->maxOpenCount = t->openCount; t->maxOpenCount = t->openCount;
} else } else
close(t->working_dir_fd); close(t->working_dir_fd);
/* Renew the current working directory. */
t->working_dir_fd = new_fd; t->working_dir_fd = new_fd;
t->flags &= ~onWorkingDir;
} }
#else
/* If it is a link, set up fd for the ascent. */
if (t->stack->flags & isDirLink)
t->stack->symlink_parent_fd = t->working_dir_fd;
else {
close(t->working_dir_fd);
t->openCount--;
}
t->working_dir_fd = -1;
t->dirname_length = archive_strlen(&t->path);
if (chdir(t->stack->name.s) != 0)
{
t->tree_errno = errno;
r = TREE_ERROR_DIR;
} else {
t->depth++;
t->working_dir_fd = open(".", O_RDONLY);
t->openCount++;
if (t->openCount > t->maxOpenCount)
t->maxOpenCount = t->openCount;
}
#endif
return (r); return (r);
} }
@ -1856,37 +2095,21 @@ static int
tree_ascend(struct tree *t) tree_ascend(struct tree *t)
{ {
struct tree_entry *te; struct tree_entry *te;
int r = 0, prev_dir_fd; int new_fd, r = 0, prev_dir_fd;
te = t->stack; te = t->stack;
prev_dir_fd = t->working_dir_fd; prev_dir_fd = t->working_dir_fd;
#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
if (te->flags & isDirLink) if (te->flags & isDirLink)
t->working_dir_fd = te->symlink_parent_fd; new_fd = te->symlink_parent_fd;
else { else
int new_fd = openat(t->working_dir_fd, "..", O_RDONLY); new_fd = open_on_current_dir(t, "..", O_RDONLY);
if (new_fd < 0) { if (new_fd < 0) {
t->tree_errno = errno; t->tree_errno = errno;
r = TREE_ERROR_FATAL; r = TREE_ERROR_FATAL;
} else
t->working_dir_fd = new_fd;
}
#else
if (te->flags & isDirLink) {
if (fchdir(te->symlink_parent_fd) != 0) {
t->tree_errno = errno;
r = TREE_ERROR_FATAL;
} else
t->working_dir_fd = te->symlink_parent_fd;
} else { } else {
if (chdir("..") != 0) { /* Renew the current working directory. */
t->tree_errno = errno; t->working_dir_fd = new_fd;
r = TREE_ERROR_FATAL; t->flags &= ~onWorkingDir;
} else
t->working_dir_fd = open(".", O_RDONLY);
}
#endif
if (r == 0) {
/* Current directory has been changed, we should /* Current directory has been changed, we should
* close an fd of previous working directory. */ * close an fd of previous working directory. */
close_and_restore_time(prev_dir_fd, t, &te->restore_time); close_and_restore_time(prev_dir_fd, t, &te->restore_time);
@ -1907,10 +2130,12 @@ tree_enter_initial_dir(struct tree *t)
{ {
int r = 0; int r = 0;
if (t->flags & onWorkingDir) { if ((t->flags & onInitialDir) == 0) {
r = fchdir(t->initial_dir_fd); r = fchdir(t->initial_dir_fd);
if (r == 0) if (r == 0) {
t->flags &= ~onWorkingDir; t->flags &= ~onWorkingDir;
t->flags |= onInitialDir;
}
} }
return (r); return (r);
} }
@ -1930,8 +2155,10 @@ tree_enter_working_dir(struct tree *t)
*/ */
if (t->depth > 0 && (t->flags & onWorkingDir) == 0) { if (t->depth > 0 && (t->flags & onWorkingDir) == 0) {
r = fchdir(t->working_dir_fd); r = fchdir(t->working_dir_fd);
if (r == 0) if (r == 0) {
t->flags &= ~onInitialDir;
t->flags |= onWorkingDir; t->flags |= onWorkingDir;
}
} }
return (r); return (r);
} }
@ -2040,7 +2267,8 @@ tree_dir_next_posix(struct tree *t)
#if defined(HAVE_FDOPENDIR) #if defined(HAVE_FDOPENDIR)
if ((t->d = fdopendir(dup(t->working_dir_fd))) == NULL) { if ((t->d = fdopendir(dup(t->working_dir_fd))) == NULL) {
#else #else
if ((t->d = opendir(".")) == NULL) { if (tree_enter_working_dir(t) != 0 ||
(t->d = opendir(".")) == NULL) {
#endif #endif
r = tree_ascend(t); /* Undo "chdir" */ r = tree_ascend(t); /* Undo "chdir" */
tree_pop(t); tree_pop(t);
@ -2111,6 +2339,8 @@ tree_current_stat(struct tree *t)
if (fstatat(tree_current_dir_fd(t), if (fstatat(tree_current_dir_fd(t),
tree_current_access_path(t), &t->st, 0) != 0) tree_current_access_path(t), &t->st, 0) != 0)
#else #else
if (tree_enter_working_dir(t) != 0)
return NULL;
if (stat(tree_current_access_path(t), &t->st) != 0) if (stat(tree_current_access_path(t), &t->st) != 0)
#endif #endif
return NULL; return NULL;
@ -2131,6 +2361,8 @@ tree_current_lstat(struct tree *t)
tree_current_access_path(t), &t->lst, tree_current_access_path(t), &t->lst,
AT_SYMLINK_NOFOLLOW) != 0) AT_SYMLINK_NOFOLLOW) != 0)
#else #else
if (tree_enter_working_dir(t) != 0)
return NULL;
if (lstat(tree_current_access_path(t), &t->lst) != 0) if (lstat(tree_current_access_path(t), &t->lst) != 0)
#endif #endif
return NULL; return NULL;
@ -2152,7 +2384,10 @@ tree_current_is_dir(struct tree *t)
*/ */
if (t->flags & hasLstat) { if (t->flags & hasLstat) {
/* If lstat() says it's a dir, it must be a dir. */ /* If lstat() says it's a dir, it must be a dir. */
if (S_ISDIR(tree_current_lstat(t)->st_mode)) st = tree_current_lstat(t);
if (st == NULL)
return 0;
if (S_ISDIR(st->st_mode))
return 1; return 1;
/* Not a dir; might be a link to a dir. */ /* Not a dir; might be a link to a dir. */
/* If it's not a link, then it's not a link to a dir. */ /* If it's not a link, then it's not a link to a dir. */
@ -2186,9 +2421,13 @@ tree_current_is_physical_dir(struct tree *t)
* If stat() says it isn't a dir, then it's not a dir. * If stat() says it isn't a dir, then it's not a dir.
* If stat() data is cached, this check is free, so do it first. * If stat() data is cached, this check is free, so do it first.
*/ */
if ((t->flags & hasStat) if (t->flags & hasStat) {
&& (!S_ISDIR(tree_current_stat(t)->st_mode))) st = tree_current_stat(t);
return 0; if (st == NULL)
return (0);
if (!S_ISDIR(st->st_mode))
return (0);
}
/* /*
* Either stat() said it was a dir (in which case, we have * Either stat() said it was a dir (in which case, we have
@ -2232,7 +2471,7 @@ tree_current_is_symblic_link_target(struct tree *t)
lst = tree_current_lstat(t); lst = tree_current_lstat(t);
st = tree_current_stat(t); st = tree_current_stat(t);
return (st != NULL && return (st != NULL && lst != NULL &&
(int64_t)st->st_dev == t->current_filesystem->dev && (int64_t)st->st_dev == t->current_filesystem->dev &&
st->st_dev != lst->st_dev); st->st_dev != lst->st_dev);
} }

View File

@ -34,6 +34,7 @@
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED #define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
struct tree; struct tree;
struct archive_entry;
struct archive_read_disk { struct archive_read_disk {
struct archive archive; struct archive archive;
@ -55,10 +56,18 @@ struct archive_read_disk {
/* Directory traversals. */ /* Directory traversals. */
struct tree *tree; struct tree *tree;
int (*open_on_current_dir)(struct tree*, const char *, int);
int (*tree_current_dir_fd)(struct tree*);
int (*tree_enter_working_dir)(struct tree*);
/* Set 1 if users request to restore atime . */ /* Set 1 if users request to restore atime . */
int restore_time; int restore_time;
int entry_wd_fd; /* Set 1 if users request to honor nodump flag . */
int honor_nodump;
/* Set 1 if users request to enable mac copyfile. */
int enable_copyfile;
/* Set 1 if users request to traverse mount points. */
int traverse_mount_points;
const char * (*lookup_gname)(void *private, int64_t gid); const char * (*lookup_gname)(void *private, int64_t gid);
void (*cleanup_gname)(void *private); void (*cleanup_gname)(void *private);
@ -66,6 +75,18 @@ struct archive_read_disk {
const char * (*lookup_uname)(void *private, int64_t uid); const char * (*lookup_uname)(void *private, int64_t uid);
void (*cleanup_uname)(void *private); void (*cleanup_uname)(void *private);
void *lookup_uname_data; void *lookup_uname_data;
int (*metadata_filter_func)(struct archive *, void *,
struct archive_entry *);
void *metadata_filter_data;
/* ARCHIVE_MATCH object. */
struct archive *matching;
/* Callback function, this will be invoked when ARCHIVE_MATCH
* archive_match_*_excluded_ae return true. */
void (*excluded_cb_func)(struct archive *, void *,
struct archive_entry *);
void *excluded_cb_data;
}; };
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 22, 2011 .Dd February 2, 2012
.Dt ARCHIVE_READ_EXTRACT 3 .Dt ARCHIVE_READ_EXTRACT 3
.Os .Os
.Sh NAME .Sh NAME
@ -32,6 +32,8 @@
.Nm archive_read_extract2 , .Nm archive_read_extract2 ,
.Nm archive_read_extract_set_progress_callback .Nm archive_read_extract_set_progress_callback
.Nd functions for reading streaming archives .Nd functions for reading streaming archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft int .Ft int

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 19, 2011 .Dd February 2, 2012
.Dt ARCHIVE_READ_FILTER 3 .Dt ARCHIVE_READ_FILTER 3
.Os .Os
.Sh NAME .Sh NAME
@ -39,6 +39,8 @@
.Nm archive_read_support_filter_program_signature .Nm archive_read_support_filter_program_signature
.Nd functions for reading streaming archives .Nd functions for reading streaming archives
.\" .\"
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft int .Ft int

View File

@ -22,9 +22,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $ .\" $FreeBSD$
.\" .\"
.Dd March 19, 2011 .Dd February 2, 2012
.Dt ARCHIVE_READ_FORMAT 3 .Dt ARCHIVE_READ_FORMAT 3
.Os .Os
.Sh NAME .Sh NAME
@ -45,6 +45,8 @@
.Nm archive_read_support_format_zip .Nm archive_read_support_format_zip
.Nd functions for reading streaming archives .Nd functions for reading streaming archives
.\" .\"
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft int .Ft int

View File

@ -22,9 +22,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $ .\" $FreeBSD$
.\" .\"
.Dd March 20, 2011 .Dd February 2, 2012
.Dt ARCHIVE_READ_FREE 3 .Dt ARCHIVE_READ_FREE 3
.Os .Os
.Sh NAME .Sh NAME
@ -32,6 +32,8 @@
.Nm archive_read_finish , .Nm archive_read_finish ,
.Nm archive_read_free .Nm archive_read_free
.Nd functions for reading streaming archives .Nd functions for reading streaming archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft int .Ft int

View File

@ -24,13 +24,15 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 22, 2011 .Dd February 2, 2012
.Dt ARCHIVE_READ_HEADER 3 .Dt ARCHIVE_READ_HEADER 3
.Os .Os
.Sh NAME .Sh NAME
.Nm archive_read_next_header , .Nm archive_read_next_header ,
.Nm archive_read_next_header2 .Nm archive_read_next_header2
.Nd functions for reading streaming archives .Nd functions for reading streaming archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft int .Ft int

View File

@ -22,14 +22,16 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $ .\" $FreeBSD$
.\" .\"
.Dd March 20, 2011 .Dd February 2, 2012
.Dt ARCHIVE_READ_NEW 3 .Dt ARCHIVE_READ_NEW 3
.Os .Os
.Sh NAME .Sh NAME
.Nm archive_read_new .Nm archive_read_new
.Nd functions for reading streaming archives .Nd functions for reading streaming archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft struct archive * .Ft struct archive *

View File

@ -22,9 +22,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $ .\" $FreeBSD$
.\" .\"
.Dd March 19, 2011 .Dd February 2, 2012
.Dt ARCHIVE_READ_OPEN 3 .Dt ARCHIVE_READ_OPEN 3
.Os .Os
.Sh NAME .Sh NAME
@ -35,6 +35,8 @@
.Nm archive_read_open_filename , .Nm archive_read_open_filename ,
.Nm archive_read_open_memory , .Nm archive_read_open_memory ,
.Nd functions for reading streaming archives .Nd functions for reading streaming archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft int .Ft int

View File

@ -129,8 +129,8 @@ static int64_t
file_skip(struct archive *a, void *client_data, int64_t request) file_skip(struct archive *a, void *client_data, int64_t request)
{ {
struct read_fd_data *mine = (struct read_fd_data *)client_data; struct read_fd_data *mine = (struct read_fd_data *)client_data;
off_t skip = (off_t)request; int64_t skip = request;
off_t old_offset, new_offset; int64_t old_offset, new_offset;
int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */ int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */
if (!mine->use_lseek) if (!mine->use_lseek)

View File

@ -130,9 +130,13 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
archive_string_init(&fn); archive_string_init(&fn);
if (archive_string_append_from_wcs(&fn, wfilename, if (archive_string_append_from_wcs(&fn, wfilename,
wcslen(wfilename)) != 0) { wcslen(wfilename)) != 0) {
archive_set_error(a, EINVAL, if (errno == ENOMEM)
"Failed to convert a wide-character filename to" archive_set_error(a, errno,
" a multi-byte filename"); "Can't allocate memory");
else
archive_set_error(a, EINVAL,
"Failed to convert a wide-character"
" filename to a multi-byte filename");
archive_string_free(&fn); archive_string_free(&fn);
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
@ -450,7 +454,7 @@ static int64_t
file_seek(struct archive *a, void *client_data, int64_t request, int whence) file_seek(struct archive *a, void *client_data, int64_t request, int whence)
{ {
struct read_file_data *mine = (struct read_file_data *)client_data; struct read_file_data *mine = (struct read_file_data *)client_data;
off_t r; int64_t r;
/* We use off_t here because lseek() is declared that way. */ /* We use off_t here because lseek() is declared that way. */
/* See above for notes about when off_t is less than 64 bits. */ /* See above for notes about when off_t is less than 64 bits. */

View File

@ -134,8 +134,8 @@ struct archive_read {
/* Dev/ino of the archive being read/written. */ /* Dev/ino of the archive being read/written. */
int skip_file_set; int skip_file_set;
dev_t skip_file_dev; int64_t skip_file_dev;
ino_t skip_file_ino; int64_t skip_file_ino;
/* /*
* Used by archive_read_data() to track blocks and copy * Used by archive_read_data() to track blocks and copy

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd April 13, 2009 .Dd February 2, 2012
.Dt ARCHIVE_READ_OPTIONS 3 .Dt ARCHIVE_READ_OPTIONS 3
.Os .Os
.Sh NAME .Sh NAME
@ -34,6 +34,8 @@
.Nm archive_read_set_options .Nm archive_read_set_options
.Nd functions controlling options for reading archives .Nd functions controlling options for reading archives
.\" .\"
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.Ft int .Ft int
.Fo archive_read_set_filter_option .Fo archive_read_set_filter_option

View File

@ -188,7 +188,7 @@ rpm_filter_read(struct archive_read_filter *self, const void **buff)
if (rpm->total_in + avail_in < RPM_LEAD_SIZE) if (rpm->total_in + avail_in < RPM_LEAD_SIZE)
used += avail_in; used += avail_in;
else { else {
n = RPM_LEAD_SIZE - rpm->total_in; n = (size_t)(RPM_LEAD_SIZE - rpm->total_in);
used += n; used += n;
b += n; b += n;
rpm->state = ST_HEADER; rpm->state = ST_HEADER;

View File

@ -580,7 +580,7 @@ archive_read_format_7zip_read_header(struct archive_read *a,
free_Header(&header); free_Header(&header);
if (r != ARCHIVE_OK) if (r != ARCHIVE_OK)
return (r); return (r);
zip->entries_remaining = zip->numFiles; zip->entries_remaining = (size_t)zip->numFiles;
zip->entry = zip->entries; zip->entry = zip->entries;
} else { } else {
++zip->entry; ++zip->entry;
@ -653,19 +653,24 @@ archive_read_format_7zip_read_header(struct archive_read *a,
*/ */
while (zip->entry_bytes_remaining > 0) { while (zip->entry_bytes_remaining > 0) {
const void *buff; const void *buff;
unsigned char *mem;
size_t size; size_t size;
int64_t offset; int64_t offset;
r = archive_read_format_7zip_read_data(a, &buff, r = archive_read_format_7zip_read_data(a, &buff,
&size, &offset); &size, &offset);
if (r < ARCHIVE_WARN) if (r < ARCHIVE_WARN) {
free(symname);
return (r); return (r);
symname = realloc(symname, symsize + size + 1); }
if (symname == NULL) { mem = realloc(symname, symsize + size + 1);
if (mem == NULL) {
free(symname);
archive_set_error(&a->archive, ENOMEM, archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for Symname"); "Can't allocate memory for Symname");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
symname = mem;
memcpy(symname+symsize, buff, size); memcpy(symname+symsize, buff, size);
symsize += size; symsize += size;
} }
@ -715,7 +720,8 @@ archive_read_format_7zip_read_data(struct archive_read *a,
return (ARCHIVE_EOF); return (ARCHIVE_EOF);
} }
bytes = read_stream(a, buff, zip->entry_bytes_remaining, 0); bytes = read_stream(a, buff,
(size_t)zip->entry_bytes_remaining, 0);
if (bytes < 0) if (bytes < 0)
return ((int)bytes); return ((int)bytes);
if (bytes == 0) { if (bytes == 0) {
@ -773,7 +779,7 @@ archive_read_format_7zip_read_data_skip(struct archive_read *a)
* If the length is at the beginning, we can skip the * If the length is at the beginning, we can skip the
* compressed data much more quickly. * compressed data much more quickly.
*/ */
bytes_skipped = skip_stream(a, zip->entry_bytes_remaining); bytes_skipped = skip_stream(a, (size_t)zip->entry_bytes_remaining);
if (bytes_skipped < 0) if (bytes_skipped < 0)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
zip->entry_bytes_remaining = 0; zip->entry_bytes_remaining = 0;
@ -1053,7 +1059,7 @@ init_decompression(struct archive_read *a, struct _7zip *zip,
ff = &filters[fi]; ff = &filters[fi];
#endif #endif
r = lzma_properties_decode(&filters[fi], NULL, r = lzma_properties_decode(&filters[fi], NULL,
coder1->properties, coder1->propertiesSize); coder1->properties, (size_t)coder1->propertiesSize);
if (r != LZMA_OK) { if (r != LZMA_OK) {
set_error(a, r); set_error(a, r);
return (ARCHIVE_FAILED); return (ARCHIVE_FAILED);
@ -1441,8 +1447,8 @@ decompress(struct archive_read *a, struct _7zip *zip,
} while (zip->ppstream.avail_out && } while (zip->ppstream.avail_out &&
(zip->ppstream.avail_in || flush_bytes)); (zip->ppstream.avail_in || flush_bytes));
t_avail_in = zip->ppstream.avail_in; t_avail_in = (size_t)zip->ppstream.avail_in;
t_avail_out = zip->ppstream.avail_out; t_avail_out = (size_t)zip->ppstream.avail_out;
break; break;
} }
default: default:
@ -1505,6 +1511,10 @@ free_decompression(struct archive_read *a, struct _7zip *zip)
{ {
int r = ARCHIVE_OK; int r = ARCHIVE_OK;
#if !defined(HAVE_ZLIB_H) &&\
!(defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR))
(void)a;/* UNUSED */
#endif
#ifdef HAVE_LZMA_H #ifdef HAVE_LZMA_H
if (zip->lzstream_valid) if (zip->lzstream_valid)
lzma_end(&(zip->lzstream)); lzma_end(&(zip->lzstream));
@ -1671,8 +1681,8 @@ read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
return (0); return (0);
if (*p != kSize) if (*p != kSize)
return (-1); return (-1);
pi->sizes = calloc(pi->numPackStreams, sizeof(uint64_t)); pi->sizes = calloc((size_t)pi->numPackStreams, sizeof(uint64_t));
pi->positions = calloc(pi->numPackStreams, sizeof(uint64_t)); pi->positions = calloc((size_t)pi->numPackStreams, sizeof(uint64_t));
if (pi->sizes == NULL || pi->positions == NULL) if (pi->sizes == NULL || pi->positions == NULL)
return (-1); return (-1);
@ -1689,9 +1699,9 @@ read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
if (*p == kEnd) { if (*p == kEnd) {
/* PackStreamDigests[num] are not present. */ /* PackStreamDigests[num] are not present. */
pi->digest.defineds = pi->digest.defineds =
calloc(pi->numPackStreams, sizeof(*pi->digest.defineds)); calloc((size_t)pi->numPackStreams, sizeof(*pi->digest.defineds));
pi->digest.digests = pi->digest.digests =
calloc(pi->numPackStreams, sizeof(*pi->digest.digests)); calloc((size_t)pi->numPackStreams, sizeof(*pi->digest.digests));
if (pi->digest.defineds == NULL || pi->digest.digests == NULL) if (pi->digest.defineds == NULL || pi->digest.digests == NULL)
return (-1); return (-1);
return (0); return (0);
@ -1700,7 +1710,7 @@ read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
if (*p != kSize) if (*p != kSize)
return (-1); return (-1);
if (read_Digests(a, &(pi->digest), pi->numPackStreams) < 0) if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0)
return (-1); return (-1);
/* /*
@ -1749,7 +1759,7 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
/* Too many coders. */ /* Too many coders. */
return (-1); return (-1);
f->coders = calloc(f->numCoders, sizeof(*f->coders)); f->coders = calloc((size_t)f->numCoders, sizeof(*f->coders));
if (f->coders == NULL) if (f->coders == NULL)
return (-1); return (-1);
for (i = 0; i< f->numCoders; i++) { for (i = 0; i< f->numCoders; i++) {
@ -1801,14 +1811,14 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
a, &(f->coders[i].propertiesSize)) < 0) a, &(f->coders[i].propertiesSize)) < 0)
return (-1); return (-1);
if ((p = header_bytes( if ((p = header_bytes(
a, f->coders[i].propertiesSize)) == NULL) a, (size_t)f->coders[i].propertiesSize)) == NULL)
return (-1); return (-1);
f->coders[i].properties = f->coders[i].properties =
malloc(f->coders[i].propertiesSize); malloc((size_t)f->coders[i].propertiesSize);
if (f->coders[i].properties == NULL) if (f->coders[i].properties == NULL)
return (-1); return (-1);
memcpy(f->coders[i].properties, p, memcpy(f->coders[i].properties, p,
f->coders[i].propertiesSize); (size_t)f->coders[i].propertiesSize);
} }
numInStreamsTotal += f->coders[i].numInStreams; numInStreamsTotal += f->coders[i].numInStreams;
@ -1822,9 +1832,13 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
f->numBindPairs = numOutStreamsTotal - 1; f->numBindPairs = numOutStreamsTotal - 1;
if (zip->header_bytes_remaining < f->numBindPairs) if (zip->header_bytes_remaining < f->numBindPairs)
return (-1); return (-1);
f->bindPairs = calloc(f->numBindPairs, sizeof(*f->bindPairs)); if (f->numBindPairs > 0) {
if (f->bindPairs == NULL) f->bindPairs =
return (-1); calloc((size_t)f->numBindPairs, sizeof(*f->bindPairs));
if (f->bindPairs == NULL)
return (-1);
} else
f->bindPairs = NULL;
for (i = 0; i < f->numBindPairs; i++) { for (i = 0; i < f->numBindPairs; i++) {
if (parse_7zip_uint64(a, &(f->bindPairs[i].inIndex)) < 0) if (parse_7zip_uint64(a, &(f->bindPairs[i].inIndex)) < 0)
return (-1); return (-1);
@ -1838,7 +1852,7 @@ read_Folder(struct archive_read *a, struct _7z_folder *f)
f->numPackedStreams = numInStreamsTotal - f->numBindPairs; f->numPackedStreams = numInStreamsTotal - f->numBindPairs;
f->packedStreams = f->packedStreams =
calloc(f->numPackedStreams, sizeof(*f->packedStreams)); calloc((size_t)f->numPackedStreams, sizeof(*f->packedStreams));
if (f->packedStreams == NULL) if (f->packedStreams == NULL)
return (-1); return (-1);
if (f->numPackedStreams == 1) { if (f->numPackedStreams == 1) {
@ -1910,7 +1924,8 @@ read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
goto failed; goto failed;
switch (*p) { switch (*p) {
case 0: case 0:
ci->folders = calloc(ci->numFolders, sizeof(*ci->folders)); ci->folders =
calloc((size_t)ci->numFolders, sizeof(*ci->folders));
if (ci->folders == NULL) if (ci->folders == NULL)
return (-1); return (-1);
for (i = 0; i < ci->numFolders; i++) { for (i = 0; i < ci->numFolders; i++) {
@ -1936,7 +1951,7 @@ read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
unsigned j; unsigned j;
folder->unPackSize = folder->unPackSize =
calloc(folder->numOutStreams, sizeof(*folder->unPackSize)); calloc((size_t)folder->numOutStreams, sizeof(*folder->unPackSize));
if (folder->unPackSize == NULL) if (folder->unPackSize == NULL)
goto failed; goto failed;
for (j = 0; j < folder->numOutStreams; j++) { for (j = 0; j < folder->numOutStreams; j++) {
@ -1954,7 +1969,7 @@ read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
return (0); return (0);
if (*p != kCRC) if (*p != kCRC)
goto failed; goto failed;
if (read_Digests(a, &digest, ci->numFolders) < 0) if (read_Digests(a, &digest, (size_t)ci->numFolders) < 0)
goto failed; goto failed;
for (i = 0; i < ci->numFolders; i++) { for (i = 0; i < ci->numFolders; i++) {
ci->folders[i].digest_defined = digest.defineds[i]; ci->folders[i].digest_defined = digest.defineds[i];
@ -1978,8 +1993,8 @@ failed:
static uint64_t static uint64_t
folder_uncompressed_size(struct _7z_folder *f) folder_uncompressed_size(struct _7z_folder *f)
{ {
int n = f->numOutStreams; int n = (int)f->numOutStreams;
unsigned pairs = f->numBindPairs; unsigned pairs = (unsigned)f->numBindPairs;
while (--n >= 0) { while (--n >= 0) {
unsigned i; unsigned i;
@ -2028,7 +2043,7 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
return (-1); return (-1);
if (1000000 < f[i].numUnpackStreams) if (1000000 < f[i].numUnpackStreams)
return (-1); return (-1);
unpack_streams += f[i].numUnpackStreams; unpack_streams += (size_t)f[i].numUnpackStreams;
} }
if ((p = header_bytes(a, 1)) == NULL) if ((p = header_bytes(a, 1)) == NULL)
return (-1); return (-1);
@ -2082,7 +2097,7 @@ read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
numDigests = 0; numDigests = 0;
for (i = 0; i < numFolders; i++) { for (i = 0; i < numFolders; i++) {
if (f[i].numUnpackStreams != 1 || !f[i].digest_defined) if (f[i].numUnpackStreams != 1 || !f[i].digest_defined)
numDigests += f[i].numUnpackStreams; numDigests += (uint32_t)f[i].numUnpackStreams;
} }
if (type == kCRC) { if (type == kCRC) {
@ -2180,7 +2195,7 @@ read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
f = si->ci.folders; f = si->ci.folders;
for (i = 0; i < si->ci.numFolders; i++) { for (i = 0; i < si->ci.numFolders; i++) {
f[i].packIndex = packIndex; f[i].packIndex = packIndex;
packIndex += f[i].numPackedStreams; packIndex += (uint32_t)f[i].numPackedStreams;
if (packIndex > si->pi.numPackStreams) if (packIndex > si->pi.numPackStreams)
return (-1); return (-1);
} }
@ -2190,7 +2205,7 @@ read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
if (*p == kSubStreamsInfo) { if (*p == kSubStreamsInfo) {
if (read_SubStreamsInfo(a, &(si->ss), if (read_SubStreamsInfo(a, &(si->ss),
si->ci.folders, si->ci.numFolders) < 0) si->ci.folders, (size_t)si->ci.numFolders) < 0)
return (-1); return (-1);
if ((p = header_bytes(a, 1)) == NULL) if ((p = header_bytes(a, 1)) == NULL)
return (-1); return (-1);
@ -2278,7 +2293,7 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
if (1000000 < zip->numFiles) if (1000000 < zip->numFiles)
return (-1); return (-1);
zip->entries = calloc(zip->numFiles, sizeof(*zip->entries)); zip->entries = calloc((size_t)zip->numFiles, sizeof(*zip->entries));
if (zip->entries == NULL) if (zip->entries == NULL)
return (-1); return (-1);
entries = zip->entries; entries = zip->entries;
@ -2303,12 +2318,12 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
switch (type) { switch (type) {
case kEmptyStream: case kEmptyStream:
h->emptyStreamBools = calloc(zip->numFiles, h->emptyStreamBools = calloc((size_t)zip->numFiles,
sizeof(*h->emptyStreamBools)); sizeof(*h->emptyStreamBools));
if (h->emptyStreamBools == NULL) if (h->emptyStreamBools == NULL)
return (-1); return (-1);
if (read_Bools( if (read_Bools(
a, h->emptyStreamBools, zip->numFiles) < 0) a, h->emptyStreamBools, (size_t)zip->numFiles) < 0)
return (-1); return (-1);
empty_streams = 0; empty_streams = 0;
for (i = 0; i < zip->numFiles; i++) { for (i = 0; i < zip->numFiles; i++) {
@ -2317,6 +2332,12 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
} }
break; break;
case kEmptyFile: case kEmptyFile:
if (empty_streams <= 0) {
/* Unexcepted sequence. Skip this. */
if (header_bytes(a, ll) == NULL)
return (-1);
break;
}
h->emptyFileBools = calloc(empty_streams, h->emptyFileBools = calloc(empty_streams,
sizeof(*h->emptyFileBools)); sizeof(*h->emptyFileBools));
if (h->emptyFileBools == NULL) if (h->emptyFileBools == NULL)
@ -2325,6 +2346,12 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
return (-1); return (-1);
break; break;
case kAnti: case kAnti:
if (empty_streams <= 0) {
/* Unexcepted sequence. Skip this. */
if (header_bytes(a, ll) == NULL)
return (-1);
break;
}
h->antiBools = calloc(empty_streams, h->antiBools = calloc(empty_streams,
sizeof(*h->antiBools)); sizeof(*h->antiBools));
if (h->antiBools == NULL) if (h->antiBools == NULL)
@ -2403,15 +2430,15 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
if ((p = header_bytes(a, 2)) == NULL) if ((p = header_bytes(a, 2)) == NULL)
return (-1); return (-1);
allAreDefined = *p; allAreDefined = *p;
h->attrBools = calloc(zip->numFiles, h->attrBools = calloc((size_t)zip->numFiles,
sizeof(*h->attrBools)); sizeof(*h->attrBools));
if (h->attrBools == NULL) if (h->attrBools == NULL)
return (-1); return (-1);
if (allAreDefined) if (allAreDefined)
memset(h->attrBools, 1, zip->numFiles); memset(h->attrBools, 1, (size_t)zip->numFiles);
else { else {
if (read_Bools(a, h->attrBools, if (read_Bools(a, h->attrBools,
zip->numFiles) < 0) (size_t)zip->numFiles) < 0)
return (-1); return (-1);
} }
for (i = 0; i < zip->numFiles; i++) { for (i = 0; i < zip->numFiles; i++) {
@ -2445,7 +2472,7 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
if ((size_t)sindex >= si->ss.unpack_streams) if ((size_t)sindex >= si->ss.unpack_streams)
return (-1); return (-1);
if (entries[i].mode == 0) if (entries[i].mode == 0)
entries[i].mode = AE_IFREG | 0777; entries[i].mode = AE_IFREG | 0666;
if (si->ss.digestsDefined[sindex]) if (si->ss.digestsDefined[sindex])
entries[i].flg |= CRC32_IS_SET; entries[i].flg |= CRC32_IS_SET;
entries[i].ssIndex = sindex; entries[i].ssIndex = sindex;
@ -2465,7 +2492,7 @@ read_Header(struct archive_read *a, struct _7z_header_info *h,
if (dir) if (dir)
entries[i].mode = AE_IFDIR | 0777; entries[i].mode = AE_IFDIR | 0777;
else else
entries[i].mode = AE_IFREG | 0777; entries[i].mode = AE_IFREG | 0666;
} else if (dir && } else if (dir &&
(entries[i].mode & AE_IFMT) != AE_IFDIR) { (entries[i].mode & AE_IFMT) != AE_IFDIR) {
entries[i].mode &= ~AE_IFMT; entries[i].mode &= ~AE_IFMT;
@ -2541,7 +2568,7 @@ read_Times(struct archive_read *a, struct _7z_header_info *h, int type)
int allAreDefined; int allAreDefined;
unsigned i; unsigned i;
timeBools = calloc(zip->numFiles, sizeof(*timeBools)); timeBools = calloc((size_t)zip->numFiles, sizeof(*timeBools));
if (timeBools == NULL) if (timeBools == NULL)
return (-1); return (-1);
@ -2550,9 +2577,9 @@ read_Times(struct archive_read *a, struct _7z_header_info *h, int type)
goto failed; goto failed;
allAreDefined = *p; allAreDefined = *p;
if (allAreDefined) if (allAreDefined)
memset(timeBools, 1, zip->numFiles); memset(timeBools, 1, (size_t)zip->numFiles);
else { else {
if (read_Bools(a, timeBools, zip->numFiles) < 0) if (read_Bools(a, timeBools, (size_t)zip->numFiles) < 0)
goto failed; goto failed;
} }
@ -2563,7 +2590,7 @@ read_Times(struct archive_read *a, struct _7z_header_info *h, int type)
if (parse_7zip_uint64(a, &(h->dataIndex)) < 0) if (parse_7zip_uint64(a, &(h->dataIndex)) < 0)
goto failed; goto failed;
if (1000000 < h->dataIndex) if (1000000 < h->dataIndex)
return (-1); goto failed;
} }
for (i = 0; i < zip->numFiles; i++) { for (i = 0; i < zip->numFiles; i++) {
@ -2897,10 +2924,10 @@ extract_pack_stream(struct archive_read *a, size_t minimum)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if (bytes_avail > (ssize_t)zip->pack_stream_inbytes_remaining) if (bytes_avail > (ssize_t)zip->pack_stream_inbytes_remaining)
bytes_avail = zip->pack_stream_inbytes_remaining; bytes_avail = (ssize_t)zip->pack_stream_inbytes_remaining;
zip->pack_stream_inbytes_remaining -= bytes_avail; zip->pack_stream_inbytes_remaining -= bytes_avail;
if (bytes_avail > (ssize_t)zip->folder_outbytes_remaining) if (bytes_avail > (ssize_t)zip->folder_outbytes_remaining)
bytes_avail = zip->folder_outbytes_remaining; bytes_avail = (ssize_t)zip->folder_outbytes_remaining;
zip->folder_outbytes_remaining -= bytes_avail; zip->folder_outbytes_remaining -= bytes_avail;
zip->uncompressed_buffer_bytes_remaining = bytes_avail; zip->uncompressed_buffer_bytes_remaining = bytes_avail;
return (ARCHIVE_OK); return (ARCHIVE_OK);
@ -2965,7 +2992,7 @@ extract_pack_stream(struct archive_read *a, size_t minimum)
size_t bytes_in, bytes_out; size_t bytes_in, bytes_out;
const void *buff_in; const void *buff_in;
unsigned char *buff_out; unsigned char *buff_out;
int eof; int end_of_data;
/* /*
* Note: '1' here is a performance optimization. * Note: '1' here is a performance optimization.
@ -2987,23 +3014,23 @@ extract_pack_stream(struct archive_read *a, size_t minimum)
- zip->uncompressed_buffer_bytes_remaining; - zip->uncompressed_buffer_bytes_remaining;
bytes_in = bytes_avail; bytes_in = bytes_avail;
if (bytes_in > zip->pack_stream_inbytes_remaining) if (bytes_in > zip->pack_stream_inbytes_remaining)
bytes_in = zip->pack_stream_inbytes_remaining; bytes_in = (size_t)zip->pack_stream_inbytes_remaining;
/* Drive decompression. */ /* Drive decompression. */
r = decompress(a, zip, buff_out, &bytes_out, r = decompress(a, zip, buff_out, &bytes_out,
buff_in, &bytes_in); buff_in, &bytes_in);
switch (r) { switch (r) {
case ARCHIVE_OK: case ARCHIVE_OK:
eof = 0; end_of_data = 0;
break; break;
case ARCHIVE_EOF: case ARCHIVE_EOF:
eof = 1; end_of_data = 1;
break; break;
default: default:
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
zip->pack_stream_inbytes_remaining -= bytes_in; zip->pack_stream_inbytes_remaining -= bytes_in;
if (bytes_out > zip->folder_outbytes_remaining) if (bytes_out > zip->folder_outbytes_remaining)
bytes_out = zip->folder_outbytes_remaining; bytes_out = (size_t)zip->folder_outbytes_remaining;
zip->folder_outbytes_remaining -= bytes_out; zip->folder_outbytes_remaining -= bytes_out;
zip->uncompressed_buffer_bytes_remaining += bytes_out; zip->uncompressed_buffer_bytes_remaining += bytes_out;
zip->pack_stream_bytes_unconsumed = bytes_in; zip->pack_stream_bytes_unconsumed = bytes_in;
@ -3021,7 +3048,7 @@ extract_pack_stream(struct archive_read *a, size_t minimum)
if (zip->pack_stream_inbytes_remaining == 0 && if (zip->pack_stream_inbytes_remaining == 0 &&
zip->folder_outbytes_remaining == 0) zip->folder_outbytes_remaining == 0)
break; break;
if (eof || (bytes_in == 0 && bytes_out == 0)) { if (end_of_data || (bytes_in == 0 && bytes_out == 0)) {
archive_set_error(&(a->archive), archive_set_error(&(a->archive),
ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive"); ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
@ -3160,7 +3187,8 @@ read_stream(struct archive_read *a, const void **buff, size_t size,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
} }
skipped = get_uncompressed_data(a, buff, skip_bytes, 0); skipped = get_uncompressed_data(
a, buff, (size_t)skip_bytes, 0);
if (skipped < 0) if (skipped < 0)
return (skipped); return (skipped);
skip_bytes -= skipped; skip_bytes -= skipped;
@ -3292,13 +3320,13 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
} }
coder2 = &(fc[3]); coder2 = &(fc[3]);
zip->main_stream_bytes_remaining = zip->main_stream_bytes_remaining =
folder->unPackSize[2]; (size_t)folder->unPackSize[2];
} else if (coder2 != NULL && coder2->codec == _7Z_X86_BCJ2 && } else if (coder2 != NULL && coder2->codec == _7Z_X86_BCJ2 &&
zip->pack_stream_remaining == 4 && zip->pack_stream_remaining == 4 &&
folder->numInStreams == 5 && folder->numOutStreams == 2) { folder->numInStreams == 5 && folder->numOutStreams == 2) {
/* Source type 0 made by 7z */ /* Source type 0 made by 7z */
zip->main_stream_bytes_remaining = zip->main_stream_bytes_remaining =
folder->unPackSize[0]; (size_t)folder->unPackSize[0];
} else { } else {
/* We got an unexpected form. */ /* We got an unexpected form. */
archive_set_error(&(a->archive), archive_set_error(&(a->archive),
@ -3311,7 +3339,7 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
if ((r = seek_pack(a)) < 0) if ((r = seek_pack(a)) < 0)
return (r); return (r);
zip->pack_stream_bytes_unconsumed = zip->pack_stream_bytes_unconsumed =
zip->pack_stream_inbytes_remaining; (size_t)zip->pack_stream_inbytes_remaining;
read_consume(a); read_consume(a);
/* Read following three sub streams. */ /* Read following three sub streams. */
@ -3333,7 +3361,7 @@ setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
/* Allocate memory for the decorded data of a sub /* Allocate memory for the decorded data of a sub
* stream. */ * stream. */
b[i] = malloc(zip->folder_outbytes_remaining); b[i] = malloc((size_t)zip->folder_outbytes_remaining);
if (b[i] == NULL) { if (b[i] == NULL) {
archive_set_error(&a->archive, ENOMEM, archive_set_error(&a->archive, ENOMEM,
"No memory for 7-Zip decompression"); "No memory for 7-Zip decompression");
@ -3428,7 +3456,7 @@ skip_stream(struct archive_read *a, size_t skip_bytes)
"Truncated 7-Zip file body"); "Truncated 7-Zip file body");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
bytes -= skipped_bytes; bytes -= (size_t)skipped_bytes;
if (zip->pack_stream_bytes_unconsumed) if (zip->pack_stream_bytes_unconsumed)
read_consume(a); read_consume(a);
} }

View File

@ -292,6 +292,8 @@ struct cab {
char end_of_archive; char end_of_archive;
char end_of_entry; char end_of_entry;
char end_of_entry_cleanup; char end_of_entry_cleanup;
char read_data_invoked;
int64_t bytes_skipped;
unsigned char *uncompressed_buffer; unsigned char *uncompressed_buffer;
size_t uncompressed_buffer_size; size_t uncompressed_buffer_size;
@ -798,7 +800,7 @@ cab_read_header(struct archive_read *a)
file->offset = archive_le32dec(p + CFFILE_uoffFolderStart); file->offset = archive_le32dec(p + CFFILE_uoffFolderStart);
file->folder = archive_le16dec(p + CFFILE_iFolder); file->folder = archive_le16dec(p + CFFILE_iFolder);
file->mtime = cab_dos_time(p + CFFILE_date_time); file->mtime = cab_dos_time(p + CFFILE_date_time);
file->attr = archive_le16dec(p + CFFILE_attribs); file->attr = (uint8_t)archive_le16dec(p + CFFILE_attribs);
__archive_read_consume(a, 16); __archive_read_consume(a, 16);
cab->cab_offset += 16; cab->cab_offset += 16;
@ -988,7 +990,7 @@ archive_read_format_cab_read_header(struct archive_read *a,
if (file->attr & ATTR_RDONLY) if (file->attr & ATTR_RDONLY)
archive_entry_set_mode(entry, AE_IFREG | 0555); archive_entry_set_mode(entry, AE_IFREG | 0555);
else else
archive_entry_set_mode(entry, AE_IFREG | 0777); archive_entry_set_mode(entry, AE_IFREG | 0666);
archive_entry_set_mtime(entry, file->mtime, 0); archive_entry_set_mtime(entry, file->mtime, 0);
cab->entry_bytes_remaining = file->uncompressed_size; cab->entry_bytes_remaining = file->uncompressed_size;
@ -1026,9 +1028,22 @@ archive_read_format_cab_read_data(struct archive_read *a,
default: default:
break; break;
} }
if (cab->read_data_invoked == 0) {
if (cab->bytes_skipped) {
if (cab->entry_cfdata == NULL) {
r = cab_next_cfdata(a);
if (r < 0)
return (r);
}
if (cab_consume_cfdata(a, cab->bytes_skipped) < 0)
return (ARCHIVE_FATAL);
cab->bytes_skipped = 0;
}
cab->read_data_invoked = 1;
}
if (cab->entry_unconsumed) { if (cab->entry_unconsumed) {
/* Consume as much as the compressor actually used. */ /* Consume as much as the compressor actually used. */
r = cab_consume_cfdata(a, cab->entry_unconsumed); r = (int)cab_consume_cfdata(a, cab->entry_unconsumed);
cab->entry_unconsumed = 0; cab->entry_unconsumed = 0;
if (r < 0) if (r < 0)
return (r); return (r);
@ -1358,46 +1373,25 @@ cab_read_ahead_cfdata_none(struct archive_read *a, ssize_t *avail)
struct cab *cab = (struct cab *)(a->format->data); struct cab *cab = (struct cab *)(a->format->data);
struct cfdata *cfdata; struct cfdata *cfdata;
const void *d; const void *d;
int64_t skipped_bytes;
cfdata = cab->entry_cfdata; cfdata = cab->entry_cfdata;
if (cfdata->uncompressed_avail == 0 && /*
cfdata->read_offset > 0) { * Note: '1' here is a performance optimization.
/* we've already skipped some bytes before really read. */ * Recall that the decompression layer returns a count of
skipped_bytes = cfdata->read_offset; * available bytes; asking for more than that forces the
cfdata->read_offset = 0; * decompressor to combine reads by copying data.
cfdata->uncompressed_bytes_remaining += skipped_bytes; */
} else d = __archive_read_ahead(a, 1, avail);
skipped_bytes = 0; if (*avail <= 0) {
do { *avail = truncated_error(a);
/* return (NULL);
* Note: '1' here is a performance optimization. }
* Recall that the decompression layer returns a count of if (*avail > cfdata->uncompressed_bytes_remaining)
* available bytes; asking for more than that forces the *avail = cfdata->uncompressed_bytes_remaining;
* decompressor to combine reads by copying data. cfdata->uncompressed_avail = cfdata->uncompressed_size;
*/ cfdata->unconsumed = *avail;
d = __archive_read_ahead(a, 1, avail); cfdata->sum_ptr = d;
if (*avail <= 0) {
*avail = truncated_error(a);
return (NULL);
}
if (*avail > cfdata->uncompressed_bytes_remaining)
*avail = cfdata->uncompressed_bytes_remaining;
cfdata->uncompressed_avail = cfdata->uncompressed_size;
cfdata->unconsumed = *avail;
cfdata->sum_ptr = d;
if (skipped_bytes > 0) {
skipped_bytes =
cab_minimum_consume_cfdata(a, skipped_bytes);
if (skipped_bytes < 0) {
*avail = ARCHIVE_FATAL;
return (NULL);
}
continue;
}
} while (0);
return (d); return (d);
} }
@ -1543,7 +1537,7 @@ cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
return (NULL); return (NULL);
} }
} }
uavail = cab->stream.total_out; uavail = (uint16_t)cab->stream.total_out;
if (uavail < cfdata->uncompressed_size) { if (uavail < cfdata->uncompressed_size) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@ -1721,7 +1715,7 @@ cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
} }
} }
uavail = cab->xstrm.total_out; uavail = (uint16_t)cab->xstrm.total_out;
/* /*
* Make sure a read pointer advances to next CFDATA. * Make sure a read pointer advances to next CFDATA.
*/ */
@ -1793,9 +1787,8 @@ cab_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
rbytes -= cbytes; rbytes -= cbytes;
if (cfdata->uncompressed_avail == 0 && if (cfdata->uncompressed_avail == 0 &&
(cab->entry_cffolder->comptype == COMPTYPE_NONE || (cab->entry_cffile->folder == iFoldCONTINUED_PREV_AND_NEXT ||
cab->entry_cffile->folder == iFoldCONTINUED_PREV_AND_NEXT || cab->entry_cffile->folder == iFoldCONTINUED_FROM_PREV)) {
cab->entry_cffile->folder == iFoldCONTINUED_FROM_PREV)) {
/* We have not read any data yet. */ /* We have not read any data yet. */
if (cbytes == cfdata->uncompressed_bytes_remaining) { if (cbytes == cfdata->uncompressed_bytes_remaining) {
/* Skip whole current CFDATA. */ /* Skip whole current CFDATA. */
@ -1821,8 +1814,8 @@ cab_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
} }
continue; continue;
} }
cfdata->read_offset += cbytes; cfdata->read_offset += (uint16_t)cbytes;
cfdata->uncompressed_bytes_remaining -= cbytes; cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes;
break; break;
} else if (cbytes == 0) { } else if (cbytes == 0) {
err = cab_next_cfdata(a); err = cab_next_cfdata(a);
@ -1846,7 +1839,7 @@ cab_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
if (avail <= 0) if (avail <= 0)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
if (avail > cbytes) if (avail > cbytes)
avail = cbytes; avail = (ssize_t)cbytes;
if (cab_minimum_consume_cfdata(a, avail) < 0) if (cab_minimum_consume_cfdata(a, avail) < 0)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
cbytes -= avail; cbytes -= avail;
@ -1875,8 +1868,8 @@ cab_minimum_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
else else
cbytes = cfdata->unconsumed; cbytes = cfdata->unconsumed;
rbytes -= cbytes; rbytes -= cbytes;
cfdata->read_offset += cbytes; cfdata->read_offset += (uint16_t)cbytes;
cfdata->uncompressed_bytes_remaining -= cbytes; cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes;
cfdata->unconsumed -= cbytes; cfdata->unconsumed -= cbytes;
} else { } else {
cbytes = cfdata->uncompressed_avail - cfdata->read_offset; cbytes = cfdata->uncompressed_avail - cfdata->read_offset;
@ -1884,8 +1877,8 @@ cab_minimum_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
if (consumed_bytes < cbytes) if (consumed_bytes < cbytes)
cbytes = consumed_bytes; cbytes = consumed_bytes;
rbytes -= cbytes; rbytes -= cbytes;
cfdata->read_offset += cbytes; cfdata->read_offset += (uint16_t)cbytes;
cfdata->uncompressed_bytes_remaining -= cbytes; cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes;
} }
if (cfdata->unconsumed) { if (cfdata->unconsumed) {
@ -1896,12 +1889,12 @@ cab_minimum_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
} }
if (cbytes) { if (cbytes) {
/* Compute the sum. */ /* Compute the sum. */
cab_checksum_update(a, cbytes); cab_checksum_update(a, (size_t)cbytes);
/* Consume as much as the compressor actually used. */ /* Consume as much as the compressor actually used. */
__archive_read_consume(a, cbytes); __archive_read_consume(a, cbytes);
cab->cab_offset += cbytes; cab->cab_offset += cbytes;
cfdata->compressed_bytes_remaining -= cbytes; cfdata->compressed_bytes_remaining -= (uint16_t)cbytes;
if (cfdata->compressed_bytes_remaining == 0) { if (cfdata->compressed_bytes_remaining == 0) {
err = cab_checksum_finish(a); err = cab_checksum_finish(a);
if (err < 0) if (err < 0)
@ -1945,7 +1938,7 @@ cab_read_data(struct archive_read *a, const void **buff,
return (bytes_avail); return (bytes_avail);
} }
if (bytes_avail > cab->entry_bytes_remaining) if (bytes_avail > cab->entry_bytes_remaining)
bytes_avail = cab->entry_bytes_remaining; bytes_avail = (ssize_t)cab->entry_bytes_remaining;
*size = bytes_avail; *size = bytes_avail;
*offset = cab->entry_offset; *offset = cab->entry_offset;
@ -1954,6 +1947,11 @@ cab_read_data(struct archive_read *a, const void **buff,
if (cab->entry_bytes_remaining == 0) if (cab->entry_bytes_remaining == 0)
cab->end_of_entry = 1; cab->end_of_entry = 1;
cab->entry_unconsumed = bytes_avail; cab->entry_unconsumed = bytes_avail;
if (cab->entry_cffolder->comptype == COMPTYPE_NONE) {
/* Don't consume more than current entry used. */
if (cab->entry_cfdata->unconsumed > cab->entry_unconsumed)
cab->entry_cfdata->unconsumed = cab->entry_unconsumed;
}
return (ARCHIVE_OK); return (ARCHIVE_OK);
} }
@ -1969,9 +1967,17 @@ archive_read_format_cab_read_data_skip(struct archive_read *a)
if (cab->end_of_archive) if (cab->end_of_archive)
return (ARCHIVE_EOF); return (ARCHIVE_EOF);
if (!cab->read_data_invoked) {
cab->bytes_skipped += cab->entry_bytes_remaining;
cab->entry_bytes_remaining = 0;
/* This entry is finished and done. */
cab->end_of_entry_cleanup = cab->end_of_entry = 1;
return (ARCHIVE_OK);
}
if (cab->entry_unconsumed) { if (cab->entry_unconsumed) {
/* Consume as much as the compressor actually used. */ /* Consume as much as the compressor actually used. */
r = cab_consume_cfdata(a, cab->entry_unconsumed); r = (int)cab_consume_cfdata(a, cab->entry_unconsumed);
cab->entry_unconsumed = 0; cab->entry_unconsumed = 0;
if (r < 0) if (r < 0)
return (r); return (r);
@ -1993,6 +1999,11 @@ archive_read_format_cab_read_data_skip(struct archive_read *a)
if (bytes_skipped < 0) if (bytes_skipped < 0)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
/* If the compression type is none(uncompressed), we've already
* consumed data as much as the current entry size. */
if (cab->entry_cffolder->comptype == COMPTYPE_NONE)
cab->entry_cfdata->unconsumed = 0;
/* This entry is finished and done. */ /* This entry is finished and done. */
cab->end_of_entry_cleanup = cab->end_of_entry = 1; cab->end_of_entry_cleanup = cab->end_of_entry = 1;
return (ARCHIVE_OK); return (ARCHIVE_OK);
@ -2227,7 +2238,9 @@ lzx_translation(struct lzx_stream *strm, void *p, size_t size, uint32_t offset)
/* Notify how many bits we consumed. */ /* Notify how many bits we consumed. */
#define lzx_br_consume(br, n) ((br)->cache_avail -= (n)) #define lzx_br_consume(br, n) ((br)->cache_avail -= (n))
#define lzx_br_consume_unalined_bits(br) ((br)->cache_avail &= ~0x0f) #define lzx_br_consume_unaligned_bits(br) ((br)->cache_avail &= ~0x0f)
#define lzx_br_is_unaligned(br) ((br)->cache_avail & 0x0f)
static const uint32_t cache_masks[] = { static const uint32_t cache_masks[] = {
0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x00000000, 0x00000001, 0x00000003, 0x00000007,
@ -2354,24 +2367,25 @@ lzx_cleanup_bitstream(struct lzx_stream *strm)
#define ST_RD_TRANSLATION_SIZE 1 #define ST_RD_TRANSLATION_SIZE 1
#define ST_RD_BLOCK_TYPE 2 #define ST_RD_BLOCK_TYPE 2
#define ST_RD_BLOCK_SIZE 3 #define ST_RD_BLOCK_SIZE 3
#define ST_RD_R0 4 #define ST_RD_ALIGNMENT 4
#define ST_RD_R1 5 #define ST_RD_R0 5
#define ST_RD_R2 6 #define ST_RD_R1 6
#define ST_COPY_UNCOMP1 7 #define ST_RD_R2 7
#define ST_COPY_UNCOMP2 8 #define ST_COPY_UNCOMP1 8
#define ST_RD_ALIGNED_OFFSET 9 #define ST_COPY_UNCOMP2 9
#define ST_RD_VERBATIM 10 #define ST_RD_ALIGNED_OFFSET 10
#define ST_RD_PRE_MAIN_TREE_256 11 #define ST_RD_VERBATIM 11
#define ST_MAIN_TREE_256 12 #define ST_RD_PRE_MAIN_TREE_256 12
#define ST_RD_PRE_MAIN_TREE_REM 13 #define ST_MAIN_TREE_256 13
#define ST_MAIN_TREE_REM 14 #define ST_RD_PRE_MAIN_TREE_REM 14
#define ST_RD_PRE_LENGTH_TREE 15 #define ST_MAIN_TREE_REM 15
#define ST_LENGTH_TREE 16 #define ST_RD_PRE_LENGTH_TREE 16
#define ST_MAIN 17 #define ST_LENGTH_TREE 17
#define ST_LENGTH 18 #define ST_MAIN 18
#define ST_OFFSET 19 #define ST_LENGTH 19
#define ST_REAL_POS 20 #define ST_OFFSET 20
#define ST_COPY 21 #define ST_REAL_POS 21
#define ST_COPY 22
static int static int
lzx_decode(struct lzx_stream *strm, int last) lzx_decode(struct lzx_stream *strm, int last)
@ -2475,15 +2489,25 @@ lzx_read_blocks(struct lzx_stream *strm, int last)
ds->state = ST_RD_ALIGNED_OFFSET; ds->state = ST_RD_ALIGNED_OFFSET;
break; break;
} }
/* FALL THROUGH */
case ST_RD_ALIGNMENT:
/* /*
* Handle an Uncompressed Block. * Handle an Uncompressed Block.
*/ */
/* Skip padding to align following field on /* Skip padding to align following field on
* 16-bit boundary. */ * 16-bit boundary. */
if (br->cache_avail == 32 || br->cache_avail == 16) if (lzx_br_is_unaligned(br))
lzx_br_consume(br, 16); lzx_br_consume_unaligned_bits(br);
else else {
lzx_br_consume_unalined_bits(br); if (lzx_br_read_ahead(strm, br, 16))
lzx_br_consume(br, 16);
else {
ds->state = ST_RD_ALIGNMENT;
if (last)
goto failed;
return (ARCHIVE_OK);
}
}
/* Preparation to read repeated offsets R0,R1 and R2. */ /* Preparation to read repeated offsets R0,R1 and R2. */
ds->rbytes_avail = 0; ds->rbytes_avail = 0;
ds->state = ST_RD_R0; ds->state = ST_RD_R0;
@ -2508,8 +2532,7 @@ lzx_read_blocks(struct lzx_stream *strm, int last)
lzx_br_consume(br, 16); lzx_br_consume(br, 16);
archive_le16enc(ds->rbytes, u16); archive_le16enc(ds->rbytes, u16);
ds->rbytes_avail = 2; ds->rbytes_avail = 2;
} else }
ds->rbytes_avail = 0;
if (ds->rbytes_avail < 4 && ds->br.have_odd) { if (ds->rbytes_avail < 4 && ds->br.have_odd) {
ds->rbytes[ds->rbytes_avail++] = ds->rbytes[ds->rbytes_avail++] =
ds->br.odd; ds->br.odd;
@ -2525,6 +2548,7 @@ lzx_read_blocks(struct lzx_stream *strm, int last)
*strm->next_in++; *strm->next_in++;
strm->avail_in--; strm->avail_in--;
} }
ds->rbytes_avail = 0;
if (ds->state == ST_RD_R0) { if (ds->state == ST_RD_R0) {
ds->r0 = archive_le32dec(ds->rbytes); ds->r0 = archive_le32dec(ds->rbytes);
if (ds->r0 < 0) if (ds->r0 < 0)
@ -2549,8 +2573,7 @@ lzx_read_blocks(struct lzx_stream *strm, int last)
* Copy bytes form next_in to next_out directly. * Copy bytes form next_in to next_out directly.
*/ */
while (ds->block_bytes_avail) { while (ds->block_bytes_avail) {
unsigned char *d; int l;
int l,ll;
if (strm->avail_out <= 0) if (strm->avail_out <= 0)
/* Output buffer is empty. */ /* Output buffer is empty. */
@ -2568,17 +2591,16 @@ lzx_read_blocks(struct lzx_stream *strm, int last)
l = (int)strm->avail_out; l = (int)strm->avail_out;
if (l > strm->avail_in) if (l > strm->avail_in)
l = (int)strm->avail_in; l = (int)strm->avail_in;
ll = l; memcpy(strm->next_out, strm->next_in, l);
d = &(ds->w_buff[ds->w_pos]); memcpy(&(ds->w_buff[ds->w_pos]),
while (--l >= 0) { strm->next_in, l);
*strm->next_out++ = *strm->next_in; strm->next_in += l;
*d++ = *strm->next_in++; strm->avail_in -= l;
} strm->next_out += l;
strm->avail_out -= ll; strm->avail_out -= l;
strm->total_out += ll; strm->total_out += l;
strm->avail_in -= ll; ds->w_pos = (ds->w_pos + l) & ds->w_mask;
ds->w_pos = (ds->w_pos + ll) & ds->w_mask; ds->block_bytes_avail -= l;
ds->block_bytes_avail -= ll;
} }
/* FALL THROUGH */ /* FALL THROUGH */
case ST_COPY_UNCOMP2: case ST_COPY_UNCOMP2:

View File

@ -398,11 +398,12 @@ archive_read_format_cpio_read_header(struct archive_read *a,
/* If this is a symlink, read the link contents. */ /* If this is a symlink, read the link contents. */
if (archive_entry_filetype(entry) == AE_IFLNK) { if (archive_entry_filetype(entry) == AE_IFLNK) {
h = __archive_read_ahead(a, cpio->entry_bytes_remaining, NULL); h = __archive_read_ahead(a,
(size_t)cpio->entry_bytes_remaining, NULL);
if (h == NULL) if (h == NULL)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
if (archive_entry_copy_symlink_l(entry, (const char *)h, if (archive_entry_copy_symlink_l(entry, (const char *)h,
cpio->entry_bytes_remaining, sconv) != 0) { (size_t)cpio->entry_bytes_remaining, sconv) != 0) {
if (errno == ENOMEM) { if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM, archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for Linkname"); "Can't allocate memory for Linkname");
@ -458,7 +459,7 @@ archive_read_format_cpio_read_data(struct archive_read *a,
if (bytes_read <= 0) if (bytes_read <= 0)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
if (bytes_read > cpio->entry_bytes_remaining) if (bytes_read > cpio->entry_bytes_remaining)
bytes_read = cpio->entry_bytes_remaining; bytes_read = (ssize_t)cpio->entry_bytes_remaining;
*size = bytes_read; *size = bytes_read;
cpio->entry_bytes_unconsumed = bytes_read; cpio->entry_bytes_unconsumed = bytes_read;
*offset = cpio->entry_offset; *offset = cpio->entry_offset;
@ -603,17 +604,23 @@ header_newc(struct archive_read *a, struct cpio *cpio,
/* TODO: Abort here? */ /* TODO: Abort here? */
} }
archive_entry_set_devmajor(entry, atol16(header + newc_devmajor_offset, newc_devmajor_size)); archive_entry_set_devmajor(entry,
archive_entry_set_devminor(entry, atol16(header + newc_devminor_offset, newc_devminor_size)); (dev_t)atol16(header + newc_devmajor_offset, newc_devmajor_size));
archive_entry_set_devminor(entry,
(dev_t)atol16(header + newc_devminor_offset, newc_devminor_size));
archive_entry_set_ino(entry, atol16(header + newc_ino_offset, newc_ino_size)); archive_entry_set_ino(entry, atol16(header + newc_ino_offset, newc_ino_size));
archive_entry_set_mode(entry, atol16(header + newc_mode_offset, newc_mode_size)); archive_entry_set_mode(entry,
(mode_t)atol16(header + newc_mode_offset, newc_mode_size));
archive_entry_set_uid(entry, atol16(header + newc_uid_offset, newc_uid_size)); archive_entry_set_uid(entry, atol16(header + newc_uid_offset, newc_uid_size));
archive_entry_set_gid(entry, atol16(header + newc_gid_offset, newc_gid_size)); archive_entry_set_gid(entry, atol16(header + newc_gid_offset, newc_gid_size));
archive_entry_set_nlink(entry, atol16(header + newc_nlink_offset, newc_nlink_size)); archive_entry_set_nlink(entry,
archive_entry_set_rdevmajor(entry, atol16(header + newc_rdevmajor_offset, newc_rdevmajor_size)); (unsigned int)atol16(header + newc_nlink_offset, newc_nlink_size));
archive_entry_set_rdevminor(entry, atol16(header + newc_rdevminor_offset, newc_rdevminor_size)); archive_entry_set_rdevmajor(entry,
(dev_t)atol16(header + newc_rdevmajor_offset, newc_rdevmajor_size));
archive_entry_set_rdevminor(entry,
(dev_t)atol16(header + newc_rdevminor_offset, newc_rdevminor_size));
archive_entry_set_mtime(entry, atol16(header + newc_mtime_offset, newc_mtime_size), 0); archive_entry_set_mtime(entry, atol16(header + newc_mtime_offset, newc_mtime_size), 0);
*namelength = atol16(header + newc_namesize_offset, newc_namesize_size); *namelength = (size_t)atol16(header + newc_namesize_offset, newc_namesize_size);
/* Pad name to 2 more than a multiple of 4. */ /* Pad name to 2 more than a multiple of 4. */
*name_pad = (2 - *namelength) & 3; *name_pad = (2 - *namelength) & 3;
@ -767,15 +774,19 @@ header_odc(struct archive_read *a, struct cpio *cpio,
/* Parse out octal fields. */ /* Parse out octal fields. */
header = (const char *)h; header = (const char *)h;
archive_entry_set_dev(entry, atol8(header + odc_dev_offset, odc_dev_size)); archive_entry_set_dev(entry,
(dev_t)atol8(header + odc_dev_offset, odc_dev_size));
archive_entry_set_ino(entry, atol8(header + odc_ino_offset, odc_ino_size)); archive_entry_set_ino(entry, atol8(header + odc_ino_offset, odc_ino_size));
archive_entry_set_mode(entry, atol8(header + odc_mode_offset, odc_mode_size)); archive_entry_set_mode(entry,
(mode_t)atol8(header + odc_mode_offset, odc_mode_size));
archive_entry_set_uid(entry, atol8(header + odc_uid_offset, odc_uid_size)); archive_entry_set_uid(entry, atol8(header + odc_uid_offset, odc_uid_size));
archive_entry_set_gid(entry, atol8(header + odc_gid_offset, odc_gid_size)); archive_entry_set_gid(entry, atol8(header + odc_gid_offset, odc_gid_size));
archive_entry_set_nlink(entry, atol8(header + odc_nlink_offset, odc_nlink_size)); archive_entry_set_nlink(entry,
archive_entry_set_rdev(entry, atol8(header + odc_rdev_offset, odc_rdev_size)); (unsigned int)atol8(header + odc_nlink_offset, odc_nlink_size));
archive_entry_set_rdev(entry,
(dev_t)atol8(header + odc_rdev_offset, odc_rdev_size));
archive_entry_set_mtime(entry, atol8(header + odc_mtime_offset, odc_mtime_size), 0); archive_entry_set_mtime(entry, atol8(header + odc_mtime_offset, odc_mtime_size), 0);
*namelength = atol8(header + odc_namesize_offset, odc_namesize_size); *namelength = (size_t)atol8(header + odc_namesize_offset, odc_namesize_size);
*name_pad = 0; /* No padding of filename. */ *name_pad = 0; /* No padding of filename. */
/* /*
@ -816,15 +827,19 @@ header_afiol(struct archive_read *a, struct cpio *cpio,
/* Parse out octal fields. */ /* Parse out octal fields. */
header = (const char *)h; header = (const char *)h;
archive_entry_set_dev(entry, atol16(header + afiol_dev_offset, afiol_dev_size)); archive_entry_set_dev(entry,
(dev_t)atol16(header + afiol_dev_offset, afiol_dev_size));
archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size)); archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size));
archive_entry_set_mode(entry, atol8(header + afiol_mode_offset, afiol_mode_size)); archive_entry_set_mode(entry,
(mode_t)atol8(header + afiol_mode_offset, afiol_mode_size));
archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size)); archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size));
archive_entry_set_gid(entry, atol16(header + afiol_gid_offset, afiol_gid_size)); archive_entry_set_gid(entry, atol16(header + afiol_gid_offset, afiol_gid_size));
archive_entry_set_nlink(entry, atol16(header + afiol_nlink_offset, afiol_nlink_size)); archive_entry_set_nlink(entry,
archive_entry_set_rdev(entry, atol16(header + afiol_rdev_offset, afiol_rdev_size)); (unsigned int)atol16(header + afiol_nlink_offset, afiol_nlink_size));
archive_entry_set_rdev(entry,
(dev_t)atol16(header + afiol_rdev_offset, afiol_rdev_size));
archive_entry_set_mtime(entry, atol16(header + afiol_mtime_offset, afiol_mtime_size), 0); archive_entry_set_mtime(entry, atol16(header + afiol_mtime_offset, afiol_mtime_size), 0);
*namelength = atol16(header + afiol_namesize_offset, afiol_namesize_size); *namelength = (size_t)atol16(header + afiol_namesize_offset, afiol_namesize_size);
*name_pad = 0; /* No padding of filename. */ *name_pad = 0; /* No padding of filename. */
cpio->entry_bytes_remaining = cpio->entry_bytes_remaining =

View File

@ -975,8 +975,8 @@ read_children(struct archive_read *a, struct file_info *parent)
iso9660->current_position = parent->offset; iso9660->current_position = parent->offset;
} }
step = ((parent->size + iso9660->logical_block_size -1) / step = (size_t)(((parent->size + iso9660->logical_block_size -1) /
iso9660->logical_block_size) * iso9660->logical_block_size; iso9660->logical_block_size) * iso9660->logical_block_size);
b = __archive_read_ahead(a, step, NULL); b = __archive_read_ahead(a, step, NULL);
if (b == NULL) { if (b == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@ -1397,7 +1397,7 @@ zisofs_read_data(struct archive_read *a,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if (bytes_read > iso9660->entry_bytes_remaining) if (bytes_read > iso9660->entry_bytes_remaining)
bytes_read = iso9660->entry_bytes_remaining; bytes_read = (ssize_t)iso9660->entry_bytes_remaining;
avail = bytes_read; avail = bytes_read;
uncompressed_size = 0; uncompressed_size = 0;
@ -1405,9 +1405,9 @@ zisofs_read_data(struct archive_read *a,
size_t ceil, xsize; size_t ceil, xsize;
/* Allocate block pointers buffer. */ /* Allocate block pointers buffer. */
ceil = (zisofs->pz_uncompressed_size + ceil = (size_t)((zisofs->pz_uncompressed_size +
(1LL << zisofs->pz_log2_bs) - 1) (((int64_t)1) << zisofs->pz_log2_bs) - 1)
>> zisofs->pz_log2_bs; >> zisofs->pz_log2_bs);
xsize = (ceil + 1) * 4; xsize = (ceil + 1) * 4;
if (zisofs->block_pointers_alloc < xsize) { if (zisofs->block_pointers_alloc < xsize) {
size_t alloc; size_t alloc;
@ -1671,7 +1671,7 @@ archive_read_format_iso9660_read_data(struct archive_read *a,
if (*buff == NULL) if (*buff == NULL)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
if (bytes_read > iso9660->entry_bytes_remaining) if (bytes_read > iso9660->entry_bytes_remaining)
bytes_read = iso9660->entry_bytes_remaining; bytes_read = (ssize_t)iso9660->entry_bytes_remaining;
*size = bytes_read; *size = bytes_read;
*offset = iso9660->entry_sparse_offset; *offset = iso9660->entry_sparse_offset;
iso9660->entry_sparse_offset += bytes_read; iso9660->entry_sparse_offset += bytes_read;
@ -2277,7 +2277,7 @@ register_CE(struct archive_read *a, int32_t location,
archive_set_error(&a->archive, ENOMEM, "Out of memory"); archive_set_error(&a->archive, ENOMEM, "Out of memory");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
p = malloc(new_size * sizeof(p[0])); p = calloc(new_size, sizeof(p[0]));
if (p == NULL) { if (p == NULL) {
archive_set_error(&a->archive, ENOMEM, "Out of memory"); archive_set_error(&a->archive, ENOMEM, "Out of memory");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
@ -2527,9 +2527,6 @@ parse_rockridge_SL1(struct file_info *file, const unsigned char *data,
if (!file->symlink_continues || file->symlink.length < 1) if (!file->symlink_continues || file->symlink.length < 1)
archive_string_empty(&file->symlink); archive_string_empty(&file->symlink);
else if (!file->symlink_continues &&
file->symlink.s[file->symlink.length - 1] != '/')
separator = "/";
file->symlink_continues = 0; file->symlink_continues = 0;
/* /*
@ -3099,6 +3096,8 @@ isodate7(const unsigned char *v)
{ {
struct tm tm; struct tm tm;
int offset; int offset;
time_t t;
memset(&tm, 0, sizeof(tm)); memset(&tm, 0, sizeof(tm));
tm.tm_year = v[0]; tm.tm_year = v[0];
tm.tm_mon = v[1] - 1; tm.tm_mon = v[1] - 1;
@ -3112,7 +3111,10 @@ isodate7(const unsigned char *v)
tm.tm_hour -= offset / 4; tm.tm_hour -= offset / 4;
tm.tm_min -= (offset % 4) * 15; tm.tm_min -= (offset % 4) * 15;
} }
return (time_from_tm(&tm)); t = time_from_tm(&tm);
if (t == (time_t)-1)
return ((time_t)0);
return (t);
} }
static time_t static time_t
@ -3120,6 +3122,8 @@ isodate17(const unsigned char *v)
{ {
struct tm tm; struct tm tm;
int offset; int offset;
time_t t;
memset(&tm, 0, sizeof(tm)); memset(&tm, 0, sizeof(tm));
tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100 tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
+ (v[2] - '0') * 10 + (v[3] - '0') + (v[2] - '0') * 10 + (v[3] - '0')
@ -3135,7 +3139,10 @@ isodate17(const unsigned char *v)
tm.tm_hour -= offset / 4; tm.tm_hour -= offset / 4;
tm.tm_min -= (offset % 4) * 15; tm.tm_min -= (offset % 4) * 15;
} }
return (time_from_tm(&tm)); t = time_from_tm(&tm);
if (t == (time_t)-1)
return ((time_t)0);
return (t);
} }
static time_t static time_t
@ -3149,7 +3156,8 @@ time_from_tm(struct tm *t)
#else #else
/* Else use direct calculation using POSIX assumptions. */ /* Else use direct calculation using POSIX assumptions. */
/* First, fix up tm_yday based on the year/month/day. */ /* First, fix up tm_yday based on the year/month/day. */
mktime(t); if (mktime(t) == (time_t)-1)
return ((time_t)-1);
/* Then we can compute timegm() from first principles. */ /* Then we can compute timegm() from first principles. */
return (t->tm_sec + t->tm_min * 60 + t->tm_hour * 3600 return (t->tm_sec + t->tm_min * 60 + t->tm_hour * 3600
+ t->tm_yday * 86400 + (t->tm_year - 70) * 31536000 + t->tm_yday * 86400 + (t->tm_year - 70) * 31536000

View File

@ -951,7 +951,7 @@ lha_read_file_header_1(struct archive_read *a, struct lha *lha)
/* Read extended headers */ /* Read extended headers */
err2 = lha_read_file_extended_header(a, lha, NULL, 2, err2 = lha_read_file_extended_header(a, lha, NULL, 2,
lha->compsize + 2, &extdsize); (size_t)(lha->compsize + 2), &extdsize);
if (err2 < ARCHIVE_WARN) if (err2 < ARCHIVE_WARN)
return (err2); return (err2);
if (err2 < err) if (err2 < err)
@ -1446,7 +1446,7 @@ lha_read_data_none(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if (bytes_avail > lha->entry_bytes_remaining) if (bytes_avail > lha->entry_bytes_remaining)
bytes_avail = lha->entry_bytes_remaining; bytes_avail = (ssize_t)lha->entry_bytes_remaining;
lha->entry_crc_calculated = lha->entry_crc_calculated =
lha_crc16(lha->entry_crc_calculated, *buff, bytes_avail); lha_crc16(lha->entry_crc_calculated, *buff, bytes_avail);
*size = bytes_avail; *size = bytes_avail;
@ -1529,7 +1529,7 @@ lha_read_data_lzh(struct archive_read *a, const void **buff,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if (bytes_avail > lha->entry_bytes_remaining) if (bytes_avail > lha->entry_bytes_remaining)
bytes_avail = lha->entry_bytes_remaining; bytes_avail = (ssize_t)lha->entry_bytes_remaining;
lha->strm.avail_in = bytes_avail; lha->strm.avail_in = bytes_avail;
lha->strm.total_in = 0; lha->strm.total_in = 0;
@ -1575,7 +1575,7 @@ static int
archive_read_format_lha_read_data_skip(struct archive_read *a) archive_read_format_lha_read_data_skip(struct archive_read *a)
{ {
struct lha *lha; struct lha *lha;
off_t bytes_skipped; int64_t bytes_skipped;
lha = (struct lha *)(a->format->data); lha = (struct lha *)(a->format->data);
@ -2016,7 +2016,7 @@ lzh_copy_from_window(struct lzh_stream *strm, struct lzh_dec *ds)
if (ds->w_pos - ds->copy_pos <= strm->avail_out) if (ds->w_pos - ds->copy_pos <= strm->avail_out)
copy_bytes = ds->w_pos - ds->copy_pos; copy_bytes = ds->w_pos - ds->copy_pos;
else else
copy_bytes = strm->avail_out; copy_bytes = (size_t)strm->avail_out;
memcpy(strm->next_out, memcpy(strm->next_out,
ds->w_buff + ds->copy_pos, copy_bytes); ds->w_buff + ds->copy_pos, copy_bytes);
ds->copy_pos += copy_bytes; ds->copy_pos += copy_bytes;
@ -2024,7 +2024,7 @@ lzh_copy_from_window(struct lzh_stream *strm, struct lzh_dec *ds)
if (ds->w_remaining <= strm->avail_out) if (ds->w_remaining <= strm->avail_out)
copy_bytes = ds->w_remaining; copy_bytes = ds->w_remaining;
else else
copy_bytes = strm->avail_out; copy_bytes = (size_t)strm->avail_out;
memcpy(strm->next_out, memcpy(strm->next_out,
ds->w_buff + ds->w_size - ds->w_remaining, copy_bytes); ds->w_buff + ds->w_size - ds->w_remaining, copy_bytes);
ds->w_remaining -= copy_bytes; ds->w_remaining -= copy_bytes;

View File

@ -1183,7 +1183,7 @@ parse_device(struct archive *a, struct archive_entry *entry, char *val)
comma1 = strchr(val, ','); comma1 = strchr(val, ',');
if (comma1 == NULL) { if (comma1 == NULL) {
archive_entry_set_dev(entry, mtree_atol10(&val)); archive_entry_set_dev(entry, (dev_t)mtree_atol10(&val));
return (ARCHIVE_OK); return (ARCHIVE_OK);
} }
++comma1; ++comma1;
@ -1194,8 +1194,8 @@ parse_device(struct archive *a, struct archive_entry *entry, char *val)
return (ARCHIVE_WARN); return (ARCHIVE_WARN);
} }
++comma2; ++comma2;
archive_entry_set_rdevmajor(entry, mtree_atol(&comma1)); archive_entry_set_rdevmajor(entry, (dev_t)mtree_atol(&comma1));
archive_entry_set_rdevminor(entry, mtree_atol(&comma2)); archive_entry_set_rdevminor(entry, (dev_t)mtree_atol(&comma2));
return (ARCHIVE_OK); return (ARCHIVE_OK);
} }
@ -1280,7 +1280,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
if (val[0] >= '0' && val[0] <= '9') { if (val[0] >= '0' && val[0] <= '9') {
*parsed_kws |= MTREE_HAS_PERM; *parsed_kws |= MTREE_HAS_PERM;
archive_entry_set_perm(entry, archive_entry_set_perm(entry,
mtree_atol8(&val)); (mode_t)mtree_atol8(&val));
} else { } else {
archive_set_error(&a->archive, archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT, ARCHIVE_ERRNO_FILE_FORMAT,
@ -1292,7 +1292,8 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
case 'n': case 'n':
if (strcmp(key, "nlink") == 0) { if (strcmp(key, "nlink") == 0) {
*parsed_kws |= MTREE_HAS_NLINK; *parsed_kws |= MTREE_HAS_NLINK;
archive_entry_set_nlink(entry, mtree_atol10(&val)); archive_entry_set_nlink(entry,
(unsigned int)mtree_atol10(&val));
break; break;
} }
case 'r': case 'r':
@ -1434,7 +1435,7 @@ read_data(struct archive_read *a, const void **buff, size_t *size, int64_t *offs
*buff = mtree->buff; *buff = mtree->buff;
*offset = mtree->offset; *offset = mtree->offset;
if ((int64_t)mtree->buffsize > mtree->cur_size - mtree->offset) if ((int64_t)mtree->buffsize > mtree->cur_size - mtree->offset)
bytes_to_read = mtree->cur_size - mtree->offset; bytes_to_read = (size_t)(mtree->cur_size - mtree->offset);
else else
bytes_to_read = mtree->buffsize; bytes_to_read = mtree->buffsize;
bytes_read = read(mtree->fd, mtree->buff, bytes_to_read); bytes_read = read(mtree->fd, mtree->buff, bytes_to_read);

View File

@ -453,7 +453,7 @@ rar_br_fillup(struct archive_read *a, struct rar_br *br)
if (br->next_in == NULL) if (br->next_in == NULL)
return (0); return (0);
if (br->avail_in > rar->bytes_remaining) if (br->avail_in > rar->bytes_remaining)
br->avail_in = rar->bytes_remaining; br->avail_in = (ssize_t)rar->bytes_remaining;
if (br->avail_in == 0) if (br->avail_in == 0)
return (0); return (0);
} }
@ -481,7 +481,7 @@ rar_br_preparation(struct archive_read *a, struct rar_br *br)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if (br->avail_in > rar->bytes_remaining) if (br->avail_in > rar->bytes_remaining)
br->avail_in = rar->bytes_remaining; br->avail_in = (ssize_t)rar->bytes_remaining;
if (br->cache_avail == 0) if (br->cache_avail == 0)
(void)rar_br_fillup(a, br); (void)rar_br_fillup(a, br);
} }
@ -522,7 +522,7 @@ lzss_size(struct lzss *lzss)
static inline int static inline int
lzss_offset_for_position(struct lzss *lzss, int64_t pos) lzss_offset_for_position(struct lzss *lzss, int64_t pos)
{ {
return pos & lzss->mask; return (int)(pos & lzss->mask);
} }
static inline unsigned char * static inline unsigned char *
@ -1084,11 +1084,11 @@ read_header(struct archive_read *a, struct archive_entry *entry,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL) if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
/* File Header CRC check. */ /* File Header CRC check. */
crc32_val = crc32(crc32_val, h, header_size - 7); crc32_val = crc32(crc32_val, h, (unsigned)(header_size - 7));
if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) { if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Header CRC error"); "Header CRC error");
@ -1131,9 +1131,6 @@ read_header(struct archive_read *a, struct archive_entry *entry,
rar->unp_size = archive_le32dec(file_header.unp_size); rar->unp_size = archive_le32dec(file_header.unp_size);
} }
/* TODO: Need to use CRC check for these kind of cases.
* For now, check if sizes are not < 0.
*/
if (rar->packed_size < 0 || rar->unp_size < 0) if (rar->packed_size < 0 || rar->unp_size < 0)
{ {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@ -1148,7 +1145,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
size_t distance = p - (const char *)h; size_t distance = p - (const char *)h;
header_size += rar->packed_size; header_size += rar->packed_size;
/* Make sure we have the extended data. */ /* Make sure we have the extended data. */
if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL) if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
p = h; p = h;
endp = p + header_size - 7; endp = p + header_size - 7;
@ -1161,13 +1158,17 @@ read_header(struct archive_read *a, struct archive_entry *entry,
"Invalid filename size"); "Invalid filename size");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if (rar->filename_allocated < filename_size+2) { if (rar->filename_allocated < filename_size * 2 + 2) {
rar->filename = realloc(rar->filename, filename_size+2); char *newptr;
if (rar->filename == NULL) { size_t newsize = filename_size * 2 + 2;
newptr = realloc(rar->filename, newsize);
if (newptr == NULL) {
archive_set_error(&a->archive, ENOMEM, archive_set_error(&a->archive, ENOMEM,
"Couldn't allocate memory."); "Couldn't allocate memory.");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
rar->filename = newptr;
rar->filename_allocated = newsize;
} }
filename = rar->filename; filename = rar->filename;
memcpy(filename, p, filename_size); memcpy(filename, p, filename_size);
@ -1176,15 +1177,17 @@ read_header(struct archive_read *a, struct archive_entry *entry,
{ {
if (filename_size != strlen(filename)) if (filename_size != strlen(filename))
{ {
unsigned char highbyte, flagbits, flagbyte, length, offset; unsigned char highbyte, flagbits, flagbyte, offset;
unsigned fn_end;
end = filename_size; end = filename_size;
fn_end = filename_size * 2;
filename_size = 0; filename_size = 0;
offset = strlen(filename) + 1; offset = strlen(filename) + 1;
highbyte = *(p + offset++); highbyte = *(p + offset++);
flagbits = 0; flagbits = 0;
flagbyte = 0; flagbyte = 0;
while (offset < end && filename_size < end) while (offset < end && filename_size < fn_end)
{ {
if (!flagbits) if (!flagbits)
{ {
@ -1210,19 +1213,26 @@ read_header(struct archive_read *a, struct archive_entry *entry,
break; break;
case 3: case 3:
{ {
length = *(p + offset++); char extra, high;
while (length) uint8_t length = *(p + offset++);
{
if (filename_size >= end) if (length & 0x80) {
break; extra = *(p + offset++);
filename[filename_size++] = *(p + offset); high = (char)highbyte;
} else
extra = high = 0;
length = (length & 0x7f) + 2;
while (length && filename_size < fn_end) {
unsigned cp = filename_size >> 1;
filename[filename_size++] = high;
filename[filename_size++] = p[cp] + extra;
length--; length--;
} }
} }
break; break;
} }
} }
if (filename_size >= end) { if (filename_size > fn_end) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Invalid filename"); "Invalid filename");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
@ -1322,7 +1332,8 @@ read_header(struct archive_read *a, struct archive_entry *entry,
rar->bytes_remaining = rar->packed_size; rar->bytes_remaining = rar->packed_size;
rar->bytes_uncopied = rar->bytes_unconsumed = 0; rar->bytes_uncopied = rar->bytes_unconsumed = 0;
rar->lzss.position = rar->dictionary_size = rar->offset = 0; rar->lzss.position = rar->offset = 0;
rar->dictionary_size = 0;
rar->offset_outgoing = 0; rar->offset_outgoing = 0;
rar->br.cache_avail = 0; rar->br.cache_avail = 0;
rar->br.avail_in = 0; rar->br.avail_in = 0;
@ -1477,11 +1488,12 @@ read_symlink_stored(struct archive_read *a, struct archive_entry *entry,
int ret = (ARCHIVE_OK); int ret = (ARCHIVE_OK);
rar = (struct rar *)(a->format->data); rar = (struct rar *)(a->format->data);
if ((h = __archive_read_ahead(a, rar->packed_size, NULL)) == NULL) if ((h = __archive_read_ahead(a, (size_t)rar->packed_size, NULL)) == NULL)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
p = h; p = h;
if (archive_entry_copy_symlink_l(entry, p, rar->packed_size, sconv)) if (archive_entry_copy_symlink_l(entry,
p, (size_t)rar->packed_size, sconv))
{ {
if (errno == ENOMEM) if (errno == ENOMEM)
{ {
@ -1528,7 +1540,7 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if (bytes_avail > rar->bytes_remaining) if (bytes_avail > rar->bytes_remaining)
bytes_avail = rar->bytes_remaining; bytes_avail = (ssize_t)rar->bytes_remaining;
*size = bytes_avail; *size = bytes_avail;
*offset = rar->offset; *offset = rar->offset;
@ -1587,7 +1599,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
bs = rar->unp_buffer_size - rar->unp_offset; bs = rar->unp_buffer_size - rar->unp_offset;
else else
bs = rar->bytes_uncopied; bs = (size_t)rar->bytes_uncopied;
ret = copy_from_lzss_window(a, buff, rar->offset, bs); ret = copy_from_lzss_window(a, buff, rar->offset, bs);
if (ret != ARCHIVE_OK) if (ret != ARCHIVE_OK)
return (ret); return (ret);
@ -1715,7 +1727,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
bs = rar->unp_buffer_size - rar->unp_offset; bs = rar->unp_buffer_size - rar->unp_offset;
else else
bs = rar->bytes_uncopied; bs = (size_t)rar->bytes_uncopied;
ret = copy_from_lzss_window(a, buff, rar->offset, bs); ret = copy_from_lzss_window(a, buff, rar->offset, bs);
if (ret != ARCHIVE_OK) if (ret != ARCHIVE_OK)
return (ret); return (ret);
@ -1978,7 +1990,7 @@ parse_codes(struct archive_read *a)
if (rar->unp_size >= DICTIONARY_MAX_SIZE) if (rar->unp_size >= DICTIONARY_MAX_SIZE)
rar->dictionary_size = DICTIONARY_MAX_SIZE; rar->dictionary_size = DICTIONARY_MAX_SIZE;
else else
rar->dictionary_size = rar_fls(rar->unp_size) << 1; rar->dictionary_size = rar_fls((unsigned int)rar->unp_size) << 1;
rar->lzss.window = (unsigned char *)realloc(rar->lzss.window, rar->lzss.window = (unsigned char *)realloc(rar->lzss.window,
rar->dictionary_size); rar->dictionary_size);
if (rar->lzss.window == NULL) { if (rar->lzss.window == NULL) {

View File

@ -527,56 +527,57 @@ archive_read_format_tar_read_data(struct archive_read *a,
tar = (struct tar *)(a->format->data); tar = (struct tar *)(a->format->data);
skip_hole: for (;;) {
/* Remove exhausted entries from sparse list. */ /* Remove exhausted entries from sparse list. */
while (tar->sparse_list != NULL && while (tar->sparse_list != NULL &&
tar->sparse_list->remaining == 0) { tar->sparse_list->remaining == 0) {
p = tar->sparse_list; p = tar->sparse_list;
tar->sparse_list = p->next; tar->sparse_list = p->next;
free(p); free(p);
} }
if (tar->entry_bytes_unconsumed) { if (tar->entry_bytes_unconsumed) {
__archive_read_consume(a, tar->entry_bytes_unconsumed); __archive_read_consume(a, tar->entry_bytes_unconsumed);
tar->entry_bytes_unconsumed = 0; tar->entry_bytes_unconsumed = 0;
} }
/* If we're at end of file, return EOF. */ /* If we're at end of file, return EOF. */
if (tar->sparse_list == NULL || tar->entry_bytes_remaining == 0) { if (tar->sparse_list == NULL ||
if (__archive_read_consume(a, tar->entry_padding) < 0) tar->entry_bytes_remaining == 0) {
if (__archive_read_consume(a, tar->entry_padding) < 0)
return (ARCHIVE_FATAL);
tar->entry_padding = 0;
*buff = NULL;
*size = 0;
*offset = tar->realsize;
return (ARCHIVE_EOF);
}
*buff = __archive_read_ahead(a, 1, &bytes_read);
if (bytes_read < 0)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
tar->entry_padding = 0; if (*buff == NULL) {
*buff = NULL; archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
*size = 0; "Truncated tar archive");
*offset = tar->realsize; return (ARCHIVE_FATAL);
return (ARCHIVE_EOF); }
if (bytes_read > tar->entry_bytes_remaining)
bytes_read = (ssize_t)tar->entry_bytes_remaining;
/* Don't read more than is available in the
* current sparse block. */
if (tar->sparse_list->remaining < bytes_read)
bytes_read = (ssize_t)tar->sparse_list->remaining;
*size = bytes_read;
*offset = tar->sparse_list->offset;
tar->sparse_list->remaining -= bytes_read;
tar->sparse_list->offset += bytes_read;
tar->entry_bytes_remaining -= bytes_read;
tar->entry_bytes_unconsumed = bytes_read;
if (!tar->sparse_list->hole)
return (ARCHIVE_OK);
/* Current is hole data and skip this. */
} }
*buff = __archive_read_ahead(a, 1, &bytes_read);
if (bytes_read < 0)
return (ARCHIVE_FATAL);
if (*buff == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Truncated tar archive");
return (ARCHIVE_FATAL);
}
if (bytes_read > tar->entry_bytes_remaining)
bytes_read = tar->entry_bytes_remaining;
/* Don't read more than is available in the
* current sparse block. */
if (tar->sparse_list->remaining < bytes_read)
bytes_read = tar->sparse_list->remaining;
*size = bytes_read;
*offset = tar->sparse_list->offset;
tar->sparse_list->remaining -= bytes_read;
tar->sparse_list->offset += bytes_read;
tar->entry_bytes_remaining -= bytes_read;
tar->entry_bytes_unconsumed = bytes_read;
if (tar->sparse_list->hole)
goto skip_hole;
return (ARCHIVE_OK);
} }
static int static int
@ -786,7 +787,7 @@ checksum(struct archive_read *a, const void *h)
* Test the checksum. Note that POSIX specifies _unsigned_ * Test the checksum. Note that POSIX specifies _unsigned_
* bytes for this calculation. * bytes for this calculation.
*/ */
sum = tar_atol(header->checksum, sizeof(header->checksum)); sum = (int)tar_atol(header->checksum, sizeof(header->checksum));
check = 0; check = 0;
for (i = 0; i < 148; i++) for (i = 0; i < 148; i++)
check += (unsigned char)bytes[i]; check += (unsigned char)bytes[i];
@ -847,7 +848,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
* more to make sure that we don't overrun acl_text later. * more to make sure that we don't overrun acl_text later.
*/ */
header = (const struct archive_entry_header_ustar *)h; header = (const struct archive_entry_header_ustar *)h;
size = tar_atol(header->size, sizeof(header->size)); size = (size_t)tar_atol(header->size, sizeof(header->size));
err = read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed); err = read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed);
if (err != ARCHIVE_OK) if (err != ARCHIVE_OK)
return (err); return (err);
@ -1021,7 +1022,7 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
} }
/* Fail if we can't make our buffer big enough. */ /* Fail if we can't make our buffer big enough. */
if (archive_string_ensure(as, size+1) == NULL) { if (archive_string_ensure(as, (size_t)size+1) == NULL) {
archive_set_error(&a->archive, ENOMEM, archive_set_error(&a->archive, ENOMEM,
"No memory"); "No memory");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
@ -1030,15 +1031,15 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
tar_flush_unconsumed(a, unconsumed); tar_flush_unconsumed(a, unconsumed);
/* Read the body into the string. */ /* Read the body into the string. */
*unconsumed = (size + 511) & ~ 511; *unconsumed = (size_t)((size + 511) & ~ 511);
src = __archive_read_ahead(a, *unconsumed, NULL); src = __archive_read_ahead(a, *unconsumed, NULL);
if (src == NULL) { if (src == NULL) {
*unconsumed = 0; *unconsumed = 0;
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
memcpy(as->s, src, size); memcpy(as->s, src, (size_t)size);
as->s[size] = '\0'; as->s[size] = '\0';
as->length = size; as->length = (size_t)size;
return (ARCHIVE_OK); return (ARCHIVE_OK);
} }
@ -1068,7 +1069,8 @@ header_common(struct archive_read *a, struct tar *tar,
archive_string_empty(&(tar->entry_linkpath)); archive_string_empty(&(tar->entry_linkpath));
/* Parse out the numeric fields (all are octal) */ /* Parse out the numeric fields (all are octal) */
archive_entry_set_mode(entry, tar_atol(header->mode, sizeof(header->mode))); archive_entry_set_mode(entry,
(mode_t)tar_atol(header->mode, sizeof(header->mode)));
archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid))); archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid))); archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size)); tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size));
@ -1310,13 +1312,13 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
* Q: Is the above idea really possible? Even * Q: Is the above idea really possible? Even
* when there are GNU or pax extension entries? * when there are GNU or pax extension entries?
*/ */
data = __archive_read_ahead(a, size, NULL); data = __archive_read_ahead(a, (size_t)size, NULL);
if (data == NULL) { if (data == NULL) {
*unconsumed = 0; *unconsumed = 0;
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
archive_entry_copy_mac_metadata(entry, data, size); archive_entry_copy_mac_metadata(entry, data, (size_t)size);
*unconsumed = (size + 511) & ~ 511; *unconsumed = (size_t)((size + 511) & ~ 511);
tar_flush_unconsumed(a, unconsumed); tar_flush_unconsumed(a, unconsumed);
return (tar_read_header(a, tar, entry, unconsumed)); return (tar_read_header(a, tar, entry, unconsumed));
} }
@ -1424,9 +1426,9 @@ header_ustar(struct archive_read *a, struct tar *tar,
/* Parse out device numbers only for char and block specials. */ /* Parse out device numbers only for char and block specials. */
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') { if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
archive_entry_set_rdevmajor(entry, archive_entry_set_rdevmajor(entry, (dev_t)
tar_atol(header->rdevmajor, sizeof(header->rdevmajor))); tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
archive_entry_set_rdevminor(entry, archive_entry_set_rdevminor(entry, (dev_t)
tar_atol(header->rdevminor, sizeof(header->rdevminor))); tar_atol(header->rdevminor, sizeof(header->rdevminor)));
} }
@ -1663,6 +1665,9 @@ pax_attribute(struct archive_read *a, struct tar *tar,
long n; long n;
int err = ARCHIVE_OK, r; int err = ARCHIVE_OK, r;
if (value == NULL)
value = ""; /* Disable compiler warning; do not pass
* NULL pointer to strlen(). */
switch (key[0]) { switch (key[0]) {
case 'G': case 'G':
/* GNU "0.0" sparse pax format. */ /* GNU "0.0" sparse pax format. */
@ -1709,11 +1714,11 @@ pax_attribute(struct archive_read *a, struct tar *tar,
/* GNU "1.0" sparse pax format */ /* GNU "1.0" sparse pax format */
if (strcmp(key, "GNU.sparse.major") == 0) { if (strcmp(key, "GNU.sparse.major") == 0) {
tar->sparse_gnu_major = tar_atol10(value, strlen(value)); tar->sparse_gnu_major = (int)tar_atol10(value, strlen(value));
tar->sparse_gnu_pending = 1; tar->sparse_gnu_pending = 1;
} }
if (strcmp(key, "GNU.sparse.minor") == 0) { if (strcmp(key, "GNU.sparse.minor") == 0) {
tar->sparse_gnu_minor = tar_atol10(value, strlen(value)); tar->sparse_gnu_minor = (int)tar_atol10(value, strlen(value));
tar->sparse_gnu_pending = 1; tar->sparse_gnu_pending = 1;
} }
if (strcmp(key, "GNU.sparse.name") == 0) { if (strcmp(key, "GNU.sparse.name") == 0) {
@ -1796,20 +1801,20 @@ pax_attribute(struct archive_read *a, struct tar *tar,
} }
} else if (strcmp(key, "SCHILY.devmajor") == 0) { } else if (strcmp(key, "SCHILY.devmajor") == 0) {
archive_entry_set_rdevmajor(entry, archive_entry_set_rdevmajor(entry,
tar_atol10(value, strlen(value))); (dev_t)tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.devminor") == 0) { } else if (strcmp(key, "SCHILY.devminor") == 0) {
archive_entry_set_rdevminor(entry, archive_entry_set_rdevminor(entry,
tar_atol10(value, strlen(value))); (dev_t)tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.fflags") == 0) { } else if (strcmp(key, "SCHILY.fflags") == 0) {
archive_entry_copy_fflags_text(entry, value); archive_entry_copy_fflags_text(entry, value);
} else if (strcmp(key, "SCHILY.dev") == 0) { } else if (strcmp(key, "SCHILY.dev") == 0) {
archive_entry_set_dev(entry, archive_entry_set_dev(entry,
tar_atol10(value, strlen(value))); (dev_t)tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.ino") == 0) { } else if (strcmp(key, "SCHILY.ino") == 0) {
archive_entry_set_ino(entry, archive_entry_set_ino(entry,
tar_atol10(value, strlen(value))); tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.nlink") == 0) { } else if (strcmp(key, "SCHILY.nlink") == 0) {
archive_entry_set_nlink(entry, archive_entry_set_nlink(entry, (unsigned)
tar_atol10(value, strlen(value))); tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.realsize") == 0) { } else if (strcmp(key, "SCHILY.realsize") == 0) {
tar->realsize = tar_atol10(value, strlen(value)); tar->realsize = tar_atol10(value, strlen(value));
@ -2018,9 +2023,9 @@ header_gnutar(struct archive_read *a, struct tar *tar,
/* Parse out device numbers only for char and block specials */ /* Parse out device numbers only for char and block specials */
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') { if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
archive_entry_set_rdevmajor(entry, archive_entry_set_rdevmajor(entry, (dev_t)
tar_atol(header->rdevmajor, sizeof(header->rdevmajor))); tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
archive_entry_set_rdevminor(entry, archive_entry_set_rdevminor(entry, (dev_t)
tar_atol(header->rdevminor, sizeof(header->rdevminor))); tar_atol(header->rdevminor, sizeof(header->rdevminor)));
} else } else
archive_entry_set_rdev(entry, 0); archive_entry_set_rdev(entry, 0);
@ -2255,7 +2260,8 @@ gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
* don't require this, but they should. * don't require this, but they should.
*/ */
do { do {
bytes_read = readline(a, tar, &p, tar_min(*remaining, 100), unconsumed); bytes_read = readline(a, tar, &p,
(ssize_t)tar_min(*remaining, 100), unconsumed);
if (bytes_read <= 0) if (bytes_read <= 0)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
*remaining -= bytes_read; *remaining -= bytes_read;
@ -2296,7 +2302,7 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
remaining = tar->entry_bytes_remaining; remaining = tar->entry_bytes_remaining;
/* Parse entries. */ /* Parse entries. */
entries = gnu_sparse_10_atol(a, tar, &remaining, unconsumed); entries = (int)gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
if (entries < 0) if (entries < 0)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
/* Parse the individual entries. */ /* Parse the individual entries. */
@ -2314,11 +2320,11 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
} }
/* Skip rest of block... */ /* Skip rest of block... */
tar_flush_unconsumed(a, unconsumed); tar_flush_unconsumed(a, unconsumed);
bytes_read = tar->entry_bytes_remaining - remaining; bytes_read = (ssize_t)(tar->entry_bytes_remaining - remaining);
to_skip = 0x1ff & -bytes_read; to_skip = 0x1ff & -bytes_read;
if (to_skip != __archive_read_consume(a, to_skip)) if (to_skip != __archive_read_consume(a, to_skip))
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
return (bytes_read + to_skip); return ((ssize_t)(bytes_read + to_skip));
} }
/* /*

View File

@ -183,9 +183,9 @@ struct xar_file {
time_t mtime; time_t mtime;
time_t atime; time_t atime;
struct archive_string uname; struct archive_string uname;
uid_t uid; int64_t uid;
struct archive_string gname; struct archive_string gname;
gid_t gid; int64_t gid;
mode_t mode; mode_t mode;
dev_t dev; dev_t dev;
dev_t devmajor; dev_t devmajor;
@ -602,7 +602,8 @@ read_toc(struct archive_read *a)
r = move_reading_point(a, xar->toc_chksum_offset); r = move_reading_point(a, xar->toc_chksum_offset);
if (r != ARCHIVE_OK) if (r != ARCHIVE_OK)
return (r); return (r);
b = __archive_read_ahead(a, xar->toc_chksum_size, &bytes); b = __archive_read_ahead(a,
(size_t)xar->toc_chksum_size, &bytes);
if (bytes < 0) if (bytes < 0)
return ((int)bytes); return ((int)bytes);
if ((uint64_t)bytes < xar->toc_chksum_size) { if ((uint64_t)bytes < xar->toc_chksum_size) {
@ -611,7 +612,8 @@ read_toc(struct archive_read *a)
"Truncated archive file"); "Truncated archive file");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
r = checksum_final(a, b, xar->toc_chksum_size, NULL, 0); r = checksum_final(a, b,
(size_t)xar->toc_chksum_size, NULL, 0);
__archive_read_consume(a, xar->toc_chksum_size); __archive_read_consume(a, xar->toc_chksum_size);
xar->offset += xar->toc_chksum_size; xar->offset += xar->toc_chksum_size;
if (r != ARCHIVE_OK) if (r != ARCHIVE_OK)
@ -2065,7 +2067,7 @@ xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
xar->file->hdnext = xar->hdlink_orgs; xar->file->hdnext = xar->hdlink_orgs;
xar->hdlink_orgs = xar->file; xar->hdlink_orgs = xar->file;
} else { } else {
xar->file->link = atol10(attr->value, xar->file->link = (unsigned)atol10(attr->value,
strlen(attr->value)); strlen(attr->value));
if (xar->file->link > 0) if (xar->file->link > 0)
if (add_link(a, xar, xar->file) != ARCHIVE_OK) { if (add_link(a, xar, xar->file) != ARCHIVE_OK) {
@ -2761,7 +2763,7 @@ xml_data(void *userData, const char *s, int len)
xar->file->has |= HAS_MODE; xar->file->has |= HAS_MODE;
xar->file->mode = xar->file->mode =
(xar->file->mode & AE_IFMT) | (xar->file->mode & AE_IFMT) |
(atol8(s, len) & ~AE_IFMT); ((mode_t)(atol8(s, len)) & ~AE_IFMT);
break; break;
case FILE_GROUP: case FILE_GROUP:
xar->file->has |= HAS_GID; xar->file->has |= HAS_GID;
@ -3076,12 +3078,15 @@ xml2_xmlattr_setup(struct archive_read *a,
attr->name = strdup( attr->name = strdup(
(const char *)xmlTextReaderConstLocalName(reader)); (const char *)xmlTextReaderConstLocalName(reader));
if (attr->name == NULL) { if (attr->name == NULL) {
free(attr);
archive_set_error(&a->archive, ENOMEM, "Out of memory"); archive_set_error(&a->archive, ENOMEM, "Out of memory");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
attr->value = strdup( attr->value = strdup(
(const char *)xmlTextReaderConstValue(reader)); (const char *)xmlTextReaderConstValue(reader));
if (attr->value == NULL) { if (attr->value == NULL) {
free(attr->name);
free(attr);
archive_set_error(&a->archive, ENOMEM, "Out of memory"); archive_set_error(&a->archive, ENOMEM, "Out of memory");
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }

View File

@ -38,17 +38,19 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102
#endif #endif
#include "archive.h" #include "archive.h"
#include "archive_endian.h"
#include "archive_entry.h" #include "archive_entry.h"
#include "archive_entry_locale.h" #include "archive_entry_locale.h"
#include "archive_private.h" #include "archive_private.h"
#include "archive_rb.h"
#include "archive_read_private.h" #include "archive_read_private.h"
#include "archive_endian.h"
#ifndef HAVE_ZLIB_H #ifndef HAVE_ZLIB_H
#include "archive_crc32.h" #include "archive_crc32.h"
#endif #endif
struct zip_entry { struct zip_entry {
struct archive_rb_node node;
int64_t local_header_offset; int64_t local_header_offset;
int64_t compressed_size; int64_t compressed_size;
int64_t uncompressed_size; int64_t uncompressed_size;
@ -71,11 +73,13 @@ struct zip {
size_t central_directory_size; size_t central_directory_size;
size_t central_directory_entries; size_t central_directory_entries;
char have_central_directory; char have_central_directory;
int64_t offset;
/* List of entries (seekable Zip only) */ /* List of entries (seekable Zip only) */
size_t entries_remaining; size_t entries_remaining;
struct zip_entry *zip_entries; struct zip_entry *zip_entries;
struct zip_entry *entry; struct zip_entry *entry;
struct archive_rb_tree tree;
size_t unconsumed; size_t unconsumed;
@ -274,14 +278,38 @@ archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
return 32; return 32;
} }
static int
cmp_node(const struct archive_rb_node *n1, const struct archive_rb_node *n2)
{
const struct zip_entry *e1 = (const struct zip_entry *)n1;
const struct zip_entry *e2 = (const struct zip_entry *)n2;
return ((int)(e2->local_header_offset - e1->local_header_offset));
}
static int
cmp_key(const struct archive_rb_node *n, const void *key)
{
/* This function won't be called */
(void)n; /* UNUSED */
(void)key; /* UNUSED */
return 1;
}
static int static int
slurp_central_directory(struct archive_read *a, struct zip *zip) slurp_central_directory(struct archive_read *a, struct zip *zip)
{ {
unsigned i; unsigned i;
static const struct archive_rb_tree_ops rb_ops = {
&cmp_node, &cmp_key
};
__archive_read_seek(a, zip->central_directory_offset, SEEK_SET); __archive_read_seek(a, zip->central_directory_offset, SEEK_SET);
zip->offset = zip->central_directory_offset;
__archive_rb_tree_init(&zip->tree, &rb_ops);
zip->zip_entries = calloc(zip->central_directory_entries, sizeof(struct zip_entry)); zip->zip_entries = calloc(zip->central_directory_entries,
sizeof(struct zip_entry));
for (i = 0; i < zip->central_directory_entries; ++i) { for (i = 0; i < zip->central_directory_entries; ++i) {
struct zip_entry *zip_entry = &zip->zip_entries[i]; struct zip_entry *zip_entry = &zip->zip_entries[i];
size_t filename_length, extra_length, comment_length; size_t filename_length, extra_length, comment_length;
@ -300,7 +328,7 @@ slurp_central_directory(struct archive_read *a, struct zip *zip)
zip_entry->system = p[5]; zip_entry->system = p[5];
/* version_required = archive_le16dec(p + 6); */ /* version_required = archive_le16dec(p + 6); */
zip_entry->flags = archive_le16dec(p + 8); zip_entry->flags = archive_le16dec(p + 8);
zip_entry->compression = archive_le16dec(p + 10); zip_entry->compression = (char)archive_le16dec(p + 10);
zip_entry->mtime = zip_time(p + 12); zip_entry->mtime = zip_time(p + 12);
zip_entry->crc32 = archive_le32dec(p + 16); zip_entry->crc32 = archive_le32dec(p + 16);
zip_entry->compressed_size = archive_le32dec(p + 20); zip_entry->compressed_size = archive_le32dec(p + 20);
@ -320,6 +348,8 @@ slurp_central_directory(struct archive_read *a, struct zip *zip)
if (zip_entry->system == 3) { if (zip_entry->system == 3) {
zip_entry->mode = external_attributes >> 16; zip_entry->mode = external_attributes >> 16;
} }
/* Register an entry to RB tree to sort it by file offset. */
__archive_rb_tree_insert_node(&zip->tree, &zip_entry->node);
/* We don't read the filename until we get to the /* We don't read the filename until we get to the
local file header. Reading it here would speed up local file header. Reading it here would speed up
@ -333,19 +363,27 @@ slurp_central_directory(struct archive_read *a, struct zip *zip)
46 + filename_length + extra_length + comment_length); 46 + filename_length + extra_length + comment_length);
} }
/* TODO: Sort zip entries by file offset so that we
can optimize get_next_header() to use skip instead of
seek. */
return ARCHIVE_OK; return ARCHIVE_OK;
} }
static int64_t
zip_read_consume(struct archive_read *a, int64_t bytes)
{
struct zip *zip = (struct zip *)a->format->data;
int64_t skip;
skip = __archive_read_consume(a, bytes);
if (skip > 0)
zip->offset += skip;
return (skip);
}
static int static int
archive_read_format_zip_seekable_read_header(struct archive_read *a, archive_read_format_zip_seekable_read_header(struct archive_read *a,
struct archive_entry *entry) struct archive_entry *entry)
{ {
struct zip *zip = (struct zip *)a->format->data; struct zip *zip = (struct zip *)a->format->data;
int r; int r, ret = ARCHIVE_OK;
a->archive.archive_format = ARCHIVE_FORMAT_ZIP; a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
if (a->archive.archive_format_name == NULL) if (a->archive.archive_format_name == NULL)
@ -356,26 +394,33 @@ archive_read_format_zip_seekable_read_header(struct archive_read *a,
zip->entries_remaining = zip->central_directory_entries; zip->entries_remaining = zip->central_directory_entries;
if (r != ARCHIVE_OK) if (r != ARCHIVE_OK)
return r; return r;
zip->entry = zip->zip_entries; /* Get first entry whose local header offset is lower than
} else { * other entries in the archive file. */
++zip->entry; zip->entry =
(struct zip_entry *)ARCHIVE_RB_TREE_MIN(&zip->tree);
} else if (zip->entry != NULL) {
/* Get next entry in local header offset order. */
zip->entry = (struct zip_entry *)__archive_rb_tree_iterate(
&zip->tree, &zip->entry->node, ARCHIVE_RB_DIR_RIGHT);
} }
if (zip->entries_remaining <= 0) if (zip->entries_remaining <= 0 || zip->entry == NULL)
return ARCHIVE_EOF; return ARCHIVE_EOF;
--zip->entries_remaining; --zip->entries_remaining;
/* TODO: If entries are sorted by offset within the file, we if (zip->offset != zip->entry->local_header_offset) {
should be able to skip here instead of seeking. Skipping is __archive_read_seek(a, zip->entry->local_header_offset,
typically faster (easier for I/O layer to optimize). */ SEEK_SET);
__archive_read_seek(a, zip->entry->local_header_offset, SEEK_SET); zip->offset = zip->entry->local_header_offset;
}
zip->unconsumed = 0; zip->unconsumed = 0;
r = zip_read_local_file_header(a, entry, zip); r = zip_read_local_file_header(a, entry, zip);
if (r != ARCHIVE_OK) if (r != ARCHIVE_OK)
return r; return r;
if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) { if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) {
const void *p; const void *p;
size_t linkname_length = archive_entry_size(entry); struct archive_string_conv *sconv;
size_t linkname_length = (size_t)archive_entry_size(entry);
archive_entry_set_size(entry, 0); archive_entry_set_size(entry, 0);
p = __archive_read_ahead(a, linkname_length, NULL); p = __archive_read_ahead(a, linkname_length, NULL);
@ -385,17 +430,40 @@ archive_read_format_zip_seekable_read_header(struct archive_read *a,
return ARCHIVE_FATAL; return ARCHIVE_FATAL;
} }
sconv = zip->sconv;
if (sconv == NULL && (zip->entry->flags & ZIP_UTF8_NAME))
sconv = zip->sconv_utf8;
if (sconv == NULL)
sconv = zip->sconv_default;
if (archive_entry_copy_symlink_l(entry, p, linkname_length, if (archive_entry_copy_symlink_l(entry, p, linkname_length,
NULL) != 0) { sconv) != 0) {
/* NOTE: If the last argument is NULL, this will if (errno != ENOMEM && sconv == zip->sconv_utf8 &&
* fail only by memeory allocation failure. */ (zip->entry->flags & ZIP_UTF8_NAME))
archive_set_error(&a->archive, ENOMEM, archive_entry_copy_symlink_l(entry, p,
"Can't allocate memory for Symlink"); linkname_length, NULL);
return (ARCHIVE_FATAL); if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for Symlink");
return (ARCHIVE_FATAL);
}
/*
* Since there is no character-set regulation for
* symlink name, do not report the conversion error
* in an automatic conversion.
*/
if (sconv != zip->sconv_utf8 ||
(zip->entry->flags & ZIP_UTF8_NAME) == 0) {
archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Symlink cannot be converted "
"from %s to current locale.",
archive_string_conversion_charset_name(
sconv));
ret = ARCHIVE_WARN;
}
} }
/* TODO: handle character-set issues? */
} }
return ARCHIVE_OK; return (ret);
} }
static int static int
@ -489,7 +557,7 @@ archive_read_format_zip_streamable_read_header(struct archive_read *a,
memset(zip->entry, 0, sizeof(struct zip_entry)); memset(zip->entry, 0, sizeof(struct zip_entry));
/* Search ahead for the next local file header. */ /* Search ahead for the next local file header. */
__archive_read_consume(a, zip->unconsumed); zip_read_consume(a, zip->unconsumed);
zip->unconsumed = 0; zip->unconsumed = 0;
for (;;) { for (;;) {
int64_t skipped = 0; int64_t skipped = 0;
@ -509,7 +577,7 @@ archive_read_format_zip_streamable_read_header(struct archive_read *a,
if (p[2] == '\003' && p[3] == '\004') { if (p[2] == '\003' && p[3] == '\004') {
/* Regular file entry. */ /* Regular file entry. */
__archive_read_consume(a, skipped); zip_read_consume(a, skipped);
return zip_read_local_file_header(a, entry, zip); return zip_read_local_file_header(a, entry, zip);
} }
@ -520,7 +588,7 @@ archive_read_format_zip_streamable_read_header(struct archive_read *a,
++p; ++p;
++skipped; ++skipped;
} }
__archive_read_consume(a, skipped); zip_read_consume(a, skipped);
} }
} }
@ -569,7 +637,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
version = p[4]; version = p[4];
zip_entry->system = p[5]; zip_entry->system = p[5];
zip_entry->flags = archive_le16dec(p + 6); zip_entry->flags = archive_le16dec(p + 6);
zip_entry->compression = archive_le16dec(p + 8); zip_entry->compression = (char)archive_le16dec(p + 8);
zip_entry->mtime = zip_time(p + 10); zip_entry->mtime = zip_time(p + 10);
local_crc32 = archive_le32dec(p + 14); local_crc32 = archive_le32dec(p + 14);
compressed_size = archive_le32dec(p + 18); compressed_size = archive_le32dec(p + 18);
@ -577,7 +645,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
filename_length = archive_le16dec(p + 26); filename_length = archive_le16dec(p + 26);
extra_length = archive_le16dec(p + 28); extra_length = archive_le16dec(p + 28);
__archive_read_consume(a, 30); zip_read_consume(a, 30);
if (zip->have_central_directory) { if (zip->have_central_directory) {
/* If we read the central dir entry, we must have size information /* If we read the central dir entry, we must have size information
@ -647,7 +715,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
archive_string_conversion_charset_name(sconv)); archive_string_conversion_charset_name(sconv));
ret = ARCHIVE_WARN; ret = ARCHIVE_WARN;
} }
__archive_read_consume(a, filename_length); zip_read_consume(a, filename_length);
if (zip_entry->mode == 0) { if (zip_entry->mode == 0) {
/* Especially in streaming mode, we can end up /* Especially in streaming mode, we can end up
@ -659,14 +727,14 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
if (len > 0 && wp[len - 1] == L'/') if (len > 0 && wp[len - 1] == L'/')
zip_entry->mode = AE_IFDIR | 0777; zip_entry->mode = AE_IFDIR | 0777;
else else
zip_entry->mode = AE_IFREG | 0777; zip_entry->mode = AE_IFREG | 0666;
} else { } else {
cp = archive_entry_pathname(entry); cp = archive_entry_pathname(entry);
len = (cp != NULL)?strlen(cp):0; len = (cp != NULL)?strlen(cp):0;
if (len > 0 && cp[len - 1] == '/') if (len > 0 && cp[len - 1] == '/')
zip_entry->mode = AE_IFDIR | 0777; zip_entry->mode = AE_IFDIR | 0777;
else else
zip_entry->mode = AE_IFREG | 0777; zip_entry->mode = AE_IFREG | 0666;
} }
} }
@ -677,7 +745,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
process_extra(h, extra_length, zip_entry); process_extra(h, extra_length, zip_entry);
__archive_read_consume(a, extra_length); zip_read_consume(a, extra_length);
/* Populate some additional entry fields: */ /* Populate some additional entry fields: */
archive_entry_set_mode(entry, zip_entry->mode); archive_entry_set_mode(entry, zip_entry->mode);
@ -774,7 +842,7 @@ archive_read_format_zip_read_data(struct archive_read *a,
return (ARCHIVE_FAILED); return (ARCHIVE_FAILED);
} }
__archive_read_consume(a, zip->unconsumed); zip_read_consume(a, zip->unconsumed);
zip->unconsumed = 0; zip->unconsumed = 0;
switch(zip->entry->compression) { switch(zip->entry->compression) {
@ -926,7 +994,7 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
if (bytes_avail > zip->entry_bytes_remaining) if (bytes_avail > zip->entry_bytes_remaining)
bytes_avail = zip->entry_bytes_remaining; bytes_avail = (ssize_t)zip->entry_bytes_remaining;
} }
*size = bytes_avail; *size = bytes_avail;
zip->entry_bytes_remaining -= bytes_avail; zip->entry_bytes_remaining -= bytes_avail;
@ -990,7 +1058,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
compressed_buff = __archive_read_ahead(a, 1, &bytes_avail); compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END) if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)
&& bytes_avail > zip->entry_bytes_remaining) { && bytes_avail > zip->entry_bytes_remaining) {
bytes_avail = zip->entry_bytes_remaining; bytes_avail = (ssize_t)zip->entry_bytes_remaining;
} }
if (bytes_avail <= 0) { if (bytes_avail <= 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@ -1030,7 +1098,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
/* Consume as much as the compressor actually used. */ /* Consume as much as the compressor actually used. */
bytes_avail = zip->stream.total_in; bytes_avail = zip->stream.total_in;
__archive_read_consume(a, bytes_avail); zip_read_consume(a, bytes_avail);
zip->entry_bytes_remaining -= bytes_avail; zip->entry_bytes_remaining -= bytes_avail;
zip->entry_compressed_bytes_read += bytes_avail; zip->entry_compressed_bytes_read += bytes_avail;
@ -1070,14 +1138,11 @@ archive_read_format_zip_read_data_skip(struct archive_read *a)
/* If we've already read to end of data, we're done. */ /* If we've already read to end of data, we're done. */
if (zip->end_of_entry) if (zip->end_of_entry)
return (ARCHIVE_OK); return (ARCHIVE_OK);
/* If we're seeking, we're done. */
if (zip->have_central_directory)
return (ARCHIVE_OK);
/* So we know we're streaming... */ /* So we know we're streaming... */
if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)) { if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)) {
/* We know the compressed length, so we can just skip. */ /* We know the compressed length, so we can just skip. */
int64_t bytes_skipped = __archive_read_consume(a, int64_t bytes_skipped = zip_read_consume(a,
zip->entry_bytes_remaining + zip->unconsumed); zip->entry_bytes_remaining + zip->unconsumed);
if (bytes_skipped < 0) if (bytes_skipped < 0)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
@ -1100,11 +1165,11 @@ archive_read_format_zip_read_data_skip(struct archive_read *a)
if (r != ARCHIVE_OK) if (r != ARCHIVE_OK)
return (r); return (r);
} }
break; return ARCHIVE_OK;
#endif #endif
default: /* Uncompressed or unknown. */ default: /* Uncompressed or unknown. */
/* Scan for a PK\007\010 signature. */ /* Scan for a PK\007\010 signature. */
__archive_read_consume(a, zip->unconsumed); zip_read_consume(a, zip->unconsumed);
zip->unconsumed = 0; zip->unconsumed = 0;
for (;;) { for (;;) {
const char *p, *buff; const char *p, *buff;
@ -1122,14 +1187,13 @@ archive_read_format_zip_read_data_skip(struct archive_read *a)
else if (p[3] == '\007') { p += 1; } else if (p[3] == '\007') { p += 1; }
else if (p[3] == '\010' && p[2] == '\007' else if (p[3] == '\010' && p[2] == '\007'
&& p[1] == 'K' && p[0] == 'P') { && p[1] == 'K' && p[0] == 'P') {
__archive_read_consume(a, p - buff + 16); zip_read_consume(a, p - buff + 16);
return ARCHIVE_OK; return ARCHIVE_OK;
} else { p += 4; } } else { p += 4; }
} }
__archive_read_consume(a, p - buff); zip_read_consume(a, p - buff);
} }
} }
return ARCHIVE_OK;
} }
static int static int

File diff suppressed because it is too large Load Diff

View File

@ -110,18 +110,20 @@ archive_string_conversion_charset_name(struct archive_string_conv *);
void void
archive_string_conversion_set_opt(struct archive_string_conv *, int); archive_string_conversion_set_opt(struct archive_string_conv *, int);
#define SCONV_SET_OPT_UTF8_LIBARCHIVE2X 1 #define SCONV_SET_OPT_UTF8_LIBARCHIVE2X 1
#define SCONV_SET_OPT_NORMALIZATION_C 2
#define SCONV_SET_OPT_NORMALIZATION_D 4
/* Copy one archive_string to another in locale conversion. /* Copy one archive_string to another in locale conversion.
* Return -1 if conversion failes. */ * Return -1 if conversion failes. */
int int
archive_strncpy_in_locale(struct archive_string *, const void *, size_t, archive_strncpy_l(struct archive_string *, const void *, size_t,
struct archive_string_conv *); struct archive_string_conv *);
/* Copy one archive_string to another in locale conversion. /* Copy one archive_string to another in locale conversion.
* Return -1 if conversion failes. */ * Return -1 if conversion failes. */
int int
archive_strncat_in_locale(struct archive_string *, const void *, size_t, archive_strncat_l(struct archive_string *, const void *, size_t,
struct archive_string_conv *); struct archive_string_conv *);
@ -162,8 +164,8 @@ archive_wstrcat(struct archive_wstring *, const wchar_t *);
archive_strncpy((as), (p), ((p) == NULL ? 0 : strlen(p))) archive_strncpy((as), (p), ((p) == NULL ? 0 : strlen(p)))
#define archive_wstrcpy(as,p) \ #define archive_wstrcpy(as,p) \
archive_wstrncpy((as), (p), ((p) == NULL ? 0 : wcslen(p))) archive_wstrncpy((as), (p), ((p) == NULL ? 0 : wcslen(p)))
#define archive_strcpy_in_locale(as,p,lo) \ #define archive_strcpy_l(as,p,lo) \
archive_strncpy_in_locale((as), (p), ((p) == NULL ? 0 : strlen(p)), (lo)) archive_strncpy_l((as), (p), ((p) == NULL ? 0 : strlen(p)), (lo))
/* Copy a C string to an archive_string with limit, resizing as necessary. */ /* Copy a C string to an archive_string with limit, resizing as necessary. */
#define archive_strncpy(as,p,l) \ #define archive_strncpy(as,p,l) \

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2011 libarchive Project * Copyright (c) 2011-2012 libarchive Project
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -29,7 +29,7 @@
/* /*
* ATTENTION! * ATTENTION!
* This file is generated by build/utils/gen_archive_string_composition_h.sh * This file is generated by build/utils/gen_archive_string_composition_h.sh
* from http://unicode.org/Public/UNIDATA/UnicodeData.txt * from http://unicode.org/Public/6.0.0/ucd/UnicodeData.txt
* *
* See also http://unicode.org/report/tr15/ * See also http://unicode.org/report/tr15/
*/ */
@ -1348,4 +1348,945 @@ static const unsigned char ccc_index[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,37,38,}; 0, 0, 0, 0, 0, 0, 0, 0, 0,37,38,};
struct unicode_decomposition_table {
uint32_t nfc;
uint32_t cp1;
uint32_t cp2;
};
static const struct unicode_decomposition_table u_decomposition_table[] = {
{ 0x000C0 , 0x00041 , 0x00300 },
{ 0x000C1 , 0x00041 , 0x00301 },
{ 0x000C2 , 0x00041 , 0x00302 },
{ 0x000C3 , 0x00041 , 0x00303 },
{ 0x000C4 , 0x00041 , 0x00308 },
{ 0x000C5 , 0x00041 , 0x0030A },
{ 0x000C7 , 0x00043 , 0x00327 },
{ 0x000C8 , 0x00045 , 0x00300 },
{ 0x000C9 , 0x00045 , 0x00301 },
{ 0x000CA , 0x00045 , 0x00302 },
{ 0x000CB , 0x00045 , 0x00308 },
{ 0x000CC , 0x00049 , 0x00300 },
{ 0x000CD , 0x00049 , 0x00301 },
{ 0x000CE , 0x00049 , 0x00302 },
{ 0x000CF , 0x00049 , 0x00308 },
{ 0x000D1 , 0x0004E , 0x00303 },
{ 0x000D2 , 0x0004F , 0x00300 },
{ 0x000D3 , 0x0004F , 0x00301 },
{ 0x000D4 , 0x0004F , 0x00302 },
{ 0x000D5 , 0x0004F , 0x00303 },
{ 0x000D6 , 0x0004F , 0x00308 },
{ 0x000D9 , 0x00055 , 0x00300 },
{ 0x000DA , 0x00055 , 0x00301 },
{ 0x000DB , 0x00055 , 0x00302 },
{ 0x000DC , 0x00055 , 0x00308 },
{ 0x000DD , 0x00059 , 0x00301 },
{ 0x000E0 , 0x00061 , 0x00300 },
{ 0x000E1 , 0x00061 , 0x00301 },
{ 0x000E2 , 0x00061 , 0x00302 },
{ 0x000E3 , 0x00061 , 0x00303 },
{ 0x000E4 , 0x00061 , 0x00308 },
{ 0x000E5 , 0x00061 , 0x0030A },
{ 0x000E7 , 0x00063 , 0x00327 },
{ 0x000E8 , 0x00065 , 0x00300 },
{ 0x000E9 , 0x00065 , 0x00301 },
{ 0x000EA , 0x00065 , 0x00302 },
{ 0x000EB , 0x00065 , 0x00308 },
{ 0x000EC , 0x00069 , 0x00300 },
{ 0x000ED , 0x00069 , 0x00301 },
{ 0x000EE , 0x00069 , 0x00302 },
{ 0x000EF , 0x00069 , 0x00308 },
{ 0x000F1 , 0x0006E , 0x00303 },
{ 0x000F2 , 0x0006F , 0x00300 },
{ 0x000F3 , 0x0006F , 0x00301 },
{ 0x000F4 , 0x0006F , 0x00302 },
{ 0x000F5 , 0x0006F , 0x00303 },
{ 0x000F6 , 0x0006F , 0x00308 },
{ 0x000F9 , 0x00075 , 0x00300 },
{ 0x000FA , 0x00075 , 0x00301 },
{ 0x000FB , 0x00075 , 0x00302 },
{ 0x000FC , 0x00075 , 0x00308 },
{ 0x000FD , 0x00079 , 0x00301 },
{ 0x000FF , 0x00079 , 0x00308 },
{ 0x00100 , 0x00041 , 0x00304 },
{ 0x00101 , 0x00061 , 0x00304 },
{ 0x00102 , 0x00041 , 0x00306 },
{ 0x00103 , 0x00061 , 0x00306 },
{ 0x00104 , 0x00041 , 0x00328 },
{ 0x00105 , 0x00061 , 0x00328 },
{ 0x00106 , 0x00043 , 0x00301 },
{ 0x00107 , 0x00063 , 0x00301 },
{ 0x00108 , 0x00043 , 0x00302 },
{ 0x00109 , 0x00063 , 0x00302 },
{ 0x0010A , 0x00043 , 0x00307 },
{ 0x0010B , 0x00063 , 0x00307 },
{ 0x0010C , 0x00043 , 0x0030C },
{ 0x0010D , 0x00063 , 0x0030C },
{ 0x0010E , 0x00044 , 0x0030C },
{ 0x0010F , 0x00064 , 0x0030C },
{ 0x00112 , 0x00045 , 0x00304 },
{ 0x00113 , 0x00065 , 0x00304 },
{ 0x00114 , 0x00045 , 0x00306 },
{ 0x00115 , 0x00065 , 0x00306 },
{ 0x00116 , 0x00045 , 0x00307 },
{ 0x00117 , 0x00065 , 0x00307 },
{ 0x00118 , 0x00045 , 0x00328 },
{ 0x00119 , 0x00065 , 0x00328 },
{ 0x0011A , 0x00045 , 0x0030C },
{ 0x0011B , 0x00065 , 0x0030C },
{ 0x0011C , 0x00047 , 0x00302 },
{ 0x0011D , 0x00067 , 0x00302 },
{ 0x0011E , 0x00047 , 0x00306 },
{ 0x0011F , 0x00067 , 0x00306 },
{ 0x00120 , 0x00047 , 0x00307 },
{ 0x00121 , 0x00067 , 0x00307 },
{ 0x00122 , 0x00047 , 0x00327 },
{ 0x00123 , 0x00067 , 0x00327 },
{ 0x00124 , 0x00048 , 0x00302 },
{ 0x00125 , 0x00068 , 0x00302 },
{ 0x00128 , 0x00049 , 0x00303 },
{ 0x00129 , 0x00069 , 0x00303 },
{ 0x0012A , 0x00049 , 0x00304 },
{ 0x0012B , 0x00069 , 0x00304 },
{ 0x0012C , 0x00049 , 0x00306 },
{ 0x0012D , 0x00069 , 0x00306 },
{ 0x0012E , 0x00049 , 0x00328 },
{ 0x0012F , 0x00069 , 0x00328 },
{ 0x00130 , 0x00049 , 0x00307 },
{ 0x00134 , 0x0004A , 0x00302 },
{ 0x00135 , 0x0006A , 0x00302 },
{ 0x00136 , 0x0004B , 0x00327 },
{ 0x00137 , 0x0006B , 0x00327 },
{ 0x00139 , 0x0004C , 0x00301 },
{ 0x0013A , 0x0006C , 0x00301 },
{ 0x0013B , 0x0004C , 0x00327 },
{ 0x0013C , 0x0006C , 0x00327 },
{ 0x0013D , 0x0004C , 0x0030C },
{ 0x0013E , 0x0006C , 0x0030C },
{ 0x00143 , 0x0004E , 0x00301 },
{ 0x00144 , 0x0006E , 0x00301 },
{ 0x00145 , 0x0004E , 0x00327 },
{ 0x00146 , 0x0006E , 0x00327 },
{ 0x00147 , 0x0004E , 0x0030C },
{ 0x00148 , 0x0006E , 0x0030C },
{ 0x0014C , 0x0004F , 0x00304 },
{ 0x0014D , 0x0006F , 0x00304 },
{ 0x0014E , 0x0004F , 0x00306 },
{ 0x0014F , 0x0006F , 0x00306 },
{ 0x00150 , 0x0004F , 0x0030B },
{ 0x00151 , 0x0006F , 0x0030B },
{ 0x00154 , 0x00052 , 0x00301 },
{ 0x00155 , 0x00072 , 0x00301 },
{ 0x00156 , 0x00052 , 0x00327 },
{ 0x00157 , 0x00072 , 0x00327 },
{ 0x00158 , 0x00052 , 0x0030C },
{ 0x00159 , 0x00072 , 0x0030C },
{ 0x0015A , 0x00053 , 0x00301 },
{ 0x0015B , 0x00073 , 0x00301 },
{ 0x0015C , 0x00053 , 0x00302 },
{ 0x0015D , 0x00073 , 0x00302 },
{ 0x0015E , 0x00053 , 0x00327 },
{ 0x0015F , 0x00073 , 0x00327 },
{ 0x00160 , 0x00053 , 0x0030C },
{ 0x00161 , 0x00073 , 0x0030C },
{ 0x00162 , 0x00054 , 0x00327 },
{ 0x00163 , 0x00074 , 0x00327 },
{ 0x00164 , 0x00054 , 0x0030C },
{ 0x00165 , 0x00074 , 0x0030C },
{ 0x00168 , 0x00055 , 0x00303 },
{ 0x00169 , 0x00075 , 0x00303 },
{ 0x0016A , 0x00055 , 0x00304 },
{ 0x0016B , 0x00075 , 0x00304 },
{ 0x0016C , 0x00055 , 0x00306 },
{ 0x0016D , 0x00075 , 0x00306 },
{ 0x0016E , 0x00055 , 0x0030A },
{ 0x0016F , 0x00075 , 0x0030A },
{ 0x00170 , 0x00055 , 0x0030B },
{ 0x00171 , 0x00075 , 0x0030B },
{ 0x00172 , 0x00055 , 0x00328 },
{ 0x00173 , 0x00075 , 0x00328 },
{ 0x00174 , 0x00057 , 0x00302 },
{ 0x00175 , 0x00077 , 0x00302 },
{ 0x00176 , 0x00059 , 0x00302 },
{ 0x00177 , 0x00079 , 0x00302 },
{ 0x00178 , 0x00059 , 0x00308 },
{ 0x00179 , 0x0005A , 0x00301 },
{ 0x0017A , 0x0007A , 0x00301 },
{ 0x0017B , 0x0005A , 0x00307 },
{ 0x0017C , 0x0007A , 0x00307 },
{ 0x0017D , 0x0005A , 0x0030C },
{ 0x0017E , 0x0007A , 0x0030C },
{ 0x001A0 , 0x0004F , 0x0031B },
{ 0x001A1 , 0x0006F , 0x0031B },
{ 0x001AF , 0x00055 , 0x0031B },
{ 0x001B0 , 0x00075 , 0x0031B },
{ 0x001CD , 0x00041 , 0x0030C },
{ 0x001CE , 0x00061 , 0x0030C },
{ 0x001CF , 0x00049 , 0x0030C },
{ 0x001D0 , 0x00069 , 0x0030C },
{ 0x001D1 , 0x0004F , 0x0030C },
{ 0x001D2 , 0x0006F , 0x0030C },
{ 0x001D3 , 0x00055 , 0x0030C },
{ 0x001D4 , 0x00075 , 0x0030C },
{ 0x001D5 , 0x000DC , 0x00304 },
{ 0x001D6 , 0x000FC , 0x00304 },
{ 0x001D7 , 0x000DC , 0x00301 },
{ 0x001D8 , 0x000FC , 0x00301 },
{ 0x001D9 , 0x000DC , 0x0030C },
{ 0x001DA , 0x000FC , 0x0030C },
{ 0x001DB , 0x000DC , 0x00300 },
{ 0x001DC , 0x000FC , 0x00300 },
{ 0x001DE , 0x000C4 , 0x00304 },
{ 0x001DF , 0x000E4 , 0x00304 },
{ 0x001E0 , 0x00226 , 0x00304 },
{ 0x001E1 , 0x00227 , 0x00304 },
{ 0x001E2 , 0x000C6 , 0x00304 },
{ 0x001E3 , 0x000E6 , 0x00304 },
{ 0x001E6 , 0x00047 , 0x0030C },
{ 0x001E7 , 0x00067 , 0x0030C },
{ 0x001E8 , 0x0004B , 0x0030C },
{ 0x001E9 , 0x0006B , 0x0030C },
{ 0x001EA , 0x0004F , 0x00328 },
{ 0x001EB , 0x0006F , 0x00328 },
{ 0x001EC , 0x001EA , 0x00304 },
{ 0x001ED , 0x001EB , 0x00304 },
{ 0x001EE , 0x001B7 , 0x0030C },
{ 0x001EF , 0x00292 , 0x0030C },
{ 0x001F0 , 0x0006A , 0x0030C },
{ 0x001F4 , 0x00047 , 0x00301 },
{ 0x001F5 , 0x00067 , 0x00301 },
{ 0x001F8 , 0x0004E , 0x00300 },
{ 0x001F9 , 0x0006E , 0x00300 },
{ 0x001FA , 0x000C5 , 0x00301 },
{ 0x001FB , 0x000E5 , 0x00301 },
{ 0x001FC , 0x000C6 , 0x00301 },
{ 0x001FD , 0x000E6 , 0x00301 },
{ 0x001FE , 0x000D8 , 0x00301 },
{ 0x001FF , 0x000F8 , 0x00301 },
{ 0x00200 , 0x00041 , 0x0030F },
{ 0x00201 , 0x00061 , 0x0030F },
{ 0x00202 , 0x00041 , 0x00311 },
{ 0x00203 , 0x00061 , 0x00311 },
{ 0x00204 , 0x00045 , 0x0030F },
{ 0x00205 , 0x00065 , 0x0030F },
{ 0x00206 , 0x00045 , 0x00311 },
{ 0x00207 , 0x00065 , 0x00311 },
{ 0x00208 , 0x00049 , 0x0030F },
{ 0x00209 , 0x00069 , 0x0030F },
{ 0x0020A , 0x00049 , 0x00311 },
{ 0x0020B , 0x00069 , 0x00311 },
{ 0x0020C , 0x0004F , 0x0030F },
{ 0x0020D , 0x0006F , 0x0030F },
{ 0x0020E , 0x0004F , 0x00311 },
{ 0x0020F , 0x0006F , 0x00311 },
{ 0x00210 , 0x00052 , 0x0030F },
{ 0x00211 , 0x00072 , 0x0030F },
{ 0x00212 , 0x00052 , 0x00311 },
{ 0x00213 , 0x00072 , 0x00311 },
{ 0x00214 , 0x00055 , 0x0030F },
{ 0x00215 , 0x00075 , 0x0030F },
{ 0x00216 , 0x00055 , 0x00311 },
{ 0x00217 , 0x00075 , 0x00311 },
{ 0x00218 , 0x00053 , 0x00326 },
{ 0x00219 , 0x00073 , 0x00326 },
{ 0x0021A , 0x00054 , 0x00326 },
{ 0x0021B , 0x00074 , 0x00326 },
{ 0x0021E , 0x00048 , 0x0030C },
{ 0x0021F , 0x00068 , 0x0030C },
{ 0x00226 , 0x00041 , 0x00307 },
{ 0x00227 , 0x00061 , 0x00307 },
{ 0x00228 , 0x00045 , 0x00327 },
{ 0x00229 , 0x00065 , 0x00327 },
{ 0x0022A , 0x000D6 , 0x00304 },
{ 0x0022B , 0x000F6 , 0x00304 },
{ 0x0022C , 0x000D5 , 0x00304 },
{ 0x0022D , 0x000F5 , 0x00304 },
{ 0x0022E , 0x0004F , 0x00307 },
{ 0x0022F , 0x0006F , 0x00307 },
{ 0x00230 , 0x0022E , 0x00304 },
{ 0x00231 , 0x0022F , 0x00304 },
{ 0x00232 , 0x00059 , 0x00304 },
{ 0x00233 , 0x00079 , 0x00304 },
{ 0x00385 , 0x000A8 , 0x00301 },
{ 0x00386 , 0x00391 , 0x00301 },
{ 0x00388 , 0x00395 , 0x00301 },
{ 0x00389 , 0x00397 , 0x00301 },
{ 0x0038A , 0x00399 , 0x00301 },
{ 0x0038C , 0x0039F , 0x00301 },
{ 0x0038E , 0x003A5 , 0x00301 },
{ 0x0038F , 0x003A9 , 0x00301 },
{ 0x00390 , 0x003CA , 0x00301 },
{ 0x003AA , 0x00399 , 0x00308 },
{ 0x003AB , 0x003A5 , 0x00308 },
{ 0x003AC , 0x003B1 , 0x00301 },
{ 0x003AD , 0x003B5 , 0x00301 },
{ 0x003AE , 0x003B7 , 0x00301 },
{ 0x003AF , 0x003B9 , 0x00301 },
{ 0x003B0 , 0x003CB , 0x00301 },
{ 0x003CA , 0x003B9 , 0x00308 },
{ 0x003CB , 0x003C5 , 0x00308 },
{ 0x003CC , 0x003BF , 0x00301 },
{ 0x003CD , 0x003C5 , 0x00301 },
{ 0x003CE , 0x003C9 , 0x00301 },
{ 0x003D3 , 0x003D2 , 0x00301 },
{ 0x003D4 , 0x003D2 , 0x00308 },
{ 0x00400 , 0x00415 , 0x00300 },
{ 0x00401 , 0x00415 , 0x00308 },
{ 0x00403 , 0x00413 , 0x00301 },
{ 0x00407 , 0x00406 , 0x00308 },
{ 0x0040C , 0x0041A , 0x00301 },
{ 0x0040D , 0x00418 , 0x00300 },
{ 0x0040E , 0x00423 , 0x00306 },
{ 0x00419 , 0x00418 , 0x00306 },
{ 0x00439 , 0x00438 , 0x00306 },
{ 0x00450 , 0x00435 , 0x00300 },
{ 0x00451 , 0x00435 , 0x00308 },
{ 0x00453 , 0x00433 , 0x00301 },
{ 0x00457 , 0x00456 , 0x00308 },
{ 0x0045C , 0x0043A , 0x00301 },
{ 0x0045D , 0x00438 , 0x00300 },
{ 0x0045E , 0x00443 , 0x00306 },
{ 0x00476 , 0x00474 , 0x0030F },
{ 0x00477 , 0x00475 , 0x0030F },
{ 0x004C1 , 0x00416 , 0x00306 },
{ 0x004C2 , 0x00436 , 0x00306 },
{ 0x004D0 , 0x00410 , 0x00306 },
{ 0x004D1 , 0x00430 , 0x00306 },
{ 0x004D2 , 0x00410 , 0x00308 },
{ 0x004D3 , 0x00430 , 0x00308 },
{ 0x004D6 , 0x00415 , 0x00306 },
{ 0x004D7 , 0x00435 , 0x00306 },
{ 0x004DA , 0x004D8 , 0x00308 },
{ 0x004DB , 0x004D9 , 0x00308 },
{ 0x004DC , 0x00416 , 0x00308 },
{ 0x004DD , 0x00436 , 0x00308 },
{ 0x004DE , 0x00417 , 0x00308 },
{ 0x004DF , 0x00437 , 0x00308 },
{ 0x004E2 , 0x00418 , 0x00304 },
{ 0x004E3 , 0x00438 , 0x00304 },
{ 0x004E4 , 0x00418 , 0x00308 },
{ 0x004E5 , 0x00438 , 0x00308 },
{ 0x004E6 , 0x0041E , 0x00308 },
{ 0x004E7 , 0x0043E , 0x00308 },
{ 0x004EA , 0x004E8 , 0x00308 },
{ 0x004EB , 0x004E9 , 0x00308 },
{ 0x004EC , 0x0042D , 0x00308 },
{ 0x004ED , 0x0044D , 0x00308 },
{ 0x004EE , 0x00423 , 0x00304 },
{ 0x004EF , 0x00443 , 0x00304 },
{ 0x004F0 , 0x00423 , 0x00308 },
{ 0x004F1 , 0x00443 , 0x00308 },
{ 0x004F2 , 0x00423 , 0x0030B },
{ 0x004F3 , 0x00443 , 0x0030B },
{ 0x004F4 , 0x00427 , 0x00308 },
{ 0x004F5 , 0x00447 , 0x00308 },
{ 0x004F8 , 0x0042B , 0x00308 },
{ 0x004F9 , 0x0044B , 0x00308 },
{ 0x00622 , 0x00627 , 0x00653 },
{ 0x00623 , 0x00627 , 0x00654 },
{ 0x00624 , 0x00648 , 0x00654 },
{ 0x00625 , 0x00627 , 0x00655 },
{ 0x00626 , 0x0064A , 0x00654 },
{ 0x006C0 , 0x006D5 , 0x00654 },
{ 0x006C2 , 0x006C1 , 0x00654 },
{ 0x006D3 , 0x006D2 , 0x00654 },
{ 0x00929 , 0x00928 , 0x0093C },
{ 0x00931 , 0x00930 , 0x0093C },
{ 0x00934 , 0x00933 , 0x0093C },
{ 0x009CB , 0x009C7 , 0x009BE },
{ 0x009CC , 0x009C7 , 0x009D7 },
{ 0x00B48 , 0x00B47 , 0x00B56 },
{ 0x00B4B , 0x00B47 , 0x00B3E },
{ 0x00B4C , 0x00B47 , 0x00B57 },
{ 0x00B94 , 0x00B92 , 0x00BD7 },
{ 0x00BCA , 0x00BC6 , 0x00BBE },
{ 0x00BCB , 0x00BC7 , 0x00BBE },
{ 0x00BCC , 0x00BC6 , 0x00BD7 },
{ 0x00C48 , 0x00C46 , 0x00C56 },
{ 0x00CC0 , 0x00CBF , 0x00CD5 },
{ 0x00CC7 , 0x00CC6 , 0x00CD5 },
{ 0x00CC8 , 0x00CC6 , 0x00CD6 },
{ 0x00CCA , 0x00CC6 , 0x00CC2 },
{ 0x00CCB , 0x00CCA , 0x00CD5 },
{ 0x00D4A , 0x00D46 , 0x00D3E },
{ 0x00D4B , 0x00D47 , 0x00D3E },
{ 0x00D4C , 0x00D46 , 0x00D57 },
{ 0x00DDA , 0x00DD9 , 0x00DCA },
{ 0x00DDC , 0x00DD9 , 0x00DCF },
{ 0x00DDD , 0x00DDC , 0x00DCA },
{ 0x00DDE , 0x00DD9 , 0x00DDF },
{ 0x01026 , 0x01025 , 0x0102E },
{ 0x01B06 , 0x01B05 , 0x01B35 },
{ 0x01B08 , 0x01B07 , 0x01B35 },
{ 0x01B0A , 0x01B09 , 0x01B35 },
{ 0x01B0C , 0x01B0B , 0x01B35 },
{ 0x01B0E , 0x01B0D , 0x01B35 },
{ 0x01B12 , 0x01B11 , 0x01B35 },
{ 0x01B3B , 0x01B3A , 0x01B35 },
{ 0x01B3D , 0x01B3C , 0x01B35 },
{ 0x01B40 , 0x01B3E , 0x01B35 },
{ 0x01B41 , 0x01B3F , 0x01B35 },
{ 0x01B43 , 0x01B42 , 0x01B35 },
{ 0x01E00 , 0x00041 , 0x00325 },
{ 0x01E01 , 0x00061 , 0x00325 },
{ 0x01E02 , 0x00042 , 0x00307 },
{ 0x01E03 , 0x00062 , 0x00307 },
{ 0x01E04 , 0x00042 , 0x00323 },
{ 0x01E05 , 0x00062 , 0x00323 },
{ 0x01E06 , 0x00042 , 0x00331 },
{ 0x01E07 , 0x00062 , 0x00331 },
{ 0x01E08 , 0x000C7 , 0x00301 },
{ 0x01E09 , 0x000E7 , 0x00301 },
{ 0x01E0A , 0x00044 , 0x00307 },
{ 0x01E0B , 0x00064 , 0x00307 },
{ 0x01E0C , 0x00044 , 0x00323 },
{ 0x01E0D , 0x00064 , 0x00323 },
{ 0x01E0E , 0x00044 , 0x00331 },
{ 0x01E0F , 0x00064 , 0x00331 },
{ 0x01E10 , 0x00044 , 0x00327 },
{ 0x01E11 , 0x00064 , 0x00327 },
{ 0x01E12 , 0x00044 , 0x0032D },
{ 0x01E13 , 0x00064 , 0x0032D },
{ 0x01E14 , 0x00112 , 0x00300 },
{ 0x01E15 , 0x00113 , 0x00300 },
{ 0x01E16 , 0x00112 , 0x00301 },
{ 0x01E17 , 0x00113 , 0x00301 },
{ 0x01E18 , 0x00045 , 0x0032D },
{ 0x01E19 , 0x00065 , 0x0032D },
{ 0x01E1A , 0x00045 , 0x00330 },
{ 0x01E1B , 0x00065 , 0x00330 },
{ 0x01E1C , 0x00228 , 0x00306 },
{ 0x01E1D , 0x00229 , 0x00306 },
{ 0x01E1E , 0x00046 , 0x00307 },
{ 0x01E1F , 0x00066 , 0x00307 },
{ 0x01E20 , 0x00047 , 0x00304 },
{ 0x01E21 , 0x00067 , 0x00304 },
{ 0x01E22 , 0x00048 , 0x00307 },
{ 0x01E23 , 0x00068 , 0x00307 },
{ 0x01E24 , 0x00048 , 0x00323 },
{ 0x01E25 , 0x00068 , 0x00323 },
{ 0x01E26 , 0x00048 , 0x00308 },
{ 0x01E27 , 0x00068 , 0x00308 },
{ 0x01E28 , 0x00048 , 0x00327 },
{ 0x01E29 , 0x00068 , 0x00327 },
{ 0x01E2A , 0x00048 , 0x0032E },
{ 0x01E2B , 0x00068 , 0x0032E },
{ 0x01E2C , 0x00049 , 0x00330 },
{ 0x01E2D , 0x00069 , 0x00330 },
{ 0x01E2E , 0x000CF , 0x00301 },
{ 0x01E2F , 0x000EF , 0x00301 },
{ 0x01E30 , 0x0004B , 0x00301 },
{ 0x01E31 , 0x0006B , 0x00301 },
{ 0x01E32 , 0x0004B , 0x00323 },
{ 0x01E33 , 0x0006B , 0x00323 },
{ 0x01E34 , 0x0004B , 0x00331 },
{ 0x01E35 , 0x0006B , 0x00331 },
{ 0x01E36 , 0x0004C , 0x00323 },
{ 0x01E37 , 0x0006C , 0x00323 },
{ 0x01E38 , 0x01E36 , 0x00304 },
{ 0x01E39 , 0x01E37 , 0x00304 },
{ 0x01E3A , 0x0004C , 0x00331 },
{ 0x01E3B , 0x0006C , 0x00331 },
{ 0x01E3C , 0x0004C , 0x0032D },
{ 0x01E3D , 0x0006C , 0x0032D },
{ 0x01E3E , 0x0004D , 0x00301 },
{ 0x01E3F , 0x0006D , 0x00301 },
{ 0x01E40 , 0x0004D , 0x00307 },
{ 0x01E41 , 0x0006D , 0x00307 },
{ 0x01E42 , 0x0004D , 0x00323 },
{ 0x01E43 , 0x0006D , 0x00323 },
{ 0x01E44 , 0x0004E , 0x00307 },
{ 0x01E45 , 0x0006E , 0x00307 },
{ 0x01E46 , 0x0004E , 0x00323 },
{ 0x01E47 , 0x0006E , 0x00323 },
{ 0x01E48 , 0x0004E , 0x00331 },
{ 0x01E49 , 0x0006E , 0x00331 },
{ 0x01E4A , 0x0004E , 0x0032D },
{ 0x01E4B , 0x0006E , 0x0032D },
{ 0x01E4C , 0x000D5 , 0x00301 },
{ 0x01E4D , 0x000F5 , 0x00301 },
{ 0x01E4E , 0x000D5 , 0x00308 },
{ 0x01E4F , 0x000F5 , 0x00308 },
{ 0x01E50 , 0x0014C , 0x00300 },
{ 0x01E51 , 0x0014D , 0x00300 },
{ 0x01E52 , 0x0014C , 0x00301 },
{ 0x01E53 , 0x0014D , 0x00301 },
{ 0x01E54 , 0x00050 , 0x00301 },
{ 0x01E55 , 0x00070 , 0x00301 },
{ 0x01E56 , 0x00050 , 0x00307 },
{ 0x01E57 , 0x00070 , 0x00307 },
{ 0x01E58 , 0x00052 , 0x00307 },
{ 0x01E59 , 0x00072 , 0x00307 },
{ 0x01E5A , 0x00052 , 0x00323 },
{ 0x01E5B , 0x00072 , 0x00323 },
{ 0x01E5C , 0x01E5A , 0x00304 },
{ 0x01E5D , 0x01E5B , 0x00304 },
{ 0x01E5E , 0x00052 , 0x00331 },
{ 0x01E5F , 0x00072 , 0x00331 },
{ 0x01E60 , 0x00053 , 0x00307 },
{ 0x01E61 , 0x00073 , 0x00307 },
{ 0x01E62 , 0x00053 , 0x00323 },
{ 0x01E63 , 0x00073 , 0x00323 },
{ 0x01E64 , 0x0015A , 0x00307 },
{ 0x01E65 , 0x0015B , 0x00307 },
{ 0x01E66 , 0x00160 , 0x00307 },
{ 0x01E67 , 0x00161 , 0x00307 },
{ 0x01E68 , 0x01E62 , 0x00307 },
{ 0x01E69 , 0x01E63 , 0x00307 },
{ 0x01E6A , 0x00054 , 0x00307 },
{ 0x01E6B , 0x00074 , 0x00307 },
{ 0x01E6C , 0x00054 , 0x00323 },
{ 0x01E6D , 0x00074 , 0x00323 },
{ 0x01E6E , 0x00054 , 0x00331 },
{ 0x01E6F , 0x00074 , 0x00331 },
{ 0x01E70 , 0x00054 , 0x0032D },
{ 0x01E71 , 0x00074 , 0x0032D },
{ 0x01E72 , 0x00055 , 0x00324 },
{ 0x01E73 , 0x00075 , 0x00324 },
{ 0x01E74 , 0x00055 , 0x00330 },
{ 0x01E75 , 0x00075 , 0x00330 },
{ 0x01E76 , 0x00055 , 0x0032D },
{ 0x01E77 , 0x00075 , 0x0032D },
{ 0x01E78 , 0x00168 , 0x00301 },
{ 0x01E79 , 0x00169 , 0x00301 },
{ 0x01E7A , 0x0016A , 0x00308 },
{ 0x01E7B , 0x0016B , 0x00308 },
{ 0x01E7C , 0x00056 , 0x00303 },
{ 0x01E7D , 0x00076 , 0x00303 },
{ 0x01E7E , 0x00056 , 0x00323 },
{ 0x01E7F , 0x00076 , 0x00323 },
{ 0x01E80 , 0x00057 , 0x00300 },
{ 0x01E81 , 0x00077 , 0x00300 },
{ 0x01E82 , 0x00057 , 0x00301 },
{ 0x01E83 , 0x00077 , 0x00301 },
{ 0x01E84 , 0x00057 , 0x00308 },
{ 0x01E85 , 0x00077 , 0x00308 },
{ 0x01E86 , 0x00057 , 0x00307 },
{ 0x01E87 , 0x00077 , 0x00307 },
{ 0x01E88 , 0x00057 , 0x00323 },
{ 0x01E89 , 0x00077 , 0x00323 },
{ 0x01E8A , 0x00058 , 0x00307 },
{ 0x01E8B , 0x00078 , 0x00307 },
{ 0x01E8C , 0x00058 , 0x00308 },
{ 0x01E8D , 0x00078 , 0x00308 },
{ 0x01E8E , 0x00059 , 0x00307 },
{ 0x01E8F , 0x00079 , 0x00307 },
{ 0x01E90 , 0x0005A , 0x00302 },
{ 0x01E91 , 0x0007A , 0x00302 },
{ 0x01E92 , 0x0005A , 0x00323 },
{ 0x01E93 , 0x0007A , 0x00323 },
{ 0x01E94 , 0x0005A , 0x00331 },
{ 0x01E95 , 0x0007A , 0x00331 },
{ 0x01E96 , 0x00068 , 0x00331 },
{ 0x01E97 , 0x00074 , 0x00308 },
{ 0x01E98 , 0x00077 , 0x0030A },
{ 0x01E99 , 0x00079 , 0x0030A },
{ 0x01E9B , 0x0017F , 0x00307 },
{ 0x01EA0 , 0x00041 , 0x00323 },
{ 0x01EA1 , 0x00061 , 0x00323 },
{ 0x01EA2 , 0x00041 , 0x00309 },
{ 0x01EA3 , 0x00061 , 0x00309 },
{ 0x01EA4 , 0x000C2 , 0x00301 },
{ 0x01EA5 , 0x000E2 , 0x00301 },
{ 0x01EA6 , 0x000C2 , 0x00300 },
{ 0x01EA7 , 0x000E2 , 0x00300 },
{ 0x01EA8 , 0x000C2 , 0x00309 },
{ 0x01EA9 , 0x000E2 , 0x00309 },
{ 0x01EAA , 0x000C2 , 0x00303 },
{ 0x01EAB , 0x000E2 , 0x00303 },
{ 0x01EAC , 0x01EA0 , 0x00302 },
{ 0x01EAD , 0x01EA1 , 0x00302 },
{ 0x01EAE , 0x00102 , 0x00301 },
{ 0x01EAF , 0x00103 , 0x00301 },
{ 0x01EB0 , 0x00102 , 0x00300 },
{ 0x01EB1 , 0x00103 , 0x00300 },
{ 0x01EB2 , 0x00102 , 0x00309 },
{ 0x01EB3 , 0x00103 , 0x00309 },
{ 0x01EB4 , 0x00102 , 0x00303 },
{ 0x01EB5 , 0x00103 , 0x00303 },
{ 0x01EB6 , 0x01EA0 , 0x00306 },
{ 0x01EB7 , 0x01EA1 , 0x00306 },
{ 0x01EB8 , 0x00045 , 0x00323 },
{ 0x01EB9 , 0x00065 , 0x00323 },
{ 0x01EBA , 0x00045 , 0x00309 },
{ 0x01EBB , 0x00065 , 0x00309 },
{ 0x01EBC , 0x00045 , 0x00303 },
{ 0x01EBD , 0x00065 , 0x00303 },
{ 0x01EBE , 0x000CA , 0x00301 },
{ 0x01EBF , 0x000EA , 0x00301 },
{ 0x01EC0 , 0x000CA , 0x00300 },
{ 0x01EC1 , 0x000EA , 0x00300 },
{ 0x01EC2 , 0x000CA , 0x00309 },
{ 0x01EC3 , 0x000EA , 0x00309 },
{ 0x01EC4 , 0x000CA , 0x00303 },
{ 0x01EC5 , 0x000EA , 0x00303 },
{ 0x01EC6 , 0x01EB8 , 0x00302 },
{ 0x01EC7 , 0x01EB9 , 0x00302 },
{ 0x01EC8 , 0x00049 , 0x00309 },
{ 0x01EC9 , 0x00069 , 0x00309 },
{ 0x01ECA , 0x00049 , 0x00323 },
{ 0x01ECB , 0x00069 , 0x00323 },
{ 0x01ECC , 0x0004F , 0x00323 },
{ 0x01ECD , 0x0006F , 0x00323 },
{ 0x01ECE , 0x0004F , 0x00309 },
{ 0x01ECF , 0x0006F , 0x00309 },
{ 0x01ED0 , 0x000D4 , 0x00301 },
{ 0x01ED1 , 0x000F4 , 0x00301 },
{ 0x01ED2 , 0x000D4 , 0x00300 },
{ 0x01ED3 , 0x000F4 , 0x00300 },
{ 0x01ED4 , 0x000D4 , 0x00309 },
{ 0x01ED5 , 0x000F4 , 0x00309 },
{ 0x01ED6 , 0x000D4 , 0x00303 },
{ 0x01ED7 , 0x000F4 , 0x00303 },
{ 0x01ED8 , 0x01ECC , 0x00302 },
{ 0x01ED9 , 0x01ECD , 0x00302 },
{ 0x01EDA , 0x001A0 , 0x00301 },
{ 0x01EDB , 0x001A1 , 0x00301 },
{ 0x01EDC , 0x001A0 , 0x00300 },
{ 0x01EDD , 0x001A1 , 0x00300 },
{ 0x01EDE , 0x001A0 , 0x00309 },
{ 0x01EDF , 0x001A1 , 0x00309 },
{ 0x01EE0 , 0x001A0 , 0x00303 },
{ 0x01EE1 , 0x001A1 , 0x00303 },
{ 0x01EE2 , 0x001A0 , 0x00323 },
{ 0x01EE3 , 0x001A1 , 0x00323 },
{ 0x01EE4 , 0x00055 , 0x00323 },
{ 0x01EE5 , 0x00075 , 0x00323 },
{ 0x01EE6 , 0x00055 , 0x00309 },
{ 0x01EE7 , 0x00075 , 0x00309 },
{ 0x01EE8 , 0x001AF , 0x00301 },
{ 0x01EE9 , 0x001B0 , 0x00301 },
{ 0x01EEA , 0x001AF , 0x00300 },
{ 0x01EEB , 0x001B0 , 0x00300 },
{ 0x01EEC , 0x001AF , 0x00309 },
{ 0x01EED , 0x001B0 , 0x00309 },
{ 0x01EEE , 0x001AF , 0x00303 },
{ 0x01EEF , 0x001B0 , 0x00303 },
{ 0x01EF0 , 0x001AF , 0x00323 },
{ 0x01EF1 , 0x001B0 , 0x00323 },
{ 0x01EF2 , 0x00059 , 0x00300 },
{ 0x01EF3 , 0x00079 , 0x00300 },
{ 0x01EF4 , 0x00059 , 0x00323 },
{ 0x01EF5 , 0x00079 , 0x00323 },
{ 0x01EF6 , 0x00059 , 0x00309 },
{ 0x01EF7 , 0x00079 , 0x00309 },
{ 0x01EF8 , 0x00059 , 0x00303 },
{ 0x01EF9 , 0x00079 , 0x00303 },
{ 0x01F00 , 0x003B1 , 0x00313 },
{ 0x01F01 , 0x003B1 , 0x00314 },
{ 0x01F02 , 0x01F00 , 0x00300 },
{ 0x01F03 , 0x01F01 , 0x00300 },
{ 0x01F04 , 0x01F00 , 0x00301 },
{ 0x01F05 , 0x01F01 , 0x00301 },
{ 0x01F06 , 0x01F00 , 0x00342 },
{ 0x01F07 , 0x01F01 , 0x00342 },
{ 0x01F08 , 0x00391 , 0x00313 },
{ 0x01F09 , 0x00391 , 0x00314 },
{ 0x01F0A , 0x01F08 , 0x00300 },
{ 0x01F0B , 0x01F09 , 0x00300 },
{ 0x01F0C , 0x01F08 , 0x00301 },
{ 0x01F0D , 0x01F09 , 0x00301 },
{ 0x01F0E , 0x01F08 , 0x00342 },
{ 0x01F0F , 0x01F09 , 0x00342 },
{ 0x01F10 , 0x003B5 , 0x00313 },
{ 0x01F11 , 0x003B5 , 0x00314 },
{ 0x01F12 , 0x01F10 , 0x00300 },
{ 0x01F13 , 0x01F11 , 0x00300 },
{ 0x01F14 , 0x01F10 , 0x00301 },
{ 0x01F15 , 0x01F11 , 0x00301 },
{ 0x01F18 , 0x00395 , 0x00313 },
{ 0x01F19 , 0x00395 , 0x00314 },
{ 0x01F1A , 0x01F18 , 0x00300 },
{ 0x01F1B , 0x01F19 , 0x00300 },
{ 0x01F1C , 0x01F18 , 0x00301 },
{ 0x01F1D , 0x01F19 , 0x00301 },
{ 0x01F20 , 0x003B7 , 0x00313 },
{ 0x01F21 , 0x003B7 , 0x00314 },
{ 0x01F22 , 0x01F20 , 0x00300 },
{ 0x01F23 , 0x01F21 , 0x00300 },
{ 0x01F24 , 0x01F20 , 0x00301 },
{ 0x01F25 , 0x01F21 , 0x00301 },
{ 0x01F26 , 0x01F20 , 0x00342 },
{ 0x01F27 , 0x01F21 , 0x00342 },
{ 0x01F28 , 0x00397 , 0x00313 },
{ 0x01F29 , 0x00397 , 0x00314 },
{ 0x01F2A , 0x01F28 , 0x00300 },
{ 0x01F2B , 0x01F29 , 0x00300 },
{ 0x01F2C , 0x01F28 , 0x00301 },
{ 0x01F2D , 0x01F29 , 0x00301 },
{ 0x01F2E , 0x01F28 , 0x00342 },
{ 0x01F2F , 0x01F29 , 0x00342 },
{ 0x01F30 , 0x003B9 , 0x00313 },
{ 0x01F31 , 0x003B9 , 0x00314 },
{ 0x01F32 , 0x01F30 , 0x00300 },
{ 0x01F33 , 0x01F31 , 0x00300 },
{ 0x01F34 , 0x01F30 , 0x00301 },
{ 0x01F35 , 0x01F31 , 0x00301 },
{ 0x01F36 , 0x01F30 , 0x00342 },
{ 0x01F37 , 0x01F31 , 0x00342 },
{ 0x01F38 , 0x00399 , 0x00313 },
{ 0x01F39 , 0x00399 , 0x00314 },
{ 0x01F3A , 0x01F38 , 0x00300 },
{ 0x01F3B , 0x01F39 , 0x00300 },
{ 0x01F3C , 0x01F38 , 0x00301 },
{ 0x01F3D , 0x01F39 , 0x00301 },
{ 0x01F3E , 0x01F38 , 0x00342 },
{ 0x01F3F , 0x01F39 , 0x00342 },
{ 0x01F40 , 0x003BF , 0x00313 },
{ 0x01F41 , 0x003BF , 0x00314 },
{ 0x01F42 , 0x01F40 , 0x00300 },
{ 0x01F43 , 0x01F41 , 0x00300 },
{ 0x01F44 , 0x01F40 , 0x00301 },
{ 0x01F45 , 0x01F41 , 0x00301 },
{ 0x01F48 , 0x0039F , 0x00313 },
{ 0x01F49 , 0x0039F , 0x00314 },
{ 0x01F4A , 0x01F48 , 0x00300 },
{ 0x01F4B , 0x01F49 , 0x00300 },
{ 0x01F4C , 0x01F48 , 0x00301 },
{ 0x01F4D , 0x01F49 , 0x00301 },
{ 0x01F50 , 0x003C5 , 0x00313 },
{ 0x01F51 , 0x003C5 , 0x00314 },
{ 0x01F52 , 0x01F50 , 0x00300 },
{ 0x01F53 , 0x01F51 , 0x00300 },
{ 0x01F54 , 0x01F50 , 0x00301 },
{ 0x01F55 , 0x01F51 , 0x00301 },
{ 0x01F56 , 0x01F50 , 0x00342 },
{ 0x01F57 , 0x01F51 , 0x00342 },
{ 0x01F59 , 0x003A5 , 0x00314 },
{ 0x01F5B , 0x01F59 , 0x00300 },
{ 0x01F5D , 0x01F59 , 0x00301 },
{ 0x01F5F , 0x01F59 , 0x00342 },
{ 0x01F60 , 0x003C9 , 0x00313 },
{ 0x01F61 , 0x003C9 , 0x00314 },
{ 0x01F62 , 0x01F60 , 0x00300 },
{ 0x01F63 , 0x01F61 , 0x00300 },
{ 0x01F64 , 0x01F60 , 0x00301 },
{ 0x01F65 , 0x01F61 , 0x00301 },
{ 0x01F66 , 0x01F60 , 0x00342 },
{ 0x01F67 , 0x01F61 , 0x00342 },
{ 0x01F68 , 0x003A9 , 0x00313 },
{ 0x01F69 , 0x003A9 , 0x00314 },
{ 0x01F6A , 0x01F68 , 0x00300 },
{ 0x01F6B , 0x01F69 , 0x00300 },
{ 0x01F6C , 0x01F68 , 0x00301 },
{ 0x01F6D , 0x01F69 , 0x00301 },
{ 0x01F6E , 0x01F68 , 0x00342 },
{ 0x01F6F , 0x01F69 , 0x00342 },
{ 0x01F70 , 0x003B1 , 0x00300 },
{ 0x01F72 , 0x003B5 , 0x00300 },
{ 0x01F74 , 0x003B7 , 0x00300 },
{ 0x01F76 , 0x003B9 , 0x00300 },
{ 0x01F78 , 0x003BF , 0x00300 },
{ 0x01F7A , 0x003C5 , 0x00300 },
{ 0x01F7C , 0x003C9 , 0x00300 },
{ 0x01F80 , 0x01F00 , 0x00345 },
{ 0x01F81 , 0x01F01 , 0x00345 },
{ 0x01F82 , 0x01F02 , 0x00345 },
{ 0x01F83 , 0x01F03 , 0x00345 },
{ 0x01F84 , 0x01F04 , 0x00345 },
{ 0x01F85 , 0x01F05 , 0x00345 },
{ 0x01F86 , 0x01F06 , 0x00345 },
{ 0x01F87 , 0x01F07 , 0x00345 },
{ 0x01F88 , 0x01F08 , 0x00345 },
{ 0x01F89 , 0x01F09 , 0x00345 },
{ 0x01F8A , 0x01F0A , 0x00345 },
{ 0x01F8B , 0x01F0B , 0x00345 },
{ 0x01F8C , 0x01F0C , 0x00345 },
{ 0x01F8D , 0x01F0D , 0x00345 },
{ 0x01F8E , 0x01F0E , 0x00345 },
{ 0x01F8F , 0x01F0F , 0x00345 },
{ 0x01F90 , 0x01F20 , 0x00345 },
{ 0x01F91 , 0x01F21 , 0x00345 },
{ 0x01F92 , 0x01F22 , 0x00345 },
{ 0x01F93 , 0x01F23 , 0x00345 },
{ 0x01F94 , 0x01F24 , 0x00345 },
{ 0x01F95 , 0x01F25 , 0x00345 },
{ 0x01F96 , 0x01F26 , 0x00345 },
{ 0x01F97 , 0x01F27 , 0x00345 },
{ 0x01F98 , 0x01F28 , 0x00345 },
{ 0x01F99 , 0x01F29 , 0x00345 },
{ 0x01F9A , 0x01F2A , 0x00345 },
{ 0x01F9B , 0x01F2B , 0x00345 },
{ 0x01F9C , 0x01F2C , 0x00345 },
{ 0x01F9D , 0x01F2D , 0x00345 },
{ 0x01F9E , 0x01F2E , 0x00345 },
{ 0x01F9F , 0x01F2F , 0x00345 },
{ 0x01FA0 , 0x01F60 , 0x00345 },
{ 0x01FA1 , 0x01F61 , 0x00345 },
{ 0x01FA2 , 0x01F62 , 0x00345 },
{ 0x01FA3 , 0x01F63 , 0x00345 },
{ 0x01FA4 , 0x01F64 , 0x00345 },
{ 0x01FA5 , 0x01F65 , 0x00345 },
{ 0x01FA6 , 0x01F66 , 0x00345 },
{ 0x01FA7 , 0x01F67 , 0x00345 },
{ 0x01FA8 , 0x01F68 , 0x00345 },
{ 0x01FA9 , 0x01F69 , 0x00345 },
{ 0x01FAA , 0x01F6A , 0x00345 },
{ 0x01FAB , 0x01F6B , 0x00345 },
{ 0x01FAC , 0x01F6C , 0x00345 },
{ 0x01FAD , 0x01F6D , 0x00345 },
{ 0x01FAE , 0x01F6E , 0x00345 },
{ 0x01FAF , 0x01F6F , 0x00345 },
{ 0x01FB0 , 0x003B1 , 0x00306 },
{ 0x01FB1 , 0x003B1 , 0x00304 },
{ 0x01FB2 , 0x01F70 , 0x00345 },
{ 0x01FB3 , 0x003B1 , 0x00345 },
{ 0x01FB4 , 0x003AC , 0x00345 },
{ 0x01FB6 , 0x003B1 , 0x00342 },
{ 0x01FB7 , 0x01FB6 , 0x00345 },
{ 0x01FB8 , 0x00391 , 0x00306 },
{ 0x01FB9 , 0x00391 , 0x00304 },
{ 0x01FBA , 0x00391 , 0x00300 },
{ 0x01FBC , 0x00391 , 0x00345 },
{ 0x01FC1 , 0x000A8 , 0x00342 },
{ 0x01FC2 , 0x01F74 , 0x00345 },
{ 0x01FC3 , 0x003B7 , 0x00345 },
{ 0x01FC4 , 0x003AE , 0x00345 },
{ 0x01FC6 , 0x003B7 , 0x00342 },
{ 0x01FC7 , 0x01FC6 , 0x00345 },
{ 0x01FC8 , 0x00395 , 0x00300 },
{ 0x01FCA , 0x00397 , 0x00300 },
{ 0x01FCC , 0x00397 , 0x00345 },
{ 0x01FCD , 0x01FBF , 0x00300 },
{ 0x01FCE , 0x01FBF , 0x00301 },
{ 0x01FCF , 0x01FBF , 0x00342 },
{ 0x01FD0 , 0x003B9 , 0x00306 },
{ 0x01FD1 , 0x003B9 , 0x00304 },
{ 0x01FD2 , 0x003CA , 0x00300 },
{ 0x01FD6 , 0x003B9 , 0x00342 },
{ 0x01FD7 , 0x003CA , 0x00342 },
{ 0x01FD8 , 0x00399 , 0x00306 },
{ 0x01FD9 , 0x00399 , 0x00304 },
{ 0x01FDA , 0x00399 , 0x00300 },
{ 0x01FDD , 0x01FFE , 0x00300 },
{ 0x01FDE , 0x01FFE , 0x00301 },
{ 0x01FDF , 0x01FFE , 0x00342 },
{ 0x01FE0 , 0x003C5 , 0x00306 },
{ 0x01FE1 , 0x003C5 , 0x00304 },
{ 0x01FE2 , 0x003CB , 0x00300 },
{ 0x01FE4 , 0x003C1 , 0x00313 },
{ 0x01FE5 , 0x003C1 , 0x00314 },
{ 0x01FE6 , 0x003C5 , 0x00342 },
{ 0x01FE7 , 0x003CB , 0x00342 },
{ 0x01FE8 , 0x003A5 , 0x00306 },
{ 0x01FE9 , 0x003A5 , 0x00304 },
{ 0x01FEA , 0x003A5 , 0x00300 },
{ 0x01FEC , 0x003A1 , 0x00314 },
{ 0x01FED , 0x000A8 , 0x00300 },
{ 0x01FF2 , 0x01F7C , 0x00345 },
{ 0x01FF3 , 0x003C9 , 0x00345 },
{ 0x01FF4 , 0x003CE , 0x00345 },
{ 0x01FF6 , 0x003C9 , 0x00342 },
{ 0x01FF7 , 0x01FF6 , 0x00345 },
{ 0x01FF8 , 0x0039F , 0x00300 },
{ 0x01FFA , 0x003A9 , 0x00300 },
{ 0x01FFC , 0x003A9 , 0x00345 },
{ 0x0219A , 0x02190 , 0x00338 },
{ 0x0219B , 0x02192 , 0x00338 },
{ 0x021AE , 0x02194 , 0x00338 },
{ 0x021CD , 0x021D0 , 0x00338 },
{ 0x021CE , 0x021D4 , 0x00338 },
{ 0x021CF , 0x021D2 , 0x00338 },
{ 0x02204 , 0x02203 , 0x00338 },
{ 0x02209 , 0x02208 , 0x00338 },
{ 0x0220C , 0x0220B , 0x00338 },
{ 0x02224 , 0x02223 , 0x00338 },
{ 0x02226 , 0x02225 , 0x00338 },
{ 0x02241 , 0x0223C , 0x00338 },
{ 0x02244 , 0x02243 , 0x00338 },
{ 0x02247 , 0x02245 , 0x00338 },
{ 0x02249 , 0x02248 , 0x00338 },
{ 0x02260 , 0x0003D , 0x00338 },
{ 0x02262 , 0x02261 , 0x00338 },
{ 0x0226D , 0x0224D , 0x00338 },
{ 0x0226E , 0x0003C , 0x00338 },
{ 0x0226F , 0x0003E , 0x00338 },
{ 0x02270 , 0x02264 , 0x00338 },
{ 0x02271 , 0x02265 , 0x00338 },
{ 0x02274 , 0x02272 , 0x00338 },
{ 0x02275 , 0x02273 , 0x00338 },
{ 0x02278 , 0x02276 , 0x00338 },
{ 0x02279 , 0x02277 , 0x00338 },
{ 0x02280 , 0x0227A , 0x00338 },
{ 0x02281 , 0x0227B , 0x00338 },
{ 0x02284 , 0x02282 , 0x00338 },
{ 0x02285 , 0x02283 , 0x00338 },
{ 0x02288 , 0x02286 , 0x00338 },
{ 0x02289 , 0x02287 , 0x00338 },
{ 0x022AC , 0x022A2 , 0x00338 },
{ 0x022AD , 0x022A8 , 0x00338 },
{ 0x022AE , 0x022A9 , 0x00338 },
{ 0x022AF , 0x022AB , 0x00338 },
{ 0x022E0 , 0x0227C , 0x00338 },
{ 0x022E1 , 0x0227D , 0x00338 },
{ 0x022E2 , 0x02291 , 0x00338 },
{ 0x022E3 , 0x02292 , 0x00338 },
{ 0x022EA , 0x022B2 , 0x00338 },
{ 0x022EB , 0x022B3 , 0x00338 },
{ 0x022EC , 0x022B4 , 0x00338 },
{ 0x022ED , 0x022B5 , 0x00338 },
{ 0x0304C , 0x0304B , 0x03099 },
{ 0x0304E , 0x0304D , 0x03099 },
{ 0x03050 , 0x0304F , 0x03099 },
{ 0x03052 , 0x03051 , 0x03099 },
{ 0x03054 , 0x03053 , 0x03099 },
{ 0x03056 , 0x03055 , 0x03099 },
{ 0x03058 , 0x03057 , 0x03099 },
{ 0x0305A , 0x03059 , 0x03099 },
{ 0x0305C , 0x0305B , 0x03099 },
{ 0x0305E , 0x0305D , 0x03099 },
{ 0x03060 , 0x0305F , 0x03099 },
{ 0x03062 , 0x03061 , 0x03099 },
{ 0x03065 , 0x03064 , 0x03099 },
{ 0x03067 , 0x03066 , 0x03099 },
{ 0x03069 , 0x03068 , 0x03099 },
{ 0x03070 , 0x0306F , 0x03099 },
{ 0x03071 , 0x0306F , 0x0309A },
{ 0x03073 , 0x03072 , 0x03099 },
{ 0x03074 , 0x03072 , 0x0309A },
{ 0x03076 , 0x03075 , 0x03099 },
{ 0x03077 , 0x03075 , 0x0309A },
{ 0x03079 , 0x03078 , 0x03099 },
{ 0x0307A , 0x03078 , 0x0309A },
{ 0x0307C , 0x0307B , 0x03099 },
{ 0x0307D , 0x0307B , 0x0309A },
{ 0x03094 , 0x03046 , 0x03099 },
{ 0x0309E , 0x0309D , 0x03099 },
{ 0x030AC , 0x030AB , 0x03099 },
{ 0x030AE , 0x030AD , 0x03099 },
{ 0x030B0 , 0x030AF , 0x03099 },
{ 0x030B2 , 0x030B1 , 0x03099 },
{ 0x030B4 , 0x030B3 , 0x03099 },
{ 0x030B6 , 0x030B5 , 0x03099 },
{ 0x030B8 , 0x030B7 , 0x03099 },
{ 0x030BA , 0x030B9 , 0x03099 },
{ 0x030BC , 0x030BB , 0x03099 },
{ 0x030BE , 0x030BD , 0x03099 },
{ 0x030C0 , 0x030BF , 0x03099 },
{ 0x030C2 , 0x030C1 , 0x03099 },
{ 0x030C5 , 0x030C4 , 0x03099 },
{ 0x030C7 , 0x030C6 , 0x03099 },
{ 0x030C9 , 0x030C8 , 0x03099 },
{ 0x030D0 , 0x030CF , 0x03099 },
{ 0x030D1 , 0x030CF , 0x0309A },
{ 0x030D3 , 0x030D2 , 0x03099 },
{ 0x030D4 , 0x030D2 , 0x0309A },
{ 0x030D6 , 0x030D5 , 0x03099 },
{ 0x030D7 , 0x030D5 , 0x0309A },
{ 0x030D9 , 0x030D8 , 0x03099 },
{ 0x030DA , 0x030D8 , 0x0309A },
{ 0x030DC , 0x030DB , 0x03099 },
{ 0x030DD , 0x030DB , 0x0309A },
{ 0x030F4 , 0x030A6 , 0x03099 },
{ 0x030F7 , 0x030EF , 0x03099 },
{ 0x030F8 , 0x030F0 , 0x03099 },
{ 0x030F9 , 0x030F1 , 0x03099 },
{ 0x030FA , 0x030F2 , 0x03099 },
{ 0x030FE , 0x030FD , 0x03099 },
{ 0x1109A , 0x11099 , 0x110BA },
{ 0x1109C , 0x1109B , 0x110BA },
{ 0x110AB , 0x110A5 , 0x110BA },
};
#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */ #endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */

View File

@ -38,7 +38,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string_sprintf.c 189435 2009-03-
* here. This is only used to format error messages, so doesn't * here. This is only used to format error messages, so doesn't
* require any floating-point support or field-width handling. * require any floating-point support or field-width handling.
*/ */
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <stdio.h> #include <stdio.h>
#include "archive_string.h" #include "archive_string.h"
@ -129,7 +131,7 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
break; break;
case 'c': case 'c':
s = va_arg(ap, int); s = va_arg(ap, int);
archive_strappend_char(as, s); archive_strappend_char(as, (char)s);
break; break;
case 'd': case 'd':
switch(long_flag) { switch(long_flag) {
@ -146,7 +148,9 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
pw = va_arg(ap, wchar_t *); pw = va_arg(ap, wchar_t *);
if (pw == NULL) if (pw == NULL)
pw = L"(null)"; pw = L"(null)";
archive_string_append_from_wcs(as, pw, wcslen(pw)); if (archive_string_append_from_wcs(as, pw,
wcslen(pw)) != 0 && errno == ENOMEM)
__archive_errx(1, "Out of memory");
break; break;
default: default:
p2 = va_arg(ap, char *); p2 = va_arg(ap, char *);
@ -160,7 +164,9 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
pw = va_arg(ap, wchar_t *); pw = va_arg(ap, wchar_t *);
if (pw == NULL) if (pw == NULL)
pw = L"(null)"; pw = L"(null)";
archive_string_append_from_wcs(as, pw, wcslen(pw)); if (archive_string_append_from_wcs(as, pw,
wcslen(pw)) != 0 && errno == ENOMEM)
__archive_errx(1, "Out of memory");
break; break;
case 'o': case 'u': case 'x': case 'X': case 'o': case 'u': case 'x': case 'X':
/* Common handling for unsigned integer formats. */ /* Common handling for unsigned integer formats. */

View File

@ -22,9 +22,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: head/lib/libarchive/archive_util.3 201098 2009-12-28 02:58:14Z kientzle $ .\" $FreeBSD$
.\" .\"
.Dd January 8, 2005 .Dd February 2, 2012
.Dt ARCHIVE_UTIL 3 .Dt ARCHIVE_UTIL 3
.Os .Os
.Sh NAME .Sh NAME
@ -43,6 +43,8 @@
.Nm archive_position , .Nm archive_position ,
.Nm archive_set_error .Nm archive_set_error
.Nd libarchive utility functions .Nd libarchive utility functions
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft void .Ft void

View File

@ -243,8 +243,9 @@ __archive_mktemp(const char *tmpdir)
archive_wstrcpy(&temp_name, tmp); archive_wstrcpy(&temp_name, tmp);
free(tmp); free(tmp);
} else { } else {
archive_wstring_append_from_mbs(&temp_name, tmpdir, if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
strlen(tmpdir)); strlen(tmpdir)) < 0)
goto exit_tmpfile;
if (temp_name.s[temp_name.length-1] != L'/') if (temp_name.s[temp_name.length-1] != L'/')
archive_wstrappend_wchar(&temp_name, L'/'); archive_wstrappend_wchar(&temp_name, L'/');
} }

View File

@ -65,6 +65,23 @@
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
#if defined(__LA_LSEEK_NEEDED)
static BOOL SetFilePointerEx_perso(HANDLE hFile,
LARGE_INTEGER liDistanceToMove,
PLARGE_INTEGER lpNewFilePointer,
DWORD dwMoveMethod)
{
LARGE_INTEGER li;
li.QuadPart = liDistanceToMove.QuadPart;
li.LowPart = SetFilePointer(
hFile, li.LowPart, &li.HighPart, dwMoveMethod);
if(lpNewFilePointer) {
lpNewFilePointer->QuadPart = li.QuadPart;
}
return li.LowPart != -1 || GetLastError() == NO_ERROR;
}
#endif
struct ustat { struct ustat {
int64_t st_atime; int64_t st_atime;
uint32_t st_atime_nsec; uint32_t st_atime_nsec;
@ -93,7 +110,7 @@ getino(struct ustat *ub)
ULARGE_INTEGER ino64; ULARGE_INTEGER ino64;
ino64.QuadPart = ub->st_ino; ino64.QuadPart = ub->st_ino;
/* I don't know this hashing is correct way */ /* I don't know this hashing is correct way */
return (ino64.LowPart ^ (ino64.LowPart >> INOSIZE)); return ((ino_t)(ino64.LowPart ^ (ino64.LowPart >> INOSIZE)));
} }
/* /*
@ -235,6 +252,40 @@ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
return (handle); return (handle);
} }
#if defined(__LA_LSEEK_NEEDED)
__int64
__la_lseek(int fd, __int64 offset, int whence)
{
LARGE_INTEGER distance;
LARGE_INTEGER newpointer;
HANDLE handle;
if (fd < 0) {
errno = EBADF;
return (-1);
}
handle = (HANDLE)_get_osfhandle(fd);
if (GetFileType(handle) != FILE_TYPE_DISK) {
errno = EBADF;
return (-1);
}
distance.QuadPart = offset;
if (!SetFilePointerEx_perso(handle, distance, &newpointer, whence)) {
DWORD lasterr;
lasterr = GetLastError();
if (lasterr == ERROR_BROKEN_PIPE)
return (0);
if (lasterr == ERROR_ACCESS_DENIED)
errno = EBADF;
else
la_dosmaperr(lasterr);
return (-1);
}
return (newpointer.QuadPart);
}
#endif
/* This can exceed MAX_PATH limitation. */ /* This can exceed MAX_PATH limitation. */
int int
__la_open(const char *path, int flags, ...) __la_open(const char *path, int flags, ...)
@ -374,7 +425,7 @@ __la_read(int fd, void *buf, size_t nbytes)
/* Convert Windows FILETIME to UTC */ /* Convert Windows FILETIME to UTC */
__inline static void __inline static void
fileTimeToUTC(const FILETIME *filetime, time_t *time, long *ns) fileTimeToUTC(const FILETIME *filetime, time_t *t, long *ns)
{ {
ULARGE_INTEGER utc; ULARGE_INTEGER utc;
@ -382,10 +433,10 @@ fileTimeToUTC(const FILETIME *filetime, time_t *time, long *ns)
utc.LowPart = filetime->dwLowDateTime; utc.LowPart = filetime->dwLowDateTime;
if (utc.QuadPart >= EPOC_TIME) { if (utc.QuadPart >= EPOC_TIME) {
utc.QuadPart -= EPOC_TIME; utc.QuadPart -= EPOC_TIME;
*time = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */ *t = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
*ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */ *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
} else { } else {
*time = 0; *t = 0;
*ns = 0; *ns = 0;
} }
} }
@ -408,7 +459,7 @@ __hstat(HANDLE handle, struct ustat *st)
ULARGE_INTEGER ino64; ULARGE_INTEGER ino64;
DWORD ftype; DWORD ftype;
mode_t mode; mode_t mode;
time_t time; time_t t;
long ns; long ns;
switch (ftype = GetFileType(handle)) { switch (ftype = GetFileType(handle)) {
@ -465,14 +516,14 @@ __hstat(HANDLE handle, struct ustat *st)
mode |= S_IFREG; mode |= S_IFREG;
st->st_mode = mode; st->st_mode = mode;
fileTimeToUTC(&info.ftLastAccessTime, &time, &ns); fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
st->st_atime = time; st->st_atime = t;
st->st_atime_nsec = ns; st->st_atime_nsec = ns;
fileTimeToUTC(&info.ftLastWriteTime, &time, &ns); fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
st->st_mtime = time; st->st_mtime = t;
st->st_mtime_nsec = ns; st->st_mtime_nsec = ns;
fileTimeToUTC(&info.ftCreationTime, &time, &ns); fileTimeToUTC(&info.ftCreationTime, &t, &ns);
st->st_ctime = time; st->st_ctime = t;
st->st_ctime_nsec = ns; st->st_ctime_nsec = ns;
st->st_size = st->st_size =
((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1)) ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
@ -508,7 +559,7 @@ copy_stat(struct stat *st, struct ustat *us)
st->st_ino = getino(us); st->st_ino = getino(us);
st->st_mode = us->st_mode; st->st_mode = us->st_mode;
st->st_nlink = us->st_nlink; st->st_nlink = us->st_nlink;
st->st_size = us->st_size; st->st_size = (off_t)us->st_size;
st->st_uid = us->st_uid; st->st_uid = us->st_uid;
st->st_dev = us->st_dev; st->st_dev = us->st_dev;
st->st_rdev = us->st_rdev; st->st_rdev = us->st_rdev;
@ -853,7 +904,7 @@ __la_dosmaperr(unsigned long e)
return; return;
} }
for (i = 0; i < sizeof(doserrors); i++) for (i = 0; i < (int)sizeof(doserrors); i++)
{ {
if (doserrors[i].winerr == e) if (doserrors[i].winerr == e)
{ {

View File

@ -71,10 +71,6 @@
#include <windows.h> #include <windows.h>
//#define EFTYPE 7 //#define EFTYPE 7
#if defined(_MSC_VER)
/* TODO: Fix the code, don't suppress the warnings. */
#pragma warning(disable:4244) /* 'conversion' conversion from 'type1' to 'type2', possible loss of data */
#endif
#if defined(__BORLANDC__) #if defined(__BORLANDC__)
#pragma warn -8068 /* Constant out of range in comparison. */ #pragma warn -8068 /* Constant out of range in comparison. */
#pragma warn -8072 /* Suspicious pointer arithmetic. */ #pragma warn -8072 /* Suspicious pointer arithmetic. */
@ -95,7 +91,12 @@
#define fileno _fileno #define fileno _fileno
#endif #endif
#define fstat __la_fstat #define fstat __la_fstat
#if !defined(__BORLANDC__)
#define lseek _lseeki64 #define lseek _lseeki64
#else
#define lseek __la_lseek
#define __LA_LSEEK_NEEDED
#endif
#define lstat __la_stat #define lstat __la_stat
#define open __la_open #define open __la_open
#define read __la_read #define read __la_read
@ -245,6 +246,9 @@
/* Replacement POSIX function */ /* Replacement POSIX function */
extern int __la_fstat(int fd, struct stat *st); extern int __la_fstat(int fd, struct stat *st);
extern int __la_lstat(const char *path, struct stat *st); extern int __la_lstat(const char *path, struct stat *st);
#if defined(__LA_LSEEK_NEEDED)
extern __int64 __la_lseek(int fd, __int64 offset, int whence);
#endif
extern int __la_open(const char *path, int flags, ...); extern int __la_open(const char *path, int flags, ...);
extern ssize_t __la_read(int fd, void *buf, size_t nbytes); extern ssize_t __la_read(int fd, void *buf, size_t nbytes);
extern int __la_stat(const char *path, struct stat *st); extern int __la_stat(const char *path, struct stat *st);
@ -264,5 +268,27 @@ extern void __la_dosmaperr(unsigned long e);
extern struct archive_entry *__la_win_entry_in_posix_pathseparator( extern struct archive_entry *__la_win_entry_in_posix_pathseparator(
struct archive_entry *); struct archive_entry *);
#if defined(HAVE_WCRTOMB) && defined(__BORLANDC__)
typedef int mbstate_t;
size_t wcrtomb(char *, wchar_t, mbstate_t *);
#endif
#if defined(_MSC_VER) && _MSC_VER < 1300
WINBASEAPI BOOL WINAPI GetVolumePathNameW(
LPCWSTR lpszFileName,
LPWSTR lpszVolumePathName,
DWORD cchBufferLength
);
# if _WIN32_WINNT < 0x0500 /* windows.h not providing 0x500 API */
typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
LARGE_INTEGER FileOffset;
LARGE_INTEGER Length;
} FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER;
# define FSCTL_SET_SPARSE \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_WRITE_DATA)
# define FSCTL_QUERY_ALLOCATED_RANGES \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 51, METHOD_NEITHER, FILE_READ_DATA)
# endif
#endif
#endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */ #endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */

View File

@ -22,14 +22,16 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $ .\" $FreeBSD$
.\" .\"
.Dd March 23, 2011 .Dd February 2, 2012
.Dt ARCHIVE_WRITE 3 .Dt ARCHIVE_WRITE 3
.Os .Os
.Sh NAME .Sh NAME
.Nm archive_write .Nm archive_write
.Nd functions for creating archives .Nd functions for creating archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Sh DESCRIPTION .Sh DESCRIPTION

View File

@ -380,7 +380,7 @@ archive_write_client_write(struct archive_write_filter *f,
} }
} }
while ((size_t)remaining > state->buffer_size) { while ((size_t)remaining >= state->buffer_size) {
/* Write out full blocks directly to client. */ /* Write out full blocks directly to client. */
bytes_written = (a->client_writer)(&a->archive, bytes_written = (a->client_writer)(&a->archive,
a->client_data, buff, state->buffer_size); a->client_data, buff, state->buffer_size);
@ -623,7 +623,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
if (a->skip_file_set && if (a->skip_file_set &&
archive_entry_dev_is_set(entry) && archive_entry_dev_is_set(entry) &&
archive_entry_ino_is_set(entry) && archive_entry_ino_is_set(entry) &&
archive_entry_dev(entry) == a->skip_file_dev && archive_entry_dev(entry) == (dev_t)a->skip_file_dev &&
archive_entry_ino64(entry) == a->skip_file_ino) { archive_entry_ino64(entry) == a->skip_file_ino) {
archive_set_error(&a->archive, 0, archive_set_error(&a->archive, 0,
"Can't add archive to itself"); "Can't add archive to itself");

View File

@ -1,13 +1,12 @@
/*- /*-
* Copyright (c) 2003-2007 Tim Kientzle * Copyright (c) 2012 Ondrej Holy
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer * notice, this list of conditions and the following disclaimer.
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -22,25 +21,46 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/ */
#ifndef MATCHING_H #include "archive_platform.h"
#define MATCHING_H __FBSDID("$FreeBSD$");
struct lafe_matching;
int lafe_exclude(struct lafe_matching **matching, const char *pattern);
int lafe_exclude_from_file(struct lafe_matching **matching,
const char *pathname);
int lafe_include(struct lafe_matching **matching, const char *pattern);
int lafe_include_from_file(struct lafe_matching **matching,
const char *pathname, int nullSeparator);
int lafe_excluded(struct lafe_matching *, const char *pathname);
void lafe_cleanup_exclusions(struct lafe_matching **);
int lafe_unmatched_inclusions(struct lafe_matching *);
int lafe_unmatched_inclusions_warn(struct lafe_matching *, const char *msg);
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif #endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "archive.h"
#include "archive_private.h"
/* A table that maps filter codes to functions. */
static
struct { int code; int (*setter)(struct archive *); } codes[] =
{
{ ARCHIVE_FILTER_NONE, archive_write_add_filter_none },
{ ARCHIVE_FILTER_GZIP, archive_write_add_filter_gzip },
{ ARCHIVE_FILTER_BZIP2, archive_write_add_filter_bzip2 },
{ ARCHIVE_FILTER_COMPRESS, archive_write_add_filter_compress },
{ ARCHIVE_FILTER_LZMA, archive_write_add_filter_lzma },
{ ARCHIVE_FILTER_XZ, archive_write_add_filter_xz },
{ ARCHIVE_FILTER_LZIP, archive_write_add_filter_lzip },
{ -1, NULL }
};
int
archive_write_add_filter(struct archive *a, int code)
{
int i;
for (i = 0; codes[i].code != -1; i++) {
if (code == codes[i].code)
return ((codes[i].setter)(a));
}
archive_set_error(a, EINVAL, "No such filter");
return (ARCHIVE_FATAL);
}

View File

@ -133,10 +133,18 @@ archive_compressor_bzip2_open(struct archive_write_filter *f)
if (ret != 0) if (ret != 0)
return (ret); return (ret);
/* TODO: Find a better way to size this. (Maybe look at the */
/* block size expected by the following filter?) */
if (data->compressed == NULL) { if (data->compressed == NULL) {
data->compressed_buffer_size = 65536; size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)
bs = bpb;
else if (bpb != 0)
bs -= bs % bpb;
}
data->compressed_buffer_size = bs;
data->compressed data->compressed
= (char *)malloc(data->compressed_buffer_size); = (char *)malloc(data->compressed_buffer_size);
if (data->compressed == NULL) { if (data->compressed == NULL) {

View File

@ -148,6 +148,7 @@ archive_compressor_compress_open(struct archive_write_filter *f)
{ {
int ret; int ret;
struct private_data *state; struct private_data *state;
size_t bs = 65536, bpb;
f->code = ARCHIVE_COMPRESSION_COMPRESS; f->code = ARCHIVE_COMPRESSION_COMPRESS;
f->name = "compress"; f->name = "compress";
@ -163,7 +164,16 @@ archive_compressor_compress_open(struct archive_write_filter *f)
return (ARCHIVE_FATAL); return (ARCHIVE_FATAL);
} }
state->compressed_buffer_size = 65536; if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)
bs = bpb;
else if (bpb != 0)
bs -= bs % bpb;
}
state->compressed_buffer_size = bs;
state->compressed = malloc(state->compressed_buffer_size); state->compressed = malloc(state->compressed_buffer_size);
if (state->compressed == NULL) { if (state->compressed == NULL) {
@ -386,12 +396,12 @@ archive_compressor_compress_write(struct archive_write_filter *f,
state->checkpoint = state->in_count + CHECK_GAP; state->checkpoint = state->in_count + CHECK_GAP;
if (state->in_count <= 0x007fffff) if (state->in_count <= 0x007fffff && state->out_count != 0)
ratio = state->in_count * 256 / state->out_count; ratio = (int)(state->in_count * 256 / state->out_count);
else if ((ratio = state->out_count / 256) == 0) else if ((ratio = (int)(state->out_count / 256)) == 0)
ratio = 0x7fffffff; ratio = 0x7fffffff;
else else
ratio = state->in_count / ratio; ratio = (int)(state->in_count / ratio);
if (ratio > state->compress_ratio) if (ratio > state->compress_ratio)
state->compress_ratio = ratio; state->compress_ratio = ratio;

View File

@ -135,7 +135,17 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
return (ret); return (ret);
if (data->compressed == NULL) { if (data->compressed == NULL) {
data->compressed_buffer_size = 65536; size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)
bs = bpb;
else if (bpb != 0)
bs -= bs % bpb;
}
data->compressed_buffer_size = bs;
data->compressed data->compressed
= (unsigned char *)malloc(data->compressed_buffer_size); = (unsigned char *)malloc(data->compressed_buffer_size);
if (data->compressed == NULL) { if (data->compressed == NULL) {
@ -155,10 +165,10 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
data->compressed[1] = 0x8b; data->compressed[1] = 0x8b;
data->compressed[2] = 0x08; /* "Deflate" compression */ data->compressed[2] = 0x08; /* "Deflate" compression */
data->compressed[3] = 0; /* No options */ data->compressed[3] = 0; /* No options */
data->compressed[4] = (t)&0xff; /* Timestamp */ data->compressed[4] = (uint8_t)(t)&0xff; /* Timestamp */
data->compressed[5] = (t>>8)&0xff; data->compressed[5] = (uint8_t)(t>>8)&0xff;
data->compressed[6] = (t>>16)&0xff; data->compressed[6] = (uint8_t)(t>>16)&0xff;
data->compressed[7] = (t>>24)&0xff; data->compressed[7] = (uint8_t)(t>>24)&0xff;
data->compressed[8] = 0; /* No deflate options */ data->compressed[8] = 0; /* No deflate options */
data->compressed[9] = 3; /* OS=Unix */ data->compressed[9] = 3; /* OS=Unix */
data->stream.next_out += 10; data->stream.next_out += 10;
@ -270,14 +280,14 @@ archive_compressor_gzip_close(struct archive_write_filter *f)
} }
if (ret == ARCHIVE_OK) { if (ret == ARCHIVE_OK) {
/* Build and write out 8-byte trailer. */ /* Build and write out 8-byte trailer. */
trailer[0] = (data->crc)&0xff; trailer[0] = (uint8_t)(data->crc)&0xff;
trailer[1] = (data->crc >> 8)&0xff; trailer[1] = (uint8_t)(data->crc >> 8)&0xff;
trailer[2] = (data->crc >> 16)&0xff; trailer[2] = (uint8_t)(data->crc >> 16)&0xff;
trailer[3] = (data->crc >> 24)&0xff; trailer[3] = (uint8_t)(data->crc >> 24)&0xff;
trailer[4] = (data->total_in)&0xff; trailer[4] = (uint8_t)(data->total_in)&0xff;
trailer[5] = (data->total_in >> 8)&0xff; trailer[5] = (uint8_t)(data->total_in >> 8)&0xff;
trailer[6] = (data->total_in >> 16)&0xff; trailer[6] = (uint8_t)(data->total_in >> 16)&0xff;
trailer[7] = (data->total_in >> 24)&0xff; trailer[7] = (uint8_t)(data->total_in >> 24)&0xff;
ret = __archive_write_filter(f->next_filter, trailer, 8); ret = __archive_write_filter(f->next_filter, trailer, 8);
} }

View File

@ -171,60 +171,62 @@ child_write(struct archive_write_filter *f, const char *buf, size_t buf_len)
if (buf_len == 0) if (buf_len == 0)
return (-1); return (-1);
restart_write: for (;;) {
do { do {
ret = write(data->child_stdin, buf, buf_len); ret = write(data->child_stdin, buf, buf_len);
} while (ret == -1 && errno == EINTR); } while (ret == -1 && errno == EINTR);
if (ret > 0) if (ret > 0)
return (ret); return (ret);
if (ret == 0) { if (ret == 0) {
close(data->child_stdin); close(data->child_stdin);
data->child_stdin = -1; data->child_stdin = -1;
fcntl(data->child_stdout, F_SETFL, 0); fcntl(data->child_stdout, F_SETFL, 0);
return (0); return (0);
}
if (ret == -1 && errno != EAGAIN)
return (-1);
if (data->child_stdout == -1) {
fcntl(data->child_stdin, F_SETFL, 0);
__archive_check_child(data->child_stdin,
data->child_stdout);
continue;
}
do {
ret = read(data->child_stdout,
data->child_buf + data->child_buf_avail,
data->child_buf_len - data->child_buf_avail);
} while (ret == -1 && errno == EINTR);
if (ret == 0 || (ret == -1 && errno == EPIPE)) {
close(data->child_stdout);
data->child_stdout = -1;
fcntl(data->child_stdin, F_SETFL, 0);
continue;
}
if (ret == -1 && errno == EAGAIN) {
__archive_check_child(data->child_stdin,
data->child_stdout);
continue;
}
if (ret == -1)
return (-1);
data->child_buf_avail += ret;
ret = __archive_write_filter(f->next_filter,
data->child_buf, data->child_buf_avail);
if (ret <= 0)
return (-1);
if ((size_t)ret < data->child_buf_avail) {
memmove(data->child_buf, data->child_buf + ret,
data->child_buf_avail - ret);
}
data->child_buf_avail -= ret;
} }
if (ret == -1 && errno != EAGAIN)
return (-1);
if (data->child_stdout == -1) {
fcntl(data->child_stdin, F_SETFL, 0);
__archive_check_child(data->child_stdin, data->child_stdout);
goto restart_write;
}
do {
ret = read(data->child_stdout,
data->child_buf + data->child_buf_avail,
data->child_buf_len - data->child_buf_avail);
} while (ret == -1 && errno == EINTR);
if (ret == 0 || (ret == -1 && errno == EPIPE)) {
close(data->child_stdout);
data->child_stdout = -1;
fcntl(data->child_stdin, F_SETFL, 0);
goto restart_write;
}
if (ret == -1 && errno == EAGAIN) {
__archive_check_child(data->child_stdin, data->child_stdout);
goto restart_write;
}
if (ret == -1)
return (-1);
data->child_buf_avail += ret;
ret = __archive_write_filter(f->next_filter,
data->child_buf, data->child_buf_avail);
if (ret <= 0)
return (-1);
if ((size_t)ret < data->child_buf_avail) {
memmove(data->child_buf, data->child_buf + ret,
data->child_buf_avail - ret);
}
data->child_buf_avail -= ret;
goto restart_write;
} }
/* /*

View File

@ -298,7 +298,17 @@ archive_compressor_xz_open(struct archive_write_filter *f)
return (ret); return (ret);
if (data->compressed == NULL) { if (data->compressed == NULL) {
data->compressed_buffer_size = 65536; size_t bs = 65536, bpb;
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
/* Buffer size should be a multiple number of the of bytes
* per block for performance. */
bpb = archive_write_get_bytes_per_block(f->archive);
if (bpb > bs)
bs = bpb;
else if (bpb != 0)
bs -= bs % bpb;
}
data->compressed_buffer_size = bs;
data->compressed data->compressed
= (unsigned char *)malloc(data->compressed_buffer_size); = (unsigned char *)malloc(data->compressed_buffer_size);
if (data->compressed == NULL) { if (data->compressed == NULL) {

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 23, 2011 .Dd February 2, 2012
.Dt ARCHIVE_WRITE_BLOCKSIZE 3 .Dt ARCHIVE_WRITE_BLOCKSIZE 3
.Os .Os
.Sh NAME .Sh NAME
@ -33,6 +33,8 @@
.Nm archive_write_get_bytes_in_last_block , .Nm archive_write_get_bytes_in_last_block ,
.Nm archive_write_set_bytes_in_last_block .Nm archive_write_set_bytes_in_last_block
.Nd functions for creating archives .Nd functions for creating archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft int .Ft int

View File

@ -22,14 +22,16 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $ .\" $FreeBSD$
.\" .\"
.Dd March 23, 2011 .Dd February 2, 2012
.Dt ARCHIVE_WRITE 3 .Dt ARCHIVE_WRITE_DATA 3
.Os .Os
.Sh NAME .Sh NAME
.Nm archive_write_data .Nm archive_write_data
.Nd functions for creating archives .Nd functions for creating archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft ssize_t .Ft ssize_t

View File

@ -22,9 +22,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: src/lib/libarchive/archive_write_disk.3,v 1.4 2008/09/04 05:22:00 kientzle Exp $ .\" $FreeBSD$
.\" .\"
.Dd August 5, 2008 .Dd February 2, 2012
.Dt ARCHIVE_WRITE_DISK 3 .Dt ARCHIVE_WRITE_DISK 3
.Os .Os
.Sh NAME .Sh NAME
@ -42,6 +42,8 @@
.Nm archive_write_finish .Nm archive_write_finish
.Nm archive_write_free .Nm archive_write_free
.Nd functions for creating objects on disk .Nd functions for creating objects on disk
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft struct archive * .Ft struct archive *

View File

@ -188,8 +188,8 @@ struct archive_write_disk {
struct fixup_entry *current_fixup; struct fixup_entry *current_fixup;
int64_t user_uid; int64_t user_uid;
int skip_file_set; int skip_file_set;
dev_t skip_file_dev; int64_t skip_file_dev;
ino_t skip_file_ino; int64_t skip_file_ino;
time_t start_time; time_t start_time;
int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid); int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
@ -1143,9 +1143,10 @@ restore_entry(struct archive_write_disk *a)
/* If it's our archive, we're done. */ /* If it's our archive, we're done. */
if (a->skip_file_set && if (a->skip_file_set &&
a->st.st_dev == a->skip_file_dev && a->st.st_dev == (dev_t)a->skip_file_dev &&
a->st.st_ino == a->skip_file_ino) { a->st.st_ino == (ino_t)a->skip_file_ino) {
archive_set_error(&a->archive, 0, "Refusing to overwrite archive"); archive_set_error(&a->archive, 0,
"Refusing to overwrite archive");
return (ARCHIVE_FAILED); return (ARCHIVE_FAILED);
} }
@ -1163,7 +1164,7 @@ restore_entry(struct archive_write_disk *a)
/* A dir is in the way of a non-dir, rmdir it. */ /* A dir is in the way of a non-dir, rmdir it. */
if (rmdir(a->name) != 0) { if (rmdir(a->name) != 0) {
archive_set_error(&a->archive, errno, archive_set_error(&a->archive, errno,
"Can't remove already-existing dir"); "Can't replace existing directory with non-directory");
return (ARCHIVE_FAILED); return (ARCHIVE_FAILED);
} }
/* Try again. */ /* Try again. */
@ -2529,7 +2530,7 @@ set_mac_metadata(struct archive_write_disk *a, const char *pathname,
} }
written = write(fd, metadata, metadata_size); written = write(fd, metadata, metadata_size);
close(fd); close(fd);
if (written != metadata_size if ((size_t)written != metadata_size
|| copyfile(tmp.s, pathname, 0, || copyfile(tmp.s, pathname, 0,
COPYFILE_UNPACK | COPYFILE_NOFOLLOW COPYFILE_UNPACK | COPYFILE_NOFOLLOW
| COPYFILE_ACL | COPYFILE_XATTR)) { | COPYFILE_ACL | COPYFILE_XATTR)) {
@ -2584,7 +2585,7 @@ set_acl(struct archive_write_disk *a, int fd, const char *name,
acl_t acl; acl_t acl;
acl_entry_t acl_entry; acl_entry_t acl_entry;
acl_permset_t acl_permset; acl_permset_t acl_permset;
int ret; int ret, r;
int ae_type, ae_permset, ae_tag, ae_id; int ae_type, ae_permset, ae_tag, ae_id;
uid_t ae_uid; uid_t ae_uid;
gid_t ae_gid; gid_t ae_gid;
@ -2596,9 +2597,9 @@ set_acl(struct archive_write_disk *a, int fd, const char *name,
if (entries == 0) if (entries == 0)
return (ARCHIVE_OK); return (ARCHIVE_OK);
acl = acl_init(entries); acl = acl_init(entries);
while (archive_acl_next(&a->archive, abstract_acl, while ((r = archive_acl_next(&a->archive, abstract_acl,
ae_requested_type, &ae_type, &ae_permset, &ae_tag, &ae_id, ae_requested_type, &ae_type, &ae_permset, &ae_tag, &ae_id,
&ae_name) == ARCHIVE_OK) { &ae_name)) == ARCHIVE_OK) {
acl_create_entry(&acl, &acl_entry); acl_create_entry(&acl, &acl_entry);
switch (ae_tag) { switch (ae_tag) {
@ -2640,6 +2641,12 @@ set_acl(struct archive_write_disk *a, int fd, const char *name,
if (ae_permset & ARCHIVE_ENTRY_ACL_READ) if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
acl_add_perm(acl_permset, ACL_READ); acl_add_perm(acl_permset, ACL_READ);
} }
if (r == ARCHIVE_FATAL) {
acl_free(acl);
archive_set_error(&a->archive, errno,
"Failed to archive_acl_next");
return (r);
}
/* Try restoring the ACL through 'fd' if we can. */ /* Try restoring the ACL through 'fd' if we can. */
#if HAVE_ACL_SET_FD #if HAVE_ACL_SET_FD

View File

@ -122,6 +122,7 @@ lookup_gid(void *private_data, const char *gname, int64_t gid)
char _buffer[128]; char _buffer[128];
size_t bufsize = 128; size_t bufsize = 128;
char *buffer = _buffer; char *buffer = _buffer;
char *allocated = NULL;
struct group grent, *result; struct group grent, *result;
int r; int r;
@ -133,16 +134,15 @@ lookup_gid(void *private_data, const char *gname, int64_t gid)
if (r != ERANGE) if (r != ERANGE)
break; break;
bufsize *= 2; bufsize *= 2;
if (buffer != _buffer) free(allocated);
free(buffer); allocated = malloc(bufsize);
buffer = malloc(bufsize); if (allocated == NULL)
if (buffer == NULL)
break; break;
buffer = allocated;
} }
if (result != NULL) if (result != NULL)
gid = result->gr_gid; gid = result->gr_gid;
if (buffer != _buffer) free(allocated);
free(buffer);
} }
# else /* HAVE_GETGRNAM_R */ # else /* HAVE_GETGRNAM_R */
{ {
@ -158,7 +158,7 @@ lookup_gid(void *private_data, const char *gname, int64_t gid)
#else #else
#error No way to perform gid lookups on this platform #error No way to perform gid lookups on this platform
#endif #endif
b->id = gid; b->id = (gid_t)gid;
return (gid); return (gid);
} }
@ -192,6 +192,7 @@ lookup_uid(void *private_data, const char *uname, int64_t uid)
char _buffer[128]; char _buffer[128];
size_t bufsize = 128; size_t bufsize = 128;
char *buffer = _buffer; char *buffer = _buffer;
char *allocated = NULL;
struct passwd pwent, *result; struct passwd pwent, *result;
int r; int r;
@ -203,16 +204,15 @@ lookup_uid(void *private_data, const char *uname, int64_t uid)
if (r != ERANGE) if (r != ERANGE)
break; break;
bufsize *= 2; bufsize *= 2;
if (buffer != _buffer) free(allocated);
free(buffer); allocated = malloc(bufsize);
buffer = malloc(bufsize); if (allocated == NULL)
if (buffer == NULL)
break; break;
buffer = allocated;
} }
if (result != NULL) if (result != NULL)
uid = result->pw_uid; uid = result->pw_uid;
if (buffer != _buffer) free(allocated);
free(buffer);
} }
# else /* HAVE_GETPWNAM_R */ # else /* HAVE_GETPWNAM_R */
{ {
@ -228,7 +228,7 @@ lookup_uid(void *private_data, const char *uname, int64_t uid)
#else #else
#error No way to look up uids on this platform #error No way to look up uids on this platform
#endif #endif
b->id = uid; b->id = (uid_t)uid;
return (uid); return (uid);
} }

View File

@ -1,6 +1,6 @@
/*- /*-
* Copyright (c) 2003-2010 Tim Kientzle * Copyright (c) 2003-2010 Tim Kientzle
* Copyright (c) 2011 Michihiro NAKAJIMA * Copyright (c) 2011-2012 Michihiro NAKAJIMA
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -33,9 +33,6 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_UTIME_H #ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h> #include <sys/utime.h>
#endif #endif
@ -48,13 +45,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_LIMITS_H #ifdef HAVE_LIMITS_H
#include <limits.h> #include <limits.h>
#endif #endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H #ifdef HAVE_STDLIB_H
#include <stdlib.h> #include <stdlib.h>
#endif #endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <winioctl.h> #include <winioctl.h>
/* TODO: Support Mac OS 'quarantine' feature. This is really just a /* TODO: Support Mac OS 'quarantine' feature. This is really just a
@ -89,7 +82,7 @@ static BOOL SetFilePointerEx_perso(HANDLE hFile,
if(lpNewFilePointer) { if(lpNewFilePointer) {
lpNewFilePointer->QuadPart = li.QuadPart; lpNewFilePointer->QuadPart = li.QuadPart;
} }
return li.LowPart != -1 || GetLastError() == NO_ERROR; return li.LowPart != (DWORD)-1 || GetLastError() == NO_ERROR;
} }
struct fixup_entry { struct fixup_entry {
@ -144,8 +137,8 @@ struct archive_write_disk {
struct fixup_entry *current_fixup; struct fixup_entry *current_fixup;
int64_t user_uid; int64_t user_uid;
int skip_file_set; int skip_file_set;
dev_t skip_file_dev; int64_t skip_file_dev;
ino_t skip_file_ino; int64_t skip_file_ino;
time_t start_time; time_t start_time;
int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid); int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
@ -214,26 +207,24 @@ struct archive_write_disk {
static int check_symlinks(struct archive_write_disk *); static int check_symlinks(struct archive_write_disk *);
static int create_filesystem_object(struct archive_write_disk *); static int create_filesystem_object(struct archive_write_disk *);
static struct fixup_entry *current_fixup(struct archive_write_disk *, const wchar_t *pathname); static struct fixup_entry *current_fixup(struct archive_write_disk *,
#if defined(HAVE_FCHDIR) && defined(PATH_MAX) const wchar_t *pathname);
static void edit_deep_directories(struct archive_write_disk *ad);
#endif
static int cleanup_pathname(struct archive_write_disk *); static int cleanup_pathname(struct archive_write_disk *);
static int create_dir(struct archive_write_disk *, wchar_t *); static int create_dir(struct archive_write_disk *, wchar_t *);
static int create_parent_dir(struct archive_write_disk *, wchar_t *); static int create_parent_dir(struct archive_write_disk *, wchar_t *);
static int la_chmod(const wchar_t *, mode_t);
static int older(BY_HANDLE_FILE_INFORMATION *, struct archive_entry *); static int older(BY_HANDLE_FILE_INFORMATION *, struct archive_entry *);
static int permissive_name_w(struct archive_write_disk *);
static int restore_entry(struct archive_write_disk *); static int restore_entry(struct archive_write_disk *);
#ifdef HAVE_POSIX_ACL static int set_acls(struct archive_write_disk *, HANDLE h,
static int set_acl(struct archive_write_disk *, int fd, const char *, struct archive_acl *, const wchar_t *, struct archive_acl *);
acl_type_t, int archive_entry_acl_type, const char *tn);
#endif
static int set_acls(struct archive_write_disk *, HANDLE h, const wchar_t *, struct archive_acl *);
static int set_xattrs(struct archive_write_disk *); static int set_xattrs(struct archive_write_disk *);
static int set_fflags(struct archive_write_disk *); static int set_fflags(struct archive_write_disk *);
static int set_ownership(struct archive_write_disk *); static int set_ownership(struct archive_write_disk *);
static int set_mode(struct archive_write_disk *, int mode); static int set_mode(struct archive_write_disk *, int mode);
static int set_times(struct archive_write_disk *, HANDLE, int, const wchar_t *, static int set_times(struct archive_write_disk *, HANDLE, int,
time_t, long, time_t, long, time_t, long, time_t, long); const wchar_t *, time_t, long, time_t, long, time_t,
long, time_t, long);
static int set_times_from_entry(struct archive_write_disk *); static int set_times_from_entry(struct archive_write_disk *);
static struct fixup_entry *sort_dir_list(struct fixup_entry *p); static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
static ssize_t write_data_block(struct archive_write_disk *, static ssize_t write_data_block(struct archive_write_disk *,
@ -243,11 +234,14 @@ static struct archive_vtable *archive_write_disk_vtable(void);
static int _archive_write_disk_close(struct archive *); static int _archive_write_disk_close(struct archive *);
static int _archive_write_disk_free(struct archive *); static int _archive_write_disk_free(struct archive *);
static int _archive_write_disk_header(struct archive *, struct archive_entry *); static int _archive_write_disk_header(struct archive *,
struct archive_entry *);
static int64_t _archive_write_disk_filter_bytes(struct archive *, int); static int64_t _archive_write_disk_filter_bytes(struct archive *, int);
static int _archive_write_disk_finish_entry(struct archive *); static int _archive_write_disk_finish_entry(struct archive *);
static ssize_t _archive_write_disk_data(struct archive *, const void *, size_t); static ssize_t _archive_write_disk_data(struct archive *, const void *,
static ssize_t _archive_write_disk_data_block(struct archive *, const void *, size_t, int64_t); size_t);
static ssize_t _archive_write_disk_data_block(struct archive *, const void *,
size_t, int64_t);
#define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber) #define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber)
/* Treat FileIndex as i-node. We should remove a sequence number /* Treat FileIndex as i-node. We should remove a sequence number
@ -361,7 +355,7 @@ file_information(struct archive_write_disk *a, wchar_t *path,
* So we have to make the full-pathname in another way, which does not * So we have to make the full-pathname in another way, which does not
* break "../" path string. * break "../" path string.
*/ */
int static int
permissive_name_w(struct archive_write_disk *a) permissive_name_w(struct archive_write_disk *a)
{ {
wchar_t *wn, *wnp; wchar_t *wn, *wnp;
@ -424,10 +418,12 @@ permissive_name_w(struct archive_write_disk *a)
wn = _wcsdup(wnp); wn = _wcsdup(wnp);
if (wn == NULL) if (wn == NULL)
return (-1); return (-1);
archive_wstring_ensure(&(a->_name_data), 8 + wcslen(wn) + 1); archive_wstring_ensure(&(a->_name_data),
8 + wcslen(wn) + 1);
a->name = a->_name_data.s; a->name = a->_name_data.s;
/* Prepend "\\?\UNC\" */ /* Prepend "\\?\UNC\" */
archive_wstrncpy(&(a->_name_data), L"\\\\?\\UNC\\", 8); archive_wstrncpy(&(a->_name_data),
L"\\\\?\\UNC\\", 8);
archive_wstrcat(&(a->_name_data), wn+2); archive_wstrcat(&(a->_name_data), wn+2);
free(wn); free(wn);
return (0); return (0);
@ -457,7 +453,8 @@ permissive_name_w(struct archive_write_disk *a)
wn = _wcsdup(wnp); wn = _wcsdup(wnp);
if (wn == NULL) if (wn == NULL)
return (-1); return (-1);
archive_wstring_ensure(&(a->_name_data), 4 + 2 + wcslen(wn) + 1); archive_wstring_ensure(&(a->_name_data),
4 + 2 + wcslen(wn) + 1);
a->name = a->_name_data.s; a->name = a->_name_data.s;
/* Prepend "\\?\" and drive name. */ /* Prepend "\\?\" and drive name. */
archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4); archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
@ -484,7 +481,7 @@ permissive_name_w(struct archive_write_disk *a)
return (0); return (0);
} }
int static int
la_chmod(const wchar_t *path, mode_t mode) la_chmod(const wchar_t *path, mode_t mode)
{ {
DWORD attr; DWORD attr;
@ -917,6 +914,7 @@ archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
static ssize_t static ssize_t
write_data_block(struct archive_write_disk *a, const char *buff, size_t size) write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
{ {
OVERLAPPED ol;
uint64_t start_size = size; uint64_t start_size = size;
DWORD bytes_written = 0; DWORD bytes_written = 0;
ssize_t block_size = 0, bytes_to_write; ssize_t block_size = 0, bytes_to_write;
@ -968,26 +966,13 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
* truncate it to the block boundary. */ * truncate it to the block boundary. */
bytes_to_write = size; bytes_to_write = size;
if (a->offset + bytes_to_write > block_end) if (a->offset + bytes_to_write > block_end)
bytes_to_write = block_end - a->offset; bytes_to_write = (DWORD)(block_end - a->offset);
} }
/* Seek if necessary to the specified offset. */ memset(&ol, 0, sizeof(ol));
if (a->offset != a->fd_offset) { ol.Offset = (DWORD)(a->offset & 0xFFFFFFFF);
LARGE_INTEGER distance; ol.OffsetHigh = (DWORD)(a->offset >> 32);
distance.QuadPart = a->offset;
if (SetFilePointerEx_perso(a->fh, distance, NULL, FILE_BEGIN) == 0) {
DWORD lasterr = GetLastError();
if (lasterr == ERROR_ACCESS_DENIED)
errno = EBADF;
else
la_dosmaperr(lasterr);
archive_set_error(&a->archive, errno,
"Seek failed");
return (ARCHIVE_FATAL);
}
a->fd_offset = a->offset;
}
if (!WriteFile(a->fh, buff, (uint32_t)bytes_to_write, if (!WriteFile(a->fh, buff, (uint32_t)bytes_to_write,
&bytes_written, NULL)) { &bytes_written, &ol)) {
DWORD lasterr; DWORD lasterr;
lasterr = GetLastError(); lasterr = GetLastError();
@ -1004,7 +989,7 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
a->offset += bytes_written; a->offset += bytes_written;
a->fd_offset = a->offset; a->fd_offset = a->offset;
} }
return (start_size - size); return ((ssize_t)(start_size - size));
} }
static ssize_t static ssize_t
@ -1393,7 +1378,8 @@ restore_entry(struct archive_write_disk *a)
if (a->skip_file_set && if (a->skip_file_set &&
bhfi_dev(&a->st) == a->skip_file_dev && bhfi_dev(&a->st) == a->skip_file_dev &&
bhfi_ino(&a->st) == a->skip_file_ino) { bhfi_ino(&a->st) == a->skip_file_ino) {
archive_set_error(&a->archive, 0, "Refusing to overwrite archive"); archive_set_error(&a->archive, 0,
"Refusing to overwrite archive");
return (ARCHIVE_FAILED); return (ARCHIVE_FAILED);
} }
@ -2209,7 +2195,8 @@ create_dir(struct archive_write_disk *a, wchar_t *path)
* don't add it to the fixup list here, as it's already been * don't add it to the fixup list here, as it's already been
* added. * added.
*/ */
if (file_information(a, path, &st, &st_mode, 0) == 0 && S_ISDIR(st_mode)) if (file_information(a, path, &st, &st_mode, 0) == 0 &&
S_ISDIR(st_mode))
return (ARCHIVE_OK); return (ARCHIVE_OK);
archive_set_error(&a->archive, errno, "Failed to create dir '%ls'", archive_set_error(&a->archive, errno, "Failed to create dir '%ls'",
@ -2252,7 +2239,7 @@ set_times(struct archive_write_disk *a,
time_t atime, long atime_nanos, time_t atime, long atime_nanos,
time_t birthtime, long birthtime_nanos, time_t birthtime, long birthtime_nanos,
time_t mtime, long mtime_nanos, time_t mtime, long mtime_nanos,
time_t ctime, long ctime_nanos) time_t ctime_sec, long ctime_nanos)
{ {
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\ #define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
@ -2263,7 +2250,7 @@ set_times(struct archive_write_disk *a,
FILETIME *pfbtime; FILETIME *pfbtime;
FILETIME fatime, fbtime, fmtime; FILETIME fatime, fbtime, fmtime;
(void)ctime; /* UNUSED */ (void)ctime_sec; /* UNUSED */
(void)ctime_nanos; /* UNUSED */ (void)ctime_nanos; /* UNUSED */
if (h != INVALID_HANDLE_VALUE) { if (h != INVALID_HANDLE_VALUE) {
@ -2314,11 +2301,11 @@ settimes_failed:
static int static int
set_times_from_entry(struct archive_write_disk *a) set_times_from_entry(struct archive_write_disk *a)
{ {
time_t atime, birthtime, mtime, ctime; time_t atime, birthtime, mtime, ctime_sec;
long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec; long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec;
/* Suitable defaults. */ /* Suitable defaults. */
atime = birthtime = mtime = ctime = a->start_time; atime = birthtime = mtime = ctime_sec = a->start_time;
atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0; atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0;
/* If no time was provided, we're done. */ /* If no time was provided, we're done. */
@ -2340,7 +2327,7 @@ set_times_from_entry(struct archive_write_disk *a)
mtime_nsec = archive_entry_mtime_nsec(a->entry); mtime_nsec = archive_entry_mtime_nsec(a->entry);
} }
if (archive_entry_ctime_is_set(a->entry)) { if (archive_entry_ctime_is_set(a->entry)) {
ctime = archive_entry_ctime(a->entry); ctime_sec = archive_entry_ctime(a->entry);
ctime_nsec = archive_entry_ctime_nsec(a->entry); ctime_nsec = archive_entry_ctime_nsec(a->entry);
} }
@ -2348,7 +2335,7 @@ set_times_from_entry(struct archive_write_disk *a)
atime, atime_nsec, atime, atime_nsec,
birthtime, birthtime_nsec, birthtime, birthtime_nsec,
mtime, mtime_nsec, mtime, mtime_nsec,
ctime, ctime_nsec); ctime_sec, ctime_nsec);
} }
static int static int
@ -2471,7 +2458,7 @@ set_xattrs(struct archive_write_disk *a)
} }
static void static void
fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns) fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
{ {
ULARGE_INTEGER utc; ULARGE_INTEGER utc;
@ -2480,11 +2467,11 @@ fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns)
if (utc.QuadPart >= EPOC_TIME) { if (utc.QuadPart >= EPOC_TIME) {
utc.QuadPart -= EPOC_TIME; utc.QuadPart -= EPOC_TIME;
/* milli seconds base */ /* milli seconds base */
*time = (time_t)(utc.QuadPart / 10000000); *t = (time_t)(utc.QuadPart / 10000000);
/* nano seconds base */ /* nano seconds base */
*ns = (long)(utc.QuadPart % 10000000) * 100; *ns = (long)(utc.QuadPart % 10000000) * 100;
} else { } else {
*time = 0; *t = 0;
*ns = 0; *ns = 0;
} }
} }

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 23, 2011 .Dd February 2, 2012
.Dt ARCHIVE_WRITE_FILTER 3 .Dt ARCHIVE_WRITE_FILTER 3
.Os .Os
.Sh NAME .Sh NAME
@ -36,6 +36,8 @@
.Nm archive_write_add_filter_none , .Nm archive_write_add_filter_none ,
.Nm archive_write_add_filter_program , .Nm archive_write_add_filter_program ,
.Nm archive_write_add_filter_xz .Nm archive_write_add_filter_xz
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft int .Ft int

View File

@ -22,14 +22,16 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $FreeBSD: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $ .\" $FreeBSD$
.\" .\"
.Dd March 23, 2011 .Dd February 2, 2012
.Dt ARCHIVE_WRITE_FINISH_ENTRY 3 .Dt ARCHIVE_WRITE_FINISH_ENTRY 3
.Os .Os
.Sh NAME .Sh NAME
.Nm archive_write_finish_entry .Nm archive_write_finish_entry
.Nd functions for creating archives .Nd functions for creating archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft int .Ft int

View File

@ -24,7 +24,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 23, 2011 .Dd February 2, 2012
.Dt ARCHIVE_WRITE_FORMAT 3 .Dt ARCHIVE_WRITE_FORMAT 3
.Os .Os
.Sh NAME .Sh NAME
@ -35,6 +35,8 @@
.Nm archive_write_set_format_shar_dump , .Nm archive_write_set_format_shar_dump ,
.Nm archive_write_set_format_ustar .Nm archive_write_set_format_ustar
.Nd functions for creating archives .Nd functions for creating archives
.Sh LIBRARY
Streaming Archive Library (libarchive, -larchive)
.Sh SYNOPSIS .Sh SYNOPSIS
.In archive.h .In archive.h
.Ft int .Ft int

Some files were not shown because too many files have changed in this diff Show More