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)
|
||||
|
||||
IF(WIN32)
|
||||
IF(MSVC60)
|
||||
SET(WINVER 0x0400)
|
||||
ELSE()
|
||||
SET(WINVER 0x0500)
|
||||
ENDIF()
|
||||
SET(_WIN32_WINNT ${WINVER})
|
||||
#ELSEIF(WINDOWS_VERSION STREQUAL "WINXP")
|
||||
SET(NTDDI_VERSION 0x05010000)
|
||||
SET(_WIN32_WINNT 0x0501)
|
||||
SET(WINVER 0x0501)
|
||||
ENDIF(WIN32)
|
||||
|
||||
set(HAVE_PTHREAD_H 0) # no threads in CMake
|
||||
|
@ -487,12 +485,17 @@ IF(ENABLE_NETTLE)
|
|||
FIND_PACKAGE(Nettle)
|
||||
IF(NETTLE_FOUND)
|
||||
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})
|
||||
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/ripemd160.h" HAVE_NETTLE_RIPEMD160_H)
|
||||
LA_CHECK_INCLUDE_FILE("nettle/sha.h" HAVE_NETTLE_SHA_H)
|
||||
|
||||
ENDIF(NETTLE_FOUND)
|
||||
MARK_AS_ADVANCED(CLEAR NETTLE_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(CLEAR NETTLE_LIBRARIES)
|
||||
|
@ -506,6 +509,8 @@ IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
|||
FIND_PACKAGE(OpenSSL)
|
||||
IF(OPENSSL_FOUND)
|
||||
SET(HAVE_LIBCRYPTO 1)
|
||||
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
||||
LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_CRYPTO_LIBRARY})
|
||||
ENDIF(OPENSSL_FOUND)
|
||||
ELSE()
|
||||
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")
|
||||
ENDIF ()
|
||||
IF (CMAKE_C_COMPILER_ID STREQUAL "XL")
|
||||
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -qhalt=w -qflag=w:w")
|
||||
ENDIF ()
|
||||
IF (MSVC)
|
||||
# NOTE: /WX option is the same as gcc's -Werror option.
|
||||
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(EILSEQ "errno.h" HAVE_EILSEQ)
|
||||
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_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(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(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. */
|
||||
#if !defined(HAVE_INTMAX_T)
|
||||
typedef int64_t intmax_t;
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_UINTMAX_T)
|
||||
|
@ -367,6 +365,14 @@ typedef uint64_t uintmax_t;
|
|||
/* Define to 1 if you have the `cygwin_conv_path' function. */
|
||||
#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
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_INT64_MAX 1
|
||||
|
@ -375,6 +381,14 @@ typedef uint64_t uintmax_t;
|
|||
don't. */
|
||||
#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
|
||||
don't. */
|
||||
#cmakedefine HAVE_DECL_SIZE_MAX 1
|
||||
|
@ -395,6 +409,10 @@ typedef uint64_t uintmax_t;
|
|||
don't. */
|
||||
#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. */
|
||||
#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'. */
|
||||
#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. */
|
||||
#cmakedefine HAVE_NETTLE_MD5_H 1
|
||||
|
||||
|
@ -1153,7 +1177,11 @@ typedef uint64_t uintmax_t;
|
|||
/* Define for large files, on AIX-style hosts. */
|
||||
#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
|
||||
#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
|
||||
#endif // _WIN32_WINNT
|
||||
|
|
|
@ -1 +1 @@
|
|||
3001002
|
||||
3002000
|
||||
|
|
|
@ -34,6 +34,7 @@ SET(libarchive_SOURCES
|
|||
archive_entry_strmode.c
|
||||
archive_entry_xattr.c
|
||||
archive_getdate.c
|
||||
archive_getdate.h
|
||||
archive_hmac.c
|
||||
archive_hmac_private.h
|
||||
archive_match.c
|
||||
|
|
|
@ -36,11 +36,12 @@
|
|||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||
*/
|
||||
/* 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 <stddef.h> /* for wchar_t */
|
||||
#include <stdio.h> /* For FILE * */
|
||||
#include <time.h> /* For time_t */
|
||||
|
||||
/*
|
||||
* Note: archive.h is for use outside of libarchive; the configuration
|
||||
|
@ -95,6 +96,11 @@ typedef ssize_t la_ssize_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
|
||||
* .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.
|
||||
*/
|
||||
#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
|
||||
__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);
|
||||
|
||||
/*
|
||||
* 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. */
|
||||
struct archive;
|
||||
struct archive_entry;
|
||||
|
|
|
@ -31,6 +31,19 @@
|
|||
#include "archive.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
|
||||
|
||||
static int
|
||||
|
@ -256,7 +269,7 @@ aes_ctr_release(archive_crypto_ctx *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE)
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
|
||||
|
||||
static int
|
||||
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
|
||||
#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__
|
||||
# include <AvailabilityMacros.h>
|
||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||
|
@ -72,7 +83,7 @@ typedef struct {
|
|||
unsigned encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE)
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
|
||||
#if defined(HAVE_NETTLE_PBKDF2_H)
|
||||
#include <nettle/pbkdf2.h>
|
||||
#endif
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* 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
|
||||
|
@ -75,6 +75,11 @@ typedef int64_t la_int64_t;
|
|||
# define __LA_MODE_T mode_t
|
||||
#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
|
||||
* .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_ctime(entry, st->st_ctime, st->st_ctim.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
|
||||
archive_entry_set_atime(entry, st->st_atime, st->st_atime_n);
|
||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_n);
|
||||
|
|
|
@ -38,8 +38,8 @@ __FBSDID("$FreeBSD$");
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
/* This file defines a single public function. */
|
||||
time_t __archive_get_date(time_t now, const char *);
|
||||
#define __LIBARCHIVE_BUILD 1
|
||||
#include "archive_getdate.h"
|
||||
|
||||
/* Basic time units. */
|
||||
#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_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
|
||||
|
||||
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
|
||||
__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
|
||||
#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__
|
||||
# include <AvailabilityMacros.h>
|
||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||
|
@ -53,7 +64,7 @@ typedef struct {
|
|||
|
||||
} archive_hmac_sha1_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE)
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
|
||||
#include <nettle/hmac.h>
|
||||
|
||||
typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
|
||||
|
|
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_getdate.h"
|
||||
#include "archive_pathmatch.h"
|
||||
#include "archive_rb.h"
|
||||
#include "archive_string.h"
|
||||
|
@ -184,7 +185,6 @@ static int time_excluded(struct archive_match *,
|
|||
struct archive_entry *);
|
||||
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
|
||||
|
||||
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);
|
||||
|
||||
mp = m != NULL && m[0] != '\0' ? m : NULL;
|
||||
op = o != NULL && o[0] != '\0' ? o : NULL;
|
||||
vp = v != NULL && v[0] != '\0' ? v : NULL;
|
||||
mp = (m != NULL && m[0] != '\0') ? m : NULL;
|
||||
op = (o != NULL && o[0] != '\0') ? o : NULL;
|
||||
vp = (v != NULL && v[0] != '\0') ? v : NULL;
|
||||
|
||||
if (op == NULL && vp == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
|
|
|
@ -122,6 +122,12 @@
|
|||
#if !HAVE_DECL_UINT32_MAX
|
||||
#define UINT32_MAX (~(uint32_t)0)
|
||||
#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
|
||||
#define UINT64_MAX (~(uint64_t)0)
|
||||
#endif
|
||||
|
@ -131,6 +137,15 @@
|
|||
#if !HAVE_DECL_INT64_MIN
|
||||
#define INT64_MIN ((int64_t)(~INT64_MAX))
|
||||
#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(),
|
||||
|
|
|
@ -547,16 +547,20 @@ archive_read_open1(struct archive *_a)
|
|||
* it wants to handle this stream. Repeat until we've finished
|
||||
* building the pipeline.
|
||||
*/
|
||||
|
||||
/* We won't build a filter pipeline with more stages than this. */
|
||||
#define MAX_NUMBER_FILTERS 25
|
||||
|
||||
static int
|
||||
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 *filter;
|
||||
ssize_t avail;
|
||||
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]);
|
||||
|
||||
best_bid = 0;
|
||||
|
|
|
@ -1046,7 +1046,7 @@ setup_sparse(struct archive_read_disk *a,
|
|||
struct fiemap *fm;
|
||||
struct fiemap_extent *fe;
|
||||
int64_t size;
|
||||
int count, do_fiemap;
|
||||
int count, do_fiemap, iters;
|
||||
int exit_sts = ARCHIVE_OK;
|
||||
|
||||
if (archive_entry_filetype(entry) != AE_IFREG
|
||||
|
@ -1083,7 +1083,7 @@ setup_sparse(struct archive_read_disk *a,
|
|||
fm->fm_extent_count = count;
|
||||
do_fiemap = 1;
|
||||
size = archive_entry_size(entry);
|
||||
for (;;) {
|
||||
for (iters = 0; ; ++iters) {
|
||||
int i, r;
|
||||
|
||||
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. */
|
||||
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;
|
||||
}
|
||||
fe = fm->fm_extents;
|
||||
for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) {
|
||||
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 off_s, off_e; /* FreeBSD/Solaris only, so off_t okay here */
|
||||
int exit_sts = ARCHIVE_OK;
|
||||
int check_fully_sparse = 0;
|
||||
|
||||
if (archive_entry_filetype(entry) != AE_IFREG
|
||||
|| archive_entry_size(entry) <= 0
|
||||
|
@ -1191,8 +1197,14 @@ setup_sparse(struct archive_read_disk *a,
|
|||
while (off_s < size) {
|
||||
off_s = lseek(*fd, off_s, SEEK_DATA);
|
||||
if (off_s == (off_t)-1) {
|
||||
if (errno == ENXIO)
|
||||
break;/* no more hole */
|
||||
if (errno == ENXIO) {
|
||||
/* 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,
|
||||
"lseek(SEEK_HOLE) failed");
|
||||
exit_sts = ARCHIVE_FAILED;
|
||||
|
@ -1216,6 +1228,14 @@ setup_sparse(struct archive_read_disk *a,
|
|||
off_e - off_s);
|
||||
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:
|
||||
lseek(*fd, initial_off, SEEK_SET);
|
||||
return (exit_sts);
|
||||
|
|
|
@ -717,6 +717,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
|||
int r;
|
||||
ssize_t bytes;
|
||||
size_t buffbytes;
|
||||
int empty_sparse_region = 0;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
|
||||
"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)
|
||||
buffbytes = t->current_sparse->length;
|
||||
|
||||
if (t->current_sparse->length == 0)
|
||||
empty_sparse_region = 1;
|
||||
|
||||
/*
|
||||
* Skip hole.
|
||||
* TODO: Should we consider t->current_filesystem->xfer_align?
|
||||
|
@ -828,7 +832,11 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
|||
}
|
||||
} else
|
||||
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 */
|
||||
t->entry_eof = 1;
|
||||
r = ARCHIVE_EOF;
|
||||
|
@ -1576,6 +1584,7 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||
#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
|
||||
t->current_filesystem->name_max = sfs.f_namemax;
|
||||
#else
|
||||
# if defined(_PC_NAME_MAX)
|
||||
/* Mac OS X does not have f_namemax in struct statfs. */
|
||||
if (tree_current_is_symblic_link_target(t)) {
|
||||
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);
|
||||
} else
|
||||
nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
|
||||
# else
|
||||
nm = -1;
|
||||
# endif
|
||||
if (nm == -1)
|
||||
t->current_filesystem->name_max = NAME_MAX;
|
||||
else
|
||||
|
@ -1681,7 +1693,9 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||
{
|
||||
struct tree *t = a->tree;
|
||||
struct statfs sfs;
|
||||
#if defined(HAVE_STATVFS)
|
||||
struct statvfs svfs;
|
||||
#endif
|
||||
int r, vr = 0, xr = 0;
|
||||
|
||||
if (tree_current_is_symblic_link_target(t)) {
|
||||
|
@ -1698,7 +1712,9 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||
"openat failed");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#if defined(HAVE_FSTATVFS)
|
||||
vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */
|
||||
#endif
|
||||
r = fstatfs(fd, &sfs);
|
||||
if (r == 0)
|
||||
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");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#if defined(HAVE_STATVFS)
|
||||
vr = statvfs(tree_current_access_path(t), &svfs);
|
||||
#endif
|
||||
r = statfs(tree_current_access_path(t), &sfs);
|
||||
if (r == 0)
|
||||
xr = get_xfer_size(t, -1, tree_current_access_path(t));
|
||||
#endif
|
||||
} else {
|
||||
#ifdef HAVE_FSTATFS
|
||||
#if defined(HAVE_FSTATVFS)
|
||||
vr = fstatvfs(tree_current_dir_fd(t), &svfs);
|
||||
#endif
|
||||
r = fstatfs(tree_current_dir_fd(t), &sfs);
|
||||
if (r == 0)
|
||||
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");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#if defined(HAVE_STATVFS)
|
||||
vr = statvfs(".", &svfs);
|
||||
#endif
|
||||
r = statfs(".", &sfs);
|
||||
if (r == 0)
|
||||
xr = get_xfer_size(t, -1, ".");
|
||||
|
@ -1737,10 +1759,17 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||
return (ARCHIVE_FAILED);
|
||||
} else if (xr == 1) {
|
||||
/* pathconf(_PC_REX_*) operations are not supported. */
|
||||
#if defined(HAVE_STATVFS)
|
||||
t->current_filesystem->xfer_align = svfs.f_frsize;
|
||||
t->current_filesystem->max_xfer_size = -1;
|
||||
t->current_filesystem->min_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) {
|
||||
case AFS_SUPER_MAGIC:
|
||||
|
@ -1765,7 +1794,11 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||
}
|
||||
|
||||
#if defined(ST_NOATIME)
|
||||
#if defined(HAVE_STATVFS)
|
||||
if (svfs.f_flag & ST_NOATIME)
|
||||
#else
|
||||
if (sfs.f_flag & ST_NOATIME)
|
||||
#endif
|
||||
t->current_filesystem->noatime = 1;
|
||||
else
|
||||
#endif
|
||||
|
|
|
@ -53,8 +53,12 @@ Streaming Archive Library (libarchive, -larchive)
|
|||
.Ft int
|
||||
.Fn archive_read_support_filter_compress "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_grzip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_gzip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_lrzip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_lz4 "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_lzma "struct archive *"
|
||||
|
@ -86,7 +90,9 @@ Streaming Archive Library (libarchive, -larchive)
|
|||
.It Xo
|
||||
.Fn archive_read_support_filter_bzip2 ,
|
||||
.Fn archive_read_support_filter_compress ,
|
||||
.Fn archive_read_support_filter_grzip ,
|
||||
.Fn archive_read_support_filter_gzip ,
|
||||
.Fn archive_read_support_filter_lrzip ,
|
||||
.Fn archive_read_support_filter_lz4 ,
|
||||
.Fn archive_read_support_filter_lzma ,
|
||||
.Fn archive_read_support_filter_lzop ,
|
||||
|
|
|
@ -83,8 +83,9 @@ archive_read_open_FILE(struct archive *a, FILE *f)
|
|||
mine->f = f;
|
||||
/*
|
||||
* 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
|
||||
* streams, some of which don't support fileno()).)
|
||||
* a file. (On some platforms, FILE * objects can wrap I/O
|
||||
* 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)) {
|
||||
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;
|
||||
}
|
||||
|
||||
#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)
|
||||
#elif HAVE__FSEEKI64
|
||||
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
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
struct archive_string fn;
|
||||
|
|
|
@ -580,10 +580,19 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
|
|||
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(
|
||||
read_buf + 4,
|
||||
state->out_block + prefix64k, (int)compressed_size,
|
||||
state->flags.block_maximum_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Check if an error happend in decompression process. */
|
||||
|
|
|
@ -148,9 +148,12 @@ get_time_t_max(void)
|
|||
return (~(time_t)0);
|
||||
} else {
|
||||
/* Time_t is signed. */
|
||||
const uintmax_t max_unsigned_time_t = (uintmax_t)(~(time_t)0);
|
||||
const uintmax_t max_signed_time_t = max_unsigned_time_t >> 1;
|
||||
return (time_t)max_signed_time_t;
|
||||
/* Assume it's the same as int64_t or int32_t */
|
||||
if (sizeof(time_t) == sizeof(int64_t)) {
|
||||
return (time_t)INT64_MAX;
|
||||
} else {
|
||||
return (time_t)INT32_MAX;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -166,10 +169,11 @@ get_time_t_min(void)
|
|||
return (time_t)0;
|
||||
} else {
|
||||
/* Time_t is signed. */
|
||||
const uintmax_t max_unsigned_time_t = (uintmax_t)(~(time_t)0);
|
||||
const uintmax_t max_signed_time_t = max_unsigned_time_t >> 1;
|
||||
const intmax_t min_signed_time_t = (intmax_t)~max_signed_time_t;
|
||||
return (time_t)min_signed_time_t;
|
||||
if (sizeof(time_t) == sizeof(int64_t)) {
|
||||
return (time_t)INT64_MIN;
|
||||
} else {
|
||||
return (time_t)INT32_MIN;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -852,8 +856,8 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
|
|||
struct mtree_entry *entry;
|
||||
struct mtree_option *iter;
|
||||
const char *next, *eq, *name, *end;
|
||||
size_t len;
|
||||
int r;
|
||||
size_t name_len, len;
|
||||
int r, i;
|
||||
|
||||
if ((entry = malloc(sizeof(*entry))) == NULL) {
|
||||
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;
|
||||
|
||||
if (is_form_d) {
|
||||
/*
|
||||
* This form places the file name as last parameter.
|
||||
*/
|
||||
name = line + line_len -1;
|
||||
/* Filename is last item on line. */
|
||||
/* Adjust line_len to trim trailing whitespace */
|
||||
while (line_len > 0) {
|
||||
if (*name != '\r' && *name != '\n' &&
|
||||
*name != '\t' && *name != ' ')
|
||||
break;
|
||||
name--;
|
||||
line_len--;
|
||||
}
|
||||
len = 0;
|
||||
while (line_len > 0) {
|
||||
if (*name == '\r' || *name == '\n' ||
|
||||
*name == '\t' || *name == ' ') {
|
||||
name++;
|
||||
char last_character = line[line_len - 1];
|
||||
if (last_character == '\r'
|
||||
|| last_character == '\n'
|
||||
|| last_character == '\t'
|
||||
|| last_character == ' ') {
|
||||
line_len--;
|
||||
} else {
|
||||
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;
|
||||
} else {
|
||||
len = strcspn(line, " \t\r\n");
|
||||
/* Filename is first item on line */
|
||||
name_len = strcspn(line, " \t\r\n");
|
||||
name = line;
|
||||
line += len;
|
||||
line += name_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");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
memcpy(entry->name, name, len);
|
||||
entry->name[len] = '\0';
|
||||
memcpy(entry->name, name, name_len);
|
||||
entry->name[name_len] = '\0';
|
||||
parse_escapes(entry->name, entry);
|
||||
|
||||
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 my_time_t_max = get_time_t_max();
|
||||
int64_t my_time_t_min = get_time_t_min();
|
||||
long ns;
|
||||
long ns = 0;
|
||||
|
||||
*parsed_kws |= MTREE_HAS_MTIME;
|
||||
m = mtree_atol10(&val);
|
||||
|
|
|
@ -828,6 +828,7 @@ archive_read_format_rar_read_header(struct archive_read *a,
|
|||
char head_type;
|
||||
int ret;
|
||||
unsigned flags;
|
||||
unsigned long crc32_expected;
|
||||
|
||||
a->archive.archive_format = ARCHIVE_FORMAT_RAR;
|
||||
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);
|
||||
if (skip < 7) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Invalid header size");
|
||||
"Invalid header size too small");
|
||||
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 (skip < 7 + 4) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Invalid header size");
|
||||
"Invalid header size too small");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
skip += archive_le32dec(p + 7);
|
||||
if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
p = h;
|
||||
skip += archive_le32dec(p + 7);
|
||||
}
|
||||
|
||||
crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2);
|
||||
if ((crc32_val & 0xffff) != archive_le16dec(p)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Header CRC error");
|
||||
return (ARCHIVE_FATAL);
|
||||
/* Skip over the 2-byte CRC at the beginning of the header. */
|
||||
crc32_expected = archive_le16dec(p);
|
||||
__archive_read_consume(a, 2);
|
||||
skip -= 2;
|
||||
|
||||
/* 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)
|
||||
return (ARCHIVE_EOF);
|
||||
return (ARCHIVE_EOF);
|
||||
break;
|
||||
|
||||
case NEWSUB_HEAD:
|
||||
|
|
|
@ -418,10 +418,11 @@ deconst(const void *c)
|
|||
}
|
||||
|
||||
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 eon = ndl + nz;
|
||||
const char *const eoh = hay + haysize;
|
||||
const char *const eon = needle + needlesize;
|
||||
const char *hp;
|
||||
const char *np;
|
||||
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
|
||||
* then run strchr() to find a candidate in HAYSTACK (i.e. a portion
|
||||
* that happens to begin with *NEEDLE) */
|
||||
if (nz == 0UL) {
|
||||
if (needlesize == 0UL) {
|
||||
return deconst(hay);
|
||||
} else if ((hay = memchr(hay, *ndl, hz_)) == NULL) {
|
||||
} else if ((hay = memchr(hay, *needle, haysize)) == NULL) {
|
||||
/* trivial */
|
||||
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
|
||||
* of characters values of needle together with the sum of the first
|
||||
* 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;
|
||||
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) {
|
||||
/* haystack is smaller than needle, :O */
|
||||
return NULL;
|
||||
|
@ -464,10 +465,10 @@ xmemmem(const char *hay, const size_t hz_, const char *ndl, const size_t nz)
|
|||
hsum ^= *hp;
|
||||
|
||||
/* 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,
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1939,9 +1939,6 @@ unknowntag_start(struct archive_read *a, struct xar *xar, const char *name)
|
|||
{
|
||||
struct unknown_tag *tag;
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "unknowntag_start:%s\n", name);
|
||||
#endif
|
||||
tag = malloc(sizeof(*tag));
|
||||
if (tag == NULL) {
|
||||
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_strcpy(&(tag->name), name);
|
||||
if (xar->unknowntags == NULL) {
|
||||
#if DEBUG
|
||||
fprintf(stderr, "UNKNOWNTAG_START:%s\n", name);
|
||||
#endif
|
||||
xar->xmlsts_unknown = xar->xmlsts;
|
||||
xar->xmlsts = UNKNOWN;
|
||||
}
|
||||
|
@ -1963,9 +1963,6 @@ unknowntag_end(struct xar *xar, const char *name)
|
|||
{
|
||||
struct unknown_tag *tag;
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "unknowntag_end:%s\n", name);
|
||||
#endif
|
||||
tag = xar->unknowntags;
|
||||
if (tag == NULL || name == NULL)
|
||||
return;
|
||||
|
@ -1973,8 +1970,12 @@ unknowntag_end(struct xar *xar, const char *name)
|
|||
xar->unknowntags = tag->next;
|
||||
archive_string_free(&(tag->name));
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2168,7 +2169,7 @@ xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
|
|||
case FILE_ACL:
|
||||
if (strcmp(name, "appleextended") == 0)
|
||||
xar->xmlsts = FILE_ACL_APPLEEXTENDED;
|
||||
if (strcmp(name, "default") == 0)
|
||||
else if (strcmp(name, "default") == 0)
|
||||
xar->xmlsts = FILE_ACL_DEFAULT;
|
||||
else if (strcmp(name, "access") == 0)
|
||||
xar->xmlsts = FILE_ACL_ACCESS;
|
||||
|
@ -2690,9 +2691,9 @@ xml_data(void *userData, const char *s, int len)
|
|||
#if DEBUG
|
||||
{
|
||||
char buff[1024];
|
||||
if (len > sizeof(buff)-1)
|
||||
len = sizeof(buff)-1;
|
||||
memcpy(buff, s, len);
|
||||
if (len > (int)(sizeof(buff)-1))
|
||||
len = (int)(sizeof(buff)-1);
|
||||
strncpy(buff, s, len);
|
||||
buff[len] = 0;
|
||||
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
|
||||
* 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
|
||||
|
@ -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);
|
||||
|
||||
offset += 4;
|
||||
if (offset + datasize > extra_length)
|
||||
if (offset + datasize > extra_length) {
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Header id 0x%04x, length %d\n",
|
||||
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 & 2, 2 byte "internal 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;
|
||||
|
||||
|
@ -604,6 +606,19 @@ process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
|
|||
if (zip_entry->system == 3) {
|
||||
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;
|
||||
}
|
||||
offset += 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);
|
||||
|
||||
/* 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
|
||||
* stats the pipe instead of synthesizing a file entry. */
|
||||
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. */
|
||||
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);
|
||||
/* Make sure directories end in '/' */
|
||||
if ((zip_entry->mode & AE_IFMT) == AE_IFDIR) {
|
||||
wp = archive_entry_pathname_w(entry);
|
||||
if (wp != NULL) {
|
||||
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 this came from the central dir, it's size info
|
||||
* 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;
|
||||
when we read the local file header we might get
|
||||
more information. */
|
||||
zip_entry->mode = 0;
|
||||
if (zip_entry->system == 3) {
|
||||
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
|
||||
|
@ -2726,6 +2778,11 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
|
|||
|
||||
switch(rsrc->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
|
||||
case 8: /* Deflate compression. */
|
||||
#endif
|
||||
|
@ -2746,6 +2803,12 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
|
|||
(intmax_t)rsrc->uncompressed_size);
|
||||
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);
|
||||
if (metadata == NULL) {
|
||||
|
@ -2784,6 +2847,8 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
|
|||
bytes_avail = remaining_bytes;
|
||||
switch(rsrc->compression) {
|
||||
case 0: /* No compression. */
|
||||
if ((size_t)bytes_avail > metadata_bytes)
|
||||
bytes_avail = metadata_bytes;
|
||||
memcpy(mp, p, bytes_avail);
|
||||
bytes_used = (size_t)bytes_avail;
|
||||
metadata_bytes -= bytes_used;
|
||||
|
|
|
@ -737,7 +737,8 @@ archive_string_append_from_wcs_in_codepage(struct archive_string *as,
|
|||
}
|
||||
if (count == 0)
|
||||
ret = -1;
|
||||
} while (0);
|
||||
break;
|
||||
} while (1);
|
||||
}
|
||||
as->length += count;
|
||||
as->s[as->length] = '\0';
|
||||
|
|
|
@ -94,37 +94,83 @@ archive_version_details(void)
|
|||
{
|
||||
static struct archive_string str;
|
||||
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) {
|
||||
archive_string_init(&str);
|
||||
|
||||
archive_strcat(&str, ARCHIVE_VERSION_STRING);
|
||||
#ifdef HAVE_ZLIB_H
|
||||
archive_strcat(&str, " zlib/");
|
||||
archive_strcat(&str, ZLIB_VERSION);
|
||||
#endif
|
||||
#ifdef HAVE_LZMA_H
|
||||
archive_strcat(&str, " liblzma/");
|
||||
archive_strcat(&str, LZMA_VERSION_STRING);
|
||||
#endif
|
||||
#ifdef HAVE_BZLIB_H
|
||||
{
|
||||
const char *p = BZ2_bzlibVersion();
|
||||
if (zlib != NULL) {
|
||||
archive_strcat(&str, " zlib/");
|
||||
archive_strcat(&str, zlib);
|
||||
}
|
||||
if (liblzma) {
|
||||
archive_strcat(&str, " liblzma/");
|
||||
archive_strcat(&str, liblzma);
|
||||
}
|
||||
if (bzlib) {
|
||||
const char *p = bzlib;
|
||||
const char *sep = strchr(p, ',');
|
||||
if (sep == NULL)
|
||||
sep = p + strlen(p);
|
||||
archive_strcat(&str, " bz2lib/");
|
||||
archive_strncat(&str, p, sep - p);
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
|
||||
archive_string_sprintf(&str, " liblz4/%d.%d.%d",
|
||||
LZ4_VERSION_MAJOR, LZ4_VERSION_MINOR, LZ4_VERSION_RELEASE);
|
||||
#endif
|
||||
if (liblz4) {
|
||||
archive_strcat(&str, " liblz4/");
|
||||
archive_strcat(&str, liblz4);
|
||||
}
|
||||
}
|
||||
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
|
||||
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)
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
data->pdata = __archive_write_program_allocate();
|
||||
data->pdata = __archive_write_program_allocate("bzip2");
|
||||
if (data->pdata == NULL) {
|
||||
free(data);
|
||||
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");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
data->pdata = __archive_write_program_allocate();
|
||||
data->pdata = __archive_write_program_allocate("grzip");
|
||||
if (data->pdata == NULL) {
|
||||
free(data);
|
||||
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;
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
data->pdata = __archive_write_program_allocate();
|
||||
data->pdata = __archive_write_program_allocate("gzip");
|
||||
if (data->pdata == NULL) {
|
||||
free(data);
|
||||
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");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
data->pdata = __archive_write_program_allocate();
|
||||
data->pdata = __archive_write_program_allocate("lrzip");
|
||||
if (data->pdata == NULL) {
|
||||
free(data);
|
||||
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
|
||||
* instead.
|
||||
*/
|
||||
data->pdata = __archive_write_program_allocate();
|
||||
data->pdata = __archive_write_program_allocate("lz4");
|
||||
if (data->pdata == NULL) {
|
||||
free(data);
|
||||
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;
|
||||
|
||||
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')
|
||||
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);
|
||||
}
|
||||
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;
|
||||
|
||||
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
|
||||
LZ4_freeStream(data->lz4_stream);
|
||||
#else
|
||||
LZ4_free(data->lz4_stream);
|
||||
#endif
|
||||
else
|
||||
LZ4_freeHC(data->lz4_stream);
|
||||
}
|
||||
free(data->out_buffer);
|
||||
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;
|
||||
unsigned int outsize;
|
||||
|
||||
if (data->compression_level < 4)
|
||||
outsize = LZ4_compress_limitedOutput(p, data->out + 4,
|
||||
(int)length, (int)data->block_size);
|
||||
else
|
||||
#ifdef HAVE_LZ4HC_H
|
||||
if (data->compression_level >= 3)
|
||||
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
|
||||
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,
|
||||
(int)length, (int)data->block_size,
|
||||
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) {
|
||||
/* 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;
|
||||
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) {
|
||||
data->lz4_stream = LZ4_createStream();
|
||||
if (data->lz4_stream == NULL) {
|
||||
|
@ -528,23 +589,18 @@ drive_compressor_dependence(struct archive_write_filter *f, const char *p,
|
|||
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(
|
||||
data->lz4_stream, p, data->out + 4, (int)length,
|
||||
(int)data->block_size);
|
||||
} else {
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (outsize) {
|
||||
|
@ -568,14 +624,19 @@ drive_compressor_dependence(struct archive_write_filter *f, const char *p,
|
|||
}
|
||||
|
||||
if (length == data->block_size) {
|
||||
#define DICT_SIZE (64 * 1024)
|
||||
if (data->compression_level < 3)
|
||||
LZ4_saveDict(data->lz4_stream,
|
||||
data->in_buffer_allocated, DICT_SIZE);
|
||||
else {
|
||||
#ifdef HAVE_LZ4HC_H
|
||||
if (data->compression_level >= 3) {
|
||||
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
|
||||
LZ4_saveDictHC(data->lz4_stream, data->in_buffer_allocated, DICT_SIZE);
|
||||
#else
|
||||
LZ4_slideInputBufferHC(data->lz4_stream);
|
||||
#endif
|
||||
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
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
|
@ -605,7 +666,7 @@ archive_filter_lz4_open(struct archive_write_filter *f)
|
|||
if (data->block_checksum)
|
||||
archive_strcat(&as, " -BX");
|
||||
if (data->stream_checksum == 0)
|
||||
archive_strcat(&as, " -Sx");
|
||||
archive_strcat(&as, " --no-frame-crc");
|
||||
if (data->block_independence == 0)
|
||||
archive_strcat(&as, " -BD");
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ archive_write_add_filter_lzop(struct archive *_a)
|
|||
data->compression_level = 5;
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
data->pdata = __archive_write_program_allocate();
|
||||
data->pdata = __archive_write_program_allocate("lzop");
|
||||
if (data->pdata == NULL) {
|
||||
free(data);
|
||||
archive_set_error(_a, ENOMEM, "Can't allocate memory");
|
||||
|
|
|
@ -68,6 +68,7 @@ struct archive_write_program_data {
|
|||
|
||||
char *child_buf;
|
||||
size_t child_buf_len, child_buf_avail;
|
||||
char *program_name;
|
||||
};
|
||||
|
||||
struct private_data {
|
||||
|
@ -105,7 +106,7 @@ archive_write_add_filter_program(struct archive *_a, const char *cmd)
|
|||
if (data->cmd == NULL)
|
||||
goto memerr;
|
||||
|
||||
data->pdata = __archive_write_program_allocate();
|
||||
data->pdata = __archive_write_program_allocate(cmd);
|
||||
if (data->pdata == NULL)
|
||||
goto memerr;
|
||||
|
||||
|
@ -174,7 +175,7 @@ archive_compressor_program_free(struct archive_write_filter *f)
|
|||
* Allocate resources for executing an external program.
|
||||
*/
|
||||
struct archive_write_program_data *
|
||||
__archive_write_program_allocate(void)
|
||||
__archive_write_program_allocate(const char *program)
|
||||
{
|
||||
struct archive_write_program_data *data;
|
||||
|
||||
|
@ -183,6 +184,7 @@ __archive_write_program_allocate(void)
|
|||
return (data);
|
||||
data->child_stdin = -1;
|
||||
data->child_stdout = -1;
|
||||
data->program_name = strdup(program);
|
||||
return (data);
|
||||
}
|
||||
|
||||
|
@ -231,7 +233,7 @@ __archive_write_program_open(struct archive_write_filter *f,
|
|||
&data->child_stdout);
|
||||
if (child == -1) {
|
||||
archive_set_error(f->archive, EINVAL,
|
||||
"Can't initialise filter");
|
||||
"Can't launch external program: %s", cmd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
|
@ -242,7 +244,7 @@ __archive_write_program_open(struct archive_write_filter *f,
|
|||
close(data->child_stdout);
|
||||
data->child_stdout = -1;
|
||||
archive_set_error(f->archive, EINVAL,
|
||||
"Can't initialise filter");
|
||||
"Can't launch external program: %s", cmd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#else
|
||||
|
@ -334,7 +336,7 @@ __archive_write_program_write(struct archive_write_filter *f,
|
|||
ret = child_write(f, data, buf, length);
|
||||
if (ret == -1 || ret == 0) {
|
||||
archive_set_error(f->archive, EIO,
|
||||
"Can't write to filter");
|
||||
"Can't write to program: %s", data->program_name);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
length -= ret;
|
||||
|
@ -373,7 +375,7 @@ __archive_write_program_close(struct archive_write_filter *f,
|
|||
|
||||
if (bytes_read == -1) {
|
||||
archive_set_error(f->archive, errno,
|
||||
"Read from filter failed unexpectedly.");
|
||||
"Error reading from program: %s", data->program_name);
|
||||
ret = ARCHIVE_FATAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -403,7 +405,7 @@ cleanup:
|
|||
|
||||
if (status != 0) {
|
||||
archive_set_error(f->archive, EIO,
|
||||
"Filter exited with failure.");
|
||||
"Error closing program: %s", data->program_name);
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
r1 = __archive_write_close_filter(f->next_filter);
|
||||
|
|
|
@ -2386,6 +2386,9 @@ check_symlinks(struct archive_write_disk *a)
|
|||
while ((*pn != '\0') && (*p == *pn))
|
||||
++p, ++pn;
|
||||
}
|
||||
/* Skip the root directory if the path is absolute. */
|
||||
if(pn == a->name && pn[0] == '/')
|
||||
++pn;
|
||||
c = pn[0];
|
||||
/* Keep going until we've checked the entire name. */
|
||||
while (pn[0] != '\0' && (pn[0] != '/' || pn[1] != '\0')) {
|
||||
|
@ -2447,6 +2450,9 @@ check_symlinks(struct archive_write_disk *a)
|
|||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
}
|
||||
pn[0] = c;
|
||||
if (pn[0] != '\0')
|
||||
pn++; /* Advance to the next segment. */
|
||||
}
|
||||
pn[0] = c;
|
||||
/* We've checked and/or cleaned the whole path, so remember it. */
|
||||
|
|
|
@ -29,9 +29,12 @@
|
|||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_write_add_filter_b64encode ,
|
||||
.Nm archive_write_add_filter_by_name ,
|
||||
.Nm archive_write_add_filter_bzip2 ,
|
||||
.Nm archive_write_add_filter_compress ,
|
||||
.Nm archive_write_add_filter_grzip ,
|
||||
.Nm archive_write_add_filter_gzip ,
|
||||
.Nm archive_write_add_filter_lrzip ,
|
||||
.Nm archive_write_add_filter_lz4 ,
|
||||
.Nm archive_write_add_filter_lzip ,
|
||||
.Nm archive_write_add_filter_lzma ,
|
||||
|
@ -51,8 +54,12 @@ Streaming Archive Library (libarchive, -larchive)
|
|||
.Ft int
|
||||
.Fn archive_write_add_filter_compress "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_write_add_filter_grzip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_write_add_filter_gzip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_write_add_filter_lrzip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_write_add_filter_lz4 "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_write_add_filter_lzip "struct archive *"
|
||||
|
@ -71,19 +78,25 @@ Streaming Archive Library (libarchive, -larchive)
|
|||
.Sh DESCRIPTION
|
||||
.Bl -tag -width indent
|
||||
.It Xo
|
||||
.Fn archive_write_add_filter_b64encode ,
|
||||
.Fn archive_write_add_filter_bzip2 ,
|
||||
.Fn archive_write_add_filter_compress ,
|
||||
.Fn archive_write_add_filter_grzip ,
|
||||
.Fn archive_write_add_filter_gzip ,
|
||||
.Fn archive_write_add_filter_lrzip ,
|
||||
.Fn archive_write_add_filter_lz4 ,
|
||||
.Fn archive_write_add_filter_lzip ,
|
||||
.Fn archive_write_add_filter_lzma ,
|
||||
.Fn archive_write_add_filter_lzop ,
|
||||
.Fn archive_write_add_filter_uuencode ,
|
||||
.Fn archive_write_add_filter_xz ,
|
||||
.Xc
|
||||
The resulting archive will be compressed as specified.
|
||||
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
|
||||
This is never necessary.
|
||||
It is provided only for backwards compatibility.
|
||||
|
|
|
@ -28,23 +28,63 @@
|
|||
.Dt ARCHIVE_WRITE_FORMAT 3
|
||||
.Os
|
||||
.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_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_restricted ,
|
||||
.Nm archive_write_set_format_raw ,
|
||||
.Nm archive_write_set_format_shar ,
|
||||
.Nm archive_write_set_format_shar_dump ,
|
||||
.Nm archive_write_set_format_ustar ,
|
||||
.Nm archive_write_set_format_filter_by_ext ,
|
||||
.Nm archive_write_set_format_filter_by_ext_def
|
||||
.Nm archive_write_set_format_v7tar ,
|
||||
.Nm archive_write_set_format_warc ,
|
||||
.Nm archive_write_set_format_xar ,
|
||||
.Nm archive_write_set_format_zip ,
|
||||
.Nd functions for creating archives
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.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 *"
|
||||
.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 *"
|
||||
.Ft int
|
||||
.Fn archive_write_set_format_pax_restricted "struct archive *"
|
||||
|
@ -57,42 +97,60 @@ Streaming Archive Library (libarchive, -larchive)
|
|||
.Ft int
|
||||
.Fn archive_write_set_format_ustar "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_write_set_format_filter_by_ext "struct archive *" "const char *"
|
||||
.Fn archive_write_set_format_v7tar "struct archive *"
|
||||
.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
|
||||
These functions set the format that will be used for the archive.
|
||||
.Pp
|
||||
The library can write
|
||||
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.
|
||||
The library can write a variety of common archive formats.
|
||||
|
||||
.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
|
||||
.Fn archive_write_set_format_filter_by_ext ,
|
||||
.Fn archive_write_set_format_filter_by_ext_def
|
||||
.Xc
|
||||
Format and filter for archive can be set automatically, based on output file name extension.
|
||||
The functions are platform dependent.
|
||||
Sets both filters and format based on the output filename.
|
||||
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
|
||||
These functions return
|
||||
|
@ -113,5 +171,6 @@ functions.
|
|||
.Xr archive_write 3 ,
|
||||
.Xr archive_write_set_options 3 ,
|
||||
.Xr cpio 5 ,
|
||||
.Xr libarchive-formats 5 ,
|
||||
.Xr mtree 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_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_open(struct archive_write_filter *,
|
||||
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;
|
||||
|
||||
/* Close the temporary file. */
|
||||
if (zip->temp_fd >= 0)
|
||||
close(zip->temp_fd);
|
||||
|
||||
file_free_register(zip);
|
||||
compression_end(&(a->archive), &(zip->stream));
|
||||
free(zip->coder.props);
|
||||
|
|
|
@ -1036,22 +1036,12 @@ archive_write_pax_header(struct archive_write *a,
|
|||
need_extension = 1;
|
||||
|
||||
/*
|
||||
* 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).
|
||||
* Libarchive used to include these in extended headers for
|
||||
* restricted pax format, but that confused people who
|
||||
* expected ustar-like time semantics. So now we only include
|
||||
* them in full pax format.
|
||||
*/
|
||||
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 (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED) {
|
||||
if (archive_entry_ctime(entry_main) != 0 ||
|
||||
archive_entry_ctime_nsec(entry_main) != 0)
|
||||
add_pax_attr_time(&(pax->pax_header), "ctime",
|
||||
|
@ -1072,6 +1062,23 @@ archive_write_pax_header(struct archive_write *a,
|
|||
"LIBARCHIVE.creationtime",
|
||||
archive_entry_birthtime(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. */
|
||||
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 */
|
||||
if (!w->omit_warcinfo) {
|
||||
ssize_t r;
|
||||
warc_essential_hdr_t wi = {
|
||||
WT_INFO,
|
||||
/*uri*/NULL,
|
||||
/*urn*/NULL,
|
||||
/*rtm*/w->now,
|
||||
/*mtm*/w->now,
|
||||
/*rtm*/0,
|
||||
/*mtm*/0,
|
||||
/*cty*/"application/warc-fields",
|
||||
/*len*/sizeof(warcinfo) - 1U,
|
||||
};
|
||||
ssize_t r;
|
||||
wi.rtime = w->now;
|
||||
wi.mtime = w->now;
|
||||
|
||||
archive_string_init(&hdr);
|
||||
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) {
|
||||
warc_essential_hdr_t rh = {
|
||||
WT_RSRC,
|
||||
/*uri*/archive_entry_pathname(entry),
|
||||
/*uri*/NULL,
|
||||
/*urn*/NULL,
|
||||
/*rtm*/w->now,
|
||||
/*mtm*/archive_entry_mtime(entry),
|
||||
/*rtm*/0,
|
||||
/*mtm*/0,
|
||||
/*cty*/NULL,
|
||||
/*len*/(size_t)archive_entry_size(entry),
|
||||
/*len*/0,
|
||||
};
|
||||
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);
|
||||
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 */
|
||||
struct tm *rt;
|
||||
#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
|
||||
struct tm time;
|
||||
struct tm timeHere;
|
||||
#endif
|
||||
char strtime[100];
|
||||
size_t len;
|
||||
|
||||
#ifdef HAVE_GMTIME_R
|
||||
if ((rt = gmtime_r(&t, &time)) == NULL)
|
||||
if ((rt = gmtime_r(&t, &timeHere)) == NULL)
|
||||
return;
|
||||
#elif defined(HAVE__GMTIME64_S)
|
||||
_gmtime64_s(&time, &t);
|
||||
_gmtime64_s(&timeHere, &t);
|
||||
#else
|
||||
if ((rt = gmtime(&t)) == NULL)
|
||||
return;
|
||||
|
@ -396,7 +402,7 @@ _popul_ehdr(struct archive_string *tgt, size_t tsz, warc_essential_hdr_t hdr)
|
|||
* handle the minimum number following '%'.
|
||||
* So we have to use snprintf function here instead
|
||||
* of archive_string_snprintf function. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__) && !( defined(_MSC_VER) && _MSC_VER >= 1900)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
snprintf(
|
||||
|
|
|
@ -1877,6 +1877,11 @@ xar_free(struct archive_write *a)
|
|||
struct xar *xar;
|
||||
|
||||
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->tstr));
|
||||
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_UTF8_NAME (1 << 11)
|
||||
|
||||
#define ZIP_4GB_MAX ARCHIVE_LITERAL_LL(0xffffffff)
|
||||
#define ZIP_4GB_MAX_UNCOMPRESSED ARCHIVE_LITERAL_LL(0xff000000)
|
||||
|
||||
enum compression {
|
||||
COMPRESSION_UNSPECIFIED = -1,
|
||||
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) {
|
||||
/* Reject entries over 4GB. */
|
||||
if (archive_entry_size_is_set(entry)
|
||||
&& (archive_entry_size(entry) >
|
||||
ARCHIVE_LITERAL_LL(0xffffffff))) {
|
||||
&& (archive_entry_size(entry) > ZIP_4GB_MAX)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Files > 4GB require Zip64 extensions");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
/* 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,
|
||||
"Archives > 4GB require Zip64 extensions");
|
||||
return ARCHIVE_FAILED;
|
||||
|
@ -727,10 +729,8 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
|||
* (compression might make file larger)
|
||||
*/
|
||||
if ((zip->flags & ZIP_FLAG_FORCE_ZIP64)
|
||||
|| (zip->entry_uncompressed_size + additional_size >
|
||||
ARCHIVE_LITERAL_LL(0xffffffff))
|
||||
|| (zip->entry_uncompressed_size >
|
||||
ARCHIVE_LITERAL_LL(0xff000000)
|
||||
|| (zip->entry_uncompressed_size + additional_size > ZIP_4GB_MAX)
|
||||
|| (zip->entry_uncompressed_size > ZIP_4GB_MAX_UNCOMPRESSED
|
||||
&& zip->entry_compression != COMPRESSION_STORE)) {
|
||||
zip->entry_uses_zip64 = 1;
|
||||
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;
|
||||
* THEREFORE these must be set this way, even if we
|
||||
* know one of them is smaller. */
|
||||
archive_le32enc(local_header + 18, ARCHIVE_LITERAL_LL(0xffffffff));
|
||||
archive_le32enc(local_header + 22, ARCHIVE_LITERAL_LL(0xffffffff));
|
||||
archive_le32enc(local_header + 18, ZIP_4GB_MAX);
|
||||
archive_le32enc(local_header + 22, ZIP_4GB_MAX);
|
||||
} else {
|
||||
archive_le32enc(local_header + 18, (uint32_t)zip->entry_compressed_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. */
|
||||
if (zip->entry_compressed_written > ARCHIVE_LITERAL_LL(0xffffffff)
|
||||
|| zip->entry_uncompressed_written > ARCHIVE_LITERAL_LL(0xffffffff)
|
||||
|| zip->entry_offset > ARCHIVE_LITERAL_LL(0xffffffff)) {
|
||||
if (zip->entry_compressed_written > ZIP_4GB_MAX
|
||||
|| zip->entry_uncompressed_written > ZIP_4GB_MAX
|
||||
|| zip->entry_offset > ZIP_4GB_MAX) {
|
||||
unsigned char zip64[32];
|
||||
unsigned char *z = zip64, *zd;
|
||||
memcpy(z, "\001\000\000\000", 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);
|
||||
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);
|
||||
z += 8;
|
||||
}
|
||||
if (zip->entry_offset >= ARCHIVE_LITERAL_LL(0xffffffff)) {
|
||||
if (zip->entry_offset >= ZIP_4GB_MAX) {
|
||||
archive_le64enc(z, zip->entry_offset);
|
||||
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 + 20,
|
||||
(uint32_t)zipmin(zip->entry_compressed_written,
|
||||
ARCHIVE_LITERAL_LL(0xffffffff)));
|
||||
ZIP_4GB_MAX));
|
||||
archive_le32enc(zip->file_header + 24,
|
||||
(uint32_t)zipmin(zip->entry_uncompressed_written,
|
||||
ARCHIVE_LITERAL_LL(0xffffffff)));
|
||||
ZIP_4GB_MAX));
|
||||
archive_le16enc(zip->file_header + 30,
|
||||
(uint16_t)(zip->central_directory_bytes - zip->file_header_extra_offset));
|
||||
archive_le32enc(zip->file_header + 42,
|
||||
(uint32_t)zipmin(zip->entry_offset,
|
||||
ARCHIVE_LITERAL_LL(0xffffffff)));
|
||||
ZIP_4GB_MAX));
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
@ -1291,8 +1291,8 @@ archive_write_zip_close(struct archive_write *a)
|
|||
offset_end = zip->written_bytes;
|
||||
|
||||
/* If central dir info is too large, write Zip64 end-of-cd */
|
||||
if (offset_end - offset_start > ARCHIVE_LITERAL_LL(0xffffffff)
|
||||
|| offset_start > ARCHIVE_LITERAL_LL(0xffffffff)
|
||||
if (offset_end - offset_start > ZIP_4GB_MAX
|
||||
|| offset_start > ZIP_4GB_MAX
|
||||
|| zip->central_directory_entries > 0xffffUL
|
||||
|| (zip->flags & ZIP_FLAG_FORCE_ZIP64)) {
|
||||
/* 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,
|
||||
zip->central_directory_entries));
|
||||
archive_le32enc(buff + 12,
|
||||
(uint32_t)zipmin(ARCHIVE_LITERAL_LL(0xffffffff),
|
||||
(offset_end - offset_start)));
|
||||
(uint32_t)zipmin(ZIP_4GB_MAX, (offset_end - offset_start)));
|
||||
archive_le32enc(buff + 16,
|
||||
(uint32_t)zipmin(ARCHIVE_LITERAL_LL(0xffffffff),
|
||||
offset_start));
|
||||
(uint32_t)zipmin(ZIP_4GB_MAX, offset_start));
|
||||
ret = __archive_write_output(a, buff, 22);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
|
|
@ -101,7 +101,12 @@ and
|
|||
.Ar value
|
||||
will be provided to the filter or reader named
|
||||
.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,
|
||||
.Cm ARCHIVE_FAILED
|
||||
will be returned.
|
||||
|
@ -123,9 +128,7 @@ will be returned if any module accepts the option, and
|
|||
.Cm ARCHIVE_FAILED
|
||||
in all other cases.
|
||||
.\"
|
||||
.It Xo
|
||||
.Fn archive_write_set_option
|
||||
.Xc
|
||||
.It Fn archive_write_set_option
|
||||
Calls
|
||||
.Fn archive_write_set_format_option ,
|
||||
then
|
||||
|
@ -137,9 +140,7 @@ will be returned
|
|||
immediately.
|
||||
Otherwise, greater of the two values will be returned.
|
||||
.\"
|
||||
.It Xo
|
||||
.Fn archive_write_set_options
|
||||
.Xc
|
||||
.It Fn archive_write_set_options
|
||||
.Ar options
|
||||
is a comma-separated list of options.
|
||||
If
|
||||
|
@ -456,7 +457,7 @@ archive_write_open_filename(a, filename, blocksize);
|
|||
.Ed
|
||||
.\"
|
||||
.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
|
||||
and
|
||||
.Fn archive_error_string
|
||||
|
|
|
@ -55,7 +55,7 @@ It can write POSIX-standard
|
|||
.Dq ustar
|
||||
and
|
||||
.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
|
||||
All tar formats store each entry in one or more 512-byte records.
|
||||
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.
|
||||
The ustar format is old and widely supported.
|
||||
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
|
||||
.Pp
|
||||
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.
|
||||
File sizes and mtime are limited to 33 bits (8GB file size),
|
||||
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
|
||||
this format.
|
||||
The SVR4 format uses eight-digit hexadecimal values for
|
||||
|
@ -364,8 +388,10 @@ area adjacent to the entry.
|
|||
Libarchive can read both extensions,
|
||||
including archives that may include both types of long filenames.
|
||||
Programs using libarchive can write GNU/SVR4 format
|
||||
if they provide a filename table to be written into
|
||||
the archive before any of the entries.
|
||||
if they provide an entry called
|
||||
.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
|
||||
will be written using BSD-style long filenames.
|
||||
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
|
||||
will return an error for any attempt to read the entry
|
||||
body.
|
||||
.Ss LHA
|
||||
XXX Information about libarchive's LHA support XXX
|
||||
.Ss 7-Zip
|
||||
Libarchive can read and write 7-Zip format archives.
|
||||
TODO: Need more information
|
||||
.Ss CAB
|
||||
XXX Information about libarchive's CAB support XXX
|
||||
.Ss XAR
|
||||
XXX Information about libarchive's XAR support XXX
|
||||
Libarchive can read Microsoft Cabinet (
|
||||
.Dq CAB )
|
||||
format archives.
|
||||
TODO: Need more information.
|
||||
.Ss LHA
|
||||
TODO: Information about libarchive's LHA support
|
||||
.Ss RAR
|
||||
Libarchive has limited support for reading RAR format archives.
|
||||
Currently, libarchive can read RARv3 format archives
|
||||
which have been either created uncompressed, or compressed using
|
||||
any of the compression methods supported by the RARv3 format.
|
||||
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
|
||||
.Xr ar 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 :
|
||||
- xxHash source repository : http://code.google.com/p/xxhash/
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "archive_platform.h"
|
||||
#include "archive_xxhash.h"
|
||||
|
||||
#ifdef HAVE_LIBLZ4
|
||||
|
||||
/***************************************
|
||||
|
@ -83,11 +87,8 @@ You can contact the author at :
|
|||
/***************************************
|
||||
** Includes & Memory related functions
|
||||
****************************************/
|
||||
#include "archive_xxhash.h"
|
||||
#include <stdlib.h>
|
||||
#define XXH_malloc malloc
|
||||
#define XXH_free free
|
||||
#include <string.h>
|
||||
#define XXH_memcpy memcpy
|
||||
|
||||
|
||||
|
@ -497,4 +498,17 @@ struct archive_xxhash __archive_xxhash = {
|
|||
XXH32_update,
|
||||
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 */
|
||||
|
|
Loading…
Reference in New Issue