Merge branch 'upstream-LibArchive' into update-libarchive
Resolve conflicts in C code by taking their side. Resolve conflicts in CMake code by integrating the changes.
This commit is contained in:
commit
e9bc469b2a
|
@ -86,12 +86,10 @@ OPTION(ENABLE_ACL "Enable ACL support" ON)
|
||||||
OPTION(ENABLE_ICONV "Enable iconv support" ON)
|
OPTION(ENABLE_ICONV "Enable iconv support" ON)
|
||||||
|
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
IF(MSVC60)
|
#ELSEIF(WINDOWS_VERSION STREQUAL "WINXP")
|
||||||
SET(WINVER 0x0400)
|
SET(NTDDI_VERSION 0x05010000)
|
||||||
ELSE()
|
SET(_WIN32_WINNT 0x0501)
|
||||||
SET(WINVER 0x0500)
|
SET(WINVER 0x0501)
|
||||||
ENDIF()
|
|
||||||
SET(_WIN32_WINNT ${WINVER})
|
|
||||||
ENDIF(WIN32)
|
ENDIF(WIN32)
|
||||||
|
|
||||||
set(HAVE_PTHREAD_H 0) # no threads in CMake
|
set(HAVE_PTHREAD_H 0) # no threads in CMake
|
||||||
|
@ -487,12 +485,17 @@ IF(ENABLE_NETTLE)
|
||||||
FIND_PACKAGE(Nettle)
|
FIND_PACKAGE(Nettle)
|
||||||
IF(NETTLE_FOUND)
|
IF(NETTLE_FOUND)
|
||||||
SET(HAVE_LIBNETTLE 1)
|
SET(HAVE_LIBNETTLE 1)
|
||||||
SET(HAVE_NETTLE_MD5_H 1)
|
|
||||||
SET(HAVE_NETTLE_RIPEMD160_H 1)
|
|
||||||
SET(HAVE_NETTLE_SHA_H 1)
|
|
||||||
INCLUDE_DIRECTORIES(${NETTLE_INCLUDE_DIR})
|
|
||||||
LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARIES})
|
LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARIES})
|
||||||
|
INCLUDE_DIRECTORIES(${NETTLE_INCLUDE_DIR})
|
||||||
|
|
||||||
|
LIST(APPEND CMAKE_REQUIRED_INCLUDES ${NETTLE_INCLUDE_DIR})
|
||||||
|
LA_CHECK_INCLUDE_FILE("nettle/aes.h" HAVE_NETTLE_AES_H)
|
||||||
|
LA_CHECK_INCLUDE_FILE("nettle/hmac.h" HAVE_NETTLE_HMAC_H)
|
||||||
|
LA_CHECK_INCLUDE_FILE("nettle/md5.h" HAVE_NETTLE_MD5_H)
|
||||||
LA_CHECK_INCLUDE_FILE("nettle/pbkdf2.h" HAVE_NETTLE_PBKDF2_H)
|
LA_CHECK_INCLUDE_FILE("nettle/pbkdf2.h" HAVE_NETTLE_PBKDF2_H)
|
||||||
|
LA_CHECK_INCLUDE_FILE("nettle/ripemd160.h" HAVE_NETTLE_RIPEMD160_H)
|
||||||
|
LA_CHECK_INCLUDE_FILE("nettle/sha.h" HAVE_NETTLE_SHA_H)
|
||||||
|
|
||||||
ENDIF(NETTLE_FOUND)
|
ENDIF(NETTLE_FOUND)
|
||||||
MARK_AS_ADVANCED(CLEAR NETTLE_INCLUDE_DIR)
|
MARK_AS_ADVANCED(CLEAR NETTLE_INCLUDE_DIR)
|
||||||
MARK_AS_ADVANCED(CLEAR NETTLE_LIBRARIES)
|
MARK_AS_ADVANCED(CLEAR NETTLE_LIBRARIES)
|
||||||
|
@ -506,6 +509,8 @@ IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
FIND_PACKAGE(OpenSSL)
|
FIND_PACKAGE(OpenSSL)
|
||||||
IF(OPENSSL_FOUND)
|
IF(OPENSSL_FOUND)
|
||||||
SET(HAVE_LIBCRYPTO 1)
|
SET(HAVE_LIBCRYPTO 1)
|
||||||
|
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
||||||
|
LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_CRYPTO_LIBRARY})
|
||||||
ENDIF(OPENSSL_FOUND)
|
ENDIF(OPENSSL_FOUND)
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(OPENSSL_FOUND FALSE) # Override cached value
|
SET(OPENSSL_FOUND FALSE) # Override cached value
|
||||||
|
@ -723,6 +728,9 @@ MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
|
||||||
#
|
#
|
||||||
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
|
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
IF (CMAKE_C_COMPILER_ID STREQUAL "XL")
|
||||||
|
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -qhalt=w -qflag=w:w")
|
||||||
|
ENDIF ()
|
||||||
IF (MSVC)
|
IF (MSVC)
|
||||||
# NOTE: /WX option is the same as gcc's -Werror option.
|
# NOTE: /WX option is the same as gcc's -Werror option.
|
||||||
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /WX")
|
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /WX")
|
||||||
|
@ -1040,10 +1048,15 @@ ENDIF(HAVE_INTTYPES_H)
|
||||||
CHECK_SYMBOL_EXISTS(EFTYPE "errno.h" HAVE_EFTYPE)
|
CHECK_SYMBOL_EXISTS(EFTYPE "errno.h" HAVE_EFTYPE)
|
||||||
CHECK_SYMBOL_EXISTS(EILSEQ "errno.h" HAVE_EILSEQ)
|
CHECK_SYMBOL_EXISTS(EILSEQ "errno.h" HAVE_EILSEQ)
|
||||||
CHECK_SYMBOL_EXISTS(D_MD_ORDER "langinfo.h" HAVE_D_MD_ORDER)
|
CHECK_SYMBOL_EXISTS(D_MD_ORDER "langinfo.h" HAVE_D_MD_ORDER)
|
||||||
|
CHECK_SYMBOL_EXISTS(INT32_MAX "${headers}" HAVE_DECL_INT32_MAX)
|
||||||
|
CHECK_SYMBOL_EXISTS(INT32_MIN "${headers}" HAVE_DECL_INT32_MIN)
|
||||||
CHECK_SYMBOL_EXISTS(INT64_MAX "${headers}" HAVE_DECL_INT64_MAX)
|
CHECK_SYMBOL_EXISTS(INT64_MAX "${headers}" HAVE_DECL_INT64_MAX)
|
||||||
CHECK_SYMBOL_EXISTS(INT64_MIN "${headers}" HAVE_DECL_INT64_MIN)
|
CHECK_SYMBOL_EXISTS(INT64_MIN "${headers}" HAVE_DECL_INT64_MIN)
|
||||||
|
CHECK_SYMBOL_EXISTS(INTMAX_MAX "${headers}" HAVE_DECL_INTMAX_MAX)
|
||||||
|
CHECK_SYMBOL_EXISTS(INTMAX_MIN "${headers}" HAVE_DECL_INTMAX_MIN)
|
||||||
CHECK_SYMBOL_EXISTS(UINT32_MAX "${headers}" HAVE_DECL_UINT32_MAX)
|
CHECK_SYMBOL_EXISTS(UINT32_MAX "${headers}" HAVE_DECL_UINT32_MAX)
|
||||||
CHECK_SYMBOL_EXISTS(UINT64_MAX "${headers}" HAVE_DECL_UINT64_MAX)
|
CHECK_SYMBOL_EXISTS(UINT64_MAX "${headers}" HAVE_DECL_UINT64_MAX)
|
||||||
|
CHECK_SYMBOL_EXISTS(UINTMAX_MAX "${headers}" HAVE_DECL_UINTMAX_MAX)
|
||||||
CHECK_SYMBOL_EXISTS(SIZE_MAX "${headers}" HAVE_DECL_SIZE_MAX)
|
CHECK_SYMBOL_EXISTS(SIZE_MAX "${headers}" HAVE_DECL_SIZE_MAX)
|
||||||
CHECK_SYMBOL_EXISTS(SSIZE_MAX "limits.h" HAVE_DECL_SSIZE_MAX)
|
CHECK_SYMBOL_EXISTS(SSIZE_MAX "limits.h" HAVE_DECL_SSIZE_MAX)
|
||||||
|
|
||||||
|
|
|
@ -173,8 +173,6 @@ typedef unsigned char uint8_t;
|
||||||
/* Define intmax_t and uintmax_t if they are not already defined. */
|
/* Define intmax_t and uintmax_t if they are not already defined. */
|
||||||
#if !defined(HAVE_INTMAX_T)
|
#if !defined(HAVE_INTMAX_T)
|
||||||
typedef int64_t intmax_t;
|
typedef int64_t intmax_t;
|
||||||
#define INTMAX_MIN INT64_MIN
|
|
||||||
#define INTMAX_MAX INT64_MAX
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(HAVE_UINTMAX_T)
|
#if !defined(HAVE_UINTMAX_T)
|
||||||
|
@ -367,6 +365,14 @@ typedef uint64_t uintmax_t;
|
||||||
/* Define to 1 if you have the `cygwin_conv_path' function. */
|
/* Define to 1 if you have the `cygwin_conv_path' function. */
|
||||||
#cmakedefine HAVE_CYGWIN_CONV_PATH 1
|
#cmakedefine HAVE_CYGWIN_CONV_PATH 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `INT32_MAX', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#cmakedefine HAVE_DECL_INT32_MAX 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `INT32_MIN', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#cmakedefine HAVE_DECL_INT32_MIN 1
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `INT64_MAX', and to 0 if you
|
/* Define to 1 if you have the declaration of `INT64_MAX', and to 0 if you
|
||||||
don't. */
|
don't. */
|
||||||
#cmakedefine HAVE_DECL_INT64_MAX 1
|
#cmakedefine HAVE_DECL_INT64_MAX 1
|
||||||
|
@ -375,6 +381,14 @@ typedef uint64_t uintmax_t;
|
||||||
don't. */
|
don't. */
|
||||||
#cmakedefine HAVE_DECL_INT64_MIN 1
|
#cmakedefine HAVE_DECL_INT64_MIN 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `INTMAX_MAX', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#cmakedefine HAVE_DECL_INTMAX_MAX 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `INTMAX_MIN', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#cmakedefine HAVE_DECL_INTMAX_MIN 1
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
|
/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
|
||||||
don't. */
|
don't. */
|
||||||
#cmakedefine HAVE_DECL_SIZE_MAX 1
|
#cmakedefine HAVE_DECL_SIZE_MAX 1
|
||||||
|
@ -395,6 +409,10 @@ typedef uint64_t uintmax_t;
|
||||||
don't. */
|
don't. */
|
||||||
#cmakedefine HAVE_DECL_UINT64_MAX 1
|
#cmakedefine HAVE_DECL_UINT64_MAX 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `UINTMAX_MAX', and to 0 if you
|
||||||
|
don't. */
|
||||||
|
#cmakedefine HAVE_DECL_UINTMAX_MAX 1
|
||||||
|
|
||||||
/* Define to 1 if you have the <direct.h> header file. */
|
/* Define to 1 if you have the <direct.h> header file. */
|
||||||
#cmakedefine HAVE_DIRECT_H 1
|
#cmakedefine HAVE_DIRECT_H 1
|
||||||
|
|
||||||
|
@ -739,6 +757,12 @@ typedef uint64_t uintmax_t;
|
||||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||||
#cmakedefine HAVE_NDIR_H 1
|
#cmakedefine HAVE_NDIR_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <nettle/aes.h> header file. */
|
||||||
|
#cmakedefine HAVE_NETTLE_AES_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <nettle/hmac.h> header file. */
|
||||||
|
#cmakedefine HAVE_NETTLE_HMAC_H 1
|
||||||
|
|
||||||
/* Define to 1 if you have the <nettle/md5.h> header file. */
|
/* Define to 1 if you have the <nettle/md5.h> header file. */
|
||||||
#cmakedefine HAVE_NETTLE_MD5_H 1
|
#cmakedefine HAVE_NETTLE_MD5_H 1
|
||||||
|
|
||||||
|
@ -1153,7 +1177,11 @@ typedef uint64_t uintmax_t;
|
||||||
/* Define for large files, on AIX-style hosts. */
|
/* Define for large files, on AIX-style hosts. */
|
||||||
#cmakedefine _LARGE_FILES ${_LARGE_FILES}
|
#cmakedefine _LARGE_FILES ${_LARGE_FILES}
|
||||||
|
|
||||||
/* Define for Windows to use Windows 2000+ APIs. */
|
/* Define to control Windows SDK version */
|
||||||
|
#ifndef NTDDI_VERSION
|
||||||
|
#cmakedefine NTDDI_VERSION ${NTDDI_VERSION}
|
||||||
|
#endif // NTDDI_VERSION
|
||||||
|
|
||||||
#ifndef _WIN32_WINNT
|
#ifndef _WIN32_WINNT
|
||||||
#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
|
#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
|
||||||
#endif // _WIN32_WINNT
|
#endif // _WIN32_WINNT
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
3001002
|
3002000
|
||||||
|
|
|
@ -34,6 +34,7 @@ SET(libarchive_SOURCES
|
||||||
archive_entry_strmode.c
|
archive_entry_strmode.c
|
||||||
archive_entry_xattr.c
|
archive_entry_xattr.c
|
||||||
archive_getdate.c
|
archive_getdate.c
|
||||||
|
archive_getdate.h
|
||||||
archive_hmac.c
|
archive_hmac.c
|
||||||
archive_hmac_private.h
|
archive_hmac_private.h
|
||||||
archive_match.c
|
archive_match.c
|
||||||
|
|
|
@ -36,11 +36,12 @@
|
||||||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||||
*/
|
*/
|
||||||
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
||||||
#define ARCHIVE_VERSION_NUMBER 3001002
|
#define ARCHIVE_VERSION_NUMBER 3002000
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stddef.h> /* for wchar_t */
|
#include <stddef.h> /* for wchar_t */
|
||||||
#include <stdio.h> /* For FILE * */
|
#include <stdio.h> /* For FILE * */
|
||||||
|
#include <time.h> /* For time_t */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: archive.h is for use outside of libarchive; the configuration
|
* Note: archive.h is for use outside of libarchive; the configuration
|
||||||
|
@ -95,6 +96,11 @@ typedef ssize_t la_ssize_t;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Large file support for Android */
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include "android_lf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On Windows, define LIBARCHIVE_STATIC if you're building or using a
|
* On Windows, define LIBARCHIVE_STATIC if you're building or using a
|
||||||
* .lib. The default here assumes you're building a DLL. Only
|
* .lib. The default here assumes you're building a DLL. Only
|
||||||
|
@ -146,7 +152,7 @@ __LA_DECL int archive_version_number(void);
|
||||||
/*
|
/*
|
||||||
* Textual name/version of the library, useful for version displays.
|
* Textual name/version of the library, useful for version displays.
|
||||||
*/
|
*/
|
||||||
#define ARCHIVE_VERSION_ONLY_STRING "3.1.2"
|
#define ARCHIVE_VERSION_ONLY_STRING "3.2.0"
|
||||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||||
__LA_DECL const char * archive_version_string(void);
|
__LA_DECL const char * archive_version_string(void);
|
||||||
|
|
||||||
|
@ -159,6 +165,16 @@ __LA_DECL const char * archive_version_string(void);
|
||||||
*/
|
*/
|
||||||
__LA_DECL const char * archive_version_details(void);
|
__LA_DECL const char * archive_version_details(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns NULL if libarchive was compiled without the associated library.
|
||||||
|
* Otherwise, returns the version number that libarchive was compiled
|
||||||
|
* against.
|
||||||
|
*/
|
||||||
|
__LA_DECL const char * archive_zlib_version(void);
|
||||||
|
__LA_DECL const char * archive_liblzma_version(void);
|
||||||
|
__LA_DECL const char * archive_bzlib_version(void);
|
||||||
|
__LA_DECL const char * archive_liblz4_version(void);
|
||||||
|
|
||||||
/* Declare our basic types. */
|
/* Declare our basic types. */
|
||||||
struct archive;
|
struct archive;
|
||||||
struct archive_entry;
|
struct archive_entry;
|
||||||
|
|
|
@ -31,6 +31,19 @@
|
||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
#include "archive_cryptor_private.h"
|
#include "archive_cryptor_private.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On systems that do not support any recognized crypto libraries,
|
||||||
|
* this file will normally define no usable symbols.
|
||||||
|
*
|
||||||
|
* But some compilers and linkers choke on empty object files, so
|
||||||
|
* define a public symbol that will always exist. This could
|
||||||
|
* be removed someday if this file gains another always-present
|
||||||
|
* symbol definition.
|
||||||
|
*/
|
||||||
|
int __libarchive_cryptor_build_hack(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
|
#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -256,7 +269,7 @@ aes_ctr_release(archive_crypto_ctx *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(HAVE_LIBNETTLE)
|
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||||
|
|
|
@ -30,6 +30,17 @@
|
||||||
#ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
|
#ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
|
||||||
#define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
|
#define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On systems that do not support any recognized crypto libraries,
|
||||||
|
* the archive_cryptor.c file will normally define no usable symbols.
|
||||||
|
*
|
||||||
|
* But some compilers and linkers choke on empty object files, so
|
||||||
|
* define a public symbol that will always exist. This could
|
||||||
|
* be removed someday if this file gains another always-present
|
||||||
|
* symbol definition.
|
||||||
|
*/
|
||||||
|
int __libarchive_cryptor_build_hack(void);
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# include <AvailabilityMacros.h>
|
# include <AvailabilityMacros.h>
|
||||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||||
|
@ -72,7 +83,7 @@ typedef struct {
|
||||||
unsigned encr_pos;
|
unsigned encr_pos;
|
||||||
} archive_crypto_ctx;
|
} archive_crypto_ctx;
|
||||||
|
|
||||||
#elif defined(HAVE_LIBNETTLE)
|
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
|
||||||
#if defined(HAVE_NETTLE_PBKDF2_H)
|
#if defined(HAVE_NETTLE_PBKDF2_H)
|
||||||
#include <nettle/pbkdf2.h>
|
#include <nettle/pbkdf2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||||
|
|
||||||
/* Note: Compiler will complain if this does not match archive.h! */
|
/* Note: Compiler will complain if this does not match archive.h! */
|
||||||
#define ARCHIVE_VERSION_NUMBER 3001002
|
#define ARCHIVE_VERSION_NUMBER 3002000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: archive_entry.h is for use outside of libarchive; the
|
* Note: archive_entry.h is for use outside of libarchive; the
|
||||||
|
@ -75,6 +75,11 @@ typedef int64_t la_int64_t;
|
||||||
# define __LA_MODE_T mode_t
|
# define __LA_MODE_T mode_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Large file support for Android */
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include "android_lf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On Windows, define LIBARCHIVE_STATIC if you're building or using a
|
* On Windows, define LIBARCHIVE_STATIC if you're building or using a
|
||||||
* .lib. The default here assumes you're building a DLL. Only
|
* .lib. The default here assumes you're building a DLL. Only
|
||||||
|
|
|
@ -44,6 +44,10 @@ archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st)
|
||||||
archive_entry_set_atime(entry, st->st_atime, st->st_atim.tv_nsec);
|
archive_entry_set_atime(entry, st->st_atime, st->st_atim.tv_nsec);
|
||||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctim.tv_nsec);
|
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctim.tv_nsec);
|
||||||
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtim.tv_nsec);
|
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtim.tv_nsec);
|
||||||
|
#elif HAVE_STRUCT_STAT_ST_MTIME_NSEC
|
||||||
|
archive_entry_set_atime(entry, st->st_atime, st->st_atime_nsec);
|
||||||
|
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_nsec);
|
||||||
|
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_nsec);
|
||||||
#elif HAVE_STRUCT_STAT_ST_MTIME_N
|
#elif HAVE_STRUCT_STAT_ST_MTIME_N
|
||||||
archive_entry_set_atime(entry, st->st_atime, st->st_atime_n);
|
archive_entry_set_atime(entry, st->st_atime, st->st_atime_n);
|
||||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_n);
|
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_n);
|
||||||
|
|
|
@ -38,8 +38,8 @@ __FBSDID("$FreeBSD$");
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
/* This file defines a single public function. */
|
#define __LIBARCHIVE_BUILD 1
|
||||||
time_t __archive_get_date(time_t now, const char *);
|
#include "archive_getdate.h"
|
||||||
|
|
||||||
/* Basic time units. */
|
/* Basic time units. */
|
||||||
#define EPOCH 1970
|
#define EPOCH 1970
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2003-2015 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_GETDATE_H_INCLUDED
|
||||||
|
#define ARCHIVE_GETDATE_H_INCLUDED
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
time_t __archive_get_date(time_t now, const char *);
|
||||||
|
|
||||||
|
#endif
|
|
@ -31,6 +31,20 @@
|
||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
#include "archive_hmac_private.h"
|
#include "archive_hmac_private.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On systems that do not support any recognized crypto libraries,
|
||||||
|
* the archive_hmac.c file is expected to define no usable symbols.
|
||||||
|
*
|
||||||
|
* But some compilers and linkers choke on empty object files, so
|
||||||
|
* define a public symbol that will always exist. This could
|
||||||
|
* be removed someday if this file gains another always-present
|
||||||
|
* symbol definition.
|
||||||
|
*/
|
||||||
|
int __libarchive_hmac_build_hack(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto
|
#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -129,7 +143,7 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(HAVE_LIBNETTLE)
|
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||||
|
|
|
@ -30,6 +30,17 @@
|
||||||
#ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED
|
#ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED
|
||||||
#define ARCHIVE_HMAC_PRIVATE_H_INCLUDED
|
#define ARCHIVE_HMAC_PRIVATE_H_INCLUDED
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On systems that do not support any recognized crypto libraries,
|
||||||
|
* the archive_hmac.c file is expected to define no usable symbols.
|
||||||
|
*
|
||||||
|
* But some compilers and linkers choke on empty object files, so
|
||||||
|
* define a public symbol that will always exist. This could
|
||||||
|
* be removed someday if this file gains another always-present
|
||||||
|
* symbol definition.
|
||||||
|
*/
|
||||||
|
int __libarchive_hmac_build_hack(void);
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# include <AvailabilityMacros.h>
|
# include <AvailabilityMacros.h>
|
||||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||||
|
@ -53,7 +64,7 @@ typedef struct {
|
||||||
|
|
||||||
} archive_hmac_sha1_ctx;
|
} archive_hmac_sha1_ctx;
|
||||||
|
|
||||||
#elif defined(HAVE_LIBNETTLE)
|
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
|
||||||
#include <nettle/hmac.h>
|
#include <nettle/hmac.h>
|
||||||
|
|
||||||
typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
|
typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
|
||||||
|
|
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
#include "archive_private.h"
|
#include "archive_private.h"
|
||||||
#include "archive_entry.h"
|
#include "archive_entry.h"
|
||||||
|
#include "archive_getdate.h"
|
||||||
#include "archive_pathmatch.h"
|
#include "archive_pathmatch.h"
|
||||||
#include "archive_rb.h"
|
#include "archive_rb.h"
|
||||||
#include "archive_string.h"
|
#include "archive_string.h"
|
||||||
|
@ -184,7 +185,6 @@ static int time_excluded(struct archive_match *,
|
||||||
struct archive_entry *);
|
struct archive_entry *);
|
||||||
static int validate_time_flag(struct archive *, int, const char *);
|
static int validate_time_flag(struct archive *, int, const char *);
|
||||||
|
|
||||||
time_t __archive_get_date(time_t now, const char *);
|
|
||||||
#define get_date __archive_get_date
|
#define get_date __archive_get_date
|
||||||
|
|
||||||
static const struct archive_rb_tree_ops rb_ops_mbs = {
|
static const struct archive_rb_tree_ops rb_ops_mbs = {
|
||||||
|
|
|
@ -42,9 +42,9 @@ _archive_set_option(struct archive *a,
|
||||||
|
|
||||||
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
|
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
|
||||||
|
|
||||||
mp = m != NULL && m[0] != '\0' ? m : NULL;
|
mp = (m != NULL && m[0] != '\0') ? m : NULL;
|
||||||
op = o != NULL && o[0] != '\0' ? o : NULL;
|
op = (o != NULL && o[0] != '\0') ? o : NULL;
|
||||||
vp = v != NULL && v[0] != '\0' ? v : NULL;
|
vp = (v != NULL && v[0] != '\0') ? v : NULL;
|
||||||
|
|
||||||
if (op == NULL && vp == NULL)
|
if (op == NULL && vp == NULL)
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
|
|
|
@ -122,6 +122,12 @@
|
||||||
#if !HAVE_DECL_UINT32_MAX
|
#if !HAVE_DECL_UINT32_MAX
|
||||||
#define UINT32_MAX (~(uint32_t)0)
|
#define UINT32_MAX (~(uint32_t)0)
|
||||||
#endif
|
#endif
|
||||||
|
#if !HAVE_DECL_INT32_MAX
|
||||||
|
#define INT32_MAX ((int32_t)(UINT32_MAX >> 1))
|
||||||
|
#endif
|
||||||
|
#if !HAVE_DECL_INT32_MIN
|
||||||
|
#define INT32_MIN ((int32_t)(~INT32_MAX))
|
||||||
|
#endif
|
||||||
#if !HAVE_DECL_UINT64_MAX
|
#if !HAVE_DECL_UINT64_MAX
|
||||||
#define UINT64_MAX (~(uint64_t)0)
|
#define UINT64_MAX (~(uint64_t)0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -131,6 +137,15 @@
|
||||||
#if !HAVE_DECL_INT64_MIN
|
#if !HAVE_DECL_INT64_MIN
|
||||||
#define INT64_MIN ((int64_t)(~INT64_MAX))
|
#define INT64_MIN ((int64_t)(~INT64_MAX))
|
||||||
#endif
|
#endif
|
||||||
|
#if !HAVE_DECL_UINTMAX_MAX
|
||||||
|
#define UINTMAX_MAX (~(uintmax_t)0)
|
||||||
|
#endif
|
||||||
|
#if !HAVE_DECL_INTMAX_MAX
|
||||||
|
#define INTMAX_MAX ((intmax_t)(UINTMAX_MAX >> 1))
|
||||||
|
#endif
|
||||||
|
#if !HAVE_DECL_INTMAX_MIN
|
||||||
|
#define INTMAX_MIN ((intmax_t)(~INTMAX_MAX))
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
|
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
|
||||||
|
|
|
@ -547,16 +547,20 @@ archive_read_open1(struct archive *_a)
|
||||||
* it wants to handle this stream. Repeat until we've finished
|
* it wants to handle this stream. Repeat until we've finished
|
||||||
* building the pipeline.
|
* building the pipeline.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* We won't build a filter pipeline with more stages than this. */
|
||||||
|
#define MAX_NUMBER_FILTERS 25
|
||||||
|
|
||||||
static int
|
static int
|
||||||
choose_filters(struct archive_read *a)
|
choose_filters(struct archive_read *a)
|
||||||
{
|
{
|
||||||
int number_bidders, i, bid, best_bid, n;
|
int number_bidders, i, bid, best_bid, number_filters;
|
||||||
struct archive_read_filter_bidder *bidder, *best_bidder;
|
struct archive_read_filter_bidder *bidder, *best_bidder;
|
||||||
struct archive_read_filter *filter;
|
struct archive_read_filter *filter;
|
||||||
ssize_t avail;
|
ssize_t avail;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
for (n = 0; n < 25; ++n) {
|
for (number_filters = 0; number_filters < MAX_NUMBER_FILTERS; ++number_filters) {
|
||||||
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
|
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
|
||||||
|
|
||||||
best_bid = 0;
|
best_bid = 0;
|
||||||
|
|
|
@ -1046,7 +1046,7 @@ setup_sparse(struct archive_read_disk *a,
|
||||||
struct fiemap *fm;
|
struct fiemap *fm;
|
||||||
struct fiemap_extent *fe;
|
struct fiemap_extent *fe;
|
||||||
int64_t size;
|
int64_t size;
|
||||||
int count, do_fiemap;
|
int count, do_fiemap, iters;
|
||||||
int exit_sts = ARCHIVE_OK;
|
int exit_sts = ARCHIVE_OK;
|
||||||
|
|
||||||
if (archive_entry_filetype(entry) != AE_IFREG
|
if (archive_entry_filetype(entry) != AE_IFREG
|
||||||
|
@ -1083,7 +1083,7 @@ setup_sparse(struct archive_read_disk *a,
|
||||||
fm->fm_extent_count = count;
|
fm->fm_extent_count = count;
|
||||||
do_fiemap = 1;
|
do_fiemap = 1;
|
||||||
size = archive_entry_size(entry);
|
size = archive_entry_size(entry);
|
||||||
for (;;) {
|
for (iters = 0; ; ++iters) {
|
||||||
int i, r;
|
int i, r;
|
||||||
|
|
||||||
r = ioctl(*fd, FS_IOC_FIEMAP, fm);
|
r = ioctl(*fd, FS_IOC_FIEMAP, fm);
|
||||||
|
@ -1093,8 +1093,13 @@ setup_sparse(struct archive_read_disk *a,
|
||||||
* version(<2.6.28) cannot perfom FS_IOC_FIEMAP. */
|
* version(<2.6.28) cannot perfom FS_IOC_FIEMAP. */
|
||||||
goto exit_setup_sparse;
|
goto exit_setup_sparse;
|
||||||
}
|
}
|
||||||
if (fm->fm_mapped_extents == 0)
|
if (fm->fm_mapped_extents == 0) {
|
||||||
|
if (iters == 0) {
|
||||||
|
/* Fully sparse file; insert a zero-length "data" entry */
|
||||||
|
archive_entry_sparse_add_entry(entry, 0, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
fe = fm->fm_extents;
|
fe = fm->fm_extents;
|
||||||
for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) {
|
for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) {
|
||||||
if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
|
if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
|
||||||
|
@ -1139,6 +1144,7 @@ setup_sparse(struct archive_read_disk *a,
|
||||||
off_t initial_off; /* FreeBSD/Solaris only, so off_t okay here */
|
off_t initial_off; /* FreeBSD/Solaris only, so off_t okay here */
|
||||||
off_t off_s, off_e; /* FreeBSD/Solaris only, so off_t okay here */
|
off_t off_s, off_e; /* FreeBSD/Solaris only, so off_t okay here */
|
||||||
int exit_sts = ARCHIVE_OK;
|
int exit_sts = ARCHIVE_OK;
|
||||||
|
int check_fully_sparse = 0;
|
||||||
|
|
||||||
if (archive_entry_filetype(entry) != AE_IFREG
|
if (archive_entry_filetype(entry) != AE_IFREG
|
||||||
|| archive_entry_size(entry) <= 0
|
|| archive_entry_size(entry) <= 0
|
||||||
|
@ -1191,8 +1197,14 @@ setup_sparse(struct archive_read_disk *a,
|
||||||
while (off_s < size) {
|
while (off_s < size) {
|
||||||
off_s = lseek(*fd, off_s, SEEK_DATA);
|
off_s = lseek(*fd, off_s, SEEK_DATA);
|
||||||
if (off_s == (off_t)-1) {
|
if (off_s == (off_t)-1) {
|
||||||
if (errno == ENXIO)
|
if (errno == ENXIO) {
|
||||||
break;/* no more hole */
|
/* no more hole */
|
||||||
|
if (archive_entry_sparse_count(entry) == 0) {
|
||||||
|
/* Potentially a fully-sparse file. */
|
||||||
|
check_fully_sparse = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
archive_set_error(&a->archive, errno,
|
archive_set_error(&a->archive, errno,
|
||||||
"lseek(SEEK_HOLE) failed");
|
"lseek(SEEK_HOLE) failed");
|
||||||
exit_sts = ARCHIVE_FAILED;
|
exit_sts = ARCHIVE_FAILED;
|
||||||
|
@ -1216,6 +1228,14 @@ setup_sparse(struct archive_read_disk *a,
|
||||||
off_e - off_s);
|
off_e - off_s);
|
||||||
off_s = off_e;
|
off_s = off_e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (check_fully_sparse) {
|
||||||
|
if (lseek(*fd, 0, SEEK_HOLE) == 0 &&
|
||||||
|
lseek(*fd, 0, SEEK_END) == size) {
|
||||||
|
/* Fully sparse file; insert a zero-length "data" entry */
|
||||||
|
archive_entry_sparse_add_entry(entry, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
exit_setup_sparse:
|
exit_setup_sparse:
|
||||||
lseek(*fd, initial_off, SEEK_SET);
|
lseek(*fd, initial_off, SEEK_SET);
|
||||||
return (exit_sts);
|
return (exit_sts);
|
||||||
|
|
|
@ -717,6 +717,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||||
int r;
|
int r;
|
||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
size_t buffbytes;
|
size_t buffbytes;
|
||||||
|
int empty_sparse_region = 0;
|
||||||
|
|
||||||
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
|
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
|
||||||
"archive_read_data_block");
|
"archive_read_data_block");
|
||||||
|
@ -798,6 +799,9 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||||
if ((int64_t)buffbytes > t->current_sparse->length)
|
if ((int64_t)buffbytes > t->current_sparse->length)
|
||||||
buffbytes = t->current_sparse->length;
|
buffbytes = t->current_sparse->length;
|
||||||
|
|
||||||
|
if (t->current_sparse->length == 0)
|
||||||
|
empty_sparse_region = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip hole.
|
* Skip hole.
|
||||||
* TODO: Should we consider t->current_filesystem->xfer_align?
|
* TODO: Should we consider t->current_filesystem->xfer_align?
|
||||||
|
@ -828,7 +832,11 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
if (bytes == 0) {
|
/*
|
||||||
|
* Return an EOF unless we've read a leading empty sparse region, which
|
||||||
|
* is used to represent fully-sparse files.
|
||||||
|
*/
|
||||||
|
if (bytes == 0 && !empty_sparse_region) {
|
||||||
/* Get EOF */
|
/* Get EOF */
|
||||||
t->entry_eof = 1;
|
t->entry_eof = 1;
|
||||||
r = ARCHIVE_EOF;
|
r = ARCHIVE_EOF;
|
||||||
|
@ -1576,6 +1584,7 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||||
#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
|
#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
|
||||||
t->current_filesystem->name_max = sfs.f_namemax;
|
t->current_filesystem->name_max = sfs.f_namemax;
|
||||||
#else
|
#else
|
||||||
|
# if defined(_PC_NAME_MAX)
|
||||||
/* Mac OS X does not have f_namemax in struct statfs. */
|
/* Mac OS X does not have f_namemax in struct statfs. */
|
||||||
if (tree_current_is_symblic_link_target(t)) {
|
if (tree_current_is_symblic_link_target(t)) {
|
||||||
if (tree_enter_working_dir(t) != 0) {
|
if (tree_enter_working_dir(t) != 0) {
|
||||||
|
@ -1585,6 +1594,9 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||||
nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
|
nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
|
||||||
} else
|
} else
|
||||||
nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
|
nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
|
||||||
|
# else
|
||||||
|
nm = -1;
|
||||||
|
# endif
|
||||||
if (nm == -1)
|
if (nm == -1)
|
||||||
t->current_filesystem->name_max = NAME_MAX;
|
t->current_filesystem->name_max = NAME_MAX;
|
||||||
else
|
else
|
||||||
|
@ -1681,7 +1693,9 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||||
{
|
{
|
||||||
struct tree *t = a->tree;
|
struct tree *t = a->tree;
|
||||||
struct statfs sfs;
|
struct statfs sfs;
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
struct statvfs svfs;
|
struct statvfs svfs;
|
||||||
|
#endif
|
||||||
int r, vr = 0, xr = 0;
|
int r, vr = 0, xr = 0;
|
||||||
|
|
||||||
if (tree_current_is_symblic_link_target(t)) {
|
if (tree_current_is_symblic_link_target(t)) {
|
||||||
|
@ -1698,7 +1712,9 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||||
"openat failed");
|
"openat failed");
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
}
|
}
|
||||||
|
#if defined(HAVE_FSTATVFS)
|
||||||
vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */
|
vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */
|
||||||
|
#endif
|
||||||
r = fstatfs(fd, &sfs);
|
r = fstatfs(fd, &sfs);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
xr = get_xfer_size(t, fd, NULL);
|
xr = get_xfer_size(t, fd, NULL);
|
||||||
|
@ -1708,14 +1724,18 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||||
archive_set_error(&a->archive, errno, "fchdir failed");
|
archive_set_error(&a->archive, errno, "fchdir failed");
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
}
|
}
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
vr = statvfs(tree_current_access_path(t), &svfs);
|
vr = statvfs(tree_current_access_path(t), &svfs);
|
||||||
|
#endif
|
||||||
r = statfs(tree_current_access_path(t), &sfs);
|
r = statfs(tree_current_access_path(t), &sfs);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
xr = get_xfer_size(t, -1, tree_current_access_path(t));
|
xr = get_xfer_size(t, -1, tree_current_access_path(t));
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef HAVE_FSTATFS
|
#ifdef HAVE_FSTATFS
|
||||||
|
#if defined(HAVE_FSTATVFS)
|
||||||
vr = fstatvfs(tree_current_dir_fd(t), &svfs);
|
vr = fstatvfs(tree_current_dir_fd(t), &svfs);
|
||||||
|
#endif
|
||||||
r = fstatfs(tree_current_dir_fd(t), &sfs);
|
r = fstatfs(tree_current_dir_fd(t), &sfs);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
|
xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
|
||||||
|
@ -1724,7 +1744,9 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||||
archive_set_error(&a->archive, errno, "fchdir failed");
|
archive_set_error(&a->archive, errno, "fchdir failed");
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
}
|
}
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
vr = statvfs(".", &svfs);
|
vr = statvfs(".", &svfs);
|
||||||
|
#endif
|
||||||
r = statfs(".", &sfs);
|
r = statfs(".", &sfs);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
xr = get_xfer_size(t, -1, ".");
|
xr = get_xfer_size(t, -1, ".");
|
||||||
|
@ -1737,10 +1759,17 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
} else if (xr == 1) {
|
} else if (xr == 1) {
|
||||||
/* pathconf(_PC_REX_*) operations are not supported. */
|
/* pathconf(_PC_REX_*) operations are not supported. */
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
t->current_filesystem->xfer_align = svfs.f_frsize;
|
t->current_filesystem->xfer_align = svfs.f_frsize;
|
||||||
t->current_filesystem->max_xfer_size = -1;
|
t->current_filesystem->max_xfer_size = -1;
|
||||||
t->current_filesystem->min_xfer_size = svfs.f_bsize;
|
t->current_filesystem->min_xfer_size = svfs.f_bsize;
|
||||||
t->current_filesystem->incr_xfer_size = svfs.f_bsize;
|
t->current_filesystem->incr_xfer_size = svfs.f_bsize;
|
||||||
|
#else
|
||||||
|
t->current_filesystem->xfer_align = sfs.f_frsize;
|
||||||
|
t->current_filesystem->max_xfer_size = -1;
|
||||||
|
t->current_filesystem->min_xfer_size = sfs.f_bsize;
|
||||||
|
t->current_filesystem->incr_xfer_size = sfs.f_bsize;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
switch (sfs.f_type) {
|
switch (sfs.f_type) {
|
||||||
case AFS_SUPER_MAGIC:
|
case AFS_SUPER_MAGIC:
|
||||||
|
@ -1765,7 +1794,11 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ST_NOATIME)
|
#if defined(ST_NOATIME)
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
if (svfs.f_flag & ST_NOATIME)
|
if (svfs.f_flag & ST_NOATIME)
|
||||||
|
#else
|
||||||
|
if (sfs.f_flag & ST_NOATIME)
|
||||||
|
#endif
|
||||||
t->current_filesystem->noatime = 1;
|
t->current_filesystem->noatime = 1;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -53,8 +53,12 @@ Streaming Archive Library (libarchive, -larchive)
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_read_support_filter_compress "struct archive *"
|
.Fn archive_read_support_filter_compress "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn archive_read_support_filter_grzip "struct archive *"
|
||||||
|
.Ft int
|
||||||
.Fn archive_read_support_filter_gzip "struct archive *"
|
.Fn archive_read_support_filter_gzip "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn archive_read_support_filter_lrzip "struct archive *"
|
||||||
|
.Ft int
|
||||||
.Fn archive_read_support_filter_lz4 "struct archive *"
|
.Fn archive_read_support_filter_lz4 "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_read_support_filter_lzma "struct archive *"
|
.Fn archive_read_support_filter_lzma "struct archive *"
|
||||||
|
@ -86,7 +90,9 @@ Streaming Archive Library (libarchive, -larchive)
|
||||||
.It Xo
|
.It Xo
|
||||||
.Fn archive_read_support_filter_bzip2 ,
|
.Fn archive_read_support_filter_bzip2 ,
|
||||||
.Fn archive_read_support_filter_compress ,
|
.Fn archive_read_support_filter_compress ,
|
||||||
|
.Fn archive_read_support_filter_grzip ,
|
||||||
.Fn archive_read_support_filter_gzip ,
|
.Fn archive_read_support_filter_gzip ,
|
||||||
|
.Fn archive_read_support_filter_lrzip ,
|
||||||
.Fn archive_read_support_filter_lz4 ,
|
.Fn archive_read_support_filter_lz4 ,
|
||||||
.Fn archive_read_support_filter_lzma ,
|
.Fn archive_read_support_filter_lzma ,
|
||||||
.Fn archive_read_support_filter_lzop ,
|
.Fn archive_read_support_filter_lzop ,
|
||||||
|
|
|
@ -83,8 +83,9 @@ archive_read_open_FILE(struct archive *a, FILE *f)
|
||||||
mine->f = f;
|
mine->f = f;
|
||||||
/*
|
/*
|
||||||
* If we can't fstat() the file, it may just be that it's not
|
* If we can't fstat() the file, it may just be that it's not
|
||||||
* a file. (FILE * objects can wrap many kinds of I/O
|
* a file. (On some platforms, FILE * objects can wrap I/O
|
||||||
* streams, some of which don't support fileno()).)
|
* streams that don't support fileno()). As a result, fileno()
|
||||||
|
* should be used cautiously.)
|
||||||
*/
|
*/
|
||||||
if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
|
if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
|
||||||
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
|
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
|
||||||
|
@ -150,7 +151,10 @@ file_skip(struct archive *a, void *client_data, int64_t request)
|
||||||
skip = max_skip;
|
skip = max_skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_FSEEKO
|
#ifdef __ANDROID__
|
||||||
|
/* fileno() isn't safe on all platforms ... see above. */
|
||||||
|
if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
|
||||||
|
#elif HAVE_FSEEKO
|
||||||
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
|
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
|
||||||
#elif HAVE__FSEEKI64
|
#elif HAVE__FSEEKI64
|
||||||
if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
|
if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
|
||||||
|
|
|
@ -178,7 +178,7 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* POSIX system does not support a wchar_t interface for
|
* POSIX system does not support a wchar_t interface for
|
||||||
* open() system call, so we have to translate a whcar_t
|
* open() system call, so we have to translate a wchar_t
|
||||||
* filename to multi-byte one and use it.
|
* filename to multi-byte one and use it.
|
||||||
*/
|
*/
|
||||||
struct archive_string fn;
|
struct archive_string fn;
|
||||||
|
|
|
@ -580,10 +580,19 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
|
||||||
prefix64k);
|
prefix64k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
|
||||||
|
uncompressed_size = LZ4_decompress_safe_usingDict(
|
||||||
|
read_buf + 4,
|
||||||
|
state->out_block + prefix64k, (int)compressed_size,
|
||||||
|
state->flags.block_maximum_size,
|
||||||
|
state->out_block,
|
||||||
|
prefix64k);
|
||||||
|
#else
|
||||||
uncompressed_size = LZ4_decompress_safe_withPrefix64k(
|
uncompressed_size = LZ4_decompress_safe_withPrefix64k(
|
||||||
read_buf + 4,
|
read_buf + 4,
|
||||||
state->out_block + prefix64k, (int)compressed_size,
|
state->out_block + prefix64k, (int)compressed_size,
|
||||||
state->flags.block_maximum_size);
|
state->flags.block_maximum_size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if an error happend in decompression process. */
|
/* Check if an error happend in decompression process. */
|
||||||
|
|
|
@ -148,9 +148,12 @@ get_time_t_max(void)
|
||||||
return (~(time_t)0);
|
return (~(time_t)0);
|
||||||
} else {
|
} else {
|
||||||
/* Time_t is signed. */
|
/* Time_t is signed. */
|
||||||
const uintmax_t max_unsigned_time_t = (uintmax_t)(~(time_t)0);
|
/* Assume it's the same as int64_t or int32_t */
|
||||||
const uintmax_t max_signed_time_t = max_unsigned_time_t >> 1;
|
if (sizeof(time_t) == sizeof(int64_t)) {
|
||||||
return (time_t)max_signed_time_t;
|
return (time_t)INT64_MAX;
|
||||||
|
} else {
|
||||||
|
return (time_t)INT32_MAX;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -166,10 +169,11 @@ get_time_t_min(void)
|
||||||
return (time_t)0;
|
return (time_t)0;
|
||||||
} else {
|
} else {
|
||||||
/* Time_t is signed. */
|
/* Time_t is signed. */
|
||||||
const uintmax_t max_unsigned_time_t = (uintmax_t)(~(time_t)0);
|
if (sizeof(time_t) == sizeof(int64_t)) {
|
||||||
const uintmax_t max_signed_time_t = max_unsigned_time_t >> 1;
|
return (time_t)INT64_MIN;
|
||||||
const intmax_t min_signed_time_t = (intmax_t)~max_signed_time_t;
|
} else {
|
||||||
return (time_t)min_signed_time_t;
|
return (time_t)INT32_MIN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -852,8 +856,8 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
|
||||||
struct mtree_entry *entry;
|
struct mtree_entry *entry;
|
||||||
struct mtree_option *iter;
|
struct mtree_option *iter;
|
||||||
const char *next, *eq, *name, *end;
|
const char *next, *eq, *name, *end;
|
||||||
size_t len;
|
size_t name_len, len;
|
||||||
int r;
|
int r, i;
|
||||||
|
|
||||||
if ((entry = malloc(sizeof(*entry))) == NULL) {
|
if ((entry = malloc(sizeof(*entry))) == NULL) {
|
||||||
archive_set_error(&a->archive, errno, "Can't allocate memory");
|
archive_set_error(&a->archive, errno, "Can't allocate memory");
|
||||||
|
@ -873,43 +877,48 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
|
||||||
*last_entry = entry;
|
*last_entry = entry;
|
||||||
|
|
||||||
if (is_form_d) {
|
if (is_form_d) {
|
||||||
/*
|
/* Filename is last item on line. */
|
||||||
* This form places the file name as last parameter.
|
/* Adjust line_len to trim trailing whitespace */
|
||||||
*/
|
|
||||||
name = line + line_len -1;
|
|
||||||
while (line_len > 0) {
|
while (line_len > 0) {
|
||||||
if (*name != '\r' && *name != '\n' &&
|
char last_character = line[line_len - 1];
|
||||||
*name != '\t' && *name != ' ')
|
if (last_character == '\r'
|
||||||
break;
|
|| last_character == '\n'
|
||||||
name--;
|
|| last_character == '\t'
|
||||||
line_len--;
|
|| last_character == ' ') {
|
||||||
}
|
line_len--;
|
||||||
len = 0;
|
} else {
|
||||||
while (line_len > 0) {
|
|
||||||
if (*name == '\r' || *name == '\n' ||
|
|
||||||
*name == '\t' || *name == ' ') {
|
|
||||||
name++;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
name--;
|
|
||||||
line_len--;
|
|
||||||
len++;
|
|
||||||
}
|
}
|
||||||
|
/* Name starts after the last whitespace separator */
|
||||||
|
name = line;
|
||||||
|
for (i = 0; i < line_len; i++) {
|
||||||
|
if (line[i] == '\r'
|
||||||
|
|| line[i] == '\n'
|
||||||
|
|| line[i] == '\t'
|
||||||
|
|| line[i] == ' ') {
|
||||||
|
name = line + i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name_len = line + line_len - name;
|
||||||
end = name;
|
end = name;
|
||||||
} else {
|
} else {
|
||||||
len = strcspn(line, " \t\r\n");
|
/* Filename is first item on line */
|
||||||
|
name_len = strcspn(line, " \t\r\n");
|
||||||
name = line;
|
name = line;
|
||||||
line += len;
|
line += name_len;
|
||||||
end = line + line_len;
|
end = line + line_len;
|
||||||
}
|
}
|
||||||
|
/* name/name_len is the name within the line. */
|
||||||
|
/* line..end brackets the entire line except the name */
|
||||||
|
|
||||||
if ((entry->name = malloc(len + 1)) == NULL) {
|
if ((entry->name = malloc(name_len + 1)) == NULL) {
|
||||||
archive_set_error(&a->archive, errno, "Can't allocate memory");
|
archive_set_error(&a->archive, errno, "Can't allocate memory");
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(entry->name, name, len);
|
memcpy(entry->name, name, name_len);
|
||||||
entry->name[len] = '\0';
|
entry->name[name_len] = '\0';
|
||||||
parse_escapes(entry->name, entry);
|
parse_escapes(entry->name, entry);
|
||||||
|
|
||||||
for (iter = *global; iter != NULL; iter = iter->next) {
|
for (iter = *global; iter != NULL; iter = iter->next) {
|
||||||
|
@ -1561,7 +1570,7 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||||
int64_t m;
|
int64_t m;
|
||||||
int64_t my_time_t_max = get_time_t_max();
|
int64_t my_time_t_max = get_time_t_max();
|
||||||
int64_t my_time_t_min = get_time_t_min();
|
int64_t my_time_t_min = get_time_t_min();
|
||||||
long ns;
|
long ns = 0;
|
||||||
|
|
||||||
*parsed_kws |= MTREE_HAS_MTIME;
|
*parsed_kws |= MTREE_HAS_MTIME;
|
||||||
m = mtree_atol10(&val);
|
m = mtree_atol10(&val);
|
||||||
|
|
|
@ -828,6 +828,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
||||||
char head_type;
|
char head_type;
|
||||||
int ret;
|
int ret;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
unsigned long crc32_expected;
|
||||||
|
|
||||||
a->archive.archive_format = ARCHIVE_FORMAT_RAR;
|
a->archive.archive_format = ARCHIVE_FORMAT_RAR;
|
||||||
if (a->archive.archive_format_name == NULL)
|
if (a->archive.archive_format_name == NULL)
|
||||||
|
@ -940,36 +941,50 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
||||||
skip = archive_le16dec(p + 5);
|
skip = archive_le16dec(p + 5);
|
||||||
if (skip < 7) {
|
if (skip < 7) {
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
"Invalid header size");
|
"Invalid header size too small");
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
if (skip > 7) {
|
|
||||||
if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
|
|
||||||
return (ARCHIVE_FATAL);
|
|
||||||
p = h;
|
|
||||||
}
|
|
||||||
if (flags & HD_ADD_SIZE_PRESENT)
|
if (flags & HD_ADD_SIZE_PRESENT)
|
||||||
{
|
{
|
||||||
if (skip < 7 + 4) {
|
if (skip < 7 + 4) {
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
"Invalid header size");
|
"Invalid header size too small");
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
skip += archive_le32dec(p + 7);
|
|
||||||
if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
|
if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
p = h;
|
p = h;
|
||||||
|
skip += archive_le32dec(p + 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2);
|
/* Skip over the 2-byte CRC at the beginning of the header. */
|
||||||
if ((crc32_val & 0xffff) != archive_le16dec(p)) {
|
crc32_expected = archive_le16dec(p);
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
__archive_read_consume(a, 2);
|
||||||
"Header CRC error");
|
skip -= 2;
|
||||||
return (ARCHIVE_FATAL);
|
|
||||||
|
/* Skim the entire header and compute the CRC. */
|
||||||
|
crc32_val = 0;
|
||||||
|
while (skip > 0) {
|
||||||
|
size_t to_read = skip;
|
||||||
|
ssize_t did_read;
|
||||||
|
if (to_read > 32 * 1024) {
|
||||||
|
to_read = 32 * 1024;
|
||||||
|
}
|
||||||
|
if ((h = __archive_read_ahead(a, to_read, &did_read)) == NULL) {
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
}
|
||||||
|
p = h;
|
||||||
|
crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned)did_read);
|
||||||
|
__archive_read_consume(a, did_read);
|
||||||
|
skip -= did_read;
|
||||||
|
}
|
||||||
|
if ((crc32_val & 0xffff) != crc32_expected) {
|
||||||
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
|
"Header CRC error");
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
__archive_read_consume(a, skip);
|
|
||||||
if (head_type == ENDARC_HEAD)
|
if (head_type == ENDARC_HEAD)
|
||||||
return (ARCHIVE_EOF);
|
return (ARCHIVE_EOF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NEWSUB_HEAD:
|
case NEWSUB_HEAD:
|
||||||
|
|
|
@ -418,10 +418,11 @@ deconst(const void *c)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
xmemmem(const char *hay, const size_t hz_, const char *ndl, const size_t nz)
|
xmemmem(const char *hay, const size_t haysize,
|
||||||
|
const char *needle, const size_t needlesize)
|
||||||
{
|
{
|
||||||
const char *const eoh = hay + hz_;
|
const char *const eoh = hay + haysize;
|
||||||
const char *const eon = ndl + nz;
|
const char *const eon = needle + needlesize;
|
||||||
const char *hp;
|
const char *hp;
|
||||||
const char *np;
|
const char *np;
|
||||||
const char *cand;
|
const char *cand;
|
||||||
|
@ -433,9 +434,9 @@ xmemmem(const char *hay, const size_t hz_, const char *ndl, const size_t nz)
|
||||||
* a 0-sized needle is defined to be found anywhere in haystack
|
* a 0-sized needle is defined to be found anywhere in haystack
|
||||||
* then run strchr() to find a candidate in HAYSTACK (i.e. a portion
|
* then run strchr() to find a candidate in HAYSTACK (i.e. a portion
|
||||||
* that happens to begin with *NEEDLE) */
|
* that happens to begin with *NEEDLE) */
|
||||||
if (nz == 0UL) {
|
if (needlesize == 0UL) {
|
||||||
return deconst(hay);
|
return deconst(hay);
|
||||||
} else if ((hay = memchr(hay, *ndl, hz_)) == NULL) {
|
} else if ((hay = memchr(hay, *needle, haysize)) == NULL) {
|
||||||
/* trivial */
|
/* trivial */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -444,11 +445,11 @@ xmemmem(const char *hay, const size_t hz_, const char *ndl, const size_t nz)
|
||||||
* guaranteed to be at least one character long. Now computes the sum
|
* guaranteed to be at least one character long. Now computes the sum
|
||||||
* of characters values of needle together with the sum of the first
|
* of characters values of needle together with the sum of the first
|
||||||
* needle_len characters of haystack. */
|
* needle_len characters of haystack. */
|
||||||
for (hp = hay + 1U, np = ndl + 1U, hsum = *hay, nsum = *hay, eqp = 1U;
|
for (hp = hay + 1U, np = needle + 1U, hsum = *hay, nsum = *hay, eqp = 1U;
|
||||||
hp < eoh && np < eon;
|
hp < eoh && np < eon;
|
||||||
hsum ^= *hp, nsum ^= *np, eqp &= *hp == *np, hp++, np++);
|
hsum ^= *hp, nsum ^= *np, eqp &= *hp == *np, hp++, np++);
|
||||||
|
|
||||||
/* HP now references the (NZ + 1)-th character. */
|
/* HP now references the (NEEDLESIZE + 1)-th character. */
|
||||||
if (np < eon) {
|
if (np < eon) {
|
||||||
/* haystack is smaller than needle, :O */
|
/* haystack is smaller than needle, :O */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -464,10 +465,10 @@ xmemmem(const char *hay, const size_t hz_, const char *ndl, const size_t nz)
|
||||||
hsum ^= *hp;
|
hsum ^= *hp;
|
||||||
|
|
||||||
/* Since the sum of the characters is already known to be
|
/* Since the sum of the characters is already known to be
|
||||||
* equal at that point, it is enough to check just NZ - 1
|
* equal at that point, it is enough to check just NEEDLESIZE - 1
|
||||||
* characters for equality,
|
* characters for equality,
|
||||||
* also CAND is by design < HP, so no need for range checks */
|
* also CAND is by design < HP, so no need for range checks */
|
||||||
if (hsum == nsum && memcmp(cand, ndl, nz - 1U) == 0) {
|
if (hsum == nsum && memcmp(cand, needle, needlesize - 1U) == 0) {
|
||||||
return deconst(cand);
|
return deconst(cand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1939,9 +1939,6 @@ unknowntag_start(struct archive_read *a, struct xar *xar, const char *name)
|
||||||
{
|
{
|
||||||
struct unknown_tag *tag;
|
struct unknown_tag *tag;
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
fprintf(stderr, "unknowntag_start:%s\n", name);
|
|
||||||
#endif
|
|
||||||
tag = malloc(sizeof(*tag));
|
tag = malloc(sizeof(*tag));
|
||||||
if (tag == NULL) {
|
if (tag == NULL) {
|
||||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||||
|
@ -1951,6 +1948,9 @@ unknowntag_start(struct archive_read *a, struct xar *xar, const char *name)
|
||||||
archive_string_init(&(tag->name));
|
archive_string_init(&(tag->name));
|
||||||
archive_strcpy(&(tag->name), name);
|
archive_strcpy(&(tag->name), name);
|
||||||
if (xar->unknowntags == NULL) {
|
if (xar->unknowntags == NULL) {
|
||||||
|
#if DEBUG
|
||||||
|
fprintf(stderr, "UNKNOWNTAG_START:%s\n", name);
|
||||||
|
#endif
|
||||||
xar->xmlsts_unknown = xar->xmlsts;
|
xar->xmlsts_unknown = xar->xmlsts;
|
||||||
xar->xmlsts = UNKNOWN;
|
xar->xmlsts = UNKNOWN;
|
||||||
}
|
}
|
||||||
|
@ -1963,9 +1963,6 @@ unknowntag_end(struct xar *xar, const char *name)
|
||||||
{
|
{
|
||||||
struct unknown_tag *tag;
|
struct unknown_tag *tag;
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
fprintf(stderr, "unknowntag_end:%s\n", name);
|
|
||||||
#endif
|
|
||||||
tag = xar->unknowntags;
|
tag = xar->unknowntags;
|
||||||
if (tag == NULL || name == NULL)
|
if (tag == NULL || name == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -1973,8 +1970,12 @@ unknowntag_end(struct xar *xar, const char *name)
|
||||||
xar->unknowntags = tag->next;
|
xar->unknowntags = tag->next;
|
||||||
archive_string_free(&(tag->name));
|
archive_string_free(&(tag->name));
|
||||||
free(tag);
|
free(tag);
|
||||||
if (xar->unknowntags == NULL)
|
if (xar->unknowntags == NULL) {
|
||||||
|
#if DEBUG
|
||||||
|
fprintf(stderr, "UNKNOWNTAG_END:%s\n", name);
|
||||||
|
#endif
|
||||||
xar->xmlsts = xar->xmlsts_unknown;
|
xar->xmlsts = xar->xmlsts_unknown;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2168,7 +2169,7 @@ xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
|
||||||
case FILE_ACL:
|
case FILE_ACL:
|
||||||
if (strcmp(name, "appleextended") == 0)
|
if (strcmp(name, "appleextended") == 0)
|
||||||
xar->xmlsts = FILE_ACL_APPLEEXTENDED;
|
xar->xmlsts = FILE_ACL_APPLEEXTENDED;
|
||||||
if (strcmp(name, "default") == 0)
|
else if (strcmp(name, "default") == 0)
|
||||||
xar->xmlsts = FILE_ACL_DEFAULT;
|
xar->xmlsts = FILE_ACL_DEFAULT;
|
||||||
else if (strcmp(name, "access") == 0)
|
else if (strcmp(name, "access") == 0)
|
||||||
xar->xmlsts = FILE_ACL_ACCESS;
|
xar->xmlsts = FILE_ACL_ACCESS;
|
||||||
|
@ -2690,9 +2691,9 @@ xml_data(void *userData, const char *s, int len)
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
{
|
{
|
||||||
char buff[1024];
|
char buff[1024];
|
||||||
if (len > sizeof(buff)-1)
|
if (len > (int)(sizeof(buff)-1))
|
||||||
len = sizeof(buff)-1;
|
len = (int)(sizeof(buff)-1);
|
||||||
memcpy(buff, s, len);
|
strncpy(buff, s, len);
|
||||||
buff[len] = 0;
|
buff[len] = 0;
|
||||||
fprintf(stderr, "\tlen=%d:\"%s\"\n", len, buff);
|
fprintf(stderr, "\tlen=%d:\"%s\"\n", len, buff);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102
|
||||||
*
|
*
|
||||||
* History of this code: The streaming Zip reader was first added to
|
* History of this code: The streaming Zip reader was first added to
|
||||||
* libarchive in January 2005. Support for seekable input sources was
|
* libarchive in January 2005. Support for seekable input sources was
|
||||||
* added in Nov 2011.
|
* added in Nov 2011. Zip64 support (including a significant code
|
||||||
|
* refactoring) was added in 2014.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_ERRNO_H
|
#ifdef HAVE_ERRNO_H
|
||||||
|
@ -419,8 +420,9 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
|
||||||
unsigned short datasize = archive_le16dec(p + offset + 2);
|
unsigned short datasize = archive_le16dec(p + offset + 2);
|
||||||
|
|
||||||
offset += 4;
|
offset += 4;
|
||||||
if (offset + datasize > extra_length)
|
if (offset + datasize > extra_length) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "Header id 0x%04x, length %d\n",
|
fprintf(stderr, "Header id 0x%04x, length %d\n",
|
||||||
headerid, datasize);
|
headerid, datasize);
|
||||||
|
@ -555,7 +557,7 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
|
||||||
* if bitmap & 1, 2 byte "version made by"
|
* if bitmap & 1, 2 byte "version made by"
|
||||||
* if bitmap & 2, 2 byte "internal file attributes"
|
* if bitmap & 2, 2 byte "internal file attributes"
|
||||||
* if bitmap & 4, 4 byte "external file attributes"
|
* if bitmap & 4, 4 byte "external file attributes"
|
||||||
* if bitmap * 7, 2 byte comment length + n byte comment
|
* if bitmap & 8, 2 byte comment length + n byte comment
|
||||||
*/
|
*/
|
||||||
int bitmap, bitmap_last;
|
int bitmap, bitmap_last;
|
||||||
|
|
||||||
|
@ -604,6 +606,19 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
|
||||||
if (zip_entry->system == 3) {
|
if (zip_entry->system == 3) {
|
||||||
zip_entry->mode
|
zip_entry->mode
|
||||||
= external_attributes >> 16;
|
= external_attributes >> 16;
|
||||||
|
} else if (zip_entry->system == 0) {
|
||||||
|
// Interpret MSDOS directory bit
|
||||||
|
if (0x10 == (external_attributes & 0x10)) {
|
||||||
|
zip_entry->mode = AE_IFDIR | 0775;
|
||||||
|
} else {
|
||||||
|
zip_entry->mode = AE_IFREG | 0664;
|
||||||
|
}
|
||||||
|
if (0x01 == (external_attributes & 0x01)) {
|
||||||
|
// Read-only bit; strip write permissions
|
||||||
|
zip_entry->mode &= 0555;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zip_entry->mode = 0;
|
||||||
}
|
}
|
||||||
offset += 4;
|
offset += 4;
|
||||||
datasize -= 4;
|
datasize -= 4;
|
||||||
|
@ -810,6 +825,16 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||||
}
|
}
|
||||||
__archive_read_consume(a, filename_length);
|
__archive_read_consume(a, filename_length);
|
||||||
|
|
||||||
|
/* Read the extra data. */
|
||||||
|
if ((h = __archive_read_ahead(a, extra_length, NULL)) == NULL) {
|
||||||
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
|
"Truncated ZIP file header");
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
process_extra(h, extra_length, zip_entry);
|
||||||
|
__archive_read_consume(a, extra_length);
|
||||||
|
|
||||||
/* Work around a bug in Info-Zip: When reading from a pipe, it
|
/* Work around a bug in Info-Zip: When reading from a pipe, it
|
||||||
* stats the pipe instead of synthesizing a file entry. */
|
* stats the pipe instead of synthesizing a file entry. */
|
||||||
if ((zip_entry->mode & AE_IFMT) == AE_IFIFO) {
|
if ((zip_entry->mode & AE_IFMT) == AE_IFIFO) {
|
||||||
|
@ -843,16 +868,31 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the extra data. */
|
/* Make sure directories end in '/' */
|
||||||
if ((h = __archive_read_ahead(a, extra_length, NULL)) == NULL) {
|
if ((zip_entry->mode & AE_IFMT) == AE_IFDIR) {
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
wp = archive_entry_pathname_w(entry);
|
||||||
"Truncated ZIP file header");
|
if (wp != NULL) {
|
||||||
return (ARCHIVE_FATAL);
|
len = wcslen(wp);
|
||||||
|
if (len > 0 && wp[len - 1] != L'/') {
|
||||||
|
struct archive_wstring s;
|
||||||
|
archive_string_init(&s);
|
||||||
|
archive_wstrcat(&s, wp);
|
||||||
|
archive_wstrappend_wchar(&s, L'/');
|
||||||
|
archive_entry_copy_pathname_w(entry, s.s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cp = archive_entry_pathname(entry);
|
||||||
|
len = (cp != NULL)?strlen(cp):0;
|
||||||
|
if (len > 0 && cp[len - 1] != '/') {
|
||||||
|
struct archive_string s;
|
||||||
|
archive_string_init(&s);
|
||||||
|
archive_strcat(&s, cp);
|
||||||
|
archive_strappend_char(&s, '/');
|
||||||
|
archive_entry_set_pathname(entry, s.s);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process_extra(h, extra_length, zip_entry);
|
|
||||||
__archive_read_consume(a, extra_length);
|
|
||||||
|
|
||||||
if (zip_entry->flags & LA_FROM_CENTRAL_DIRECTORY) {
|
if (zip_entry->flags & LA_FROM_CENTRAL_DIRECTORY) {
|
||||||
/* If this came from the central dir, it's size info
|
/* If this came from the central dir, it's size info
|
||||||
* is definitive, so ignore the length-at-end flag. */
|
* is definitive, so ignore the length-at-end flag. */
|
||||||
|
@ -2614,9 +2654,21 @@ slurp_central_directory(struct archive_read *a, struct zip *zip)
|
||||||
/* If we can't guess the mode, leave it zero here;
|
/* If we can't guess the mode, leave it zero here;
|
||||||
when we read the local file header we might get
|
when we read the local file header we might get
|
||||||
more information. */
|
more information. */
|
||||||
zip_entry->mode = 0;
|
|
||||||
if (zip_entry->system == 3) {
|
if (zip_entry->system == 3) {
|
||||||
zip_entry->mode = external_attributes >> 16;
|
zip_entry->mode = external_attributes >> 16;
|
||||||
|
} else if (zip_entry->system == 0) {
|
||||||
|
// Interpret MSDOS directory bit
|
||||||
|
if (0x10 == (external_attributes & 0x10)) {
|
||||||
|
zip_entry->mode = AE_IFDIR | 0775;
|
||||||
|
} else {
|
||||||
|
zip_entry->mode = AE_IFREG | 0664;
|
||||||
|
}
|
||||||
|
if (0x01 == (external_attributes & 0x01)) {
|
||||||
|
// Read-only bit; strip write permissions
|
||||||
|
zip_entry->mode &= 0555;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zip_entry->mode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're done with the regular data; get the filename and
|
/* We're done with the regular data; get the filename and
|
||||||
|
@ -2726,6 +2778,11 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
|
||||||
|
|
||||||
switch(rsrc->compression) {
|
switch(rsrc->compression) {
|
||||||
case 0: /* No compression. */
|
case 0: /* No compression. */
|
||||||
|
if (rsrc->uncompressed_size != rsrc->compressed_size) {
|
||||||
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
|
"Malformed OS X metadata entry: inconsistent size");
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
}
|
||||||
#ifdef HAVE_ZLIB_H
|
#ifdef HAVE_ZLIB_H
|
||||||
case 8: /* Deflate compression. */
|
case 8: /* Deflate compression. */
|
||||||
#endif
|
#endif
|
||||||
|
@ -2746,6 +2803,12 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
|
||||||
(intmax_t)rsrc->uncompressed_size);
|
(intmax_t)rsrc->uncompressed_size);
|
||||||
return (ARCHIVE_WARN);
|
return (ARCHIVE_WARN);
|
||||||
}
|
}
|
||||||
|
if (rsrc->compressed_size > (4 * 1024 * 1024)) {
|
||||||
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
|
"Mac metadata is too large: %jd > 4M bytes",
|
||||||
|
(intmax_t)rsrc->compressed_size);
|
||||||
|
return (ARCHIVE_WARN);
|
||||||
|
}
|
||||||
|
|
||||||
metadata = malloc((size_t)rsrc->uncompressed_size);
|
metadata = malloc((size_t)rsrc->uncompressed_size);
|
||||||
if (metadata == NULL) {
|
if (metadata == NULL) {
|
||||||
|
@ -2784,6 +2847,8 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
|
||||||
bytes_avail = remaining_bytes;
|
bytes_avail = remaining_bytes;
|
||||||
switch(rsrc->compression) {
|
switch(rsrc->compression) {
|
||||||
case 0: /* No compression. */
|
case 0: /* No compression. */
|
||||||
|
if ((size_t)bytes_avail > metadata_bytes)
|
||||||
|
bytes_avail = metadata_bytes;
|
||||||
memcpy(mp, p, bytes_avail);
|
memcpy(mp, p, bytes_avail);
|
||||||
bytes_used = (size_t)bytes_avail;
|
bytes_used = (size_t)bytes_avail;
|
||||||
metadata_bytes -= bytes_used;
|
metadata_bytes -= bytes_used;
|
||||||
|
|
|
@ -737,7 +737,8 @@ archive_string_append_from_wcs_in_codepage(struct archive_string *as,
|
||||||
}
|
}
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
} while (0);
|
break;
|
||||||
|
} while (1);
|
||||||
}
|
}
|
||||||
as->length += count;
|
as->length += count;
|
||||||
as->s[as->length] = '\0';
|
as->s[as->length] = '\0';
|
||||||
|
|
|
@ -94,37 +94,83 @@ archive_version_details(void)
|
||||||
{
|
{
|
||||||
static struct archive_string str;
|
static struct archive_string str;
|
||||||
static int init = 0;
|
static int init = 0;
|
||||||
|
const char *zlib = archive_zlib_version();
|
||||||
|
const char *liblzma = archive_liblzma_version();
|
||||||
|
const char *bzlib = archive_bzlib_version();
|
||||||
|
const char *liblz4 = archive_liblz4_version();
|
||||||
|
|
||||||
if (!init) {
|
if (!init) {
|
||||||
archive_string_init(&str);
|
archive_string_init(&str);
|
||||||
|
|
||||||
archive_strcat(&str, ARCHIVE_VERSION_STRING);
|
archive_strcat(&str, ARCHIVE_VERSION_STRING);
|
||||||
#ifdef HAVE_ZLIB_H
|
if (zlib != NULL) {
|
||||||
archive_strcat(&str, " zlib/");
|
archive_strcat(&str, " zlib/");
|
||||||
archive_strcat(&str, ZLIB_VERSION);
|
archive_strcat(&str, zlib);
|
||||||
#endif
|
}
|
||||||
#ifdef HAVE_LZMA_H
|
if (liblzma) {
|
||||||
archive_strcat(&str, " liblzma/");
|
archive_strcat(&str, " liblzma/");
|
||||||
archive_strcat(&str, LZMA_VERSION_STRING);
|
archive_strcat(&str, liblzma);
|
||||||
#endif
|
}
|
||||||
#ifdef HAVE_BZLIB_H
|
if (bzlib) {
|
||||||
{
|
const char *p = bzlib;
|
||||||
const char *p = BZ2_bzlibVersion();
|
|
||||||
const char *sep = strchr(p, ',');
|
const char *sep = strchr(p, ',');
|
||||||
if (sep == NULL)
|
if (sep == NULL)
|
||||||
sep = p + strlen(p);
|
sep = p + strlen(p);
|
||||||
archive_strcat(&str, " bz2lib/");
|
archive_strcat(&str, " bz2lib/");
|
||||||
archive_strncat(&str, p, sep - p);
|
archive_strncat(&str, p, sep - p);
|
||||||
}
|
}
|
||||||
#endif
|
if (liblz4) {
|
||||||
#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
|
archive_strcat(&str, " liblz4/");
|
||||||
archive_string_sprintf(&str, " liblz4/%d.%d.%d",
|
archive_strcat(&str, liblz4);
|
||||||
LZ4_VERSION_MAJOR, LZ4_VERSION_MINOR, LZ4_VERSION_RELEASE);
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return str.s;
|
return str.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
archive_zlib_version(void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
return ZLIB_VERSION;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
archive_liblzma_version(void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LZMA_H
|
||||||
|
return LZMA_VERSION_STRING;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
archive_bzlib_version(void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_BZLIB_H
|
||||||
|
return BZ2_bzlibVersion();
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
archive_liblz4_version(void)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
|
||||||
|
#define str(s) #s
|
||||||
|
#define NUMBER(x) str(x)
|
||||||
|
return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
|
||||||
|
#undef NUMBER
|
||||||
|
#undef str
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
archive_errno(struct archive *a)
|
archive_errno(struct archive *a)
|
||||||
{
|
{
|
||||||
|
|
|
@ -105,7 +105,7 @@ archive_write_add_filter_bzip2(struct archive *_a)
|
||||||
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
|
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
#else
|
#else
|
||||||
data->pdata = __archive_write_program_allocate();
|
data->pdata = __archive_write_program_allocate("bzip2");
|
||||||
if (data->pdata == NULL) {
|
if (data->pdata == NULL) {
|
||||||
free(data);
|
free(data);
|
||||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||||
|
|
|
@ -63,7 +63,7 @@ archive_write_add_filter_grzip(struct archive *_a)
|
||||||
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
data->pdata = __archive_write_program_allocate();
|
data->pdata = __archive_write_program_allocate("grzip");
|
||||||
if (data->pdata == NULL) {
|
if (data->pdata == NULL) {
|
||||||
free(data);
|
free(data);
|
||||||
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
||||||
|
|
|
@ -119,7 +119,7 @@ archive_write_add_filter_gzip(struct archive *_a)
|
||||||
data->compression_level = Z_DEFAULT_COMPRESSION;
|
data->compression_level = Z_DEFAULT_COMPRESSION;
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
#else
|
#else
|
||||||
data->pdata = __archive_write_program_allocate();
|
data->pdata = __archive_write_program_allocate("gzip");
|
||||||
if (data->pdata == NULL) {
|
if (data->pdata == NULL) {
|
||||||
free(data);
|
free(data);
|
||||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||||
|
|
|
@ -69,7 +69,7 @@ archive_write_add_filter_lrzip(struct archive *_a)
|
||||||
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
data->pdata = __archive_write_program_allocate();
|
data->pdata = __archive_write_program_allocate("lrzip");
|
||||||
if (data->pdata == NULL) {
|
if (data->pdata == NULL) {
|
||||||
free(data);
|
free(data);
|
||||||
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
||||||
|
|
|
@ -137,7 +137,7 @@ archive_write_add_filter_lz4(struct archive *_a)
|
||||||
* We don't have lz4 library, and execute external lz4 program
|
* We don't have lz4 library, and execute external lz4 program
|
||||||
* instead.
|
* instead.
|
||||||
*/
|
*/
|
||||||
data->pdata = __archive_write_program_allocate();
|
data->pdata = __archive_write_program_allocate("lz4");
|
||||||
if (data->pdata == NULL) {
|
if (data->pdata == NULL) {
|
||||||
free(data);
|
free(data);
|
||||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||||
|
@ -160,10 +160,20 @@ archive_filter_lz4_options(struct archive_write_filter *f,
|
||||||
struct private_data *data = (struct private_data *)f->data;
|
struct private_data *data = (struct private_data *)f->data;
|
||||||
|
|
||||||
if (strcmp(key, "compression-level") == 0) {
|
if (strcmp(key, "compression-level") == 0) {
|
||||||
if (value == NULL || !(value[0] >= '1' && value[0] <= '9') ||
|
int val;
|
||||||
|
if (value == NULL || !((val = value[0] - '0') >= 1 && val <= 9) ||
|
||||||
value[1] != '\0')
|
value[1] != '\0')
|
||||||
return (ARCHIVE_WARN);
|
return (ARCHIVE_WARN);
|
||||||
data->compression_level = value[0] - '0';
|
|
||||||
|
#ifndef HAVE_LZ4HC_H
|
||||||
|
if(val >= 3)
|
||||||
|
{
|
||||||
|
archive_set_error(f->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||||
|
"High compression not included in this build");
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
data->compression_level = val;
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
if (strcmp(key, "stream-checksum") == 0) {
|
if (strcmp(key, "stream-checksum") == 0) {
|
||||||
|
@ -367,14 +377,20 @@ archive_filter_lz4_free(struct archive_write_filter *f)
|
||||||
struct private_data *data = (struct private_data *)f->data;
|
struct private_data *data = (struct private_data *)f->data;
|
||||||
|
|
||||||
if (data->lz4_stream != NULL) {
|
if (data->lz4_stream != NULL) {
|
||||||
if (data->compression_level < 3)
|
#ifdef HAVE_LZ4HC_H
|
||||||
|
if (data->compression_level >= 3)
|
||||||
|
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
|
||||||
|
LZ4_freeStreamHC(data->lz4_stream);
|
||||||
|
#else
|
||||||
|
LZ4_freeHC(data->lz4_stream);
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
#endif
|
||||||
#if LZ4_VERSION_MINOR >= 3
|
#if LZ4_VERSION_MINOR >= 3
|
||||||
LZ4_freeStream(data->lz4_stream);
|
LZ4_freeStream(data->lz4_stream);
|
||||||
#else
|
#else
|
||||||
LZ4_free(data->lz4_stream);
|
LZ4_free(data->lz4_stream);
|
||||||
#endif
|
#endif
|
||||||
else
|
|
||||||
LZ4_freeHC(data->lz4_stream);
|
|
||||||
}
|
}
|
||||||
free(data->out_buffer);
|
free(data->out_buffer);
|
||||||
free(data->in_buffer_allocated);
|
free(data->in_buffer_allocated);
|
||||||
|
@ -481,13 +497,26 @@ drive_compressor_independence(struct archive_write_filter *f, const char *p,
|
||||||
struct private_data *data = (struct private_data *)f->data;
|
struct private_data *data = (struct private_data *)f->data;
|
||||||
unsigned int outsize;
|
unsigned int outsize;
|
||||||
|
|
||||||
if (data->compression_level < 4)
|
#ifdef HAVE_LZ4HC_H
|
||||||
outsize = LZ4_compress_limitedOutput(p, data->out + 4,
|
if (data->compression_level >= 3)
|
||||||
(int)length, (int)data->block_size);
|
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
|
||||||
else
|
outsize = LZ4_compress_HC(p, data->out + 4,
|
||||||
|
(int)length, (int)data->block_size,
|
||||||
|
data->compression_level);
|
||||||
|
#else
|
||||||
outsize = LZ4_compressHC2_limitedOutput(p, data->out + 4,
|
outsize = LZ4_compressHC2_limitedOutput(p, data->out + 4,
|
||||||
(int)length, (int)data->block_size,
|
(int)length, (int)data->block_size,
|
||||||
data->compression_level);
|
data->compression_level);
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
|
||||||
|
outsize = LZ4_compress_default(p, data->out + 4,
|
||||||
|
(int)length, (int)data->block_size);
|
||||||
|
#else
|
||||||
|
outsize = LZ4_compress_limitedOutput(p, data->out + 4,
|
||||||
|
(int)length, (int)data->block_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (outsize) {
|
if (outsize) {
|
||||||
/* The buffer is compressed. */
|
/* The buffer is compressed. */
|
||||||
|
@ -518,7 +547,39 @@ drive_compressor_dependence(struct archive_write_filter *f, const char *p,
|
||||||
struct private_data *data = (struct private_data *)f->data;
|
struct private_data *data = (struct private_data *)f->data;
|
||||||
int outsize;
|
int outsize;
|
||||||
|
|
||||||
if (data->compression_level < 3) {
|
#define DICT_SIZE (64 * 1024)
|
||||||
|
#ifdef HAVE_LZ4HC_H
|
||||||
|
if (data->compression_level >= 3) {
|
||||||
|
if (data->lz4_stream == NULL) {
|
||||||
|
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
|
||||||
|
data->lz4_stream = LZ4_createStreamHC();
|
||||||
|
LZ4_resetStreamHC(data->lz4_stream, data->compression_level);
|
||||||
|
#else
|
||||||
|
data->lz4_stream =
|
||||||
|
LZ4_createHC(data->in_buffer_allocated);
|
||||||
|
#endif
|
||||||
|
if (data->lz4_stream == NULL) {
|
||||||
|
archive_set_error(f->archive, ENOMEM,
|
||||||
|
"Can't allocate data for compression"
|
||||||
|
" buffer");
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LZ4_loadDictHC(data->lz4_stream, data->in_buffer_allocated, DICT_SIZE);
|
||||||
|
|
||||||
|
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
|
||||||
|
outsize = LZ4_compress_HC_continue(
|
||||||
|
data->lz4_stream, p, data->out + 4, (int)length,
|
||||||
|
(int)data->block_size);
|
||||||
|
#else
|
||||||
|
outsize = LZ4_compressHC2_limitedOutput_continue(
|
||||||
|
data->lz4_stream, p, data->out + 4, (int)length,
|
||||||
|
(int)data->block_size, data->compression_level);
|
||||||
|
#endif
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
if (data->lz4_stream == NULL) {
|
if (data->lz4_stream == NULL) {
|
||||||
data->lz4_stream = LZ4_createStream();
|
data->lz4_stream = LZ4_createStream();
|
||||||
if (data->lz4_stream == NULL) {
|
if (data->lz4_stream == NULL) {
|
||||||
|
@ -528,23 +589,18 @@ drive_compressor_dependence(struct archive_write_filter *f, const char *p,
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
LZ4_loadDict(data->lz4_stream, data->in_buffer_allocated, DICT_SIZE);
|
||||||
|
|
||||||
|
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
|
||||||
|
outsize = LZ4_compress_fast_continue(
|
||||||
|
data->lz4_stream, p, data->out + 4, (int)length,
|
||||||
|
(int)data->block_size, 1);
|
||||||
|
#else
|
||||||
outsize = LZ4_compress_limitedOutput_continue(
|
outsize = LZ4_compress_limitedOutput_continue(
|
||||||
data->lz4_stream, p, data->out + 4, (int)length,
|
data->lz4_stream, p, data->out + 4, (int)length,
|
||||||
(int)data->block_size);
|
(int)data->block_size);
|
||||||
} else {
|
#endif
|
||||||
if (data->lz4_stream == NULL) {
|
|
||||||
data->lz4_stream =
|
|
||||||
LZ4_createHC(data->in_buffer_allocated);
|
|
||||||
if (data->lz4_stream == NULL) {
|
|
||||||
archive_set_error(f->archive, ENOMEM,
|
|
||||||
"Can't allocate data for compression"
|
|
||||||
" buffer");
|
|
||||||
return (ARCHIVE_FATAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outsize = LZ4_compressHC2_limitedOutput_continue(
|
|
||||||
data->lz4_stream, p, data->out + 4, (int)length,
|
|
||||||
(int)data->block_size, data->compression_level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outsize) {
|
if (outsize) {
|
||||||
|
@ -568,14 +624,19 @@ drive_compressor_dependence(struct archive_write_filter *f, const char *p,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length == data->block_size) {
|
if (length == data->block_size) {
|
||||||
#define DICT_SIZE (64 * 1024)
|
#ifdef HAVE_LZ4HC_H
|
||||||
if (data->compression_level < 3)
|
if (data->compression_level >= 3) {
|
||||||
LZ4_saveDict(data->lz4_stream,
|
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
|
||||||
data->in_buffer_allocated, DICT_SIZE);
|
LZ4_saveDictHC(data->lz4_stream, data->in_buffer_allocated, DICT_SIZE);
|
||||||
else {
|
#else
|
||||||
LZ4_slideInputBufferHC(data->lz4_stream);
|
LZ4_slideInputBufferHC(data->lz4_stream);
|
||||||
|
#endif
|
||||||
data->in_buffer = data->in_buffer_allocated + DICT_SIZE;
|
data->in_buffer = data->in_buffer_allocated + DICT_SIZE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
LZ4_saveDict(data->lz4_stream,
|
||||||
|
data->in_buffer_allocated, DICT_SIZE);
|
||||||
#undef DICT_SIZE
|
#undef DICT_SIZE
|
||||||
}
|
}
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
|
@ -605,7 +666,7 @@ archive_filter_lz4_open(struct archive_write_filter *f)
|
||||||
if (data->block_checksum)
|
if (data->block_checksum)
|
||||||
archive_strcat(&as, " -BX");
|
archive_strcat(&as, " -BX");
|
||||||
if (data->stream_checksum == 0)
|
if (data->stream_checksum == 0)
|
||||||
archive_strcat(&as, " -Sx");
|
archive_strcat(&as, " --no-frame-crc");
|
||||||
if (data->block_independence == 0)
|
if (data->block_independence == 0)
|
||||||
archive_strcat(&as, " -BD");
|
archive_strcat(&as, " -BD");
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ archive_write_add_filter_lzop(struct archive *_a)
|
||||||
data->compression_level = 5;
|
data->compression_level = 5;
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
#else
|
#else
|
||||||
data->pdata = __archive_write_program_allocate();
|
data->pdata = __archive_write_program_allocate("lzop");
|
||||||
if (data->pdata == NULL) {
|
if (data->pdata == NULL) {
|
||||||
free(data);
|
free(data);
|
||||||
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
||||||
|
|
|
@ -68,6 +68,7 @@ struct archive_write_program_data {
|
||||||
|
|
||||||
char *child_buf;
|
char *child_buf;
|
||||||
size_t child_buf_len, child_buf_avail;
|
size_t child_buf_len, child_buf_avail;
|
||||||
|
char *program_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct private_data {
|
struct private_data {
|
||||||
|
@ -105,7 +106,7 @@ archive_write_add_filter_program(struct archive *_a, const char *cmd)
|
||||||
if (data->cmd == NULL)
|
if (data->cmd == NULL)
|
||||||
goto memerr;
|
goto memerr;
|
||||||
|
|
||||||
data->pdata = __archive_write_program_allocate();
|
data->pdata = __archive_write_program_allocate(cmd);
|
||||||
if (data->pdata == NULL)
|
if (data->pdata == NULL)
|
||||||
goto memerr;
|
goto memerr;
|
||||||
|
|
||||||
|
@ -174,7 +175,7 @@ archive_compressor_program_free(struct archive_write_filter *f)
|
||||||
* Allocate resources for executing an external program.
|
* Allocate resources for executing an external program.
|
||||||
*/
|
*/
|
||||||
struct archive_write_program_data *
|
struct archive_write_program_data *
|
||||||
__archive_write_program_allocate(void)
|
__archive_write_program_allocate(const char *program)
|
||||||
{
|
{
|
||||||
struct archive_write_program_data *data;
|
struct archive_write_program_data *data;
|
||||||
|
|
||||||
|
@ -183,6 +184,7 @@ __archive_write_program_allocate(void)
|
||||||
return (data);
|
return (data);
|
||||||
data->child_stdin = -1;
|
data->child_stdin = -1;
|
||||||
data->child_stdout = -1;
|
data->child_stdout = -1;
|
||||||
|
data->program_name = strdup(program);
|
||||||
return (data);
|
return (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +233,7 @@ __archive_write_program_open(struct archive_write_filter *f,
|
||||||
&data->child_stdout);
|
&data->child_stdout);
|
||||||
if (child == -1) {
|
if (child == -1) {
|
||||||
archive_set_error(f->archive, EINVAL,
|
archive_set_error(f->archive, EINVAL,
|
||||||
"Can't initialise filter");
|
"Can't launch external program: %s", cmd);
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
@ -242,7 +244,7 @@ __archive_write_program_open(struct archive_write_filter *f,
|
||||||
close(data->child_stdout);
|
close(data->child_stdout);
|
||||||
data->child_stdout = -1;
|
data->child_stdout = -1;
|
||||||
archive_set_error(f->archive, EINVAL,
|
archive_set_error(f->archive, EINVAL,
|
||||||
"Can't initialise filter");
|
"Can't launch external program: %s", cmd);
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -334,7 +336,7 @@ __archive_write_program_write(struct archive_write_filter *f,
|
||||||
ret = child_write(f, data, buf, length);
|
ret = child_write(f, data, buf, length);
|
||||||
if (ret == -1 || ret == 0) {
|
if (ret == -1 || ret == 0) {
|
||||||
archive_set_error(f->archive, EIO,
|
archive_set_error(f->archive, EIO,
|
||||||
"Can't write to filter");
|
"Can't write to program: %s", data->program_name);
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
length -= ret;
|
length -= ret;
|
||||||
|
@ -373,7 +375,7 @@ __archive_write_program_close(struct archive_write_filter *f,
|
||||||
|
|
||||||
if (bytes_read == -1) {
|
if (bytes_read == -1) {
|
||||||
archive_set_error(f->archive, errno,
|
archive_set_error(f->archive, errno,
|
||||||
"Read from filter failed unexpectedly.");
|
"Error reading from program: %s", data->program_name);
|
||||||
ret = ARCHIVE_FATAL;
|
ret = ARCHIVE_FATAL;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -403,7 +405,7 @@ cleanup:
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
archive_set_error(f->archive, EIO,
|
archive_set_error(f->archive, EIO,
|
||||||
"Filter exited with failure.");
|
"Error closing program: %s", data->program_name);
|
||||||
ret = ARCHIVE_FATAL;
|
ret = ARCHIVE_FATAL;
|
||||||
}
|
}
|
||||||
r1 = __archive_write_close_filter(f->next_filter);
|
r1 = __archive_write_close_filter(f->next_filter);
|
||||||
|
|
|
@ -2386,6 +2386,9 @@ check_symlinks(struct archive_write_disk *a)
|
||||||
while ((*pn != '\0') && (*p == *pn))
|
while ((*pn != '\0') && (*p == *pn))
|
||||||
++p, ++pn;
|
++p, ++pn;
|
||||||
}
|
}
|
||||||
|
/* Skip the root directory if the path is absolute. */
|
||||||
|
if(pn == a->name && pn[0] == '/')
|
||||||
|
++pn;
|
||||||
c = pn[0];
|
c = pn[0];
|
||||||
/* Keep going until we've checked the entire name. */
|
/* Keep going until we've checked the entire name. */
|
||||||
while (pn[0] != '\0' && (pn[0] != '/' || pn[1] != '\0')) {
|
while (pn[0] != '\0' && (pn[0] != '/' || pn[1] != '\0')) {
|
||||||
|
@ -2447,6 +2450,9 @@ check_symlinks(struct archive_write_disk *a)
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pn[0] = c;
|
||||||
|
if (pn[0] != '\0')
|
||||||
|
pn++; /* Advance to the next segment. */
|
||||||
}
|
}
|
||||||
pn[0] = c;
|
pn[0] = c;
|
||||||
/* We've checked and/or cleaned the whole path, so remember it. */
|
/* We've checked and/or cleaned the whole path, so remember it. */
|
||||||
|
|
|
@ -29,9 +29,12 @@
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm archive_write_add_filter_b64encode ,
|
.Nm archive_write_add_filter_b64encode ,
|
||||||
|
.Nm archive_write_add_filter_by_name ,
|
||||||
.Nm archive_write_add_filter_bzip2 ,
|
.Nm archive_write_add_filter_bzip2 ,
|
||||||
.Nm archive_write_add_filter_compress ,
|
.Nm archive_write_add_filter_compress ,
|
||||||
|
.Nm archive_write_add_filter_grzip ,
|
||||||
.Nm archive_write_add_filter_gzip ,
|
.Nm archive_write_add_filter_gzip ,
|
||||||
|
.Nm archive_write_add_filter_lrzip ,
|
||||||
.Nm archive_write_add_filter_lz4 ,
|
.Nm archive_write_add_filter_lz4 ,
|
||||||
.Nm archive_write_add_filter_lzip ,
|
.Nm archive_write_add_filter_lzip ,
|
||||||
.Nm archive_write_add_filter_lzma ,
|
.Nm archive_write_add_filter_lzma ,
|
||||||
|
@ -51,8 +54,12 @@ Streaming Archive Library (libarchive, -larchive)
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_write_add_filter_compress "struct archive *"
|
.Fn archive_write_add_filter_compress "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn archive_write_add_filter_grzip "struct archive *"
|
||||||
|
.Ft int
|
||||||
.Fn archive_write_add_filter_gzip "struct archive *"
|
.Fn archive_write_add_filter_gzip "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn archive_write_add_filter_lrzip "struct archive *"
|
||||||
|
.Ft int
|
||||||
.Fn archive_write_add_filter_lz4 "struct archive *"
|
.Fn archive_write_add_filter_lz4 "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_write_add_filter_lzip "struct archive *"
|
.Fn archive_write_add_filter_lzip "struct archive *"
|
||||||
|
@ -71,19 +78,25 @@ Streaming Archive Library (libarchive, -larchive)
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Xo
|
.It Xo
|
||||||
.Fn archive_write_add_filter_b64encode ,
|
|
||||||
.Fn archive_write_add_filter_bzip2 ,
|
.Fn archive_write_add_filter_bzip2 ,
|
||||||
.Fn archive_write_add_filter_compress ,
|
.Fn archive_write_add_filter_compress ,
|
||||||
|
.Fn archive_write_add_filter_grzip ,
|
||||||
.Fn archive_write_add_filter_gzip ,
|
.Fn archive_write_add_filter_gzip ,
|
||||||
|
.Fn archive_write_add_filter_lrzip ,
|
||||||
.Fn archive_write_add_filter_lz4 ,
|
.Fn archive_write_add_filter_lz4 ,
|
||||||
.Fn archive_write_add_filter_lzip ,
|
.Fn archive_write_add_filter_lzip ,
|
||||||
.Fn archive_write_add_filter_lzma ,
|
.Fn archive_write_add_filter_lzma ,
|
||||||
.Fn archive_write_add_filter_lzop ,
|
.Fn archive_write_add_filter_lzop ,
|
||||||
.Fn archive_write_add_filter_uuencode ,
|
|
||||||
.Fn archive_write_add_filter_xz ,
|
.Fn archive_write_add_filter_xz ,
|
||||||
.Xc
|
.Xc
|
||||||
The resulting archive will be compressed as specified.
|
The resulting archive will be compressed as specified.
|
||||||
Note that the compressed output is always properly blocked.
|
Note that the compressed output is always properly blocked.
|
||||||
|
.It Xo
|
||||||
|
.Fn archive_write_add_filter_b64encode ,
|
||||||
|
.Fn archive_write_add_filter_uuencode ,
|
||||||
|
.Xc
|
||||||
|
The output will be encoded as specified.
|
||||||
|
The encoded output is always properly blocked.
|
||||||
.It Fn archive_write_add_filter_none
|
.It Fn archive_write_add_filter_none
|
||||||
This is never necessary.
|
This is never necessary.
|
||||||
It is provided only for backwards compatibility.
|
It is provided only for backwards compatibility.
|
||||||
|
|
|
@ -28,23 +28,63 @@
|
||||||
.Dt ARCHIVE_WRITE_FORMAT 3
|
.Dt ARCHIVE_WRITE_FORMAT 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
.Nm archive_write_set_format ,
|
||||||
|
.Nm archive_write_set_format_7zip ,
|
||||||
|
.Nm archive_write_set_format_ar ,
|
||||||
|
.Nm archive_write_set_format_ar_bsd ,
|
||||||
|
.Nm archive_write_set_format_ar_svr4 ,
|
||||||
|
.Nm archive_write_set_format_by_name ,
|
||||||
.Nm archive_write_set_format_cpio ,
|
.Nm archive_write_set_format_cpio ,
|
||||||
|
.Nm archive_write_set_format_cpio_newc ,
|
||||||
|
.Nm archive_write_set_format_filter_by_ext ,
|
||||||
|
.Nm archive_write_set_format_filter_by_ext_def ,
|
||||||
|
.Nm archive_write_set_format_gnutar ,
|
||||||
|
.Nm archive_write_set_format_iso9660 ,
|
||||||
|
.Nm archive_write_set_format_mtree ,
|
||||||
|
.Nm archive_write_set_format_mtree_classic ,
|
||||||
|
.Nm archive_write_set_format_mtree_default ,
|
||||||
.Nm archive_write_set_format_pax ,
|
.Nm archive_write_set_format_pax ,
|
||||||
.Nm archive_write_set_format_pax_restricted ,
|
.Nm archive_write_set_format_pax_restricted ,
|
||||||
.Nm archive_write_set_format_raw ,
|
.Nm archive_write_set_format_raw ,
|
||||||
.Nm archive_write_set_format_shar ,
|
.Nm archive_write_set_format_shar ,
|
||||||
.Nm archive_write_set_format_shar_dump ,
|
.Nm archive_write_set_format_shar_dump ,
|
||||||
.Nm archive_write_set_format_ustar ,
|
.Nm archive_write_set_format_ustar ,
|
||||||
.Nm archive_write_set_format_filter_by_ext ,
|
.Nm archive_write_set_format_v7tar ,
|
||||||
.Nm archive_write_set_format_filter_by_ext_def
|
.Nm archive_write_set_format_warc ,
|
||||||
|
.Nm archive_write_set_format_xar ,
|
||||||
|
.Nm archive_write_set_format_zip ,
|
||||||
.Nd functions for creating archives
|
.Nd functions for creating archives
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
Streaming Archive Library (libarchive, -larchive)
|
Streaming Archive Library (libarchive, -larchive)
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.In archive.h
|
.In archive.h
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn archive_write_set_format "struct archive *" "int code"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_7zip "struct archive *"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_ar "struct archive *"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_ar_bsd "struct archive *"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_ar_svr4 "struct archive *"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_by_name "struct archive *" "const char *name"
|
||||||
|
.Ft int
|
||||||
.Fn archive_write_set_format_cpio "struct archive *"
|
.Fn archive_write_set_format_cpio "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_cpio_newc "struct archive *"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_filter_by_ext "struct archive *" "const char *filename"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_filter_by_ext_def "struct archive *" "const char *filename" "const char *def_ext"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_gnutar "struct archive *"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_iso9660 "struct archive *"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_mtree "struct archive *"
|
||||||
|
.Ft int
|
||||||
.Fn archive_write_set_format_pax "struct archive *"
|
.Fn archive_write_set_format_pax "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_write_set_format_pax_restricted "struct archive *"
|
.Fn archive_write_set_format_pax_restricted "struct archive *"
|
||||||
|
@ -57,42 +97,60 @@ Streaming Archive Library (libarchive, -larchive)
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_write_set_format_ustar "struct archive *"
|
.Fn archive_write_set_format_ustar "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_write_set_format_filter_by_ext "struct archive *" "const char *"
|
.Fn archive_write_set_format_v7tar "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_write_set_format_filter_by_ext_def "struct archive *" "const char *" "const char *"
|
.Fn archive_write_set_format_warc "struct archive *"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_xar "struct archive *"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_write_set_format_zip "struct archive *"
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
These functions set the format that will be used for the archive.
|
These functions set the format that will be used for the archive.
|
||||||
.Pp
|
.Pp
|
||||||
The library can write
|
The library can write a variety of common archive formats.
|
||||||
POSIX octet-oriented cpio format archives,
|
|
||||||
POSIX-standard
|
|
||||||
.Dq pax interchange
|
|
||||||
format archives,
|
|
||||||
traditional
|
|
||||||
.Dq shar
|
|
||||||
archives,
|
|
||||||
enhanced
|
|
||||||
.Dq dump
|
|
||||||
shar archives that store a variety of file attributes and handle binary files,
|
|
||||||
and
|
|
||||||
POSIX-standard
|
|
||||||
.Dq ustar
|
|
||||||
archives.
|
|
||||||
The pax interchange format is a backwards-compatible tar format that
|
|
||||||
adds key/value attributes to each entry and supports arbitrary
|
|
||||||
filenames, linknames, uids, sizes, etc.
|
|
||||||
.Dq Restricted pax interchange format
|
|
||||||
is the library default; this is the same as pax format, but suppresses
|
|
||||||
the pax extended header for most normal files.
|
|
||||||
In most cases, this will result in ordinary ustar archives.
|
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
.It Fn archive_write_set_format
|
||||||
|
Sets the format based on the format code (see
|
||||||
|
.Pa archive.h
|
||||||
|
for the full list of format codes).
|
||||||
|
In particular, this can be used in conjunction with
|
||||||
|
.Fn archive_format
|
||||||
|
to create a new archive with the same format as an existing archive.
|
||||||
|
.It Fn archive_write_set_format_by_name
|
||||||
|
Sets the corresponding format based on the common name.
|
||||||
.It Xo
|
.It Xo
|
||||||
.Fn archive_write_set_format_filter_by_ext ,
|
.Fn archive_write_set_format_filter_by_ext ,
|
||||||
.Fn archive_write_set_format_filter_by_ext_def
|
.Fn archive_write_set_format_filter_by_ext_def
|
||||||
.Xc
|
.Xc
|
||||||
Format and filter for archive can be set automatically, based on output file name extension.
|
Sets both filters and format based on the output filename.
|
||||||
The functions are platform dependent.
|
|
||||||
Supported extensions: .7z, .zip, .jar, .cpio, .iso, .a, .ar, .tar, .tgz, .tar.gz, .tar.bz2, .tar.xz
|
Supported extensions: .7z, .zip, .jar, .cpio, .iso, .a, .ar, .tar, .tgz, .tar.gz, .tar.bz2, .tar.xz
|
||||||
|
.It Xo
|
||||||
|
.Fn archive_write_set_format_7zip
|
||||||
|
.Fn archive_write_set_format_ar_bsd ,
|
||||||
|
.Fn archive_write_set_format_ar_svr4 ,
|
||||||
|
.Fn archive_write_set_format_cpio
|
||||||
|
.Fn archive_write_set_format_cpio_newc
|
||||||
|
.Fn archive_write_set_format_gnutar
|
||||||
|
.Fn archive_write_set_format_iso9660
|
||||||
|
.Fn archive_write_set_format_mtree
|
||||||
|
.Fn archive_write_set_format_mtree_classic
|
||||||
|
.Fn archive_write_set_format_pax
|
||||||
|
.Fn archive_write_set_format_pax_restricted
|
||||||
|
.Fn archive_write_set_format_raw
|
||||||
|
.Fn archive_write_set_format_shar
|
||||||
|
.Fn archive_write_set_format_shar_dump
|
||||||
|
.Fn archive_write_set_format_ustar
|
||||||
|
.Fn archive_write_set_format_v7tar
|
||||||
|
.Fn archive_write_set_format_warc
|
||||||
|
.Fn archive_write_set_format_xar
|
||||||
|
.Fn archive_write_set_format_zip
|
||||||
|
.Xc
|
||||||
|
Set the format as specified.
|
||||||
|
More details on the formats supported by libarchive can be found in the
|
||||||
|
.Xr libarchive-formats 5
|
||||||
|
manual page.
|
||||||
|
.El
|
||||||
.\"
|
.\"
|
||||||
.Sh RETURN VALUES
|
.Sh RETURN VALUES
|
||||||
These functions return
|
These functions return
|
||||||
|
@ -113,5 +171,6 @@ functions.
|
||||||
.Xr archive_write 3 ,
|
.Xr archive_write 3 ,
|
||||||
.Xr archive_write_set_options 3 ,
|
.Xr archive_write_set_options 3 ,
|
||||||
.Xr cpio 5 ,
|
.Xr cpio 5 ,
|
||||||
|
.Xr libarchive-formats 5 ,
|
||||||
.Xr mtree 5 ,
|
.Xr mtree 5 ,
|
||||||
.Xr tar 5
|
.Xr tar 5
|
||||||
|
|
|
@ -144,7 +144,7 @@ __archive_write_format_header_ustar(struct archive_write *, char buff[512],
|
||||||
struct archive_string_conv *);
|
struct archive_string_conv *);
|
||||||
|
|
||||||
struct archive_write_program_data;
|
struct archive_write_program_data;
|
||||||
struct archive_write_program_data * __archive_write_program_allocate(void);
|
struct archive_write_program_data * __archive_write_program_allocate(const char *program_name);
|
||||||
int __archive_write_program_free(struct archive_write_program_data *);
|
int __archive_write_program_free(struct archive_write_program_data *);
|
||||||
int __archive_write_program_open(struct archive_write_filter *,
|
int __archive_write_program_open(struct archive_write_filter *,
|
||||||
struct archive_write_program_data *, const char *);
|
struct archive_write_program_data *, const char *);
|
||||||
|
|
|
@ -1450,6 +1450,10 @@ _7z_free(struct archive_write *a)
|
||||||
{
|
{
|
||||||
struct _7zip *zip = (struct _7zip *)a->format_data;
|
struct _7zip *zip = (struct _7zip *)a->format_data;
|
||||||
|
|
||||||
|
/* Close the temporary file. */
|
||||||
|
if (zip->temp_fd >= 0)
|
||||||
|
close(zip->temp_fd);
|
||||||
|
|
||||||
file_free_register(zip);
|
file_free_register(zip);
|
||||||
compression_end(&(a->archive), &(zip->stream));
|
compression_end(&(a->archive), &(zip->stream));
|
||||||
free(zip->coder.props);
|
free(zip->coder.props);
|
||||||
|
|
|
@ -1036,22 +1036,12 @@ archive_write_pax_header(struct archive_write *a,
|
||||||
need_extension = 1;
|
need_extension = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following items are handled differently in "pax
|
* Libarchive used to include these in extended headers for
|
||||||
* restricted" format. In particular, in "pax restricted"
|
* restricted pax format, but that confused people who
|
||||||
* format they won't be added unless need_extension is
|
* expected ustar-like time semantics. So now we only include
|
||||||
* already set (we're already generating an extended header, so
|
* them in full pax format.
|
||||||
* may as well include these).
|
|
||||||
*/
|
*/
|
||||||
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
|
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED) {
|
||||||
need_extension) {
|
|
||||||
|
|
||||||
if (archive_entry_mtime(entry_main) < 0 ||
|
|
||||||
archive_entry_mtime(entry_main) >= 0x7fffffff ||
|
|
||||||
archive_entry_mtime_nsec(entry_main) != 0)
|
|
||||||
add_pax_attr_time(&(pax->pax_header), "mtime",
|
|
||||||
archive_entry_mtime(entry_main),
|
|
||||||
archive_entry_mtime_nsec(entry_main));
|
|
||||||
|
|
||||||
if (archive_entry_ctime(entry_main) != 0 ||
|
if (archive_entry_ctime(entry_main) != 0 ||
|
||||||
archive_entry_ctime_nsec(entry_main) != 0)
|
archive_entry_ctime_nsec(entry_main) != 0)
|
||||||
add_pax_attr_time(&(pax->pax_header), "ctime",
|
add_pax_attr_time(&(pax->pax_header), "ctime",
|
||||||
|
@ -1072,6 +1062,23 @@ archive_write_pax_header(struct archive_write *a,
|
||||||
"LIBARCHIVE.creationtime",
|
"LIBARCHIVE.creationtime",
|
||||||
archive_entry_birthtime(entry_main),
|
archive_entry_birthtime(entry_main),
|
||||||
archive_entry_birthtime_nsec(entry_main));
|
archive_entry_birthtime_nsec(entry_main));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following items are handled differently in "pax
|
||||||
|
* restricted" format. In particular, in "pax restricted"
|
||||||
|
* format they won't be added unless need_extension is
|
||||||
|
* already set (we're already generating an extended header, so
|
||||||
|
* may as well include these).
|
||||||
|
*/
|
||||||
|
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
|
||||||
|
need_extension) {
|
||||||
|
if (archive_entry_mtime(entry_main) < 0 ||
|
||||||
|
archive_entry_mtime(entry_main) >= 0x7fffffff ||
|
||||||
|
archive_entry_mtime_nsec(entry_main) != 0)
|
||||||
|
add_pax_attr_time(&(pax->pax_header), "mtime",
|
||||||
|
archive_entry_mtime(entry_main),
|
||||||
|
archive_entry_mtime_nsec(entry_main));
|
||||||
|
|
||||||
/* I use a star-compatible file flag attribute. */
|
/* I use a star-compatible file flag attribute. */
|
||||||
p = archive_entry_fflags_text(entry_main);
|
p = archive_entry_fflags_text(entry_main);
|
||||||
|
|
|
@ -186,16 +186,18 @@ _warc_header(struct archive_write *a, struct archive_entry *entry)
|
||||||
|
|
||||||
/* check whether warcinfo record needs outputting */
|
/* check whether warcinfo record needs outputting */
|
||||||
if (!w->omit_warcinfo) {
|
if (!w->omit_warcinfo) {
|
||||||
|
ssize_t r;
|
||||||
warc_essential_hdr_t wi = {
|
warc_essential_hdr_t wi = {
|
||||||
WT_INFO,
|
WT_INFO,
|
||||||
/*uri*/NULL,
|
/*uri*/NULL,
|
||||||
/*urn*/NULL,
|
/*urn*/NULL,
|
||||||
/*rtm*/w->now,
|
/*rtm*/0,
|
||||||
/*mtm*/w->now,
|
/*mtm*/0,
|
||||||
/*cty*/"application/warc-fields",
|
/*cty*/"application/warc-fields",
|
||||||
/*len*/sizeof(warcinfo) - 1U,
|
/*len*/sizeof(warcinfo) - 1U,
|
||||||
};
|
};
|
||||||
ssize_t r;
|
wi.rtime = w->now;
|
||||||
|
wi.mtime = w->now;
|
||||||
|
|
||||||
archive_string_init(&hdr);
|
archive_string_init(&hdr);
|
||||||
r = _popul_ehdr(&hdr, MAX_HDR_SIZE, wi);
|
r = _popul_ehdr(&hdr, MAX_HDR_SIZE, wi);
|
||||||
|
@ -226,14 +228,18 @@ _warc_header(struct archive_write *a, struct archive_entry *entry)
|
||||||
if (w->typ == AE_IFREG) {
|
if (w->typ == AE_IFREG) {
|
||||||
warc_essential_hdr_t rh = {
|
warc_essential_hdr_t rh = {
|
||||||
WT_RSRC,
|
WT_RSRC,
|
||||||
/*uri*/archive_entry_pathname(entry),
|
/*uri*/NULL,
|
||||||
/*urn*/NULL,
|
/*urn*/NULL,
|
||||||
/*rtm*/w->now,
|
/*rtm*/0,
|
||||||
/*mtm*/archive_entry_mtime(entry),
|
/*mtm*/0,
|
||||||
/*cty*/NULL,
|
/*cty*/NULL,
|
||||||
/*len*/(size_t)archive_entry_size(entry),
|
/*len*/0,
|
||||||
};
|
};
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
|
rh.tgturi = archive_entry_pathname(entry);
|
||||||
|
rh.rtime = w->now;
|
||||||
|
rh.mtime = archive_entry_mtime(entry);
|
||||||
|
rh.cntlen = (size_t)archive_entry_size(entry);
|
||||||
|
|
||||||
archive_string_init(&hdr);
|
archive_string_init(&hdr);
|
||||||
r = _popul_ehdr(&hdr, MAX_HDR_SIZE, rh);
|
r = _popul_ehdr(&hdr, MAX_HDR_SIZE, rh);
|
||||||
|
@ -325,16 +331,16 @@ xstrftime(struct archive_string *as, const char *fmt, time_t t)
|
||||||
/** like strftime(3) but for time_t objects */
|
/** like strftime(3) but for time_t objects */
|
||||||
struct tm *rt;
|
struct tm *rt;
|
||||||
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
|
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
|
||||||
struct tm time;
|
struct tm timeHere;
|
||||||
#endif
|
#endif
|
||||||
char strtime[100];
|
char strtime[100];
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
#ifdef HAVE_GMTIME_R
|
#ifdef HAVE_GMTIME_R
|
||||||
if ((rt = gmtime_r(&t, &time)) == NULL)
|
if ((rt = gmtime_r(&t, &timeHere)) == NULL)
|
||||||
return;
|
return;
|
||||||
#elif defined(HAVE__GMTIME64_S)
|
#elif defined(HAVE__GMTIME64_S)
|
||||||
_gmtime64_s(&time, &t);
|
_gmtime64_s(&timeHere, &t);
|
||||||
#else
|
#else
|
||||||
if ((rt = gmtime(&t)) == NULL)
|
if ((rt = gmtime(&t)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -396,7 +402,7 @@ _popul_ehdr(struct archive_string *tgt, size_t tsz, warc_essential_hdr_t hdr)
|
||||||
* handle the minimum number following '%'.
|
* handle the minimum number following '%'.
|
||||||
* So we have to use snprintf function here instead
|
* So we have to use snprintf function here instead
|
||||||
* of archive_string_snprintf function. */
|
* of archive_string_snprintf function. */
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__) && !( defined(_MSC_VER) && _MSC_VER >= 1900)
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
snprintf(
|
snprintf(
|
||||||
|
|
|
@ -1877,6 +1877,11 @@ xar_free(struct archive_write *a)
|
||||||
struct xar *xar;
|
struct xar *xar;
|
||||||
|
|
||||||
xar = (struct xar *)a->format_data;
|
xar = (struct xar *)a->format_data;
|
||||||
|
|
||||||
|
/* Close the temporary file. */
|
||||||
|
if (xar->temp_fd >= 0)
|
||||||
|
close(xar->temp_fd);
|
||||||
|
|
||||||
archive_string_free(&(xar->cur_dirstr));
|
archive_string_free(&(xar->cur_dirstr));
|
||||||
archive_string_free(&(xar->tstr));
|
archive_string_free(&(xar->tstr));
|
||||||
archive_string_free(&(xar->vstr));
|
archive_string_free(&(xar->vstr));
|
||||||
|
|
|
@ -66,6 +66,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 20
|
||||||
#define ZIP_ENTRY_FLAG_LENGTH_AT_END (1<<3)
|
#define ZIP_ENTRY_FLAG_LENGTH_AT_END (1<<3)
|
||||||
#define ZIP_ENTRY_FLAG_UTF8_NAME (1 << 11)
|
#define ZIP_ENTRY_FLAG_UTF8_NAME (1 << 11)
|
||||||
|
|
||||||
|
#define ZIP_4GB_MAX ARCHIVE_LITERAL_LL(0xffffffff)
|
||||||
|
#define ZIP_4GB_MAX_UNCOMPRESSED ARCHIVE_LITERAL_LL(0xff000000)
|
||||||
|
|
||||||
enum compression {
|
enum compression {
|
||||||
COMPRESSION_UNSPECIFIED = -1,
|
COMPRESSION_UNSPECIFIED = -1,
|
||||||
COMPRESSION_STORE = 0,
|
COMPRESSION_STORE = 0,
|
||||||
|
@ -532,14 +535,13 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
||||||
if (zip->flags & ZIP_FLAG_AVOID_ZIP64) {
|
if (zip->flags & ZIP_FLAG_AVOID_ZIP64) {
|
||||||
/* Reject entries over 4GB. */
|
/* Reject entries over 4GB. */
|
||||||
if (archive_entry_size_is_set(entry)
|
if (archive_entry_size_is_set(entry)
|
||||||
&& (archive_entry_size(entry) >
|
&& (archive_entry_size(entry) > ZIP_4GB_MAX)) {
|
||||||
ARCHIVE_LITERAL_LL(0xffffffff))) {
|
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||||
"Files > 4GB require Zip64 extensions");
|
"Files > 4GB require Zip64 extensions");
|
||||||
return ARCHIVE_FAILED;
|
return ARCHIVE_FAILED;
|
||||||
}
|
}
|
||||||
/* Reject entries if archive is > 4GB. */
|
/* Reject entries if archive is > 4GB. */
|
||||||
if (zip->written_bytes > ARCHIVE_LITERAL_LL(0xffffffff)) {
|
if (zip->written_bytes > ZIP_4GB_MAX) {
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||||
"Archives > 4GB require Zip64 extensions");
|
"Archives > 4GB require Zip64 extensions");
|
||||||
return ARCHIVE_FAILED;
|
return ARCHIVE_FAILED;
|
||||||
|
@ -727,10 +729,8 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
||||||
* (compression might make file larger)
|
* (compression might make file larger)
|
||||||
*/
|
*/
|
||||||
if ((zip->flags & ZIP_FLAG_FORCE_ZIP64)
|
if ((zip->flags & ZIP_FLAG_FORCE_ZIP64)
|
||||||
|| (zip->entry_uncompressed_size + additional_size >
|
|| (zip->entry_uncompressed_size + additional_size > ZIP_4GB_MAX)
|
||||||
ARCHIVE_LITERAL_LL(0xffffffff))
|
|| (zip->entry_uncompressed_size > ZIP_4GB_MAX_UNCOMPRESSED
|
||||||
|| (zip->entry_uncompressed_size >
|
|
||||||
ARCHIVE_LITERAL_LL(0xff000000)
|
|
||||||
&& zip->entry_compression != COMPRESSION_STORE)) {
|
&& zip->entry_compression != COMPRESSION_STORE)) {
|
||||||
zip->entry_uses_zip64 = 1;
|
zip->entry_uses_zip64 = 1;
|
||||||
version_needed = 45;
|
version_needed = 45;
|
||||||
|
@ -788,8 +788,8 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
||||||
* are included only if these are 0xffffffff;
|
* are included only if these are 0xffffffff;
|
||||||
* THEREFORE these must be set this way, even if we
|
* THEREFORE these must be set this way, even if we
|
||||||
* know one of them is smaller. */
|
* know one of them is smaller. */
|
||||||
archive_le32enc(local_header + 18, ARCHIVE_LITERAL_LL(0xffffffff));
|
archive_le32enc(local_header + 18, ZIP_4GB_MAX);
|
||||||
archive_le32enc(local_header + 22, ARCHIVE_LITERAL_LL(0xffffffff));
|
archive_le32enc(local_header + 22, ZIP_4GB_MAX);
|
||||||
} else {
|
} else {
|
||||||
archive_le32enc(local_header + 18, (uint32_t)zip->entry_compressed_size);
|
archive_le32enc(local_header + 18, (uint32_t)zip->entry_compressed_size);
|
||||||
archive_le32enc(local_header + 22, (uint32_t)zip->entry_uncompressed_size);
|
archive_le32enc(local_header + 22, (uint32_t)zip->entry_uncompressed_size);
|
||||||
|
@ -1217,22 +1217,22 @@ archive_write_zip_finish_entry(struct archive_write *a)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append Zip64 extra data to central directory information. */
|
/* Append Zip64 extra data to central directory information. */
|
||||||
if (zip->entry_compressed_written > ARCHIVE_LITERAL_LL(0xffffffff)
|
if (zip->entry_compressed_written > ZIP_4GB_MAX
|
||||||
|| zip->entry_uncompressed_written > ARCHIVE_LITERAL_LL(0xffffffff)
|
|| zip->entry_uncompressed_written > ZIP_4GB_MAX
|
||||||
|| zip->entry_offset > ARCHIVE_LITERAL_LL(0xffffffff)) {
|
|| zip->entry_offset > ZIP_4GB_MAX) {
|
||||||
unsigned char zip64[32];
|
unsigned char zip64[32];
|
||||||
unsigned char *z = zip64, *zd;
|
unsigned char *z = zip64, *zd;
|
||||||
memcpy(z, "\001\000\000\000", 4);
|
memcpy(z, "\001\000\000\000", 4);
|
||||||
z += 4;
|
z += 4;
|
||||||
if (zip->entry_uncompressed_written >= ARCHIVE_LITERAL_LL(0xffffffff)) {
|
if (zip->entry_uncompressed_written >= ZIP_4GB_MAX) {
|
||||||
archive_le64enc(z, zip->entry_uncompressed_written);
|
archive_le64enc(z, zip->entry_uncompressed_written);
|
||||||
z += 8;
|
z += 8;
|
||||||
}
|
}
|
||||||
if (zip->entry_compressed_written >= ARCHIVE_LITERAL_LL(0xffffffff)) {
|
if (zip->entry_compressed_written >= ZIP_4GB_MAX) {
|
||||||
archive_le64enc(z, zip->entry_compressed_written);
|
archive_le64enc(z, zip->entry_compressed_written);
|
||||||
z += 8;
|
z += 8;
|
||||||
}
|
}
|
||||||
if (zip->entry_offset >= ARCHIVE_LITERAL_LL(0xffffffff)) {
|
if (zip->entry_offset >= ZIP_4GB_MAX) {
|
||||||
archive_le64enc(z, zip->entry_offset);
|
archive_le64enc(z, zip->entry_offset);
|
||||||
z += 8;
|
z += 8;
|
||||||
}
|
}
|
||||||
|
@ -1256,15 +1256,15 @@ archive_write_zip_finish_entry(struct archive_write *a)
|
||||||
archive_le32enc(zip->file_header + 16, zip->entry_crc32);
|
archive_le32enc(zip->file_header + 16, zip->entry_crc32);
|
||||||
archive_le32enc(zip->file_header + 20,
|
archive_le32enc(zip->file_header + 20,
|
||||||
(uint32_t)zipmin(zip->entry_compressed_written,
|
(uint32_t)zipmin(zip->entry_compressed_written,
|
||||||
ARCHIVE_LITERAL_LL(0xffffffff)));
|
ZIP_4GB_MAX));
|
||||||
archive_le32enc(zip->file_header + 24,
|
archive_le32enc(zip->file_header + 24,
|
||||||
(uint32_t)zipmin(zip->entry_uncompressed_written,
|
(uint32_t)zipmin(zip->entry_uncompressed_written,
|
||||||
ARCHIVE_LITERAL_LL(0xffffffff)));
|
ZIP_4GB_MAX));
|
||||||
archive_le16enc(zip->file_header + 30,
|
archive_le16enc(zip->file_header + 30,
|
||||||
(uint16_t)(zip->central_directory_bytes - zip->file_header_extra_offset));
|
(uint16_t)(zip->central_directory_bytes - zip->file_header_extra_offset));
|
||||||
archive_le32enc(zip->file_header + 42,
|
archive_le32enc(zip->file_header + 42,
|
||||||
(uint32_t)zipmin(zip->entry_offset,
|
(uint32_t)zipmin(zip->entry_offset,
|
||||||
ARCHIVE_LITERAL_LL(0xffffffff)));
|
ZIP_4GB_MAX));
|
||||||
|
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
|
@ -1291,8 +1291,8 @@ archive_write_zip_close(struct archive_write *a)
|
||||||
offset_end = zip->written_bytes;
|
offset_end = zip->written_bytes;
|
||||||
|
|
||||||
/* If central dir info is too large, write Zip64 end-of-cd */
|
/* If central dir info is too large, write Zip64 end-of-cd */
|
||||||
if (offset_end - offset_start > ARCHIVE_LITERAL_LL(0xffffffff)
|
if (offset_end - offset_start > ZIP_4GB_MAX
|
||||||
|| offset_start > ARCHIVE_LITERAL_LL(0xffffffff)
|
|| offset_start > ZIP_4GB_MAX
|
||||||
|| zip->central_directory_entries > 0xffffUL
|
|| zip->central_directory_entries > 0xffffUL
|
||||||
|| (zip->flags & ZIP_FLAG_FORCE_ZIP64)) {
|
|| (zip->flags & ZIP_FLAG_FORCE_ZIP64)) {
|
||||||
/* Zip64 end-of-cd record */
|
/* Zip64 end-of-cd record */
|
||||||
|
@ -1332,11 +1332,9 @@ archive_write_zip_close(struct archive_write *a)
|
||||||
archive_le16enc(buff + 10, (uint16_t)zipmin(0xffffU,
|
archive_le16enc(buff + 10, (uint16_t)zipmin(0xffffU,
|
||||||
zip->central_directory_entries));
|
zip->central_directory_entries));
|
||||||
archive_le32enc(buff + 12,
|
archive_le32enc(buff + 12,
|
||||||
(uint32_t)zipmin(ARCHIVE_LITERAL_LL(0xffffffff),
|
(uint32_t)zipmin(ZIP_4GB_MAX, (offset_end - offset_start)));
|
||||||
(offset_end - offset_start)));
|
|
||||||
archive_le32enc(buff + 16,
|
archive_le32enc(buff + 16,
|
||||||
(uint32_t)zipmin(ARCHIVE_LITERAL_LL(0xffffffff),
|
(uint32_t)zipmin(ZIP_4GB_MAX, offset_start));
|
||||||
offset_start));
|
|
||||||
ret = __archive_write_output(a, buff, 22);
|
ret = __archive_write_output(a, buff, 22);
|
||||||
if (ret != ARCHIVE_OK)
|
if (ret != ARCHIVE_OK)
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
|
|
|
@ -101,7 +101,12 @@ and
|
||||||
.Ar value
|
.Ar value
|
||||||
will be provided to the filter or reader named
|
will be provided to the filter or reader named
|
||||||
.Ar module .
|
.Ar module .
|
||||||
The return value will be that of the module.
|
The return value will be either
|
||||||
|
.Cm ARCHIVE_OK
|
||||||
|
if the option was successfully handled or
|
||||||
|
.Cm ARCHIVE_WARN
|
||||||
|
if the option was unrecognized by the module or could otherwise
|
||||||
|
not be handled.
|
||||||
If there is no such module,
|
If there is no such module,
|
||||||
.Cm ARCHIVE_FAILED
|
.Cm ARCHIVE_FAILED
|
||||||
will be returned.
|
will be returned.
|
||||||
|
@ -123,9 +128,7 @@ will be returned if any module accepts the option, and
|
||||||
.Cm ARCHIVE_FAILED
|
.Cm ARCHIVE_FAILED
|
||||||
in all other cases.
|
in all other cases.
|
||||||
.\"
|
.\"
|
||||||
.It Xo
|
.It Fn archive_write_set_option
|
||||||
.Fn archive_write_set_option
|
|
||||||
.Xc
|
|
||||||
Calls
|
Calls
|
||||||
.Fn archive_write_set_format_option ,
|
.Fn archive_write_set_format_option ,
|
||||||
then
|
then
|
||||||
|
@ -137,9 +140,7 @@ will be returned
|
||||||
immediately.
|
immediately.
|
||||||
Otherwise, greater of the two values will be returned.
|
Otherwise, greater of the two values will be returned.
|
||||||
.\"
|
.\"
|
||||||
.It Xo
|
.It Fn archive_write_set_options
|
||||||
.Fn archive_write_set_options
|
|
||||||
.Xc
|
|
||||||
.Ar options
|
.Ar options
|
||||||
is a comma-separated list of options.
|
is a comma-separated list of options.
|
||||||
If
|
If
|
||||||
|
@ -456,7 +457,7 @@ archive_write_open_filename(a, filename, blocksize);
|
||||||
.Ed
|
.Ed
|
||||||
.\"
|
.\"
|
||||||
.Sh ERRORS
|
.Sh ERRORS
|
||||||
Detailed error codes and textual descriptions are available from the
|
More detailed error codes and textual descriptions are available from the
|
||||||
.Fn archive_errno
|
.Fn archive_errno
|
||||||
and
|
and
|
||||||
.Fn archive_error_string
|
.Fn archive_error_string
|
||||||
|
|
|
@ -55,7 +55,7 @@ It can write POSIX-standard
|
||||||
.Dq ustar
|
.Dq ustar
|
||||||
and
|
and
|
||||||
.Dq pax interchange
|
.Dq pax interchange
|
||||||
formats and a subset of the legacy GNU tar format.
|
formats as well as v7 tar format and a subset of the legacy GNU tar format.
|
||||||
.Pp
|
.Pp
|
||||||
All tar formats store each entry in one or more 512-byte records.
|
All tar formats store each entry in one or more 512-byte records.
|
||||||
The first record is used for file metadata, including filename,
|
The first record is used for file metadata, including filename,
|
||||||
|
@ -150,6 +150,30 @@ Archive entries are limited to 8 gigabytes in size.
|
||||||
Note that the pax interchange format has none of these restrictions.
|
Note that the pax interchange format has none of these restrictions.
|
||||||
The ustar format is old and widely supported.
|
The ustar format is old and widely supported.
|
||||||
It is recommended when compatibility is the primary concern.
|
It is recommended when compatibility is the primary concern.
|
||||||
|
.It Cm v7
|
||||||
|
The libarchive library can read and write the legacy v7 tar format.
|
||||||
|
This format has the following limitations:
|
||||||
|
.Bl -bullet -compact
|
||||||
|
.It
|
||||||
|
Only regular files, directories, and symbolic links can be archived.
|
||||||
|
Block and character device nodes, FIFOs, and sockets cannot be archived.
|
||||||
|
.It
|
||||||
|
Path names in the archive are limited to 100 bytes.
|
||||||
|
.It
|
||||||
|
Symbolic links and hard links are stored in the archive with
|
||||||
|
the name of the referenced file.
|
||||||
|
This name is limited to 100 bytes.
|
||||||
|
.It
|
||||||
|
User and group information are stored as numeric IDs; there
|
||||||
|
is no provision for storing user or group names.
|
||||||
|
.It
|
||||||
|
Extended attributes, file flags, and other extended
|
||||||
|
security information cannot be stored.
|
||||||
|
.It
|
||||||
|
Archive entries are limited to 8 gigabytes in size.
|
||||||
|
.El
|
||||||
|
Generally, users should prefer the ustar format for portability
|
||||||
|
as the v7 tar format is both less useful and less portable.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The libarchive library also reads a variety of commonly-used extensions to
|
The libarchive library also reads a variety of commonly-used extensions to
|
||||||
|
@ -211,7 +235,7 @@ This format stores the header contents as octal values in ASCII.
|
||||||
It is standard, portable, and immune from byte-order confusion.
|
It is standard, portable, and immune from byte-order confusion.
|
||||||
File sizes and mtime are limited to 33 bits (8GB file size),
|
File sizes and mtime are limited to 33 bits (8GB file size),
|
||||||
other fields are limited to 18 bits.
|
other fields are limited to 18 bits.
|
||||||
.It Cm SVR4
|
.It Cm SVR4/newc
|
||||||
The libarchive library can read both CRC and non-CRC variants of
|
The libarchive library can read both CRC and non-CRC variants of
|
||||||
this format.
|
this format.
|
||||||
The SVR4 format uses eight-digit hexadecimal values for
|
The SVR4 format uses eight-digit hexadecimal values for
|
||||||
|
@ -364,8 +388,10 @@ area adjacent to the entry.
|
||||||
Libarchive can read both extensions,
|
Libarchive can read both extensions,
|
||||||
including archives that may include both types of long filenames.
|
including archives that may include both types of long filenames.
|
||||||
Programs using libarchive can write GNU/SVR4 format
|
Programs using libarchive can write GNU/SVR4 format
|
||||||
if they provide a filename table to be written into
|
if they provide an entry called
|
||||||
the archive before any of the entries.
|
.Pa //
|
||||||
|
containing a filename table to be written into the archive
|
||||||
|
before any of the entries.
|
||||||
Any entries whose names are not in the filename table
|
Any entries whose names are not in the filename table
|
||||||
will be written using BSD-style long filenames.
|
will be written using BSD-style long filenames.
|
||||||
This can cause problems for programs such as
|
This can cause problems for programs such as
|
||||||
|
@ -406,18 +432,29 @@ using libarchive.
|
||||||
If it cannot locate and open the file on disk, libarchive
|
If it cannot locate and open the file on disk, libarchive
|
||||||
will return an error for any attempt to read the entry
|
will return an error for any attempt to read the entry
|
||||||
body.
|
body.
|
||||||
.Ss LHA
|
.Ss 7-Zip
|
||||||
XXX Information about libarchive's LHA support XXX
|
Libarchive can read and write 7-Zip format archives.
|
||||||
|
TODO: Need more information
|
||||||
.Ss CAB
|
.Ss CAB
|
||||||
XXX Information about libarchive's CAB support XXX
|
Libarchive can read Microsoft Cabinet (
|
||||||
.Ss XAR
|
.Dq CAB )
|
||||||
XXX Information about libarchive's XAR support XXX
|
format archives.
|
||||||
|
TODO: Need more information.
|
||||||
|
.Ss LHA
|
||||||
|
TODO: Information about libarchive's LHA support
|
||||||
.Ss RAR
|
.Ss RAR
|
||||||
Libarchive has limited support for reading RAR format archives.
|
Libarchive has limited support for reading RAR format archives.
|
||||||
Currently, libarchive can read RARv3 format archives
|
Currently, libarchive can read RARv3 format archives
|
||||||
which have been either created uncompressed, or compressed using
|
which have been either created uncompressed, or compressed using
|
||||||
any of the compression methods supported by the RARv3 format.
|
any of the compression methods supported by the RARv3 format.
|
||||||
Libarchive can also read self-extracting RAR archives.
|
Libarchive can also read self-extracting RAR archives.
|
||||||
|
.Ss Warc
|
||||||
|
Libarchive can read and write
|
||||||
|
.Dq web archives .
|
||||||
|
TODO: Need more information
|
||||||
|
.Ss XAR
|
||||||
|
Libarchive can read and write the XAR format used by many Apple tools.
|
||||||
|
TODO: Need more information
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr ar 1 ,
|
.Xr ar 1 ,
|
||||||
.Xr cpio 1 ,
|
.Xr cpio 1 ,
|
||||||
|
|
|
@ -29,8 +29,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
You can contact the author at :
|
You can contact the author at :
|
||||||
- xxHash source repository : http://code.google.com/p/xxhash/
|
- xxHash source repository : http://code.google.com/p/xxhash/
|
||||||
*/
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "archive_platform.h"
|
#include "archive_platform.h"
|
||||||
|
#include "archive_xxhash.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBLZ4
|
#ifdef HAVE_LIBLZ4
|
||||||
|
|
||||||
/***************************************
|
/***************************************
|
||||||
|
@ -83,11 +87,8 @@ You can contact the author at :
|
||||||
/***************************************
|
/***************************************
|
||||||
** Includes & Memory related functions
|
** Includes & Memory related functions
|
||||||
****************************************/
|
****************************************/
|
||||||
#include "archive_xxhash.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#define XXH_malloc malloc
|
#define XXH_malloc malloc
|
||||||
#define XXH_free free
|
#define XXH_free free
|
||||||
#include <string.h>
|
|
||||||
#define XXH_memcpy memcpy
|
#define XXH_memcpy memcpy
|
||||||
|
|
||||||
|
|
||||||
|
@ -497,4 +498,17 @@ struct archive_xxhash __archive_xxhash = {
|
||||||
XXH32_update,
|
XXH32_update,
|
||||||
XXH32_digest
|
XXH32_digest
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define an empty version of the struct if we aren't using the LZ4 library.
|
||||||
|
*/
|
||||||
|
const
|
||||||
|
struct archive_xxhash __archive_xxhash = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* HAVE_LIBLZ4 */
|
#endif /* HAVE_LIBLZ4 */
|
||||||
|
|
Loading…
Reference in New Issue