Update vendor libarchive dist to new "release" branch (post 3.0.3)

Git branch:	release
Git commit:	9af87742342aa4f37a22ec12c4cc1c82e00ffa2f

Obtained from:	https://github.com/libarchive/libarchive.git
This commit is contained in:
Martin Matuska 2012-02-08 12:53:14 +00:00
parent d8b2811c01
commit 17993d47e9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/libarchive/dist/; revision=231200
509 changed files with 133310 additions and 15052 deletions

View File

@ -2,11 +2,16 @@
#
PROJECT(libarchive C)
#
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin)
endif()
SET(CMAKE_BUILD_TYPE "Release")
# On MacOS, prefer MacPorts libraries to system libraries.
# I haven't come up with a compelling argument for this to be conditional.
list(APPEND CMAKE_PREFIX_PATH /opt/local)
#
# Version - read from 'version' file.
@ -21,41 +26,52 @@ STRING(REGEX REPLACE
STRING(REGEX REPLACE
"^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]([a-z]?)$" "\\1" _quality ${_version})
SET(_version_number ${_major}${_minor}${_revision})
STRING(REGEX REPLACE "[0]*([^0][0-9]*)$" "\\1" _minor ${_minor})
STRING(REGEX REPLACE "[0]*([^0][0-9]*)$" "\\1" _revision ${_revision})
STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_minor ${_minor})
STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_revision ${_revision})
#
SET(VERSION "${_major}.${_minor}.${_revision}${_quality}")
SET(VERSION "${_major}.${_trimmed_minor}.${_trimmed_revision}${_quality}")
SET(BSDCPIO_VERSION_STRING "${VERSION}")
SET(BSDTAR_VERSION_STRING "${VERSION}")
SET(LIBARCHIVE_VERSION_NUMBER "${_version_number}")
SET(LIBARCHIVE_VERSION_STRING "${VERSION}")
# Shared library number
SET(SOVERSION 8)
# INTERFACE_VERSION increments with every release
# libarchive 2.7 == interface version 9 = 2 + 7
# libarchive 2.8 == interface version 10 = 2 + 8
# libarchive 2.9 == interface version 11 = 2 + 9
# libarchive 3.0 == interface version 12
# libarchive 3.x == interface version 12 + x
math(EXPR INTERFACE_VERSION "12 + ${_minor}")
# Set SOVERSION == Interface version
# ?? Should there be more here ??
SET(SOVERSION "${INTERFACE_VERSION}")
# Especially for early development, we want to be a little
# aggressive about diagnosing build problems; this can get
# relaxed somewhat in final shipping versions.
IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
ADD_DEFINITIONS(-Wall)
SET(CMAKE_REQUIRED_FLAGS "-Wall")
ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
# Enable CTest/CDash support
include(CTest)
# Provide ADD_TEST_28 macro to approximate CMake 2.8 ADD_TEST(NAME).
# TODO: Require CMake 2.8 and drop this workaround (perhaps late 2010).
INCLUDE(AddTest28)
OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
OPTION(ENABLE_TAR "Enable tar building" ON)
OPTION(ENABLE_TAR_SHARED "Enable dynamic build of tar" OFF)
OPTION(ENABLE_TAR_SHARED "Enable dynamic build of tar" FALSE)
OPTION(ENABLE_CPIO "Enable cpio building" ON)
OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" OFF)
OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE)
OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
OPTION(ENABLE_ACL "Enable ACL support" ON)
OPTION(ENABLE_ICONV "Enable iconv support" ON)
OPTION(ENABLE_TEST "Enable unit and regression tests" ON)
IF(ENABLE_TEST)
ENABLE_TESTING()
ENDIF(ENABLE_TEST)
IF(WIN32 AND NOT CYGWIN)
# Currently, dynamic build only.
SET(ENABLE_TAR_SHARED ON)
SET(ENABLE_CPIO_SHARED ON)
ENDIF(WIN32 AND NOT CYGWIN)
IF(WIN32)
SET(_WIN32_WINNT 0x0500 CACHE INTERNAL "Setting _WIN32_WINNT to 0x0500 for Windows 2000 APIs")
@ -63,6 +79,7 @@ IF(WIN32)
ENDIF(WIN32)
#
INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckCSourceRuns)
INCLUDE(CheckFileOffsetBits)
INCLUDE(CheckFuncs)
@ -185,18 +202,11 @@ IF(LZMA_FOUND)
SET(HAVE_LZMA_H 1)
INCLUDE_DIRECTORIES(${LZMA_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${LZMA_LIBRARIES})
MARK_AS_ADVANCED(CLEAR LZMA_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR LZMA_LIBRARY)
ELSEIF(LZMADEC_FOUND)
SET(HAVE_LIBLZMADEC 1)
SET(HAVE_LZMADEC_H 1)
INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
MARK_AS_ADVANCED(CLEAR LZMADEC_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR LZMADEC_LIBRARY)
ELSE(LZMA_FOUND)
MARK_AS_ADVANCED(CLEAR LZMA_INCLUDE_DIR)
MARK_AS_ADVANCED(CLEAR LZMA_LIBRARY)
ENDIF(LZMA_FOUND)
#
@ -218,17 +228,25 @@ LA_CHECK_INCLUDE_FILE("sys/types.h" HAVE_SYS_TYPES_H)
# Alphabetize the rest unless there's a compelling reason
LA_CHECK_INCLUDE_FILE("acl/libacl.h" HAVE_ACL_LIBACL_H)
LA_CHECK_INCLUDE_FILE("ctype.h" HAVE_CTYPE_H)
LA_CHECK_INCLUDE_FILE("copyfile.h" HAVE_COPYFILE_H)
LA_CHECK_INCLUDE_FILE("direct.h" HAVE_DIRECT_H)
LA_CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLFCN_H)
LA_CHECK_INCLUDE_FILE("errno.h" HAVE_ERRNO_H)
LA_CHECK_INCLUDE_FILE("ext2fs/ext2_fs.h" HAVE_EXT2FS_EXT2_FS_H)
CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
#include <ext2fs/ext2_fs.h>
int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H)
LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H)
LA_CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H)
LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H)
LA_CHECK_INCLUDE_FILE("limits.h" HAVE_LIMITS_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/magic.h" HAVE_LINUX_MAGIC_H)
LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H)
LA_CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H)
LA_CHECK_INCLUDE_FILE("paths.h" HAVE_PATHS_H)
@ -246,12 +264,17 @@ LA_CHECK_INCLUDE_FILE("sys/acl.h" HAVE_SYS_ACL_H)
LA_CHECK_INCLUDE_FILE("sys/cdefs.h" HAVE_SYS_CDEFS_H)
LA_CHECK_INCLUDE_FILE("sys/ioctl.h" HAVE_SYS_IOCTL_H)
LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
LA_CHECK_INCLUDE_FILE("sys/statfs.h" HAVE_SYS_STATFS_H)
LA_CHECK_INCLUDE_FILE("sys/statvfs.h" HAVE_SYS_STATVFS_H)
LA_CHECK_INCLUDE_FILE("sys/time.h" HAVE_SYS_TIME_H)
LA_CHECK_INCLUDE_FILE("sys/utime.h" HAVE_SYS_UTIME_H)
LA_CHECK_INCLUDE_FILE("sys/utsname.h" HAVE_SYS_UTSNAME_H)
LA_CHECK_INCLUDE_FILE("sys/vfs.h" HAVE_SYS_VFS_H)
LA_CHECK_INCLUDE_FILE("sys/wait.h" HAVE_SYS_WAIT_H)
LA_CHECK_INCLUDE_FILE("time.h" HAVE_TIME_H)
LA_CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H)
@ -259,17 +282,47 @@ LA_CHECK_INCLUDE_FILE("utime.h" HAVE_UTIME_H)
LA_CHECK_INCLUDE_FILE("wchar.h" HAVE_WCHAR_H)
LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
# Following files need windwos.h, so we should test it after windows.h test.
LA_CHECK_INCLUDE_FILE("wincrypt.h" HAVE_WINCRYPT_H)
LA_CHECK_INCLUDE_FILE("winioctl.h" HAVE_WINIOCTL_H)
#
# Some headers require extra includes when they're available.
# Check whether use of __EXTENSIONS__ is safe.
# We need some macro such as _GNU_SOURCE to use extension functions.
#
SET(_INCLUDE_FILES)
FOREACH (it ${_HEADER})
SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
ENDFOREACH (it)
CHECK_C_SOURCE_COMPILES(
"#define __EXTENSIONS__ 1
${_INCLUDE_FILES}
int main() { return 0;}"
SAFE_TO_DEFINE_EXTENSIONS)
#
# Find Nettle
#
IF(ENABLE_NETTLE)
CHECK_LIBRARY_EXISTS(nettle "nettle_sha1_digest" "" NETTLE_FOUND)
IF(NETTLE_FOUND)
SET(CMAKE_REQUIRED_LIBRARIES "nettle")
FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle)
LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARY})
ELSE(NETTLE_FOUND)
SET(ENABLE_NETTLE OFF)
ENDIF(NETTLE_FOUND)
ENDIF(ENABLE_NETTLE)
#
# Find OpenSSL
# (Except on Mac, where OpenSSL is deprecated.)
#
IF(ENABLE_OPENSSL)
IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
FIND_PACKAGE(OpenSSL)
ELSE()
SET(OPENSSL_FOUND FALSE) # Override cached value
ENDIF()
# FreeBSD libmd
@ -281,126 +334,134 @@ IF(LIBMD_FOUND)
ENDIF(LIBMD_FOUND)
#
# How to prove that HASH functions, which have several names on various
# platforms, can be mapped to archive_{hash name}_init,
# archive_{hash name}_update and archive_{hash name}_final through
# archive_hash.h
# How to prove that CRYPTO functions, which have several names on various
# platforms, just see if archive_crypto.c can compile and link against
# required libraries.
#
MACRO(CHECK_MD HASH IMPLEMENTATIONS)
MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
IF(HAVE_SYS_TYPES_H)
SET(HASH_HEADER_CONFIG "#define HAVE_SYS_TYPES_H 1\n")
SET(CRYPTO_HEADER_CONFIG "#define HAVE_SYS_TYPES_H 1\n")
ELSE(HAVE_SYS_TYPES_H)
SET(HASH_HEADER_CONFIG "")
SET(CRYPTO_HEADER_CONFIG "")
ENDIF(HAVE_SYS_TYPES_H)
FOREACH(IMPLEMENTATION ${IMPLEMENTATIONS})
IF(NOT DEFINED ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
STRING(TOLOWER "${HASH}" lower_hash)
STRING(TOUPPER "${HASH}" hash)
FOREACH(ALGORITHM ${ALGORITHMS})
STRING(TOLOWER "${ALGORITHM}" lower_algorithm)
STRING(TOUPPER "${ALGORITHM}" algorithm)
IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NOT NETTLE_FOUND)
SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
SET(HASH_REQUIRED_INCLUDES)
SET(TRY_HASH_REQUIRED_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_CURRENT_SOURCE_DIR}/libarchive")
SET(HASH_REQUIRED_LIBS)
SET(TRY_HASH_REQUIRED_LIBS)
IF(NOT DEFINED ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
# Probe the local implementation for whether this
# crypto implementation is available on this platform.
SET(TRY_CRYPTO_REQUIRED_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_CURRENT_SOURCE_DIR}/libarchive;${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp")
SET(TRY_CRYPTO_REQUIRED_LIBS)
IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
SET(HASH_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
SET(TRY_HASH_REQUIRED_INCLUDES
"${TRY_HASH_REQUIRED_INCLUDES};${OPENSSL_INCLUDE_DIR}")
SET(HASH_REQUIRED_LIBS ${OPENSSL_LIBRARIES})
SET(TRY_HASH_REQUIRED_LIBS
SET(TRY_CRYPTO_REQUIRED_INCLUDES
"${TRY_CRYPTO_REQUIRED_INCLUDES};${OPENSSL_INCLUDE_DIR}")
SET(TRY_CRYPTO_REQUIRED_LIBS
"-DLINK_LIBRARIES:STRING=${OPENSSL_LIBRARIES}")
ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NETTLE_FOUND)
SET(TRY_CRYPTO_REQUIRED_LIBS
"-DLINK_LIBRARIES:STRING=${NETTLE_LIBRARY}")
ELSEIF("${IMPLEMENTATION}" MATCHES "^LIBMD$" AND LIBMD_FOUND)
SET(TRY_HASH_REQUIRED_LIBS
SET(TRY_CRYPTO_REQUIRED_LIBS
"-DLINK_LIBRARIES:STRING=${LIBMD_LIBRARY}")
ENDIF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
SET(SOURCE "#define ${hash}_COMPILE_TEST
#define ARCHIVE_HASH_${hash}_${IMPLEMENTATION}
#define __LIBARCHIVE_BUILD
${HASH_HEADER_CONFIG}
#include \"archive_hash.h\"
FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/libarchive/archive_crypto.c"
ARCHIVE_CRYPTO_C)
SET(SOURCE "
#define ARCHIVE_${algorithm}_COMPILE_TEST
#define ARCHIVE_CRYPTO_${algorithm}_${IMPLEMENTATION}
#define PLATFORM_CONFIG_H \"check_crypto_md.h\"
${ARCHIVE_CRYPTO_C}
int
main(int argc, char **argv)
{
archive_${lower_hash}_ctx ctx;
archive_${lower_hash}_init(&ctx);
archive_${lower_hash}_update(&ctx, *argv, argc);
archive_${lower_hash}_final(&ctx, *argv);
return 0;
archive_${lower_crypto}_ctx ctx;
archive_${lower_crypto}_init(&ctx);
archive_${lower_crypto}_update(&ctx, *argv, argc);
archive_${lower_crypto}_final(&ctx, NULL);
return 0;
}
")
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_hash_md.c" "${SOURCE}")
MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION}")
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.h" "")
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}")
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}")
TRY_COMPILE(ARCHIVE_HASH_${HASH}_${IMPLEMENTATION}
TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_hash_md.c
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c
CMAKE_FLAGS
"${TRY_HASH_REQUIRED_LIBS}"
"${TRY_HASH_REQUIRED_INCLUDES}"
"${TRY_CRYPTO_REQUIRED_LIBS}"
"${TRY_CRYPTO_REQUIRED_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
IF (ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION} -- found")
IF (HASH_REQUIRED_INCLUDES)
INCLUDE_DIRECTORIES(${HASH_REQUIRED_INCLUDES})
ENDIF (HASH_REQUIRED_INCLUDES)
IF (HASH_REQUIRED_LIBS)
LIST(APPEND ADDITIONAL_LIBS ${HASH_REQUIRED_LIBS})
LIST(REMOVE_DUPLICATES ADDITIONAL_LIBS)
ENDIF (HASH_REQUIRED_LIBS)
BREAK()
ENDIF (ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION} -- not found")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION} failed with the following output:\n"
# Inform user whether or not we found it; if not, log why we didn't.
IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- found")
ELSE (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- not found")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} failed with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
ELSE(NOT DEFINED ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
IF(ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
BREAK()
ENDIF(ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
ENDIF(NOT DEFINED ARCHIVE_HASH_${HASH}_${IMPLEMENTATION})
ENDFOREACH(IMPLEMENTATION)
ENDMACRO(CHECK_MD HASH IMPLEMENTATIONS)
ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
# Add appropriate libs/includes depending on whether the implementation
# was found on this platform.
IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_LIBRARIES})
LIST(REMOVE_DUPLICATES ADDITIONAL_LIBS)
ENDIF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
ENDFOREACH(ALGORITHM ${ALGORITHMS})
ENDMACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
#
# HASH functions on Windows is defined at archive_windows.c, thus we do not
# need the test what the functions can be mapped to archive_{hash name}_init,
# archive_{hash name}_update and archive_{hash name}_final.
# The functions on Windows use CALG_{hash name} macro to create a crypt object
# and then we need to know what CALG_{hash name} macros is available to show
# ARCHIVE_HASH_{hash name}_WIN macros because Windows 2000 and earlier version
# CRYPTO functions on Windows is defined at archive_windows.c, thus we do not
# need the test what the functions can be mapped to archive_{crypto name}_init,
# archive_{crypto name}_update and archive_{crypto name}_final.
# The functions on Windows use CALG_{crypto name} macro to create a crypt object
# and then we need to know what CALG_{crypto name} macros is available to show
# ARCHIVE_CRYPTO_{crypto name}_WIN macros because Windows 2000 and earlier version
# of Windows XP do not support SHA256, SHA384 and SHA512.
#
MACRO(CHECK_HASH_WIN HASH_LIST)
MACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
IF(WIN32 AND NOT CYGWIN)
FOREACH(HASH ${HASH_LIST})
IF(NOT DEFINED ARCHIVE_HASH_${HASH}_WIN)
STRING(TOUPPER "${HASH}" hash)
FOREACH(CRYPTO ${CRYPTO_LIST})
IF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
STRING(TOUPPER "${CRYPTO}" crypto)
SET(ALGID "")
IF ("${HASH}" MATCHES "^MD5$")
IF ("${CRYPTO}" MATCHES "^MD5$")
SET(ALGID "CALG_MD5")
ENDIF ("${HASH}" MATCHES "^MD5$")
IF ("${HASH}" MATCHES "^SHA1$")
ENDIF ("${CRYPTO}" MATCHES "^MD5$")
IF ("${CRYPTO}" MATCHES "^SHA1$")
SET(ALGID "CALG_SHA1")
ENDIF ("${HASH}" MATCHES "^SHA1$")
IF ("${HASH}" MATCHES "^SHA256$")
ENDIF ("${CRYPTO}" MATCHES "^SHA1$")
IF ("${CRYPTO}" MATCHES "^SHA256$")
SET(ALGID "CALG_SHA_256")
ENDIF ("${HASH}" MATCHES "^SHA256$")
IF ("${HASH}" MATCHES "^SHA384$")
ENDIF ("${CRYPTO}" MATCHES "^SHA256$")
IF ("${CRYPTO}" MATCHES "^SHA384$")
SET(ALGID "CALG_SHA_384")
ENDIF ("${HASH}" MATCHES "^SHA384$")
IF ("${HASH}" MATCHES "^SHA512$")
ENDIF ("${CRYPTO}" MATCHES "^SHA384$")
IF ("${CRYPTO}" MATCHES "^SHA512$")
SET(ALGID "CALG_SHA_512")
ENDIF ("${HASH}" MATCHES "^SHA512$")
ENDIF ("${CRYPTO}" MATCHES "^SHA512$")
SET(SOURCE "#define ${hash}_COMPILE_TEST
SET(SOURCE "#define ${crypto}_COMPILE_TEST
#define _WIN32_WINNT ${_WIN32_WINNT}
#define WINVER ${WINVER}
#include <windows.h>
@ -412,45 +473,112 @@ main(int argc, char **argv)
return ${ALGID};
}
")
SET(SOURCE_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_hash_win.c")
SET(SOURCE_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_win.c")
FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_WIN")
MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
TRY_COMPILE(ARCHIVE_HASH_${HASH}_WIN
TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
${CMAKE_BINARY_DIR}
${SOURCE_FILE}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_CURRENT_SOURCE_DIR}/libarchive"
OUTPUT_VARIABLE OUTPUT)
IF (ARCHIVE_HASH_${HASH}_WIN)
IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
MESSAGE(STATUS
"Checking support for ARCHIVE_HASH_${HASH}_WIN -- found")
ELSE (ARCHIVE_HASH_${HASH}_WIN)
"Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- found")
ELSE (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
MESSAGE(STATUS
"Checking support for ARCHIVE_HASH_${HASH}_WIN -- not found")
"Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- not found")
FILE(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Checking support for ARCHIVE_HASH_${HASH}_WIN failed with the following output:\n"
"Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN failed with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
ENDIF (ARCHIVE_HASH_${HASH}_WIN)
ENDIF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
ENDIF(NOT DEFINED ARCHIVE_HASH_${HASH}_WIN)
ENDFOREACH(HASH)
ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
ENDFOREACH(CRYPTO)
ENDIF(WIN32 AND NOT CYGWIN)
ENDMACRO(CHECK_HASH_WIN HASH_LIST)
ENDMACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
#
# Check MD5/RMD160/SHA support
# Find iconv
# POSIX defines the second arg as const char **
# and requires it to be in libc. But we can accept
# a non-const argument here and can support iconv()
# being in libiconv.
#
CHECK_MD(MD5 "LIBC;LIBMD;LIBSYSTEM;OPENSSL")
CHECK_MD(RMD160 "LIBC;OPENSSL")
CHECK_MD(SHA1 "LIBC;LIBMD;LIBSYSTEM;OPENSSL")
CHECK_MD(SHA256 "LIBC;LIBC2;LIBC3;LIBMD;LIBSYSTEM;OPENSSL")
CHECK_MD(SHA384 "LIBC;LIBC2;LIBC3;LIBSYSTEM;OPENSSL")
CHECK_MD(SHA512 "LIBC;LIBC2;LIBC3;LIBMD;LIBSYSTEM;OPENSSL")
CHECK_HASH_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
IF(NOT HAVE_ICONV)
CHECK_C_SOURCE_COMPILES(
"#include <stdlib.h>
#include <iconv.h>
int main() {
${TRY_ICONV_CONST} char *ccp;
iconv_t cd = iconv_open(\"\", \"\");
iconv(cd, &ccp, (size_t *)0, (char **)0, (size_t *)0);
iconv_close(cd);
return 0;
}"
HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
IF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
SET(HAVE_ICONV true)
SET(ICONV_CONST ${TRY_ICONV_CONST})
ENDIF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
ENDIF(NOT HAVE_ICONV)
ENDMACRO(CHECK_ICONV TRY_ICONV_CONST)
IF(ENABLE_ICONV)
FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
IF(ICONV_INCLUDE_DIR)
#SET(INCLUDES ${INCLUDES} "iconv.h")
SET(HAVE_ICONV_H 1)
INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
CHECK_ICONV("libc" "const")
CHECK_ICONV("libc" "")
# If iconv isn't in libc and we have a libiconv, try that.
FIND_LIBRARY(LIBICONV_PATH iconv)
IF(NOT HAVE_ICONV AND LIBICONV_PATH)
LIST(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBICONV_PATH})
CHECK_ICONV("libiconv" "const")
CHECK_ICONV("libiconv" "")
IF (HAVE_ICONV)
LIST(APPEND ADDITIONAL_LIBS ${LIBICONV_PATH})
ENDIF(HAVE_ICONV)
ENDIF(NOT HAVE_ICONV AND LIBICONV_PATH)
ENDIF(ICONV_INCLUDE_DIR)
#
# Find locale_charset() for libiconv.
#
IF(LIBICONV_PATH)
CHECK_INCLUDE_FILES("localcharset.h" HAVE_LOCALCHARSET_H)
CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET)
IF(NOT HAVE_LOCALE_CHARSET)
FIND_LIBRARY(LIBCHARSET_PATH charset)
IF(LIBCHARSET_PATH)
SET(CMAKE_REQUIRED_LIBRARIES ${LIBCHARSET_PATH})
CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET)
IF(HAVE_LOCALE_CHARSET)
LIST(APPEND ADDITIONAL_LIBS ${LIBCHARSET_PATH})
ENDIF(HAVE_LOCALE_CHARSET)
ENDIF(LIBCHARSET_PATH)
ENDIF(NOT HAVE_LOCALE_CHARSET)
ENDIF(LIBICONV_PATH)
ELSE(ENABLE_ICONV)
# Make sure ICONV variables are not in CACHE after ENABLE_ICONV disabled
# (once enabled).
UNSET(HAVE_LOCALE_CHARSET CACHE)
UNSET(HAVE_ICONV CACHE)
UNSET(HAVE_ICONV_libc_ CACHE)
UNSET(HAVE_ICONV_libc_const CACHE)
UNSET(HAVE_ICONV_libiconv_ CACHE)
UNSET(HAVE_ICONV_libiconv_const CACHE)
UNSET(ICONV_INCLUDE_DIR CACHE)
UNSET(LIBICONV_PATH CACHE)
ENDIF(ENABLE_ICONV)
#
# Find Libxml2
@ -461,12 +589,9 @@ IF(LIBXML2_FOUND)
LIST(APPEND ADDITIONAL_LIBS ${LIBXML2_LIBRARIES})
SET(HAVE_LIBXML2 1)
# libxml2's include files use iconv.h
# We need a directory path of iconv.h so that it won't fail to check
# "libxml/xmlreader.h".
FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
INCLUDE_DIRECTORIES(${ICONV_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/xmlwriter.h" HAVE_LIBXML_XMLWRITER_H)
SET(CMAKE_REQUIRED_INCLUDES "")
ELSE(LIBXML2_FOUND)
#
@ -484,39 +609,59 @@ ENDIF(LIBXML2_FOUND)
#
# Check functions
#
CHECK_SYMBOL_EXISTS(CreateHardLinkA "windows.h" HAVE_CREATEHARDLINKA)
CHECK_SYMBOL_EXISTS(CreateHardLinkW "windows.h" HAVE_CREATEHARDLINKW)
IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
#
# During checking functions, we should use -fno-builtin to avoid the
# failure of function detection which failure is an error "conflicting
# 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")
ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
CHECK_SYMBOL_EXISTS(_CrtSetReportMode "crtdbg.h" HAVE__CrtSetReportMode)
CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN)
CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT)
CHECK_FUNCTION_EXISTS_GLIBC(ctime_r HAVE_CTIME_R)
CHECK_FUNCTION_EXISTS_GLIBC(fchdir HAVE_FCHDIR)
CHECK_FUNCTION_EXISTS_GLIBC(fchflags HAVE_FCHFLAGS)
CHECK_FUNCTION_EXISTS_GLIBC(fchmod HAVE_FCHMOD)
CHECK_FUNCTION_EXISTS_GLIBC(fchown HAVE_FCHOWN)
CHECK_FUNCTION_EXISTS_GLIBC(fcntl HAVE_FCNTL)
CHECK_FUNCTION_EXISTS_GLIBC(fdopendir HAVE_FDOPENDIR)
CHECK_FUNCTION_EXISTS_GLIBC(fork HAVE_FORK)
CHECK_FUNCTION_EXISTS_GLIBC(fstat HAVE_FSTAT)
CHECK_FUNCTION_EXISTS_GLIBC(fstatat HAVE_FSTATAT)
CHECK_FUNCTION_EXISTS_GLIBC(fstatfs HAVE_FSTATFS)
CHECK_FUNCTION_EXISTS_GLIBC(fstatvfs HAVE_FSTATVFS)
CHECK_FUNCTION_EXISTS_GLIBC(ftruncate HAVE_FTRUNCATE)
CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS)
CHECK_FUNCTION_EXISTS_GLIBC(futimes HAVE_FUTIMES)
CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME)
CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R)
CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS)
CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD)
CHECK_FUNCTION_EXISTS_GLIBC(lchown HAVE_LCHOWN)
CHECK_FUNCTION_EXISTS_GLIBC(link HAVE_LINK)
CHECK_FUNCTION_EXISTS_GLIBC(localtime_r HAVE_LOCALTIME_R)
CHECK_FUNCTION_EXISTS_GLIBC(lstat HAVE_LSTAT)
CHECK_FUNCTION_EXISTS_GLIBC(lutimes HAVE_LUTIMES)
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(mkdir HAVE_MKDIR)
CHECK_FUNCTION_EXISTS_GLIBC(mkfifo HAVE_MKFIFO)
CHECK_FUNCTION_EXISTS_GLIBC(mknod HAVE_MKNOD)
CHECK_FUNCTION_EXISTS_GLIBC(mkstemp HAVE_MKSTEMP)
CHECK_FUNCTION_EXISTS_GLIBC(nl_langinfo HAVE_NL_LANGINFO)
CHECK_FUNCTION_EXISTS_GLIBC(openat HAVE_OPENAT)
CHECK_FUNCTION_EXISTS_GLIBC(pipe HAVE_PIPE)
CHECK_FUNCTION_EXISTS_GLIBC(poll HAVE_POLL)
CHECK_FUNCTION_EXISTS_GLIBC(readlink HAVE_READLINK)
@ -524,6 +669,8 @@ CHECK_FUNCTION_EXISTS_GLIBC(select HAVE_SELECT)
CHECK_FUNCTION_EXISTS_GLIBC(setenv HAVE_SETENV)
CHECK_FUNCTION_EXISTS_GLIBC(setlocale HAVE_SETLOCALE)
CHECK_FUNCTION_EXISTS_GLIBC(sigaction HAVE_SIGACTION)
CHECK_FUNCTION_EXISTS_GLIBC(statfs HAVE_STATFS)
CHECK_FUNCTION_EXISTS_GLIBC(statvfs HAVE_STATVFS)
CHECK_FUNCTION_EXISTS_GLIBC(strchr HAVE_STRCHR)
CHECK_FUNCTION_EXISTS_GLIBC(strdup HAVE_STRDUP)
CHECK_FUNCTION_EXISTS_GLIBC(strerror HAVE_STRERROR)
@ -541,19 +688,52 @@ CHECK_FUNCTION_EXISTS_GLIBC(wcrtomb HAVE_WCRTOMB)
CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP)
CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
CHECK_FUNCTION_EXISTS_GLIBC(wcsnrtombs HAVE_WCSNRTOMBS)
CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
CHECK_SYMBOL_EXISTS(wmemcmp "wchar.h" HAVE_WMEMCMP)
CHECK_SYMBOL_EXISTS(wmemcpy "wchar.h" HAVE_WMEMCPY)
CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S)
CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64)
SET(CMAKE_REQUIRED_LIBRARIES "")
CHECK_SYMBOL_EXISTS(fseeko "stdio.h" HAVE_FSEEKO)
CHECK_SYMBOL_EXISTS(strerror_r "string.h" HAVE_STRERROR_R)
CHECK_SYMBOL_EXISTS(strftime "time.h" HAVE_STRFTIME)
CHECK_SYMBOL_EXISTS(vprintf "stdio.h" HAVE_VPRINTF)
CHECK_SYMBOL_EXISTS(cygwin_conv_path "sys/cygwin.h" HAVE_CYGWIN_CONV_PATH)
CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH)
CHECK_FUNCTION_EXISTS(fseeko HAVE_FSEEKO)
CHECK_FUNCTION_EXISTS(strerror_r HAVE_STRERROR_R)
CHECK_FUNCTION_EXISTS(strftime HAVE_STRFTIME)
CHECK_FUNCTION_EXISTS(vprintf HAVE_VPRINTF)
CHECK_FUNCTION_EXISTS(wmemcmp HAVE_WMEMCMP)
CHECK_FUNCTION_EXISTS(wmemcpy HAVE_WMEMCPY)
CHECK_SYMBOL_EXISTS(major "sys/mkdev.h" MAJOR_IN_MKDEV)
CHECK_SYMBOL_EXISTS(major "sys/sysmacros.h" MAJOR_IN_SYSMACROS)
# Restore CMAKE_REQUIRED_FLAGS
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
# older 2-argument version.
CHECK_C_SOURCE_COMPILES(
"#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}"
HAVE_READDIR_R)
# Only detect readlinkat() if we also have AT_FDCWD in unistd.h.
# NOTE: linux requires fcntl.h for AT_FDCWD.
CHECK_C_SOURCE_COMPILES(
"#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
HAVE_READLINKAT)
# To verify major(), we need to both include the header
# of interest and verify that the result can be linked.
# CHECK_FUNCTION_EXISTS doesn't accept a header argument,
# CHECK_SYMBOL_EXISTS doesn't test linkage.
CHECK_C_SOURCE_COMPILES(
"#include <sys/mkdev.h>\nint main() { return major(256); }"
MAJOR_IN_MKDEV)
CHECK_C_SOURCE_COMPILES(
"#include <sys/sysmacros.h>\nint main() { return major(256); }"
MAJOR_IN_SYSMACROS)
IF(HAVE_STRERROR_R)
SET(HAVE_DECL_STRERROR_R 1)
@ -572,8 +752,6 @@ ENDIF(HAVE_INTTYPES_H)
CHECK_SYMBOL_EXISTS(EFTYPE "errno.h" HAVE_EFTYPE)
CHECK_SYMBOL_EXISTS(EILSEQ "errno.h" HAVE_EILSEQ)
CHECK_SYMBOL_EXISTS(D_MD_ORDER "langinfo.h" HAVE_D_MD_ORDER)
CHECK_SYMBOL_EXISTS(optarg "unistd.h" HAVE_DECL_OPTARG)
CHECK_SYMBOL_EXISTS(optind "unistd.h" HAVE_DECL_OPTIND)
CHECK_SYMBOL_EXISTS(INT64_MAX "${headers}" HAVE_DECL_INT64_MAX)
CHECK_SYMBOL_EXISTS(INT64_MIN "${headers}" HAVE_DECL_INT64_MIN)
CHECK_SYMBOL_EXISTS(UINT32_MAX "${headers}" HAVE_DECL_UINT32_MAX)
@ -584,6 +762,16 @@ CHECK_SYMBOL_EXISTS(SSIZE_MAX "limits.h" HAVE_DECL_SSIZE_MAX)
#
# Check struct members
#
# Check for tm_gmtoff in struct tm
CHECK_STRUCT_MEMBER("struct tm" tm_gmtoff
"time.h" HAVE_STRUCT_TM_TM_GMTOFF)
CHECK_STRUCT_MEMBER("struct tm" __tm_gmtoff
"time.h" HAVE_STRUCT_TM___TM_GMTOFF)
# Check for f_namemax in struct statfs
CHECK_STRUCT_MEMBER("struct statfs" f_namemax
"sys/param.h;sys/mount.h" HAVE_STRUCT_STATFS_F_NAMEMAX)
# Check for birthtime in struct stat
CHECK_STRUCT_MEMBER("struct stat" st_birthtime
"sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BIRTHTIME)
@ -615,13 +803,30 @@ CHECK_STRUCT_MEMBER("struct tm" tm_sec
#
# Check for integer types
#
# XXX There must be a way to make this simpler <sigh> XXXX
#
CHECK_TYPE_SIZE("long long int" LONG_LONG_INT)
CHECK_TYPE_SIZE("unsigned long long" UNSIGNED_LONG_LONG)
CHECK_TYPE_SIZE("unsigned long long int" UNSIGNED_LONG_LONG_INT)
CHECK_TYPE_SIZE("short" SIZE_OF_SHORT)
CHECK_TYPE_SIZE("int" SIZE_OF_INT)
CHECK_TYPE_SIZE("long" SIZE_OF_LONG)
CHECK_TYPE_SIZE("long long" SIZE_OF_LONG_LONG)
CHECK_TYPE_SIZE("unsigned short" SIZE_OF_UNSIGNED_SHORT)
CHECK_TYPE_SIZE("unsigned" SIZE_OF_UNSIGNED)
CHECK_TYPE_SIZE("unsigned long" SIZE_OF_UNSIGNED_LONG)
CHECK_TYPE_SIZE("unsigned long long" SIZE_OF_UNSIGNED_LONG_LONG)
CHECK_TYPE_SIZE("__int64" __INT64)
CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
CHECK_TYPE_SIZE(int16_t INT16_T)
CHECK_TYPE_SIZE(int32_t INT32_T)
CHECK_TYPE_SIZE(int64_t INT64_T)
CHECK_TYPE_SIZE(intmax_t INTMAX_T)
CHECK_TYPE_SIZE(uint8_t UINT8_T)
CHECK_TYPE_SIZE(uint16_t UINT16_T)
CHECK_TYPE_SIZE(uint32_t UINT32_T)
CHECK_TYPE_SIZE(uint64_t UINT64_T)
CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
#
CHECK_TYPE_SIZE(dev_t DEV_T)
IF(NOT HAVE_DEV_T)
IF(MSVC)
@ -647,23 +852,6 @@ IF(NOT HAVE_ID_T)
ENDIF(WIN32)
ENDIF(NOT HAVE_ID_T)
#
CHECK_TYPE_SIZE(int32_t INT32_T)
IF(NOT HAVE_INT32_T)
SET(int32_t "int")
ENDIF(NOT HAVE_INT32_T)
#
CHECK_TYPE_SIZE(int64_t INT64_T)
IF(NOT HAVE_INT64_T)
IF(WIN32)
SET(int64_t __int64)
ENDIF(WIN32)
ENDIF(NOT HAVE_INT64_T)
#
CHECK_TYPE_SIZE(intmax_t INTMAX_T)
IF(NOT HAVE_INTMAX_T)
SET(intmax_t "int64_t")
ENDIF(NOT HAVE_INTMAX_T)
#
CHECK_TYPE_SIZE(mode_t MODE_T)
IF(NOT HAVE_MODE_T)
IF(WIN32)
@ -714,28 +902,6 @@ IF(NOT HAVE_PID_T)
ENDIF(WIN32)
ENDIF(NOT HAVE_PID_T)
#
CHECK_TYPE_SIZE(uint16_t UINT16_T)
IF(NOT HAVE_UINT16_T)
SET(uint16_t "unsigned short")
ENDIF(NOT HAVE_UINT16_T)
#
CHECK_TYPE_SIZE(uint32_t UINT32_T)
IF(NOT HAVE_UINT32_T)
SET(uint32_t "unsigned int")
ENDIF(NOT HAVE_UINT32_T)
#
CHECK_TYPE_SIZE(uint64_t UINT64_T)
IF(NOT HAVE_UINT64_T)
IF(WIN32)
SET(uint64_t "unsigned __int64")
ENDIF(WIN32)
ENDIF(NOT HAVE_UINT64_T)
#
CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
IF(NOT HAVE_UINTMAX_T)
SET(uintmax_t "uint64_t")
ENDIF(NOT HAVE_UINTMAX_T)
#
CHECK_TYPE_SIZE(intptr_t INTPTR_T)
IF(NOT HAVE_INTPTR_T)
IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
@ -763,8 +929,6 @@ ENDIF(HAVE_SIZEOF_WCHAR_T)
#
CHECK_FILE_OFFSET_BITS()
#
# Check for Extended Attribute libraries, headers, and functions
#
@ -772,21 +936,57 @@ IF(ENABLE_XATTR)
LA_CHECK_INCLUDE_FILE(attr/xattr.h HAVE_ATTR_XATTR_H)
LA_CHECK_INCLUDE_FILE(sys/xattr.h HAVE_SYS_XATTR_H)
LA_CHECK_INCLUDE_FILE(sys/extattr.h HAVE_SYS_EXTATTR_H)
CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_ATTR_LIB)
IF(HAVE_ATTR_LIB)
CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_LIBATTR)
IF(HAVE_LIBATTR)
SET(CMAKE_REQUIRED_LIBRARIES "attr")
ENDIF(HAVE_ATTR_LIB)
ENDIF(HAVE_LIBATTR)
CHECK_SYMBOL_EXISTS(EXTATTR_NAMESPACE_USER "sys/types.h;sys/extattr.h" HAVE_DECL_EXTATTR_NAMESPACE_USER)
CHECK_FUNCTION_EXISTS_GLIBC(extattr_get_file HAVE_EXTATTR_GET_FILE)
CHECK_FUNCTION_EXISTS_GLIBC(extattr_list_file HAVE_EXTATTR_LIST_FILE)
CHECK_FUNCTION_EXISTS_GLIBC(extattr_set_fd HAVE_EXTATTR_SET_FD)
CHECK_FUNCTION_EXISTS_GLIBC(extattr_set_file HAVE_EXTATTR_SET_FILE)
CHECK_FUNCTION_EXISTS_GLIBC(fgetxattr HAVE_FGETXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(flistxattr HAVE_FLISTXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(fsetxattr HAVE_FSETXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(getxattr HAVE_GETXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(lgetxattr HAVE_LGETXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(listxattr HAVE_LISTXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(llistxattr HAVE_LLISTXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(lsetxattr HAVE_LSETXATTR)
CHECK_FUNCTION_EXISTS_GLIBC(fgetea HAVE_FGETEA)
CHECK_FUNCTION_EXISTS_GLIBC(flistea HAVE_FLISTEA)
CHECK_FUNCTION_EXISTS_GLIBC(fsetea HAVE_FSETEA)
CHECK_FUNCTION_EXISTS_GLIBC(getea HAVE_GETEA)
CHECK_FUNCTION_EXISTS_GLIBC(lgetea HAVE_LGETEA)
CHECK_FUNCTION_EXISTS_GLIBC(listea HAVE_LISTEA)
CHECK_FUNCTION_EXISTS_GLIBC(llistea HAVE_LLISTEA)
CHECK_FUNCTION_EXISTS_GLIBC(lsetea HAVE_LSETEA)
ELSE(ENABLE_XATTR)
SET(HAVE_ATTR_LIB FALSE)
SET(HAVE_ATTR_XATTR_H FALSE)
SET(HAVE_DECL_EXTATTR_NAMESPACE_USER FALSE)
SET(HAVE_EXTATTR_GET_FILE FALSE)
SET(HAVE_EXTATTR_LIST_FILE FALSE)
SET(HAVE_EXTATTR_SET_FD FALSE)
SET(HAVE_EXTATTR_SET_FILE FALSE)
SET(HAVE_FGETEA FALSE)
SET(HAVE_FGETXATTR FALSE)
SET(HAVE_FLISTEA FALSE)
SET(HAVE_FLISTXATTR FALSE)
SET(HAVE_FSETEA FALSE)
SET(HAVE_FSETXATTR FALSE)
SET(HAVE_GETEA FALSE)
SET(HAVE_GETXATTR FALSE)
SET(HAVE_LGETEA FALSE)
SET(HAVE_LGETXATTR FALSE)
SET(HAVE_LISTEA FALSE)
SET(HAVE_LISTXATTR FALSE)
SET(HAVE_LLISTEA FALSE)
SET(HAVE_LLISTXATTR FALSE)
SET(HAVE_LSETEA FALSE)
SET(HAVE_LSETXATTR FALSE)
SET(HAVE_SYS_EXTATTR_H FALSE)
SET(HAVE_SYS_XATTR_H FALSE)
ENDIF(ENABLE_XATTR)
#
@ -798,12 +998,12 @@ ENDIF(ENABLE_XATTR)
# which makes the following checks rather more complex than I would like.
#
IF(ENABLE_ACL)
CHECK_LIBRARY_EXISTS(acl "acl_get_file" "" HAVE_ACL_LIB)
IF(HAVE_ACL_LIB)
CHECK_LIBRARY_EXISTS(acl "acl_get_file" "" HAVE_LIBACL)
IF(HAVE_LIBACL)
SET(CMAKE_REQUIRED_LIBRARIES "acl")
FIND_LIBRARY(ACL_LIBRARY NAMES acl)
LIST(APPEND ADDITIONAL_LIBS ${ACL_LIBRARY})
ENDIF(HAVE_ACL_LIB)
ENDIF(HAVE_LIBACL)
#
CHECK_FUNCTION_EXISTS_GLIBC(acl_create_entry HAVE_ACL_CREATE_ENTRY)
CHECK_FUNCTION_EXISTS_GLIBC(acl_init HAVE_ACL_INIT)
@ -817,16 +1017,47 @@ IF(ENABLE_ACL)
# test for specific permissions in a permset.) Linux uses the obvious
# name, FreeBSD adds _np to mark it as "non-Posix extension."
# Test for both as a double-check that we really have POSIX-style ACL support.
CHECK_SYMBOL_EXISTS(acl_get_perm "${INCLUDES}" HAVE_ACL_GET_PERM)
CHECK_SYMBOL_EXISTS(acl_get_perm_np "${INCLUDES}" HAVE_ACL_GET_PERM_NP)
CHECK_SYMBOL_EXISTS(acl_get_link "${INCLUDES}" HAVE_ACL_GET_LINK)
CHECK_SYMBOL_EXISTS(acl_get_link_np "${INCLUDES}" HAVE_ACL_GET_LINK_NP)
CHECK_FUNCTION_EXISTS(acl_get_perm HAVE_ACL_GET_PERM)
CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
CHECK_FUNCTION_EXISTS(acl_get_link HAVE_ACL_GET_LINK)
CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
# MacOS has an acl.h that isn't POSIX. It can be detected by
# checking for ACL_USER
CHECK_SYMBOL_EXISTS(ACL_USER "${INCLUDES}" HAVE_ACL_USER)
ELSE(ENABLE_ACL)
# If someone runs cmake, then disables ACL support, we need
# to forcibly override the cached values for these.
SET(HAVE_ACL_CREATE_ENTRY FALSE)
SET(HAVE_ACL_GET_LINK FALSE)
SET(HAVE_ACL_GET_LINK_NP FALSE)
SET(HAVE_ACL_GET_PERM FALSE)
SET(HAVE_ACL_GET_PERM_NP FALSE)
SET(HAVE_ACL_INIT FALSE)
SET(HAVE_ACL_LIB FALSE)
SET(HAVE_ACL_PERMSET_T FALSE)
SET(HAVE_ACL_SET_FD FALSE)
SET(HAVE_ACL_SET_FD_NP FALSE)
SET(HAVE_ACL_SET_FILE FALSE)
SET(HAVE_ACL_USER FALSE)
ENDIF(ENABLE_ACL)
#
# Check MD5/RMD160/SHA support
# NOTE: Crypto checks must be run last before generating config.h
#
CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" LIBC)
CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC2)
CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC3)
CHECK_CRYPTO("MD5;SHA1;SHA256;SHA384;SHA512" LIBSYSTEM)
CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" NETTLE)
CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" OPENSSL)
# Libmd has to be probed after OpenSSL.
CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA512" LIBMD)
CHECK_CRYPTO_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
# Generate "config.h" from "build/cmake/config.h.in"
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h)
@ -858,8 +1089,13 @@ IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
ENDIF(MSVC)
# We need CoreServices on Mac OS.
IF(APPLE)
LIST(APPEND ADDITIONAL_LIBS "-framework CoreServices")
ENDIF(APPLE)
IF(ENABLE_TEST)
ADD_CUSTOM_TARGET(run_all_tests)
ADD_CUSTOM_TARGET(run_all_tests)
ENDIF(ENABLE_TEST)
add_subdirectory(libarchive)

View File

@ -16,8 +16,8 @@ the actual statements in the files are controlling.
a 3-clause UC Regents copyright; please read the individual source
files for details:
libarchive/archive_entry.c
libarchive/archive_read_support_compression_compress.c
libarchive/archive_write_set_compression_compress.c
libarchive/archive_read_support_filter_compress.c
libarchive/archive_write_set_filter_compress.c
libarchive/mtree.5
tar/matching.c

View File

@ -19,7 +19,7 @@ configure script and other build files:
To create a distribution, please use the 'distcheck' target:
/bin/sh build/autogen.sh && ./configure && make distcheck
On non-Unix-like systems, use the "cmake" utility (available from
On Unix-like and non-Unix-like systems, use the "cmake" utility (available from
http://cmake.org/) to generate suitable build files for your platform.
Cmake requires the name of the directory containing CmakeLists.txt and
the "generator" to use for your build environment. For example, to
@ -27,4 +27,9 @@ build with Xcode on Mac OS, you can use the following command:
cmake -G "Xcode" ~/libarchive-download-dir/
The result will be appropriate makefiles, solution files, or project
files that can be used with the corresponding development tool.
See the libarchive Wiki or the cmake site for further documentation.
The default on Unix-like systems is to generate Makefiles, so you
can also use cmake instead of the configure script:
cmake ~/libarchive-download-dir/
make
make install
See the libarchive Wiki or the cmake site for further documentation.

View File

@ -21,10 +21,7 @@ TESTS= libarchive_test $(bsdtar_test_programs) $(bsdcpio_test_programs)
TESTS_ENVIRONMENT= $(libarchive_TESTS_ENVIRONMENT) $(bsdtar_TESTS_ENVIRONMENT) $(bsdcpio_TESTS_ENVIRONMENT)
# Always build and test both bsdtar and bsdcpio as part of 'distcheck'
DISTCHECK_CONFIGURE_FLAGS = --enable-bsdtar --enable-bsdcpio
# Uncommenting this line can help diagnose some errors. This is ordinarily
# enabled in the libarchive development branch but is disabled
# for libarchive production releases.
#AM_CFLAGS=-Wall -Werror
AM_CFLAGS=-Wall
PLATFORMCPPFLAGS = @PLATFORMCPPFLAGS@
AM_CPPFLAGS=$(PLATFORMCPPFLAGS)
@ -59,12 +56,6 @@ dist-hook:
-rm -f $(distdir)/*/Makefile $(distdir)/*/*/Makefile
cd $(distdir)/doc && /bin/sh update.sh
# Verify cmake builds as part of the acceptance
distcheck-hook:
mkdir $(distdir)/_build/cmtest
cd $(distdir)/_build/cmtest && cmake ../.. && make && make test
rm -rf $(distdir)/_build/cmtest
#
# Extra rules for cleanup
#
@ -92,24 +83,36 @@ distclean-local:
include_HEADERS= libarchive/archive.h libarchive/archive_entry.h
libarchive_la_SOURCES= \
libarchive/archive_acl.c \
libarchive/archive_acl_private.h \
libarchive/archive_check_magic.c \
libarchive/archive_crc32.h \
libarchive/archive_crypto.c \
libarchive/archive_crypto_private.h \
libarchive/archive_endian.h \
libarchive/archive_entry.c \
libarchive/archive_entry.h \
libarchive/archive_entry_copy_stat.c \
libarchive/archive_entry_link_resolver.c \
libarchive/archive_entry_locale.h \
libarchive/archive_entry_private.h \
libarchive/archive_entry_sparse.c \
libarchive/archive_entry_stat.c \
libarchive/archive_entry_strmode.c \
libarchive/archive_entry_xattr.c \
libarchive/archive_hash.h \
libarchive/archive_options.c \
libarchive/archive_options_private.h \
libarchive/archive_platform.h \
libarchive/archive_ppmd_private.h \
libarchive/archive_ppmd7.c \
libarchive/archive_ppmd7_private.h \
libarchive/archive_private.h \
libarchive/archive_rb.c \
libarchive/archive_rb.h \
libarchive/archive_read.c \
libarchive/archive_read_data_into_fd.c \
libarchive/archive_read_disk.c \
libarchive/archive_read_disk_entry_from_file.c \
libarchive/archive_read_disk_posix.c \
libarchive/archive_read_disk_private.h \
libarchive/archive_read_disk_set_standard_lookup.c \
libarchive/archive_read_extract.c \
@ -118,32 +121,39 @@ libarchive_la_SOURCES= \
libarchive/archive_read_open_filename.c \
libarchive/archive_read_open_memory.c \
libarchive/archive_read_private.h \
libarchive/archive_read_support_compression_all.c \
libarchive/archive_read_support_compression_bzip2.c \
libarchive/archive_read_support_compression_compress.c \
libarchive/archive_read_support_compression_gzip.c \
libarchive/archive_read_support_compression_none.c \
libarchive/archive_read_support_compression_program.c \
libarchive/archive_read_support_compression_rpm.c \
libarchive/archive_read_support_compression_uu.c \
libarchive/archive_read_support_compression_xz.c \
libarchive/archive_read_set_options.c \
libarchive/archive_read_support_filter_all.c \
libarchive/archive_read_support_filter_bzip2.c \
libarchive/archive_read_support_filter_compress.c \
libarchive/archive_read_support_filter_gzip.c \
libarchive/archive_read_support_filter_none.c \
libarchive/archive_read_support_filter_program.c \
libarchive/archive_read_support_filter_rpm.c \
libarchive/archive_read_support_filter_uu.c \
libarchive/archive_read_support_filter_xz.c \
libarchive/archive_read_support_format_7zip.c \
libarchive/archive_read_support_format_all.c \
libarchive/archive_read_support_format_ar.c \
libarchive/archive_read_support_format_by_code.c \
libarchive/archive_read_support_format_cab.c \
libarchive/archive_read_support_format_cpio.c \
libarchive/archive_read_support_format_empty.c \
libarchive/archive_read_support_format_iso9660.c \
libarchive/archive_read_support_format_lha.c \
libarchive/archive_read_support_format_mtree.c \
libarchive/archive_read_support_format_rar.c \
libarchive/archive_read_support_format_raw.c \
libarchive/archive_read_support_format_tar.c \
libarchive/archive_read_support_format_xar.c \
libarchive/archive_read_support_format_zip.c \
libarchive/archive_string.c \
libarchive/archive_string.h \
libarchive/archive_string_composition.h \
libarchive/archive_string_sprintf.c \
libarchive/archive_util.c \
libarchive/archive_virtual.c \
libarchive/archive_write.c \
libarchive/archive_write_disk.c \
libarchive/archive_write_disk_posix.c \
libarchive/archive_write_disk_private.h \
libarchive/archive_write_disk_set_standard_lookup.c \
libarchive/archive_write_open_fd.c \
@ -151,22 +161,27 @@ libarchive_la_SOURCES= \
libarchive/archive_write_open_filename.c \
libarchive/archive_write_open_memory.c \
libarchive/archive_write_private.h \
libarchive/archive_write_set_compression_bzip2.c \
libarchive/archive_write_set_compression_compress.c \
libarchive/archive_write_set_compression_gzip.c \
libarchive/archive_write_set_compression_none.c \
libarchive/archive_write_set_compression_program.c \
libarchive/archive_write_set_compression_xz.c \
libarchive/archive_write_add_filter_bzip2.c \
libarchive/archive_write_add_filter_compress.c \
libarchive/archive_write_add_filter_gzip.c \
libarchive/archive_write_add_filter_none.c \
libarchive/archive_write_add_filter_program.c \
libarchive/archive_write_add_filter_xz.c \
libarchive/archive_write_set_format.c \
libarchive/archive_write_set_format_7zip.c \
libarchive/archive_write_set_format_ar.c \
libarchive/archive_write_set_format_by_name.c \
libarchive/archive_write_set_format_cpio.c \
libarchive/archive_write_set_format_cpio_newc.c \
libarchive/archive_write_set_format_iso9660.c \
libarchive/archive_write_set_format_mtree.c \
libarchive/archive_write_set_format_pax.c \
libarchive/archive_write_set_format_shar.c \
libarchive/archive_write_set_format_ustar.c \
libarchive/archive_write_set_format_gnutar.c \
libarchive/archive_write_set_format_xar.c \
libarchive/archive_write_set_format_zip.c \
libarchive/archive_write_set_options.c \
libarchive/config_freebsd.h \
libarchive/filter_fork.c \
libarchive/filter_fork.h
@ -174,23 +189,34 @@ libarchive_la_SOURCES= \
if INC_WINDOWS_FILES
libarchive_la_SOURCES+= \
libarchive/archive_entry_copy_bhfi.c \
libarchive/archive_read_disk_windows.c \
libarchive/archive_windows.h \
libarchive/archive_windows.c \
libarchive/archive_write_disk_windows.c \
libarchive/filter_fork_windows.c
endif
# -no-undefined marks that libarchive doesn't rely on symbols
# defined in the application. This is mandatory for cygwin.
libarchive_la_LDFLAGS= -no-undefined -version-info $(ARCHIVE_LIBTOOL_VERSION)
libarchive_la_LIBADD= $(LTLIBICONV)
# Manpages to install
libarchive_man_MANS= \
libarchive/archive_entry.3 \
libarchive/archive_entry_acl.3 \
libarchive/archive_entry_linkify.3 \
libarchive/archive_entry_paths.3 \
libarchive/archive_entry_perms.3 \
libarchive/archive_entry_stat.3 \
libarchive/archive_entry_time.3 \
libarchive/archive_read.3 \
libarchive/archive_read_disk.3 \
libarchive/archive_read_set_options.3 \
libarchive/archive_util.3 \
libarchive/archive_write.3 \
libarchive/archive_write_disk.3 \
libarchive/archive_write_set_options.3 \
libarchive/cpio.5 \
libarchive/libarchive.3 \
libarchive/libarchive_internals.3 \
@ -200,7 +226,6 @@ libarchive_man_MANS= \
# Additional libarchive files to include in the distribution
libarchive_EXTRA_DIST= \
libarchive/test/list.h \
libarchive/archive_windows.c \
libarchive/archive_windows.h \
libarchive/filter_fork_windows.c \
@ -221,25 +246,52 @@ libarchive_test_SOURCES= \
libarchive/test/main.c \
libarchive/test/read_open_memory.c \
libarchive/test/test.h \
libarchive/test/test_acl_basic.c \
libarchive/test/test_acl_freebsd.c \
libarchive/test/test_acl_nfs4.c \
libarchive/test/test_acl_pax.c \
libarchive/test/test_acl_posix1e.c \
libarchive/test/test_archive_api_feature.c \
libarchive/test/test_archive_clear_error.c \
libarchive/test/test_archive_crypto.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_filename.c \
libarchive/test/test_archive_read_next_header_empty.c \
libarchive/test/test_archive_read_next_header_raw.c \
libarchive/test/test_archive_read_open2.c \
libarchive/test/test_archive_read_set_filter_option.c \
libarchive/test/test_archive_read_set_format_option.c \
libarchive/test/test_archive_read_set_option.c \
libarchive/test/test_archive_read_set_options.c \
libarchive/test/test_archive_read_support.c \
libarchive/test/test_archive_set_error.c \
libarchive/test/test_archive_string.c \
libarchive/test/test_archive_string_conversion.c \
libarchive/test/test_archive_write_set_filter_option.c \
libarchive/test/test_archive_write_set_format_option.c \
libarchive/test/test_archive_write_set_option.c \
libarchive/test/test_archive_write_set_options.c \
libarchive/test/test_bad_fd.c \
libarchive/test/test_compat_bzip2.c \
libarchive/test/test_compat_cpio.c \
libarchive/test/test_compat_gtar.c \
libarchive/test/test_compat_gzip.c \
libarchive/test/test_compat_lzip.c \
libarchive/test/test_compat_lzma.c \
libarchive/test/test_compat_mac.c \
libarchive/test/test_compat_pax_libarchive_2x.c \
libarchive/test/test_compat_solaris_tar_acl.c \
libarchive/test/test_compat_solaris_pax_sparse.c \
libarchive/test/test_compat_tar_hardlink.c \
libarchive/test/test_compat_xz.c \
libarchive/test/test_compat_zip.c \
libarchive/test/test_empty_write.c \
libarchive/test/test_entry.c \
libarchive/test/test_extattr_freebsd.c \
libarchive/test/test_fuzz.c \
libarchive/test/test_entry_strmode.c \
libarchive/test/test_extattr_freebsd.c \
libarchive/test/test_filter_count.c \
libarchive/test/test_fuzz.c \
libarchive/test/test_gnutar_filename_encoding.c \
libarchive/test/test_link_resolver.c \
libarchive/test/test_open_failure.c \
libarchive/test/test_open_fd.c \
@ -249,87 +301,121 @@ libarchive_test_SOURCES= \
libarchive/test/test_read_compress_program.c \
libarchive/test/test_read_data_large.c \
libarchive/test/test_read_disk.c \
libarchive/test/test_read_disk_directory_traversals.c \
libarchive/test/test_read_disk_entry_from_file.c \
libarchive/test/test_read_extract.c \
libarchive/test/test_read_file_nonexistent.c \
libarchive/test/test_read_format_7zip.c \
libarchive/test/test_read_format_ar.c \
libarchive/test/test_read_format_cab.c \
libarchive/test/test_read_format_cab_filename.c \
libarchive/test/test_read_format_cpio_afio.c \
libarchive/test/test_read_format_cpio_bin.c \
libarchive/test/test_read_format_cpio_bin_Z.c \
libarchive/test/test_read_format_cpio_bin_be.c \
libarchive/test/test_read_format_cpio_bin_bz2.c \
libarchive/test/test_read_format_cpio_bin_gz.c \
libarchive/test/test_read_format_cpio_bin_lzip.c \
libarchive/test/test_read_format_cpio_bin_lzma.c \
libarchive/test/test_read_format_cpio_bin_xz.c \
libarchive/test/test_read_format_cpio_filename.c \
libarchive/test/test_read_format_cpio_odc.c \
libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c \
libarchive/test/test_read_format_cpio_svr4_gzip.c \
libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c \
libarchive/test/test_read_format_cpio_svr4c_Z.c \
libarchive/test/test_read_format_empty.c \
libarchive/test/test_read_format_gtar_filename.c \
libarchive/test/test_read_format_gtar_gz.c \
libarchive/test/test_read_format_gtar_lzma.c \
libarchive/test/test_read_format_gtar_sparse.c \
libarchive/test/test_read_format_iso_Z.c \
libarchive/test/test_read_format_iso_multi_extent.c \
libarchive/test/test_read_format_iso_xorriso.c \
libarchive/test/test_read_format_isojoliet_bz2.c \
libarchive/test/test_read_format_isojoliet_long.c \
libarchive/test/test_read_format_isojoliet_rr.c \
libarchive/test/test_read_format_isojoliet_versioned.c \
libarchive/test/test_read_format_isorr_bz2.c \
libarchive/test/test_read_format_isorr_ce.c \
libarchive/test/test_read_format_isorr_new_bz2.c \
libarchive/test/test_read_format_isorr_rr_moved.c \
libarchive/test/test_read_format_isozisofs_bz2.c \
libarchive/test/test_read_format_lha.c \
libarchive/test/test_read_format_lha_filename.c \
libarchive/test/test_read_format_mtree.c \
libarchive/test/test_read_format_pax_bz2.c \
libarchive/test/test_read_format_rar.c \
libarchive/test/test_read_format_raw.c \
libarchive/test/test_read_format_tar.c \
libarchive/test/test_read_format_tar_empty_filename.c \
libarchive/test/test_read_format_tar_filename.c \
libarchive/test/test_read_format_tbz.c \
libarchive/test/test_read_format_tgz.c \
libarchive/test/test_read_format_tlz.c \
libarchive/test/test_read_format_txz.c \
libarchive/test/test_read_format_tz.c \
libarchive/test/test_read_format_ustar_filename.c \
libarchive/test/test_read_format_xar.c \
libarchive/test/test_read_format_zip.c \
libarchive/test/test_read_format_zip_filename.c \
libarchive/test/test_read_large.c \
libarchive/test/test_read_pax_truncated.c \
libarchive/test/test_read_position.c \
libarchive/test/test_read_truncated.c \
libarchive/test/test_read_truncated_filter.c \
libarchive/test/test_read_uu.c \
libarchive/test/test_sparse_basic.c \
libarchive/test/test_tar_filenames.c \
libarchive/test/test_tar_large.c \
libarchive/test/test_ustar_filenames.c \
libarchive/test/test_ustar_filename_encoding.c \
libarchive/test/test_write_compress.c \
libarchive/test/test_write_compress_bzip2.c \
libarchive/test/test_write_compress_gzip.c \
libarchive/test/test_write_compress_lzip.c \
libarchive/test/test_write_compress_lzma.c \
libarchive/test/test_write_compress_program.c \
libarchive/test/test_write_compress_xz.c \
libarchive/test/test_write_disk.c \
libarchive/test/test_write_disk_failures.c \
libarchive/test/test_write_disk_hardlink.c \
libarchive/test/test_write_disk_lookup.c \
libarchive/test/test_write_disk_perms.c \
libarchive/test/test_write_disk_secure.c \
libarchive/test/test_write_disk_sparse.c \
libarchive/test/test_write_disk_symlink.c \
libarchive/test/test_write_disk_times.c \
libarchive/test/test_write_format_7zip.c \
libarchive/test/test_write_format_ar.c \
libarchive/test/test_write_format_cpio.c \
libarchive/test/test_write_format_cpio_empty.c \
libarchive/test/test_write_format_cpio_odc.c \
libarchive/test/test_write_format_cpio_newc.c \
libarchive/test/test_write_format_cpio_odc.c \
libarchive/test/test_write_format_gnutar.c \
libarchive/test/test_write_format_iso9660.c \
libarchive/test/test_write_format_iso9660_boot.c \
libarchive/test/test_write_format_iso9660_empty.c \
libarchive/test/test_write_format_iso9660_filename.c \
libarchive/test/test_write_format_iso9660_zisofs.c \
libarchive/test/test_write_format_mtree.c \
libarchive/test/test_write_format_mtree_fflags.c \
libarchive/test/test_write_format_pax.c \
libarchive/test/test_write_format_shar_empty.c \
libarchive/test/test_write_format_tar.c \
libarchive/test/test_write_format_tar_empty.c \
libarchive/test/test_write_format_tar_sparse.c \
libarchive/test/test_write_format_tar_ustar.c \
libarchive/test/test_write_format_xar.c \
libarchive/test/test_write_format_xar_empty.c \
libarchive/test/test_write_format_zip.c \
libarchive/test/test_write_format_zip_empty.c \
libarchive/test/test_write_format_zip_no_compression.c \
libarchive/test/test_write_open_memory.c
libarchive/test/test_write_open_memory.c \
libarchive/test/test_zip_filename_encoding.c
libarchive_test_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_builddir)/libarchive/test -DLIBARCHIVE_STATIC $(PLATFORMCPPFLAGS)
libarchive_test_LDADD= $(LTLIBICONV)
# The "list.h" file just lists all of the tests defined in all of the sources.
# Building it automatically provides a sanity-check on libarchive_test_SOURCES
@ -340,25 +426,83 @@ libarchive/test/list.h: Makefile
libarchive_TESTS_ENVIRONMENT= LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/libarchive/test
libarchive_test_EXTRA_DIST=\
libarchive/test/list.h \
libarchive/test/test_acl_pax.tar.uu \
libarchive/test/test_archive_string_conversion.txt.Z.uu \
libarchive/test/test_compat_bzip2_1.tbz.uu \
libarchive/test/test_compat_bzip2_2.tbz.uu \
libarchive/test/test_compat_cpio_1.cpio.uu \
libarchive/test/test_compat_gtar_1.tar.uu \
libarchive/test/test_compat_gzip_1.tgz.uu \
libarchive/test/test_compat_gzip_2.tgz.uu \
libarchive/test/test_compat_lzip_1.tlz.uu \
libarchive/test/test_compat_lzip_2.tlz.uu \
libarchive/test/test_compat_lzma_1.tlz.uu \
libarchive/test/test_compat_lzma_2.tlz.uu \
libarchive/test/test_compat_lzma_3.tlz.uu \
libarchive/test/test_compat_mac-1.tar.Z.uu \
libarchive/test/test_compat_mac-2.tar.Z.uu \
libarchive/test/test_compat_pax_libarchive_2x.tar.Z.uu \
libarchive/test/test_compat_solaris_tar_acl.tar.uu \
libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu \
libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu \
libarchive/test/test_compat_tar_hardlink_1.tar.uu \
libarchive/test/test_compat_xz_1.txz.uu \
libarchive/test/test_compat_zip_1.zip.uu \
libarchive/test/test_compat_zip_2.zip.uu \
libarchive/test/test_compat_zip_3.zip.uu \
libarchive/test/test_compat_zip_4.zip.uu \
libarchive/test/test_compat_zip_5.zip.uu \
libarchive/test/test_compat_zip_6.zip.uu \
libarchive/test/test_compat_zip_7.xps.uu \
libarchive/test/test_fuzz_1.iso.Z.uu \
libarchive/test/test_fuzz.cab.uu \
libarchive/test/test_fuzz.lzh.uu \
libarchive/test/test_pax_filename_encoding.tar.uu \
libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu \
libarchive/test/test_read_format_7zip_bcj_copy.7z.uu \
libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu \
libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu \
libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu \
libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu \
libarchive/test/test_read_format_7zip_bzip2.7z.uu \
libarchive/test/test_read_format_7zip_copy.7z.uu \
libarchive/test/test_read_format_7zip_copy_2.7z.uu \
libarchive/test/test_read_format_7zip_deflate.7z.uu \
libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu \
libarchive/test/test_read_format_7zip_delta_lzma2.7z.uu \
libarchive/test/test_read_format_7zip_empty_archive.7z.uu \
libarchive/test/test_read_format_7zip_empty_file.7z.uu \
libarchive/test/test_read_format_7zip_lzma1.7z.uu \
libarchive/test/test_read_format_7zip_lzma1_2.7z.uu \
libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu \
libarchive/test/test_read_format_7zip_lzma2.7z.uu \
libarchive/test/test_read_format_7zip_ppmd.7z.uu \
libarchive/test/test_read_format_7zip_symbolic_name.7z.uu \
libarchive/test/test_read_format_ar.ar.uu \
libarchive/test/test_read_format_cab_1.cab.uu \
libarchive/test/test_read_format_cab_2.cab.uu \
libarchive/test/test_read_format_cab_3.cab.uu \
libarchive/test/test_read_format_cab_filename_cp932.cab.uu \
libarchive/test/test_read_format_cpio_bin_be.cpio.uu \
libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu \
libarchive/test/test_read_format_cpio_filename_eucjp.cpio.uu \
libarchive/test/test_read_format_cpio_filename_koi8r.cpio.uu \
libarchive/test/test_read_format_cpio_filename_utf8_jp.cpio.uu \
libarchive/test/test_read_format_cpio_filename_utf8_ru.cpio.uu \
libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.rpm.uu \
libarchive/test/test_read_format_cpio_svr4_gzip_rpm.rpm.uu \
libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu \
libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu \
libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_gtar_sparse_1_13.tar.uu \
libarchive/test/test_read_format_gtar_sparse_1_17.tar.uu \
libarchive/test/test_read_format_gtar_sparse_1_17_posix00.tar.uu \
@ -368,6 +512,7 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_iso.iso.Z.uu \
libarchive/test/test_read_format_iso_2.iso.Z.uu \
libarchive/test/test_read_format_iso_joliet.iso.Z.uu \
libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu \
libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu \
libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu \
libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu \
@ -375,12 +520,47 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_iso_rockridge_ce.iso.Z.uu \
libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu \
libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu\
libarchive/test/test_read_format_iso_xorriso.iso.Z.uu \
libarchive/test/test_read_format_iso_zisofs.iso.Z.uu \
libarchive/test/test_read_format_lha_filename_cp932.lzh.uu \
libarchive/test/test_read_format_lha_header0.lzh.uu \
libarchive/test/test_read_format_lha_header1.lzh.uu \
libarchive/test/test_read_format_lha_header2.lzh.uu \
libarchive/test/test_read_format_lha_header3.lzh.uu \
libarchive/test/test_read_format_lha_lh0.lzh.uu \
libarchive/test/test_read_format_lha_lh6.lzh.uu \
libarchive/test/test_read_format_lha_lh7.lzh.uu \
libarchive/test/test_read_format_lha_withjunk.lzh.uu \
libarchive/test/test_read_format_mtree.mtree.uu \
libarchive/test/test_read_format_mtree_nomagic.mtree.uu \
libarchive/test/test_read_format_rar.rar.uu \
libarchive/test/test_read_format_rar_binary_data.rar.uu \
libarchive/test/test_read_format_rar_compress_best.rar.uu \
libarchive/test/test_read_format_rar_compress_normal.rar.uu \
libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu \
libarchive/test/test_read_format_rar_noeof.rar.uu \
libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu\
libarchive/test/test_read_format_rar_sfx.exe.uu \
libarchive/test/test_read_format_rar_subblock.rar.uu \
libarchive/test/test_read_format_rar_unicode.rar.uu \
libarchive/test/test_read_format_rar_windows.rar.uu \
libarchive/test/test_read_format_raw.data.Z.uu \
libarchive/test/test_read_format_raw.data.uu \
libarchive/test/test_read_format_tar_empty_filename.tar.uu \
libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu \
libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \
libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \
libarchive/test/test_read_format_zip.zip.uu \
libarchive/test/test_read_format_zip_filename_cp866.zip.uu \
libarchive/test/test_read_format_zip_filename_cp932.zip.uu \
libarchive/test/test_read_format_zip_filename_koi8r.zip.uu \
libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu \
libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu \
libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu \
libarchive/test/test_read_format_zip_length_at_end.zip.uu \
libarchive/test/test_read_format_zip_symlink.zip.uu \
libarchive/test/test_read_format_zip_ux.zip.uu \
libarchive/test/CMakeLists.txt \
libarchive/test/README
@ -433,7 +613,7 @@ bsdtar_ldstatic=
bsdtar_ccstatic=
endif
bsdtar_LDADD= libarchive.la libarchive_fe.la
bsdtar_LDADD= libarchive.la libarchive_fe.la $(LTLIBICONV)
bsdtar_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdtar_ccstatic) $(PLATFORMCPPFLAGS)
bsdtar_LDFLAGS= $(bsdtar_ldstatic)
@ -442,8 +622,7 @@ bsdtar_EXTRA_DIST= \
tar/bsdtar_windows.h \
tar/bsdtar_windows.c \
tar/CMakeLists.txt \
tar/config_freebsd.h \
tar/test/list.h
tar/config_freebsd.h
if BUILD_BSDTAR
@ -468,24 +647,32 @@ bsdtar_test_SOURCES= \
tar/test/test_empty_mtree.c \
tar/test/test_getdate.c \
tar/test/test_help.c \
tar/test/test_option_C_upper.c \
tar/test/test_option_H_upper.c \
tar/test/test_option_L_upper.c \
tar/test/test_option_O_upper.c \
tar/test/test_option_T_upper.c \
tar/test/test_option_U_upper.c \
tar/test/test_option_X_upper.c \
tar/test/test_option_b.c \
tar/test/test_option_exclude.c \
tar/test/test_option_gid_gname.c \
tar/test/test_option_k.c \
tar/test/test_option_keep_newer_files.c \
tar/test/test_option_n.c \
tar/test/test_option_newer_than.c \
tar/test/test_option_q.c \
tar/test/test_option_r.c \
tar/test/test_option_s.c \
tar/test/test_option_uid_uname.c \
tar/test/test_patterns.c \
tar/test/test_print_longpath.c \
tar/test/test_stdio.c \
tar/test/test_strip_components.c \
tar/test/test_symlink_dir.c \
tar/test/test_version.c \
tar/test/test_windows.c
# For now, bsdtar_test uses Windows shims from tar/bsdtar_windows.*
if INC_WINDOWS_FILES
bsdtar_test_SOURCES+= \
tar/bsdtar_windows.h \
tar/bsdtar_windows.c
endif
bsdtar_test_CPPFLAGS=\
-I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \
-I$(top_srcdir)/tar -I$(top_builddir)/tar/test \
@ -503,9 +690,13 @@ bsdtar_TESTS_ENVIRONMENT=
endif
bsdtar_test_EXTRA_DIST= \
tar/test/list.h \
tar/test/test_option_keep_newer_files.tar.Z.uu \
tar/test/test_option_s.tar.Z.uu \
tar/test/test_patterns_2.tar.uu \
tar/test/test_patterns_3.tar.uu \
tar/test/test_patterns_4.tar.uu \
tar/test/test_print_longpath.tar.Z.uu \
tar/test/CMakeLists.txt
@ -538,12 +729,11 @@ bsdcpio_ldstatic=
bsdcpio_ccstatic=
endif
bsdcpio_LDADD= libarchive_fe.la libarchive.la
bsdcpio_LDADD= libarchive_fe.la libarchive.la $(LTLIBICONV)
bsdcpio_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdcpio_ccstatic) $(PLATFORMCPPFLAGS)
bsdcpio_LDFLAGS= $(bsdcpio_ldstatic)
bsdcpio_EXTRA_DIST= \
cpio/test/list.h \
cpio/bsdcpio.1 \
cpio/cpio_windows.h \
cpio/cpio_windows.c \
@ -573,6 +763,7 @@ bsdcpio_test_SOURCES= \
cpio/test/test_cmdline.c \
cpio/test/test_format_newc.c \
cpio/test/test_gcpio_compat.c \
cpio/test/test_option_0.c \
cpio/test/test_option_B_upper.c \
cpio/test/test_option_C_upper.c \
cpio/test/test_option_J_upper.c \
@ -614,6 +805,7 @@ bsdcpio_TESTS_ENVIRONMENT=
endif
bsdcpio_test_EXTRA_DIST= \
cpio/test/list.h \
cpio/test/test_gcpio_compat_ref.bin.uu \
cpio/test/test_gcpio_compat_ref.crc.uu \
cpio/test/test_gcpio_compat_ref.newc.uu \

93
NEWS
View File

@ -1,27 +1,80 @@
Feb 05, 2011: Fix issue 134: Improve handling of open failures
Dec 06, 2010: Fix issue 119: Relax ISO verification
Dec 06, 2010: Fix issue 121: mtree parsing
Dec 05, 2010: Fix extraction of GNU tar 'D' directory entries
Dec 05, 2010: Be less demanding in LZMA/XZ compression tests
Jun 30, 2010: libarchive 2.8.4 released
Jun 30, 2010: Improved reliability of hash function detection
Jun 30, 2010: Fix issues on ancient FreeBSD, QNX, ancient NetBSD and Minix
Jan 10, 2012: Issue 223: Skip atime tests if atime not supported
Jan 09, 2012: Issue 222: Errors saving sparse files to pax archives
Jan 09, 2012: Issue 221: allow archive_*_free(NULL)
Dec 31, 2011: Issue 212: configure script on Solaris
Dec 30, 2011: Issue 218: empty contents extracting Zip files with bsdcpio
Dec 30, 2011: Issue 217: fix compile warning
Dec 30, 2011: Issue 216: truncated filenames in listings
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
Mar 14, 2010: libarchive 2.8.3 released
Mar 14, 2010: Symlink dereference fix for Linux broke the build there; corrected.
Dec 24, 2011: libarchive 3.0.2 released
Dec 23, 2011: Various fixes merged from FreeBSD
Dec 23, 2011: Symlink support in Zip reader and writer
Dec 23, 2011: Robustness fixes to 7Zip reader
Mar 14, 2010: libarchive 2.8.2 released
Mar 12, 2010: Fix NULL deference for short self-extracting zip archives.
Nov 27, 2011: libarchive 3.0.1b released
Nov 26, 2011: 7Zip reader
Nov 26, 2011: Small fixes to ISO and Zip to improve robustness with corrupted input
Nov 24, 2011: Improve streaming Zip reader's support for uncompressed entries
Nov 20, 2011: New seeking Zip reader supports SFX Zip archives
Nov 20, 2011: Build fixes on Windows
Nov 13, 2011: libarchive 3.0.0a released
Nov 06, 2011: Update shared-library version calculations for libarchive 3.x
Sep 04, 2011: Fix tar -s; follow GNU tar for controlling hardlink/symlink substitutions
Aug 18, 2011: Fix reading ISO images built by NetBSD's mkisofs
Aug 15, 2011: Old archive_read_support_compression_XXX functions are deprecated and
will disappear in libarchive 4.0.
Jun 26, 2011: RAR reader
Jun 16, 2011: Add tar:compat-2x option to emulate broken libarchive 2.x
handling of pax UTF-8 headers
Apr 25, 2011: Refactor read_open() into a collection of single-item setters;
support the old interfaces as wrappers
Apr 12, 2011: Split disk writer into separate POSIX and Windows implementations
Apr 10, 2011: Improvements to character translations on Windows.
Mar 30, 2011: More work to return errors instead of calling abort()
Mar 23, 2011: Add charset option to many writers to control MBCS filenames
Mar 17, 2011: Overhauled support for per-format extension options
Mar 17, 2011: Track character set used for mbcs strings, support
translating to/from user-specified locale
Mar 09, 2011: Recognize mtree files without requiring a signature
Mar 06, 2011: Use iconv to convert to/from Unicode instead of making bad
assumptions about the C90 character set translation functions
Feb 17, 2011: Fixes for AIX, TRU64, and other platforms
Dec 22, 2010: CAB reader
Dec 20, 2010: LHA/LZH reader
Jul 03, 2010: minitar example demonstrates archive_read_disk directory traversal
Jun 29, 2010: Many improvements to ISO reader compatibility
Jun 26, 2010: Use larger buffers when copy files into an archive
Jun 18, 2010: Reimplement Mac OS extensions in libarchive
Jun 09, 2010: archive_read_disk now supports traversals
May 28, 2010: XAR writer
May 16, 2010: Fix ^T handling; don't exit on interrupted reads and writes
May 09, 2010: Improved detection of platform-specific crypto support
May 04, 2010: lzip read and write filters
May 01, 2010: New options: tar --gid --gname --uid --uname
Apr 28, 2010: Use Red-black tree for ISO reader/writer to improve performance
Apr 17, 2010: Minimal writer for legacy GNU tar format
Mar 12, 2010: Don't dereference symlinks on Linux when reading ACLs.
Mar 07, 2010: Better detection of SHA2 support for old OpenSSL versions.
Mar 07, 2010: Fix parsing of input files for bsdtar -T.
Mar 07, 2010: Do not leak setup_xattr into the global namespace.
Mar 06, 2010: libarchive 2.8.1 released
Mar 06, 2010: Fix build when an older libarchive is already installed
Mar 03, 2010: Use O_BINARY opening files in bsdtar
Mar 02, 2010: Include missing archive_crc32.h
Mar 01, 2010: Correctly include iconv.h required by libxml2.
Feb 28, 2010: Relax handling of state failures; misuse by clients now generally
results in a sticky ARCHIVE_FATAL rather than a visit to abort()
Feb 25, 2010: ISO writer
Feb 21, 2010: Split many man pages into smaller chunks.
Feb 21, 2010: Performance: Cheat on block sizes when reading archives from disk.
Feb 21, 2010: Use int64_t instead of off_t, dev_t, ino_t, uid_t, and gid_t
Feb 20, 2010: Document new ACL functions.
Feb 19, 2010: Support multiple write filters
Feb 07, 2010: Remove some legacy libarchive 1.x APIs
Feb 04, 2010: Read afio headers
Feb 02, 2010: Archive sparse files compatibly with GNU tar
Feb 01, 2010: Integrate Apple extensions for Mac OS extended attributes into bsdtar
Jan 31, 2010: Support cpio -V
Feb 04, 2010: libarchive 2.8.0 released
Jan 17, 2010: Fix error handling for 'echo nonexistent | cpio -o'

35
README
View File

@ -13,8 +13,6 @@ This distribution bundle includes the following components:
essentially the same functionality
* examples: Some small example programs that you may find useful.
* examples/minitar: a compact sample demonstrating use of libarchive.
I use this for testing link pollution; it should produce a very
small executable file on most systems.
* contrib: Various items sent to me by third parties;
please contact the authors with any questions.
@ -51,16 +49,11 @@ The manual pages above are provided in the 'doc' directory in
a number of different formats.
You should also read the copious comments in "archive.h" and the
source code for the sample programs for more details. Please let me
source code for the sample programs for more details. Please let us
know about any errors or omissions you find.
Currently, the library automatically detects and reads the following:
* gzip compression
* bzip2 compression
* compress/LZW compression
* lzma and xz compression
* GNU tar format (including GNU long filenames, long link names, and
sparse files)
Currently, the library automatically detects and reads the following fomats:
* GNU tar format (including GNU long filenames, long link names, and sparse files)
* Solaris 9 extended tar format (including ACLs)
* Old V7 tar archives
* POSIX ustar
@ -73,22 +66,40 @@ Currently, the library automatically detects and reads the following:
* ZIP archives (with uncompressed or "deflate" compressed entries)
* GNU and BSD 'ar' archives
* 'mtree' format
* Microsoft CAB format
* LHA and LZH archives
* RAR archives
* XAR archives
The library can write:
The library also detects and handles any of the following before evaluating the archive:
* uuencoded files
* files with RPM wrapper
* gzip compression
* bzip2 compression
* compress/LZW compression
* lzma and xz compression
* lzma, lzip, and xz compression
The library can create archives in any of the following formats:
* POSIX ustar
* POSIX pax interchange format
* "restricted" pax format, which will create ustar archives except for
entries that require pax extensions (for long filenames, ACLs, etc).
* Old GNU tar format
* POSIX octet-oriented cpio
* SVR4 "newc" cpio
* shar archives
* ZIP archives (with uncompressed or "deflate" compressed entries)
* GNU and BSD 'ar' archives
* 'mtree' format
* ISO9660 format
* XAR archives
When creating archives, the result can be filtered with any of the following:
* uuencode
* gzip compression
* bzip2 compression
* compress/LZW compression
* lzma, lzip, and xz compression
Notes about the library architecture:

696
build/autoconf/config.rpath Executable file
View File

@ -0,0 +1,696 @@
#! /bin/sh
#
# NOTE: This file was brought from
# http://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/config.rpath
# You should sometimes check if the file is updated and bring it to
# our trunk and copy this note to the top of that file.
#
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
# Copyright 1996-2011 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# The first argument passed to this file is the canonical host specification,
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
# should be set by the caller.
#
# The set of defined variables is at the end of this script.
# Known limitations:
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
# than 256 bytes, otherwise the compiler driver will dump core. The only
# known workaround is to choose shorter directory names for the build
# directory and/or the installation directory.
# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
shrext=.so
host="$1"
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
# Code taken from libtool.m4's _LT_CC_BASENAME.
for cc_temp in $CC""; do
case $cc_temp in
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
\-*) ;;
*) break;;
esac
done
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
# Code taken from libtool.m4's _LT_COMPILER_PIC.
wl=
if test "$GCC" = yes; then
wl='-Wl,'
else
case "$host_os" in
aix*)
wl='-Wl,'
;;
mingw* | cygwin* | pw32* | os2* | cegcc*)
;;
hpux9* | hpux10* | hpux11*)
wl='-Wl,'
;;
irix5* | irix6* | nonstopux*)
wl='-Wl,'
;;
linux* | k*bsd*-gnu | kopensolaris*-gnu)
case $cc_basename in
ecc*)
wl='-Wl,'
;;
icc* | ifort*)
wl='-Wl,'
;;
lf95*)
wl='-Wl,'
;;
nagfor*)
wl='-Wl,-Wl,,'
;;
pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
wl='-Wl,'
;;
ccc*)
wl='-Wl,'
;;
xl* | bgxl* | bgf* | mpixl*)
wl='-Wl,'
;;
como)
wl='-lopt='
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ F* | *Sun*Fortran*)
wl=
;;
*Sun\ C*)
wl='-Wl,'
;;
esac
;;
esac
;;
newsos6)
;;
*nto* | *qnx*)
;;
osf3* | osf4* | osf5*)
wl='-Wl,'
;;
rdos*)
;;
solaris*)
case $cc_basename in
f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
wl='-Qoption ld '
;;
*)
wl='-Wl,'
;;
esac
;;
sunos4*)
wl='-Qoption ld '
;;
sysv4 | sysv4.2uw2* | sysv4.3*)
wl='-Wl,'
;;
sysv4*MP*)
;;
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
wl='-Wl,'
;;
unicos*)
wl='-Wl,'
;;
uts4*)
;;
esac
fi
# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
hardcode_libdir_flag_spec=
hardcode_libdir_separator=
hardcode_direct=no
hardcode_minus_L=no
case "$host_os" in
cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
if test "$GCC" != yes; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd*)
with_gnu_ld=no
;;
esac
ld_shlibs=yes
if test "$with_gnu_ld" = yes; then
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
# Unlike libtool, we use -rpath here, not --rpath, since the documented
# option of GNU ld is called -rpath, not --rpath.
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
case "$host_os" in
aix[3-9]*)
# On AIX/PPC, the GNU linker is very broken
if test "$host_cpu" != ia64; then
ld_shlibs=no
fi
;;
amigaos*)
case "$host_cpu" in
powerpc)
;;
m68k)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
esac
;;
beos*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
cygwin* | mingw* | pw32* | cegcc*)
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
haiku*)
;;
interix[3-9]*)
hardcode_direct=no
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
netbsd*)
;;
solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs=no
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
case `$LD -v 2>&1` in
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
ld_shlibs=no
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
else
ld_shlibs=no
fi
;;
esac
;;
sunos4*)
hardcode_direct=yes
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
esac
if test "$ld_shlibs" = no; then
hardcode_libdir_flag_spec=
fi
else
case "$host_os" in
aix3*)
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L=yes
if test "$GCC" = yes; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct=unsupported
fi
;;
aix[4-9]*)
if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
break
fi
done
;;
esac
fi
hardcode_direct=yes
hardcode_libdir_separator=':'
if test "$GCC" = yes; then
case $host_os in aix4.[012]|aix4.[012].*)
collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" && \
strings "$collect2name" | grep resolve_lib_name >/dev/null
then
# We have reworked collect2
:
else
# We have old collect2
hardcode_direct=unsupported
hardcode_minus_L=yes
hardcode_libdir_flag_spec='-L$libdir'
hardcode_libdir_separator=
fi
;;
esac
fi
# Begin _LT_AC_SYS_LIBPATH_AIX.
echo 'int main () { return 0; }' > conftest.c
${CC} ${LDFLAGS} conftest.c -o conftest
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
if test -z "$aix_libpath"; then
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
fi
if test -z "$aix_libpath"; then
aix_libpath="/usr/lib:/lib"
fi
rm -f conftest.c conftest
# End _LT_AC_SYS_LIBPATH_AIX.
if test "$aix_use_runtimelinking" = yes; then
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
else
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
fi
fi
;;
amigaos*)
case "$host_cpu" in
powerpc)
;;
m68k)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
esac
;;
bsdi[45]*)
;;
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec=' '
libext=lib
;;
darwin* | rhapsody*)
hardcode_direct=no
if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
:
else
ld_shlibs=no
fi
;;
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
freebsd2.2*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
freebsd2*)
hardcode_direct=yes
hardcode_minus_L=yes
;;
freebsd* | dragonfly*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
hpux9*)
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
hpux10*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
fi
;;
hpux11*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
case $host_cpu in
hppa*64*|ia64*)
hardcode_direct=no
;;
*)
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
esac
fi
;;
irix5* | irix6* | nonstopux*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
netbsd*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
newsos6)
hardcode_direct=yes
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
*nto* | *qnx*)
;;
openbsd*)
if test -f /usr/libexec/ld.so; then
hardcode_direct=yes
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
else
case "$host_os" in
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
fi
else
ld_shlibs=no
fi
;;
os2*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
osf3*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
osf4* | osf5*)
if test "$GCC" = yes; then
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
# Both cc and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
fi
hardcode_libdir_separator=:
;;
solaris*)
hardcode_libdir_flag_spec='-R$libdir'
;;
sunos4*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_direct=yes
hardcode_minus_L=yes
;;
sysv4)
case $host_vendor in
sni)
hardcode_direct=yes # is this really true???
;;
siemens)
hardcode_direct=no
;;
motorola)
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
;;
esac
;;
sysv4.3*)
;;
sysv4*MP*)
if test -d /usr/nec; then
ld_shlibs=yes
fi
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
;;
sysv5* | sco3.2v5* | sco5v6*)
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
hardcode_libdir_separator=':'
;;
uts4*)
hardcode_libdir_flag_spec='-L$libdir'
;;
*)
ld_shlibs=no
;;
esac
fi
# Check dynamic linker characteristics
# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
# only about the one the linker finds when passed -lNAME. This is the last
# element of library_names_spec in libtool.m4, or possibly two of them if the
# linker has special search rules.
library_names_spec= # the last element of library_names_spec in libtool.m4
libname_spec='lib$name'
case "$host_os" in
aix3*)
library_names_spec='$libname.a'
;;
aix[4-9]*)
library_names_spec='$libname$shrext'
;;
amigaos*)
case "$host_cpu" in
powerpc*)
library_names_spec='$libname$shrext' ;;
m68k)
library_names_spec='$libname.a' ;;
esac
;;
beos*)
library_names_spec='$libname$shrext'
;;
bsdi[45]*)
library_names_spec='$libname$shrext'
;;
cygwin* | mingw* | pw32* | cegcc*)
shrext=.dll
library_names_spec='$libname.dll.a $libname.lib'
;;
darwin* | rhapsody*)
shrext=.dylib
library_names_spec='$libname$shrext'
;;
dgux*)
library_names_spec='$libname$shrext'
;;
freebsd* | dragonfly*)
case "$host_os" in
freebsd[123]*)
library_names_spec='$libname$shrext$versuffix' ;;
*)
library_names_spec='$libname$shrext' ;;
esac
;;
gnu*)
library_names_spec='$libname$shrext'
;;
haiku*)
library_names_spec='$libname$shrext'
;;
hpux9* | hpux10* | hpux11*)
case $host_cpu in
ia64*)
shrext=.so
;;
hppa*64*)
shrext=.sl
;;
*)
shrext=.sl
;;
esac
library_names_spec='$libname$shrext'
;;
interix[3-9]*)
library_names_spec='$libname$shrext'
;;
irix5* | irix6* | nonstopux*)
library_names_spec='$libname$shrext'
case "$host_os" in
irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
case $LD in
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
*) libsuff= shlibsuff= ;;
esac
;;
esac
;;
linux*oldld* | linux*aout* | linux*coff*)
;;
linux* | k*bsd*-gnu | kopensolaris*-gnu)
library_names_spec='$libname$shrext'
;;
knetbsd*-gnu)
library_names_spec='$libname$shrext'
;;
netbsd*)
library_names_spec='$libname$shrext'
;;
newsos6)
library_names_spec='$libname$shrext'
;;
*nto* | *qnx*)
library_names_spec='$libname$shrext'
;;
openbsd*)
library_names_spec='$libname$shrext$versuffix'
;;
os2*)
libname_spec='$name'
shrext=.dll
library_names_spec='$libname.a'
;;
osf3* | osf4* | osf5*)
library_names_spec='$libname$shrext'
;;
rdos*)
;;
solaris*)
library_names_spec='$libname$shrext'
;;
sunos4*)
library_names_spec='$libname$shrext$versuffix'
;;
sysv4 | sysv4.3*)
library_names_spec='$libname$shrext'
;;
sysv4*MP*)
library_names_spec='$libname$shrext'
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
library_names_spec='$libname$shrext'
;;
tpf*)
library_names_spec='$libname$shrext'
;;
uts4*)
library_names_spec='$libname$shrext'
;;
esac
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
# How to pass a linker flag through the compiler.
wl="$escaped_wl"
# Static library suffix (normally "a").
libext="$libext"
# Shared library suffix (normally "so").
shlibext="$shlibext"
# Format of library name prefix.
libname_spec="$escaped_libname_spec"
# Library names that the linker finds when passed -lNAME.
library_names_spec="$escaped_library_names_spec"
# Flag to hardcode \$libdir into a binary during linking.
# This must work even if \$libdir does not exist.
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
# Whether we need a single -rpath flag with a separated argument.
hardcode_libdir_separator="$hardcode_libdir_separator"
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
# resulting binary.
hardcode_direct="$hardcode_direct"
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
# resulting binary.
hardcode_minus_L="$hardcode_minus_L"
EOF

268
build/autoconf/iconv.m4 Normal file
View File

@ -0,0 +1,268 @@
# iconv.m4 serial 18 (gettext-0.18.2)
dnl Copyright (C) 2000-2002, 2007-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
[
dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
dnl accordingly.
AC_LIB_LINKFLAGS_BODY([iconv])
])
AC_DEFUN([AM_ICONV_LINK],
[
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
dnl those with the standalone portable GNU libiconv installed).
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
dnl accordingly.
AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
dnl Add $INCICONV to CPPFLAGS before performing the following checks,
dnl because if the user has installed libiconv and not disabled its use
dnl via --without-libiconv-prefix, he wants to use it. The first
dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed.
am_save_CPPFLAGS="$CPPFLAGS"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
am_cv_func_iconv="no, consider installing GNU libiconv"
am_cv_lib_iconv=no
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
]],
[[iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);]])],
[am_cv_func_iconv=yes])
if test "$am_cv_func_iconv" != yes; then
am_save_LIBS="$LIBS"
LIBS="$LIBS $LIBICONV"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
]],
[[iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);]])],
[am_cv_lib_iconv=yes]
[am_cv_func_iconv=yes])
LIBS="$am_save_LIBS"
fi
])
if test "$am_cv_func_iconv" = yes; then
AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11,
dnl Solaris 10.
am_save_LIBS="$LIBS"
if test $am_cv_lib_iconv = yes; then
LIBS="$LIBS $LIBICONV"
fi
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <iconv.h>
#include <string.h>
int main ()
{
int result = 0;
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
returns. */
{
iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
if (cd_utf8_to_88591 != (iconv_t)(-1))
{
static const char input[] = "\342\202\254"; /* EURO SIGN */
char buf[10];
const char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_utf8_to_88591,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 1;
iconv_close (cd_utf8_to_88591);
}
}
/* Test against Solaris 10 bug: Failures are not distinguishable from
successful returns. */
{
iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
if (cd_ascii_to_88591 != (iconv_t)(-1))
{
static const char input[] = "\263";
char buf[10];
const char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_ascii_to_88591,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 2;
iconv_close (cd_ascii_to_88591);
}
}
/* Test against AIX 6.1..7.1 bug: Buffer overrun. */
{
iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
static const char input[] = "\304";
static char buf[2] = { (char)0xDE, (char)0xAD };
const char *inptr = input;
size_t inbytesleft = 1;
char *outptr = buf;
size_t outbytesleft = 1;
size_t res = iconv (cd_88591_to_utf8,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
result |= 4;
iconv_close (cd_88591_to_utf8);
}
}
#if 0 /* This bug could be worked around by the caller. */
/* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
{
iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
char buf[50];
const char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_88591_to_utf8,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
if ((int)res > 0)
result |= 8;
iconv_close (cd_88591_to_utf8);
}
}
#endif
/* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
provided. */
if (/* Try standardized names. */
iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
/* Try IRIX, OSF/1 names. */
&& iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
/* Try AIX names. */
&& iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
/* Try HP-UX names. */
&& iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
result |= 16;
return result;
}]])],
[am_cv_func_iconv_works=yes],
[am_cv_func_iconv_works=no],
[
changequote(,)dnl
case "$host_os" in
aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
*) am_cv_func_iconv_works="guessing yes" ;;
esac
changequote([,])dnl
])
LIBS="$am_save_LIBS"
])
case "$am_cv_func_iconv_works" in
*no) am_func_iconv=no am_cv_lib_iconv=no ;;
*) am_func_iconv=yes ;;
esac
else
am_func_iconv=no am_cv_lib_iconv=no
fi
if test "$am_func_iconv" = yes; then
AC_DEFINE([HAVE_ICONV], [1],
[Define if you have the iconv() function and it works.])
fi
if test "$am_cv_lib_iconv" = yes; then
AC_MSG_CHECKING([how to link with libiconv])
AC_MSG_RESULT([$LIBICONV])
else
dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
dnl either.
CPPFLAGS="$am_save_CPPFLAGS"
LIBICONV=
LTLIBICONV=
fi
AC_SUBST([LIBICONV])
AC_SUBST([LTLIBICONV])
])
dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
dnl avoid warnings like
dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
dnl This is tricky because of the way 'aclocal' is implemented:
dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
dnl Otherwise aclocal's initial scan pass would miss the macro definition.
dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
dnl warnings.
m4_define([gl_iconv_AC_DEFUN],
m4_version_prereq([2.64],
[[AC_DEFUN_ONCE(
[$1], [$2])]],
[m4_ifdef([gl_00GNULIB],
[[AC_DEFUN_ONCE(
[$1], [$2])]],
[[AC_DEFUN(
[$1], [$2])]])]))
gl_iconv_AC_DEFUN([AM_ICONV],
[
AM_ICONV_LINK
if test "$am_cv_func_iconv" = yes; then
AC_MSG_CHECKING([for iconv declaration])
AC_CACHE_VAL([am_cv_proto_iconv], [
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
extern
#ifdef __cplusplus
"C"
#endif
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
#else
size_t iconv();
#endif
]],
[[]])],
[am_cv_proto_iconv_arg1=""],
[am_cv_proto_iconv_arg1="const"])
am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
AC_MSG_RESULT([
$am_cv_proto_iconv])
AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
[Define as const if the declaration of iconv() needs const.])
dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
m4_ifdef([gl_ICONV_H_DEFAULTS],
[AC_REQUIRE([gl_ICONV_H_DEFAULTS])
if test -n "$am_cv_proto_iconv_arg1"; then
ICONV_CONST="const"
fi
])
fi
])

109
build/autoconf/lib-ld.m4 Normal file
View File

@ -0,0 +1,109 @@
# lib-ld.m4 serial 5 (gettext-0.18.2)
dnl Copyright (C) 1996-2003, 2009-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl Subroutines of libtool.m4,
dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
dnl with libtool.m4.
dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
AC_DEFUN([AC_LIB_PROG_LD_GNU],
[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
case `$LD -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
acl_cv_prog_gnu_ld=yes ;;
*)
acl_cv_prog_gnu_ld=no ;;
esac])
with_gnu_ld=$acl_cv_prog_gnu_ld
])
dnl From libtool-1.4. Sets the variable LD.
AC_DEFUN([AC_LIB_PROG_LD],
[AC_ARG_WITH([gnu-ld],
[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
# Prepare PATH_SEPARATOR.
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
# Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
# contains only /bin. Note that ksh looks also at the FPATH variable,
# so we have to set that as well for the test.
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
&& { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
|| PATH_SEPARATOR=';'
}
fi
ac_prog=ld
if test "$GCC" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by GCC])
case $host in
*-*-mingw*)
# gcc leaves a trailing carriage return which upsets mingw
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
*)
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
esac
case $ac_prog in
# Accept absolute paths.
[[\\/]* | [A-Za-z]:[\\/]*)]
[re_direlt='/[^/][^/]*/\.\./']
# Canonicalize the path of ld
ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
done
test -z "$LD" && LD="$ac_prog"
;;
"")
# If it fails, then pretend we aren't using GCC.
ac_prog=ld
;;
*)
# If it is relative, then search for the first ld in PATH.
with_gnu_ld=unknown
;;
esac
elif test "$with_gnu_ld" = yes; then
AC_MSG_CHECKING([for GNU ld])
else
AC_MSG_CHECKING([for non-GNU ld])
fi
AC_CACHE_VAL([acl_cv_path_LD],
[if test -z "$LD"; then
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
acl_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some GNU ld's only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
*GNU* | *'with BFD'*)
test "$with_gnu_ld" != no && break ;;
*)
test "$with_gnu_ld" != yes && break ;;
esac
fi
done
IFS="$ac_save_ifs"
else
acl_cv_path_LD="$LD" # Let the user override the test with a path.
fi])
LD="$acl_cv_path_LD"
if test -n "$LD"; then
AC_MSG_RESULT([$LD])
else
AC_MSG_RESULT([no])
fi
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
AC_LIB_PROG_LD_GNU
])

777
build/autoconf/lib-link.m4 Normal file
View File

@ -0,0 +1,777 @@
# lib-link.m4 serial 26 (gettext-0.18.2)
dnl Copyright (C) 2001-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
AC_PREREQ([2.54])
dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
dnl the libraries corresponding to explicit and implicit dependencies.
dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
dnl augments the CPPFLAGS variable.
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
pushdef([Name],[m4_translit([$1],[./+-], [____])])
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
AC_LIB_LINKFLAGS_BODY([$1], [$2])
ac_cv_lib[]Name[]_libs="$LIB[]NAME"
ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
])
LIB[]NAME="$ac_cv_lib[]Name[]_libs"
LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
AC_SUBST([LIB]NAME)
AC_SUBST([LTLIB]NAME)
AC_SUBST([LIB]NAME[_PREFIX])
dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
dnl results of this search when this library appears as a dependency.
HAVE_LIB[]NAME=yes
popdef([NAME])
popdef([Name])
])
dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
dnl searches for libname and the libraries corresponding to explicit and
dnl implicit dependencies, together with the specified include files and
dnl the ability to compile and link the specified testcode. The missing-message
dnl defaults to 'no' and may contain additional hints for the user.
dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
pushdef([Name],[m4_translit([$1],[./+-], [____])])
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
dnl accordingly.
AC_LIB_LINKFLAGS_BODY([$1], [$2])
dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
dnl because if the user has installed lib[]Name and not disabled its use
dnl via --without-lib[]Name-prefix, he wants to use it.
ac_save_CPPFLAGS="$CPPFLAGS"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
ac_save_LIBS="$LIBS"
dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
dnl because these -l options might require -L options that are present in
dnl LIBS. -l options benefit only from the -L options listed before it.
dnl Otherwise, add it to the front of LIBS, because it may be a static
dnl library that depends on another static library that is present in LIBS.
dnl Static libraries benefit only from the static libraries listed after
dnl it.
case " $LIB[]NAME" in
*" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
*) LIBS="$LIB[]NAME $LIBS" ;;
esac
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[$3]], [[$4]])],
[ac_cv_lib[]Name=yes],
[ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
LIBS="$ac_save_LIBS"
])
if test "$ac_cv_lib[]Name" = yes; then
HAVE_LIB[]NAME=yes
AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
AC_MSG_CHECKING([how to link with lib[]$1])
AC_MSG_RESULT([$LIB[]NAME])
else
HAVE_LIB[]NAME=no
dnl If $LIB[]NAME didn't lead to a usable library, we don't need
dnl $INC[]NAME either.
CPPFLAGS="$ac_save_CPPFLAGS"
LIB[]NAME=
LTLIB[]NAME=
LIB[]NAME[]_PREFIX=
fi
AC_SUBST([HAVE_LIB]NAME)
AC_SUBST([LIB]NAME)
AC_SUBST([LTLIB]NAME)
AC_SUBST([LIB]NAME[_PREFIX])
popdef([NAME])
popdef([Name])
])
dnl Determine the platform dependent parameters needed to use rpath:
dnl acl_libext,
dnl acl_shlibext,
dnl acl_libname_spec,
dnl acl_library_names_spec,
dnl acl_hardcode_libdir_flag_spec,
dnl acl_hardcode_libdir_separator,
dnl acl_hardcode_direct,
dnl acl_hardcode_minus_L.
AC_DEFUN([AC_LIB_RPATH],
[
dnl Tell automake >= 1.10 to complain if config.rpath is missing.
m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
. ./conftest.sh
rm -f ./conftest.sh
acl_cv_rpath=done
])
wl="$acl_cv_wl"
acl_libext="$acl_cv_libext"
acl_shlibext="$acl_cv_shlibext"
acl_libname_spec="$acl_cv_libname_spec"
acl_library_names_spec="$acl_cv_library_names_spec"
acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
acl_hardcode_direct="$acl_cv_hardcode_direct"
acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
dnl Determine whether the user wants rpath handling at all.
AC_ARG_ENABLE([rpath],
[ --disable-rpath do not hardcode runtime library paths],
:, enable_rpath=yes)
])
dnl AC_LIB_FROMPACKAGE(name, package)
dnl declares that libname comes from the given package. The configure file
dnl will then not have a --with-libname-prefix option but a
dnl --with-package-prefix option. Several libraries can come from the same
dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
dnl macro call that searches for libname.
AC_DEFUN([AC_LIB_FROMPACKAGE],
[
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
define([acl_frompackage_]NAME, [$2])
popdef([NAME])
pushdef([PACK],[$2])
pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
define([acl_libsinpackage_]PACKUP,
m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1])
popdef([PACKUP])
popdef([PACK])
])
dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
dnl the libraries corresponding to explicit and implicit dependencies.
dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
[
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
dnl Autoconf >= 2.61 supports dots in --with options.
pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
AC_ARG_WITH(P_A_C_K[-prefix],
[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
--without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]],
[
if test "X$withval" = "Xno"; then
use_additional=no
else
if test "X$withval" = "X"; then
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
else
additional_includedir="$withval/include"
additional_libdir="$withval/$acl_libdirstem"
if test "$acl_libdirstem2" != "$acl_libdirstem" \
&& ! test -d "$withval/$acl_libdirstem"; then
additional_libdir="$withval/$acl_libdirstem2"
fi
fi
fi
])
dnl Search the library and its dependencies in $additional_libdir and
dnl $LDFLAGS. Using breadth-first-seach.
LIB[]NAME=
LTLIB[]NAME=
INC[]NAME=
LIB[]NAME[]_PREFIX=
dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
dnl computed. So it has to be reset here.
HAVE_LIB[]NAME=
rpathdirs=
ltrpathdirs=
names_already_handled=
names_next_round='$1 $2'
while test -n "$names_next_round"; do
names_this_round="$names_next_round"
names_next_round=
for name in $names_this_round; do
already_handled=
for n in $names_already_handled; do
if test "$n" = "$name"; then
already_handled=yes
break
fi
done
if test -z "$already_handled"; then
names_already_handled="$names_already_handled $name"
dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
dnl or AC_LIB_HAVE_LINKFLAGS call.
uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'`
eval value=\"\$HAVE_LIB$uppername\"
if test -n "$value"; then
if test "$value" = yes; then
eval value=\"\$LIB$uppername\"
test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
eval value=\"\$LTLIB$uppername\"
test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
else
dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
dnl that this library doesn't exist. So just drop it.
:
fi
else
dnl Search the library lib$name in $additional_libdir and $LDFLAGS
dnl and the already constructed $LIBNAME/$LTLIBNAME.
found_dir=
found_la=
found_so=
found_a=
eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
if test -n "$acl_shlibext"; then
shrext=".$acl_shlibext" # typically: shrext=.so
else
shrext=
fi
if test $use_additional = yes; then
dir="$additional_libdir"
dnl The same code as in the loop below:
dnl First look for a shared library.
if test -n "$acl_shlibext"; then
if test -f "$dir/$libname$shrext"; then
found_dir="$dir"
found_so="$dir/$libname$shrext"
else
if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
ver=`(cd "$dir" && \
for f in "$libname$shrext".*; do echo "$f"; done \
| sed -e "s,^$libname$shrext\\\\.,," \
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
| sed 1q ) 2>/dev/null`
if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
found_dir="$dir"
found_so="$dir/$libname$shrext.$ver"
fi
else
eval library_names=\"$acl_library_names_spec\"
for f in $library_names; do
if test -f "$dir/$f"; then
found_dir="$dir"
found_so="$dir/$f"
break
fi
done
fi
fi
fi
dnl Then look for a static library.
if test "X$found_dir" = "X"; then
if test -f "$dir/$libname.$acl_libext"; then
found_dir="$dir"
found_a="$dir/$libname.$acl_libext"
fi
fi
if test "X$found_dir" != "X"; then
if test -f "$dir/$libname.la"; then
found_la="$dir/$libname.la"
fi
fi
fi
if test "X$found_dir" = "X"; then
for x in $LDFLAGS $LTLIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
case "$x" in
-L*)
dir=`echo "X$x" | sed -e 's/^X-L//'`
dnl First look for a shared library.
if test -n "$acl_shlibext"; then
if test -f "$dir/$libname$shrext"; then
found_dir="$dir"
found_so="$dir/$libname$shrext"
else
if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
ver=`(cd "$dir" && \
for f in "$libname$shrext".*; do echo "$f"; done \
| sed -e "s,^$libname$shrext\\\\.,," \
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
| sed 1q ) 2>/dev/null`
if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
found_dir="$dir"
found_so="$dir/$libname$shrext.$ver"
fi
else
eval library_names=\"$acl_library_names_spec\"
for f in $library_names; do
if test -f "$dir/$f"; then
found_dir="$dir"
found_so="$dir/$f"
break
fi
done
fi
fi
fi
dnl Then look for a static library.
if test "X$found_dir" = "X"; then
if test -f "$dir/$libname.$acl_libext"; then
found_dir="$dir"
found_a="$dir/$libname.$acl_libext"
fi
fi
if test "X$found_dir" != "X"; then
if test -f "$dir/$libname.la"; then
found_la="$dir/$libname.la"
fi
fi
;;
esac
if test "X$found_dir" != "X"; then
break
fi
done
fi
if test "X$found_dir" != "X"; then
dnl Found the library.
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
if test "X$found_so" != "X"; then
dnl Linking with a shared library. We attempt to hardcode its
dnl directory into the executable's runpath, unless it's the
dnl standard /usr/lib.
if test "$enable_rpath" = no \
|| test "X$found_dir" = "X/usr/$acl_libdirstem" \
|| test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
dnl No hardcoding is needed.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
dnl Use an explicit option to hardcode DIR into the resulting
dnl binary.
dnl Potentially add DIR to ltrpathdirs.
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
haveit=
for x in $ltrpathdirs; do
if test "X$x" = "X$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
ltrpathdirs="$ltrpathdirs $found_dir"
fi
dnl The hardcoding into $LIBNAME is system dependent.
if test "$acl_hardcode_direct" = yes; then
dnl Using DIR/libNAME.so during linking hardcodes DIR into the
dnl resulting binary.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
dnl Use an explicit option to hardcode DIR into the resulting
dnl binary.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
dnl Potentially add DIR to rpathdirs.
dnl The rpathdirs will be appended to $LIBNAME at the end.
haveit=
for x in $rpathdirs; do
if test "X$x" = "X$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
rpathdirs="$rpathdirs $found_dir"
fi
else
dnl Rely on "-L$found_dir".
dnl But don't add it if it's already contained in the LDFLAGS
dnl or the already constructed $LIBNAME
haveit=
for x in $LDFLAGS $LIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
fi
if test "$acl_hardcode_minus_L" != no; then
dnl FIXME: Not sure whether we should use
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
dnl here.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
dnl here, because this doesn't fit in flags passed to the
dnl compiler. So give up. No hardcoding. This affects only
dnl very old systems.
dnl FIXME: Not sure whether we should use
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
dnl here.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
fi
fi
fi
fi
else
if test "X$found_a" != "X"; then
dnl Linking with a static library.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
else
dnl We shouldn't come here, but anyway it's good to have a
dnl fallback.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
fi
fi
dnl Assume the include files are nearby.
additional_includedir=
case "$found_dir" in
*/$acl_libdirstem | */$acl_libdirstem/)
basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
if test "$name" = '$1'; then
LIB[]NAME[]_PREFIX="$basedir"
fi
additional_includedir="$basedir/include"
;;
*/$acl_libdirstem2 | */$acl_libdirstem2/)
basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
if test "$name" = '$1'; then
LIB[]NAME[]_PREFIX="$basedir"
fi
additional_includedir="$basedir/include"
;;
esac
if test "X$additional_includedir" != "X"; then
dnl Potentially add $additional_includedir to $INCNAME.
dnl But don't add it
dnl 1. if it's the standard /usr/include,
dnl 2. if it's /usr/local/include and we are using GCC on Linux,
dnl 3. if it's already present in $CPPFLAGS or the already
dnl constructed $INCNAME,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_includedir" != "X/usr/include"; then
haveit=
if test "X$additional_includedir" = "X/usr/local/include"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
for x in $CPPFLAGS $INC[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-I$additional_includedir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_includedir"; then
dnl Really add $additional_includedir to $INCNAME.
INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
fi
fi
fi
fi
fi
dnl Look for dependencies.
if test -n "$found_la"; then
dnl Read the .la file. It defines the variables
dnl dlname, library_names, old_library, dependency_libs, current,
dnl age, revision, installed, dlopen, dlpreopen, libdir.
save_libdir="$libdir"
case "$found_la" in
*/* | *\\*) . "$found_la" ;;
*) . "./$found_la" ;;
esac
libdir="$save_libdir"
dnl We use only dependency_libs.
for dep in $dependency_libs; do
case "$dep" in
-L*)
additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
dnl But don't add it
dnl 1. if it's the standard /usr/lib,
dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
dnl 3. if it's already present in $LDFLAGS or the already
dnl constructed $LIBNAME,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
&& test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
haveit=
if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
|| test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
haveit=
for x in $LDFLAGS $LIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LIBNAME.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
fi
fi
haveit=
for x in $LDFLAGS $LTLIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LTLIBNAME.
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
fi
fi
fi
fi
;;
-R*)
dir=`echo "X$dep" | sed -e 's/^X-R//'`
if test "$enable_rpath" != no; then
dnl Potentially add DIR to rpathdirs.
dnl The rpathdirs will be appended to $LIBNAME at the end.
haveit=
for x in $rpathdirs; do
if test "X$x" = "X$dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
rpathdirs="$rpathdirs $dir"
fi
dnl Potentially add DIR to ltrpathdirs.
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
haveit=
for x in $ltrpathdirs; do
if test "X$x" = "X$dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
ltrpathdirs="$ltrpathdirs $dir"
fi
fi
;;
-l*)
dnl Handle this in the next round.
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
;;
*.la)
dnl Handle this in the next round. Throw away the .la's
dnl directory; it is already contained in a preceding -L
dnl option.
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
;;
*)
dnl Most likely an immediate library name.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
;;
esac
done
fi
else
dnl Didn't find the library; assume it is in the system directories
dnl known to the linker and runtime loader. (All the system
dnl directories known to the linker should also be known to the
dnl runtime loader, otherwise the system is severely misconfigured.)
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
fi
fi
fi
done
done
if test "X$rpathdirs" != "X"; then
if test -n "$acl_hardcode_libdir_separator"; then
dnl Weird platform: only the last -rpath option counts, the user must
dnl pass all path elements in one option. We can arrange that for a
dnl single library, but not when more than one $LIBNAMEs are used.
alldirs=
for found_dir in $rpathdirs; do
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
done
dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
acl_save_libdir="$libdir"
libdir="$alldirs"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
else
dnl The -rpath options are cumulative.
for found_dir in $rpathdirs; do
acl_save_libdir="$libdir"
libdir="$found_dir"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
done
fi
fi
if test "X$ltrpathdirs" != "X"; then
dnl When using libtool, the option that works for both libraries and
dnl executables is -R. The -R options are cumulative.
for found_dir in $ltrpathdirs; do
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
done
fi
popdef([P_A_C_K])
popdef([PACKLIBS])
popdef([PACKUP])
popdef([PACK])
popdef([NAME])
])
dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
dnl unless already present in VAR.
dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
dnl contains two or three consecutive elements that belong together.
AC_DEFUN([AC_LIB_APPENDTOVAR],
[
for element in [$2]; do
haveit=
for x in $[$1]; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X$element"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
[$1]="${[$1]}${[$1]:+ }$element"
fi
done
])
dnl For those cases where a variable contains several -L and -l options
dnl referring to unknown libraries and directories, this macro determines the
dnl necessary additional linker options for the runtime path.
dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
dnl otherwise linking without libtool is assumed.
AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
[
AC_REQUIRE([AC_LIB_RPATH])
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
$1=
if test "$enable_rpath" != no; then
if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
dnl Use an explicit option to hardcode directories into the resulting
dnl binary.
rpathdirs=
next=
for opt in $2; do
if test -n "$next"; then
dir="$next"
dnl No need to hardcode the standard /usr/lib.
if test "X$dir" != "X/usr/$acl_libdirstem" \
&& test "X$dir" != "X/usr/$acl_libdirstem2"; then
rpathdirs="$rpathdirs $dir"
fi
next=
else
case $opt in
-L) next=yes ;;
-L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
dnl No need to hardcode the standard /usr/lib.
if test "X$dir" != "X/usr/$acl_libdirstem" \
&& test "X$dir" != "X/usr/$acl_libdirstem2"; then
rpathdirs="$rpathdirs $dir"
fi
next= ;;
*) next= ;;
esac
fi
done
if test "X$rpathdirs" != "X"; then
if test -n ""$3""; then
dnl libtool is used for linking. Use -R options.
for dir in $rpathdirs; do
$1="${$1}${$1:+ }-R$dir"
done
else
dnl The linker is used for linking directly.
if test -n "$acl_hardcode_libdir_separator"; then
dnl Weird platform: only the last -rpath option counts, the user
dnl must pass all path elements in one option.
alldirs=
for dir in $rpathdirs; do
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
done
acl_save_libdir="$libdir"
libdir="$alldirs"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
$1="$flag"
else
dnl The -rpath options are cumulative.
for dir in $rpathdirs; do
acl_save_libdir="$libdir"
libdir="$dir"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
$1="${$1}${$1:+ }$flag"
done
fi
fi
fi
fi
fi
AC_SUBST([$1])
])

View File

@ -0,0 +1,224 @@
# lib-prefix.m4 serial 7 (gettext-0.18)
dnl Copyright (C) 2001-2005, 2008-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
dnl require excessive bracketing.
ifdef([AC_HELP_STRING],
[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
dnl to access previously installed libraries. The basic assumption is that
dnl a user will want packages to use other packages he previously installed
dnl with the same --prefix option.
dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
dnl libraries, but is otherwise very convenient.
AC_DEFUN([AC_LIB_PREFIX],
[
AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
AC_LIB_ARG_WITH([lib-prefix],
[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
--without-lib-prefix don't search for libraries in includedir and libdir],
[
if test "X$withval" = "Xno"; then
use_additional=no
else
if test "X$withval" = "X"; then
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
else
additional_includedir="$withval/include"
additional_libdir="$withval/$acl_libdirstem"
fi
fi
])
if test $use_additional = yes; then
dnl Potentially add $additional_includedir to $CPPFLAGS.
dnl But don't add it
dnl 1. if it's the standard /usr/include,
dnl 2. if it's already present in $CPPFLAGS,
dnl 3. if it's /usr/local/include and we are using GCC on Linux,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_includedir" != "X/usr/include"; then
haveit=
for x in $CPPFLAGS; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-I$additional_includedir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test "X$additional_includedir" = "X/usr/local/include"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
if test -d "$additional_includedir"; then
dnl Really add $additional_includedir to $CPPFLAGS.
CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
fi
fi
fi
fi
dnl Potentially add $additional_libdir to $LDFLAGS.
dnl But don't add it
dnl 1. if it's the standard /usr/lib,
dnl 2. if it's already present in $LDFLAGS,
dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
haveit=
for x in $LDFLAGS; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
if test -n "$GCC"; then
case $host_os in
linux*) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LDFLAGS.
LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
fi
fi
fi
fi
fi
])
dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
dnl acl_final_exec_prefix, containing the values to which $prefix and
dnl $exec_prefix will expand at the end of the configure script.
AC_DEFUN([AC_LIB_PREPARE_PREFIX],
[
dnl Unfortunately, prefix and exec_prefix get only finally determined
dnl at the end of configure.
if test "X$prefix" = "XNONE"; then
acl_final_prefix="$ac_default_prefix"
else
acl_final_prefix="$prefix"
fi
if test "X$exec_prefix" = "XNONE"; then
acl_final_exec_prefix='${prefix}'
else
acl_final_exec_prefix="$exec_prefix"
fi
acl_save_prefix="$prefix"
prefix="$acl_final_prefix"
eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
prefix="$acl_save_prefix"
])
dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
dnl variables prefix and exec_prefix bound to the values they will have
dnl at the end of the configure script.
AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
[
acl_save_prefix="$prefix"
prefix="$acl_final_prefix"
acl_save_exec_prefix="$exec_prefix"
exec_prefix="$acl_final_exec_prefix"
$1
exec_prefix="$acl_save_exec_prefix"
prefix="$acl_save_prefix"
])
dnl AC_LIB_PREPARE_MULTILIB creates
dnl - a variable acl_libdirstem, containing the basename of the libdir, either
dnl "lib" or "lib64" or "lib/64",
dnl - a variable acl_libdirstem2, as a secondary possible value for
dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
dnl "lib/amd64".
AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
[
dnl There is no formal standard regarding lib and lib64.
dnl On glibc systems, the current practice is that on a system supporting
dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
dnl the compiler's default mode by looking at the compiler's library search
dnl path. If at least one of its elements ends in /lib64 or points to a
dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
dnl Otherwise we use the default, namely "lib".
dnl On Solaris systems, the current practice is that on a system supporting
dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
AC_REQUIRE([AC_CANONICAL_HOST])
acl_libdirstem=lib
acl_libdirstem2=
case "$host_os" in
solaris*)
dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
dnl symlink is missing, so we set acl_libdirstem2 too.
AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
[AC_EGREP_CPP([sixtyfour bits], [
#ifdef _LP64
sixtyfour bits
#endif
], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
])
if test $gl_cv_solaris_64bit = yes; then
acl_libdirstem=lib/64
case "$host_cpu" in
sparc*) acl_libdirstem2=lib/sparcv9 ;;
i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
esac
fi
;;
*)
searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
if test -n "$searchpath"; then
acl_save_IFS="${IFS= }"; IFS=":"
for searchdir in $searchpath; do
if test -d "$searchdir"; then
case "$searchdir" in
*/lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
*/../ | */.. )
# Better ignore directories of this form. They are misleading.
;;
*) searchdir=`cd "$searchdir" && pwd`
case "$searchdir" in
*/lib64 ) acl_libdirstem=lib64 ;;
esac ;;
esac
fi
done
IFS="$acl_save_IFS"
fi
;;
esac
test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
])

View File

@ -40,8 +40,9 @@ cd ..
# Clean up the source dir as much as we can.
/bin/sh build/clean.sh
# Substitute the integer version into Libarchive's archive.h
# Substitute the versions into Libarchive's archive.h and archive_entry.h
perl -p -i -e "s/^(#define\tARCHIVE_VERSION_NUMBER).*/\$1 $VN/" libarchive/archive.h
perl -p -i -e "s/^(#define\tARCHIVE_VERSION_NUMBER).*/\$1 $VN/" libarchive/archive_entry.h
perl -p -i -e "s/^(#define\tARCHIVE_VERSION_STRING).*/\$1 \"libarchive $VS\"/" libarchive/archive.h
# Substitute versions into configure.ac as well
perl -p -i -e 's/(m4_define\(\[LIBARCHIVE_VERSION_S\]),.*\)/$1,['"$VS"'])/' configure.ac
@ -59,10 +60,3 @@ esac
autoconf
autoheader
automake -a -c
curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' > build/autoconf/config.guess
curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' > build/autoconf/config.sub
./configure
make distcheck
make dist-zip

View File

@ -1,17 +1,16 @@
#!/bin/sh
#
# Attempt to remove as many generated files as we can.
# Ideally, a well-used development sandbox would look like
# a pristine checkout after running this script.
#
if [ \! -f build/version ]; then
echo 'Must run the clean script from the top-level dir of the libarchive distribution' 1>&2
exit 1
fi
#
# The automake-generated 'maintainer-clean' target does clean up a
# lot. If that fails, try plain 'clean' in case we're using the cmake
# or other makefile. But don't worry if we can't...
#
make maintainer-clean || make clean || true
# If we're on BSD, blow away the build dir under /usr/obj
rm -rf /usr/obj`pwd`
@ -19,22 +18,32 @@ rm -rf /usr/obj`pwd`
# Try to clean up a bit more...
#
find . -name '*.So' | xargs rm
find . -name '*.a' | xargs rm
find . -name '*.la' | xargs rm
find . -name '*.lo' | xargs rm
find . -name '*.o' | xargs rm
find . -name '*.orig' | xargs rm
find . -name '*.po' | xargs rm
find . -name '*.rej' | xargs rm
find . -name '*~' | xargs rm
find . -name '.depend' | xargs rm
find . -name '*.So' | xargs rm -f
find . -name '*.a' | xargs rm -f
find . -name '*.la' | xargs rm -f
find . -name '*.lo' | xargs rm -f
find . -name '*.o' | xargs rm -f
find . -name '*.orig' | xargs rm -f
find . -name '*.po' | xargs rm -f
find . -name '*.rej' | xargs rm -f
find . -name '*~' | xargs rm -f
find . -name '.depend' | xargs rm -f
find . -name '.deps' | xargs rm -rf
find . -name '.dirstamp' | xargs rm
find . -name '.dirstamp' | xargs rm -f
find . -name '.libs' | xargs rm -rf
find . -name 'CMakeFiles' | xargs rm -rf
find . -name 'cmake_install.cmake' | xargs rm -f
find . -name 'CTestTestfile.cmake' | xargs rm -f
rm -rf Testing
rm -rf autom4te.cache
rm -rf bin
rm -rf cmake.tmp
rm -rf libarchive/Testing
rm -f CMakeCache.txt
rm -f DartConfiguration.tcl
rm -f Makefile
rm -f Makefile.in
rm -f aclocal.m4
rm -f bsdcpio
@ -42,7 +51,8 @@ rm -f bsdcpio_test
rm -f bsdtar
rm -f bsdtar_test
rm -f build/autoconf/compile
rm -f build/autoconf/config.*
rm -f build/autoconf/config.guess
rm -f build/autoconf/config.sub
rm -f build/autoconf/depcomp
rm -f build/autoconf/install-sh
rm -f build/autoconf/libtool.m4
@ -60,7 +70,9 @@ rm -f config.log
rm -f config.status
rm -f configure
rm -f cpio/*.1.gz
rm -f cpio/Makefile
rm -f cpio/bsdcpio
rm -f cpio/test/Makefile
rm -f cpio/test/bsdcpio_test
rm -f cpio/test/list.h
rm -f doc/html/*
@ -69,13 +81,17 @@ rm -f doc/pdf/*
rm -f doc/text/*
rm -f doc/wiki/*
rm -f libarchive/*.[35].gz
rm -f libarchive/Makefile
rm -f libarchive/libarchive.so*
rm -f libarchive/test/Makefile
rm -f libarchive/test/libarchive_test
rm -f libarchive/test/list.h
rm -f libarchive_test
rm -f libtool
rm -f stamp-h1
rm -f tar/*.1.gz
rm -f tar/Makefile
rm -f tar/bsdtar
rm -f tar/test/Makefile
rm -f tar/test/bsdtar_test
rm -f tar/test/list.h

View File

@ -1,107 +0,0 @@
# - Macro approximating the CMake 2.8 ADD_TEST(NAME) signature.
# ADD_TEST_28(NAME <name> COMMAND <command> [arg1 [arg2 ...]])
# <name> - The name of the test
# <command> - The test executable
# [argN...] - Arguments to the test executable
# This macro approximates the ADD_TEST(NAME) signature provided in
# CMake 2.8 but works with CMake 2.6 too. See CMake 2.8 documentation
# of ADD_TEST()for details.
#
# This macro automatically replaces a <command> that names an
# executable target with the target location. A generator expression
# of the form "$<TARGET_FILE:tgt>" is supported in both the command
# and arguments of the test. Howerver, this macro only works for
# targets without per-config output name properties set.
#
# Example usage:
# add_test(NAME mytest COMMAND testDriver --exe $<TARGET_FILE:myexe>)
# This creates a test "mytest" whose command runs a testDriver tool
# passing the full path to the executable file produced by target
# "myexe".
#=============================================================================
# Copyright 2009 Kitware, Inc.
# 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
# in this position and unchanged.
# 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.
#=============================================================================
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3)
# CMake 2.8 supports ADD_TEST(NAME) natively.
IF(NOT "${CMAKE_VERSION}" VERSION_LESS "2.8")
MACRO(ADD_TEST_28)
ADD_TEST(${ARGV})
ENDMACRO()
RETURN()
ENDIF()
# Simulate ADD_TEST(NAME) signature from CMake 2.8.
MACRO(ADD_TEST_28 NAME name COMMAND command)
# Enforce the signature.
IF(NOT "x${NAME}" STREQUAL "xNAME")
MESSAGE(FATAL_ERROR "First ADD_TEST_28 argument must be \"NAME\"")
ENDIF()
IF(NOT "x${COMMAND}" STREQUAL "xCOMMAND")
MESSAGE(FATAL_ERROR "Third ADD_TEST_28 argument must be \"COMMAND\"")
ENDIF()
# Perform "COMMAND myexe ..." substitution.
SET(cmd "${command}")
IF(TARGET "${cmd}")
_ADD_TEST_28_GET_EXE(${cmd} cmd)
ENDIF()
# Perform "COMMAND ... $<TARGET_FILE:myexe> ..." substitution.
SET(target_file "\\$<TARGET_FILE:(.+)>")
SET(args)
FOREACH(ARG ${cmd} ${ARGN})
SET(arg "${ARG}")
IF("${arg}" MATCHES "${target_file}")
STRING(REGEX REPLACE "${target_file}" "\\1" tgt "${arg}")
IF(TARGET "${tgt}")
_ADD_TEST_28_GET_EXE(${tgt} exe)
STRING(REGEX REPLACE "${target_file}" "${exe}" arg "${arg}")
ENDIF()
ENDIF()
LIST(APPEND args "${arg}")
ENDFOREACH()
# Invoke old ADD_TEST() signature with transformed arguments.
ADD_TEST(${name} ${args})
ENDMACRO()
# Get the test-time location of an executable target.
MACRO(_ADD_TEST_28_GET_EXE tgt exe_var)
# The LOCATION property gives a build-time location.
GET_TARGET_PROPERTY(${exe_var} ${tgt} LOCATION)
# In single-configuration generatrs the build-time and test-time
# locations are the same because there is no per-config variable
# reference. In multi-configuration generators the following
# substitution converts the build-time configuration variable
# reference to a test-time configuration variable reference.
IF(CMAKE_CONFIGURATION_TYPES)
STRING(REPLACE "${CMAKE_CFG_INTDIR}" "\${CTEST_CONFIGURATION_TYPE}"
${exe_var} "${${exe_var}}")
ENDIF(CMAKE_CONFIGURATION_TYPES)
ENDMACRO()

View File

@ -14,7 +14,7 @@ IF (LZMA_INCLUDE_DIR)
ENDIF (LZMA_INCLUDE_DIR)
FIND_PATH(LZMA_INCLUDE_DIR lzma.h)
FIND_LIBRARY(LZMA_LIBRARY NAMES lzma )
FIND_LIBRARY(LZMA_LIBRARY NAMES lzma liblzma)
# handle the QUIETLY and REQUIRED arguments and set LZMA_FOUND to TRUE if
# all listed variables are TRUE
@ -46,7 +46,3 @@ ELSE(LZMA_FOUND)
SET( LZMADEC_LIBRARIES )
ENDIF(LZMADEC_FOUND)
ENDIF(LZMA_FOUND)
MARK_AS_ADVANCED( LZMA_LIBRARY LZMA_INCLUDE_DIR
LZMADEC_LIBRARY LZMADEC_INCLUDE_DIR )

View File

@ -1,91 +1,287 @@
/* config.h. Generated from config.h.cmake by cmake configure */
/* config.h. Generated from build/cmake/config.h.in by cmake configure */
/*
* Ensure we have C99-style int64_t, etc, all defined.
*/
/* First, we need to know if the system has already defined them. */
#cmakedefine HAVE_INT16_T
#cmakedefine HAVE_INT32_T
#cmakedefine HAVE_INT64_T
#cmakedefine HAVE_INTMAX_T
#cmakedefine HAVE_UINT8_T
#cmakedefine HAVE_UINT16_T
#cmakedefine HAVE_UINT32_T
#cmakedefine HAVE_UINT64_T
#cmakedefine HAVE_UINTMAX_T
/* We might have the types we want under other spellings. */
#cmakedefine HAVE___INT64
#cmakedefine HAVE_U_INT64_T
#cmakedefine HAVE_UNSIGNED___INT64
/* The sizes of various standard integer types. */
@SIZE_OF_SHORT_CODE@
@SIZE_OF_INT_CODE@
@SIZE_OF_LONG_CODE@
@SIZE_OF_LONG_LONG_CODE@
@SIZE_OF_UNSIGNED_SHORT_CODE@
@SIZE_OF_UNSIGNED_CODE@
@SIZE_OF_UNSIGNED_LONG_CODE@
@SIZE_OF_UNSIGNED_LONG_LONG_CODE@
/*
* If we lack int64_t, define it to the first of __int64, int, long, and long long
* that exists and is the right size.
*/
#if !defined(HAVE_INT64_T) && defined(HAVE___INT64)
typedef __int64 int64_t;
#define HAVE_INT64_T
#endif
#if !defined(HAVE_INT64_T) && SIZE_OF_INT == 8
typedef int int64_t;
#define HAVE_INT64_T
#endif
#if !defined(HAVE_INT64_T) && SIZE_OF_LONG == 8
typedef long int64_t;
#define HAVE_INT64_T
#endif
#if !defined(HAVE_INT64_T) && SIZE_OF_LONG_LONG == 8
typedef long long int64_t;
#define HAVE_INT64_T
#endif
#if !defined(HAVE_INT64_T)
#error No 64-bit integer type was found.
#endif
/*
* Similarly for int32_t
*/
#if !defined(HAVE_INT32_T) && SIZE_OF_INT == 4
typedef long int32_t;
#define HAVE_INT32_T
#endif
#if !defined(HAVE_INT32_T) && SIZE_OF_LONG == 4
typedef long int32_t;
#define HAVE_INT32_T
#endif
#if !defined(HAVE_INT32_T)
#error No 32-bit integer type was found.
#endif
/*
* Similarly for int16_t
*/
#if !defined(HAVE_INT16_T) && SIZE_OF_INT == 2
typedef int int16_t;
#define HAVE_INT16_T
#endif
#if !defined(HAVE_INT16_T) && SIZE_OF_SHORT == 2
typedef short int16_t;
#define HAVE_INT16_T
#endif
#if !defined(HAVE_INT16_T)
#error No 16-bit integer type was found.
#endif
/*
* Similarly for uint64_t
*/
#if !defined(HAVE_UINT64_T) && defined(HAVE_UNSIGNED___INT64)
typedef unsigned __int64 uint64_t;
#define HAVE_UINT64_T
#endif
#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED == 8
typedef unsigned uint64_t;
#define HAVE_UINT64_T
#endif
#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG == 8
typedef unsigned long uint64_t;
#define HAVE_UINT64_T
#endif
#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG_LONG == 8
typedef unsigned long long uint64_t;
#define HAVE_UINT64_T
#endif
#if !defined(HAVE_UINT64_T)
#error No 64-bit unsigned integer type was found.
#endif
/*
* Similarly for uint32_t
*/
#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED == 4
typedef unsigned uint32_t;
#define HAVE_UINT32_T
#endif
#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED_LONG == 4
typedef unsigned long uint32_t;
#define HAVE_UINT32_T
#endif
#if !defined(HAVE_UINT32_T)
#error No 32-bit unsigned integer type was found.
#endif
/*
* Similarly for uint16_t
*/
#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED == 2
typedef unsigned uint16_t;
#define HAVE_UINT16_T
#endif
#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED_SHORT == 2
typedef unsigned short uint16_t;
#define HAVE_UINT16_T
#endif
#if !defined(HAVE_UINT16_T)
#error No 16-bit unsigned integer type was found.
#endif
/*
* Similarly for uint8_t
*/
#if !defined(HAVE_UINT8_T)
typedef unsigned char uint8_t;
#define HAVE_UINT8_T
#endif
#if !defined(HAVE_UINT16_T)
#error No 8-bit unsigned integer type was found.
#endif
/* Define intmax_t and uintmax_t if they are not already defined. */
#if !defined(HAVE_INTMAX_T)
typedef int64_t intmax_t;
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#endif
#if !defined(HAVE_UINTMAX_T)
typedef uint64_t uintmax_t;
#endif
/* Define ZLIB_WINAPI if zlib was built on Visual Studio. */
#cmakedefine ZLIB_WINAPI 1
/* MD5 via ARCHIVE_HASH_MD5_LIBC supported. */
#cmakedefine ARCHIVE_HASH_MD5_LIBC
/* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */
#cmakedefine ARCHIVE_CRYPTO_MD5_LIBC 1
/* MD5 via ARCHIVE_HASH_MD5_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_HASH_MD5_LIBSYSTEM
/* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1
/* MD5 via ARCHIVE_HASH_MD5_OPENSSL supported. */
#cmakedefine ARCHIVE_HASH_MD5_OPENSSL
/* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_MD5_NETTLE 1
/* MD5 via ARCHIVE_HASH_MD5_WIN supported. */
#cmakedefine ARCHIVE_HASH_MD5_WIN
/* MD5 via ARCHIVE_CRYPTO_MD5_OPENSSL supported. */
#cmakedefine ARCHIVE_CRYPTO_MD5_OPENSSL 1
/* RMD160 via ARCHIVE_HASH_RMD160_LIBC supported. */
#cmakedefine ARCHIVE_HASH_RMD160_LIBC
/* MD5 via ARCHIVE_CRYPTO_MD5_WIN supported. */
#cmakedefine ARCHIVE_CRYPTO_MD5_WIN 1
/* RMD160 via ARCHIVE_HASH_RMD160_OPENSSL supported. */
#cmakedefine ARCHIVE_HASH_RMD160_OPENSSL
/* RMD160 via ARCHIVE_CRYPTO_RMD160_LIBC supported. */
#cmakedefine ARCHIVE_CRYPTO_RMD160_LIBC 1
/* SHA1 via ARCHIVE_HASH_SHA1_LIBC supported. */
#cmakedefine ARCHIVE_HASH_SHA1_LIBC
/* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_RMD160_NETTLE 1
/* SHA1 via ARCHIVE_HASH_SHA1_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_HASH_SHA1_LIBSYSTEM
/* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */
#cmakedefine ARCHIVE_CRYPTO_RMD160_OPENSSL 1
/* SHA1 via ARCHIVE_HASH_SHA1_OPENSSL supported. */
#cmakedefine ARCHIVE_HASH_SHA1_OPENSSL
/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBC supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBC 1
/* SHA1 via ARCHIVE_HASH_SHA1_WIN supported. */
#cmakedefine ARCHIVE_HASH_SHA1_WIN
/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1
/* SHA256 via ARCHIVE_HASH_SHA256_LIBC supported. */
#cmakedefine ARCHIVE_HASH_SHA256_LIBC
/* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA1_NETTLE 1
/* SHA256 via ARCHIVE_HASH_SHA256_LIBC2 supported. */
#cmakedefine ARCHIVE_HASH_SHA256_LIBC2
/* SHA1 via ARCHIVE_CRYPTO_SHA1_OPENSSL supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA1_OPENSSL 1
/* SHA256 via ARCHIVE_HASH_SHA256_LIBC3 supported. */
#cmakedefine ARCHIVE_HASH_SHA256_LIBC3
/* SHA1 via ARCHIVE_CRYPTO_SHA1_WIN supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA1_WIN 1
/* SHA256 via ARCHIVE_HASH_SHA256_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_HASH_SHA256_LIBSYSTEM
/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC 1
/* SHA256 via ARCHIVE_HASH_SHA256_OPENSSL supported. */
#cmakedefine ARCHIVE_HASH_SHA256_OPENSSL
/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC2 supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC2 1
/* SHA256 via ARCHIVE_HASH_SHA256_WIN supported. */
#cmakedefine ARCHIVE_HASH_SHA256_WIN
/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC3 supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC3 1
/* SHA384 via ARCHIVE_HASH_SHA384_LIBC supported. */
#cmakedefine ARCHIVE_HASH_SHA384_LIBC
/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1
/* SHA384 via ARCHIVE_HASH_SHA384_LIBC2 supported. */
#cmakedefine ARCHIVE_HASH_SHA384_LIBC2
/* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA256_NETTLE 1
/* SHA384 via ARCHIVE_HASH_SHA384_LIBC3 supported. */
#cmakedefine ARCHIVE_HASH_SHA384_LIBC3
/* SHA256 via ARCHIVE_CRYPTO_SHA256_OPENSSL supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA256_OPENSSL 1
/* SHA384 via ARCHIVE_HASH_SHA384_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_HASH_SHA384_LIBSYSTEM
/* SHA256 via ARCHIVE_CRYPTO_SHA256_WIN supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA256_WIN 1
/* SHA384 via ARCHIVE_HASH_SHA384_OPENSSL supported. */
#cmakedefine ARCHIVE_HASH_SHA384_OPENSSL
/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC 1
/* SHA384 via ARCHIVE_HASH_SHA384_WIN supported. */
#cmakedefine ARCHIVE_HASH_SHA384_WIN
/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC2 supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC2 1
/* SHA512 via ARCHIVE_HASH_SHA512_LIBC supported. */
#cmakedefine ARCHIVE_HASH_SHA512_LIBC
/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC3 supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC3 1
/* SHA512 via ARCHIVE_HASH_SHA512_LIBC2 supported. */
#cmakedefine ARCHIVE_HASH_SHA512_LIBC2
/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1
/* SHA512 via ARCHIVE_HASH_SHA512_LIBC3 supported. */
#cmakedefine ARCHIVE_HASH_SHA512_LIBC3
/* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA384_NETTLE 1
/* SHA512 via ARCHIVE_HASH_SHA512_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_HASH_SHA512_LIBSYSTEM
/* SHA384 via ARCHIVE_CRYPTO_SHA384_OPENSSL supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA384_OPENSSL 1
/* SHA512 via ARCHIVE_HASH_SHA512_OPENSSL supported. */
#cmakedefine ARCHIVE_HASH_SHA512_OPENSSL
/* SHA384 via ARCHIVE_CRYPTO_SHA384_WIN supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA384_WIN 1
/* SHA512 via ARCHIVE_HASH_SHA512_WIN supported. */
#cmakedefine ARCHIVE_HASH_SHA512_WIN
/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC 1
/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC2 supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC2 1
/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC3 supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC3 1
/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1
/* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_NETTLE 1
/* SHA512 via ARCHIVE_CRYPTO_SHA512_OPENSSL supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_OPENSSL 1
/* SHA512 via ARCHIVE_CRYPTO_SHA512_WIN supported. */
#cmakedefine ARCHIVE_CRYPTO_SHA512_WIN 1
/* Version number of bsdcpio */
#cmakedefine BSDCPIO_VERSION_STRING "${BSDCPIO_VERSION_STRING}"
@ -147,11 +343,11 @@
/* Define to 1 if you have the `chroot' function. */
#cmakedefine HAVE_CHROOT 1
/* Define to 1 if you have the `CreateHardLinkA' function. */
#cmakedefine HAVE_CREATEHARDLINKA 1
/* Define to 1 if you have the <copyfile.h> header file. */
#cmakedefine HAVE_COPYFILE_H 1
/* Define to 1 if you have the `CreateHardLinkW' function. */
#cmakedefine HAVE_CREATEHARDLINKW 1
/* Define to 1 if you have the `ctime_r' function. */
#cmakedefine HAVE_CTIME_R 1
/* Define to 1 if you have the <ctype.h> header file. */
#cmakedefine HAVE_CTYPE_H 1
@ -167,14 +363,6 @@
don't. */
#cmakedefine HAVE_DECL_INT64_MIN 1
/* Define to 1 if you have the declaration of `optarg', and to 0 if you don't.
*/
#cmakedefine HAVE_DECL_OPTARG 1
/* Define to 1 if you have the declaration of `optind', and to 0 if you don't.
*/
#cmakedefine HAVE_DECL_OPTIND 1
/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
don't. */
#cmakedefine HAVE_DECL_SIZE_MAX 1
@ -238,6 +426,9 @@
/* Define to 1 if you have the `extattr_set_file' function. */
#cmakedefine HAVE_EXTATTR_SET_FILE 1
/* Define to 1 if EXTATTR_NAMESPACE_USER is defined in sys/extattr.h. */
#cmakedefine HAVE_DECL_EXTATTR_NAMESPACE_USER 1
/* Define to 1 if you have the `fchdir' function. */
#cmakedefine HAVE_FCHDIR 1
@ -256,18 +447,45 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H 1
/* Define to 1 if you have the `fdopendir' function. */
#cmakedefine HAVE_FDOPENDIR 1
/* Define to 1 if you have the `fgetea' function. */
#cmakedefine HAVE_FGETEA 1
/* Define to 1 if you have the `fgetxattr' function. */
#cmakedefine HAVE_FGETXATTR 1
/* Define to 1 if you have the `flistea' function. */
#cmakedefine HAVE_FLISTEA 1
/* Define to 1 if you have the `flistxattr' function. */
#cmakedefine HAVE_FLISTXATTR 1
/* Define to 1 if you have the `fork' function. */
#cmakedefine HAVE_FORK 1
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#cmakedefine HAVE_FSEEKO 1
/* Define to 1 if you have the `fsetea' function. */
#cmakedefine HAVE_FSETEA 1
/* Define to 1 if you have the `fsetxattr' function. */
#cmakedefine HAVE_FSETXATTR 1
/* Define to 1 if you have the `fstat' function. */
#cmakedefine HAVE_FSTAT 1
/* Define to 1 if you have the `fstatat' function. */
#cmakedefine HAVE_FSTATAT 1
/* Define to 1 if you have the `fstatfs' function. */
#cmakedefine HAVE_FSTATFS 1
/* Define to 1 if you have the `fstatvfs' function. */
#cmakedefine HAVE_FSTATVFS 1
/* Define to 1 if you have the `ftruncate' function. */
#cmakedefine HAVE_FTRUNCATE 1
@ -277,6 +495,12 @@
/* Define to 1 if you have the `futimes' function. */
#cmakedefine HAVE_FUTIMES 1
/* Define to 1 if you have the `futimesat' function. */
#cmakedefine HAVE_FUTIMESAT 1
/* Define to 1 if you have the `getea' function. */
#cmakedefine HAVE_GETEA 1
/* Define to 1 if you have the `geteuid' function. */
#cmakedefine HAVE_GETEUID 1
@ -286,23 +510,32 @@
/* Define to 1 if you have the `getgrnam_r' function. */
#cmakedefine HAVE_GETGRNAM_R 1
/* Define to 1 if you have the `getpid' function. */
#cmakedefine HAVE_GETPID 1
/* Define to 1 if you have the `getpwnam_r' function. */
#cmakedefine HAVE_GETPWNAM_R 1
/* Define to 1 if you have the `getpwuid_r' function. */
#cmakedefine HAVE_GETPWUID_R 1
/* Define to 1 if you have the `getpid' function. */
#cmakedefine HAVE_GETPID 1
/* Define to 1 if you have the `getvfsbyname' function. */
#cmakedefine HAVE_GETVFSBYNAME 1
/* Define to 1 if you have the `getxattr' function. */
#cmakedefine HAVE_GETXATTR 1
/* Define to 1 if you have the `gmtime_r' function. */
#cmakedefine HAVE_GMTIME_R 1
/* Define to 1 if you have the <grp.h> header file. */
#cmakedefine HAVE_GRP_H 1
/* Define to 1 if the system has the type `intmax_t'. */
#cmakedefine HAVE_INTMAX_T 1
/* Define to 1 if you have the `iconv' function. */
#cmakedefine HAVE_ICONV 1
/* Define to 1 if you have the <iconv.h> header file. */
#cmakedefine HAVE_ICONV_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
@ -322,6 +555,9 @@
/* Define to 1 if you have the `lchown' function. */
#cmakedefine HAVE_LCHOWN 1
/* Define to 1 if you have the `lgetea' function. */
#cmakedefine HAVE_LGETEA 1
/* Define to 1 if you have the `lgetxattr' function. */
#cmakedefine HAVE_LGETXATTR 1
@ -352,30 +588,57 @@
/* Define to 1 if you have the <libxml/xmlreader.h> header file. */
#cmakedefine HAVE_LIBXML_XMLREADER_H 1
/* Define to 1 if you have the <libxml/xmlwriter.h> header file. */
#cmakedefine HAVE_LIBXML_XMLWRITER_H 1
/* Define to 1 if you have the `z' library (-lz). */
#cmakedefine HAVE_LIBZ 1
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H 1
/* Define to 1 if you have the link() function. */
/* Define to 1 if you have the `link' function. */
#cmakedefine HAVE_LINK 1
/* Define to 1 if you have the <linux/fiemap.h> header file. */
#cmakedefine HAVE_LINUX_FIEMAP_H 1
/* Define to 1 if you have the <linux/fs.h> header file. */
#cmakedefine HAVE_LINUX_FS_H 1
/* Define to 1 if you have the <linux/magic.h> header file. */
#cmakedefine HAVE_LINUX_MAGIC_H 1
/* Define to 1 if you have the `listea' function. */
#cmakedefine HAVE_LISTEA 1
/* Define to 1 if you have the `listxattr' function. */
#cmakedefine HAVE_LISTXATTR 1
/* Define to 1 if you have the `llistea' function. */
#cmakedefine HAVE_LLISTEA 1
/* Define to 1 if you have the `llistxattr' function. */
#cmakedefine HAVE_LLISTXATTR 1
/* Define to 1 if you have the <localcharset.h> header file. */
#cmakedefine HAVE_LOCALCHARSET_H 1
/* Define to 1 if you have the `locale_charset' function. */
#cmakedefine HAVE_LOCALE_CHARSET 1
/* Define to 1 if you have the <locale.h> header file. */
#cmakedefine HAVE_LOCALE_H 1
/* Define to 1 if you have the `localtime_r' function. */
#cmakedefine HAVE_LOCALTIME_R 1
/* Define to 1 if the system has the type `long long int'. */
#cmakedefine HAVE_LONG_LONG_INT 1
/* Define to 1 if you have the `lsetea' function. */
#cmakedefine HAVE_LSETEA 1
/* Define to 1 if you have the `lsetxattr' function. */
#cmakedefine HAVE_LSETXATTR 1
@ -395,6 +658,12 @@
/* Define to 1 if you have the <lzma.h> header file. */
#cmakedefine HAVE_LZMA_H 1
/* Define to 1 if you have the `mbrtowc' function. */
#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. */
#cmakedefine HAVE_MEMMOVE 1
@ -410,12 +679,18 @@
/* Define to 1 if you have the `mknod' function. */
#cmakedefine HAVE_MKNOD 1
/* Define to 1 if you have the `mkstemp' function. */
#cmakedefine HAVE_MKSTEMP 1
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#cmakedefine HAVE_NDIR_H 1
/* Define to 1 if you have the `nl_langinfo' function. */
#cmakedefine HAVE_NL_LANGINFO 1
/* Define to 1 if you have the `openat' function. */
#cmakedefine HAVE_OPENAT 1
/* Define to 1 if you have the <paths.h> header file. */
#cmakedefine HAVE_PATHS_H 1
@ -434,9 +709,15 @@
/* Define to 1 if you have the <pwd.h> header file. */
#cmakedefine HAVE_PWD_H 1
/* Define to 1 if you have the `readdir_r' function. */
#cmakedefine HAVE_READDIR_R 1
/* Define to 1 if you have the `readlink' function. */
#cmakedefine HAVE_READLINK 1
/* Define to 1 if you have the `readlinkat' function. */
#cmakedefine HAVE_READLINKAT 1
/* Define to 1 if you have the <regex.h> header file. */
#cmakedefine HAVE_REGEX_H 1
@ -455,6 +736,12 @@
/* Define to 1 if you have the <signal.h> header file. */
#cmakedefine HAVE_SIGNAL_H 1
/* Define to 1 if you have the `statfs' function. */
#cmakedefine HAVE_STATFS 1
/* Define to 1 if you have the `statvfs' function. */
#cmakedefine HAVE_STATVFS 1
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
#cmakedefine HAVE_STAT_EMPTY_STRING_BUG 1
@ -492,34 +779,43 @@
/* Define to 1 if you have the `strrchr' function. */
#cmakedefine HAVE_STRRCHR 1
/* Define to 1 if `st_birthtime' is member of `struct stat'. */
/* Define to 1 if `f_namemax' is a member of `struct statfs'. */
#cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1
/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIME 1
/* Define to 1 if `st_birthtimespec.tv_nsec' is member of `struct stat'. */
/* Define to 1 if `st_birthtimespec.tv_nsec' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1
/* Define to 1 if `st_blksize' is member of `struct stat'. */
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_BLKSIZE 1
/* Define to 1 if `st_flags' is member of `struct stat'. */
/* Define to 1 if `st_flags' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_FLAGS 1
/* Define to 1 if `st_mtimespec.tv_nsec' is member of `struct stat'. */
/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
/* Define to 1 if `st_mtime_n' is member of `struct stat'. */
/* Define to 1 if `st_mtime_n' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_MTIME_N 1
/* Define to 1 if `st_mtime_usec' is member of `struct stat'. */
/* Define to 1 if `st_mtime_usec' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_MTIME_USEC 1
/* Define to 1 if `st_mtim.tv_nsec' is member of `struct stat'. */
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1
/* Define to 1 if `st_umtime' is member of `struct stat'. */
/* Define to 1 if `st_umtime' is a member of `struct stat'. */
#cmakedefine HAVE_STRUCT_STAT_ST_UMTIME 1
/* Define to 1 if you have the symlink() function. */
/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */
#cmakedefine HAVE_STRUCT_TM_TM_GMTOFF 1
/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */
#cmakedefine HAVE_STRUCT_TM___TM_GMTOFF 1
/* Define to 1 if you have the `symlink' function. */
#cmakedefine HAVE_SYMLINK 1
/* Define to 1 if you have the <sys/acl.h> header file. */
@ -532,6 +828,9 @@
*/
#cmakedefine HAVE_SYS_DIR_H 1
/* Define to 1 if you have the <sys/ea.h> header file. */
#cmakedefine HAVE_SYS_EA_H 1
/* Define to 1 if you have the <sys/extattr.h> header file. */
#cmakedefine HAVE_SYS_EXTATTR_H 1
@ -541,6 +840,9 @@
/* Define to 1 if you have the <sys/mkdev.h> header file. */
#cmakedefine HAVE_SYS_MKDEV_H 1
/* Define to 1 if you have the <sys/mount.h> header file. */
#cmakedefine HAVE_SYS_MOUNT_H 1
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#cmakedefine HAVE_SYS_NDIR_H 1
@ -554,6 +856,12 @@
/* Define to 1 if you have the <sys/select.h> header file. */
#cmakedefine HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/statfs.h> header file. */
#cmakedefine HAVE_SYS_STATFS_H 1
/* Define to 1 if you have the <sys/statvfs.h> header file. */
#cmakedefine HAVE_SYS_STATVFS_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#cmakedefine HAVE_SYS_STAT_H 1
@ -566,6 +874,12 @@
/* Define to 1 if you have the <sys/utime.h> header file. */
#cmakedefine HAVE_SYS_UTIME_H 1
/* Define to 1 if you have the <sys/utsname.h> header file. */
#cmakedefine HAVE_SYS_UTSNAME_H 1
/* Define to 1 if you have the <sys/vfs.h> header file. */
#cmakedefine HAVE_SYS_VFS_H 1
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#cmakedefine HAVE_SYS_WAIT_H 1
@ -581,9 +895,6 @@
/* Define to 1 if you have the `tzset' function. */
#cmakedefine HAVE_TZSET 1
/* Define to 1 if the system has the type `uintmax_t'. */
#cmakedefine HAVE_UINTMAX_T 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
@ -632,15 +943,24 @@
/* Define to 1 if you have the `wcslen' function. */
#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. */
#cmakedefine HAVE_WCTOMB 1
/* Define to 1 if you have the <wctype.h> header file. */
#cmakedefine HAVE_WCTYPE_H 1
/* Define to 1 if you have the <wincrypt.h> header file. */
#cmakedefine HAVE_WINCRYPT_H 1
/* Define to 1 if you have the <windows.h> header file. */
#cmakedefine HAVE_WINDOWS_H 1
/* Define to 1 if you have the <winioctl.h> header file. */
#cmakedefine HAVE_WINIOCTL_H 1
/* Define to 1 if you have _CrtSetReportMode in <crtdbg.h> */
#cmakedefine HAVE__CrtSetReportMode 1
@ -650,9 +970,30 @@
/* Define to 1 if you have the `wmemcpy' function. */
#cmakedefine HAVE_WMEMCPY 1
/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */
#cmakedefine HAVE_WORKING_EXT2_IOC_GETFLAGS 1
/* Define to 1 if you have the <zlib.h> header file. */
#cmakedefine HAVE_ZLIB_H 1
/* Define to 1 if you have the `_ctime64_s' function. */
#cmakedefine HAVE__CTIME64_S 1
/* Define to 1 if you have the `_fseeki64' function. */
#cmakedefine HAVE__FSEEKI64 1
/* Define to 1 if you have the `_get_timezone' function. */
#cmakedefine HAVE__GET_TIMEZONE 1
/* Define to 1 if you have the `_localtime64_s' function. */
#cmakedefine HAVE__LOCALTIME64_S 1
/* Define to 1 if you have the `_mkgmtime64' function. */
#cmakedefine HAVE__MKGMTIME64 1
/* Define as const if the declaration of iconv() needs const. */
#define ICONV_CONST ${ICONV_CONST}
/* Version number of libarchive as a single integer */
#cmakedefine LIBARCHIVE_VERSION_NUMBER "${LIBARCHIVE_VERSION_NUMBER}"
@ -683,6 +1024,33 @@
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#cmakedefine TIME_WITH_SYS_TIME 1
/*
* Some platform requires a macro to use extension functions.
*/
#cmakedefine SAFE_TO_DEFINE_EXTENSIONS 1
#ifdef SAFE_TO_DEFINE_EXTENSIONS
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
#endif /* SAFE_TO_DEFINE_EXTENSIONS */
/* Version number of package */
#cmakedefine VERSION "${VERSION}"
@ -695,10 +1063,9 @@
/* Define for large files, on AIX-style hosts. */
#cmakedefine _LARGE_FILES ${_LARGE_FILES}
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#cmakedefine _UINT64_T
/* Define for Windows to use Windows 2000+ APIs. */
#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
#cmakedefine WINVER ${WINVER}
/* Define to empty if `const' does not conform to ANSI C. */
#cmakedefine const ${const}
@ -709,17 +1076,6 @@
/* Define to `unsigned long' if <sys/types.h> does not define. */
#cmakedefine id_t ${id_t}
/* Define to `int' if <sys/types.h> doesn't define. */
#cmakedefine int32_t ${int32_t}
/* Define to the type of a signed integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
#cmakedefine int64_t ${int64_t}
/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
not define. */
#cmakedefine intmax_t ${intmax_t}
/* Define to `int' if <sys/types.h> does not define. */
#cmakedefine mode_t ${mode_t}
@ -738,20 +1094,6 @@
/* Define to `int' if <sys/types.h> doesn't define. */
#cmakedefine uid_t ${uid_t}
/* Define to `unsigned short' if <sys/types.h> doesn't define. */
#cmakedefine uint16_t ${uint16_t}
/* Define to `unsigned int' if <sys/types.h> doesn't define. */
#cmakedefine uint32_t ${uint32_t}
/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
#cmakedefine uint64_t ${uint64_t}
/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
do not define. */
#cmakedefine uintmax_t ${uintmax_t}
/* Define to `int' if <sys/types.h> does not define. */
#cmakedefine intptr_t ${intptr_t}

57
build/makerelease.sh Executable file
View File

@ -0,0 +1,57 @@
#!/bin/sh
#
# This script exists primarily to document some of the
# steps needed when building an "official libarchive distribution".
# Feel free to hack it up as necessary to adjust to the peculiarities
# of a particular build environment.
#
PATH=/usr/local/gnu-autotools/bin/:$PATH
export PATH
# Start from one level above the build directory
if [ -f version ]; then
cd ..
fi
if [ \! -f build/version ]; then
echo "Can't find source directory"
exit 1
fi
# BSD make's "OBJDIR" support freaks out the automake-generated
# Makefile. Effectively disable it.
export MAKEOBJDIRPREFIX=/junk
set -ex
#
# Scrub the local tree before running the build tests below.
#
/bin/sh build/clean.sh
#
# Verify the CMake-generated build
#
mkdir -p _cmtest
cd _cmtest
cmake ..
make
make test
cd ..
rm -rf _cmtest
# TODO: Build distribution using cmake
#
# Construct and verify the autoconf build system
#
/bin/sh build/autogen.sh
# Get the newest config.guess/config.sub from savannah.gnu.org
curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' > build/autoconf/config.guess
curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' > build/autoconf/config.sub
./configure
make distcheck
make dist-zip

View File

@ -6,5 +6,6 @@ includedir=@includedir@
Name: libarchive
Description: library that can create and read several streaming archive formats
Version: @VERSION@
Libs: -larchive
Cflags: -I${includedir}
Libs: -L${libdir} -larchive
Libs.private: @LIBS@

View File

@ -0,0 +1,418 @@
#!/bin/sh
#
# This needs http://unicode.org/Public/UNIDATA/UnicodeData.txt
#
inputfile="$1" # Expect UnicodeData.txt
outfile=archive_string_composition.h
pickout=/tmp/mk_unicode_composition_tbl$$.awk
#################################################################################
#
# Append the file header of "archive_string_composition.h"
#
#################################################################################
append_copyright()
{
cat > ${outfile} <<CR_END
/*-
* Copyright (c) 2011 libarchive Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* \$FreeBSD\$
*
*/
/*
* ATTENTION!
* This file is generated by build/utils/gen_archive_string_composition_h.sh
* from http://unicode.org/Public/UNIDATA/UnicodeData.txt
*
* See also http://unicode.org/report/tr15/
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
struct unicode_composition_table {
uint32_t cp1;
uint32_t cp2;
uint32_t nfc;
};
CR_END
}
#################################################################################
#
# awk script
#
#################################################################################
cat > ${pickout} <<AWK_END
#
BEGIN {
FS = ";"
min = "";
max = "";
cmd="sort | awk -F ' ' '{printf \"\\\\t{ 0x%s , 0x%s , 0x%s },\\\\n\",\$1,\$2,\$3}'"
print "static const struct unicode_composition_table u_composition_table[] = {"
}
END {
close(cmd)
print "};"
print ""
#
# Output Canonical Combining Class tables used for translating NFD to NFC.
#
printf "#define CANONICAL_CLASS_MIN\\t0x%s\\n", min
printf "#define CANONICAL_CLASS_MAX\\t0x%s\\n", max
print ""
printf "#define IS_DECOMPOSABLE_BLOCK(uc)\\t\\\\\n"
printf "\\t(((uc)>>8) <= 0x%X && u_decomposable_blocks[(uc)>>8])\\n", highnum
printf "static const char u_decomposable_blocks[0x%X+1] = {\\n\\t", highnum
#
# Output blockmap
for (i = 0; i <= highnum; i++) {
if (i != 0 && i % 32 == 0)
printf "\\n\\t"
# Additionally Hangul[11XX(17), AC00(172) - D7FF(215)] is decomposable.
if (blockmap[i] || i == 17 || (i >= 172 && i <= 215))
printf "1,"
else
printf "0,"
}
printf "\\n};\\n\\n"
#
# Output a macro to get a canonical combining class.
#
print "/* Get Canonical Combining Class(CCC). */"
printf "#define CCC(uc)\\t\\\\\n"
printf "\\t(((uc) > 0x%s)?0:\\\\\\n", max
printf "\\tccc_val[ccc_val_index[ccc_index[(uc)>>8]][((uc)>>4)&0x0F]][(uc)&0x0F])\\n"
print ""
#
# Output a canonical combining class value table.
#
midcnt = 0
printf "/* The table of the value of Canonical Cimbining Class */\\n"
print "static const unsigned char ccc_val[][16] = {"
print " /* idx=0: XXXX0 - XXXXF */"
print " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },"
for (h = 0; h <= highnum; h++) {
if (!blockmap[h])
continue;
for (m = 0; m < 16; m++) {
if (!xx_blockmap[h, m])
continue;
midcnt++
printf " /* idx=%d: %03X%1X0 - %03X%1XF */\\n {", midcnt, h, m, h, m
for (l = 0; l < 15; l++) {
printf "%d, ", xxx_blockmap[h, m, l]
}
printf "%d },\n", xxx_blockmap[h, m, 15]
}
}
printf "};\n"
#
# Output the index table of the canonical combining class value table.
#
cnt = 0
midcnt = 0
printf "\\n/* The index table to ccc_val[*][16] */\\n"
print "static const unsigned char ccc_val_index[][16] = {"
print " /* idx=0: XXX00 - XXXFF */"
print " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },"
for (h = 0; h <= highnum; h++) {
if (!blockmap[h])
continue;
cnt++
printf " /* idx=%d: %03X00 - %03XFF */\\n {", cnt, h, h
for (m = 0; m < 16; m++) {
if (m != 0)
printf ","
if (xx_blockmap[h, m]) {
midcnt++
printf "%2d", midcnt
} else
printf " 0"
}
printf " },\\n"
}
printf "};\\n"
#
# Output the index table to the index table of the canonical combining
# class value table.
#
printf "\\n/* The index table to ccc_val_index[*][16] */\\n"
printf "static const unsigned char ccc_index[] = {\\n ", h
cnt = 0
for (h = 0; h <= highnum; h++) {
if (h != 0 && h % 24 == 0)
printf "\\n "
if (blockmap[h]) {
cnt++;
printf "%2d,", cnt
} else
printf " 0,"
}
print "};"
print ""
print "#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */"
}
#
#
function hextoi(hex)
{
dec = 0
for (i=0; i < length(hex); i++) {
x = substr(hex, i+1, 1)
if (x ~/[0-9]/)
dec = dec * 16 + x;
else if (x == "A")
dec = dec * 16 + 10;
else if (x == "B")
dec = dec * 16 + 11;
else if (x == "C")
dec = dec * 16 + 12;
else if (x == "D")
dec = dec * 16 + 13;
else if (x == "E")
dec = dec * 16 + 14;
else if (x == "F")
dec = dec * 16 + 15;
}
return dec
}
#
# Collect Canonical Combining Class values.
#
\$4 ~/^[0-9A-F]+$/ {
if (\$4 !~/^0$/) {
if (min == "") {
min = \$1
}
max = \$1
high = substr(\$1, 1, length(\$1) -2)
highnum = hextoi(high)
mid = substr(\$1, length(\$1) -1, 1)
midnum = hextoi(mid)
low = substr(\$1, length(\$1), 1)
lownum = hextoi(low)
blockmap[highnum] = 1
xx_blockmap[highnum, midnum] = 1
xxx_blockmap[highnum, midnum, lownum] = \$4
}
}
#
# Following code points are not decomposed in MAC OS.
# U+2000 - U+2FFF
# U+F900 - U+FAFF
# U+2F800 - U+2FAFF
#
#\$1 ~/^2[0-9A-F][0-9A-F][0-9A-F]\$/ {
# next
#}
#\$1 ~/^F[9A][0-9A-F][0-9A-F]\$/ {
# next
#}
#\$1 ~/^2F[89A][0-9A-F][0-9A-F]\$/ {
# next
#}
#
# Exclusion code points specified by
# http://unicode.org/Public/UNIDATA/CompositionExclusions.txt
##
# 1. Script Specifices
##
\$1 ~/^095[89ABCDEF]\$/ {
next
}
\$1 ~/^09D[CDF]\$/ {
next
}
\$1 ~/^0A3[36]\$/ {
next
}
\$1 ~/^0A5[9ABE]\$/ {
next
}
\$1 ~/^0B5[CD]\$/ {
next
}
\$1 ~/^0F4[3D]\$/ {
next
}
\$1 ~/^0F5[27C]\$/ {
next
}
\$1 ~/^0F69\$/ {
next
}
\$1 ~/^0F7[68]\$/ {
next
}
\$1 ~/^0F9[3D]\$/ {
next
}
\$1 ~/^0FA[27C]\$/ {
next
}
\$1 ~/^0FB9\$/ {
next
}
\$1 ~/^FB1[DF]\$/ {
next
}
\$1 ~/^FB2[ABCDEF]\$/ {
next
}
\$1 ~/^FB3[012345689ABCE]\$/ {
next
}
\$1 ~/^FB4[01346789ABCDE]\$/ {
next
}
##
# 2. Post Composition Version precomposed characters
##
\$1 ~/^2ADC\$/ {
next
}
\$1 ~/^1D15[EF]\$/ {
next
}
\$1 ~/^1D16[01234]\$/ {
next
}
\$1 ~/^1D1B[BCDEF]\$/ {
next
}
\$1 ~/^1D1C0\$/ {
next
}
##
# 3. Singleton Decompositions
##
\$1 ~/^034[01]\$/ {
next
}
\$1 ~/^037[4E]\$/ {
next
}
\$1 ~/^0387\$/ {
next
}
\$1 ~/^1F7[13579BD]\$/ {
next
}
\$1 ~/^1FB[BE]\$/ {
next
}
\$1 ~/^1FC[9B]\$/ {
next
}
\$1 ~/^1FD[3B]\$/ {
next
}
\$1 ~/^1FE[3BEF]\$/ {
next
}
\$1 ~/^1FF[9BD]\$/ {
next
}
\$1 ~/^200[01]\$/ {
next
}
\$1 ~/^212[6AB]\$/ {
next
}
\$1 ~/^232[9A]\$/ {
next
}
\$1 ~/^F9[0-9A-F][0-9A-F]\$/ {
next
}
\$1 ~/^FA0[0-9A-D]\$/ {
next
}
\$1 ~/^FA1[025-9A-E]\$/ {
next
}
\$1 ~/^FA2[0256A-D]\$/ {
next
}
\$1 ~/^FA[3-5][0-9A-F]\$/ {
next
}
\$1 ~/^FA6[0-9A-D]\$/ {
next
}
\$1 ~/^FA[7-9A-C][0-9A-F]\$/ {
next
}
\$1 ~/^FAD[0-9]\$/ {
next
}
\$1 ~/^2F[89][0-9A-F][0-9A-F]\$/ {
next
}
\$1 ~/^2FA0[0-9A-F]\$/ {
next
}
\$1 ~/^2FA1[0-9A-D]\$/ {
next
}
##
# 4. Non-Starter Decompositions
##
\$1 ~/^0344\$/ {
next
}
\$1 ~/^0F7[35]\$/ {
next
}
\$1 ~/^0F81\$/ {
next
}
#
# Output combinations for NFD ==> NFC.
#
\$6 ~/^[0-9A-F]+ [0-9A-F]+\$/ {
split(\$6, cp, " ")
if (length(\$1) == 4)
print "0"cp[1], "0"cp[2], "0"\$1 | cmd
else
print cp[1], cp[2], \$1 | cmd
}
AWK_END
#################################################################################
#
# Run awk a script.
#
#################################################################################
append_copyright
awk -f ${pickout} ${inputfile} >> ${outfile}
#
# Remove awk the script.
rm ${pickout}

View File

@ -1 +1 @@
2008005
3000003

View File

@ -4,18 +4,20 @@ dnl First, define all of the version numbers up front.
dnl In particular, this allows the version macro to be used in AC_INIT
dnl These first two version numbers are updated automatically on each release.
m4_define([LIBARCHIVE_VERSION_S],[2.8.5])
m4_define([LIBARCHIVE_VERSION_N],[2008005])
m4_define([LIBARCHIVE_VERSION_S],[3.0.3])
m4_define([LIBARCHIVE_VERSION_N],[3000003])
dnl bsdtar and bsdcpio versioning tracks libarchive
m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S())
m4_define([BSDCPIO_VERSION_S],LIBARCHIVE_VERSION_S())
AC_PREREQ(2.65)
#
# Now starts the "real" configure script.
#
AC_INIT([libarchive],LIBARCHIVE_VERSION_S(),[kientzle@freebsd.org])
AC_INIT([libarchive],LIBARCHIVE_VERSION_S(),[kientzle@FreeBSD.org])
# Make sure the srcdir contains "libarchive" directory
AC_CONFIG_SRCDIR([libarchive])
# Use auxiliary subscripts from this subdirectory (cleans up root)
@ -25,15 +27,21 @@ AC_CONFIG_MACRO_DIR([build/autoconf])
# Must follow AC_CONFIG macros above...
AM_INIT_AUTOMAKE()
# Libtool versioning uses different conventions on different
# platforms. At least on FreeBSD, libtool uses an overly complex
# convention that attempts to solve problems that most people just
# don't have and which just causes confusion for most end users.
ARCHIVE_MAJOR=$(( LIBARCHIVE_VERSION_N() / 1000000 ))
# Libtool's "interface version" can be computed from the libarchive version.
# Libtool interface version bumps on any API change, so increments
# whenever libarchive minor version does.
ARCHIVE_MINOR=$(( (LIBARCHIVE_VERSION_N() / 1000) % 1000 ))
# Libarchive 2.7 == libtool interface 9 = 2 + 7
# Libarchive 2.8 == libtool interface 10 = 2 + 8
# Libarchive 2.9 == libtool interface 11 = 2 + 8
# Libarchive 3.0 == libtool interface 12
# Libarchive 3.x == libtool interface 12 + x
ARCHIVE_INTERFACE=`echo $((12 + ${ARCHIVE_MINOR}))`
# Libarchive revision is bumped on any source change === libtool revision
ARCHIVE_REVISION=$(( LIBARCHIVE_VERSION_N() % 1000 ))
ARCHIVE_LIBTOOL_MAJOR=`echo $((${ARCHIVE_MAJOR} + ${ARCHIVE_MINOR}))`
ARCHIVE_LIBTOOL_VERSION=$ARCHIVE_LIBTOOL_MAJOR:$ARCHIVE_REVISION:$ARCHIVE_MINOR
# Libarchive minor is bumped on any interface addition === libtool age
ARCHIVE_LIBTOOL_VERSION=$ARCHIVE_INTERFACE:$ARCHIVE_REVISION:$ARCHIVE_MINOR
# Stick the version numbers into config.h
AC_DEFINE([LIBARCHIVE_VERSION_STRING],"LIBARCHIVE_VERSION_S()",
@ -189,17 +197,47 @@ case $host in
;;
esac
# We need CoreServices on Mac OS.
case $host in
*darwin* )
LIBS="${LIBS} -framework CoreServices"
;;
esac
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([acl/libacl.h attr/xattr.h ctype.h errno.h])
AC_CHECK_HEADERS([ext2fs/ext2_fs.h fcntl.h grp.h])
AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h linux/fs.h])
AC_CHECK_HEADERS([acl/libacl.h attr/xattr.h copyfile.h ctype.h])
AC_CHECK_HEADERS([errno.h ext2fs/ext2_fs.h fcntl.h grp.h])
AC_CACHE_CHECK([whether EXT2_IOC_GETFLAGS is usable],
[ac_cv_have_decl_EXT2_IOC_GETFLAGS],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <sys/ioctl.h>
@%:@include <ext2fs/ext2_fs.h>],
[int x = EXT2_IOC_GETFLAGS])],
[AS_VAR_SET([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes])],
[AS_VAR_SET([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [no])])])
AS_VAR_IF([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes],
[AC_DEFINE_UNQUOTED([HAVE_WORKING_EXT2_IOC_GETFLAGS], [1],
[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([linux/fiemap.h linux/fs.h linux/magic.h])
AC_CHECK_HEADERS([locale.h paths.h poll.h pwd.h regex.h signal.h stdarg.h])
AC_CHECK_HEADERS([stdint.h stdlib.h string.h])
AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h sys/ioctl.h sys/mkdev.h])
AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/time.h sys/utime.h])
AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h windows.h])
AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h sys/ioctl.h])
AC_CHECK_HEADERS([sys/mkdev.h sys/mount.h])
AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/statfs.h sys/statvfs.h])
AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h])
AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h])
AC_CHECK_HEADERS([windows.h])
# check windows.h first; the other headers require it.
AC_CHECK_HEADERS([wincrypt.h winioctl.h],[],[],
[[#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
]])
# Checks for libraries.
AC_ARG_WITH([zlib],
@ -226,6 +264,25 @@ if test "x$with_lzmadec" != "xno"; then
AC_CHECK_LIB(lzmadec,lzmadec_decode)
fi
AC_ARG_WITH([iconv],
AS_HELP_STRING([--without-iconv], [Don't try to link against iconv]))
if test "x$with_iconv" != "xno"; then
AC_CHECK_HEADERS([iconv.h],[],[],[#include <stdlib.h>])
AM_ICONV
if test "x$am_cv_func_iconv" = "xyes"; then
AC_CHECK_HEADERS([localcharset.h])
am_save_LIBS="$LIBS"
LIBS="${LIBS} ${LIBICONV}"
AC_CHECK_FUNCS([locale_charset])
LIBS="${am_save_LIBS}"
if test "x$ac_cv_func_locale_charset" != "xyes"; then
# If locale_charset() is not in libiconv, we have to find libcharset.
AC_CHECK_LIB(charset,locale_charset)
fi
fi
fi
AC_ARG_WITH([lzma],
AS_HELP_STRING([--without-lzma], [Don't build support for xz through lzma]))
@ -234,8 +291,13 @@ if test "x$with_lzma" != "xno"; then
AC_CHECK_LIB(lzma,lzma_stream_decoder)
fi
AC_ARG_WITH([nettle],
AS_HELP_STRING([--without-nettle], [Don't build with crypto support from Nettle]))
AC_ARG_WITH([openssl],
AS_HELP_STRING([--without-openssl], [Don't build support for mtree and xar hashes through openssl]))
case "$host_os" in
*darwin* ) with_openssl=no ;;
esac
AC_ARG_WITH([xml2],
AS_HELP_STRING([--without-xml2], [Don't build support for xar through libxml2]))
@ -247,9 +309,11 @@ if test "x$with_xml2" != "xno"; then
if test "x$XML2_CONFIG" != "x"; then
CPPFLAGS="${CPPFLAGS} `${XML2_CONFIG} --cflags`"
LIBS="${LIBS} `${XML2_CONFIG} --libs`"
AC_CHECK_LIB(xml2,xmlInitParser,[true],AC_MSG_FAILURE(Missing xml2 library))
else
AC_CHECK_LIB(xml2,xmlInitParser)
fi
AC_CHECK_HEADERS([libxml/xmlreader.h])
AC_CHECK_LIB(xml2,xmlInitParser)
AC_CHECK_HEADERS([libxml/xmlreader.h libxml/xmlwriter.h])
fi
if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then
if test "x$with_expat" != "xno"; then
@ -258,72 +322,6 @@ if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then
fi
fi
AC_DEFUN([MD_CHECK], [
if test "$found_$1" != yes; then
saved_LIBS="$LIBS"
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -I$srcdir/libarchive"
if test $ac_cv_header_sys_types_h = yes; then
CPPFLAGS="$CPPFLAGS -DHAVE_SYS_TYPES_H=1"
fi
LIBS="$LIBS $4"
AC_MSG_CHECKING([support for ARCHIVE_HASH_$1_$2])
AC_LINK_IFELSE([
#define $1_COMPILE_TEST
#define ARCHIVE_HASH_$1_$2
#define __LIBARCHIVE_BUILD
#include "archive_hash.h"
int
main(int argc, char **argv)
{
archive_$3_ctx ctx;
archive_$3_init(&ctx);
archive_$3_update(&ctx, *argv, argc);
archive_$3_final(&ctx, *argv);
return 0;
}
],
[ AC_MSG_RESULT([yes])
found_$1=yes
mdLIBS="$mdLIBS $4"
AC_DEFINE(ARCHIVE_HASH_$1_$2, 1, [ $1 via ARCHIVE_HASH_$1_$2 supported.])
],
[ AC_MSG_RESULT([no])])
LIBS="$saved_LIBS"
CPPFLAGS="$saved_CPPFLAGS"
fi
])
MD_CHECK(MD5, LIBC, md5)
MD_CHECK(MD5, LIBSYSTEM, md5)
MD_CHECK(RMD160, LIBC, rmd160)
MD_CHECK(SHA1, LIBC, sha1)
MD_CHECK(SHA1, LIBSYSTEM, sha1)
MD_CHECK(SHA256, LIBC, sha256)
MD_CHECK(SHA256, LIBC2, sha256)
MD_CHECK(SHA256, LIBC3, sha256)
MD_CHECK(SHA256, LIBSYSTEM, sha256)
MD_CHECK(SHA384, LIBC, sha384)
MD_CHECK(SHA384, LIBC2, sha384)
MD_CHECK(SHA384, LIBC3, sha384)
MD_CHECK(SHA384, LIBSYSTEM, sha384)
MD_CHECK(SHA512, LIBC, sha512)
MD_CHECK(SHA512, LIBC2, sha512)
MD_CHECK(SHA512, LIBC3, sha512)
MD_CHECK(SHA512, LIBSYSTEM, sha512)
if test "x$with_openssl" != "xno"; then
MD_CHECK(MD5, OPENSSL, md5, -lcrypto)
MD_CHECK(RMD160, OPENSSL, rmd160, -lcrypto)
MD_CHECK(SHA1, OPENSSL, sha1, -lcrypto)
MD_CHECK(SHA256, OPENSSL, sha256, -lcrypto)
MD_CHECK(SHA384, OPENSSL, sha384, -lcrypto)
MD_CHECK(SHA512, OPENSSL, sha512, -lcrypto)
fi
LIBS="$LIBS $mdLIBS"
# TODO: Give the user the option of using a pre-existing system
# libarchive. This will define HAVE_LIBARCHIVE which will cause
# bsdtar_platform.h to use #include <...> for the libarchive headers.
@ -344,6 +342,19 @@ AC_TYPE_SIZE_T
AC_CHECK_TYPE(id_t, [unsigned long])
AC_CHECK_TYPE(uintptr_t, [unsigned int])
# Check for tm_gmtoff in struct tm
AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,,
[
#include <time.h>
])
# Check for f_namemax in struct statfs
AC_CHECK_MEMBERS([struct statfs.f_namemax],,,
[
#include <sys/param.h>
#include <sys/mount.h>
])
# Check for birthtime in struct stat
AC_CHECK_MEMBERS([struct stat.st_birthtime])
@ -364,14 +375,24 @@ AC_CHECK_MEMBERS([struct stat.st_flags])
# TODO: Check for %ju and %llu support directly.
AC_CHECK_TYPES([uintmax_t, unsigned long long])
# We need int64_t, uint64_t, intmax_t, and uintmax_t
# We use C99-style integer types
# Declare them if the local platform doesn't already do so.
AC_TYPE_INTMAX_T
AC_TYPE_INT64_T
AC_TYPE_UINTMAX_T
AC_TYPE_INT64_T
AC_TYPE_UINT64_T
AC_TYPE_INT32_T
AC_TYPE_UINT32_T
AC_TYPE_INT16_T
AC_TYPE_UINT16_T
AC_TYPE_UINT8_T
# TODO: If any of these are missing, define them right here.
AC_CHECK_DECLS([SIZE_MAX, SSIZE_MAX, INT64_MAX, INT64_MIN, UINT64_MAX, UINT32_MAX])
AC_CHECK_DECLS([SIZE_MAX, INT64_MAX, INT64_MIN, UINT64_MAX, UINT32_MAX])
AC_CHECK_DECL([SSIZE_MAX],
[AC_DEFINE(HAVE_DECL_SSIZE_MAX, 1, [Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you don't.])],
[],
[#include <limits.h>])
AC_CHECK_DECL([EFTYPE],
[AC_DEFINE(HAVE_EFTYPE, 1, [A possible errno value for invalid file format errors])],
@ -403,20 +424,34 @@ AC_FUNC_VPRINTF
# To avoid necessity for including windows.h or special forward declaration
# workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *'
AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *])
AC_CHECK_FUNCS([chflags chown chroot])
AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fork])
AC_CHECK_FUNCS([fstat ftruncate futimens futimes geteuid getpid])
AC_CHECK_FUNCS([getgrgid_r getgrnam_r getpwnam_r getpwuid_r ])
AC_CHECK_FUNCS([lchflags lchmod lchown link lstat])
AC_CHECK_FUNCS([lutimes memmove memset mkdir mkfifo mknod])
AC_CHECK_FUNCS([nl_langinfo pipe poll readlink])
AC_CHECK_FUNCS([select setenv setlocale sigaction])
AC_CHECK_FUNCS([chflags chown chroot ctime_r])
AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fork])
AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate])
AC_CHECK_FUNCS([futimens futimes futimesat])
AC_CHECK_FUNCS([geteuid getpid getgrgid_r getgrnam_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([mbrtowc mbsnrtowcs memmove memset])
AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp])
AC_CHECK_FUNCS([nl_langinfo openat pipe poll readlink readlinkat])
AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs])
AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm])
AC_CHECK_FUNCS([tzset unsetenv utime utimensat utimes vfork])
AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy])
AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wcsnrtombs wctomb wmemcmp wmemcpy])
AC_CHECK_FUNCS([_ctime64_s _fseeki64])
AC_CHECK_FUNCS([_get_timezone _localtime64_s _mkgmtime64])
# detects cygwin-1.7, as opposed to older versions
AC_CHECK_FUNCS([cygwin_conv_path])
# There are several variants of readdir_r around; we only
# accept the POSIX-compliant version.
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[#include <dirent.h>]],
[[DIR *dir; struct dirent e, *r;
return(readdir_r(dir, &e, &r));]])],
[AC_DEFINE(HAVE_READDIR_R,1,[Define to 1 if you have a POSIX compatible readdir_r])]
)
# FreeBSD's nl_langinfo supports an option to specify whether the
# current locale uses month/day or day/month ordering. It makes the
# output a little prettier...
@ -444,12 +479,14 @@ AC_ARG_ENABLE([xattr],
if test "x$enable_xattr" != "xno"; then
AC_CHECK_HEADERS([attr/xattr.h])
AC_CHECK_HEADERS([sys/xattr.h])
AC_CHECK_HEADERS([sys/xattr.h sys/ea.h])
AC_CHECK_LIB(attr,setxattr)
AC_CHECK_FUNCS([extattr_get_file extattr_list_file])
AC_CHECK_FUNCS([extattr_set_fd extattr_set_file])
AC_CHECK_FUNCS([fsetxattr getxattr])
AC_CHECK_FUNCS([fgetxattr flistxattr fsetxattr getxattr])
AC_CHECK_FUNCS([lgetxattr listxattr llistxattr lsetxattr])
AC_CHECK_FUNCS([fgetea flistea fsetea getea])
AC_CHECK_FUNCS([lgetea listea llistea lsetea])
AC_CHECK_DECLS([EXTATTR_NAMESPACE_USER], [], [], [#include <sys/types.h>
#include <sys/extattr.h>
])
@ -505,4 +542,91 @@ fi
# Additional requirements
AC_SYS_LARGEFILE
dnl NOTE: Crypto checks must run last.
AC_DEFUN([CRYPTO_CHECK], [
if test "$found_$1" != yes; then
saved_LIBS="$LIBS"
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive"
LIBS="$LIBS $mdLIBS $4"
touch "check_crypto_md.h"
AC_MSG_CHECKING([support for ARCHIVE_CRYPTO_$1_$2])
AC_LINK_IFELSE([AC_LANG_SOURCE([
#define ARCHIVE_$1_COMPILE_TEST
#define ARCHIVE_CRYPTO_$1_$2
#define PLATFORM_CONFIG_H "check_crypto_md.h"
$(cat "$srcdir/libarchive/archive_crypto.c")
int
main(int argc, char **argv)
{
archive_$3_ctx ctx;
archive_$3_init(&ctx);
archive_$3_update(&ctx, *argv, argc);
archive_$3_final(&ctx, NULL);
return 0;
}
])],
[ AC_MSG_RESULT([yes])
found_$1=yes
if [[ -n "$4" ]]; then
# The .$4 avoids -e, which doesn't work on Solaris 10
# The _$mdLIBS allows .$4 to match at beginning of string <sigh>
test -n "$(echo _$mdLIBS | $GREP .$4)" || mdLIBS="$mdLIBS $4"
fi
AC_DEFINE(ARCHIVE_CRYPTO_$1_$2, 1, [ $1 via ARCHIVE_CRYPTO_$1_$2 supported.])
],
[ AC_MSG_RESULT([no])])
LIBS="$saved_LIBS"
CPPFLAGS="$saved_CPPFLAGS"
rm "check_crypto_md.h"
fi
])
CRYPTO_CHECK(MD5, LIBC, md5)
CRYPTO_CHECK(MD5, LIBSYSTEM, md5)
CRYPTO_CHECK(RMD160, LIBC, rmd160)
CRYPTO_CHECK(SHA1, LIBC, sha1)
CRYPTO_CHECK(SHA1, LIBSYSTEM, sha1)
CRYPTO_CHECK(SHA256, LIBC, sha256)
CRYPTO_CHECK(SHA256, LIBC2, sha256)
CRYPTO_CHECK(SHA256, LIBC3, sha256)
CRYPTO_CHECK(SHA256, LIBSYSTEM, sha256)
CRYPTO_CHECK(SHA384, LIBC, sha384)
CRYPTO_CHECK(SHA384, LIBC2, sha384)
CRYPTO_CHECK(SHA384, LIBC3, sha384)
CRYPTO_CHECK(SHA384, LIBSYSTEM, sha384)
CRYPTO_CHECK(SHA512, LIBC, sha512)
CRYPTO_CHECK(SHA512, LIBC2, sha512)
CRYPTO_CHECK(SHA512, LIBC3, sha512)
CRYPTO_CHECK(SHA512, LIBSYSTEM, sha512)
if test "x$with_nettle" != "xno"; then
CRYPTO_CHECK(MD5, NETTLE, md5, -lnettle)
CRYPTO_CHECK(RMD160, NETTLE, rmd160, -lnettle)
CRYPTO_CHECK(SHA1, NETTLE, sha1, -lnettle)
CRYPTO_CHECK(SHA256, NETTLE, sha256, -lnettle)
CRYPTO_CHECK(SHA384, NETTLE, sha384, -lnettle)
CRYPTO_CHECK(SHA512, NETTLE, sha512, -lnettle)
fi
if test "x$with_openssl" != "xno"; then
CRYPTO_CHECK(MD5, OPENSSL, md5, -lcrypto)
CRYPTO_CHECK(RMD160, OPENSSL, rmd160, -lcrypto)
CRYPTO_CHECK(SHA1, OPENSSL, sha1, -lcrypto)
CRYPTO_CHECK(SHA256, OPENSSL, sha256, -lcrypto)
CRYPTO_CHECK(SHA384, OPENSSL, sha384, -lcrypto)
CRYPTO_CHECK(SHA512, OPENSSL, sha512, -lcrypto)
fi
# Probe libmd AFTER OpenSSL/libcrypto.
# The two are incompatible and OpenSSL is more complete.
CRYPTO_CHECK(MD5, LIBMD, md5, -lmd)
CRYPTO_CHECK(RMD160, LIBMD, rmd160, -lmd)
CRYPTO_CHECK(SHA1, LIBMD, sha1, -lmd)
CRYPTO_CHECK(SHA256, LIBMD, sha256, -lmd)
CRYPTO_CHECK(SHA512, LIBMD, sha512, -lmd)
LIBS="$LIBS $mdLIBS"
AC_OUTPUT

View File

@ -1,5 +1,6 @@
Many people have graciously sent me configuration
files and other useful tidbits for use with libarchive.
files, small programs that use libarchive, and other
useful and interesting tidbits.
I do not support or use any of these; but if you can use them, enjoy!
@ -30,3 +31,29 @@ libarchive.1aix53.spec
As above, for use on AIX5.3.
======================================================================
psota-benchmark
Some scripts used by Jan Psota in benchmarking
various tar implementations.
I've edited his results slightly to correctly reflect that
bsdtar does not support a "compare" operation.
======================================================================
shar
A simple shar program written on top of libarchive.
======================================================================
untar.c
A very simple and very portable standalone program that can
extract basic ustar archives.
This does not use libarchive and so can be used to extract
the libarchive distribution on any system that has a C compiler
but does not have a tar program.
======================================================================

View File

@ -1,4 +1,4 @@
# $LastChangedRevision: 8 $, $LastChangedDate: 2008-05-01 00:11:33 +0200 (št , 01 máj 2008) $
# $LastChangedRevision$, $LastChangedDate$
Summary: Library to create and read several different archive formats
Summary(pl): Biblioteka do tworzenia i odczytu ró¿nych formatów archiwów
Name: libarchive
@ -140,7 +140,7 @@ Revision 1.6 2006/11/15 10:41:28 qboosh
Revision 1.5 2006/11/08 22:22:25 twittner
- up to 1.3.1
- added BR: e2fsprogs-devel
- added -CVE-2006-5680.patch agains entering in infinite
- added -CVE-2006-5680.patch against entering an infinite
loop in corrupt archives
- added bsdtar package (bsdtar is included now in libarchive
sources)

View File

@ -1,4 +1,4 @@
# $LastChangedRevision: 8 $, $LastChangedDate: 2008-05-01 00:11:33 +0200 (št , 01 máj 2008) $
# $LastChangedRevision$, $LastChangedDate$
Summary: Library to create and read several different archive formats
Summary(pl): Biblioteka do tworzenia i odczytu ró¿nych formatów archiwów
Name: libarchive
@ -127,7 +127,7 @@ Revision 1.6 2006/11/15 10:41:28 qboosh
Revision 1.5 2006/11/08 22:22:25 twittner
- up to 1.3.1
- added BR: e2fsprogs-devel
- added -CVE-2006-5680.patch agains entering in infinite
- added -CVE-2006-5680.patch against entering an infinite
loop in corrupt archives
- added bsdtar package (bsdtar is included now in libarchive
sources)

View File

@ -1,4 +1,4 @@
ODP: [Bug-tar] GNU tar, star and BSD tar speed comparision +new script
ODP: [Bug-tar] GNU tar, star and BSD tar speed comparison +new script
Jan Psota
Thu, 25 Oct 2007 06:51:13 -0700
@ -120,3 +120,17 @@ star extract 100.814 0.400 39.906 39.98 20849 KB/s
bsdtar compare 0.003 0.000 0.004 100.00 700657000 KB/s
gnutar compare 80.174 3.932 20.365 30.30 26217 KB/s
star compare 73.911 8.341 27.670 48.72 28439 KB/s
=============================================================
Note by Tim Kientzle: The "bsdtar compare" results here are
invalid since bsdtar does not support that operation.
For the list numbers, note that libarchive automatically optimizes
list operations on uncompressed tar archives on disk by using lseek()
to skip over the bodies of entries. GNU tar added an option to
provide the same feature.
The biggest problem with these tests is that they only
cover uncompressed archives stored on disk. The results for
compressed archives and/or archives stored on tape are
likely quite different.

View File

@ -1,9 +1,9 @@
#!/bin/sh
# tar comparision program
# tar comparison program
# 2007-10-25 Jan Psota
n=3 # number of repetitions
TAR=(bsdtar gnutar star) # TApeArchivers to compare
TAR="bsdtar gnutar star" # Tape archivers to compare
OPT=("" "--seek" "-no-fsync")
pax="--format=pax" # comment out for defaults
OPN=(create list extract compare) # operations
@ -16,9 +16,9 @@ test $# -ge 2 || {
[where_to_extract_it]
TCP, version $version
TCP stands for Tar Comparision Program here.
TCP stands for Tar Comparison Program here.
It currently compares: BSD tar (bsdtar), GNU tar (gnutar) and star in archive
creation, listing, extraction and archive-to-extracted comparision.
creation, listing, extraction and archive-to-extracted comparison.
Tcp prints out best time of n=$n repetitions.
Tcp creates temporary archive named tcp.tar with $pax and some native
@ -60,15 +60,21 @@ test -e /etc/gentoo-release \
&& gcc --version | head -1 && grep ^CFLAGS /etc/make.conf
# tar versions
t=
echo
for tar in [EMAIL PROTECTED]; do echo -ne "$tar:\t"; $tar --version | head -1;
for tar in $TAR; do
if which $tar &> /dev/null; then
t="$t $tar";
echo -ne "$tar:\t"; $tar --version | head -1;
fi
done
TAR="$t"
echo -e "\nbest time of $n repetitions,\n"\
" src=$src, "\
`du -sh $src | awk '{print $1}'`" in "`find $src | wc -l`" files, "\
"avg "$((`du -sk $src | awk '{print $1}'`/`find $src -type f | wc
-l`))"KB/file,\n"\
"avg "$((`du -sk $src | awk '{print $1}'`/`find $src -type f | wc -l`))"KB/file,\n"\
" archive=$dst, extract to $dst_path"
echo -e "program\toperation\treal\tuser\tsystem\t%CPU\t speed"
@ -77,7 +83,7 @@ let op_num=0
for op in "cf $dst $pax -C $src ." "tf $dst" "xf $dst -C $dst_path" \
"f $dst -C $dst_path --diff"; do
let tar_num=0
for tar in [EMAIL PROTECTED]; do
for tar in $TAR; do
echo -en "$tar\t${OPN[op_num]}\t"
for ((i=1; i<=$n; i++)); do
echo $op | grep -q ^cf && rm -f $dst

View File

@ -269,7 +269,7 @@ shar_write(char **fn, size_t nfn)
}
}
if (archive_write_finish(a) != ARCHIVE_OK)
if (archive_write_free(a) != ARCHIVE_OK)
errx(EXIT_FAILURE, "%s", archive_error_string(a));
if (error != 0)

View File

@ -38,7 +38,7 @@ parseoct(const char *p, size_t n)
{
int i = 0;
while (*p < '0' || *p > '7') {
while ((*p < '0' || *p > '7') && n > 0) {
++p;
--n;
}
@ -140,7 +140,7 @@ untar(FILE *a, const char *path)
if (bytes_read < 512) {
fprintf(stderr,
"Short read on %s: expected 512, got %d\n",
path, bytes_read);
path, (int)bytes_read);
return;
}
if (is_end_of_archive(buff)) {
@ -183,7 +183,7 @@ untar(FILE *a, const char *path)
if (bytes_read < 512) {
fprintf(stderr,
"Short read on %s: Expected 512, got %d\n",
path, bytes_read);
path, (int)bytes_read);
return;
}
if (filesize < 512)

View File

@ -24,8 +24,8 @@
.\"
.\" $FreeBSD$
.\"
.Dd September 5, 2010
.Dt BSDCPIO 1
.Dd December 21, 2007
.Dt CPIO 1
.Os
.Sh NAME
.Nm cpio
@ -59,7 +59,7 @@ is a mode indicator from the following list:
.Bl -tag -compact -width indent
.It Fl i
Input.
Read an archive from standard input (unless overriden) and extract the
Read an archive from standard input (unless overridden) and extract the
contents to disk or (if the
.Fl t
option is specified)
@ -69,7 +69,7 @@ one of the patterns will be extracted.
.It Fl o
Output.
Read a list of filenames from standard input and produce a new archive
on standard output (unless overriden) containing the specified items.
on standard output (unless overridden) containing the specified items.
.It Fl p
Pass-through.
Read a list of filenames from standard input and copy the files to the
@ -80,7 +80,7 @@ specified directory.
Unless specifically stated otherwise, options are applicable in
all operating modes.
.Bl -tag -width indent
.It Fl 0
.It Fl 0 , Fl Fl null
Read filenames separated by NUL characters instead of newlines.
This is necessary if any of the filenames being read might contain newlines.
.It Fl A
@ -102,8 +102,8 @@ bytes.
(o mode only)
Use the old POSIX portable character format.
Equivalent to
.Fl -format Ar odc .
.It Fl d
.Fl Fl format Ar odc .
.It Fl d , Fl Fl make-directories
(i and p modes)
Create directories as necessary.
.It Fl E Ar file
@ -111,14 +111,14 @@ Create directories as necessary.
Read list of file name patterns from
.Ar file
to list and extract.
.It Fl F Ar file
.It Fl F Ar file , Fl Fl file Ar file
Read archive from or write archive to
.Ar file .
.It Fl f Ar pattern
(i mode only)
Ignore files that match
.Ar pattern .
.It Fl -format Ar format
.It Fl H Ar format , Fl Fl format Ar format
(o mode only)
Produce the output archive in the specified format.
Supported formats include:
@ -145,24 +145,21 @@ for more complete information about the
formats currently supported by the underlying
.Xr libarchive 3
library.
.It Fl H Ar format
Synonym for
.Fl -format .
.It Fl h , Fl -help
.It Fl h , Fl Fl help
Print usage information.
.It Fl I Ar file
Read archive from
.Ar file .
.It Fl i
.It Fl i , Fl Fl extract
Input mode.
See above for description.
.It Fl -insecure
.It Fl Fl insecure
(i and p mode only)
Disable security checks during extraction or copying.
This allows extraction via symbolic links and path names containing
.Sq ..
in the name.
.It Fl J
.It Fl J , Fl Fl xz
(o mode only)
Compress the file with xz-compatible compression before writing it.
In input mode, this option is ignored; xz compression is recognized
@ -175,20 +172,20 @@ Synonym for
All symbolic links will be followed.
Normally, symbolic links are archived and copied as symbolic links.
With this option, the target of the link will be archived or copied instead.
.It Fl l
.It Fl l , Fl Fl link
(p mode only)
Create links from the target directory to the original files,
instead of copying.
.It Fl lzma
.It Fl Fl lzma
(o mode only)
Compress the file with lzma-compatible compression before writing it.
In input mode, this option is ignored; lzma compression is recognized
automatically on input.
.It Fl m
.It Fl m , Fl Fl preserve-modification-time
(i and p modes)
Set file modification time on created files to match
those in the source.
.It Fl n
.It Fl n , Fl Fl numeric-uid-gid
(i mode, only with
.Fl t )
Display numeric uid and gid.
@ -197,26 +194,26 @@ By default,
displays the user and group names when they are provided in the
archive, or looks up the user and group names in the system
password database.
.It Fl no-preserve-owner
.It Fl Fl no-preserve-owner
(i mode only)
Do not attempt to restore file ownership.
This is the default when run by non-root users.
.It Fl O Ar file
Write archive to
.Ar file .
.It Fl o
.It Fl o , Fl Fl create
Output mode.
See above for description.
.It Fl p
.It Fl p , Fl Fl pass-through
Pass-through mode.
See above for description.
.It Fl preserve-owner
.It Fl Fl preserve-owner
(i mode only)
Restore file ownership.
This is the default when run by the root user.
.It Fl -quiet
.It Fl Fl quiet
Suppress unnecessary messages.
.It Fl R Oo user Oc Ns Oo : Oc Ns Oo group Oc
.It Fl R Oo user Oc Ns Oo : Oc Ns Oo group Oc , Fl Fl owner Oo user Oc Ns Oo : Oc Ns Oo group Oc
Set the owner and/or group on files in the output.
If group is specified with no user
(for example,
@ -244,20 +241,24 @@ containing the name of the file and a line is read from
If the line read is blank, the file is skipped.
If the line contains a single period, the file is processed normally.
Otherwise, the line is taken to be the new name of the file.
.It Fl t
.It Fl t , Fl Fl list
(i mode only)
List the contents of the archive to stdout;
do not restore the contents to disk.
.It Fl u
.It Fl u , Fl Fl unconditional
(i and p modes)
Unconditionally overwrite existing files.
Ordinarily, an older file will not overwrite a newer file on disk.
.It Fl v
.It Fl V , Fl Fl dot
Print a dot to stderr for each file as it is processed.
Superseded by
.Fl v .
.It Fl v , Fl Fl verbose
Print the name of each file to stderr as it is processed.
With
.Fl t ,
provide a detailed listing of each file.
.It Fl -version
.It Fl Fl version
Print the program version information and exit.
.It Fl y
(o mode only)
@ -275,6 +276,8 @@ Compress the archive with gzip-compatible compression before writing it.
In input mode, this option is ignored;
gzip compression is recognized automatically on input.
.El
.Sh EXIT STATUS
.Ex -std
.Sh ENVIRONMENT
The following environment variables affect the execution of
.Nm :
@ -290,8 +293,6 @@ See
.Xr environ 7
for more information.
.El
.Sh EXIT STATUS
.Ex -std
.Sh EXAMPLES
The
.Nm

View File

@ -51,7 +51,7 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cmdline.c,v 1.5 2008/12/06 07:30:40 kientzl
/*
* Short options for cpio. Please keep this sorted.
*/
static const char *short_options = "0AaBC:cdE:F:f:H:hI:iJjLlmnO:opR:rtuvW:yZz";
static const char *short_options = "0AaBC:cdE:F:f:H:hI:iJjLlmnO:opR:rtuVvW:yZz";
/*
* Long options for cpio. Please keep this sorted.
@ -62,6 +62,7 @@ static const struct option {
int equivalent; /* Equivalent short option. */
} cpio_longopts[] = {
{ "create", 0, 'o' },
{ "dot", 0, 'V' },
{ "extract", 0, 'i' },
{ "file", 1, 'F' },
{ "format", 1, 'H' },
@ -109,7 +110,7 @@ cpio_getopt(struct cpio *cpio)
int opt = '?';
int required = 0;
cpio->optarg = NULL;
cpio->argument = NULL;
/* First time through, initialize everything. */
if (state == state_start) {
@ -188,7 +189,7 @@ cpio_getopt(struct cpio *cpio)
long_prefix = "-W "; /* For clearer errors. */
} else {
state = state_next_word;
cpio->optarg = opt_word;
cpio->argument = opt_word;
}
}
}
@ -202,7 +203,7 @@ cpio_getopt(struct cpio *cpio)
p = strchr(opt_word, '=');
if (p != NULL) {
optlength = (size_t)(p - opt_word);
cpio->optarg = (char *)(uintptr_t)(p + 1);
cpio->argument = (char *)(uintptr_t)(p + 1);
} else {
optlength = strlen(opt_word);
}
@ -241,9 +242,9 @@ cpio_getopt(struct cpio *cpio)
/* We've found a unique match; does it need an argument? */
if (match->required) {
/* Argument required: get next word if necessary. */
if (cpio->optarg == NULL) {
cpio->optarg = *cpio->argv;
if (cpio->optarg == NULL) {
if (cpio->argument == NULL) {
cpio->argument = *cpio->argv;
if (cpio->argument == NULL) {
lafe_warnc(0,
"Option %s%s requires an argument",
long_prefix, match->name);
@ -254,7 +255,7 @@ cpio_getopt(struct cpio *cpio)
}
} else {
/* Argument forbidden: fail if there is one. */
if (cpio->optarg != NULL) {
if (cpio->argument != NULL) {
lafe_warnc(0,
"Option %s%s does not allow an argument",
long_prefix, match->name);
@ -340,7 +341,7 @@ owner_parse(const char *spec, int *uid, int *gid)
} else {
char *end;
errno = 0;
*uid = strtoul(user, &end, 10);
*uid = (int)strtoul(user, &end, 10);
if (errno || *end != '\0') {
snprintf(errbuff, sizeof(errbuff),
"Couldn't lookup user ``%s''", user);
@ -358,7 +359,7 @@ owner_parse(const char *spec, int *uid, int *gid)
} else {
char *end;
errno = 0;
*gid = strtoul(g, &end, 10);
*gid = (int)strtoul(g, &end, 10);
if (errno || *end != '\0') {
snprintf(errbuff, sizeof(errbuff),
"Couldn't lookup group ``%s''", g);

View File

@ -50,9 +50,15 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.15 2008/12/06 07:30:40 kientzle
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
@ -69,9 +75,6 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.15 2008/12/06 07:30:40 kientzle
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
@ -136,6 +139,16 @@ main(int argc, char *argv[])
cpio->buff = buff;
cpio->buff_size = sizeof(buff);
#if defined(HAVE_SIGACTION) && defined(SIGPIPE)
{ /* Ignore SIGPIPE signals. */
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
}
#endif
/* Need lafe_progname before calling lafe_warnc. */
if (*argv == NULL)
lafe_progname = "bsdcpio";
@ -150,6 +163,10 @@ main(int argc, char *argv[])
else
lafe_progname = *argv;
}
#if HAVE_SETLOCALE
if (setlocale(LC_ALL, "") == NULL)
lafe_warnc(0, "Failed to set default locale");
#endif
cpio->uid_override = -1;
cpio->gid_override = -1;
@ -187,9 +204,9 @@ main(int argc, char *argv[])
cpio->bytes_per_block = 5120;
break;
case 'C': /* NetBSD/OpenBSD */
cpio->bytes_per_block = atoi(cpio->optarg);
cpio->bytes_per_block = atoi(cpio->argument);
if (cpio->bytes_per_block <= 0)
lafe_errc(1, 0, "Invalid blocksize %s", cpio->optarg);
lafe_errc(1, 0, "Invalid blocksize %s", cpio->argument);
break;
case 'c': /* POSIX 1997 */
cpio->format = "odc";
@ -199,22 +216,22 @@ main(int argc, char *argv[])
break;
case 'E': /* NetBSD/OpenBSD */
lafe_include_from_file(&cpio->matching,
cpio->optarg, cpio->option_null);
cpio->argument, cpio->option_null);
break;
case 'F': /* NetBSD/OpenBSD/GNU cpio */
cpio->filename = cpio->optarg;
cpio->filename = cpio->argument;
break;
case 'f': /* POSIX 1997 */
lafe_exclude(&cpio->matching, cpio->optarg);
lafe_exclude(&cpio->matching, cpio->argument);
break;
case 'H': /* GNU cpio (also --format) */
cpio->format = cpio->optarg;
cpio->format = cpio->argument;
break;
case 'h':
long_help();
break;
case 'I': /* NetBSD/OpenBSD */
cpio->filename = cpio->optarg;
cpio->filename = cpio->argument;
break;
case 'i': /* POSIX 1997 */
if (cpio->mode != '\0')
@ -251,7 +268,7 @@ main(int argc, char *argv[])
cpio->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
break;
case 'O': /* GNU cpio */
cpio->filename = cpio->optarg;
cpio->filename = cpio->argument;
break;
case 'o': /* POSIX 1997 */
if (cpio->mode != '\0')
@ -275,7 +292,7 @@ main(int argc, char *argv[])
case 'R': /* GNU cpio, also --owner */
/* TODO: owner_parse should return uname/gname
* also; use that to set [ug]name_override. */
errmsg = owner_parse(cpio->optarg, &uid, &gid);
errmsg = owner_parse(cpio->argument, &uid, &gid);
if (errmsg) {
lafe_warnc(-1, "%s", errmsg);
usage();
@ -302,6 +319,9 @@ main(int argc, char *argv[])
case 'v': /* POSIX 1997 */
cpio->verbose++;
break;
case 'V': /* GNU cpio */
cpio->dot++;
break;
case OPTION_VERSION: /* GNU convention */
version();
break;
@ -345,6 +365,12 @@ main(int argc, char *argv[])
/* -l requires -p */
if (cpio->option_link && cpio->mode != 'p')
lafe_errc(1, 0, "Option -l requires -p");
/* -v overrides -V */
if (cpio->dot && cpio->verbose)
cpio->dot = 0;
/* -v overrides -V */
if (cpio->dot && cpio->verbose)
cpio->dot = 0;
/* TODO: Flag other nonsensical combinations. */
switch (cpio->mode) {
@ -402,7 +428,7 @@ static const char *long_help_msg =
"First option must be a mode specifier:\n"
" -i Input -o Output -p Pass\n"
"Common Options:\n"
" -v Verbose\n"
" -v Verbose filenames -V one dot per file\n"
"Create: %p -o [options] < [list of files] > [archive]\n"
" -J,-y,-z,--lzma Compress archive with xz/bzip2/gzip/lzma\n"
" --format {odc|newc|ustar} Select archive format\n"
@ -451,7 +477,7 @@ version(void)
{
fprintf(stdout,"bsdcpio %s -- %s\n",
BSDCPIO_VERSION_STRING,
archive_version());
archive_version_string());
exit(0);
}
@ -533,6 +559,8 @@ mode_out(struct cpio *cpio)
}
r = archive_write_close(cpio->archive);
if (cpio->dot)
fprintf(stderr, "\n");
if (r != ARCHIVE_OK)
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
@ -543,7 +571,7 @@ mode_out(struct cpio *cpio)
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
blocks == 1 ? "block" : "blocks");
}
archive_write_finish(cpio->archive);
archive_write_free(cpio->archive);
}
/*
@ -656,6 +684,8 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
/* Print out the destination name to the user. */
if (cpio->verbose)
fprintf(stderr,"%s", destpath);
if (cpio->dot)
fprintf(stderr, ".");
/*
* Option_link only makes sense in pass mode and for
@ -725,7 +755,7 @@ entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
if (r == ARCHIVE_FATAL)
exit(1);
if (r >= ARCHIVE_WARN && fd >= 0) {
if (r >= ARCHIVE_WARN && archive_entry_size(entry) > 0 && fd >= 0) {
bytes_read = read(fd, cpio->buff, cpio->buff_size);
while (bytes_read > 0) {
r = archive_write_data(cpio->archive,
@ -825,7 +855,7 @@ mode_in(struct cpio *cpio)
a = archive_read_new();
if (a == NULL)
lafe_errc(1, 0, "Couldn't allocate archive object");
archive_read_support_compression_all(a);
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
@ -849,7 +879,9 @@ mode_in(struct cpio *cpio)
if (destpath == NULL)
continue;
if (cpio->verbose)
fprintf(stdout, "%s\n", destpath);
fprintf(stderr, "%s\n", destpath);
if (cpio->dot)
fprintf(stderr, ".");
if (cpio->uid_override >= 0)
archive_entry_set_uid(entry, cpio->uid_override);
if (cpio->gid_override >= 0)
@ -859,13 +891,16 @@ mode_in(struct cpio *cpio)
fprintf(stderr, "%s: %s\n",
archive_entry_pathname(entry),
archive_error_string(ext));
} else if (archive_entry_size(entry) > 0) {
} else if (!archive_entry_size_is_set(entry)
|| archive_entry_size(entry) > 0) {
r = extract_data(a, ext);
if (r != ARCHIVE_OK)
cpio->return_value = 1;
}
}
r = archive_read_close(a);
if (cpio->dot)
fprintf(stderr, "\n");
if (r != ARCHIVE_OK)
lafe_errc(1, 0, "%s", archive_error_string(a));
r = archive_write_close(ext);
@ -877,8 +912,8 @@ mode_in(struct cpio *cpio)
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
blocks == 1 ? "block" : "blocks");
}
archive_read_finish(a);
archive_write_finish(ext);
archive_read_free(a);
archive_write_free(ext);
exit(cpio->return_value);
}
@ -892,7 +927,7 @@ extract_data(struct archive *ar, struct archive *aw)
int r;
size_t size;
const void *block;
off_t offset;
int64_t offset;
for (;;) {
r = archive_read_data_block(ar, &block, &size, &offset);
@ -922,7 +957,7 @@ mode_list(struct cpio *cpio)
a = archive_read_new();
if (a == NULL)
lafe_errc(1, 0, "Couldn't allocate archive object");
archive_read_support_compression_all(a);
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
@ -952,7 +987,7 @@ mode_list(struct cpio *cpio)
fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
blocks == 1 ? "block" : "blocks");
}
archive_read_finish(a);
archive_read_free(a);
exit(0);
}
@ -989,11 +1024,11 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
/* Use uname if it's present, else lookup name from uid. */
uname = archive_entry_uname(entry);
if (uname == NULL)
uname = lookup_uname(cpio, archive_entry_uid(entry));
uname = lookup_uname(cpio, (uid_t)archive_entry_uid(entry));
/* Use gname if it's present, else lookup name from gid. */
gname = archive_entry_gname(entry);
if (gname == NULL)
gname = lookup_gname(cpio, archive_entry_gid(entry));
gname = lookup_gname(cpio, (uid_t)archive_entry_gid(entry));
}
/* Print device number or file size. */
@ -1075,6 +1110,8 @@ mode_pass(struct cpio *cpio, const char *destdir)
archive_entry_linkresolver_free(cpio->linkresolver);
r = archive_write_close(cpio->archive);
if (cpio->dot)
fprintf(stderr, "\n");
if (r != ARCHIVE_OK)
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
@ -1086,7 +1123,7 @@ mode_pass(struct cpio *cpio, const char *destdir)
blocks == 1 ? "block" : "blocks");
}
archive_write_finish(cpio->archive);
archive_write_free(cpio->archive);
}
/*
@ -1260,8 +1297,9 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
const char *
cpio_i64toa(int64_t n0)
{
// 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice.
// We also need 1 byte for '-' and 1 for '\0'.
/* 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice.
* We also need 1 byte for '-' and 1 for '\0'.
*/
static char buff[22];
int64_t n = n0 < 0 ? -n0 : n0;
char *p = buff + sizeof(buff);

View File

@ -43,18 +43,18 @@
*/
struct cpio {
/* Option parsing */
const char *optarg;
const char *argument;
/* Options */
const char *filename;
char mode; /* -i -o -p */
char compress; /* -j, -y, or -z */
int mode; /* -i -o -p */
int compress; /* -j, -y, or -z */
const char *format; /* -H format */
int bytes_per_block; /* -b block_size */
int verbose; /* -v */
int dot; /* -V */
int quiet; /* --quiet */
int extract_flags; /* Flags for extract operation */
char symlink_mode; /* H or L, per BSD conventions */
const char *compress_program;
int option_append; /* -A, only relevant for -o */
int option_atime_restore; /* -a */

View File

@ -15,6 +15,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
test_cmdline.c
test_format_newc.c
test_gcpio_compat.c
test_option_0.c
test_option_B_upper.c
test_option_C_upper.c
test_option_J_upper.c
@ -38,9 +39,6 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
test_passthrough_reverse.c
test_pathmatch.c
)
IF(WIN32 AND NOT CYGWIN)
LIST(APPEND bsdcpio_test_SOURCES ../cpio_windows.h)
ENDIF(WIN32 AND NOT CYGWIN)
#
# Register target
@ -60,7 +58,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
# test. We can use that to define the tests for cmake by
# defining a DEFINE_TEST macro and reading list.h in.
MACRO (DEFINE_TEST _testname)
ADD_TEST_28(
ADD_TEST(
NAME bsdcpio_${_testname}
COMMAND bsdcpio_test -vv
-p $<TARGET_FILE:bsdcpio>

File diff suppressed because it is too large Load Diff

View File

@ -48,9 +48,6 @@
#include <sys/types.h> /* Windows requires this before sys/stat.h */
#include <sys/stat.h>
#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif
#if HAVE_DIRENT_H
#include <dirent.h>
#endif
@ -63,6 +60,9 @@
#ifdef HAVE_IO_H
#include <io.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -83,13 +83,9 @@
/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
#include "../cpio_windows.h"
#if !defined(__BORLANDC__)
#define strdup _strdup
#endif
#define LOCALE_DE "deu"
#else
#define LOCALE_DE "de_DE.UTF-8"
#endif
/* Visual Studio */
@ -97,13 +93,11 @@
#define snprintf sprintf_s
#endif
/* Cygwin */
#if defined(__CYGWIN__)
/* Cygwin-1.7.x is lazy about populating nlinks, so don't
* expect it to be accurate. */
# define NLINKS_INACCURATE_FOR_DIRS
#if defined(__BORLANDC__)
#pragma warn -8068 /* Constant out of range in comparison. */
#endif
/* Haiku OS and QNX */
#if defined(__HAIKU__) || defined(__QNXNTO__)
/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
#include <stdint.h>
@ -139,24 +133,24 @@
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* Assert two strings are the same. Reports value of each one if not. */
#define assertEqualString(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
#define assertEqualUTF8String(v1,v2) \
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
/* As above, but v1 and v2 are wchar_t * */
#define assertEqualWString(v1,v2) \
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
/* Assert two files are the same; allow printf-style expansion of second name.
* See below for comments about variable arguments here...
*/
#define assertEqualFile \
assertion_setup(__FILE__, __LINE__);assertion_equal_file
/* Assert that a file is empty; supports printf-style arguments. */
#define assertEmptyFile \
assertion_setup(__FILE__, __LINE__);assertion_empty_file
/* Assert that a file is not empty; supports printf-style arguments. */
#define assertNonEmptyFile \
assertion_setup(__FILE__, __LINE__);assertion_non_empty_file
/* Assert two files are the same. */
#define assertEqualFile(f1, f2) \
assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
/* Assert that a file is empty. */
#define assertEmptyFile(pathname) \
assertion_empty_file(__FILE__, __LINE__, (pathname))
/* Assert that a file is not empty. */
#define assertNonEmptyFile(pathname) \
assertion_non_empty_file(__FILE__, __LINE__, (pathname))
#define assertFileAtime(pathname, sec, nsec) \
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileAtimeRecent(pathname) \
@ -166,14 +160,14 @@
#define assertFileBirthtimeRecent(pathname) \
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileExists \
assertion_setup(__FILE__, __LINE__);assertion_file_exists
/* Assert that a file exists; supports printf-style arguments. */
#define assertFileNotExists \
assertion_setup(__FILE__, __LINE__);assertion_file_not_exists
/* Assert that file contents match a string; supports printf-style arguments. */
#define assertFileContents \
assertion_setup(__FILE__, __LINE__);assertion_file_contents
#define assertFileExists(pathname) \
assertion_file_exists(__FILE__, __LINE__, pathname)
/* Assert that a file exists. */
#define assertFileNotExists(pathname) \
assertion_file_not_exists(__FILE__, __LINE__, pathname)
/* Assert that file contents match a string. */
#define assertFileContents(data, data_size, pathname) \
assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
@ -182,8 +176,10 @@
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size) \
assertion_file_size(__FILE__, __LINE__, pathname, size)
#define assertTextFileContents \
assertion_setup(__FILE__, __LINE__);assertion_text_file_contents
#define assertTextFileContents(text, pathname) \
assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
#define assertFileContainsLinesAnyOrder(pathname, lines) \
assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
#define assertIsDir(pathname, mode) \
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
#define assertIsHardlink(path1, path2) \
@ -205,6 +201,8 @@
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
#define assertUmask(mask) \
assertion_umask(__FILE__, __LINE__, mask)
#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
/*
* This would be simple with C99 variadic macros, but I don't want to
@ -213,28 +211,29 @@
* but effective.
*/
#define skipping \
assertion_setup(__FILE__, __LINE__);test_skipping
skipping_setup(__FILE__, __LINE__);test_skipping
/* Function declarations. These are defined in test_utility.c. */
void failure(const char *fmt, ...);
int assertion_assert(const char *, int, int, const char *, void *);
int assertion_chdir(const char *, int, const char *);
int assertion_empty_file(const char *, ...);
int assertion_equal_file(const char *, const char *, ...);
int assertion_empty_file(const char *, int, const char *);
int assertion_equal_file(const char *, int, const char *, const char *);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *);
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contents(const void *, int, const char *, ...);
int assertion_file_exists(const char *, ...);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
int assertion_file_contents(const char *, int, const void *, int, const char *);
int assertion_file_exists(const char *, int, const char *);
int assertion_file_mtime(const char *, int, const char *, long, long);
int assertion_file_mtime_recent(const char *, int, const char *);
int assertion_file_nlinks(const char *, int, const char *, int);
int assertion_file_not_exists(const char *, ...);
int assertion_file_not_exists(const char *, int, const char *);
int assertion_file_size(const char *, int, const char *, long);
int assertion_is_dir(const char *, int, const char *, int);
int assertion_is_hardlink(const char *, int, const char *, const char *);
@ -245,11 +244,12 @@ 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_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_non_empty_file(const char *, ...);
int assertion_text_file_contents(const char *buff, const char *f);
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_umask(const char *, int, int);
void assertion_setup(const char *, int);
int assertion_utimes(const char *, int, const char *, long, long, long, long );
void skipping_setup(const char *, int);
void test_skipping(const char *fmt, ...);
/* Like sprintf, then system() */
@ -267,6 +267,9 @@ int canGzip(void);
/* Return true if this platform can run the "gunzip" program. */
int canGunzip(void);
/* Return true if the file has large i-node number(>0xffffffff). */
int is_LargeInode(const char *);
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
@ -274,6 +277,9 @@ char *slurpfile(size_t *, const char *fmt, ...);
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
/* Path to working directory for current test */
const char *testworkdir;
/*
* Special interfaces for program test harness.
*/
@ -283,3 +289,7 @@ const char *testprogfile;
/* Name of exe to use in printf-formatted command strings. */
/* On Windows, this includes leading/trailing quotes. */
const char *testprog;
#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif

View File

@ -40,15 +40,23 @@ DEFINE_TEST(test_0)
struct stat st;
failure("File %s does not exist?!", testprogfile);
if (!assertEqualInt(0, stat(testprogfile, &st)))
if (!assertEqualInt(0, stat(testprogfile, &st))) {
fprintf(stderr,
"\nFile %s does not exist; aborting test.\n\n",
testprog);
exit(1);
}
failure("%s is not executable?!", testprogfile);
if (!assert((st.st_mode & 0111) != 0))
if (!assert((st.st_mode & 0111) != 0)) {
fprintf(stderr,
"\nFile %s not executable; aborting test.\n\n",
testprog);
exit(1);
}
/*
* Try to succesfully run the program; this requires that
* Try to successfully run the program; this requires that
* we know some option that will succeed.
*/
if (0 == systemf("%s --version >" DEV_NULL, testprog)) {

View File

@ -33,12 +33,15 @@ verify_files(const char *msg)
*/
/* Regular file with 2 links. */
failure(msg);
assertIsReg("file", 0644);
failure(msg);
assertFileSize("file", 10);
failure(msg);
assertFileNLinks("file", 2);
/* Another name for the same file. */
failure(msg);
assertIsHardlink("linkfile", "file");
/* Symlink */
@ -46,8 +49,11 @@ verify_files(const char *msg)
assertIsSymlink("symlink", "file");
/* Another file with 1 link and different permissions. */
failure(msg);
assertIsReg("file2", 0777);
failure(msg);
assertFileSize("file2", 10);
failure(msg);
assertFileNLinks("file2", 1);
/* dir */
@ -58,7 +64,7 @@ static void
basic_cpio(const char *target,
const char *pack_options,
const char *unpack_options,
const char *se)
const char *se, const char *se2)
{
int r;
@ -87,7 +93,7 @@ basic_cpio(const char *target,
/* Verify stderr. */
failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target);
assertTextFileContents(se, "unpack.err");
assertTextFileContents(se2, "unpack.err");
verify_files(pack_options);
@ -125,6 +131,7 @@ DEFINE_TEST(test_basic)
{
FILE *filelist;
const char *msg;
char result[1024];
assertUmask(0);
@ -132,28 +139,56 @@ DEFINE_TEST(test_basic)
* Create an assortment of files on disk.
*/
filelist = fopen("filelist", "w");
memset(result, 0, sizeof(result));
/* File with 10 bytes content. */
assertMakeFile("file", 0644, "1234567890");
fprintf(filelist, "file\n");
if (is_LargeInode("file"))
strncat(result,
"bsdcpio: file: large inode number truncated: "
"Numerical result out of range\n",
sizeof(result) - strlen(result));
/* hardlink to above file. */
assertMakeHardlink("linkfile", "file");
fprintf(filelist, "linkfile\n");
if (is_LargeInode("linkfile"))
strncat(result,
"bsdcpio: linkfile: large inode number truncated: "
"Numerical result out of range\n",
sizeof(result) - strlen(result));
/* Symlink to above file. */
if (canSymlink()) {
assertMakeSymlink("symlink", "file");
fprintf(filelist, "symlink\n");
if (is_LargeInode("symlink"))
strncat(result,
"bsdcpio: symlink: large inode number truncated: "
"Numerical result out of range\n",
sizeof(result) - strlen(result));
}
/* Another file with different permissions. */
assertMakeFile("file2", 0777, "1234567890");
fprintf(filelist, "file2\n");
if (is_LargeInode("file2"))
strncat(result,
"bsdcpio: file2: large inode number truncated: "
"Numerical result out of range\n",
sizeof(result) - strlen(result));
/* Directory. */
assertMakeDir("dir", 0775);
fprintf(filelist, "dir\n");
if (is_LargeInode("dir"))
strncat(result,
"bsdcpio: dir: large inode number truncated: "
"Numerical result out of range\n",
sizeof(result) - strlen(result));
strncat(result, "2 blocks\n", sizeof(result) - strlen(result));
/* All done. */
fclose(filelist);
@ -161,12 +196,12 @@ DEFINE_TEST(test_basic)
/* Archive/dearchive with a variety of options. */
msg = canSymlink() ? "2 blocks\n" : "1 block\n";
basic_cpio("copy", "", "", msg);
basic_cpio("copy_odc", "--format=odc", "", msg);
basic_cpio("copy_newc", "-H newc", "", "2 blocks\n");
basic_cpio("copy_cpio", "-H odc", "", msg);
basic_cpio("copy", "", "", msg, msg);
basic_cpio("copy_odc", "--format=odc", "", msg, msg);
basic_cpio("copy_newc", "-H newc", "", result, "2 blocks\n");
basic_cpio("copy_cpio", "-H odc", "", msg, msg);
msg = canSymlink() ? "9 blocks\n" : "8 blocks\n";
basic_cpio("copy_ustar", "-H ustar", "", msg);
basic_cpio("copy_ustar", "-H ustar", "", msg, msg);
/* Copy in one step using -p */
passthrough("passthrough");

View File

@ -68,6 +68,16 @@ from_hex(const char *p, size_t l)
return (r);
}
#if !defined(_WIN32) || defined(__CYGWIN__)
static int
nlinks(const char *p)
{
struct stat st;
assertEqualInt(0, stat(p, &st));
return st.st_nlink;
}
#endif
DEFINE_TEST(test_format_newc)
{
FILE *list;
@ -77,6 +87,7 @@ DEFINE_TEST(test_format_newc)
time_t t, t2, now;
char *p, *e;
size_t s, fs, ns;
char result[1024];
assertUmask(0);
@ -111,6 +122,29 @@ DEFINE_TEST(test_format_newc)
assertMakeDir("dir", 0775);
fprintf(list, "dir\n");
/* Setup result message. */
memset(result, 0, sizeof(result));
if (is_LargeInode("file1"))
strncat(result,
"bsdcpio: file1: large inode number truncated: "
"Numerical result out of range\n",
sizeof(result) - strlen(result) -1);
if (canSymlink() && is_LargeInode("symlink"))
strncat(result,
"bsdcpio: symlink: large inode number truncated: "
"Numerical result out of range\n",
sizeof(result) - strlen(result) -1);
if (is_LargeInode("dir"))
strncat(result,
"bsdcpio: dir: large inode number truncated: "
"Numerical result out of range\n",
sizeof(result) - strlen(result) -1);
if (is_LargeInode("hardlink"))
strncat(result,
"bsdcpio: hardlink: large inode number truncated: "
"Numerical result out of range\n",
sizeof(result) - strlen(result) -1);
/* Record some facts about what we just created: */
now = time(NULL); /* They were all created w/in last two seconds. */
@ -123,10 +157,11 @@ DEFINE_TEST(test_format_newc)
/* Verify that nothing went to stderr. */
if (canSymlink()) {
assertTextFileContents("2 blocks\n", "newc.err");
strncat(result, "2 blocks\n", sizeof(result) - strlen(result));
} else {
assertTextFileContents("1 block\n", "newc.err");
strncat(result, "1 block\n", sizeof(result) - strlen(result));
}
assertTextFileContents(result, "newc.err");
/* Verify that stdout is a well-formed cpio file in "newc" format. */
p = slurpfile(&s, "newc.out");
@ -216,10 +251,10 @@ DEFINE_TEST(test_format_newc)
/* Mode: sgid bit sometimes propagates from parent dirs, ignore it. */
assertEqualInt(040775, from_hex(e + 14, 8) & ~02000);
#endif
assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
assertEqualInt(uid, from_hex(e + 22, 8)); /* uid */
assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */
#ifndef NLINKS_INACCURATE_FOR_DIRS
assertEqualMem(e + 38, "00000002", 8); /* nlink */
#if !defined(_WIN32) || defined(__CYGWIN__)
assertEqualInt(nlinks("dir"), from_hex(e + 38, 8)); /* nlinks */
#endif
t2 = from_hex(e + 46, 8); /* mtime */
failure("First entry created at t=0x%08x this entry created at t2=0x%08x", t, t2);

92
cpio/test/test_option_0.c Normal file
View File

@ -0,0 +1,92 @@
/*-
* Copyright (c) 2003-2010 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$");
DEFINE_TEST(test_option_0)
{
FILE *filelist;
int r;
assertUmask(0);
/* Create a few files. */
assertMakeFile("file1", 0644, "1234567890");
assertMakeFile("file2", 0644, "1234567890");
assertMakeFile("file3", 0644, "1234567890");
assertMakeFile("file4", 0644, "1234567890");
/* Create a file list of filenames with varying end-of-line. */
filelist = fopen("filelist", "wb");
assertEqualInt(fwrite("file1\x0a", 1, 6, filelist), 6);
assertEqualInt(fwrite("file2\x0d", 1, 6, filelist), 6);
assertEqualInt(fwrite("file3\x0a\x0d", 1, 7, filelist), 7);
assertEqualInt(fwrite("file4", 1, 5, filelist), 5);
fclose(filelist);
/* Create a file list of null-delimited names. */
filelist = fopen("filelistNull", "wb");
assertEqualInt(fwrite("file1\0", 1, 6, filelist), 6);
assertEqualInt(fwrite("file2\0", 1, 6, filelist), 6);
assertEqualInt(fwrite("file3\0", 1, 6, filelist), 6);
assertEqualInt(fwrite("file4", 1, 5, filelist), 5);
fclose(filelist);
assertUmask(022);
/* Pack up using the file list with text line endings. */
r = systemf("%s -o < filelist > archive 2> stderr1.txt", testprog);
assertEqualInt(r, 0);
/* Extract into a new dir. */
assertMakeDir("copy", 0775);
assertChdir("copy");
r = systemf("%s -i < ../archive > stdout3.txt 2> stderr3.txt", testprog);
assertEqualInt(r, 0);
/* Verify the files. */
assertIsReg("file1", 0644);
assertIsReg("file2", 0644);
assertIsReg("file3", 0644);
assertIsReg("file4", 0644);
assertChdir("..");
/* Pack up using the file list with nulls. */
r = systemf("%s -o0 < filelistNull > archiveNull 2> stderr2.txt", testprog);
assertEqualInt(r, 0);
/* Extract into a new dir. */
assertMakeDir("copyNull", 0775);
assertChdir("copyNull");
r = systemf("%s -i < ../archiveNull > stdout4.txt 2> stderr4.txt", testprog);
assertEqualInt(r, 0);
/* Verify the files. */
assertIsReg("file1", 0644);
assertIsReg("file2", 0644);
assertIsReg("file3", 0644);
assertIsReg("file4", 0644);
}

View File

@ -51,6 +51,16 @@ from_octal(const char *p, size_t l)
return (r);
}
#if !defined(_WIN32) || defined(__CYGWIN__)
static int
nlinks(const char *p)
{
struct stat st;
assertEqualInt(0, stat(p, &st));
return st.st_nlink;
}
#endif
DEFINE_TEST(test_option_c)
{
FILE *filelist;
@ -181,17 +191,19 @@ DEFINE_TEST(test_option_c)
/* Group members bits and others bits do not work. */
assertEqualMem(e + 18, "040777", 6); /* Mode */
#else
/* Accept 042775 to accomodate systems where sgid bit propagates. */
/* Accept 042775 to accommodate systems where sgid bit propagates. */
if (memcmp(e + 18, "042775", 6) != 0)
assertEqualMem(e + 18, "040775", 6); /* Mode */
#endif
assertEqualInt(from_octal(e + 24, 6), uid); /* uid */
assertEqualInt(uid, from_octal(e + 24, 6)); /* uid */
/* Gid should be same as first entry. */
assert(is_octal(e + 30, 6)); /* gid */
assertEqualInt(gid, from_octal(e + 30, 6));
#ifndef NLINKS_INACCURATE_FOR_DIRS
assertEqualMem(e + 36, "000002", 6); /* Nlink */
#if !defined(_WIN32) || defined(__CYGWIN__)
assertEqualInt(nlinks("dir"), from_octal(e + 36, 6)); /* Nlink */
#endif
t = from_octal(e + 48, 11); /* mtime */
assert(t <= now); /* File wasn't created in future. */
assert(t >= now - 2); /* File was created w/in last 2 secs. */

View File

@ -25,11 +25,17 @@
#include "test.h"
__FBSDID("$FreeBSD$");
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
DEFINE_TEST(test_option_t)
{
char *p;
int r;
time_t mtime;
char date[32];
char date2[32];
/* List reference archive, make sure the TOC is correct. */
extract_reference_file("test_option_t.cpio");
@ -75,17 +81,20 @@ DEFINE_TEST(test_option_t)
/* Since -n uses numeric UID/GID, this part should be the
* same on every system. */
assertEqualMem(p, "-rw-r--r-- 1 1000 1000 0 ",42);
/* Date varies depending on local timezone. */
if (memcmp(p + 42, "Dec 31 1969", 12) == 0) {
/* East of Greenwich we get Dec 31, 1969. */
} else {
/* West of Greenwich get Jan 1, 1970 */
assertEqualMem(p + 42, "Jan ", 4);
/* Some systems format "Jan 01", some "Jan 1" */
assert(p[46] == ' ' || p[46] == '0');
assertEqualMem(p + 47, "1 1970 ", 8);
}
assertEqualMem(p + 54, " file", 5);
/* Date varies depending on local timezone and locale. */
mtime = 1;
#ifdef HAVE_LOCALE_H
setlocale(LC_ALL, "");
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
strftime(date2, sizeof(date), "%b %d %Y", localtime(&mtime));
_snprintf(date, sizeof(date)-1, "%12s file", date2);
#else
strftime(date2, sizeof(date), "%b %e %Y", localtime(&mtime));
snprintf(date, sizeof(date)-1, "%12s file", date2);
#endif
assertEqualMem(p + 42, date, strlen(date));
free(p);
/* But "-n" without "-t" is an error. */

View File

@ -41,7 +41,7 @@ DEFINE_TEST(test_option_u)
assertMakeFile("f", 0644, "a");
/* Copy the file to the "copy" dir. */
r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
r = systemf("echo f| %s -pd copy >copy.out 2>copy.err",
testprog);
assertEqualInt(r, 0);
@ -60,7 +60,7 @@ DEFINE_TEST(test_option_u)
assertEqualInt(0, utime("f", &times));
/* Copy the file to the "copy" dir. */
r = systemf("echo f | %s -pd copy >copy.out 2>copy.err",
r = systemf("echo f| %s -pd copy >copy.out 2>copy.err",
testprog);
assertEqualInt(r, 0);
@ -70,7 +70,7 @@ DEFINE_TEST(test_option_u)
assertEqualMem(p, "a", 1);
/* Copy the file to the "copy" dir with -u (force) */
r = systemf("echo f | %s -pud copy >copy.out 2>copy.err",
r = systemf("echo f| %s -pud copy >copy.out 2>copy.err",
testprog);
assertEqualInt(r, 0);

View File

@ -30,9 +30,8 @@ __FBSDID("$FreeBSD$");
#if !defined(_WIN32)
#define ROOT "root"
static int root_uids[] = { 0 };
/* Solaris 9 root has gid 1 (other) */
static int root_gids[] = { 0, 1 };
static const int root_uids[] = { 0 };
static const int root_gids[] = { 0, 1 };
#elif defined(__CYGWIN__)
/* On cygwin, the Administrator user most likely exists (unless
* it has been renamed or is in a non-English localization), but
@ -43,13 +42,13 @@ static int root_gids[] = { 0, 1 };
* Use CreateWellKnownSID() and LookupAccountName()?
*/
#define ROOT "Administrator"
static int root_uids[] = { 500 };
static int root_gids[] = { 513, 545, 544 };
static const int root_uids[] = { 500 };
static const int root_gids[] = { 513, 545, 544 };
#endif
#if defined(ROOT)
static int
int_in_list(int i, int *l, size_t n)
int_in_list(int i, const int *l, size_t n)
{
while (n-- > 0)
if (*l++ == i)

2
doc/html/.ignore_me Normal file
View File

@ -0,0 +1,2 @@
*** PLEASE DO NOT DELETE THIS FILE! ***
This file is used to track an otherwise empty directory in git.

2
doc/man/.ignore_me Normal file
View File

@ -0,0 +1,2 @@
*** PLEASE DO NOT DELETE THIS FILE! ***
This file is used to track an otherwise empty directory in git.

View File

@ -255,10 +255,7 @@ function splitwords(l, dest, n, o, w) {
} else if(match(words[w],"^Nd$")) {
add("- " wtail())
} else if(match(words[w],"^Fl$")) {
if (displaylines == 0)
add("*-" words[++w] "*")
else
add("-" words[++w])
addopen("-")
} else if(match(words[w],"^Ar$")) {
if(w==nwords)
add("_file ..._")
@ -422,6 +419,9 @@ function splitwords(l, dest, n, o, w) {
addpunct("<li>")
listnext[listdepth] = "</li>"
}
} else if(match(words[w], "^Vt$")) {
w++
add("_" words[w] "_")
} else if(match(words[w],"^Xo$")) {
# TODO: Figure out how to handle this
} else if(match(words[w],"^Xc$")) {

2
doc/pdf/.ignore_me Normal file
View File

@ -0,0 +1,2 @@
*** PLEASE DO NOT DELETE THIS FILE! ***
This file is used to track an otherwise empty directory in git.

2
doc/text/.ignore_me Normal file
View File

@ -0,0 +1,2 @@
*** PLEASE DO NOT DELETE THIS FILE! ***
This file is used to track an otherwise empty directory in git.

2
doc/wiki/.ignore_me Normal file
View File

@ -0,0 +1,2 @@
*** PLEASE DO NOT DELETE THIS FILE! ***
This file is used to track an otherwise empty directory in git.

View File

@ -5,29 +5,21 @@
#
CFLAGS= \
-DNO_BZIP2_CREATE \
-DNO_BZIP2_EXTRACT \
-DNO_COMPRESS_EXTRACT \
-DNO_CPIO_EXTRACT \
-DNO_CREATE \
-DNO_GZIP_CREATE \
-DNO_GZIP_EXTRACT \
-DNO_LOOKUP
-I../../libarchive \
-g
# Omit 'tree.o' if you're not including create support
#OBJS= minitar.o tree.o
OBJS= minitar.o
# How to link against libarchive.
LIBARCHIVE= ../../libarchive/libarchive.a
all: minitar
minitar: $(OBJS)
cc -o minitar -static $(OBJS) -larchive -lz -lbz2
minitar: minitar.o
cc -g -o minitar minitar.o $(LIBARCHIVE) -lz -lbz2
strip minitar
ls -l minitar
minitar.o: minitar.c
tree.o: tree.c
clean::
rm -f *.o
rm -f minitar

View File

@ -40,8 +40,6 @@
*/
#include <sys/types.h>
__FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <archive.h>
@ -52,10 +50,6 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
#ifndef NO_CREATE
#include "tree.h"
#endif
/*
* NO_CREATE implies NO_BZIP2_CREATE and NO_GZIP_CREATE and NO_COMPRESS_CREATE.
*/
@ -264,32 +258,75 @@ create(const char *filename, int compress, const char **argv)
archive_read_disk_set_standard_lookup(disk);
#endif
while (*argv != NULL) {
struct tree *t = tree_open(*argv);
while (tree_next(t)) {
struct archive *disk = archive_read_disk_new();
int r;
r = archive_read_disk_open(disk, *argv);
if (r != ARCHIVE_OK) {
errmsg(archive_error_string(disk));
errmsg("\n");
exit(1);
}
for (;;) {
int needcr = 0;
entry = archive_entry_new();
archive_entry_set_pathname(entry, tree_current_path(t));
archive_read_disk_entry_from_file(disk, entry, -1,
tree_current_stat(t));
r = archive_read_next_header2(disk, entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK) {
errmsg(archive_error_string(disk));
errmsg("\n");
exit(1);
}
archive_read_disk_descend(disk);
if (verbose) {
msg("a ");
msg(tree_current_path(t));
msg(archive_entry_pathname(entry));
needcr = 1;
}
archive_write_header(a, entry);
fd = open(tree_current_access_path(t), O_RDONLY);
len = read(fd, buff, sizeof(buff));
while (len > 0) {
archive_write_data(a, buff, len);
r = archive_write_header(a, entry);
if (r < ARCHIVE_OK) {
errmsg(": ");
errmsg(archive_error_string(a));
needcr = 1;
}
if (r == ARCHIVE_FATAL)
exit(1);
if (r > ARCHIVE_FAILED) {
#if 0
/* Ideally, we would be able to use
* the same code to copy a body from
* an archive_read_disk to an
* archive_write that we use for
* copying data from an archive_read
* to an archive_write_disk.
* Unfortunately, this doesn't quite
* work yet. */
copy_data(disk, a);
#else
/* For now, we use a simpler loop to copy data
* into the target archive. */
fd = open(archive_entry_sourcepath(entry), O_RDONLY);
len = read(fd, buff, sizeof(buff));
while (len > 0) {
archive_write_data(a, buff, len);
len = read(fd, buff, sizeof(buff));
}
close(fd);
#endif
}
close(fd);
archive_entry_free(entry);
if (verbose)
if (needcr)
msg("\n");
}
archive_read_close(disk);
archive_read_free(disk);
argv++;
}
archive_write_close(a);
archive_write_finish(a);
archive_write_free(a);
}
#endif
@ -305,13 +342,13 @@ extract(const char *filename, int do_extract, int flags)
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
#ifndef NO_BZIP2_EXTRACT
archive_read_support_compression_bzip2(a);
archive_read_support_filter_bzip2(a);
#endif
#ifndef NO_GZIP_EXTRACT
archive_read_support_compression_gzip(a);
archive_read_support_filter_gzip(a);
#endif
#ifndef NO_COMPRESS_EXTRACT
archive_read_support_compression_compress(a);
archive_read_support_filter_compress(a);
#endif
#ifndef NO_TAR_EXTRACT
archive_read_support_format_tar(a);
@ -353,7 +390,7 @@ extract(const char *filename, int do_extract, int flags)
msg("\n");
}
archive_read_close(a);
archive_read_finish(a);
archive_read_free(a);
exit(0);
}

View File

@ -1,423 +0,0 @@
/*-
* Copyright (c) 2003-2004 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
* in this position and unchanged.
* 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.
*/
/*-
* There is a single list of "tree_entry" items that represent
* filesystem objects that require further attention. Non-directories
* are not kept in memory: they are pulled from readdir(), returned to
* the client, then freed as soon as possible. Any directory entry to
* be traversed gets pushed onto the stack.
*
* There is surprisingly little information that needs to be kept for
* each item on the stack. Just the name, depth (represented here as the
* string length of the parent directory's pathname), and some markers
* indicating how to get back to the parent (via chdir("..") for a
* regular dir or via fchdir(2) for a symlink).
*/
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tree.h"
/*
* TODO:
* 1) Loop checking.
* 3) Arbitrary logical traversals by closing/reopening intermediate fds.
*/
struct tree_entry {
struct tree_entry *next;
char *name;
size_t dirname_length;
int fd;
int flags;
};
/* Definitions for tree_entry.flags bitmap. */
#define isDir 1 /* This entry is a regular directory. */
#define isDirLink 2 /* This entry is a symbolic link to a directory. */
#define needsTraversal 4 /* This entry hasn't yet been traversed. */
/*
* Local data for this package.
*/
struct tree {
struct tree_entry *stack;
DIR *d;
int initialDirFd;
int flags;
char *buff;
char *basename;
size_t buff_length;
size_t path_length;
size_t dirname_length;
int depth;
int openCount;
int maxOpenCount;
struct stat lst;
struct stat st;
};
/* Definitions for tree.flags bitmap. */
#define needsReturn 8 /* Marks first entry as not having been returned yet. */
#define hasStat 16 /* The st entry is set. */
#define hasLstat 32 /* The lst entry is set. */
#define HAVE_DIRENT_D_NAMLEN 1
#ifdef HAVE_DIRENT_D_NAMLEN
/* BSD extension; avoids need for a strlen() call. */
#define D_NAMELEN(dp) (dp)->d_namlen
#else
#define D_NAMELEN(dp) (strlen((dp)->d_name))
#endif
#if 0
static void
dumpStack(struct tree *t)
{
struct tree_entry *te;
printf("\tbuff: %s\n", t->buff);
printf("\tpwd: "); fflush(stdout); system("pwd");
printf("\tstack:\n");
for (te = t->stack; te != NULL; te = te->next) {
printf("\t\tte->name: %s %s\n", te->name, te->flags & needsTraversal ? "" : "*");
}
}
#endif
/*
* Add a directory path to the current stack.
*/
static void
tree_add(struct tree *t, const char *path)
{
struct tree_entry *te;
te = malloc(sizeof(*te));
memset(te, 0, sizeof(*te));
te->next = t->stack;
t->stack = te;
te->fd = -1;
te->name = strdup(path);
te->flags = needsTraversal;
te->dirname_length = t->dirname_length;
}
/*
* Append a name to the current path.
*/
static void
tree_append(struct tree *t, const char *name, size_t name_length)
{
if (t->buff != NULL)
t->buff[t->dirname_length] = '\0';
/* Resize pathname buffer as needed. */
while (name_length + 1 + t->dirname_length >= t->buff_length) {
t->buff_length *= 2;
if (t->buff_length < 1024)
t->buff_length = 1024;
t->buff = realloc(t->buff, t->buff_length);
}
t->basename = t->buff + t->dirname_length;
t->path_length = t->dirname_length + name_length;
if (t->dirname_length > 0) {
*t->basename++ = '/';
t->path_length ++;
}
strcpy(t->basename, name);
}
/*
* Open a directory tree for traversal.
*/
struct tree *
tree_open(const char *path)
{
struct tree *t;
t = malloc(sizeof(*t));
memset(t, 0, sizeof(*t));
tree_append(t, path, strlen(path));
t->initialDirFd = open(".", O_RDONLY);
/*
* During most of the traversal, items are set up and then
* returned immediately from tree_next(). That doesn't work
* for the very first entry, so we set a flag for this special
* case.
*/
t->flags = needsReturn;
return (t);
}
/*
* We've finished a directory; ascend back to the parent.
*/
static void
tree_ascend(struct tree *t)
{
struct tree_entry *te;
te = t->stack;
t->depth--;
if (te->flags & isDirLink) {
fchdir(te->fd);
close(te->fd);
t->openCount--;
} else {
chdir("..");
}
}
/*
* Pop the working stack.
*/
static void
tree_pop(struct tree *t)
{
struct tree_entry *te;
te = t->stack;
t->stack = te->next;
t->dirname_length = te->dirname_length;
free(te->name);
free(te);
}
/*
* Get the next item in the tree traversal.
*/
int
tree_next(struct tree *t)
{
struct dirent *de = NULL;
/* Handle the startup case by returning the initial entry. */
if (t->flags & needsReturn) {
t->flags &= ~needsReturn;
return (1);
}
while (t->stack != NULL) {
/* If there's an open dir, get the next entry from there. */
while (t->d != NULL) {
de = readdir(t->d);
if (de == NULL) {
closedir(t->d);
t->d = NULL;
} else if (de->d_name[0] == '.'
&& de->d_name[1] == '\0') {
/* Skip '.' */
} else if (de->d_name[0] == '.'
&& de->d_name[1] == '.'
&& de->d_name[2] == '\0') {
/* Skip '..' */
} else {
/*
* Append the path to the current path
* and return it.
*/
tree_append(t, de->d_name, D_NAMELEN(de));
t->flags &= ~hasLstat;
t->flags &= ~hasStat;
return (1);
}
}
/* If the current dir needs to be traversed, set it up. */
if (t->stack->flags & needsTraversal) {
tree_append(t, t->stack->name, strlen(t->stack->name));
t->stack->flags &= ~needsTraversal;
/* If it is a link, set up fd for the ascent. */
if (t->stack->flags & isDirLink) {
t->stack->fd = open(".", O_RDONLY);
t->openCount++;
if (t->openCount > t->maxOpenCount)
t->maxOpenCount = t->openCount;
}
if (chdir(t->stack->name) == 0) {
t->depth++;
t->dirname_length = t->path_length;
t->d = opendir(".");
} else
tree_pop(t);
continue;
}
/* We've done everything necessary for the top stack entry. */
tree_ascend(t);
tree_pop(t);
}
return (0);
}
/*
* Called by the client to mark the directory just returned from
* tree_next() as needing to be visited.
*/
void
tree_descend(struct tree *t)
{
const struct stat *s = tree_current_lstat(t);
if (S_ISDIR(s->st_mode)) {
tree_add(t, t->basename);
t->stack->flags |= isDir;
}
if (S_ISLNK(s->st_mode) && S_ISDIR(tree_current_stat(t)->st_mode)) {
tree_add(t, t->basename);
t->stack->flags |= isDirLink;
}
}
/*
* Get the stat() data for the entry just returned from tree_next().
*/
const struct stat *
tree_current_stat(struct tree *t)
{
if (!(t->flags & hasStat)) {
stat(t->basename, &t->st);
t->flags |= hasStat;
}
return (&t->st);
}
/*
* Get the lstat() data for the entry just returned from tree_next().
*/
const struct stat *
tree_current_lstat(struct tree *t)
{
if (!(t->flags & hasLstat)) {
lstat(t->basename, &t->lst);
t->flags |= hasLstat;
}
return (&t->lst);
}
/*
* Return the access path for the entry just returned from tree_next().
*/
const char *
tree_current_access_path(struct tree *t)
{
return (t->basename);
}
/*
* Return the full path for the entry just returned from tree_next().
*/
const char *
tree_current_path(struct tree *t)
{
return (t->buff);
}
/*
* Return the length of the path for the entry just returned from tree_next().
*/
size_t
tree_current_pathlen(struct tree *t)
{
return (t->path_length);
}
/*
* Return the nesting depth of the entry just returned from tree_next().
*/
int
tree_current_depth(struct tree *t)
{
return (t->depth);
}
/*
* Terminate the traversal and release any resources.
*/
void
tree_close(struct tree *t)
{
/* Release anything remaining in the stack. */
while (t->stack != NULL)
tree_pop(t);
if (t->buff)
free(t->buff);
/* chdir() back to where we started. */
if (t->initialDirFd >= 0) {
fchdir(t->initialDirFd);
close(t->initialDirFd);
t->initialDirFd = -1;
}
free(t);
}
#if 0
/* Main function for testing. */
#include <stdio.h>
int main(int argc, char **argv)
{
size_t max_path_len = 0;
int max_depth = 0;
system("pwd");
while (*++argv) {
struct tree *t = tree_open(*argv);
while (tree_next(t)) {
size_t path_len = tree_current_pathlen(t);
int depth = tree_current_depth(t);
if (path_len > max_path_len)
max_path_len = path_len;
if (depth > max_depth)
max_depth = depth;
printf("%s\n", tree_current_path(t));
if (S_ISDIR(tree_current_lstat(t)->st_mode))
tree_descend(t); /* Descend into every dir. */
}
tree_close(t);
printf("Max path length: %d\n", max_path_len);
printf("Max depth: %d\n", max_depth);
printf("Final open count: %d\n", t->openCount);
printf("Max open count: %d\n", t->maxOpenCount);
fflush(stdout);
system("pwd");
}
return (0);
}
#endif

View File

@ -1,78 +0,0 @@
/*-
* Copyright (c) 2003-2004 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
* in this position and unchanged.
* 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.
*/
/*-
* A set of routines for traversing directory trees.
* Similar in concept to the fts library, but with a few
* important differences:
* * Uses less memory. In particular, fts stores an entire directory
* in memory at a time. This package only keeps enough subdirectory
* information in memory to track the traversal. Information
* about non-directories is discarded as soon as possible.
* * Supports very deep logical traversals. The fts package
* uses "non-chdir" approach for logical traversals. This
* package does use a chdir approach for logical traversals
* and can therefore handle pathnames much longer than
* PATH_MAX.
* * Supports deep physical traversals "out of the box."
* Due to the memory optimizations above, there's no need to
* limit dir names to 32k.
*/
#include <sys/stat.h>
struct tree;
struct tree *tree_open(const char *);
/* Returns TRUE if there is a next entry. Zero if there is no next entry. */
int tree_next(struct tree *);
/* Return information about the current entry. */
int tree_current_depth(struct tree *);
/*
* The current full pathname, length of the full pathname,
* and a name that can be used to access the file.
* Because tree does use chdir extensively, the access path is
* almost never the same as the full current path.
*/
const char *tree_current_path(struct tree *);
size_t tree_current_pathlen(struct tree *);
const char *tree_current_access_path(struct tree *);
/*
* Request the lstat() or stat() data for the current path.
* Since the tree package needs to do some of this anyway,
* you should take advantage of it here if you need it.
*/
const struct stat *tree_current_stat(struct tree *);
const struct stat *tree_current_lstat(struct tree *);
/*
* Request that current entry be visited. If you invoke it on every
* directory, you'll get a physical traversal. This is ignored if the
* current entry isn't a directory or a link to a directory. So, if
* you invoke this on every returned path, you'll get a full logical
* traversal.
*/
void tree_descend(struct tree *);
void tree_close(struct tree *);

View File

@ -49,7 +49,7 @@ main(int argc, char **argv)
ina = archive_read_new();
if (ina == NULL)
die("Couldn't create archive reader.");
if (archive_read_support_compression_all(ina) != ARCHIVE_OK)
if (archive_read_support_filter_all(ina) != ARCHIVE_OK)
die("Couldn't enable decompression");
if (archive_read_support_format_all(ina) != ARCHIVE_OK)
die("Couldn't enable read formats");
@ -105,9 +105,9 @@ main(int argc, char **argv)
if (r != ARCHIVE_EOF)
die("Error reading archive");
/* Close the archives. */
if (archive_read_finish(ina) != ARCHIVE_OK)
if (archive_read_free(ina) != ARCHIVE_OK)
die("Error closing input archive");
if (archive_write_finish(outa) != ARCHIVE_OK)
if (archive_write_free(outa) != ARCHIVE_OK)
die("Error closing output archive");
return (0);
}

View File

@ -190,7 +190,7 @@ extract(const char *filename, int do_extract, int flags)
msg("\n");
}
archive_read_close(a);
archive_read_finish(a);
archive_read_free(a);
exit(0);
}
@ -200,7 +200,11 @@ copy_data(struct archive *ar, struct archive *aw)
int r;
const void *buff;
size_t size;
#if ARCHIVE_VERSION >= 3000000
int64_t offset;
#else
off_t offset;
#endif
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);

View File

@ -13,23 +13,34 @@ SET(include_HEADERS
# Sources and private headers
SET(libarchive_SOURCES
archive_acl.c
archive_check_magic.c
archive_crypto.c
archive_crypto_private.h
archive_endian.h
archive_entry.c
archive_entry.h
archive_entry_copy_stat.c
archive_entry_link_resolver.c
archive_entry_locale.h
archive_entry_private.h
archive_entry_sparse.c
archive_entry_stat.c
archive_entry_strmode.c
archive_entry_xattr.c
archive_hash.h
archive_options.c
archive_options_private.h
archive_platform.h
archive_ppmd_private.h
archive_ppmd7.c
archive_ppmd7_private.h
archive_private.h
archive_rb.c
archive_rb.h
archive_read.c
archive_read_data_into_fd.c
archive_read_disk.c
archive_read_disk_entry_from_file.c
archive_read_disk_posix.c
archive_read_disk_private.h
archive_read_disk_set_standard_lookup.c
archive_read_extract.c
@ -38,32 +49,39 @@ SET(libarchive_SOURCES
archive_read_open_filename.c
archive_read_open_memory.c
archive_read_private.h
archive_read_support_compression_all.c
archive_read_support_compression_bzip2.c
archive_read_support_compression_compress.c
archive_read_support_compression_gzip.c
archive_read_support_compression_none.c
archive_read_support_compression_program.c
archive_read_support_compression_rpm.c
archive_read_support_compression_uu.c
archive_read_support_compression_xz.c
archive_read_set_options.c
archive_read_support_filter_all.c
archive_read_support_filter_bzip2.c
archive_read_support_filter_compress.c
archive_read_support_filter_gzip.c
archive_read_support_filter_none.c
archive_read_support_filter_program.c
archive_read_support_filter_rpm.c
archive_read_support_filter_uu.c
archive_read_support_filter_xz.c
archive_read_support_format_7zip.c
archive_read_support_format_all.c
archive_read_support_format_ar.c
archive_read_support_format_by_code.c
archive_read_support_format_cab.c
archive_read_support_format_cpio.c
archive_read_support_format_empty.c
archive_read_support_format_iso9660.c
archive_read_support_format_lha.c
archive_read_support_format_mtree.c
archive_read_support_format_rar.c
archive_read_support_format_raw.c
archive_read_support_format_tar.c
archive_read_support_format_xar.c
archive_read_support_format_zip.c
archive_string.c
archive_string.h
archive_string_composition.h
archive_string_sprintf.c
archive_util.c
archive_virtual.c
archive_write.c
archive_write_disk.c
archive_write_disk_posix.c
archive_write_disk_private.h
archive_write_disk_set_standard_lookup.c
archive_write_private.h
@ -71,22 +89,27 @@ SET(libarchive_SOURCES
archive_write_open_file.c
archive_write_open_filename.c
archive_write_open_memory.c
archive_write_set_compression_bzip2.c
archive_write_set_compression_compress.c
archive_write_set_compression_gzip.c
archive_write_set_compression_none.c
archive_write_set_compression_program.c
archive_write_set_compression_xz.c
archive_write_add_filter_bzip2.c
archive_write_add_filter_compress.c
archive_write_add_filter_gzip.c
archive_write_add_filter_none.c
archive_write_add_filter_program.c
archive_write_add_filter_xz.c
archive_write_set_format.c
archive_write_set_format_7zip.c
archive_write_set_format_ar.c
archive_write_set_format_by_name.c
archive_write_set_format_cpio.c
archive_write_set_format_cpio_newc.c
archive_write_set_format_gnutar.c
archive_write_set_format_iso9660.c
archive_write_set_format_mtree.c
archive_write_set_format_pax.c
archive_write_set_format_shar.c
archive_write_set_format_ustar.c
archive_write_set_format_xar.c
archive_write_set_format_zip.c
archive_write_set_options.c
filter_fork.c
filter_fork.h
)
@ -94,11 +117,19 @@ SET(libarchive_SOURCES
# Man pages
SET(libarchive_MANS
archive_entry.3
archive_entry_acl.3
archive_entry_linkify.3
archive_entry_paths.3
archive_entry_perms.3
archive_entry_stat.3
archive_entry_time.3
archive_read.3
archive_read_disk.3
archive_read_set_options.3
archive_util.3
archive_write.3
archive_write_disk.3
archive_write_set_options.3
cpio.5
libarchive.3
libarchive_internals.3
@ -109,8 +140,10 @@ SET(libarchive_MANS
IF(WIN32 AND NOT CYGWIN)
LIST(APPEND libarchive_SOURCES archive_entry_copy_bhfi.c)
LIST(APPEND libarchive_SOURCES archive_read_disk_windows.c)
LIST(APPEND libarchive_SOURCES archive_windows.c)
LIST(APPEND libarchive_SOURCES archive_windows.h)
LIST(APPEND libarchive_SOURCES archive_write_disk_windows.c)
LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
ENDIF(WIN32 AND NOT CYGWIN)

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -28,6 +28,10 @@
#ifndef ARCHIVE_H_INCLUDED
#define ARCHIVE_H_INCLUDED
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
#include <stdio.h> /* For FILE * */
/*
* Note: archive.h is for use outside of libarchive; the configuration
* headers (config.h, archive_platform.h, etc.) are purely internal.
@ -36,22 +40,15 @@
* platform macros.
*/
#if defined(__BORLANDC__) && __BORLANDC__ >= 0x560
# define __LA_STDINT_H <stdint.h>
#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__)
# define __LA_STDINT_H <inttypes.h>
# include <stdint.h>
#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS)
# include <inttypes.h>
#endif
#include <sys/stat.h>
#include <sys/types.h> /* Linux requires this for off_t */
#ifdef __LA_STDINT_H
# include __LA_STDINT_H /* int64_t, etc. */
#endif
#include <stdio.h> /* For FILE * */
/* Get appropriate definitions of standard POSIX-style types. */
/* These should match the types used in 'struct stat' */
#if defined(_WIN32) && !defined(__CYGWIN__)
#define __LA_INT64_T __int64
# define __LA_INT64_T __int64
# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
# define __LA_SSIZE_T ssize_t
# elif defined(_WIN64)
@ -67,11 +64,15 @@
# define __LA_GID_T short
# endif
#else
#include <unistd.h> /* ssize_t, uid_t, and gid_t */
#define __LA_INT64_T int64_t
#define __LA_SSIZE_T ssize_t
#define __LA_UID_T uid_t
#define __LA_GID_T gid_t
# include <unistd.h> /* ssize_t, uid_t, and gid_t */
# if defined(_SCO_DS)
# define __LA_INT64_T long long
# else
# define __LA_INT64_T int64_t
# endif
# define __LA_SSIZE_T ssize_t
# define __LA_UID_T uid_t
# define __LA_GID_T gid_t
#endif
/*
@ -88,7 +89,7 @@
# endif
# else
# ifdef __GNUC__
# define __LA_DECL __attribute__((dllimport)) extern
# define __LA_DECL
# else
# define __LA_DECL __declspec(dllimport)
# endif
@ -98,7 +99,7 @@
# define __LA_DECL
#endif
#if defined(__GNUC__) && __GNUC__ >= 3
#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__MINGW32__)
#define __LA_PRINTF(fmtarg, firstvararg) \
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
#else
@ -123,50 +124,18 @@ extern "C" {
* easy to compare versions at build time: for version a.b.c, the
* version number is printf("%d%03d%03d",a,b,c). For example, if you
* know your application requires version 2.12.108 or later, you can
* assert that ARCHIVE_VERSION >= 2012108.
*
* This single-number format was introduced with libarchive 1.9.0 in
* the libarchive 1.x family and libarchive 2.2.4 in the libarchive
* 2.x family. The following may be useful if you really want to do
* feature detection for earlier libarchive versions (which defined
* ARCHIVE_API_VERSION and ARCHIVE_API_FEATURE instead):
*
* #ifndef ARCHIVE_VERSION_NUMBER
* #define ARCHIVE_VERSION_NUMBER \
* (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000)
* #endif
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
#define ARCHIVE_VERSION_NUMBER 2008005
/* Note: Compiler will complain if this does not match archive_entry.h! */
#define ARCHIVE_VERSION_NUMBER 3000003
__LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
#define ARCHIVE_VERSION_STRING "libarchive 2.8.5"
#define ARCHIVE_VERSION_STRING "libarchive 3.0.3"
__LA_DECL const char * archive_version_string(void);
#if ARCHIVE_VERSION_NUMBER < 3000000
/*
* Deprecated; these are older names that will be removed in favor of
* the simpler definitions above.
*/
#define ARCHIVE_VERSION_STAMP ARCHIVE_VERSION_NUMBER
__LA_DECL int archive_version_stamp(void);
#define ARCHIVE_LIBRARY_VERSION ARCHIVE_VERSION_STRING
__LA_DECL const char * archive_version(void);
#define ARCHIVE_API_VERSION (ARCHIVE_VERSION_NUMBER / 1000000)
__LA_DECL int archive_api_version(void);
#define ARCHIVE_API_FEATURE ((ARCHIVE_VERSION_NUMBER / 1000) % 1000)
__LA_DECL int archive_api_feature(void);
#endif
#if ARCHIVE_VERSION_NUMBER < 3000000
/* This should never have been here in the first place. */
/* Legacy of old tar assumptions, will be removed in libarchive 3.0. */
#define ARCHIVE_BYTES_PER_RECORD 512
#define ARCHIVE_DEFAULT_BYTES_PER_BLOCK 10240
#endif
/* Declare our basic types. */
struct archive;
struct archive_entry;
@ -210,48 +179,56 @@ struct archive_entry;
typedef __LA_SSIZE_T archive_read_callback(struct archive *,
void *_client_data, const void **_buffer);
/* Skips at most request bytes from archive and returns the skipped amount */
#if ARCHIVE_VERSION_NUMBER < 2000000
/* Libarchive 1.0 used ssize_t for the return, which is only 32 bits
* on most 32-bit platforms; not large enough. */
typedef __LA_SSIZE_T archive_skip_callback(struct archive *,
void *_client_data, size_t request);
#elif ARCHIVE_VERSION_NUMBER < 3000000
/* Libarchive 2.0 used off_t here, but that is a bad idea on Linux and a
* few other platforms where off_t varies with build settings. */
typedef off_t archive_skip_callback(struct archive *,
void *_client_data, off_t request);
#else
/* Libarchive 3.0 uses int64_t here, which is actually guaranteed to be
* 64 bits on every platform. */
/* Skips at most request bytes from archive and returns the skipped amount.
* This may skip fewer bytes than requested; it may even skip zero bytes.
* If you do skip fewer bytes than requested, libarchive will invoke your
* read callback and discard data as necessary to make up the full skip.
*/
typedef __LA_INT64_T archive_skip_callback(struct archive *,
void *_client_data, __LA_INT64_T request);
#endif
/* Seeks to specified location in the file and returns the position.
* Whence values are SEEK_SET, SEEK_CUR, SEEK_END from stdio.h.
* Return ARCHIVE_FATAL if the seek fails for any reason.
*/
typedef __LA_INT64_T archive_seek_callback(struct archive *,
void *_client_data, __LA_INT64_T offset, int whence);
/* Returns size actually written, zero on EOF, -1 on error. */
typedef __LA_SSIZE_T archive_write_callback(struct archive *,
void *_client_data,
const void *_buffer, size_t _length);
#if ARCHIVE_VERSION_NUMBER < 3000000
/* Open callback is actually never needed; remove it in libarchive 3.0. */
typedef int archive_open_callback(struct archive *, void *_client_data);
#endif
typedef int archive_close_callback(struct archive *, void *_client_data);
/*
* Codes for archive_compression.
* Codes to identify various stream filters.
*/
#define ARCHIVE_COMPRESSION_NONE 0
#define ARCHIVE_COMPRESSION_GZIP 1
#define ARCHIVE_COMPRESSION_BZIP2 2
#define ARCHIVE_COMPRESSION_COMPRESS 3
#define ARCHIVE_COMPRESSION_PROGRAM 4
#define ARCHIVE_COMPRESSION_LZMA 5
#define ARCHIVE_COMPRESSION_XZ 6
#define ARCHIVE_COMPRESSION_UU 7
#define ARCHIVE_COMPRESSION_RPM 8
#define ARCHIVE_FILTER_NONE 0
#define ARCHIVE_FILTER_GZIP 1
#define ARCHIVE_FILTER_BZIP2 2
#define ARCHIVE_FILTER_COMPRESS 3
#define ARCHIVE_FILTER_PROGRAM 4
#define ARCHIVE_FILTER_LZMA 5
#define ARCHIVE_FILTER_XZ 6
#define ARCHIVE_FILTER_UU 7
#define ARCHIVE_FILTER_RPM 8
#define ARCHIVE_FILTER_LZIP 9
#if ARCHIVE_VERSION_NUMBER < 4000000
#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE
#define ARCHIVE_COMPRESSION_GZIP ARCHIVE_FILTER_GZIP
#define ARCHIVE_COMPRESSION_BZIP2 ARCHIVE_FILTER_BZIP2
#define ARCHIVE_COMPRESSION_COMPRESS ARCHIVE_FILTER_COMPRESS
#define ARCHIVE_COMPRESSION_PROGRAM ARCHIVE_FILTER_PROGRAM
#define ARCHIVE_COMPRESSION_LZMA ARCHIVE_FILTER_LZMA
#define ARCHIVE_COMPRESSION_XZ ARCHIVE_FILTER_XZ
#define ARCHIVE_COMPRESSION_UU ARCHIVE_FILTER_UU
#define ARCHIVE_COMPRESSION_RPM ARCHIVE_FILTER_RPM
#define ARCHIVE_COMPRESSION_LZIP ARCHIVE_FILTER_LZIP
#endif
/*
* Codes returned by archive_format.
@ -265,7 +242,7 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
* will change the format code to indicate the extended format that
* was used). In other cases, it's because different tools have
* modified the archive and so different parts of the archive
* actually have slightly different formts. (Both tar and cpio store
* actually have slightly different formats. (Both tar and cpio store
* format codes in each entry, so it is quite possible for each
* entry to be in a different format.)
*/
@ -276,6 +253,7 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
#define ARCHIVE_FORMAT_CPIO_BIN_BE (ARCHIVE_FORMAT_CPIO | 3)
#define ARCHIVE_FORMAT_CPIO_SVR4_NOCRC (ARCHIVE_FORMAT_CPIO | 4)
#define ARCHIVE_FORMAT_CPIO_SVR4_CRC (ARCHIVE_FORMAT_CPIO | 5)
#define ARCHIVE_FORMAT_CPIO_AFIO_LARGE (ARCHIVE_FORMAT_CPIO | 6)
#define ARCHIVE_FORMAT_SHAR 0x20000
#define ARCHIVE_FORMAT_SHAR_BASE (ARCHIVE_FORMAT_SHAR | 1)
#define ARCHIVE_FORMAT_SHAR_DUMP (ARCHIVE_FORMAT_SHAR | 2)
@ -294,6 +272,10 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
#define ARCHIVE_FORMAT_MTREE 0x80000
#define ARCHIVE_FORMAT_RAW 0x90000
#define ARCHIVE_FORMAT_XAR 0xA0000
#define ARCHIVE_FORMAT_LHA 0xB0000
#define ARCHIVE_FORMAT_CAB 0xC0000
#define ARCHIVE_FORMAT_RAR 0xD0000
#define ARCHIVE_FORMAT_7ZIP 0xE0000
/*-
* Basic outline for reading an archive:
@ -316,40 +298,81 @@ __LA_DECL struct archive *archive_read_new(void);
* support_compression_bzip2(). The "all" functions provide the
* obvious shorthand.
*/
__LA_DECL int archive_read_support_compression_all(struct archive *);
__LA_DECL int archive_read_support_compression_bzip2(struct archive *);
__LA_DECL int archive_read_support_compression_compress(struct archive *);
__LA_DECL int archive_read_support_compression_gzip(struct archive *);
__LA_DECL int archive_read_support_compression_lzma(struct archive *);
__LA_DECL int archive_read_support_compression_none(struct archive *);
__LA_DECL int archive_read_support_compression_program(struct archive *,
#if ARCHIVE_VERSION_NUMBER < 4000000
__LA_DECL int archive_read_support_compression_all(struct archive *);
__LA_DECL int archive_read_support_compression_bzip2(struct archive *);
__LA_DECL int archive_read_support_compression_compress(struct archive *);
__LA_DECL int archive_read_support_compression_gzip(struct archive *);
__LA_DECL int archive_read_support_compression_lzip(struct archive *);
__LA_DECL int archive_read_support_compression_lzma(struct archive *);
__LA_DECL int archive_read_support_compression_none(struct archive *);
__LA_DECL int archive_read_support_compression_program(struct archive *,
const char *command);
__LA_DECL int archive_read_support_compression_program_signature
(struct archive *, const char *,
__LA_DECL int archive_read_support_compression_program_signature
(struct archive *, const char *,
const void * /* match */, size_t);
__LA_DECL int archive_read_support_compression_rpm(struct archive *);
__LA_DECL int archive_read_support_compression_uu(struct archive *);
__LA_DECL int archive_read_support_compression_xz(struct archive *);
__LA_DECL int archive_read_support_compression_rpm(struct archive *);
__LA_DECL int archive_read_support_compression_uu(struct archive *);
__LA_DECL int archive_read_support_compression_xz(struct archive *);
#endif
__LA_DECL int archive_read_support_format_all(struct archive *);
__LA_DECL int archive_read_support_format_ar(struct archive *);
__LA_DECL int archive_read_support_format_cpio(struct archive *);
__LA_DECL int archive_read_support_format_empty(struct archive *);
__LA_DECL int archive_read_support_format_gnutar(struct archive *);
__LA_DECL int archive_read_support_format_iso9660(struct archive *);
__LA_DECL int archive_read_support_format_mtree(struct archive *);
__LA_DECL int archive_read_support_format_raw(struct archive *);
__LA_DECL int archive_read_support_format_tar(struct archive *);
__LA_DECL int archive_read_support_format_xar(struct archive *);
__LA_DECL int archive_read_support_format_zip(struct archive *);
__LA_DECL int archive_read_support_filter_all(struct archive *);
__LA_DECL int archive_read_support_filter_bzip2(struct archive *);
__LA_DECL int archive_read_support_filter_compress(struct archive *);
__LA_DECL int archive_read_support_filter_gzip(struct archive *);
__LA_DECL int archive_read_support_filter_lzip(struct archive *);
__LA_DECL int archive_read_support_filter_lzma(struct archive *);
__LA_DECL int archive_read_support_filter_none(struct archive *);
__LA_DECL int archive_read_support_filter_program(struct archive *,
const char *command);
__LA_DECL int archive_read_support_filter_program_signature
(struct archive *, const char *,
const void * /* match */, size_t);
__LA_DECL int archive_read_support_filter_rpm(struct archive *);
__LA_DECL int archive_read_support_filter_uu(struct archive *);
__LA_DECL int archive_read_support_filter_xz(struct archive *);
/* Open the archive using callbacks for archive I/O. */
__LA_DECL int archive_read_open(struct archive *, void *_client_data,
__LA_DECL int archive_read_support_format_7zip(struct archive *);
__LA_DECL int archive_read_support_format_all(struct archive *);
__LA_DECL int archive_read_support_format_ar(struct archive *);
__LA_DECL int archive_read_support_format_by_code(struct archive *, int);
__LA_DECL int archive_read_support_format_cab(struct archive *);
__LA_DECL int archive_read_support_format_cpio(struct archive *);
__LA_DECL int archive_read_support_format_empty(struct archive *);
__LA_DECL int archive_read_support_format_gnutar(struct archive *);
__LA_DECL int archive_read_support_format_iso9660(struct archive *);
__LA_DECL int archive_read_support_format_lha(struct archive *);
__LA_DECL int archive_read_support_format_mtree(struct archive *);
__LA_DECL int archive_read_support_format_rar(struct archive *);
__LA_DECL int archive_read_support_format_raw(struct archive *);
__LA_DECL int archive_read_support_format_tar(struct archive *);
__LA_DECL int archive_read_support_format_xar(struct archive *);
__LA_DECL int archive_read_support_format_zip(struct archive *);
/* Set various callbacks. */
__LA_DECL int archive_read_set_open_callback(struct archive *,
archive_open_callback *);
__LA_DECL int archive_read_set_read_callback(struct archive *,
archive_read_callback *);
__LA_DECL int archive_read_set_seek_callback(struct archive *,
archive_seek_callback *);
__LA_DECL int archive_read_set_skip_callback(struct archive *,
archive_skip_callback *);
__LA_DECL int archive_read_set_close_callback(struct archive *,
archive_close_callback *);
/* The callback data is provided to all of the callbacks above. */
__LA_DECL int archive_read_set_callback_data(struct archive *, void *);
/* Opening freezes the callbacks. */
__LA_DECL int archive_read_open1(struct archive *);
/* Convenience wrappers around the above. */
__LA_DECL int archive_read_open(struct archive *, void *_client_data,
archive_open_callback *, archive_read_callback *,
archive_close_callback *);
__LA_DECL int archive_read_open2(struct archive *, void *_client_data,
__LA_DECL int archive_read_open2(struct archive *, void *_client_data,
archive_open_callback *, archive_read_callback *,
archive_skip_callback *, archive_close_callback *);
@ -359,30 +382,32 @@ __LA_DECL int archive_read_open2(struct archive *, void *_client_data,
* accept a block size handle tape blocking correctly.
*/
/* Use this if you know the filename. Note: NULL indicates stdin. */
__LA_DECL int archive_read_open_filename(struct archive *,
__LA_DECL int archive_read_open_filename(struct archive *,
const char *_filename, size_t _block_size);
__LA_DECL int archive_read_open_filename_w(struct archive *,
const wchar_t *_filename, size_t _block_size);
/* archive_read_open_file() is a deprecated synonym for ..._open_filename(). */
__LA_DECL int archive_read_open_file(struct archive *,
__LA_DECL int archive_read_open_file(struct archive *,
const char *_filename, size_t _block_size);
/* Read an archive that's stored in memory. */
__LA_DECL int archive_read_open_memory(struct archive *,
__LA_DECL int archive_read_open_memory(struct archive *,
void * buff, size_t size);
/* A more involved version that is only used for internal testing. */
__LA_DECL int archive_read_open_memory2(struct archive *a, void *buff,
__LA_DECL int archive_read_open_memory2(struct archive *a, void *buff,
size_t size, size_t read_size);
/* Read an archive that's already open, using the file descriptor. */
__LA_DECL int archive_read_open_fd(struct archive *, int _fd,
__LA_DECL int archive_read_open_fd(struct archive *, int _fd,
size_t _block_size);
/* Read an archive that's already open, using a FILE *. */
/* Note: DO NOT use this with tape drives. */
__LA_DECL int archive_read_open_FILE(struct archive *, FILE *_file);
__LA_DECL int archive_read_open_FILE(struct archive *, FILE *_file);
/* Parses and returns next entry header. */
__LA_DECL int archive_read_next_header(struct archive *,
__LA_DECL int archive_read_next_header(struct archive *,
struct archive_entry **);
/* Parses and returns next entry header using the archive_entry passed in */
__LA_DECL int archive_read_next_header2(struct archive *,
__LA_DECL int archive_read_next_header2(struct archive *,
struct archive_entry *);
/*
@ -401,14 +426,8 @@ __LA_DECL __LA_SSIZE_T archive_read_data(struct archive *,
* the desired size of the block. The API does guarantee that offsets will
* be strictly increasing and that returned blocks will not overlap.
*/
#if ARCHIVE_VERSION_NUMBER < 3000000
__LA_DECL int archive_read_data_block(struct archive *a,
const void **buff, size_t *size, off_t *offset);
#else
__LA_DECL int archive_read_data_block(struct archive *a,
const void **buff, size_t *size,
__LA_INT64_T *offset);
#endif
__LA_DECL int archive_read_data_block(struct archive *a,
const void **buff, size_t *size, __LA_INT64_T *offset);
/*-
* Some convenience functions that are built on archive_read_data:
@ -416,23 +435,27 @@ __LA_DECL int archive_read_data_block(struct archive *a,
* 'into_buffer': writes data into memory buffer that you provide
* 'into_fd': writes data to specified filedes
*/
__LA_DECL int archive_read_data_skip(struct archive *);
__LA_DECL int archive_read_data_into_buffer(struct archive *,
void *buffer, __LA_SSIZE_T len);
__LA_DECL int archive_read_data_into_fd(struct archive *, int fd);
__LA_DECL int archive_read_data_skip(struct archive *);
__LA_DECL int archive_read_data_into_fd(struct archive *, int fd);
/*
* Set read options.
*/
/* Apply option string to the format only. */
__LA_DECL int archive_read_set_format_options(struct archive *_a,
const char *s);
/* Apply option string to the filter only. */
__LA_DECL int archive_read_set_filter_options(struct archive *_a,
const char *s);
/* Apply option to the format only. */
__LA_DECL int archive_read_set_format_option(struct archive *_a,
const char *m, const char *o,
const char *v);
/* Apply option to the filter only. */
__LA_DECL int archive_read_set_filter_option(struct archive *_a,
const char *m, const char *o,
const char *v);
/* Apply option to both the format and the filter. */
__LA_DECL int archive_read_set_option(struct archive *_a,
const char *m, const char *o,
const char *v);
/* Apply option string to both the format and the filter. */
__LA_DECL int archive_read_set_options(struct archive *_a,
const char *s);
__LA_DECL int archive_read_set_options(struct archive *_a,
const char *opts);
/*-
* Convenience function to recreate the current entry (whose header
@ -477,10 +500,13 @@ __LA_DECL int archive_read_set_options(struct archive *_a,
#define ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER (0x0800)
/* Detect blocks of 0 and write holes instead. */
#define ARCHIVE_EXTRACT_SPARSE (0x1000)
/* Default: Do not restore Mac extended metadata. */
/* This has no effect except on Mac OS. */
#define ARCHIVE_EXTRACT_MAC_METADATA (0x2000)
__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
int flags);
__LA_DECL int archive_read_extract2(struct archive *, struct archive_entry *,
__LA_DECL int archive_read_extract2(struct archive *, struct archive_entry *,
struct archive * /* dest */);
__LA_DECL void archive_read_extract_set_progress_callback(struct archive *,
void (*_progress_func)(void *), void *_user_data);
@ -488,7 +514,7 @@ __LA_DECL void archive_read_extract_set_progress_callback(struct archive *,
/* Record the dev/ino of a file that will not be written. This is
* generally set to the dev/ino of the archive being read. */
__LA_DECL void archive_read_extract_set_skip_file(struct archive *,
dev_t, ino_t);
__LA_INT64_T, __LA_INT64_T);
/* Close the file and release most resources. */
__LA_DECL int archive_read_close(struct archive *);
@ -502,7 +528,7 @@ __LA_DECL int archive_read_finish(struct archive *);
/*-
* To create an archive:
* 1) Ask archive_write_new for a archive writer object.
* 1) Ask archive_write_new for an archive writer object.
* 2) Set any global properties. In particular, you should set
* the compression and format to use.
* 3) Call archive_write_open to open the file (most people
@ -516,85 +542,93 @@ __LA_DECL int archive_read_finish(struct archive *);
* 6) archive_write_free to cleanup the writer and release resources
*/
__LA_DECL struct archive *archive_write_new(void);
__LA_DECL int archive_write_set_bytes_per_block(struct archive *,
__LA_DECL int archive_write_set_bytes_per_block(struct archive *,
int bytes_per_block);
__LA_DECL int archive_write_get_bytes_per_block(struct archive *);
__LA_DECL int archive_write_get_bytes_per_block(struct archive *);
/* XXX This is badly misnamed; suggestions appreciated. XXX */
__LA_DECL int archive_write_set_bytes_in_last_block(struct archive *,
__LA_DECL int archive_write_set_bytes_in_last_block(struct archive *,
int bytes_in_last_block);
__LA_DECL int archive_write_get_bytes_in_last_block(struct archive *);
__LA_DECL int archive_write_get_bytes_in_last_block(struct archive *);
/* The dev/ino of a file that won't be archived. This is used
* to avoid recursively adding an archive to itself. */
__LA_DECL int archive_write_set_skip_file(struct archive *, dev_t, ino_t);
__LA_DECL int archive_write_set_skip_file(struct archive *,
__LA_INT64_T, __LA_INT64_T);
__LA_DECL int archive_write_set_compression_bzip2(struct archive *);
__LA_DECL int archive_write_set_compression_compress(struct archive *);
__LA_DECL int archive_write_set_compression_gzip(struct archive *);
__LA_DECL int archive_write_set_compression_lzma(struct archive *);
__LA_DECL int archive_write_set_compression_none(struct archive *);
__LA_DECL int archive_write_set_compression_program(struct archive *,
#if ARCHIVE_VERSION_NUMBER < 4000000
__LA_DECL int archive_write_set_compression_bzip2(struct archive *);
__LA_DECL int archive_write_set_compression_compress(struct archive *);
__LA_DECL int archive_write_set_compression_gzip(struct archive *);
__LA_DECL int archive_write_set_compression_lzip(struct archive *);
__LA_DECL int archive_write_set_compression_lzma(struct archive *);
__LA_DECL int archive_write_set_compression_none(struct archive *);
__LA_DECL int archive_write_set_compression_program(struct archive *,
const char *cmd);
__LA_DECL int archive_write_set_compression_xz(struct archive *);
__LA_DECL int archive_write_set_compression_xz(struct archive *);
#endif
__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_gzip(struct archive *);
__LA_DECL int archive_write_add_filter_lzip(struct archive *);
__LA_DECL int archive_write_add_filter_lzma(struct archive *);
__LA_DECL int archive_write_add_filter_none(struct archive *);
__LA_DECL int archive_write_add_filter_program(struct archive *,
const char *cmd);
__LA_DECL int archive_write_add_filter_xz(struct archive *);
/* A convenience function to set the format based on the code or name. */
__LA_DECL int archive_write_set_format(struct archive *, int format_code);
__LA_DECL int archive_write_set_format_by_name(struct archive *,
__LA_DECL int archive_write_set_format(struct archive *, int format_code);
__LA_DECL int archive_write_set_format_by_name(struct archive *,
const char *name);
/* To minimize link pollution, use one or more of the following. */
__LA_DECL int archive_write_set_format_ar_bsd(struct archive *);
__LA_DECL int archive_write_set_format_ar_svr4(struct archive *);
__LA_DECL int archive_write_set_format_cpio(struct archive *);
__LA_DECL int archive_write_set_format_cpio_newc(struct archive *);
__LA_DECL int archive_write_set_format_mtree(struct archive *);
__LA_DECL int archive_write_set_format_7zip(struct archive *);
__LA_DECL int archive_write_set_format_ar_bsd(struct archive *);
__LA_DECL int archive_write_set_format_ar_svr4(struct archive *);
__LA_DECL int archive_write_set_format_cpio(struct archive *);
__LA_DECL int archive_write_set_format_cpio_newc(struct archive *);
__LA_DECL int archive_write_set_format_gnutar(struct archive *);
__LA_DECL int archive_write_set_format_iso9660(struct archive *);
__LA_DECL int archive_write_set_format_mtree(struct archive *);
/* TODO: int archive_write_set_format_old_tar(struct archive *); */
__LA_DECL int archive_write_set_format_pax(struct archive *);
__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
__LA_DECL int archive_write_set_format_shar(struct archive *);
__LA_DECL int archive_write_set_format_shar_dump(struct archive *);
__LA_DECL int archive_write_set_format_ustar(struct archive *);
__LA_DECL int archive_write_set_format_zip(struct archive *);
__LA_DECL int archive_write_open(struct archive *, void *,
__LA_DECL int archive_write_set_format_pax(struct archive *);
__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
__LA_DECL int archive_write_set_format_shar(struct archive *);
__LA_DECL int archive_write_set_format_shar_dump(struct archive *);
__LA_DECL int archive_write_set_format_ustar(struct archive *);
__LA_DECL int archive_write_set_format_xar(struct archive *);
__LA_DECL int archive_write_set_format_zip(struct archive *);
__LA_DECL int archive_write_open(struct archive *, void *,
archive_open_callback *, archive_write_callback *,
archive_close_callback *);
__LA_DECL int archive_write_open_fd(struct archive *, int _fd);
__LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
__LA_DECL int archive_write_open_fd(struct archive *, int _fd);
__LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
__LA_DECL int archive_write_open_filename_w(struct archive *,
const wchar_t *_file);
/* A deprecated synonym for archive_write_open_filename() */
__LA_DECL int archive_write_open_file(struct archive *, const char *_file);
__LA_DECL int archive_write_open_FILE(struct archive *, FILE *);
__LA_DECL int archive_write_open_file(struct archive *, const char *_file);
__LA_DECL int archive_write_open_FILE(struct archive *, FILE *);
/* _buffSize is the size of the buffer, _used refers to a variable that
* will be updated after each write into the buffer. */
__LA_DECL int archive_write_open_memory(struct archive *,
__LA_DECL int archive_write_open_memory(struct archive *,
void *_buffer, size_t _buffSize, size_t *_used);
/*
* Note that the library will truncate writes beyond the size provided
* to archive_write_header or pad if the provided data is short.
*/
__LA_DECL int archive_write_header(struct archive *,
__LA_DECL int archive_write_header(struct archive *,
struct archive_entry *);
#if ARCHIVE_VERSION_NUMBER < 2000000
/* This was erroneously declared to return "int" in libarchive 1.x. */
__LA_DECL int archive_write_data(struct archive *,
__LA_DECL __LA_SSIZE_T archive_write_data(struct archive *,
const void *, size_t);
#else
/* Libarchive 2.0 and later return ssize_t here. */
__LA_DECL __LA_SSIZE_T archive_write_data(struct archive *,
const void *, size_t);
#endif
#if ARCHIVE_VERSION_NUMBER < 3000000
/* Libarchive 1.x and 2.x use off_t for the argument, but that's not
* stable on Linux. */
__LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *,
const void *, size_t, off_t);
#else
/* Libarchive 3.0 uses explicit int64_t to ensure consistent 64-bit support. */
/* This interface is currently only available for archive_write_disk handles. */
__LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *,
const void *, size_t, __LA_INT64_T);
#endif
__LA_DECL int archive_write_finish_entry(struct archive *);
__LA_DECL int archive_write_close(struct archive *);
/* This can fail if the archive wasn't already closed, in which case
* archive_write_free() will implicitly call archive_write_close(). */
__LA_DECL int archive_write_free(struct archive *);
@ -606,16 +640,21 @@ __LA_DECL int archive_write_finish(struct archive *);
/*
* Set write options.
*/
/* Apply option string to the format only. */
__LA_DECL int archive_write_set_format_options(struct archive *_a,
const char *s);
/* Apply option string to the compressor only. */
__LA_DECL int archive_write_set_compressor_options(struct archive *_a,
const char *s);
/* Apply option string to both the format and the compressor. */
__LA_DECL int archive_write_set_options(struct archive *_a,
const char *s);
/* Apply option to the format only. */
__LA_DECL int archive_write_set_format_option(struct archive *_a,
const char *m, const char *o,
const char *v);
/* Apply option to the filter only. */
__LA_DECL int archive_write_set_filter_option(struct archive *_a,
const char *m, const char *o,
const char *v);
/* Apply option to both the format and the filter. */
__LA_DECL int archive_write_set_option(struct archive *_a,
const char *m, const char *o,
const char *v);
/* Apply option string to both the format and the filter. */
__LA_DECL int archive_write_set_options(struct archive *_a,
const char *opts);
/*-
* ARCHIVE_WRITE_DISK API
@ -635,8 +674,8 @@ __LA_DECL int archive_write_set_options(struct archive *_a,
*/
__LA_DECL struct archive *archive_write_disk_new(void);
/* This file will not be overwritten. */
__LA_DECL int archive_write_disk_set_skip_file(struct archive *,
dev_t, ino_t);
__LA_DECL int archive_write_disk_set_skip_file(struct archive *,
__LA_INT64_T, __LA_INT64_T);
/* Set flags to control how the next item gets created.
* This accepts a bitmask of ARCHIVE_EXTRACT_XXX flags defined above. */
__LA_DECL int archive_write_disk_set_options(struct archive *,
@ -664,14 +703,16 @@ __LA_DECL int archive_write_disk_set_standard_lookup(struct archive *);
* your needs, you can write your own and register them. Be sure to
* include a cleanup function if you have allocated private data.
*/
__LA_DECL int archive_write_disk_set_group_lookup(struct archive *,
void * /* private_data */,
__LA_GID_T (*)(void *, const char *, __LA_GID_T),
void (* /* cleanup */)(void *));
__LA_DECL int archive_write_disk_set_user_lookup(struct archive *,
void * /* private_data */,
__LA_UID_T (*)(void *, const char *, __LA_UID_T),
void (* /* cleanup */)(void *));
__LA_DECL int archive_write_disk_set_group_lookup(struct archive *,
void * /* private_data */,
__LA_INT64_T (*)(void *, const char *, __LA_INT64_T),
void (* /* cleanup */)(void *));
__LA_DECL int archive_write_disk_set_user_lookup(struct archive *,
void * /* private_data */,
__LA_INT64_T (*)(void *, const char *, __LA_INT64_T),
void (* /* cleanup */)(void *));
__LA_DECL __LA_INT64_T archive_write_disk_gid(struct archive *, const char *, __LA_INT64_T);
__LA_DECL __LA_INT64_T archive_write_disk_uid(struct archive *, const char *, __LA_INT64_T);
/*
* ARCHIVE_READ_DISK API
@ -692,32 +733,64 @@ __LA_DECL int archive_read_disk_entry_from_file(struct archive *,
struct archive_entry *, int /* fd */, const struct stat *);
/* Look up gname for gid or uname for uid. */
/* Default implementations are very, very stupid. */
__LA_DECL const char *archive_read_disk_gname(struct archive *, __LA_GID_T);
__LA_DECL const char *archive_read_disk_uname(struct archive *, __LA_UID_T);
__LA_DECL const char *archive_read_disk_gname(struct archive *, __LA_INT64_T);
__LA_DECL const char *archive_read_disk_uname(struct archive *, __LA_INT64_T);
/* "Standard" implementation uses getpwuid_r, getgrgid_r and caches the
* results for performance. */
__LA_DECL int archive_read_disk_set_standard_lookup(struct archive *);
/* You can install your own lookups if you like. */
__LA_DECL int archive_read_disk_set_gname_lookup(struct archive *,
void * /* private_data */,
const char *(* /* lookup_fn */)(void *, __LA_GID_T),
const char *(* /* lookup_fn */)(void *, __LA_INT64_T),
void (* /* cleanup_fn */)(void *));
__LA_DECL int archive_read_disk_set_uname_lookup(struct archive *,
void * /* private_data */,
const char *(* /* lookup_fn */)(void *, __LA_UID_T),
const char *(* /* lookup_fn */)(void *, __LA_INT64_T),
void (* /* cleanup_fn */)(void *));
/* Start traversal. */
__LA_DECL int archive_read_disk_open(struct archive *, const char *);
__LA_DECL int archive_read_disk_open_w(struct archive *, const wchar_t *);
/*
* Request that current entry be visited. If you invoke it on every
* directory, you'll get a physical traversal. This is ignored if the
* current entry isn't a directory or a link to a directory. So, if
* you invoke this on every returned path, you'll get a full logical
* traversal.
*/
__LA_DECL int archive_read_disk_descend(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_remote(struct archive *);
/* Request that the access time of the entry visited by travesal be restored. */
__LA_DECL int archive_read_disk_set_atime_restored(struct archive *);
/*
* Accessor functions to read/set various information in
* the struct archive object:
*/
/* Bytes written after compression or read before decompression. */
__LA_DECL __LA_INT64_T archive_position_compressed(struct archive *);
/* Bytes written to compressor or read from decompressor. */
__LA_DECL __LA_INT64_T archive_position_uncompressed(struct archive *);
/* Number of filters in the current filter pipeline. */
/* Filter #0 is the one closest to the format, -1 is a synonym for the
* last filter, which is always the pseudo-filter that wraps the
* client callbacks. */
__LA_DECL int archive_filter_count(struct archive *);
__LA_DECL __LA_INT64_T archive_filter_bytes(struct archive *, int);
__LA_DECL int archive_filter_code(struct archive *, int);
__LA_DECL const char * archive_filter_name(struct archive *, int);
#if ARCHIVE_VERSION_NUMBER < 4000000
/* These don't properly handle multiple filters, so are deprecated and
* will eventually be removed. */
/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, -1); */
__LA_DECL __LA_INT64_T archive_position_compressed(struct archive *);
/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, 0); */
__LA_DECL __LA_INT64_T archive_position_uncompressed(struct archive *);
/* As of libarchive 3.0, this is an alias for archive_filter_name(a, 0); */
__LA_DECL const char *archive_compression_name(struct archive *);
/* As of libarchive 3.0, this is an alias for archive_filter_code(a, 0); */
__LA_DECL int archive_compression(struct archive *);
#endif
__LA_DECL int archive_errno(struct archive *);
__LA_DECL const char *archive_error_string(struct archive *);
__LA_DECL const char *archive_format_name(struct archive *);

1264
libarchive/archive_acl.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,87 @@
/*-
* Copyright (c) 2003-2010 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.
*
* $FreeBSD$
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
#include "archive_string.h"
struct archive_acl_entry {
struct archive_acl_entry *next;
int type; /* E.g., access or default */
int tag; /* E.g., user/group/other/mask */
int permset; /* r/w/x bits */
int id; /* uid/gid for user/group */
struct archive_mstring name; /* uname/gname */
};
struct archive_acl {
mode_t mode;
struct archive_acl_entry *acl_head;
struct archive_acl_entry *acl_p;
int acl_state; /* See acl_next for details. */
wchar_t *acl_text_w;
char *acl_text;
int acl_types;
};
void archive_acl_clear(struct archive_acl *);
void archive_acl_copy(struct archive_acl *, struct archive_acl *);
int archive_acl_count(struct archive_acl *, int);
int archive_acl_reset(struct archive_acl *, int);
int archive_acl_next(struct archive *, struct archive_acl *, int,
int *, int *, int *, int *, const char **);
int archive_acl_add_entry(struct archive_acl *, int, int, int, int, const char *);
int archive_acl_add_entry_w_len(struct archive_acl *,
int, int, int, int, const wchar_t *, size_t);
int archive_acl_add_entry_len(struct archive_acl *,
int, int, int, int, const char *, size_t);
const wchar_t *archive_acl_text_w(struct archive *, struct archive_acl *, int);
int archive_acl_text_l(struct archive_acl *, int, const char **, size_t *,
struct archive_string_conv *);
/*
* Private ACL parser. This is private because it handles some
* very weird formats that clients should not be messing with.
* Clients should only deal with their platform-native formats.
* Because of the need to support many formats cleanly, new arguments
* are likely to get added on a regular basis. Clients who try to use
* this interface are likely to be surprised when it changes.
*/
int archive_acl_parse_w(struct archive_acl *,
const wchar_t *, int /* type */);
int archive_acl_parse_l(struct archive_acl *,
const char *, int /* type */,
struct archive_string_conv *);
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -86,49 +86,89 @@ state_name(unsigned s)
}
}
static const char *
archive_handle_type_name(unsigned m)
{
switch (m) {
case ARCHIVE_WRITE_MAGIC: return ("archive_write");
case ARCHIVE_READ_MAGIC: return ("archive_read");
case ARCHIVE_WRITE_DISK_MAGIC: return ("archive_write_disk");
case ARCHIVE_READ_DISK_MAGIC: return ("archive_read_disk");
default: return NULL;
}
}
static void
write_all_states(unsigned int states)
static char *
write_all_states(char *buff, unsigned int states)
{
unsigned int lowbit;
buff[0] = '\0';
/* A trick for computing the lowest set bit. */
while ((lowbit = states & (1 + ~states)) != 0) {
states &= ~lowbit; /* Clear the low bit. */
errmsg(state_name(lowbit));
strcat(buff, state_name(lowbit));
if (states != 0)
errmsg("/");
strcat(buff, "/");
}
return buff;
}
/*
* Check magic value and current state; bail if it isn't valid.
* Check magic value and current state.
* Magic value mismatches are fatal and result in calls to abort().
* State mismatches return ARCHIVE_FATAL.
* Otherwise, returns ARCHIVE_OK.
*
* This is designed to catch serious programming errors that violate
* the libarchive API.
*/
void
int
__archive_check_magic(struct archive *a, unsigned int magic,
unsigned int state, const char *function)
{
if (a->magic != magic) {
errmsg("INTERNAL ERROR: Function ");
char states1[64];
char states2[64];
const char *handle_type;
/*
* If this isn't some form of archive handle,
* then the library user has screwed up so bad that
* we don't even have a reliable way to report an error.
*/
handle_type = archive_handle_type_name(a->magic);
if (!handle_type) {
errmsg("PROGRAMMER ERROR: Function ");
errmsg(function);
errmsg(" invoked with invalid struct archive structure.\n");
errmsg(" invoked with invalid archive handle.\n");
diediedie();
}
if (state == ARCHIVE_STATE_ANY)
return;
if (a->magic != magic) {
archive_set_error(a, -1,
"PROGRAMMER ERROR: Function '%s' invoked"
" on '%s' archive object, which is not supported.",
function,
handle_type);
a->state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
if ((a->state & state) == 0) {
errmsg("INTERNAL ERROR: Function '");
errmsg(function);
errmsg("' invoked with archive structure in state '");
write_all_states(a->state);
errmsg("', should be in state '");
write_all_states(state);
errmsg("'\n");
diediedie();
/* If we're already FATAL, don't overwrite the error. */
if (a->state != ARCHIVE_STATE_FATAL)
archive_set_error(a, -1,
"INTERNAL ERROR: Function '%s' invoked with"
" archive structure in state '%s',"
" should be in state '%s'",
function,
write_all_states(states1, a->state),
write_all_states(states2, state));
a->state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
return ARCHIVE_OK;
}

View File

@ -60,6 +60,18 @@ crc32(unsigned long crc, const void *_p, size_t len)
}
crc = crc ^ 0xffffffffUL;
/* A use of this loop is about 20% - 30% faster than
* no use version in any optimization option of gcc. */
for (;len >= 8; len -= 8) {
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
}
while (len--)
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
return (crc ^ 0xffffffffUL);

1427
libarchive/archive_crypto.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,376 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* Copyright (c) 2011 Andres Mejia
* 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.
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
#define ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
/*
* Crypto support in various Operating Systems:
*
* NetBSD:
* - MD5 and SHA1 in libc: without _ after algorithm name
* - SHA2 in libc: with _ after algorithm name
*
* OpenBSD:
* - MD5, SHA1 and SHA2 in libc: without _ after algorithm name
* - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name
*
* DragonFly and FreeBSD:
* - MD5 libmd: without _ after algorithm name
* - SHA1, SHA256 and SHA512 in libmd: with _ after algorithm name
*
* Mac OS X (10.4 and later):
* - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name
*
* OpenSSL:
* - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name
*
* Windows:
* - MD5, SHA1 and SHA2 in archive_crypto.c using Windows crypto API
*/
/* libc crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
#include <md5.h>
#endif
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
#include <rmd160.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
#include <sha1.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
#include <sha2.h>
#endif
/* libmd crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_LIBMD) ||\
defined(ARCHIVE_CRYPTO_RMD160_LIBMD) ||\
defined(ARCHIVE_CRYPTO_SHA1_LIBMD) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
#define ARCHIVE_CRYPTO_LIBMD 1
#endif
#if defined(ARCHIVE_CRYPTO_MD5_LIBMD)
#include <md5.h>
#endif
#if defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
#include <ripemd.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
#include <sha.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
#include <sha256.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
#include <sha512.h>
#endif
/* libSystem crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
#include <CommonCrypto/CommonDigest.h>
#endif
/* Nettle crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_NETTLE)
#include <nettle/md5.h>
#endif
#if defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
#include <nettle/ripemd160.h>
#endif
#if defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
#include <nettle/sha.h>
#endif
/* OpenSSL crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
#define ARCHIVE_CRYPTO_OPENSSL 1
#include <openssl/evp.h>
#endif
/* Windows crypto headers */
#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
#include <wincrypt.h>
typedef struct {
int valid;
HCRYPTPROV cryptProv;
HCRYPTHASH hash;
} Digest_CTX;
#endif
/* typedefs */
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
typedef MD5_CTX archive_md5_ctx;
#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
typedef MD5_CTX archive_md5_ctx;
#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
typedef CC_MD5_CTX archive_md5_ctx;
#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
typedef struct md5_ctx archive_md5_ctx;
#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
typedef EVP_MD_CTX archive_md5_ctx;
#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
typedef Digest_CTX archive_md5_ctx;
#else
typedef unsigned char archive_md5_ctx;
#endif
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
typedef RMD160_CTX archive_rmd160_ctx;
#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
typedef RIPEMD160_CTX archive_rmd160_ctx;
#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
typedef struct ripemd160_ctx archive_rmd160_ctx;
#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
typedef EVP_MD_CTX archive_rmd160_ctx;
#else
typedef unsigned char archive_rmd160_ctx;
#endif
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
typedef SHA1_CTX archive_sha1_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
typedef SHA1_CTX archive_sha1_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
typedef CC_SHA1_CTX archive_sha1_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
typedef struct sha1_ctx archive_sha1_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
typedef EVP_MD_CTX archive_sha1_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
typedef Digest_CTX archive_sha1_ctx;
#else
typedef unsigned char archive_sha1_ctx;
#endif
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
typedef SHA256_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
typedef SHA256_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
typedef SHA2_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
typedef SHA256_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
typedef CC_SHA256_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
typedef struct sha256_ctx archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
typedef EVP_MD_CTX archive_sha256_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
typedef Digest_CTX archive_sha256_ctx;
#else
typedef unsigned char archive_sha256_ctx;
#endif
#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
typedef SHA384_CTX archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
typedef SHA384_CTX archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
typedef SHA2_CTX archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
typedef CC_SHA512_CTX archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
typedef struct sha384_ctx archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
typedef EVP_MD_CTX archive_sha384_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
typedef Digest_CTX archive_sha384_ctx;
#else
typedef unsigned char archive_sha384_ctx;
#endif
#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
typedef SHA512_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
typedef SHA512_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
typedef SHA2_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
typedef SHA512_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
typedef CC_SHA512_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
typedef struct sha512_ctx archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
typedef EVP_MD_CTX archive_sha512_ctx;
#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
typedef Digest_CTX archive_sha512_ctx;
#else
typedef unsigned char archive_sha512_ctx;
#endif
/* defines */
#if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\
defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \
defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\
defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_MD5_WIN)
#define ARCHIVE_HAS_MD5
#endif
#define archive_md5_init(ctx)\
__archive_crypto.md5init(ctx)
#define archive_md5_final(ctx, md)\
__archive_crypto.md5final(ctx, md)
#define archive_md5_update(ctx, buf, n)\
__archive_crypto.md5update(ctx, buf, n)
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
#define ARCHIVE_HAS_RMD160
#endif
#define archive_rmd160_init(ctx)\
__archive_crypto.rmd160init(ctx)
#define archive_rmd160_final(ctx, md)\
__archive_crypto.rmd160final(ctx, md)
#define archive_rmd160_update(ctx, buf, n)\
__archive_crypto.rmd160update(ctx, buf, n)
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \
defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA1_WIN)
#define ARCHIVE_HAS_SHA1
#endif
#define archive_sha1_init(ctx)\
__archive_crypto.sha1init(ctx)
#define archive_sha1_final(ctx, md)\
__archive_crypto.sha1final(ctx, md)
#define archive_sha1_update(ctx, buf, n)\
__archive_crypto.sha1update(ctx, buf, n)
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA256_WIN)
#define ARCHIVE_HAS_SHA256
#endif
#define archive_sha256_init(ctx)\
__archive_crypto.sha256init(ctx)
#define archive_sha256_final(ctx, md)\
__archive_crypto.sha256final(ctx, md)
#define archive_sha256_update(ctx, buf, n)\
__archive_crypto.sha256update(ctx, buf, n)
#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN)
#define ARCHIVE_HAS_SHA384
#endif
#define archive_sha384_init(ctx)\
__archive_crypto.sha384init(ctx)
#define archive_sha384_final(ctx, md)\
__archive_crypto.sha384final(ctx, md)
#define archive_sha384_update(ctx, buf, n)\
__archive_crypto.sha384update(ctx, buf, n)
#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\
defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\
defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\
defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
#define ARCHIVE_HAS_SHA512
#endif
#define archive_sha512_init(ctx)\
__archive_crypto.sha512init(ctx)
#define archive_sha512_final(ctx, md)\
__archive_crypto.sha512final(ctx, md)
#define archive_sha512_update(ctx, buf, n)\
__archive_crypto.sha512update(ctx, buf, n)
/* Minimal interface to crypto functionality for internal use in libarchive */
struct archive_crypto
{
/* Message Digest */
int (*md5init)(archive_md5_ctx *ctx);
int (*md5update)(archive_md5_ctx *, const void *, size_t);
int (*md5final)(archive_md5_ctx *, void *);
int (*rmd160init)(archive_rmd160_ctx *);
int (*rmd160update)(archive_rmd160_ctx *, const void *, size_t);
int (*rmd160final)(archive_rmd160_ctx *, void *);
int (*sha1init)(archive_sha1_ctx *);
int (*sha1update)(archive_sha1_ctx *, const void *, size_t);
int (*sha1final)(archive_sha1_ctx *, void *);
int (*sha256init)(archive_sha256_ctx *);
int (*sha256update)(archive_sha256_ctx *, const void *, size_t);
int (*sha256final)(archive_sha256_ctx *, void *);
int (*sha384init)(archive_sha384_ctx *);
int (*sha384update)(archive_sha384_ctx *, const void *, size_t);
int (*sha384final)(archive_sha384_ctx *, void *);
int (*sha512init)(archive_sha512_ctx *);
int (*sha512update)(archive_sha512_ctx *, const void *, size_t);
int (*sha512final)(archive_sha512_ctx *, void *);
};
extern const struct archive_crypto __archive_crypto;
#endif

View File

@ -1,4 +1,5 @@
.\" Copyright (c) 2003-2007 Tim Kientzle
.\" Copyright (c) 2010 Joerg Sonnenberger
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -24,267 +25,25 @@
.\"
.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $
.\"
.Dd May 12, 2008
.Dd Feburary 22, 2010
.Dt ARCHIVE_ENTRY 3
.Os
.Sh NAME
.Nm archive_entry_acl_add_entry ,
.Nm archive_entry_acl_add_entry_w ,
.Nm archive_entry_acl_clear ,
.Nm archive_entry_acl_count ,
.Nm archive_entry_acl_next ,
.Nm archive_entry_acl_next_w ,
.Nm archive_entry_acl_reset ,
.Nm archive_entry_acl_text_w ,
.Nm archive_entry_atime ,
.Nm archive_entry_atime_nsec ,
.Nm archive_entry_clear ,
.Nm archive_entry_clone ,
.Nm archive_entry_copy_fflags_text ,
.Nm archive_entry_copy_fflags_text_w ,
.Nm archive_entry_copy_gname ,
.Nm archive_entry_copy_gname_w ,
.Nm archive_entry_copy_hardlink ,
.Nm archive_entry_copy_hardlink_w ,
.Nm archive_entry_copy_link ,
.Nm archive_entry_copy_link_w ,
.Nm archive_entry_copy_pathname_w ,
.Nm archive_entry_copy_sourcepath ,
.Nm archive_entry_copy_stat ,
.Nm archive_entry_copy_symlink ,
.Nm archive_entry_copy_symlink_w ,
.Nm archive_entry_copy_uname ,
.Nm archive_entry_copy_uname_w ,
.Nm archive_entry_dev ,
.Nm archive_entry_devmajor ,
.Nm archive_entry_devminor ,
.Nm archive_entry_filetype ,
.Nm archive_entry_fflags ,
.Nm archive_entry_fflags_text ,
.Nm archive_entry_free ,
.Nm archive_entry_gid ,
.Nm archive_entry_gname ,
.Nm archive_entry_hardlink ,
.Nm archive_entry_ino ,
.Nm archive_entry_mode ,
.Nm archive_entry_mtime ,
.Nm archive_entry_mtime_nsec ,
.Nm archive_entry_nlink ,
.Nm archive_entry_new ,
.Nm archive_entry_pathname ,
.Nm archive_entry_pathname_w ,
.Nm archive_entry_rdev ,
.Nm archive_entry_rdevmajor ,
.Nm archive_entry_rdevminor ,
.Nm archive_entry_set_atime ,
.Nm archive_entry_set_ctime ,
.Nm archive_entry_set_dev ,
.Nm archive_entry_set_devmajor ,
.Nm archive_entry_set_devminor ,
.Nm archive_entry_set_filetype ,
.Nm archive_entry_set_fflags ,
.Nm archive_entry_set_gid ,
.Nm archive_entry_set_gname ,
.Nm archive_entry_set_hardlink ,
.Nm archive_entry_set_link ,
.Nm archive_entry_set_mode ,
.Nm archive_entry_set_mtime ,
.Nm archive_entry_set_pathname ,
.Nm archive_entry_set_rdevmajor ,
.Nm archive_entry_set_rdevminor ,
.Nm archive_entry_set_size ,
.Nm archive_entry_set_symlink ,
.Nm archive_entry_set_uid ,
.Nm archive_entry_set_uname ,
.Nm archive_entry_size ,
.Nm archive_entry_sourcepath ,
.Nm archive_entry_stat ,
.Nm archive_entry_symlink ,
.Nm archive_entry_uid ,
.Nm archive_entry_uname
.Nd functions for manipulating archive entry descriptions
.Nd functions for managing archive entry descriptions
.Sh SYNOPSIS
.In archive_entry.h
.Ft void
.Fo archive_entry_acl_add_entry
.Fa "struct archive_entry *"
.Fa "int type"
.Fa "int permset"
.Fa "int tag"
.Fa "int qual"
.Fa "const char *name"
.Fc
.Ft void
.Fo archive_entry_acl_add_entry_w
.Fa "struct archive_entry *"
.Fa "int type"
.Fa "int permset"
.Fa "int tag"
.Fa "int qual"
.Fa "const wchar_t *name"
.Fc
.Ft void
.Fn archive_entry_acl_clear "struct archive_entry *"
.Ft int
.Fn archive_entry_acl_count "struct archive_entry *" "int type"
.Ft int
.Fo archive_entry_acl_next
.Fa "struct archive_entry *"
.Fa "int want_type"
.Fa "int *type"
.Fa "int *permset"
.Fa "int *tag"
.Fa "int *qual"
.Fa "const char **name"
.Fc
.Ft int
.Fo archive_entry_acl_next_w
.Fa "struct archive_entry *"
.Fa "int want_type"
.Fa "int *type"
.Fa "int *permset"
.Fa "int *tag"
.Fa "int *qual"
.Fa "const wchar_t **name"
.Fc
.Ft int
.Fn archive_entry_acl_reset "struct archive_entry *" "int want_type"
.Ft const wchar_t *
.Fn archive_entry_acl_text_w "struct archive_entry *" "int flags"
.Ft time_t
.Fn archive_entry_atime "struct archive_entry *"
.Ft long
.Fn archive_entry_atime_nsec "struct archive_entry *"
.Ft "struct archive_entry *"
.Fn archive_entry_clear "struct archive_entry *"
.Ft struct archive_entry *
.Fn archive_entry_clone "struct archive_entry *"
.Ft const char * *
.Fn archive_entry_copy_fflags_text_w "struct archive_entry *" "const char *"
.Ft const wchar_t *
.Fn archive_entry_copy_fflags_text_w "struct archive_entry *" "const wchar_t *"
.Ft void
.Fn archive_entry_copy_gname "struct archive_entry *" "const char *"
.Ft void
.Fn archive_entry_copy_gname_w "struct archive_entry *" "const wchar_t *"
.Ft void
.Fn archive_entry_copy_hardlink "struct archive_entry *" "const char *"
.Ft void
.Fn archive_entry_copy_hardlink_w "struct archive_entry *" "const wchar_t *"
.Ft void
.Fn archive_entry_copy_sourcepath "struct archive_entry *" "const char *"
.Ft void
.Fn archive_entry_copy_pathname_w "struct archive_entry *" "const wchar_t *"
.Ft void
.Fn archive_entry_copy_stat "struct archive_entry *" "const struct stat *"
.Ft void
.Fn archive_entry_copy_symlink "struct archive_entry *" "const char *"
.Ft void
.Fn archive_entry_copy_symlink_w "struct archive_entry *" "const wchar_t *"
.Ft void
.Fn archive_entry_copy_uname "struct archive_entry *" "const char *"
.Ft void
.Fn archive_entry_copy_uname_w "struct archive_entry *" "const wchar_t *"
.Ft dev_t
.Fn archive_entry_dev "struct archive_entry *"
.Ft dev_t
.Fn archive_entry_devmajor "struct archive_entry *"
.Ft dev_t
.Fn archive_entry_devminor "struct archive_entry *"
.Ft mode_t
.Fn archive_entry_filetype "struct archive_entry *"
.Ft void
.Fo archive_entry_fflags
.Fa "struct archive_entry *"
.Fa "unsigned long *set"
.Fa "unsigned long *clear"
.Fc
.Ft const char *
.Fn archive_entry_fflags_text "struct archive_entry *"
.Ft void
.Fn archive_entry_free "struct archive_entry *"
.Ft const char *
.Fn archive_entry_gname "struct archive_entry *"
.Ft const char *
.Fn archive_entry_hardlink "struct archive_entry *"
.Ft ino_t
.Fn archive_entry_ino "struct archive_entry *"
.Ft mode_t
.Fn archive_entry_mode "struct archive_entry *"
.Ft time_t
.Fn archive_entry_mtime "struct archive_entry *"
.Ft long
.Fn archive_entry_mtime_nsec "struct archive_entry *"
.Ft unsigned int
.Fn archive_entry_nlink "struct archive_entry *"
.Ft struct archive_entry *
.Fn archive_entry_new "void"
.Ft const char *
.Fn archive_entry_pathname "struct archive_entry *"
.Ft const wchar_t *
.Fn archive_entry_pathname_w "struct archive_entry *"
.Ft dev_t
.Fn archive_entry_rdev "struct archive_entry *"
.Ft dev_t
.Fn archive_entry_rdevmajor "struct archive_entry *"
.Ft dev_t
.Fn archive_entry_rdevminor "struct archive_entry *"
.Ft void
.Fn archive_entry_set_dev "struct archive_entry *" "dev_t"
.Ft void
.Fn archive_entry_set_devmajor "struct archive_entry *" "dev_t"
.Ft void
.Fn archive_entry_set_devminor "struct archive_entry *" "dev_t"
.Ft void
.Fn archive_entry_set_filetype "struct archive_entry *" "unsigned int"
.Ft void
.Fo archive_entry_set_fflags
.Fa "struct archive_entry *"
.Fa "unsigned long set"
.Fa "unsigned long clear"
.Fc
.Ft void
.Fn archive_entry_set_gid "struct archive_entry *" "gid_t"
.Ft void
.Fn archive_entry_set_gname "struct archive_entry *" "const char *"
.Ft void
.Fn archive_entry_set_hardlink "struct archive_entry *" "const char *"
.Ft void
.Fn archive_entry_set_ino "struct archive_entry *" "unsigned long"
.Ft void
.Fn archive_entry_set_link "struct archive_entry *" "const char *"
.Ft void
.Fn archive_entry_set_mode "struct archive_entry *" "mode_t"
.Ft void
.Fn archive_entry_set_mtime "struct archive_entry *" "time_t" "long nanos"
.Ft void
.Fn archive_entry_set_nlink "struct archive_entry *" "unsigned int"
.Ft void
.Fn archive_entry_set_pathname "struct archive_entry *" "const char *"
.Ft void
.Fn archive_entry_set_rdev "struct archive_entry *" "dev_t"
.Ft void
.Fn archive_entry_set_rdevmajor "struct archive_entry *" "dev_t"
.Ft void
.Fn archive_entry_set_rdevminor "struct archive_entry *" "dev_t"
.Ft void
.Fn archive_entry_set_size "struct archive_entry *" "int64_t"
.Ft void
.Fn archive_entry_set_symlink "struct archive_entry *" "const char *"
.Ft void
.Fn archive_entry_set_uid "struct archive_entry *" "uid_t"
.Ft void
.Fn archive_entry_set_uname "struct archive_entry *" "const char *"
.Ft int64_t
.Fn archive_entry_size "struct archive_entry *"
.Ft const char *
.Fn archive_entry_sourcepath "struct archive_entry *"
.Ft const struct stat *
.Fn archive_entry_stat "struct archive_entry *"
.Ft const char *
.Fn archive_entry_symlink "struct archive_entry *"
.Ft const char *
.Fn archive_entry_uname "struct archive_entry *"
.Sh DESCRIPTION
These functions create and manipulate data objects that
represent entries within an archive.
@ -320,8 +79,24 @@ Allocate and return a blank
.Tn struct archive_entry
object.
.El
.Ss Set and Get Functions
Most of the functions here set or read entries in an object.
.Ss Function groups
Due to high number of functions, the accessor functions can be found in
man pages grouped by the purpose.
.Bl -tag -width ".Xr archive_entry_perms 3"
.It Xr archive_entry_acl 3
Access Control List manipulation
.It Xr archive_entry_paths 3
Path name manipulation
.It Xr archive_entry_perms 3
User, group and mode manipulation
.It Xr archive_entry_stat 3
Functions not in the other groups and copying to/from
.Vt struct stat .
.It Xr archive_entry_time 3
Time field manipulation
.El
.Pp
Most of the functions set or read entries in an object.
Such functions have one of the following forms:
.Bl -tag -compact -width indent
.It Fn archive_entry_set_XXXX
@ -350,75 +125,15 @@ Similarly, if you store a wide string and then store a
narrow string for the same data, the previously-set wide string will
be discarded in favor of the new data.
.Pp
There are a few set/get functions that merit additional description:
.Bl -tag -compact -width indent
.It Fn archive_entry_set_link
This function sets the symlink field if it is already set.
Otherwise, it sets the hardlink field.
.El
.Ss File Flags
File flags are transparently converted between a bitmap
representation and a textual format.
For example, if you set the bitmap and ask for text, the library
will build a canonical text format.
However, if you set a text format and request a text format,
you will get back the same text, even if it is ill-formed.
If you need to canonicalize a textual flags string, you should first set the
text form, then request the bitmap form, then use that to set the bitmap form.
Setting the bitmap format will clear the internal text representation
and force it to be reconstructed when you next request the text form.
.Pp
The bitmap format consists of two integers, one containing bits
that should be set, the other specifying bits that should be
cleared.
Bits not mentioned in either bitmap will be ignored.
Usually, the bitmap of bits to be cleared will be set to zero.
In unusual circumstances, you can force a fully-specified set
of file flags by setting the bitmap of flags to clear to the complement
of the bitmap of flags to set.
(This differs from
.Xr fflagstostr 3 ,
which only includes names for set bits.)
Converting a bitmap to a textual string is a platform-specific
operation; bits that are not meaningful on the current platform
will be ignored.
.Pp
The canonical text format is a comma-separated list of flag names.
The
.Fn archive_entry_copy_fflags_text
and
.Fn archive_entry_copy_fflags_text_w
functions parse the provided text and sets the internal bitmap values.
This is a platform-specific operation; names that are not meaningful
on the current platform will be ignored.
The function returns a pointer to the start of the first name that was not
recognized, or NULL if every name was recognized.
Note that every name--including names that follow an unrecognized name--will
be evaluated, and the bitmaps will be set to reflect every name that is
recognized.
(In particular, this differs from
.Xr strtofflags 3 ,
which stops parsing at the first unrecognized name.)
.Ss ACL Handling
XXX This needs serious help.
XXX
.Pp
An
.Dq Access Control List
(ACL) is a list of permissions that grant access to particular users or
groups beyond what would normally be provided by standard POSIX mode bits.
The ACL handling here addresses some deficiencies in the POSIX.1e draft 17 ACL
specification.
In particular, POSIX.1e draft 17 specifies several different formats, but
none of those formats include both textual user/group names and numeric
UIDs/GIDs.
.Pp
XXX explain ACL stuff XXX
.\" .Sh EXAMPLE
.\" .Sh RETURN VALUES
.\" .Sh ERRORS
.Sh SEE ALSO
.Xr archive 3
.Xr archive 3 ,
.Xr archive_entry_acl 3 ,
.Xr archive_entry_paths 3 ,
.Xr archive_entry_perms 3 ,
.Xr archive_entry_time 3
.Sh HISTORY
The
.Nm libarchive

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,9 @@
#ifndef ARCHIVE_ENTRY_H_INCLUDED
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3000003
/*
* Note: archive_entry.h is for use outside of libarchive; the
* configuration headers (config.h, archive_platform.h, etc.) are
@ -49,30 +52,31 @@
#if defined(_WIN32) && !defined(__CYGWIN__)
#define __LA_INT64_T __int64
# if defined(__BORLANDC__)
# define __LA_UID_T uid_t
# define __LA_GID_T gid_t
# 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
# define __LA_GID_T short
# 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
#include <unistd.h>
#define __LA_INT64_T int64_t
#define __LA_UID_T uid_t
#define __LA_GID_T gid_t
#define __LA_DEV_T dev_t
#define __LA_MODE_T mode_t
# if defined(_SCO_DS)
# define __LA_INT64_T long long
# else
# define __LA_INT64_T int64_t
# 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
/*
* XXX Is this defined for all Windows compilers? If so, in what
* header? It would be nice to remove the __LA_INO_T indirection and
* just use plain ino_t everywhere. Likewise for the other types just
* above.
* Remove this for libarchive 3.2, since ino_t is no longer used.
*/
#define __LA_INO_T ino_t
@ -91,7 +95,7 @@
# endif
# else
# ifdef __GNUC__
# define __LA_DECL __attribute__((dllimport)) extern
# define __LA_DECL
# else
# define __LA_DECL __declspec(dllimport)
# endif
@ -121,6 +125,7 @@ extern "C" {
* applications (e.g., a package manager could attach special
* package-management attributes to each entry).
*/
struct archive;
struct archive_entry;
/*
@ -163,6 +168,15 @@ __LA_DECL struct archive_entry *archive_entry_clone(struct archive_entry *);
__LA_DECL void archive_entry_free(struct archive_entry *);
__LA_DECL struct archive_entry *archive_entry_new(void);
/*
* This form of archive_entry_new2() will pull character-set
* conversion information from the specified archive handle. The
* older archive_entry_new(void) form is equivalent to calling
* archive_entry_new2(NULL) and will result in the use of an internal
* default character-set conversion.
*/
__LA_DECL struct archive_entry *archive_entry_new2(struct archive *);
/*
* Retrieve fields from an archive_entry.
*
@ -192,6 +206,7 @@ __LA_DECL time_t archive_entry_ctime(struct archive_entry *);
__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_ctime_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_dev(struct archive_entry *);
__LA_DECL int archive_entry_dev_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_devminor(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *);
@ -199,13 +214,14 @@ __LA_DECL void archive_entry_fflags(struct archive_entry *,
unsigned long * /* set */,
unsigned long * /* clear */);
__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
__LA_DECL __LA_GID_T archive_entry_gid(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_gid(struct archive_entry *);
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
__LA_DECL __LA_INO_T archive_entry_ino(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_ino(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_ino64(struct archive_entry *);
__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *);
__LA_DECL time_t archive_entry_mtime(struct archive_entry *);
__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
@ -213,35 +229,34 @@ __LA_DECL int archive_entry_mtime_is_set(struct archive_entry *);
__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *);
__LA_DECL const char *archive_entry_pathname(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_size(struct archive_entry *);
__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
__LA_DECL __LA_UID_T archive_entry_uid(struct archive_entry *);
__LA_DECL __LA_INT64_T archive_entry_uid(struct archive_entry *);
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
/*
* Set fields in an archive_entry.
*
* Note that string 'set' functions do not copy the string, only the pointer.
* In contrast, 'copy' functions do copy the object pointed to.
*
* Note: As of libarchive 2.4, 'set' functions do copy the string and
* are therefore exact synonyms for the 'copy' versions. The 'copy'
* names will be retired in libarchive 3.0.
* Note: Before libarchive 2.4, there were 'set' and 'copy' versions
* of the string setters. 'copy' copied the actual string, 'set' just
* stored the pointer. In libarchive 2.4 and later, strings are
* always copied.
*/
__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_atime(struct archive_entry *);
#if defined(_WIN32) && !defined(__CYGWIN__)
__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *,
BY_HANDLE_FILE_INFORMATION *);
__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *);
#endif
__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *);
@ -259,7 +274,7 @@ __LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
const char *);
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
const wchar_t *);
__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_GID_T);
__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
@ -268,12 +283,7 @@ __LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_hardlink_utf8(struct archive_entry *, const char *);
#if ARCHIVE_VERSION_NUMBER >= 3000000
/* Starting with libarchive 3.0, this will be synonym for ino64. */
__LA_DECL void archive_entry_set_ino(struct archive_entry *, __LA_INT64_T);
#else
__LA_DECL void archive_entry_set_ino(struct archive_entry *, unsigned long);
#endif
__LA_DECL void archive_entry_set_ino64(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *);
@ -294,11 +304,12 @@ __LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_size(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_unset_size(struct archive_entry *);
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_uid(struct archive_entry *, __LA_UID_T);
__LA_DECL void archive_entry_set_uid(struct archive_entry *, __LA_INT64_T);
__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
@ -315,6 +326,15 @@ __LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char
__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *);
__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
/*
* Storage for Mac OS-specific AppleDouble metadata information.
* Apple-format tar files store a separate binary blob containing
* encoded metadata with ACL, extended attributes, etc.
* This provides a place to store that blob.
*/
__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *);
__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
/*
* ACL routines. This used to simply store and return text-format ACL
@ -326,32 +346,95 @@ __LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat
*
* This last point, in particular, forces me to implement a reasonably
* complete set of ACL support routines.
*
* TODO: Extend this to support NFSv4/NTFS permissions. That should
* allow full ACL support on Mac OS, in particular, which uses
* POSIX.1e-style interfaces to manipulate NFSv4/NTFS permissions.
*/
/*
* Permission bits mimic POSIX.1e. Note that I've not followed POSIX.1e's
* "permset"/"perm" abstract type nonsense. A permset is just a simple
* bitmap, following long-standing Unix tradition.
* Permission bits.
*/
#define ARCHIVE_ENTRY_ACL_EXECUTE 1
#define ARCHIVE_ENTRY_ACL_WRITE 2
#define ARCHIVE_ENTRY_ACL_READ 4
#define ARCHIVE_ENTRY_ACL_EXECUTE 0x00000001
#define ARCHIVE_ENTRY_ACL_WRITE 0x00000002
#define ARCHIVE_ENTRY_ACL_READ 0x00000004
#define ARCHIVE_ENTRY_ACL_READ_DATA 0x00000008
#define ARCHIVE_ENTRY_ACL_LIST_DIRECTORY 0x00000008
#define ARCHIVE_ENTRY_ACL_WRITE_DATA 0x00000010
#define ARCHIVE_ENTRY_ACL_ADD_FILE 0x00000010
#define ARCHIVE_ENTRY_ACL_APPEND_DATA 0x00000020
#define ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY 0x00000020
#define ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS 0x00000040
#define ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS 0x00000080
#define ARCHIVE_ENTRY_ACL_DELETE_CHILD 0x00000100
#define ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES 0x00000200
#define ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES 0x00000400
#define ARCHIVE_ENTRY_ACL_DELETE 0x00000800
#define ARCHIVE_ENTRY_ACL_READ_ACL 0x00001000
#define ARCHIVE_ENTRY_ACL_WRITE_ACL 0x00002000
#define ARCHIVE_ENTRY_ACL_WRITE_OWNER 0x00004000
#define ARCHIVE_ENTRY_ACL_SYNCHRONIZE 0x00008000
/* We need to be able to specify either or both of these. */
#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 256
#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 512
#define ARCHIVE_ENTRY_ACL_PERMS_POSIX1E \
(ARCHIVE_ENTRY_ACL_EXECUTE \
| ARCHIVE_ENTRY_ACL_WRITE \
| ARCHIVE_ENTRY_ACL_READ)
#define ARCHIVE_ENTRY_ACL_PERMS_NFS4 \
(ARCHIVE_ENTRY_ACL_EXECUTE \
| ARCHIVE_ENTRY_ACL_READ_DATA \
| ARCHIVE_ENTRY_ACL_LIST_DIRECTORY \
| ARCHIVE_ENTRY_ACL_WRITE_DATA \
| ARCHIVE_ENTRY_ACL_ADD_FILE \
| ARCHIVE_ENTRY_ACL_APPEND_DATA \
| ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY \
| ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS \
| ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS \
| ARCHIVE_ENTRY_ACL_DELETE_CHILD \
| ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES \
| ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES \
| ARCHIVE_ENTRY_ACL_DELETE \
| ARCHIVE_ENTRY_ACL_READ_ACL \
| ARCHIVE_ENTRY_ACL_WRITE_ACL \
| ARCHIVE_ENTRY_ACL_WRITE_OWNER \
| ARCHIVE_ENTRY_ACL_SYNCHRONIZE)
/*
* Inheritance values (NFS4 ACLs only); included in permset.
*/
#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000
#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000
#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000
#define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000
#define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000
#define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000
#define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \
(ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \
| ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \
| ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS)
/* We need to be able to specify combinations of these. */
#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 256 /* POSIX.1e only */
#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 512 /* POSIX.1e only */
#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 1024 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_DENY 2048 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 4096 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 8192 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \
| ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)
#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \
| ARCHIVE_ENTRY_ACL_TYPE_DENY \
| ARCHIVE_ENTRY_ACL_TYPE_AUDIT \
| ARCHIVE_ENTRY_ACL_TYPE_ALARM)
/* Tag values mimic POSIX.1e */
#define ARCHIVE_ENTRY_ACL_USER 10001 /* Specified user. */
#define ARCHIVE_ENTRY_ACL_USER_OBJ 10002 /* User who owns the file. */
#define ARCHIVE_ENTRY_ACL_GROUP 10003 /* Specified group. */
#define ARCHIVE_ENTRY_ACL_GROUP_OBJ 10004 /* Group who owns the file. */
#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access. */
#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public. */
#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access (POSIX.1e only) */
#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public (POSIX.1e only) */
#define ARCHIVE_ENTRY_ACL_EVERYONE 10107 /* Everyone (NFS4 only) */
/*
* Set the ACL by clearing it and adding entries one at a time.
@ -363,17 +446,17 @@ __LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat
* default and access information in a single ACL list.
*/
__LA_DECL void archive_entry_acl_clear(struct archive_entry *);
__LA_DECL void archive_entry_acl_add_entry(struct archive_entry *,
__LA_DECL int archive_entry_acl_add_entry(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const char * /* name */);
__LA_DECL void archive_entry_acl_add_entry_w(struct archive_entry *,
__LA_DECL int archive_entry_acl_add_entry_w(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const wchar_t * /* name */);
/*
* To retrieve the ACL, first "reset", then repeatedly ask for the
* "next" entry. The want_type parameter allows you to request only
* access entries or only default entries.
* certain types of entries.
*/
__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */);
__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
@ -387,36 +470,29 @@ __LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type
* Construct a text-format ACL. The flags argument is a bitmask that
* can include any of the following:
*
* ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include access entries.
* ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include default entries.
* ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries.
* ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries.
* ARCHIVE_ENTRY_ACL_TYPE_NFS4 - Include NFS4 entries.
* ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
* each ACL entry. (As used by 'star'.)
* each ACL entry. ('star' introduced this for POSIX.1e, this flag
* also applies to NFS4.)
* ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each
* default ACL entry.
* default ACL entry, as used in old Solaris ACLs.
*/
#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
int /* flags */);
__LA_DECL const char *archive_entry_acl_text(struct archive_entry *,
int /* flags */);
/* Return a count of entries matching 'want_type' */
__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
/*
* Private ACL parser. This is private because it handles some
* very weird formats that clients should not be messing with.
* Clients should only deal with their platform-native formats.
* Because of the need to support many formats cleanly, new arguments
* are likely to get added on a regular basis. Clients who try to use
* this interface are likely to be surprised when it changes.
*
* You were warned!
*
* TODO: Move this declaration out of the public header and into
* a private header. Warnings above are silly.
*/
__LA_DECL int __archive_entry_acl_parse_w(struct archive_entry *,
const wchar_t *, int /* type */);
/* Return an opaque ACL object. */
/* There's not yet anything clients can actually do with this... */
struct archive_acl;
__LA_DECL struct archive_acl *archive_entry_acl(struct archive_entry *);
/*
* extended attributes
@ -437,6 +513,24 @@ __LA_DECL int archive_entry_xattr_reset(struct archive_entry *);
__LA_DECL int archive_entry_xattr_next(struct archive_entry *,
const char ** /* name */, const void ** /* value */, size_t *);
/*
* sparse
*/
__LA_DECL void archive_entry_sparse_clear(struct archive_entry *);
__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
__LA_INT64_T /* offset */, __LA_INT64_T /* length */);
/*
* To retrieve the xattr list, first "reset", then repeatedly ask for the
* "next" entry.
*/
__LA_DECL int archive_entry_sparse_count(struct archive_entry *);
__LA_DECL int archive_entry_sparse_reset(struct archive_entry *);
__LA_DECL int archive_entry_sparse_next(struct archive_entry *,
__LA_INT64_T * /* offset */, __LA_INT64_T * /* length */);
/*
* Utility to match up hardlinks.
*
@ -449,7 +543,7 @@ __LA_DECL int archive_entry_xattr_next(struct archive_entry *,
* be written.
* 4. Call archive_entry_linkify(resolver, NULL) until
* no more entries are returned.
* 5. Call archive_entry_link_resolver_free(resolver) to free resources.
* 5. Call archive_entry_linkresolver_free(resolver) to free resources.
*
* The entries returned have their hardlink and size fields updated
* appropriately. If an entry is passed in that does not refer to
@ -499,7 +593,7 @@ struct archive_entry_linkresolver;
* linkify(l2) => l1
* linkify(NULL) => l2 (at end, you retrieve remaining links)
* As the name suggests, this strategy is used by newer cpio variants.
* It's noticably more complex for the archiver, slightly more complex
* It's noticeably more complex for the archiver, slightly more complex
* for the dearchiver than the tar strategy, but makes it straightforward
* to restore a file using any link by simply continuing to scan until
* you see a link that is stored with a body. In contrast, the tar
@ -513,6 +607,8 @@ __LA_DECL void archive_entry_linkresolver_set_strategy(
__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *);
__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
struct archive_entry **, struct archive_entry **);
__LA_DECL struct archive_entry *archive_entry_partial_links(
struct archive_entry_linkresolver *res, unsigned int *links);
#ifdef __cplusplus
}

View File

@ -0,0 +1,233 @@
.\" Copyright (c) 2010 Joerg Sonnenberger
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd February 21, 2010
.Dt ARCHIVE_ENTRY_ACL 3
.Os
.Sh NAME
.Nm archive_entry_acl_add_entry ,
.Nm archive_entry_acl_add_entry_w ,
.Nm archive_entry_acl_clear ,
.Nm archive_entry_acl_count ,
.Nm archive_entry_acl_next ,
.Nm archive_entry_acl_next_w ,
.Nm archive_entry_acl_reset ,
.Nm archive_entry_acl_text_w
.Nd functions for manipulating Access Control Lists in archive entry descriptions
.Sh SYNOPSIS
.In archive_entry.h
.Ft void
.Fo archive_entry_acl_add_entry
.Fa "struct archive_entry *a"
.Fa "int type"
.Fa "int permset"
.Fa "int tag"
.Fa "int qualifier"
.Fa "const char *name"
.Fc
.Ft void
.Fo archive_entry_acl_add_entry_w
.Fa "struct archive_entry *a"
.Fa "int type"
.Fa "int permset"
.Fa "int tag"
.Fa "int qualifier"
.Fa "const wchar_t *name"
.Fc
.Ft void
.Fn archive_entry_acl_clear "struct archive_entry *a"
.Ft int
.Fn archive_entry_acl_count "struct archive_entry *a" "int type"
.Ft int
.Fo archive_entry_acl_next
.Fa "struct archive_entry *a"
.Fa "int type"
.Fa "int *ret_type"
.Fa "int *ret_permset"
.Fa "int *ret_tag"
.Fa "int *ret_qual"
.Fa "const char **ret_name"
.Fc
.Ft int
.Fo archive_entry_acl_next_w
.Fa "struct archive_entry *a"
.Fa "int type"
.Fa "int *ret_type"
.Fa "int *ret_permset"
.Fa "int *ret_tag"
.Fa "int *ret_qual"
.Fa "const wchar_t **ret_name"
.Fc
.Ft int
.Fn archive_entry_acl_reset "struct archive_entry *a" "int type"
.Ft const wchar_t *
.Fn archive_entry_acl_text_w "struct archive_entry *a" "int flags"
.\" enum?
.Sh DESCRIPTION
An
.Dq Access Control List
is a generalisation of the classic Unix permission system.
The ACL interface of
.Nm libarchive
is derived from the POSIX.1e draft, but restricted to simplify dealing
with practical implementations in various Operating Systems and archive formats.
.Pp
An ACL consists of a number of independent entries.
Each entry specifies the permission set as bitmask of basic permissions.
Valid permissions are:
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_EXECUTE"
.It Dv ARCHIVE_ENTRY_ACL_EXECUTE
.It Dv ARCHIVE_ENTRY_ACL_WRITE
.It Dv ARCHIVE_ENTRY_ACL_READ
.El
The permissions correspond to the normal Unix permissions.
.Pp
The tag specifies the principal to which the permission applies.
Valid values are:
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_GROUP_OBJ"
.It Dv ARCHIVE_ENTRY_ACL_USER
The user specified by the name field.
.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
The owner of the file.
.It Dv ARCHIVE_ENTRY_ACL_GROUP
The group specied by the name field.
.It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
The group who owns the file.
.It Dv ARCHIVE_ENTRY_ACL_MASK
The maximum permissions to be obtained via group permissions.
.It Dv ARCHIVE_ENTRY_ACL_OTHER
Any principal who doesn't have a user or group entry.
.El
The principals
.Dv ARCHIVE_ENTRY_ACL_USER_OBJ ,
.Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
and
.Dv ARCHIVE_ENTRY_ACL_OTHER
are equivalent to user, group and other in the classic Unix permission
model and specify non-extended ACL entries.
.Pp
All files have an access ACL
.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS .
This specifies the permissions required for access to the file itself.
Directories have an additional ACL
.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT ,
which controls the initial access ACL for newly created directory entries.
.Pp
.Fn archive_entry_acl_add_entry
and
.Fn archive_entry_acl_add_entry_w
add a single ACL entry.
For the access ACL and non-extended principals, the classic Unix permissions
are updated.
.Pp
.Fn archive_entry_acl_clear
removes all ACL entries and resets the enumeration pointer.
.Pp
.Fn archive_entry_acl_count
counts the ACL entries that have the given type mask.
.Fa type
can be the bitwise-or of
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
and
.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT .
If
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
is included and at least one extended ACL entry is found,
the three non-extened ACLs are added.
.Pp
.Fn archive_entry_acl_next
and
.Fn archive_entry_acl_next_w
return the next entry of the ACL list.
This functions may only be called after
.Fn archive_entry_acl_reset
has indicated the presence of extended ACL entries.
.Pp
.Fn archive_entry_acl_reset
prepare reading the list of ACL entries with
.Fn archive_entry_acl_next
or
.Fn archive_entry_acl_next_w .
The function returns either 0, if no non-extended ACLs are found.
In this case, the access permissions should be obtained by
.Xr archive_entry_mode 3
or set using
.Xr chmod 2 .
Otherwise, the function returns the same value as
.Fn archive_entry_acl_count .
.Pp
.Fn archive_entry_acl_text_w
converts the ACL entries for the given type mask into a wide string.
In addition to the normal type flags,
.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
and
.Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT
can be specified to further customize the result.
The returned long string is valid until the next call to
.Fn archive_entry_acl_clear ,
.Fn archive_entry_acl_add_entry ,
.Fn archive_entry_acl_add_entry_w
or
.Fn archive_entry_acl_text_w .
.Sh RETURN VALUES
.Fn archive_entry_acl_count
and
.Fn archive_entry_acl_reset
returns the number of ACL entries that match the given type mask.
If the type mask includes
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
and at least one extended ACL entry exists, the three classic Unix
permissions are counted.
.Pp
.Fn archive_entry_acl_next
and
.Fn archive_entry_acl_next_w
return
.Dv ARCHIVE_OK
on success,
.Dv ARCHIVE_EOF
if no more ACL entries exist
and
.Dv ARCHIVE_WARN
if
.Fn archive_entry_acl_reset
has not been called first.
.Pp
.Fn archive_entry_text_w
returns a wide string representation of the ACL entrise matching the
given type mask.
The returned long string is valid until the next call to
.Fn archive_entry_acl_clear ,
.Fn archive_entry_acl_add_entry ,
.Fn archive_entry_acl_add_entry_w
or
.Fn archive_entry_acl_text_w .
.Sh SEE ALSO
.Xr archive 3 ,
.Xr archive_entry 3
.Sh BUGS
.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
and
.Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT
are not documented.

View File

@ -63,12 +63,13 @@ archive_entry_copy_bhfi(struct archive_entry *entry,
archive_entry_set_mtime(entry, secs, nsecs);
fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
archive_entry_set_birthtime(entry, secs, nsecs);
archive_entry_set_ctime(entry, secs, nsecs);
archive_entry_set_dev(entry, bhfi->dwVolumeSerialNumber);
archive_entry_set_ino64(entry, (((int64_t)bhfi->nFileIndexHigh) << 32)
+ bhfi->nFileIndexLow);
archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
archive_entry_set_size(entry, (((int64_t)bhfi->nFileSizeHigh) << 32)
+ bhfi->nFileSizeLow);
// archive_entry_set_mode(entry, st->st_mode);
/* archive_entry_set_mode(entry, st->st_mode); */
}
#endif

View File

@ -30,6 +30,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_copy_stat.c 189466 2009-03
#include <sys/stat.h>
#endif
#include "archive.h"
#include "archive_entry.h"
void
@ -59,12 +60,13 @@ archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st)
archive_entry_set_atime(entry, st->st_atime, 0);
archive_entry_set_ctime(entry, st->st_ctime, 0);
archive_entry_set_mtime(entry, st->st_mtime, 0);
#if HAVE_STRUCT_STAT_ST_BIRTHTIME
archive_entry_set_birthtime(entry, st->st_birthtime, 0);
#endif
#endif
#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
archive_entry_set_birthtime(entry, st->st_birthtime, st->st_birthtimespec.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_BIRTHTIME
archive_entry_set_birthtime(entry, st->st_birthtime, 0);
#else
archive_entry_unset_birthtime(entry);
#endif
archive_entry_set_dev(entry, st->st_dev);
archive_entry_set_gid(entry, st->st_gid);

View File

@ -70,10 +70,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_link_resolver.c 201100 200
struct links_entry {
struct links_entry *next;
struct links_entry *previous;
int links; /* # links not yet seen */
int hash;
struct archive_entry *canonical;
struct archive_entry *entry;
size_t hash;
unsigned int links; /* # links not yet seen */
};
struct archive_entry_linkresolver {
@ -84,32 +84,37 @@ struct archive_entry_linkresolver {
int strategy;
};
#define NEXT_ENTRY_DEFERRED 1
#define NEXT_ENTRY_PARTIAL 2
#define NEXT_ENTRY_ALL (NEXT_ENTRY_DEFERRED | NEXT_ENTRY_PARTIAL)
static struct links_entry *find_entry(struct archive_entry_linkresolver *,
struct archive_entry *);
static void grow_hash(struct archive_entry_linkresolver *);
static struct links_entry *insert_entry(struct archive_entry_linkresolver *,
struct archive_entry *);
static struct links_entry *next_entry(struct archive_entry_linkresolver *);
static struct links_entry *next_entry(struct archive_entry_linkresolver *,
int);
struct archive_entry_linkresolver *
archive_entry_linkresolver_new(void)
{
struct archive_entry_linkresolver *res;
size_t i;
res = malloc(sizeof(struct archive_entry_linkresolver));
/* Check for positive power-of-two */
if (links_cache_initial_size == 0 ||
(links_cache_initial_size & (links_cache_initial_size - 1)) != 0)
return (NULL);
res = calloc(1, sizeof(struct archive_entry_linkresolver));
if (res == NULL)
return (NULL);
memset(res, 0, sizeof(struct archive_entry_linkresolver));
res->number_buckets = links_cache_initial_size;
res->buckets = malloc(res->number_buckets *
sizeof(res->buckets[0]));
res->buckets = calloc(res->number_buckets, sizeof(res->buckets[0]));
if (res->buckets == NULL) {
free(res);
return (NULL);
}
for (i = 0; i < res->number_buckets; i++)
res->buckets[i] = NULL;
return (res);
}
@ -120,6 +125,11 @@ archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *res,
int fmtbase = fmt & ARCHIVE_FORMAT_BASE_MASK;
switch (fmtbase) {
case ARCHIVE_FORMAT_7ZIP:
case ARCHIVE_FORMAT_AR:
case ARCHIVE_FORMAT_ZIP:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
break;
case ARCHIVE_FORMAT_CPIO:
switch (fmt) {
case ARCHIVE_FORMAT_CPIO_SVR4_NOCRC:
@ -134,11 +144,14 @@ archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *res,
case ARCHIVE_FORMAT_MTREE:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE;
break;
case ARCHIVE_FORMAT_ISO9660:
case ARCHIVE_FORMAT_SHAR:
case ARCHIVE_FORMAT_TAR:
case ARCHIVE_FORMAT_XAR:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_TAR;
break;
default:
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_TAR;
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
break;
}
}
@ -151,12 +164,9 @@ archive_entry_linkresolver_free(struct archive_entry_linkresolver *res)
if (res == NULL)
return;
if (res->buckets != NULL) {
while ((le = next_entry(res)) != NULL)
archive_entry_free(le->entry);
free(res->buckets);
res->buckets = NULL;
}
while ((le = next_entry(res, NEXT_ENTRY_ALL)) != NULL)
archive_entry_free(le->entry);
free(res->buckets);
free(res);
}
@ -170,7 +180,7 @@ archive_entry_linkify(struct archive_entry_linkresolver *res,
*f = NULL; /* Default: Don't return a second entry. */
if (*e == NULL) {
le = next_entry(res);
le = next_entry(res, NEXT_ENTRY_DEFERRED);
if (le != NULL) {
*e = le->entry;
le->entry = NULL;
@ -249,7 +259,7 @@ find_entry(struct archive_entry_linkresolver *res,
struct archive_entry *entry)
{
struct links_entry *le;
int hash, bucket;
size_t hash, bucket;
dev_t dev;
int64_t ino;
@ -261,16 +271,12 @@ find_entry(struct archive_entry_linkresolver *res,
res->spare = NULL;
}
/* If the links cache overflowed and got flushed, don't bother. */
if (res->buckets == NULL)
return (NULL);
dev = archive_entry_dev(entry);
ino = archive_entry_ino64(entry);
hash = (int)(dev ^ ino);
hash = (size_t)(dev ^ ino);
/* Try to locate this entry in the links cache. */
bucket = hash % res->number_buckets;
bucket = hash & (res->number_buckets - 1);
for (le = res->buckets[bucket]; le != NULL; le = le->next) {
if (le->hash == hash
&& dev == archive_entry_dev(le->canonical)
@ -301,7 +307,7 @@ find_entry(struct archive_entry_linkresolver *res,
}
static struct links_entry *
next_entry(struct archive_entry_linkresolver *res)
next_entry(struct archive_entry_linkresolver *res, int mode)
{
struct links_entry *le;
size_t bucket;
@ -309,22 +315,27 @@ next_entry(struct archive_entry_linkresolver *res)
/* Free a held entry. */
if (res->spare != NULL) {
archive_entry_free(res->spare->canonical);
archive_entry_free(res->spare->entry);
free(res->spare);
res->spare = NULL;
}
/* If the links cache overflowed and got flushed, don't bother. */
if (res->buckets == NULL)
return (NULL);
/* Look for next non-empty bucket in the links cache. */
for (bucket = 0; bucket < res->number_buckets; bucket++) {
le = res->buckets[bucket];
if (le != NULL) {
for (le = res->buckets[bucket]; le != NULL; le = le->next) {
if (le->entry != NULL &&
(mode & NEXT_ENTRY_DEFERRED) == 0)
continue;
if (le->entry == NULL &&
(mode & NEXT_ENTRY_PARTIAL) == 0)
continue;
/* Remove it from this hash bucket. */
if (le->next != NULL)
le->next->previous = le->previous;
res->buckets[bucket] = le->next;
if (le->previous != NULL)
le->previous->next = le->next;
else
res->buckets[bucket] = le->next;
res->number_entries--;
/* Defer freeing this entry. */
res->spare = le;
@ -339,13 +350,12 @@ insert_entry(struct archive_entry_linkresolver *res,
struct archive_entry *entry)
{
struct links_entry *le;
int hash, bucket;
size_t hash, bucket;
/* Add this entry to the links cache. */
le = malloc(sizeof(struct links_entry));
le = calloc(1, sizeof(struct links_entry));
if (le == NULL)
return (NULL);
memset(le, 0, sizeof(*le));
le->canonical = archive_entry_clone(entry);
/* If the links cache is getting too full, enlarge the hash table. */
@ -353,7 +363,7 @@ insert_entry(struct archive_entry_linkresolver *res,
grow_hash(res);
hash = archive_entry_dev(entry) ^ archive_entry_ino64(entry);
bucket = hash % res->number_buckets;
bucket = hash & (res->number_buckets - 1);
/* If we could allocate the entry, record it. */
if (res->buckets[bucket] != NULL)
@ -376,30 +386,59 @@ grow_hash(struct archive_entry_linkresolver *res)
/* Try to enlarge the bucket list. */
new_size = res->number_buckets * 2;
new_buckets = malloc(new_size * sizeof(struct links_entry *));
if (new_size < res->number_buckets)
return;
new_buckets = calloc(new_size, sizeof(struct links_entry *));
if (new_buckets != NULL) {
memset(new_buckets, 0,
new_size * sizeof(struct links_entry *));
for (i = 0; i < res->number_buckets; i++) {
while (res->buckets[i] != NULL) {
/* Remove entry from old bucket. */
le = res->buckets[i];
res->buckets[i] = le->next;
if (new_buckets == NULL)
return;
/* Add entry to new bucket. */
bucket = le->hash % new_size;
for (i = 0; i < res->number_buckets; i++) {
while (res->buckets[i] != NULL) {
/* Remove entry from old bucket. */
le = res->buckets[i];
res->buckets[i] = le->next;
if (new_buckets[bucket] != NULL)
new_buckets[bucket]->previous =
le;
le->next = new_buckets[bucket];
le->previous = NULL;
new_buckets[bucket] = le;
}
/* Add entry to new bucket. */
bucket = le->hash & (new_size - 1);
if (new_buckets[bucket] != NULL)
new_buckets[bucket]->previous = le;
le->next = new_buckets[bucket];
le->previous = NULL;
new_buckets[bucket] = le;
}
free(res->buckets);
res->buckets = new_buckets;
res->number_buckets = new_size;
}
free(res->buckets);
res->buckets = new_buckets;
res->number_buckets = new_size;
}
struct archive_entry *
archive_entry_partial_links(struct archive_entry_linkresolver *res,
unsigned int *links)
{
struct archive_entry *e;
struct links_entry *le;
/* Free a held entry. */
if (res->spare != NULL) {
archive_entry_free(res->spare->canonical);
archive_entry_free(res->spare->entry);
free(res->spare);
res->spare = NULL;
}
le = next_entry(res, NEXT_ENTRY_PARTIAL);
if (le != NULL) {
e = le->canonical;
if (links != NULL)
*links = le->links;
le->canonical = NULL;
} else {
e = NULL;
if (links != NULL)
*links = 0;
}
return (e);
}

View File

@ -0,0 +1,224 @@
.\" Copyright (c) 2010 Joerg Sonnenberger
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd February 20, 2010
.Dt ARCHIVE_ENTRY_LINKIFY 3
.Os
.Sh NAME
.Nm archive_entry_linkresolver ,
.Nm archive_entry_linkresolver_new ,
.Nm archive_entry_linkresolver_set_strategy ,
.Nm archive_entry_linkresolver_free ,
.Nm archive_entry_linkify
.Nd hardlink resolver functions
.Sh LIBRARY
.Lb libarchive
.Sh SYNOPSIS
.In archive_entry.h
.Ft struct archive_entry_linkresolver *
.Fn archive_entry_linkresolver_new void
.Ft void
.Fo archive_entry_linkresolver_set_strategy
.Fa "struct archive_entry_linkresolver *resolver"
.Fa "int format"
.Fc
.Ft void
.Fo archive_entry_linkresolver_free
.Fa "struct archive_entry_linkresolver *resolver"
.Fc
.Ft void
.Fo archive_entry_linkify
.Fa "struct archive_entry_linkresolver *resolver"
.Fa "struct archive_entry **entry"
.Fa "struct archive_entry **sparse"
.Fc
.Sh DESCRIPTION
Programs that want to create archives have to deal with hardlinks.
Hardlinks are handled in different ways by the archive formats.
The basic strategies are:
.Bl -enum
.It
Ignore hardlinks and store the body for each reference (old cpio, zip).
.It
Store the body the first time an inode is seen (ustar, pax).
.It
Store the body the last time an inode is seen (new cpio).
.El
.Pp
The
.Nm
functions help by providing a unified interface and handling the complexity
behind the scene.
.Pp
The
.Nm
functions assume that
.Vt archive_entry
instances have valid nlinks, inode and device values.
The inode and device value is used to match entries.
The nlinks value is used to determined if all references have been found and
if the internal references can be recycled.
.Pp
The
.Fn archive_entry_linkresolver_new
function allocates a new link resolver.
The instance can be freed using
.Fn archive_entry_linkresolver_free .
All deferred entries are flushed and the internal storage is freed.
.Pp
The
.Fn archive_entry_linkresolver_set_strategy
function selects the optimal hardlink strategy for the given format.
The format code can be obtained from
.Xr archive_format 3 .
The function can be called more than once, but it is recommended to
flush all deferred entries first.
.Pp
The
.Fn archive_entry_linkify
function is the core of
.Nm .
The
.Fn entry
argument points to the
.Vt archive_entry
that should be written.
Depending on the strategy one of the following actions is taken:
.Bl -enum
.It
For the simple archive formats
.Va *entry
is left unmodified and
.Va *sparse
is set to
.Dv NULL .
.It
For tar like archive formats,
.Va *sparse
is set to
.Dv NULL .
If
.Va *entry
is
.Dv NULL ,
no action is taken.
If the hardlink count of
.Va *entry
is larger than 1 and the file type is a regular file or symbolic link,
the internal list is searched for a matching inode.
If such an inode is found, the link count is decremented and the file size
of
.Va *entry
is set to 0 to notify that no body should be written.
If no such inode is found, a copy of the entry is added to the internal cache
with a link count reduced by one.
.It
For new cpio like archive formats a value for
.Va *entry
of
.Dv NULL
is used to flush deferred entries.
In that case
.Va *entry
is set to an arbitrary deferred entry and the entry itself is removed from the
internal list.
If the internal list is empty,
.Va *entry
is set to
.Dv NULL .
In either case,
.Va *sparse
is set to
.Dv NULL
and the function returns.
If the hardlink count of
.Va *entry
is one or the file type is a directory or device,
.Va *sparse
is set to
.Dv NULL
and no further action is taken.
Otherwise, the internal list is searched for a matching inode.
If such an inode is not found, the entry is added to the internal list,
both
.Va *entry
and
.Va *sparse
are set to
.Dv NULL
and the function returns.
If such an inode is found, the link count is decremented.
If it remains larger than one, the existing entry on the internal list
is swapped with
.Va *entry
after retaining the link count.
The existing entry is returned in
.Va *entry .
If the link count reached one, the new entry is also removed from the
internal list and returned in
.Va *sparse .
Otherwise
.Va *sparse
is set to
.Dv NULL .
.El
.Pp
The general usage is therefore:
.Bl -enum
.It
For each new archive entry, call
.Fn archive_entry_linkify .
.It
Keep in mind that the entries returned may have a size of 0 now.
.It
If
.Va *entry
is not
.Dv NULL ,
archive it.
.It
If
.Va *sparse
is not
.Dv NULL ,
archive it.
.It
After all entries have been written to disk, call
.Fn archive_entry_linkify
with
.Va *entry
set to
.Dv NULL
and archive the returned entry as long as it is not
.Dv NULL .
.El
.Sh RETURN VALUES
.Fn archive_entry_linkresolver_new
returns
.Dv NULL
on
.Xr malloc 3
failures.
.Sh SEE ALSO
.Xr archive_entry 3

View File

@ -0,0 +1,88 @@
/*-
* Copyright (c) 2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
struct archive_entry;
struct archive_string_conv;
/*
* Utility functions to set and get entry attributes by translating
* character-set. These are designed for use in format readers and writers.
*
* The return code and interface of these are quite different from other
* functions for archive_entry defined in archive_entry.h.
* Common return code are:
* Return 0 if the string conversion succeeded.
* Return -1 if the string conversion failed.
*/
#define archive_entry_gname_l _archive_entry_gname_l
int _archive_entry_gname_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_hardlink_l _archive_entry_hardlink_l
int _archive_entry_hardlink_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_pathname_l _archive_entry_pathname_l
int _archive_entry_pathname_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_symlink_l _archive_entry_symlink_l
int _archive_entry_symlink_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_uname_l _archive_entry_uname_l
int _archive_entry_uname_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_acl_text_l _archive_entry_acl_text_l
int _archive_entry_acl_text_l(struct archive_entry *, int,
const char **, size_t *, struct archive_string_conv *);
#define archive_entry_copy_gname_l _archive_entry_copy_gname_l
int _archive_entry_copy_gname_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#define archive_entry_copy_hardlink_l _archive_entry_copy_hardlink_l
int _archive_entry_copy_hardlink_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#define archive_entry_copy_link_l _archive_entry_copy_link_l
int _archive_entry_copy_link_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#define archive_entry_copy_pathname_l _archive_entry_copy_pathname_l
int _archive_entry_copy_pathname_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#define archive_entry_copy_symlink_l _archive_entry_copy_symlink_l
int _archive_entry_copy_symlink_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#define archive_entry_copy_uname_l _archive_entry_copy_uname_l
int _archive_entry_copy_uname_l(struct archive_entry *,
const char *, size_t, struct archive_string_conv *);
#endif /* ARCHIVE_ENTRY_LOCALE_H_INCLUDED */

View File

@ -0,0 +1,151 @@
.\" Copyright (c) 2010 Joerg Sonnenberger
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd February 22, 2010
.Dt ARCHIVE_ENTRY_PATHS 3
.Os
.Sh NAME
.Nm archive_entry_hardlink ,
.Nm archive_entry_hardlink_w ,
.Nm archive_entry_set_hardlink ,
.Nm archive_entry_copy_hardlink ,
.Nm archive_entry_copy_hardlink_w ,
.Nm archve_entry_update_hardlink_utf8 ,
.Nm archive_entry_set_link ,
.Nm archive_entry_copy_link ,
.Nm archive_entry_copy_link_w ,
.Nm archve_entry_update_link_utf8 ,
.Nm archive_entry_pathname ,
.Nm archive_entry_pathname_w ,
.Nm archive_entry_set_pathname ,
.Nm archive_entry_copy_pathname ,
.Nm archive_entry_copy_pathname_w ,
.Nm archve_entry_update_pathname_utf8 ,
.Nm archive_entry_sourcepath ,
.Nm archive_entry_copy_sourcepath ,
.Nm archive_entry_symlink,
.Nm archive_entry_symlink_w,
.Nm archive_entry_set_symlink ,
.Nm archive_entry_copy_symlink ,
.Nm archive_entry_copy_symlink_w ,
.Nm archve_entry_update_symlink_utf8
.Nd functions for manipulating path names in archive entry descriptions
.Sh SYNOPSIS
.In archive_entry.h
.Ft const char *
.Fn archive_entry_hardlink "struct archive_entry *a"
.Ft const wchar_t *
.Fn archive_entry_hardlink_w "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_hardlink "struct archive_entry *a" "const char *path"
.Ft void
.Fn archive_entry_copy_hardlink "struct archive_entry *a" "const char *path"
.Ft void
.Fn archive_entry_copy_hardlink_w "struct archive_entry *a "const wchar_t *path"
.Ft int
.Fn archive_entry_update_hardlink_utf8 "struct archive_entry *a" "const char *path"
.Ft void
.Fn archive_entry_set_link "struct archive_entry *a" "const char *path"
.Ft void
.Fn archive_entry_copy_link "struct archive_entry *a" " const char *path"
.Ft void
.Fn archive_entry_copy_link_w "struct archive_entry *a" " const wchar_t *path"
.Ft int
.Fn archive_entry_update_link_utf8 "struct archive_entry *a" " const char *path"
.Ft const char *
.Fn archive_entry_pathname "struct archive_entry *a"
.Ft const wchar_t *
.Fn archive_entry_pathname_w "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_pathname "struct archive_entry *a" "const char *path"
.Ft void
.Fn archive_entry_copy_pathname "struct archive_entry *a" "const char *path"
.Ft void
.Fn archive_entry_copy_pathname_w "struct archive_entry *a" "const wchar_t *path"
.Ft int
.Fn archive_entry_update_pathname_utf8 "struct archive_entry *a" "const char *path"
.Ft const char *
.Fn archive_entry_sourcepath "struct archive_entry *a"
.Ft void
.Fn archive_entry_copy_sourcepath "struct archive_entry *a" "const char *path"
.Ft const char *
.Fn archive_entry_symlink "struct archive_entry *a"
.Ft const wchar_t *
.Fn archive_entry_symlink_w "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_symlink "struct archive_entry *a" "const char *path"
.Ft void
.Fn archive_entry_copy_symlink "struct archive_entry *a" "const char *path"
.Ft void
.Fn archive_entry_copy_symlink_w "struct archive_entry *a" "const wchar_t *path"
.Ft int
.Fn archive_entry_update_symlink_utf8 "struct archive_entry *a" "const char *path"
.Sh DESCRIPTION
Path names supported by
.Xr archive_entry 3 :
.Bl -tag -width "sourcepath" -compact
.It hardlink
Destination of the hardlink.
.It link
Update only.
For a symlink, update the destination.
Otherwise, make the entry a hardlink and alter
the destination for that.
.It pathname
Path in the archive
.It sourcepath
Path on the disk for use by
.Xr archive_read_disk 3 .
.It symlink
Destination of the symbolic link.
.El
.Pp
Path names can be provided in one of three different ways:
.Bl -tag -width "wchar_t *"
.It char *
Multibyte strings in the current locale.
.It wchar_t *
Wide character strings in the current locale.
The accessor functions are named
.Fn XXX_w .
.It UTF-8
Unicode strings encoded as UTF-8.
This are convience functions to update both the multibyte and wide
character strings at the same time.
.El
.Pp
The sourcepath is a pure filesystem concept and never stored in an
archive directly.
.Pp
For that reason, it is only available as multibyte string.
The link path is a convience function for conditionally setting
hardlink or symlink destination.
It doesn't have a corresponding get accessor function.
.Pp
.Fn archive_entry_set_XXX
is an alias for
.Fn archive_entry_copy_XXX .
.Sh SEE ALSO
.Xr archive 3 ,
.Xr archive_entry 3

View File

@ -0,0 +1,207 @@
.\" Copyright (c) 2003-2007 Tim Kientzle
.\" Copyright (c) 2010 Joerg Sonnenberger
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd February 22, 2010
.Dt ARCHIVE_ENTRY_PERMS 3
.Os
.Sh NAME
.Nm archive_entry_gid ,
.Nm archive_entry_set_gid ,
.Nm archive_entry_uid ,
.Nm archive_entry_set_uid ,
.Nm archive_entry_perm ,
.Nm archive_entry_set_perm ,
.Nm archive_entry_strmode ,
.Nm archive_entry_uname
.Nm archive_entry_uname_w
.Nm archive_entry_set_uname ,
.Nm archive_entry_copy_uname ,
.Nm archive_entry_copy_uname_w ,
.Nm archive_entry_update_uname_utf8 ,
.Nm archive_entry_gname ,
.Nm archive_entry_gname_w ,
.Nm archive_entry_set_gname ,
.Nm archive_entry_copy_gname ,
.Nm archive_entry_copy_gname_w ,
.Nm archive_entry_update_gname_utf8 ,
.Nm archive_entry_fflags ,
.Nm archive_entry_fflags_text ,
.Nm archive_entry_set_fflags ,
.Nm archive_entry_copy_fflags_text ,
.Nm archive_entry_copy_fflags_text_w
.Nd functions for manipulating ownership and permissions in archive entry descriptions
.Sh SYNOPSIS
.In archive_entry.h
.Ft gid_t
.Fn archive_entry_gid "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_gid "struct archive_entry *a" "gid_t gid"
.Ft uid_t
.Fn archive_entry_uid "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_uid "struct archive_entry *a" "uid_t uid"
.Ft mode_t
.Fn archive_entry_perm "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_perm "struct archive_entry *a" "mode_t mode"
.Ft const char *
.Fn archive_entry_strmode "struct archive_entry *a"
.Ft const char *
.Fn archive_entry_gname "struct archive_entry *a"
.Ft const wchar_t *
.Fn archive_entry_gname_w "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_gname "struct archive_entry *a" "const char *a"
.Ft void
.Fn archive_entry_copy_gname "struct archive_entry *a" "const char *name"
.Ft void
.Fn archive_entry_copy_gname_w "struct archive_entry *a" "const wchar_t *name"
.Ft int
.Fn archive_entry_update_gname_utf8 "struct archive_entry *a" "const char *name"
.Ft const char *
.Fn archive_entry_uname "struct archive_entry *a"
.Ft const wchar_t *
.Fn archive_entry_uname_w "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_uname "struct archive_entry *a" "const char *name"
.Ft void
.Fn archive_entry_copy_uname "struct archive_entry *a" "const char *name"
.Ft void
.Fn archive_entry_copy_uname_w "struct archive_entry *a" "const wchar_t *name"
.Ft int
.Fn archive_entry_update_uname_utf8 "struct archive_entry *a" "const char *name"
.Ft void
.Fo archive_entry_fflags
.Fa "struct archive_entry *a"
.Fa "unsigned long *set_bits"
.Fa "unsigned long *clear_bits"
.Fc
.Ft const char *
.Fn archive_entry_fflags_text "struct archive_entry *a"
.Ft void
.Fo archive_entry_set_fflags
.Fa "struct archive_entry *a"
.Fa "unsigned long set_bits"
.Fa "unsigned long clear_bits"
.Fc
.Ft const char *
.Fn archive_entry_copy_fflags_text "struct archive_entry *a" "const char *text"
.Ft const wchar_t *
.Fn archive_entry_copy_fflags_text_w "struct archive_entry *a" "const wchar_t *text"
.Sh DESCRIPTION
.Ss User id, group id and mode
The functions
.Fn archive_entry_uid ,
.Fn archive_entry_gid ,
and
.Fn archive_entry_perm
can be used to extract the user id, group id and permission from the given entry.
The corresponding functions
.Fn archive_entry_set_uid ,
.Fn archive_entry_set_gid ,
and
.Fn archive_entry_set_perm
store the given user id, group id and permission in the entry.
The permission is also set as side effect of calling
.Fn archive_entry_set_mode .
.Pp
.Fn archive_entry_strmode
returns a string representation of the permission as used by the long mode of
.Xr ls 1 .
.Ss User and group name
User and group names can be provided in one of three different ways:
.Bl -tag -width "wchar_t *"
.It char *
Multibyte strings in the current locale.
.It wchar_t *
Wide character strings in the current locale.
The accessor functions are named
.Fn XXX_w .
.It UTF-8
Unicode strings encoded as UTF-8.
This are convience functions to update both the multibyte and wide
character strings at the same time.
.El
.Pp
.Fn archive_entry_set_XXX
is an alias for
.Fn archive_entry_copy_XXX .
.Ss File Flags
File flags are transparently converted between a bitmap
representation and a textual format.
For example, if you set the bitmap and ask for text, the library
will build a canonical text format.
However, if you set a text format and request a text format,
you will get back the same text, even if it is ill-formed.
If you need to canonicalize a textual flags string, you should first set the
text form, then request the bitmap form, then use that to set the bitmap form.
Setting the bitmap format will clear the internal text representation
and force it to be reconstructed when you next request the text form.
.Pp
The bitmap format consists of two integers, one containing bits
that should be set, the other specifying bits that should be
cleared.
Bits not mentioned in either bitmap will be ignored.
Usually, the bitmap of bits to be cleared will be set to zero.
In unusual circumstances, you can force a fully-specified set
of file flags by setting the bitmap of flags to clear to the complement
of the bitmap of flags to set.
(This differs from
.Xr fflagstostr 3 ,
which only includes names for set bits.)
Converting a bitmap to a textual string is a platform-specific
operation; bits that are not meaningful on the current platform
will be ignored.
.Pp
The canonical text format is a comma-separated list of flag names.
The
.Fn archive_entry_copy_fflags_text
and
.Fn archive_entry_copy_fflags_text_w
functions parse the provided text and sets the internal bitmap values.
This is a platform-specific operation; names that are not meaningful
on the current platform will be ignored.
The function returns a pointer to the start of the first name that was not
recognized, or NULL if every name was recognized.
Note that every name \(em including names that follow an unrecognized
name \(em will be evaluated, and the bitmaps will be set to reflect
every name that is recognized.
(In particular, this differs from
.Xr strtofflags 3 ,
which stops parsing at the first unrecognized name.)
.Sh SEE ALSO
.Xr archive 3 ,
.Xr archive_entry 3 ,
.Xr archive_entry_acl 3 ,
.Xr archive_read_disk 3 ,
.Xr archive_write_disk 3
.Sh BUGS
The platform types
.Vt uid_t
and
.Vt gid_t
are often 16 or 32 bit wide.
In this case it is possible that the ids can not be correctly restored
from archives and get truncated.

View File

@ -32,36 +32,9 @@
#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
#include "archive_acl_private.h"
#include "archive_string.h"
/*
* Handle wide character (i.e., Unicode) and non-wide character
* strings transparently.
*/
struct aes {
struct archive_string aes_mbs;
struct archive_string aes_utf8;
const wchar_t *aes_wcs;
/* Bitmap of which of the above are valid. Because we're lazy
* about malloc-ing and reusing the underlying storage, we
* can't rely on NULL pointers to indicate whether a string
* has been set. */
int aes_set;
#define AES_SET_MBS 1
#define AES_SET_UTF8 2
#define AES_SET_WCS 4
};
struct ae_acl {
struct ae_acl *next;
int type; /* E.g., access or default */
int tag; /* E.g., user/group/other/mask */
int permset; /* r/w/x bits */
int id; /* uid/gid for user/group */
struct aes name; /* uname/gname */
};
struct ae_xattr {
struct ae_xattr *next;
@ -70,6 +43,13 @@ struct ae_xattr {
size_t size;
};
struct ae_sparse {
struct ae_sparse *next;
int64_t offset;
int64_t length;
};
/*
* Description of an archive entry.
*
@ -91,6 +71,8 @@ struct ae_xattr {
* TODO: Design a good API for handling sparse files.
*/
struct archive_entry {
struct archive *archive;
/*
* Note that ae_stat.st_mode & AE_IFMT can be 0!
*
@ -101,10 +83,15 @@ struct archive_entry {
*/
/*
* Read archive_entry_copy_stat.c for an explanation of why I
* don't just use "struct stat" instead of "struct aest" here
* and why I have this odd pointer to a separately-allocated
* struct stat.
* We have a "struct aest" for holding file metadata rather than just
* a "struct stat" because on some platforms the "struct stat" has
* fields which are too narrow to hold the range of possible values;
* we don't want to lose information if we read an archive and write
* out another (e.g., in "tar -cf new.tar @old.tar").
*
* The "stat" pointer points to some form of platform-specific struct
* stat; it is declared as a void * rather than a struct stat * as
* some platforms have multiple varieties of stat structures.
*/
void *stat;
int stat_valid; /* Set to 0 whenever a field in aest changes. */
@ -118,12 +105,11 @@ struct archive_entry {
uint32_t aest_mtime_nsec;
int64_t aest_birthtime;
uint32_t aest_birthtime_nsec;
gid_t aest_gid;
int64_t aest_gid;
int64_t aest_ino;
mode_t aest_mode;
uint32_t aest_nlink;
uint64_t aest_size;
uid_t aest_uid;
int64_t aest_uid;
/*
* Because converting between device codes and
* major/minor values is platform-specific and
@ -150,35 +136,41 @@ struct archive_entry {
#define AE_SET_MTIME 16
#define AE_SET_BIRTHTIME 32
#define AE_SET_SIZE 64
#define AE_SET_INO 128
#define AE_SET_DEV 256
/*
* Use aes here so that we get transparent mbs<->wcs conversions.
*/
struct aes ae_fflags_text; /* Text fflags per fflagstostr(3) */
struct archive_mstring ae_fflags_text; /* Text fflags per fflagstostr(3) */
unsigned long ae_fflags_set; /* Bitmap fflags */
unsigned long ae_fflags_clear;
struct aes ae_gname; /* Name of owning group */
struct aes ae_hardlink; /* Name of target for hardlink */
struct aes ae_pathname; /* Name of entry */
struct aes ae_symlink; /* symlink contents */
struct aes ae_uname; /* Name of owner */
struct archive_mstring ae_gname; /* Name of owning group */
struct archive_mstring ae_hardlink; /* Name of target for hardlink */
struct archive_mstring ae_pathname; /* Name of entry */
struct archive_mstring ae_symlink; /* symlink contents */
struct archive_mstring ae_uname; /* Name of owner */
/* Not used within libarchive; useful for some clients. */
struct aes ae_sourcepath; /* Path this entry is sourced from. */
struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */
void *mac_metadata;
size_t mac_metadata_size;
/* ACL support. */
struct ae_acl *acl_head;
struct ae_acl *acl_p;
int acl_state; /* See acl_next for details. */
wchar_t *acl_text_w;
struct archive_acl acl;
/* extattr support. */
struct ae_xattr *xattr_head;
struct ae_xattr *xattr_p;
/* sparse support. */
struct ae_sparse *sparse_head;
struct ae_sparse *sparse_tail;
struct ae_sparse *sparse_p;
/* Miscellaneous. */
char strmode[12];
};
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */

View File

@ -0,0 +1,156 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* Copyright (c) 2010-2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_entry_private.h"
/*
* sparse handling
*/
void
archive_entry_sparse_clear(struct archive_entry *entry)
{
struct ae_sparse *sp;
while (entry->sparse_head != NULL) {
sp = entry->sparse_head->next;
free(entry->sparse_head);
entry->sparse_head = sp;
}
entry->sparse_tail = NULL;
}
void
archive_entry_sparse_add_entry(struct archive_entry *entry,
int64_t offset, int64_t length)
{
struct ae_sparse *sp;
if (offset < 0 || length < 0)
/* Invalid value */
return;
if (offset + length < 0 ||
offset + length > archive_entry_size(entry))
/* A value of "length" parameter is too large. */
return;
if ((sp = entry->sparse_tail) != NULL) {
if (sp->offset + sp->length > offset)
/* Invalid value. */
return;
if (sp->offset + sp->length == offset) {
if (sp->offset + sp->length + length < 0)
/* A value of "length" parameter is
* too large. */
return;
/* Expand existing sparse block size. */
sp->length += length;
return;
}
}
if ((sp = (struct ae_sparse *)malloc(sizeof(*sp))) == NULL)
/* XXX Error XXX */
return;
sp->offset = offset;
sp->length = length;
sp->next = NULL;
if (entry->sparse_head == NULL)
entry->sparse_head = entry->sparse_tail = sp;
else {
/* Add a new sparse block to the tail of list. */
if (entry->sparse_tail != NULL)
entry->sparse_tail->next = sp;
entry->sparse_tail = sp;
}
}
/*
* returns number of the sparse entries
*/
int
archive_entry_sparse_count(struct archive_entry *entry)
{
struct ae_sparse *sp;
int count = 0;
for (sp = entry->sparse_head; sp != NULL; sp = sp->next)
count++;
/*
* Sanity check if this entry is exactly sparse.
* If amount of sparse blocks is just one and it indicates the whole
* file data, we should remove it and return zero.
*/
if (count == 1) {
sp = entry->sparse_head;
if (sp->offset == 0 &&
sp->length >= archive_entry_size(entry)) {
count = 0;
archive_entry_sparse_clear(entry);
}
}
return (count);
}
int
archive_entry_sparse_reset(struct archive_entry * entry)
{
entry->sparse_p = entry->sparse_head;
return archive_entry_sparse_count(entry);
}
int
archive_entry_sparse_next(struct archive_entry * entry,
int64_t *offset, int64_t *length)
{
if (entry->sparse_p) {
*offset = entry->sparse_p->offset;
*length = entry->sparse_p->length;
entry->sparse_p = entry->sparse_p->next;
return (ARCHIVE_OK);
} else {
*offset = 0;
*length = 0;
return (ARCHIVE_WARN);
}
}
/*
* end of sparse handling
*/

View File

@ -0,0 +1,272 @@
.\" Copyright (c) 2010 Joerg Sonnenberger
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd May 12, 2008
.Dt ARCHIVE_ENTRY 3
.Os
.Sh NAME
.Nm archive_entry_stat ,
.Nm archive_entry_copy_stat ,
.Nm archive_entry_filetype ,
.Nm archive_entry_set_filetype ,
.Nm archive_entry_mode ,
.Nm archive_entry_set_mode ,
.Nm archive_entry_size ,
.Nm archive_entry_size_is_set ,
.Nm archive_entry_set_size ,
.Nm archive_entry_unset_size ,
.Nm archive_entry_dev ,
.Nm archive_entry_set_dev ,
.Nm archive_entry_dev_is_set ,
.Nm archive_entry_devmajor ,
.Nm archive_entry_set_devmajor ,
.Nm archive_entry_devminor ,
.Nm archive_entry_set_devminor ,
.Nm archive_entry_ino ,
.Nm archive_entry_set_ino ,
.Nm archive_entry_ino_is_set ,
.Nm archive_entry_ino64 ,
.Nm archive_entry_set_ino64 ,
.Nm archive_entry_nlink ,
.Nm archive_entry_rdev ,
.Nm archive_entry_set_rdev ,
.Nm archive_entry_rdevmajor ,
.Nm archive_entry_set_rdevmajor ,
.Nm archive_entry_rdevminor ,
.Nm archive_entry_set_rdevminor ,
.Nd accessor functions for manipulating archive entry descriptions
.Sh SYNOPSIS
.In archive_entry.h
.Ft const struct stat *
.Fn archive_entry_stat "struct archive_entry *a"
.Ft void
.Fn archive_entry_copy_stat "struct archive_entry *a" "const struct stat *sb"
.Ft mode_t
.Fn archive_entry_filetype "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_filetype "struct archive_entry *a" "unsigned int type"
.Ft mode_t
.Fn archive_entry_mode "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_mode "struct archive_entry *a" "mode_t mode"
.Ft int64_t
.Fn archive_entry_size "struct archive_entry *a"
.Ft int
.Fn archive_entry_size_is_set "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_size "struct archive_entry *a" "int64_t size"
.Ft void
.Fn archive_entry_unset_size "struct archive_entry *a"
.Ft dev_t
.Fn archive_entry_dev "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_dev "struct archive_entry *a" "dev_t dev"
.Ft int
.Fn archive_entry_dev_is_set "struct archive_entry *a"
.Ft dev_t
.Fn archive_entry_devmajor "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_devmajor "struct archive_entry *a" "dev_t major"
.Ft dev_t
.Fn archive_entry_devminor "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_devminor "struct archive_entry *a" "dev_t minor"
.Ft ino_t
.Fn archive_entry_ino "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_ino "struct archive_entry *a" "unsigned long ino"
.Ft int
.Fn archive_entry_ino_is_set "struct archive_entry *a"
.Ft int64_t
.Fn archive_entry_ino64 "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_ino64 "struct archive_entry *a" "int64_t ino"
.Ft unsigned int
.Fn archive_entry_nlink "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_nlink "struct archive_entry *a" "unsigned int count"
.Ft dev_t
.Fn archive_entry_rdev "struct archive_entry *a"
.Ft dev_t
.Fn archive_entry_rdevmajor "struct archive_entry *a"
.Ft dev_t
.Fn archive_entry_rdevminor "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_rdev "struct archive_entry *a" "dev_t dev"
.Ft void
.Fn archive_entry_set_rdevmajor "struct archive_entry *a" "dev_t major"
.Ft void
.Fn archive_entry_set_rdevminor "struct archive_entry *a" "dev_t minor"
.Sh DESCRIPTION
.Ss Copying to and from Vt struct stat
The function
.Fn archive_entry_stat
converts the various fields stored in the archive entry to the format
used by
.Xr stat 2 .
The return value remains valid until either
.Fn archive_entry_clear
or
.Fn archive_entry_free
is called.
It is not affected by calls to the set accessor functions.
It currently sets the following values in
.Vt struct stat :
.Vt st_atime ,
.Vt st_ctime ,
.Vt st_dev ,
.Vt st_gid ,
.Vt st_ino ,
.Vt st_mode ,
.Vt st_mtime ,
.Vt st_nlink ,
.Vt st_rdev ,
.Vt st_size ,
.Vt st_uid .
In addition,
.Vt st_birthtime
and high-precision information for time-related fields
will be included on platforms that support it.
.Pp
The function
.Fn archive_entry_copy_stat
copies fields from the platform's
.Vt struct stat .
Fields not provided by
.Vt struct stat
are unchanged.
.Ss General accessor functions
The functions
.Fn archive_entry_filetype
and
.Fn archive_entry_set_filetype
get respectively set the filetype.
The file type is one of the following constants:
.Bl -tag -width "AE_IFSOCK" -compact -offset indent
.It AE_IFREG
Regular file
.It AE_IFLNK
Symbolic link
.It AE_IFSOCK
Socket
.It AE_IFCHR
Character device
.It AE_IFBLK
Block device
.It AE_IFDIR
Directory
.It AE_IFIFO
Named pipe (fifo)
.El
Not all file types are supported by all platforms.
The constants used by
.Xr stat 2
may have different numeric values from the
corresponding constants above.
.Pp
The functions
.Fn archive_entry_mode
and
.Fn archive_entry_set_mode
get/set a combination of file type and permissions and provide the
equivalent of
.Va st_mode .
Use of
.Fn archive_entry_filetype
and
.Fn archive_entry_perm
for getting and
.Fn archive_entry_set_filetype
and
.Fn archive_entry_set_perm
for setting is recommended.
.Pp
The function
.Fn archive_entry_size
returns the file size, if it has been set, and 0 otherwise.
.Fn archive_entry_size
can be used to query that status.
.Fn archive_entry_set_size
and
.Fn archive_entry_unset_size
set and unset the size, respectively.
.Pp
The number of references (hardlinks) can be obtained by calling
.Fn archive_entry_nlinks
and set with
.Fn archive_entry_set_nlinks .
.Ss Identifying unique files
The functions
.Fn archive_entry_dev
and
.Fn archive_entry_ino64
are used by
.Xr archive_entry_linkify 3
to find hardlinks.
The pair of device and inode is suppossed to identify hardlinked files.
.Pp
The device major and minor number can be obtained independently using
.Fn archive_entry_devmajor
and
.Fn archive_entry_devminor .
The device can be set either via
.Fn archive_entry_set_dev
or by the combination of major and minor number using
.Fn archive_entry_set_devmajor
and
.Fn archive_entry_set_devminor .
.Pp
The inode number can be obtained using
.Fn archive_entry_ino .
This is a legacy interface that uses the platform
.Vt ino_t ,
which may be very small.
To set the inode number,
.Fn archive_entry_set_ino64
is the preferred interface.
.Ss Accessor functions for block and character devices
Block and character devices are characterised either using a device number
or a pair of major and minor number.
The combined device number can be obtained with
.Fn archive_device_rdev
and set with
.Fn archive_device_set_rdev .
The major and minor numbers are accessed by
.Fn archive_device_rdevmajor ,
.Fn archive_device_rdevminor
.Fn archive_device_set_rdevmajor
and
.Fn archive_device_set_rdevminor .
.Pp
The process of splitting the combined device number into major and
minor number and the reverse process of combing them differs between
platforms.
Some archive formats use the combined form, while other formats use
the split form.
.Sh SEE ALSO
.Xr archive 3 ,
.Xr archive_entry_acl 3 ,
.Xr archive_entry_perms 3 ,
.Xr archive_entry_time 3 ,
.Xr stat 2

View File

@ -41,7 +41,7 @@ archive_entry_stat(struct archive_entry *entry)
{
struct stat *st;
if (entry->stat == NULL) {
entry->stat = malloc(sizeof(*st));
entry->stat = calloc(1, sizeof(*st));
if (entry->stat == NULL)
return (NULL);
entry->stat_valid = 0;
@ -110,7 +110,7 @@ archive_entry_stat(struct archive_entry *entry)
/*
* TODO: On Linux, store 32 or 64 here depending on whether
* the cached stat structure is a stat32 or a stat64. This
* will allow us to support both variants interchangably.
* will allow us to support both variants interchangeably.
*/
entry->stat_valid = 1;

View File

@ -0,0 +1,127 @@
.\" Copyright (c) 2003-2007 Tim Kientzle
.\" Copyright (c) 2010 Joerg Sonnenberger
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $
.\"
.Dd February 21, 2010
.Dt ARCHIVE_ENTRY_TIME 3
.Os
.Sh NAME
.Nm archive_entry_atime ,
.Nm archive_entry_atime_nsec ,
.Nm archive_entry_atime_is_set ,
.Nm archive_entry_set_atime ,
.Nm archive_entry_unset_atime ,
.Nm archive_entry_birthtime ,
.Nm archive_entry_birthtime_nsec ,
.Nm archive_entry_birthtime_is_set ,
.Nm archive_entry_set_birthtime ,
.Nm archive_entry_unset_birthtime ,
.Nm archive_entry_ctime ,
.Nm archive_entry_ctime_nsec ,
.Nm archive_entry_ctime_is_set ,
.Nm archive_entry_set_ctime ,
.Nm archive_entry_unset_ctime ,
.Nm archive_entry_mtime ,
.Nm archive_entry_mtime_nsec ,
.Nm archive_entry_mtime_is_set ,
.Nm archive_entry_set_mtime ,
.Nm archive_entry_unset_mtime ,
.Nd functions for manipulating times in archive entry descriptions
.Sh SYNOPSIS
.In archive_entry.h
.Ft time_t
.Fn archive_entry_atime "struct archive_entry *a"
.Ft long
.Fn archive_entry_atime_nsec "struct archive_entry *a"
.Ft int
.Fn archive_entry_atime_is_set "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_atime "struct archive_entry *a" "time_t sec" "long nanosec"
.Ft void
.Fn archive_entry_unset_atime "struct archive_entry *a"
.Ft time_t
.Fn archive_entry_birthtime "struct archive_entry *a"
.Ft long
.Fn archive_entry_birthtime_nsec "struct archive_entry *a"
.Ft int
.Fn archive_entry_birthtime_is_set "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_birthtime "struct archive_entry *a" "time_t sec" "long nanosec"
.Ft void
.Fn archive_entry_unset_birthtime "struct archive_entry *a"
.Ft time_t
.Fn archive_entry_ctime "struct archive_entry *a"
.Ft long
.Fn archive_entry_ctime_nsec "struct archive_entry *a"
.Ft int
.Fn archive_entry_ctime_is_set "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_ctime "struct archive_entry *a" "time_t sec" "long nanosec"
.Ft void
.Fn archive_entry_unset_ctime "struct archive_entry *a"
.Ft time_t
.Fn archive_entry_mtime "struct archive_entry *a"
.Ft long
.Fn archive_entry_mtime_nsec "struct archive_entry *a"
.Ft int
.Fn archive_entry_mtime_is_set "struct archive_entry *a"
.Ft void
.Fn archive_entry_set_mtime "struct archive_entry *a" "time_t sec" "long nanosec"
.Ft void
.Fn archive_entry_unset_mtime "struct archive_entry *a"
.Sh DESCRIPTION
These functions create and manipulate the time fields in an
.Vt archive_entry .
Supported time fields are atime (access time), birthtime (creation time),
ctime (last time an inode property was changed) and mtime (modification time).
.Pp
.Xr libarchive 3
provides a high-resolution interface.
The timestamps are truncated automatically depending on the archive format
(for archiving) or the filesystem capabilities (for restoring).
.Pp
All timestamp fields are optional.
The
.Fn XXX_unset
functions can be used to mark the corresponding field as missing.
The current state can be queried using
.Fn XXX_is_set .
Unset time fields have a second and nanosecond field of 0.
.Sh SEE ALSO
.Xr archive 3 ,
.Xr archive_entry 3
.Sh HISTORY
The
.Nm libarchive
library first appeared in
.Fx 5.3 .
.Sh AUTHORS
.An -nosplit
The
.Nm libarchive
library was written by
.An Tim Kientzle Aq kientzle@acm.org .
.\" .Sh BUGS

View File

@ -1,309 +0,0 @@
/*-
* Copyright (c) 2009 Joerg Sonnenberger
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_hash.h 201171 2009-12-29 06:39:07Z kientzle $
*/
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
/*
* Hash function support in various Operating Systems:
*
* NetBSD:
* - MD5 and SHA1 in libc: without _ after algorithm name
* - SHA2 in libc: with _ after algorithm name
*
* OpenBSD:
* - MD5, SHA1 and SHA2 in libc: without _ after algorithm name
* - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name
*
* DragonFly and FreeBSD (XXX not used yet):
* - MD5 and SHA1 in libmd: without _ after algorithm name
* - SHA256: with _ after algorithm name
*
* Mac OS X (10.4 and later):
* - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name
*
* OpenSSL:
* - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name
*
* Windows:
* - MD5, SHA1 and SHA2 in archive_windows.c: without algorithm name
* and with __la_ prefix.
*/
#if defined(ARCHIVE_HASH_MD5_WIN) ||\
defined(ARCHIVE_HASH_SHA1_WIN) || defined(ARCHIVE_HASH_SHA256_WIN) ||\
defined(ARCHIVE_HASH_SHA384_WIN) || defined(ARCHIVE_HASH_SHA512_WIN)
#include <wincrypt.h>
typedef struct {
int valid;
HCRYPTPROV cryptProv;
HCRYPTHASH hash;
} Digest_CTX;
extern void __la_hash_Init(Digest_CTX *, ALG_ID);
extern void __la_hash_Final(unsigned char *, size_t, Digest_CTX *);
extern void __la_hash_Update(Digest_CTX *, const unsigned char *, size_t);
#endif
#if defined(ARCHIVE_HASH_MD5_LIBC)
# include <md5.h>
# define ARCHIVE_HAS_MD5
typedef MD5_CTX archive_md5_ctx;
# define archive_md5_init(ctx) MD5Init(ctx)
# define archive_md5_final(ctx, buf) MD5Final(buf, ctx)
# define archive_md5_update(ctx, buf, n) MD5Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_MD5_LIBMD)
# include <md5.h>
# define ARCHIVE_HAS_MD5
typedef MD5_CTX archive_md5_ctx;
# define archive_md5_init(ctx) MD5Init(ctx)
# define archive_md5_final(ctx, buf) MD5Final(buf, ctx)
# define archive_md5_update(ctx, buf, n) MD5Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_MD5_LIBSYSTEM)
# include <CommonCrypto/CommonDigest.h>
# define ARCHIVE_HAS_MD5
typedef CC_MD5_CTX archive_md5_ctx;
# define archive_md5_init(ctx) CC_MD5_Init(ctx)
# define archive_md5_final(ctx, buf) CC_MD5_Final(buf, ctx)
# define archive_md5_update(ctx, buf, n) CC_MD5_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_MD5_OPENSSL)
# include <openssl/md5.h>
# define ARCHIVE_HAS_MD5
typedef MD5_CTX archive_md5_ctx;
# define archive_md5_init(ctx) MD5_Init(ctx)
# define archive_md5_final(ctx, buf) MD5_Final(buf, ctx)
# define archive_md5_update(ctx, buf, n) MD5_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_MD5_WIN)
# define ARCHIVE_HAS_MD5
# define MD5_DIGEST_LENGTH 16
typedef Digest_CTX archive_md5_ctx;
# define archive_md5_init(ctx) __la_hash_Init(ctx, CALG_MD5)
# define archive_md5_final(ctx, buf) __la_hash_Final(buf, MD5_DIGEST_LENGTH, ctx)
# define archive_md5_update(ctx, buf, n) __la_hash_Update(ctx, buf, n)
#endif
#if defined(ARCHIVE_HASH_RMD160_LIBC)
# include <rmd160.h>
# define ARCHIVE_HAS_RMD160
typedef RMD160_CTX archive_rmd160_ctx;
# define archive_rmd160_init(ctx) RMD160Init(ctx)
# define archive_rmd160_final(ctx, buf) RMD160Final(buf, ctx)
# define archive_rmd160_update(ctx, buf, n) RMD160Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_RMD160_OPENSSL)
# include <openssl/ripemd.h>
# define ARCHIVE_HAS_RMD160
typedef RIPEMD160_CTX archive_rmd160_ctx;
# define archive_rmd160_init(ctx) RIPEMD160_Init(ctx)
# define archive_rmd160_final(ctx, buf) RIPEMD160_Final(buf, ctx)
# define archive_rmd160_update(ctx, buf, n) RIPEMD160_Update(ctx, buf, n)
#endif
#if defined(ARCHIVE_HASH_SHA1_LIBC)
# include <sha1.h>
# define ARCHIVE_HAS_SHA1
typedef SHA1_CTX archive_sha1_ctx;
# define archive_sha1_init(ctx) SHA1Init(ctx)
# define archive_sha1_final(ctx, buf) SHA1Final(buf, ctx)
# define archive_sha1_update(ctx, buf, n) SHA1Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA1_LIBMD)
# include <sha.h>
# define ARCHIVE_HAS_SHA1
typedef SHA1_CTX archive_sha1_ctx;
# define archive_sha1_init(ctx) SHA1_Init(ctx)
# define archive_sha1_final(ctx, buf) SHA1_Final(buf, ctx)
# define archive_sha1_update(ctx, buf, n) SHA1_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA1_LIBSYSTEM)
# include <CommonCrypto/CommonDigest.h>
# define ARCHIVE_HAS_SHA1
typedef CC_SHA1_CTX archive_sha1_ctx;
# define archive_sha1_init(ctx) CC_SHA1_Init(ctx)
# define archive_sha1_final(ctx, buf) CC_SHA1_Final(buf, ctx)
# define archive_sha1_update(ctx, buf, n) CC_SHA1_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA1_OPENSSL)
# include <openssl/sha.h>
# define ARCHIVE_HAS_SHA1
typedef SHA_CTX archive_sha1_ctx;
# define archive_sha1_init(ctx) SHA1_Init(ctx)
# define archive_sha1_final(ctx, buf) SHA1_Final(buf, ctx)
# define archive_sha1_update(ctx, buf, n) SHA1_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA1_WIN)
# define ARCHIVE_HAS_SHA1
# define SHA1_DIGEST_LENGTH 20
typedef Digest_CTX archive_sha1_ctx;
# define archive_sha1_init(ctx) __la_hash_Init(ctx, CALG_SHA1)
# define archive_sha1_final(ctx, buf) __la_hash_Final(buf, SHA1_DIGEST_LENGTH, ctx)
# define archive_sha1_update(ctx, buf, n) __la_hash_Update(ctx, buf, n)
#endif
#if defined(ARCHIVE_HASH_SHA256_LIBC)
# include <sha2.h>
# define ARCHIVE_HAS_SHA256
typedef SHA256_CTX archive_sha256_ctx;
# define archive_sha256_init(ctx) SHA256_Init(ctx)
# define archive_sha256_final(ctx, buf) SHA256_Final(buf, ctx)
# define archive_sha256_update(ctx, buf, n) SHA256_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA256_LIBC2)
# include <sha2.h>
# define ARCHIVE_HAS_SHA256
typedef SHA256_CTX archive_sha256_ctx;
# define archive_sha256_init(ctx) SHA256Init(ctx)
# define archive_sha256_final(ctx, buf) SHA256Final(buf, ctx)
# define archive_sha256_update(ctx, buf, n) SHA256Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA256_LIBC3)
# include <sha2.h>
# define ARCHIVE_HAS_SHA256
typedef SHA2_CTX archive_sha256_ctx;
# define archive_sha256_init(ctx) SHA256Init(ctx)
# define archive_sha256_final(ctx, buf) SHA256Final(buf, ctx)
# define archive_sha256_update(ctx, buf, n) SHA256Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA256_LIBMD)
# include <sha256.h>
# define ARCHIVE_HAS_SHA256
typedef SHA256_CTX archive_sha256_ctx;
# define archive_sha256_init(ctx) SHA256_Init(ctx)
# define archive_sha256_final(ctx, buf) SHA256_Final(buf, ctx)
# define archive_sha256_update(ctx, buf, n) SHA256_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA256_LIBSYSTEM)
# include <CommonCrypto/CommonDigest.h>
# define ARCHIVE_HAS_SHA256
typedef CC_SHA256_CTX archive_shs256_ctx;
# define archive_shs256_init(ctx) CC_SHA256_Init(ctx)
# define archive_shs256_final(ctx, buf) CC_SHA256_Final(buf, ctx)
# define archive_shs256_update(ctx, buf, n) CC_SHA256_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA256_OPENSSL)
# include <openssl/sha.h>
# define ARCHIVE_HAS_SHA256
typedef SHA256_CTX archive_sha256_ctx;
# define archive_sha256_init(ctx) SHA256_Init(ctx)
# define archive_sha256_final(ctx, buf) SHA256_Final(buf, ctx)
# define archive_sha256_update(ctx, buf, n) SHA256_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA256_WIN)
# define ARCHIVE_HAS_SHA256
# define SHA256_DIGEST_LENGTH 32
typedef Digest_CTX archive_sha256_ctx;
# define archive_sha256_init(ctx) __la_hash_Init(ctx, CALG_SHA_256)
# define archive_sha256_final(ctx, buf) __la_hash_Final(buf, SHA256_DIGEST_LENGTH, ctx)
# define archive_sha256_update(ctx, buf, n) __la_hash_Update(ctx, buf, n)
#endif
#if defined(ARCHIVE_HASH_SHA384_LIBC)
# include <sha2.h>
# define ARCHIVE_HAS_SHA384
typedef SHA384_CTX archive_sha384_ctx;
# define archive_sha384_init(ctx) SHA384_Init(ctx)
# define archive_sha384_final(ctx, buf) SHA384_Final(buf, ctx)
# define archive_sha384_update(ctx, buf, n) SHA384_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA384_LIBC2)
# include <sha2.h>
# define ARCHIVE_HAS_SHA384
typedef SHA384_CTX archive_sha384_ctx;
# define archive_sha384_init(ctx) SHA384Init(ctx)
# define archive_sha384_final(ctx, buf) SHA384Final(buf, ctx)
# define archive_sha384_update(ctx, buf, n) SHA384Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA384_LIBC3)
# include <sha2.h>
# define ARCHIVE_HAS_SHA384
typedef SHA2_CTX archive_sha384_ctx;
# define archive_sha384_init(ctx) SHA384Init(ctx)
# define archive_sha384_final(ctx, buf) SHA384Final(buf, ctx)
# define archive_sha384_update(ctx, buf, n) SHA384Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA384_LIBSYSTEM)
# include <CommonCrypto/CommonDigest.h>
# define ARCHIVE_HAS_SHA384
typedef CC_SHA512_CTX archive_shs384_ctx;
# define archive_shs384_init(ctx) CC_SHA384_Init(ctx)
# define archive_shs384_final(ctx, buf) CC_SHA384_Final(buf, ctx)
# define archive_shs384_update(ctx, buf, n) CC_SHA384_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA384_OPENSSL)
# include <openssl/sha.h>
# define ARCHIVE_HAS_SHA384
typedef SHA512_CTX archive_sha384_ctx;
# define archive_sha384_init(ctx) SHA384_Init(ctx)
# define archive_sha384_final(ctx, buf) SHA384_Final(buf, ctx)
# define archive_sha384_update(ctx, buf, n) SHA384_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA384_WIN)
# define ARCHIVE_HAS_SHA384
# define SHA384_DIGEST_LENGTH 48
typedef Digest_CTX archive_sha384_ctx;
# define archive_sha384_init(ctx) __la_hash_Init(ctx, CALG_SHA_384)
# define archive_sha384_final(ctx, buf) __la_hash_Final(buf, SHA384_DIGEST_LENGTH, ctx)
# define archive_sha384_update(ctx, buf, n) __la_hash_Update(ctx, buf, n)
#endif
#if defined(ARCHIVE_HASH_SHA512_LIBC)
# include <sha2.h>
# define ARCHIVE_HAS_SHA512
typedef SHA512_CTX archive_sha512_ctx;
# define archive_sha512_init(ctx) SHA512_Init(ctx)
# define archive_sha512_final(ctx, buf) SHA512_Final(buf, ctx)
# define archive_sha512_update(ctx, buf, n) SHA512_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA512_LIBC2)
# include <sha2.h>
# define ARCHIVE_HAS_SHA512
typedef SHA512_CTX archive_sha512_ctx;
# define archive_sha512_init(ctx) SHA512Init(ctx)
# define archive_sha512_final(ctx, buf) SHA512Final(buf, ctx)
# define archive_sha512_update(ctx, buf, n) SHA512Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA512_LIBC3)
# include <sha2.h>
# define ARCHIVE_HAS_SHA512
typedef SHA2_CTX archive_sha512_ctx;
# define archive_sha512_init(ctx) SHA512Init(ctx)
# define archive_sha512_final(ctx, buf) SHA512Final(buf, ctx)
# define archive_sha512_update(ctx, buf, n) SHA512Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA512_LIBMD)
# include <sha512.h>
# define ARCHIVE_HAS_SHA512
typedef SHA512_CTX archive_sha512_ctx;
# define archive_sha512_init(ctx) SHA512_Init(ctx)
# define archive_sha512_final(ctx, buf) SHA512_Final(buf, ctx)
# define archive_sha512_update(ctx, buf, n) SHA512_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA512_LIBSYSTEM)
# include <CommonCrypto/CommonDigest.h>
# define ARCHIVE_HAS_SHA512
typedef CC_SHA512_CTX archive_shs512_ctx;
# define archive_shs512_init(ctx) CC_SHA512_Init(ctx)
# define archive_shs512_final(ctx, buf) CC_SHA512_Final(buf, ctx)
# define archive_shs512_update(ctx, buf, n) CC_SHA512_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA512_OPENSSL)
# include <openssl/sha.h>
# define ARCHIVE_HAS_SHA512
typedef SHA512_CTX archive_sha512_ctx;
# define archive_sha512_init(ctx) SHA512_Init(ctx)
# define archive_sha512_final(ctx, buf) SHA512_Final(buf, ctx)
# define archive_sha512_update(ctx, buf, n) SHA512_Update(ctx, buf, n)
#elif defined(ARCHIVE_HASH_SHA512_WIN)
# define ARCHIVE_HAS_SHA512
# define SHA512_DIGEST_LENGTH 64
typedef Digest_CTX archive_sha512_ctx;
# define archive_sha512_init(ctx) __la_hash_Init(ctx, CALG_SHA_512)
# define archive_sha512_final(ctx, buf) __la_hash_Final(buf, SHA512_DIGEST_LENGTH, ctx)
# define archive_sha512_update(ctx, buf, n) __la_hash_Update(ctx, buf, n)
#endif

View File

@ -0,0 +1,164 @@
/*-
* Copyright (c) 2011 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#include "archive_options_private.h"
static const char *
parse_option(const char **str,
const char **mod, const char **opt, const char **val);
int
_archive_set_option(struct archive *a,
const char *m, const char *o, const char *v,
int magic, const char *fn, option_handler use_option)
{
const char *mp, *op, *vp;
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
mp = m != NULL && m[0] == '\0' ? NULL : m;
op = o != NULL && o[0] == '\0' ? NULL : o;
vp = v != NULL && v[0] == '\0' ? NULL : v;
if (op == NULL && vp == NULL)
return (ARCHIVE_OK);
if (op == NULL)
return (ARCHIVE_FAILED);
return use_option(a, mp, op, vp);
}
int
_archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,
option_handler use_format_option, option_handler use_filter_option)
{
int r1, r2;
if (o == NULL && v == NULL)
return (ARCHIVE_OK);
if (o == NULL)
return (ARCHIVE_FAILED);
r1 = use_format_option(a, m, o, v);
if (r1 == ARCHIVE_FATAL)
return (ARCHIVE_FATAL);
r2 = use_filter_option(a, m, o, v);
if (r2 == ARCHIVE_FATAL)
return (ARCHIVE_FATAL);
return r1 > r2 ? r1 : r2;
}
int
_archive_set_options(struct archive *a, const char *options,
int magic, const char *fn, option_handler use_option)
{
int allok = 1, anyok = 0, r;
char *data;
const char *s, *mod, *opt, *val;
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
if (options == NULL || options[0] == '\0')
return ARCHIVE_OK;
data = (char *)malloc(strlen(options) + 1);
strcpy(data, options);
s = (const char *)data;
do {
mod = opt = val = NULL;
parse_option(&s, &mod, &opt, &val);
r = use_option(a, mod, opt, val);
if (r == ARCHIVE_FATAL) {
free(data);
return (ARCHIVE_FATAL);
}
if (r == ARCHIVE_OK)
anyok = 1;
else
allok = 0;
} while (s != NULL);
free(data);
return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;
}
static const char *
parse_option(const char **s, const char **m, const char **o, const char **v)
{
const char *end, *mod, *opt, *val;
char *p;
end = NULL;
mod = NULL;
opt = *s;
val = "1";
p = strchr(opt, ',');
if (p != NULL) {
*p = '\0';
end = ((const char *)p) + 1;
}
if (0 == strlen(opt)) {
*s = end;
*m = NULL;
*o = NULL;
*v = NULL;
return end;
}
p = strchr(opt, ':');
if (p != NULL) {
*p = '\0';
mod = opt;
opt = ++p;
}
p = strchr(opt, '=');
if (p != NULL) {
*p = '\0';
val = ++p;
} else if (opt[0] == '!') {
++opt;
val = NULL;
}
*s = end;
*m = mod;
*o = opt;
*v = val;
return end;
}

View File

@ -0,0 +1,47 @@
/*-
* Copyright (c) 2011 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#include "archive_private.h"
typedef int (*option_handler)(struct archive *a,
const char *mod, const char *opt, const char *val);
int
_archive_set_option(struct archive *a,
const char *mod, const char *opt, const char *val,
int magic, const char *fn, option_handler use_option);
int
_archive_set_options(struct archive *a, const char *options,
int magic, const char *fn, option_handler use_option);
int
_archive_set_either_option(struct archive *a,
const char *m, const char *o, const char *v,
option_handler use_format_option, option_handler use_filter_option);

1164
libarchive/archive_ppmd7.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,119 @@
/* Ppmd7.h -- PPMdH compression codec
2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
/* This code supports virtual RangeDecoder and includes the implementation
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
#include "archive_ppmd_private.h"
#define PPMD7_MIN_ORDER 2
#define PPMD7_MAX_ORDER 64
#define PPMD7_MIN_MEM_SIZE (1 << 11)
#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
struct CPpmd7_Context_;
typedef
#ifdef PPMD_32BIT
struct CPpmd7_Context_ *
#else
UInt32
#endif
CPpmd7_Context_Ref;
typedef struct CPpmd7_Context_
{
UInt16 NumStats;
UInt16 SummFreq;
CPpmd_State_Ref Stats;
CPpmd7_Context_Ref Suffix;
} CPpmd7_Context;
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
typedef struct
{
CPpmd7_Context *MinContext, *MaxContext;
CPpmd_State *FoundState;
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
Int32 RunLength, InitRL; /* must be 32-bit at least */
UInt32 Size;
UInt32 GlueCount;
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
UInt32 AlignOffset;
Byte Indx2Units[PPMD_NUM_INDEXES];
Byte Units2Indx[128];
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
CPpmd_See DummySee, See[25][16];
UInt16 BinSumm[128][64];
} CPpmd7;
/* ---------- Decode ---------- */
typedef struct
{
UInt32 (*GetThreshold)(void *p, UInt32 total);
void (*Decode)(void *p, UInt32 start, UInt32 size);
UInt32 (*DecodeBit)(void *p, UInt32 size0);
} IPpmd7_RangeDec;
typedef struct
{
IPpmd7_RangeDec p;
UInt32 Range;
UInt32 Code;
UInt32 Low;
UInt32 Bottom;
IByteIn *Stream;
} CPpmd7z_RangeDec;
/* ---------- Encode ---------- */
typedef struct
{
UInt64 Low;
UInt32 Range;
Byte Cache;
UInt64 CacheSize;
IByteOut *Stream;
} CPpmd7z_RangeEnc;
typedef struct
{
/* Base Functions */
void (*Ppmd7_Construct)(CPpmd7 *p);
Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
void (*Ppmd7_Free)(CPpmd7 *p, ISzAlloc *alloc);
void (*Ppmd7_Init)(CPpmd7 *p, unsigned maxOrder);
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
/* Decode Functions */
void (*Ppmd7z_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
void (*PpmdRAR_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
Bool (*Ppmd7z_RangeDec_Init)(CPpmd7z_RangeDec *p);
Bool (*PpmdRAR_RangeDec_Init)(CPpmd7z_RangeDec *p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int (*Ppmd7_DecodeSymbol)(CPpmd7 *p, IPpmd7_RangeDec *rc);
/* Encode Functions */
void (*Ppmd7z_RangeEnc_Init)(CPpmd7z_RangeEnc *p);
void (*Ppmd7z_RangeEnc_FlushData)(CPpmd7z_RangeEnc *p);
void (*Ppmd7_EncodeSymbol)(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
} IPpmd7;
extern const IPpmd7 __archive_ppmd7_functions;
#endif

View File

@ -0,0 +1,158 @@
/* Ppmd.h -- PPMD codec common code
2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
#include <stddef.h>
#include "archive_read_private.h"
/*** Begin defined in Types.h ***/
#if !defined(ZCONF_H)
typedef unsigned char Byte;
#endif
typedef short Int16;
typedef unsigned short UInt16;
#ifdef _LZMA_UINT32_IS_ULONG
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
#ifdef _SZ_NO_INT_64
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
NOTES: Some code will work incorrectly in that case! */
typedef long Int64;
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL
#endif
#endif
typedef int Bool;
#define True 1
#define False 0
/* The following interfaces use first parameter as pointer to structure */
typedef struct
{
struct archive_read *a;
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn;
typedef struct
{
struct archive_write *a;
void (*Write)(void *p, Byte b);
} IByteOut;
typedef struct
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
/*** End defined in Types.h ***/
/*** Begin defined in CpuArch.h ***/
#if defined(_M_IX86) || defined(__i386__)
#define MY_CPU_X86
#endif
#if defined(MY_CPU_X86) || defined(_M_ARM)
#define MY_CPU_32BIT
#endif
#ifdef MY_CPU_32BIT
#define PPMD_32BIT
#endif
/*** End defined in CpuArch.h ***/
#define PPMD_INT_BITS 7
#define PPMD_PERIOD_BITS 7
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
#define PPMD_N1 4
#define PPMD_N2 4
#define PPMD_N3 4
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
/* SEE-contexts for PPM-contexts with masked symbols */
typedef struct
{
UInt16 Summ; /* Freq */
Byte Shift; /* Speed of Freq change; low Shift is for fast change */
Byte Count; /* Count to next change of Shift */
} CPpmd_See;
#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
typedef struct
{
Byte Symbol;
Byte Freq;
UInt16 SuccessorLow;
UInt16 SuccessorHigh;
} CPpmd_State;
typedef
#ifdef PPMD_32BIT
CPpmd_State *
#else
UInt32
#endif
CPpmd_State_Ref;
typedef
#ifdef PPMD_32BIT
void *
#else
UInt32
#endif
CPpmd_Void_Ref;
typedef
#ifdef PPMD_32BIT
Byte *
#else
UInt32
#endif
CPpmd_Byte_Ref;
#define PPMD_SetAllBitsIn256Bytes(p) \
{ unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
#endif

View File

@ -32,6 +32,10 @@
#ifndef ARCHIVE_PRIVATE_H_INCLUDED
#define ARCHIVE_PRIVATE_H_INCLUDED
#if HAVE_ICONV_H
#include <iconv.h>
#endif
#include "archive.h"
#include "archive_string.h"
@ -47,14 +51,13 @@
#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U)
#define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U)
#define ARCHIVE_STATE_ANY 0xFFFFU
#define ARCHIVE_STATE_NEW 1U
#define ARCHIVE_STATE_HEADER 2U
#define ARCHIVE_STATE_DATA 4U
#define ARCHIVE_STATE_DATA_END 8U
#define ARCHIVE_STATE_EOF 0x10U
#define ARCHIVE_STATE_CLOSED 0x20U
#define ARCHIVE_STATE_FATAL 0x8000U
#define ARCHIVE_STATE_ANY (0xFFFFU & ~ARCHIVE_STATE_FATAL)
struct archive_vtable {
int (*archive_close)(struct archive *);
@ -65,9 +68,23 @@ struct archive_vtable {
ssize_t (*archive_write_data)(struct archive *,
const void *, size_t);
ssize_t (*archive_write_data_block)(struct archive *,
const void *, size_t, off_t);
const void *, size_t, int64_t);
int (*archive_read_next_header)(struct archive *,
struct archive_entry **);
int (*archive_read_next_header2)(struct archive *,
struct archive_entry *);
int (*archive_read_data_block)(struct archive *,
const void **, size_t *, int64_t *);
int (*archive_filter_count)(struct archive *);
int64_t (*archive_filter_bytes)(struct archive *, int);
int (*archive_filter_code)(struct archive *, int);
const char * (*archive_filter_name)(struct archive *, int);
};
struct archive_string_conv;
struct archive {
/*
* The magic/state values are used to sanity-check the
@ -90,26 +107,35 @@ struct archive {
int compression_code; /* Currently active compression. */
const char *compression_name;
/* Position in UNCOMPRESSED data stream. */
int64_t file_position;
/* Position in COMPRESSED data stream. */
int64_t raw_position;
/* Number of file entries processed. */
int file_count;
int archive_error_number;
const char *error;
struct archive_string error_string;
char *current_code;
unsigned current_codepage; /* Current ACP(ANSI CodePage). */
unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */
struct archive_string_conv *sconv;
};
/* Check magic value and state; exit if it isn't valid. */
void __archive_check_magic(struct archive *, unsigned int magic,
/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
int __archive_check_magic(struct archive *, unsigned int magic,
unsigned int state, const char *func);
#define archive_check_magic(a, expected_magic, allowed_states, function_name) \
do { \
int magic_test = __archive_check_magic((a), (expected_magic), \
(allowed_states), (function_name)); \
if (magic_test == ARCHIVE_FATAL) \
return ARCHIVE_FATAL; \
} while (0)
void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
int __archive_parse_options(const char *p, const char *fn,
int keysize, char *key, int valsize, char *val);
int __archive_mktemp(const char *tmpdir);
int __archive_clean(struct archive *);
#define err_combine(a,b) ((a) < (b) ? (a) : (b))

701
libarchive/archive_rb.c Normal file
View File

@ -0,0 +1,701 @@
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas <matt@3am-software.com>.
*
* 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Based on: NetBSD: rb.c,v 1.6 2010/04/30 13:58:09 joerg Exp
*/
#include "archive_platform.h"
#include <stddef.h>
#include "archive_rb.h"
/* Keep in sync with archive_rb.h */
#define RB_DIR_LEFT 0
#define RB_DIR_RIGHT 1
#define RB_DIR_OTHER 1
#define rb_left rb_nodes[RB_DIR_LEFT]
#define rb_right rb_nodes[RB_DIR_RIGHT]
#define RB_FLAG_POSITION 0x2
#define RB_FLAG_RED 0x1
#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED)
#define RB_FATHER(rb) \
((struct archive_rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
#define RB_SET_FATHER(rb, father) \
((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
#define RB_SENTINEL_P(rb) ((rb) == NULL)
#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left)
#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
#define RB_CHILDLESS_P(rb) \
(RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
#define RB_TWOCHILDREN_P(rb) \
(!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
#define RB_POSITION(rb) \
(((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT)
#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT)
#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED))
#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED))
#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED))
#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb))
#define RB_SET_POSITION(rb, position) \
((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
((rb)->rb_info &= ~RB_FLAG_POSITION)))
#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
#define RB_COPY_PROPERTIES(dst, src) \
((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
#define RB_SWAP_PROPERTIES(a, b) do { \
uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
(a)->rb_info ^= xorinfo; \
(b)->rb_info ^= xorinfo; \
} while (/*CONSTCOND*/ 0)
static void __archive_rb_tree_insert_rebalance(struct archive_rb_tree *,
struct archive_rb_node *);
static void __archive_rb_tree_removal_rebalance(struct archive_rb_tree *,
struct archive_rb_node *, unsigned int);
#define RB_SENTINEL_NODE NULL
#define T 1
#define F 0
void
__archive_rb_tree_init(struct archive_rb_tree *rbt,
const struct archive_rb_tree_ops *ops)
{
rbt->rbt_ops = ops;
*((const struct archive_rb_node **)&rbt->rbt_root) = RB_SENTINEL_NODE;
}
struct archive_rb_node *
__archive_rb_tree_find_node(struct archive_rb_tree *rbt, const void *key)
{
archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
struct archive_rb_node *parent = rbt->rbt_root;
while (!RB_SENTINEL_P(parent)) {
const signed int diff = (*compare_key)(parent, key);
if (diff == 0)
return parent;
parent = parent->rb_nodes[diff > 0];
}
return NULL;
}
struct archive_rb_node *
__archive_rb_tree_find_node_geq(struct archive_rb_tree *rbt, const void *key)
{
archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
struct archive_rb_node *parent = rbt->rbt_root;
struct archive_rb_node *last = NULL;
while (!RB_SENTINEL_P(parent)) {
const signed int diff = (*compare_key)(parent, key);
if (diff == 0)
return parent;
if (diff < 0)
last = parent;
parent = parent->rb_nodes[diff > 0];
}
return last;
}
struct archive_rb_node *
__archive_rb_tree_find_node_leq(struct archive_rb_tree *rbt, const void *key)
{
archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
struct archive_rb_node *parent = rbt->rbt_root;
struct archive_rb_node *last = NULL;
while (!RB_SENTINEL_P(parent)) {
const signed int diff = (*compare_key)(parent, key);
if (diff == 0)
return parent;
if (diff > 0)
last = parent;
parent = parent->rb_nodes[diff > 0];
}
return last;
}
int
__archive_rb_tree_insert_node(struct archive_rb_tree *rbt,
struct archive_rb_node *self)
{
archive_rbto_compare_nodes_fn compare_nodes = rbt->rbt_ops->rbto_compare_nodes;
struct archive_rb_node *parent, *tmp;
unsigned int position;
int rebalance;
tmp = rbt->rbt_root;
/*
* This is a hack. Because rbt->rbt_root is just a
* struct archive_rb_node *, just like rb_node->rb_nodes[RB_DIR_LEFT],
* we can use this fact to avoid a lot of tests for root and know
* that even at root, updating
* RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will
* update rbt->rbt_root.
*/
parent = (struct archive_rb_node *)(void *)&rbt->rbt_root;
position = RB_DIR_LEFT;
/*
* Find out where to place this new leaf.
*/
while (!RB_SENTINEL_P(tmp)) {
const signed int diff = (*compare_nodes)(tmp, self);
if (diff == 0) {
/*
* Node already exists; don't insert.
*/
return F;
}
parent = tmp;
position = (diff > 0);
tmp = parent->rb_nodes[position];
}
/*
* Initialize the node and insert as a leaf into the tree.
*/
RB_SET_FATHER(self, parent);
RB_SET_POSITION(self, position);
if (parent == (struct archive_rb_node *)(void *)&rbt->rbt_root) {
RB_MARK_BLACK(self); /* root is always black */
rebalance = F;
} else {
/*
* All new nodes are colored red. We only need to rebalance
* if our parent is also red.
*/
RB_MARK_RED(self);
rebalance = RB_RED_P(parent);
}
self->rb_left = parent->rb_nodes[position];
self->rb_right = parent->rb_nodes[position];
parent->rb_nodes[position] = self;
/*
* Rebalance tree after insertion
*/
if (rebalance)
__archive_rb_tree_insert_rebalance(rbt, self);
return T;
}
/*
* Swap the location and colors of 'self' and its child @ which. The child
* can not be a sentinel node. This is our rotation function. However,
* since it preserves coloring, it great simplifies both insertion and
* removal since rotation almost always involves the exchanging of colors
* as a separate step.
*/
/*ARGSUSED*/
static void
__archive_rb_tree_reparent_nodes(
struct archive_rb_node *old_father, const unsigned int which)
{
const unsigned int other = which ^ RB_DIR_OTHER;
struct archive_rb_node * const grandpa = RB_FATHER(old_father);
struct archive_rb_node * const old_child = old_father->rb_nodes[which];
struct archive_rb_node * const new_father = old_child;
struct archive_rb_node * const new_child = old_father;
/*
* Exchange descendant linkages.
*/
grandpa->rb_nodes[RB_POSITION(old_father)] = new_father;
new_child->rb_nodes[which] = old_child->rb_nodes[other];
new_father->rb_nodes[other] = new_child;
/*
* Update ancestor linkages
*/
RB_SET_FATHER(new_father, grandpa);
RB_SET_FATHER(new_child, new_father);
/*
* Exchange properties between new_father and new_child. The only
* change is that new_child's position is now on the other side.
*/
RB_SWAP_PROPERTIES(new_father, new_child);
RB_SET_POSITION(new_child, other);
/*
* Make sure to reparent the new child to ourself.
*/
if (!RB_SENTINEL_P(new_child->rb_nodes[which])) {
RB_SET_FATHER(new_child->rb_nodes[which], new_child);
RB_SET_POSITION(new_child->rb_nodes[which], which);
}
}
static void
__archive_rb_tree_insert_rebalance(struct archive_rb_tree *rbt,
struct archive_rb_node *self)
{
struct archive_rb_node * father = RB_FATHER(self);
struct archive_rb_node * grandpa;
struct archive_rb_node * uncle;
unsigned int which;
unsigned int other;
for (;;) {
/*
* We are red and our parent is red, therefore we must have a
* grandfather and he must be black.
*/
grandpa = RB_FATHER(father);
which = (father == grandpa->rb_right);
other = which ^ RB_DIR_OTHER;
uncle = grandpa->rb_nodes[other];
if (RB_BLACK_P(uncle))
break;
/*
* Case 1: our uncle is red
* Simply invert the colors of our parent and
* uncle and make our grandparent red. And
* then solve the problem up at his level.
*/
RB_MARK_BLACK(uncle);
RB_MARK_BLACK(father);
if (RB_ROOT_P(rbt, grandpa)) {
/*
* If our grandpa is root, don't bother
* setting him to red, just return.
*/
return;
}
RB_MARK_RED(grandpa);
self = grandpa;
father = RB_FATHER(self);
if (RB_BLACK_P(father)) {
/*
* If our greatgrandpa is black, we're done.
*/
return;
}
}
/*
* Case 2&3: our uncle is black.
*/
if (self == father->rb_nodes[other]) {
/*
* Case 2: we are on the same side as our uncle
* Swap ourselves with our parent so this case
* becomes case 3. Basically our parent becomes our
* child.
*/
__archive_rb_tree_reparent_nodes(father, other);
}
/*
* Case 3: we are opposite a child of a black uncle.
* Swap our parent and grandparent. Since our grandfather
* is black, our father will become black and our new sibling
* (former grandparent) will become red.
*/
__archive_rb_tree_reparent_nodes(grandpa, which);
/*
* Final step: Set the root to black.
*/
RB_MARK_BLACK(rbt->rbt_root);
}
static void
__archive_rb_tree_prune_node(struct archive_rb_tree *rbt,
struct archive_rb_node *self, int rebalance)
{
const unsigned int which = RB_POSITION(self);
struct archive_rb_node *father = RB_FATHER(self);
/*
* Since we are childless, we know that self->rb_left is pointing
* to the sentinel node.
*/
father->rb_nodes[which] = self->rb_left;
/*
* Rebalance if requested.
*/
if (rebalance)
__archive_rb_tree_removal_rebalance(rbt, father, which);
}
/*
* When deleting an interior node
*/
static void
__archive_rb_tree_swap_prune_and_rebalance(struct archive_rb_tree *rbt,
struct archive_rb_node *self, struct archive_rb_node *standin)
{
const unsigned int standin_which = RB_POSITION(standin);
unsigned int standin_other = standin_which ^ RB_DIR_OTHER;
struct archive_rb_node *standin_son;
struct archive_rb_node *standin_father = RB_FATHER(standin);
int rebalance = RB_BLACK_P(standin);
if (standin_father == self) {
/*
* As a child of self, any children would be opposite of
* our parent.
*/
standin_son = standin->rb_nodes[standin_which];
} else {
/*
* Since we aren't a child of self, any children would be
* on the same side as our parent.
*/
standin_son = standin->rb_nodes[standin_other];
}
if (RB_RED_P(standin_son)) {
/*
* We know we have a red child so if we flip it to black
* we don't have to rebalance.
*/
RB_MARK_BLACK(standin_son);
rebalance = F;
if (standin_father != self) {
/*
* Change the son's parentage to point to his grandpa.
*/
RB_SET_FATHER(standin_son, standin_father);
RB_SET_POSITION(standin_son, standin_which);
}
}
if (standin_father == self) {
/*
* If we are about to delete the standin's father, then when
* we call rebalance, we need to use ourselves as our father.
* Otherwise remember our original father. Also, since we are
* our standin's father we only need to reparent the standin's
* brother.
*
* | R --> S |
* | Q S --> Q T |
* | t --> |
*
* Have our son/standin adopt his brother as his new son.
*/
standin_father = standin;
} else {
/*
* | R --> S . |
* | / \ | T --> / \ | / |
* | ..... | S --> ..... | T |
*
* Sever standin's connection to his father.
*/
standin_father->rb_nodes[standin_which] = standin_son;
/*
* Adopt the far son.
*/
standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
/*
* Use standin_other because we need to preserve standin_which
* for the removal_rebalance.
*/
standin_other = standin_which;
}
/*
* Move the only remaining son to our standin. If our standin is our
* son, this will be the only son needed to be moved.
*/
standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
/*
* Now copy the result of self to standin and then replace
* self with standin in the tree.
*/
RB_COPY_PROPERTIES(standin, self);
RB_SET_FATHER(standin, RB_FATHER(self));
RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin;
if (rebalance)
__archive_rb_tree_removal_rebalance(rbt, standin_father, standin_which);
}
/*
* We could do this by doing
* __archive_rb_tree_node_swap(rbt, self, which);
* __archive_rb_tree_prune_node(rbt, self, F);
*
* But it's more efficient to just evaluate and recolor the child.
*/
static void
__archive_rb_tree_prune_blackred_branch(
struct archive_rb_node *self, unsigned int which)
{
struct archive_rb_node *father = RB_FATHER(self);
struct archive_rb_node *son = self->rb_nodes[which];
/*
* Remove ourselves from the tree and give our former child our
* properties (position, color, root).
*/
RB_COPY_PROPERTIES(son, self);
father->rb_nodes[RB_POSITION(son)] = son;
RB_SET_FATHER(son, father);
}
/*
*
*/
void
__archive_rb_tree_remove_node(struct archive_rb_tree *rbt,
struct archive_rb_node *self)
{
struct archive_rb_node *standin;
unsigned int which;
/*
* In the following diagrams, we (the node to be removed) are S. Red
* nodes are lowercase. T could be either red or black.
*
* Remember the major axiom of the red-black tree: the number of
* black nodes from the root to each leaf is constant across all
* leaves, only the number of red nodes varies.
*
* Thus removing a red leaf doesn't require any other changes to a
* red-black tree. So if we must remove a node, attempt to rearrange
* the tree so we can remove a red node.
*
* The simplest case is a childless red node or a childless root node:
*
* | T --> T | or | R --> * |
* | s --> * |
*/
if (RB_CHILDLESS_P(self)) {
const int rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self);
__archive_rb_tree_prune_node(rbt, self, rebalance);
return;
}
if (!RB_TWOCHILDREN_P(self)) {
/*
* The next simplest case is the node we are deleting is
* black and has one red child.
*
* | T --> T --> T |
* | S --> R --> R |
* | r --> s --> * |
*/
which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT;
__archive_rb_tree_prune_blackred_branch(self, which);
return;
}
/*
* We invert these because we prefer to remove from the inside of
* the tree.
*/
which = RB_POSITION(self) ^ RB_DIR_OTHER;
/*
* Let's find the node closes to us opposite of our parent
* Now swap it with ourself, "prune" it, and rebalance, if needed.
*/
standin = __archive_rb_tree_iterate(rbt, self, which);
__archive_rb_tree_swap_prune_and_rebalance(rbt, self, standin);
}
static void
__archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt,
struct archive_rb_node *parent, unsigned int which)
{
while (RB_BLACK_P(parent->rb_nodes[which])) {
unsigned int other = which ^ RB_DIR_OTHER;
struct archive_rb_node *brother = parent->rb_nodes[other];
/*
* For cases 1, 2a, and 2b, our brother's children must
* be black and our father must be black
*/
if (RB_BLACK_P(parent)
&& RB_BLACK_P(brother->rb_left)
&& RB_BLACK_P(brother->rb_right)) {
if (RB_RED_P(brother)) {
/*
* Case 1: Our brother is red, swap its
* position (and colors) with our parent.
* This should now be case 2b (unless C or E
* has a red child which is case 3; thus no
* explicit branch to case 2b).
*
* B -> D
* A d -> b E
* C E -> A C
*/
__archive_rb_tree_reparent_nodes(parent, other);
brother = parent->rb_nodes[other];
} else {
/*
* Both our parent and brother are black.
* Change our brother to red, advance up rank
* and go through the loop again.
*
* B -> *B
* *A D -> A d
* C E -> C E
*/
RB_MARK_RED(brother);
if (RB_ROOT_P(rbt, parent))
return; /* root == parent == black */
which = RB_POSITION(parent);
parent = RB_FATHER(parent);
continue;
}
}
/*
* Avoid an else here so that case 2a above can hit either
* case 2b, 3, or 4.
*/
if (RB_RED_P(parent)
&& RB_BLACK_P(brother)
&& RB_BLACK_P(brother->rb_left)
&& RB_BLACK_P(brother->rb_right)) {
/*
* We are black, our father is red, our brother and
* both nephews are black. Simply invert/exchange the
* colors of our father and brother (to black and red
* respectively).
*
* | f --> F |
* | * B --> * b |
* | N N --> N N |
*/
RB_MARK_BLACK(parent);
RB_MARK_RED(brother);
break; /* We're done! */
} else {
/*
* Our brother must be black and have at least one
* red child (it may have two).
*/
if (RB_BLACK_P(brother->rb_nodes[other])) {
/*
* Case 3: our brother is black, our near
* nephew is red, and our far nephew is black.
* Swap our brother with our near nephew.
* This result in a tree that matches case 4.
* (Our father could be red or black).
*
* | F --> F |
* | x B --> x B |
* | n --> n |
*/
__archive_rb_tree_reparent_nodes(brother, which);
brother = parent->rb_nodes[other];
}
/*
* Case 4: our brother is black and our far nephew
* is red. Swap our father and brother locations and
* change our far nephew to black. (these can be
* done in either order so we change the color first).
* The result is a valid red-black tree and is a
* terminal case. (again we don't care about the
* father's color)
*
* If the father is red, we will get a red-black-black
* tree:
* | f -> f --> b |
* | B -> B --> F N |
* | n -> N --> |
*
* If the father is black, we will get an all black
* tree:
* | F -> F --> B |
* | B -> B --> F N |
* | n -> N --> |
*
* If we had two red nephews, then after the swap,
* our former father would have a red grandson.
*/
RB_MARK_BLACK(brother->rb_nodes[other]);
__archive_rb_tree_reparent_nodes(parent, other);
break; /* We're done! */
}
}
}
struct archive_rb_node *
__archive_rb_tree_iterate(struct archive_rb_tree *rbt,
struct archive_rb_node *self, const unsigned int direction)
{
const unsigned int other = direction ^ RB_DIR_OTHER;
if (self == NULL) {
self = rbt->rbt_root;
if (RB_SENTINEL_P(self))
return NULL;
while (!RB_SENTINEL_P(self->rb_nodes[direction]))
self = self->rb_nodes[direction];
return self;
}
/*
* We can't go any further in this direction. We proceed up in the
* opposite direction until our parent is in direction we want to go.
*/
if (RB_SENTINEL_P(self->rb_nodes[direction])) {
while (!RB_ROOT_P(rbt, self)) {
if (other == RB_POSITION(self))
return RB_FATHER(self);
self = RB_FATHER(self);
}
return NULL;
}
/*
* Advance down one in current direction and go down as far as possible
* in the opposite direction.
*/
self = self->rb_nodes[direction];
while (!RB_SENTINEL_P(self->rb_nodes[other]))
self = self->rb_nodes[other];
return self;
}

100
libarchive/archive_rb.h Normal file
View File

@ -0,0 +1,100 @@
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas <matt@3am-software.com>.
*
* 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp
*/
#ifndef ARCHIVE_RB_H_
#define ARCHIVE_RB_H_
struct archive_rb_node {
struct archive_rb_node *rb_nodes[2];
/*
* rb_info contains the two flags and the parent back pointer.
* We put the two flags in the low two bits since we know that
* rb_node will have an alignment of 4 or 8 bytes.
*/
uintptr_t rb_info;
};
#define ARCHIVE_RB_DIR_LEFT 0
#define ARCHIVE_RB_DIR_RIGHT 1
#define ARCHIVE_RB_TREE_MIN(T) \
__archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT)
#define ARCHIVE_RB_TREE_MAX(T) \
__archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT)
#define ARCHIVE_RB_TREE_FOREACH(N, T) \
for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \
(N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT))
#define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \
for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \
(N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT))
/*
* archive_rbto_compare_nodes_fn:
* return a positive value if the first node < the second node.
* return a negative value if the first node > the second node.
* return 0 if they are considered same.
*
* archive_rbto_compare_key_fn:
* return a positive value if the node < the key.
* return a negative value if the node > the key.
* return 0 if they are considered same.
*/
typedef signed int (*const archive_rbto_compare_nodes_fn)(const struct archive_rb_node *,
const struct archive_rb_node *);
typedef signed int (*const archive_rbto_compare_key_fn)(const struct archive_rb_node *,
const void *);
struct archive_rb_tree_ops {
archive_rbto_compare_nodes_fn rbto_compare_nodes;
archive_rbto_compare_key_fn rbto_compare_key;
};
struct archive_rb_tree {
struct archive_rb_node *rbt_root;
const struct archive_rb_tree_ops *rbt_ops;
};
void __archive_rb_tree_init(struct archive_rb_tree *,
const struct archive_rb_tree_ops *);
int __archive_rb_tree_insert_node(struct archive_rb_tree *,
struct archive_rb_node *);
struct archive_rb_node *
__archive_rb_tree_find_node(struct archive_rb_tree *, const void *);
struct archive_rb_node *
__archive_rb_tree_find_node_geq(struct archive_rb_tree *, const void *);
struct archive_rb_node *
__archive_rb_tree_find_node_leq(struct archive_rb_tree *, const void *);
void __archive_rb_tree_remove_node(struct archive_rb_tree *, struct archive_rb_node *);
struct archive_rb_node *
__archive_rb_tree_iterate(struct archive_rb_tree *,
struct archive_rb_node *, const unsigned int);
#endif /* ARCHIVE_RB_H_*/

View File

@ -24,179 +24,14 @@
.\"
.\" $FreeBSD: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
.\"
.Dd April 13, 2009
.Dd March 23, 2011
.Dt ARCHIVE_READ 3
.Os
.Sh NAME
.Nm archive_read_new ,
.Nm archive_read_set_filter_options ,
.Nm archive_read_set_format_options ,
.Nm archive_read_set_options ,
.Nm archive_read_support_compression_all ,
.Nm archive_read_support_compression_bzip2 ,
.Nm archive_read_support_compression_compress ,
.Nm archive_read_support_compression_gzip ,
.Nm archive_read_support_compression_lzma ,
.Nm archive_read_support_compression_none ,
.Nm archive_read_support_compression_xz ,
.Nm archive_read_support_compression_program ,
.Nm archive_read_support_compression_program_signature ,
.Nm archive_read_support_format_all ,
.Nm archive_read_support_format_ar ,
.Nm archive_read_support_format_cpio ,
.Nm archive_read_support_format_empty ,
.Nm archive_read_support_format_iso9660 ,
.Nm archive_read_support_format_mtree,
.Nm archive_read_support_format_raw,
.Nm archive_read_support_format_tar ,
.Nm archive_read_support_format_zip ,
.Nm archive_read_open ,
.Nm archive_read_open2 ,
.Nm archive_read_open_fd ,
.Nm archive_read_open_FILE ,
.Nm archive_read_open_filename ,
.Nm archive_read_open_memory ,
.Nm archive_read_next_header ,
.Nm archive_read_next_header2 ,
.Nm archive_read_data ,
.Nm archive_read_data_block ,
.Nm archive_read_data_skip ,
.\" #if ARCHIVE_API_VERSION < 3
.Nm archive_read_data_into_buffer ,
.\" #endif
.Nm archive_read_data_into_fd ,
.Nm archive_read_extract ,
.Nm archive_read_extract2 ,
.Nm archive_read_extract_set_progress_callback ,
.Nm archive_read_close ,
.Nm archive_read_free
.Nm archive_read
.Nd functions for reading streaming archives
.Sh SYNOPSIS
.In archive.h
.Ft struct archive *
.Fn archive_read_new "void"
.Ft int
.Fn archive_read_support_compression_all "struct archive *"
.Ft int
.Fn archive_read_support_compression_bzip2 "struct archive *"
.Ft int
.Fn archive_read_support_compression_compress "struct archive *"
.Ft int
.Fn archive_read_support_compression_gzip "struct archive *"
.Ft int
.Fn archive_read_support_compression_lzma "struct archive *"
.Ft int
.Fn archive_read_support_compression_none "struct archive *"
.Ft int
.Fn archive_read_support_compression_xz "struct archive *"
.Ft int
.Fo archive_read_support_compression_program
.Fa "struct archive *"
.Fa "const char *cmd"
.Fc
.Ft int
.Fo archive_read_support_compression_program_signature
.Fa "struct archive *"
.Fa "const char *cmd"
.Fa "const void *signature"
.Fa "size_t signature_length"
.Fc
.Ft int
.Fn archive_read_support_format_all "struct archive *"
.Ft int
.Fn archive_read_support_format_ar "struct archive *"
.Ft int
.Fn archive_read_support_format_cpio "struct archive *"
.Ft int
.Fn archive_read_support_format_empty "struct archive *"
.Ft int
.Fn archive_read_support_format_iso9660 "struct archive *"
.Ft int
.Fn archive_read_support_format_mtree "struct archive *"
.Ft int
.Fn archive_read_support_format_raw "struct archive *"
.Ft int
.Fn archive_read_support_format_tar "struct archive *"
.Ft int
.Fn archive_read_support_format_zip "struct archive *"
.Ft int
.Fn archive_read_set_filter_options "struct archive *" "const char *"
.Ft int
.Fn archive_read_set_format_options "struct archive *" "const char *"
.Ft int
.Fn archive_read_set_options "struct archive *" "const char *"
.Ft int
.Fo archive_read_open
.Fa "struct archive *"
.Fa "void *client_data"
.Fa "archive_open_callback *"
.Fa "archive_read_callback *"
.Fa "archive_close_callback *"
.Fc
.Ft int
.Fo archive_read_open2
.Fa "struct archive *"
.Fa "void *client_data"
.Fa "archive_open_callback *"
.Fa "archive_read_callback *"
.Fa "archive_skip_callback *"
.Fa "archive_close_callback *"
.Fc
.Ft int
.Fn archive_read_open_FILE "struct archive *" "FILE *file"
.Ft int
.Fn archive_read_open_fd "struct archive *" "int fd" "size_t block_size"
.Ft int
.Fo archive_read_open_filename
.Fa "struct archive *"
.Fa "const char *filename"
.Fa "size_t block_size"
.Fc
.Ft int
.Fn archive_read_open_memory "struct archive *" "void *buff" "size_t size"
.Ft int
.Fn archive_read_next_header "struct archive *" "struct archive_entry **"
.Ft int
.Fn archive_read_next_header2 "struct archive *" "struct archive_entry *"
.Ft ssize_t
.Fn archive_read_data "struct archive *" "void *buff" "size_t len"
.Ft int
.Fo archive_read_data_block
.Fa "struct archive *"
.Fa "const void **buff"
.Fa "size_t *len"
.Fa "off_t *offset"
.Fc
.Ft int
.Fn archive_read_data_skip "struct archive *"
.\" #if ARCHIVE_API_VERSION < 3
.Ft int
.Fn archive_read_data_into_buffer "struct archive *" "void *" "ssize_t len"
.\" #endif
.Ft int
.Fn archive_read_data_into_fd "struct archive *" "int fd"
.Ft int
.Fo archive_read_extract
.Fa "struct archive *"
.Fa "struct archive_entry *"
.Fa "int flags"
.Fc
.Ft int
.Fo archive_read_extract2
.Fa "struct archive *src"
.Fa "struct archive_entry *"
.Fa "struct archive *dest"
.Fc
.Ft void
.Fo archive_read_extract_set_progress_callback
.Fa "struct archive *"
.Fa "void (*func)(void *)"
.Fa "void *user_data"
.Fc
.Ft int
.Fn archive_read_close "struct archive *"
.Ft int
.Fn archive_read_free "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for reading streaming archives.
The general process is to first create the
@ -204,375 +39,120 @@ The general process is to first create the
object, set options, initialize the reader, iterate over the archive
headers and associated data, then close the archive and release all
resources.
The following summary describes the functions in approximately the
order they would be used:
.Bl -tag -compact -width indent
.It Fn archive_read_new
Allocates and initializes a
.Tn struct archive
object suitable for reading from an archive.
.It Xo
.Fn archive_read_support_compression_bzip2 ,
.Fn archive_read_support_compression_compress ,
.Fn archive_read_support_compression_gzip ,
.Fn archive_read_support_compression_lzma ,
.Fn archive_read_support_compression_none ,
.Fn archive_read_support_compression_xz
.Xc
Enables auto-detection code and decompression support for the
specified compression.
Returns
.Cm ARCHIVE_OK
if the compression is fully supported, or
.Cm ARCHIVE_WARN
if the compression is supported only through an external program.
Note that decompression using an external program is usually slower than
decompression through built-in libraries.
Note that
.Dq none
is always enabled by default.
.It Fn archive_read_support_compression_all
Enables all available decompression filters.
.It Fn archive_read_support_compression_program
Data is fed through the specified external program before being dearchived.
Note that this disables automatic detection of the compression format,
so it makes no sense to specify this in conjunction with any other
decompression option.
.It Fn archive_read_support_compression_program_signature
This feeds data through the specified external program
but only if the initial bytes of the data match the specified
signature value.
.It Xo
.Fn archive_read_support_format_all ,
.Fn archive_read_support_format_ar ,
.Fn archive_read_support_format_cpio ,
.Fn archive_read_support_format_empty ,
.Fn archive_read_support_format_iso9660 ,
.Fn archive_read_support_format_mtree ,
.Fn archive_read_support_format_tar ,
.Fn archive_read_support_format_zip
.Xc
Enables support---including auto-detection code---for the
specified archive format.
For example,
.Fn archive_read_support_format_tar
enables support for a variety of standard tar formats, old-style tar,
ustar, pax interchange format, and many common variants.
For convenience,
.Fn archive_read_support_format_all
enables support for all available formats.
Only empty archives are supported by default.
.It Fn archive_read_support_format_raw
The
.Dq raw
format handler allows libarchive to be used to read arbitrary data.
It treats any data stream as an archive with a single entry.
The pathname of this entry is
.Dq data ;
all other entry fields are unset.
This is not enabled by
.Fn archive_read_support_format_all
in order to avoid erroneous handling of damaged archives.
.It Xo
.Fn archive_read_set_filter_options ,
.Fn archive_read_set_format_options ,
.Fn archive_read_set_options
.Xc
Specifies options that will be passed to currently-registered
filters (including decompression filters) and/or format readers.
The argument is a comma-separated list of individual options.
Individual options have one of the following forms:
.Bl -tag -compact -width indent
.It Ar option=value
The option/value pair will be provided to every module.
Modules that do not accept an option with this name will ignore it.
.It Ar option
The option will be provided to every module with a value of
.Dq 1 .
.It Ar !option
The option will be provided to every module with a NULL value.
.It Ar module:option=value , Ar module:option , Ar module:!option
As above, but the corresponding option and value will be provided
only to modules whose name matches
.Ar module .
.El
The return value will be
.Cm ARCHIVE_OK
if any module accepts the option, or
.Cm ARCHIVE_WARN
if no module accepted the option, or
.Cm ARCHIVE_FATAL
if there was a fatal error while attempting to process the option.
.\"
.Ss Create archive object
See
.Xr archive_read_new 3 .
.Pp
The currently supported options are:
.Bl -tag -compact -width indent
.It Format iso9660
.Bl -tag -compact -width indent
.It Cm joliet
Support Joliet extensions.
Defaults to enabled, use
.Cm !joliet
to disable.
.El
.El
.It Fn archive_read_open
The same as
.Fn archive_read_open2 ,
except that the skip callback is assumed to be
.Dv NULL .
.It Fn archive_read_open2
Freeze the settings, open the archive, and prepare for reading entries.
This is the most generic version of this call, which accepts
four callback functions.
Most clients will want to use
.Fn archive_read_open_filename ,
.Fn archive_read_open_FILE ,
.Fn archive_read_open_fd ,
or
.Fn archive_read_open_memory
instead.
The library invokes the client-provided functions to obtain
raw bytes from the archive.
.It Fn archive_read_open_FILE
Like
.Fn archive_read_open ,
except that it accepts a
To read an archive, you must first obtain an initialized
.Tn struct archive
object from
.Fn archive_read_new .
.\"
.Ss Enable filters and formats
See
.Xr archive_read_filter 3
and
.Xr archive_read_format 3 .
.Pp
You can then modify this object for the desired operations with the
various
.Fn archive_read_set_XXX
and
.Fn archive_read_support_XXX
functions.
In particular, you will need to invoke appropriate
.Fn archive_read_support_XXX
functions to enable the corresponding compression and format
support.
Note that these latter functions perform two distinct operations:
they cause the corresponding support code to be linked into your
program, and they enable the corresponding auto-detect code.
Unless you have specific constraints, you will generally want
to invoke
.Fn archive_read_support_filter_all
and
.Fn archive_read_support_format_all
to enable auto-detect for all formats and compression types
currently supported by the library.
.\"
.Ss Set options
See
.Xr archive_read_set_options 3 .
.\"
.Ss Open archive
See
.Xr archive_read_open 3 .
.Pp
Once you have prepared the
.Tn struct archive
object, you call
.Fn archive_read_open
to actually open the archive and prepare it for reading.
There are several variants of this function;
the most basic expects you to provide pointers to several
functions that can provide blocks of bytes from the archive.
There are convenience forms that allow you to
specify a filename, file descriptor,
.Ft "FILE *"
pointer.
This function should not be used with tape drives or other devices
that require strict I/O blocking.
.It Fn archive_read_open_fd
Like
.Fn archive_read_open ,
except that it accepts a file descriptor and block size rather than
a set of function pointers.
Note that the file descriptor will not be automatically closed at
end-of-archive.
This function is safe for use with tape drives or other blocked devices.
.It Fn archive_read_open_file
This is a deprecated synonym for
.Fn archive_read_open_filename .
.It Fn archive_read_open_filename
Like
.Fn archive_read_open ,
except that it accepts a simple filename and a block size.
A NULL filename represents standard input.
This function is safe for use with tape drives or other blocked devices.
.It Fn archive_read_open_memory
Like
.Fn archive_read_open ,
except that it accepts a pointer and size of a block of
memory containing the archive data.
.It Fn archive_read_next_header
Read the header for the next entry and return a pointer to
a
.Tn struct archive_entry .
This is a convenience wrapper around
.Fn archive_read_next_header2
that reuses an internal
object, or a block of memory from which to read the archive data.
Note that the core library makes no assumptions about the
size of the blocks read;
callback functions are free to read whatever block size is
most appropriate for the medium.
.\"
.Ss Consume archive
See
.Xr archive_read_header 3 ,
.Xr archive_read_data 3
and
.Xr archive_read_extract 3 .
.Pp
Each archive entry consists of a header followed by a certain
amount of data.
You can obtain the next header with
.Fn archive_read_next_header ,
which returns a pointer to an
.Tn struct archive_entry
object for each request.
.It Fn archive_read_next_header2
Read the header for the next entry and populate the provided
.Tn struct archive_entry .
.It Fn archive_read_data
Read data associated with the header just read.
Internally, this is a convenience function that calls
.Fn archive_read_data_block
and fills any gaps with nulls so that callers see a single
continuous stream of data.
.It Fn archive_read_data_block
Return the next available block of data for this entry.
Unlike
.Fn archive_read_data ,
the
.Fn archive_read_data_block
function avoids copying data and allows you to correctly handle
sparse files, as supported by some archive formats.
The library guarantees that offsets will increase and that blocks
will not overlap.
Note that the blocks returned from this function can be much larger
than the block size read from disk, due to compression
and internal buffer optimizations.
.It Fn archive_read_data_skip
A convenience function that repeatedly calls
.Fn archive_read_data_block
to skip all of the data for this archive entry.
.\" #if ARCHIVE_API_VERSION < 3
.It Fn archive_read_data_into_buffer
This function is deprecated and will be removed.
Use
structure with information about the current archive element.
If the entry is a regular file, then the header will be followed
by the file data.
You can use
.Fn archive_read_data
instead.
.\" #endif
.It Fn archive_read_data_into_fd
A convenience function that repeatedly calls
(which works much like the
.Xr read 2
system call)
to read this data from the archive, or
.Fn archive_read_data_block
to copy the entire entry to the provided file descriptor.
.It Fn archive_read_extract , Fn archive_read_extract_set_skip_file
A convenience function that wraps the corresponding
.Xr archive_write_disk 3
interfaces.
The first call to
which provides a slightly more efficient interface.
You may prefer to use the higher-level
.Fn archive_read_data_skip ,
which reads and discards the data for this entry,
.Fn archive_read_data_to_file ,
which copies the data to the provided file descriptor, or
.Fn archive_read_extract ,
which recreates the specified entry on disk and copies data
from the archive.
In particular, note that
.Fn archive_read_extract
creates a restore object using
.Xr archive_write_disk_new 3
and
.Xr archive_write_disk_set_standard_lookup 3 ,
then transparently invokes
.Xr archive_write_disk_set_options 3 ,
.Xr archive_write_header 3 ,
.Xr archive_write_data 3 ,
and
.Xr archive_write_finish_entry 3
to create the entry on disk and copy data into it.
The
.Va flags
argument is passed unmodified to
.Xr archive_write_disk_set_options 3 .
.It Fn archive_read_extract2
This is another version of
.Fn archive_read_extract
that allows you to provide your own restore object.
In particular, this allows you to override the standard lookup functions
using
.Xr archive_write_disk_set_group_lookup 3 ,
and
.Xr archive_write_disk_set_user_lookup 3 .
Note that
.Fn archive_read_extract2
does not accept a
.Va flags
argument; you should use
.Fn archive_write_disk_set_options
to set the restore options yourself.
.It Fn archive_read_extract_set_progress_callback
Sets a pointer to a user-defined callback that can be used
for updating progress displays during extraction.
The progress function will be invoked during the extraction of large
regular files.
The progress function will be invoked with the pointer provided to this call.
Generally, the data pointed to should include a reference to the archive
object and the archive_entry object so that various statistics
can be retrieved for the progress display.
.It Fn archive_read_close
Complete the archive and invoke the close callback.
.It Fn archive_read_free
Invokes
.Fn archive_read_close
if it was not invoked manually, then release all resources.
Note: In libarchive 1.x, this function was declared to return
.Ft void ,
which made it impossible to detect certain errors when
.Fn archive_read_close
was invoked implicitly from this function.
The declaration is corrected beginning with libarchive 2.0.
.El
.Pp
Note that the library determines most of the relevant information about
the archive by inspection.
In particular, it automatically detects
.Xr gzip 1
or
.Xr bzip2 1
compression and transparently performs the appropriate decompression.
It also automatically detects the archive format.
.Pp
A complete description of the
.Tn struct archive
and
uses the
.Tn struct archive_entry
objects can be found in the overview manual page for
.Xr libarchive 3 .
.Sh CLIENT CALLBACKS
The callback functions must match the following prototypes:
.Bl -item -offset indent
.It
.Ft typedef ssize_t
.Fo archive_read_callback
.Fa "struct archive *"
.Fa "void *client_data"
.Fa "const void **buffer"
.Fc
.It
.\" #if ARCHIVE_API_VERSION < 2
.Ft typedef int
.Fo archive_skip_callback
.Fa "struct archive *"
.Fa "void *client_data"
.Fa "size_t request"
.Fc
.\" #else
.\" .Ft typedef off_t
.\" .Fo archive_skip_callback
.\" .Fa "struct archive *"
.\" .Fa "void *client_data"
.\" .Fa "off_t request"
.\" .Fc
.\" #endif
.It
.Ft typedef int
.Fn archive_open_callback "struct archive *" "void *client_data"
.It
.Ft typedef int
.Fn archive_close_callback "struct archive *" "void *client_data"
.El
structure that you provide it, which may differ from the
entry just read from the archive.
In particular, many applications will want to override the
pathname, file permissions, or ownership.
.\"
.Ss Release resources
See
.Xr archive_read_free 3 .
.Pp
The open callback is invoked by
.Fn archive_open .
It should return
.Cm ARCHIVE_OK
if the underlying file or data source is successfully
opened.
If the open fails, it should call
.Fn archive_set_error
to register an error code and message and return
.Cm ARCHIVE_FATAL .
.Pp
The read callback is invoked whenever the library
requires raw bytes from the archive.
The read callback should read data into a buffer,
set the
.Li const void **buffer
argument to point to the available data, and
return a count of the number of bytes available.
The library will invoke the read callback again
only after it has consumed this data.
The library imposes no constraints on the size
of the data blocks returned.
On end-of-file, the read callback should
return zero.
On error, the read callback should invoke
.Fn archive_set_error
to register an error code and message and
return -1.
.Pp
The skip callback is invoked when the
library wants to ignore a block of data.
The return value is the number of bytes actually
skipped, which may differ from the request.
If the callback cannot skip data, it should return
zero.
If the skip callback is not provided (the
function pointer is
.Dv NULL ),
the library will invoke the read function
instead and simply discard the result.
A skip callback can provide significant
performance gains when reading uncompressed
archives from slow disk drives or other media
that can skip quickly.
.Pp
The close callback is invoked by archive_close when
the archive processing is complete.
The callback should return
.Cm ARCHIVE_OK
on success.
On failure, the callback should invoke
.Fn archive_set_error
to register an error code and message and
return
.Cm ARCHIVE_FATAL.
Once you have finished reading data from the archive, you
should call
.Fn archive_read_close
to close the archive, then call
.Fn archive_read_free
to release all resources, including all memory allocated by the library.
.\"
.Sh EXAMPLE
The following illustrates basic usage of the library.
In this example,
@ -593,7 +173,7 @@ list_archive(const char *name)
mydata = malloc(sizeof(struct mydata));
a = archive_read_new();
mydata->name = name;
archive_read_support_compression_all(a);
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
archive_read_open(a, mydata, myopen, myread, myclose);
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
@ -632,62 +212,18 @@ myclose(struct archive *a, void *client_data)
return (ARCHIVE_OK);
}
.Ed
.Sh RETURN VALUES
Most functions return zero on success, non-zero on error.
The possible return codes include:
.Cm ARCHIVE_OK
(the operation succeeded),
.Cm ARCHIVE_WARN
(the operation succeeded but a non-critical error was encountered),
.Cm ARCHIVE_EOF
(end-of-archive was encountered),
.Cm ARCHIVE_RETRY
(the operation failed but can be retried),
and
.Cm ARCHIVE_FATAL
(there was a fatal error; the archive should be closed immediately).
Detailed error codes and textual descriptions are available from the
.Fn archive_errno
and
.Fn archive_error_string
functions.
.Pp
.Fn archive_read_new
returns a pointer to a freshly allocated
.Tn struct archive
object.
It returns
.Dv NULL
on error.
.Pp
.Fn archive_read_data
returns a count of bytes actually read or zero at the end of the entry.
On error, a value of
.Cm ARCHIVE_FATAL ,
.Cm ARCHIVE_WARN ,
or
.Cm ARCHIVE_RETRY
is returned and an error code and textual description can be retrieved from the
.Fn archive_errno
and
.Fn archive_error_string
functions.
.Pp
The library expects the client callbacks to behave similarly.
If there is an error, you can use
.Fn archive_set_error
to set an appropriate error code and description,
then return one of the non-zero values above.
(Note that the value eventually returned to the client may
not be the same; many errors that are not critical at the level
of basic I/O can prevent the archive from being properly read,
thus most I/O errors eventually cause
.Cm ARCHIVE_FATAL
to be returned.)
.\" .Sh ERRORS
.Sh SEE ALSO
.Xr tar 1 ,
.Xr archive 3 ,
.Xr libarchive 3 ,
.Xr archive_read_new 3 ,
.Xr archive_read_data 3 ,
.Xr archive_read_extract 3 ,
.Xr archive_read_filter 3 ,
.Xr archive_read_format 3 ,
.Xr archive_read_header 3 ,
.Xr archive_read_open 3 ,
.Xr archive_read_set_options 3 ,
.Xr archive_util 3 ,
.Xr tar 5
.Sh HISTORY

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
.\" Copyright (c) 2003-2011 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 AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd March 22, 2011
.Dt ARCHIVE_READ_DATA 3
.Os
.Sh NAME
.Nm archive_read_data
.Nm archive_read_data_block ,
.Nm archive_read_data_skip ,
.Nm archive_read_data_into_fd
.Nd functions for reading streaming archives
.Sh SYNOPSIS
.In archive.h
.Ft ssize_t
.Fn archive_read_data "struct archive *" "void *buff" "size_t len"
.Ft int
.Fo archive_read_data_block
.Fa "struct archive *"
.Fa "const void **buff"
.Fa "size_t *len"
.Fa "off_t *offset"
.Fc
.Ft int
.Fn archive_read_data_skip "struct archive *"
.Ft int
.Fn archive_read_data_into_fd "struct archive *" "int fd"
.\"
.Sh DESCRIPTION
.Bl -tag -compact -width indent
.It Fn archive_read_data
Read data associated with the header just read.
Internally, this is a convenience function that calls
.Fn archive_read_data_block
and fills any gaps with nulls so that callers see a single
continuous stream of data.
.It Fn archive_read_data_block
Return the next available block of data for this entry.
Unlike
.Fn archive_read_data ,
the
.Fn archive_read_data_block
function avoids copying data and allows you to correctly handle
sparse files, as supported by some archive formats.
The library guarantees that offsets will increase and that blocks
will not overlap.
Note that the blocks returned from this function can be much larger
than the block size read from disk, due to compression
and internal buffer optimizations.
.It Fn archive_read_data_skip
A convenience function that repeatedly calls
.Fn archive_read_data_block
to skip all of the data for this archive entry.
Note that this function is invoked automatically by
.Fn archive_read_next_header2
if the previous entry was not completely consumed.
.It Fn archive_read_data_into_fd
A convenience function that repeatedly calls
.Fn archive_read_data_block
to copy the entire entry to the provided file descriptor.
.El
.\"
.Sh RETURN VALUES
Most functions return zero on success, non-zero on error.
The possible return codes include:
.Cm ARCHIVE_OK
(the operation succeeded),
.Cm ARCHIVE_WARN
(the operation succeeded but a non-critical error was encountered),
.Cm ARCHIVE_EOF
(end-of-archive was encountered),
.Cm ARCHIVE_RETRY
(the operation failed but can be retried),
and
.Cm ARCHIVE_FATAL
(there was a fatal error; the archive should be closed immediately).
.Pp
.Fn archive_read_data
returns a count of bytes actually read or zero at the end of the entry.
On error, a value of
.Cm ARCHIVE_FATAL ,
.Cm ARCHIVE_WARN ,
or
.Cm ARCHIVE_RETRY
is returned.
.\"
.Sh ERRORS
Detailed error codes and textual descriptions are available from the
.Fn archive_errno
and
.Fn archive_error_string
functions.
.\"
.Sh SEE ALSO
.Xr tar 1 ,
.Xr libarchive 3 ,
.Xr archive_read 3 ,
.Xr archive_read_extract 3 ,
.Xr archive_read_filter 3 ,
.Xr archive_read_format 3 ,
.Xr archive_read_header 3 ,
.Xr archive_read_open 3 ,
.Xr archive_read_set_options 3 ,
.Xr archive_util 3 ,
.Xr tar 5

View File

@ -45,31 +45,68 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_read_data_into_fd.c,v 1.16 2008/0
/*
* This implementation minimizes copying of data and is sparse-file aware.
*/
static int
pad_to(struct archive *a, int fd, int can_lseek,
size_t nulls_size, const char *nulls,
int64_t target_offset, int64_t actual_offset)
{
size_t to_write;
ssize_t bytes_written;
if (can_lseek) {
actual_offset = lseek(fd,
target_offset - actual_offset, SEEK_CUR);
if (actual_offset != target_offset) {
archive_set_error(a, errno, "Seek error");
return (ARCHIVE_FATAL);
}
return (ARCHIVE_OK);
}
while (target_offset > actual_offset) {
to_write = nulls_size;
if (target_offset < actual_offset + nulls_size)
to_write = (size_t)(target_offset - actual_offset);
bytes_written = write(fd, nulls, to_write);
if (bytes_written < 0) {
archive_set_error(a, errno, "Write error");
return (ARCHIVE_FATAL);
}
actual_offset += bytes_written;
}
return (ARCHIVE_OK);
}
int
archive_read_data_into_fd(struct archive *a, int fd)
{
int r;
struct stat st;
int r, r2;
const void *buff;
size_t size, bytes_to_write;
ssize_t bytes_written, total_written;
off_t offset;
off_t output_offset;
ssize_t bytes_written;
int64_t target_offset;
int64_t actual_offset = 0;
int can_lseek;
char *nulls = NULL;
size_t nulls_size = 16384;
__archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, "archive_read_data_into_fd");
archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
"archive_read_data_into_fd");
total_written = 0;
output_offset = 0;
can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
if (!can_lseek)
nulls = calloc(1, nulls_size);
while ((r = archive_read_data_block(a, &buff, &size, &offset)) ==
while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
ARCHIVE_OK) {
const char *p = buff;
if (offset > output_offset) {
output_offset = lseek(fd,
offset - output_offset, SEEK_CUR);
if (output_offset != offset) {
archive_set_error(a, errno, "Seek error");
return (ARCHIVE_FATAL);
}
if (target_offset > actual_offset) {
r = pad_to(a, fd, can_lseek, nulls_size, nulls,
target_offset, actual_offset);
if (r != ARCHIVE_OK)
break;
actual_offset = target_offset;
}
while (size > 0) {
bytes_to_write = size;
@ -78,15 +115,24 @@ archive_read_data_into_fd(struct archive *a, int fd)
bytes_written = write(fd, p, bytes_to_write);
if (bytes_written < 0) {
archive_set_error(a, errno, "Write error");
return (ARCHIVE_FATAL);
r = ARCHIVE_FATAL;
goto cleanup;
}
output_offset += bytes_written;
total_written += bytes_written;
actual_offset += bytes_written;
p += bytes_written;
size -= bytes_written;
}
}
if (r == ARCHIVE_EOF && target_offset > actual_offset) {
r2 = pad_to(a, fd, can_lseek, nulls_size, nulls,
target_offset, actual_offset);
if (r2 != ARCHIVE_OK)
r = r2;
}
cleanup:
free(nulls);
if (r != ARCHIVE_EOF)
return (r);
return (ARCHIVE_OK);

View File

@ -39,6 +39,7 @@
.Nm archive_read_disk_set_gname_lookup ,
.Nm archive_read_disk_set_standard_lookup ,
.Nm archive_read_close ,
.Nm archive_read_finish ,
.Nm archive_read_free
.Nd functions for reading objects from disk
.Sh SYNOPSIS
@ -81,6 +82,8 @@
.Ft int
.Fn archive_read_close "struct archive *"
.Ft int
.Fn archive_read_finish "struct archive *"
.Ft int
.Fn archive_read_free "struct archive *"
.Sh DESCRIPTION
These functions provide an API for reading information about
@ -177,7 +180,12 @@ This affects the file ownership fields and ACL values in the
.Tn struct archive_entry
object.
.It Fn archive_read_close
This currently does nothing.
Does nothing for
.Tn archive_read_disk
handles.
.It Fn archive_read_finish
This is a deprecated synonym for
.Fn archive_read_free .
.It Fn archive_read_free
Invokes
.Fn archive_read_close
@ -207,7 +215,7 @@ file_to_archive(struct archive *a, const char *name)
fd = open(name, O_RDONLY);
if (fd < 0)
return;
archive_entry_copy_sourcepath(entry, name);
archive_entry_copy_pathname(entry, name);
archive_read_disk_entry_from_file(ard, entry, fd, NULL);
archive_write_header(a, entry);
while ((bytes_read = read(fd, buff, sizeof(buff))) > 0)
@ -229,15 +237,6 @@ for operations that might succeed if retried,
for unusual conditions that do not prevent further operations, and
.Cm ARCHIVE_FATAL
for serious errors that make remaining operations impossible.
The
.Xr archive_errno 3
and
.Xr archive_error_string 3
functions can be used to retrieve an appropriate error code and a
textual error message.
(See
.Xr archive_util 3
for details.)
.Pp
.Fn archive_read_disk_new
returns a pointer to a newly-allocated
@ -253,9 +252,17 @@ pointers to the textual name or NULL if the lookup failed for any reason.
The returned pointer points to internal storage that
may be reused on the next call to either of these functions;
callers should copy the string if they need to continue accessing it.
.Pp
.\"
.Sh ERRORS
Detailed error codes and textual descriptions are available from the
.Fn archive_errno
and
.Fn archive_error_string
functions.
.\"
.Sh SEE ALSO
.Xr archive_read 3 ,
.Xr archive_util 3 ,
.Xr archive_write 3 ,
.Xr archive_write_disk 3 ,
.Xr tar 1 ,

View File

@ -1,198 +0,0 @@
/*-
* Copyright (c) 2003-2009 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
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk.c 189429 2009-03-06 04:35:31Z kientzle $");
#include "archive.h"
#include "archive_string.h"
#include "archive_entry.h"
#include "archive_private.h"
#include "archive_read_disk_private.h"
static int _archive_read_free(struct archive *);
static int _archive_read_close(struct archive *);
static const char *trivial_lookup_gname(void *, gid_t gid);
static const char *trivial_lookup_uname(void *, uid_t uid);
static struct archive_vtable *
archive_read_disk_vtable(void)
{
static struct archive_vtable av;
static int inited = 0;
if (!inited) {
av.archive_free = _archive_read_free;
av.archive_close = _archive_read_close;
}
return (&av);
}
const char *
archive_read_disk_gname(struct archive *_a, gid_t gid)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
if (a->lookup_gname != NULL)
return ((*a->lookup_gname)(a->lookup_gname_data, gid));
return (NULL);
}
const char *
archive_read_disk_uname(struct archive *_a, uid_t uid)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
if (a->lookup_uname != NULL)
return ((*a->lookup_uname)(a->lookup_uname_data, uid));
return (NULL);
}
int
archive_read_disk_set_gname_lookup(struct archive *_a,
void *private_data,
const char * (*lookup_gname)(void *private, gid_t gid),
void (*cleanup_gname)(void *private))
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
__archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
(a->cleanup_gname)(a->lookup_gname_data);
a->lookup_gname = lookup_gname;
a->cleanup_gname = cleanup_gname;
a->lookup_gname_data = private_data;
return (ARCHIVE_OK);
}
int
archive_read_disk_set_uname_lookup(struct archive *_a,
void *private_data,
const char * (*lookup_uname)(void *private, uid_t uid),
void (*cleanup_uname)(void *private))
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
__archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
(a->cleanup_uname)(a->lookup_uname_data);
a->lookup_uname = lookup_uname;
a->cleanup_uname = cleanup_uname;
a->lookup_uname_data = private_data;
return (ARCHIVE_OK);
}
/*
* Create a new archive_read_disk object and initialize it with global state.
*/
struct archive *
archive_read_disk_new(void)
{
struct archive_read_disk *a;
a = (struct archive_read_disk *)malloc(sizeof(*a));
if (a == NULL)
return (NULL);
memset(a, 0, sizeof(*a));
a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
/* We're ready to write a header immediately. */
a->archive.state = ARCHIVE_STATE_HEADER;
a->archive.vtable = archive_read_disk_vtable();
a->lookup_uname = trivial_lookup_uname;
a->lookup_gname = trivial_lookup_gname;
return (&a->archive);
}
static int
_archive_read_free(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
(a->cleanup_gname)(a->lookup_gname_data);
if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
(a->cleanup_uname)(a->lookup_uname_data);
archive_string_free(&a->archive.error_string);
free(a);
return (ARCHIVE_OK);
}
static int
_archive_read_close(struct archive *_a)
{
(void)_a; /* UNUSED */
return (ARCHIVE_OK);
}
int
archive_read_disk_set_symlink_logical(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
a->symlink_mode = 'L';
a->follow_symlinks = 1;
return (ARCHIVE_OK);
}
int
archive_read_disk_set_symlink_physical(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
a->symlink_mode = 'P';
a->follow_symlinks = 0;
return (ARCHIVE_OK);
}
int
archive_read_disk_set_symlink_hybrid(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
a->symlink_mode = 'H';
a->follow_symlinks = 1; /* Follow symlinks initially. */
return (ARCHIVE_OK);
}
/*
* Trivial implementations of gname/uname lookup functions.
* These are normally overridden by the client, but these stub
* versions ensure that we always have something that works.
*/
static const char *
trivial_lookup_gname(void *private_data, gid_t gid)
{
(void)private_data; /* UNUSED */
(void)gid; /* UNUSED */
return (NULL);
}
static const char *
trivial_lookup_uname(void *private_data, uid_t uid)
{
(void)private_data; /* UNUSED */
(void)uid; /* UNUSED */
return (NULL);
}

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2009 Tim Kientzle
* Copyright (c) 2010 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,6 +27,9 @@
#include "archive_platform.h"
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 201084 2009-12-28 02:14:09Z kientzle $");
/* This is the tree-walking code for POSIX systems. */
#if !defined(_WIN32) || defined(__CYGWIN__)
#ifdef HAVE_SYS_TYPES_H
/* Mac OSX requires sys/types.h before sys/acl.h. */
#include <sys/types.h>
@ -36,6 +40,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
#ifdef HAVE_SYS_EXTATTR_H
#include <sys/extattr.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
@ -45,20 +52,48 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
#ifdef HAVE_SYS_XATTR_H
#include <sys/xattr.h>
#endif
#ifdef HAVE_SYS_EA_H
#include <sys/ea.h>
#endif
#ifdef HAVE_ACL_LIBACL_H
#include <acl/libacl.h>
#endif
#ifdef HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#endif
#ifdef HAVE_COPYFILE_H
#include <copyfile.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#ifdef HAVE_LINUX_FIEMAP_H
#include <linux/fiemap.h>
#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_PATHS_H
#include <paths.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "archive.h"
@ -78,13 +113,18 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
static int setup_acls_posix1e(struct archive_read_disk *,
struct archive_entry *, int fd);
static int setup_mac_metadata(struct archive_read_disk *,
struct archive_entry *, int fd);
static int setup_xattrs(struct archive_read_disk *,
struct archive_entry *, int fd);
static int setup_sparse(struct archive_read_disk *,
struct archive_entry *, int fd);
int
archive_read_disk_entry_from_file(struct archive *_a,
struct archive_entry *entry,
int fd, const struct stat *st)
int fd,
const struct stat *st)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
const char *path, *name;
@ -97,54 +137,35 @@ archive_read_disk_entry_from_file(struct archive *_a,
if (path == NULL)
path = archive_entry_pathname(entry);
#ifdef EXT2_IOC_GETFLAGS
/* Linux requires an extra ioctl to pull the flags. Although
* 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. */
if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
if (fd < 0)
fd = open(pathname, O_RDONLY | O_NONBLOCK | O_BINARY);
if (fd >= 0) {
unsigned long stflags;
int r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
if (r == 0 && stflags != 0)
archive_entry_set_fflags(entry, stflags, 0);
}
}
#endif
if (st == NULL) {
/* TODO: On Windows, use GetFileInfoByHandle() here.
* Using Windows stat() call is badly broken, but
* even the stat() wrapper has problems because
* 'struct stat' is broken on Windows.
*/
if (a->tree == NULL) {
if (st == NULL) {
#if HAVE_FSTAT
if (fd >= 0) {
if (fstat(fd, &s) != 0) {
archive_set_error(&a->archive, errno,
"Can't fstat");
return (ARCHIVE_FAILED);
}
} else
if (fd >= 0) {
if (fstat(fd, &s) != 0) {
archive_set_error(&a->archive, errno,
"Can't fstat");
return (ARCHIVE_FAILED);
}
} else
#endif
#if HAVE_LSTAT
if (!a->follow_symlinks) {
if (lstat(path, &s) != 0) {
if (!a->follow_symlinks) {
if (lstat(path, &s) != 0) {
archive_set_error(&a->archive, errno,
"Can't lstat %s", path);
return (ARCHIVE_FAILED);
}
} else
#endif
if (stat(path, &s) != 0) {
archive_set_error(&a->archive, errno,
"Can't lstat %s", path);
"Can't stat %s", path);
return (ARCHIVE_FAILED);
}
} else
#endif
if (stat(path, &s) != 0) {
archive_set_error(&a->archive, errno,
"Can't lstat %s", path);
return (ARCHIVE_FAILED);
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));
@ -161,30 +182,185 @@ archive_read_disk_entry_from_file(struct archive *_a,
archive_entry_set_fflags(entry, st->st_flags, 0);
#endif
#ifdef HAVE_READLINK
#if defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
/* Linux requires an extra ioctl to pull the flags. Although
* 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. */
if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
if (fd < 0)
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd >= 0) {
unsigned long stflags;
int r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
if (r == 0 && stflags != 0)
archive_entry_set_fflags(entry, stflags, 0);
}
}
#endif
#if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
if (S_ISLNK(st->st_mode)) {
char linkbuffer[PATH_MAX + 1];
int lnklen = readlink(path, linkbuffer, PATH_MAX);
size_t linkbuffer_len = st->st_size + 1;
char *linkbuffer;
int lnklen;
linkbuffer = malloc(linkbuffer_len);
if (linkbuffer == NULL) {
archive_set_error(&a->archive, ENOMEM,
"Couldn't read link data");
return (ARCHIVE_FAILED);
}
#ifdef HAVE_READLINKAT
if (a->entry_wd_fd >= 0)
lnklen = readlinkat(a->entry_wd_fd, path,
linkbuffer, linkbuffer_len);
else
#endif /* HAVE_READLINKAT */
lnklen = readlink(path, linkbuffer, linkbuffer_len);
if (lnklen < 0) {
archive_set_error(&a->archive, errno,
"Couldn't read link data");
free(linkbuffer);
return (ARCHIVE_FAILED);
}
linkbuffer[lnklen] = 0;
archive_entry_set_symlink(entry, linkbuffer);
free(linkbuffer);
}
#endif
#endif /* HAVE_READLINK || HAVE_READLINKAT */
r = setup_acls_posix1e(a, entry, fd);
r1 = setup_xattrs(a, entry, fd);
if (r1 < r)
r = r1;
r1 = setup_mac_metadata(a, entry, fd);
if (r1 < r)
r = r1;
r1 = setup_sparse(a, entry, fd);
if (r1 < r)
r = r1;
/* If we opened the file earlier in this function, close it. */
if (initial_fd != fd)
close(fd);
return (r);
}
#if defined(__APPLE__) && defined(HAVE_COPYFILE_H)
/*
* The Mac OS "copyfile()" API copies the extended metadata for a
* file into a separate file in AppleDouble format (see RFC 1740).
*
* Mac OS tar and cpio implementations store this extended
* metadata as a separate entry just before the regular entry
* with a "._" prefix added to the filename.
*
* Note that this is currently done unconditionally; the tar program has
* an option to discard this information before the archive is written.
*
* TODO: If there's a failure, report it and return ARCHIVE_WARN.
*/
static int
setup_mac_metadata(struct archive_read_disk *a,
struct archive_entry *entry, int fd)
{
int tempfd = -1;
int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR;
struct stat copyfile_stat;
int ret = ARCHIVE_OK;
void *buff;
int have_attrs;
const char *name, *tempdir, *tempfile = NULL;
name = archive_entry_sourcepath(entry);
if (name == NULL)
name = archive_entry_pathname(entry);
if (name == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Can't open file to read extended attributes: No name");
return (ARCHIVE_WARN);
}
/* Short-circuit if there's nothing to do. */
have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
if (have_attrs == -1) {
archive_set_error(&a->archive, errno,
"Could not check extended attributes");
return (ARCHIVE_WARN);
}
if (have_attrs == 0)
return (ARCHIVE_OK);
tempdir = NULL;
if (issetugid() == 0)
tempdir = getenv("TMPDIR");
if (tempdir == NULL)
tempdir = _PATH_TMP;
tempfile = tempnam(tempdir, "tar.md.");
/* XXX I wish copyfile() could pack directly to a memory
* buffer; that would avoid the temp file here. For that
* matter, it would be nice if fcopyfile() actually worked,
* that would reduce the many open/close races here. */
if (copyfile(name, tempfile, 0, copyfile_flags | COPYFILE_PACK)) {
archive_set_error(&a->archive, errno,
"Could not pack extended attributes");
ret = ARCHIVE_WARN;
goto cleanup;
}
tempfd = open(tempfile, O_RDONLY);
if (tempfd < 0) {
archive_set_error(&a->archive, errno,
"Could not open extended attribute file");
ret = ARCHIVE_WARN;
goto cleanup;
}
if (fstat(tempfd, &copyfile_stat)) {
archive_set_error(&a->archive, errno,
"Could not check size of extended attributes");
ret = ARCHIVE_WARN;
goto cleanup;
}
buff = malloc(copyfile_stat.st_size);
if (buff == NULL) {
archive_set_error(&a->archive, errno,
"Could not allocate memory for extended attributes");
ret = ARCHIVE_WARN;
goto cleanup;
}
if (copyfile_stat.st_size != read(tempfd, buff, copyfile_stat.st_size)) {
archive_set_error(&a->archive, errno,
"Could not read extended attributes into memory");
ret = ARCHIVE_WARN;
goto cleanup;
}
archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size);
cleanup:
if (tempfd >= 0)
close(tempfd);
if (tempfile != NULL)
unlink(tempfile);
return (ret);
}
#else
/*
* Stub implementation for non-Mac systems.
*/
static int
setup_mac_metadata(struct archive_read_disk *a,
struct archive_entry *entry, int fd)
{
(void)a; /* UNUSED */
(void)entry; /* UNUSED */
(void)fd; /* UNUSED */
return (ARCHIVE_OK);
}
#endif
#ifdef HAVE_POSIX_ACL
static void setup_acl_posix1e(struct archive_read_disk *a,
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
@ -307,10 +483,12 @@ setup_acls_posix1e(struct archive_read_disk *a,
}
#endif
#if HAVE_LISTXATTR && HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR
#if (HAVE_FGETXATTR && HAVE_FLISTXATTR && HAVE_LISTXATTR && \
HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR) || \
(HAVE_FGETEA && HAVE_FLISTEA && HAVE_LISTEA)
/*
* Linux extended attribute support.
* Linux and AIX extended attribute support.
*
* TODO: By using a stack-allocated buffer for the first
* call to getxattr(), we might be able to avoid the second
@ -329,16 +507,25 @@ setup_xattr(struct archive_read_disk *a,
void *value = NULL;
const char *accpath;
(void)fd; /* UNUSED */
accpath = archive_entry_sourcepath(entry);
if (accpath == NULL)
accpath = archive_entry_pathname(entry);
if (!a->follow_symlinks)
#if HAVE_FGETXATTR
if (fd >= 0)
size = fgetxattr(fd, name, NULL, 0);
else if (!a->follow_symlinks)
size = lgetxattr(accpath, name, NULL, 0);
else
size = getxattr(accpath, name, NULL, 0);
#elif HAVE_FGETEA
if (fd >= 0)
size = fgetea(fd, name, NULL, 0);
else if (!a->follow_symlinks)
size = lgetea(accpath, name, NULL, 0);
else
size = getea(accpath, name, NULL, 0);
#endif
if (size == -1) {
archive_set_error(&a->archive, errno,
@ -351,10 +538,21 @@ setup_xattr(struct archive_read_disk *a,
return (ARCHIVE_FATAL);
}
if (!a->follow_symlinks)
#if HAVE_FGETXATTR
if (fd >= 0)
size = fgetxattr(fd, name, value, size);
else if (!a->follow_symlinks)
size = lgetxattr(accpath, name, value, size);
else
size = getxattr(accpath, name, value, size);
#elif HAVE_FGETEA
if (fd >= 0)
size = fgetea(fd, name, value, size);
else if (!a->follow_symlinks)
size = lgetea(accpath, name, value, size);
else
size = getea(accpath, name, value, size);
#endif
if (size == -1) {
archive_set_error(&a->archive, errno,
@ -376,18 +574,28 @@ setup_xattrs(struct archive_read_disk *a,
const char *path;
ssize_t list_size;
path = archive_entry_sourcepath(entry);
if (path == NULL)
path = archive_entry_pathname(entry);
if (!a->follow_symlinks)
#if HAVE_FLISTXATTR
if (fd >= 0)
list_size = flistxattr(fd, NULL, 0);
else if (!a->follow_symlinks)
list_size = llistxattr(path, NULL, 0);
else
list_size = listxattr(path, NULL, 0);
#elif HAVE_FLISTEA
if (fd >= 0)
list_size = flistea(fd, NULL, 0);
else if (!a->follow_symlinks)
list_size = llistea(path, NULL, 0);
else
list_size = listea(path, NULL, 0);
#endif
if (list_size == -1) {
if (errno == ENOTSUP)
if (errno == ENOTSUP || errno == ENOSYS)
return (ARCHIVE_OK);
archive_set_error(&a->archive, errno,
"Couldn't list extended attributes");
@ -402,10 +610,21 @@ setup_xattrs(struct archive_read_disk *a,
return (ARCHIVE_FATAL);
}
if (!a->follow_symlinks)
#if HAVE_FLISTXATTR
if (fd >= 0)
list_size = flistxattr(fd, list, list_size);
else if (!a->follow_symlinks)
list_size = llistxattr(path, list, list_size);
else
list_size = listxattr(path, list, list_size);
#elif HAVE_FLISTEA
if (fd >= 0)
list_size = flistea(fd, list, list_size);
else if (!a->follow_symlinks)
list_size = llistea(path, list, list_size);
else
list_size = listea(path, list, list_size);
#endif
if (list_size == -1) {
archive_set_error(&a->archive, errno,
@ -449,13 +668,13 @@ setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
void *value = NULL;
const char *accpath;
(void)fd; /* UNUSED */
accpath = archive_entry_sourcepath(entry);
if (accpath == NULL)
accpath = archive_entry_pathname(entry);
if (!a->follow_symlinks)
if (fd >= 0)
size = extattr_get_fd(fd, namespace, name, NULL, 0);
else if (!a->follow_symlinks)
size = extattr_get_link(accpath, namespace, name, NULL, 0);
else
size = extattr_get_file(accpath, namespace, name, NULL, 0);
@ -471,7 +690,9 @@ setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
return (ARCHIVE_FATAL);
}
if (!a->follow_symlinks)
if (fd >= 0)
size = extattr_get_fd(fd, namespace, name, value, size);
else if (!a->follow_symlinks)
size = extattr_get_link(accpath, namespace, name, value, size);
else
size = extattr_get_file(accpath, namespace, name, value, size);
@ -502,7 +723,9 @@ setup_xattrs(struct archive_read_disk *a,
if (path == NULL)
path = archive_entry_pathname(entry);
if (!a->follow_symlinks)
if (fd >= 0)
list_size = extattr_list_fd(fd, namespace, NULL, 0);
else if (!a->follow_symlinks)
list_size = extattr_list_link(path, namespace, NULL, 0);
else
list_size = extattr_list_file(path, namespace, NULL, 0);
@ -523,7 +746,9 @@ setup_xattrs(struct archive_read_disk *a,
return (ARCHIVE_FATAL);
}
if (!a->follow_symlinks)
if (fd >= 0)
list_size = extattr_list_fd(fd, namespace, list, list_size);
else if (!a->follow_symlinks)
list_size = extattr_list_link(path, namespace, list, list_size);
else
list_size = extattr_list_file(path, namespace, list, list_size);
@ -568,3 +793,213 @@ setup_xattrs(struct archive_read_disk *a,
}
#endif
#if defined(HAVE_LINUX_FIEMAP_H)
/*
* Linux sparse interface.
*
* The FIEMAP ioctl returns an "extent" for each physical allocation
* on disk. We need to process those to generate a more compact list
* of logical file blocks. We also need to be very careful to use
* FIEMAP_FLAG_SYNC here, since there are reports that Linux sometimes
* does not report allocations for newly-written data that hasn't
* been synced to disk.
*
* It's important to return a minimal sparse file list because we want
* to not trigger sparse file extensions if we don't have to, since
* not all readers support them.
*/
static int
setup_sparse(struct archive_read_disk *a,
struct archive_entry *entry, int fd)
{
char buff[4096];
struct fiemap *fm;
struct fiemap_extent *fe;
int64_t size;
int count, do_fiemap;
int initial_fd = fd;
int exit_sts = ARCHIVE_OK;
if (archive_entry_filetype(entry) != AE_IFREG
|| archive_entry_size(entry) <= 0
|| archive_entry_hardlink(entry) != NULL)
return (ARCHIVE_OK);
if (fd < 0) {
const char *path;
path = archive_entry_sourcepath(entry);
if (path == NULL)
path = archive_entry_pathname(entry);
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
archive_set_error(&a->archive, errno,
"Can't open `%s'", path);
return (ARCHIVE_FAILED);
}
}
count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe);
fm = (struct fiemap *)buff;
fm->fm_start = 0;
fm->fm_length = ~0ULL;;
fm->fm_flags = FIEMAP_FLAG_SYNC;
fm->fm_extent_count = count;
do_fiemap = 1;
size = archive_entry_size(entry);
for (;;) {
int i, r;
r = ioctl(fd, FS_IOC_FIEMAP, fm);
if (r < 0) {
/* When errno is ENOTTY, it is better we should
* return ARCHIVE_OK because an earlier 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;
}
if (fm->fm_mapped_extents == 0)
break;
fe = fm->fm_extents;
for (i = 0; i < fm->fm_mapped_extents; i++, fe++) {
if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
/* The fe_length of the last block does not
* adjust itself to its size files. */
int64_t length = fe->fe_length;
if (fe->fe_logical + length > size)
length -= fe->fe_logical + length - size;
if (fe->fe_logical == 0 && length == size) {
/* This is not sparse. */
do_fiemap = 0;
break;
}
if (length > 0)
archive_entry_sparse_add_entry(entry,
fe->fe_logical, length);
}
if (fe->fe_flags & FIEMAP_EXTENT_LAST)
do_fiemap = 0;
}
if (do_fiemap) {
fe = fm->fm_extents + fm->fm_mapped_extents -1;
fm->fm_start = fe->fe_logical + fe->fe_length;
} else
break;
}
exit_setup_sparse:
if (initial_fd != fd)
close(fd);
return (exit_sts);
}
#elif defined(SEEK_HOLE) && defined(SEEK_DATA) && defined(_PC_MIN_HOLE_SIZE)
/*
* FreeBSD and Solaris sparse interface.
*/
static int
setup_sparse(struct archive_read_disk *a,
struct archive_entry *entry, int fd)
{
int64_t size;
int initial_fd = fd;
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 */
int exit_sts = ARCHIVE_OK;
if (archive_entry_filetype(entry) != AE_IFREG
|| archive_entry_size(entry) <= 0
|| archive_entry_hardlink(entry) != NULL)
return (ARCHIVE_OK);
/* Does filesystem support the reporting of hole ? */
if (fd >= 0) {
if (fpathconf(fd, _PC_MIN_HOLE_SIZE) <= 0)
return (ARCHIVE_OK);
initial_off = lseek(fd, 0, SEEK_CUR);
if (initial_off != 0)
lseek(fd, 0, SEEK_SET);
} else {
const char *path;
path = archive_entry_sourcepath(entry);
if (path == NULL)
path = archive_entry_pathname(entry);
if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
return (ARCHIVE_OK);
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
archive_set_error(&a->archive, errno,
"Can't open `%s'", path);
return (ARCHIVE_FAILED);
}
initial_off = 0;
}
off_s = 0;
size = archive_entry_size(entry);
while (off_s < size) {
off_s = lseek(fd, off_s, SEEK_DATA);
if (off_s == (off_t)-1) {
if (errno == ENXIO)
break;/* no more hole */
archive_set_error(&a->archive, errno,
"lseek(SEEK_HOLE) failed");
exit_sts = ARCHIVE_FAILED;
goto exit_setup_sparse;
}
off_e = lseek(fd, off_s, SEEK_HOLE);
if (off_s == (off_t)-1) {
if (errno == ENXIO) {
off_e = lseek(fd, 0, SEEK_END);
if (off_e != (off_t)-1)
break;/* no more data */
}
archive_set_error(&a->archive, errno,
"lseek(SEEK_DATA) failed");
exit_sts = ARCHIVE_FAILED;
goto exit_setup_sparse;
}
if (off_s == 0 && off_e == size)
break;/* This is not spase. */
archive_entry_sparse_add_entry(entry, off_s,
off_e - off_s);
off_s = off_e;
}
exit_setup_sparse:
if (initial_fd != fd)
close(fd);
else
lseek(fd, initial_off, SEEK_SET);
return (exit_sts);
}
#else
/*
* Generic (stub) sparse support.
*/
static int
setup_sparse(struct archive_read_disk *a,
struct archive_entry *entry, int fd)
{
(void)a; /* UNUSED */
(void)entry; /* UNUSED */
(void)fd; /* UNUSED */
return (ARCHIVE_OK);
}
#endif
#endif /* !defined(_WIN32) || defined(__CYGWIN__) */

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,8 @@
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
struct tree;
struct archive_read_disk {
struct archive archive;
@ -51,10 +53,17 @@ struct archive_read_disk {
*/
char follow_symlinks; /* Either 'L' or 'P'. */
const char * (*lookup_gname)(void *private, gid_t gid);
/* Directory traversals. */
struct tree *tree;
/* Set 1 if users request to restore atime . */
int restore_time;
int entry_wd_fd;
const char * (*lookup_gname)(void *private, int64_t gid);
void (*cleanup_gname)(void *private);
void *lookup_gname_data;
const char * (*lookup_uname)(void *private, gid_t gid);
const char * (*lookup_uname)(void *private, int64_t uid);
void (*cleanup_uname)(void *private);
void *lookup_uname_data;
};

View File

@ -72,8 +72,8 @@ struct name_cache {
} cache[name_cache_size];
};
static const char * lookup_gname(void *, gid_t);
static const char * lookup_uname(void *, uid_t);
static const char * lookup_gname(void *, int64_t);
static const char * lookup_uname(void *, int64_t);
static void cleanup(void *);
static const char * lookup_gname_helper(struct name_cache *, id_t gid);
static const char * lookup_uname_helper(struct name_cache *, id_t uid);
@ -175,7 +175,7 @@ lookup_name(struct name_cache *cache,
}
static const char *
lookup_uname(void *data, uid_t uid)
lookup_uname(void *data, int64_t uid)
{
struct name_cache *uname_cache = (struct name_cache *)data;
return (lookup_name(uname_cache,
@ -187,6 +187,8 @@ static const char *
lookup_uname_helper(struct name_cache *cache, id_t id)
{
struct passwd pwent, *result;
char * nbuff;
size_t nbuff_size;
int r;
if (cache->buff_size == 0) {
@ -208,10 +210,12 @@ lookup_uname_helper(struct name_cache *cache, id_t id)
* we just double it and try again. Because the buffer
* is kept around in the cache object, we shouldn't
* have to do this very often. */
cache->buff_size *= 2;
cache->buff = realloc(cache->buff, cache->buff_size);
if (cache->buff == NULL)
nbuff_size = cache->buff_size * 2;
nbuff = realloc(cache->buff, nbuff_size);
if (nbuff == NULL)
break;
cache->buff = nbuff;
cache->buff_size = nbuff_size;
}
if (r != 0) {
archive_set_error(cache->archive, errno,
@ -239,7 +243,7 @@ lookup_uname_helper(struct name_cache *cache, id_t id)
#endif
static const char *
lookup_gname(void *data, gid_t gid)
lookup_gname(void *data, int64_t gid)
{
struct name_cache *gname_cache = (struct name_cache *)data;
return (lookup_name(gname_cache,
@ -251,6 +255,8 @@ static const char *
lookup_gname_helper(struct name_cache *cache, id_t id)
{
struct group grent, *result;
char * nbuff;
size_t nbuff_size;
int r;
if (cache->buff_size == 0) {
@ -270,10 +276,12 @@ lookup_gname_helper(struct name_cache *cache, id_t id)
/* ERANGE means our buffer was too small, but POSIX
* doesn't tell us how big the buffer should be, so
* we just double it and try again. */
cache->buff_size *= 2;
cache->buff = realloc(cache->buff, cache->buff_size);
if (cache->buff == NULL)
nbuff_size = cache->buff_size * 2;
nbuff = realloc(cache->buff, nbuff_size);
if (nbuff == NULL)
break;
cache->buff = nbuff;
cache->buff_size = nbuff_size;
}
if (r != 0) {
archive_set_error(cache->archive, errno,

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,135 @@
.\" Copyright (c) 2003-2011 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 AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd March 22, 2011
.Dt ARCHIVE_READ_EXTRACT 3
.Os
.Sh NAME
.Nm archive_read_extract ,
.Nm archive_read_extract2 ,
.Nm archive_read_extract_set_progress_callback
.Nd functions for reading streaming archives
.Sh SYNOPSIS
.In archive.h
.Ft int
.Fo archive_read_extract
.Fa "struct archive *"
.Fa "struct archive_entry *"
.Fa "int flags"
.Fc
.Ft int
.Fo archive_read_extract2
.Fa "struct archive *src"
.Fa "struct archive_entry *"
.Fa "struct archive *dest"
.Fc
.Ft void
.Fo archive_read_extract_set_progress_callback
.Fa "struct archive *"
.Fa "void (*func)(void *)"
.Fa "void *user_data"
.Fc
.Sh DESCRIPTION
.Bl -tag -compact -width indent
.It Fn archive_read_extract , Fn archive_read_extract_set_skip_file
A convenience function that wraps the corresponding
.Xr archive_write_disk 3
interfaces.
The first call to
.Fn archive_read_extract
creates a restore object using
.Xr archive_write_disk_new 3
and
.Xr archive_write_disk_set_standard_lookup 3 ,
then transparently invokes
.Xr archive_write_disk_set_options 3 ,
.Xr archive_write_header 3 ,
.Xr archive_write_data 3 ,
and
.Xr archive_write_finish_entry 3
to create the entry on disk and copy data into it.
The
.Va flags
argument is passed unmodified to
.Xr archive_write_disk_set_options 3 .
.It Fn archive_read_extract2
This is another version of
.Fn archive_read_extract
that allows you to provide your own restore object.
In particular, this allows you to override the standard lookup functions
using
.Xr archive_write_disk_set_group_lookup 3 ,
and
.Xr archive_write_disk_set_user_lookup 3 .
Note that
.Fn archive_read_extract2
does not accept a
.Va flags
argument; you should use
.Fn archive_write_disk_set_options
to set the restore options yourself.
.It Fn archive_read_extract_set_progress_callback
Sets a pointer to a user-defined callback that can be used
for updating progress displays during extraction.
The progress function will be invoked during the extraction of large
regular files.
The progress function will be invoked with the pointer provided to this call.
Generally, the data pointed to should include a reference to the archive
object and the archive_entry object so that various statistics
can be retrieved for the progress display.
.El
.\"
.Sh RETURN VALUES
Most functions return zero on success, non-zero on error.
The possible return codes include:
.Cm ARCHIVE_OK
(the operation succeeded),
.Cm ARCHIVE_WARN
(the operation succeeded but a non-critical error was encountered),
.Cm ARCHIVE_EOF
(end-of-archive was encountered),
.Cm ARCHIVE_RETRY
(the operation failed but can be retried),
and
.Cm ARCHIVE_FATAL
(there was a fatal error; the archive should be closed immediately).
.Sh ERRORS
Detailed error codes and textual descriptions are available from the
.Fn archive_errno
and
.Fn archive_error_string
functions.
.Sh SEE ALSO
.Xr tar 1 ,
.Xr libarchive 3 ,
.Xr archive_read 3 ,
.Xr archive_read_data 3 ,
.Xr archive_read_filter 3 ,
.Xr archive_read_format 3 ,
.Xr archive_read_open 3 ,
.Xr archive_read_set_options 3 ,
.Xr archive_util 3 ,
.Xr tar 5

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