mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-02 20:29:49 -05:00
Merge topic 'update-libarchive'
6287b02147libarchive: Limit xz compression level to 6 on AIX651ecdddfaUtilities: Add hard-coded try_compile result for libarchive strnlen check107df8e650Merge branch 'upstream-LibArchive' into update-libarchivedadea0e5ceLibArchive 2020-12-26 (227a4b97)3d05964b02libarchive: Update script to get 3.5.1 Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !6464
This commit is contained in:
@@ -8,7 +8,7 @@ readonly name="LibArchive"
|
||||
readonly ownership="LibArchive Upstream <libarchive-discuss@googlegroups.com>"
|
||||
readonly subtree="Utilities/cmlibarchive"
|
||||
readonly repo="https://github.com/libarchive/libarchive.git"
|
||||
readonly tag="v3.4.2"
|
||||
readonly tag="v3.5.1"
|
||||
readonly shortlog=false
|
||||
readonly paths="
|
||||
CMakeLists.txt
|
||||
|
||||
@@ -180,6 +180,7 @@ if(WIN32)
|
||||
set(HAVE_STRERROR_R 0)
|
||||
set(HAVE_STRNCMPI 0)
|
||||
set(HAVE_STRNCPY_S 1)
|
||||
set(HAVE_STRNLEN 1)
|
||||
set(HAVE_STROPTS_H 0)
|
||||
set(HAVE__STRTOI64 1)
|
||||
set(HAVE_STRTOLL 1)
|
||||
|
||||
@@ -171,32 +171,32 @@ IF (MSVC)
|
||||
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
|
||||
# Enable level 4 C4062: The enumerate has no associated handler in a switch
|
||||
# statement and there is no default that can catch it.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4062")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14062")
|
||||
# Enable level 4 C4254: A larger bit field was assigned to a smaller bit
|
||||
# field.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4254")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14254")
|
||||
# Enable level 4 C4295: An array was initialized but the last character in
|
||||
# the array is not a null; accessing the array may
|
||||
# produce unexpected results.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4295")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14295")
|
||||
# Enable level 4 C4296: An unsigned variable was used in a comparison
|
||||
# operation with zero.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4296")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14296")
|
||||
# Enable level 4 C4389: An operation involved signed and unsigned variables.
|
||||
# This could result in a loss of data.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4389")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14389")
|
||||
# Enable level 4 C4505: The given function is local and not referenced in
|
||||
# the body of the module; therefore, the function is
|
||||
# dead code.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4505")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14505")
|
||||
# Enable level 4 C4514: The optimizer removed an inline function that is not
|
||||
# called.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4514")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14514")
|
||||
# Enable level 4 C4702: Unreachable code.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4702")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14702")
|
||||
# Enable level 4 C4706: The test value in a conditional expression was the
|
||||
# result of an assignment.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4706")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14706")
|
||||
# /Oi option enables built-in functions.
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Oi")
|
||||
#################################################################
|
||||
@@ -1404,6 +1404,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(strchr HAVE_STRCHR)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(strdup HAVE_STRDUP)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(strerror HAVE_STRERROR)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(strncpy_s HAVE_STRNCPY_S)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(strnlen HAVE_STRNLEN)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
|
||||
@@ -1475,15 +1476,19 @@ CHECK_C_SOURCE_COMPILES(
|
||||
"#include <sys/sysmacros.h>\nint main() { return major(256); }"
|
||||
MAJOR_IN_SYSMACROS)
|
||||
|
||||
IF(ENABLE_LZMA)
|
||||
CMAKE_PUSH_CHECK_STATE()
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES})
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR})
|
||||
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
"#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
|
||||
HAVE_LZMA_STREAM_ENCODER_MT)
|
||||
HAVE_LZMA_STREAM_ENCODER_MT)
|
||||
|
||||
CMAKE_POP_CHECK_STATE()
|
||||
ELSE()
|
||||
SET(HAVE_LZMA_STREAM_ENCODER_MT 0)
|
||||
ENDIF(ENABLE_LZMA)
|
||||
|
||||
IF(HAVE_STRERROR_R)
|
||||
SET(HAVE_DECL_STRERROR_R 1)
|
||||
@@ -2007,6 +2012,11 @@ IF(MSVC)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
|
||||
ENDIF(MSVC)
|
||||
|
||||
IF(APPLE)
|
||||
# CC_MD5_Init() functions are deprecated on macOS 10.15, but we want to use them
|
||||
ADD_DEFINITIONS(-Wno-deprecated-declarations)
|
||||
ENDIF(APPLE)
|
||||
|
||||
IF(0) # CMake does not build libarchive's tests.
|
||||
IF(ENABLE_TEST)
|
||||
ADD_CUSTOM_TARGET(run_all_tests)
|
||||
|
||||
@@ -15,7 +15,6 @@ the actual statements in the files are controlling.
|
||||
* The following source files are also subject in whole or in part to
|
||||
a 3-clause UC Regents copyright; please read the individual source
|
||||
files for details:
|
||||
libarchive/archive_entry.c
|
||||
libarchive/archive_read_support_filter_compress.c
|
||||
libarchive/archive_write_add_filter_compress.c
|
||||
libarchive/mtree.5
|
||||
|
||||
@@ -24,10 +24,10 @@ ENDFOREACH()
|
||||
# thus there's a good chance it'll make some binutils versions unhappy...
|
||||
# This only affects Libs.private (looked up for static builds) though.
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc.in
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/build/pkgconfig/libarchive.pc
|
||||
@ONLY)
|
||||
# And install it, of course ;).
|
||||
IF(ENABLE_INSTALL)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/build/pkgconfig/libarchive.pc
|
||||
DESTINATION "lib/pkgconfig")
|
||||
ENDIF()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* config.h. Generated from build/cmake/config.h.in by cmake configure */
|
||||
#define __LIBARCHIVE_CONFIG_H_INCLUDED 1
|
||||
#if defined(__osf__)
|
||||
# define _OSF_SOURCE
|
||||
#endif
|
||||
@@ -742,6 +743,9 @@
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#cmakedefine HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strnlen' function. */
|
||||
#cmakedefine HAVE_STRNLEN 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#cmakedefine HAVE_STRDUP 1
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
3004002
|
||||
3005001
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||
*/
|
||||
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3004002
|
||||
#define ARCHIVE_VERSION_NUMBER 3005001
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stddef.h> /* for wchar_t */
|
||||
@@ -152,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.4.2"
|
||||
#define ARCHIVE_VERSION_ONLY_STRING "3.5.1"
|
||||
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||
__LA_DECL const char * archive_version_string(void);
|
||||
|
||||
@@ -243,6 +243,8 @@ typedef int archive_open_callback(struct archive *, void *_client_data);
|
||||
|
||||
typedef int archive_close_callback(struct archive *, void *_client_data);
|
||||
|
||||
typedef int archive_free_callback(struct archive *, void *_client_data);
|
||||
|
||||
/* Switches from one client data object to the next/prev client data object.
|
||||
* This is useful for reading from different data blocks such as a set of files
|
||||
* that make up one large file.
|
||||
@@ -415,6 +417,7 @@ __LA_DECL int archive_read_support_compression_xz(struct archive *)
|
||||
#endif
|
||||
|
||||
__LA_DECL int archive_read_support_filter_all(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_by_code(struct archive *, int);
|
||||
__LA_DECL int archive_read_support_filter_bzip2(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_compress(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_gzip(struct archive *);
|
||||
@@ -814,9 +817,13 @@ __LA_DECL int archive_write_set_format_filter_by_ext(struct archive *a, const ch
|
||||
__LA_DECL int archive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext);
|
||||
__LA_DECL int archive_write_zip_set_compression_deflate(struct archive *);
|
||||
__LA_DECL int archive_write_zip_set_compression_store(struct archive *);
|
||||
/* Deprecated; use archive_write_open2 instead */
|
||||
__LA_DECL int archive_write_open(struct archive *, void *,
|
||||
archive_open_callback *, archive_write_callback *,
|
||||
archive_close_callback *);
|
||||
__LA_DECL int archive_write_open2(struct archive *, void *,
|
||||
archive_open_callback *, archive_write_callback *,
|
||||
archive_close_callback *, archive_free_callback *);
|
||||
__LA_DECL int archive_write_open_fd(struct archive *, int _fd);
|
||||
__LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
|
||||
__LA_DECL int archive_write_open_filename_w(struct archive *,
|
||||
|
||||
@@ -595,7 +595,7 @@ archive_acl_text_len(struct archive_acl *acl, int want_type, int flags,
|
||||
else
|
||||
length += sizeof(uid_t) * 3 + 1;
|
||||
} else {
|
||||
r = archive_mstring_get_mbs_l(&ap->name, &name,
|
||||
r = archive_mstring_get_mbs_l(a, &ap->name, &name,
|
||||
&len, sc);
|
||||
if (r != 0)
|
||||
return (0);
|
||||
@@ -968,7 +968,7 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
else
|
||||
prefix = NULL;
|
||||
r = archive_mstring_get_mbs_l(
|
||||
&ap->name, &name, &len, sc);
|
||||
NULL, &ap->name, &name, &len, sc);
|
||||
if (r != 0) {
|
||||
free(s);
|
||||
return (NULL);
|
||||
@@ -1402,14 +1402,14 @@ isint_w(const wchar_t *start, const wchar_t *end, int *result)
|
||||
if (start >= end)
|
||||
return (0);
|
||||
while (start < end) {
|
||||
if (*start < '0' || *start > '9')
|
||||
if (*start < L'0' || *start > L'9')
|
||||
return (0);
|
||||
if (n > (INT_MAX / 10) ||
|
||||
(n == INT_MAX / 10 && (*start - '0') > INT_MAX % 10)) {
|
||||
(n == INT_MAX / 10 && (*start - L'0') > INT_MAX % 10)) {
|
||||
n = INT_MAX;
|
||||
} else {
|
||||
n *= 10;
|
||||
n += *start - '0';
|
||||
n += *start - L'0';
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ errmsg(const char *m)
|
||||
ssize_t written;
|
||||
|
||||
while (s > 0) {
|
||||
written = write(2, m, strlen(m));
|
||||
written = write(2, m, s);
|
||||
if (written <= 0)
|
||||
return;
|
||||
m += written;
|
||||
|
||||
@@ -347,8 +347,31 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
#if NETTLE_VERSION_MAJOR < 3
|
||||
aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key);
|
||||
aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce);
|
||||
#else
|
||||
switch(ctx->key_len) {
|
||||
case AES128_KEY_SIZE:
|
||||
aes128_set_encrypt_key(&ctx->ctx.c128, ctx->key);
|
||||
aes128_encrypt(&ctx->ctx.c128, AES_BLOCK_SIZE, ctx->encr_buf,
|
||||
ctx->nonce);
|
||||
break;
|
||||
case AES192_KEY_SIZE:
|
||||
aes192_set_encrypt_key(&ctx->ctx.c192, ctx->key);
|
||||
aes192_encrypt(&ctx->ctx.c192, AES_BLOCK_SIZE, ctx->encr_buf,
|
||||
ctx->nonce);
|
||||
break;
|
||||
case AES256_KEY_SIZE:
|
||||
aes256_set_encrypt_key(&ctx->ctx.c256, ctx->key);
|
||||
aes256_encrypt(&ctx->ctx.c256, AES_BLOCK_SIZE, ctx->encr_buf,
|
||||
ctx->nonce);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,9 +104,18 @@ typedef struct {
|
||||
#include <nettle/pbkdf2.h>
|
||||
#endif
|
||||
#include <nettle/aes.h>
|
||||
#include <nettle/version.h>
|
||||
|
||||
typedef struct {
|
||||
#if NETTLE_VERSION_MAJOR < 3
|
||||
struct aes_ctx ctx;
|
||||
#else
|
||||
union {
|
||||
struct aes128_ctx c128;
|
||||
struct aes192_ctx c192;
|
||||
struct aes256_ctx c256;
|
||||
} ctx;
|
||||
#endif
|
||||
uint8_t key[AES_MAX_KEY_SIZE];
|
||||
unsigned key_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,10 @@
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#ifndef __LIBARCHIVE_CONFIG_H_INCLUDED
|
||||
#error "Should have include config.h first!"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Crypto support in various Operating Systems:
|
||||
*
|
||||
|
||||
@@ -208,6 +208,19 @@ archive_entry_clone(struct archive_entry *entry)
|
||||
|
||||
/* Copy encryption status */
|
||||
entry2->encryption = entry->encryption;
|
||||
|
||||
/* Copy digests */
|
||||
#define copy_digest(_e2, _e, _t) \
|
||||
memcpy(_e2->digest._t, _e->digest._t, sizeof(_e2->digest._t))
|
||||
|
||||
copy_digest(entry2, entry, md5);
|
||||
copy_digest(entry2, entry, rmd160);
|
||||
copy_digest(entry2, entry, sha1);
|
||||
copy_digest(entry2, entry, sha256);
|
||||
copy_digest(entry2, entry, sha384);
|
||||
copy_digest(entry2, entry, sha512);
|
||||
|
||||
#undef copy_digest
|
||||
|
||||
/* Copy ACL data over. */
|
||||
archive_acl_copy(&entry2->acl, &entry->acl);
|
||||
@@ -353,7 +366,7 @@ archive_entry_devminor(struct archive_entry *entry)
|
||||
return minor(entry->ae_stat.aest_dev);
|
||||
}
|
||||
|
||||
mode_t
|
||||
__LA_MODE_T
|
||||
archive_entry_filetype(struct archive_entry *entry)
|
||||
{
|
||||
return (AE_IFMT & entry->acl.mode);
|
||||
@@ -450,7 +463,7 @@ int
|
||||
_archive_entry_gname_l(struct archive_entry *entry,
|
||||
const char **p, size_t *len, struct archive_string_conv *sc)
|
||||
{
|
||||
return (archive_mstring_get_mbs_l(&entry->ae_gname, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc));
|
||||
}
|
||||
|
||||
const char *
|
||||
@@ -504,7 +517,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
|
||||
*len = 0;
|
||||
return (0);
|
||||
}
|
||||
return (archive_mstring_get_mbs_l(&entry->ae_hardlink, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc));
|
||||
}
|
||||
|
||||
la_int64_t
|
||||
@@ -525,7 +538,7 @@ archive_entry_ino64(struct archive_entry *entry)
|
||||
return (entry->ae_stat.aest_ino);
|
||||
}
|
||||
|
||||
mode_t
|
||||
__LA_MODE_T
|
||||
archive_entry_mode(struct archive_entry *entry)
|
||||
{
|
||||
return (entry->acl.mode);
|
||||
@@ -595,10 +608,10 @@ int
|
||||
_archive_entry_pathname_l(struct archive_entry *entry,
|
||||
const char **p, size_t *len, struct archive_string_conv *sc)
|
||||
{
|
||||
return (archive_mstring_get_mbs_l(&entry->ae_pathname, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_pathname, p, len, sc));
|
||||
}
|
||||
|
||||
mode_t
|
||||
__LA_MODE_T
|
||||
archive_entry_perm(struct archive_entry *entry)
|
||||
{
|
||||
return (~AE_IFMT & entry->acl.mode);
|
||||
@@ -723,7 +736,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
|
||||
*len = 0;
|
||||
return (0);
|
||||
}
|
||||
return (archive_mstring_get_mbs_l( &entry->ae_symlink, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc));
|
||||
}
|
||||
|
||||
la_int64_t
|
||||
@@ -769,7 +782,7 @@ int
|
||||
_archive_entry_uname_l(struct archive_entry *entry,
|
||||
const char **p, size_t *len, struct archive_string_conv *sc)
|
||||
{
|
||||
return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
|
||||
return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_uname, p, len, sc));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1416,6 +1429,62 @@ archive_entry_copy_mac_metadata(struct archive_entry *entry,
|
||||
}
|
||||
}
|
||||
|
||||
/* Digest handling */
|
||||
const unsigned char *
|
||||
archive_entry_digest(struct archive_entry *entry, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_DIGEST_MD5:
|
||||
return entry->digest.md5;
|
||||
case ARCHIVE_ENTRY_DIGEST_RMD160:
|
||||
return entry->digest.rmd160;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA1:
|
||||
return entry->digest.sha1;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA256:
|
||||
return entry->digest.sha256;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA384:
|
||||
return entry->digest.sha384;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA512:
|
||||
return entry->digest.sha512;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_set_digest(struct archive_entry *entry, int type,
|
||||
const unsigned char *digest)
|
||||
{
|
||||
#define copy_digest(_e, _t, _d)\
|
||||
memcpy(_e->digest._t, _d, sizeof(_e->digest._t))
|
||||
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_DIGEST_MD5:
|
||||
copy_digest(entry, md5, digest);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_RMD160:
|
||||
copy_digest(entry, rmd160, digest);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA1:
|
||||
copy_digest(entry, sha1, digest);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA256:
|
||||
copy_digest(entry, sha256, digest);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA384:
|
||||
copy_digest(entry, sha384, digest);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA512:
|
||||
copy_digest(entry, sha512, digest);
|
||||
break;
|
||||
default:
|
||||
return ARCHIVE_WARN;
|
||||
}
|
||||
|
||||
return ARCHIVE_OK;
|
||||
#undef copy_digest
|
||||
}
|
||||
|
||||
/*
|
||||
* ACL management. The following would, of course, be a lot simpler
|
||||
* if: 1) the last draft of POSIX.1e were a really thorough and
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3004002
|
||||
#define ARCHIVE_VERSION_NUMBER 3005001
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
@@ -393,6 +393,19 @@ __LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat
|
||||
__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *);
|
||||
__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
|
||||
|
||||
/*
|
||||
* Digest routine. This is used to query the raw hex digest for the
|
||||
* given entry. The type of digest is provided as an argument.
|
||||
*/
|
||||
#define ARCHIVE_ENTRY_DIGEST_MD5 0x00000001
|
||||
#define ARCHIVE_ENTRY_DIGEST_RMD160 0x00000002
|
||||
#define ARCHIVE_ENTRY_DIGEST_SHA1 0x00000003
|
||||
#define ARCHIVE_ENTRY_DIGEST_SHA256 0x00000004
|
||||
#define ARCHIVE_ENTRY_DIGEST_SHA384 0x00000005
|
||||
#define ARCHIVE_ENTRY_DIGEST_SHA512 0x00000006
|
||||
|
||||
__LA_DECL const unsigned char * archive_entry_digest(struct archive_entry *, int /* type */);
|
||||
|
||||
/*
|
||||
* ACL routines. This used to simply store and return text-format ACL
|
||||
* strings, but that proved insufficient for a number of reasons:
|
||||
|
||||
@@ -50,6 +50,15 @@ struct ae_sparse {
|
||||
int64_t length;
|
||||
};
|
||||
|
||||
struct ae_digest {
|
||||
unsigned char md5[16];
|
||||
unsigned char rmd160[20];
|
||||
unsigned char sha1[20];
|
||||
unsigned char sha256[32];
|
||||
unsigned char sha384[48];
|
||||
unsigned char sha512[64];
|
||||
};
|
||||
|
||||
/*
|
||||
* Description of an archive entry.
|
||||
*
|
||||
@@ -162,6 +171,9 @@ struct archive_entry {
|
||||
void *mac_metadata;
|
||||
size_t mac_metadata_size;
|
||||
|
||||
/* Digest support. */
|
||||
struct ae_digest digest;
|
||||
|
||||
/* ACL support. */
|
||||
struct archive_acl acl;
|
||||
|
||||
@@ -181,4 +193,8 @@ struct archive_entry {
|
||||
int ae_symlink_type;
|
||||
};
|
||||
|
||||
int
|
||||
archive_entry_set_digest(struct archive_entry *entry, int type,
|
||||
const unsigned char *digest);
|
||||
|
||||
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
|
||||
|
||||
@@ -215,9 +215,9 @@ and
|
||||
set and unset the size, respectively.
|
||||
.Pp
|
||||
The number of references (hardlinks) can be obtained by calling
|
||||
.Fn archive_entry_nlinks
|
||||
.Fn archive_entry_nlink
|
||||
and set with
|
||||
.Fn archive_entry_set_nlinks .
|
||||
.Fn archive_entry_set_nlink .
|
||||
.Ss Identifying unique files
|
||||
The functions
|
||||
.Fn archive_entry_dev
|
||||
|
||||
@@ -4,7 +4,7 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "archive_ppmd7_private.h"
|
||||
|
||||
|
||||
@@ -892,15 +892,16 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
|
||||
len = a->read_data_remaining;
|
||||
if (len > s)
|
||||
len = s;
|
||||
if (len)
|
||||
if (len) {
|
||||
memcpy(dest, a->read_data_block, len);
|
||||
s -= len;
|
||||
a->read_data_block += len;
|
||||
a->read_data_remaining -= len;
|
||||
a->read_data_output_offset += len;
|
||||
a->read_data_offset += len;
|
||||
dest += len;
|
||||
bytes_read += len;
|
||||
s -= len;
|
||||
a->read_data_block += len;
|
||||
a->read_data_remaining -= len;
|
||||
a->read_data_output_offset += len;
|
||||
a->read_data_offset += len;
|
||||
dest += len;
|
||||
bytes_read += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
a->read_data_is_posix_read = 0;
|
||||
|
||||
@@ -57,6 +57,10 @@ insert_passphrase_to_head(struct archive_read *a,
|
||||
{
|
||||
p->next = a->passphrases.first;
|
||||
a->passphrases.first = p;
|
||||
if (&a->passphrases.first == a->passphrases.last) {
|
||||
a->passphrases.last = &p->next;
|
||||
p->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct archive_read_passphrase *
|
||||
|
||||
@@ -103,6 +103,10 @@ __FBSDID("$FreeBSD");
|
||||
|
||||
static int setup_mac_metadata(struct archive_read_disk *,
|
||||
struct archive_entry *, int *fd);
|
||||
#ifdef ARCHIVE_XATTR_FREEBSD
|
||||
static int setup_xattrs_namespace(struct archive_read_disk *,
|
||||
struct archive_entry *, int *, int);
|
||||
#endif
|
||||
static int setup_xattrs(struct archive_read_disk *,
|
||||
struct archive_entry *, int *fd);
|
||||
static int setup_sparse(struct archive_read_disk *,
|
||||
@@ -701,14 +705,13 @@ setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
|
||||
}
|
||||
|
||||
static int
|
||||
setup_xattrs(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
setup_xattrs_namespace(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd, int namespace)
|
||||
{
|
||||
char buff[512];
|
||||
char *list, *p;
|
||||
ssize_t list_size;
|
||||
const char *path;
|
||||
int namespace = EXTATTR_NAMESPACE_USER;
|
||||
|
||||
path = NULL;
|
||||
|
||||
@@ -727,6 +730,8 @@ setup_xattrs(struct archive_read_disk *a,
|
||||
|
||||
if (list_size == -1 && errno == EOPNOTSUPP)
|
||||
return (ARCHIVE_OK);
|
||||
if (list_size == -1 && errno == EPERM)
|
||||
return (ARCHIVE_OK);
|
||||
if (list_size == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't list extended attributes");
|
||||
@@ -760,7 +765,17 @@ setup_xattrs(struct archive_read_disk *a,
|
||||
size_t len = 255 & (int)*p;
|
||||
char *name;
|
||||
|
||||
strcpy(buff, "user.");
|
||||
if (namespace == EXTATTR_NAMESPACE_SYSTEM) {
|
||||
if (!strcmp(p + 1, "nfs4.acl") ||
|
||||
!strcmp(p + 1, "posix1e.acl_access") ||
|
||||
!strcmp(p + 1, "posix1e.acl_default")) {
|
||||
p += 1 + len;
|
||||
continue;
|
||||
}
|
||||
strcpy(buff, "system.");
|
||||
} else {
|
||||
strcpy(buff, "user.");
|
||||
}
|
||||
name = buff + strlen(buff);
|
||||
memcpy(name, p + 1, len);
|
||||
name[len] = '\0';
|
||||
@@ -772,6 +787,31 @@ setup_xattrs(struct archive_read_disk *a,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
setup_xattrs(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
int namespaces[2];
|
||||
int i, res;
|
||||
|
||||
namespaces[0] = EXTATTR_NAMESPACE_USER;
|
||||
namespaces[1] = EXTATTR_NAMESPACE_SYSTEM;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
res = setup_xattrs_namespace(a, entry, fd,
|
||||
namespaces[i]);
|
||||
switch (res) {
|
||||
case (ARCHIVE_OK):
|
||||
case (ARCHIVE_WARN):
|
||||
break;
|
||||
default:
|
||||
return (res);
|
||||
}
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
|
||||
@@ -1658,7 +1658,7 @@ static int
|
||||
setup_current_filesystem(struct archive_read_disk *a)
|
||||
{
|
||||
struct tree *t = a->tree;
|
||||
struct statvfs sfs;
|
||||
struct statvfs svfs;
|
||||
int r, xr = 0;
|
||||
|
||||
t->current_filesystem->synthetic = -1;
|
||||
@@ -1667,16 +1667,16 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (tree_current_is_symblic_link_target(t)) {
|
||||
r = statvfs(tree_current_access_path(t), &sfs);
|
||||
r = statvfs(tree_current_access_path(t), &svfs);
|
||||
if (r == 0)
|
||||
xr = get_xfer_size(t, -1, tree_current_access_path(t));
|
||||
} else {
|
||||
#ifdef HAVE_FSTATVFS
|
||||
r = fstatvfs(tree_current_dir_fd(t), &sfs);
|
||||
r = fstatvfs(tree_current_dir_fd(t), &svfs);
|
||||
if (r == 0)
|
||||
xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
|
||||
#else
|
||||
r = statvfs(".", &sfs);
|
||||
r = statvfs(".", &svfs);
|
||||
if (r == 0)
|
||||
xr = get_xfer_size(t, -1, ".");
|
||||
#endif
|
||||
@@ -1688,30 +1688,30 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
} else if (xr == 1) {
|
||||
/* Usually come here unless NetBSD supports _PC_REC_XFER_ALIGN
|
||||
* for pathconf() function. */
|
||||
t->current_filesystem->xfer_align = sfs.f_frsize;
|
||||
t->current_filesystem->xfer_align = svfs.f_frsize;
|
||||
t->current_filesystem->max_xfer_size = -1;
|
||||
#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
|
||||
t->current_filesystem->min_xfer_size = sfs.f_iosize;
|
||||
t->current_filesystem->incr_xfer_size = sfs.f_iosize;
|
||||
t->current_filesystem->min_xfer_size = svfs.f_iosize;
|
||||
t->current_filesystem->incr_xfer_size = svfs.f_iosize;
|
||||
#else
|
||||
t->current_filesystem->min_xfer_size = sfs.f_bsize;
|
||||
t->current_filesystem->incr_xfer_size = sfs.f_bsize;
|
||||
t->current_filesystem->min_xfer_size = svfs.f_bsize;
|
||||
t->current_filesystem->incr_xfer_size = svfs.f_bsize;
|
||||
#endif
|
||||
}
|
||||
if (sfs.f_flag & ST_LOCAL)
|
||||
if (svfs.f_flag & ST_LOCAL)
|
||||
t->current_filesystem->remote = 0;
|
||||
else
|
||||
t->current_filesystem->remote = 1;
|
||||
|
||||
#if defined(ST_NOATIME)
|
||||
if (sfs.f_flag & ST_NOATIME)
|
||||
if (svfs.f_flag & ST_NOATIME)
|
||||
t->current_filesystem->noatime = 1;
|
||||
else
|
||||
#endif
|
||||
t->current_filesystem->noatime = 0;
|
||||
|
||||
/* Set maximum filename length. */
|
||||
t->current_filesystem->name_max = sfs.f_namemax;
|
||||
t->current_filesystem->name_max = svfs.f_namemax;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@@ -1840,7 +1840,7 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
#if defined(HAVE_STATVFS)
|
||||
if (svfs.f_flag & ST_NOATIME)
|
||||
#else
|
||||
if (sfs.f_flag & ST_NOATIME)
|
||||
if (sfs.f_flags & ST_NOATIME)
|
||||
#endif
|
||||
t->current_filesystem->noatime = 1;
|
||||
else
|
||||
@@ -1864,7 +1864,7 @@ static int
|
||||
setup_current_filesystem(struct archive_read_disk *a)
|
||||
{
|
||||
struct tree *t = a->tree;
|
||||
struct statvfs sfs;
|
||||
struct statvfs svfs;
|
||||
int r, xr = 0;
|
||||
|
||||
t->current_filesystem->synthetic = -1;/* Not supported */
|
||||
@@ -1883,7 +1883,7 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
"openat failed");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
r = fstatvfs(fd, &sfs);
|
||||
r = fstatvfs(fd, &svfs);
|
||||
if (r == 0)
|
||||
xr = get_xfer_size(t, fd, NULL);
|
||||
close(fd);
|
||||
@@ -1892,13 +1892,13 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
archive_set_error(&a->archive, errno, "fchdir failed");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
r = statvfs(tree_current_access_path(t), &sfs);
|
||||
r = statvfs(tree_current_access_path(t), &svfs);
|
||||
if (r == 0)
|
||||
xr = get_xfer_size(t, -1, tree_current_access_path(t));
|
||||
#endif
|
||||
} else {
|
||||
#ifdef HAVE_FSTATVFS
|
||||
r = fstatvfs(tree_current_dir_fd(t), &sfs);
|
||||
r = fstatvfs(tree_current_dir_fd(t), &svfs);
|
||||
if (r == 0)
|
||||
xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
|
||||
#else
|
||||
@@ -1906,7 +1906,7 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
archive_set_error(&a->archive, errno, "fchdir failed");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
r = statvfs(".", &sfs);
|
||||
r = statvfs(".", &svfs);
|
||||
if (r == 0)
|
||||
xr = get_xfer_size(t, -1, ".");
|
||||
#endif
|
||||
@@ -1918,14 +1918,14 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
return (ARCHIVE_FAILED);
|
||||
} else if (xr == 1) {
|
||||
/* pathconf(_PC_REX_*) operations are not supported. */
|
||||
t->current_filesystem->xfer_align = sfs.f_frsize;
|
||||
t->current_filesystem->xfer_align = svfs.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;
|
||||
t->current_filesystem->min_xfer_size = svfs.f_bsize;
|
||||
t->current_filesystem->incr_xfer_size = svfs.f_bsize;
|
||||
}
|
||||
|
||||
#if defined(ST_NOATIME)
|
||||
if (sfs.f_flag & ST_NOATIME)
|
||||
if (svfs.f_flag & ST_NOATIME)
|
||||
t->current_filesystem->noatime = 1;
|
||||
else
|
||||
#endif
|
||||
@@ -1933,7 +1933,7 @@ setup_current_filesystem(struct archive_read_disk *a)
|
||||
|
||||
#if defined(USE_READDIR_R)
|
||||
/* Set maximum filename length. */
|
||||
t->current_filesystem->name_max = sfs.f_namemax;
|
||||
t->current_filesystem->name_max = svfs.f_namemax;
|
||||
#endif
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 14, 2014
|
||||
.Dd June 9, 2020
|
||||
.Dt ARCHIVE_READ_FILTER 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -50,6 +50,8 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_all "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_by_code "struct archive *" "int"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_bzip2 "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_compress "struct archive *"
|
||||
@@ -116,6 +118,14 @@ Note that
|
||||
is always enabled by default.
|
||||
.It Fn archive_read_support_filter_all
|
||||
Enables all available decompression filters.
|
||||
.It Fn archive_read_support_filter_by_code
|
||||
Enables a single filter specified by the filter code.
|
||||
This function does not work with
|
||||
.Cm ARCHIVE_FILTER_PROGRAM .
|
||||
Note: In statically-linked executables, this will cause
|
||||
your program to include support for every filter.
|
||||
If executable size is a concern, you may wish to avoid
|
||||
using this function.
|
||||
.It Fn archive_read_support_filter_program
|
||||
Data is fed through the specified external program before being dearchived.
|
||||
Note that this disables automatic detection of the compression format,
|
||||
|
||||
@@ -221,7 +221,9 @@ file_open(struct archive *a, void *client_data)
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
void *buffer;
|
||||
const char *filename = NULL;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
const wchar_t *wfilename = NULL;
|
||||
#endif
|
||||
int fd = -1;
|
||||
int is_disk_like = 0;
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
@@ -281,10 +283,12 @@ file_open(struct archive *a, void *client_data)
|
||||
#endif
|
||||
}
|
||||
if (fstat(fd, &st) != 0) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
if (mine->filename_type == FNT_WCS)
|
||||
archive_set_error(a, errno, "Can't stat '%S'",
|
||||
wfilename);
|
||||
else
|
||||
#endif
|
||||
archive_set_error(a, errno, "Can't stat '%s'",
|
||||
filename);
|
||||
goto fail;
|
||||
|
||||
@@ -61,6 +61,9 @@ archive_read_set_format(struct archive *_a, int code)
|
||||
case ARCHIVE_FORMAT_CPIO:
|
||||
strcpy(str, "cpio");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_EMPTY:
|
||||
strcpy(str, "empty");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ISO9660:
|
||||
strcpy(str, "iso9660");
|
||||
break;
|
||||
@@ -76,9 +79,15 @@ archive_read_set_format(struct archive *_a, int code)
|
||||
case ARCHIVE_FORMAT_RAR_V5:
|
||||
strcpy(str, "rar5");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAW:
|
||||
strcpy(str, "raw");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
strcpy(str, "tar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_WARC:
|
||||
strcpy(str, "warc");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_XAR:
|
||||
strcpy(str, "xar");
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*-
|
||||
* Copyright (c) 2020 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
int
|
||||
archive_read_support_filter_by_code(struct archive *a, int filter_code)
|
||||
{
|
||||
archive_check_magic(a, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_filter_by_code");
|
||||
|
||||
switch (filter_code) {
|
||||
case ARCHIVE_FILTER_NONE:
|
||||
return archive_read_support_filter_none(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_GZIP:
|
||||
return archive_read_support_filter_gzip(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_BZIP2:
|
||||
return archive_read_support_filter_bzip2(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_COMPRESS:
|
||||
return archive_read_support_filter_compress(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZMA:
|
||||
return archive_read_support_filter_lzma(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_XZ:
|
||||
return archive_read_support_filter_xz(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_UU:
|
||||
return archive_read_support_filter_uu(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_RPM:
|
||||
return archive_read_support_filter_rpm(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZIP:
|
||||
return archive_read_support_filter_lzip(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LRZIP:
|
||||
return archive_read_support_filter_lrzip(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZOP:
|
||||
return archive_read_support_filter_lzop(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_GRZIP:
|
||||
return archive_read_support_filter_grzip(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZ4:
|
||||
return archive_read_support_filter_lz4(a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_ZSTD:
|
||||
return archive_read_support_filter_zstd(a);
|
||||
break;
|
||||
}
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
@@ -400,7 +400,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
|
||||
static const size_t out_buf_len = 65536;
|
||||
char *out_buf;
|
||||
const char *prefix = "Program: ";
|
||||
pid_t child;
|
||||
int ret;
|
||||
size_t l;
|
||||
|
||||
l = strlen(prefix) + strlen(cmd) + 1;
|
||||
@@ -426,9 +426,9 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
|
||||
state->out_buf = out_buf;
|
||||
state->out_buf_len = out_buf_len;
|
||||
|
||||
child = __archive_create_child(cmd, &state->child_stdin,
|
||||
&state->child_stdout);
|
||||
if (child == -1) {
|
||||
ret = __archive_create_child(cmd, &state->child_stdin,
|
||||
&state->child_stdout, &state->child);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
free(state->out_buf);
|
||||
archive_string_free(&state->description);
|
||||
free(state);
|
||||
@@ -437,21 +437,6 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
|
||||
cmd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
state->child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, child);
|
||||
if (state->child == NULL) {
|
||||
child_stop(self, state);
|
||||
free(state->out_buf);
|
||||
archive_string_free(&state->description);
|
||||
free(state);
|
||||
archive_set_error(&self->archive->archive, EINVAL,
|
||||
"Can't initialize filter; unable to run program \"%s\"",
|
||||
cmd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#else
|
||||
state->child = child;
|
||||
#endif
|
||||
|
||||
self->data = state;
|
||||
self->read = program_filter_read;
|
||||
|
||||
@@ -119,6 +119,8 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
|
||||
/* Zstd frame magic values */
|
||||
const unsigned zstd_magic = 0xFD2FB528U;
|
||||
const unsigned zstd_magic_skippable_start = 0x184D2A50U;
|
||||
const unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
|
||||
|
||||
(void) self; /* UNUSED */
|
||||
|
||||
@@ -129,6 +131,8 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
prefix = archive_le32dec(buffer);
|
||||
if (prefix == zstd_magic)
|
||||
return (32);
|
||||
if ((prefix & zstd_magic_skippable_mask) == zstd_magic_skippable_start)
|
||||
return (32);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
@@ -48,6 +52,9 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
|
||||
case ARCHIVE_FORMAT_CPIO:
|
||||
return archive_read_support_format_cpio(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_EMPTY:
|
||||
return archive_read_support_format_empty(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ISO9660:
|
||||
return archive_read_support_format_iso9660(a);
|
||||
break;
|
||||
@@ -63,9 +70,15 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
|
||||
case ARCHIVE_FORMAT_RAR_V5:
|
||||
return archive_read_support_format_rar5(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAW:
|
||||
return archive_read_support_format_raw(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
return archive_read_support_format_tar(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_WARC:
|
||||
return archive_read_support_format_warc(a);
|
||||
break;
|
||||
case ARCHIVE_FORMAT_XAR:
|
||||
return archive_read_support_format_xar(a);
|
||||
break;
|
||||
@@ -73,5 +86,7 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
|
||||
return archive_read_support_format_zip(a);
|
||||
break;
|
||||
}
|
||||
archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Invalid format code specified");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
@@ -1172,7 +1172,7 @@ cab_checksum_finish(struct archive_read *a)
|
||||
cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
|
||||
if (cfdata->sum_calculated != cfdata->sum) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Checksum error CFDATA[%d] %x:%x in %d bytes",
|
||||
"Checksum error CFDATA[%d] %" PRIx32 ":%" PRIx32 " in %d bytes",
|
||||
cab->entry_cffolder->cfdata_index -1,
|
||||
cfdata->sum, cfdata->sum_calculated,
|
||||
cfdata->compressed_size);
|
||||
|
||||
@@ -47,7 +47,7 @@ archive_read_support_format_empty(struct archive *_a)
|
||||
|
||||
r = __archive_read_register_format(a,
|
||||
NULL,
|
||||
NULL,
|
||||
"empty",
|
||||
archive_read_format_empty_bid,
|
||||
NULL,
|
||||
archive_read_format_empty_read_header,
|
||||
|
||||
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_entry_private.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_rb.h"
|
||||
#include "archive_read_private.h"
|
||||
@@ -135,6 +136,9 @@ static int skip(struct archive_read *a);
|
||||
static int read_header(struct archive_read *,
|
||||
struct archive_entry *);
|
||||
static int64_t mtree_atol(char **, int base);
|
||||
#ifndef HAVE_STRNLEN
|
||||
static size_t mtree_strnlen(const char *, size_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* There's no standard for TIME_T_MAX/TIME_T_MIN. So we compute them
|
||||
@@ -186,6 +190,24 @@ get_time_t_min(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRNLEN
|
||||
#define mtree_strnlen(a,b) strnlen(a,b)
|
||||
#else
|
||||
static size_t
|
||||
mtree_strnlen(const char *p, size_t maxlen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i <= maxlen; i++) {
|
||||
if (p[i] == 0)
|
||||
break;
|
||||
}
|
||||
if (i > maxlen)
|
||||
return (-1);/* invalid */
|
||||
return (i);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
archive_read_format_mtree_options(struct archive_read *a,
|
||||
const char *key, const char *val)
|
||||
@@ -1482,6 +1504,84 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
|
||||
#undef MAX_PACK_ARGS
|
||||
}
|
||||
|
||||
static int
|
||||
parse_hex_nibble(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return 10 + c - 'a';
|
||||
#if 0
|
||||
/* XXX: Is uppercase something we should support? */
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return 10 + c - 'A';
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_digest(struct archive_read *a, struct archive_entry *entry,
|
||||
const char *digest, int type)
|
||||
{
|
||||
unsigned char digest_buf[64];
|
||||
int high, low;
|
||||
size_t i, j, len;
|
||||
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_DIGEST_MD5:
|
||||
len = sizeof(entry->digest.md5);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_RMD160:
|
||||
len = sizeof(entry->digest.rmd160);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA1:
|
||||
len = sizeof(entry->digest.sha1);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA256:
|
||||
len = sizeof(entry->digest.sha256);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA384:
|
||||
len = sizeof(entry->digest.sha384);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_DIGEST_SHA512:
|
||||
len = sizeof(entry->digest.sha512);
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: Unknown digest type");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
if (len > sizeof(digest_buf)) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: Digest storage too large");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
len *= 2;
|
||||
|
||||
if (mtree_strnlen(digest, len+1) != len) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"incorrect digest length, ignoring");
|
||||
return ARCHIVE_WARN;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < len; i += 2, j++) {
|
||||
high = parse_hex_nibble(digest[i]);
|
||||
low = parse_hex_nibble(digest[i+1]);
|
||||
if (high == -1 || low == -1) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"invalid digest data, ignoring");
|
||||
return ARCHIVE_WARN;
|
||||
}
|
||||
|
||||
digest_buf[j] = high << 4 | low;
|
||||
}
|
||||
|
||||
return archive_entry_set_digest(entry, type, digest_buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a single keyword and its value.
|
||||
*/
|
||||
@@ -1580,8 +1680,10 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 'm':
|
||||
if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0)
|
||||
break;
|
||||
if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_MD5);
|
||||
}
|
||||
if (strcmp(key, "mode") == 0) {
|
||||
if (val[0] >= '0' && val[0] <= '7') {
|
||||
*parsed_kws |= MTREE_HAS_PERM;
|
||||
@@ -1617,21 +1719,32 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
|
||||
return r;
|
||||
}
|
||||
if (strcmp(key, "rmd160") == 0 ||
|
||||
strcmp(key, "rmd160digest") == 0)
|
||||
break;
|
||||
strcmp(key, "rmd160digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_RMD160);
|
||||
}
|
||||
__LA_FALLTHROUGH;
|
||||
case 's':
|
||||
if (strcmp(key, "sha1") == 0 || strcmp(key, "sha1digest") == 0)
|
||||
break;
|
||||
if (strcmp(key, "sha1") == 0 ||
|
||||
strcmp(key, "sha1digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_SHA1);
|
||||
}
|
||||
if (strcmp(key, "sha256") == 0 ||
|
||||
strcmp(key, "sha256digest") == 0)
|
||||
break;
|
||||
strcmp(key, "sha256digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_SHA256);
|
||||
}
|
||||
if (strcmp(key, "sha384") == 0 ||
|
||||
strcmp(key, "sha384digest") == 0)
|
||||
break;
|
||||
strcmp(key, "sha384digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_SHA384);
|
||||
}
|
||||
if (strcmp(key, "sha512") == 0 ||
|
||||
strcmp(key, "sha512digest") == 0)
|
||||
break;
|
||||
strcmp(key, "sha512digest") == 0) {
|
||||
return parse_digest(a, entry, val,
|
||||
ARCHIVE_ENTRY_DIGEST_SHA512);
|
||||
}
|
||||
if (strcmp(key, "size") == 0) {
|
||||
archive_entry_set_size(entry, mtree_atol(&val, 10));
|
||||
break;
|
||||
|
||||
@@ -151,6 +151,9 @@
|
||||
#undef minimum
|
||||
#define minimum(a, b) ((a)<(b)?(a):(b))
|
||||
|
||||
/* Stack overflow check */
|
||||
#define MAX_COMPRESS_DEPTH 1024
|
||||
|
||||
/* Fields common to all headers */
|
||||
struct rar_header
|
||||
{
|
||||
@@ -340,7 +343,7 @@ static int read_symlink_stored(struct archive_read *, struct archive_entry *,
|
||||
static int read_data_stored(struct archive_read *, const void **, size_t *,
|
||||
int64_t *);
|
||||
static int read_data_compressed(struct archive_read *, const void **, size_t *,
|
||||
int64_t *);
|
||||
int64_t *, size_t);
|
||||
static int rar_br_preparation(struct archive_read *, struct rar_br *);
|
||||
static int parse_codes(struct archive_read *);
|
||||
static void free_codes(struct archive_read *);
|
||||
@@ -1026,7 +1029,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
||||
case COMPRESS_METHOD_NORMAL:
|
||||
case COMPRESS_METHOD_GOOD:
|
||||
case COMPRESS_METHOD_BEST:
|
||||
ret = read_data_compressed(a, buff, size, offset);
|
||||
ret = read_data_compressed(a, buff, size, offset, 0);
|
||||
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
|
||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
|
||||
rar->start_new_table = 1;
|
||||
@@ -1883,8 +1886,11 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
|
||||
|
||||
static int
|
||||
read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
int64_t *offset)
|
||||
int64_t *offset, size_t looper)
|
||||
{
|
||||
if (looper++ > MAX_COMPRESS_DEPTH)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
struct rar *rar;
|
||||
int64_t start, end, actualend;
|
||||
size_t bs;
|
||||
@@ -1982,7 +1988,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||
{
|
||||
case 0:
|
||||
rar->start_new_table = 1;
|
||||
return read_data_compressed(a, buff, size, offset);
|
||||
return read_data_compressed(a, buff, size, offset, looper);
|
||||
|
||||
case 2:
|
||||
rar->ppmd_eod = 1;/* End Of ppmd Data. */
|
||||
|
||||
@@ -3084,12 +3084,6 @@ static int do_uncompress_block(struct archive_read* a, const uint8_t* p) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The program counter shouldn't reach here. */
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Unsupported block code: 0x%x", num);
|
||||
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
|
||||
return ARCHIVE_OK;
|
||||
@@ -3837,7 +3831,7 @@ static int verify_checksums(struct archive_read* a) {
|
||||
|
||||
DEBUG_CODE {
|
||||
printf("Checksum error: CRC32 "
|
||||
"(was: %08x, expected: %08x)\n",
|
||||
"(was: %08" PRIx32 ", expected: %08" PRIx32 ")\n",
|
||||
rar->file.calculated_crc32,
|
||||
rar->file.stored_crc32);
|
||||
}
|
||||
@@ -3851,7 +3845,7 @@ static int verify_checksums(struct archive_read* a) {
|
||||
} else {
|
||||
DEBUG_CODE {
|
||||
printf("Checksum OK: CRC32 "
|
||||
"(%08x/%08x)\n",
|
||||
"(%08" PRIx32 "/%08" PRIx32 ")\n",
|
||||
rar->file.stored_crc32,
|
||||
rar->file.calculated_crc32);
|
||||
}
|
||||
@@ -3912,6 +3906,9 @@ static int rar5_read_data(struct archive_read *a, const void **buff,
|
||||
int ret;
|
||||
struct rar5* rar = get_context(a);
|
||||
|
||||
if (size)
|
||||
*size = 0;
|
||||
|
||||
if(rar->file.dir > 0) {
|
||||
/* Don't process any data if this file entry was declared
|
||||
* as a directory. This is needed, because entries marked as
|
||||
|
||||
@@ -1796,6 +1796,16 @@ pax_attribute_schily_xattr(struct archive_entry *entry,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pax_attribute_rht_security_selinux(struct archive_entry *entry,
|
||||
const char *value, size_t value_length)
|
||||
{
|
||||
archive_entry_xattr_add_entry(entry, "security.selinux",
|
||||
value, value_length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pax_attribute_acl(struct archive_read *a, struct tar *tar,
|
||||
struct archive_entry *entry, const char *value, int type)
|
||||
@@ -1966,6 +1976,14 @@ pax_attribute(struct archive_read *a, struct tar *tar,
|
||||
if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
|
||||
pax_attribute_xattr(entry, key, value);
|
||||
break;
|
||||
case 'R':
|
||||
/* GNU tar uses RHT.security header to store SELinux xattrs
|
||||
* SCHILY.xattr.security.selinux == RHT.security.selinux */
|
||||
if (strcmp(key, "RHT.security.selinux") == 0) {
|
||||
pax_attribute_rht_security_selinux(entry, value,
|
||||
value_length);
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
/* We support some keys used by the "star" archiver */
|
||||
if (strcmp(key, "SCHILY.acl.access") == 0) {
|
||||
|
||||
@@ -127,7 +127,7 @@ static int _warc_skip(struct archive_read *a);
|
||||
static int _warc_rdhdr(struct archive_read *a, struct archive_entry *e);
|
||||
|
||||
/* private routines */
|
||||
static unsigned int _warc_rdver(const char buf[10], size_t bsz);
|
||||
static unsigned int _warc_rdver(const char *buf, size_t bsz);
|
||||
static unsigned int _warc_rdtyp(const char *buf, size_t bsz);
|
||||
static warc_string_t _warc_rduri(const char *buf, size_t bsz);
|
||||
static ssize_t _warc_rdlen(const char *buf, size_t bsz);
|
||||
@@ -337,6 +337,14 @@ start_over:
|
||||
mtime = rtime;
|
||||
}
|
||||
break;
|
||||
case WT_NONE:
|
||||
case WT_INFO:
|
||||
case WT_META:
|
||||
case WT_REQ:
|
||||
case WT_RVIS:
|
||||
case WT_CONV:
|
||||
case WT_CONT:
|
||||
case LAST_WT:
|
||||
default:
|
||||
fnam.len = 0U;
|
||||
fnam.str = NULL;
|
||||
@@ -361,6 +369,14 @@ start_over:
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WT_NONE:
|
||||
case WT_INFO:
|
||||
case WT_META:
|
||||
case WT_REQ:
|
||||
case WT_RVIS:
|
||||
case WT_CONV:
|
||||
case WT_CONT:
|
||||
case LAST_WT:
|
||||
default:
|
||||
/* consume the content and start over */
|
||||
_warc_skip(a);
|
||||
@@ -427,7 +443,7 @@ _warc_skip(struct archive_read *a)
|
||||
static void*
|
||||
deconst(const void *c)
|
||||
{
|
||||
return (char *)0x1 + (((const char *)c) - (const char *)0x1);
|
||||
return (void *)(uintptr_t)c;
|
||||
}
|
||||
|
||||
static char*
|
||||
|
||||
@@ -458,6 +458,11 @@ archive_read_support_format_xar(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* initialize xar->file_queue */
|
||||
xar->file_queue.allocated = 0;
|
||||
xar->file_queue.used = 0;
|
||||
xar->file_queue.files = NULL;
|
||||
|
||||
r = __archive_read_register_format(a,
|
||||
xar,
|
||||
"xar",
|
||||
@@ -1221,10 +1226,12 @@ heap_add_entry(struct archive_read *a,
|
||||
/* Expand our pending files list as necessary. */
|
||||
if (heap->used >= heap->allocated) {
|
||||
struct xar_file **new_pending_files;
|
||||
int new_size = heap->allocated * 2;
|
||||
int new_size;
|
||||
|
||||
if (heap->allocated < 1024)
|
||||
new_size = 1024;
|
||||
else
|
||||
new_size = heap->allocated * 2;
|
||||
/* Overflow might keep us from growing the list. */
|
||||
if (new_size <= heap->allocated) {
|
||||
archive_set_error(&a->archive,
|
||||
@@ -1238,9 +1245,11 @@ heap_add_entry(struct archive_read *a,
|
||||
ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
memcpy(new_pending_files, heap->files,
|
||||
heap->allocated * sizeof(new_pending_files[0]));
|
||||
free(heap->files);
|
||||
if (heap->allocated) {
|
||||
memcpy(new_pending_files, heap->files,
|
||||
heap->allocated * sizeof(new_pending_files[0]));
|
||||
free(heap->files);
|
||||
}
|
||||
heap->files = new_pending_files;
|
||||
heap->allocated = new_size;
|
||||
}
|
||||
|
||||
@@ -899,6 +899,81 @@ process_extra(struct archive_read *a, struct archive_entry *entry,
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
||||
/*
|
||||
* Auxiliary function to uncompress data chunk from zipx archive
|
||||
* (zip with lzma compression).
|
||||
*/
|
||||
static int
|
||||
zipx_lzma_uncompress_buffer(const char *compressed_buffer,
|
||||
size_t compressed_buffer_size,
|
||||
char *uncompressed_buffer,
|
||||
size_t uncompressed_buffer_size)
|
||||
{
|
||||
int status = ARCHIVE_FATAL;
|
||||
// length of 'lzma properties data' in lzma compressed
|
||||
// data segment (stream) inside zip archive
|
||||
const size_t lzma_params_length = 5;
|
||||
// offset of 'lzma properties data' from the beginning of lzma stream
|
||||
const size_t lzma_params_offset = 4;
|
||||
// end position of 'lzma properties data' in lzma stream
|
||||
const size_t lzma_params_end = lzma_params_offset + lzma_params_length;
|
||||
if (compressed_buffer == NULL ||
|
||||
compressed_buffer_size < lzma_params_end ||
|
||||
uncompressed_buffer == NULL)
|
||||
return status;
|
||||
|
||||
// prepare header for lzma_alone_decoder to replace zipx header
|
||||
// (see comments in 'zipx_lzma_alone_init' for justification)
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct _alone_header
|
||||
{
|
||||
uint8_t bytes[5]; // lzma_params_length
|
||||
uint64_t uncompressed_size;
|
||||
} alone_header;
|
||||
#pragma pack(pop)
|
||||
// copy 'lzma properties data' blob
|
||||
memcpy(&alone_header.bytes[0], compressed_buffer + lzma_params_offset,
|
||||
lzma_params_length);
|
||||
alone_header.uncompressed_size = UINT64_MAX;
|
||||
|
||||
// prepare new compressed buffer, see 'zipx_lzma_alone_init' for details
|
||||
const size_t lzma_alone_buffer_size =
|
||||
compressed_buffer_size - lzma_params_end + sizeof(alone_header);
|
||||
unsigned char *lzma_alone_compressed_buffer =
|
||||
(unsigned char*) malloc(lzma_alone_buffer_size);
|
||||
if (lzma_alone_compressed_buffer == NULL)
|
||||
return status;
|
||||
// copy lzma_alone header into new buffer
|
||||
memcpy(lzma_alone_compressed_buffer, (void*) &alone_header,
|
||||
sizeof(alone_header));
|
||||
// copy compressed data into new buffer
|
||||
memcpy(lzma_alone_compressed_buffer + sizeof(alone_header),
|
||||
compressed_buffer + lzma_params_end,
|
||||
compressed_buffer_size - lzma_params_end);
|
||||
|
||||
// create and fill in lzma_alone_decoder stream
|
||||
lzma_stream stream = LZMA_STREAM_INIT;
|
||||
lzma_ret ret = lzma_alone_decoder(&stream, UINT64_MAX);
|
||||
if (ret == LZMA_OK)
|
||||
{
|
||||
stream.next_in = lzma_alone_compressed_buffer;
|
||||
stream.avail_in = lzma_alone_buffer_size;
|
||||
stream.total_in = 0;
|
||||
stream.next_out = (unsigned char*)uncompressed_buffer;
|
||||
stream.avail_out = uncompressed_buffer_size;
|
||||
stream.total_out = 0;
|
||||
ret = lzma_code(&stream, LZMA_RUN);
|
||||
if (ret == LZMA_OK || ret == LZMA_STREAM_END)
|
||||
status = ARCHIVE_OK;
|
||||
}
|
||||
lzma_end(&stream);
|
||||
free(lzma_alone_compressed_buffer);
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assumes file pointer is at beginning of local file header.
|
||||
*/
|
||||
@@ -1173,18 +1248,64 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
"Truncated Zip file");
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
// take into account link compression if any
|
||||
size_t linkname_full_length = linkname_length;
|
||||
if (zip->entry->compression != 0)
|
||||
{
|
||||
// symlink target string appeared to be compressed
|
||||
int status = ARCHIVE_FATAL;
|
||||
char *uncompressed_buffer =
|
||||
(char*) malloc(zip_entry->uncompressed_size);
|
||||
if (uncompressed_buffer == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory for lzma decompression");
|
||||
return status;
|
||||
}
|
||||
|
||||
switch (zip->entry->compression)
|
||||
{
|
||||
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
||||
case 14: /* ZIPx LZMA compression. */
|
||||
/*(see zip file format specification, section 4.4.5)*/
|
||||
status = zipx_lzma_uncompress_buffer(p,
|
||||
linkname_length,
|
||||
uncompressed_buffer,
|
||||
(size_t)zip_entry->uncompressed_size);
|
||||
break;
|
||||
#endif
|
||||
default: /* Unsupported compression. */
|
||||
break;
|
||||
}
|
||||
if (status == ARCHIVE_OK)
|
||||
{
|
||||
p = uncompressed_buffer;
|
||||
linkname_full_length =
|
||||
(size_t)zip_entry->uncompressed_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Unsupported ZIP compression method "
|
||||
"during decompression of link entry (%d: %s)",
|
||||
zip->entry->compression,
|
||||
compression_name(zip->entry->compression));
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
sconv = zip->sconv;
|
||||
if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME))
|
||||
sconv = zip->sconv_utf8;
|
||||
if (sconv == NULL)
|
||||
sconv = zip->sconv_default;
|
||||
if (archive_entry_copy_symlink_l(entry, p, linkname_length,
|
||||
if (archive_entry_copy_symlink_l(entry, p, linkname_full_length,
|
||||
sconv) != 0) {
|
||||
if (errno != ENOMEM && sconv == zip->sconv_utf8 &&
|
||||
(zip->entry->zip_flags & ZIP_UTF8_NAME))
|
||||
archive_entry_copy_symlink_l(entry, p,
|
||||
linkname_length, NULL);
|
||||
linkname_full_length, NULL);
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Symlink");
|
||||
@@ -1901,15 +2022,15 @@ zipx_ppmd8_init(struct archive_read *a, struct zip *zip)
|
||||
|
||||
if(order < 2 || restore_method > 2) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Invalid parameter set in PPMd8 stream (order=%d, "
|
||||
"restore=%d)", order, restore_method);
|
||||
"Invalid parameter set in PPMd8 stream (order=%" PRId32 ", "
|
||||
"restore=%" PRId32 ")", order, restore_method);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
/* Allocate the memory needed to properly decompress the file. */
|
||||
if(!__archive_ppmd8_functions.Ppmd8_Alloc(&zip->ppmd8, mem << 20)) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Unable to allocate memory for PPMd8 stream: %d bytes",
|
||||
"Unable to allocate memory for PPMd8 stream: %" PRId32 " bytes",
|
||||
mem << 20);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
@@ -3881,6 +3881,11 @@ archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
|
||||
}
|
||||
|
||||
*p = NULL;
|
||||
/* Try converting WCS to MBS first if MBS does not exist yet. */
|
||||
if ((aes->aes_set & AES_SET_MBS) == 0) {
|
||||
const char *pm; /* unused */
|
||||
archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */
|
||||
}
|
||||
if (aes->aes_set & AES_SET_MBS) {
|
||||
sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
|
||||
if (sc == NULL)
|
||||
@@ -3903,9 +3908,9 @@ int
|
||||
archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
|
||||
const char **p)
|
||||
{
|
||||
struct archive_string_conv *sc;
|
||||
int r, ret = 0;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
/* If we already have an MBS form, return that immediately. */
|
||||
if (aes->aes_set & AES_SET_MBS) {
|
||||
*p = aes->aes_mbs.s;
|
||||
@@ -3926,10 +3931,23 @@ archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only a UTF-8 form cannot avail because its conversion already
|
||||
* failed at archive_mstring_update_utf8().
|
||||
*/
|
||||
/* If there's a UTF-8 form, try converting with the native locale. */
|
||||
if (aes->aes_set & AES_SET_UTF8) {
|
||||
archive_string_empty(&(aes->aes_mbs));
|
||||
sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
|
||||
if (sc == NULL)
|
||||
return (-1);/* Couldn't allocate memory for sc. */
|
||||
r = archive_strncpy_l(&(aes->aes_mbs),
|
||||
aes->aes_utf8.s, aes->aes_utf8.length, sc);
|
||||
if (a == NULL)
|
||||
free_sconv_object(sc);
|
||||
*p = aes->aes_mbs.s;
|
||||
if (r == 0) {
|
||||
aes->aes_set |= AES_SET_MBS;
|
||||
ret = 0;/* success; overwrite previous error. */
|
||||
} else
|
||||
ret = -1;/* failure. */
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -3947,6 +3965,11 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
|
||||
}
|
||||
|
||||
*wp = NULL;
|
||||
/* Try converting UTF8 to MBS first if MBS does not exist yet. */
|
||||
if ((aes->aes_set & AES_SET_MBS) == 0) {
|
||||
const char *p; /* unused */
|
||||
archive_mstring_get_mbs(a, aes, &p); /* ignore errors, we'll handle it later */
|
||||
}
|
||||
/* Try converting MBS to WCS using native locale. */
|
||||
if (aes->aes_set & AES_SET_MBS) {
|
||||
archive_wstring_empty(&(aes->aes_wcs));
|
||||
@@ -3962,11 +3985,12 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
|
||||
}
|
||||
|
||||
int
|
||||
archive_mstring_get_mbs_l(struct archive_mstring *aes,
|
||||
archive_mstring_get_mbs_l(struct archive *a, struct archive_mstring *aes,
|
||||
const char **p, size_t *length, struct archive_string_conv *sc)
|
||||
{
|
||||
int r, ret = 0;
|
||||
|
||||
(void)r; /* UNUSED */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/*
|
||||
* Internationalization programming on Windows must use Wide
|
||||
@@ -3989,20 +4013,12 @@ archive_mstring_get_mbs_l(struct archive_mstring *aes,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If there is not an MBS form but is a WCS form, try converting
|
||||
/* If there is not an MBS form but there is a WCS or UTF8 form, try converting
|
||||
* with the native locale to be used for translating it to specified
|
||||
* character-set. */
|
||||
if ((aes->aes_set & AES_SET_MBS) == 0 &&
|
||||
(aes->aes_set & AES_SET_WCS) != 0) {
|
||||
archive_string_empty(&(aes->aes_mbs));
|
||||
r = archive_string_append_from_wcs(&(aes->aes_mbs),
|
||||
aes->aes_wcs.s, aes->aes_wcs.length);
|
||||
if (r == 0)
|
||||
aes->aes_set |= AES_SET_MBS;
|
||||
else if (errno == ENOMEM)
|
||||
return (-1);
|
||||
else
|
||||
ret = -1;
|
||||
if ((aes->aes_set & AES_SET_MBS) == 0) {
|
||||
const char *pm; /* unused */
|
||||
archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */
|
||||
}
|
||||
/* If we already have an MBS form, use it to be translated to
|
||||
* specified character-set. */
|
||||
|
||||
@@ -226,7 +226,7 @@ void archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *
|
||||
int archive_mstring_get_mbs(struct archive *, struct archive_mstring *, const char **);
|
||||
int archive_mstring_get_utf8(struct archive *, struct archive_mstring *, const char **);
|
||||
int archive_mstring_get_wcs(struct archive *, struct archive_mstring *, const wchar_t **);
|
||||
int archive_mstring_get_mbs_l(struct archive_mstring *, const char **,
|
||||
int archive_mstring_get_mbs_l(struct archive *, struct archive_mstring *, const char **,
|
||||
size_t *, struct archive_string_conv *);
|
||||
int archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs);
|
||||
int archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs,
|
||||
|
||||
@@ -365,6 +365,7 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
|
||||
}
|
||||
fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR);
|
||||
if (fd == -1) {
|
||||
la_dosmaperr(GetLastError());
|
||||
CloseHandle(h);
|
||||
goto exit_tmpfile;
|
||||
} else
|
||||
@@ -432,6 +433,11 @@ __archive_mktemp(const char *tmpdir)
|
||||
if (temp_name.s[temp_name.length-1] != '/')
|
||||
archive_strappend_char(&temp_name, '/');
|
||||
}
|
||||
#ifdef O_TMPFILE
|
||||
fd = open(temp_name.s, O_RDWR|O_CLOEXEC|O_TMPFILE|O_EXCL, 0600);
|
||||
if(fd >= 0)
|
||||
goto exit_tmpfile;
|
||||
#endif
|
||||
archive_strcat(&temp_name, "libarchive_XXXXXX");
|
||||
fd = mkstemp(temp_name.s);
|
||||
if (fd < 0)
|
||||
|
||||
@@ -455,6 +455,25 @@ archive_write_client_write(struct archive_write_filter *f,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_write_client_free(struct archive_write_filter *f)
|
||||
{
|
||||
struct archive_write *a = (struct archive_write *)f->archive;
|
||||
|
||||
if (a->client_freer)
|
||||
(*a->client_freer)(&a->archive, a->client_data);
|
||||
a->client_data = NULL;
|
||||
|
||||
/* Clear passphrase. */
|
||||
if (a->passphrase != NULL) {
|
||||
memset(a->passphrase, 0, strlen(a->passphrase));
|
||||
free(a->passphrase);
|
||||
a->passphrase = NULL;
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_write_client_close(struct archive_write_filter *f)
|
||||
{
|
||||
@@ -493,13 +512,7 @@ archive_write_client_close(struct archive_write_filter *f)
|
||||
(*a->client_closer)(&a->archive, a->client_data);
|
||||
free(state->buffer);
|
||||
free(state);
|
||||
a->client_data = NULL;
|
||||
/* Clear passphrase. */
|
||||
if (a->passphrase != NULL) {
|
||||
memset(a->passphrase, 0, strlen(a->passphrase));
|
||||
free(a->passphrase);
|
||||
a->passphrase = NULL;
|
||||
}
|
||||
|
||||
/* Clear the close handler myself not to be called again. */
|
||||
f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
|
||||
return (ret);
|
||||
@@ -509,9 +522,9 @@ archive_write_client_close(struct archive_write_filter *f)
|
||||
* Open the archive using the current settings.
|
||||
*/
|
||||
int
|
||||
archive_write_open(struct archive *_a, void *client_data,
|
||||
archive_write_open2(struct archive *_a, void *client_data,
|
||||
archive_open_callback *opener, archive_write_callback *writer,
|
||||
archive_close_callback *closer)
|
||||
archive_close_callback *closer, archive_free_callback *freer)
|
||||
{
|
||||
struct archive_write *a = (struct archive_write *)_a;
|
||||
struct archive_write_filter *client_filter;
|
||||
@@ -524,12 +537,14 @@ archive_write_open(struct archive *_a, void *client_data,
|
||||
a->client_writer = writer;
|
||||
a->client_opener = opener;
|
||||
a->client_closer = closer;
|
||||
a->client_freer = freer;
|
||||
a->client_data = client_data;
|
||||
|
||||
client_filter = __archive_write_allocate_filter(_a);
|
||||
client_filter->open = archive_write_client_open;
|
||||
client_filter->write = archive_write_client_write;
|
||||
client_filter->close = archive_write_client_close;
|
||||
client_filter->free = archive_write_client_free;
|
||||
|
||||
ret = __archive_write_filters_open(a);
|
||||
if (ret < ARCHIVE_WARN) {
|
||||
@@ -544,6 +559,15 @@ archive_write_open(struct archive *_a, void *client_data,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
archive_write_open(struct archive *_a, void *client_data,
|
||||
archive_open_callback *opener, archive_write_callback *writer,
|
||||
archive_close_callback *closer)
|
||||
{
|
||||
return archive_write_open2(_a, client_data, opener, writer,
|
||||
closer, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close out the archive.
|
||||
*/
|
||||
|
||||
@@ -196,10 +196,6 @@ __archive_write_program_free(struct archive_write_program_data *data)
|
||||
{
|
||||
|
||||
if (data) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
if (data->child)
|
||||
CloseHandle(data->child);
|
||||
#endif
|
||||
free(data->program_name);
|
||||
free(data->child_buf);
|
||||
free(data);
|
||||
@@ -211,7 +207,7 @@ int
|
||||
__archive_write_program_open(struct archive_write_filter *f,
|
||||
struct archive_write_program_data *data, const char *cmd)
|
||||
{
|
||||
pid_t child;
|
||||
int ret;
|
||||
|
||||
if (data->child_buf == NULL) {
|
||||
data->child_buf_len = 65536;
|
||||
@@ -225,27 +221,13 @@ __archive_write_program_open(struct archive_write_filter *f,
|
||||
}
|
||||
}
|
||||
|
||||
child = __archive_create_child(cmd, &data->child_stdin,
|
||||
&data->child_stdout);
|
||||
if (child == -1) {
|
||||
ret = __archive_create_child(cmd, &data->child_stdin,
|
||||
&data->child_stdout, &data->child);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
archive_set_error(f->archive, EINVAL,
|
||||
"Can't launch external program: %s", cmd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
data->child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, child);
|
||||
if (data->child == NULL) {
|
||||
close(data->child_stdin);
|
||||
data->child_stdin = -1;
|
||||
close(data->child_stdout);
|
||||
data->child_stdout = -1;
|
||||
archive_set_error(f->archive, EINVAL,
|
||||
"Can't launch external program: %s", cmd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#else
|
||||
data->child = child;
|
||||
#endif
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -382,8 +382,12 @@ archive_compressor_xz_options(struct archive_write_filter *f,
|
||||
value[1] != '\0')
|
||||
return (ARCHIVE_WARN);
|
||||
data->compression_level = value[0] - '0';
|
||||
if (data->compression_level > 9)
|
||||
data->compression_level = 9;
|
||||
#ifdef _AIX
|
||||
if (data->compression_level > 6)
|
||||
data->compression_level = 6;
|
||||
#endif
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "threads") == 0) {
|
||||
char *endptr;
|
||||
|
||||
@@ -59,6 +59,16 @@ struct private_data {
|
||||
#endif
|
||||
};
|
||||
|
||||
/* If we don't have the library use default range values (zstdcli.c v1.4.0) */
|
||||
#define CLEVEL_MIN -99
|
||||
#define CLEVEL_STD_MIN 0 /* prior to 1.3.4 and more recent without using --fast */
|
||||
#define CLEVEL_DEFAULT 3
|
||||
#define CLEVEL_STD_MAX 19 /* without using --ultra */
|
||||
#define CLEVEL_MAX 22
|
||||
|
||||
#define MINVER_NEGCLEVEL 10304
|
||||
#define MINVER_MINCLEVEL 10306
|
||||
|
||||
static int archive_compressor_zstd_options(struct archive_write_filter *,
|
||||
const char *, const char *);
|
||||
static int archive_compressor_zstd_open(struct archive_write_filter *);
|
||||
@@ -96,7 +106,7 @@ archive_write_add_filter_zstd(struct archive *_a)
|
||||
f->free = &archive_compressor_zstd_free;
|
||||
f->code = ARCHIVE_FILTER_ZSTD;
|
||||
f->name = "zstd";
|
||||
data->compression_level = 3; /* Default level used by the zstd CLI */
|
||||
data->compression_level = CLEVEL_DEFAULT;
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
data->cstream = ZSTD_createCStream();
|
||||
if (data->cstream == NULL) {
|
||||
@@ -135,6 +145,31 @@ archive_compressor_zstd_free(struct archive_write_filter *f)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int string_is_numeric (const char* value)
|
||||
{
|
||||
size_t len = strlen(value);
|
||||
size_t i;
|
||||
|
||||
if (len == 0) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
else if (len == 1 && !(value[0] >= '0' && value[0] <= '9')) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
else if (!(value[0] >= '0' && value[0] <= '9') &&
|
||||
value[0] != '-' && value[0] != '+') {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
for (i = 1; i < len; i++) {
|
||||
if (!(value[i] >= '0' && value[i] <= '9')) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set write options.
|
||||
*/
|
||||
@@ -146,12 +181,25 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
|
||||
|
||||
if (strcmp(key, "compression-level") == 0) {
|
||||
int level = atoi(value);
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
if (level < 1 || level > ZSTD_maxCLevel()) {
|
||||
#else
|
||||
/* If we don't have the library, hard-code the max level */
|
||||
if (level < 1 || level > 22) {
|
||||
int minimum = CLEVEL_MIN;
|
||||
int maximum = CLEVEL_MAX;
|
||||
if (string_is_numeric(value) != ARCHIVE_OK) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
maximum = ZSTD_maxCLevel();
|
||||
#if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL
|
||||
if (ZSTD_versionNumber() >= MINVER_MINCLEVEL) {
|
||||
minimum = ZSTD_minCLevel();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (ZSTD_versionNumber() < MINVER_NEGCLEVEL) {
|
||||
minimum = CLEVEL_STD_MIN;
|
||||
}
|
||||
#endif
|
||||
if (level < minimum || level > maximum) {
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
data->compression_level = level;
|
||||
@@ -297,7 +345,26 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
|
||||
int r;
|
||||
|
||||
archive_string_init(&as);
|
||||
archive_string_sprintf(&as, "zstd -%d", data->compression_level);
|
||||
/* --no-check matches library default */
|
||||
archive_strcpy(&as, "zstd --no-check");
|
||||
|
||||
if (data->compression_level < CLEVEL_STD_MIN) {
|
||||
struct archive_string as2;
|
||||
archive_string_init(&as2);
|
||||
archive_string_sprintf(&as2, " --fast=%d", -data->compression_level);
|
||||
archive_string_concat(&as, &as2);
|
||||
archive_string_free(&as2);
|
||||
} else {
|
||||
struct archive_string as2;
|
||||
archive_string_init(&as2);
|
||||
archive_string_sprintf(&as2, " -%d", data->compression_level);
|
||||
archive_string_concat(&as, &as2);
|
||||
archive_string_free(&as2);
|
||||
}
|
||||
|
||||
if (data->compression_level > CLEVEL_STD_MAX) {
|
||||
archive_strcat(&as, " --ultra");
|
||||
}
|
||||
|
||||
f->write = archive_compressor_zstd_write;
|
||||
r = __archive_write_program_open(f, data->pdata, as.s);
|
||||
|
||||
@@ -546,6 +546,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
||||
{
|
||||
struct archive_write_disk *a = (struct archive_write_disk *)_a;
|
||||
struct fixup_entry *fe;
|
||||
const char *linkname;
|
||||
int ret, r;
|
||||
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
|
||||
@@ -590,6 +591,17 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
|
||||
/*
|
||||
* Check if we have a hardlink that points to itself.
|
||||
*/
|
||||
linkname = archive_entry_hardlink(a->entry);
|
||||
if (linkname != NULL && strcmp(a->name, linkname) == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Skipping hardlink pointing to itself: %s",
|
||||
a->name);
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the umask so we get predictable mode settings.
|
||||
* This gets done on every call to _write_header in case the
|
||||
@@ -1856,8 +1868,9 @@ finish_metadata:
|
||||
if (a->tmpname) {
|
||||
if (rename(a->tmpname, a->name) == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"rename failed");
|
||||
ret = ARCHIVE_FATAL;
|
||||
"Failed to rename temporary file");
|
||||
ret = ARCHIVE_FAILED;
|
||||
unlink(a->tmpname);
|
||||
}
|
||||
a->tmpname = NULL;
|
||||
}
|
||||
@@ -2144,8 +2157,11 @@ restore_entry(struct archive_write_disk *a)
|
||||
if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
|
||||
S_ISREG(a->st.st_mode)) {
|
||||
/* Use a temporary file to extract */
|
||||
if ((a->fd = la_mktemp(a)) == -1)
|
||||
if ((a->fd = la_mktemp(a)) == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Can't create temporary file");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
a->pst = NULL;
|
||||
en = 0;
|
||||
} else {
|
||||
@@ -4407,10 +4423,19 @@ set_xattrs(struct archive_write_disk *a)
|
||||
int e;
|
||||
int namespace;
|
||||
|
||||
namespace = EXTATTR_NAMESPACE_USER;
|
||||
|
||||
if (strncmp(name, "user.", 5) == 0) {
|
||||
/* "user." attributes go to user namespace */
|
||||
name += 5;
|
||||
namespace = EXTATTR_NAMESPACE_USER;
|
||||
} else if (strncmp(name, "system.", 7) == 0) {
|
||||
name += 7;
|
||||
namespace = EXTATTR_NAMESPACE_SYSTEM;
|
||||
if (!strcmp(name, "nfs4.acl") ||
|
||||
!strcmp(name, "posix1e.acl_access") ||
|
||||
!strcmp(name, "posix1e.acl_default"))
|
||||
continue;
|
||||
} else {
|
||||
/* Other namespaces are unsupported */
|
||||
archive_strcat(&errlist, name);
|
||||
@@ -4421,8 +4446,29 @@ set_xattrs(struct archive_write_disk *a)
|
||||
}
|
||||
|
||||
if (a->fd >= 0) {
|
||||
/*
|
||||
* On FreeBSD, extattr_set_fd does not
|
||||
* return the same as
|
||||
* extattr_set_file. It returns zero
|
||||
* on success, non-zero on failure.
|
||||
*
|
||||
* We can detect the failure by
|
||||
* manually setting errno prior to the
|
||||
* call and checking after.
|
||||
*
|
||||
* If errno remains zero, fake the
|
||||
* return value by setting e to size.
|
||||
*
|
||||
* This is a hack for now until I
|
||||
* (Shawn Webb) get FreeBSD to fix the
|
||||
* issue, if that's even possible.
|
||||
*/
|
||||
errno = 0;
|
||||
e = extattr_set_fd(a->fd, namespace, name,
|
||||
value, size);
|
||||
if (e == 0 && errno == 0) {
|
||||
e = size;
|
||||
}
|
||||
} else {
|
||||
e = extattr_set_link(
|
||||
archive_entry_pathname(entry), namespace,
|
||||
|
||||
@@ -549,6 +549,8 @@ la_mktemp(struct archive_write_disk *a)
|
||||
a->tmpname = a->_tmpname_data.s;
|
||||
|
||||
fd = __archive_mkstemp(a->tmpname);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
mode = a->mode & 0777 & ~a->user_umask;
|
||||
if (la_chmod(a->tmpname, mode) == -1) {
|
||||
@@ -1281,9 +1283,11 @@ _archive_write_disk_finish_entry(struct archive *_a)
|
||||
/* Windows does not support atomic rename */
|
||||
disk_unlink(a->name);
|
||||
if (_wrename(a->tmpname, a->name) != 0) {
|
||||
la_dosmaperr(GetLastError());
|
||||
archive_set_error(&a->archive, errno,
|
||||
"rename failed");
|
||||
ret = ARCHIVE_FATAL;
|
||||
"Failed to rename temporary file");
|
||||
ret = ARCHIVE_FAILED;
|
||||
disk_unlink(a->tmpname);
|
||||
}
|
||||
a->tmpname = NULL;
|
||||
}
|
||||
@@ -1573,12 +1577,17 @@ restore_entry(struct archive_write_disk *a)
|
||||
S_ISREG(st_mode)) {
|
||||
int fd = la_mktemp(a);
|
||||
|
||||
if (fd == -1)
|
||||
if (fd == -1) {
|
||||
la_dosmaperr(GetLastError());
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Can't create temporary file");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
a->fh = (HANDLE)_get_osfhandle(fd);
|
||||
if (a->fh == INVALID_HANDLE_VALUE)
|
||||
if (a->fh == INVALID_HANDLE_VALUE) {
|
||||
la_dosmaperr(GetLastError());
|
||||
return (ARCHIVE_FAILED);
|
||||
|
||||
}
|
||||
a->pst = NULL;
|
||||
en = 0;
|
||||
} else {
|
||||
|
||||
@@ -24,11 +24,12 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dd November 12, 2020
|
||||
.Dt ARCHIVE_WRITE_OPEN 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_write_open ,
|
||||
.Nm archive_write_open2 ,
|
||||
.Nm archive_write_open_fd ,
|
||||
.Nm archive_write_open_FILE ,
|
||||
.Nm archive_write_open_filename ,
|
||||
@@ -47,6 +48,15 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Fa "archive_close_callback *"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_write_open2
|
||||
.Fa "struct archive *"
|
||||
.Fa "void *client_data"
|
||||
.Fa "archive_open_callback *"
|
||||
.Fa "archive_write_callback *"
|
||||
.Fa "archive_close_callback *"
|
||||
.Fa "archive_free_callback *"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_write_open_fd "struct archive *" "int fd"
|
||||
.Ft int
|
||||
.Fn archive_write_open_FILE "struct archive *" "FILE *file"
|
||||
@@ -67,6 +77,11 @@ This is the most generic form of this function, which accepts
|
||||
pointers to three callback functions which will be invoked by
|
||||
the compression layer to write the constructed archive.
|
||||
This does not alter the default archive padding.
|
||||
.It Fn archive_write_open2
|
||||
Same as
|
||||
.Fn archive_write_open
|
||||
with an additional fourth free callback. This function should be preferred to
|
||||
.Fn archive_write_open .
|
||||
.It Fn archive_write_open_fd
|
||||
A convenience form of
|
||||
.Fn archive_write_open
|
||||
@@ -106,14 +121,14 @@ to a character or block device node, it will disable padding otherwise.
|
||||
You can override this by manually invoking
|
||||
.Fn archive_write_set_bytes_in_last_block
|
||||
before calling
|
||||
.Fn archive_write_open .
|
||||
.Fn archive_write_open2 .
|
||||
The
|
||||
.Fn archive_write_open_filename
|
||||
function is safe for use with tape drives or other
|
||||
block-oriented devices.
|
||||
.It Fn archive_write_open_memory
|
||||
A convenience form of
|
||||
.Fn archive_write_open
|
||||
.Fn archive_write_open2
|
||||
that accepts a pointer to a block of memory that will receive
|
||||
the archive.
|
||||
The final
|
||||
@@ -145,7 +160,7 @@ To use this library, you will need to define and register
|
||||
callback functions that will be invoked to write data to the
|
||||
resulting archive.
|
||||
These functions are registered by calling
|
||||
.Fn archive_write_open :
|
||||
.Fn archive_write_open2 :
|
||||
.Bl -item -offset indent
|
||||
.It
|
||||
.Ft typedef int
|
||||
@@ -162,6 +177,8 @@ If the open fails, it should call
|
||||
.Fn archive_set_error
|
||||
to register an error code and message and return
|
||||
.Cm ARCHIVE_FATAL .
|
||||
Please note that if open fails, close is not called and resources must be
|
||||
freed inside the open callback or with the free callback.
|
||||
.Bl -item -offset indent
|
||||
.It
|
||||
.Ft typedef la_ssize_t
|
||||
@@ -192,7 +209,8 @@ to register an error code and message and return -1.
|
||||
.El
|
||||
.Pp
|
||||
The close callback is invoked by archive_close when
|
||||
the archive processing is complete.
|
||||
the archive processing is complete. If the open callback fails, the close
|
||||
callback is not invoked.
|
||||
The callback should return
|
||||
.Cm ARCHIVE_OK
|
||||
on success.
|
||||
@@ -200,7 +218,14 @@ On failure, the callback should invoke
|
||||
.Fn archive_set_error
|
||||
to register an error code and message and
|
||||
return
|
||||
.Cm ARCHIVE_FATAL .
|
||||
.Bl -item -offset indent
|
||||
.It
|
||||
.Ft typedef int
|
||||
.Fn archive_free_callback "struct archive *" "void *client_data"
|
||||
.El
|
||||
.Pp
|
||||
The free callback is always invoked on archive_free.
|
||||
The return code of this callback is not processed.
|
||||
.Pp
|
||||
Note that if the client-provided write callback function
|
||||
returns a non-zero value, that error will be propagated back to the caller
|
||||
|
||||
@@ -54,7 +54,7 @@ struct write_fd_data {
|
||||
int fd;
|
||||
};
|
||||
|
||||
static int file_close(struct archive *, void *);
|
||||
static int file_free(struct archive *, void *);
|
||||
static int file_open(struct archive *, void *);
|
||||
static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
|
||||
|
||||
@@ -72,8 +72,8 @@ archive_write_open_fd(struct archive *a, int fd)
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
setmode(mine->fd, O_BINARY);
|
||||
#endif
|
||||
return (archive_write_open(a, mine,
|
||||
file_open, file_write, file_close));
|
||||
return (archive_write_open2(a, mine,
|
||||
file_open, file_write, NULL, file_free));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -134,11 +134,13 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
|
||||
}
|
||||
|
||||
static int
|
||||
file_close(struct archive *a, void *client_data)
|
||||
file_free(struct archive *a, void *client_data)
|
||||
{
|
||||
struct write_fd_data *mine = (struct write_fd_data *)client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
if (mine == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ struct write_FILE_data {
|
||||
FILE *f;
|
||||
};
|
||||
|
||||
static int file_close(struct archive *, void *);
|
||||
static int file_free(struct archive *, void *);
|
||||
static int file_open(struct archive *, void *);
|
||||
static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
|
||||
|
||||
@@ -66,8 +66,8 @@ archive_write_open_FILE(struct archive *a, FILE *f)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
mine->f = f;
|
||||
return (archive_write_open(a, mine,
|
||||
file_open, file_write, file_close));
|
||||
return (archive_write_open2(a, mine, file_open, file_write,
|
||||
NULL, file_free));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -99,11 +99,13 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
|
||||
}
|
||||
|
||||
static int
|
||||
file_close(struct archive *a, void *client_data)
|
||||
file_free(struct archive *a, void *client_data)
|
||||
{
|
||||
struct write_FILE_data *mine = client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
if (mine == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ struct write_file_data {
|
||||
};
|
||||
|
||||
static int file_close(struct archive *, void *);
|
||||
static int file_free(struct archive *, void *);
|
||||
static int file_open(struct archive *, void *);
|
||||
static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
|
||||
static int open_filename(struct archive *, int, const void *);
|
||||
@@ -123,8 +124,8 @@ open_filename(struct archive *a, int mbs_fn, const void *filename)
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
mine->fd = -1;
|
||||
return (archive_write_open(a, mine,
|
||||
file_open, file_write, file_close));
|
||||
return (archive_write_open2(a, mine,
|
||||
file_open, file_write, file_close, file_free));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -244,9 +245,25 @@ file_close(struct archive *a, void *client_data)
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
|
||||
if (mine == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
if (mine->fd >= 0)
|
||||
close(mine->fd);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
file_free(struct archive *a, void *client_data)
|
||||
{
|
||||
struct write_file_data *mine = (struct write_file_data *)client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
|
||||
if (mine == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
archive_mstring_clean(&mine->filename);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
@@ -39,7 +39,7 @@ struct write_memory_data {
|
||||
unsigned char * buff;
|
||||
};
|
||||
|
||||
static int memory_write_close(struct archive *, void *);
|
||||
static int memory_write_free(struct archive *, void *);
|
||||
static int memory_write_open(struct archive *, void *);
|
||||
static ssize_t memory_write(struct archive *, void *, const void *buff, size_t);
|
||||
|
||||
@@ -61,8 +61,8 @@ archive_write_open_memory(struct archive *a, void *buff, size_t buffSize, size_t
|
||||
mine->buff = buff;
|
||||
mine->size = buffSize;
|
||||
mine->client_size = used;
|
||||
return (archive_write_open(a, mine,
|
||||
memory_write_open, memory_write, memory_write_close));
|
||||
return (archive_write_open2(a, mine,
|
||||
memory_write_open, memory_write, NULL, memory_write_free));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -103,11 +103,13 @@ memory_write(struct archive *a, void *client_data, const void *buff, size_t leng
|
||||
}
|
||||
|
||||
static int
|
||||
memory_write_close(struct archive *a, void *client_data)
|
||||
memory_write_free(struct archive *a, void *client_data)
|
||||
{
|
||||
struct write_memory_data *mine;
|
||||
(void)a; /* UNUSED */
|
||||
mine = client_data;
|
||||
if (mine == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ struct archive_write {
|
||||
archive_open_callback *client_opener;
|
||||
archive_write_callback *client_writer;
|
||||
archive_close_callback *client_closer;
|
||||
archive_free_callback *client_freer;
|
||||
void *client_data;
|
||||
|
||||
/*
|
||||
|
||||
@@ -82,7 +82,7 @@ void
|
||||
__archive_write_entry_filetype_unsupported(struct archive *a,
|
||||
struct archive_entry *entry, const char *format)
|
||||
{
|
||||
char *name = NULL;
|
||||
const char *name = NULL;
|
||||
|
||||
switch (archive_entry_filetype(entry)) {
|
||||
/*
|
||||
|
||||
@@ -1927,8 +1927,8 @@ compression_init_encoder_lzma(struct archive *a,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
lzmafilters = (lzma_filter *)(strm+1);
|
||||
if (level > 6)
|
||||
level = 6;
|
||||
if (level > 9)
|
||||
level = 9;
|
||||
if (lzma_lzma_preset(&lzma_opt, level)) {
|
||||
free(strm);
|
||||
lastrm->real_stream = NULL;
|
||||
|
||||
@@ -250,7 +250,7 @@ archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry)
|
||||
const char *path;
|
||||
size_t len;
|
||||
|
||||
if (archive_entry_filetype(entry) == 0) {
|
||||
if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
|
||||
archive_set_error(&a->archive, -1, "Filetype required");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
@@ -348,7 +348,7 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
|
||||
if (archive_entry_filetype(entry) == AE_IFBLK
|
||||
|| archive_entry_filetype(entry) == AE_IFCHR)
|
||||
format_octal(archive_entry_dev(entry), h + c_rdev_offset, c_rdev_size);
|
||||
format_octal(archive_entry_rdev(entry), h + c_rdev_offset, c_rdev_size);
|
||||
else
|
||||
format_octal(0, h + c_rdev_offset, c_rdev_size);
|
||||
format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
|
||||
|
||||
@@ -190,7 +190,7 @@ archive_write_newc_header(struct archive_write *a, struct archive_entry *entry)
|
||||
const char *path;
|
||||
size_t len;
|
||||
|
||||
if (archive_entry_filetype(entry) == 0) {
|
||||
if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
|
||||
archive_set_error(&a->archive, -1, "Filetype required");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
@@ -2178,7 +2178,8 @@ get_system_identitier(char *system_id, size_t size)
|
||||
strncpy(system_id, "Windows", size-1);
|
||||
system_id[size-1] = '\0';
|
||||
#else
|
||||
#error no way to get the system identifier on your platform.
|
||||
strncpy(system_id, "Unknown", size-1);
|
||||
system_id[size-1] = '\0';
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171
|
||||
#include "archive.h"
|
||||
#include "archive_digest_private.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_entry_private.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_rb.h"
|
||||
#include "archive_string.h"
|
||||
@@ -82,24 +83,7 @@ struct dir_info {
|
||||
struct reg_info {
|
||||
int compute_sum;
|
||||
uint32_t crc;
|
||||
#ifdef ARCHIVE_HAS_MD5
|
||||
unsigned char buf_md5[16];
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_RMD160
|
||||
unsigned char buf_rmd160[20];
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA1
|
||||
unsigned char buf_sha1[20];
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA256
|
||||
unsigned char buf_sha256[32];
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA384
|
||||
unsigned char buf_sha384[48];
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA512
|
||||
unsigned char buf_sha512[64];
|
||||
#endif
|
||||
struct ae_digest digest;
|
||||
};
|
||||
|
||||
struct mtree_entry {
|
||||
@@ -1571,27 +1555,27 @@ sum_final(struct mtree_writer *mtree, struct reg_info *reg)
|
||||
}
|
||||
#ifdef ARCHIVE_HAS_MD5
|
||||
if (mtree->compute_sum & F_MD5)
|
||||
archive_md5_final(&mtree->md5ctx, reg->buf_md5);
|
||||
archive_md5_final(&mtree->md5ctx, reg->digest.md5);
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_RMD160
|
||||
if (mtree->compute_sum & F_RMD160)
|
||||
archive_rmd160_final(&mtree->rmd160ctx, reg->buf_rmd160);
|
||||
archive_rmd160_final(&mtree->rmd160ctx, reg->digest.rmd160);
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA1
|
||||
if (mtree->compute_sum & F_SHA1)
|
||||
archive_sha1_final(&mtree->sha1ctx, reg->buf_sha1);
|
||||
archive_sha1_final(&mtree->sha1ctx, reg->digest.sha1);
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA256
|
||||
if (mtree->compute_sum & F_SHA256)
|
||||
archive_sha256_final(&mtree->sha256ctx, reg->buf_sha256);
|
||||
archive_sha256_final(&mtree->sha256ctx, reg->digest.sha256);
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA384
|
||||
if (mtree->compute_sum & F_SHA384)
|
||||
archive_sha384_final(&mtree->sha384ctx, reg->buf_sha384);
|
||||
archive_sha384_final(&mtree->sha384ctx, reg->digest.sha384);
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA512
|
||||
if (mtree->compute_sum & F_SHA512)
|
||||
archive_sha512_final(&mtree->sha512ctx, reg->buf_sha512);
|
||||
archive_sha512_final(&mtree->sha512ctx, reg->digest.sha512);
|
||||
#endif
|
||||
/* Save what types of sum are computed. */
|
||||
reg->compute_sum = mtree->compute_sum;
|
||||
@@ -1621,42 +1605,47 @@ sum_write(struct archive_string *str, struct reg_info *reg)
|
||||
archive_string_sprintf(str, " cksum=%ju",
|
||||
(uintmax_t)reg->crc);
|
||||
}
|
||||
|
||||
#define append_digest(_s, _r, _t) \
|
||||
strappend_bin(_s, _r->digest._t, sizeof(_r->digest._t))
|
||||
|
||||
#ifdef ARCHIVE_HAS_MD5
|
||||
if (reg->compute_sum & F_MD5) {
|
||||
archive_strcat(str, " md5digest=");
|
||||
strappend_bin(str, reg->buf_md5, sizeof(reg->buf_md5));
|
||||
append_digest(str, reg, md5);
|
||||
}
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_RMD160
|
||||
if (reg->compute_sum & F_RMD160) {
|
||||
archive_strcat(str, " rmd160digest=");
|
||||
strappend_bin(str, reg->buf_rmd160, sizeof(reg->buf_rmd160));
|
||||
append_digest(str, reg, rmd160);
|
||||
}
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA1
|
||||
if (reg->compute_sum & F_SHA1) {
|
||||
archive_strcat(str, " sha1digest=");
|
||||
strappend_bin(str, reg->buf_sha1, sizeof(reg->buf_sha1));
|
||||
append_digest(str, reg, sha1);
|
||||
}
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA256
|
||||
if (reg->compute_sum & F_SHA256) {
|
||||
archive_strcat(str, " sha256digest=");
|
||||
strappend_bin(str, reg->buf_sha256, sizeof(reg->buf_sha256));
|
||||
append_digest(str, reg, sha256);
|
||||
}
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA384
|
||||
if (reg->compute_sum & F_SHA384) {
|
||||
archive_strcat(str, " sha384digest=");
|
||||
strappend_bin(str, reg->buf_sha384, sizeof(reg->buf_sha384));
|
||||
append_digest(str, reg, sha384);
|
||||
}
|
||||
#endif
|
||||
#ifdef ARCHIVE_HAS_SHA512
|
||||
if (reg->compute_sum & F_SHA512) {
|
||||
archive_strcat(str, " sha512digest=");
|
||||
strappend_bin(str, reg->buf_sha512, sizeof(reg->buf_sha512));
|
||||
append_digest(str, reg, sha512);
|
||||
}
|
||||
#endif
|
||||
#undef append_digest
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -681,7 +681,8 @@ xar_write_data(struct archive_write *a, const void *buff, size_t s)
|
||||
{
|
||||
struct xar *xar;
|
||||
enum la_zaction run;
|
||||
size_t size, rsize;
|
||||
size_t size = 0;
|
||||
size_t rsize;
|
||||
int r;
|
||||
|
||||
xar = (struct xar *)a->format_data;
|
||||
@@ -2930,8 +2931,8 @@ compression_init_encoder_xz(struct archive *a,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
lzmafilters = (lzma_filter *)(strm+1);
|
||||
if (level > 6)
|
||||
level = 6;
|
||||
if (level > 9)
|
||||
level = 9;
|
||||
if (lzma_lzma_preset(&lzma_opt, level)) {
|
||||
free(strm);
|
||||
lastrm->real_stream = NULL;
|
||||
|
||||
@@ -584,6 +584,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
||||
zip->entry_flags |= ZIP_ENTRY_FLAG_ENCRYPTED;
|
||||
zip->entry_encryption = zip->encryption_type;
|
||||
break;
|
||||
case ENCRYPTION_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -710,6 +711,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
||||
+ AUTH_CODE_SIZE;
|
||||
version_needed = 20;
|
||||
break;
|
||||
case ENCRYPTION_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -762,6 +764,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
||||
if (version_needed < 20)
|
||||
version_needed = 20;
|
||||
break;
|
||||
case ENCRYPTION_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1029,6 +1032,7 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
|
||||
zip->cctx_valid = zip->hctx_valid = 1;
|
||||
}
|
||||
break;
|
||||
case ENCRYPTION_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1117,6 +1121,7 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
|
||||
break;
|
||||
#endif
|
||||
|
||||
case COMPRESSION_UNSPECIFIED:
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid ZIP compression type");
|
||||
|
||||
@@ -255,7 +255,8 @@ If supported, the default value is read from
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm compression-level
|
||||
The value is interpreted as a decimal integer specifying the
|
||||
compression level. Supported values are from 1 to 22.
|
||||
compression level. Supported values depend on the library version,
|
||||
common values are from 1 to 22.
|
||||
.El
|
||||
.It Format 7zip
|
||||
.Bl -tag -compact -width indent
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#define __LIBARCHIVE_CONFIG_H_INCLUDED 1
|
||||
|
||||
#include <osreldate.h>
|
||||
|
||||
@@ -183,6 +184,7 @@
|
||||
#define HAVE_STRFTIME 1
|
||||
#define HAVE_STRINGS_H 1
|
||||
#define HAVE_STRING_H 1
|
||||
#define HAVE_STRNLEN 1
|
||||
#define HAVE_STRRCHR 1
|
||||
#define HAVE_STRUCT_STATFS_F_NAMEMAX 1
|
||||
#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
|
||||
|
||||
@@ -244,7 +244,7 @@ Note that this format supports only 4 gigabyte files (unlike the
|
||||
older ASCII format, which supports 8 gigabyte files).
|
||||
.Pp
|
||||
In this format, hardlinked files are handled by setting the
|
||||
filesize to zero for each entry except the last one that
|
||||
filesize to zero for each entry except the first one that
|
||||
appears in the archive.
|
||||
.Ss New CRC Format
|
||||
The CRC format is identical to the new ASCII format described
|
||||
|
||||
@@ -32,8 +32,13 @@
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
pid_t
|
||||
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout);
|
||||
int
|
||||
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
HANDLE *out_child);
|
||||
#else
|
||||
pid_t *out_child);
|
||||
#endif
|
||||
|
||||
void
|
||||
__archive_check_child(int in, int out);
|
||||
|
||||
@@ -72,8 +72,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/filter_fork.c 182958 2008-09-12 05:33:00
|
||||
|
||||
#include "filter_fork.h"
|
||||
|
||||
pid_t
|
||||
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
|
||||
int
|
||||
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
|
||||
pid_t *out_child)
|
||||
{
|
||||
pid_t child;
|
||||
int stdin_pipe[2], stdout_pipe[2], tmp;
|
||||
@@ -177,7 +178,8 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
|
||||
fcntl(*child_stdout, F_SETFL, O_NONBLOCK);
|
||||
__archive_cmdline_free(cmdline);
|
||||
|
||||
return child;
|
||||
*out_child = child;
|
||||
return ARCHIVE_OK;
|
||||
|
||||
#if HAVE_POSIX_SPAWNP
|
||||
actions_inited:
|
||||
@@ -192,7 +194,7 @@ stdin_opened:
|
||||
close(stdin_pipe[1]);
|
||||
state_allocated:
|
||||
__archive_cmdline_free(cmdline);
|
||||
return -1;
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -31,8 +31,9 @@
|
||||
|
||||
#include "filter_fork.h"
|
||||
|
||||
pid_t
|
||||
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
|
||||
int
|
||||
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
|
||||
HANDLE *out_child)
|
||||
{
|
||||
HANDLE childStdout[2], childStdin[2],childStderr;
|
||||
SECURITY_ATTRIBUTES secAtts;
|
||||
@@ -44,6 +45,7 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
|
||||
char *arg0, *ext;
|
||||
int i, l;
|
||||
DWORD fl, fl_old;
|
||||
HANDLE child;
|
||||
|
||||
childStdout[0] = childStdout[1] = INVALID_HANDLE_VALUE;
|
||||
childStdin[0] = childStdin[1] = INVALID_HANDLE_VALUE;
|
||||
@@ -154,13 +156,20 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
|
||||
*child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY);
|
||||
*child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY);
|
||||
|
||||
child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
|
||||
childInfo.dwProcessId);
|
||||
if (child == NULL) // INVALID_HANDLE_VALUE ?
|
||||
goto fail;
|
||||
|
||||
*out_child = child;
|
||||
|
||||
CloseHandle(childStdout[1]);
|
||||
CloseHandle(childStdin[0]);
|
||||
|
||||
archive_string_free(&cmdline);
|
||||
archive_string_free(&fullpath);
|
||||
__archive_cmdline_free(acmd);
|
||||
return (childInfo.dwProcessId);
|
||||
return ARCHIVE_OK;
|
||||
|
||||
fail:
|
||||
if (childStdout[0] != INVALID_HANDLE_VALUE)
|
||||
@@ -176,7 +185,7 @@ fail:
|
||||
archive_string_free(&cmdline);
|
||||
archive_string_free(&fullpath);
|
||||
__archive_cmdline_free(acmd);
|
||||
return (-1);
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user