mirror of
https://github.com/cmclark00/retro-imager.git
synced 2025-05-19 00:15:21 +01:00
Qt/QML edition
This commit is contained in:
commit
d7b361ba44
2168 changed files with 721948 additions and 0 deletions
265
dependencies/libarchive-3.4.2/libarchive/CMakeLists.txt
vendored
Normal file
265
dependencies/libarchive-3.4.2/libarchive/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,265 @@
|
|||
|
||||
############################################
|
||||
#
|
||||
# How to build libarchive
|
||||
#
|
||||
############################################
|
||||
|
||||
# Public headers
|
||||
SET(include_HEADERS
|
||||
archive.h
|
||||
archive_entry.h
|
||||
)
|
||||
|
||||
# Sources and private headers
|
||||
SET(libarchive_SOURCES
|
||||
archive_acl.c
|
||||
archive_acl_private.h
|
||||
archive_check_magic.c
|
||||
archive_cmdline.c
|
||||
archive_cmdline_private.h
|
||||
archive_crc32.h
|
||||
archive_cryptor.c
|
||||
archive_cryptor_private.h
|
||||
archive_digest.c
|
||||
archive_digest_private.h
|
||||
archive_endian.h
|
||||
archive_entry.c
|
||||
archive_entry.h
|
||||
archive_entry_copy_stat.c
|
||||
archive_entry_link_resolver.c
|
||||
archive_entry_locale.h
|
||||
archive_entry_private.h
|
||||
archive_entry_sparse.c
|
||||
archive_entry_stat.c
|
||||
archive_entry_strmode.c
|
||||
archive_entry_xattr.c
|
||||
archive_getdate.c
|
||||
archive_getdate.h
|
||||
archive_hmac.c
|
||||
archive_hmac_private.h
|
||||
archive_match.c
|
||||
archive_openssl_evp_private.h
|
||||
archive_openssl_hmac_private.h
|
||||
archive_options.c
|
||||
archive_options_private.h
|
||||
archive_pack_dev.h
|
||||
archive_pack_dev.c
|
||||
archive_pathmatch.c
|
||||
archive_pathmatch.h
|
||||
archive_platform.h
|
||||
archive_platform_acl.h
|
||||
archive_platform_xattr.h
|
||||
archive_ppmd_private.h
|
||||
archive_ppmd8.c
|
||||
archive_ppmd8_private.h
|
||||
archive_ppmd7.c
|
||||
archive_ppmd7_private.h
|
||||
archive_private.h
|
||||
archive_random.c
|
||||
archive_random_private.h
|
||||
archive_rb.c
|
||||
archive_rb.h
|
||||
archive_read.c
|
||||
archive_read_add_passphrase.c
|
||||
archive_read_append_filter.c
|
||||
archive_read_data_into_fd.c
|
||||
archive_read_disk_entry_from_file.c
|
||||
archive_read_disk_posix.c
|
||||
archive_read_disk_private.h
|
||||
archive_read_disk_set_standard_lookup.c
|
||||
archive_read_extract.c
|
||||
archive_read_extract2.c
|
||||
archive_read_open_fd.c
|
||||
archive_read_open_file.c
|
||||
archive_read_open_filename.c
|
||||
archive_read_open_memory.c
|
||||
archive_read_private.h
|
||||
archive_read_set_format.c
|
||||
archive_read_set_options.c
|
||||
archive_read_support_filter_all.c
|
||||
archive_read_support_filter_bzip2.c
|
||||
archive_read_support_filter_compress.c
|
||||
archive_read_support_filter_gzip.c
|
||||
archive_read_support_filter_grzip.c
|
||||
archive_read_support_filter_lrzip.c
|
||||
archive_read_support_filter_lz4.c
|
||||
archive_read_support_filter_lzop.c
|
||||
archive_read_support_filter_none.c
|
||||
archive_read_support_filter_program.c
|
||||
archive_read_support_filter_rpm.c
|
||||
archive_read_support_filter_uu.c
|
||||
archive_read_support_filter_xz.c
|
||||
archive_read_support_filter_zstd.c
|
||||
archive_read_support_format_7zip.c
|
||||
archive_read_support_format_all.c
|
||||
archive_read_support_format_ar.c
|
||||
archive_read_support_format_by_code.c
|
||||
archive_read_support_format_cab.c
|
||||
archive_read_support_format_cpio.c
|
||||
archive_read_support_format_empty.c
|
||||
archive_read_support_format_iso9660.c
|
||||
archive_read_support_format_lha.c
|
||||
archive_read_support_format_mtree.c
|
||||
archive_read_support_format_rar.c
|
||||
archive_read_support_format_rar5.c
|
||||
archive_read_support_format_raw.c
|
||||
archive_read_support_format_tar.c
|
||||
archive_read_support_format_warc.c
|
||||
archive_read_support_format_xar.c
|
||||
archive_read_support_format_zip.c
|
||||
archive_string.c
|
||||
archive_string.h
|
||||
archive_string_composition.h
|
||||
archive_string_sprintf.c
|
||||
archive_util.c
|
||||
archive_version_details.c
|
||||
archive_virtual.c
|
||||
archive_write.c
|
||||
archive_write_disk_posix.c
|
||||
archive_write_disk_private.h
|
||||
archive_write_disk_set_standard_lookup.c
|
||||
archive_write_private.h
|
||||
archive_write_open_fd.c
|
||||
archive_write_open_file.c
|
||||
archive_write_open_filename.c
|
||||
archive_write_open_memory.c
|
||||
archive_write_add_filter.c
|
||||
archive_write_add_filter_b64encode.c
|
||||
archive_write_add_filter_by_name.c
|
||||
archive_write_add_filter_bzip2.c
|
||||
archive_write_add_filter_compress.c
|
||||
archive_write_add_filter_grzip.c
|
||||
archive_write_add_filter_gzip.c
|
||||
archive_write_add_filter_lrzip.c
|
||||
archive_write_add_filter_lz4.c
|
||||
archive_write_add_filter_lzop.c
|
||||
archive_write_add_filter_none.c
|
||||
archive_write_add_filter_program.c
|
||||
archive_write_add_filter_uuencode.c
|
||||
archive_write_add_filter_xz.c
|
||||
archive_write_add_filter_zstd.c
|
||||
archive_write_set_format.c
|
||||
archive_write_set_format_7zip.c
|
||||
archive_write_set_format_ar.c
|
||||
archive_write_set_format_by_name.c
|
||||
archive_write_set_format_cpio.c
|
||||
archive_write_set_format_cpio_newc.c
|
||||
archive_write_set_format_filter_by_ext.c
|
||||
archive_write_set_format_gnutar.c
|
||||
archive_write_set_format_iso9660.c
|
||||
archive_write_set_format_mtree.c
|
||||
archive_write_set_format_pax.c
|
||||
archive_write_set_format_private.h
|
||||
archive_write_set_format_raw.c
|
||||
archive_write_set_format_shar.c
|
||||
archive_write_set_format_ustar.c
|
||||
archive_write_set_format_v7tar.c
|
||||
archive_write_set_format_warc.c
|
||||
archive_write_set_format_xar.c
|
||||
archive_write_set_format_zip.c
|
||||
archive_write_set_options.c
|
||||
archive_write_set_passphrase.c
|
||||
archive_xxhash.h
|
||||
filter_fork_posix.c
|
||||
filter_fork.h
|
||||
xxhash.c
|
||||
)
|
||||
|
||||
# Man pages
|
||||
SET(libarchive_MANS
|
||||
archive_entry.3
|
||||
archive_entry_acl.3
|
||||
archive_entry_linkify.3
|
||||
archive_entry_misc.3
|
||||
archive_entry_paths.3
|
||||
archive_entry_perms.3
|
||||
archive_entry_stat.3
|
||||
archive_entry_time.3
|
||||
archive_read.3
|
||||
archive_read_add_passphrase.3
|
||||
archive_read_data.3
|
||||
archive_read_disk.3
|
||||
archive_read_extract.3
|
||||
archive_read_filter.3
|
||||
archive_read_format.3
|
||||
archive_read_free.3
|
||||
archive_read_header.3
|
||||
archive_read_new.3
|
||||
archive_read_open.3
|
||||
archive_read_set_options.3
|
||||
archive_util.3
|
||||
archive_write.3
|
||||
archive_write_blocksize.3
|
||||
archive_write_data.3
|
||||
archive_write_disk.3
|
||||
archive_write_filter.3
|
||||
archive_write_finish_entry.3
|
||||
archive_write_format.3
|
||||
archive_write_free.3
|
||||
archive_write_header.3
|
||||
archive_write_new.3
|
||||
archive_write_open.3
|
||||
archive_write_set_options.3
|
||||
archive_write_set_passphrase.3
|
||||
cpio.5
|
||||
libarchive.3
|
||||
libarchive_changes.3
|
||||
libarchive_internals.3
|
||||
libarchive-formats.5
|
||||
mtree.5
|
||||
tar.5
|
||||
)
|
||||
|
||||
IF(WIN32 AND NOT CYGWIN)
|
||||
LIST(APPEND libarchive_SOURCES archive_entry_copy_bhfi.c)
|
||||
LIST(APPEND libarchive_SOURCES archive_read_disk_windows.c)
|
||||
LIST(APPEND libarchive_SOURCES archive_windows.c)
|
||||
LIST(APPEND libarchive_SOURCES archive_windows.h)
|
||||
LIST(APPEND libarchive_SOURCES archive_write_disk_windows.c)
|
||||
LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
|
||||
ENDIF(WIN32 AND NOT CYGWIN)
|
||||
|
||||
IF(ARCHIVE_BLAKE2)
|
||||
LIST(APPEND libarchive_SOURCES archive_blake2sp_ref.c)
|
||||
LIST(APPEND libarchive_SOURCES archive_blake2s_ref.c)
|
||||
ENDIF(ARCHIVE_BLAKE2)
|
||||
|
||||
IF(ARCHIVE_ACL_DARWIN)
|
||||
LIST(APPEND libarchive_SOURCES archive_disk_acl_darwin.c)
|
||||
ELSEIF(ARCHIVE_ACL_FREEBSD)
|
||||
LIST(APPEND libarchive_SOURCES archive_disk_acl_freebsd.c)
|
||||
ELSEIF(ARCHIVE_ACL_LIBACL)
|
||||
LIST(APPEND libarchive_SOURCES archive_disk_acl_linux.c)
|
||||
ELSEIF(ARCHIVE_ACL_SUNOS)
|
||||
LIST(APPEND libarchive_SOURCES archive_disk_acl_sunos.c)
|
||||
ENDIF()
|
||||
|
||||
# Libarchive is a shared library
|
||||
#ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
|
||||
#TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
|
||||
#TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
|
||||
#SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
|
||||
|
||||
# archive_static is a static library
|
||||
ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS})
|
||||
TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS})
|
||||
SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
|
||||
LIBARCHIVE_STATIC)
|
||||
# On Posix systems, libarchive.so and libarchive.a can co-exist.
|
||||
IF(NOT WIN32 OR CYGWIN)
|
||||
SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
|
||||
ENDIF(NOT WIN32 OR CYGWIN)
|
||||
|
||||
IF(ENABLE_INSTALL)
|
||||
# How to install the libraries
|
||||
#INSTALL(TARGETS archive archive_static
|
||||
INSTALL(TARGETS archive_static
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib)
|
||||
INSTALL_MAN(${libarchive_MANS})
|
||||
INSTALL(FILES ${include_HEADERS} DESTINATION include)
|
||||
ENDIF()
|
||||
|
||||
add_subdirectory(test)
|
1197
dependencies/libarchive-3.4.2/libarchive/archive.h
vendored
Normal file
1197
dependencies/libarchive-3.4.2/libarchive/archive.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
2097
dependencies/libarchive-3.4.2/libarchive/archive_acl.c
vendored
Normal file
2097
dependencies/libarchive-3.4.2/libarchive/archive_acl.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
83
dependencies/libarchive-3.4.2/libarchive/archive_acl_private.h
vendored
Normal file
83
dependencies/libarchive-3.4.2/libarchive/archive_acl_private.h
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2010 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include "archive_string.h"
|
||||
|
||||
struct archive_acl_entry {
|
||||
struct archive_acl_entry *next;
|
||||
int type; /* E.g., access or default */
|
||||
int tag; /* E.g., user/group/other/mask */
|
||||
int permset; /* r/w/x bits */
|
||||
int id; /* uid/gid for user/group */
|
||||
struct archive_mstring name; /* uname/gname */
|
||||
};
|
||||
|
||||
struct archive_acl {
|
||||
mode_t mode;
|
||||
struct archive_acl_entry *acl_head;
|
||||
struct archive_acl_entry *acl_p;
|
||||
int acl_state; /* See acl_next for details. */
|
||||
wchar_t *acl_text_w;
|
||||
char *acl_text;
|
||||
int acl_types;
|
||||
};
|
||||
|
||||
void archive_acl_clear(struct archive_acl *);
|
||||
void archive_acl_copy(struct archive_acl *, struct archive_acl *);
|
||||
int archive_acl_count(struct archive_acl *, int);
|
||||
int archive_acl_types(struct archive_acl *);
|
||||
int archive_acl_reset(struct archive_acl *, int);
|
||||
int archive_acl_next(struct archive *, struct archive_acl *, int,
|
||||
int *, int *, int *, int *, const char **);
|
||||
|
||||
int archive_acl_add_entry(struct archive_acl *, int, int, int, int, const char *);
|
||||
int archive_acl_add_entry_w_len(struct archive_acl *,
|
||||
int, int, int, int, const wchar_t *, size_t);
|
||||
int archive_acl_add_entry_len(struct archive_acl *,
|
||||
int, int, int, int, const char *, size_t);
|
||||
|
||||
wchar_t *archive_acl_to_text_w(struct archive_acl *, ssize_t *, int,
|
||||
struct archive *);
|
||||
char *archive_acl_to_text_l(struct archive_acl *, ssize_t *, int,
|
||||
struct archive_string_conv *);
|
||||
|
||||
/*
|
||||
* ACL text parser.
|
||||
*/
|
||||
int archive_acl_from_text_w(struct archive_acl *, const wchar_t * /* wtext */,
|
||||
int /* type */);
|
||||
int archive_acl_from_text_l(struct archive_acl *, const char * /* text */,
|
||||
int /* type */, struct archive_string_conv *);
|
||||
|
||||
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
|
195
dependencies/libarchive-3.4.2/libarchive/archive_blake2.h
vendored
Normal file
195
dependencies/libarchive-3.4.2/libarchive/archive_blake2.h
vendored
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_BLAKE2_H
|
||||
#define ARCHIVE_BLAKE2_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
|
||||
#else
|
||||
#define BLAKE2_PACKED(x) x __attribute__((packed))
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum blake2s_constant
|
||||
{
|
||||
BLAKE2S_BLOCKBYTES = 64,
|
||||
BLAKE2S_OUTBYTES = 32,
|
||||
BLAKE2S_KEYBYTES = 32,
|
||||
BLAKE2S_SALTBYTES = 8,
|
||||
BLAKE2S_PERSONALBYTES = 8
|
||||
};
|
||||
|
||||
enum blake2b_constant
|
||||
{
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_OUTBYTES = 64,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
BLAKE2B_SALTBYTES = 16,
|
||||
BLAKE2B_PERSONALBYTES = 16
|
||||
};
|
||||
|
||||
typedef struct blake2s_state__
|
||||
{
|
||||
uint32_t h[8];
|
||||
uint32_t t[2];
|
||||
uint32_t f[2];
|
||||
uint8_t buf[BLAKE2S_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
size_t outlen;
|
||||
uint8_t last_node;
|
||||
} blake2s_state;
|
||||
|
||||
typedef struct blake2b_state__
|
||||
{
|
||||
uint64_t h[8];
|
||||
uint64_t t[2];
|
||||
uint64_t f[2];
|
||||
uint8_t buf[BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
size_t outlen;
|
||||
uint8_t last_node;
|
||||
} blake2b_state;
|
||||
|
||||
typedef struct blake2sp_state__
|
||||
{
|
||||
blake2s_state S[8][1];
|
||||
blake2s_state R[1];
|
||||
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
size_t outlen;
|
||||
} blake2sp_state;
|
||||
|
||||
typedef struct blake2bp_state__
|
||||
{
|
||||
blake2b_state S[4][1];
|
||||
blake2b_state R[1];
|
||||
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
size_t outlen;
|
||||
} blake2bp_state;
|
||||
|
||||
BLAKE2_PACKED(struct blake2s_param__
|
||||
{
|
||||
uint8_t digest_length; /* 1 */
|
||||
uint8_t key_length; /* 2 */
|
||||
uint8_t fanout; /* 3 */
|
||||
uint8_t depth; /* 4 */
|
||||
uint32_t leaf_length; /* 8 */
|
||||
uint32_t node_offset; /* 12 */
|
||||
uint16_t xof_length; /* 14 */
|
||||
uint8_t node_depth; /* 15 */
|
||||
uint8_t inner_length; /* 16 */
|
||||
/* uint8_t reserved[0]; */
|
||||
uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */
|
||||
uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */
|
||||
});
|
||||
|
||||
typedef struct blake2s_param__ blake2s_param;
|
||||
|
||||
BLAKE2_PACKED(struct blake2b_param__
|
||||
{
|
||||
uint8_t digest_length; /* 1 */
|
||||
uint8_t key_length; /* 2 */
|
||||
uint8_t fanout; /* 3 */
|
||||
uint8_t depth; /* 4 */
|
||||
uint32_t leaf_length; /* 8 */
|
||||
uint32_t node_offset; /* 12 */
|
||||
uint32_t xof_length; /* 16 */
|
||||
uint8_t node_depth; /* 17 */
|
||||
uint8_t inner_length; /* 18 */
|
||||
uint8_t reserved[14]; /* 32 */
|
||||
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
|
||||
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
|
||||
});
|
||||
|
||||
typedef struct blake2b_param__ blake2b_param;
|
||||
|
||||
typedef struct blake2xs_state__
|
||||
{
|
||||
blake2s_state S[1];
|
||||
blake2s_param P[1];
|
||||
} blake2xs_state;
|
||||
|
||||
typedef struct blake2xb_state__
|
||||
{
|
||||
blake2b_state S[1];
|
||||
blake2b_param P[1];
|
||||
} blake2xb_state;
|
||||
|
||||
/* Padded structs result in a compile-time error */
|
||||
enum {
|
||||
BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES),
|
||||
BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES)
|
||||
};
|
||||
|
||||
/* Streaming API */
|
||||
int blake2s_init( blake2s_state *S, size_t outlen );
|
||||
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
|
||||
int blake2s_update( blake2s_state *S, const void *in, size_t inlen );
|
||||
int blake2s_final( blake2s_state *S, void *out, size_t outlen );
|
||||
|
||||
int blake2b_init( blake2b_state *S, size_t outlen );
|
||||
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
|
||||
int blake2b_update( blake2b_state *S, const void *in, size_t inlen );
|
||||
int blake2b_final( blake2b_state *S, void *out, size_t outlen );
|
||||
|
||||
int blake2sp_init( blake2sp_state *S, size_t outlen );
|
||||
int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );
|
||||
int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen );
|
||||
int blake2sp_final( blake2sp_state *S, void *out, size_t outlen );
|
||||
|
||||
int blake2bp_init( blake2bp_state *S, size_t outlen );
|
||||
int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );
|
||||
int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen );
|
||||
int blake2bp_final( blake2bp_state *S, void *out, size_t outlen );
|
||||
|
||||
/* Variable output length API */
|
||||
int blake2xs_init( blake2xs_state *S, const size_t outlen );
|
||||
int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen );
|
||||
int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen );
|
||||
int blake2xs_final(blake2xs_state *S, void *out, size_t outlen);
|
||||
|
||||
int blake2xb_init( blake2xb_state *S, const size_t outlen );
|
||||
int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen );
|
||||
int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen );
|
||||
int blake2xb_final(blake2xb_state *S, void *out, size_t outlen);
|
||||
|
||||
/* Simple API */
|
||||
int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
|
||||
int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
|
||||
int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
|
||||
/* This is simply an alias for blake2b */
|
||||
int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
161
dependencies/libarchive-3.4.2/libarchive/archive_blake2_impl.h
vendored
Normal file
161
dependencies/libarchive-3.4.2/libarchive/archive_blake2_impl.h
vendored
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_BLAKE2_IMPL_H
|
||||
#define ARCHIVE_BLAKE2_IMPL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
|
||||
#if defined(_MSC_VER)
|
||||
#define BLAKE2_INLINE __inline
|
||||
#elif defined(__GNUC__)
|
||||
#define BLAKE2_INLINE __inline__
|
||||
#else
|
||||
#define BLAKE2_INLINE
|
||||
#endif
|
||||
#else
|
||||
#define BLAKE2_INLINE inline
|
||||
#endif
|
||||
|
||||
static BLAKE2_INLINE uint32_t load32( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint32_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
return (( uint32_t )( p[0] ) << 0) |
|
||||
(( uint32_t )( p[1] ) << 8) |
|
||||
(( uint32_t )( p[2] ) << 16) |
|
||||
(( uint32_t )( p[3] ) << 24) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint64_t load64( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint64_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
return (( uint64_t )( p[0] ) << 0) |
|
||||
(( uint64_t )( p[1] ) << 8) |
|
||||
(( uint64_t )( p[2] ) << 16) |
|
||||
(( uint64_t )( p[3] ) << 24) |
|
||||
(( uint64_t )( p[4] ) << 32) |
|
||||
(( uint64_t )( p[5] ) << 40) |
|
||||
(( uint64_t )( p[6] ) << 48) |
|
||||
(( uint64_t )( p[7] ) << 56) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint16_t load16( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint16_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
return ( uint16_t )((( uint32_t )( p[0] ) << 0) |
|
||||
(( uint32_t )( p[1] ) << 8));
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store16( void *dst, uint16_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store32( void *dst, uint32_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
p[0] = (uint8_t)(w >> 0);
|
||||
p[1] = (uint8_t)(w >> 8);
|
||||
p[2] = (uint8_t)(w >> 16);
|
||||
p[3] = (uint8_t)(w >> 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store64( void *dst, uint64_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
p[0] = (uint8_t)(w >> 0);
|
||||
p[1] = (uint8_t)(w >> 8);
|
||||
p[2] = (uint8_t)(w >> 16);
|
||||
p[3] = (uint8_t)(w >> 24);
|
||||
p[4] = (uint8_t)(w >> 32);
|
||||
p[5] = (uint8_t)(w >> 40);
|
||||
p[6] = (uint8_t)(w >> 48);
|
||||
p[7] = (uint8_t)(w >> 56);
|
||||
#endif
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint64_t load48( const void *src )
|
||||
{
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
return (( uint64_t )( p[0] ) << 0) |
|
||||
(( uint64_t )( p[1] ) << 8) |
|
||||
(( uint64_t )( p[2] ) << 16) |
|
||||
(( uint64_t )( p[3] ) << 24) |
|
||||
(( uint64_t )( p[4] ) << 32) |
|
||||
(( uint64_t )( p[5] ) << 40) ;
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void store48( void *dst, uint64_t w )
|
||||
{
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
p[0] = (uint8_t)(w >> 0);
|
||||
p[1] = (uint8_t)(w >> 8);
|
||||
p[2] = (uint8_t)(w >> 16);
|
||||
p[3] = (uint8_t)(w >> 24);
|
||||
p[4] = (uint8_t)(w >> 32);
|
||||
p[5] = (uint8_t)(w >> 40);
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 32 - c ) );
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 64 - c ) );
|
||||
}
|
||||
|
||||
/* prevents compiler optimizing out memset() */
|
||||
static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
|
||||
{
|
||||
static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
|
||||
memset_v(v, 0, n);
|
||||
}
|
||||
|
||||
#endif
|
367
dependencies/libarchive-3.4.2/libarchive/archive_blake2s_ref.c
vendored
Normal file
367
dependencies/libarchive-3.4.2/libarchive/archive_blake2s_ref.c
vendored
Normal file
|
@ -0,0 +1,367 @@
|
|||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "archive_blake2.h"
|
||||
#include "archive_blake2_impl.h"
|
||||
|
||||
static const uint32_t blake2s_IV[8] =
|
||||
{
|
||||
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
||||
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||
};
|
||||
|
||||
static const uint8_t blake2s_sigma[10][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
};
|
||||
|
||||
static void blake2s_set_lastnode( blake2s_state *S )
|
||||
{
|
||||
S->f[1] = (uint32_t)-1;
|
||||
}
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
static int blake2s_is_lastblock( const blake2s_state *S )
|
||||
{
|
||||
return S->f[0] != 0;
|
||||
}
|
||||
|
||||
static void blake2s_set_lastblock( blake2s_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2s_set_lastnode( S );
|
||||
|
||||
S->f[0] = (uint32_t)-1;
|
||||
}
|
||||
|
||||
static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
|
||||
{
|
||||
S->t[0] += inc;
|
||||
S->t[1] += ( S->t[0] < inc );
|
||||
}
|
||||
|
||||
static void blake2s_init0( blake2s_state *S )
|
||||
{
|
||||
size_t i;
|
||||
memset( S, 0, sizeof( blake2s_state ) );
|
||||
|
||||
for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
|
||||
}
|
||||
|
||||
/* init2 xors IV with input parameter block */
|
||||
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
|
||||
{
|
||||
const unsigned char *p = ( const unsigned char * )( P );
|
||||
size_t i;
|
||||
|
||||
blake2s_init0( S );
|
||||
|
||||
/* IV XOR ParamBlock */
|
||||
for( i = 0; i < 8; ++i )
|
||||
S->h[i] ^= load32( &p[i * 4] );
|
||||
|
||||
S->outlen = P->digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Sequential blake2s initialization */
|
||||
int blake2s_init( blake2s_state *S, size_t outlen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
|
||||
/* Move interval verification here? */
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||
|
||||
P->digest_length = (uint8_t)outlen;
|
||||
P->key_length = 0;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store32( &P->node_offset, 0 );
|
||||
store16( &P->xof_length, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
/* memset(P->reserved, 0, sizeof(P->reserved) ); */
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2s_init_param( S, P );
|
||||
}
|
||||
|
||||
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||
|
||||
if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
P->digest_length = (uint8_t)outlen;
|
||||
P->key_length = (uint8_t)keylen;
|
||||
P->fanout = 1;
|
||||
P->depth = 1;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store32( &P->node_offset, 0 );
|
||||
store16( &P->xof_length, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = 0;
|
||||
/* memset(P->reserved, 0, sizeof(P->reserved) ); */
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
|
||||
if( blake2s_init_param( S, P ) < 0 ) return -1;
|
||||
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define G(r,i,a,b,c,d) \
|
||||
do { \
|
||||
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
|
||||
d = rotr32(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr32(b ^ c, 12); \
|
||||
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
|
||||
d = rotr32(d ^ a, 8); \
|
||||
c = c + d; \
|
||||
b = rotr32(b ^ c, 7); \
|
||||
} while(0)
|
||||
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
||||
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
||||
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
||||
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
||||
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
||||
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
||||
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
||||
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
||||
} while(0)
|
||||
|
||||
static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] )
|
||||
{
|
||||
uint32_t m[16];
|
||||
uint32_t v[16];
|
||||
size_t i;
|
||||
|
||||
for( i = 0; i < 16; ++i ) {
|
||||
m[i] = load32( in + i * sizeof( m[i] ) );
|
||||
}
|
||||
|
||||
for( i = 0; i < 8; ++i ) {
|
||||
v[i] = S->h[i];
|
||||
}
|
||||
|
||||
v[ 8] = blake2s_IV[0];
|
||||
v[ 9] = blake2s_IV[1];
|
||||
v[10] = blake2s_IV[2];
|
||||
v[11] = blake2s_IV[3];
|
||||
v[12] = S->t[0] ^ blake2s_IV[4];
|
||||
v[13] = S->t[1] ^ blake2s_IV[5];
|
||||
v[14] = S->f[0] ^ blake2s_IV[6];
|
||||
v[15] = S->f[1] ^ blake2s_IV[7];
|
||||
|
||||
ROUND( 0 );
|
||||
ROUND( 1 );
|
||||
ROUND( 2 );
|
||||
ROUND( 3 );
|
||||
ROUND( 4 );
|
||||
ROUND( 5 );
|
||||
ROUND( 6 );
|
||||
ROUND( 7 );
|
||||
ROUND( 8 );
|
||||
ROUND( 9 );
|
||||
|
||||
for( i = 0; i < 8; ++i ) {
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
}
|
||||
}
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
|
||||
int blake2s_update( blake2s_state *S, const void *pin, size_t inlen )
|
||||
{
|
||||
const unsigned char * in = (const unsigned char *)pin;
|
||||
if( inlen > 0 )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = BLAKE2S_BLOCKBYTES - left;
|
||||
if( inlen > fill )
|
||||
{
|
||||
S->buflen = 0;
|
||||
memcpy( S->buf + left, in, fill ); /* Fill buffer */
|
||||
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||
blake2s_compress( S, S->buf ); /* Compress */
|
||||
in += fill; inlen -= fill;
|
||||
while(inlen > BLAKE2S_BLOCKBYTES) {
|
||||
blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
|
||||
blake2s_compress( S, in );
|
||||
in += BLAKE2S_BLOCKBYTES;
|
||||
inlen -= BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
memcpy( S->buf + S->buflen, in, inlen );
|
||||
S->buflen += inlen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2s_final( blake2s_state *S, void *out, size_t outlen )
|
||||
{
|
||||
uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
|
||||
size_t i;
|
||||
|
||||
if( out == NULL || outlen < S->outlen )
|
||||
return -1;
|
||||
|
||||
if( blake2s_is_lastblock( S ) )
|
||||
return -1;
|
||||
|
||||
blake2s_increment_counter( S, ( uint32_t )S->buflen );
|
||||
blake2s_set_lastblock( S );
|
||||
memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
|
||||
blake2s_compress( S, S->buf );
|
||||
|
||||
for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
|
||||
store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
|
||||
|
||||
memcpy( out, buffer, outlen );
|
||||
secure_zero_memory(buffer, sizeof(buffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
|
||||
{
|
||||
blake2s_state S[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in && inlen > 0 ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if ( NULL == key && keylen > 0) return -1;
|
||||
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
if( keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( blake2s_init( S, outlen ) < 0 ) return -1;
|
||||
}
|
||||
|
||||
blake2s_update( S, ( const uint8_t * )in, inlen );
|
||||
blake2s_final( S, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(SUPERCOP)
|
||||
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
|
||||
{
|
||||
return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BLAKE2S_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( void )
|
||||
{
|
||||
uint8_t key[BLAKE2S_KEYBYTES];
|
||||
uint8_t buf[BLAKE2_KAT_LENGTH];
|
||||
size_t i, step;
|
||||
|
||||
for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
/* Test simple API */
|
||||
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test streaming API */
|
||||
for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {
|
||||
for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2s_state S;
|
||||
uint8_t * p = buf;
|
||||
size_t mlen = i;
|
||||
int err = 0;
|
||||
|
||||
if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
while (mlen >= step) {
|
||||
if ( (err = blake2s_update(&S, p, step)) < 0 ) {
|
||||
goto fail;
|
||||
}
|
||||
mlen -= step;
|
||||
p += step;
|
||||
}
|
||||
if ( (err = blake2s_update(&S, p, mlen)) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
fail:
|
||||
puts("error");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
359
dependencies/libarchive-3.4.2/libarchive/archive_blake2sp_ref.c
vendored
Normal file
359
dependencies/libarchive-3.4.2/libarchive/archive_blake2sp_ref.c
vendored
Normal file
|
@ -0,0 +1,359 @@
|
|||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "archive_blake2.h"
|
||||
#include "archive_blake2_impl.h"
|
||||
|
||||
#define PARALLELISM_DEGREE 8
|
||||
|
||||
/*
|
||||
blake2sp_init_param defaults to setting the expecting output length
|
||||
from the digest_length parameter block field.
|
||||
|
||||
In some cases, however, we do not want this, as the output length
|
||||
of these instances is given by inner_length instead.
|
||||
*/
|
||||
static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P )
|
||||
{
|
||||
int err = blake2s_init_param(S, P);
|
||||
S->outlen = P->inner_length;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint32_t offset )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
P->digest_length = (uint8_t)outlen;
|
||||
P->key_length = (uint8_t)keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store32( &P->node_offset, offset );
|
||||
store16( &P->xof_length, 0 );
|
||||
P->node_depth = 0;
|
||||
P->inner_length = BLAKE2S_OUTBYTES;
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2sp_init_leaf_param( S, P );
|
||||
}
|
||||
|
||||
static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen )
|
||||
{
|
||||
blake2s_param P[1];
|
||||
P->digest_length = (uint8_t)outlen;
|
||||
P->key_length = (uint8_t)keylen;
|
||||
P->fanout = PARALLELISM_DEGREE;
|
||||
P->depth = 2;
|
||||
store32( &P->leaf_length, 0 );
|
||||
store32( &P->node_offset, 0 );
|
||||
store16( &P->xof_length, 0 );
|
||||
P->node_depth = 1;
|
||||
P->inner_length = BLAKE2S_OUTBYTES;
|
||||
memset( P->salt, 0, sizeof( P->salt ) );
|
||||
memset( P->personal, 0, sizeof( P->personal ) );
|
||||
return blake2s_init_param( S, P );
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_init( blake2sp_state *S, size_t outlen )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
S->outlen = outlen;
|
||||
|
||||
if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S->S[i], outlen, 0, (uint32_t)i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
S->outlen = outlen;
|
||||
|
||||
if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S->S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1;
|
||||
|
||||
S->R->last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen )
|
||||
{
|
||||
const unsigned char * in = (const unsigned char *)pin;
|
||||
size_t left = S->buflen;
|
||||
size_t fill = sizeof( S->buf ) - left;
|
||||
size_t i;
|
||||
|
||||
if( left && inlen >= fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill );
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t i = omp_get_thread_num();
|
||||
#endif
|
||||
size_t inlen__ = inlen;
|
||||
const unsigned char *in__ = ( const unsigned char * )in;
|
||||
in__ += i * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
|
||||
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
|
||||
inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
if( inlen > 0 )
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
|
||||
S->buflen = left + inlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2sp_final( blake2sp_state *S, void *out, size_t outlen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||
size_t i;
|
||||
|
||||
if(out == NULL || outlen < S->outlen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
{
|
||||
if( S->buflen > i * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;
|
||||
|
||||
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
|
||||
}
|
||||
|
||||
blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );
|
||||
}
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
|
||||
|
||||
return blake2s_final( S->R, out, S->outlen );
|
||||
}
|
||||
|
||||
|
||||
int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
|
||||
{
|
||||
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||
blake2s_state S[PARALLELISM_DEGREE][1];
|
||||
blake2s_state FS[1];
|
||||
size_t i;
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in && inlen > 0 ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if ( NULL == key && keylen > 0) return -1;
|
||||
|
||||
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||
|
||||
if( keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
if( blake2sp_init_leaf( S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1;
|
||||
|
||||
S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */
|
||||
|
||||
if( keylen > 0 )
|
||||
{
|
||||
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)
|
||||
#else
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
#endif
|
||||
{
|
||||
#if defined(_OPENMP)
|
||||
size_t i = omp_get_thread_num();
|
||||
#endif
|
||||
size_t inlen__ = inlen;
|
||||
const unsigned char *in__ = ( const unsigned char * )in;
|
||||
in__ += i * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
|
||||
if( inlen__ > i * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES;
|
||||
const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
|
||||
blake2s_update( S[i], in__, len );
|
||||
}
|
||||
|
||||
blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES );
|
||||
}
|
||||
|
||||
if( blake2sp_init_root( FS, outlen, keylen ) < 0 )
|
||||
return -1;
|
||||
|
||||
FS->last_node = 1;
|
||||
|
||||
for( i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );
|
||||
|
||||
return blake2s_final( FS, out, outlen );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(BLAKE2SP_SELFTEST)
|
||||
#include <string.h>
|
||||
#include "blake2-kat.h"
|
||||
int main( void )
|
||||
{
|
||||
uint8_t key[BLAKE2S_KEYBYTES];
|
||||
uint8_t buf[BLAKE2_KAT_LENGTH];
|
||||
size_t i, step;
|
||||
|
||||
for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
|
||||
key[i] = ( uint8_t )i;
|
||||
|
||||
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
|
||||
buf[i] = ( uint8_t )i;
|
||||
|
||||
/* Test simple API */
|
||||
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
|
||||
{
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );
|
||||
|
||||
if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test streaming API */
|
||||
for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {
|
||||
for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
|
||||
uint8_t hash[BLAKE2S_OUTBYTES];
|
||||
blake2sp_state S;
|
||||
uint8_t * p = buf;
|
||||
size_t mlen = i;
|
||||
int err = 0;
|
||||
|
||||
if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
while (mlen >= step) {
|
||||
if ( (err = blake2sp_update(&S, p, step)) < 0 ) {
|
||||
goto fail;
|
||||
}
|
||||
mlen -= step;
|
||||
p += step;
|
||||
}
|
||||
if ( (err = blake2sp_update(&S, p, mlen)) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
puts( "ok" );
|
||||
return 0;
|
||||
fail:
|
||||
puts("error");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
175
dependencies/libarchive-3.4.2/libarchive/archive_check_magic.c
vendored
Normal file
175
dependencies/libarchive-3.4.2/libarchive/archive_check_magic.c
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2010 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/archive_check_magic.c 201089 2009-12-28 02:20:23Z kientzle $");
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#endif
|
||||
|
||||
#include "archive_private.h"
|
||||
|
||||
static void
|
||||
errmsg(const char *m)
|
||||
{
|
||||
size_t s = strlen(m);
|
||||
ssize_t written;
|
||||
|
||||
while (s > 0) {
|
||||
written = write(2, m, strlen(m));
|
||||
if (written <= 0)
|
||||
return;
|
||||
m += written;
|
||||
s -= written;
|
||||
}
|
||||
}
|
||||
|
||||
static __LA_DEAD void
|
||||
diediedie(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
|
||||
/* Cause a breakpoint exception */
|
||||
DebugBreak();
|
||||
#endif
|
||||
abort(); /* Terminate the program abnormally. */
|
||||
}
|
||||
|
||||
static const char *
|
||||
state_name(unsigned s)
|
||||
{
|
||||
switch (s) {
|
||||
case ARCHIVE_STATE_NEW: return ("new");
|
||||
case ARCHIVE_STATE_HEADER: return ("header");
|
||||
case ARCHIVE_STATE_DATA: return ("data");
|
||||
case ARCHIVE_STATE_EOF: return ("eof");
|
||||
case ARCHIVE_STATE_CLOSED: return ("closed");
|
||||
case ARCHIVE_STATE_FATAL: return ("fatal");
|
||||
default: return ("??");
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
archive_handle_type_name(unsigned m)
|
||||
{
|
||||
switch (m) {
|
||||
case ARCHIVE_WRITE_MAGIC: return ("archive_write");
|
||||
case ARCHIVE_READ_MAGIC: return ("archive_read");
|
||||
case ARCHIVE_WRITE_DISK_MAGIC: return ("archive_write_disk");
|
||||
case ARCHIVE_READ_DISK_MAGIC: return ("archive_read_disk");
|
||||
case ARCHIVE_MATCH_MAGIC: return ("archive_match");
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
write_all_states(char *buff, unsigned int states)
|
||||
{
|
||||
unsigned int lowbit;
|
||||
|
||||
buff[0] = '\0';
|
||||
|
||||
/* A trick for computing the lowest set bit. */
|
||||
while ((lowbit = states & (1 + ~states)) != 0) {
|
||||
states &= ~lowbit; /* Clear the low bit. */
|
||||
strcat(buff, state_name(lowbit));
|
||||
if (states != 0)
|
||||
strcat(buff, "/");
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check magic value and current state.
|
||||
* Magic value mismatches are fatal and result in calls to abort().
|
||||
* State mismatches return ARCHIVE_FATAL.
|
||||
* Otherwise, returns ARCHIVE_OK.
|
||||
*
|
||||
* This is designed to catch serious programming errors that violate
|
||||
* the libarchive API.
|
||||
*/
|
||||
int
|
||||
__archive_check_magic(struct archive *a, unsigned int magic,
|
||||
unsigned int state, const char *function)
|
||||
{
|
||||
char states1[64];
|
||||
char states2[64];
|
||||
const char *handle_type;
|
||||
|
||||
/*
|
||||
* If this isn't some form of archive handle,
|
||||
* then the library user has screwed up so bad that
|
||||
* we don't even have a reliable way to report an error.
|
||||
*/
|
||||
handle_type = archive_handle_type_name(a->magic);
|
||||
|
||||
if (!handle_type) {
|
||||
errmsg("PROGRAMMER ERROR: Function ");
|
||||
errmsg(function);
|
||||
errmsg(" invoked with invalid archive handle.\n");
|
||||
diediedie();
|
||||
}
|
||||
|
||||
if (a->magic != magic) {
|
||||
archive_set_error(a, -1,
|
||||
"PROGRAMMER ERROR: Function '%s' invoked"
|
||||
" on '%s' archive object, which is not supported.",
|
||||
function,
|
||||
handle_type);
|
||||
a->state = ARCHIVE_STATE_FATAL;
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
if ((a->state & state) == 0) {
|
||||
/* If we're already FATAL, don't overwrite the error. */
|
||||
if (a->state != ARCHIVE_STATE_FATAL)
|
||||
archive_set_error(a, -1,
|
||||
"INTERNAL ERROR: Function '%s' invoked with"
|
||||
" archive structure in state '%s',"
|
||||
" should be in state '%s'",
|
||||
function,
|
||||
write_all_states(states1, a->state),
|
||||
write_all_states(states2, state));
|
||||
a->state = ARCHIVE_STATE_FATAL;
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
return ARCHIVE_OK;
|
||||
}
|
227
dependencies/libarchive-3.4.2/libarchive/archive_cmdline.c
vendored
Normal file
227
dependencies/libarchive-3.4.2/libarchive/archive_cmdline.c
vendored
Normal file
|
@ -0,0 +1,227 @@
|
|||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_cmdline_private.h"
|
||||
#include "archive_string.h"
|
||||
|
||||
static int cmdline_set_path(struct archive_cmdline *, const char *);
|
||||
static int cmdline_add_arg(struct archive_cmdline *, const char *);
|
||||
|
||||
static ssize_t
|
||||
extract_quotation(struct archive_string *as, const char *p)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
for (s = p + 1; *s;) {
|
||||
if (*s == '\\') {
|
||||
if (s[1] != '\0') {
|
||||
archive_strappend_char(as, s[1]);
|
||||
s += 2;
|
||||
} else
|
||||
s++;
|
||||
} else if (*s == '"')
|
||||
break;
|
||||
else {
|
||||
archive_strappend_char(as, s[0]);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (*s != '"')
|
||||
return (ARCHIVE_FAILED);/* Invalid sequence. */
|
||||
return ((ssize_t)(s + 1 - p));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
get_argument(struct archive_string *as, const char *p)
|
||||
{
|
||||
const char *s = p;
|
||||
|
||||
archive_string_empty(as);
|
||||
|
||||
/* Skip beginning space characters. */
|
||||
while (*s != '\0' && *s == ' ')
|
||||
s++;
|
||||
/* Copy non-space characters. */
|
||||
while (*s != '\0' && *s != ' ') {
|
||||
if (*s == '\\') {
|
||||
if (s[1] != '\0') {
|
||||
archive_strappend_char(as, s[1]);
|
||||
s += 2;
|
||||
} else {
|
||||
s++;/* Ignore this character.*/
|
||||
break;
|
||||
}
|
||||
} else if (*s == '"') {
|
||||
ssize_t q = extract_quotation(as, s);
|
||||
if (q < 0)
|
||||
return (ARCHIVE_FAILED);/* Invalid sequence. */
|
||||
s += q;
|
||||
} else {
|
||||
archive_strappend_char(as, s[0]);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return ((ssize_t)(s - p));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up command line arguments.
|
||||
* Returns ARCHIVE_OK if everything okey.
|
||||
* Returns ARCHIVE_FAILED if there is a lack of the `"' terminator or an
|
||||
* empty command line.
|
||||
* Returns ARCHIVE_FATAL if no memory.
|
||||
*/
|
||||
int
|
||||
__archive_cmdline_parse(struct archive_cmdline *data, const char *cmd)
|
||||
{
|
||||
struct archive_string as;
|
||||
const char *p;
|
||||
ssize_t al;
|
||||
int r;
|
||||
|
||||
archive_string_init(&as);
|
||||
|
||||
/* Get first argument as a command path. */
|
||||
al = get_argument(&as, cmd);
|
||||
if (al < 0) {
|
||||
r = ARCHIVE_FAILED;/* Invalid sequence. */
|
||||
goto exit_function;
|
||||
}
|
||||
if (archive_strlen(&as) == 0) {
|
||||
r = ARCHIVE_FAILED;/* An empty command path. */
|
||||
goto exit_function;
|
||||
}
|
||||
r = cmdline_set_path(data, as.s);
|
||||
if (r != ARCHIVE_OK)
|
||||
goto exit_function;
|
||||
p = strrchr(as.s, '/');
|
||||
if (p == NULL)
|
||||
p = as.s;
|
||||
else
|
||||
p++;
|
||||
r = cmdline_add_arg(data, p);
|
||||
if (r != ARCHIVE_OK)
|
||||
goto exit_function;
|
||||
cmd += al;
|
||||
|
||||
for (;;) {
|
||||
al = get_argument(&as, cmd);
|
||||
if (al < 0) {
|
||||
r = ARCHIVE_FAILED;/* Invalid sequence. */
|
||||
goto exit_function;
|
||||
}
|
||||
if (al == 0)
|
||||
break;
|
||||
cmd += al;
|
||||
if (archive_strlen(&as) == 0 && *cmd == '\0')
|
||||
break;
|
||||
r = cmdline_add_arg(data, as.s);
|
||||
if (r != ARCHIVE_OK)
|
||||
goto exit_function;
|
||||
}
|
||||
r = ARCHIVE_OK;
|
||||
exit_function:
|
||||
archive_string_free(&as);
|
||||
return (r);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the program path.
|
||||
*/
|
||||
static int
|
||||
cmdline_set_path(struct archive_cmdline *data, const char *path)
|
||||
{
|
||||
char *newptr;
|
||||
|
||||
newptr = realloc(data->path, strlen(path) + 1);
|
||||
if (newptr == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
data->path = newptr;
|
||||
strcpy(data->path, path);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a argument for the program.
|
||||
*/
|
||||
static int
|
||||
cmdline_add_arg(struct archive_cmdline *data, const char *arg)
|
||||
{
|
||||
char **newargv;
|
||||
|
||||
if (data->path == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
|
||||
newargv = realloc(data->argv, (data->argc + 2) * sizeof(char *));
|
||||
if (newargv == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
data->argv = newargv;
|
||||
data->argv[data->argc] = strdup(arg);
|
||||
if (data->argv[data->argc] == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
/* Set the terminator of argv. */
|
||||
data->argv[++data->argc] = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
struct archive_cmdline *
|
||||
__archive_cmdline_allocate(void)
|
||||
{
|
||||
return (struct archive_cmdline *)
|
||||
calloc(1, sizeof(struct archive_cmdline));
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the resources.
|
||||
*/
|
||||
int
|
||||
__archive_cmdline_free(struct archive_cmdline *data)
|
||||
{
|
||||
|
||||
if (data) {
|
||||
free(data->path);
|
||||
if (data->argv != NULL) {
|
||||
int i;
|
||||
for (i = 0; data->argv[i] != NULL; i++)
|
||||
free(data->argv[i]);
|
||||
free(data->argv);
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
47
dependencies/libarchive-3.4.2/libarchive/archive_cmdline_private.h
vendored
Normal file
47
dependencies/libarchive-3.4.2/libarchive/archive_cmdline_private.h
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_CMDLINE_PRIVATE_H
|
||||
#define ARCHIVE_CMDLINE_PRIVATE_H
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct archive_cmdline {
|
||||
char *path;
|
||||
char **argv;
|
||||
int argc;
|
||||
};
|
||||
|
||||
struct archive_cmdline *__archive_cmdline_allocate(void);
|
||||
int __archive_cmdline_parse(struct archive_cmdline *, const char *);
|
||||
int __archive_cmdline_free(struct archive_cmdline *);
|
||||
|
||||
#endif
|
83
dependencies/libarchive-3.4.2/libarchive/archive_crc32.h
vendored
Normal file
83
dependencies/libarchive-3.4.2/libarchive/archive_crc32.h
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*-
|
||||
* Copyright (c) 2009 Joerg Sonnenberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: head/lib/libarchive/archive_crc32.h 201102 2009-12-28 03:11:36Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_CRC32_H
|
||||
#define ARCHIVE_CRC32_H
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When zlib is unavailable, we should still be able to validate
|
||||
* uncompressed zip archives. That requires us to be able to compute
|
||||
* the CRC32 check value. This is a drop-in compatible replacement
|
||||
* for crc32() from zlib. It's slower than the zlib implementation,
|
||||
* but still pretty fast: This runs about 300MB/s on my 3GHz P4
|
||||
* compared to about 800MB/s for the zlib implementation.
|
||||
*/
|
||||
static unsigned long
|
||||
crc32(unsigned long crc, const void *_p, size_t len)
|
||||
{
|
||||
unsigned long crc2, b, i;
|
||||
const unsigned char *p = _p;
|
||||
static volatile int crc_tbl_inited = 0;
|
||||
static unsigned long crc_tbl[256];
|
||||
|
||||
if (!crc_tbl_inited) {
|
||||
for (b = 0; b < 256; ++b) {
|
||||
crc2 = b;
|
||||
for (i = 8; i > 0; --i) {
|
||||
if (crc2 & 1)
|
||||
crc2 = (crc2 >> 1) ^ 0xedb88320UL;
|
||||
else
|
||||
crc2 = (crc2 >> 1);
|
||||
}
|
||||
crc_tbl[b] = crc2;
|
||||
}
|
||||
crc_tbl_inited = 1;
|
||||
}
|
||||
|
||||
crc = crc ^ 0xffffffffUL;
|
||||
/* A use of this loop is about 20% - 30% faster than
|
||||
* no use version in any optimization option of gcc. */
|
||||
for (;len >= 8; len -= 8) {
|
||||
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
}
|
||||
while (len--)
|
||||
crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
|
||||
return (crc ^ 0xffffffffUL);
|
||||
}
|
||||
|
||||
#endif
|
519
dependencies/libarchive-3.4.2/libarchive/archive_cryptor.c
vendored
Normal file
519
dependencies/libarchive-3.4.2/libarchive/archive_cryptor.c
vendored
Normal file
|
@ -0,0 +1,519 @@
|
|||
/*-
|
||||
* Copyright (c) 2014 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#include "archive.h"
|
||||
#include "archive_cryptor_private.h"
|
||||
|
||||
/*
|
||||
* On systems that do not support any recognized crypto libraries,
|
||||
* this file will normally define no usable symbols.
|
||||
*
|
||||
* But some compilers and linkers choke on empty object files, so
|
||||
* define a public symbol that will always exist. This could
|
||||
* be removed someday if this file gains another always-present
|
||||
* symbol definition.
|
||||
*/
|
||||
int __libarchive_cryptor_build_hack(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
|
||||
|
||||
static int
|
||||
pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
|
||||
size_t salt_len, unsigned rounds, uint8_t *derived_key,
|
||||
size_t derived_key_len)
|
||||
{
|
||||
CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pw,
|
||||
pw_len, salt, salt_len, kCCPRFHmacAlgSHA1, rounds,
|
||||
derived_key, derived_key_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "Bcrypt.lib")
|
||||
#endif
|
||||
|
||||
static int
|
||||
pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
|
||||
size_t salt_len, unsigned rounds, uint8_t *derived_key,
|
||||
size_t derived_key_len)
|
||||
{
|
||||
NTSTATUS status;
|
||||
BCRYPT_ALG_HANDLE hAlg;
|
||||
|
||||
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM,
|
||||
MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
return -1;
|
||||
|
||||
status = BCryptDeriveKeyPBKDF2(hAlg,
|
||||
(PUCHAR)(uintptr_t)pw, (ULONG)pw_len,
|
||||
(PUCHAR)(uintptr_t)salt, (ULONG)salt_len, rounds,
|
||||
(PUCHAR)derived_key, (ULONG)derived_key_len, 0);
|
||||
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
|
||||
return (BCRYPT_SUCCESS(status)) ? 0: -1;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_PKCS5_H)
|
||||
|
||||
static int
|
||||
pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
|
||||
size_t salt_len, unsigned rounds, uint8_t *derived_key,
|
||||
size_t derived_key_len)
|
||||
{
|
||||
mbedtls_md_context_t ctx;
|
||||
const mbedtls_md_info_t *info;
|
||||
int ret;
|
||||
|
||||
mbedtls_md_init(&ctx);
|
||||
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
||||
if (info == NULL) {
|
||||
mbedtls_md_free(&ctx);
|
||||
return (-1);
|
||||
}
|
||||
ret = mbedtls_md_setup(&ctx, info, 1);
|
||||
if (ret != 0) {
|
||||
mbedtls_md_free(&ctx);
|
||||
return (-1);
|
||||
}
|
||||
ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char *)pw,
|
||||
pw_len, salt, salt_len, rounds, derived_key_len, derived_key);
|
||||
|
||||
mbedtls_md_free(&ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H)
|
||||
|
||||
static int
|
||||
pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
|
||||
size_t salt_len, unsigned rounds, uint8_t *derived_key,
|
||||
size_t derived_key_len) {
|
||||
pbkdf2_hmac_sha1((unsigned)pw_len, (const uint8_t *)pw, rounds,
|
||||
salt_len, salt, derived_key_len, derived_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBCRYPTO) && defined(HAVE_PKCS5_PBKDF2_HMAC_SHA1)
|
||||
|
||||
static int
|
||||
pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
|
||||
size_t salt_len, unsigned rounds, uint8_t *derived_key,
|
||||
size_t derived_key_len) {
|
||||
|
||||
PKCS5_PBKDF2_HMAC_SHA1(pw, pw_len, salt, salt_len, rounds,
|
||||
derived_key_len, derived_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Stub */
|
||||
static int
|
||||
pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
|
||||
size_t salt_len, unsigned rounds, uint8_t *derived_key,
|
||||
size_t derived_key_len) {
|
||||
(void)pw; /* UNUSED */
|
||||
(void)pw_len; /* UNUSED */
|
||||
(void)salt; /* UNUSED */
|
||||
(void)salt_len; /* UNUSED */
|
||||
(void)rounds; /* UNUSED */
|
||||
(void)derived_key; /* UNUSED */
|
||||
(void)derived_key_len; /* UNUSED */
|
||||
return -1; /* UNSUPPORTED */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
|
||||
# if MAC_OS_X_VERSION_MAX_ALLOWED < 1090
|
||||
# define kCCAlgorithmAES kCCAlgorithmAES128
|
||||
# endif
|
||||
|
||||
static int
|
||||
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
CCCryptorStatus r;
|
||||
|
||||
ctx->key_len = key_len;
|
||||
memcpy(ctx->key, key, key_len);
|
||||
memset(ctx->nonce, 0, sizeof(ctx->nonce));
|
||||
ctx->encr_pos = AES_BLOCK_SIZE;
|
||||
r = CCCryptorCreateWithMode(kCCEncrypt, kCCModeECB, kCCAlgorithmAES,
|
||||
ccNoPadding, NULL, key, key_len, NULL, 0, 0, 0, &ctx->ctx);
|
||||
return (r == kCCSuccess)? 0: -1;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
CCCryptorRef ref = ctx->ctx;
|
||||
CCCryptorStatus r;
|
||||
|
||||
r = CCCryptorReset(ref, NULL);
|
||||
if (r != kCCSuccess && r != kCCUnimplemented)
|
||||
return -1;
|
||||
r = CCCryptorUpdate(ref, ctx->nonce, AES_BLOCK_SIZE, ctx->encr_buf,
|
||||
AES_BLOCK_SIZE, NULL);
|
||||
return (r == kCCSuccess)? 0: -1;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_release(archive_crypto_ctx *ctx)
|
||||
{
|
||||
memset(ctx->key, 0, ctx->key_len);
|
||||
memset(ctx->nonce, 0, sizeof(ctx->nonce));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
|
||||
|
||||
static int
|
||||
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
BCRYPT_ALG_HANDLE hAlg;
|
||||
BCRYPT_KEY_HANDLE hKey;
|
||||
DWORD keyObj_len, aes_key_len;
|
||||
PBYTE keyObj;
|
||||
ULONG result;
|
||||
NTSTATUS status;
|
||||
BCRYPT_KEY_LENGTHS_STRUCT key_lengths;
|
||||
|
||||
ctx->hAlg = NULL;
|
||||
ctx->hKey = NULL;
|
||||
ctx->keyObj = NULL;
|
||||
switch (key_len) {
|
||||
case 16: aes_key_len = 128; break;
|
||||
case 24: aes_key_len = 192; break;
|
||||
case 32: aes_key_len = 256; break;
|
||||
default: return -1;
|
||||
}
|
||||
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM,
|
||||
MS_PRIMITIVE_PROVIDER, 0);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
return -1;
|
||||
status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths,
|
||||
sizeof(key_lengths), &result, 0);
|
||||
if (!BCRYPT_SUCCESS(status)) {
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
return -1;
|
||||
}
|
||||
if (key_lengths.dwMinLength > aes_key_len
|
||||
|| key_lengths.dwMaxLength < aes_key_len) {
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
return -1;
|
||||
}
|
||||
status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len,
|
||||
sizeof(keyObj_len), &result, 0);
|
||||
if (!BCRYPT_SUCCESS(status)) {
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
return -1;
|
||||
}
|
||||
keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len);
|
||||
if (keyObj == NULL) {
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
return -1;
|
||||
}
|
||||
status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE,
|
||||
(PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
|
||||
if (!BCRYPT_SUCCESS(status)) {
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
HeapFree(GetProcessHeap(), 0, keyObj);
|
||||
return -1;
|
||||
}
|
||||
status = BCryptGenerateSymmetricKey(hAlg, &hKey,
|
||||
keyObj, keyObj_len,
|
||||
(PUCHAR)(uintptr_t)key, (ULONG)key_len, 0);
|
||||
if (!BCRYPT_SUCCESS(status)) {
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
HeapFree(GetProcessHeap(), 0, keyObj);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->hAlg = hAlg;
|
||||
ctx->hKey = hKey;
|
||||
ctx->keyObj = keyObj;
|
||||
ctx->keyObj_len = keyObj_len;
|
||||
ctx->encr_pos = AES_BLOCK_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ULONG result;
|
||||
|
||||
status = BCryptEncrypt(ctx->hKey, (PUCHAR)ctx->nonce, AES_BLOCK_SIZE,
|
||||
NULL, NULL, 0, (PUCHAR)ctx->encr_buf, AES_BLOCK_SIZE,
|
||||
&result, 0);
|
||||
return BCRYPT_SUCCESS(status) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_release(archive_crypto_ctx *ctx)
|
||||
{
|
||||
|
||||
if (ctx->hAlg != NULL) {
|
||||
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
|
||||
ctx->hAlg = NULL;
|
||||
BCryptDestroyKey(ctx->hKey);
|
||||
ctx->hKey = NULL;
|
||||
HeapFree(GetProcessHeap(), 0, ctx->keyObj);
|
||||
ctx->keyObj = NULL;
|
||||
}
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H)
|
||||
|
||||
static int
|
||||
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
mbedtls_aes_init(&ctx->ctx);
|
||||
ctx->key_len = key_len;
|
||||
memcpy(ctx->key, key, key_len);
|
||||
memset(ctx->nonce, 0, sizeof(ctx->nonce));
|
||||
ctx->encr_pos = AES_BLOCK_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
if (mbedtls_aes_setkey_enc(&ctx->ctx, ctx->key,
|
||||
ctx->key_len * 8) != 0)
|
||||
return (-1);
|
||||
if (mbedtls_aes_crypt_ecb(&ctx->ctx, MBEDTLS_AES_ENCRYPT, ctx->nonce,
|
||||
ctx->encr_buf) != 0)
|
||||
return (-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_release(archive_crypto_ctx *ctx)
|
||||
{
|
||||
mbedtls_aes_free(&ctx->ctx);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
|
||||
|
||||
static int
|
||||
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
ctx->key_len = key_len;
|
||||
memcpy(ctx->key, key, key_len);
|
||||
memset(ctx->nonce, 0, sizeof(ctx->nonce));
|
||||
ctx->encr_pos = AES_BLOCK_SIZE;
|
||||
memset(&ctx->ctx, 0, sizeof(ctx->ctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key);
|
||||
aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_release(archive_crypto_ctx *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBCRYPTO)
|
||||
|
||||
static int
|
||||
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
if ((ctx->ctx = EVP_CIPHER_CTX_new()) == NULL)
|
||||
return -1;
|
||||
|
||||
switch (key_len) {
|
||||
case 16: ctx->type = EVP_aes_128_ecb(); break;
|
||||
case 24: ctx->type = EVP_aes_192_ecb(); break;
|
||||
case 32: ctx->type = EVP_aes_256_ecb(); break;
|
||||
default: ctx->type = NULL; return -1;
|
||||
}
|
||||
|
||||
ctx->key_len = key_len;
|
||||
memcpy(ctx->key, key, key_len);
|
||||
memset(ctx->nonce, 0, sizeof(ctx->nonce));
|
||||
ctx->encr_pos = AES_BLOCK_SIZE;
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
if (!EVP_CIPHER_CTX_reset(ctx->ctx)) {
|
||||
EVP_CIPHER_CTX_free(ctx->ctx);
|
||||
ctx->ctx = NULL;
|
||||
}
|
||||
#else
|
||||
EVP_CIPHER_CTX_init(ctx->ctx);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
int outl = 0;
|
||||
int r;
|
||||
|
||||
r = EVP_EncryptInit_ex(ctx->ctx, ctx->type, NULL, ctx->key, NULL);
|
||||
if (r == 0)
|
||||
return -1;
|
||||
r = EVP_EncryptUpdate(ctx->ctx, ctx->encr_buf, &outl, ctx->nonce,
|
||||
AES_BLOCK_SIZE);
|
||||
if (r == 0 || outl != AES_BLOCK_SIZE)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_release(archive_crypto_ctx *ctx)
|
||||
{
|
||||
EVP_CIPHER_CTX_free(ctx->ctx);
|
||||
memset(ctx->key, 0, ctx->key_len);
|
||||
memset(ctx->nonce, 0, sizeof(ctx->nonce));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define ARCHIVE_CRYPTOR_STUB
|
||||
/* Stub */
|
||||
static int
|
||||
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
(void)ctx; /* UNUSED */
|
||||
(void)key; /* UNUSED */
|
||||
(void)key_len; /* UNUSED */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
(void)ctx; /* UNUSED */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_release(archive_crypto_ctx *ctx)
|
||||
{
|
||||
(void)ctx; /* UNUSED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ARCHIVE_CRYPTOR_STUB
|
||||
static int
|
||||
aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
|
||||
size_t in_len, uint8_t * const out, size_t *out_len)
|
||||
{
|
||||
(void)ctx; /* UNUSED */
|
||||
(void)in; /* UNUSED */
|
||||
(void)in_len; /* UNUSED */
|
||||
(void)out; /* UNUSED */
|
||||
(void)out_len; /* UNUSED */
|
||||
aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
static void
|
||||
aes_ctr_increase_counter(archive_crypto_ctx *ctx)
|
||||
{
|
||||
uint8_t *const nonce = ctx->nonce;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (++nonce[j])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in,
|
||||
size_t in_len, uint8_t * const out, size_t *out_len)
|
||||
{
|
||||
uint8_t *const ebuf = ctx->encr_buf;
|
||||
unsigned pos = ctx->encr_pos;
|
||||
unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len);
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < max; ) {
|
||||
if (pos == AES_BLOCK_SIZE) {
|
||||
aes_ctr_increase_counter(ctx);
|
||||
if (aes_ctr_encrypt_counter(ctx) != 0)
|
||||
return -1;
|
||||
while (max -i >= AES_BLOCK_SIZE) {
|
||||
for (pos = 0; pos < AES_BLOCK_SIZE; pos++)
|
||||
out[i+pos] = in[i+pos] ^ ebuf[pos];
|
||||
i += AES_BLOCK_SIZE;
|
||||
aes_ctr_increase_counter(ctx);
|
||||
if (aes_ctr_encrypt_counter(ctx) != 0)
|
||||
return -1;
|
||||
}
|
||||
pos = 0;
|
||||
if (i >= max)
|
||||
break;
|
||||
}
|
||||
out[i] = in[i] ^ ebuf[pos++];
|
||||
i++;
|
||||
}
|
||||
ctx->encr_pos = pos;
|
||||
*out_len = i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* ARCHIVE_CRYPTOR_STUB */
|
||||
|
||||
|
||||
const struct archive_cryptor __archive_cryptor =
|
||||
{
|
||||
&pbkdf2_sha1,
|
||||
&aes_ctr_init,
|
||||
&aes_ctr_update,
|
||||
&aes_ctr_release,
|
||||
&aes_ctr_init,
|
||||
&aes_ctr_update,
|
||||
&aes_ctr_release,
|
||||
};
|
179
dependencies/libarchive-3.4.2/libarchive/archive_cryptor_private.h
vendored
Normal file
179
dependencies/libarchive-3.4.2/libarchive/archive_cryptor_private.h
vendored
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*-
|
||||
* Copyright (c) 2014 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
/*
|
||||
* On systems that do not support any recognized crypto libraries,
|
||||
* the archive_cryptor.c file will normally define no usable symbols.
|
||||
*
|
||||
* But some compilers and linkers choke on empty object files, so
|
||||
* define a public symbol that will always exist. This could
|
||||
* be removed someday if this file gains another always-present
|
||||
* symbol definition.
|
||||
*/
|
||||
int __libarchive_cryptor_build_hack(void);
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <AvailabilityMacros.h>
|
||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||
# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
|
||||
#include <CommonCrypto/CommonCryptor.h>
|
||||
#include <CommonCrypto/CommonKeyDerivation.h>
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES_MAX_KEY_SIZE kCCKeySizeAES256
|
||||
|
||||
typedef struct {
|
||||
CCCryptorRef ctx;
|
||||
uint8_t key[AES_MAX_KEY_SIZE];
|
||||
unsigned key_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
uint8_t encr_buf[AES_BLOCK_SIZE];
|
||||
unsigned encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
|
||||
#include <bcrypt.h>
|
||||
|
||||
/* Common in other bcrypt implementations, but missing from VS2008. */
|
||||
#ifndef BCRYPT_SUCCESS
|
||||
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
|
||||
#endif
|
||||
|
||||
#define AES_MAX_KEY_SIZE 32
|
||||
#define AES_BLOCK_SIZE 16
|
||||
typedef struct {
|
||||
BCRYPT_ALG_HANDLE hAlg;
|
||||
BCRYPT_KEY_HANDLE hKey;
|
||||
PBYTE keyObj;
|
||||
DWORD keyObj_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
uint8_t encr_buf[AES_BLOCK_SIZE];
|
||||
unsigned encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H)
|
||||
#include <mbedtls/aes.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/pkcs5.h>
|
||||
|
||||
#define AES_MAX_KEY_SIZE 32
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
typedef struct {
|
||||
mbedtls_aes_context ctx;
|
||||
uint8_t key[AES_MAX_KEY_SIZE];
|
||||
unsigned key_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
uint8_t encr_buf[AES_BLOCK_SIZE];
|
||||
unsigned encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
|
||||
#if defined(HAVE_NETTLE_PBKDF2_H)
|
||||
#include <nettle/pbkdf2.h>
|
||||
#endif
|
||||
#include <nettle/aes.h>
|
||||
|
||||
typedef struct {
|
||||
struct aes_ctx ctx;
|
||||
uint8_t key[AES_MAX_KEY_SIZE];
|
||||
unsigned key_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
uint8_t encr_buf[AES_BLOCK_SIZE];
|
||||
unsigned encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBCRYPTO)
|
||||
#include "archive_openssl_evp_private.h"
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES_MAX_KEY_SIZE 32
|
||||
|
||||
typedef struct {
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
const EVP_CIPHER *type;
|
||||
uint8_t key[AES_MAX_KEY_SIZE];
|
||||
unsigned key_len;
|
||||
uint8_t nonce[AES_BLOCK_SIZE];
|
||||
uint8_t encr_buf[AES_BLOCK_SIZE];
|
||||
unsigned encr_pos;
|
||||
} archive_crypto_ctx;
|
||||
|
||||
#else
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES_MAX_KEY_SIZE 32
|
||||
typedef int archive_crypto_ctx;
|
||||
|
||||
#endif
|
||||
|
||||
/* defines */
|
||||
#define archive_pbkdf2_sha1(pw, pw_len, salt, salt_len, rounds, dk, dk_len)\
|
||||
__archive_cryptor.pbkdf2sha1(pw, pw_len, salt, salt_len, rounds, dk, dk_len)
|
||||
|
||||
#define archive_decrypto_aes_ctr_init(ctx, key, key_len) \
|
||||
__archive_cryptor.decrypto_aes_ctr_init(ctx, key, key_len)
|
||||
#define archive_decrypto_aes_ctr_update(ctx, in, in_len, out, out_len) \
|
||||
__archive_cryptor.decrypto_aes_ctr_update(ctx, in, in_len, out, out_len)
|
||||
#define archive_decrypto_aes_ctr_release(ctx) \
|
||||
__archive_cryptor.decrypto_aes_ctr_release(ctx)
|
||||
|
||||
#define archive_encrypto_aes_ctr_init(ctx, key, key_len) \
|
||||
__archive_cryptor.encrypto_aes_ctr_init(ctx, key, key_len)
|
||||
#define archive_encrypto_aes_ctr_update(ctx, in, in_len, out, out_len) \
|
||||
__archive_cryptor.encrypto_aes_ctr_update(ctx, in, in_len, out, out_len)
|
||||
#define archive_encrypto_aes_ctr_release(ctx) \
|
||||
__archive_cryptor.encrypto_aes_ctr_release(ctx)
|
||||
|
||||
/* Minimal interface to cryptographic functionality for internal use in
|
||||
* libarchive */
|
||||
struct archive_cryptor
|
||||
{
|
||||
/* PKCS5 PBKDF2 HMAC-SHA1 */
|
||||
int (*pbkdf2sha1)(const char *pw, size_t pw_len, const uint8_t *salt,
|
||||
size_t salt_len, unsigned rounds, uint8_t *derived_key,
|
||||
size_t derived_key_len);
|
||||
/* AES CTR mode(little endian version) */
|
||||
int (*decrypto_aes_ctr_init)(archive_crypto_ctx *, const uint8_t *, size_t);
|
||||
int (*decrypto_aes_ctr_update)(archive_crypto_ctx *, const uint8_t *,
|
||||
size_t, uint8_t *, size_t *);
|
||||
int (*decrypto_aes_ctr_release)(archive_crypto_ctx *);
|
||||
int (*encrypto_aes_ctr_init)(archive_crypto_ctx *, const uint8_t *, size_t);
|
||||
int (*encrypto_aes_ctr_update)(archive_crypto_ctx *, const uint8_t *,
|
||||
size_t, uint8_t *, size_t *);
|
||||
int (*encrypto_aes_ctr_release)(archive_crypto_ctx *);
|
||||
};
|
||||
|
||||
extern const struct archive_cryptor __archive_cryptor;
|
||||
|
||||
#endif
|
1691
dependencies/libarchive-3.4.2/libarchive/archive_digest.c
vendored
Normal file
1691
dependencies/libarchive-3.4.2/libarchive/archive_digest.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
412
dependencies/libarchive-3.4.2/libarchive/archive_digest_private.h
vendored
Normal file
412
dependencies/libarchive-3.4.2/libarchive/archive_digest_private.h
vendored
Normal file
|
@ -0,0 +1,412 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2011 Andres Mejia
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_DIGEST_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_DIGEST_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
/*
|
||||
* Crypto support in various Operating Systems:
|
||||
*
|
||||
* NetBSD:
|
||||
* - MD5 and SHA1 in libc: without _ after algorithm name
|
||||
* - SHA2 in libc: with _ after algorithm name
|
||||
*
|
||||
* OpenBSD:
|
||||
* - MD5, SHA1 and SHA2 in libc: without _ after algorithm name
|
||||
* - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name
|
||||
*
|
||||
* DragonFly and FreeBSD:
|
||||
* - MD5 libmd: without _ after algorithm name
|
||||
* - SHA1, SHA256 and SHA512 in libmd: with _ after algorithm name
|
||||
*
|
||||
* Mac OS X (10.4 and later):
|
||||
* - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name
|
||||
*
|
||||
* OpenSSL:
|
||||
* - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name
|
||||
*
|
||||
* Windows:
|
||||
* - MD5, SHA1 and SHA2 in archive_crypto.c using Windows crypto API
|
||||
*/
|
||||
|
||||
/* libc crypto headers */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
|
||||
#include <md5.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
|
||||
#include <rmd160.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
|
||||
#include <sha1.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
|
||||
#include <sha2.h>
|
||||
#endif
|
||||
|
||||
/* libmd crypto headers */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_LIBMD) ||\
|
||||
defined(ARCHIVE_CRYPTO_RMD160_LIBMD) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_LIBMD) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
|
||||
#define ARCHIVE_CRYPTO_LIBMD 1
|
||||
#endif
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_LIBMD)
|
||||
#include <md5.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
|
||||
#include <ripemd.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
|
||||
#include <sha.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
|
||||
#include <sha256.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
|
||||
#include <sha512.h>
|
||||
#endif
|
||||
|
||||
/* libSystem crypto headers */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#endif
|
||||
|
||||
/* mbed TLS crypto headers */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
|
||||
#include <mbedtls/md5.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
|
||||
#include <mbedtls/ripemd160.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
|
||||
#include <mbedtls/sha1.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
|
||||
#include <mbedtls/sha256.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
|
||||
#include <mbedtls/sha512.h>
|
||||
#endif
|
||||
|
||||
/* Nettle crypto headers */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_NETTLE)
|
||||
#include <nettle/md5.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
|
||||
#include <nettle/ripemd160.h>
|
||||
#endif
|
||||
#if defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
|
||||
#include <nettle/sha.h>
|
||||
#endif
|
||||
|
||||
/* OpenSSL crypto headers */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
|
||||
#define ARCHIVE_CRYPTO_OPENSSL 1
|
||||
#include "archive_openssl_evp_private.h"
|
||||
#endif
|
||||
|
||||
/* Windows crypto headers */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_WIN)
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
typedef struct {
|
||||
int valid;
|
||||
HCRYPTPROV cryptProv;
|
||||
HCRYPTHASH hash;
|
||||
} Digest_CTX;
|
||||
#endif
|
||||
|
||||
/* typedefs */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
|
||||
typedef MD5_CTX archive_md5_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
|
||||
typedef MD5_CTX archive_md5_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
|
||||
typedef CC_MD5_CTX archive_md5_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
|
||||
typedef mbedtls_md5_context archive_md5_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
|
||||
typedef struct md5_ctx archive_md5_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
|
||||
typedef EVP_MD_CTX *archive_md5_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
|
||||
typedef Digest_CTX archive_md5_ctx;
|
||||
#else
|
||||
typedef unsigned char archive_md5_ctx;
|
||||
#endif
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
|
||||
typedef RMD160_CTX archive_rmd160_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
|
||||
typedef RIPEMD160_CTX archive_rmd160_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
|
||||
typedef mbedtls_ripemd160_context archive_rmd160_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
|
||||
typedef struct ripemd160_ctx archive_rmd160_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
|
||||
typedef EVP_MD_CTX *archive_rmd160_ctx;
|
||||
#else
|
||||
typedef unsigned char archive_rmd160_ctx;
|
||||
#endif
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
|
||||
typedef SHA1_CTX archive_sha1_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
|
||||
typedef SHA1_CTX archive_sha1_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
|
||||
typedef CC_SHA1_CTX archive_sha1_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
|
||||
typedef mbedtls_sha1_context archive_sha1_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
|
||||
typedef struct sha1_ctx archive_sha1_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
|
||||
typedef EVP_MD_CTX *archive_sha1_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
|
||||
typedef Digest_CTX archive_sha1_ctx;
|
||||
#else
|
||||
typedef unsigned char archive_sha1_ctx;
|
||||
#endif
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
|
||||
typedef SHA256_CTX archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
|
||||
typedef SHA256_CTX archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
|
||||
typedef SHA2_CTX archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
|
||||
typedef SHA256_CTX archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
|
||||
typedef CC_SHA256_CTX archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
|
||||
typedef mbedtls_sha256_context archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
|
||||
typedef struct sha256_ctx archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
|
||||
typedef EVP_MD_CTX *archive_sha256_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
|
||||
typedef Digest_CTX archive_sha256_ctx;
|
||||
#else
|
||||
typedef unsigned char archive_sha256_ctx;
|
||||
#endif
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
|
||||
typedef SHA384_CTX archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
|
||||
typedef SHA384_CTX archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
|
||||
typedef SHA2_CTX archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
|
||||
typedef CC_SHA512_CTX archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
|
||||
typedef mbedtls_sha512_context archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
|
||||
typedef struct sha384_ctx archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
|
||||
typedef EVP_MD_CTX *archive_sha384_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
|
||||
typedef Digest_CTX archive_sha384_ctx;
|
||||
#else
|
||||
typedef unsigned char archive_sha384_ctx;
|
||||
#endif
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
|
||||
typedef SHA512_CTX archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
|
||||
typedef SHA512_CTX archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
|
||||
typedef SHA2_CTX archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
|
||||
typedef SHA512_CTX archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
|
||||
typedef CC_SHA512_CTX archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
|
||||
typedef mbedtls_sha512_context archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
|
||||
typedef struct sha512_ctx archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
|
||||
typedef EVP_MD_CTX *archive_sha512_ctx;
|
||||
#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
|
||||
typedef Digest_CTX archive_sha512_ctx;
|
||||
#else
|
||||
typedef unsigned char archive_sha512_ctx;
|
||||
#endif
|
||||
|
||||
/* defines */
|
||||
#if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \
|
||||
defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_MD5_WIN)
|
||||
#define ARCHIVE_HAS_MD5
|
||||
#endif
|
||||
#define archive_md5_init(ctx)\
|
||||
__archive_digest.md5init(ctx)
|
||||
#define archive_md5_final(ctx, md)\
|
||||
__archive_digest.md5final(ctx, md)
|
||||
#define archive_md5_update(ctx, buf, n)\
|
||||
__archive_digest.md5update(ctx, buf, n)
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
|
||||
#define ARCHIVE_HAS_RMD160
|
||||
#endif
|
||||
#define archive_rmd160_init(ctx)\
|
||||
__archive_digest.rmd160init(ctx)
|
||||
#define archive_rmd160_final(ctx, md)\
|
||||
__archive_digest.rmd160final(ctx, md)
|
||||
#define archive_rmd160_update(ctx, buf, n)\
|
||||
__archive_digest.rmd160update(ctx, buf, n)
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \
|
||||
defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA1_WIN)
|
||||
#define ARCHIVE_HAS_SHA1
|
||||
#endif
|
||||
#define archive_sha1_init(ctx)\
|
||||
__archive_digest.sha1init(ctx)
|
||||
#define archive_sha1_final(ctx, md)\
|
||||
__archive_digest.sha1final(ctx, md)
|
||||
#define archive_sha1_update(ctx, buf, n)\
|
||||
__archive_digest.sha1update(ctx, buf, n)
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA256_WIN)
|
||||
#define ARCHIVE_HAS_SHA256
|
||||
#endif
|
||||
#define archive_sha256_init(ctx)\
|
||||
__archive_digest.sha256init(ctx)
|
||||
#define archive_sha256_final(ctx, md)\
|
||||
__archive_digest.sha256final(ctx, md)
|
||||
#define archive_sha256_update(ctx, buf, n)\
|
||||
__archive_digest.sha256update(ctx, buf, n)
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA384_WIN)
|
||||
#define ARCHIVE_HAS_SHA384
|
||||
#endif
|
||||
#define archive_sha384_init(ctx)\
|
||||
__archive_digest.sha384init(ctx)
|
||||
#define archive_sha384_final(ctx, md)\
|
||||
__archive_digest.sha384final(ctx, md)
|
||||
#define archive_sha384_update(ctx, buf, n)\
|
||||
__archive_digest.sha384update(ctx, buf, n)
|
||||
|
||||
#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\
|
||||
defined(ARCHIVE_CRYPTO_SHA512_WIN)
|
||||
#define ARCHIVE_HAS_SHA512
|
||||
#endif
|
||||
#define archive_sha512_init(ctx)\
|
||||
__archive_digest.sha512init(ctx)
|
||||
#define archive_sha512_final(ctx, md)\
|
||||
__archive_digest.sha512final(ctx, md)
|
||||
#define archive_sha512_update(ctx, buf, n)\
|
||||
__archive_digest.sha512update(ctx, buf, n)
|
||||
|
||||
/* Minimal interface to digest functionality for internal use in libarchive */
|
||||
struct archive_digest
|
||||
{
|
||||
/* Message Digest */
|
||||
int (*md5init)(archive_md5_ctx *ctx);
|
||||
int (*md5update)(archive_md5_ctx *, const void *, size_t);
|
||||
int (*md5final)(archive_md5_ctx *, void *);
|
||||
int (*rmd160init)(archive_rmd160_ctx *);
|
||||
int (*rmd160update)(archive_rmd160_ctx *, const void *, size_t);
|
||||
int (*rmd160final)(archive_rmd160_ctx *, void *);
|
||||
int (*sha1init)(archive_sha1_ctx *);
|
||||
int (*sha1update)(archive_sha1_ctx *, const void *, size_t);
|
||||
int (*sha1final)(archive_sha1_ctx *, void *);
|
||||
int (*sha256init)(archive_sha256_ctx *);
|
||||
int (*sha256update)(archive_sha256_ctx *, const void *, size_t);
|
||||
int (*sha256final)(archive_sha256_ctx *, void *);
|
||||
int (*sha384init)(archive_sha384_ctx *);
|
||||
int (*sha384update)(archive_sha384_ctx *, const void *, size_t);
|
||||
int (*sha384final)(archive_sha384_ctx *, void *);
|
||||
int (*sha512init)(archive_sha512_ctx *);
|
||||
int (*sha512update)(archive_sha512_ctx *, const void *, size_t);
|
||||
int (*sha512final)(archive_sha512_ctx *, void *);
|
||||
};
|
||||
|
||||
extern const struct archive_digest __archive_digest;
|
||||
|
||||
#endif
|
559
dependencies/libarchive-3.4.2/libarchive/archive_disk_acl_darwin.c
vendored
Normal file
559
dependencies/libarchive-3.4.2/libarchive/archive_disk_acl_darwin.c
vendored
Normal file
|
@ -0,0 +1,559 @@
|
|||
/*-
|
||||
* Copyright (c) 2017 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"
|
||||
|
||||
#if ARCHIVE_ACL_DARWIN
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_MEMBERSHIP_H
|
||||
#include <membership.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
|
||||
typedef struct {
|
||||
const int a_perm; /* Libarchive permission or flag */
|
||||
const int p_perm; /* Platform permission or flag */
|
||||
} acl_perm_map_t;
|
||||
|
||||
static const acl_perm_map_t acl_nfs4_perm_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
|
||||
#if HAVE_DECL_ACL_SYNCHRONIZE
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#endif
|
||||
};
|
||||
|
||||
static const int acl_nfs4_perm_map_size =
|
||||
(int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
|
||||
|
||||
static const acl_perm_map_t acl_nfs4_flag_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
|
||||
};
|
||||
|
||||
static const int acl_nfs4_flag_map_size =
|
||||
(int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
|
||||
|
||||
static int translate_guid(struct archive *a, acl_entry_t acl_entry,
|
||||
int *ae_id, int *ae_tag, const char **ae_name)
|
||||
{
|
||||
void *q;
|
||||
uid_t ugid;
|
||||
int r, idtype;
|
||||
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q == NULL)
|
||||
return (1);
|
||||
r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
|
||||
if (r != 0) {
|
||||
acl_free(q);
|
||||
return (1);
|
||||
}
|
||||
if (idtype == ID_TYPE_UID) {
|
||||
*ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
*ae_id = ugid;
|
||||
*ae_name = archive_read_disk_uname(a, *ae_id);
|
||||
} else if (idtype == ID_TYPE_GID) {
|
||||
*ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
*ae_id = ugid;
|
||||
*ae_name = archive_read_disk_gname(a, *ae_id);
|
||||
} else
|
||||
r = 1;
|
||||
|
||||
acl_free(q);
|
||||
return (r);
|
||||
}
|
||||
|
||||
static void
|
||||
add_trivial_nfs4_acl(struct archive_entry *entry)
|
||||
{
|
||||
mode_t mode;
|
||||
int i;
|
||||
const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA;
|
||||
const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA;
|
||||
const int eperm = ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
const int pubset = ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
|
||||
const int ownset = pubset | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER;
|
||||
|
||||
struct {
|
||||
const int type;
|
||||
const int tag;
|
||||
int permset;
|
||||
} tacl_entry[] = {
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, ownset},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_GROUP_OBJ, pubset},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EVERYONE, pubset}
|
||||
};
|
||||
|
||||
mode = archive_entry_mode(entry);
|
||||
|
||||
/* Permissions for everyone@ */
|
||||
if (mode & 0004)
|
||||
tacl_entry[5].permset |= rperm;
|
||||
if (mode & 0002)
|
||||
tacl_entry[5].permset |= wperm;
|
||||
if (mode & 0001)
|
||||
tacl_entry[5].permset |= eperm;
|
||||
|
||||
/* Permissions for group@ */
|
||||
if (mode & 0040)
|
||||
tacl_entry[4].permset |= rperm;
|
||||
else if (mode & 0004)
|
||||
tacl_entry[2].permset |= rperm;
|
||||
if (mode & 0020)
|
||||
tacl_entry[4].permset |= wperm;
|
||||
else if (mode & 0002)
|
||||
tacl_entry[2].permset |= wperm;
|
||||
if (mode & 0010)
|
||||
tacl_entry[4].permset |= eperm;
|
||||
else if (mode & 0001)
|
||||
tacl_entry[2].permset |= eperm;
|
||||
|
||||
/* Permissions for owner@ */
|
||||
if (mode & 0400) {
|
||||
tacl_entry[3].permset |= rperm;
|
||||
if (!(mode & 0040) && (mode & 0004))
|
||||
tacl_entry[0].permset |= rperm;
|
||||
} else if ((mode & 0040) || (mode & 0004))
|
||||
tacl_entry[1].permset |= rperm;
|
||||
if (mode & 0200) {
|
||||
tacl_entry[3].permset |= wperm;
|
||||
if (!(mode & 0020) && (mode & 0002))
|
||||
tacl_entry[0].permset |= wperm;
|
||||
} else if ((mode & 0020) || (mode & 0002))
|
||||
tacl_entry[1].permset |= wperm;
|
||||
if (mode & 0100) {
|
||||
tacl_entry[3].permset |= eperm;
|
||||
if (!(mode & 0010) && (mode & 0001))
|
||||
tacl_entry[0].permset |= eperm;
|
||||
} else if ((mode & 0010) || (mode & 0001))
|
||||
tacl_entry[1].permset |= eperm;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (tacl_entry[i].permset != 0) {
|
||||
archive_entry_acl_add_entry(entry,
|
||||
tacl_entry[i].type, tacl_entry[i].permset,
|
||||
tacl_entry[i].tag, -1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl)
|
||||
{
|
||||
acl_tag_t acl_tag;
|
||||
acl_flagset_t acl_flagset;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
int i, entry_acl_type;
|
||||
int r, s, ae_id, ae_tag, ae_perm;
|
||||
const char *ae_name;
|
||||
|
||||
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get first ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
while (s == 0) {
|
||||
ae_id = -1;
|
||||
ae_name = NULL;
|
||||
ae_perm = 0;
|
||||
|
||||
if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get ACL tag type");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (acl_tag) {
|
||||
case ACL_EXTENDED_ALLOW:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
r = translate_guid(&a->archive, acl_entry,
|
||||
&ae_id, &ae_tag, &ae_name);
|
||||
break;
|
||||
case ACL_EXTENDED_DENY:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
r = translate_guid(&a->archive, acl_entry,
|
||||
&ae_id, &ae_tag, &ae_name);
|
||||
break;
|
||||
default:
|
||||
/* Skip types that libarchive can't support. */
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip if translate_guid() above failed */
|
||||
if (r != 0) {
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Libarchive stores "flag" (NFSv4 inheritance bits)
|
||||
* in the ae_perm bitmap.
|
||||
*
|
||||
* acl_get_flagset_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get flagset from a NFSv4 ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
r = acl_get_flag_np(acl_flagset,
|
||||
acl_nfs4_flag_map[i].p_perm);
|
||||
if (r == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to check flag in a NFSv4 "
|
||||
"ACL flagset");
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= acl_nfs4_flag_map[i].a_perm;
|
||||
}
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get ACL permission set");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
|
||||
/*
|
||||
* acl_get_perm() is spelled differently on different
|
||||
* platforms; see above.
|
||||
*/
|
||||
r = acl_get_perm_np(acl_permset,
|
||||
acl_nfs4_perm_map[i].p_perm);
|
||||
if (r == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to check permission in an ACL "
|
||||
"permission set");
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= acl_nfs4_perm_map[i].a_perm;
|
||||
}
|
||||
|
||||
#if !HAVE_DECL_ACL_SYNCHRONIZE
|
||||
/* On Mac OS X without ACL_SYNCHRONIZE assume it is set */
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
|
||||
#endif
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag,
|
||||
ae_id, ae_name);
|
||||
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
set_acl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl,
|
||||
int ae_requested_type, const char *tname)
|
||||
{
|
||||
acl_t acl;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
acl_flagset_t acl_flagset;
|
||||
int ret;
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
uuid_t ae_uuid;
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
|
||||
ret = ARCHIVE_OK;
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
if (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
errno = ENOENT;
|
||||
archive_set_error(a, errno, "Unsupported ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
acl = acl_init(entries);
|
||||
if (acl == (acl_t)NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to initialize ACL working storage");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
/*
|
||||
* Mac OS doesn't support NFSv4 ACLs for
|
||||
* owner@, group@ and everyone@.
|
||||
* We skip any of these ACLs found.
|
||||
*/
|
||||
if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
|
||||
ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
|
||||
ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
|
||||
continue;
|
||||
|
||||
if (acl_create_entry(&acl, &acl_entry) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to create a new ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
switch (ae_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
|
||||
break;
|
||||
default:
|
||||
/* We don't support any other types on MacOS */
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (ae_tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
if (mbr_uid_to_uuid(ae_uid, ae_uuid) != 0)
|
||||
continue;
|
||||
if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
|
||||
continue;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
if (mbr_gid_to_uuid(ae_gid, ae_uuid) != 0)
|
||||
continue;
|
||||
if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL tag");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get ACL permission set");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_perms(acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear ACL permissions");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
|
||||
if (ae_permset & acl_nfs4_perm_map[i].a_perm) {
|
||||
if (acl_add_perm(acl_permset,
|
||||
acl_nfs4_perm_map[i].p_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add ACL permission");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* acl_get_flagset_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get flagset from an NFSv4 ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_flags_np(acl_flagset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear flags from an NFSv4 ACL flagset");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
|
||||
if (acl_add_flag_np(acl_flagset,
|
||||
acl_nfs4_flag_map[i].p_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add flag to "
|
||||
"NFSv4 ACL flagset");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
if (acl_set_fd_np(fd, acl, ACL_TYPE_EXTENDED) == 0)
|
||||
ret = ARCHIVE_OK;
|
||||
else {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set acl on fd: %s", tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
} else if (acl_set_link_np(name, ACL_TYPE_EXTENDED, acl) != 0) {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Failed to set acl: %s",
|
||||
tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
exit_free:
|
||||
acl_free(acl);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
acl_t acl;
|
||||
int r;
|
||||
|
||||
accpath = NULL;
|
||||
|
||||
if (*fd < 0) {
|
||||
accpath = archive_read_disk_entry_setup_path(a, entry, fd);
|
||||
if (accpath == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
archive_entry_acl_clear(entry);
|
||||
|
||||
acl = NULL;
|
||||
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_EXTENDED);
|
||||
else if (!a->follow_symlinks)
|
||||
acl = acl_get_link_np(accpath, ACL_TYPE_EXTENDED);
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_EXTENDED);
|
||||
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl);
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate NFSv4 ACLs");
|
||||
}
|
||||
|
||||
/*
|
||||
* Because Mac OS doesn't support owner@, group@ and everyone@
|
||||
* ACLs we need to add NFSv4 ACLs mirroring the file mode to
|
||||
* the archive entry. Otherwise extraction on non-Mac platforms
|
||||
* would lead to an invalid file mode.
|
||||
*/
|
||||
if ((archive_entry_acl_types(entry) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0)
|
||||
add_trivial_nfs4_acl(entry);
|
||||
|
||||
return (r);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl, __LA_MODE_T mode)
|
||||
{
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
(void)mode; /* UNUSED */
|
||||
|
||||
if ((archive_acl_types(abstract_acl) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_DARWIN */
|
702
dependencies/libarchive-3.4.2/libarchive/archive_disk_acl_freebsd.c
vendored
Normal file
702
dependencies/libarchive-3.4.2/libarchive/archive_disk_acl_freebsd.c
vendored
Normal file
|
@ -0,0 +1,702 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2009 Tim Kientzle
|
||||
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2017 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"
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
|
||||
typedef struct {
|
||||
const int a_perm; /* Libarchive permission or flag */
|
||||
const int p_perm; /* Platform permission or flag */
|
||||
} acl_perm_map_t;
|
||||
|
||||
static const acl_perm_map_t acl_posix_perm_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||
};
|
||||
|
||||
static const int acl_posix_perm_map_size =
|
||||
(int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
static const acl_perm_map_t acl_nfs4_perm_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
};
|
||||
|
||||
static const int acl_nfs4_perm_map_size =
|
||||
(int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
|
||||
|
||||
static const acl_perm_map_t acl_nfs4_flag_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
|
||||
#ifdef ACL_ENTRY_INHERITED
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
|
||||
#endif
|
||||
};
|
||||
|
||||
static const int acl_nfs4_flag_map_size =
|
||||
(int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
|
||||
#endif /* ARCHIVE_ACL_FREEBSD_NFS4 */
|
||||
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
|
||||
{
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
int brand;
|
||||
acl_flagset_t acl_flagset;
|
||||
acl_entry_type_t acl_type;
|
||||
#endif
|
||||
acl_tag_t acl_tag;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
int i, entry_acl_type, perm_map_size;
|
||||
const acl_perm_map_t *perm_map;
|
||||
int r, s, ae_id, ae_tag, ae_perm;
|
||||
void *q;
|
||||
const char *ae_name;
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
|
||||
// Make sure the "brand" on this ACL is consistent
|
||||
// with the default_entry_acl_type bits provided.
|
||||
if (acl_get_brand_np(acl, &brand) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to read ACL brand");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (brand) {
|
||||
case ACL_BRAND_POSIX:
|
||||
switch (default_entry_acl_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid ACL entry type for POSIX.1e ACL");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
break;
|
||||
case ACL_BRAND_NFS4:
|
||||
if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid ACL entry type for NFSv4 ACL");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Unknown ACL brand");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
#endif
|
||||
|
||||
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get first ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
while (s == 1) {
|
||||
ae_id = -1;
|
||||
ae_name = NULL;
|
||||
ae_perm = 0;
|
||||
|
||||
if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get ACL tag type");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (acl_tag) {
|
||||
case ACL_USER:
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q != NULL) {
|
||||
ae_id = (int)*(uid_t *)q;
|
||||
acl_free(q);
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
break;
|
||||
case ACL_GROUP:
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q != NULL) {
|
||||
ae_id = (int)*(gid_t *)q;
|
||||
acl_free(q);
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
break;
|
||||
case ACL_MASK:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_MASK;
|
||||
break;
|
||||
case ACL_USER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
break;
|
||||
case ACL_GROUP_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
break;
|
||||
case ACL_OTHER:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||
break;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
case ACL_EVERYONE:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* Skip types that libarchive can't support. */
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
// XXX acl_type maps to allow/deny/audit/YYYY bits
|
||||
entry_acl_type = default_entry_acl_type;
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
/*
|
||||
* acl_get_entry_type_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) {
|
||||
archive_set_error(&a->archive, errno, "Failed "
|
||||
"to get ACL type from a NFSv4 ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (acl_type) {
|
||||
case ACL_ENTRY_TYPE_ALLOW:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_DENY:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_AUDIT:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_ALARM:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Invalid NFSv4 ACL entry type");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Libarchive stores "flag" (NFSv4 inheritance bits)
|
||||
* in the ae_perm bitmap.
|
||||
*
|
||||
* acl_get_flagset_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get flagset from a NFSv4 "
|
||||
"ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
r = acl_get_flag_np(acl_flagset,
|
||||
acl_nfs4_flag_map[i].p_perm);
|
||||
if (r == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to check flag in a NFSv4 "
|
||||
"ACL flagset");
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= acl_nfs4_flag_map[i].a_perm;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get ACL permission set");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
perm_map_size = acl_nfs4_perm_map_size;
|
||||
perm_map = acl_nfs4_perm_map;
|
||||
} else {
|
||||
#endif
|
||||
perm_map_size = acl_posix_perm_map_size;
|
||||
perm_map = acl_posix_perm_map;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < perm_map_size; ++i) {
|
||||
r = acl_get_perm_np(acl_permset, perm_map[i].p_perm);
|
||||
if (r == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to check permission in an ACL "
|
||||
"permission set");
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= perm_map[i].a_perm;
|
||||
}
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag,
|
||||
ae_id, ae_name);
|
||||
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get next ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
set_acl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl,
|
||||
int ae_requested_type, const char *tname)
|
||||
{
|
||||
int acl_type = 0;
|
||||
acl_t acl;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
acl_flagset_t acl_flagset;
|
||||
int r;
|
||||
#endif
|
||||
int ret;
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
int perm_map_size;
|
||||
const acl_perm_map_t *perm_map;
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
|
||||
ret = ARCHIVE_OK;
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
|
||||
switch (ae_requested_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
acl_type = ACL_TYPE_ACCESS;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
acl_type = ACL_TYPE_DEFAULT;
|
||||
break;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
|
||||
acl_type = ACL_TYPE_NFS4;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = ENOENT;
|
||||
archive_set_error(a, errno, "Unsupported ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
acl = acl_init(entries);
|
||||
if (acl == (acl_t)NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to initialize ACL working storage");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
if (acl_create_entry(&acl, &acl_entry) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to create a new ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
switch (ae_tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
acl_set_tag_type(acl_entry, ACL_USER);
|
||||
acl_set_qualifier(acl_entry, &ae_uid);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP);
|
||||
acl_set_qualifier(acl_entry, &ae_gid);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_USER_OBJ);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
acl_set_tag_type(acl_entry, ACL_MASK);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
acl_set_tag_type(acl_entry, ACL_OTHER);
|
||||
break;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
acl_set_tag_type(acl_entry, ACL_EVERYONE);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL tag");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
r = 0;
|
||||
switch (ae_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
r = acl_set_entry_type_np(acl_entry,
|
||||
ACL_ENTRY_TYPE_ALLOW);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
r = acl_set_entry_type_np(acl_entry,
|
||||
ACL_ENTRY_TYPE_DENY);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
r = acl_set_entry_type_np(acl_entry,
|
||||
ACL_ENTRY_TYPE_AUDIT);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
r = acl_set_entry_type_np(acl_entry,
|
||||
ACL_ENTRY_TYPE_ALARM);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
// These don't translate directly into the system ACL.
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (r != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get ACL permission set");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_perms(acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear ACL permissions");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
perm_map_size = acl_nfs4_perm_map_size;
|
||||
perm_map = acl_nfs4_perm_map;
|
||||
} else {
|
||||
#endif
|
||||
perm_map_size = acl_posix_perm_map_size;
|
||||
perm_map = acl_posix_perm_map;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < perm_map_size; ++i) {
|
||||
if (ae_permset & perm_map[i].a_perm) {
|
||||
if (acl_add_perm(acl_permset,
|
||||
perm_map[i].p_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add ACL permission");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
/*
|
||||
* acl_get_flagset_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get flagset from an NFSv4 "
|
||||
"ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_flags_np(acl_flagset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear flags from an NFSv4 "
|
||||
"ACL flagset");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
|
||||
if (acl_add_flag_np(acl_flagset,
|
||||
acl_nfs4_flag_map[i].p_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add flag to "
|
||||
"NFSv4 ACL flagset");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Try restoring the ACL through 'fd' if we can. */
|
||||
if (fd >= 0) {
|
||||
if (acl_set_fd_np(fd, acl, acl_type) == 0)
|
||||
ret = ARCHIVE_OK;
|
||||
else {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set acl on fd: %s", tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if HAVE_ACL_SET_LINK_NP
|
||||
else if (acl_set_link_np(name, acl_type, acl) != 0)
|
||||
#else
|
||||
/* FreeBSD older than 8.0 */
|
||||
else if (acl_set_file(name, acl_type, acl) != 0)
|
||||
#endif
|
||||
{
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Failed to set acl: %s",
|
||||
tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
exit_free:
|
||||
acl_free(acl);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
acl_t acl;
|
||||
int r;
|
||||
|
||||
accpath = NULL;
|
||||
|
||||
if (*fd < 0) {
|
||||
accpath = archive_read_disk_entry_setup_path(a, entry, fd);
|
||||
if (accpath == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
archive_entry_acl_clear(entry);
|
||||
|
||||
acl = NULL;
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
/* Try NFSv4 ACL first. */
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4);
|
||||
else if (!a->follow_symlinks)
|
||||
acl = acl_get_link_np(accpath, ACL_TYPE_NFS4);
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_NFS4);
|
||||
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate NFSv4 ACLs");
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Retrieve access ACL from file. */
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_ACCESS);
|
||||
#if HAVE_ACL_GET_LINK_NP
|
||||
else if (!a->follow_symlinks)
|
||||
acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
|
||||
#else
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
/* We can't get the ACL of a symlink, so we assume it can't
|
||||
have one. */
|
||||
acl = NULL;
|
||||
#endif
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
|
||||
|
||||
#if HAVE_ACL_IS_TRIVIAL_NP
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate access ACLs");
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only directories can have default ACLs. */
|
||||
if (S_ISDIR(archive_entry_mode(entry))) {
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT);
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
|
||||
acl_free(acl);
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate default ACLs");
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl, __LA_MODE_T mode)
|
||||
{
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
(void)mode; /* UNUSED */
|
||||
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
}
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
|
||||
|
||||
/* Simultaneous POSIX.1e and NFSv4 is not supported */
|
||||
return (ret);
|
||||
}
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
else if ((archive_acl_types(abstract_acl) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
}
|
||||
#endif
|
||||
return (ret);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_FREEBSD */
|
743
dependencies/libarchive-3.4.2/libarchive/archive_disk_acl_linux.c
vendored
Normal file
743
dependencies/libarchive-3.4.2/libarchive/archive_disk_acl_linux.c
vendored
Normal file
|
@ -0,0 +1,743 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2009 Tim Kientzle
|
||||
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2017 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"
|
||||
|
||||
#if ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_LIBRICHACL
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#if HAVE_ACL_LIBACL_H
|
||||
#include <acl/libacl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_RICHACL_H
|
||||
#include <sys/richacl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
|
||||
typedef struct {
|
||||
const int a_perm; /* Libarchive permission or flag */
|
||||
const int p_perm; /* Platform permission or flag */
|
||||
} acl_perm_map_t;
|
||||
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
static const acl_perm_map_t acl_posix_perm_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||
};
|
||||
|
||||
static const int acl_posix_perm_map_size =
|
||||
(int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
|
||||
#endif /* ARCHIVE_ACL_LIBACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
static const acl_perm_map_t acl_nfs4_perm_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, RICHACE_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, RICHACE_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, RICHACE_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, RICHACE_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, RICHACE_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, RICHACE_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, RICHACE_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, RICHACE_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, RICHACE_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, RICHACE_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, RICHACE_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, RICHACE_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, RICHACE_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, RICHACE_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, RICHACE_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, RICHACE_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, RICHACE_SYNCHRONIZE}
|
||||
};
|
||||
|
||||
static const int acl_nfs4_perm_map_size =
|
||||
(int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
|
||||
|
||||
static const acl_perm_map_t acl_nfs4_flag_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, RICHACE_FILE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, RICHACE_DIRECTORY_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, RICHACE_NO_PROPAGATE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE}
|
||||
};
|
||||
|
||||
static const int acl_nfs4_flag_map_size =
|
||||
(int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
|
||||
#endif /* ARCHIVE_ACL_LIBRICHACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
/*
|
||||
* Translate POSIX.1e ACLs into libarchive internal structure
|
||||
*/
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
|
||||
{
|
||||
acl_tag_t acl_tag;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
int i, entry_acl_type;
|
||||
int r, s, ae_id, ae_tag, ae_perm;
|
||||
void *q;
|
||||
const char *ae_name;
|
||||
|
||||
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get first ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
while (s == 1) {
|
||||
ae_id = -1;
|
||||
ae_name = NULL;
|
||||
ae_perm = 0;
|
||||
|
||||
if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get ACL tag type");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (acl_tag) {
|
||||
case ACL_USER:
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q != NULL) {
|
||||
ae_id = (int)*(uid_t *)q;
|
||||
acl_free(q);
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
break;
|
||||
case ACL_GROUP:
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q != NULL) {
|
||||
ae_id = (int)*(gid_t *)q;
|
||||
acl_free(q);
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
break;
|
||||
case ACL_MASK:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_MASK;
|
||||
break;
|
||||
case ACL_USER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
break;
|
||||
case ACL_GROUP_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
break;
|
||||
case ACL_OTHER:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||
break;
|
||||
default:
|
||||
/* Skip types that libarchive can't support. */
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
// XXX acl_type maps to allow/deny/audit/YYYY bits
|
||||
entry_acl_type = default_entry_acl_type;
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get ACL permission set");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_posix_perm_map_size; ++i) {
|
||||
r = acl_get_perm(acl_permset,
|
||||
acl_posix_perm_map[i].p_perm);
|
||||
if (r == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to check permission in an ACL "
|
||||
"permission set");
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= acl_posix_perm_map[i].a_perm;
|
||||
}
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag,
|
||||
ae_id, ae_name);
|
||||
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get next ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
/*
|
||||
* Translate RichACL into libarchive internal ACL
|
||||
*/
|
||||
static int
|
||||
translate_richacl(struct archive_read_disk *a, struct archive_entry *entry,
|
||||
struct richacl *richacl)
|
||||
{
|
||||
int ae_id, ae_tag, ae_perm;
|
||||
int entry_acl_type, i;
|
||||
const char *ae_name;
|
||||
|
||||
struct richace *richace;
|
||||
|
||||
richacl_for_each_entry(richace, richacl) {
|
||||
ae_name = NULL;
|
||||
ae_tag = 0;
|
||||
ae_perm = 0;
|
||||
ae_id = -1;
|
||||
|
||||
switch (richace->e_type) {
|
||||
case RICHACE_ACCESS_ALLOWED_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
break;
|
||||
case RICHACE_ACCESS_DENIED_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
break;
|
||||
default: /* Unknown entry type, skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Unsupported */
|
||||
if (richace->e_flags & RICHACE_UNMAPPED_WHO)
|
||||
continue;
|
||||
|
||||
if (richace->e_flags & RICHACE_SPECIAL_WHO) {
|
||||
switch (richace->e_id) {
|
||||
case RICHACE_OWNER_SPECIAL_ID:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
break;
|
||||
case RICHACE_GROUP_SPECIAL_ID:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
break;
|
||||
case RICHACE_EVERYONE_SPECIAL_ID:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||
break;
|
||||
default: /* Unknown special ID type */
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
ae_id = richace->e_id;
|
||||
if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) {
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
(gid_t)(richace->e_id));
|
||||
} else {
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
(uid_t)(richace->e_id));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if ((richace->e_flags &
|
||||
acl_nfs4_flag_map[i].p_perm) != 0)
|
||||
ae_perm |= acl_nfs4_flag_map[i].a_perm;
|
||||
}
|
||||
for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
|
||||
if ((richace->e_mask &
|
||||
acl_nfs4_perm_map[i].p_perm) != 0)
|
||||
ae_perm |=
|
||||
acl_nfs4_perm_map[i].a_perm;
|
||||
}
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag, ae_id, ae_name);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBRICHACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
static int
|
||||
_richacl_mode_to_mask(short mode)
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
if (mode & S_IROTH)
|
||||
mask |= RICHACE_POSIX_MODE_READ;
|
||||
if (mode & S_IWOTH)
|
||||
mask |= RICHACE_POSIX_MODE_WRITE;
|
||||
if (mode & S_IXOTH)
|
||||
mask |= RICHACE_POSIX_MODE_EXEC;
|
||||
|
||||
return (mask);
|
||||
}
|
||||
|
||||
static void
|
||||
_richacl_mode_to_masks(struct richacl *richacl, __LA_MODE_T mode)
|
||||
{
|
||||
richacl->a_owner_mask = _richacl_mode_to_mask((mode & 0700) >> 6);
|
||||
richacl->a_group_mask = _richacl_mode_to_mask((mode & 0070) >> 3);
|
||||
richacl->a_other_mask = _richacl_mode_to_mask(mode & 0007);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBRICHACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
static int
|
||||
set_richacl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl, __LA_MODE_T mode,
|
||||
int ae_requested_type, const char *tname)
|
||||
{
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
int ret;
|
||||
int e = 0;
|
||||
struct richacl *richacl = NULL;
|
||||
struct richace *richace;
|
||||
|
||||
ret = ARCHIVE_OK;
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
if (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
errno = ENOENT;
|
||||
archive_set_error(a, errno, "Unsupported ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
richacl = richacl_alloc(entries);
|
||||
if (richacl == NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to initialize RichACL working storage");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
e = 0;
|
||||
|
||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
richace = &(richacl->a_entries[e]);
|
||||
|
||||
richace->e_flags = 0;
|
||||
richace->e_mask = 0;
|
||||
|
||||
switch (ae_tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
richace->e_id = ae_uid;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
richace->e_id = ae_gid;
|
||||
richace->e_flags |= RICHACE_IDENTIFIER_GROUP;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
richace->e_flags |= RICHACE_SPECIAL_WHO;
|
||||
richace->e_id = RICHACE_OWNER_SPECIAL_ID;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
richace->e_flags |= RICHACE_SPECIAL_WHO;
|
||||
richace->e_id = RICHACE_GROUP_SPECIAL_ID;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
richace->e_flags |= RICHACE_SPECIAL_WHO;
|
||||
richace->e_id = RICHACE_EVERYONE_SPECIAL_ID;
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL tag");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
switch (ae_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
richace->e_type =
|
||||
RICHACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
richace->e_type =
|
||||
RICHACE_ACCESS_DENIED_ACE_TYPE;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
|
||||
if (ae_permset & acl_nfs4_perm_map[i].a_perm)
|
||||
richace->e_mask |= acl_nfs4_perm_map[i].p_perm;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if (ae_permset &
|
||||
acl_nfs4_flag_map[i].a_perm)
|
||||
richace->e_flags |= acl_nfs4_flag_map[i].p_perm;
|
||||
}
|
||||
e++;
|
||||
}
|
||||
|
||||
/* Fill RichACL masks */
|
||||
_richacl_mode_to_masks(richacl, mode);
|
||||
|
||||
if (fd >= 0) {
|
||||
if (richacl_set_fd(fd, richacl) == 0)
|
||||
ret = ARCHIVE_OK;
|
||||
else {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set richacl on fd: %s", tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
} else if (richacl_set_file(name, richacl) != 0) {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Failed to set richacl: %s",
|
||||
tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
exit_free:
|
||||
richacl_free(richacl);
|
||||
return (ret);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_RICHACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
static int
|
||||
set_acl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl,
|
||||
int ae_requested_type, const char *tname)
|
||||
{
|
||||
int acl_type = 0;
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
int ret;
|
||||
acl_t acl = NULL;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
|
||||
ret = ARCHIVE_OK;
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
switch (ae_requested_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
acl_type = ACL_TYPE_ACCESS;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
acl_type = ACL_TYPE_DEFAULT;
|
||||
break;
|
||||
default:
|
||||
errno = ENOENT;
|
||||
archive_set_error(a, errno, "Unsupported ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
acl = acl_init(entries);
|
||||
if (acl == (acl_t)NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to initialize ACL working storage");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
|
||||
if (acl_create_entry(&acl, &acl_entry) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to create a new ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
switch (ae_tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
acl_set_tag_type(acl_entry, ACL_USER);
|
||||
acl_set_qualifier(acl_entry, &ae_uid);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP);
|
||||
acl_set_qualifier(acl_entry, &ae_gid);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_USER_OBJ);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
acl_set_tag_type(acl_entry, ACL_MASK);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
acl_set_tag_type(acl_entry, ACL_OTHER);
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL tag");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get ACL permission set");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_perms(acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear ACL permissions");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_posix_perm_map_size; ++i) {
|
||||
if (ae_permset & acl_posix_perm_map[i].a_perm) {
|
||||
if (acl_add_perm(acl_permset,
|
||||
acl_posix_perm_map[i].p_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add ACL permission");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (fd >= 0 && ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
|
||||
if (acl_set_fd(fd, acl) == 0)
|
||||
ret = ARCHIVE_OK;
|
||||
else {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set acl on fd: %s", tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
} else if (acl_set_file(name, acl_type, acl) != 0) {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Failed to set acl: %s",
|
||||
tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
exit_free:
|
||||
acl_free(acl);
|
||||
return (ret);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBACL */
|
||||
|
||||
int
|
||||
archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
int r;
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
acl_t acl;
|
||||
#endif
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
struct richacl *richacl;
|
||||
mode_t mode;
|
||||
#endif
|
||||
|
||||
accpath = NULL;
|
||||
r = ARCHIVE_OK;
|
||||
|
||||
/* For default ACLs we need reachable accpath */
|
||||
if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) {
|
||||
accpath = archive_read_disk_entry_setup_path(a, entry, fd);
|
||||
if (accpath == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
archive_entry_acl_clear(entry);
|
||||
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
acl = NULL;
|
||||
#endif
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
richacl = NULL;
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
/* Try NFSv4 ACL first. */
|
||||
if (*fd >= 0)
|
||||
richacl = richacl_get_fd(*fd);
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
/* We can't get the ACL of a symlink, so we assume it can't
|
||||
have one */
|
||||
richacl = NULL;
|
||||
else
|
||||
richacl = richacl_get_file(accpath);
|
||||
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (richacl != NULL) {
|
||||
mode = archive_entry_mode(entry);
|
||||
if (richacl_equiv_mode(richacl, &mode) == 0) {
|
||||
richacl_free(richacl);
|
||||
richacl = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
}
|
||||
|
||||
if (richacl != NULL) {
|
||||
r = translate_richacl(a, entry, richacl);
|
||||
richacl_free(richacl);
|
||||
richacl = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate NFSv4 ACLs");
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBRICHACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
/* Retrieve access ACL from file. */
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd(*fd);
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
/* We can't get the ACL of a symlink, so we assume it can't
|
||||
have one. */
|
||||
acl = NULL;
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
|
||||
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate access ACLs");
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only directories can have default ACLs. */
|
||||
if (S_ISDIR(archive_entry_mode(entry))) {
|
||||
acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
|
||||
acl_free(acl);
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate default ACLs");
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBACL */
|
||||
return (r);
|
||||
}
|
||||
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl, __LA_MODE_T mode)
|
||||
{
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
#if !ARCHIVE_ACL_LIBRICHACL
|
||||
(void)mode; /* UNUSED */
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = set_richacl(a, fd, name, abstract_acl, mode,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
}
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
else
|
||||
#endif
|
||||
#endif /* ARCHIVE_ACL_LIBRICHACL */
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
}
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBACL */
|
||||
return (ret);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_LIBRICHACL */
|
819
dependencies/libarchive-3.4.2/libarchive/archive_disk_acl_sunos.c
vendored
Normal file
819
dependencies/libarchive-3.4.2/libarchive/archive_disk_acl_sunos.c
vendored
Normal file
|
@ -0,0 +1,819 @@
|
|||
/*-
|
||||
* Copyright (c) 2017 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"
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
|
||||
typedef struct {
|
||||
const int a_perm; /* Libarchive permission or flag */
|
||||
const int p_perm; /* Platform permission or flag */
|
||||
} acl_perm_map_t;
|
||||
|
||||
static const acl_perm_map_t acl_posix_perm_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, S_IXOTH },
|
||||
{ARCHIVE_ENTRY_ACL_WRITE, S_IWOTH },
|
||||
{ARCHIVE_ENTRY_ACL_READ, S_IROTH }
|
||||
};
|
||||
|
||||
static const int acl_posix_perm_map_size =
|
||||
(int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
static const acl_perm_map_t acl_nfs4_perm_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
|
||||
};
|
||||
|
||||
static const int acl_nfs4_perm_map_size =
|
||||
(int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
|
||||
|
||||
static const acl_perm_map_t acl_nfs4_flag_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
|
||||
#ifdef ACE_INHERITED_ACE
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
|
||||
#endif
|
||||
};
|
||||
|
||||
const int acl_nfs4_flag_map_size =
|
||||
(int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
|
||||
|
||||
#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
|
||||
static void *
|
||||
sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
|
||||
{
|
||||
int cnt, cntcmd;
|
||||
size_t size;
|
||||
void *aclp;
|
||||
|
||||
if (cmd == GETACL) {
|
||||
cntcmd = GETACLCNT;
|
||||
size = sizeof(aclent_t);
|
||||
}
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else if (cmd == ACE_GETACL) {
|
||||
cntcmd = ACE_GETACLCNT;
|
||||
size = sizeof(ace_t);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
errno = EINVAL;
|
||||
*aclcnt = -1;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
aclp = NULL;
|
||||
cnt = -2;
|
||||
|
||||
while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
|
||||
if (path != NULL)
|
||||
cnt = acl(path, cntcmd, 0, NULL);
|
||||
else
|
||||
cnt = facl(fd, cntcmd, 0, NULL);
|
||||
|
||||
if (cnt > 0) {
|
||||
if (aclp == NULL)
|
||||
aclp = malloc(cnt * size);
|
||||
else
|
||||
aclp = realloc(NULL, cnt * size);
|
||||
if (aclp != NULL) {
|
||||
if (path != NULL)
|
||||
cnt = acl(path, cmd, cnt, aclp);
|
||||
else
|
||||
cnt = facl(fd, cmd, cnt, aclp);
|
||||
}
|
||||
} else {
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*aclcnt = cnt;
|
||||
return (aclp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if acl is trivial
|
||||
* This is a FreeBSD acl_is_trivial_np() implementation for Solaris
|
||||
*/
|
||||
static int
|
||||
sun_acl_is_trivial(void *aclp, int aclcnt, mode_t mode, int is_nfs4,
|
||||
int is_dir, int *trivialp)
|
||||
{
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
int i, p;
|
||||
const uint32_t rperm = ACE_READ_DATA;
|
||||
const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
|
||||
const uint32_t eperm = ACE_EXECUTE;
|
||||
const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
|
||||
ACE_READ_ACL | ACE_SYNCHRONIZE;
|
||||
const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES |
|
||||
ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER;
|
||||
|
||||
ace_t *ace;
|
||||
ace_t tace[6];
|
||||
#endif
|
||||
|
||||
if (aclp == NULL || trivialp == NULL)
|
||||
return (-1);
|
||||
|
||||
*trivialp = 0;
|
||||
|
||||
/*
|
||||
* POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
|
||||
* FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
|
||||
* including mask.
|
||||
*/
|
||||
if (!is_nfs4) {
|
||||
if (aclcnt == 4)
|
||||
*trivialp = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
/*
|
||||
* Continue with checking NFSv4 ACLs
|
||||
*
|
||||
* Create list of trivial ace's to be compared
|
||||
*/
|
||||
|
||||
/* owner@ allow pre */
|
||||
tace[0].a_flags = ACE_OWNER;
|
||||
tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[0].a_access_mask = 0;
|
||||
|
||||
/* owner@ deny */
|
||||
tace[1].a_flags = ACE_OWNER;
|
||||
tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
|
||||
tace[1].a_access_mask = 0;
|
||||
|
||||
/* group@ deny */
|
||||
tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
|
||||
tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
|
||||
tace[2].a_access_mask = 0;
|
||||
|
||||
/* owner@ allow */
|
||||
tace[3].a_flags = ACE_OWNER;
|
||||
tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[3].a_access_mask = ownset;
|
||||
|
||||
/* group@ allow */
|
||||
tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
|
||||
tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[4].a_access_mask = pubset;
|
||||
|
||||
/* everyone@ allow */
|
||||
tace[5].a_flags = ACE_EVERYONE;
|
||||
tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[5].a_access_mask = pubset;
|
||||
|
||||
/* Permissions for everyone@ */
|
||||
if (mode & 0004)
|
||||
tace[5].a_access_mask |= rperm;
|
||||
if (mode & 0002)
|
||||
tace[5].a_access_mask |= wperm;
|
||||
if (mode & 0001)
|
||||
tace[5].a_access_mask |= eperm;
|
||||
|
||||
/* Permissions for group@ */
|
||||
if (mode & 0040)
|
||||
tace[4].a_access_mask |= rperm;
|
||||
else if (mode & 0004)
|
||||
tace[2].a_access_mask |= rperm;
|
||||
if (mode & 0020)
|
||||
tace[4].a_access_mask |= wperm;
|
||||
else if (mode & 0002)
|
||||
tace[2].a_access_mask |= wperm;
|
||||
if (mode & 0010)
|
||||
tace[4].a_access_mask |= eperm;
|
||||
else if (mode & 0001)
|
||||
tace[2].a_access_mask |= eperm;
|
||||
|
||||
/* Permissions for owner@ */
|
||||
if (mode & 0400) {
|
||||
tace[3].a_access_mask |= rperm;
|
||||
if (!(mode & 0040) && (mode & 0004))
|
||||
tace[0].a_access_mask |= rperm;
|
||||
} else if ((mode & 0040) || (mode & 0004))
|
||||
tace[1].a_access_mask |= rperm;
|
||||
if (mode & 0200) {
|
||||
tace[3].a_access_mask |= wperm;
|
||||
if (!(mode & 0020) && (mode & 0002))
|
||||
tace[0].a_access_mask |= wperm;
|
||||
} else if ((mode & 0020) || (mode & 0002))
|
||||
tace[1].a_access_mask |= wperm;
|
||||
if (mode & 0100) {
|
||||
tace[3].a_access_mask |= eperm;
|
||||
if (!(mode & 0010) && (mode & 0001))
|
||||
tace[0].a_access_mask |= eperm;
|
||||
} else if ((mode & 0010) || (mode & 0001))
|
||||
tace[1].a_access_mask |= eperm;
|
||||
|
||||
/* Check if the acl count matches */
|
||||
p = 3;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (tace[i].a_access_mask != 0)
|
||||
p++;
|
||||
}
|
||||
if (aclcnt != p)
|
||||
return (0);
|
||||
|
||||
p = 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (tace[i].a_access_mask != 0) {
|
||||
ace = &((ace_t *)aclp)[p];
|
||||
/*
|
||||
* Illumos added ACE_DELETE_CHILD to write perms for
|
||||
* directories. We have to check against that, too.
|
||||
*/
|
||||
if (ace->a_flags != tace[i].a_flags ||
|
||||
ace->a_type != tace[i].a_type ||
|
||||
(ace->a_access_mask != tace[i].a_access_mask &&
|
||||
(!is_dir || (tace[i].a_access_mask & wperm) == 0 ||
|
||||
ace->a_access_mask !=
|
||||
(tace[i].a_access_mask | ACE_DELETE_CHILD))))
|
||||
return (0);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
*trivialp = 1;
|
||||
#else /* !ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
(void)is_dir; /* UNUSED */
|
||||
(void)aclp; /* UNUSED */
|
||||
#endif /* !ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL
|
||||
*/
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, void *aclp, int aclcnt,
|
||||
int default_entry_acl_type)
|
||||
{
|
||||
int e, i;
|
||||
int ae_id, ae_tag, ae_perm;
|
||||
int entry_acl_type;
|
||||
const char *ae_name;
|
||||
aclent_t *aclent;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
ace_t *ace;
|
||||
#endif
|
||||
|
||||
if (aclcnt <= 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
for (e = 0; e < aclcnt; e++) {
|
||||
ae_name = NULL;
|
||||
ae_tag = 0;
|
||||
ae_perm = 0;
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
ace = &((ace_t *)aclp)[e];
|
||||
ae_id = ace->a_who;
|
||||
|
||||
switch(ace->a_type) {
|
||||
case ACE_ACCESS_ALLOWED_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
break;
|
||||
case ACE_ACCESS_DENIED_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
break;
|
||||
case ACE_SYSTEM_AUDIT_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
break;
|
||||
case ACE_SYSTEM_ALARM_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
|
||||
break;
|
||||
default:
|
||||
/* Unknown entry type, skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ace->a_flags & ACE_OWNER) != 0)
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
else if ((ace->a_flags & ACE_GROUP) != 0)
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
else if ((ace->a_flags & ACE_EVERYONE) != 0)
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||
else if ((ace->a_flags & ACE_IDENTIFIER_GROUP) != 0) {
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
} else {
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if ((ace->a_flags &
|
||||
acl_nfs4_flag_map[i].p_perm) != 0)
|
||||
ae_perm |= acl_nfs4_flag_map[i].a_perm;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
|
||||
if ((ace->a_access_mask &
|
||||
acl_nfs4_perm_map[i].p_perm) != 0)
|
||||
ae_perm |= acl_nfs4_perm_map[i].a_perm;
|
||||
}
|
||||
} else
|
||||
#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
|
||||
aclent = &((aclent_t *)aclp)[e];
|
||||
if ((aclent->a_type & ACL_DEFAULT) != 0)
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
|
||||
else
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
ae_id = aclent->a_id;
|
||||
|
||||
switch(aclent->a_type) {
|
||||
case DEF_USER:
|
||||
case USER:
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
break;
|
||||
case DEF_GROUP:
|
||||
case GROUP:
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
break;
|
||||
case DEF_CLASS_OBJ:
|
||||
case CLASS_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_MASK;
|
||||
break;
|
||||
case DEF_USER_OBJ:
|
||||
case USER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
break;
|
||||
case DEF_GROUP_OBJ:
|
||||
case GROUP_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
break;
|
||||
case DEF_OTHER_OBJ:
|
||||
case OTHER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||
break;
|
||||
default:
|
||||
/* Unknown tag type, skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_posix_perm_map_size; ++i) {
|
||||
if ((aclent->a_perm &
|
||||
acl_posix_perm_map[i].p_perm) != 0)
|
||||
ae_perm |= acl_posix_perm_map[i].a_perm;
|
||||
}
|
||||
} else
|
||||
return (ARCHIVE_WARN);
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag, ae_id, ae_name);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
set_acl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl,
|
||||
int ae_requested_type, const char *tname)
|
||||
{
|
||||
aclent_t *aclent;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
ace_t *ace;
|
||||
#endif
|
||||
int cmd, e, r;
|
||||
void *aclp;
|
||||
int ret;
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
int perm_map_size;
|
||||
const acl_perm_map_t *perm_map;
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
|
||||
ret = ARCHIVE_OK;
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
|
||||
switch (ae_requested_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
|
||||
cmd = SETACL;
|
||||
aclp = malloc(entries * sizeof(aclent_t));
|
||||
break;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
|
||||
cmd = ACE_SETACL;
|
||||
aclp = malloc(entries * sizeof(ace_t));
|
||||
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = ENOENT;
|
||||
archive_set_error(a, errno, "Unsupported ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
if (aclp == NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Can't allocate memory for acl buffer");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
e = 0;
|
||||
|
||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
aclent = NULL;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
ace = NULL;
|
||||
#endif
|
||||
if (cmd == SETACL) {
|
||||
aclent = &((aclent_t *)aclp)[e];
|
||||
aclent->a_id = -1;
|
||||
aclent->a_type = 0;
|
||||
aclent->a_perm = 0;
|
||||
}
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else { /* cmd == ACE_SETACL */
|
||||
ace = &((ace_t *)aclp)[e];
|
||||
ace->a_who = -1;
|
||||
ace->a_access_mask = 0;
|
||||
ace->a_flags = 0;
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
|
||||
switch (ae_tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
if (aclent != NULL) {
|
||||
aclent->a_id = ae_uid;
|
||||
aclent->a_type |= USER;
|
||||
}
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else {
|
||||
ace->a_who = ae_uid;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
if (aclent != NULL) {
|
||||
aclent->a_id = ae_gid;
|
||||
aclent->a_type |= GROUP;
|
||||
}
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else {
|
||||
ace->a_who = ae_gid;
|
||||
ace->a_flags |= ACE_IDENTIFIER_GROUP;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= USER_OBJ;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else {
|
||||
ace->a_flags |= ACE_OWNER;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= GROUP_OBJ;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else {
|
||||
ace->a_flags |= ACE_GROUP;
|
||||
ace->a_flags |= ACE_IDENTIFIER_GROUP;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= CLASS_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= OTHER_OBJ;
|
||||
break;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
if (ace != NULL)
|
||||
ace->a_flags |= ACE_EVERYONE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL tag");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
switch (ae_type) {
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
#endif
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
if (aclent == NULL)
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= ACL_DEFAULT;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (r != 0) {
|
||||
errno = EINVAL;
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
perm_map_size = acl_nfs4_perm_map_size;
|
||||
perm_map = acl_nfs4_perm_map;
|
||||
} else {
|
||||
#endif
|
||||
perm_map_size = acl_posix_perm_map_size;
|
||||
perm_map = acl_posix_perm_map;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i < perm_map_size; ++i) {
|
||||
if (ae_permset & perm_map[i].a_perm) {
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (ae_requested_type ==
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4)
|
||||
ace->a_access_mask |=
|
||||
perm_map[i].p_perm;
|
||||
else
|
||||
#endif
|
||||
aclent->a_perm |= perm_map[i].p_perm;
|
||||
}
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
|
||||
ace->a_flags |=
|
||||
acl_nfs4_flag_map[i].p_perm;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
e++;
|
||||
}
|
||||
|
||||
/* Try restoring the ACL through 'fd' if we can. */
|
||||
if (fd >= 0) {
|
||||
if (facl(fd, cmd, entries, aclp) == 0)
|
||||
ret = ARCHIVE_OK;
|
||||
else {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set acl on fd: %s", tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
} else if (acl(name, cmd, entries, aclp) != 0) {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Failed to set acl: %s",
|
||||
tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
exit_free:
|
||||
free(aclp);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
void *aclp;
|
||||
int aclcnt;
|
||||
int r;
|
||||
|
||||
accpath = NULL;
|
||||
|
||||
if (*fd < 0) {
|
||||
accpath = archive_read_disk_entry_setup_path(a, entry, fd);
|
||||
if (accpath == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
archive_entry_acl_clear(entry);
|
||||
|
||||
aclp = NULL;
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (*fd >= 0)
|
||||
aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL);
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
/* We can't get the ACL of a symlink, so we assume it can't
|
||||
have one. */
|
||||
aclp = NULL;
|
||||
else
|
||||
aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath);
|
||||
|
||||
if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
|
||||
archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)),
|
||||
&r) == 0 && r == 1) {
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
if (aclp != NULL) {
|
||||
r = translate_acl(a, entry, aclp, aclcnt,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4);
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate NFSv4 ACLs");
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
|
||||
/* Retrieve POSIX.1e ACLs from file. */
|
||||
if (*fd >= 0)
|
||||
aclp = sunacl_get(GETACL, &aclcnt, *fd, NULL);
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
/* We can't get the ACL of a symlink, so we assume it can't
|
||||
have one. */
|
||||
aclp = NULL;
|
||||
else
|
||||
aclp = sunacl_get(GETACL, &aclcnt, 0, accpath);
|
||||
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
|
||||
archive_entry_mode(entry), 0, S_ISDIR(archive_entry_mode(entry)),
|
||||
&r) == 0 && r == 1) {
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
}
|
||||
|
||||
if (aclp != NULL)
|
||||
{
|
||||
r = translate_acl(a, entry, aclp, aclcnt,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate access ACLs");
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl, __LA_MODE_T mode)
|
||||
{
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
(void)mode; /* UNUSED */
|
||||
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
||||
/* Solaris writes POSIX.1e access and default ACLs together */
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
|
||||
|
||||
/* Simultaneous POSIX.1e and NFSv4 is not supported */
|
||||
return (ret);
|
||||
}
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else if ((archive_acl_types(abstract_acl) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
}
|
||||
#endif
|
||||
return (ret);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_SUNOS */
|
195
dependencies/libarchive-3.4.2/libarchive/archive_endian.h
vendored
Normal file
195
dependencies/libarchive-3.4.2/libarchive/archive_endian.h
vendored
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*-
|
||||
* Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: head/lib/libarchive/archive_endian.h 201085 2009-12-28 02:17:15Z kientzle $
|
||||
*
|
||||
* Borrowed from FreeBSD's <sys/endian.h>
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_ENDIAN_H_INCLUDED
|
||||
#define ARCHIVE_ENDIAN_H_INCLUDED
|
||||
|
||||
/* Note: This is a purely internal header! */
|
||||
/* Do not use this outside of libarchive internal code! */
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Disabling inline keyword for compilers known to choke on it:
|
||||
* - Watcom C++ in C code. (For any version?)
|
||||
* - SGI MIPSpro
|
||||
* - Microsoft Visual C++ 6.0 (supposedly newer versions too)
|
||||
* - IBM VisualAge 6 (XL v6)
|
||||
* - Sun WorkShop C (SunPro) before 5.9
|
||||
*/
|
||||
#if defined(__WATCOMC__) || defined(__sgi) || defined(__hpux) || defined(__BORLANDC__)
|
||||
#define inline
|
||||
#elif defined(__IBMC__) && __IBMC__ < 700
|
||||
#define inline
|
||||
#elif defined(__SUNPRO_C) && __SUNPRO_C < 0x590
|
||||
#define inline
|
||||
#elif defined(_MSC_VER) || defined(__osf__)
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
|
||||
|
||||
static inline uint16_t
|
||||
archive_be16dec(const void *pp)
|
||||
{
|
||||
unsigned char const *p = (unsigned char const *)pp;
|
||||
|
||||
/* Store into unsigned temporaries before left shifting, to avoid
|
||||
promotion to signed int and then left shifting into the sign bit,
|
||||
which is undefined behaviour. */
|
||||
unsigned int p1 = p[1];
|
||||
unsigned int p0 = p[0];
|
||||
|
||||
return ((p0 << 8) | p1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
archive_be32dec(const void *pp)
|
||||
{
|
||||
unsigned char const *p = (unsigned char const *)pp;
|
||||
|
||||
/* Store into unsigned temporaries before left shifting, to avoid
|
||||
promotion to signed int and then left shifting into the sign bit,
|
||||
which is undefined behaviour. */
|
||||
unsigned int p3 = p[3];
|
||||
unsigned int p2 = p[2];
|
||||
unsigned int p1 = p[1];
|
||||
unsigned int p0 = p[0];
|
||||
|
||||
return ((p0 << 24) | (p1 << 16) | (p2 << 8) | p3);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
archive_be64dec(const void *pp)
|
||||
{
|
||||
unsigned char const *p = (unsigned char const *)pp;
|
||||
|
||||
return (((uint64_t)archive_be32dec(p) << 32) | archive_be32dec(p + 4));
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
archive_le16dec(const void *pp)
|
||||
{
|
||||
unsigned char const *p = (unsigned char const *)pp;
|
||||
|
||||
/* Store into unsigned temporaries before left shifting, to avoid
|
||||
promotion to signed int and then left shifting into the sign bit,
|
||||
which is undefined behaviour. */
|
||||
unsigned int p1 = p[1];
|
||||
unsigned int p0 = p[0];
|
||||
|
||||
return ((p1 << 8) | p0);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
archive_le32dec(const void *pp)
|
||||
{
|
||||
unsigned char const *p = (unsigned char const *)pp;
|
||||
|
||||
/* Store into unsigned temporaries before left shifting, to avoid
|
||||
promotion to signed int and then left shifting into the sign bit,
|
||||
which is undefined behaviour. */
|
||||
unsigned int p3 = p[3];
|
||||
unsigned int p2 = p[2];
|
||||
unsigned int p1 = p[1];
|
||||
unsigned int p0 = p[0];
|
||||
|
||||
return ((p3 << 24) | (p2 << 16) | (p1 << 8) | p0);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
archive_le64dec(const void *pp)
|
||||
{
|
||||
unsigned char const *p = (unsigned char const *)pp;
|
||||
|
||||
return (((uint64_t)archive_le32dec(p + 4) << 32) | archive_le32dec(p));
|
||||
}
|
||||
|
||||
static inline void
|
||||
archive_be16enc(void *pp, uint16_t u)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)pp;
|
||||
|
||||
p[0] = (u >> 8) & 0xff;
|
||||
p[1] = u & 0xff;
|
||||
}
|
||||
|
||||
static inline void
|
||||
archive_be32enc(void *pp, uint32_t u)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)pp;
|
||||
|
||||
p[0] = (u >> 24) & 0xff;
|
||||
p[1] = (u >> 16) & 0xff;
|
||||
p[2] = (u >> 8) & 0xff;
|
||||
p[3] = u & 0xff;
|
||||
}
|
||||
|
||||
static inline void
|
||||
archive_be64enc(void *pp, uint64_t u)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)pp;
|
||||
|
||||
archive_be32enc(p, (uint32_t)(u >> 32));
|
||||
archive_be32enc(p + 4, (uint32_t)(u & 0xffffffff));
|
||||
}
|
||||
|
||||
static inline void
|
||||
archive_le16enc(void *pp, uint16_t u)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)pp;
|
||||
|
||||
p[0] = u & 0xff;
|
||||
p[1] = (u >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static inline void
|
||||
archive_le32enc(void *pp, uint32_t u)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)pp;
|
||||
|
||||
p[0] = u & 0xff;
|
||||
p[1] = (u >> 8) & 0xff;
|
||||
p[2] = (u >> 16) & 0xff;
|
||||
p[3] = (u >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static inline void
|
||||
archive_le64enc(void *pp, uint64_t u)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)pp;
|
||||
|
||||
archive_le32enc(p, (uint32_t)(u & 0xffffffff));
|
||||
archive_le32enc(p + 4, (uint32_t)(u >> 32));
|
||||
}
|
||||
|
||||
#endif
|
149
dependencies/libarchive-3.4.2/libarchive/archive_entry.3
vendored
Normal file
149
dependencies/libarchive-3.4.2/libarchive/archive_entry.3
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
.\" Copyright (c) 2003-2007 Tim Kientzle
|
||||
.\" Copyright (c) 2010 Joerg Sonnenberger
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_ENTRY 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_entry_clear ,
|
||||
.Nm archive_entry_clone ,
|
||||
.Nm archive_entry_free ,
|
||||
.Nm archive_entry_new
|
||||
.Nd functions for managing archive entry descriptions
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive_entry.h
|
||||
.Ft "struct archive_entry *"
|
||||
.Fn archive_entry_clear "struct archive_entry *"
|
||||
.Ft struct archive_entry *
|
||||
.Fn archive_entry_clone "struct archive_entry *"
|
||||
.Ft void
|
||||
.Fn archive_entry_free "struct archive_entry *"
|
||||
.Ft struct archive_entry *
|
||||
.Fn archive_entry_new "void"
|
||||
.Sh DESCRIPTION
|
||||
These functions create and manipulate data objects that
|
||||
represent entries within an archive.
|
||||
You can think of a
|
||||
.Tn struct archive_entry
|
||||
as a heavy-duty version of
|
||||
.Tn struct stat :
|
||||
it includes everything from
|
||||
.Tn struct stat
|
||||
plus associated pathname, textual group and user names, etc.
|
||||
These objects are used by
|
||||
.Xr libarchive 3
|
||||
to represent the metadata associated with a particular
|
||||
entry in an archive.
|
||||
.Ss Create and Destroy
|
||||
There are functions to allocate, destroy, clear, and copy
|
||||
.Va archive_entry
|
||||
objects:
|
||||
.Bl -tag -compact -width indent
|
||||
.It Fn archive_entry_clear
|
||||
Erases the object, resetting all internal fields to the
|
||||
same state as a newly-created object.
|
||||
This is provided to allow you to quickly recycle objects
|
||||
without thrashing the heap.
|
||||
.It Fn archive_entry_clone
|
||||
A deep copy operation; all text fields are duplicated.
|
||||
.It Fn archive_entry_free
|
||||
Releases the
|
||||
.Tn struct archive_entry
|
||||
object.
|
||||
.It Fn archive_entry_new
|
||||
Allocate and return a blank
|
||||
.Tn struct archive_entry
|
||||
object.
|
||||
.El
|
||||
.Ss Function groups
|
||||
Due to high number of functions, the accessor functions can be found in
|
||||
man pages grouped by the purpose.
|
||||
.Bl -tag -width ".Xr archive_entry_perms 3"
|
||||
.It Xr archive_entry_acl 3
|
||||
Access Control List manipulation
|
||||
.It Xr archive_entry_paths 3
|
||||
Path name manipulation
|
||||
.It Xr archive_entry_perms 3
|
||||
User, group and mode manipulation
|
||||
.It Xr archive_entry_stat 3
|
||||
Functions not in the other groups and copying to/from
|
||||
.Vt struct stat .
|
||||
.It Xr archive_entry_time 3
|
||||
Time field manipulation
|
||||
.El
|
||||
.Pp
|
||||
Most of the functions set or read entries in an object.
|
||||
Such functions have one of the following forms:
|
||||
.Bl -tag -compact -width indent
|
||||
.It Fn archive_entry_set_XXXX
|
||||
Stores the provided data in the object.
|
||||
In particular, for strings, the pointer is stored,
|
||||
not the referenced string.
|
||||
.It Fn archive_entry_copy_XXXX
|
||||
As above, except that the referenced data is copied
|
||||
into the object.
|
||||
.It Fn archive_entry_XXXX
|
||||
Returns the specified data.
|
||||
In the case of strings, a const-qualified pointer to
|
||||
the string is returned.
|
||||
.El
|
||||
String data can be set or accessed as wide character strings
|
||||
or normal
|
||||
.Va char
|
||||
strings.
|
||||
The functions that use wide character strings are suffixed with
|
||||
.Cm _w .
|
||||
Note that these are different representations of the same data:
|
||||
For example, if you store a narrow string and read the corresponding
|
||||
wide string, the object will transparently convert formats
|
||||
using the current locale.
|
||||
Similarly, if you store a wide string and then store a
|
||||
narrow string for the same data, the previously-set wide string will
|
||||
be discarded in favor of the new data.
|
||||
.\" .Sh EXAMPLE
|
||||
.\" .Sh RETURN VALUES
|
||||
.\" .Sh ERRORS
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry_acl 3 ,
|
||||
.Xr archive_entry_paths 3 ,
|
||||
.Xr archive_entry_perms 3 ,
|
||||
.Xr archive_entry_time 3 ,
|
||||
.Xr libarchive 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm libarchive
|
||||
library first appeared in
|
||||
.Fx 5.3 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm libarchive
|
||||
library was written by
|
||||
.An Tim Kientzle Aq kientzle@acm.org .
|
||||
.\" .Sh BUGS
|
2066
dependencies/libarchive-3.4.2/libarchive/archive_entry.c
vendored
Normal file
2066
dependencies/libarchive-3.4.2/libarchive/archive_entry.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
708
dependencies/libarchive-3.4.2/libarchive/archive_entry.h
vendored
Normal file
708
dependencies/libarchive-3.4.2/libarchive/archive_entry.h
vendored
Normal file
|
@ -0,0 +1,708 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2008 Tim Kientzle
|
||||
* Copyright (c) 2016 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.
|
||||
*
|
||||
* $FreeBSD: head/lib/libarchive/archive_entry.h 201096 2009-12-28 02:41:27Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_ENTRY_H_INCLUDED
|
||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||
|
||||
/* Note: Compiler will complain if this does not match archive.h! */
|
||||
#define ARCHIVE_VERSION_NUMBER 3004002
|
||||
|
||||
/*
|
||||
* Note: archive_entry.h is for use outside of libarchive; the
|
||||
* configuration headers (config.h, archive_platform.h, etc.) are
|
||||
* purely internal. Do NOT use HAVE_XXX configuration macros to
|
||||
* control the behavior of this header! If you must conditionalize,
|
||||
* use predefined compiler and/or platform macros.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h> /* for wchar_t */
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/* Get a suitable 64-bit integer type. */
|
||||
#if !defined(__LA_INT64_T_DEFINED)
|
||||
# if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
#define __LA_INT64_T la_int64_t
|
||||
# endif
|
||||
#define __LA_INT64_T_DEFINED
|
||||
# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
|
||||
typedef __int64 la_int64_t;
|
||||
# else
|
||||
#include <unistd.h>
|
||||
# if defined(_SCO_DS) || defined(__osf__)
|
||||
typedef long long la_int64_t;
|
||||
# else
|
||||
typedef int64_t la_int64_t;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The la_ssize_t should match the type used in 'struct stat' */
|
||||
#if !defined(__LA_SSIZE_T_DEFINED)
|
||||
/* Older code relied on the __LA_SSIZE_T macro; after 4.0 we'll switch to the typedef exclusively. */
|
||||
# if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
#define __LA_SSIZE_T la_ssize_t
|
||||
# endif
|
||||
#define __LA_SSIZE_T_DEFINED
|
||||
# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
|
||||
# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
|
||||
typedef ssize_t la_ssize_t;
|
||||
# elif defined(_WIN64)
|
||||
typedef __int64 la_ssize_t;
|
||||
# else
|
||||
typedef long la_ssize_t;
|
||||
# endif
|
||||
# else
|
||||
# include <unistd.h> /* ssize_t */
|
||||
typedef ssize_t la_ssize_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Get a suitable definition for mode_t */
|
||||
#if ARCHIVE_VERSION_NUMBER >= 3999000
|
||||
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
|
||||
# define __LA_MODE_T int
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
|
||||
# define __LA_MODE_T unsigned short
|
||||
#else
|
||||
# define __LA_MODE_T mode_t
|
||||
#endif
|
||||
|
||||
/* Large file support for Android */
|
||||
#ifdef __ANDROID__
|
||||
#include "android_lf.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On Windows, define LIBARCHIVE_STATIC if you're building or using a
|
||||
* .lib. The default here assumes you're building a DLL. Only
|
||||
* libarchive source should ever define __LIBARCHIVE_BUILD.
|
||||
*/
|
||||
#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC)
|
||||
# ifdef __LIBARCHIVE_BUILD
|
||||
# ifdef __GNUC__
|
||||
# define __LA_DECL __attribute__((dllexport)) extern
|
||||
# else
|
||||
# define __LA_DECL __declspec(dllexport)
|
||||
# endif
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
# define __LA_DECL
|
||||
# else
|
||||
# define __LA_DECL __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
/* Static libraries on all platforms and shared libraries on non-Windows. */
|
||||
# define __LA_DECL
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ >= 1
|
||||
# define __LA_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
# define __LA_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Description of an archive entry.
|
||||
*
|
||||
* You can think of this as "struct stat" with some text fields added in.
|
||||
*
|
||||
* TODO: Add "comment", "charset", and possibly other entries that are
|
||||
* supported by "pax interchange" format. However, GNU, ustar, cpio,
|
||||
* and other variants don't support these features, so they're not an
|
||||
* excruciatingly high priority right now.
|
||||
*
|
||||
* TODO: "pax interchange" format allows essentially arbitrary
|
||||
* key/value attributes to be attached to any entry. Supporting
|
||||
* such extensions may make this library useful for special
|
||||
* applications (e.g., a package manager could attach special
|
||||
* package-management attributes to each entry).
|
||||
*/
|
||||
struct archive;
|
||||
struct archive_entry;
|
||||
|
||||
/*
|
||||
* File-type constants. These are returned from archive_entry_filetype()
|
||||
* and passed to archive_entry_set_filetype().
|
||||
*
|
||||
* These values match S_XXX defines on every platform I've checked,
|
||||
* including Windows, AIX, Linux, Solaris, and BSD. They're
|
||||
* (re)defined here because platforms generally don't define the ones
|
||||
* they don't support. For example, Windows doesn't define S_IFLNK or
|
||||
* S_IFBLK. Instead of having a mass of conditional logic and system
|
||||
* checks to define any S_XXX values that aren't supported locally,
|
||||
* I've just defined a new set of such constants so that
|
||||
* libarchive-based applications can manipulate and identify archive
|
||||
* entries properly even if the hosting platform can't store them on
|
||||
* disk.
|
||||
*
|
||||
* These values are also used directly within some portable formats,
|
||||
* such as cpio. If you find a platform that varies from these, the
|
||||
* correct solution is to leave these alone and translate from these
|
||||
* portable values to platform-native values when entries are read from
|
||||
* or written to disk.
|
||||
*/
|
||||
/*
|
||||
* In libarchive 4.0, we can drop the casts here.
|
||||
* They're needed to work around Borland C's broken mode_t.
|
||||
*/
|
||||
#define AE_IFMT ((__LA_MODE_T)0170000)
|
||||
#define AE_IFREG ((__LA_MODE_T)0100000)
|
||||
#define AE_IFLNK ((__LA_MODE_T)0120000)
|
||||
#define AE_IFSOCK ((__LA_MODE_T)0140000)
|
||||
#define AE_IFCHR ((__LA_MODE_T)0020000)
|
||||
#define AE_IFBLK ((__LA_MODE_T)0060000)
|
||||
#define AE_IFDIR ((__LA_MODE_T)0040000)
|
||||
#define AE_IFIFO ((__LA_MODE_T)0010000)
|
||||
|
||||
/*
|
||||
* Symlink types
|
||||
*/
|
||||
#define AE_SYMLINK_TYPE_UNDEFINED 0
|
||||
#define AE_SYMLINK_TYPE_FILE 1
|
||||
#define AE_SYMLINK_TYPE_DIRECTORY 2
|
||||
|
||||
/*
|
||||
* Basic object manipulation
|
||||
*/
|
||||
|
||||
__LA_DECL struct archive_entry *archive_entry_clear(struct archive_entry *);
|
||||
/* The 'clone' function does a deep copy; all of the strings are copied too. */
|
||||
__LA_DECL struct archive_entry *archive_entry_clone(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_free(struct archive_entry *);
|
||||
__LA_DECL struct archive_entry *archive_entry_new(void);
|
||||
|
||||
/*
|
||||
* This form of archive_entry_new2() will pull character-set
|
||||
* conversion information from the specified archive handle. The
|
||||
* older archive_entry_new(void) form is equivalent to calling
|
||||
* archive_entry_new2(NULL) and will result in the use of an internal
|
||||
* default character-set conversion.
|
||||
*/
|
||||
__LA_DECL struct archive_entry *archive_entry_new2(struct archive *);
|
||||
|
||||
/*
|
||||
* Retrieve fields from an archive_entry.
|
||||
*
|
||||
* There are a number of implicit conversions among these fields. For
|
||||
* example, if a regular string field is set and you read the _w wide
|
||||
* character field, the entry will implicitly convert narrow-to-wide
|
||||
* using the current locale. Similarly, dev values are automatically
|
||||
* updated when you write devmajor or devminor and vice versa.
|
||||
*
|
||||
* In addition, fields can be "set" or "unset." Unset string fields
|
||||
* return NULL, non-string fields have _is_set() functions to test
|
||||
* whether they've been set. You can "unset" a string field by
|
||||
* assigning NULL; non-string fields have _unset() functions to
|
||||
* unset them.
|
||||
*
|
||||
* Note: There is one ambiguity in the above; string fields will
|
||||
* also return NULL when implicit character set conversions fail.
|
||||
* This is usually what you want.
|
||||
*/
|
||||
__LA_DECL time_t archive_entry_atime(struct archive_entry *);
|
||||
__LA_DECL long archive_entry_atime_nsec(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_atime_is_set(struct archive_entry *);
|
||||
__LA_DECL time_t archive_entry_birthtime(struct archive_entry *);
|
||||
__LA_DECL long archive_entry_birthtime_nsec(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_birthtime_is_set(struct archive_entry *);
|
||||
__LA_DECL time_t archive_entry_ctime(struct archive_entry *);
|
||||
__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_ctime_is_set(struct archive_entry *);
|
||||
__LA_DECL dev_t archive_entry_dev(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_dev_is_set(struct archive_entry *);
|
||||
__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *);
|
||||
__LA_DECL dev_t archive_entry_devminor(struct archive_entry *);
|
||||
__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_fflags(struct archive_entry *,
|
||||
unsigned long * /* set */,
|
||||
unsigned long * /* clear */);
|
||||
__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
|
||||
__LA_DECL la_int64_t archive_entry_gid(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_gname_utf8(struct archive_entry *);
|
||||
__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_hardlink_utf8(struct archive_entry *);
|
||||
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
|
||||
__LA_DECL la_int64_t archive_entry_ino(struct archive_entry *);
|
||||
__LA_DECL la_int64_t archive_entry_ino64(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
|
||||
__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *);
|
||||
__LA_DECL time_t archive_entry_mtime(struct archive_entry *);
|
||||
__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_mtime_is_set(struct archive_entry *);
|
||||
__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_pathname(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_pathname_utf8(struct archive_entry *);
|
||||
__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
|
||||
__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
|
||||
__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
|
||||
__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
|
||||
__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *);
|
||||
__LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
|
||||
__LA_DECL la_int64_t archive_entry_size(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_symlink_type(struct archive_entry *);
|
||||
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
|
||||
__LA_DECL la_int64_t archive_entry_uid(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
|
||||
__LA_DECL const char *archive_entry_uname_utf8(struct archive_entry *);
|
||||
__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_is_data_encrypted(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_is_metadata_encrypted(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_is_encrypted(struct archive_entry *);
|
||||
|
||||
/*
|
||||
* Set fields in an archive_entry.
|
||||
*
|
||||
* Note: Before libarchive 2.4, there were 'set' and 'copy' versions
|
||||
* of the string setters. 'copy' copied the actual string, 'set' just
|
||||
* stored the pointer. In libarchive 2.4 and later, strings are
|
||||
* always copied.
|
||||
*/
|
||||
|
||||
__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
|
||||
__LA_DECL void archive_entry_unset_atime(struct archive_entry *);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *);
|
||||
#endif
|
||||
__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
|
||||
__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long);
|
||||
__LA_DECL void archive_entry_unset_ctime(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_set_dev(struct archive_entry *, dev_t);
|
||||
__LA_DECL void archive_entry_set_devmajor(struct archive_entry *, dev_t);
|
||||
__LA_DECL void archive_entry_set_devminor(struct archive_entry *, dev_t);
|
||||
__LA_DECL void archive_entry_set_filetype(struct archive_entry *, unsigned int);
|
||||
__LA_DECL void archive_entry_set_fflags(struct archive_entry *,
|
||||
unsigned long /* set */, unsigned long /* clear */);
|
||||
/* Returns pointer to start of first invalid token, or NULL if none. */
|
||||
/* Note that all recognized tokens are processed, regardless. */
|
||||
__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
|
||||
const char *);
|
||||
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
|
||||
const wchar_t *);
|
||||
__LA_DECL void archive_entry_set_gid(struct archive_entry *, la_int64_t);
|
||||
__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_gname_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
|
||||
__LA_DECL int archive_entry_update_gname_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_hardlink_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
|
||||
__LA_DECL int archive_entry_update_hardlink_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_ino(struct archive_entry *, la_int64_t);
|
||||
__LA_DECL void archive_entry_set_ino64(struct archive_entry *, la_int64_t);
|
||||
__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_link_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *);
|
||||
__LA_DECL int archive_entry_update_link_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_mode(struct archive_entry *, __LA_MODE_T);
|
||||
__LA_DECL void archive_entry_set_mtime(struct archive_entry *, time_t, long);
|
||||
__LA_DECL void archive_entry_unset_mtime(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_set_nlink(struct archive_entry *, unsigned int);
|
||||
__LA_DECL void archive_entry_set_pathname(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_pathname_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_pathname(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
|
||||
__LA_DECL int archive_entry_update_pathname_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T);
|
||||
__LA_DECL void archive_entry_set_rdev(struct archive_entry *, dev_t);
|
||||
__LA_DECL void archive_entry_set_rdevmajor(struct archive_entry *, dev_t);
|
||||
__LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
|
||||
__LA_DECL void archive_entry_set_size(struct archive_entry *, la_int64_t);
|
||||
__LA_DECL void archive_entry_unset_size(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
|
||||
__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_symlink_type(struct archive_entry *, int);
|
||||
__LA_DECL void archive_entry_set_symlink_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
|
||||
__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_uid(struct archive_entry *, la_int64_t);
|
||||
__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_uname_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
|
||||
__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *);
|
||||
__LA_DECL void archive_entry_set_is_data_encrypted(struct archive_entry *, char is_encrypted);
|
||||
__LA_DECL void archive_entry_set_is_metadata_encrypted(struct archive_entry *, char is_encrypted);
|
||||
/*
|
||||
* Routines to bulk copy fields to/from a platform-native "struct
|
||||
* stat." Libarchive used to just store a struct stat inside of each
|
||||
* archive_entry object, but this created issues when trying to
|
||||
* manipulate archives on systems different than the ones they were
|
||||
* created on.
|
||||
*
|
||||
* TODO: On Linux and other LFS systems, provide both stat32 and
|
||||
* stat64 versions of these functions and all of the macro glue so
|
||||
* that archive_entry_stat is magically defined to
|
||||
* archive_entry_stat32 or archive_entry_stat64 as appropriate.
|
||||
*/
|
||||
__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
|
||||
|
||||
/*
|
||||
* Storage for Mac OS-specific AppleDouble metadata information.
|
||||
* Apple-format tar files store a separate binary blob containing
|
||||
* encoded metadata with ACL, extended attributes, etc.
|
||||
* This provides a place to store that blob.
|
||||
*/
|
||||
|
||||
__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *);
|
||||
__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
|
||||
|
||||
/*
|
||||
* ACL routines. This used to simply store and return text-format ACL
|
||||
* strings, but that proved insufficient for a number of reasons:
|
||||
* = clients need control over uname/uid and gname/gid mappings
|
||||
* = there are many different ACL text formats
|
||||
* = would like to be able to read/convert archives containing ACLs
|
||||
* on platforms that lack ACL libraries
|
||||
*
|
||||
* This last point, in particular, forces me to implement a reasonably
|
||||
* complete set of ACL support routines.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Permission bits.
|
||||
*/
|
||||
#define ARCHIVE_ENTRY_ACL_EXECUTE 0x00000001
|
||||
#define ARCHIVE_ENTRY_ACL_WRITE 0x00000002
|
||||
#define ARCHIVE_ENTRY_ACL_READ 0x00000004
|
||||
#define ARCHIVE_ENTRY_ACL_READ_DATA 0x00000008
|
||||
#define ARCHIVE_ENTRY_ACL_LIST_DIRECTORY 0x00000008
|
||||
#define ARCHIVE_ENTRY_ACL_WRITE_DATA 0x00000010
|
||||
#define ARCHIVE_ENTRY_ACL_ADD_FILE 0x00000010
|
||||
#define ARCHIVE_ENTRY_ACL_APPEND_DATA 0x00000020
|
||||
#define ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY 0x00000020
|
||||
#define ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS 0x00000040
|
||||
#define ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS 0x00000080
|
||||
#define ARCHIVE_ENTRY_ACL_DELETE_CHILD 0x00000100
|
||||
#define ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES 0x00000200
|
||||
#define ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES 0x00000400
|
||||
#define ARCHIVE_ENTRY_ACL_DELETE 0x00000800
|
||||
#define ARCHIVE_ENTRY_ACL_READ_ACL 0x00001000
|
||||
#define ARCHIVE_ENTRY_ACL_WRITE_ACL 0x00002000
|
||||
#define ARCHIVE_ENTRY_ACL_WRITE_OWNER 0x00004000
|
||||
#define ARCHIVE_ENTRY_ACL_SYNCHRONIZE 0x00008000
|
||||
|
||||
#define ARCHIVE_ENTRY_ACL_PERMS_POSIX1E \
|
||||
(ARCHIVE_ENTRY_ACL_EXECUTE \
|
||||
| ARCHIVE_ENTRY_ACL_WRITE \
|
||||
| ARCHIVE_ENTRY_ACL_READ)
|
||||
|
||||
#define ARCHIVE_ENTRY_ACL_PERMS_NFS4 \
|
||||
(ARCHIVE_ENTRY_ACL_EXECUTE \
|
||||
| ARCHIVE_ENTRY_ACL_READ_DATA \
|
||||
| ARCHIVE_ENTRY_ACL_LIST_DIRECTORY \
|
||||
| ARCHIVE_ENTRY_ACL_WRITE_DATA \
|
||||
| ARCHIVE_ENTRY_ACL_ADD_FILE \
|
||||
| ARCHIVE_ENTRY_ACL_APPEND_DATA \
|
||||
| ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY \
|
||||
| ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS \
|
||||
| ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS \
|
||||
| ARCHIVE_ENTRY_ACL_DELETE_CHILD \
|
||||
| ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES \
|
||||
| ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES \
|
||||
| ARCHIVE_ENTRY_ACL_DELETE \
|
||||
| ARCHIVE_ENTRY_ACL_READ_ACL \
|
||||
| ARCHIVE_ENTRY_ACL_WRITE_ACL \
|
||||
| ARCHIVE_ENTRY_ACL_WRITE_OWNER \
|
||||
| ARCHIVE_ENTRY_ACL_SYNCHRONIZE)
|
||||
|
||||
/*
|
||||
* Inheritance values (NFS4 ACLs only); included in permset.
|
||||
*/
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_INHERITED 0x01000000
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000
|
||||
|
||||
#define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \
|
||||
(ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT \
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS \
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_INHERITED)
|
||||
|
||||
/* We need to be able to specify combinations of these. */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 0x00000100 /* POSIX.1e only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 0x00000200 /* POSIX.1e only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 0x00000400 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_DENY 0x00000800 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 0x00001000 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 0x00002000 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \
|
||||
| ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \
|
||||
| ARCHIVE_ENTRY_ACL_TYPE_DENY \
|
||||
| ARCHIVE_ENTRY_ACL_TYPE_AUDIT \
|
||||
| ARCHIVE_ENTRY_ACL_TYPE_ALARM)
|
||||
|
||||
/* Tag values mimic POSIX.1e */
|
||||
#define ARCHIVE_ENTRY_ACL_USER 10001 /* Specified user. */
|
||||
#define ARCHIVE_ENTRY_ACL_USER_OBJ 10002 /* User who owns the file. */
|
||||
#define ARCHIVE_ENTRY_ACL_GROUP 10003 /* Specified group. */
|
||||
#define ARCHIVE_ENTRY_ACL_GROUP_OBJ 10004 /* Group who owns the file. */
|
||||
#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access (POSIX.1e only) */
|
||||
#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public (POSIX.1e only) */
|
||||
#define ARCHIVE_ENTRY_ACL_EVERYONE 10107 /* Everyone (NFS4 only) */
|
||||
|
||||
/*
|
||||
* Set the ACL by clearing it and adding entries one at a time.
|
||||
* Unlike the POSIX.1e ACL routines, you must specify the type
|
||||
* (access/default) for each entry. Internally, the ACL data is just
|
||||
* a soup of entries. API calls here allow you to retrieve just the
|
||||
* entries of interest. This design (which goes against the spirit of
|
||||
* POSIX.1e) is useful for handling archive formats that combine
|
||||
* default and access information in a single ACL list.
|
||||
*/
|
||||
__LA_DECL void archive_entry_acl_clear(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_acl_add_entry(struct archive_entry *,
|
||||
int /* type */, int /* permset */, int /* tag */,
|
||||
int /* qual */, const char * /* name */);
|
||||
__LA_DECL int archive_entry_acl_add_entry_w(struct archive_entry *,
|
||||
int /* type */, int /* permset */, int /* tag */,
|
||||
int /* qual */, const wchar_t * /* name */);
|
||||
|
||||
/*
|
||||
* To retrieve the ACL, first "reset", then repeatedly ask for the
|
||||
* "next" entry. The want_type parameter allows you to request only
|
||||
* certain types of entries.
|
||||
*/
|
||||
__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */);
|
||||
__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
|
||||
int * /* type */, int * /* permset */, int * /* tag */,
|
||||
int * /* qual */, const char ** /* name */);
|
||||
|
||||
/*
|
||||
* Construct a text-format ACL. The flags argument is a bitmask that
|
||||
* can include any of the following:
|
||||
*
|
||||
* Flags only for archive entries with POSIX.1e ACL:
|
||||
* ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries.
|
||||
* ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries.
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each
|
||||
* default ACL entry.
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_SOLARIS - Output only one colon after "other" and
|
||||
* "mask" entries.
|
||||
*
|
||||
* Flags only for archive entries with NFSv4 ACL:
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_COMPACT - Do not output the minus character for
|
||||
* unset permissions and flags in NFSv4 ACL permission and flag fields
|
||||
*
|
||||
* Flags for for archive entries with POSIX.1e ACL or NFSv4 ACL:
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
|
||||
* each ACL entry.
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA - Separate entries with comma
|
||||
* instead of newline.
|
||||
*/
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 0x00000001
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 0x00000002
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_SOLARIS 0x00000004
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA 0x00000008
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_COMPACT 0x00000010
|
||||
|
||||
__LA_DECL wchar_t *archive_entry_acl_to_text_w(struct archive_entry *,
|
||||
la_ssize_t * /* len */, int /* flags */);
|
||||
__LA_DECL char *archive_entry_acl_to_text(struct archive_entry *,
|
||||
la_ssize_t * /* len */, int /* flags */);
|
||||
__LA_DECL int archive_entry_acl_from_text_w(struct archive_entry *,
|
||||
const wchar_t * /* wtext */, int /* type */);
|
||||
__LA_DECL int archive_entry_acl_from_text(struct archive_entry *,
|
||||
const char * /* text */, int /* type */);
|
||||
|
||||
/* Deprecated constants */
|
||||
#define OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
|
||||
#define OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
|
||||
|
||||
/* Deprecated functions */
|
||||
__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
|
||||
int /* flags */) __LA_DEPRECATED;
|
||||
__LA_DECL const char *archive_entry_acl_text(struct archive_entry *,
|
||||
int /* flags */) __LA_DEPRECATED;
|
||||
|
||||
/* Return bitmask of ACL types in an archive entry */
|
||||
__LA_DECL int archive_entry_acl_types(struct archive_entry *);
|
||||
|
||||
/* Return a count of entries matching 'want_type' */
|
||||
__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
|
||||
|
||||
/* Return an opaque ACL object. */
|
||||
/* There's not yet anything clients can actually do with this... */
|
||||
struct archive_acl;
|
||||
__LA_DECL struct archive_acl *archive_entry_acl(struct archive_entry *);
|
||||
|
||||
/*
|
||||
* extended attributes
|
||||
*/
|
||||
|
||||
__LA_DECL void archive_entry_xattr_clear(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_xattr_add_entry(struct archive_entry *,
|
||||
const char * /* name */, const void * /* value */,
|
||||
size_t /* size */);
|
||||
|
||||
/*
|
||||
* To retrieve the xattr list, first "reset", then repeatedly ask for the
|
||||
* "next" entry.
|
||||
*/
|
||||
|
||||
__LA_DECL int archive_entry_xattr_count(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_xattr_reset(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_xattr_next(struct archive_entry *,
|
||||
const char ** /* name */, const void ** /* value */, size_t *);
|
||||
|
||||
/*
|
||||
* sparse
|
||||
*/
|
||||
|
||||
__LA_DECL void archive_entry_sparse_clear(struct archive_entry *);
|
||||
__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
|
||||
la_int64_t /* offset */, la_int64_t /* length */);
|
||||
|
||||
/*
|
||||
* To retrieve the xattr list, first "reset", then repeatedly ask for the
|
||||
* "next" entry.
|
||||
*/
|
||||
|
||||
__LA_DECL int archive_entry_sparse_count(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_sparse_reset(struct archive_entry *);
|
||||
__LA_DECL int archive_entry_sparse_next(struct archive_entry *,
|
||||
la_int64_t * /* offset */, la_int64_t * /* length */);
|
||||
|
||||
/*
|
||||
* Utility to match up hardlinks.
|
||||
*
|
||||
* The 'struct archive_entry_linkresolver' is a cache of archive entries
|
||||
* for files with multiple links. Here's how to use it:
|
||||
* 1. Create a lookup object with archive_entry_linkresolver_new()
|
||||
* 2. Tell it the archive format you're using.
|
||||
* 3. Hand each archive_entry to archive_entry_linkify().
|
||||
* That function will return 0, 1, or 2 entries that should
|
||||
* be written.
|
||||
* 4. Call archive_entry_linkify(resolver, NULL) until
|
||||
* no more entries are returned.
|
||||
* 5. Call archive_entry_linkresolver_free(resolver) to free resources.
|
||||
*
|
||||
* The entries returned have their hardlink and size fields updated
|
||||
* appropriately. If an entry is passed in that does not refer to
|
||||
* a file with multiple links, it is returned unchanged. The intention
|
||||
* is that you should be able to simply filter all entries through
|
||||
* this machine.
|
||||
*
|
||||
* To make things more efficient, be sure that each entry has a valid
|
||||
* nlinks value. The hardlink cache uses this to track when all links
|
||||
* have been found. If the nlinks value is zero, it will keep every
|
||||
* name in the cache indefinitely, which can use a lot of memory.
|
||||
*
|
||||
* Note that archive_entry_size() is reset to zero if the file
|
||||
* body should not be written to the archive. Pay attention!
|
||||
*/
|
||||
struct archive_entry_linkresolver;
|
||||
|
||||
/*
|
||||
* There are three different strategies for marking hardlinks.
|
||||
* The descriptions below name them after the best-known
|
||||
* formats that rely on each strategy:
|
||||
*
|
||||
* "Old cpio" is the simplest, it always returns any entry unmodified.
|
||||
* As far as I know, only cpio formats use this. Old cpio archives
|
||||
* store every link with the full body; the onus is on the dearchiver
|
||||
* to detect and properly link the files as they are restored.
|
||||
* "tar" is also pretty simple; it caches a copy the first time it sees
|
||||
* any link. Subsequent appearances are modified to be hardlink
|
||||
* references to the first one without any body. Used by all tar
|
||||
* formats, although the newest tar formats permit the "old cpio" strategy
|
||||
* as well. This strategy is very simple for the dearchiver,
|
||||
* and reasonably straightforward for the archiver.
|
||||
* "new cpio" is trickier. It stores the body only with the last
|
||||
* occurrence. The complication is that we might not
|
||||
* see every link to a particular file in a single session, so
|
||||
* there's no easy way to know when we've seen the last occurrence.
|
||||
* The solution here is to queue one link until we see the next.
|
||||
* At the end of the session, you can enumerate any remaining
|
||||
* entries by calling archive_entry_linkify(NULL) and store those
|
||||
* bodies. If you have a file with three links l1, l2, and l3,
|
||||
* you'll get the following behavior if you see all three links:
|
||||
* linkify(l1) => NULL (the resolver stores l1 internally)
|
||||
* linkify(l2) => l1 (resolver stores l2, you write l1)
|
||||
* linkify(l3) => l2, l3 (all links seen, you can write both).
|
||||
* If you only see l1 and l2, you'll get this behavior:
|
||||
* linkify(l1) => NULL
|
||||
* linkify(l2) => l1
|
||||
* linkify(NULL) => l2 (at end, you retrieve remaining links)
|
||||
* As the name suggests, this strategy is used by newer cpio variants.
|
||||
* It's noticeably more complex for the archiver, slightly more complex
|
||||
* for the dearchiver than the tar strategy, but makes it straightforward
|
||||
* to restore a file using any link by simply continuing to scan until
|
||||
* you see a link that is stored with a body. In contrast, the tar
|
||||
* strategy requires you to rescan the archive from the beginning to
|
||||
* correctly extract an arbitrary link.
|
||||
*/
|
||||
|
||||
__LA_DECL struct archive_entry_linkresolver *archive_entry_linkresolver_new(void);
|
||||
__LA_DECL void archive_entry_linkresolver_set_strategy(
|
||||
struct archive_entry_linkresolver *, int /* format_code */);
|
||||
__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *);
|
||||
__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
|
||||
struct archive_entry **, struct archive_entry **);
|
||||
__LA_DECL struct archive_entry *archive_entry_partial_links(
|
||||
struct archive_entry_linkresolver *res, unsigned int *links);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This is meaningless outside of this header. */
|
||||
#undef __LA_DECL
|
||||
|
||||
#endif /* !ARCHIVE_ENTRY_H_INCLUDED */
|
458
dependencies/libarchive-3.4.2/libarchive/archive_entry_acl.3
vendored
Normal file
458
dependencies/libarchive-3.4.2/libarchive/archive_entry_acl.3
vendored
Normal file
|
@ -0,0 +1,458 @@
|
|||
.\" Copyright (c) 2010 Joerg Sonnenberger
|
||||
.\" Copyright (c) 2016 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 AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 15, 2017
|
||||
.Dt ARCHIVE_ENTRY_ACL 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_entry_acl_add_entry ,
|
||||
.Nm archive_entry_acl_add_entry_w ,
|
||||
.Nm archive_entry_acl_clear ,
|
||||
.Nm archive_entry_acl_count ,
|
||||
.Nm archive_entry_acl_from_text ,
|
||||
.Nm archive_entry_acl_from_text_w ,
|
||||
.Nm archive_entry_acl_next ,
|
||||
.Nm archive_entry_acl_reset ,
|
||||
.Nm archive_entry_acl_to_text ,
|
||||
.Nm archive_entry_acl_to_text_w ,
|
||||
.Nm archive_entry_acl_types
|
||||
.Nd functions for manipulating Access Control Lists in archive entry descriptions
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive_entry.h
|
||||
.Ft void
|
||||
.Fo archive_entry_acl_add_entry
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "int type"
|
||||
.Fa "int permset"
|
||||
.Fa "int tag"
|
||||
.Fa "int qualifier"
|
||||
.Fa "const char *name"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo archive_entry_acl_add_entry_w
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "int type"
|
||||
.Fa "int permset"
|
||||
.Fa "int tag"
|
||||
.Fa "int qualifier"
|
||||
.Fa "const wchar_t *name"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn archive_entry_acl_clear "struct archive_entry *a"
|
||||
.Ft int
|
||||
.Fn archive_entry_acl_count "struct archive_entry *a" "int type"
|
||||
.Ft int
|
||||
.Fo archive_entry_acl_from_text
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "const char *text"
|
||||
.Fa "int type"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_entry_acl_from_text_w
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "const wchar_t *text"
|
||||
.Fa "int type"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_entry_acl_next
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "int type"
|
||||
.Fa "int *ret_type"
|
||||
.Fa "int *ret_permset"
|
||||
.Fa "int *ret_tag"
|
||||
.Fa "int *ret_qual"
|
||||
.Fa "const char **ret_name"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_entry_acl_reset "struct archive_entry *a" "int type"
|
||||
.Ft char *
|
||||
.Fo archive_entry_acl_to_text
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "ssize_t *len_p"
|
||||
.Fa "int flags"
|
||||
.Fc
|
||||
.Ft wchar_t *
|
||||
.Fo archive_entry_acl_to_text_w
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "ssize_t *len_p"
|
||||
.Fa "int flags"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_entry_acl_types "struct archive_entry *a"
|
||||
.\" enum?
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Dq Access Control Lists (ACLs)
|
||||
extend the standard Unix permission model.
|
||||
The ACL interface of
|
||||
.Nm libarchive
|
||||
supports both POSIX.1e and NFSv4 style ACLs.
|
||||
Use of ACLs is restricted by
|
||||
various levels of ACL support in operating systems, file systems and archive
|
||||
formats.
|
||||
.Ss POSIX.1e Access Control Lists
|
||||
A POSIX.1e ACL consists of a number of independent entries.
|
||||
Each entry specifies the permission set as a bitmask of basic permissions.
|
||||
Valid permissions in the
|
||||
.Fa permset
|
||||
are:
|
||||
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_EXECUTE"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ ( Sy r )
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE ( Sy w )
|
||||
.It Dv ARCHIVE_ENTRY_ACL_EXECUTE ( Sy x )
|
||||
.El
|
||||
The permissions correspond to the normal Unix permissions.
|
||||
.Pp
|
||||
The
|
||||
.Fa tag
|
||||
specifies the principal to which the permission applies.
|
||||
Valid values are:
|
||||
.Bl -hang -offset indent -compact -width "ARCHIVE_ENTRY_ACL_GROUP_OBJ"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_USER
|
||||
The user specified by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
|
||||
The owner of the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_GROUP
|
||||
The group specified by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
|
||||
The group which owns the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_MASK
|
||||
The maximum permissions to be obtained via group permissions.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_OTHER
|
||||
Any principal who is not the file owner or a member of the owning group.
|
||||
.El
|
||||
.Pp
|
||||
The principals
|
||||
.Dv ARCHIVE_ENTRY_ACL_USER_OBJ ,
|
||||
.Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
|
||||
and
|
||||
.Dv ARCHIVE_ENTRY_ACL_OTHER
|
||||
are equivalent to user, group and other in the classic Unix permission
|
||||
model and specify non-extended ACL entries.
|
||||
.Pp
|
||||
All files have an access ACL
|
||||
.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS .
|
||||
This specifies the permissions required for access to the file itself.
|
||||
Directories have an additional ACL
|
||||
.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT ,
|
||||
which controls the initial access ACL for newly-created directory entries.
|
||||
.Ss NFSv4 Access Control Lists
|
||||
A NFSv4 ACL consists of multiple individual entries called Access Control
|
||||
Entries (ACEs).
|
||||
.Pp
|
||||
There are four possible types of a NFSv4 ACE:
|
||||
.Bl -hang -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYE_ALLOW"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALLOW
|
||||
Allow principal to perform actions requiring given permissions.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_DENY
|
||||
Prevent principal from performing actions requiring given permissions.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_AUDIT
|
||||
Log access attempts by principal which require given permissions.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALARM
|
||||
Trigger a system alarm on access attempts by principal which require given
|
||||
permissions.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fa tag
|
||||
specifies the principal to which the permission applies.
|
||||
Valid values are:
|
||||
.Bl -hang -offset indent -compact -width "ARCHIVE_ENTRY_ACL_GROUP_OBJ"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_USER
|
||||
The user specified by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
|
||||
The owner of the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_GROUP
|
||||
The group specified by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
|
||||
The group which owns the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_EVERYONE
|
||||
Any principal who is not the file owner or a member of the owning group.
|
||||
.El
|
||||
.Pp
|
||||
Entries with the
|
||||
.Dv ARCHIVE_ENTRY_ACL_USER
|
||||
or
|
||||
.Dv ARCHIVE_ENTRY_ACL_GROUP
|
||||
tag store the user and group name in the
|
||||
.Fa name
|
||||
string and optionally the user or group ID in the
|
||||
.Fa qualifier
|
||||
integer.
|
||||
.Pp
|
||||
NFSv4 ACE permissions and flags are stored in the same
|
||||
.Fa permset
|
||||
bitfield.
|
||||
Some permissions share the same constant and permission character
|
||||
but have different effect on directories than on files.
|
||||
The following ACE permissions are supported:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ_DATA ( Sy r )
|
||||
Read data (file).
|
||||
.It Dv ARCHIVE_ENTRY_ACL_LIST_DIRECTORY ( Sy r )
|
||||
List entries (directory).
|
||||
.It ARCHIVE_ENTRY_ACL_WRITE_DATA ( Sy w )
|
||||
Write data (file).
|
||||
.It ARCHIVE_ENTRY_ACL_ADD_FILE ( Sy w )
|
||||
Create files (directory).
|
||||
.It Dv ARCHIVE_ENTRY_ACL_EXECUTE ( Sy x )
|
||||
Execute file or change into a directory.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_APPEND_DATA ( Sy p )
|
||||
Append data (file).
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY ( Sy p )
|
||||
Create subdirectories (directory).
|
||||
.It Dv ARCHIVE_ENTRY_ACL_DELETE_CHILD ( Sy D )
|
||||
Remove files and subdirectories inside a directory.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_DELETE ( Sy d )
|
||||
Remove file or directory.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES ( Sy a )
|
||||
Read file or directory attributes.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES ( Sy A )
|
||||
Write file or directory attributes.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS ( Sy R )
|
||||
Read named file or directory attributes.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS ( Sy W )
|
||||
Write named file or directory attributes.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ_ACL ( Sy c )
|
||||
Read file or directory ACL.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE_ACL ( Sy C )
|
||||
Write file or directory ACL.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE_OWNER ( Sy o )
|
||||
Change owner of a file or directory.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_SYNCHRONIZE ( Sy s )
|
||||
Use synchronous I/O.
|
||||
.El
|
||||
.Pp
|
||||
The following NFSv4 ACL inheritance flags are supported:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT ( Sy f )
|
||||
Inherit parent directory ACE to files.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT ( Sy d )
|
||||
Inherit parent directory ACE to subdirectories.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY ( Sy i )
|
||||
Only inherit, do not apply the permission on the directory itself.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT ( Sy n )
|
||||
Do not propagate inherit flags.
|
||||
Only first-level entries inherit ACLs.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS ( Sy S )
|
||||
Trigger alarm or audit on successful access.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS ( Sy F )
|
||||
Trigger alarm or audit on failed access.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERITED ( Sy I )
|
||||
Mark that ACE was inherited.
|
||||
.El
|
||||
.Ss Functions
|
||||
.Fn archive_entry_acl_add_entry
|
||||
and
|
||||
.Fn archive_entry_acl_add_entry_w
|
||||
add a single ACL entry.
|
||||
For the access ACL and non-extended principals, the classic Unix permissions
|
||||
are updated.
|
||||
An archive entry cannot contain both POSIX.1e and NFSv4 ACL entries.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_clear
|
||||
removes all ACL entries and resets the enumeration pointer.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_count
|
||||
counts the ACL entries that have the given type mask.
|
||||
.Fa type
|
||||
can be the bitwise-or of
|
||||
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_DEFAULT"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
.El
|
||||
for POSIX.1e ACLs and
|
||||
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_ALLOW"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALLOW
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_DENY
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_AUDIT
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALARM
|
||||
.El
|
||||
for NFSv4 ACLs.
|
||||
For POSIX.1e ACLs if
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
is included and at least one extended ACL entry is found,
|
||||
the three non-extended ACLs are added.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_from_text
|
||||
and
|
||||
.Fn archive_entry_acl_from_text_w
|
||||
add new
|
||||
.Pq or merge with existing
|
||||
ACL entries from
|
||||
.Pq wide
|
||||
text.
|
||||
The argument
|
||||
.Fa type
|
||||
may take one of the following values:
|
||||
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_DEFAULT"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_NFS4
|
||||
.El
|
||||
Supports all formats that can be created with
|
||||
.Fn archive_entry_acl_to_text
|
||||
or respectively
|
||||
.Fn archive_entry_acl_to_text_w .
|
||||
Existing ACL entries are preserved.
|
||||
To get a clean new ACL from text
|
||||
.Fn archive_entry_acl_clear
|
||||
must be called first.
|
||||
Entries prefixed with
|
||||
.Dq default:
|
||||
are treated as
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
unless
|
||||
.Fa type
|
||||
is
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_NFS4 .
|
||||
Invalid entries, non-parseable ACL entries and entries beginning with
|
||||
the
|
||||
.Sq #
|
||||
character
|
||||
.Pq comments
|
||||
are skipped.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_next
|
||||
return the next entry of the ACL list.
|
||||
This functions may only be called after
|
||||
.Fn archive_entry_acl_reset
|
||||
has indicated the presence of extended ACL entries.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_reset
|
||||
prepare reading the list of ACL entries with
|
||||
.Fn archive_entry_acl_next .
|
||||
The function returns 0 if no non-extended ACLs are found.
|
||||
In this case, the access permissions should be obtained by
|
||||
.Xr archive_entry_mode 3
|
||||
or set using
|
||||
.Xr chmod 2 .
|
||||
Otherwise, the function returns the same value as
|
||||
.Fn archive_entry_acl_count .
|
||||
.Pp
|
||||
.Fn archive_entry_acl_to_text
|
||||
and
|
||||
.Fn archive_entry_acl_to_text_w
|
||||
convert the ACL entries for the given type into a
|
||||
.Pq wide
|
||||
string of ACL entries separated by newline.
|
||||
If the pointer
|
||||
.Fa len_p
|
||||
is not NULL, then the function shall return the length of the string
|
||||
.Pq not including the NULL terminator
|
||||
in the location pointed to by
|
||||
.Fa len_p .
|
||||
The
|
||||
.Fa flag
|
||||
argument is a bitwise-or.
|
||||
.Pp
|
||||
The following flags are effective only on POSIX.1e ACL:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
Output access ACLs.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
Output POSIX.1e default ACLs.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT
|
||||
Prefix each default ACL entry with the word
|
||||
.Dq default: .
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_SOLARIS
|
||||
The mask and other ACLs don not contain a double colon.
|
||||
.El
|
||||
.Pp
|
||||
The following flags are effecive only on NFSv4 ACL:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_COMPACT
|
||||
Do not output minus characters for unset permissions and flags in NFSv4 ACL
|
||||
permission and flag fields.
|
||||
.El
|
||||
.Pp
|
||||
The following flags are effective on both POSIX.1e and NFSv4 ACL:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
|
||||
Add an additional colon-separated field containing the user or group id.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA
|
||||
Separate ACL entries with comma instead of newline.
|
||||
.El
|
||||
.Pp
|
||||
If the archive entry contains NFSv4 ACLs, all types of NFSv4 ACLs are returned.
|
||||
It the entry contains POSIX.1e ACLs and none of the flags
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
or
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
are specified, both access and default entries are returned and default entries
|
||||
are prefixed with
|
||||
.Dq default: .
|
||||
.Pp
|
||||
.Fn archive_entry_acl_types
|
||||
get ACL entry types contained in an archive entry's ACL.
|
||||
As POSIX.1e and NFSv4
|
||||
ACL entries cannot be mixed, this function is a very efficient way to detect if
|
||||
an ACL already contains POSIX.1e or NFSv4 ACL entries.
|
||||
.Sh RETURN VALUES
|
||||
.Fn archive_entry_acl_count
|
||||
and
|
||||
.Fn archive_entry_acl_reset
|
||||
returns the number of ACL entries that match the given type mask.
|
||||
For POSIX.1e ACLS if the type mask includes
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
and at least one extended ACL entry exists, the three classic Unix
|
||||
permissions are counted.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_from_text
|
||||
and
|
||||
.Fn archive_entry_acl_from_text_w
|
||||
return
|
||||
.Dv ARCHIVE_OK
|
||||
if all entries were successfully parsed and
|
||||
.Dv ARCHIVE_WARN
|
||||
if one or more entries were invalid or non-parseable.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_next
|
||||
returns
|
||||
.Dv ARCHIVE_OK
|
||||
on success,
|
||||
.Dv ARCHIVE_EOF
|
||||
if no more ACL entries exist
|
||||
and
|
||||
.Dv ARCHIVE_WARN
|
||||
if
|
||||
.Fn archive_entry_acl_reset
|
||||
has not been called first.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_to_text
|
||||
returns a string representing the ACL entries matching the given type and
|
||||
flags on success or NULL on error.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_to_text_w
|
||||
returns a wide string representing the ACL entries matching the given type
|
||||
and flags on success or NULL on error.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_types
|
||||
returns a bitmask of ACL entry types or 0 if archive entry has no ACL entries.
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr libarchive 3
|
75
dependencies/libarchive-3.4.2/libarchive/archive_entry_copy_bhfi.c
vendored
Normal file
75
dependencies/libarchive-3.4.2/libarchive/archive_entry_copy_bhfi.c
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "archive_private.h"
|
||||
#include "archive_entry.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
|
||||
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
|
||||
|
||||
__inline static void
|
||||
fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
|
||||
{
|
||||
ULARGE_INTEGER utc;
|
||||
|
||||
utc.HighPart = filetime->dwHighDateTime;
|
||||
utc.LowPart = filetime->dwLowDateTime;
|
||||
if (utc.QuadPart >= EPOC_TIME) {
|
||||
utc.QuadPart -= EPOC_TIME;
|
||||
*t = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
|
||||
*ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
|
||||
} else {
|
||||
*t = 0;
|
||||
*ns = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_copy_bhfi(struct archive_entry *entry,
|
||||
BY_HANDLE_FILE_INFORMATION *bhfi)
|
||||
{
|
||||
time_t secs;
|
||||
long nsecs;
|
||||
|
||||
fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
|
||||
archive_entry_set_atime(entry, secs, nsecs);
|
||||
fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
|
||||
archive_entry_set_mtime(entry, secs, nsecs);
|
||||
fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
|
||||
archive_entry_set_birthtime(entry, secs, nsecs);
|
||||
archive_entry_set_ctime(entry, secs, nsecs);
|
||||
archive_entry_set_dev(entry, bhfi->dwVolumeSerialNumber);
|
||||
archive_entry_set_ino64(entry, (((int64_t)bhfi->nFileIndexHigh) << 32)
|
||||
+ bhfi->nFileIndexLow);
|
||||
archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
|
||||
archive_entry_set_size(entry, (((int64_t)bhfi->nFileSizeHigh) << 32)
|
||||
+ bhfi->nFileSizeLow);
|
||||
/* archive_entry_set_mode(entry, st->st_mode); */
|
||||
}
|
||||
#endif
|
83
dependencies/libarchive-3.4.2/libarchive/archive_entry_copy_stat.c
vendored
Normal file
83
dependencies/libarchive-3.4.2/libarchive/archive_entry_copy_stat.c
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_copy_stat.c 189466 2009-03-07 00:52:02Z kientzle $");
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
|
||||
void
|
||||
archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st)
|
||||
{
|
||||
#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||
archive_entry_set_atime(entry, st->st_atime, st->st_atimespec.tv_nsec);
|
||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctimespec.tv_nsec);
|
||||
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtimespec.tv_nsec);
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
archive_entry_set_atime(entry, st->st_atime, st->st_atim.tv_nsec);
|
||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctim.tv_nsec);
|
||||
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtim.tv_nsec);
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIME_NSEC
|
||||
archive_entry_set_atime(entry, st->st_atime, st->st_atime_nsec);
|
||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_nsec);
|
||||
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_nsec);
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIME_N
|
||||
archive_entry_set_atime(entry, st->st_atime, st->st_atime_n);
|
||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_n);
|
||||
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_n);
|
||||
#elif HAVE_STRUCT_STAT_ST_UMTIME
|
||||
archive_entry_set_atime(entry, st->st_atime, st->st_uatime * 1000);
|
||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_uctime * 1000);
|
||||
archive_entry_set_mtime(entry, st->st_mtime, st->st_umtime * 1000);
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
|
||||
archive_entry_set_atime(entry, st->st_atime, st->st_atime_usec * 1000);
|
||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_usec * 1000);
|
||||
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_usec * 1000);
|
||||
#else
|
||||
archive_entry_set_atime(entry, st->st_atime, 0);
|
||||
archive_entry_set_ctime(entry, st->st_ctime, 0);
|
||||
archive_entry_set_mtime(entry, st->st_mtime, 0);
|
||||
#endif
|
||||
#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
|
||||
archive_entry_set_birthtime(entry, st->st_birthtime, st->st_birthtimespec.tv_nsec);
|
||||
#elif HAVE_STRUCT_STAT_ST_BIRTHTIME
|
||||
archive_entry_set_birthtime(entry, st->st_birthtime, 0);
|
||||
#else
|
||||
archive_entry_unset_birthtime(entry);
|
||||
#endif
|
||||
archive_entry_set_dev(entry, st->st_dev);
|
||||
archive_entry_set_gid(entry, st->st_gid);
|
||||
archive_entry_set_uid(entry, st->st_uid);
|
||||
archive_entry_set_ino(entry, st->st_ino);
|
||||
archive_entry_set_nlink(entry, st->st_nlink);
|
||||
archive_entry_set_rdev(entry, st->st_rdev);
|
||||
archive_entry_set_size(entry, st->st_size);
|
||||
archive_entry_set_mode(entry, st->st_mode);
|
||||
}
|
447
dependencies/libarchive-3.4.2/libarchive/archive_entry_link_resolver.c
vendored
Normal file
447
dependencies/libarchive-3.4.2/libarchive/archive_entry_link_resolver.c
vendored
Normal file
|
@ -0,0 +1,447 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_link_resolver.c 201100 2009-12-28 03:05:31Z kientzle $");
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
|
||||
/*
|
||||
* This is mostly a pretty straightforward hash table implementation.
|
||||
* The only interesting bit is the different strategies used to
|
||||
* match up links. These strategies match those used by various
|
||||
* archiving formats:
|
||||
* tar - content stored with first link, remainder refer back to it.
|
||||
* This requires us to match each subsequent link up with the
|
||||
* first appearance.
|
||||
* cpio - Old cpio just stored body with each link, match-ups were
|
||||
* implicit. This is trivial.
|
||||
* new cpio - New cpio only stores body with last link, match-ups
|
||||
* are implicit. This is actually quite tricky; see the notes
|
||||
* below.
|
||||
*/
|
||||
|
||||
/* Users pass us a format code, we translate that into a strategy here. */
|
||||
#define ARCHIVE_ENTRY_LINKIFY_LIKE_TAR 0
|
||||
#define ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE 1
|
||||
#define ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO 2
|
||||
#define ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO 3
|
||||
|
||||
/* Initial size of link cache. */
|
||||
#define links_cache_initial_size 1024
|
||||
|
||||
struct links_entry {
|
||||
struct links_entry *next;
|
||||
struct links_entry *previous;
|
||||
struct archive_entry *canonical;
|
||||
struct archive_entry *entry;
|
||||
size_t hash;
|
||||
unsigned int links; /* # links not yet seen */
|
||||
};
|
||||
|
||||
struct archive_entry_linkresolver {
|
||||
struct links_entry **buckets;
|
||||
struct links_entry *spare;
|
||||
unsigned long number_entries;
|
||||
size_t number_buckets;
|
||||
int strategy;
|
||||
};
|
||||
|
||||
#define NEXT_ENTRY_DEFERRED 1
|
||||
#define NEXT_ENTRY_PARTIAL 2
|
||||
#define NEXT_ENTRY_ALL (NEXT_ENTRY_DEFERRED | NEXT_ENTRY_PARTIAL)
|
||||
|
||||
static struct links_entry *find_entry(struct archive_entry_linkresolver *,
|
||||
struct archive_entry *);
|
||||
static void grow_hash(struct archive_entry_linkresolver *);
|
||||
static struct links_entry *insert_entry(struct archive_entry_linkresolver *,
|
||||
struct archive_entry *);
|
||||
static struct links_entry *next_entry(struct archive_entry_linkresolver *,
|
||||
int);
|
||||
|
||||
struct archive_entry_linkresolver *
|
||||
archive_entry_linkresolver_new(void)
|
||||
{
|
||||
struct archive_entry_linkresolver *res;
|
||||
|
||||
/* Check for positive power-of-two */
|
||||
if (links_cache_initial_size == 0 ||
|
||||
(links_cache_initial_size & (links_cache_initial_size - 1)) != 0)
|
||||
return (NULL);
|
||||
|
||||
res = calloc(1, sizeof(struct archive_entry_linkresolver));
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
res->number_buckets = links_cache_initial_size;
|
||||
res->buckets = calloc(res->number_buckets, sizeof(res->buckets[0]));
|
||||
if (res->buckets == NULL) {
|
||||
free(res);
|
||||
return (NULL);
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *res,
|
||||
int fmt)
|
||||
{
|
||||
int fmtbase = fmt & ARCHIVE_FORMAT_BASE_MASK;
|
||||
|
||||
switch (fmtbase) {
|
||||
case ARCHIVE_FORMAT_7ZIP:
|
||||
case ARCHIVE_FORMAT_AR:
|
||||
case ARCHIVE_FORMAT_ZIP:
|
||||
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
|
||||
break;
|
||||
case ARCHIVE_FORMAT_CPIO:
|
||||
switch (fmt) {
|
||||
case ARCHIVE_FORMAT_CPIO_SVR4_NOCRC:
|
||||
case ARCHIVE_FORMAT_CPIO_SVR4_CRC:
|
||||
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO;
|
||||
break;
|
||||
default:
|
||||
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ARCHIVE_FORMAT_MTREE:
|
||||
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE;
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ISO9660:
|
||||
case ARCHIVE_FORMAT_SHAR:
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
case ARCHIVE_FORMAT_XAR:
|
||||
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_TAR;
|
||||
break;
|
||||
default:
|
||||
res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_linkresolver_free(struct archive_entry_linkresolver *res)
|
||||
{
|
||||
struct links_entry *le;
|
||||
|
||||
if (res == NULL)
|
||||
return;
|
||||
|
||||
while ((le = next_entry(res, NEXT_ENTRY_ALL)) != NULL)
|
||||
archive_entry_free(le->entry);
|
||||
free(res->buckets);
|
||||
free(res);
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_linkify(struct archive_entry_linkresolver *res,
|
||||
struct archive_entry **e, struct archive_entry **f)
|
||||
{
|
||||
struct links_entry *le;
|
||||
struct archive_entry *t;
|
||||
|
||||
*f = NULL; /* Default: Don't return a second entry. */
|
||||
|
||||
if (*e == NULL) {
|
||||
le = next_entry(res, NEXT_ENTRY_DEFERRED);
|
||||
if (le != NULL) {
|
||||
*e = le->entry;
|
||||
le->entry = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* If it has only one link, then we're done. */
|
||||
if (archive_entry_nlink(*e) == 1)
|
||||
return;
|
||||
/* Directories, devices never have hardlinks. */
|
||||
if (archive_entry_filetype(*e) == AE_IFDIR
|
||||
|| archive_entry_filetype(*e) == AE_IFBLK
|
||||
|| archive_entry_filetype(*e) == AE_IFCHR)
|
||||
return;
|
||||
|
||||
switch (res->strategy) {
|
||||
case ARCHIVE_ENTRY_LINKIFY_LIKE_TAR:
|
||||
le = find_entry(res, *e);
|
||||
if (le != NULL) {
|
||||
archive_entry_unset_size(*e);
|
||||
archive_entry_copy_hardlink(*e,
|
||||
archive_entry_pathname(le->canonical));
|
||||
} else
|
||||
insert_entry(res, *e);
|
||||
return;
|
||||
case ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE:
|
||||
le = find_entry(res, *e);
|
||||
if (le != NULL) {
|
||||
archive_entry_copy_hardlink(*e,
|
||||
archive_entry_pathname(le->canonical));
|
||||
} else
|
||||
insert_entry(res, *e);
|
||||
return;
|
||||
case ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO:
|
||||
/* This one is trivial. */
|
||||
return;
|
||||
case ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO:
|
||||
le = find_entry(res, *e);
|
||||
if (le != NULL) {
|
||||
/*
|
||||
* Put the new entry in le, return the
|
||||
* old entry from le.
|
||||
*/
|
||||
t = *e;
|
||||
*e = le->entry;
|
||||
le->entry = t;
|
||||
/* Make the old entry into a hardlink. */
|
||||
archive_entry_unset_size(*e);
|
||||
archive_entry_copy_hardlink(*e,
|
||||
archive_entry_pathname(le->canonical));
|
||||
/* If we ran out of links, return the
|
||||
* final entry as well. */
|
||||
if (le->links == 0) {
|
||||
*f = le->entry;
|
||||
le->entry = NULL;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* If we haven't seen it, tuck it away
|
||||
* for future use.
|
||||
*/
|
||||
le = insert_entry(res, *e);
|
||||
if (le == NULL)
|
||||
/* XXX We should return an error code XXX */
|
||||
return;
|
||||
le->entry = *e;
|
||||
*e = NULL;
|
||||
}
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static struct links_entry *
|
||||
find_entry(struct archive_entry_linkresolver *res,
|
||||
struct archive_entry *entry)
|
||||
{
|
||||
struct links_entry *le;
|
||||
size_t hash, bucket;
|
||||
dev_t dev;
|
||||
int64_t ino;
|
||||
|
||||
/* Free a held entry. */
|
||||
if (res->spare != NULL) {
|
||||
archive_entry_free(res->spare->canonical);
|
||||
archive_entry_free(res->spare->entry);
|
||||
free(res->spare);
|
||||
res->spare = NULL;
|
||||
}
|
||||
|
||||
dev = archive_entry_dev(entry);
|
||||
ino = archive_entry_ino64(entry);
|
||||
hash = (size_t)(dev ^ ino);
|
||||
|
||||
/* Try to locate this entry in the links cache. */
|
||||
bucket = hash & (res->number_buckets - 1);
|
||||
for (le = res->buckets[bucket]; le != NULL; le = le->next) {
|
||||
if (le->hash == hash
|
||||
&& dev == archive_entry_dev(le->canonical)
|
||||
&& ino == archive_entry_ino64(le->canonical)) {
|
||||
/*
|
||||
* Decrement link count each time and release
|
||||
* the entry if it hits zero. This saves
|
||||
* memory and is necessary for detecting
|
||||
* missed links.
|
||||
*/
|
||||
--le->links;
|
||||
if (le->links > 0)
|
||||
return (le);
|
||||
/* Remove it from this hash bucket. */
|
||||
if (le->previous != NULL)
|
||||
le->previous->next = le->next;
|
||||
if (le->next != NULL)
|
||||
le->next->previous = le->previous;
|
||||
if (res->buckets[bucket] == le)
|
||||
res->buckets[bucket] = le->next;
|
||||
res->number_entries--;
|
||||
/* Defer freeing this entry. */
|
||||
res->spare = le;
|
||||
return (le);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct links_entry *
|
||||
next_entry(struct archive_entry_linkresolver *res, int mode)
|
||||
{
|
||||
struct links_entry *le;
|
||||
size_t bucket;
|
||||
|
||||
/* Free a held entry. */
|
||||
if (res->spare != NULL) {
|
||||
archive_entry_free(res->spare->canonical);
|
||||
archive_entry_free(res->spare->entry);
|
||||
free(res->spare);
|
||||
res->spare = NULL;
|
||||
}
|
||||
|
||||
/* Look for next non-empty bucket in the links cache. */
|
||||
for (bucket = 0; bucket < res->number_buckets; bucket++) {
|
||||
for (le = res->buckets[bucket]; le != NULL; le = le->next) {
|
||||
if (le->entry != NULL &&
|
||||
(mode & NEXT_ENTRY_DEFERRED) == 0)
|
||||
continue;
|
||||
if (le->entry == NULL &&
|
||||
(mode & NEXT_ENTRY_PARTIAL) == 0)
|
||||
continue;
|
||||
/* Remove it from this hash bucket. */
|
||||
if (le->next != NULL)
|
||||
le->next->previous = le->previous;
|
||||
if (le->previous != NULL)
|
||||
le->previous->next = le->next;
|
||||
else
|
||||
res->buckets[bucket] = le->next;
|
||||
res->number_entries--;
|
||||
/* Defer freeing this entry. */
|
||||
res->spare = le;
|
||||
return (le);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct links_entry *
|
||||
insert_entry(struct archive_entry_linkresolver *res,
|
||||
struct archive_entry *entry)
|
||||
{
|
||||
struct links_entry *le;
|
||||
size_t hash, bucket;
|
||||
|
||||
/* Add this entry to the links cache. */
|
||||
le = calloc(1, sizeof(struct links_entry));
|
||||
if (le == NULL)
|
||||
return (NULL);
|
||||
le->canonical = archive_entry_clone(entry);
|
||||
|
||||
/* If the links cache is getting too full, enlarge the hash table. */
|
||||
if (res->number_entries > res->number_buckets * 2)
|
||||
grow_hash(res);
|
||||
|
||||
hash = (size_t)(archive_entry_dev(entry) ^ archive_entry_ino64(entry));
|
||||
bucket = hash & (res->number_buckets - 1);
|
||||
|
||||
/* If we could allocate the entry, record it. */
|
||||
if (res->buckets[bucket] != NULL)
|
||||
res->buckets[bucket]->previous = le;
|
||||
res->number_entries++;
|
||||
le->next = res->buckets[bucket];
|
||||
le->previous = NULL;
|
||||
res->buckets[bucket] = le;
|
||||
le->hash = hash;
|
||||
le->links = archive_entry_nlink(entry) - 1;
|
||||
return (le);
|
||||
}
|
||||
|
||||
static void
|
||||
grow_hash(struct archive_entry_linkresolver *res)
|
||||
{
|
||||
struct links_entry *le, **new_buckets;
|
||||
size_t new_size;
|
||||
size_t i, bucket;
|
||||
|
||||
/* Try to enlarge the bucket list. */
|
||||
new_size = res->number_buckets * 2;
|
||||
if (new_size < res->number_buckets)
|
||||
return;
|
||||
new_buckets = calloc(new_size, sizeof(struct links_entry *));
|
||||
|
||||
if (new_buckets == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < res->number_buckets; i++) {
|
||||
while (res->buckets[i] != NULL) {
|
||||
/* Remove entry from old bucket. */
|
||||
le = res->buckets[i];
|
||||
res->buckets[i] = le->next;
|
||||
|
||||
/* Add entry to new bucket. */
|
||||
bucket = le->hash & (new_size - 1);
|
||||
|
||||
if (new_buckets[bucket] != NULL)
|
||||
new_buckets[bucket]->previous = le;
|
||||
le->next = new_buckets[bucket];
|
||||
le->previous = NULL;
|
||||
new_buckets[bucket] = le;
|
||||
}
|
||||
}
|
||||
free(res->buckets);
|
||||
res->buckets = new_buckets;
|
||||
res->number_buckets = new_size;
|
||||
}
|
||||
|
||||
struct archive_entry *
|
||||
archive_entry_partial_links(struct archive_entry_linkresolver *res,
|
||||
unsigned int *links)
|
||||
{
|
||||
struct archive_entry *e;
|
||||
struct links_entry *le;
|
||||
|
||||
/* Free a held entry. */
|
||||
if (res->spare != NULL) {
|
||||
archive_entry_free(res->spare->canonical);
|
||||
archive_entry_free(res->spare->entry);
|
||||
free(res->spare);
|
||||
res->spare = NULL;
|
||||
}
|
||||
|
||||
le = next_entry(res, NEXT_ENTRY_PARTIAL);
|
||||
if (le != NULL) {
|
||||
e = le->canonical;
|
||||
if (links != NULL)
|
||||
*links = le->links;
|
||||
le->canonical = NULL;
|
||||
} else {
|
||||
e = NULL;
|
||||
if (links != NULL)
|
||||
*links = 0;
|
||||
}
|
||||
return (e);
|
||||
}
|
224
dependencies/libarchive-3.4.2/libarchive/archive_entry_linkify.3
vendored
Normal file
224
dependencies/libarchive-3.4.2/libarchive/archive_entry_linkify.3
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
.\" Copyright (c) 2010 Joerg Sonnenberger
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_ENTRY_LINKIFY 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_entry_linkresolver ,
|
||||
.Nm archive_entry_linkresolver_new ,
|
||||
.Nm archive_entry_linkresolver_set_strategy ,
|
||||
.Nm archive_entry_linkresolver_free ,
|
||||
.Nm archive_entry_linkify
|
||||
.Nd hardlink resolver functions
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive_entry.h
|
||||
.Ft struct archive_entry_linkresolver *
|
||||
.Fn archive_entry_linkresolver_new void
|
||||
.Ft void
|
||||
.Fo archive_entry_linkresolver_set_strategy
|
||||
.Fa "struct archive_entry_linkresolver *resolver"
|
||||
.Fa "int format"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo archive_entry_linkresolver_free
|
||||
.Fa "struct archive_entry_linkresolver *resolver"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo archive_entry_linkify
|
||||
.Fa "struct archive_entry_linkresolver *resolver"
|
||||
.Fa "struct archive_entry **entry"
|
||||
.Fa "struct archive_entry **sparse"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
Programs that want to create archives have to deal with hardlinks.
|
||||
Hardlinks are handled in different ways by the archive formats.
|
||||
The basic strategies are:
|
||||
.Bl -enum
|
||||
.It
|
||||
Ignore hardlinks and store the body for each reference (old cpio, zip).
|
||||
.It
|
||||
Store the body the first time an inode is seen (ustar, pax).
|
||||
.It
|
||||
Store the body the last time an inode is seen (new cpio).
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
functions help by providing a unified interface and handling the complexity
|
||||
behind the scene.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
functions assume that
|
||||
.Vt archive_entry
|
||||
instances have valid nlinks, inode and device values.
|
||||
The inode and device value is used to match entries.
|
||||
The nlinks value is used to determined if all references have been found and
|
||||
if the internal references can be recycled.
|
||||
.Pp
|
||||
The
|
||||
.Fn archive_entry_linkresolver_new
|
||||
function allocates a new link resolver.
|
||||
The instance can be freed using
|
||||
.Fn archive_entry_linkresolver_free .
|
||||
All deferred entries are flushed and the internal storage is freed.
|
||||
.Pp
|
||||
The
|
||||
.Fn archive_entry_linkresolver_set_strategy
|
||||
function selects the optimal hardlink strategy for the given format.
|
||||
The format code can be obtained from
|
||||
.Xr archive_format 3 .
|
||||
The function can be called more than once, but it is recommended to
|
||||
flush all deferred entries first.
|
||||
.Pp
|
||||
The
|
||||
.Fn archive_entry_linkify
|
||||
function is the core of
|
||||
.Nm .
|
||||
The
|
||||
.Fn entry
|
||||
argument points to the
|
||||
.Vt archive_entry
|
||||
that should be written.
|
||||
Depending on the strategy one of the following actions is taken:
|
||||
.Bl -enum
|
||||
.It
|
||||
For the simple archive formats
|
||||
.Va *entry
|
||||
is left unmodified and
|
||||
.Va *sparse
|
||||
is set to
|
||||
.Dv NULL .
|
||||
.It
|
||||
For tar like archive formats,
|
||||
.Va *sparse
|
||||
is set to
|
||||
.Dv NULL .
|
||||
If
|
||||
.Va *entry
|
||||
is
|
||||
.Dv NULL ,
|
||||
no action is taken.
|
||||
If the hardlink count of
|
||||
.Va *entry
|
||||
is larger than 1 and the file type is a regular file or symbolic link,
|
||||
the internal list is searched for a matching inode.
|
||||
If such an inode is found, the link count is decremented and the file size
|
||||
of
|
||||
.Va *entry
|
||||
is set to 0 to notify that no body should be written.
|
||||
If no such inode is found, a copy of the entry is added to the internal cache
|
||||
with a link count reduced by one.
|
||||
.It
|
||||
For new cpio like archive formats a value for
|
||||
.Va *entry
|
||||
of
|
||||
.Dv NULL
|
||||
is used to flush deferred entries.
|
||||
In that case
|
||||
.Va *entry
|
||||
is set to an arbitrary deferred entry and the entry itself is removed from the
|
||||
internal list.
|
||||
If the internal list is empty,
|
||||
.Va *entry
|
||||
is set to
|
||||
.Dv NULL .
|
||||
In either case,
|
||||
.Va *sparse
|
||||
is set to
|
||||
.Dv NULL
|
||||
and the function returns.
|
||||
If the hardlink count of
|
||||
.Va *entry
|
||||
is one or the file type is a directory or device,
|
||||
.Va *sparse
|
||||
is set to
|
||||
.Dv NULL
|
||||
and no further action is taken.
|
||||
Otherwise, the internal list is searched for a matching inode.
|
||||
If such an inode is not found, the entry is added to the internal list,
|
||||
both
|
||||
.Va *entry
|
||||
and
|
||||
.Va *sparse
|
||||
are set to
|
||||
.Dv NULL
|
||||
and the function returns.
|
||||
If such an inode is found, the link count is decremented.
|
||||
If it remains larger than one, the existing entry on the internal list
|
||||
is swapped with
|
||||
.Va *entry
|
||||
after retaining the link count.
|
||||
The existing entry is returned in
|
||||
.Va *entry .
|
||||
If the link count reached one, the new entry is also removed from the
|
||||
internal list and returned in
|
||||
.Va *sparse .
|
||||
Otherwise
|
||||
.Va *sparse
|
||||
is set to
|
||||
.Dv NULL .
|
||||
.El
|
||||
.Pp
|
||||
The general usage is therefore:
|
||||
.Bl -enum
|
||||
.It
|
||||
For each new archive entry, call
|
||||
.Fn archive_entry_linkify .
|
||||
.It
|
||||
Keep in mind that the entries returned may have a size of 0 now.
|
||||
.It
|
||||
If
|
||||
.Va *entry
|
||||
is not
|
||||
.Dv NULL ,
|
||||
archive it.
|
||||
.It
|
||||
If
|
||||
.Va *sparse
|
||||
is not
|
||||
.Dv NULL ,
|
||||
archive it.
|
||||
.It
|
||||
After all entries have been written to disk, call
|
||||
.Fn archive_entry_linkify
|
||||
with
|
||||
.Va *entry
|
||||
set to
|
||||
.Dv NULL
|
||||
and archive the returned entry as long as it is not
|
||||
.Dv NULL .
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
.Fn archive_entry_linkresolver_new
|
||||
returns
|
||||
.Dv NULL
|
||||
on
|
||||
.Xr malloc 3
|
||||
failures.
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3
|
92
dependencies/libarchive-3.4.2/libarchive/archive_entry_locale.h
vendored
Normal file
92
dependencies/libarchive-3.4.2/libarchive/archive_entry_locale.h
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*-
|
||||
* Copyright (c) 2011 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
|
||||
#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
struct archive_entry;
|
||||
struct archive_string_conv;
|
||||
|
||||
/*
|
||||
* Utility functions to set and get entry attributes by translating
|
||||
* character-set. These are designed for use in format readers and writers.
|
||||
*
|
||||
* The return code and interface of these are quite different from other
|
||||
* functions for archive_entry defined in archive_entry.h.
|
||||
* Common return code are:
|
||||
* Return 0 if the string conversion succeeded.
|
||||
* Return -1 if the string conversion failed.
|
||||
*/
|
||||
|
||||
#define archive_entry_gname_l _archive_entry_gname_l
|
||||
int _archive_entry_gname_l(struct archive_entry *,
|
||||
const char **, size_t *, struct archive_string_conv *);
|
||||
#define archive_entry_hardlink_l _archive_entry_hardlink_l
|
||||
int _archive_entry_hardlink_l(struct archive_entry *,
|
||||
const char **, size_t *, struct archive_string_conv *);
|
||||
#define archive_entry_pathname_l _archive_entry_pathname_l
|
||||
int _archive_entry_pathname_l(struct archive_entry *,
|
||||
const char **, size_t *, struct archive_string_conv *);
|
||||
#define archive_entry_symlink_l _archive_entry_symlink_l
|
||||
int _archive_entry_symlink_l(struct archive_entry *,
|
||||
const char **, size_t *, struct archive_string_conv *);
|
||||
#define archive_entry_uname_l _archive_entry_uname_l
|
||||
int _archive_entry_uname_l(struct archive_entry *,
|
||||
const char **, size_t *, struct archive_string_conv *);
|
||||
#define archive_entry_acl_text_l _archive_entry_acl_text_l
|
||||
int _archive_entry_acl_text_l(struct archive_entry *, int,
|
||||
const char **, size_t *, struct archive_string_conv *) __LA_DEPRECATED;
|
||||
#define archive_entry_acl_to_text_l _archive_entry_acl_to_text_l
|
||||
char *_archive_entry_acl_to_text_l(struct archive_entry *, ssize_t *, int,
|
||||
struct archive_string_conv *);
|
||||
#define archive_entry_acl_from_text_l _archive_entry_acl_from_text_l
|
||||
int _archive_entry_acl_from_text_l(struct archive_entry *, const char* text,
|
||||
int type, struct archive_string_conv *);
|
||||
#define archive_entry_copy_gname_l _archive_entry_copy_gname_l
|
||||
int _archive_entry_copy_gname_l(struct archive_entry *,
|
||||
const char *, size_t, struct archive_string_conv *);
|
||||
#define archive_entry_copy_hardlink_l _archive_entry_copy_hardlink_l
|
||||
int _archive_entry_copy_hardlink_l(struct archive_entry *,
|
||||
const char *, size_t, struct archive_string_conv *);
|
||||
#define archive_entry_copy_link_l _archive_entry_copy_link_l
|
||||
int _archive_entry_copy_link_l(struct archive_entry *,
|
||||
const char *, size_t, struct archive_string_conv *);
|
||||
#define archive_entry_copy_pathname_l _archive_entry_copy_pathname_l
|
||||
int _archive_entry_copy_pathname_l(struct archive_entry *,
|
||||
const char *, size_t, struct archive_string_conv *);
|
||||
#define archive_entry_copy_symlink_l _archive_entry_copy_symlink_l
|
||||
int _archive_entry_copy_symlink_l(struct archive_entry *,
|
||||
const char *, size_t, struct archive_string_conv *);
|
||||
#define archive_entry_copy_uname_l _archive_entry_copy_uname_l
|
||||
int _archive_entry_copy_uname_l(struct archive_entry *,
|
||||
const char *, size_t, struct archive_string_conv *);
|
||||
|
||||
#endif /* ARCHIVE_ENTRY_LOCALE_H_INCLUDED */
|
63
dependencies/libarchive-3.4.2/libarchive/archive_entry_misc.3
vendored
Normal file
63
dependencies/libarchive-3.4.2/libarchive/archive_entry_misc.3
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
.\" Copyright (c) 2019 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 AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd April 15, 2019
|
||||
.Dt ARCHIVE_ENTRY_MISC 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_entry_symlink_type ,
|
||||
.Nm archive_entry_set_symlink_type
|
||||
.Nd miscellaneous functions for manipulating properties of archive_entry
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive_entry.h
|
||||
.Ft int
|
||||
.Fn archive_entry_symlink_type "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_symlink_type "struct archive_entry *a" "int"
|
||||
.Sh DESCRIPTION
|
||||
The function
|
||||
.Fn archive_entry_symlink_type
|
||||
returns and the function
|
||||
.Fn archive_entry_set_symlink_type
|
||||
sets the type of the symbolic link stored in an archive entry.
|
||||
These functions
|
||||
have special meaning on operating systems that support multiple symbolic link
|
||||
types (e.g. Microsoft Windows).
|
||||
.Pp
|
||||
Supported values are:
|
||||
.Bl -tag -width "AE_SYMLINK_TYPE_DIRECTORY" -compact
|
||||
.It AE_SYMLINK_TYPE_UNDEFINED
|
||||
Symbolic link target type is not defined (default on unix systems)
|
||||
.It AE_SYMLINK_TYPE_FILE
|
||||
Symbolic link points to a file
|
||||
.It AE_SYMLINK_TYPE_DIRECTORY
|
||||
Symbolic link points to a directory
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr archive_entry_paths 3 ,
|
||||
.Xr archive_entry_stat 3 ,
|
||||
.Xr libarchive 3
|
153
dependencies/libarchive-3.4.2/libarchive/archive_entry_paths.3
vendored
Normal file
153
dependencies/libarchive-3.4.2/libarchive/archive_entry_paths.3
vendored
Normal file
|
@ -0,0 +1,153 @@
|
|||
.\" Copyright (c) 2010 Joerg Sonnenberger
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_ENTRY_PATHS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_entry_hardlink ,
|
||||
.Nm archive_entry_hardlink_w ,
|
||||
.Nm archive_entry_set_hardlink ,
|
||||
.Nm archive_entry_copy_hardlink ,
|
||||
.Nm archive_entry_copy_hardlink_w ,
|
||||
.Nm archive_entry_update_hardlink_utf8 ,
|
||||
.Nm archive_entry_set_link ,
|
||||
.Nm archive_entry_copy_link ,
|
||||
.Nm archive_entry_copy_link_w ,
|
||||
.Nm archive_entry_update_link_utf8 ,
|
||||
.Nm archive_entry_pathname ,
|
||||
.Nm archive_entry_pathname_w ,
|
||||
.Nm archive_entry_set_pathname ,
|
||||
.Nm archive_entry_copy_pathname ,
|
||||
.Nm archive_entry_copy_pathname_w ,
|
||||
.Nm archive_entry_update_pathname_utf8 ,
|
||||
.Nm archive_entry_sourcepath ,
|
||||
.Nm archive_entry_copy_sourcepath ,
|
||||
.Nm archive_entry_symlink ,
|
||||
.Nm archive_entry_symlink_w ,
|
||||
.Nm archive_entry_set_symlink ,
|
||||
.Nm archive_entry_copy_symlink ,
|
||||
.Nm archive_entry_copy_symlink_w ,
|
||||
.Nm archive_entry_update_symlink_utf8
|
||||
.Nd functions for manipulating path names in archive entry descriptions
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive_entry.h
|
||||
.Ft const char *
|
||||
.Fn archive_entry_hardlink "struct archive_entry *a"
|
||||
.Ft const wchar_t *
|
||||
.Fn archive_entry_hardlink_w "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_hardlink "struct archive_entry *a" "const char *path"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_hardlink "struct archive_entry *a" "const char *path"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_hardlink_w "struct archive_entry *a "const wchar_t *path"
|
||||
.Ft int
|
||||
.Fn archive_entry_update_hardlink_utf8 "struct archive_entry *a" "const char *path"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_link "struct archive_entry *a" "const char *path"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_link "struct archive_entry *a" " const char *path"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_link_w "struct archive_entry *a" " const wchar_t *path"
|
||||
.Ft int
|
||||
.Fn archive_entry_update_link_utf8 "struct archive_entry *a" " const char *path"
|
||||
.Ft const char *
|
||||
.Fn archive_entry_pathname "struct archive_entry *a"
|
||||
.Ft const wchar_t *
|
||||
.Fn archive_entry_pathname_w "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_pathname "struct archive_entry *a" "const char *path"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_pathname "struct archive_entry *a" "const char *path"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_pathname_w "struct archive_entry *a" "const wchar_t *path"
|
||||
.Ft int
|
||||
.Fn archive_entry_update_pathname_utf8 "struct archive_entry *a" "const char *path"
|
||||
.Ft const char *
|
||||
.Fn archive_entry_sourcepath "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_sourcepath "struct archive_entry *a" "const char *path"
|
||||
.Ft const char *
|
||||
.Fn archive_entry_symlink "struct archive_entry *a"
|
||||
.Ft const wchar_t *
|
||||
.Fn archive_entry_symlink_w "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_symlink "struct archive_entry *a" "const char *path"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_symlink "struct archive_entry *a" "const char *path"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_symlink_w "struct archive_entry *a" "const wchar_t *path"
|
||||
.Ft int
|
||||
.Fn archive_entry_update_symlink_utf8 "struct archive_entry *a" "const char *path"
|
||||
.Sh DESCRIPTION
|
||||
Path names supported by
|
||||
.Xr archive_entry 3 :
|
||||
.Bl -tag -width "sourcepath" -compact
|
||||
.It hardlink
|
||||
Destination of the hardlink.
|
||||
.It link
|
||||
Update only.
|
||||
For a symlink, update the destination.
|
||||
Otherwise, make the entry a hardlink and alter
|
||||
the destination for that.
|
||||
.It pathname
|
||||
Path in the archive
|
||||
.It sourcepath
|
||||
Path on the disk for use by
|
||||
.Xr archive_read_disk 3 .
|
||||
.It symlink
|
||||
Destination of the symbolic link.
|
||||
.El
|
||||
.Pp
|
||||
Path names can be provided in one of three different ways:
|
||||
.Bl -tag -width "wchar_t *"
|
||||
.It char *
|
||||
Multibyte strings in the current locale.
|
||||
.It wchar_t *
|
||||
Wide character strings in the current locale.
|
||||
The accessor functions are named
|
||||
.Fn XXX_w .
|
||||
.It UTF-8
|
||||
Unicode strings encoded as UTF-8.
|
||||
These are convenience functions to update both the multibyte and wide
|
||||
character strings at the same time.
|
||||
.El
|
||||
.Pp
|
||||
The sourcepath is a pure filesystem concept and never stored in an
|
||||
archive directly.
|
||||
.Pp
|
||||
For that reason, it is only available as multibyte string.
|
||||
The link path is a convenience function for conditionally setting
|
||||
hardlink or symlink destination.
|
||||
It doesn't have a corresponding get accessor function.
|
||||
.Pp
|
||||
.Fn archive_entry_set_XXX
|
||||
is an alias for
|
||||
.Fn archive_entry_copy_XXX .
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr libarchive 3
|
209
dependencies/libarchive-3.4.2/libarchive/archive_entry_perms.3
vendored
Normal file
209
dependencies/libarchive-3.4.2/libarchive/archive_entry_perms.3
vendored
Normal file
|
@ -0,0 +1,209 @@
|
|||
.\" Copyright (c) 2003-2007 Tim Kientzle
|
||||
.\" Copyright (c) 2010 Joerg Sonnenberger
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_ENTRY_PERMS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_entry_gid ,
|
||||
.Nm archive_entry_set_gid ,
|
||||
.Nm archive_entry_uid ,
|
||||
.Nm archive_entry_set_uid ,
|
||||
.Nm archive_entry_perm ,
|
||||
.Nm archive_entry_set_perm ,
|
||||
.Nm archive_entry_strmode ,
|
||||
.Nm archive_entry_uname ,
|
||||
.Nm archive_entry_uname_w ,
|
||||
.Nm archive_entry_set_uname ,
|
||||
.Nm archive_entry_copy_uname ,
|
||||
.Nm archive_entry_copy_uname_w ,
|
||||
.Nm archive_entry_update_uname_utf8 ,
|
||||
.Nm archive_entry_gname ,
|
||||
.Nm archive_entry_gname_w ,
|
||||
.Nm archive_entry_set_gname ,
|
||||
.Nm archive_entry_copy_gname ,
|
||||
.Nm archive_entry_copy_gname_w ,
|
||||
.Nm archive_entry_update_gname_utf8 ,
|
||||
.Nm archive_entry_fflags ,
|
||||
.Nm archive_entry_fflags_text ,
|
||||
.Nm archive_entry_set_fflags ,
|
||||
.Nm archive_entry_copy_fflags_text ,
|
||||
.Nm archive_entry_copy_fflags_text_w
|
||||
.Nd functions for manipulating ownership and permissions in archive entry descriptions
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive_entry.h
|
||||
.Ft gid_t
|
||||
.Fn archive_entry_gid "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_gid "struct archive_entry *a" "gid_t gid"
|
||||
.Ft uid_t
|
||||
.Fn archive_entry_uid "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_uid "struct archive_entry *a" "uid_t uid"
|
||||
.Ft mode_t
|
||||
.Fn archive_entry_perm "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_perm "struct archive_entry *a" "mode_t mode"
|
||||
.Ft const char *
|
||||
.Fn archive_entry_strmode "struct archive_entry *a"
|
||||
.Ft const char *
|
||||
.Fn archive_entry_gname "struct archive_entry *a"
|
||||
.Ft const wchar_t *
|
||||
.Fn archive_entry_gname_w "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_gname "struct archive_entry *a" "const char *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_gname "struct archive_entry *a" "const char *name"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_gname_w "struct archive_entry *a" "const wchar_t *name"
|
||||
.Ft int
|
||||
.Fn archive_entry_update_gname_utf8 "struct archive_entry *a" "const char *name"
|
||||
.Ft const char *
|
||||
.Fn archive_entry_uname "struct archive_entry *a"
|
||||
.Ft const wchar_t *
|
||||
.Fn archive_entry_uname_w "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_uname "struct archive_entry *a" "const char *name"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_uname "struct archive_entry *a" "const char *name"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_uname_w "struct archive_entry *a" "const wchar_t *name"
|
||||
.Ft int
|
||||
.Fn archive_entry_update_uname_utf8 "struct archive_entry *a" "const char *name"
|
||||
.Ft void
|
||||
.Fo archive_entry_fflags
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "unsigned long *set_bits"
|
||||
.Fa "unsigned long *clear_bits"
|
||||
.Fc
|
||||
.Ft const char *
|
||||
.Fn archive_entry_fflags_text "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fo archive_entry_set_fflags
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "unsigned long set_bits"
|
||||
.Fa "unsigned long clear_bits"
|
||||
.Fc
|
||||
.Ft const char *
|
||||
.Fn archive_entry_copy_fflags_text "struct archive_entry *a" "const char *text"
|
||||
.Ft const wchar_t *
|
||||
.Fn archive_entry_copy_fflags_text_w "struct archive_entry *a" "const wchar_t *text"
|
||||
.Sh DESCRIPTION
|
||||
.Ss User id, group id and mode
|
||||
The functions
|
||||
.Fn archive_entry_uid ,
|
||||
.Fn archive_entry_gid ,
|
||||
and
|
||||
.Fn archive_entry_perm
|
||||
can be used to extract the user id, group id and permission from the given entry.
|
||||
The corresponding functions
|
||||
.Fn archive_entry_set_uid ,
|
||||
.Fn archive_entry_set_gid ,
|
||||
and
|
||||
.Fn archive_entry_set_perm
|
||||
store the given user id, group id and permission in the entry.
|
||||
The permission is also set as a side effect of calling
|
||||
.Fn archive_entry_set_mode .
|
||||
.Pp
|
||||
.Fn archive_entry_strmode
|
||||
returns a string representation of the permission as used by the long mode of
|
||||
.Xr ls 1 .
|
||||
.Ss User and group name
|
||||
User and group names can be provided in one of three different ways:
|
||||
.Bl -tag -width "wchar_t *"
|
||||
.It char *
|
||||
Multibyte strings in the current locale.
|
||||
.It wchar_t *
|
||||
Wide character strings in the current locale.
|
||||
The accessor functions are named
|
||||
.Fn XXX_w .
|
||||
.It UTF-8
|
||||
Unicode strings encoded as UTF-8.
|
||||
These are convenience functions to update both the multibyte and wide
|
||||
character strings at the same time.
|
||||
.El
|
||||
.Pp
|
||||
.Fn archive_entry_set_XXX
|
||||
is an alias for
|
||||
.Fn archive_entry_copy_XXX .
|
||||
.Ss File Flags
|
||||
File flags are transparently converted between a bitmap
|
||||
representation and a textual format.
|
||||
For example, if you set the bitmap and ask for text, the library
|
||||
will build a canonical text format.
|
||||
However, if you set a text format and request a text format,
|
||||
you will get back the same text, even if it is ill-formed.
|
||||
If you need to canonicalize a textual flags string, you should first set the
|
||||
text form, then request the bitmap form, then use that to set the bitmap form.
|
||||
Setting the bitmap format will clear the internal text representation
|
||||
and force it to be reconstructed when you next request the text form.
|
||||
.Pp
|
||||
The bitmap format consists of two integers, one containing bits
|
||||
that should be set, the other specifying bits that should be
|
||||
cleared.
|
||||
Bits not mentioned in either bitmap will be ignored.
|
||||
Usually, the bitmap of bits to be cleared will be set to zero.
|
||||
In unusual circumstances, you can force a fully-specified set
|
||||
of file flags by setting the bitmap of flags to clear to the complement
|
||||
of the bitmap of flags to set.
|
||||
(This differs from
|
||||
.Xr fflagstostr 3 ,
|
||||
which only includes names for set bits.)
|
||||
Converting a bitmap to a textual string is a platform-specific
|
||||
operation; bits that are not meaningful on the current platform
|
||||
will be ignored.
|
||||
.Pp
|
||||
The canonical text format is a comma-separated list of flag names.
|
||||
The
|
||||
.Fn archive_entry_copy_fflags_text
|
||||
and
|
||||
.Fn archive_entry_copy_fflags_text_w
|
||||
functions parse the provided text and set the internal bitmap values.
|
||||
This is a platform-specific operation; names that are not meaningful
|
||||
on the current platform will be ignored.
|
||||
The function returns a pointer to the start of the first name that was not
|
||||
recognized, or NULL if every name was recognized.
|
||||
Note that every name \(em including names that follow an unrecognized
|
||||
name \(em will be evaluated, and the bitmaps will be set to reflect
|
||||
every name that is recognized.
|
||||
(In particular, this differs from
|
||||
.Xr strtofflags 3 ,
|
||||
which stops parsing at the first unrecognized name.)
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr archive_entry_acl 3 ,
|
||||
.Xr archive_read_disk 3 ,
|
||||
.Xr archive_write_disk 3 ,
|
||||
.Xr libarchive 3
|
||||
.Sh BUGS
|
||||
The platform types
|
||||
.Vt uid_t
|
||||
and
|
||||
.Vt gid_t
|
||||
are often 16 or 32 bit wide.
|
||||
In this case it is possible that the ids can not be correctly restored
|
||||
from archives and get truncated.
|
184
dependencies/libarchive-3.4.2/libarchive/archive_entry_private.h
vendored
Normal file
184
dependencies/libarchive-3.4.2/libarchive/archive_entry_private.h
vendored
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: head/lib/libarchive/archive_entry_private.h 201096 2009-12-28 02:41:27Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include "archive_acl_private.h"
|
||||
#include "archive_string.h"
|
||||
|
||||
struct ae_xattr {
|
||||
struct ae_xattr *next;
|
||||
|
||||
char *name;
|
||||
void *value;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct ae_sparse {
|
||||
struct ae_sparse *next;
|
||||
|
||||
int64_t offset;
|
||||
int64_t length;
|
||||
};
|
||||
|
||||
/*
|
||||
* Description of an archive entry.
|
||||
*
|
||||
* Basically, this is a "struct stat" with a few text fields added in.
|
||||
*
|
||||
* TODO: Add "comment", "charset", and possibly other entries
|
||||
* that are supported by "pax interchange" format. However, GNU, ustar,
|
||||
* cpio, and other variants don't support these features, so they're not an
|
||||
* excruciatingly high priority right now.
|
||||
*
|
||||
* TODO: "pax interchange" format allows essentially arbitrary
|
||||
* key/value attributes to be attached to any entry. Supporting
|
||||
* such extensions may make this library useful for special
|
||||
* applications (e.g., a package manager could attach special
|
||||
* package-management attributes to each entry). There are tricky
|
||||
* API issues involved, so this is not going to happen until
|
||||
* there's a real demand for it.
|
||||
*
|
||||
* TODO: Design a good API for handling sparse files.
|
||||
*/
|
||||
struct archive_entry {
|
||||
struct archive *archive;
|
||||
|
||||
/*
|
||||
* Note that ae_stat.st_mode & AE_IFMT can be 0!
|
||||
*
|
||||
* This occurs when the actual file type of the object is not
|
||||
* in the archive. For example, 'tar' archives store
|
||||
* hardlinks without marking the type of the underlying
|
||||
* object.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We have a "struct aest" for holding file metadata rather than just
|
||||
* a "struct stat" because on some platforms the "struct stat" has
|
||||
* fields which are too narrow to hold the range of possible values;
|
||||
* we don't want to lose information if we read an archive and write
|
||||
* out another (e.g., in "tar -cf new.tar @old.tar").
|
||||
*
|
||||
* The "stat" pointer points to some form of platform-specific struct
|
||||
* stat; it is declared as a void * rather than a struct stat * as
|
||||
* some platforms have multiple varieties of stat structures.
|
||||
*/
|
||||
void *stat;
|
||||
int stat_valid; /* Set to 0 whenever a field in aest changes. */
|
||||
|
||||
struct aest {
|
||||
int64_t aest_atime;
|
||||
uint32_t aest_atime_nsec;
|
||||
int64_t aest_ctime;
|
||||
uint32_t aest_ctime_nsec;
|
||||
int64_t aest_mtime;
|
||||
uint32_t aest_mtime_nsec;
|
||||
int64_t aest_birthtime;
|
||||
uint32_t aest_birthtime_nsec;
|
||||
int64_t aest_gid;
|
||||
int64_t aest_ino;
|
||||
uint32_t aest_nlink;
|
||||
uint64_t aest_size;
|
||||
int64_t aest_uid;
|
||||
/*
|
||||
* Because converting between device codes and
|
||||
* major/minor values is platform-specific and
|
||||
* inherently a bit risky, we only do that conversion
|
||||
* lazily. That way, we will do a better job of
|
||||
* preserving information in those cases where no
|
||||
* conversion is actually required.
|
||||
*/
|
||||
int aest_dev_is_broken_down;
|
||||
dev_t aest_dev;
|
||||
dev_t aest_devmajor;
|
||||
dev_t aest_devminor;
|
||||
int aest_rdev_is_broken_down;
|
||||
dev_t aest_rdev;
|
||||
dev_t aest_rdevmajor;
|
||||
dev_t aest_rdevminor;
|
||||
} ae_stat;
|
||||
|
||||
int ae_set; /* bitmap of fields that are currently set */
|
||||
#define AE_SET_HARDLINK 1
|
||||
#define AE_SET_SYMLINK 2
|
||||
#define AE_SET_ATIME 4
|
||||
#define AE_SET_CTIME 8
|
||||
#define AE_SET_MTIME 16
|
||||
#define AE_SET_BIRTHTIME 32
|
||||
#define AE_SET_SIZE 64
|
||||
#define AE_SET_INO 128
|
||||
#define AE_SET_DEV 256
|
||||
|
||||
/*
|
||||
* Use aes here so that we get transparent mbs<->wcs conversions.
|
||||
*/
|
||||
struct archive_mstring ae_fflags_text; /* Text fflags per fflagstostr(3) */
|
||||
unsigned long ae_fflags_set; /* Bitmap fflags */
|
||||
unsigned long ae_fflags_clear;
|
||||
struct archive_mstring ae_gname; /* Name of owning group */
|
||||
struct archive_mstring ae_hardlink; /* Name of target for hardlink */
|
||||
struct archive_mstring ae_pathname; /* Name of entry */
|
||||
struct archive_mstring ae_symlink; /* symlink contents */
|
||||
struct archive_mstring ae_uname; /* Name of owner */
|
||||
|
||||
/* Not used within libarchive; useful for some clients. */
|
||||
struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */
|
||||
|
||||
#define AE_ENCRYPTION_NONE 0
|
||||
#define AE_ENCRYPTION_DATA 1
|
||||
#define AE_ENCRYPTION_METADATA 2
|
||||
char encryption;
|
||||
|
||||
void *mac_metadata;
|
||||
size_t mac_metadata_size;
|
||||
|
||||
/* ACL support. */
|
||||
struct archive_acl acl;
|
||||
|
||||
/* extattr support. */
|
||||
struct ae_xattr *xattr_head;
|
||||
struct ae_xattr *xattr_p;
|
||||
|
||||
/* sparse support. */
|
||||
struct ae_sparse *sparse_head;
|
||||
struct ae_sparse *sparse_tail;
|
||||
struct ae_sparse *sparse_p;
|
||||
|
||||
/* Miscellaneous. */
|
||||
char strmode[12];
|
||||
|
||||
/* Symlink type support */
|
||||
int ae_symlink_type;
|
||||
};
|
||||
|
||||
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
|
156
dependencies/libarchive-3.4.2/libarchive/archive_entry_sparse.c
vendored
Normal file
156
dependencies/libarchive-3.4.2/libarchive/archive_entry_sparse.c
vendored
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2010-2011 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_entry_private.h"
|
||||
|
||||
/*
|
||||
* sparse handling
|
||||
*/
|
||||
|
||||
void
|
||||
archive_entry_sparse_clear(struct archive_entry *entry)
|
||||
{
|
||||
struct ae_sparse *sp;
|
||||
|
||||
while (entry->sparse_head != NULL) {
|
||||
sp = entry->sparse_head->next;
|
||||
free(entry->sparse_head);
|
||||
entry->sparse_head = sp;
|
||||
}
|
||||
entry->sparse_tail = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_sparse_add_entry(struct archive_entry *entry,
|
||||
la_int64_t offset, la_int64_t length)
|
||||
{
|
||||
struct ae_sparse *sp;
|
||||
|
||||
if (offset < 0 || length < 0)
|
||||
/* Invalid value */
|
||||
return;
|
||||
if (offset > INT64_MAX - length ||
|
||||
offset + length > archive_entry_size(entry))
|
||||
/* A value of "length" parameter is too large. */
|
||||
return;
|
||||
if ((sp = entry->sparse_tail) != NULL) {
|
||||
if (sp->offset + sp->length > offset)
|
||||
/* Invalid value. */
|
||||
return;
|
||||
if (sp->offset + sp->length == offset) {
|
||||
if (sp->offset + sp->length + length < 0)
|
||||
/* A value of "length" parameter is
|
||||
* too large. */
|
||||
return;
|
||||
/* Expand existing sparse block size. */
|
||||
sp->length += length;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((sp = (struct ae_sparse *)malloc(sizeof(*sp))) == NULL)
|
||||
/* XXX Error XXX */
|
||||
return;
|
||||
|
||||
sp->offset = offset;
|
||||
sp->length = length;
|
||||
sp->next = NULL;
|
||||
|
||||
if (entry->sparse_head == NULL)
|
||||
entry->sparse_head = entry->sparse_tail = sp;
|
||||
else {
|
||||
/* Add a new sparse block to the tail of list. */
|
||||
if (entry->sparse_tail != NULL)
|
||||
entry->sparse_tail->next = sp;
|
||||
entry->sparse_tail = sp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* returns number of the sparse entries
|
||||
*/
|
||||
int
|
||||
archive_entry_sparse_count(struct archive_entry *entry)
|
||||
{
|
||||
struct ae_sparse *sp;
|
||||
int count = 0;
|
||||
|
||||
for (sp = entry->sparse_head; sp != NULL; sp = sp->next)
|
||||
count++;
|
||||
|
||||
/*
|
||||
* Sanity check if this entry is exactly sparse.
|
||||
* If amount of sparse blocks is just one and it indicates the whole
|
||||
* file data, we should remove it and return zero.
|
||||
*/
|
||||
if (count == 1) {
|
||||
sp = entry->sparse_head;
|
||||
if (sp->offset == 0 &&
|
||||
sp->length >= archive_entry_size(entry)) {
|
||||
count = 0;
|
||||
archive_entry_sparse_clear(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_sparse_reset(struct archive_entry * entry)
|
||||
{
|
||||
entry->sparse_p = entry->sparse_head;
|
||||
|
||||
return archive_entry_sparse_count(entry);
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_sparse_next(struct archive_entry * entry,
|
||||
la_int64_t *offset, la_int64_t *length)
|
||||
{
|
||||
if (entry->sparse_p) {
|
||||
*offset = entry->sparse_p->offset;
|
||||
*length = entry->sparse_p->length;
|
||||
|
||||
entry->sparse_p = entry->sparse_p->next;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
} else {
|
||||
*offset = 0;
|
||||
*length = 0;
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* end of sparse handling
|
||||
*/
|
274
dependencies/libarchive-3.4.2/libarchive/archive_entry_stat.3
vendored
Normal file
274
dependencies/libarchive-3.4.2/libarchive/archive_entry_stat.3
vendored
Normal file
|
@ -0,0 +1,274 @@
|
|||
.\" Copyright (c) 2010 Joerg Sonnenberger
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_ENTRY_STAT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_entry_stat ,
|
||||
.Nm archive_entry_copy_stat ,
|
||||
.Nm archive_entry_filetype ,
|
||||
.Nm archive_entry_set_filetype ,
|
||||
.Nm archive_entry_mode ,
|
||||
.Nm archive_entry_set_mode ,
|
||||
.Nm archive_entry_size ,
|
||||
.Nm archive_entry_size_is_set ,
|
||||
.Nm archive_entry_set_size ,
|
||||
.Nm archive_entry_unset_size ,
|
||||
.Nm archive_entry_dev ,
|
||||
.Nm archive_entry_set_dev ,
|
||||
.Nm archive_entry_dev_is_set ,
|
||||
.Nm archive_entry_devmajor ,
|
||||
.Nm archive_entry_set_devmajor ,
|
||||
.Nm archive_entry_devminor ,
|
||||
.Nm archive_entry_set_devminor ,
|
||||
.Nm archive_entry_ino ,
|
||||
.Nm archive_entry_set_ino ,
|
||||
.Nm archive_entry_ino_is_set ,
|
||||
.Nm archive_entry_ino64 ,
|
||||
.Nm archive_entry_set_ino64 ,
|
||||
.Nm archive_entry_nlink ,
|
||||
.Nm archive_entry_rdev ,
|
||||
.Nm archive_entry_set_rdev ,
|
||||
.Nm archive_entry_rdevmajor ,
|
||||
.Nm archive_entry_set_rdevmajor ,
|
||||
.Nm archive_entry_rdevminor ,
|
||||
.Nm archive_entry_set_rdevminor
|
||||
.Nd accessor functions for manipulating archive entry descriptions
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive_entry.h
|
||||
.Ft const struct stat *
|
||||
.Fn archive_entry_stat "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_copy_stat "struct archive_entry *a" "const struct stat *sb"
|
||||
.Ft mode_t
|
||||
.Fn archive_entry_filetype "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_filetype "struct archive_entry *a" "unsigned int type"
|
||||
.Ft mode_t
|
||||
.Fn archive_entry_mode "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_mode "struct archive_entry *a" "mode_t mode"
|
||||
.Ft int64_t
|
||||
.Fn archive_entry_size "struct archive_entry *a"
|
||||
.Ft int
|
||||
.Fn archive_entry_size_is_set "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_size "struct archive_entry *a" "int64_t size"
|
||||
.Ft void
|
||||
.Fn archive_entry_unset_size "struct archive_entry *a"
|
||||
.Ft dev_t
|
||||
.Fn archive_entry_dev "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_dev "struct archive_entry *a" "dev_t dev"
|
||||
.Ft int
|
||||
.Fn archive_entry_dev_is_set "struct archive_entry *a"
|
||||
.Ft dev_t
|
||||
.Fn archive_entry_devmajor "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_devmajor "struct archive_entry *a" "dev_t major"
|
||||
.Ft dev_t
|
||||
.Fn archive_entry_devminor "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_devminor "struct archive_entry *a" "dev_t minor"
|
||||
.Ft ino_t
|
||||
.Fn archive_entry_ino "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_ino "struct archive_entry *a" "unsigned long ino"
|
||||
.Ft int
|
||||
.Fn archive_entry_ino_is_set "struct archive_entry *a"
|
||||
.Ft int64_t
|
||||
.Fn archive_entry_ino64 "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_ino64 "struct archive_entry *a" "int64_t ino"
|
||||
.Ft unsigned int
|
||||
.Fn archive_entry_nlink "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_nlink "struct archive_entry *a" "unsigned int count"
|
||||
.Ft dev_t
|
||||
.Fn archive_entry_rdev "struct archive_entry *a"
|
||||
.Ft dev_t
|
||||
.Fn archive_entry_rdevmajor "struct archive_entry *a"
|
||||
.Ft dev_t
|
||||
.Fn archive_entry_rdevminor "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_rdev "struct archive_entry *a" "dev_t dev"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_rdevmajor "struct archive_entry *a" "dev_t major"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_rdevminor "struct archive_entry *a" "dev_t minor"
|
||||
.Sh DESCRIPTION
|
||||
.Ss Copying to and from Vt struct stat
|
||||
The function
|
||||
.Fn archive_entry_stat
|
||||
converts the various fields stored in the archive entry to the format
|
||||
used by
|
||||
.Xr stat 2 .
|
||||
The return value remains valid until either
|
||||
.Fn archive_entry_clear
|
||||
or
|
||||
.Fn archive_entry_free
|
||||
is called.
|
||||
It is not affected by calls to the set accessor functions.
|
||||
It currently sets the following values in
|
||||
.Vt struct stat :
|
||||
.Vt st_atime ,
|
||||
.Vt st_ctime ,
|
||||
.Vt st_dev ,
|
||||
.Vt st_gid ,
|
||||
.Vt st_ino ,
|
||||
.Vt st_mode ,
|
||||
.Vt st_mtime ,
|
||||
.Vt st_nlink ,
|
||||
.Vt st_rdev ,
|
||||
.Vt st_size ,
|
||||
.Vt st_uid .
|
||||
In addition,
|
||||
.Vt st_birthtime
|
||||
and high-precision information for time-related fields
|
||||
will be included on platforms that support it.
|
||||
.Pp
|
||||
The function
|
||||
.Fn archive_entry_copy_stat
|
||||
copies fields from the platform's
|
||||
.Vt struct stat .
|
||||
Fields not provided by
|
||||
.Vt struct stat
|
||||
are unchanged.
|
||||
.Ss General accessor functions
|
||||
The functions
|
||||
.Fn archive_entry_filetype
|
||||
and
|
||||
.Fn archive_entry_set_filetype
|
||||
get respectively set the filetype.
|
||||
The file type is one of the following constants:
|
||||
.Bl -tag -width "AE_IFSOCK" -compact -offset indent
|
||||
.It AE_IFREG
|
||||
Regular file
|
||||
.It AE_IFLNK
|
||||
Symbolic link
|
||||
.It AE_IFSOCK
|
||||
Socket
|
||||
.It AE_IFCHR
|
||||
Character device
|
||||
.It AE_IFBLK
|
||||
Block device
|
||||
.It AE_IFDIR
|
||||
Directory
|
||||
.It AE_IFIFO
|
||||
Named pipe (fifo)
|
||||
.El
|
||||
Not all file types are supported by all platforms.
|
||||
The constants used by
|
||||
.Xr stat 2
|
||||
may have different numeric values from the
|
||||
corresponding constants above.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn archive_entry_mode
|
||||
and
|
||||
.Fn archive_entry_set_mode
|
||||
get/set a combination of file type and permissions and provide the
|
||||
equivalent of
|
||||
.Va st_mode .
|
||||
Use of
|
||||
.Fn archive_entry_filetype
|
||||
and
|
||||
.Fn archive_entry_perm
|
||||
for getting and
|
||||
.Fn archive_entry_set_filetype
|
||||
and
|
||||
.Fn archive_entry_set_perm
|
||||
for setting is recommended.
|
||||
.Pp
|
||||
The function
|
||||
.Fn archive_entry_size
|
||||
returns the file size, if it has been set, and 0 otherwise.
|
||||
.Fn archive_entry_size
|
||||
can be used to query that status.
|
||||
.Fn archive_entry_set_size
|
||||
and
|
||||
.Fn archive_entry_unset_size
|
||||
set and unset the size, respectively.
|
||||
.Pp
|
||||
The number of references (hardlinks) can be obtained by calling
|
||||
.Fn archive_entry_nlinks
|
||||
and set with
|
||||
.Fn archive_entry_set_nlinks .
|
||||
.Ss Identifying unique files
|
||||
The functions
|
||||
.Fn archive_entry_dev
|
||||
and
|
||||
.Fn archive_entry_ino64
|
||||
are used by
|
||||
.Xr archive_entry_linkify 3
|
||||
to find hardlinks.
|
||||
The pair of device and inode is supposed to identify hardlinked files.
|
||||
.Pp
|
||||
The device major and minor number can be obtained independently using
|
||||
.Fn archive_entry_devmajor
|
||||
and
|
||||
.Fn archive_entry_devminor .
|
||||
The device can be set either via
|
||||
.Fn archive_entry_set_dev
|
||||
or by the combination of major and minor number using
|
||||
.Fn archive_entry_set_devmajor
|
||||
and
|
||||
.Fn archive_entry_set_devminor .
|
||||
.Pp
|
||||
The inode number can be obtained using
|
||||
.Fn archive_entry_ino .
|
||||
This is a legacy interface that uses the platform
|
||||
.Vt ino_t ,
|
||||
which may be very small.
|
||||
To set the inode number,
|
||||
.Fn archive_entry_set_ino64
|
||||
is the preferred interface.
|
||||
.Ss Accessor functions for block and character devices
|
||||
Block and character devices are characterised either using a device number
|
||||
or a pair of major and minor number.
|
||||
The combined device number can be obtained with
|
||||
.Fn archive_device_rdev
|
||||
and set with
|
||||
.Fn archive_device_set_rdev .
|
||||
The major and minor numbers are accessed by
|
||||
.Fn archive_device_rdevmajor ,
|
||||
.Fn archive_device_rdevminor
|
||||
.Fn archive_device_set_rdevmajor
|
||||
and
|
||||
.Fn archive_device_set_rdevminor .
|
||||
.Pp
|
||||
The process of splitting the combined device number into major and
|
||||
minor number and the reverse process of combing them differs between
|
||||
platforms.
|
||||
Some archive formats use the combined form, while other formats use
|
||||
the split form.
|
||||
.Sh SEE ALSO
|
||||
.Xr stat 2 ,
|
||||
.Xr archive_entry_acl 3 ,
|
||||
.Xr archive_entry_perms 3 ,
|
||||
.Xr archive_entry_time 3 ,
|
||||
.Xr libarchive 3
|
118
dependencies/libarchive-3.4.2/libarchive/archive_entry_stat.c
vendored
Normal file
118
dependencies/libarchive-3.4.2/libarchive/archive_entry_stat.c
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_stat.c 201100 2009-12-28 03:05:31Z kientzle $");
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_entry_private.h"
|
||||
|
||||
const struct stat *
|
||||
archive_entry_stat(struct archive_entry *entry)
|
||||
{
|
||||
struct stat *st;
|
||||
if (entry->stat == NULL) {
|
||||
entry->stat = calloc(1, sizeof(*st));
|
||||
if (entry->stat == NULL)
|
||||
return (NULL);
|
||||
entry->stat_valid = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If none of the underlying fields have been changed, we
|
||||
* don't need to regenerate. In theory, we could use a bitmap
|
||||
* here to flag only those items that have changed, but the
|
||||
* extra complexity probably isn't worth it. It will be very
|
||||
* rare for anyone to change just one field then request a new
|
||||
* stat structure.
|
||||
*/
|
||||
if (entry->stat_valid)
|
||||
return (entry->stat);
|
||||
|
||||
st = entry->stat;
|
||||
/*
|
||||
* Use the public interfaces to extract items, so that
|
||||
* the appropriate conversions get invoked.
|
||||
*/
|
||||
st->st_atime = archive_entry_atime(entry);
|
||||
#if HAVE_STRUCT_STAT_ST_BIRTHTIME
|
||||
st->st_birthtime = archive_entry_birthtime(entry);
|
||||
#endif
|
||||
st->st_ctime = archive_entry_ctime(entry);
|
||||
st->st_mtime = archive_entry_mtime(entry);
|
||||
st->st_dev = archive_entry_dev(entry);
|
||||
st->st_gid = (gid_t)archive_entry_gid(entry);
|
||||
st->st_uid = (uid_t)archive_entry_uid(entry);
|
||||
st->st_ino = (ino_t)archive_entry_ino64(entry);
|
||||
st->st_nlink = archive_entry_nlink(entry);
|
||||
st->st_rdev = archive_entry_rdev(entry);
|
||||
st->st_size = (off_t)archive_entry_size(entry);
|
||||
st->st_mode = archive_entry_mode(entry);
|
||||
|
||||
/*
|
||||
* On systems that support high-res timestamps, copy that
|
||||
* information into struct stat.
|
||||
*/
|
||||
#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||
st->st_atimespec.tv_nsec = archive_entry_atime_nsec(entry);
|
||||
st->st_ctimespec.tv_nsec = archive_entry_ctime_nsec(entry);
|
||||
st->st_mtimespec.tv_nsec = archive_entry_mtime_nsec(entry);
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
st->st_atim.tv_nsec = archive_entry_atime_nsec(entry);
|
||||
st->st_ctim.tv_nsec = archive_entry_ctime_nsec(entry);
|
||||
st->st_mtim.tv_nsec = archive_entry_mtime_nsec(entry);
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIME_N
|
||||
st->st_atime_n = archive_entry_atime_nsec(entry);
|
||||
st->st_ctime_n = archive_entry_ctime_nsec(entry);
|
||||
st->st_mtime_n = archive_entry_mtime_nsec(entry);
|
||||
#elif HAVE_STRUCT_STAT_ST_UMTIME
|
||||
st->st_uatime = archive_entry_atime_nsec(entry) / 1000;
|
||||
st->st_uctime = archive_entry_ctime_nsec(entry) / 1000;
|
||||
st->st_umtime = archive_entry_mtime_nsec(entry) / 1000;
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
|
||||
st->st_atime_usec = archive_entry_atime_nsec(entry) / 1000;
|
||||
st->st_ctime_usec = archive_entry_ctime_nsec(entry) / 1000;
|
||||
st->st_mtime_usec = archive_entry_mtime_nsec(entry) / 1000;
|
||||
#endif
|
||||
#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
|
||||
st->st_birthtimespec.tv_nsec = archive_entry_birthtime_nsec(entry);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO: On Linux, store 32 or 64 here depending on whether
|
||||
* the cached stat structure is a stat32 or a stat64. This
|
||||
* will allow us to support both variants interchangeably.
|
||||
*/
|
||||
entry->stat_valid = 1;
|
||||
|
||||
return (st);
|
||||
}
|
87
dependencies/libarchive-3.4.2/libarchive/archive_entry_strmode.c
vendored
Normal file
87
dependencies/libarchive-3.4.2/libarchive/archive_entry_strmode.c
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_strmode.c,v 1.4 2008/06/15 05:14:01 kientzle Exp $");
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_entry_private.h"
|
||||
|
||||
const char *
|
||||
archive_entry_strmode(struct archive_entry *entry)
|
||||
{
|
||||
static const mode_t permbits[] =
|
||||
{ 0400, 0200, 0100, 0040, 0020, 0010, 0004, 0002, 0001 };
|
||||
char *bp = entry->strmode;
|
||||
mode_t mode;
|
||||
int i;
|
||||
|
||||
/* Fill in a default string, then selectively override. */
|
||||
strcpy(bp, "?rwxrwxrwx ");
|
||||
|
||||
mode = archive_entry_mode(entry);
|
||||
switch (archive_entry_filetype(entry)) {
|
||||
case AE_IFREG: bp[0] = '-'; break;
|
||||
case AE_IFBLK: bp[0] = 'b'; break;
|
||||
case AE_IFCHR: bp[0] = 'c'; break;
|
||||
case AE_IFDIR: bp[0] = 'd'; break;
|
||||
case AE_IFLNK: bp[0] = 'l'; break;
|
||||
case AE_IFSOCK: bp[0] = 's'; break;
|
||||
case AE_IFIFO: bp[0] = 'p'; break;
|
||||
default:
|
||||
if (archive_entry_hardlink(entry) != NULL) {
|
||||
bp[0] = 'h';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
if (!(mode & permbits[i]))
|
||||
bp[i+1] = '-';
|
||||
|
||||
if (mode & S_ISUID) {
|
||||
if (mode & 0100) bp[3] = 's';
|
||||
else bp[3] = 'S';
|
||||
}
|
||||
if (mode & S_ISGID) {
|
||||
if (mode & 0010) bp[6] = 's';
|
||||
else bp[6] = 'S';
|
||||
}
|
||||
if (mode & S_ISVTX) {
|
||||
if (mode & 0001) bp[9] = 't';
|
||||
else bp[9] = 'T';
|
||||
}
|
||||
if (archive_entry_acl_types(entry) != 0)
|
||||
bp[10] = '+';
|
||||
|
||||
return (bp);
|
||||
}
|
129
dependencies/libarchive-3.4.2/libarchive/archive_entry_time.3
vendored
Normal file
129
dependencies/libarchive-3.4.2/libarchive/archive_entry_time.3
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
.\" Copyright (c) 2003-2007 Tim Kientzle
|
||||
.\" Copyright (c) 2010 Joerg Sonnenberger
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_ENTRY_TIME 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_entry_atime ,
|
||||
.Nm archive_entry_atime_nsec ,
|
||||
.Nm archive_entry_atime_is_set ,
|
||||
.Nm archive_entry_set_atime ,
|
||||
.Nm archive_entry_unset_atime ,
|
||||
.Nm archive_entry_birthtime ,
|
||||
.Nm archive_entry_birthtime_nsec ,
|
||||
.Nm archive_entry_birthtime_is_set ,
|
||||
.Nm archive_entry_set_birthtime ,
|
||||
.Nm archive_entry_unset_birthtime ,
|
||||
.Nm archive_entry_ctime ,
|
||||
.Nm archive_entry_ctime_nsec ,
|
||||
.Nm archive_entry_ctime_is_set ,
|
||||
.Nm archive_entry_set_ctime ,
|
||||
.Nm archive_entry_unset_ctime ,
|
||||
.Nm archive_entry_mtime ,
|
||||
.Nm archive_entry_mtime_nsec ,
|
||||
.Nm archive_entry_mtime_is_set ,
|
||||
.Nm archive_entry_set_mtime ,
|
||||
.Nm archive_entry_unset_mtime
|
||||
.Nd functions for manipulating times in archive entry descriptions
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive_entry.h
|
||||
.Ft time_t
|
||||
.Fn archive_entry_atime "struct archive_entry *a"
|
||||
.Ft long
|
||||
.Fn archive_entry_atime_nsec "struct archive_entry *a"
|
||||
.Ft int
|
||||
.Fn archive_entry_atime_is_set "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_atime "struct archive_entry *a" "time_t sec" "long nanosec"
|
||||
.Ft void
|
||||
.Fn archive_entry_unset_atime "struct archive_entry *a"
|
||||
.Ft time_t
|
||||
.Fn archive_entry_birthtime "struct archive_entry *a"
|
||||
.Ft long
|
||||
.Fn archive_entry_birthtime_nsec "struct archive_entry *a"
|
||||
.Ft int
|
||||
.Fn archive_entry_birthtime_is_set "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_birthtime "struct archive_entry *a" "time_t sec" "long nanosec"
|
||||
.Ft void
|
||||
.Fn archive_entry_unset_birthtime "struct archive_entry *a"
|
||||
.Ft time_t
|
||||
.Fn archive_entry_ctime "struct archive_entry *a"
|
||||
.Ft long
|
||||
.Fn archive_entry_ctime_nsec "struct archive_entry *a"
|
||||
.Ft int
|
||||
.Fn archive_entry_ctime_is_set "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_ctime "struct archive_entry *a" "time_t sec" "long nanosec"
|
||||
.Ft void
|
||||
.Fn archive_entry_unset_ctime "struct archive_entry *a"
|
||||
.Ft time_t
|
||||
.Fn archive_entry_mtime "struct archive_entry *a"
|
||||
.Ft long
|
||||
.Fn archive_entry_mtime_nsec "struct archive_entry *a"
|
||||
.Ft int
|
||||
.Fn archive_entry_mtime_is_set "struct archive_entry *a"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_mtime "struct archive_entry *a" "time_t sec" "long nanosec"
|
||||
.Ft void
|
||||
.Fn archive_entry_unset_mtime "struct archive_entry *a"
|
||||
.Sh DESCRIPTION
|
||||
These functions create and manipulate the time fields in an
|
||||
.Vt archive_entry .
|
||||
Supported time fields are atime (access time), birthtime (creation time),
|
||||
ctime (last time an inode property was changed) and mtime (modification time).
|
||||
.Pp
|
||||
.Xr libarchive 3
|
||||
provides a high-resolution interface.
|
||||
The timestamps are truncated automatically depending on the archive format
|
||||
(for archiving) or the filesystem capabilities (for restoring).
|
||||
.Pp
|
||||
All timestamp fields are optional.
|
||||
The
|
||||
.Fn XXX_unset
|
||||
functions can be used to mark the corresponding field as missing.
|
||||
The current state can be queried using
|
||||
.Fn XXX_is_set .
|
||||
Unset time fields have a second and nanosecond field of 0.
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr libarchive 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm libarchive
|
||||
library first appeared in
|
||||
.Fx 5.3 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm libarchive
|
||||
library was written by
|
||||
.An Tim Kientzle Aq kientzle@acm.org .
|
||||
.\" .Sh BUGS
|
156
dependencies/libarchive-3.4.2/libarchive/archive_entry_xattr.c
vendored
Normal file
156
dependencies/libarchive-3.4.2/libarchive/archive_entry_xattr.c
vendored
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_xattr.c 201096 2009-12-28 02:41:27Z kientzle $");
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_LINUX_FS_H
|
||||
#include <linux/fs.h> /* for Linux file flags */
|
||||
#endif
|
||||
/*
|
||||
* Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
|
||||
* As the include guards don't agree, the order of include is important.
|
||||
*/
|
||||
#ifdef HAVE_LINUX_EXT2_FS_H
|
||||
#include <linux/ext2_fs.h> /* for Linux file flags */
|
||||
#endif
|
||||
#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
|
||||
#include <ext2fs/ext2_fs.h> /* for Linux file flags */
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_WCHAR_H
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_entry_private.h"
|
||||
|
||||
/*
|
||||
* extended attribute handling
|
||||
*/
|
||||
|
||||
void
|
||||
archive_entry_xattr_clear(struct archive_entry *entry)
|
||||
{
|
||||
struct ae_xattr *xp;
|
||||
|
||||
while (entry->xattr_head != NULL) {
|
||||
xp = entry->xattr_head->next;
|
||||
free(entry->xattr_head->name);
|
||||
free(entry->xattr_head->value);
|
||||
free(entry->xattr_head);
|
||||
entry->xattr_head = xp;
|
||||
}
|
||||
|
||||
entry->xattr_head = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_xattr_add_entry(struct archive_entry *entry,
|
||||
const char *name, const void *value, size_t size)
|
||||
{
|
||||
struct ae_xattr *xp;
|
||||
|
||||
if ((xp = (struct ae_xattr *)malloc(sizeof(struct ae_xattr))) == NULL)
|
||||
__archive_errx(1, "Out of memory");
|
||||
|
||||
if ((xp->name = strdup(name)) == NULL)
|
||||
__archive_errx(1, "Out of memory");
|
||||
|
||||
if ((xp->value = malloc(size)) != NULL) {
|
||||
memcpy(xp->value, value, size);
|
||||
xp->size = size;
|
||||
} else
|
||||
xp->size = 0;
|
||||
|
||||
xp->next = entry->xattr_head;
|
||||
entry->xattr_head = xp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* returns number of the extended attribute entries
|
||||
*/
|
||||
int
|
||||
archive_entry_xattr_count(struct archive_entry *entry)
|
||||
{
|
||||
struct ae_xattr *xp;
|
||||
int count = 0;
|
||||
|
||||
for (xp = entry->xattr_head; xp != NULL; xp = xp->next)
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_xattr_reset(struct archive_entry * entry)
|
||||
{
|
||||
entry->xattr_p = entry->xattr_head;
|
||||
|
||||
return archive_entry_xattr_count(entry);
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_xattr_next(struct archive_entry * entry,
|
||||
const char **name, const void **value, size_t *size)
|
||||
{
|
||||
if (entry->xattr_p) {
|
||||
*name = entry->xattr_p->name;
|
||||
*value = entry->xattr_p->value;
|
||||
*size = entry->xattr_p->size;
|
||||
|
||||
entry->xattr_p = entry->xattr_p->next;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
} else {
|
||||
*name = NULL;
|
||||
*value = NULL;
|
||||
*size = (size_t)0;
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* end of xattr handling
|
||||
*/
|
1165
dependencies/libarchive-3.4.2/libarchive/archive_getdate.c
vendored
Normal file
1165
dependencies/libarchive-3.4.2/libarchive/archive_getdate.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
39
dependencies/libarchive-3.4.2/libarchive/archive_getdate.h
vendored
Normal file
39
dependencies/libarchive-3.4.2/libarchive/archive_getdate.h
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2015 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_GETDATE_H_INCLUDED
|
||||
#define ARCHIVE_GETDATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
time_t __archive_get_date(time_t now, const char *);
|
||||
|
||||
#endif
|
305
dependencies/libarchive-3.4.2/libarchive/archive_hmac.c
vendored
Normal file
305
dependencies/libarchive-3.4.2/libarchive/archive_hmac.c
vendored
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*-
|
||||
* Copyright (c) 2014 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#include "archive.h"
|
||||
#include "archive_hmac_private.h"
|
||||
|
||||
/*
|
||||
* On systems that do not support any recognized crypto libraries,
|
||||
* the archive_hmac.c file is expected to define no usable symbols.
|
||||
*
|
||||
* But some compilers and linkers choke on empty object files, so
|
||||
* define a public symbol that will always exist. This could
|
||||
* be removed someday if this file gains another always-present
|
||||
* symbol definition.
|
||||
*/
|
||||
int __libarchive_hmac_build_hack(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto
|
||||
|
||||
static int
|
||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
CCHmacInit(ctx, kCCHmacAlgSHA1, key, key_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
|
||||
size_t data_len)
|
||||
{
|
||||
CCHmacUpdate(ctx, data, data_len);
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
|
||||
{
|
||||
CCHmacFinal(ctx, out);
|
||||
*out_len = 20;
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
|
||||
|
||||
#ifndef BCRYPT_HASH_REUSABLE_FLAG
|
||||
# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020
|
||||
#endif
|
||||
|
||||
static int
|
||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
#endif
|
||||
BCRYPT_ALG_HANDLE hAlg;
|
||||
BCRYPT_HASH_HANDLE hHash;
|
||||
DWORD hash_len;
|
||||
PBYTE hash;
|
||||
ULONG result;
|
||||
NTSTATUS status;
|
||||
|
||||
ctx->hAlg = NULL;
|
||||
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM,
|
||||
MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
if (!BCRYPT_SUCCESS(status))
|
||||
return -1;
|
||||
status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len,
|
||||
sizeof(hash_len), &result, 0);
|
||||
if (!BCRYPT_SUCCESS(status)) {
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
return -1;
|
||||
}
|
||||
hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len);
|
||||
if (hash == NULL) {
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
return -1;
|
||||
}
|
||||
status = BCryptCreateHash(hAlg, &hHash, NULL, 0,
|
||||
(PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG);
|
||||
if (!BCRYPT_SUCCESS(status)) {
|
||||
BCryptCloseAlgorithmProvider(hAlg, 0);
|
||||
HeapFree(GetProcessHeap(), 0, hash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->hAlg = hAlg;
|
||||
ctx->hHash = hHash;
|
||||
ctx->hash_len = hash_len;
|
||||
ctx->hash = hash;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
|
||||
size_t data_len)
|
||||
{
|
||||
BCryptHashData(ctx->hHash, (PUCHAR)(uintptr_t)data, (ULONG)data_len, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
|
||||
{
|
||||
BCryptFinishHash(ctx->hHash, ctx->hash, ctx->hash_len, 0);
|
||||
if (ctx->hash_len == *out_len)
|
||||
memcpy(out, ctx->hash, *out_len);
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||
{
|
||||
if (ctx->hAlg != NULL) {
|
||||
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
|
||||
HeapFree(GetProcessHeap(), 0, ctx->hash);
|
||||
ctx->hAlg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H)
|
||||
|
||||
static int
|
||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
const mbedtls_md_info_t *info;
|
||||
int ret;
|
||||
|
||||
mbedtls_md_init(ctx);
|
||||
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
||||
if (info == NULL) {
|
||||
mbedtls_md_free(ctx);
|
||||
return (-1);
|
||||
}
|
||||
ret = mbedtls_md_setup(ctx, info, 1);
|
||||
if (ret != 0) {
|
||||
mbedtls_md_free(ctx);
|
||||
return (-1);
|
||||
}
|
||||
ret = mbedtls_md_hmac_starts(ctx, key, key_len);
|
||||
if (ret != 0) {
|
||||
mbedtls_md_free(ctx);
|
||||
return (-1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
|
||||
size_t data_len)
|
||||
{
|
||||
mbedtls_md_hmac_update(ctx, data, data_len);
|
||||
}
|
||||
|
||||
static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
|
||||
{
|
||||
(void)out_len; /* UNUSED */
|
||||
|
||||
mbedtls_md_hmac_finish(ctx, out);
|
||||
}
|
||||
|
||||
static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||
{
|
||||
mbedtls_md_free(ctx);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
|
||||
|
||||
static int
|
||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
hmac_sha1_set_key(ctx, key_len, key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
|
||||
size_t data_len)
|
||||
{
|
||||
hmac_sha1_update(ctx, data_len, data);
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
|
||||
{
|
||||
hmac_sha1_digest(ctx, (unsigned)*out_len, out);
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
#elif defined(HAVE_LIBCRYPTO)
|
||||
|
||||
static int
|
||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
*ctx = HMAC_CTX_new();
|
||||
if (*ctx == NULL)
|
||||
return -1;
|
||||
HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
|
||||
size_t data_len)
|
||||
{
|
||||
HMAC_Update(*ctx, data, data_len);
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
|
||||
{
|
||||
unsigned int len = (unsigned int)*out_len;
|
||||
|
||||
HMAC_Final(*ctx, out, &len);
|
||||
*out_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||
{
|
||||
HMAC_CTX_free(*ctx);
|
||||
*ctx = NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Stub */
|
||||
static int
|
||||
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||
{
|
||||
(void)ctx;/* UNUSED */
|
||||
(void)key;/* UNUSED */
|
||||
(void)key_len;/* UNUSED */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
|
||||
size_t data_len)
|
||||
{
|
||||
(void)ctx;/* UNUSED */
|
||||
(void)data;/* UNUSED */
|
||||
(void)data_len;/* UNUSED */
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
|
||||
{
|
||||
(void)ctx;/* UNUSED */
|
||||
(void)out;/* UNUSED */
|
||||
(void)out_len;/* UNUSED */
|
||||
}
|
||||
|
||||
static void
|
||||
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
|
||||
{
|
||||
(void)ctx;/* UNUSED */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const struct archive_hmac __archive_hmac = {
|
||||
&__hmac_sha1_init,
|
||||
&__hmac_sha1_update,
|
||||
&__hmac_sha1_final,
|
||||
&__hmac_sha1_cleanup,
|
||||
};
|
110
dependencies/libarchive-3.4.2/libarchive/archive_hmac_private.h
vendored
Normal file
110
dependencies/libarchive-3.4.2/libarchive/archive_hmac_private.h
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*-
|
||||
* Copyright (c) 2014 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_HMAC_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
/*
|
||||
* On systems that do not support any recognized crypto libraries,
|
||||
* the archive_hmac.c file is expected to define no usable symbols.
|
||||
*
|
||||
* But some compilers and linkers choke on empty object files, so
|
||||
* define a public symbol that will always exist. This could
|
||||
* be removed someday if this file gains another always-present
|
||||
* symbol definition.
|
||||
*/
|
||||
int __libarchive_hmac_build_hack(void);
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <AvailabilityMacros.h>
|
||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||
# define ARCHIVE_HMAC_USE_Apple_CommonCrypto
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto
|
||||
#include <CommonCrypto/CommonHMAC.h>
|
||||
|
||||
typedef CCHmacContext archive_hmac_sha1_ctx;
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
|
||||
#include <bcrypt.h>
|
||||
|
||||
typedef struct {
|
||||
BCRYPT_ALG_HANDLE hAlg;
|
||||
BCRYPT_HASH_HANDLE hHash;
|
||||
DWORD hash_len;
|
||||
PBYTE hash;
|
||||
|
||||
} archive_hmac_sha1_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H)
|
||||
#include <mbedtls/md.h>
|
||||
|
||||
typedef mbedtls_md_context_t archive_hmac_sha1_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
|
||||
#include <nettle/hmac.h>
|
||||
|
||||
typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
|
||||
|
||||
#elif defined(HAVE_LIBCRYPTO)
|
||||
#include "archive_openssl_hmac_private.h"
|
||||
|
||||
typedef HMAC_CTX* archive_hmac_sha1_ctx;
|
||||
|
||||
#else
|
||||
|
||||
typedef int archive_hmac_sha1_ctx;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* HMAC */
|
||||
#define archive_hmac_sha1_init(ctx, key, key_len)\
|
||||
__archive_hmac.__hmac_sha1_init(ctx, key, key_len)
|
||||
#define archive_hmac_sha1_update(ctx, data, data_len)\
|
||||
__archive_hmac.__hmac_sha1_update(ctx, data, data_len)
|
||||
#define archive_hmac_sha1_final(ctx, out, out_len)\
|
||||
__archive_hmac.__hmac_sha1_final(ctx, out, out_len)
|
||||
#define archive_hmac_sha1_cleanup(ctx)\
|
||||
__archive_hmac.__hmac_sha1_cleanup(ctx)
|
||||
|
||||
|
||||
struct archive_hmac {
|
||||
/* HMAC */
|
||||
int (*__hmac_sha1_init)(archive_hmac_sha1_ctx *, const uint8_t *,
|
||||
size_t);
|
||||
void (*__hmac_sha1_update)(archive_hmac_sha1_ctx *, const uint8_t *,
|
||||
size_t);
|
||||
void (*__hmac_sha1_final)(archive_hmac_sha1_ctx *, uint8_t *, size_t *);
|
||||
void (*__hmac_sha1_cleanup)(archive_hmac_sha1_ctx *);
|
||||
};
|
||||
|
||||
extern const struct archive_hmac __archive_hmac;
|
||||
#endif /* ARCHIVE_HMAC_PRIVATE_H_INCLUDED */
|
1875
dependencies/libarchive-3.4.2/libarchive/archive_match.c
vendored
Normal file
1875
dependencies/libarchive-3.4.2/libarchive/archive_match.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
53
dependencies/libarchive-3.4.2/libarchive/archive_openssl_evp_private.h
vendored
Normal file
53
dependencies/libarchive-3.4.2/libarchive/archive_openssl_evp_private.h
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* memset */
|
||||
static inline EVP_MD_CTX *EVP_MD_CTX_new(void)
|
||||
{
|
||||
EVP_MD_CTX *ctx = (EVP_MD_CTX *)calloc(1, sizeof(EVP_MD_CTX));
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static inline void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
|
||||
{
|
||||
EVP_MD_CTX_cleanup(ctx);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
54
dependencies/libarchive-3.4.2/libarchive/archive_openssl_hmac_private.h
vendored
Normal file
54
dependencies/libarchive-3.4.2/libarchive/archive_openssl_hmac_private.h
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* memset */
|
||||
static inline HMAC_CTX *HMAC_CTX_new(void)
|
||||
{
|
||||
HMAC_CTX *ctx = (HMAC_CTX *)calloc(1, sizeof(HMAC_CTX));
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static inline void HMAC_CTX_free(HMAC_CTX *ctx)
|
||||
{
|
||||
HMAC_CTX_cleanup(ctx);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
218
dependencies/libarchive-3.4.2/libarchive/archive_options.c
vendored
Normal file
218
dependencies/libarchive-3.4.2/libarchive/archive_options.c
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*-
|
||||
* Copyright (c) 2011 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "archive_options_private.h"
|
||||
|
||||
static const char *
|
||||
parse_option(const char **str,
|
||||
const char **mod, const char **opt, const char **val);
|
||||
|
||||
int
|
||||
_archive_set_option(struct archive *a,
|
||||
const char *m, const char *o, const char *v,
|
||||
int magic, const char *fn, option_handler use_option)
|
||||
{
|
||||
const char *mp, *op, *vp;
|
||||
int r;
|
||||
|
||||
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
|
||||
|
||||
mp = (m != NULL && m[0] != '\0') ? m : NULL;
|
||||
op = (o != NULL && o[0] != '\0') ? o : NULL;
|
||||
vp = (v != NULL && v[0] != '\0') ? v : NULL;
|
||||
|
||||
if (op == NULL && vp == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
if (op == NULL) {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC, "Empty option");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
r = use_option(a, mp, op, vp);
|
||||
if (r == ARCHIVE_WARN - 1) {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unknown module name: `%s'", mp);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (r == ARCHIVE_WARN) {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Undefined option: `%s%s%s%s%s%s'",
|
||||
vp?"":"!", mp?mp:"", mp?":":"", op, vp?"=":"", vp?vp:"");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
|
||||
int
|
||||
_archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,
|
||||
option_handler use_format_option, option_handler use_filter_option)
|
||||
{
|
||||
int r1, r2;
|
||||
|
||||
if (o == NULL && v == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
if (o == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
|
||||
r1 = use_format_option(a, m, o, v);
|
||||
if (r1 == ARCHIVE_FATAL)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
r2 = use_filter_option(a, m, o, v);
|
||||
if (r2 == ARCHIVE_FATAL)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
if (r2 == ARCHIVE_WARN - 1)
|
||||
return r1;
|
||||
return r1 > r2 ? r1 : r2;
|
||||
}
|
||||
|
||||
int
|
||||
_archive_set_options(struct archive *a, const char *options,
|
||||
int magic, const char *fn, option_handler use_option)
|
||||
{
|
||||
int allok = 1, anyok = 0, ignore_mod_err = 0, r;
|
||||
char *data;
|
||||
const char *s, *mod, *opt, *val;
|
||||
|
||||
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
|
||||
|
||||
if (options == NULL || options[0] == '\0')
|
||||
return ARCHIVE_OK;
|
||||
|
||||
if ((data = strdup(options)) == NULL) {
|
||||
archive_set_error(a,
|
||||
ENOMEM, "Out of memory adding file to list");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
s = (const char *)data;
|
||||
|
||||
do {
|
||||
mod = opt = val = NULL;
|
||||
|
||||
parse_option(&s, &mod, &opt, &val);
|
||||
if (mod == NULL && opt != NULL &&
|
||||
strcmp("__ignore_wrong_module_name__", opt) == 0) {
|
||||
/* Ignore module name error */
|
||||
if (val != NULL) {
|
||||
ignore_mod_err = 1;
|
||||
anyok = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
r = use_option(a, mod, opt, val);
|
||||
if (r == ARCHIVE_FATAL) {
|
||||
free(data);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (r == ARCHIVE_FAILED && mod != NULL) {
|
||||
free(data);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (r == ARCHIVE_WARN - 1) {
|
||||
if (ignore_mod_err)
|
||||
continue;
|
||||
/* The module name is wrong. */
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unknown module name: `%s'", mod);
|
||||
free(data);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (r == ARCHIVE_WARN) {
|
||||
/* The option name is wrong. No-one used this. */
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Undefined option: `%s%s%s'",
|
||||
mod?mod:"", mod?":":"", opt);
|
||||
free(data);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (r == ARCHIVE_OK)
|
||||
anyok = 1;
|
||||
else
|
||||
allok = 0;
|
||||
} while (s != NULL);
|
||||
|
||||
free(data);
|
||||
return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;
|
||||
}
|
||||
|
||||
static const char *
|
||||
parse_option(const char **s, const char **m, const char **o, const char **v)
|
||||
{
|
||||
const char *end, *mod, *opt, *val;
|
||||
char *p;
|
||||
|
||||
end = NULL;
|
||||
mod = NULL;
|
||||
opt = *s;
|
||||
val = "1";
|
||||
|
||||
p = strchr(opt, ',');
|
||||
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
end = ((const char *)p) + 1;
|
||||
}
|
||||
|
||||
if (0 == strlen(opt)) {
|
||||
*s = end;
|
||||
*m = NULL;
|
||||
*o = NULL;
|
||||
*v = NULL;
|
||||
return end;
|
||||
}
|
||||
|
||||
p = strchr(opt, ':');
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
mod = opt;
|
||||
opt = ++p;
|
||||
}
|
||||
|
||||
p = strchr(opt, '=');
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
val = ++p;
|
||||
} else if (opt[0] == '!') {
|
||||
++opt;
|
||||
val = NULL;
|
||||
}
|
||||
|
||||
*s = end;
|
||||
*m = mod;
|
||||
*o = opt;
|
||||
*v = val;
|
||||
|
||||
return end;
|
||||
}
|
||||
|
51
dependencies/libarchive-3.4.2/libarchive/archive_options_private.h
vendored
Normal file
51
dependencies/libarchive-3.4.2/libarchive/archive_options_private.h
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*-
|
||||
* Copyright (c) 2011 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "archive_private.h"
|
||||
|
||||
typedef int (*option_handler)(struct archive *a,
|
||||
const char *mod, const char *opt, const char *val);
|
||||
|
||||
int
|
||||
_archive_set_option(struct archive *a,
|
||||
const char *mod, const char *opt, const char *val,
|
||||
int magic, const char *fn, option_handler use_option);
|
||||
|
||||
int
|
||||
_archive_set_options(struct archive *a, const char *options,
|
||||
int magic, const char *fn, option_handler use_option);
|
||||
|
||||
int
|
||||
_archive_set_either_option(struct archive *a,
|
||||
const char *m, const char *o, const char *v,
|
||||
option_handler use_format_option, option_handler use_filter_option);
|
||||
|
||||
#endif
|
336
dependencies/libarchive-3.4.2/libarchive/archive_pack_dev.c
vendored
Normal file
336
dependencies/libarchive-3.4.2/libarchive/archive_pack_dev.c
vendored
Normal file
|
@ -0,0 +1,336 @@
|
|||
/* $NetBSD: pack_dev.c,v 1.12 2013/06/14 16:28:20 tsutsui Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Charles M. Hannum.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Originally from NetBSD's mknod(8) source. */
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#if HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
#if !defined(lint)
|
||||
__RCSID("$NetBSD$");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#if MAJOR_IN_MKDEV
|
||||
#include <sys/mkdev.h>
|
||||
#define HAVE_MAJOR
|
||||
#elif MAJOR_IN_SYSMACROS
|
||||
#include <sys/sysmacros.h>
|
||||
#define HAVE_MAJOR
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "archive_pack_dev.h"
|
||||
|
||||
static pack_t pack_netbsd;
|
||||
static pack_t pack_freebsd;
|
||||
static pack_t pack_8_8;
|
||||
static pack_t pack_12_20;
|
||||
static pack_t pack_14_18;
|
||||
static pack_t pack_8_24;
|
||||
static pack_t pack_bsdos;
|
||||
static int compare_format(const void *, const void *);
|
||||
|
||||
static const char iMajorError[] = "invalid major number";
|
||||
static const char iMinorError[] = "invalid minor number";
|
||||
static const char tooManyFields[] = "too many fields for format";
|
||||
|
||||
/* This is blatantly stolen from libarchive/archive_entry.c,
|
||||
* in an attempt to get this to play nice on MinGW... */
|
||||
#if !defined(HAVE_MAJOR) && !defined(major)
|
||||
/* Replacement for major/minor/makedev. */
|
||||
#define major(x) ((int)(0x00ff & ((x) >> 8)))
|
||||
#define minor(x) ((int)(0xffff00ff & (x)))
|
||||
#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min)))
|
||||
#endif
|
||||
|
||||
/* Play games to come up with a suitable makedev() definition. */
|
||||
#ifdef __QNXNTO__
|
||||
/* QNX. <sigh> */
|
||||
#include <sys/netmgr.h>
|
||||
#define apd_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min))
|
||||
#elif defined makedev
|
||||
/* There's a "makedev" macro. */
|
||||
#define apd_makedev(maj, min) makedev((maj), (min))
|
||||
#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__))
|
||||
/* Windows. <sigh> */
|
||||
#define apd_makedev(maj, min) mkdev((maj), (min))
|
||||
#else
|
||||
/* There's a "makedev" function. */
|
||||
#define apd_makedev(maj, min) makedev((maj), (min))
|
||||
#endif
|
||||
|
||||
/* exported */
|
||||
dev_t
|
||||
pack_native(int n, unsigned long numbers[], const char **error)
|
||||
{
|
||||
dev_t dev = 0;
|
||||
|
||||
if (n == 2) {
|
||||
dev = apd_makedev(numbers[0], numbers[1]);
|
||||
if ((unsigned long)major(dev) != numbers[0])
|
||||
*error = iMajorError;
|
||||
else if ((unsigned long)minor(dev) != numbers[1])
|
||||
*error = iMinorError;
|
||||
} else
|
||||
*error = tooManyFields;
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
static dev_t
|
||||
pack_netbsd(int n, unsigned long numbers[], const char **error)
|
||||
{
|
||||
dev_t dev = 0;
|
||||
|
||||
if (n == 2) {
|
||||
dev = makedev_netbsd(numbers[0], numbers[1]);
|
||||
if ((unsigned long)major_netbsd(dev) != numbers[0])
|
||||
*error = iMajorError;
|
||||
else if ((unsigned long)minor_netbsd(dev) != numbers[1])
|
||||
*error = iMinorError;
|
||||
} else
|
||||
*error = tooManyFields;
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
#define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
|
||||
#define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0))
|
||||
#define makedev_freebsd(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \
|
||||
(((y) << 0) & 0xffff00ff)))
|
||||
|
||||
static dev_t
|
||||
pack_freebsd(int n, unsigned long numbers[], const char **error)
|
||||
{
|
||||
dev_t dev = 0;
|
||||
|
||||
if (n == 2) {
|
||||
dev = makedev_freebsd(numbers[0], numbers[1]);
|
||||
if ((unsigned long)major_freebsd(dev) != numbers[0])
|
||||
*error = iMajorError;
|
||||
if ((unsigned long)minor_freebsd(dev) != numbers[1])
|
||||
*error = iMinorError;
|
||||
} else
|
||||
*error = tooManyFields;
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
#define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
|
||||
#define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
|
||||
#define makedev_8_8(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \
|
||||
(((y) << 0) & 0x000000ff)))
|
||||
|
||||
static dev_t
|
||||
pack_8_8(int n, unsigned long numbers[], const char **error)
|
||||
{
|
||||
dev_t dev = 0;
|
||||
|
||||
if (n == 2) {
|
||||
dev = makedev_8_8(numbers[0], numbers[1]);
|
||||
if ((unsigned long)major_8_8(dev) != numbers[0])
|
||||
*error = iMajorError;
|
||||
if ((unsigned long)minor_8_8(dev) != numbers[1])
|
||||
*error = iMinorError;
|
||||
} else
|
||||
*error = tooManyFields;
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
#define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20))
|
||||
#define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0))
|
||||
#define makedev_12_20(x,y) ((dev_t)((((x) << 20) & 0xfff00000) | \
|
||||
(((y) << 0) & 0x000fffff)))
|
||||
|
||||
static dev_t
|
||||
pack_12_20(int n, unsigned long numbers[], const char **error)
|
||||
{
|
||||
dev_t dev = 0;
|
||||
|
||||
if (n == 2) {
|
||||
dev = makedev_12_20(numbers[0], numbers[1]);
|
||||
if ((unsigned long)major_12_20(dev) != numbers[0])
|
||||
*error = iMajorError;
|
||||
if ((unsigned long)minor_12_20(dev) != numbers[1])
|
||||
*error = iMinorError;
|
||||
} else
|
||||
*error = tooManyFields;
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
#define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18))
|
||||
#define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0))
|
||||
#define makedev_14_18(x,y) ((dev_t)((((x) << 18) & 0xfffc0000) | \
|
||||
(((y) << 0) & 0x0003ffff)))
|
||||
|
||||
static dev_t
|
||||
pack_14_18(int n, unsigned long numbers[], const char **error)
|
||||
{
|
||||
dev_t dev = 0;
|
||||
|
||||
if (n == 2) {
|
||||
dev = makedev_14_18(numbers[0], numbers[1]);
|
||||
if ((unsigned long)major_14_18(dev) != numbers[0])
|
||||
*error = iMajorError;
|
||||
if ((unsigned long)minor_14_18(dev) != numbers[1])
|
||||
*error = iMinorError;
|
||||
} else
|
||||
*error = tooManyFields;
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
#define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24))
|
||||
#define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0))
|
||||
#define makedev_8_24(x,y) ((dev_t)((((x) << 24) & 0xff000000) | \
|
||||
(((y) << 0) & 0x00ffffff)))
|
||||
|
||||
static dev_t
|
||||
pack_8_24(int n, unsigned long numbers[], const char **error)
|
||||
{
|
||||
dev_t dev = 0;
|
||||
|
||||
if (n == 2) {
|
||||
dev = makedev_8_24(numbers[0], numbers[1]);
|
||||
if ((unsigned long)major_8_24(dev) != numbers[0])
|
||||
*error = iMajorError;
|
||||
if ((unsigned long)minor_8_24(dev) != numbers[1])
|
||||
*error = iMinorError;
|
||||
} else
|
||||
*error = tooManyFields;
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
#define major_12_12_8(x) ((int32_t)(((x) & 0xfff00000) >> 20))
|
||||
#define unit_12_12_8(x) ((int32_t)(((x) & 0x000fff00) >> 8))
|
||||
#define subunit_12_12_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
|
||||
#define makedev_12_12_8(x,y,z) ((dev_t)((((x) << 20) & 0xfff00000) | \
|
||||
(((y) << 8) & 0x000fff00) | \
|
||||
(((z) << 0) & 0x000000ff)))
|
||||
|
||||
static dev_t
|
||||
pack_bsdos(int n, unsigned long numbers[], const char **error)
|
||||
{
|
||||
dev_t dev = 0;
|
||||
|
||||
if (n == 2) {
|
||||
dev = makedev_12_20(numbers[0], numbers[1]);
|
||||
if ((unsigned long)major_12_20(dev) != numbers[0])
|
||||
*error = iMajorError;
|
||||
if ((unsigned long)minor_12_20(dev) != numbers[1])
|
||||
*error = iMinorError;
|
||||
} else if (n == 3) {
|
||||
dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]);
|
||||
if ((unsigned long)major_12_12_8(dev) != numbers[0])
|
||||
*error = iMajorError;
|
||||
if ((unsigned long)unit_12_12_8(dev) != numbers[1])
|
||||
*error = "invalid unit number";
|
||||
if ((unsigned long)subunit_12_12_8(dev) != numbers[2])
|
||||
*error = "invalid subunit number";
|
||||
} else
|
||||
*error = tooManyFields;
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
/* list of formats and pack functions */
|
||||
/* this list must be sorted lexically */
|
||||
static const struct format {
|
||||
const char *name;
|
||||
pack_t *pack;
|
||||
} formats[] = {
|
||||
{"386bsd", pack_8_8},
|
||||
{"4bsd", pack_8_8},
|
||||
{"bsdos", pack_bsdos},
|
||||
{"freebsd", pack_freebsd},
|
||||
{"hpux", pack_8_24},
|
||||
{"isc", pack_8_8},
|
||||
{"linux", pack_8_8},
|
||||
{"native", pack_native},
|
||||
{"netbsd", pack_netbsd},
|
||||
{"osf1", pack_12_20},
|
||||
{"sco", pack_8_8},
|
||||
{"solaris", pack_14_18},
|
||||
{"sunos", pack_8_8},
|
||||
{"svr3", pack_8_8},
|
||||
{"svr4", pack_14_18},
|
||||
{"ultrix", pack_8_8},
|
||||
};
|
||||
|
||||
static int
|
||||
compare_format(const void *key, const void *element)
|
||||
{
|
||||
const char *name;
|
||||
const struct format *format;
|
||||
|
||||
name = key;
|
||||
format = element;
|
||||
|
||||
return (strcmp(name, format->name));
|
||||
}
|
||||
|
||||
|
||||
pack_t *
|
||||
pack_find(const char *name)
|
||||
{
|
||||
struct format *format;
|
||||
|
||||
format = bsearch(name, formats,
|
||||
sizeof(formats)/sizeof(formats[0]),
|
||||
sizeof(formats[0]), compare_format);
|
||||
if (format == 0)
|
||||
return (NULL);
|
||||
return (format->pack);
|
||||
}
|
49
dependencies/libarchive-3.4.2/libarchive/archive_pack_dev.h
vendored
Normal file
49
dependencies/libarchive-3.4.2/libarchive/archive_pack_dev.h
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* $NetBSD: pack_dev.h,v 1.8 2013/06/14 16:28:20 tsutsui Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Charles M. Hannum.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Originally from NetBSD's mknod(8) source. */
|
||||
|
||||
#ifndef ARCHIVE_PACK_DEV_H
|
||||
#define ARCHIVE_PACK_DEV_H
|
||||
|
||||
typedef dev_t pack_t(int, unsigned long [], const char **);
|
||||
|
||||
pack_t *pack_find(const char *);
|
||||
pack_t pack_native;
|
||||
|
||||
#define major_netbsd(x) ((int32_t)((((x) & 0x000fff00) >> 8)))
|
||||
#define minor_netbsd(x) ((int32_t)((((x) & 0xfff00000) >> 12) | \
|
||||
(((x) & 0x000000ff) >> 0)))
|
||||
#define makedev_netbsd(x,y) ((dev_t)((((x) << 8) & 0x000fff00) | \
|
||||
(((y) << 12) & 0xfff00000) | \
|
||||
(((y) << 0) & 0x000000ff)))
|
||||
|
||||
#endif /* ARCHIVE_PACK_DEV_H */
|
459
dependencies/libarchive-3.4.2/libarchive/archive_pathmatch.c
vendored
Normal file
459
dependencies/libarchive-3.4.2/libarchive/archive_pathmatch.c
vendored
Normal file
|
@ -0,0 +1,459 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_WCHAR_H
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "archive_pathmatch.h"
|
||||
|
||||
/*
|
||||
* Check whether a character 'c' is matched by a list specification [...]:
|
||||
* * Leading '!' or '^' negates the class.
|
||||
* * <char>-<char> is a range of characters
|
||||
* * \<char> removes any special meaning for <char>
|
||||
*
|
||||
* Some interesting boundary cases:
|
||||
* a-d-e is one range (a-d) followed by two single characters - and e.
|
||||
* \a-\d is same as a-d
|
||||
* a\-d is three single characters: a, d, -
|
||||
* Trailing - is not special (so [a-] is two characters a and -).
|
||||
* Initial - is not special ([a-] is same as [-a] is same as [\\-a])
|
||||
* This function never sees a trailing \.
|
||||
* [] always fails
|
||||
* [!] always succeeds
|
||||
*/
|
||||
static int
|
||||
pm_list(const char *start, const char *end, const char c, int flags)
|
||||
{
|
||||
const char *p = start;
|
||||
char rangeStart = '\0', nextRangeStart;
|
||||
int match = 1, nomatch = 0;
|
||||
|
||||
/* This will be used soon... */
|
||||
(void)flags; /* UNUSED */
|
||||
|
||||
/* If this is a negated class, return success for nomatch. */
|
||||
if ((*p == '!' || *p == '^') && p < end) {
|
||||
match = 0;
|
||||
nomatch = 1;
|
||||
++p;
|
||||
}
|
||||
|
||||
while (p < end) {
|
||||
nextRangeStart = '\0';
|
||||
switch (*p) {
|
||||
case '-':
|
||||
/* Trailing or initial '-' is not special. */
|
||||
if ((rangeStart == '\0') || (p == end - 1)) {
|
||||
if (*p == c)
|
||||
return (match);
|
||||
} else {
|
||||
char rangeEnd = *++p;
|
||||
if (rangeEnd == '\\')
|
||||
rangeEnd = *++p;
|
||||
if ((rangeStart <= c) && (c <= rangeEnd))
|
||||
return (match);
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
++p;
|
||||
/* Fall through */
|
||||
default:
|
||||
if (*p == c)
|
||||
return (match);
|
||||
nextRangeStart = *p; /* Possible start of range. */
|
||||
}
|
||||
rangeStart = nextRangeStart;
|
||||
++p;
|
||||
}
|
||||
return (nomatch);
|
||||
}
|
||||
|
||||
static int
|
||||
pm_list_w(const wchar_t *start, const wchar_t *end, const wchar_t c, int flags)
|
||||
{
|
||||
const wchar_t *p = start;
|
||||
wchar_t rangeStart = L'\0', nextRangeStart;
|
||||
int match = 1, nomatch = 0;
|
||||
|
||||
/* This will be used soon... */
|
||||
(void)flags; /* UNUSED */
|
||||
|
||||
/* If this is a negated class, return success for nomatch. */
|
||||
if ((*p == L'!' || *p == L'^') && p < end) {
|
||||
match = 0;
|
||||
nomatch = 1;
|
||||
++p;
|
||||
}
|
||||
|
||||
while (p < end) {
|
||||
nextRangeStart = L'\0';
|
||||
switch (*p) {
|
||||
case L'-':
|
||||
/* Trailing or initial '-' is not special. */
|
||||
if ((rangeStart == L'\0') || (p == end - 1)) {
|
||||
if (*p == c)
|
||||
return (match);
|
||||
} else {
|
||||
wchar_t rangeEnd = *++p;
|
||||
if (rangeEnd == L'\\')
|
||||
rangeEnd = *++p;
|
||||
if ((rangeStart <= c) && (c <= rangeEnd))
|
||||
return (match);
|
||||
}
|
||||
break;
|
||||
case L'\\':
|
||||
++p;
|
||||
/* Fall through */
|
||||
default:
|
||||
if (*p == c)
|
||||
return (match);
|
||||
nextRangeStart = *p; /* Possible start of range. */
|
||||
}
|
||||
rangeStart = nextRangeStart;
|
||||
++p;
|
||||
}
|
||||
return (nomatch);
|
||||
}
|
||||
|
||||
/*
|
||||
* If s is pointing to "./", ".//", "./././" or the like, skip it.
|
||||
*/
|
||||
static const char *
|
||||
pm_slashskip(const char *s) {
|
||||
while ((*s == '/')
|
||||
|| (s[0] == '.' && s[1] == '/')
|
||||
|| (s[0] == '.' && s[1] == '\0'))
|
||||
++s;
|
||||
return (s);
|
||||
}
|
||||
|
||||
static const wchar_t *
|
||||
pm_slashskip_w(const wchar_t *s) {
|
||||
while ((*s == L'/')
|
||||
|| (s[0] == L'.' && s[1] == L'/')
|
||||
|| (s[0] == L'.' && s[1] == L'\0'))
|
||||
++s;
|
||||
return (s);
|
||||
}
|
||||
|
||||
static int
|
||||
pm(const char *p, const char *s, int flags)
|
||||
{
|
||||
const char *end;
|
||||
|
||||
/*
|
||||
* Ignore leading './', './/', '././', etc.
|
||||
*/
|
||||
if (s[0] == '.' && s[1] == '/')
|
||||
s = pm_slashskip(s + 1);
|
||||
if (p[0] == '.' && p[1] == '/')
|
||||
p = pm_slashskip(p + 1);
|
||||
|
||||
for (;;) {
|
||||
switch (*p) {
|
||||
case '\0':
|
||||
if (s[0] == '/') {
|
||||
if (flags & PATHMATCH_NO_ANCHOR_END)
|
||||
return (1);
|
||||
/* "dir" == "dir/" == "dir/." */
|
||||
s = pm_slashskip(s);
|
||||
}
|
||||
return (*s == '\0');
|
||||
case '?':
|
||||
/* ? always succeeds, unless we hit end of 's' */
|
||||
if (*s == '\0')
|
||||
return (0);
|
||||
break;
|
||||
case '*':
|
||||
/* "*" == "**" == "***" ... */
|
||||
while (*p == '*')
|
||||
++p;
|
||||
/* Trailing '*' always succeeds. */
|
||||
if (*p == '\0')
|
||||
return (1);
|
||||
while (*s) {
|
||||
if (archive_pathmatch(p, s, flags))
|
||||
return (1);
|
||||
++s;
|
||||
}
|
||||
return (0);
|
||||
case '[':
|
||||
/*
|
||||
* Find the end of the [...] character class,
|
||||
* ignoring \] that might occur within the class.
|
||||
*/
|
||||
end = p + 1;
|
||||
while (*end != '\0' && *end != ']') {
|
||||
if (*end == '\\' && end[1] != '\0')
|
||||
++end;
|
||||
++end;
|
||||
}
|
||||
if (*end == ']') {
|
||||
/* We found [...], try to match it. */
|
||||
if (!pm_list(p + 1, end, *s, flags))
|
||||
return (0);
|
||||
p = end; /* Jump to trailing ']' char. */
|
||||
break;
|
||||
} else
|
||||
/* No final ']', so just match '['. */
|
||||
if (*p != *s)
|
||||
return (0);
|
||||
break;
|
||||
case '\\':
|
||||
/* Trailing '\\' matches itself. */
|
||||
if (p[1] == '\0') {
|
||||
if (*s != '\\')
|
||||
return (0);
|
||||
} else {
|
||||
++p;
|
||||
if (*p != *s)
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
if (*s != '/' && *s != '\0')
|
||||
return (0);
|
||||
/* Note: pattern "/\./" won't match "/";
|
||||
* pm_slashskip() correctly stops at backslash. */
|
||||
p = pm_slashskip(p);
|
||||
s = pm_slashskip(s);
|
||||
if (*p == '\0' && (flags & PATHMATCH_NO_ANCHOR_END))
|
||||
return (1);
|
||||
--p; /* Counteract the increment below. */
|
||||
--s;
|
||||
break;
|
||||
case '$':
|
||||
/* '$' is special only at end of pattern and only
|
||||
* if PATHMATCH_NO_ANCHOR_END is specified. */
|
||||
if (p[1] == '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
|
||||
/* "dir" == "dir/" == "dir/." */
|
||||
return (*pm_slashskip(s) == '\0');
|
||||
}
|
||||
/* Otherwise, '$' is not special. */
|
||||
/* FALL THROUGH */
|
||||
default:
|
||||
if (*p != *s)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pm_w(const wchar_t *p, const wchar_t *s, int flags)
|
||||
{
|
||||
const wchar_t *end;
|
||||
|
||||
/*
|
||||
* Ignore leading './', './/', '././', etc.
|
||||
*/
|
||||
if (s[0] == L'.' && s[1] == L'/')
|
||||
s = pm_slashskip_w(s + 1);
|
||||
if (p[0] == L'.' && p[1] == L'/')
|
||||
p = pm_slashskip_w(p + 1);
|
||||
|
||||
for (;;) {
|
||||
switch (*p) {
|
||||
case L'\0':
|
||||
if (s[0] == L'/') {
|
||||
if (flags & PATHMATCH_NO_ANCHOR_END)
|
||||
return (1);
|
||||
/* "dir" == "dir/" == "dir/." */
|
||||
s = pm_slashskip_w(s);
|
||||
}
|
||||
return (*s == L'\0');
|
||||
case L'?':
|
||||
/* ? always succeeds, unless we hit end of 's' */
|
||||
if (*s == L'\0')
|
||||
return (0);
|
||||
break;
|
||||
case L'*':
|
||||
/* "*" == "**" == "***" ... */
|
||||
while (*p == L'*')
|
||||
++p;
|
||||
/* Trailing '*' always succeeds. */
|
||||
if (*p == L'\0')
|
||||
return (1);
|
||||
while (*s) {
|
||||
if (archive_pathmatch_w(p, s, flags))
|
||||
return (1);
|
||||
++s;
|
||||
}
|
||||
return (0);
|
||||
case L'[':
|
||||
/*
|
||||
* Find the end of the [...] character class,
|
||||
* ignoring \] that might occur within the class.
|
||||
*/
|
||||
end = p + 1;
|
||||
while (*end != L'\0' && *end != L']') {
|
||||
if (*end == L'\\' && end[1] != L'\0')
|
||||
++end;
|
||||
++end;
|
||||
}
|
||||
if (*end == L']') {
|
||||
/* We found [...], try to match it. */
|
||||
if (!pm_list_w(p + 1, end, *s, flags))
|
||||
return (0);
|
||||
p = end; /* Jump to trailing ']' char. */
|
||||
break;
|
||||
} else
|
||||
/* No final ']', so just match '['. */
|
||||
if (*p != *s)
|
||||
return (0);
|
||||
break;
|
||||
case L'\\':
|
||||
/* Trailing '\\' matches itself. */
|
||||
if (p[1] == L'\0') {
|
||||
if (*s != L'\\')
|
||||
return (0);
|
||||
} else {
|
||||
++p;
|
||||
if (*p != *s)
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
case L'/':
|
||||
if (*s != L'/' && *s != L'\0')
|
||||
return (0);
|
||||
/* Note: pattern "/\./" won't match "/";
|
||||
* pm_slashskip() correctly stops at backslash. */
|
||||
p = pm_slashskip_w(p);
|
||||
s = pm_slashskip_w(s);
|
||||
if (*p == L'\0' && (flags & PATHMATCH_NO_ANCHOR_END))
|
||||
return (1);
|
||||
--p; /* Counteract the increment below. */
|
||||
--s;
|
||||
break;
|
||||
case L'$':
|
||||
/* '$' is special only at end of pattern and only
|
||||
* if PATHMATCH_NO_ANCHOR_END is specified. */
|
||||
if (p[1] == L'\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
|
||||
/* "dir" == "dir/" == "dir/." */
|
||||
return (*pm_slashskip_w(s) == L'\0');
|
||||
}
|
||||
/* Otherwise, '$' is not special. */
|
||||
/* FALL THROUGH */
|
||||
default:
|
||||
if (*p != *s)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
/* Main entry point. */
|
||||
int
|
||||
__archive_pathmatch(const char *p, const char *s, int flags)
|
||||
{
|
||||
/* Empty pattern only matches the empty string. */
|
||||
if (p == NULL || *p == '\0')
|
||||
return (s == NULL || *s == '\0');
|
||||
|
||||
/* Leading '^' anchors the start of the pattern. */
|
||||
if (*p == '^') {
|
||||
++p;
|
||||
flags &= ~PATHMATCH_NO_ANCHOR_START;
|
||||
}
|
||||
|
||||
if (*p == '/' && *s != '/')
|
||||
return (0);
|
||||
|
||||
/* Certain patterns anchor implicitly. */
|
||||
if (*p == '*' || *p == '/') {
|
||||
while (*p == '/')
|
||||
++p;
|
||||
while (*s == '/')
|
||||
++s;
|
||||
return (pm(p, s, flags));
|
||||
}
|
||||
|
||||
/* If start is unanchored, try to match start of each path element. */
|
||||
if (flags & PATHMATCH_NO_ANCHOR_START) {
|
||||
for ( ; s != NULL; s = strchr(s, '/')) {
|
||||
if (*s == '/')
|
||||
s++;
|
||||
if (pm(p, s, flags))
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Default: Match from beginning. */
|
||||
return (pm(p, s, flags));
|
||||
}
|
||||
|
||||
int
|
||||
__archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags)
|
||||
{
|
||||
/* Empty pattern only matches the empty string. */
|
||||
if (p == NULL || *p == L'\0')
|
||||
return (s == NULL || *s == L'\0');
|
||||
|
||||
/* Leading '^' anchors the start of the pattern. */
|
||||
if (*p == L'^') {
|
||||
++p;
|
||||
flags &= ~PATHMATCH_NO_ANCHOR_START;
|
||||
}
|
||||
|
||||
if (*p == L'/' && *s != L'/')
|
||||
return (0);
|
||||
|
||||
/* Certain patterns anchor implicitly. */
|
||||
if (*p == L'*' || *p == L'/') {
|
||||
while (*p == L'/')
|
||||
++p;
|
||||
while (*s == L'/')
|
||||
++s;
|
||||
return (pm_w(p, s, flags));
|
||||
}
|
||||
|
||||
/* If start is unanchored, try to match start of each path element. */
|
||||
if (flags & PATHMATCH_NO_ANCHOR_START) {
|
||||
for ( ; s != NULL; s = wcschr(s, L'/')) {
|
||||
if (*s == L'/')
|
||||
s++;
|
||||
if (pm_w(p, s, flags))
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Default: Match from beginning. */
|
||||
return (pm_w(p, s, flags));
|
||||
}
|
52
dependencies/libarchive-3.4.2/libarchive/archive_pathmatch.h
vendored
Normal file
52
dependencies/libarchive-3.4.2/libarchive/archive_pathmatch.h
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_PATHMATCH_H
|
||||
#define ARCHIVE_PATHMATCH_H
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Don't anchor at beginning unless the pattern starts with "^" */
|
||||
#define PATHMATCH_NO_ANCHOR_START 1
|
||||
/* Don't anchor at end unless the pattern ends with "$" */
|
||||
#define PATHMATCH_NO_ANCHOR_END 2
|
||||
|
||||
/* Note that "^" and "$" are not special unless you set the corresponding
|
||||
* flag above. */
|
||||
|
||||
int __archive_pathmatch(const char *p, const char *s, int flags);
|
||||
int __archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags);
|
||||
|
||||
#define archive_pathmatch(p, s, f) __archive_pathmatch(p, s, f)
|
||||
#define archive_pathmatch_w(p, s, f) __archive_pathmatch_w(p, s, f)
|
||||
|
||||
#endif
|
202
dependencies/libarchive-3.4.2/libarchive/archive_platform.h
vendored
Normal file
202
dependencies/libarchive-3.4.2/libarchive/archive_platform.h
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: head/lib/libarchive/archive_platform.h 201090 2009-12-28 02:22:04Z kientzle $
|
||||
*/
|
||||
|
||||
/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
|
||||
|
||||
/*
|
||||
* This header is the first thing included in any of the libarchive
|
||||
* source files. As far as possible, platform-specific issues should
|
||||
* be dealt with here and not within individual source files. I'm
|
||||
* actively trying to minimize #if blocks within the main source,
|
||||
* since they obfuscate the code.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_PLATFORM_H_INCLUDED
|
||||
#define ARCHIVE_PLATFORM_H_INCLUDED
|
||||
|
||||
/* archive.h and archive_entry.h require this. */
|
||||
#define __LIBARCHIVE_BUILD 1
|
||||
|
||||
#if defined(PLATFORM_CONFIG_H)
|
||||
/* Use hand-built config.h in environments that need it. */
|
||||
#include PLATFORM_CONFIG_H
|
||||
#elif defined(HAVE_CONFIG_H)
|
||||
/* Most POSIX platforms use the 'configure' script to build config.h */
|
||||
#include "config.h"
|
||||
#else
|
||||
/* Warn if the library hasn't been (automatically or manually) configured. */
|
||||
#error Oops: No config.h and no pre-built configuration in archive_platform.h.
|
||||
#endif
|
||||
|
||||
/* On macOS check for some symbols based on the deployment target version. */
|
||||
#if defined(__APPLE__)
|
||||
# undef HAVE_FUTIMENS
|
||||
# undef HAVE_UTIMENSAT
|
||||
# include <AvailabilityMacros.h>
|
||||
# if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
|
||||
# define HAVE_FUTIMENS 1
|
||||
# define HAVE_UTIMENSAT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* It should be possible to get rid of this by extending the feature-test
|
||||
* macros to cover Windows API functions, probably along with non-trivial
|
||||
* refactoring of code to find structures that sit more cleanly on top of
|
||||
* either Windows or Posix APIs. */
|
||||
#if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
|
||||
#include "archive_windows.h"
|
||||
#else
|
||||
#define la_stat(path,stref) stat(path,stref)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The config files define a lot of feature macros. The following
|
||||
* uses those macros to select/define replacements and include key
|
||||
* headers as required.
|
||||
*/
|
||||
|
||||
/* Get a real definition for __FBSDID or __RCSID if we can */
|
||||
#if HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
/* If not, define them so as to avoid dangling semicolons. */
|
||||
#ifndef __FBSDID
|
||||
#define __FBSDID(a) struct _undefined_hack
|
||||
#endif
|
||||
#ifndef __RCSID
|
||||
#define __RCSID(a) struct _undefined_hack
|
||||
#endif
|
||||
|
||||
/* Try to get standard C99-style integer type definitions. */
|
||||
#if HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#if HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* Borland warns about its own constants! */
|
||||
#if defined(__BORLANDC__)
|
||||
# if HAVE_DECL_UINT64_MAX
|
||||
# undef UINT64_MAX
|
||||
# undef HAVE_DECL_UINT64_MAX
|
||||
# endif
|
||||
# if HAVE_DECL_UINT64_MIN
|
||||
# undef UINT64_MIN
|
||||
# undef HAVE_DECL_UINT64_MIN
|
||||
# endif
|
||||
# if HAVE_DECL_INT64_MAX
|
||||
# undef INT64_MAX
|
||||
# undef HAVE_DECL_INT64_MAX
|
||||
# endif
|
||||
# if HAVE_DECL_INT64_MIN
|
||||
# undef INT64_MIN
|
||||
# undef HAVE_DECL_INT64_MIN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some platforms lack the standard *_MAX definitions. */
|
||||
#if !HAVE_DECL_SIZE_MAX
|
||||
#define SIZE_MAX (~(size_t)0)
|
||||
#endif
|
||||
#if !HAVE_DECL_SSIZE_MAX
|
||||
#define SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1))
|
||||
#endif
|
||||
#if !HAVE_DECL_UINT32_MAX
|
||||
#define UINT32_MAX (~(uint32_t)0)
|
||||
#endif
|
||||
#if !HAVE_DECL_INT32_MAX
|
||||
#define INT32_MAX ((int32_t)(UINT32_MAX >> 1))
|
||||
#endif
|
||||
#if !HAVE_DECL_INT32_MIN
|
||||
#define INT32_MIN ((int32_t)(~INT32_MAX))
|
||||
#endif
|
||||
#if !HAVE_DECL_UINT64_MAX
|
||||
#define UINT64_MAX (~(uint64_t)0)
|
||||
#endif
|
||||
#if !HAVE_DECL_INT64_MAX
|
||||
#define INT64_MAX ((int64_t)(UINT64_MAX >> 1))
|
||||
#endif
|
||||
#if !HAVE_DECL_INT64_MIN
|
||||
#define INT64_MIN ((int64_t)(~INT64_MAX))
|
||||
#endif
|
||||
#if !HAVE_DECL_UINTMAX_MAX
|
||||
#define UINTMAX_MAX (~(uintmax_t)0)
|
||||
#endif
|
||||
#if !HAVE_DECL_INTMAX_MAX
|
||||
#define INTMAX_MAX ((intmax_t)(UINTMAX_MAX >> 1))
|
||||
#endif
|
||||
#if !HAVE_DECL_INTMAX_MIN
|
||||
#define INTMAX_MIN ((intmax_t)(~INTMAX_MAX))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we can't restore metadata using a file descriptor, then
|
||||
* for compatibility's sake, close files before trying to restore metadata.
|
||||
*/
|
||||
#if defined(HAVE_FCHMOD) || defined(HAVE_FUTIMES) || defined(HAVE_ACL_SET_FD) || defined(HAVE_ACL_SET_FD_NP) || defined(HAVE_FCHOWN)
|
||||
#define CAN_RESTORE_METADATA_FD
|
||||
#endif
|
||||
|
||||
/*
|
||||
* glibc 2.24 deprecates readdir_r
|
||||
*/
|
||||
#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24))
|
||||
#define USE_READDIR_R 1
|
||||
#else
|
||||
#undef USE_READDIR_R
|
||||
#endif
|
||||
|
||||
/* Set up defaults for internal error codes. */
|
||||
#ifndef ARCHIVE_ERRNO_FILE_FORMAT
|
||||
#if HAVE_EFTYPE
|
||||
#define ARCHIVE_ERRNO_FILE_FORMAT EFTYPE
|
||||
#else
|
||||
#if HAVE_EILSEQ
|
||||
#define ARCHIVE_ERRNO_FILE_FORMAT EILSEQ
|
||||
#else
|
||||
#define ARCHIVE_ERRNO_FILE_FORMAT EINVAL
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_ERRNO_PROGRAMMER
|
||||
#define ARCHIVE_ERRNO_PROGRAMMER EINVAL
|
||||
#endif
|
||||
|
||||
#ifndef ARCHIVE_ERRNO_MISC
|
||||
#define ARCHIVE_ERRNO_MISC (-1)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 7)
|
||||
#define __LA_FALLTHROUGH __attribute__((fallthrough))
|
||||
#else
|
||||
#define __LA_FALLTHROUGH
|
||||
#endif
|
||||
|
||||
#endif /* !ARCHIVE_PLATFORM_H_INCLUDED */
|
55
dependencies/libarchive-3.4.2/libarchive/archive_platform_acl.h
vendored
Normal file
55
dependencies/libarchive-3.4.2/libarchive/archive_platform_acl.h
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*-
|
||||
* Copyright (c) 2017 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
|
||||
|
||||
#ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED
|
||||
#define ARCHIVE_PLATFORM_ACL_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST_COMMON
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Determine what ACL types are supported
|
||||
*/
|
||||
#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_SUNOS || ARCHIVE_ACL_LIBACL
|
||||
#define ARCHIVE_ACL_POSIX1E 1
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_SUNOS_NFS4 || \
|
||||
ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
|
||||
#define ARCHIVE_ACL_NFS4 1
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_POSIX1E || ARCHIVE_ACL_NFS4
|
||||
#define ARCHIVE_ACL_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#endif /* ARCHIVE_PLATFORM_ACL_H_INCLUDED */
|
47
dependencies/libarchive-3.4.2/libarchive/archive_platform_xattr.h
vendored
Normal file
47
dependencies/libarchive-3.4.2/libarchive/archive_platform_xattr.h
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-
|
||||
* Copyright (c) 2017 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
|
||||
|
||||
#ifndef ARCHIVE_PLATFORM_XATTR_H_INCLUDED
|
||||
#define ARCHIVE_PLATFORM_XATTR_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST_COMMON
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Determine if we support extended attributes
|
||||
*/
|
||||
#if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_FREEBSD || \
|
||||
ARCHIVE_XATTR_AIX
|
||||
#define ARCHIVE_XATTR_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#endif /* ARCHIVE_PLATFORM_XATTR_H_INCLUDED */
|
1168
dependencies/libarchive-3.4.2/libarchive/archive_ppmd7.c
vendored
Normal file
1168
dependencies/libarchive-3.4.2/libarchive/archive_ppmd7.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
119
dependencies/libarchive-3.4.2/libarchive/archive_ppmd7_private.h
vendored
Normal file
119
dependencies/libarchive-3.4.2/libarchive/archive_ppmd7_private.h
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* Ppmd7.h -- PPMdH compression codec
|
||||
2010-03-12 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
/* This code supports virtual RangeDecoder and includes the implementation
|
||||
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
|
||||
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
|
||||
|
||||
#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include "archive_ppmd_private.h"
|
||||
|
||||
#define PPMD7_MIN_ORDER 2
|
||||
#define PPMD7_MAX_ORDER 64
|
||||
|
||||
#define PPMD7_MIN_MEM_SIZE (1 << 11)
|
||||
#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFFu - 12 * 3)
|
||||
|
||||
struct CPpmd7_Context_;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
struct CPpmd7_Context_ *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd7_Context_Ref;
|
||||
|
||||
typedef struct CPpmd7_Context_
|
||||
{
|
||||
UInt16 NumStats;
|
||||
UInt16 SummFreq;
|
||||
CPpmd_State_Ref Stats;
|
||||
CPpmd7_Context_Ref Suffix;
|
||||
} CPpmd7_Context;
|
||||
|
||||
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CPpmd7_Context *MinContext, *MaxContext;
|
||||
CPpmd_State *FoundState;
|
||||
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
|
||||
Int32 RunLength, InitRL; /* must be 32-bit at least */
|
||||
|
||||
UInt32 Size;
|
||||
UInt32 GlueCount;
|
||||
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
|
||||
UInt32 AlignOffset;
|
||||
|
||||
Byte Indx2Units[PPMD_NUM_INDEXES];
|
||||
Byte Units2Indx[128];
|
||||
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
|
||||
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
|
||||
CPpmd_See DummySee, See[25][16];
|
||||
UInt16 BinSumm[128][64];
|
||||
} CPpmd7;
|
||||
|
||||
/* ---------- Decode ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 (*GetThreshold)(void *p, UInt32 total);
|
||||
void (*Decode)(void *p, UInt32 start, UInt32 size);
|
||||
UInt32 (*DecodeBit)(void *p, UInt32 size0);
|
||||
} IPpmd7_RangeDec;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IPpmd7_RangeDec p;
|
||||
UInt32 Range;
|
||||
UInt32 Code;
|
||||
UInt32 Low;
|
||||
UInt32 Bottom;
|
||||
IByteIn *Stream;
|
||||
} CPpmd7z_RangeDec;
|
||||
|
||||
/* ---------- Encode ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt64 Low;
|
||||
UInt32 Range;
|
||||
Byte Cache;
|
||||
UInt64 CacheSize;
|
||||
IByteOut *Stream;
|
||||
} CPpmd7z_RangeEnc;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Base Functions */
|
||||
void (*Ppmd7_Construct)(CPpmd7 *p);
|
||||
Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size);
|
||||
void (*Ppmd7_Free)(CPpmd7 *p);
|
||||
void (*Ppmd7_Init)(CPpmd7 *p, unsigned maxOrder);
|
||||
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
||||
|
||||
/* Decode Functions */
|
||||
void (*Ppmd7z_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
|
||||
void (*PpmdRAR_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
|
||||
Bool (*Ppmd7z_RangeDec_Init)(CPpmd7z_RangeDec *p);
|
||||
Bool (*PpmdRAR_RangeDec_Init)(CPpmd7z_RangeDec *p);
|
||||
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
||||
int (*Ppmd7_DecodeSymbol)(CPpmd7 *p, IPpmd7_RangeDec *rc);
|
||||
|
||||
/* Encode Functions */
|
||||
void (*Ppmd7z_RangeEnc_Init)(CPpmd7z_RangeEnc *p);
|
||||
void (*Ppmd7z_RangeEnc_FlushData)(CPpmd7z_RangeEnc *p);
|
||||
|
||||
void (*Ppmd7_EncodeSymbol)(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
|
||||
} IPpmd7;
|
||||
|
||||
extern const IPpmd7 __archive_ppmd7_functions;
|
||||
#endif
|
1287
dependencies/libarchive-3.4.2/libarchive/archive_ppmd8.c
vendored
Normal file
1287
dependencies/libarchive-3.4.2/libarchive/archive_ppmd8.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
148
dependencies/libarchive-3.4.2/libarchive/archive_ppmd8_private.h
vendored
Normal file
148
dependencies/libarchive-3.4.2/libarchive/archive_ppmd8_private.h
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
/* Ppmd8.h -- PPMdI codec
|
||||
2011-01-27 : Igor Pavlov : Public domain
|
||||
This code is based on:
|
||||
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
||||
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||
|
||||
#ifndef ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive_ppmd_private.h"
|
||||
|
||||
#define PPMD8_MIN_ORDER 2
|
||||
#define PPMD8_MAX_ORDER 16
|
||||
|
||||
struct CPpmd8_Context_;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
struct CPpmd8_Context_ *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd8_Context_Ref;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct CPpmd8_Context_
|
||||
{
|
||||
Byte NumStats;
|
||||
Byte Flags;
|
||||
UInt16 SummFreq;
|
||||
CPpmd_State_Ref Stats;
|
||||
CPpmd8_Context_Ref Suffix;
|
||||
} CPpmd8_Context;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
|
||||
|
||||
/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
|
||||
code is not compatible with original code for some files compressed
|
||||
in FREEZE mode. So we disable FREEZE mode support. */
|
||||
|
||||
enum
|
||||
{
|
||||
PPMD8_RESTORE_METHOD_RESTART,
|
||||
PPMD8_RESTORE_METHOD_CUT_OFF
|
||||
#ifdef PPMD8_FREEZE_SUPPORT
|
||||
, PPMD8_RESTORE_METHOD_FREEZE
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CPpmd8_Context *MinContext, *MaxContext;
|
||||
CPpmd_State *FoundState;
|
||||
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder;
|
||||
Int32 RunLength, InitRL; /* must be 32-bit at least */
|
||||
|
||||
UInt32 Size;
|
||||
UInt32 GlueCount;
|
||||
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
|
||||
UInt32 AlignOffset;
|
||||
unsigned RestoreMethod;
|
||||
|
||||
/* Range Coder */
|
||||
UInt32 Range;
|
||||
UInt32 Code;
|
||||
UInt32 Low;
|
||||
union
|
||||
{
|
||||
IByteIn *In;
|
||||
IByteOut *Out;
|
||||
} Stream;
|
||||
|
||||
Byte Indx2Units[PPMD_NUM_INDEXES];
|
||||
Byte Units2Indx[128];
|
||||
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
|
||||
UInt32 Stamps[PPMD_NUM_INDEXES];
|
||||
|
||||
Byte NS2BSIndx[256], NS2Indx[260];
|
||||
CPpmd_See DummySee, See[24][32];
|
||||
UInt16 BinSumm[25][64];
|
||||
} CPpmd8;
|
||||
|
||||
void Ppmd8_Construct(CPpmd8 *p);
|
||||
Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size);
|
||||
void Ppmd8_Free(CPpmd8 *p);
|
||||
void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
|
||||
#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
|
||||
|
||||
|
||||
/* ---------- Internal Functions ---------- */
|
||||
|
||||
extern const Byte PPMD8_kExpEscape[16];
|
||||
|
||||
#ifdef PPMD_32BIT
|
||||
#define Ppmd8_GetPtr(p, ptr) (ptr)
|
||||
#define Ppmd8_GetContext(p, ptr) (ptr)
|
||||
#define Ppmd8_GetStats(p, ctx) ((ctx)->Stats)
|
||||
#else
|
||||
#define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
|
||||
#define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs)))
|
||||
#define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats)))
|
||||
#endif
|
||||
|
||||
void Ppmd8_Update1(CPpmd8 *p);
|
||||
void Ppmd8_Update1_0(CPpmd8 *p);
|
||||
void Ppmd8_Update2(CPpmd8 *p);
|
||||
void Ppmd8_UpdateBin(CPpmd8 *p);
|
||||
|
||||
#define Ppmd8_GetBinSumm(p) \
|
||||
&p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
|
||||
p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
|
||||
p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
|
||||
|
||||
CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
|
||||
|
||||
|
||||
/* ---------- Decode ---------- */
|
||||
|
||||
Bool Ppmd8_RangeDec_Init(CPpmd8 *p);
|
||||
#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
||||
int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */
|
||||
|
||||
/* ---------- Encode ---------- */
|
||||
|
||||
#define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
|
||||
void Ppmd8_RangeEnc_FlushData(CPpmd8 *p);
|
||||
void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Base Functions */
|
||||
void (*Ppmd8_Construct)(CPpmd8 *p);
|
||||
Bool (*Ppmd8_Alloc)(CPpmd8 *p, UInt32 size);
|
||||
void (*Ppmd8_Free)(CPpmd8 *p);
|
||||
void (*Ppmd8_Init)(CPpmd8 *p, unsigned max_order, unsigned restore_method);
|
||||
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
||||
|
||||
/* Decode Functions */
|
||||
int (*Ppmd8_RangeDec_Init)(CPpmd8 *p);
|
||||
int (*Ppmd8_DecodeSymbol)(CPpmd8 *p);
|
||||
} IPpmd8;
|
||||
|
||||
extern const IPpmd8 __archive_ppmd8_functions;
|
||||
|
||||
#endif
|
151
dependencies/libarchive-3.4.2/libarchive/archive_ppmd_private.h
vendored
Normal file
151
dependencies/libarchive-3.4.2/libarchive/archive_ppmd_private.h
vendored
Normal file
|
@ -0,0 +1,151 @@
|
|||
/* Ppmd.h -- PPMD codec common code
|
||||
2010-03-12 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "archive_read_private.h"
|
||||
|
||||
/*** Begin defined in Types.h ***/
|
||||
|
||||
#if !defined(ZCONF_H)
|
||||
typedef unsigned char Byte;
|
||||
#endif
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#ifdef _LZMA_UINT32_IS_ULONG
|
||||
typedef long Int32;
|
||||
typedef unsigned long UInt32;
|
||||
#else
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
#endif
|
||||
|
||||
#ifdef _SZ_NO_INT_64
|
||||
|
||||
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||
NOTES: Some code will work incorrectly in that case! */
|
||||
|
||||
typedef long Int64;
|
||||
typedef unsigned long UInt64;
|
||||
|
||||
#else
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#define UINT64_CONST(n) n
|
||||
#else
|
||||
typedef long long int Int64;
|
||||
typedef unsigned long long int UInt64;
|
||||
#define UINT64_CONST(n) n ## ULL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
typedef int Bool;
|
||||
#define True 1
|
||||
#define False 0
|
||||
|
||||
/* The following interfaces use first parameter as pointer to structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct archive_read *a;
|
||||
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||
} IByteIn;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct archive_write *a;
|
||||
void (*Write)(void *p, Byte b);
|
||||
} IByteOut;
|
||||
|
||||
/*** End defined in Types.h ***/
|
||||
/*** Begin defined in CpuArch.h ***/
|
||||
|
||||
#if defined(_M_IX86) || defined(__i386__)
|
||||
#define MY_CPU_X86
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86) || defined(_M_ARM)
|
||||
#define MY_CPU_32BIT
|
||||
#endif
|
||||
|
||||
#ifdef MY_CPU_32BIT
|
||||
#define PPMD_32BIT
|
||||
#endif
|
||||
|
||||
/*** End defined in CpuArch.h ***/
|
||||
|
||||
#define PPMD_INT_BITS 7
|
||||
#define PPMD_PERIOD_BITS 7
|
||||
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
|
||||
|
||||
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
|
||||
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
|
||||
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
|
||||
#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
|
||||
|
||||
#define PPMD_N1 4
|
||||
#define PPMD_N2 4
|
||||
#define PPMD_N3 4
|
||||
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
|
||||
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
|
||||
|
||||
/* SEE-contexts for PPM-contexts with masked symbols */
|
||||
typedef struct
|
||||
{
|
||||
UInt16 Summ; /* Freq */
|
||||
Byte Shift; /* Speed of Freq change; low Shift is for fast change */
|
||||
Byte Count; /* Count to next change of Shift */
|
||||
} CPpmd_See;
|
||||
|
||||
#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
|
||||
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte Symbol;
|
||||
Byte Freq;
|
||||
UInt16 SuccessorLow;
|
||||
UInt16 SuccessorHigh;
|
||||
} CPpmd_State;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
CPpmd_State *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd_State_Ref;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
void *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd_Void_Ref;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
Byte *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd_Byte_Ref;
|
||||
|
||||
#define PPMD_SetAllBitsIn256Bytes(p) \
|
||||
{ unsigned j; for (j = 0; j < 256 / sizeof(p[0]); j += 8) { \
|
||||
p[j+7] = p[j+6] = p[j+5] = p[j+4] = p[j+3] = p[j+2] = p[j+1] = p[j+0] = ~(size_t)0; }}
|
||||
|
||||
#endif
|
176
dependencies/libarchive-3.4.2/libarchive/archive_private.h
vendored
Normal file
176
dependencies/libarchive-3.4.2/libarchive/archive_private.h
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: head/lib/libarchive/archive_private.h 201098 2009-12-28 02:58:14Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#if HAVE_ICONV_H
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_string.h"
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2 || \
|
||||
(__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
|
||||
#define __LA_DEAD __attribute__((__noreturn__))
|
||||
#else
|
||||
#define __LA_DEAD
|
||||
#endif
|
||||
|
||||
#define ARCHIVE_WRITE_MAGIC (0xb0c5c0deU)
|
||||
#define ARCHIVE_READ_MAGIC (0xdeb0c5U)
|
||||
#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U)
|
||||
#define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U)
|
||||
#define ARCHIVE_MATCH_MAGIC (0xcad11c9U)
|
||||
|
||||
#define ARCHIVE_STATE_NEW 1U
|
||||
#define ARCHIVE_STATE_HEADER 2U
|
||||
#define ARCHIVE_STATE_DATA 4U
|
||||
#define ARCHIVE_STATE_EOF 0x10U
|
||||
#define ARCHIVE_STATE_CLOSED 0x20U
|
||||
#define ARCHIVE_STATE_FATAL 0x8000U
|
||||
#define ARCHIVE_STATE_ANY (0xFFFFU & ~ARCHIVE_STATE_FATAL)
|
||||
|
||||
struct archive_vtable {
|
||||
int (*archive_close)(struct archive *);
|
||||
int (*archive_free)(struct archive *);
|
||||
int (*archive_write_header)(struct archive *,
|
||||
struct archive_entry *);
|
||||
int (*archive_write_finish_entry)(struct archive *);
|
||||
ssize_t (*archive_write_data)(struct archive *,
|
||||
const void *, size_t);
|
||||
ssize_t (*archive_write_data_block)(struct archive *,
|
||||
const void *, size_t, int64_t);
|
||||
|
||||
int (*archive_read_next_header)(struct archive *,
|
||||
struct archive_entry **);
|
||||
int (*archive_read_next_header2)(struct archive *,
|
||||
struct archive_entry *);
|
||||
int (*archive_read_data_block)(struct archive *,
|
||||
const void **, size_t *, int64_t *);
|
||||
|
||||
int (*archive_filter_count)(struct archive *);
|
||||
int64_t (*archive_filter_bytes)(struct archive *, int);
|
||||
int (*archive_filter_code)(struct archive *, int);
|
||||
const char * (*archive_filter_name)(struct archive *, int);
|
||||
};
|
||||
|
||||
struct archive_string_conv;
|
||||
|
||||
struct archive {
|
||||
/*
|
||||
* The magic/state values are used to sanity-check the
|
||||
* client's usage. If an API function is called at a
|
||||
* ridiculous time, or the client passes us an invalid
|
||||
* pointer, these values allow me to catch that.
|
||||
*/
|
||||
unsigned int magic;
|
||||
unsigned int state;
|
||||
|
||||
/*
|
||||
* Some public API functions depend on the "real" type of the
|
||||
* archive object.
|
||||
*/
|
||||
struct archive_vtable *vtable;
|
||||
|
||||
int archive_format;
|
||||
const char *archive_format_name;
|
||||
|
||||
int compression_code; /* Currently active compression. */
|
||||
const char *compression_name;
|
||||
|
||||
/* Number of file entries processed. */
|
||||
int file_count;
|
||||
|
||||
int archive_error_number;
|
||||
const char *error;
|
||||
struct archive_string error_string;
|
||||
|
||||
char *current_code;
|
||||
unsigned current_codepage; /* Current ACP(ANSI CodePage). */
|
||||
unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */
|
||||
struct archive_string_conv *sconv;
|
||||
|
||||
/*
|
||||
* Used by archive_read_data() to track blocks and copy
|
||||
* data to client buffers, filling gaps with zero bytes.
|
||||
*/
|
||||
const char *read_data_block;
|
||||
int64_t read_data_offset;
|
||||
int64_t read_data_output_offset;
|
||||
size_t read_data_remaining;
|
||||
|
||||
/*
|
||||
* Used by formats/filters to determine the amount of data
|
||||
* requested from a call to archive_read_data(). This is only
|
||||
* useful when the format/filter has seek support.
|
||||
*/
|
||||
char read_data_is_posix_read;
|
||||
size_t read_data_requested;
|
||||
};
|
||||
|
||||
/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
|
||||
int __archive_check_magic(struct archive *, unsigned int magic,
|
||||
unsigned int state, const char *func);
|
||||
#define archive_check_magic(a, expected_magic, allowed_states, function_name) \
|
||||
do { \
|
||||
int magic_test = __archive_check_magic((a), (expected_magic), \
|
||||
(allowed_states), (function_name)); \
|
||||
if (magic_test == ARCHIVE_FATAL) \
|
||||
return ARCHIVE_FATAL; \
|
||||
} while (0)
|
||||
|
||||
void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
|
||||
|
||||
void __archive_ensure_cloexec_flag(int fd);
|
||||
int __archive_mktemp(const char *tmpdir);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
int __archive_mkstemp(wchar_t *template);
|
||||
#else
|
||||
int __archive_mkstemp(char *template);
|
||||
#endif
|
||||
|
||||
int __archive_clean(struct archive *);
|
||||
|
||||
void __archive_reset_read_data(struct archive *);
|
||||
|
||||
#define err_combine(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER <= 1300)
|
||||
# define ARCHIVE_LITERAL_LL(x) x##i64
|
||||
# define ARCHIVE_LITERAL_ULL(x) x##ui64
|
||||
#else
|
||||
# define ARCHIVE_LITERAL_LL(x) x##ll
|
||||
# define ARCHIVE_LITERAL_ULL(x) x##ull
|
||||
#endif
|
||||
|
||||
#endif
|
272
dependencies/libarchive-3.4.2/libarchive/archive_random.c
vendored
Normal file
272
dependencies/libarchive-3.4.2/libarchive/archive_random.c
vendored
Normal file
|
@ -0,0 +1,272 @@
|
|||
/*-
|
||||
* Copyright (c) 2014 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
|
||||
|
||||
#ifdef HAVE_FCNTL
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_PTHREAD_H
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
static void arc4random_buf(void *, size_t);
|
||||
|
||||
#endif /* HAVE_ARC4RANDOM_BUF */
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_random_private.h"
|
||||
|
||||
#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
|
||||
#include <wincrypt.h>
|
||||
#endif
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Random number generator function.
|
||||
* This simply calls arc4random_buf function if the platform provides it.
|
||||
*/
|
||||
|
||||
int
|
||||
archive_random(void *buf, size_t nbytes)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
HCRYPTPROV hProv;
|
||||
BOOL success;
|
||||
|
||||
success = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT);
|
||||
if (!success && GetLastError() == (DWORD)NTE_BAD_KEYSET) {
|
||||
success = CryptAcquireContext(&hProv, NULL, NULL,
|
||||
PROV_RSA_FULL, CRYPT_NEWKEYSET);
|
||||
}
|
||||
if (success) {
|
||||
success = CryptGenRandom(hProv, (DWORD)nbytes, (BYTE*)buf);
|
||||
CryptReleaseContext(hProv, 0);
|
||||
if (success)
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
/* TODO: Does this case really happen? */
|
||||
return ARCHIVE_FAILED;
|
||||
#else
|
||||
arc4random_buf(buf, nbytes);
|
||||
return ARCHIVE_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
|
||||
|
||||
/* $OpenBSD: arc4random.c,v 1.24 2013/06/11 16:59:50 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1996, David Mazieres <dm@uun.org>
|
||||
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Arc4 random number generator for OpenBSD.
|
||||
*
|
||||
* This code is derived from section 17.1 of Applied Cryptography,
|
||||
* second edition, which describes a stream cipher allegedly
|
||||
* compatible with RSA Labs "RC4" cipher (the actual description of
|
||||
* which is a trade secret). The same algorithm is used as a stream
|
||||
* cipher called "arcfour" in Tatu Ylonen's ssh package.
|
||||
*
|
||||
* RC4 is a registered trademark of RSA Laboratories.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define inline __inline
|
||||
#else /* !__GNUC__ */
|
||||
#define inline
|
||||
#endif /* !__GNUC__ */
|
||||
|
||||
struct arc4_stream {
|
||||
uint8_t i;
|
||||
uint8_t j;
|
||||
uint8_t s[256];
|
||||
};
|
||||
|
||||
#define RANDOMDEV "/dev/urandom"
|
||||
#define KEYSIZE 128
|
||||
#ifdef HAVE_PTHREAD_H
|
||||
static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx);
|
||||
#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx);
|
||||
#else
|
||||
#define _ARC4_LOCK()
|
||||
#define _ARC4_UNLOCK()
|
||||
#endif
|
||||
|
||||
static int rs_initialized;
|
||||
static struct arc4_stream rs;
|
||||
static pid_t arc4_stir_pid;
|
||||
static int arc4_count;
|
||||
|
||||
static inline uint8_t arc4_getbyte(void);
|
||||
static void arc4_stir(void);
|
||||
|
||||
static inline void
|
||||
arc4_init(void)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
rs.s[n] = n;
|
||||
rs.i = 0;
|
||||
rs.j = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
arc4_addrandom(u_char *dat, int datlen)
|
||||
{
|
||||
int n;
|
||||
uint8_t si;
|
||||
|
||||
rs.i--;
|
||||
for (n = 0; n < 256; n++) {
|
||||
rs.i = (rs.i + 1);
|
||||
si = rs.s[rs.i];
|
||||
rs.j = (rs.j + si + dat[n % datlen]);
|
||||
rs.s[rs.i] = rs.s[rs.j];
|
||||
rs.s[rs.j] = si;
|
||||
}
|
||||
rs.j = rs.i;
|
||||
}
|
||||
|
||||
static void
|
||||
arc4_stir(void)
|
||||
{
|
||||
int done, fd, i;
|
||||
struct {
|
||||
struct timeval tv;
|
||||
pid_t pid;
|
||||
u_char rnd[KEYSIZE];
|
||||
} rdat;
|
||||
|
||||
if (!rs_initialized) {
|
||||
arc4_init();
|
||||
rs_initialized = 1;
|
||||
}
|
||||
done = 0;
|
||||
fd = open(RANDOMDEV, O_RDONLY | O_CLOEXEC, 0);
|
||||
if (fd >= 0) {
|
||||
if (read(fd, &rdat, KEYSIZE) == KEYSIZE)
|
||||
done = 1;
|
||||
(void)close(fd);
|
||||
}
|
||||
if (!done) {
|
||||
(void)gettimeofday(&rdat.tv, NULL);
|
||||
rdat.pid = getpid();
|
||||
/* We'll just take whatever was on the stack too... */
|
||||
}
|
||||
|
||||
arc4_addrandom((u_char *)&rdat, KEYSIZE);
|
||||
|
||||
/*
|
||||
* Discard early keystream, as per recommendations in:
|
||||
* "(Not So) Random Shuffles of RC4" by Ilya Mironov.
|
||||
* As per the Network Operations Division, cryptographic requirements
|
||||
* published on wikileaks on March 2017.
|
||||
*/
|
||||
|
||||
for (i = 0; i < 3072; i++)
|
||||
(void)arc4_getbyte();
|
||||
arc4_count = 1600000;
|
||||
}
|
||||
|
||||
static void
|
||||
arc4_stir_if_needed(void)
|
||||
{
|
||||
pid_t pid = getpid();
|
||||
|
||||
if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid) {
|
||||
arc4_stir_pid = pid;
|
||||
arc4_stir();
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint8_t
|
||||
arc4_getbyte(void)
|
||||
{
|
||||
uint8_t si, sj;
|
||||
|
||||
rs.i = (rs.i + 1);
|
||||
si = rs.s[rs.i];
|
||||
rs.j = (rs.j + si);
|
||||
sj = rs.s[rs.j];
|
||||
rs.s[rs.i] = sj;
|
||||
rs.s[rs.j] = si;
|
||||
return (rs.s[(si + sj) & 0xff]);
|
||||
}
|
||||
|
||||
static void
|
||||
arc4random_buf(void *_buf, size_t n)
|
||||
{
|
||||
u_char *buf = (u_char *)_buf;
|
||||
_ARC4_LOCK();
|
||||
arc4_stir_if_needed();
|
||||
while (n--) {
|
||||
if (--arc4_count <= 0)
|
||||
arc4_stir();
|
||||
buf[n] = arc4_getbyte();
|
||||
}
|
||||
_ARC4_UNLOCK();
|
||||
}
|
||||
|
||||
#endif /* !HAVE_ARC4RANDOM_BUF */
|
36
dependencies/libarchive-3.4.2/libarchive/archive_random_private.h
vendored
Normal file
36
dependencies/libarchive-3.4.2/libarchive/archive_random_private.h
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*-
|
||||
* Copyright (c) 2014 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
/* Random number generator. */
|
||||
int archive_random(void *buf, size_t nbytes);
|
||||
|
||||
#endif /* ARCHIVE_RANDOM_PRIVATE_H_INCLUDED */
|
709
dependencies/libarchive-3.4.2/libarchive/archive_rb.c
vendored
Normal file
709
dependencies/libarchive-3.4.2/libarchive/archive_rb.c
vendored
Normal file
|
@ -0,0 +1,709 @@
|
|||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Matt Thomas <matt@3am-software.com>.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Based on: NetBSD: rb.c,v 1.6 2010/04/30 13:58:09 joerg Exp
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "archive_rb.h"
|
||||
|
||||
/* Keep in sync with archive_rb.h */
|
||||
#define RB_DIR_LEFT 0
|
||||
#define RB_DIR_RIGHT 1
|
||||
#define RB_DIR_OTHER 1
|
||||
#define rb_left rb_nodes[RB_DIR_LEFT]
|
||||
#define rb_right rb_nodes[RB_DIR_RIGHT]
|
||||
|
||||
#define RB_FLAG_POSITION 0x2
|
||||
#define RB_FLAG_RED 0x1
|
||||
#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED)
|
||||
#define RB_FATHER(rb) \
|
||||
((struct archive_rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
|
||||
#define RB_SET_FATHER(rb, father) \
|
||||
((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
|
||||
|
||||
#define RB_SENTINEL_P(rb) ((rb) == NULL)
|
||||
#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left)
|
||||
#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
|
||||
#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
|
||||
#define RB_CHILDLESS_P(rb) \
|
||||
(RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
|
||||
#define RB_TWOCHILDREN_P(rb) \
|
||||
(!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
|
||||
|
||||
#define RB_POSITION(rb) \
|
||||
(((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
|
||||
#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT)
|
||||
#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT)
|
||||
#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
|
||||
#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
|
||||
#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED))
|
||||
#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED))
|
||||
#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED))
|
||||
#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb))
|
||||
#define RB_SET_POSITION(rb, position) \
|
||||
((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
|
||||
((rb)->rb_info &= ~RB_FLAG_POSITION)))
|
||||
#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
|
||||
#define RB_COPY_PROPERTIES(dst, src) \
|
||||
((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
|
||||
#define RB_SWAP_PROPERTIES(a, b) do { \
|
||||
uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
|
||||
(a)->rb_info ^= xorinfo; \
|
||||
(b)->rb_info ^= xorinfo; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
static void __archive_rb_tree_insert_rebalance(struct archive_rb_tree *,
|
||||
struct archive_rb_node *);
|
||||
static void __archive_rb_tree_removal_rebalance(struct archive_rb_tree *,
|
||||
struct archive_rb_node *, unsigned int);
|
||||
|
||||
#define RB_SENTINEL_NODE NULL
|
||||
|
||||
#define T 1
|
||||
#define F 0
|
||||
|
||||
void
|
||||
__archive_rb_tree_init(struct archive_rb_tree *rbt,
|
||||
const struct archive_rb_tree_ops *ops)
|
||||
{
|
||||
rbt->rbt_ops = ops;
|
||||
*((struct archive_rb_node **)&rbt->rbt_root) = RB_SENTINEL_NODE;
|
||||
}
|
||||
|
||||
struct archive_rb_node *
|
||||
__archive_rb_tree_find_node(struct archive_rb_tree *rbt, const void *key)
|
||||
{
|
||||
archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
|
||||
struct archive_rb_node *parent = rbt->rbt_root;
|
||||
|
||||
while (!RB_SENTINEL_P(parent)) {
|
||||
const signed int diff = (*compare_key)(parent, key);
|
||||
if (diff == 0)
|
||||
return parent;
|
||||
parent = parent->rb_nodes[diff > 0];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct archive_rb_node *
|
||||
__archive_rb_tree_find_node_geq(struct archive_rb_tree *rbt, const void *key)
|
||||
{
|
||||
archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
|
||||
struct archive_rb_node *parent = rbt->rbt_root;
|
||||
struct archive_rb_node *last = NULL;
|
||||
|
||||
while (!RB_SENTINEL_P(parent)) {
|
||||
const signed int diff = (*compare_key)(parent, key);
|
||||
if (diff == 0)
|
||||
return parent;
|
||||
if (diff < 0)
|
||||
last = parent;
|
||||
parent = parent->rb_nodes[diff > 0];
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
struct archive_rb_node *
|
||||
__archive_rb_tree_find_node_leq(struct archive_rb_tree *rbt, const void *key)
|
||||
{
|
||||
archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
|
||||
struct archive_rb_node *parent = rbt->rbt_root;
|
||||
struct archive_rb_node *last = NULL;
|
||||
|
||||
while (!RB_SENTINEL_P(parent)) {
|
||||
const signed int diff = (*compare_key)(parent, key);
|
||||
if (diff == 0)
|
||||
return parent;
|
||||
if (diff > 0)
|
||||
last = parent;
|
||||
parent = parent->rb_nodes[diff > 0];
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
int
|
||||
__archive_rb_tree_insert_node(struct archive_rb_tree *rbt,
|
||||
struct archive_rb_node *self)
|
||||
{
|
||||
archive_rbto_compare_nodes_fn compare_nodes = rbt->rbt_ops->rbto_compare_nodes;
|
||||
struct archive_rb_node *parent, *tmp;
|
||||
unsigned int position;
|
||||
int rebalance;
|
||||
|
||||
tmp = rbt->rbt_root;
|
||||
/*
|
||||
* This is a hack. Because rbt->rbt_root is just a
|
||||
* struct archive_rb_node *, just like rb_node->rb_nodes[RB_DIR_LEFT],
|
||||
* we can use this fact to avoid a lot of tests for root and know
|
||||
* that even at root, updating
|
||||
* RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will
|
||||
* update rbt->rbt_root.
|
||||
*/
|
||||
parent = (struct archive_rb_node *)(void *)&rbt->rbt_root;
|
||||
position = RB_DIR_LEFT;
|
||||
|
||||
/*
|
||||
* Find out where to place this new leaf.
|
||||
*/
|
||||
while (!RB_SENTINEL_P(tmp)) {
|
||||
const signed int diff = (*compare_nodes)(tmp, self);
|
||||
if (diff == 0) {
|
||||
/*
|
||||
* Node already exists; don't insert.
|
||||
*/
|
||||
return F;
|
||||
}
|
||||
parent = tmp;
|
||||
position = (diff > 0);
|
||||
tmp = parent->rb_nodes[position];
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the node and insert as a leaf into the tree.
|
||||
*/
|
||||
RB_SET_FATHER(self, parent);
|
||||
RB_SET_POSITION(self, position);
|
||||
if (parent == (struct archive_rb_node *)(void *)&rbt->rbt_root) {
|
||||
RB_MARK_BLACK(self); /* root is always black */
|
||||
rebalance = F;
|
||||
} else {
|
||||
/*
|
||||
* All new nodes are colored red. We only need to rebalance
|
||||
* if our parent is also red.
|
||||
*/
|
||||
RB_MARK_RED(self);
|
||||
rebalance = RB_RED_P(parent);
|
||||
}
|
||||
self->rb_left = parent->rb_nodes[position];
|
||||
self->rb_right = parent->rb_nodes[position];
|
||||
parent->rb_nodes[position] = self;
|
||||
|
||||
/*
|
||||
* Rebalance tree after insertion
|
||||
*/
|
||||
if (rebalance)
|
||||
__archive_rb_tree_insert_rebalance(rbt, self);
|
||||
|
||||
return T;
|
||||
}
|
||||
|
||||
/*
|
||||
* Swap the location and colors of 'self' and its child @ which. The child
|
||||
* can not be a sentinel node. This is our rotation function. However,
|
||||
* since it preserves coloring, it great simplifies both insertion and
|
||||
* removal since rotation almost always involves the exchanging of colors
|
||||
* as a separate step.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
__archive_rb_tree_reparent_nodes(
|
||||
struct archive_rb_node *old_father, const unsigned int which)
|
||||
{
|
||||
const unsigned int other = which ^ RB_DIR_OTHER;
|
||||
struct archive_rb_node * const grandpa = RB_FATHER(old_father);
|
||||
struct archive_rb_node * const old_child = old_father->rb_nodes[which];
|
||||
struct archive_rb_node * const new_father = old_child;
|
||||
struct archive_rb_node * const new_child = old_father;
|
||||
|
||||
if (new_father == NULL)
|
||||
return;
|
||||
/*
|
||||
* Exchange descendant linkages.
|
||||
*/
|
||||
grandpa->rb_nodes[RB_POSITION(old_father)] = new_father;
|
||||
new_child->rb_nodes[which] = old_child->rb_nodes[other];
|
||||
new_father->rb_nodes[other] = new_child;
|
||||
|
||||
/*
|
||||
* Update ancestor linkages
|
||||
*/
|
||||
RB_SET_FATHER(new_father, grandpa);
|
||||
RB_SET_FATHER(new_child, new_father);
|
||||
|
||||
/*
|
||||
* Exchange properties between new_father and new_child. The only
|
||||
* change is that new_child's position is now on the other side.
|
||||
*/
|
||||
RB_SWAP_PROPERTIES(new_father, new_child);
|
||||
RB_SET_POSITION(new_child, other);
|
||||
|
||||
/*
|
||||
* Make sure to reparent the new child to ourself.
|
||||
*/
|
||||
if (!RB_SENTINEL_P(new_child->rb_nodes[which])) {
|
||||
RB_SET_FATHER(new_child->rb_nodes[which], new_child);
|
||||
RB_SET_POSITION(new_child->rb_nodes[which], which);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
__archive_rb_tree_insert_rebalance(struct archive_rb_tree *rbt,
|
||||
struct archive_rb_node *self)
|
||||
{
|
||||
struct archive_rb_node * father = RB_FATHER(self);
|
||||
struct archive_rb_node * grandpa;
|
||||
struct archive_rb_node * uncle;
|
||||
unsigned int which;
|
||||
unsigned int other;
|
||||
|
||||
for (;;) {
|
||||
/*
|
||||
* We are red and our parent is red, therefore we must have a
|
||||
* grandfather and he must be black.
|
||||
*/
|
||||
grandpa = RB_FATHER(father);
|
||||
which = (father == grandpa->rb_right);
|
||||
other = which ^ RB_DIR_OTHER;
|
||||
uncle = grandpa->rb_nodes[other];
|
||||
|
||||
if (RB_BLACK_P(uncle))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Case 1: our uncle is red
|
||||
* Simply invert the colors of our parent and
|
||||
* uncle and make our grandparent red. And
|
||||
* then solve the problem up at his level.
|
||||
*/
|
||||
RB_MARK_BLACK(uncle);
|
||||
RB_MARK_BLACK(father);
|
||||
if (RB_ROOT_P(rbt, grandpa)) {
|
||||
/*
|
||||
* If our grandpa is root, don't bother
|
||||
* setting him to red, just return.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
RB_MARK_RED(grandpa);
|
||||
self = grandpa;
|
||||
father = RB_FATHER(self);
|
||||
if (RB_BLACK_P(father)) {
|
||||
/*
|
||||
* If our great-grandpa is black, we're done.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Case 2&3: our uncle is black.
|
||||
*/
|
||||
if (self == father->rb_nodes[other]) {
|
||||
/*
|
||||
* Case 2: we are on the same side as our uncle
|
||||
* Swap ourselves with our parent so this case
|
||||
* becomes case 3. Basically our parent becomes our
|
||||
* child.
|
||||
*/
|
||||
__archive_rb_tree_reparent_nodes(father, other);
|
||||
}
|
||||
/*
|
||||
* Case 3: we are opposite a child of a black uncle.
|
||||
* Swap our parent and grandparent. Since our grandfather
|
||||
* is black, our father will become black and our new sibling
|
||||
* (former grandparent) will become red.
|
||||
*/
|
||||
__archive_rb_tree_reparent_nodes(grandpa, which);
|
||||
|
||||
/*
|
||||
* Final step: Set the root to black.
|
||||
*/
|
||||
RB_MARK_BLACK(rbt->rbt_root);
|
||||
}
|
||||
|
||||
static void
|
||||
__archive_rb_tree_prune_node(struct archive_rb_tree *rbt,
|
||||
struct archive_rb_node *self, int rebalance)
|
||||
{
|
||||
const unsigned int which = RB_POSITION(self);
|
||||
struct archive_rb_node *father = RB_FATHER(self);
|
||||
|
||||
/*
|
||||
* Since we are childless, we know that self->rb_left is pointing
|
||||
* to the sentinel node.
|
||||
*/
|
||||
father->rb_nodes[which] = self->rb_left;
|
||||
|
||||
/*
|
||||
* Rebalance if requested.
|
||||
*/
|
||||
if (rebalance)
|
||||
__archive_rb_tree_removal_rebalance(rbt, father, which);
|
||||
}
|
||||
|
||||
/*
|
||||
* When deleting an interior node
|
||||
*/
|
||||
static void
|
||||
__archive_rb_tree_swap_prune_and_rebalance(struct archive_rb_tree *rbt,
|
||||
struct archive_rb_node *self, struct archive_rb_node *standin)
|
||||
{
|
||||
const unsigned int standin_which = RB_POSITION(standin);
|
||||
unsigned int standin_other = standin_which ^ RB_DIR_OTHER;
|
||||
struct archive_rb_node *standin_son;
|
||||
struct archive_rb_node *standin_father = RB_FATHER(standin);
|
||||
int rebalance = RB_BLACK_P(standin);
|
||||
|
||||
if (standin_father == self) {
|
||||
/*
|
||||
* As a child of self, any children would be opposite of
|
||||
* our parent.
|
||||
*/
|
||||
standin_son = standin->rb_nodes[standin_which];
|
||||
} else {
|
||||
/*
|
||||
* Since we aren't a child of self, any children would be
|
||||
* on the same side as our parent.
|
||||
*/
|
||||
standin_son = standin->rb_nodes[standin_other];
|
||||
}
|
||||
|
||||
if (RB_RED_P(standin_son)) {
|
||||
/*
|
||||
* We know we have a red child so if we flip it to black
|
||||
* we don't have to rebalance.
|
||||
*/
|
||||
RB_MARK_BLACK(standin_son);
|
||||
rebalance = F;
|
||||
|
||||
if (standin_father != self) {
|
||||
/*
|
||||
* Change the son's parentage to point to his grandpa.
|
||||
*/
|
||||
RB_SET_FATHER(standin_son, standin_father);
|
||||
RB_SET_POSITION(standin_son, standin_which);
|
||||
}
|
||||
}
|
||||
|
||||
if (standin_father == self) {
|
||||
/*
|
||||
* If we are about to delete the standin's father, then when
|
||||
* we call rebalance, we need to use ourselves as our father.
|
||||
* Otherwise remember our original father. Also, since we are
|
||||
* our standin's father we only need to reparent the standin's
|
||||
* brother.
|
||||
*
|
||||
* | R --> S |
|
||||
* | Q S --> Q T |
|
||||
* | t --> |
|
||||
*
|
||||
* Have our son/standin adopt his brother as his new son.
|
||||
*/
|
||||
standin_father = standin;
|
||||
} else {
|
||||
/*
|
||||
* | R --> S . |
|
||||
* | / \ | T --> / \ | / |
|
||||
* | ..... | S --> ..... | T |
|
||||
*
|
||||
* Sever standin's connection to his father.
|
||||
*/
|
||||
standin_father->rb_nodes[standin_which] = standin_son;
|
||||
/*
|
||||
* Adopt the far son.
|
||||
*/
|
||||
standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
|
||||
RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
|
||||
/*
|
||||
* Use standin_other because we need to preserve standin_which
|
||||
* for the removal_rebalance.
|
||||
*/
|
||||
standin_other = standin_which;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the only remaining son to our standin. If our standin is our
|
||||
* son, this will be the only son needed to be moved.
|
||||
*/
|
||||
standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
|
||||
RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
|
||||
|
||||
/*
|
||||
* Now copy the result of self to standin and then replace
|
||||
* self with standin in the tree.
|
||||
*/
|
||||
RB_COPY_PROPERTIES(standin, self);
|
||||
RB_SET_FATHER(standin, RB_FATHER(self));
|
||||
RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin;
|
||||
|
||||
if (rebalance)
|
||||
__archive_rb_tree_removal_rebalance(rbt, standin_father, standin_which);
|
||||
}
|
||||
|
||||
/*
|
||||
* We could do this by doing
|
||||
* __archive_rb_tree_node_swap(rbt, self, which);
|
||||
* __archive_rb_tree_prune_node(rbt, self, F);
|
||||
*
|
||||
* But it's more efficient to just evaluate and recolor the child.
|
||||
*/
|
||||
static void
|
||||
__archive_rb_tree_prune_blackred_branch(
|
||||
struct archive_rb_node *self, unsigned int which)
|
||||
{
|
||||
struct archive_rb_node *father = RB_FATHER(self);
|
||||
struct archive_rb_node *son = self->rb_nodes[which];
|
||||
|
||||
/*
|
||||
* Remove ourselves from the tree and give our former child our
|
||||
* properties (position, color, root).
|
||||
*/
|
||||
RB_COPY_PROPERTIES(son, self);
|
||||
father->rb_nodes[RB_POSITION(son)] = son;
|
||||
RB_SET_FATHER(son, father);
|
||||
}
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void
|
||||
__archive_rb_tree_remove_node(struct archive_rb_tree *rbt,
|
||||
struct archive_rb_node *self)
|
||||
{
|
||||
struct archive_rb_node *standin;
|
||||
unsigned int which;
|
||||
|
||||
/*
|
||||
* In the following diagrams, we (the node to be removed) are S. Red
|
||||
* nodes are lowercase. T could be either red or black.
|
||||
*
|
||||
* Remember the major axiom of the red-black tree: the number of
|
||||
* black nodes from the root to each leaf is constant across all
|
||||
* leaves, only the number of red nodes varies.
|
||||
*
|
||||
* Thus removing a red leaf doesn't require any other changes to a
|
||||
* red-black tree. So if we must remove a node, attempt to rearrange
|
||||
* the tree so we can remove a red node.
|
||||
*
|
||||
* The simplest case is a childless red node or a childless root node:
|
||||
*
|
||||
* | T --> T | or | R --> * |
|
||||
* | s --> * |
|
||||
*/
|
||||
if (RB_CHILDLESS_P(self)) {
|
||||
const int rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self);
|
||||
__archive_rb_tree_prune_node(rbt, self, rebalance);
|
||||
return;
|
||||
}
|
||||
if (!RB_TWOCHILDREN_P(self)) {
|
||||
/*
|
||||
* The next simplest case is the node we are deleting is
|
||||
* black and has one red child.
|
||||
*
|
||||
* | T --> T --> T |
|
||||
* | S --> R --> R |
|
||||
* | r --> s --> * |
|
||||
*/
|
||||
which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT;
|
||||
__archive_rb_tree_prune_blackred_branch(self, which);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We invert these because we prefer to remove from the inside of
|
||||
* the tree.
|
||||
*/
|
||||
which = RB_POSITION(self) ^ RB_DIR_OTHER;
|
||||
|
||||
/*
|
||||
* Let's find the node closes to us opposite of our parent
|
||||
* Now swap it with ourself, "prune" it, and rebalance, if needed.
|
||||
*/
|
||||
standin = __archive_rb_tree_iterate(rbt, self, which);
|
||||
__archive_rb_tree_swap_prune_and_rebalance(rbt, self, standin);
|
||||
}
|
||||
|
||||
static void
|
||||
__archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt,
|
||||
struct archive_rb_node *parent, unsigned int which)
|
||||
{
|
||||
|
||||
while (RB_BLACK_P(parent->rb_nodes[which])) {
|
||||
unsigned int other = which ^ RB_DIR_OTHER;
|
||||
struct archive_rb_node *brother = parent->rb_nodes[other];
|
||||
|
||||
if (brother == NULL)
|
||||
return;/* The tree may be broken. */
|
||||
/*
|
||||
* For cases 1, 2a, and 2b, our brother's children must
|
||||
* be black and our father must be black
|
||||
*/
|
||||
if (RB_BLACK_P(parent)
|
||||
&& RB_BLACK_P(brother->rb_left)
|
||||
&& RB_BLACK_P(brother->rb_right)) {
|
||||
if (RB_RED_P(brother)) {
|
||||
/*
|
||||
* Case 1: Our brother is red, swap its
|
||||
* position (and colors) with our parent.
|
||||
* This should now be case 2b (unless C or E
|
||||
* has a red child which is case 3; thus no
|
||||
* explicit branch to case 2b).
|
||||
*
|
||||
* B -> D
|
||||
* A d -> b E
|
||||
* C E -> A C
|
||||
*/
|
||||
__archive_rb_tree_reparent_nodes(parent, other);
|
||||
brother = parent->rb_nodes[other];
|
||||
if (brother == NULL)
|
||||
return;/* The tree may be broken. */
|
||||
} else {
|
||||
/*
|
||||
* Both our parent and brother are black.
|
||||
* Change our brother to red, advance up rank
|
||||
* and go through the loop again.
|
||||
*
|
||||
* B -> *B
|
||||
* *A D -> A d
|
||||
* C E -> C E
|
||||
*/
|
||||
RB_MARK_RED(brother);
|
||||
if (RB_ROOT_P(rbt, parent))
|
||||
return; /* root == parent == black */
|
||||
which = RB_POSITION(parent);
|
||||
parent = RB_FATHER(parent);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Avoid an else here so that case 2a above can hit either
|
||||
* case 2b, 3, or 4.
|
||||
*/
|
||||
if (RB_RED_P(parent)
|
||||
&& RB_BLACK_P(brother)
|
||||
&& RB_BLACK_P(brother->rb_left)
|
||||
&& RB_BLACK_P(brother->rb_right)) {
|
||||
/*
|
||||
* We are black, our father is red, our brother and
|
||||
* both nephews are black. Simply invert/exchange the
|
||||
* colors of our father and brother (to black and red
|
||||
* respectively).
|
||||
*
|
||||
* | f --> F |
|
||||
* | * B --> * b |
|
||||
* | N N --> N N |
|
||||
*/
|
||||
RB_MARK_BLACK(parent);
|
||||
RB_MARK_RED(brother);
|
||||
break; /* We're done! */
|
||||
} else {
|
||||
/*
|
||||
* Our brother must be black and have at least one
|
||||
* red child (it may have two).
|
||||
*/
|
||||
if (RB_BLACK_P(brother->rb_nodes[other])) {
|
||||
/*
|
||||
* Case 3: our brother is black, our near
|
||||
* nephew is red, and our far nephew is black.
|
||||
* Swap our brother with our near nephew.
|
||||
* This result in a tree that matches case 4.
|
||||
* (Our father could be red or black).
|
||||
*
|
||||
* | F --> F |
|
||||
* | x B --> x B |
|
||||
* | n --> n |
|
||||
*/
|
||||
__archive_rb_tree_reparent_nodes(brother, which);
|
||||
brother = parent->rb_nodes[other];
|
||||
}
|
||||
/*
|
||||
* Case 4: our brother is black and our far nephew
|
||||
* is red. Swap our father and brother locations and
|
||||
* change our far nephew to black. (these can be
|
||||
* done in either order so we change the color first).
|
||||
* The result is a valid red-black tree and is a
|
||||
* terminal case. (again we don't care about the
|
||||
* father's color)
|
||||
*
|
||||
* If the father is red, we will get a red-black-black
|
||||
* tree:
|
||||
* | f -> f --> b |
|
||||
* | B -> B --> F N |
|
||||
* | n -> N --> |
|
||||
*
|
||||
* If the father is black, we will get an all black
|
||||
* tree:
|
||||
* | F -> F --> B |
|
||||
* | B -> B --> F N |
|
||||
* | n -> N --> |
|
||||
*
|
||||
* If we had two red nephews, then after the swap,
|
||||
* our former father would have a red grandson.
|
||||
*/
|
||||
if (brother->rb_nodes[other] == NULL)
|
||||
return;/* The tree may be broken. */
|
||||
RB_MARK_BLACK(brother->rb_nodes[other]);
|
||||
__archive_rb_tree_reparent_nodes(parent, other);
|
||||
break; /* We're done! */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct archive_rb_node *
|
||||
__archive_rb_tree_iterate(struct archive_rb_tree *rbt,
|
||||
struct archive_rb_node *self, const unsigned int direction)
|
||||
{
|
||||
const unsigned int other = direction ^ RB_DIR_OTHER;
|
||||
|
||||
if (self == NULL) {
|
||||
self = rbt->rbt_root;
|
||||
if (RB_SENTINEL_P(self))
|
||||
return NULL;
|
||||
while (!RB_SENTINEL_P(self->rb_nodes[direction]))
|
||||
self = self->rb_nodes[direction];
|
||||
return self;
|
||||
}
|
||||
/*
|
||||
* We can't go any further in this direction. We proceed up in the
|
||||
* opposite direction until our parent is in direction we want to go.
|
||||
*/
|
||||
if (RB_SENTINEL_P(self->rb_nodes[direction])) {
|
||||
while (!RB_ROOT_P(rbt, self)) {
|
||||
if (other == (unsigned int)RB_POSITION(self))
|
||||
return RB_FATHER(self);
|
||||
self = RB_FATHER(self);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Advance down one in current direction and go down as far as possible
|
||||
* in the opposite direction.
|
||||
*/
|
||||
self = self->rb_nodes[direction];
|
||||
while (!RB_SENTINEL_P(self->rb_nodes[other]))
|
||||
self = self->rb_nodes[other];
|
||||
return self;
|
||||
}
|
113
dependencies/libarchive-3.4.2/libarchive/archive_rb.h
vendored
Normal file
113
dependencies/libarchive-3.4.2/libarchive/archive_rb.h
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Matt Thomas <matt@3am-software.com>.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_RB_H_INCLUDED
|
||||
#define ARCHIVE_RB_H_INCLUDED
|
||||
|
||||
struct archive_rb_node {
|
||||
struct archive_rb_node *rb_nodes[2];
|
||||
/*
|
||||
* rb_info contains the two flags and the parent back pointer.
|
||||
* We put the two flags in the low two bits since we know that
|
||||
* rb_node will have an alignment of 4 or 8 bytes.
|
||||
*/
|
||||
uintptr_t rb_info;
|
||||
};
|
||||
|
||||
#define ARCHIVE_RB_DIR_LEFT 0
|
||||
#define ARCHIVE_RB_DIR_RIGHT 1
|
||||
|
||||
#define ARCHIVE_RB_TREE_MIN(T) \
|
||||
__archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT)
|
||||
#define ARCHIVE_RB_TREE_MAX(T) \
|
||||
__archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT)
|
||||
#define ARCHIVE_RB_TREE_NEXT(T, N) \
|
||||
__archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT)
|
||||
#define ARCHIVE_RB_TREE_PREV(T, N) \
|
||||
__archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT)
|
||||
#define ARCHIVE_RB_TREE_FOREACH(N, T) \
|
||||
for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \
|
||||
(N) = ARCHIVE_RB_TREE_NEXT((T), (N)))
|
||||
#define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \
|
||||
for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \
|
||||
(N) = ARCHIVE_RB_TREE_PREV((T), (N)))
|
||||
#define ARCHIVE_RB_TREE_FOREACH_SAFE(N, T, S) \
|
||||
for ((N) = ARCHIVE_RB_TREE_MIN(T); \
|
||||
(N) && ((S) = ARCHIVE_RB_TREE_NEXT((T), (N)), 1); \
|
||||
(N) = (S))
|
||||
#define ARCHIVE_RB_TREE_FOREACH_REVERSE_SAFE(N, T, S) \
|
||||
for ((N) = ARCHIVE_RB_TREE_MAX(T); \
|
||||
(N) && ((S) = ARCHIVE_RB_TREE_PREV((T), (N)), 1); \
|
||||
(N) = (S))
|
||||
|
||||
/*
|
||||
* archive_rbto_compare_nodes_fn:
|
||||
* return a positive value if the first node < the second node.
|
||||
* return a negative value if the first node > the second node.
|
||||
* return 0 if they are considered same.
|
||||
*
|
||||
* archive_rbto_compare_key_fn:
|
||||
* return a positive value if the node < the key.
|
||||
* return a negative value if the node > the key.
|
||||
* return 0 if they are considered same.
|
||||
*/
|
||||
|
||||
typedef signed int (*const archive_rbto_compare_nodes_fn)(const struct archive_rb_node *,
|
||||
const struct archive_rb_node *);
|
||||
typedef signed int (*const archive_rbto_compare_key_fn)(const struct archive_rb_node *,
|
||||
const void *);
|
||||
|
||||
struct archive_rb_tree_ops {
|
||||
archive_rbto_compare_nodes_fn rbto_compare_nodes;
|
||||
archive_rbto_compare_key_fn rbto_compare_key;
|
||||
};
|
||||
|
||||
struct archive_rb_tree {
|
||||
struct archive_rb_node *rbt_root;
|
||||
const struct archive_rb_tree_ops *rbt_ops;
|
||||
};
|
||||
|
||||
void __archive_rb_tree_init(struct archive_rb_tree *,
|
||||
const struct archive_rb_tree_ops *);
|
||||
int __archive_rb_tree_insert_node(struct archive_rb_tree *,
|
||||
struct archive_rb_node *);
|
||||
struct archive_rb_node *
|
||||
__archive_rb_tree_find_node(struct archive_rb_tree *, const void *);
|
||||
struct archive_rb_node *
|
||||
__archive_rb_tree_find_node_geq(struct archive_rb_tree *, const void *);
|
||||
struct archive_rb_node *
|
||||
__archive_rb_tree_find_node_leq(struct archive_rb_tree *, const void *);
|
||||
void __archive_rb_tree_remove_node(struct archive_rb_tree *, struct archive_rb_node *);
|
||||
struct archive_rb_node *
|
||||
__archive_rb_tree_iterate(struct archive_rb_tree *,
|
||||
struct archive_rb_node *, const unsigned int);
|
||||
|
||||
#endif /* ARCHIVE_RB_H_*/
|
252
dependencies/libarchive-3.4.2/libarchive/archive_read.3
vendored
Normal file
252
dependencies/libarchive-3.4.2/libarchive/archive_read.3
vendored
Normal file
|
@ -0,0 +1,252 @@
|
|||
.\" Copyright (c) 2003-2007 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_READ 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read
|
||||
.Nd functions for reading streaming archives
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Sh DESCRIPTION
|
||||
These functions provide a complete API for reading streaming archives.
|
||||
The general process is to first create the
|
||||
.Tn struct archive
|
||||
object, set options, initialize the reader, iterate over the archive
|
||||
headers and associated data, then close the archive and release all
|
||||
resources.
|
||||
.\"
|
||||
.Ss Create archive object
|
||||
See
|
||||
.Xr archive_read_new 3 .
|
||||
.Pp
|
||||
To read an archive, you must first obtain an initialized
|
||||
.Tn struct archive
|
||||
object from
|
||||
.Fn archive_read_new .
|
||||
.\"
|
||||
.Ss Enable filters and formats
|
||||
See
|
||||
.Xr archive_read_filter 3
|
||||
and
|
||||
.Xr archive_read_format 3 .
|
||||
.Pp
|
||||
You can then modify this object for the desired operations with the
|
||||
various
|
||||
.Fn archive_read_set_XXX
|
||||
and
|
||||
.Fn archive_read_support_XXX
|
||||
functions.
|
||||
In particular, you will need to invoke appropriate
|
||||
.Fn archive_read_support_XXX
|
||||
functions to enable the corresponding compression and format
|
||||
support.
|
||||
Note that these latter functions perform two distinct operations:
|
||||
they cause the corresponding support code to be linked into your
|
||||
program, and they enable the corresponding auto-detect code.
|
||||
Unless you have specific constraints, you will generally want
|
||||
to invoke
|
||||
.Fn archive_read_support_filter_all
|
||||
and
|
||||
.Fn archive_read_support_format_all
|
||||
to enable auto-detect for all formats and compression types
|
||||
currently supported by the library.
|
||||
.\"
|
||||
.Ss Set options
|
||||
See
|
||||
.Xr archive_read_set_options 3 .
|
||||
.\"
|
||||
.Ss Open archive
|
||||
See
|
||||
.Xr archive_read_open 3 .
|
||||
.Pp
|
||||
Once you have prepared the
|
||||
.Tn struct archive
|
||||
object, you call
|
||||
.Fn archive_read_open
|
||||
to actually open the archive and prepare it for reading.
|
||||
There are several variants of this function;
|
||||
the most basic expects you to provide pointers to several
|
||||
functions that can provide blocks of bytes from the archive.
|
||||
There are convenience forms that allow you to
|
||||
specify a filename, file descriptor,
|
||||
.Ft "FILE *"
|
||||
object, or a block of memory from which to read the archive data.
|
||||
Note that the core library makes no assumptions about the
|
||||
size of the blocks read;
|
||||
callback functions are free to read whatever block size is
|
||||
most appropriate for the medium.
|
||||
.\"
|
||||
.Ss Consume archive
|
||||
See
|
||||
.Xr archive_read_header 3 ,
|
||||
.Xr archive_read_data 3
|
||||
and
|
||||
.Xr archive_read_extract 3 .
|
||||
.Pp
|
||||
Each archive entry consists of a header followed by a certain
|
||||
amount of data.
|
||||
You can obtain the next header with
|
||||
.Fn archive_read_next_header ,
|
||||
which returns a pointer to an
|
||||
.Tn struct archive_entry
|
||||
structure with information about the current archive element.
|
||||
If the entry is a regular file, then the header will be followed
|
||||
by the file data.
|
||||
You can use
|
||||
.Fn archive_read_data
|
||||
(which works much like the
|
||||
.Xr read 2
|
||||
system call)
|
||||
to read this data from the archive, or
|
||||
.Fn archive_read_data_block
|
||||
which provides a slightly more efficient interface.
|
||||
You may prefer to use the higher-level
|
||||
.Fn archive_read_data_skip ,
|
||||
which reads and discards the data for this entry,
|
||||
.Fn archive_read_data_into_fd ,
|
||||
which copies the data to the provided file descriptor, or
|
||||
.Fn archive_read_extract ,
|
||||
which recreates the specified entry on disk and copies data
|
||||
from the archive.
|
||||
In particular, note that
|
||||
.Fn archive_read_extract
|
||||
uses the
|
||||
.Tn struct archive_entry
|
||||
structure that you provide it, which may differ from the
|
||||
entry just read from the archive.
|
||||
In particular, many applications will want to override the
|
||||
pathname, file permissions, or ownership.
|
||||
.\"
|
||||
.Ss Release resources
|
||||
See
|
||||
.Xr archive_read_free 3 .
|
||||
.Pp
|
||||
Once you have finished reading data from the archive, you
|
||||
should call
|
||||
.Fn archive_read_close
|
||||
to close the archive, then call
|
||||
.Fn archive_read_free
|
||||
to release all resources, including all memory allocated by the library.
|
||||
.\"
|
||||
.Sh EXAMPLES
|
||||
The following illustrates basic usage of the library.
|
||||
In this example,
|
||||
the callback functions are simply wrappers around the standard
|
||||
.Xr open 2 ,
|
||||
.Xr read 2 ,
|
||||
and
|
||||
.Xr close 2
|
||||
system calls.
|
||||
.Bd -literal -offset indent
|
||||
void
|
||||
list_archive(const char *name)
|
||||
{
|
||||
struct mydata *mydata;
|
||||
struct archive *a;
|
||||
struct archive_entry *entry;
|
||||
|
||||
mydata = malloc(sizeof(struct mydata));
|
||||
a = archive_read_new();
|
||||
mydata->name = name;
|
||||
archive_read_support_filter_all(a);
|
||||
archive_read_support_format_all(a);
|
||||
archive_read_open(a, mydata, myopen, myread, myclose);
|
||||
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
|
||||
printf("%s\en",archive_entry_pathname(entry));
|
||||
archive_read_data_skip(a);
|
||||
}
|
||||
archive_read_free(a);
|
||||
free(mydata);
|
||||
}
|
||||
|
||||
la_ssize_t
|
||||
myread(struct archive *a, void *client_data, const void **buff)
|
||||
{
|
||||
struct mydata *mydata = client_data;
|
||||
|
||||
*buff = mydata->buff;
|
||||
return (read(mydata->fd, mydata->buff, 10240));
|
||||
}
|
||||
|
||||
int
|
||||
myopen(struct archive *a, void *client_data)
|
||||
{
|
||||
struct mydata *mydata = client_data;
|
||||
|
||||
mydata->fd = open(mydata->name, O_RDONLY);
|
||||
return (mydata->fd >= 0 ? ARCHIVE_OK : ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
int
|
||||
myclose(struct archive *a, void *client_data)
|
||||
{
|
||||
struct mydata *mydata = client_data;
|
||||
|
||||
if (mydata->fd > 0)
|
||||
close(mydata->fd);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
.Ed
|
||||
.\" .Sh ERRORS
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_extract 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_header 3 ,
|
||||
.Xr archive_read_new 3 ,
|
||||
.Xr archive_read_open 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm libarchive
|
||||
library first appeared in
|
||||
.Fx 5.3 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm libarchive
|
||||
library was written by
|
||||
.An Tim Kientzle Aq kientzle@acm.org .
|
||||
.Sh BUGS
|
||||
Many traditional archiver programs treat
|
||||
empty files as valid empty archives.
|
||||
For example, many implementations of
|
||||
.Xr tar 1
|
||||
allow you to append entries to an empty file.
|
||||
Of course, it is impossible to determine the format of an empty file
|
||||
by inspecting the contents, so this library treats empty files as
|
||||
having a special
|
||||
.Dq empty
|
||||
format.
|
1751
dependencies/libarchive-3.4.2/libarchive/archive_read.c
vendored
Normal file
1751
dependencies/libarchive-3.4.2/libarchive/archive_read.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
74
dependencies/libarchive-3.4.2/libarchive/archive_read_add_passphrase.3
vendored
Normal file
74
dependencies/libarchive-3.4.2/libarchive/archive_read_add_passphrase.3
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
.\" Copyright (c) 2014 Michihiro NAKAJIMA
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 14, 2014
|
||||
.Dt ARCHIVE_READ_ADD_PASSPHRASE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_add_passphrase ,
|
||||
.Nm archive_read_set_passphrase_callback
|
||||
.Nd functions for reading encrypted archives
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Ft int
|
||||
.Fo archive_read_add_passphrase
|
||||
.Fa "struct archive *"
|
||||
.Fa "const char *passphrase"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_read_set_passphrase_callback
|
||||
.Fa "struct archive *"
|
||||
.Fa "void *client_data"
|
||||
.Fa "archive_passphrase_callback *"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -width indent
|
||||
.It Fn archive_read_add_passphrase
|
||||
Register passphrases for reading an encryption archive.
|
||||
If
|
||||
.Ar passphrase
|
||||
is
|
||||
.Dv NULL
|
||||
or empty, this function will do nothing and
|
||||
.Cm ARCHIVE_FAILED
|
||||
will be returned.
|
||||
Otherwise,
|
||||
.Cm ARCHIVE_OK
|
||||
will be returned.
|
||||
.It Fn archive_read_set_passphrase_callback
|
||||
Register a callback function that will be invoked to get a passphrase
|
||||
for decryption after trying all the passphrases registered by the
|
||||
.Fn archive_read_add_passphrase
|
||||
function failed.
|
||||
.El
|
||||
.\" .Sh ERRORS
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr libarchive 3
|
186
dependencies/libarchive-3.4.2/libarchive/archive_read_add_passphrase.c
vendored
Normal file
186
dependencies/libarchive-3.4.2/libarchive/archive_read_add_passphrase.c
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*-
|
||||
* Copyright (c) 2014 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include "archive_read_private.h"
|
||||
|
||||
static void
|
||||
add_passphrase_to_tail(struct archive_read *a,
|
||||
struct archive_read_passphrase *p)
|
||||
{
|
||||
*a->passphrases.last = p;
|
||||
a->passphrases.last = &p->next;
|
||||
p->next = NULL;
|
||||
}
|
||||
|
||||
static struct archive_read_passphrase *
|
||||
remove_passphrases_from_head(struct archive_read *a)
|
||||
{
|
||||
struct archive_read_passphrase *p;
|
||||
|
||||
p = a->passphrases.first;
|
||||
if (p != NULL)
|
||||
a->passphrases.first = p->next;
|
||||
return (p);
|
||||
}
|
||||
|
||||
static void
|
||||
insert_passphrase_to_head(struct archive_read *a,
|
||||
struct archive_read_passphrase *p)
|
||||
{
|
||||
p->next = a->passphrases.first;
|
||||
a->passphrases.first = p;
|
||||
}
|
||||
|
||||
static struct archive_read_passphrase *
|
||||
new_read_passphrase(struct archive_read *a, const char *passphrase)
|
||||
{
|
||||
struct archive_read_passphrase *p;
|
||||
|
||||
p = malloc(sizeof(*p));
|
||||
if (p == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory");
|
||||
return (NULL);
|
||||
}
|
||||
p->passphrase = strdup(passphrase);
|
||||
if (p->passphrase == NULL) {
|
||||
free(p);
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory");
|
||||
return (NULL);
|
||||
}
|
||||
return (p);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_add_passphrase(struct archive *_a, const char *passphrase)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_passphrase *p;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_add_passphrase");
|
||||
|
||||
if (passphrase == NULL || passphrase[0] == '\0') {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Empty passphrase is unacceptable");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
p = new_read_passphrase(a, passphrase);
|
||||
if (p == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
add_passphrase_to_tail(a, p);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_set_passphrase_callback(struct archive *_a, void *client_data,
|
||||
archive_passphrase_callback *cb)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||
"archive_read_set_passphrase_callback");
|
||||
|
||||
a->passphrases.callback = cb;
|
||||
a->passphrases.client_data = client_data;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this in advance when you start to get a passphrase for decryption
|
||||
* for a entry.
|
||||
*/
|
||||
void
|
||||
__archive_read_reset_passphrase(struct archive_read *a)
|
||||
{
|
||||
|
||||
a->passphrases.candidate = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a passphrase for decryption.
|
||||
*/
|
||||
const char *
|
||||
__archive_read_next_passphrase(struct archive_read *a)
|
||||
{
|
||||
struct archive_read_passphrase *p;
|
||||
const char *passphrase;
|
||||
|
||||
if (a->passphrases.candidate < 0) {
|
||||
/* Count out how many passphrases we have. */
|
||||
int cnt = 0;
|
||||
|
||||
for (p = a->passphrases.first; p != NULL; p = p->next)
|
||||
cnt++;
|
||||
a->passphrases.candidate = cnt;
|
||||
p = a->passphrases.first;
|
||||
} else if (a->passphrases.candidate > 1) {
|
||||
/* Rotate a passphrase list. */
|
||||
a->passphrases.candidate--;
|
||||
p = remove_passphrases_from_head(a);
|
||||
add_passphrase_to_tail(a, p);
|
||||
/* Pick a new passphrase candidate up. */
|
||||
p = a->passphrases.first;
|
||||
} else if (a->passphrases.candidate == 1) {
|
||||
/* This case is that all candidates failed to decrypt. */
|
||||
a->passphrases.candidate = 0;
|
||||
if (a->passphrases.first->next != NULL) {
|
||||
/* Rotate a passphrase list. */
|
||||
p = remove_passphrases_from_head(a);
|
||||
add_passphrase_to_tail(a, p);
|
||||
}
|
||||
p = NULL;
|
||||
} else /* There is no passphrase candidate. */
|
||||
p = NULL;
|
||||
|
||||
if (p != NULL)
|
||||
passphrase = p->passphrase;
|
||||
else if (a->passphrases.callback != NULL) {
|
||||
/* Get a passphrase through a call-back function
|
||||
* since we tried all passphrases out or we don't
|
||||
* have it. */
|
||||
passphrase = a->passphrases.callback(&a->archive,
|
||||
a->passphrases.client_data);
|
||||
if (passphrase != NULL) {
|
||||
p = new_read_passphrase(a, passphrase);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
insert_passphrase_to_head(a, p);
|
||||
a->passphrases.candidate = 1;
|
||||
}
|
||||
} else
|
||||
passphrase = NULL;
|
||||
|
||||
return (passphrase);
|
||||
}
|
204
dependencies/libarchive-3.4.2/libarchive/archive_read_append_filter.c
vendored
Normal file
204
dependencies/libarchive-3.4.2/libarchive/archive_read_append_filter.c
vendored
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2012 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
int
|
||||
archive_read_append_filter(struct archive *_a, int code)
|
||||
{
|
||||
int r1, r2, number_bidders, i;
|
||||
char str[20];
|
||||
struct archive_read_filter_bidder *bidder;
|
||||
struct archive_read_filter *filter;
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
|
||||
r2 = (ARCHIVE_OK);
|
||||
switch (code)
|
||||
{
|
||||
case ARCHIVE_FILTER_NONE:
|
||||
/* No filter to add, so do nothing.
|
||||
* NOTE: An initial "NONE" type filter is always set at the end of the
|
||||
* filter chain.
|
||||
*/
|
||||
r1 = (ARCHIVE_OK);
|
||||
break;
|
||||
case ARCHIVE_FILTER_GZIP:
|
||||
strcpy(str, "gzip");
|
||||
r1 = archive_read_support_filter_gzip(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_BZIP2:
|
||||
strcpy(str, "bzip2");
|
||||
r1 = archive_read_support_filter_bzip2(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_COMPRESS:
|
||||
strcpy(str, "compress (.Z)");
|
||||
r1 = archive_read_support_filter_compress(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_PROGRAM:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Cannot append program filter using archive_read_append_filter");
|
||||
return (ARCHIVE_FATAL);
|
||||
case ARCHIVE_FILTER_LZMA:
|
||||
strcpy(str, "lzma");
|
||||
r1 = archive_read_support_filter_lzma(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_XZ:
|
||||
strcpy(str, "xz");
|
||||
r1 = archive_read_support_filter_xz(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_UU:
|
||||
strcpy(str, "uu");
|
||||
r1 = archive_read_support_filter_uu(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_RPM:
|
||||
strcpy(str, "rpm");
|
||||
r1 = archive_read_support_filter_rpm(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZ4:
|
||||
strcpy(str, "lz4");
|
||||
r1 = archive_read_support_filter_lz4(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_ZSTD:
|
||||
strcpy(str, "zstd");
|
||||
r1 = archive_read_support_filter_zstd(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZIP:
|
||||
strcpy(str, "lzip");
|
||||
r1 = archive_read_support_filter_lzip(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LRZIP:
|
||||
strcpy(str, "lrzip");
|
||||
r1 = archive_read_support_filter_lrzip(_a);
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Invalid filter code specified");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
if (code != ARCHIVE_FILTER_NONE)
|
||||
{
|
||||
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
|
||||
|
||||
bidder = a->bidders;
|
||||
for (i = 0; i < number_bidders; i++, bidder++)
|
||||
{
|
||||
if (!bidder->name || !strcmp(bidder->name, str))
|
||||
break;
|
||||
}
|
||||
if (!bidder->name || strcmp(bidder->name, str))
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: Unable to append filter");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
filter
|
||||
= (struct archive_read_filter *)calloc(1, sizeof(*filter));
|
||||
if (filter == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
filter->bidder = bidder;
|
||||
filter->archive = a;
|
||||
filter->upstream = a->filter;
|
||||
a->filter = filter;
|
||||
r2 = (bidder->init)(a->filter);
|
||||
if (r2 != ARCHIVE_OK) {
|
||||
__archive_read_free_filters(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
a->bypass_filter_bidding = 1;
|
||||
return (r1 < r2) ? r1 : r2;
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_append_filter_program(struct archive *_a, const char *cmd)
|
||||
{
|
||||
return (archive_read_append_filter_program_signature(_a, cmd, NULL, 0));
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_append_filter_program_signature(struct archive *_a,
|
||||
const char *cmd, const void *signature, size_t signature_len)
|
||||
{
|
||||
int r, number_bidders, i;
|
||||
struct archive_read_filter_bidder *bidder;
|
||||
struct archive_read_filter *filter;
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
|
||||
if (archive_read_support_filter_program_signature(_a, cmd, signature,
|
||||
signature_len) != (ARCHIVE_OK))
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
|
||||
|
||||
bidder = a->bidders;
|
||||
for (i = 0; i < number_bidders; i++, bidder++)
|
||||
{
|
||||
/* Program bidder name set to filter name after initialization */
|
||||
if (bidder->data && !bidder->name)
|
||||
break;
|
||||
}
|
||||
if (!bidder->data)
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: Unable to append program filter");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
filter
|
||||
= (struct archive_read_filter *)calloc(1, sizeof(*filter));
|
||||
if (filter == NULL)
|
||||
{
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
filter->bidder = bidder;
|
||||
filter->archive = a;
|
||||
filter->upstream = a->filter;
|
||||
a->filter = filter;
|
||||
r = (bidder->init)(a->filter);
|
||||
if (r != ARCHIVE_OK) {
|
||||
__archive_read_free_filters(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
bidder->name = a->filter->name;
|
||||
|
||||
a->bypass_filter_bidding = 1;
|
||||
return r;
|
||||
}
|
130
dependencies/libarchive-3.4.2/libarchive/archive_read_data.3
vendored
Normal file
130
dependencies/libarchive-3.4.2/libarchive/archive_read_data.3
vendored
Normal file
|
@ -0,0 +1,130 @@
|
|||
.\" Copyright (c) 2003-2011 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_READ_DATA 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_data ,
|
||||
.Nm archive_read_data_block ,
|
||||
.Nm archive_read_data_skip ,
|
||||
.Nm archive_read_data_into_fd
|
||||
.Nd functions for reading streaming archives
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Ft la_ssize_t
|
||||
.Fn archive_read_data "struct archive *" "void *buff" "size_t len"
|
||||
.Ft int
|
||||
.Fo archive_read_data_block
|
||||
.Fa "struct archive *"
|
||||
.Fa "const void **buff"
|
||||
.Fa "size_t *len"
|
||||
.Fa "off_t *offset"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_read_data_skip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_data_into_fd "struct archive *" "int fd"
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -compact -width indent
|
||||
.It Fn archive_read_data
|
||||
Read data associated with the header just read.
|
||||
Internally, this is a convenience function that calls
|
||||
.Fn archive_read_data_block
|
||||
and fills any gaps with nulls so that callers see a single
|
||||
continuous stream of data.
|
||||
.It Fn archive_read_data_block
|
||||
Return the next available block of data for this entry.
|
||||
Unlike
|
||||
.Fn archive_read_data ,
|
||||
the
|
||||
.Fn archive_read_data_block
|
||||
function avoids copying data and allows you to correctly handle
|
||||
sparse files, as supported by some archive formats.
|
||||
The library guarantees that offsets will increase and that blocks
|
||||
will not overlap.
|
||||
Note that the blocks returned from this function can be much larger
|
||||
than the block size read from disk, due to compression
|
||||
and internal buffer optimizations.
|
||||
.It Fn archive_read_data_skip
|
||||
A convenience function that repeatedly calls
|
||||
.Fn archive_read_data_block
|
||||
to skip all of the data for this archive entry.
|
||||
Note that this function is invoked automatically by
|
||||
.Fn archive_read_next_header2
|
||||
if the previous entry was not completely consumed.
|
||||
.It Fn archive_read_data_into_fd
|
||||
A convenience function that repeatedly calls
|
||||
.Fn archive_read_data_block
|
||||
to copy the entire entry to the provided file descriptor.
|
||||
.El
|
||||
.\"
|
||||
.Sh RETURN VALUES
|
||||
Most functions return zero on success, non-zero on error.
|
||||
The possible return codes include:
|
||||
.Cm ARCHIVE_OK
|
||||
(the operation succeeded),
|
||||
.Cm ARCHIVE_WARN
|
||||
(the operation succeeded but a non-critical error was encountered),
|
||||
.Cm ARCHIVE_EOF
|
||||
(end-of-archive was encountered),
|
||||
.Cm ARCHIVE_RETRY
|
||||
(the operation failed but can be retried),
|
||||
and
|
||||
.Cm ARCHIVE_FATAL
|
||||
(there was a fatal error; the archive should be closed immediately).
|
||||
.Pp
|
||||
.Fn archive_read_data
|
||||
returns a count of bytes actually read or zero at the end of the entry.
|
||||
On error, a value of
|
||||
.Cm ARCHIVE_FATAL ,
|
||||
.Cm ARCHIVE_WARN ,
|
||||
or
|
||||
.Cm ARCHIVE_RETRY
|
||||
is returned.
|
||||
.\"
|
||||
.Sh ERRORS
|
||||
Detailed error codes and textual descriptions are available from the
|
||||
.Fn archive_errno
|
||||
and
|
||||
.Fn archive_error_string
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_extract 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_header 3 ,
|
||||
.Xr archive_read_open 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
139
dependencies/libarchive-3.4.2/libarchive/archive_read_data_into_fd.c
vendored
Normal file
139
dependencies/libarchive-3.4.2/libarchive/archive_read_data_into_fd.c
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_data_into_fd.c,v 1.16 2008/05/23 05:01:29 cperciva Exp $");
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
/* Maximum amount of data to write at one time. */
|
||||
#define MAX_WRITE (1024 * 1024)
|
||||
|
||||
/*
|
||||
* This implementation minimizes copying of data and is sparse-file aware.
|
||||
*/
|
||||
static int
|
||||
pad_to(struct archive *a, int fd, int can_lseek,
|
||||
size_t nulls_size, const char *nulls,
|
||||
int64_t target_offset, int64_t actual_offset)
|
||||
{
|
||||
size_t to_write;
|
||||
ssize_t bytes_written;
|
||||
|
||||
if (can_lseek) {
|
||||
actual_offset = lseek(fd,
|
||||
target_offset - actual_offset, SEEK_CUR);
|
||||
if (actual_offset != target_offset) {
|
||||
archive_set_error(a, errno, "Seek error");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
while (target_offset > actual_offset) {
|
||||
to_write = nulls_size;
|
||||
if (target_offset < actual_offset + (int64_t)nulls_size)
|
||||
to_write = (size_t)(target_offset - actual_offset);
|
||||
bytes_written = write(fd, nulls, to_write);
|
||||
if (bytes_written < 0) {
|
||||
archive_set_error(a, errno, "Write error");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
actual_offset += bytes_written;
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
archive_read_data_into_fd(struct archive *a, int fd)
|
||||
{
|
||||
struct stat st;
|
||||
int r, r2;
|
||||
const void *buff;
|
||||
size_t size, bytes_to_write;
|
||||
ssize_t bytes_written;
|
||||
int64_t target_offset;
|
||||
int64_t actual_offset = 0;
|
||||
int can_lseek;
|
||||
char *nulls = NULL;
|
||||
size_t nulls_size = 16384;
|
||||
|
||||
archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
|
||||
"archive_read_data_into_fd");
|
||||
|
||||
can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
|
||||
if (!can_lseek)
|
||||
nulls = calloc(1, nulls_size);
|
||||
|
||||
while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
|
||||
ARCHIVE_OK) {
|
||||
const char *p = buff;
|
||||
if (target_offset > actual_offset) {
|
||||
r = pad_to(a, fd, can_lseek, nulls_size, nulls,
|
||||
target_offset, actual_offset);
|
||||
if (r != ARCHIVE_OK)
|
||||
break;
|
||||
actual_offset = target_offset;
|
||||
}
|
||||
while (size > 0) {
|
||||
bytes_to_write = size;
|
||||
if (bytes_to_write > MAX_WRITE)
|
||||
bytes_to_write = MAX_WRITE;
|
||||
bytes_written = write(fd, p, bytes_to_write);
|
||||
if (bytes_written < 0) {
|
||||
archive_set_error(a, errno, "Write error");
|
||||
r = ARCHIVE_FATAL;
|
||||
goto cleanup;
|
||||
}
|
||||
actual_offset += bytes_written;
|
||||
p += bytes_written;
|
||||
size -= bytes_written;
|
||||
}
|
||||
}
|
||||
|
||||
if (r == ARCHIVE_EOF && target_offset > actual_offset) {
|
||||
r2 = pad_to(a, fd, can_lseek, nulls_size, nulls,
|
||||
target_offset, actual_offset);
|
||||
if (r2 != ARCHIVE_OK)
|
||||
r = r2;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
free(nulls);
|
||||
if (r != ARCHIVE_EOF)
|
||||
return (r);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
346
dependencies/libarchive-3.4.2/libarchive/archive_read_disk.3
vendored
Normal file
346
dependencies/libarchive-3.4.2/libarchive/archive_read_disk.3
vendored
Normal file
|
@ -0,0 +1,346 @@
|
|||
.\" Copyright (c) 2003-2009 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 3, 2017
|
||||
.Dt ARCHIVE_READ_DISK 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_disk_new ,
|
||||
.Nm archive_read_disk_set_behavior ,
|
||||
.Nm archive_read_disk_set_symlink_logical ,
|
||||
.Nm archive_read_disk_set_symlink_physical ,
|
||||
.Nm archive_read_disk_set_symlink_hybrid ,
|
||||
.Nm archive_read_disk_entry_from_file ,
|
||||
.Nm archive_read_disk_gname ,
|
||||
.Nm archive_read_disk_uname ,
|
||||
.Nm archive_read_disk_set_uname_lookup ,
|
||||
.Nm archive_read_disk_set_gname_lookup ,
|
||||
.Nm archive_read_disk_set_standard_lookup
|
||||
.Nd functions for reading objects from disk
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Ft struct archive *
|
||||
.Fn archive_read_disk_new "void"
|
||||
.Ft int
|
||||
.Fn archive_read_disk_set_behavior "struct archive *" "int"
|
||||
.Ft int
|
||||
.Fn archive_read_disk_set_symlink_logical "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_disk_set_symlink_physical "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_disk_set_symlink_hybrid "struct archive *"
|
||||
.Ft const char *
|
||||
.Fn archive_read_disk_gname "struct archive *" "gid_t"
|
||||
.Ft const char *
|
||||
.Fn archive_read_disk_uname "struct archive *" "uid_t"
|
||||
.Ft int
|
||||
.Fo archive_read_disk_set_gname_lookup
|
||||
.Fa "struct archive *"
|
||||
.Fa "void *"
|
||||
.Fa "const char *(*lookup)(void *, gid_t)"
|
||||
.Fa "void (*cleanup)(void *)"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_read_disk_set_uname_lookup
|
||||
.Fa "struct archive *"
|
||||
.Fa "void *"
|
||||
.Fa "const char *(*lookup)(void *, uid_t)"
|
||||
.Fa "void (*cleanup)(void *)"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_read_disk_set_standard_lookup "struct archive *"
|
||||
.Ft int
|
||||
.Fo archive_read_disk_entry_from_file
|
||||
.Fa "struct archive *"
|
||||
.Fa "struct archive_entry *"
|
||||
.Fa "int fd"
|
||||
.Fa "const struct stat *"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
These functions provide an API for reading information about
|
||||
objects on disk.
|
||||
In particular, they provide an interface for populating
|
||||
.Tn struct archive_entry
|
||||
objects.
|
||||
.Bl -tag -width indent
|
||||
.It Fn archive_read_disk_new
|
||||
Allocates and initializes a
|
||||
.Tn struct archive
|
||||
object suitable for reading object information from disk.
|
||||
.It Fn archive_read_disk_set_behavior
|
||||
Configures various behavior options when reading entries from disk.
|
||||
The flags field consists of a bitwise OR of one or more of the
|
||||
following values:
|
||||
.Bl -tag -compact -width "indent"
|
||||
.It Cm ARCHIVE_READDISK_HONOR_NODUMP
|
||||
Skip files and directories with the nodump file attribute (file flag) set.
|
||||
By default, the nodump file attribute is ignored.
|
||||
.It Cm ARCHIVE_READDISK_MAC_COPYFILE
|
||||
Mac OS X specific.
|
||||
Read metadata (ACLs and extended attributes) with
|
||||
.Xr copyfile 3 .
|
||||
By default, metadata is read using
|
||||
.Xr copyfile 3 .
|
||||
.It Cm ARCHIVE_READDISK_NO_ACL
|
||||
Do not read Access Control Lists.
|
||||
By default, ACLs are read from disk.
|
||||
.It Cm ARCHIVE_READDISK_NO_FFLAGS
|
||||
Do not read file attributes (file flags).
|
||||
By default, file attributes are read from disk.
|
||||
See
|
||||
.Xr chattr 1
|
||||
.Pq Linux
|
||||
or
|
||||
.Xr chflags 1
|
||||
.Pq FreeBSD, Mac OS X
|
||||
for more information on file attributes.
|
||||
.It Cm ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS
|
||||
Do not traverse mount points.
|
||||
By default, mount points are traversed.
|
||||
.It Cm ARCHIVE_READDISK_NO_XATTR
|
||||
Do not read extended file attributes (xattrs).
|
||||
By default, extended file attributes are read from disk.
|
||||
See
|
||||
.Xr xattr 7
|
||||
.Pq Linux ,
|
||||
.Xr xattr 2
|
||||
.Pq Mac OS X ,
|
||||
or
|
||||
.Xr getextattr 8
|
||||
.Pq FreeBSD
|
||||
for more information on extended file attributes.
|
||||
.It Cm ARCHIVE_READDISK_RESTORE_ATIME
|
||||
Restore access time of traversed files.
|
||||
By default, access time of traversed files is not restored.
|
||||
.El
|
||||
.It Xo
|
||||
.Fn archive_read_disk_set_symlink_logical ,
|
||||
.Fn archive_read_disk_set_symlink_physical ,
|
||||
.Fn archive_read_disk_set_symlink_hybrid
|
||||
.Xc
|
||||
This sets the mode used for handling symbolic links.
|
||||
The
|
||||
.Dq logical
|
||||
mode follows all symbolic links.
|
||||
The
|
||||
.Dq physical
|
||||
mode does not follow any symbolic links.
|
||||
The
|
||||
.Dq hybrid
|
||||
mode currently behaves identically to the
|
||||
.Dq logical
|
||||
mode.
|
||||
.It Xo
|
||||
.Fn archive_read_disk_gname ,
|
||||
.Fn archive_read_disk_uname
|
||||
.Xc
|
||||
Returns a user or group name given a gid or uid value.
|
||||
By default, these always return a NULL string.
|
||||
.It Xo
|
||||
.Fn archive_read_disk_set_gname_lookup ,
|
||||
.Fn archive_read_disk_set_uname_lookup
|
||||
.Xc
|
||||
These allow you to override the functions used for
|
||||
user and group name lookups.
|
||||
You may also provide a
|
||||
.Tn void *
|
||||
pointer to a private data structure and a cleanup function for
|
||||
that data.
|
||||
The cleanup function will be invoked when the
|
||||
.Tn struct archive
|
||||
object is destroyed or when new lookup functions are registered.
|
||||
.It Fn archive_read_disk_set_standard_lookup
|
||||
This convenience function installs a standard set of user
|
||||
and group name lookup functions.
|
||||
These functions use
|
||||
.Xr getpwuid 3
|
||||
and
|
||||
.Xr getgrgid 3
|
||||
to convert ids to names, defaulting to NULL if the names cannot
|
||||
be looked up.
|
||||
These functions also implement a simple memory cache to reduce
|
||||
the number of calls to
|
||||
.Xr getpwuid 3
|
||||
and
|
||||
.Xr getgrgid 3 .
|
||||
.It Fn archive_read_disk_entry_from_file
|
||||
Populates a
|
||||
.Tn struct archive_entry
|
||||
object with information about a particular file.
|
||||
The
|
||||
.Tn archive_entry
|
||||
object must have already been created with
|
||||
.Xr archive_entry_new 3
|
||||
and at least one of the source path or path fields must already be set.
|
||||
(If both are set, the source path will be used.)
|
||||
.Pp
|
||||
Information is read from disk using the path name from the
|
||||
.Tn struct archive_entry
|
||||
object.
|
||||
If a file descriptor is provided, some information will be obtained using
|
||||
that file descriptor, on platforms that support the appropriate
|
||||
system calls.
|
||||
.Pp
|
||||
If a pointer to a
|
||||
.Tn struct stat
|
||||
is provided, information from that structure will be used instead
|
||||
of reading from the disk where appropriate.
|
||||
This can provide performance benefits in scenarios where
|
||||
.Tn struct stat
|
||||
information has already been read from the disk as a side effect
|
||||
of some other operation.
|
||||
(For example, directory traversal libraries often provide this information.)
|
||||
.Pp
|
||||
Where necessary, user and group ids are converted to user and group names
|
||||
using the currently-registered lookup functions above.
|
||||
This affects the file ownership fields and ACL values in the
|
||||
.Tn struct archive_entry
|
||||
object.
|
||||
.El
|
||||
More information about the
|
||||
.Va struct archive
|
||||
object and the overall design of the library can be found in the
|
||||
.Xr libarchive 3
|
||||
overview.
|
||||
.Sh EXAMPLES
|
||||
The following illustrates basic usage of the library by
|
||||
showing how to use it to copy an item on disk into an archive.
|
||||
.Bd -literal -offset indent
|
||||
void
|
||||
file_to_archive(struct archive *a, const char *name)
|
||||
{
|
||||
char buff[8192];
|
||||
size_t bytes_read;
|
||||
struct archive *ard;
|
||||
struct archive_entry *entry;
|
||||
int fd;
|
||||
|
||||
ard = archive_read_disk_new();
|
||||
archive_read_disk_set_standard_lookup(ard);
|
||||
entry = archive_entry_new();
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return;
|
||||
archive_entry_copy_pathname(entry, name);
|
||||
archive_read_disk_entry_from_file(ard, entry, fd, NULL);
|
||||
archive_write_header(a, entry);
|
||||
while ((bytes_read = read(fd, buff, sizeof(buff))) > 0)
|
||||
archive_write_data(a, buff, bytes_read);
|
||||
archive_write_finish_entry(a);
|
||||
archive_read_free(ard);
|
||||
archive_entry_free(entry);
|
||||
}
|
||||
.Ed
|
||||
.Sh RETURN VALUES
|
||||
Most functions return
|
||||
.Cm ARCHIVE_OK
|
||||
(zero) on success, or one of several negative
|
||||
error codes for errors.
|
||||
Specific error codes include:
|
||||
.Cm ARCHIVE_RETRY
|
||||
for operations that might succeed if retried,
|
||||
.Cm ARCHIVE_WARN
|
||||
for unusual conditions that do not prevent further operations, and
|
||||
.Cm ARCHIVE_FATAL
|
||||
for serious errors that make remaining operations impossible.
|
||||
.Pp
|
||||
.Fn archive_read_disk_new
|
||||
returns a pointer to a newly-allocated
|
||||
.Tn struct archive
|
||||
object or NULL if the allocation failed for any reason.
|
||||
.Pp
|
||||
.Fn archive_read_disk_gname
|
||||
and
|
||||
.Fn archive_read_disk_uname
|
||||
return
|
||||
.Tn const char *
|
||||
pointers to the textual name or NULL if the lookup failed for any reason.
|
||||
The returned pointer points to internal storage that
|
||||
may be reused on the next call to either of these functions;
|
||||
callers should copy the string if they need to continue accessing it.
|
||||
.\"
|
||||
.Sh ERRORS
|
||||
Detailed error codes and textual descriptions are available from the
|
||||
.Fn archive_errno
|
||||
and
|
||||
.Fn archive_error_string
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr archive_write 3 ,
|
||||
.Xr archive_write_disk 3 ,
|
||||
.Xr libarchive 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm libarchive
|
||||
library first appeared in
|
||||
.Fx 5.3 .
|
||||
The
|
||||
.Nm archive_read_disk
|
||||
interface was added to
|
||||
.Nm libarchive 2.6
|
||||
and first appeared in
|
||||
.Fx 8.0 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm libarchive
|
||||
library was written by
|
||||
.An Tim Kientzle Aq kientzle@FreeBSD.org .
|
||||
.Sh BUGS
|
||||
The
|
||||
.Dq standard
|
||||
user name and group name lookup functions are not the defaults because
|
||||
.Xr getgrgid 3
|
||||
and
|
||||
.Xr getpwuid 3
|
||||
are sometimes too large for particular applications.
|
||||
The current design allows the application author to use a more
|
||||
compact implementation when appropriate.
|
||||
.Pp
|
||||
The full list of metadata read from disk by
|
||||
.Fn archive_read_disk_entry_from_file
|
||||
is necessarily system-dependent.
|
||||
.Pp
|
||||
The
|
||||
.Fn archive_read_disk_entry_from_file
|
||||
function reads as much information as it can from disk.
|
||||
Some method should be provided to limit this so that clients who
|
||||
do not need ACLs, for instance, can avoid the extra work needed
|
||||
to look up such information.
|
||||
.Pp
|
||||
This API should provide a set of methods for walking a directory tree.
|
||||
That would make it a direct parallel of the
|
||||
.Xr archive_read 3
|
||||
API.
|
||||
When such methods are implemented, the
|
||||
.Dq hybrid
|
||||
symbolic link mode will make sense.
|
1044
dependencies/libarchive-3.4.2/libarchive/archive_read_disk_entry_from_file.c
vendored
Normal file
1044
dependencies/libarchive-3.4.2/libarchive/archive_read_disk_entry_from_file.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
2722
dependencies/libarchive-3.4.2/libarchive/archive_read_disk_posix.c
vendored
Normal file
2722
dependencies/libarchive-3.4.2/libarchive/archive_read_disk_posix.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
98
dependencies/libarchive-3.4.2/libarchive/archive_read_disk_private.h
vendored
Normal file
98
dependencies/libarchive-3.4.2/libarchive/archive_read_disk_private.h
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2009 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: head/lib/libarchive/archive_read_disk_private.h 201105 2009-12-28 03:20:54Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
|
||||
#include "archive_platform_acl.h"
|
||||
|
||||
struct tree;
|
||||
struct archive_entry;
|
||||
|
||||
struct archive_read_disk {
|
||||
struct archive archive;
|
||||
|
||||
/* Reused by archive_read_next_header() */
|
||||
struct archive_entry *entry;
|
||||
|
||||
/*
|
||||
* Symlink mode is one of 'L'ogical, 'P'hysical, or 'H'ybrid,
|
||||
* following an old BSD convention. 'L' follows all symlinks,
|
||||
* 'P' follows none, 'H' follows symlinks only for the first
|
||||
* item.
|
||||
*/
|
||||
char symlink_mode;
|
||||
|
||||
/*
|
||||
* Since symlink interaction changes, we need to track whether
|
||||
* we're following symlinks for the current item. 'L' mode above
|
||||
* sets this true, 'P' sets it false, 'H' changes it as we traverse.
|
||||
*/
|
||||
char follow_symlinks; /* Either 'L' or 'P'. */
|
||||
|
||||
/* Directory traversals. */
|
||||
struct tree *tree;
|
||||
int (*open_on_current_dir)(struct tree*, const char *, int);
|
||||
int (*tree_current_dir_fd)(struct tree*);
|
||||
int (*tree_enter_working_dir)(struct tree*);
|
||||
|
||||
/* Bitfield with ARCHIVE_READDISK_* tunables */
|
||||
int flags;
|
||||
|
||||
const char * (*lookup_gname)(void *private, int64_t gid);
|
||||
void (*cleanup_gname)(void *private);
|
||||
void *lookup_gname_data;
|
||||
const char * (*lookup_uname)(void *private, int64_t uid);
|
||||
void (*cleanup_uname)(void *private);
|
||||
void *lookup_uname_data;
|
||||
|
||||
int (*metadata_filter_func)(struct archive *, void *,
|
||||
struct archive_entry *);
|
||||
void *metadata_filter_data;
|
||||
|
||||
/* ARCHIVE_MATCH object. */
|
||||
struct archive *matching;
|
||||
/* Callback function, this will be invoked when ARCHIVE_MATCH
|
||||
* archive_match_*_excluded_ae return true. */
|
||||
void (*excluded_cb_func)(struct archive *, void *,
|
||||
struct archive_entry *);
|
||||
void *excluded_cb_data;
|
||||
};
|
||||
|
||||
const char *
|
||||
archive_read_disk_entry_setup_path(struct archive_read_disk *,
|
||||
struct archive_entry *, int *);
|
||||
|
||||
int
|
||||
archive_read_disk_entry_setup_acls(struct archive_read_disk *,
|
||||
struct archive_entry *, int *);
|
||||
#endif
|
313
dependencies/libarchive-3.4.2/libarchive/archive_read_disk_set_standard_lookup.c
vendored
Normal file
313
dependencies/libarchive-3.4.2/libarchive/archive_read_disk_set_standard_lookup.c
vendored
Normal file
|
@ -0,0 +1,313 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_set_standard_lookup.c 201109 2009-12-28 03:30:31Z kientzle $");
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_GRP_H
|
||||
#include <grp.h>
|
||||
#endif
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
int
|
||||
archive_read_disk_set_standard_lookup(struct archive *a)
|
||||
{
|
||||
archive_set_error(a, -1, "Standard lookups not available on Windows");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#else /* ! (_WIN32 && !__CYGWIN__) */
|
||||
#define name_cache_size 127
|
||||
|
||||
static const char * const NO_NAME = "(noname)";
|
||||
|
||||
struct name_cache {
|
||||
struct archive *archive;
|
||||
char *buff;
|
||||
size_t buff_size;
|
||||
int probes;
|
||||
int hits;
|
||||
size_t size;
|
||||
struct {
|
||||
id_t id;
|
||||
const char *name;
|
||||
} cache[name_cache_size];
|
||||
};
|
||||
|
||||
static const char * lookup_gname(void *, int64_t);
|
||||
static const char * lookup_uname(void *, int64_t);
|
||||
static void cleanup(void *);
|
||||
static const char * lookup_gname_helper(struct name_cache *, id_t gid);
|
||||
static const char * lookup_uname_helper(struct name_cache *, id_t uid);
|
||||
|
||||
/*
|
||||
* Installs functions that use getpwuid()/getgrgid()---along with
|
||||
* a simple cache to accelerate such lookups---into the archive_read_disk
|
||||
* object. This is in a separate file because getpwuid()/getgrgid()
|
||||
* can pull in a LOT of library code (including NIS/LDAP functions, which
|
||||
* pull in DNS resolvers, etc). This can easily top 500kB, which makes
|
||||
* it inappropriate for some space-constrained applications.
|
||||
*
|
||||
* Applications that are size-sensitive may want to just use the
|
||||
* real default functions (defined in archive_read_disk.c) that just
|
||||
* use the uid/gid without the lookup. Or define your own custom functions
|
||||
* if you prefer.
|
||||
*/
|
||||
int
|
||||
archive_read_disk_set_standard_lookup(struct archive *a)
|
||||
{
|
||||
struct name_cache *ucache = malloc(sizeof(struct name_cache));
|
||||
struct name_cache *gcache = malloc(sizeof(struct name_cache));
|
||||
|
||||
if (ucache == NULL || gcache == NULL) {
|
||||
archive_set_error(a, ENOMEM,
|
||||
"Can't allocate uname/gname lookup cache");
|
||||
free(ucache);
|
||||
free(gcache);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
memset(ucache, 0, sizeof(*ucache));
|
||||
ucache->archive = a;
|
||||
ucache->size = name_cache_size;
|
||||
memset(gcache, 0, sizeof(*gcache));
|
||||
gcache->archive = a;
|
||||
gcache->size = name_cache_size;
|
||||
|
||||
archive_read_disk_set_gname_lookup(a, gcache, lookup_gname, cleanup);
|
||||
archive_read_disk_set_uname_lookup(a, ucache, lookup_uname, cleanup);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup(void *data)
|
||||
{
|
||||
struct name_cache *cache = (struct name_cache *)data;
|
||||
size_t i;
|
||||
|
||||
if (cache != NULL) {
|
||||
for (i = 0; i < cache->size; i++) {
|
||||
if (cache->cache[i].name != NULL &&
|
||||
cache->cache[i].name != NO_NAME)
|
||||
free((void *)(uintptr_t)cache->cache[i].name);
|
||||
}
|
||||
free(cache->buff);
|
||||
free(cache);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup uid/gid from uname/gname, return NULL if no match.
|
||||
*/
|
||||
static const char *
|
||||
lookup_name(struct name_cache *cache,
|
||||
const char * (*lookup_fn)(struct name_cache *, id_t), id_t id)
|
||||
{
|
||||
const char *name;
|
||||
int slot;
|
||||
|
||||
|
||||
cache->probes++;
|
||||
|
||||
slot = id % cache->size;
|
||||
if (cache->cache[slot].name != NULL) {
|
||||
if (cache->cache[slot].id == id) {
|
||||
cache->hits++;
|
||||
if (cache->cache[slot].name == NO_NAME)
|
||||
return (NULL);
|
||||
return (cache->cache[slot].name);
|
||||
}
|
||||
if (cache->cache[slot].name != NO_NAME)
|
||||
free((void *)(uintptr_t)cache->cache[slot].name);
|
||||
cache->cache[slot].name = NULL;
|
||||
}
|
||||
|
||||
name = (lookup_fn)(cache, id);
|
||||
if (name == NULL) {
|
||||
/* Cache and return the negative response. */
|
||||
cache->cache[slot].name = NO_NAME;
|
||||
cache->cache[slot].id = id;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
cache->cache[slot].name = name;
|
||||
cache->cache[slot].id = id;
|
||||
return (cache->cache[slot].name);
|
||||
}
|
||||
|
||||
static const char *
|
||||
lookup_uname(void *data, int64_t uid)
|
||||
{
|
||||
struct name_cache *uname_cache = (struct name_cache *)data;
|
||||
return (lookup_name(uname_cache,
|
||||
&lookup_uname_helper, (id_t)uid));
|
||||
}
|
||||
|
||||
#if HAVE_GETPWUID_R
|
||||
static const char *
|
||||
lookup_uname_helper(struct name_cache *cache, id_t id)
|
||||
{
|
||||
struct passwd pwent, *result;
|
||||
char * nbuff;
|
||||
size_t nbuff_size;
|
||||
int r;
|
||||
|
||||
if (cache->buff_size == 0) {
|
||||
cache->buff_size = 256;
|
||||
cache->buff = malloc(cache->buff_size);
|
||||
}
|
||||
if (cache->buff == NULL)
|
||||
return (NULL);
|
||||
for (;;) {
|
||||
result = &pwent; /* Old getpwuid_r ignores last arg. */
|
||||
r = getpwuid_r((uid_t)id, &pwent,
|
||||
cache->buff, cache->buff_size, &result);
|
||||
if (r == 0)
|
||||
break;
|
||||
if (r != ERANGE)
|
||||
break;
|
||||
/* ERANGE means our buffer was too small, but POSIX
|
||||
* doesn't tell us how big the buffer should be, so
|
||||
* we just double it and try again. Because the buffer
|
||||
* is kept around in the cache object, we shouldn't
|
||||
* have to do this very often. */
|
||||
nbuff_size = cache->buff_size * 2;
|
||||
nbuff = realloc(cache->buff, nbuff_size);
|
||||
if (nbuff == NULL)
|
||||
break;
|
||||
cache->buff = nbuff;
|
||||
cache->buff_size = nbuff_size;
|
||||
}
|
||||
if (r != 0) {
|
||||
archive_set_error(cache->archive, errno,
|
||||
"Can't lookup user for id %d", (int)id);
|
||||
return (NULL);
|
||||
}
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
|
||||
return strdup(result->pw_name);
|
||||
}
|
||||
#else
|
||||
static const char *
|
||||
lookup_uname_helper(struct name_cache *cache, id_t id)
|
||||
{
|
||||
struct passwd *result;
|
||||
(void)cache; /* UNUSED */
|
||||
|
||||
result = getpwuid((uid_t)id);
|
||||
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
|
||||
return strdup(result->pw_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
lookup_gname(void *data, int64_t gid)
|
||||
{
|
||||
struct name_cache *gname_cache = (struct name_cache *)data;
|
||||
return (lookup_name(gname_cache,
|
||||
&lookup_gname_helper, (id_t)gid));
|
||||
}
|
||||
|
||||
#if HAVE_GETGRGID_R
|
||||
static const char *
|
||||
lookup_gname_helper(struct name_cache *cache, id_t id)
|
||||
{
|
||||
struct group grent, *result;
|
||||
char * nbuff;
|
||||
size_t nbuff_size;
|
||||
int r;
|
||||
|
||||
if (cache->buff_size == 0) {
|
||||
cache->buff_size = 256;
|
||||
cache->buff = malloc(cache->buff_size);
|
||||
}
|
||||
if (cache->buff == NULL)
|
||||
return (NULL);
|
||||
for (;;) {
|
||||
result = &grent; /* Old getgrgid_r ignores last arg. */
|
||||
r = getgrgid_r((gid_t)id, &grent,
|
||||
cache->buff, cache->buff_size, &result);
|
||||
if (r == 0)
|
||||
break;
|
||||
if (r != ERANGE)
|
||||
break;
|
||||
/* ERANGE means our buffer was too small, but POSIX
|
||||
* doesn't tell us how big the buffer should be, so
|
||||
* we just double it and try again. */
|
||||
nbuff_size = cache->buff_size * 2;
|
||||
nbuff = realloc(cache->buff, nbuff_size);
|
||||
if (nbuff == NULL)
|
||||
break;
|
||||
cache->buff = nbuff;
|
||||
cache->buff_size = nbuff_size;
|
||||
}
|
||||
if (r != 0) {
|
||||
archive_set_error(cache->archive, errno,
|
||||
"Can't lookup group for id %d", (int)id);
|
||||
return (NULL);
|
||||
}
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
|
||||
return strdup(result->gr_name);
|
||||
}
|
||||
#else
|
||||
static const char *
|
||||
lookup_gname_helper(struct name_cache *cache, id_t id)
|
||||
{
|
||||
struct group *result;
|
||||
(void)cache; /* UNUSED */
|
||||
|
||||
result = getgrgid((gid_t)id);
|
||||
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
|
||||
return strdup(result->gr_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! (_WIN32 && !__CYGWIN__) */
|
2477
dependencies/libarchive-3.4.2/libarchive/archive_read_disk_windows.c
vendored
Normal file
2477
dependencies/libarchive-3.4.2/libarchive/archive_read_disk_windows.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
137
dependencies/libarchive-3.4.2/libarchive/archive_read_extract.3
vendored
Normal file
137
dependencies/libarchive-3.4.2/libarchive/archive_read_extract.3
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
.\" Copyright (c) 2003-2011 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_READ_EXTRACT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_extract ,
|
||||
.Nm archive_read_extract2 ,
|
||||
.Nm archive_read_extract_set_progress_callback
|
||||
.Nd functions for reading streaming archives
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Ft int
|
||||
.Fo archive_read_extract
|
||||
.Fa "struct archive *"
|
||||
.Fa "struct archive_entry *"
|
||||
.Fa "int flags"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_read_extract2
|
||||
.Fa "struct archive *src"
|
||||
.Fa "struct archive_entry *"
|
||||
.Fa "struct archive *dest"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo archive_read_extract_set_progress_callback
|
||||
.Fa "struct archive *"
|
||||
.Fa "void (*func)(void *)"
|
||||
.Fa "void *user_data"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -compact -width indent
|
||||
.It Fn archive_read_extract , Fn archive_read_extract_set_skip_file
|
||||
A convenience function that wraps the corresponding
|
||||
.Xr archive_write_disk 3
|
||||
interfaces.
|
||||
The first call to
|
||||
.Fn archive_read_extract
|
||||
creates a restore object using
|
||||
.Xr archive_write_disk_new 3
|
||||
and
|
||||
.Xr archive_write_disk_set_standard_lookup 3 ,
|
||||
then transparently invokes
|
||||
.Xr archive_write_disk_set_options 3 ,
|
||||
.Xr archive_write_header 3 ,
|
||||
.Xr archive_write_data 3 ,
|
||||
and
|
||||
.Xr archive_write_finish_entry 3
|
||||
to create the entry on disk and copy data into it.
|
||||
The
|
||||
.Va flags
|
||||
argument is passed unmodified to
|
||||
.Xr archive_write_disk_set_options 3 .
|
||||
.It Fn archive_read_extract2
|
||||
This is another version of
|
||||
.Fn archive_read_extract
|
||||
that allows you to provide your own restore object.
|
||||
In particular, this allows you to override the standard lookup functions
|
||||
using
|
||||
.Xr archive_write_disk_set_group_lookup 3 ,
|
||||
and
|
||||
.Xr archive_write_disk_set_user_lookup 3 .
|
||||
Note that
|
||||
.Fn archive_read_extract2
|
||||
does not accept a
|
||||
.Va flags
|
||||
argument; you should use
|
||||
.Fn archive_write_disk_set_options
|
||||
to set the restore options yourself.
|
||||
.It Fn archive_read_extract_set_progress_callback
|
||||
Sets a pointer to a user-defined callback that can be used
|
||||
for updating progress displays during extraction.
|
||||
The progress function will be invoked during the extraction of large
|
||||
regular files.
|
||||
The progress function will be invoked with the pointer provided to this call.
|
||||
Generally, the data pointed to should include a reference to the archive
|
||||
object and the archive_entry object so that various statistics
|
||||
can be retrieved for the progress display.
|
||||
.El
|
||||
.\"
|
||||
.Sh RETURN VALUES
|
||||
Most functions return zero on success, non-zero on error.
|
||||
The possible return codes include:
|
||||
.Cm ARCHIVE_OK
|
||||
(the operation succeeded),
|
||||
.Cm ARCHIVE_WARN
|
||||
(the operation succeeded but a non-critical error was encountered),
|
||||
.Cm ARCHIVE_EOF
|
||||
(end-of-archive was encountered),
|
||||
.Cm ARCHIVE_RETRY
|
||||
(the operation failed but can be retried),
|
||||
and
|
||||
.Cm ARCHIVE_FATAL
|
||||
(there was a fatal error; the archive should be closed immediately).
|
||||
.Sh ERRORS
|
||||
Detailed error codes and textual descriptions are available from the
|
||||
.Fn archive_errno
|
||||
and
|
||||
.Fn archive_error_string
|
||||
functions.
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_open 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
60
dependencies/libarchive-3.4.2/libarchive/archive_read_extract.c
vendored
Normal file
60
dependencies/libarchive-3.4.2/libarchive/archive_read_extract.c
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
int
|
||||
archive_read_extract(struct archive *_a, struct archive_entry *entry, int flags)
|
||||
{
|
||||
struct archive_read_extract *extract;
|
||||
struct archive_read * a = (struct archive_read *)_a;
|
||||
|
||||
extract = __archive_read_get_extract(a);
|
||||
if (extract == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
/* If we haven't initialized the archive_write_disk object, do it now. */
|
||||
if (extract->ad == NULL) {
|
||||
extract->ad = archive_write_disk_new();
|
||||
if (extract->ad == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Can't extract");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_write_disk_set_standard_lookup(extract->ad);
|
||||
}
|
||||
|
||||
archive_write_disk_set_options(extract->ad, flags);
|
||||
return (archive_read_extract2(&a->archive, entry, extract->ad));
|
||||
}
|
155
dependencies/libarchive-3.4.2/libarchive/archive_read_extract2.c
vendored
Normal file
155
dependencies/libarchive-3.4.2/libarchive/archive_read_extract2.c
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $");
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
static int copy_data(struct archive *ar, struct archive *aw);
|
||||
static int archive_read_extract_cleanup(struct archive_read *);
|
||||
|
||||
|
||||
/* Retrieve an extract object without initialising the associated
|
||||
* archive_write_disk object.
|
||||
*/
|
||||
struct archive_read_extract *
|
||||
__archive_read_get_extract(struct archive_read *a)
|
||||
{
|
||||
if (a->extract == NULL) {
|
||||
a->extract = (struct archive_read_extract *)calloc(1, sizeof(*a->extract));
|
||||
if (a->extract == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Can't extract");
|
||||
return (NULL);
|
||||
}
|
||||
a->cleanup_archive_extract = archive_read_extract_cleanup;
|
||||
}
|
||||
return (a->extract);
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup function for archive_extract.
|
||||
*/
|
||||
static int
|
||||
archive_read_extract_cleanup(struct archive_read *a)
|
||||
{
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
if (a->extract->ad != NULL) {
|
||||
ret = archive_write_free(a->extract->ad);
|
||||
}
|
||||
free(a->extract);
|
||||
a->extract = NULL;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_extract2(struct archive *_a, struct archive_entry *entry,
|
||||
struct archive *ad)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
int r, r2;
|
||||
|
||||
/* Set up for this particular entry. */
|
||||
if (a->skip_file_set)
|
||||
archive_write_disk_set_skip_file(ad,
|
||||
a->skip_file_dev, a->skip_file_ino);
|
||||
r = archive_write_header(ad, entry);
|
||||
if (r < ARCHIVE_WARN)
|
||||
r = ARCHIVE_WARN;
|
||||
if (r != ARCHIVE_OK)
|
||||
/* If _write_header failed, copy the error. */
|
||||
archive_copy_error(&a->archive, ad);
|
||||
else if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) > 0)
|
||||
/* Otherwise, pour data into the entry. */
|
||||
r = copy_data(_a, ad);
|
||||
r2 = archive_write_finish_entry(ad);
|
||||
if (r2 < ARCHIVE_WARN)
|
||||
r2 = ARCHIVE_WARN;
|
||||
/* Use the first message. */
|
||||
if (r2 != ARCHIVE_OK && r == ARCHIVE_OK)
|
||||
archive_copy_error(&a->archive, ad);
|
||||
/* Use the worst error return. */
|
||||
if (r2 < r)
|
||||
r = r2;
|
||||
return (r);
|
||||
}
|
||||
|
||||
void
|
||||
archive_read_extract_set_progress_callback(struct archive *_a,
|
||||
void (*progress_func)(void *), void *user_data)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_extract *extract = __archive_read_get_extract(a);
|
||||
if (extract != NULL) {
|
||||
extract->extract_progress = progress_func;
|
||||
extract->extract_progress_user_data = user_data;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
copy_data(struct archive *ar, struct archive *aw)
|
||||
{
|
||||
int64_t offset;
|
||||
const void *buff;
|
||||
struct archive_read_extract *extract;
|
||||
size_t size;
|
||||
int r;
|
||||
|
||||
extract = __archive_read_get_extract((struct archive_read *)ar);
|
||||
if (extract == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
for (;;) {
|
||||
r = archive_read_data_block(ar, &buff, &size, &offset);
|
||||
if (r == ARCHIVE_EOF)
|
||||
return (ARCHIVE_OK);
|
||||
if (r != ARCHIVE_OK)
|
||||
return (r);
|
||||
r = (int)archive_write_data_block(aw, buff, size, offset);
|
||||
if (r < ARCHIVE_WARN)
|
||||
r = ARCHIVE_WARN;
|
||||
if (r < ARCHIVE_OK) {
|
||||
archive_set_error(ar, archive_errno(aw),
|
||||
"%s", archive_error_string(aw));
|
||||
return (r);
|
||||
}
|
||||
if (extract->extract_progress)
|
||||
(extract->extract_progress)
|
||||
(extract->extract_progress_user_data);
|
||||
}
|
||||
}
|
154
dependencies/libarchive-3.4.2/libarchive/archive_read_filter.3
vendored
Normal file
154
dependencies/libarchive-3.4.2/libarchive/archive_read_filter.3
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
.\" Copyright (c) 2003-2011 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 14, 2014
|
||||
.Dt ARCHIVE_READ_FILTER 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_support_filter_all ,
|
||||
.Nm archive_read_support_filter_bzip2 ,
|
||||
.Nm archive_read_support_filter_compress ,
|
||||
.Nm archive_read_support_filter_gzip ,
|
||||
.Nm archive_read_support_filter_lz4 ,
|
||||
.Nm archive_read_support_filter_lzma ,
|
||||
.Nm archive_read_support_filter_none ,
|
||||
.Nm archive_read_support_filter_rpm ,
|
||||
.Nm archive_read_support_filter_uu ,
|
||||
.Nm archive_read_support_filter_xz ,
|
||||
.Nm archive_read_support_filter_zstd ,
|
||||
.Nm archive_read_support_filter_program ,
|
||||
.Nm archive_read_support_filter_program_signature
|
||||
.Nd functions for reading streaming archives
|
||||
.\"
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_all "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_bzip2 "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_compress "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_grzip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_gzip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_lrzip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_lz4 "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_lzma "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_lzop "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_none "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_rpm "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_uu "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_xz "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_zstd "struct archive *"
|
||||
.Ft int
|
||||
.Fo archive_read_support_filter_program
|
||||
.Fa "struct archive *"
|
||||
.Fa "const char *cmd"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_read_support_filter_program_signature
|
||||
.Fa "struct archive *"
|
||||
.Fa "const char *cmd"
|
||||
.Fa "const void *signature"
|
||||
.Fa "size_t signature_length"
|
||||
.Fc
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -compact -width indent
|
||||
.It Xo
|
||||
.Fn archive_read_support_filter_bzip2 ,
|
||||
.Fn archive_read_support_filter_compress ,
|
||||
.Fn archive_read_support_filter_grzip ,
|
||||
.Fn archive_read_support_filter_gzip ,
|
||||
.Fn archive_read_support_filter_lrzip ,
|
||||
.Fn archive_read_support_filter_lz4 ,
|
||||
.Fn archive_read_support_filter_lzma ,
|
||||
.Fn archive_read_support_filter_lzop ,
|
||||
.Fn archive_read_support_filter_none ,
|
||||
.Fn archive_read_support_filter_rpm ,
|
||||
.Fn archive_read_support_filter_uu ,
|
||||
.Fn archive_read_support_filter_xz ,
|
||||
.Fn archive_read_support_filter_zstd ,
|
||||
.Xc
|
||||
Enables auto-detection code and decompression support for the
|
||||
specified compression.
|
||||
These functions may fall back on external programs if an appropriate
|
||||
library was not available at build time.
|
||||
Decompression using an external program is usually slower than
|
||||
decompression through built-in libraries.
|
||||
Note that
|
||||
.Dq none
|
||||
is always enabled by default.
|
||||
.It Fn archive_read_support_filter_all
|
||||
Enables all available decompression filters.
|
||||
.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,
|
||||
so it makes no sense to specify this in conjunction with any other
|
||||
decompression option.
|
||||
.It Fn archive_read_support_filter_program_signature
|
||||
This feeds data through the specified external program
|
||||
but only if the initial bytes of the data match the specified
|
||||
signature value.
|
||||
.El
|
||||
.\"
|
||||
.\". Sh EXAMPLE
|
||||
.\"
|
||||
.Sh RETURN VALUES
|
||||
These functions return
|
||||
.Cm ARCHIVE_OK
|
||||
if the compression is fully supported,
|
||||
.Cm ARCHIVE_WARN
|
||||
if the compression is supported only through an external program.
|
||||
.Pp
|
||||
.Fn archive_read_support_filter_none
|
||||
always succeeds.
|
||||
.\"
|
||||
.Sh ERRORS
|
||||
Detailed error codes and textual descriptions are available from the
|
||||
.Fn archive_errno
|
||||
and
|
||||
.Fn archive_error_string
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr libarchive 3
|
177
dependencies/libarchive-3.4.2/libarchive/archive_read_format.3
vendored
Normal file
177
dependencies/libarchive-3.4.2/libarchive/archive_read_format.3
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
.\" Copyright (c) 2003-2011 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_READ_FORMAT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_support_format_7zip ,
|
||||
.Nm archive_read_support_format_all ,
|
||||
.Nm archive_read_support_format_ar ,
|
||||
.Nm archive_read_support_format_by_code ,
|
||||
.Nm archive_read_support_format_cab ,
|
||||
.Nm archive_read_support_format_cpio ,
|
||||
.Nm archive_read_support_format_empty ,
|
||||
.Nm archive_read_support_format_iso9660 ,
|
||||
.Nm archive_read_support_format_lha ,
|
||||
.Nm archive_read_support_format_mtree ,
|
||||
.Nm archive_read_support_format_rar ,
|
||||
.Nm archive_read_support_format_raw ,
|
||||
.Nm archive_read_support_format_tar ,
|
||||
.Nm archive_read_support_format_xar ,
|
||||
.Nm archive_read_support_format_zip
|
||||
.Nd functions for reading streaming archives
|
||||
.\"
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_7zip "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_all "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_ar "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_by_code "struct archive *" "int"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_cab "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_cpio "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_empty "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_iso9660 "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_lha "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_mtree "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_rar "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_raw "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_tar "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_xar "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_format_zip "struct archive *"
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -compact -width indent
|
||||
.It Xo
|
||||
.Fn archive_read_support_format_7zip ,
|
||||
.Fn archive_read_support_format_ar ,
|
||||
.Fn archive_read_support_format_cab ,
|
||||
.Fn archive_read_support_format_cpio ,
|
||||
.Fn archive_read_support_format_iso9660 ,
|
||||
.Fn archive_read_support_format_lha ,
|
||||
.Fn archive_read_support_format_mtree ,
|
||||
.Fn archive_read_support_format_rar ,
|
||||
.Fn archive_read_support_format_raw ,
|
||||
.Fn archive_read_support_format_tar ,
|
||||
.Fn archive_read_support_format_xar ,
|
||||
.Fn archive_read_support_format_zip
|
||||
.Xc
|
||||
Enables support---including auto-detection code---for the
|
||||
specified archive format.
|
||||
For example,
|
||||
.Fn archive_read_support_format_tar
|
||||
enables support for a variety of standard tar formats, old-style tar,
|
||||
ustar, pax interchange format, and many common variants.
|
||||
.It Fn archive_read_support_format_all
|
||||
Enables support for all available formats except the
|
||||
.Dq raw
|
||||
format (see below).
|
||||
.It Fn archive_read_support_format_by_code
|
||||
Enables a single format specified by the format code.
|
||||
This can be useful when reading a single archive twice;
|
||||
use
|
||||
.Fn archive_format
|
||||
after reading the first time and pass the resulting code
|
||||
to this function to selectively enable only the necessary
|
||||
format support.
|
||||
Note: In statically-linked executables, this will cause
|
||||
your program to include support for every format.
|
||||
If executable size is a concern, you may wish to avoid
|
||||
using this function.
|
||||
.It Fn archive_read_support_format_empty
|
||||
Enables support for treating empty files as empty archives.
|
||||
Because empty files are valid for several different formats,
|
||||
it is not possible to accurately determine a format for
|
||||
an empty file based purely on contents.
|
||||
So empty files are treated by libarchive as a distinct
|
||||
format.
|
||||
.It Fn archive_read_support_format_raw
|
||||
The
|
||||
.Dq raw
|
||||
format handler allows libarchive to be used to read arbitrary data.
|
||||
It treats any data stream as an archive with a single entry.
|
||||
The pathname of this entry is
|
||||
.Dq data ;
|
||||
all other entry fields are unset.
|
||||
This is not enabled by
|
||||
.Fn archive_read_support_format_all
|
||||
in order to avoid erroneous handling of damaged archives.
|
||||
.El
|
||||
.\" .Sh EXAMPLE
|
||||
.Sh RETURN VALUES
|
||||
These functions return
|
||||
.Cm ARCHIVE_OK
|
||||
on success, or
|
||||
.Cm ARCHIVE_FATAL .
|
||||
.\"
|
||||
.Sh ERRORS
|
||||
Detailed error codes and textual descriptions are available from the
|
||||
.Fn archive_errno
|
||||
and
|
||||
.Fn archive_error_string
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
||||
.Sh BUGS
|
||||
Many traditional archiver programs treat
|
||||
empty files as valid empty archives.
|
||||
For example, many implementations of
|
||||
.Xr tar 1
|
||||
allow you to append entries to an empty file.
|
||||
Of course, it is impossible to determine the format of an empty file
|
||||
by inspecting the contents, so this library treats empty files as
|
||||
having a special
|
||||
.Dq empty
|
||||
format.
|
||||
.Pp
|
||||
Using the
|
||||
.Dq raw
|
||||
handler together with any other handler will often work
|
||||
but can produce surprising results.
|
93
dependencies/libarchive-3.4.2/libarchive/archive_read_free.3
vendored
Normal file
93
dependencies/libarchive-3.4.2/libarchive/archive_read_free.3
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
.\" Copyright (c) 2003-2011 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_READ_FREE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_close ,
|
||||
.Nm archive_read_finish ,
|
||||
.Nm archive_read_free
|
||||
.Nd functions for reading streaming archives
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Ft int
|
||||
.Fn archive_read_close "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_finish "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_free "struct archive *"
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -compact -width indent
|
||||
.It Fn archive_read_close
|
||||
Complete the archive and invoke the close callback.
|
||||
.It Fn archive_read_finish
|
||||
This is a deprecated synonym for
|
||||
.Fn archive_read_free .
|
||||
The new name was introduced with libarchive 3.0.
|
||||
Applications that need to compile with either libarchive 2
|
||||
or libarchive 3 should continue to use the
|
||||
.Fn archive_read_finish
|
||||
name.
|
||||
Both names will be supported until libarchive 4.0 is
|
||||
released, which is not expected to occur earlier
|
||||
than 2013.
|
||||
.It Fn archive_read_free
|
||||
Invokes
|
||||
.Fn archive_read_close
|
||||
if it was not invoked manually, then release all resources.
|
||||
Note: In libarchive 1.x, this function was declared to return
|
||||
.Ft void ,
|
||||
which made it impossible to detect certain errors when
|
||||
.Fn archive_read_close
|
||||
was invoked implicitly from this function.
|
||||
The declaration is corrected beginning with libarchive 2.0.
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
These functions return
|
||||
.Cm ARCHIVE_OK
|
||||
on success, or
|
||||
.Cm ARCHIVE_FATAL .
|
||||
.\"
|
||||
.Sh ERRORS
|
||||
Detailed error codes and textual descriptions are available from the
|
||||
.Fn archive_errno
|
||||
and
|
||||
.Fn archive_error_string
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_new 3 ,
|
||||
.Xr archive_read_open 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3
|
91
dependencies/libarchive-3.4.2/libarchive/archive_read_header.3
vendored
Normal file
91
dependencies/libarchive-3.4.2/libarchive/archive_read_header.3
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
.\" Copyright (c) 2003-2011 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_READ_HEADER 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_next_header ,
|
||||
.Nm archive_read_next_header2
|
||||
.Nd functions for reading streaming archives
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Ft int
|
||||
.Fn archive_read_next_header "struct archive *" "struct archive_entry **"
|
||||
.Ft int
|
||||
.Fn archive_read_next_header2 "struct archive *" "struct archive_entry *"
|
||||
.\"
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -compact -width indent
|
||||
.It Fn archive_read_next_header
|
||||
Read the header for the next entry and return a pointer to
|
||||
a
|
||||
.Tn struct archive_entry .
|
||||
This is a convenience wrapper around
|
||||
.Fn archive_read_next_header2
|
||||
that reuses an internal
|
||||
.Tn struct archive_entry
|
||||
object for each request.
|
||||
.It Fn archive_read_next_header2
|
||||
Read the header for the next entry and populate the provided
|
||||
.Tn struct archive_entry .
|
||||
.El
|
||||
.\"
|
||||
.Sh RETURN VALUES
|
||||
These functions return
|
||||
.Cm ARCHIVE_OK
|
||||
(the operation succeeded),
|
||||
.Cm ARCHIVE_WARN
|
||||
(the operation succeeded but a non-critical error was encountered),
|
||||
.Cm ARCHIVE_EOF
|
||||
(end-of-archive was encountered),
|
||||
.Cm ARCHIVE_RETRY
|
||||
(the operation failed but can be retried),
|
||||
and
|
||||
.Cm ARCHIVE_FATAL
|
||||
(there was a fatal error; the archive should be closed immediately).
|
||||
.\"
|
||||
.Sh ERRORS
|
||||
Detailed error codes and textual descriptions are available from the
|
||||
.Fn archive_errno
|
||||
and
|
||||
.Fn archive_error_string
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_extract 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_open 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
59
dependencies/libarchive-3.4.2/libarchive/archive_read_new.3
vendored
Normal file
59
dependencies/libarchive-3.4.2/libarchive/archive_read_new.3
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
.\" Copyright (c) 2003-2011 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_READ_NEW 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_new
|
||||
.Nd functions for reading streaming archives
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Ft struct archive *
|
||||
.Fn archive_read_new "void"
|
||||
.Sh DESCRIPTION
|
||||
Allocates and initializes a
|
||||
.Tn struct archive
|
||||
object suitable for reading from an archive.
|
||||
.Dv NULL
|
||||
is returned on error.
|
||||
.Pp
|
||||
A complete description of the
|
||||
.Tn struct archive
|
||||
object can be found in the overview manual page for
|
||||
.Xr libarchive 3 .
|
||||
.\" .Sh ERRORS
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
233
dependencies/libarchive-3.4.2/libarchive/archive_read_open.3
vendored
Normal file
233
dependencies/libarchive-3.4.2/libarchive/archive_read_open.3
vendored
Normal file
|
@ -0,0 +1,233 @@
|
|||
.\" Copyright (c) 2003-2011 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_READ_OPEN 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_open ,
|
||||
.Nm archive_read_open2 ,
|
||||
.Nm archive_read_open_fd ,
|
||||
.Nm archive_read_open_FILE ,
|
||||
.Nm archive_read_open_filename ,
|
||||
.Nm archive_read_open_memory
|
||||
.Nd functions for reading streaming archives
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.In archive.h
|
||||
.Ft int
|
||||
.Fo archive_read_open
|
||||
.Fa "struct archive *"
|
||||
.Fa "void *client_data"
|
||||
.Fa "archive_open_callback *"
|
||||
.Fa "archive_read_callback *"
|
||||
.Fa "archive_close_callback *"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_read_open2
|
||||
.Fa "struct archive *"
|
||||
.Fa "void *client_data"
|
||||
.Fa "archive_open_callback *"
|
||||
.Fa "archive_read_callback *"
|
||||
.Fa "archive_skip_callback *"
|
||||
.Fa "archive_close_callback *"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_read_open_FILE "struct archive *" "FILE *file"
|
||||
.Ft int
|
||||
.Fn archive_read_open_fd "struct archive *" "int fd" "size_t block_size"
|
||||
.Ft int
|
||||
.Fo archive_read_open_filename
|
||||
.Fa "struct archive *"
|
||||
.Fa "const char *filename"
|
||||
.Fa "size_t block_size"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_read_open_memory "struct archive *" "const void *buff" "size_t size"
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -compact -width indent
|
||||
.It Fn archive_read_open
|
||||
The same as
|
||||
.Fn archive_read_open2 ,
|
||||
except that the skip callback is assumed to be
|
||||
.Dv NULL .
|
||||
.It Fn archive_read_open2
|
||||
Freeze the settings, open the archive, and prepare for reading entries.
|
||||
This is the most generic version of this call, which accepts
|
||||
four callback functions.
|
||||
Most clients will want to use
|
||||
.Fn archive_read_open_filename ,
|
||||
.Fn archive_read_open_FILE ,
|
||||
.Fn archive_read_open_fd ,
|
||||
or
|
||||
.Fn archive_read_open_memory
|
||||
instead.
|
||||
The library invokes the client-provided functions to obtain
|
||||
raw bytes from the archive.
|
||||
.It Fn archive_read_open_FILE
|
||||
Like
|
||||
.Fn archive_read_open ,
|
||||
except that it accepts a
|
||||
.Ft "FILE *"
|
||||
pointer.
|
||||
This function should not be used with tape drives or other devices
|
||||
that require strict I/O blocking.
|
||||
.It Fn archive_read_open_fd
|
||||
Like
|
||||
.Fn archive_read_open ,
|
||||
except that it accepts a file descriptor and block size rather than
|
||||
a set of function pointers.
|
||||
Note that the file descriptor will not be automatically closed at
|
||||
end-of-archive.
|
||||
This function is safe for use with tape drives or other blocked devices.
|
||||
.It Fn archive_read_open_file
|
||||
This is a deprecated synonym for
|
||||
.Fn archive_read_open_filename .
|
||||
.It Fn archive_read_open_filename
|
||||
Like
|
||||
.Fn archive_read_open ,
|
||||
except that it accepts a simple filename and a block size.
|
||||
A NULL filename represents standard input.
|
||||
This function is safe for use with tape drives or other blocked devices.
|
||||
.It Fn archive_read_open_memory
|
||||
Like
|
||||
.Fn archive_read_open ,
|
||||
except that it accepts a pointer and size of a block of
|
||||
memory containing the archive data.
|
||||
.El
|
||||
.Pp
|
||||
A complete description of the
|
||||
.Tn struct archive
|
||||
and
|
||||
.Tn struct archive_entry
|
||||
objects can be found in the overview manual page for
|
||||
.Xr libarchive 3 .
|
||||
.Sh CLIENT CALLBACKS
|
||||
The callback functions must match the following prototypes:
|
||||
.Bl -item -offset indent
|
||||
.It
|
||||
.Ft typedef la_ssize_t
|
||||
.Fo archive_read_callback
|
||||
.Fa "struct archive *"
|
||||
.Fa "void *client_data"
|
||||
.Fa "const void **buffer"
|
||||
.Fc
|
||||
.It
|
||||
.Ft typedef la_int64_t
|
||||
.Fo archive_skip_callback
|
||||
.Fa "struct archive *"
|
||||
.Fa "void *client_data"
|
||||
.Fa "off_t request"
|
||||
.Fc
|
||||
.It
|
||||
.Ft typedef int
|
||||
.Fn archive_open_callback "struct archive *" "void *client_data"
|
||||
.It
|
||||
.Ft typedef int
|
||||
.Fn archive_close_callback "struct archive *" "void *client_data"
|
||||
.El
|
||||
.Pp
|
||||
The open callback is invoked by
|
||||
.Fn archive_open .
|
||||
It should return
|
||||
.Cm ARCHIVE_OK
|
||||
if the underlying file or data source is successfully
|
||||
opened.
|
||||
If the open fails, it should call
|
||||
.Fn archive_set_error
|
||||
to register an error code and message and return
|
||||
.Cm ARCHIVE_FATAL .
|
||||
.Pp
|
||||
The read callback is invoked whenever the library
|
||||
requires raw bytes from the archive.
|
||||
The read callback should read data into a buffer,
|
||||
set the
|
||||
.Li const void **buffer
|
||||
argument to point to the available data, and
|
||||
return a count of the number of bytes available.
|
||||
The library will invoke the read callback again
|
||||
only after it has consumed this data.
|
||||
The library imposes no constraints on the size
|
||||
of the data blocks returned.
|
||||
On end-of-file, the read callback should
|
||||
return zero.
|
||||
On error, the read callback should invoke
|
||||
.Fn archive_set_error
|
||||
to register an error code and message and
|
||||
return -1.
|
||||
.Pp
|
||||
The skip callback is invoked when the
|
||||
library wants to ignore a block of data.
|
||||
The return value is the number of bytes actually
|
||||
skipped, which may differ from the request.
|
||||
If the callback cannot skip data, it should return
|
||||
zero.
|
||||
If the skip callback is not provided (the
|
||||
function pointer is
|
||||
.Dv NULL ),
|
||||
the library will invoke the read function
|
||||
instead and simply discard the result.
|
||||
A skip callback can provide significant
|
||||
performance gains when reading uncompressed
|
||||
archives from slow disk drives or other media
|
||||
that can skip quickly.
|
||||
.Pp
|
||||
The close callback is invoked by archive_close when
|
||||
the archive processing is complete.
|
||||
The callback should return
|
||||
.Cm ARCHIVE_OK
|
||||
on success.
|
||||
On failure, the callback should invoke
|
||||
.Fn archive_set_error
|
||||
to register an error code and message and
|
||||
return
|
||||
.Cm ARCHIVE_FATAL .
|
||||
.\" .Sh EXAMPLE
|
||||
.\"
|
||||
.Sh RETURN VALUES
|
||||
These functions return
|
||||
.Cm ARCHIVE_OK
|
||||
on success, or
|
||||
.Cm ARCHIVE_FATAL .
|
||||
.\"
|
||||
.Sh ERRORS
|
||||
Detailed error codes and textual descriptions are available from the
|
||||
.Fn archive_errno
|
||||
and
|
||||
.Fn archive_error_string
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_read_data 3 ,
|
||||
.Xr archive_read_filter 3 ,
|
||||
.Xr archive_read_format 3 ,
|
||||
.Xr archive_read_set_options 3 ,
|
||||
.Xr archive_util 3 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr tar 5
|
211
dependencies/libarchive-3.4.2/libarchive/archive_read_open_fd.c
vendored
Normal file
211
dependencies/libarchive-3.4.2/libarchive/archive_read_open_fd.c
vendored
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_fd.c 201103 2009-12-28 03:13:49Z kientzle $");
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
|
||||
struct read_fd_data {
|
||||
int fd;
|
||||
size_t block_size;
|
||||
char use_lseek;
|
||||
void *buffer;
|
||||
};
|
||||
|
||||
static int file_close(struct archive *, void *);
|
||||
static ssize_t file_read(struct archive *, void *, const void **buff);
|
||||
static int64_t file_seek(struct archive *, void *, int64_t request, int);
|
||||
static int64_t file_skip(struct archive *, void *, int64_t request);
|
||||
|
||||
int
|
||||
archive_read_open_fd(struct archive *a, int fd, size_t block_size)
|
||||
{
|
||||
struct stat st;
|
||||
struct read_fd_data *mine;
|
||||
void *b;
|
||||
|
||||
archive_clear_error(a);
|
||||
if (fstat(fd, &st) != 0) {
|
||||
archive_set_error(a, errno, "Can't stat fd %d", fd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
mine = (struct read_fd_data *)calloc(1, sizeof(*mine));
|
||||
b = malloc(block_size);
|
||||
if (mine == NULL || b == NULL) {
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
free(mine);
|
||||
free(b);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
mine->block_size = block_size;
|
||||
mine->buffer = b;
|
||||
mine->fd = fd;
|
||||
/*
|
||||
* Skip support is a performance optimization for anything
|
||||
* that supports lseek(). On FreeBSD, only regular files and
|
||||
* raw disk devices support lseek() and there's no portable
|
||||
* way to determine if a device is a raw disk device, so we
|
||||
* only enable this optimization for regular files.
|
||||
*/
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
|
||||
mine->use_lseek = 1;
|
||||
}
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
setmode(mine->fd, O_BINARY);
|
||||
#endif
|
||||
|
||||
archive_read_set_read_callback(a, file_read);
|
||||
archive_read_set_skip_callback(a, file_skip);
|
||||
archive_read_set_seek_callback(a, file_seek);
|
||||
archive_read_set_close_callback(a, file_close);
|
||||
archive_read_set_callback_data(a, mine);
|
||||
return (archive_read_open1(a));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
file_read(struct archive *a, void *client_data, const void **buff)
|
||||
{
|
||||
struct read_fd_data *mine = (struct read_fd_data *)client_data;
|
||||
ssize_t bytes_read;
|
||||
|
||||
*buff = mine->buffer;
|
||||
for (;;) {
|
||||
bytes_read = read(mine->fd, mine->buffer, mine->block_size);
|
||||
if (bytes_read < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
archive_set_error(a, errno, "Error reading fd %d",
|
||||
mine->fd);
|
||||
}
|
||||
return (bytes_read);
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t
|
||||
file_skip(struct archive *a, void *client_data, int64_t request)
|
||||
{
|
||||
struct read_fd_data *mine = (struct read_fd_data *)client_data;
|
||||
int64_t skip = request;
|
||||
int64_t old_offset, new_offset;
|
||||
int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */
|
||||
|
||||
if (!mine->use_lseek)
|
||||
return (0);
|
||||
|
||||
/* Reduce a request that would overflow the 'skip' variable. */
|
||||
if (sizeof(request) > sizeof(skip)) {
|
||||
int64_t max_skip =
|
||||
(((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
|
||||
if (request > max_skip)
|
||||
skip = max_skip;
|
||||
}
|
||||
|
||||
/* Reduce request to the next smallest multiple of block_size */
|
||||
request = (request / mine->block_size) * mine->block_size;
|
||||
if (request == 0)
|
||||
return (0);
|
||||
|
||||
if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) &&
|
||||
((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0))
|
||||
return (new_offset - old_offset);
|
||||
|
||||
/* If seek failed once, it will probably fail again. */
|
||||
mine->use_lseek = 0;
|
||||
|
||||
/* Let libarchive recover with read+discard. */
|
||||
if (errno == ESPIPE)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* There's been an error other than ESPIPE. This is most
|
||||
* likely caused by a programmer error (too large request)
|
||||
* or a corrupted archive file.
|
||||
*/
|
||||
archive_set_error(a, errno, "Error seeking");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Store the offset and use it in the read callback.
|
||||
*/
|
||||
static int64_t
|
||||
file_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
{
|
||||
struct read_fd_data *mine = (struct read_fd_data *)client_data;
|
||||
int64_t r;
|
||||
|
||||
/* We use off_t here because lseek() is declared that way. */
|
||||
/* See above for notes about when off_t is less than 64 bits. */
|
||||
r = lseek(mine->fd, request, whence);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
||||
if (errno == ESPIPE) {
|
||||
archive_set_error(a, errno,
|
||||
"A file descriptor(%d) is not seekable(PIPE)", mine->fd);
|
||||
return (ARCHIVE_FAILED);
|
||||
} else {
|
||||
/* If the input is corrupted or truncated, fail. */
|
||||
archive_set_error(a, errno,
|
||||
"Error seeking in a file descriptor(%d)", mine->fd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
file_close(struct archive *a, void *client_data)
|
||||
{
|
||||
struct read_fd_data *mine = (struct read_fd_data *)client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
free(mine->buffer);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
180
dependencies/libarchive-3.4.2/libarchive/archive_read_open_file.c
vendored
Normal file
180
dependencies/libarchive-3.4.2/libarchive/archive_read_open_file.c
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_file.c 201093 2009-12-28 02:28:44Z kientzle $");
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
|
||||
struct read_FILE_data {
|
||||
FILE *f;
|
||||
size_t block_size;
|
||||
void *buffer;
|
||||
char can_skip;
|
||||
};
|
||||
|
||||
static int file_close(struct archive *, void *);
|
||||
static ssize_t file_read(struct archive *, void *, const void **buff);
|
||||
static int64_t file_skip(struct archive *, void *, int64_t request);
|
||||
|
||||
int
|
||||
archive_read_open_FILE(struct archive *a, FILE *f)
|
||||
{
|
||||
struct stat st;
|
||||
struct read_FILE_data *mine;
|
||||
size_t block_size = 128 * 1024;
|
||||
void *b;
|
||||
|
||||
archive_clear_error(a);
|
||||
mine = (struct read_FILE_data *)malloc(sizeof(*mine));
|
||||
b = malloc(block_size);
|
||||
if (mine == NULL || b == NULL) {
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
free(mine);
|
||||
free(b);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
mine->block_size = block_size;
|
||||
mine->buffer = b;
|
||||
mine->f = f;
|
||||
/*
|
||||
* If we can't fstat() the file, it may just be that it's not
|
||||
* a file. (On some platforms, FILE * objects can wrap I/O
|
||||
* streams that don't support fileno()). As a result, fileno()
|
||||
* should be used cautiously.)
|
||||
*/
|
||||
if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
|
||||
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
|
||||
/* Enable the seek optimization only for regular files. */
|
||||
mine->can_skip = 1;
|
||||
} else
|
||||
mine->can_skip = 0;
|
||||
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
setmode(fileno(mine->f), O_BINARY);
|
||||
#endif
|
||||
|
||||
archive_read_set_read_callback(a, file_read);
|
||||
archive_read_set_skip_callback(a, file_skip);
|
||||
archive_read_set_close_callback(a, file_close);
|
||||
archive_read_set_callback_data(a, mine);
|
||||
return (archive_read_open1(a));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
file_read(struct archive *a, void *client_data, const void **buff)
|
||||
{
|
||||
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
|
||||
size_t bytes_read;
|
||||
|
||||
*buff = mine->buffer;
|
||||
bytes_read = fread(mine->buffer, 1, mine->block_size, mine->f);
|
||||
if (bytes_read < mine->block_size && ferror(mine->f)) {
|
||||
archive_set_error(a, errno, "Error reading file");
|
||||
}
|
||||
return (bytes_read);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
file_skip(struct archive *a, void *client_data, int64_t request)
|
||||
{
|
||||
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
|
||||
#if HAVE_FSEEKO
|
||||
off_t skip = (off_t)request;
|
||||
#elif HAVE__FSEEKI64
|
||||
int64_t skip = request;
|
||||
#else
|
||||
long skip = (long)request;
|
||||
#endif
|
||||
int skip_bits = sizeof(skip) * 8 - 1;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
|
||||
/*
|
||||
* If we can't skip, return 0 as the amount we did step and
|
||||
* the caller will work around by reading and discarding.
|
||||
*/
|
||||
if (!mine->can_skip)
|
||||
return (0);
|
||||
if (request == 0)
|
||||
return (0);
|
||||
|
||||
/* If request is too big for a long or an off_t, reduce it. */
|
||||
if (sizeof(request) > sizeof(skip)) {
|
||||
int64_t max_skip =
|
||||
(((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
|
||||
if (request > max_skip)
|
||||
skip = max_skip;
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
/* fileno() isn't safe on all platforms ... see above. */
|
||||
if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
|
||||
#elif HAVE_FSEEKO
|
||||
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
|
||||
#elif HAVE__FSEEKI64
|
||||
if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
|
||||
#else
|
||||
if (fseek(mine->f, skip, SEEK_CUR) != 0)
|
||||
#endif
|
||||
{
|
||||
mine->can_skip = 0;
|
||||
return (0);
|
||||
}
|
||||
return (request);
|
||||
}
|
||||
|
||||
static int
|
||||
file_close(struct archive *a, void *client_data)
|
||||
{
|
||||
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
free(mine->buffer);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
582
dependencies/libarchive-3.4.2/libarchive/archive_read_open_filename.c
vendored
Normal file
582
dependencies/libarchive-3.4.2/libarchive/archive_read_open_filename.c
vendored
Normal file
|
@ -0,0 +1,582 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2010 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_filename.c 201093 2009-12-28 02:28:44Z kientzle $");
|
||||
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
#include <sys/disk.h>
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/dkio.h>
|
||||
#elif defined(__DragonFly__)
|
||||
#include <sys/diskslice.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_string.h"
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
struct read_file_data {
|
||||
int fd;
|
||||
size_t block_size;
|
||||
void *buffer;
|
||||
mode_t st_mode; /* Mode bits for opened file. */
|
||||
char use_lseek;
|
||||
enum fnt_e { FNT_STDIN, FNT_MBS, FNT_WCS } filename_type;
|
||||
union {
|
||||
char m[1];/* MBS filename. */
|
||||
wchar_t w[1];/* WCS filename. */
|
||||
} filename; /* Must be last! */
|
||||
};
|
||||
|
||||
static int file_open(struct archive *, void *);
|
||||
static int file_close(struct archive *, void *);
|
||||
static int file_close2(struct archive *, void *);
|
||||
static int file_switch(struct archive *, void *, void *);
|
||||
static ssize_t file_read(struct archive *, void *, const void **buff);
|
||||
static int64_t file_seek(struct archive *, void *, int64_t request, int);
|
||||
static int64_t file_skip(struct archive *, void *, int64_t request);
|
||||
static int64_t file_skip_lseek(struct archive *, void *, int64_t request);
|
||||
|
||||
int
|
||||
archive_read_open_file(struct archive *a, const char *filename,
|
||||
size_t block_size)
|
||||
{
|
||||
return (archive_read_open_filename(a, filename, block_size));
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_open_filename(struct archive *a, const char *filename,
|
||||
size_t block_size)
|
||||
{
|
||||
const char *filenames[2];
|
||||
filenames[0] = filename;
|
||||
filenames[1] = NULL;
|
||||
return archive_read_open_filenames(a, filenames, block_size);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_open_filenames(struct archive *a, const char **filenames,
|
||||
size_t block_size)
|
||||
{
|
||||
struct read_file_data *mine;
|
||||
const char *filename = NULL;
|
||||
if (filenames)
|
||||
filename = *(filenames++);
|
||||
|
||||
archive_clear_error(a);
|
||||
do
|
||||
{
|
||||
if (filename == NULL)
|
||||
filename = "";
|
||||
mine = (struct read_file_data *)calloc(1,
|
||||
sizeof(*mine) + strlen(filename));
|
||||
if (mine == NULL)
|
||||
goto no_memory;
|
||||
strcpy(mine->filename.m, filename);
|
||||
mine->block_size = block_size;
|
||||
mine->fd = -1;
|
||||
mine->buffer = NULL;
|
||||
mine->st_mode = mine->use_lseek = 0;
|
||||
if (filename == NULL || filename[0] == '\0') {
|
||||
mine->filename_type = FNT_STDIN;
|
||||
} else
|
||||
mine->filename_type = FNT_MBS;
|
||||
if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
|
||||
return (ARCHIVE_FATAL);
|
||||
if (filenames == NULL)
|
||||
break;
|
||||
filename = *(filenames++);
|
||||
} while (filename != NULL && filename[0] != '\0');
|
||||
archive_read_set_open_callback(a, file_open);
|
||||
archive_read_set_read_callback(a, file_read);
|
||||
archive_read_set_skip_callback(a, file_skip);
|
||||
archive_read_set_close_callback(a, file_close);
|
||||
archive_read_set_switch_callback(a, file_switch);
|
||||
archive_read_set_seek_callback(a, file_seek);
|
||||
|
||||
return (archive_read_open1(a));
|
||||
no_memory:
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
|
||||
size_t block_size)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)calloc(1,
|
||||
sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
|
||||
if (!mine)
|
||||
{
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
mine->fd = -1;
|
||||
mine->block_size = block_size;
|
||||
|
||||
if (wfilename == NULL || wfilename[0] == L'\0') {
|
||||
mine->filename_type = FNT_STDIN;
|
||||
} else {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
mine->filename_type = FNT_WCS;
|
||||
wcscpy(mine->filename.w, wfilename);
|
||||
#else
|
||||
/*
|
||||
* POSIX system does not support a wchar_t interface for
|
||||
* open() system call, so we have to translate a wchar_t
|
||||
* filename to multi-byte one and use it.
|
||||
*/
|
||||
struct archive_string fn;
|
||||
|
||||
archive_string_init(&fn);
|
||||
if (archive_string_append_from_wcs(&fn, wfilename,
|
||||
wcslen(wfilename)) != 0) {
|
||||
if (errno == ENOMEM)
|
||||
archive_set_error(a, errno,
|
||||
"Can't allocate memory");
|
||||
else
|
||||
archive_set_error(a, EINVAL,
|
||||
"Failed to convert a wide-character"
|
||||
" filename to a multi-byte filename");
|
||||
archive_string_free(&fn);
|
||||
free(mine);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
mine->filename_type = FNT_MBS;
|
||||
strcpy(mine->filename.m, fn.s);
|
||||
archive_string_free(&fn);
|
||||
#endif
|
||||
}
|
||||
if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
|
||||
return (ARCHIVE_FATAL);
|
||||
archive_read_set_open_callback(a, file_open);
|
||||
archive_read_set_read_callback(a, file_read);
|
||||
archive_read_set_skip_callback(a, file_skip);
|
||||
archive_read_set_close_callback(a, file_close);
|
||||
archive_read_set_switch_callback(a, file_switch);
|
||||
archive_read_set_seek_callback(a, file_seek);
|
||||
|
||||
return (archive_read_open1(a));
|
||||
}
|
||||
|
||||
static int
|
||||
file_open(struct archive *a, void *client_data)
|
||||
{
|
||||
struct stat st;
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
void *buffer;
|
||||
const char *filename = NULL;
|
||||
const wchar_t *wfilename = NULL;
|
||||
int fd = -1;
|
||||
int is_disk_like = 0;
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
off_t mediasize = 0; /* FreeBSD-specific, so off_t okay here. */
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
struct disklabel dl;
|
||||
#elif defined(__DragonFly__)
|
||||
struct partinfo pi;
|
||||
#endif
|
||||
|
||||
archive_clear_error(a);
|
||||
if (mine->filename_type == FNT_STDIN) {
|
||||
/* We used to delegate stdin support by
|
||||
* directly calling archive_read_open_fd(a,0,block_size)
|
||||
* here, but that doesn't (and shouldn't) handle the
|
||||
* end-of-file flush when reading stdout from a pipe.
|
||||
* Basically, read_open_fd() is intended for folks who
|
||||
* are willing to handle such details themselves. This
|
||||
* API is intended to be a little smarter for folks who
|
||||
* want easy handling of the common case.
|
||||
*/
|
||||
fd = 0;
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
setmode(0, O_BINARY);
|
||||
#endif
|
||||
filename = "";
|
||||
} else if (mine->filename_type == FNT_MBS) {
|
||||
filename = mine->filename.m;
|
||||
fd = open(filename, O_RDONLY | O_BINARY | O_CLOEXEC);
|
||||
__archive_ensure_cloexec_flag(fd);
|
||||
if (fd < 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to open '%s'", filename);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
} else {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
wfilename = mine->filename.w;
|
||||
fd = _wopen(wfilename, O_RDONLY | O_BINARY);
|
||||
if (fd < 0 && errno == ENOENT) {
|
||||
wchar_t *fullpath;
|
||||
fullpath = __la_win_permissive_name_w(wfilename);
|
||||
if (fullpath != NULL) {
|
||||
fd = _wopen(fullpath, O_RDONLY | O_BINARY);
|
||||
free(fullpath);
|
||||
}
|
||||
}
|
||||
if (fd < 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to open '%S'", wfilename);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#else
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unexpedted operation in archive_read_open_filename");
|
||||
goto fail;
|
||||
#endif
|
||||
}
|
||||
if (fstat(fd, &st) != 0) {
|
||||
if (mine->filename_type == FNT_WCS)
|
||||
archive_set_error(a, errno, "Can't stat '%S'",
|
||||
wfilename);
|
||||
else
|
||||
archive_set_error(a, errno, "Can't stat '%s'",
|
||||
filename);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether the input looks like a disk device or a
|
||||
* tape device. The results are used below to select an I/O
|
||||
* strategy:
|
||||
* = "disk-like" devices support arbitrary lseek() and will
|
||||
* support I/O requests of any size. So we get easy skipping
|
||||
* and can cheat on block sizes to get better performance.
|
||||
* = "tape-like" devices require strict blocking and use
|
||||
* specialized ioctls for seeking.
|
||||
* = "socket-like" devices cannot seek at all but can improve
|
||||
* performance by using nonblocking I/O to read "whatever is
|
||||
* available right now".
|
||||
*
|
||||
* Right now, we only specially recognize disk-like devices,
|
||||
* but it should be straightforward to add probes and strategy
|
||||
* here for tape-like and socket-like devices.
|
||||
*/
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
/* Safety: Tell the extractor not to overwrite the input. */
|
||||
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
|
||||
/* Regular files act like disks. */
|
||||
is_disk_like = 1;
|
||||
}
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
/* FreeBSD: if it supports DIOCGMEDIASIZE ioctl, it's disk-like. */
|
||||
else if (S_ISCHR(st.st_mode) &&
|
||||
ioctl(fd, DIOCGMEDIASIZE, &mediasize) == 0 &&
|
||||
mediasize > 0) {
|
||||
is_disk_like = 1;
|
||||
}
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
/* Net/OpenBSD: if it supports DIOCGDINFO ioctl, it's disk-like. */
|
||||
else if ((S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) &&
|
||||
ioctl(fd, DIOCGDINFO, &dl) == 0 &&
|
||||
dl.d_partitions[DISKPART(st.st_rdev)].p_size > 0) {
|
||||
is_disk_like = 1;
|
||||
}
|
||||
#elif defined(__DragonFly__)
|
||||
/* DragonFly BSD: if it supports DIOCGPART ioctl, it's disk-like. */
|
||||
else if (S_ISCHR(st.st_mode) &&
|
||||
ioctl(fd, DIOCGPART, &pi) == 0 &&
|
||||
pi.media_size > 0) {
|
||||
is_disk_like = 1;
|
||||
}
|
||||
#elif defined(__linux__)
|
||||
/* Linux: All block devices are disk-like. */
|
||||
else if (S_ISBLK(st.st_mode) &&
|
||||
lseek(fd, 0, SEEK_CUR) == 0 &&
|
||||
lseek(fd, 0, SEEK_SET) == 0 &&
|
||||
lseek(fd, 0, SEEK_END) > 0 &&
|
||||
lseek(fd, 0, SEEK_SET) == 0) {
|
||||
is_disk_like = 1;
|
||||
}
|
||||
#endif
|
||||
/* TODO: Add an "is_tape_like" variable and appropriate tests. */
|
||||
|
||||
/* Disk-like devices prefer power-of-two block sizes. */
|
||||
/* Use provided block_size as a guide so users have some control. */
|
||||
if (is_disk_like) {
|
||||
size_t new_block_size = 64 * 1024;
|
||||
while (new_block_size < mine->block_size
|
||||
&& new_block_size < 64 * 1024 * 1024)
|
||||
new_block_size *= 2;
|
||||
mine->block_size = new_block_size;
|
||||
}
|
||||
buffer = malloc(mine->block_size);
|
||||
if (buffer == NULL) {
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
goto fail;
|
||||
}
|
||||
mine->buffer = buffer;
|
||||
mine->fd = fd;
|
||||
/* Remember mode so close can decide whether to flush. */
|
||||
mine->st_mode = st.st_mode;
|
||||
|
||||
/* Disk-like inputs can use lseek(). */
|
||||
if (is_disk_like)
|
||||
mine->use_lseek = 1;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
fail:
|
||||
/*
|
||||
* Don't close file descriptors not opened or ones pointing referring
|
||||
* to `FNT_STDIN`.
|
||||
*/
|
||||
if (fd != -1 && fd != 0)
|
||||
close(fd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
file_read(struct archive *a, void *client_data, const void **buff)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
ssize_t bytes_read;
|
||||
|
||||
/* TODO: If a recent lseek() operation has left us
|
||||
* mis-aligned, read and return a short block to try to get
|
||||
* us back in alignment. */
|
||||
|
||||
/* TODO: Someday, try mmap() here; if that succeeds, give
|
||||
* the entire file to libarchive as a single block. That
|
||||
* could be a lot faster than block-by-block manual I/O. */
|
||||
|
||||
/* TODO: We might be able to improve performance on pipes and
|
||||
* sockets by setting non-blocking I/O and just accepting
|
||||
* whatever we get here instead of waiting for a full block
|
||||
* worth of data. */
|
||||
|
||||
*buff = mine->buffer;
|
||||
for (;;) {
|
||||
bytes_read = read(mine->fd, mine->buffer, mine->block_size);
|
||||
if (bytes_read < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else if (mine->filename_type == FNT_STDIN)
|
||||
archive_set_error(a, errno,
|
||||
"Error reading stdin");
|
||||
else if (mine->filename_type == FNT_MBS)
|
||||
archive_set_error(a, errno,
|
||||
"Error reading '%s'", mine->filename.m);
|
||||
else
|
||||
archive_set_error(a, errno,
|
||||
"Error reading '%S'", mine->filename.w);
|
||||
}
|
||||
return (bytes_read);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Regular files and disk-like block devices can use simple lseek
|
||||
* without needing to round the request to the block size.
|
||||
*
|
||||
* TODO: This can leave future reads mis-aligned. Since we know the
|
||||
* offset here, we should store it and use it in file_read() above
|
||||
* to determine whether we should perform a short read to get back
|
||||
* into alignment. Long series of mis-aligned reads can negatively
|
||||
* impact disk throughput. (Of course, the performance impact should
|
||||
* be carefully tested; extra code complexity is only worthwhile if
|
||||
* it does provide measurable improvement.)
|
||||
*
|
||||
* TODO: Be lazy about the actual seek. There are a few pathological
|
||||
* cases where libarchive makes a bunch of seek requests in a row
|
||||
* without any intervening reads. This isn't a huge performance
|
||||
* problem, since the kernel handles seeks lazily already, but
|
||||
* it would be very slightly faster if we simply remembered the
|
||||
* seek request here and then actually performed the seek at the
|
||||
* top of the read callback above.
|
||||
*/
|
||||
static int64_t
|
||||
file_skip_lseek(struct archive *a, void *client_data, int64_t request)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* We use _lseeki64() on Windows. */
|
||||
int64_t old_offset, new_offset;
|
||||
#else
|
||||
off_t old_offset, new_offset;
|
||||
#endif
|
||||
|
||||
/* We use off_t here because lseek() is declared that way. */
|
||||
|
||||
/* TODO: Deal with case where off_t isn't 64 bits.
|
||||
* This shouldn't be a problem on Linux or other POSIX
|
||||
* systems, since the configuration logic for libarchive
|
||||
* tries to obtain a 64-bit off_t.
|
||||
*/
|
||||
if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 &&
|
||||
(new_offset = lseek(mine->fd, request, SEEK_CUR)) >= 0)
|
||||
return (new_offset - old_offset);
|
||||
|
||||
/* If lseek() fails, don't bother trying again. */
|
||||
mine->use_lseek = 0;
|
||||
|
||||
/* Let libarchive recover with read+discard */
|
||||
if (errno == ESPIPE)
|
||||
return (0);
|
||||
|
||||
/* If the input is corrupted or truncated, fail. */
|
||||
if (mine->filename_type == FNT_STDIN)
|
||||
archive_set_error(a, errno, "Error seeking in stdin");
|
||||
else if (mine->filename_type == FNT_MBS)
|
||||
archive_set_error(a, errno, "Error seeking in '%s'",
|
||||
mine->filename.m);
|
||||
else
|
||||
archive_set_error(a, errno, "Error seeking in '%S'",
|
||||
mine->filename.w);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* TODO: Implement another file_skip_XXXX that uses MTIO ioctls to
|
||||
* accelerate operation on tape drives.
|
||||
*/
|
||||
|
||||
static int64_t
|
||||
file_skip(struct archive *a, void *client_data, int64_t request)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
|
||||
/* Delegate skip requests. */
|
||||
if (mine->use_lseek)
|
||||
return (file_skip_lseek(a, client_data, request));
|
||||
|
||||
/* If we can't skip, return 0; libarchive will read+discard instead. */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Store the offset and use it in the read callback.
|
||||
*/
|
||||
static int64_t
|
||||
file_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
int64_t r;
|
||||
|
||||
/* We use off_t here because lseek() is declared that way. */
|
||||
/* See above for notes about when off_t is less than 64 bits. */
|
||||
r = lseek(mine->fd, request, whence);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
||||
/* If the input is corrupted or truncated, fail. */
|
||||
if (mine->filename_type == FNT_STDIN)
|
||||
archive_set_error(a, errno, "Error seeking in stdin");
|
||||
else if (mine->filename_type == FNT_MBS)
|
||||
archive_set_error(a, errno, "Error seeking in '%s'",
|
||||
mine->filename.m);
|
||||
else
|
||||
archive_set_error(a, errno, "Error seeking in '%S'",
|
||||
mine->filename.w);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static int
|
||||
file_close2(struct archive *a, void *client_data)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
|
||||
/* Only flush and close if open succeeded. */
|
||||
if (mine->fd >= 0) {
|
||||
/*
|
||||
* Sometimes, we should flush the input before closing.
|
||||
* Regular files: faster to just close without flush.
|
||||
* Disk-like devices: Ditto.
|
||||
* Tapes: must not flush (user might need to
|
||||
* read the "next" item on a non-rewind device).
|
||||
* Pipes and sockets: must flush (otherwise, the
|
||||
* program feeding the pipe or socket may complain).
|
||||
* Here, I flush everything except for regular files and
|
||||
* device nodes.
|
||||
*/
|
||||
if (!S_ISREG(mine->st_mode)
|
||||
&& !S_ISCHR(mine->st_mode)
|
||||
&& !S_ISBLK(mine->st_mode)) {
|
||||
ssize_t bytesRead;
|
||||
do {
|
||||
bytesRead = read(mine->fd, mine->buffer,
|
||||
mine->block_size);
|
||||
} while (bytesRead > 0);
|
||||
}
|
||||
/* If a named file was opened, then it needs to be closed. */
|
||||
if (mine->filename_type != FNT_STDIN)
|
||||
close(mine->fd);
|
||||
}
|
||||
free(mine->buffer);
|
||||
mine->buffer = NULL;
|
||||
mine->fd = -1;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
file_close(struct archive *a, void *client_data)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
file_close2(a, client_data);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
file_switch(struct archive *a, void *client_data1, void *client_data2)
|
||||
{
|
||||
file_close2(a, client_data1);
|
||||
return file_open(a, client_data2);
|
||||
}
|
186
dependencies/libarchive-3.4.2/libarchive/archive_read_open_memory.c
vendored
Normal file
186
dependencies/libarchive-3.4.2/libarchive/archive_read_open_memory.c
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_memory.c,v 1.6 2007/07/06 15:51:59 kientzle Exp $");
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "archive.h"
|
||||
|
||||
/*
|
||||
* Glue to read an archive from a block of memory.
|
||||
*
|
||||
* This is mostly a huge help in building test harnesses;
|
||||
* test programs can build archives in memory and read them
|
||||
* back again without having to mess with files on disk.
|
||||
*/
|
||||
|
||||
struct read_memory_data {
|
||||
const unsigned char *start;
|
||||
const unsigned char *p;
|
||||
const unsigned char *end;
|
||||
ssize_t read_size;
|
||||
};
|
||||
|
||||
static int memory_read_close(struct archive *, void *);
|
||||
static int memory_read_open(struct archive *, void *);
|
||||
static int64_t memory_read_seek(struct archive *, void *, int64_t offset, int whence);
|
||||
static int64_t memory_read_skip(struct archive *, void *, int64_t request);
|
||||
static ssize_t memory_read(struct archive *, void *, const void **buff);
|
||||
|
||||
int
|
||||
archive_read_open_memory(struct archive *a, const void *buff, size_t size)
|
||||
{
|
||||
return archive_read_open_memory2(a, buff, size, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't use _open_memory2() in production code; the archive_read_open_memory()
|
||||
* version is the one you really want. This is just here so that
|
||||
* test harnesses can exercise block operations inside the library.
|
||||
*/
|
||||
int
|
||||
archive_read_open_memory2(struct archive *a, const void *buff,
|
||||
size_t size, size_t read_size)
|
||||
{
|
||||
struct read_memory_data *mine;
|
||||
|
||||
mine = (struct read_memory_data *)calloc(1, sizeof(*mine));
|
||||
if (mine == NULL) {
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
mine->start = mine->p = (const unsigned char *)buff;
|
||||
mine->end = mine->start + size;
|
||||
mine->read_size = read_size;
|
||||
archive_read_set_open_callback(a, memory_read_open);
|
||||
archive_read_set_read_callback(a, memory_read);
|
||||
archive_read_set_seek_callback(a, memory_read_seek);
|
||||
archive_read_set_skip_callback(a, memory_read_skip);
|
||||
archive_read_set_close_callback(a, memory_read_close);
|
||||
archive_read_set_callback_data(a, mine);
|
||||
return (archive_read_open1(a));
|
||||
}
|
||||
|
||||
/*
|
||||
* There's nothing to open.
|
||||
*/
|
||||
static int
|
||||
memory_read_open(struct archive *a, void *client_data)
|
||||
{
|
||||
(void)a; /* UNUSED */
|
||||
(void)client_data; /* UNUSED */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is scary simple: Just advance a pointer. Limiting
|
||||
* to read_size is not technically necessary, but it exercises
|
||||
* more of the internal logic when used with a small block size
|
||||
* in a test harness. Production use should not specify a block
|
||||
* size; then this is much faster.
|
||||
*/
|
||||
static ssize_t
|
||||
memory_read(struct archive *a, void *client_data, const void **buff)
|
||||
{
|
||||
struct read_memory_data *mine = (struct read_memory_data *)client_data;
|
||||
ssize_t size;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
*buff = mine->p;
|
||||
size = mine->end - mine->p;
|
||||
if (size > mine->read_size)
|
||||
size = mine->read_size;
|
||||
mine->p += size;
|
||||
return (size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Advancing is just as simple. Again, this is doing more than
|
||||
* necessary in order to better exercise internal code when used
|
||||
* as a test harness.
|
||||
*/
|
||||
static int64_t
|
||||
memory_read_skip(struct archive *a, void *client_data, int64_t skip)
|
||||
{
|
||||
struct read_memory_data *mine = (struct read_memory_data *)client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
if ((int64_t)skip > (int64_t)(mine->end - mine->p))
|
||||
skip = mine->end - mine->p;
|
||||
/* Round down to block size. */
|
||||
skip /= mine->read_size;
|
||||
skip *= mine->read_size;
|
||||
mine->p += skip;
|
||||
return (skip);
|
||||
}
|
||||
|
||||
/*
|
||||
* Seeking.
|
||||
*/
|
||||
static int64_t
|
||||
memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence)
|
||||
{
|
||||
struct read_memory_data *mine = (struct read_memory_data *)client_data;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
mine->p = mine->start + offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
mine->p += offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
mine->p = mine->end + offset;
|
||||
break;
|
||||
default:
|
||||
return ARCHIVE_FATAL;
|
||||
}
|
||||
if (mine->p < mine->start) {
|
||||
mine->p = mine->start;
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
if (mine->p > mine->end) {
|
||||
mine->p = mine->end;
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
return (mine->p - mine->start);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close is just cleaning up our one small bit of data.
|
||||
*/
|
||||
static int
|
||||
memory_read_close(struct archive *a, void *client_data)
|
||||
{
|
||||
struct read_memory_data *mine = (struct read_memory_data *)client_data;
|
||||
(void)a; /* UNUSED */
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
266
dependencies/libarchive-3.4.2/libarchive/archive_read_private.h
vendored
Normal file
266
dependencies/libarchive-3.4.2/libarchive/archive_read_private.h
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: head/lib/libarchive/archive_read_private.h 201088 2009-12-28 02:18:55Z kientzle $
|
||||
*/
|
||||
|
||||
#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_READ_PRIVATE_H_INCLUDED
|
||||
|
||||
#ifndef __LIBARCHIVE_BUILD
|
||||
#ifndef __LIBARCHIVE_TEST
|
||||
#error This header is only to be used internally to libarchive.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_string.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
struct archive_read;
|
||||
struct archive_read_filter_bidder;
|
||||
struct archive_read_filter;
|
||||
|
||||
/*
|
||||
* How bidding works for filters:
|
||||
* * The bid manager initializes the client-provided reader as the
|
||||
* first filter.
|
||||
* * It invokes the bidder for each registered filter with the
|
||||
* current head filter.
|
||||
* * The bidders can use archive_read_filter_ahead() to peek ahead
|
||||
* at the incoming data to compose their bids.
|
||||
* * The bid manager creates a new filter structure for the winning
|
||||
* bidder and gives the winning bidder a chance to initialize it.
|
||||
* * The new filter becomes the new top filter and we repeat the
|
||||
* process.
|
||||
* This ends only when no bidder provides a non-zero bid. Then
|
||||
* we perform a similar dance with the registered format handlers.
|
||||
*/
|
||||
struct archive_read_filter_bidder {
|
||||
/* Configuration data for the bidder. */
|
||||
void *data;
|
||||
/* Name of the filter */
|
||||
const char *name;
|
||||
/* Taste the upstream filter to see if we handle this. */
|
||||
int (*bid)(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
/* Initialize a newly-created filter. */
|
||||
int (*init)(struct archive_read_filter *);
|
||||
/* Set an option for the filter bidder. */
|
||||
int (*options)(struct archive_read_filter_bidder *,
|
||||
const char *key, const char *value);
|
||||
/* Release the bidder's configuration data. */
|
||||
int (*free)(struct archive_read_filter_bidder *);
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure is allocated within the archive_read core
|
||||
* and initialized by archive_read and the init() method of the
|
||||
* corresponding bidder above.
|
||||
*/
|
||||
struct archive_read_filter {
|
||||
int64_t position;
|
||||
/* Essentially all filters will need these values, so
|
||||
* just declare them here. */
|
||||
struct archive_read_filter_bidder *bidder; /* My bidder. */
|
||||
struct archive_read_filter *upstream; /* Who I read from. */
|
||||
struct archive_read *archive; /* Associated archive. */
|
||||
/* Open a block for reading */
|
||||
int (*open)(struct archive_read_filter *self);
|
||||
/* Return next block. */
|
||||
ssize_t (*read)(struct archive_read_filter *, const void **);
|
||||
/* Skip forward this many bytes. */
|
||||
int64_t (*skip)(struct archive_read_filter *self, int64_t request);
|
||||
/* Seek to an absolute location. */
|
||||
int64_t (*seek)(struct archive_read_filter *self, int64_t offset, int whence);
|
||||
/* Close (just this filter) and free(self). */
|
||||
int (*close)(struct archive_read_filter *self);
|
||||
/* Function that handles switching from reading one block to the next/prev */
|
||||
int (*sswitch)(struct archive_read_filter *self, unsigned int iindex);
|
||||
/* Read any header metadata if available. */
|
||||
int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry);
|
||||
/* My private data. */
|
||||
void *data;
|
||||
|
||||
const char *name;
|
||||
int code;
|
||||
|
||||
/* Used by reblocking logic. */
|
||||
char *buffer;
|
||||
size_t buffer_size;
|
||||
char *next; /* Current read location. */
|
||||
size_t avail; /* Bytes in my buffer. */
|
||||
const void *client_buff; /* Client buffer information. */
|
||||
size_t client_total;
|
||||
const char *client_next;
|
||||
size_t client_avail;
|
||||
char end_of_file;
|
||||
char closed;
|
||||
char fatal;
|
||||
};
|
||||
|
||||
/*
|
||||
* The client looks a lot like a filter, so we just wrap it here.
|
||||
*
|
||||
* TODO: Make archive_read_filter and archive_read_client identical so
|
||||
* that users of the library can easily register their own
|
||||
* transformation filters. This will probably break the API/ABI and
|
||||
* so should be deferred at least until libarchive 3.0.
|
||||
*/
|
||||
struct archive_read_data_node {
|
||||
int64_t begin_position;
|
||||
int64_t total_size;
|
||||
void *data;
|
||||
};
|
||||
struct archive_read_client {
|
||||
archive_open_callback *opener;
|
||||
archive_read_callback *reader;
|
||||
archive_skip_callback *skipper;
|
||||
archive_seek_callback *seeker;
|
||||
archive_close_callback *closer;
|
||||
archive_switch_callback *switcher;
|
||||
unsigned int nodes;
|
||||
unsigned int cursor;
|
||||
int64_t position;
|
||||
struct archive_read_data_node *dataset;
|
||||
};
|
||||
struct archive_read_passphrase {
|
||||
char *passphrase;
|
||||
struct archive_read_passphrase *next;
|
||||
};
|
||||
|
||||
struct archive_read_extract {
|
||||
struct archive *ad; /* archive_write_disk object */
|
||||
|
||||
/* Progress function invoked during extract. */
|
||||
void (*extract_progress)(void *);
|
||||
void *extract_progress_user_data;
|
||||
};
|
||||
|
||||
struct archive_read {
|
||||
struct archive archive;
|
||||
|
||||
struct archive_entry *entry;
|
||||
|
||||
/* Dev/ino of the archive being read/written. */
|
||||
int skip_file_set;
|
||||
int64_t skip_file_dev;
|
||||
int64_t skip_file_ino;
|
||||
|
||||
/* Callbacks to open/read/write/close client archive streams. */
|
||||
struct archive_read_client client;
|
||||
|
||||
/* Registered filter bidders. */
|
||||
struct archive_read_filter_bidder bidders[16];
|
||||
|
||||
/* Last filter in chain */
|
||||
struct archive_read_filter *filter;
|
||||
|
||||
/* Whether to bypass filter bidding process */
|
||||
int bypass_filter_bidding;
|
||||
|
||||
/* File offset of beginning of most recently-read header. */
|
||||
int64_t header_position;
|
||||
|
||||
/* Nodes and offsets of compressed data block */
|
||||
unsigned int data_start_node;
|
||||
unsigned int data_end_node;
|
||||
|
||||
/*
|
||||
* Format detection is mostly the same as compression
|
||||
* detection, with one significant difference: The bidders
|
||||
* use the read_ahead calls above to examine the stream rather
|
||||
* than having the supervisor hand them a block of data to
|
||||
* examine.
|
||||
*/
|
||||
|
||||
struct archive_format_descriptor {
|
||||
void *data;
|
||||
const char *name;
|
||||
int (*bid)(struct archive_read *, int best_bid);
|
||||
int (*options)(struct archive_read *, const char *key,
|
||||
const char *value);
|
||||
int (*read_header)(struct archive_read *, struct archive_entry *);
|
||||
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *);
|
||||
int (*read_data_skip)(struct archive_read *);
|
||||
int64_t (*seek_data)(struct archive_read *, int64_t, int);
|
||||
int (*cleanup)(struct archive_read *);
|
||||
int (*format_capabilties)(struct archive_read *);
|
||||
int (*has_encrypted_entries)(struct archive_read *);
|
||||
} formats[16];
|
||||
struct archive_format_descriptor *format; /* Active format. */
|
||||
|
||||
/*
|
||||
* Various information needed by archive_extract.
|
||||
*/
|
||||
struct archive_read_extract *extract;
|
||||
int (*cleanup_archive_extract)(struct archive_read *);
|
||||
|
||||
/*
|
||||
* Decryption passphrase.
|
||||
*/
|
||||
struct {
|
||||
struct archive_read_passphrase *first;
|
||||
struct archive_read_passphrase **last;
|
||||
int candidate;
|
||||
archive_passphrase_callback *callback;
|
||||
void *client_data;
|
||||
} passphrases;
|
||||
};
|
||||
|
||||
int __archive_read_register_format(struct archive_read *a,
|
||||
void *format_data,
|
||||
const char *name,
|
||||
int (*bid)(struct archive_read *, int),
|
||||
int (*options)(struct archive_read *, const char *, const char *),
|
||||
int (*read_header)(struct archive_read *, struct archive_entry *),
|
||||
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
|
||||
int (*read_data_skip)(struct archive_read *),
|
||||
int64_t (*seek_data)(struct archive_read *, int64_t, int),
|
||||
int (*cleanup)(struct archive_read *),
|
||||
int (*format_capabilities)(struct archive_read *),
|
||||
int (*has_encrypted_entries)(struct archive_read *));
|
||||
|
||||
int __archive_read_get_bidder(struct archive_read *a,
|
||||
struct archive_read_filter_bidder **bidder);
|
||||
|
||||
const void *__archive_read_ahead(struct archive_read *, size_t, ssize_t *);
|
||||
const void *__archive_read_filter_ahead(struct archive_read_filter *,
|
||||
size_t, ssize_t *);
|
||||
int64_t __archive_read_seek(struct archive_read*, int64_t, int);
|
||||
int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
|
||||
int64_t __archive_read_consume(struct archive_read *, int64_t);
|
||||
int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
|
||||
int __archive_read_header(struct archive_read *, struct archive_entry *);
|
||||
int __archive_read_program(struct archive_read_filter *, const char *);
|
||||
void __archive_read_free_filters(struct archive_read *);
|
||||
struct archive_read_extract *__archive_read_get_extract(struct archive_read *);
|
||||
|
||||
|
||||
/*
|
||||
* Get a decryption passphrase.
|
||||
*/
|
||||
void __archive_read_reset_passphrase(struct archive_read *a);
|
||||
const char * __archive_read_next_passphrase(struct archive_read *a);
|
||||
#endif
|
108
dependencies/libarchive-3.4.2/libarchive/archive_read_set_format.c
vendored
Normal file
108
dependencies/libarchive-3.4.2/libarchive/archive_read_set_format.c
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2012 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
int
|
||||
archive_read_set_format(struct archive *_a, int code)
|
||||
{
|
||||
int r1, r2, slots, i;
|
||||
char str[10];
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
|
||||
if ((r1 = archive_read_support_format_by_code(_a, code)) < (ARCHIVE_OK))
|
||||
return r1;
|
||||
|
||||
r1 = r2 = (ARCHIVE_OK);
|
||||
if (a->format)
|
||||
r2 = (ARCHIVE_WARN);
|
||||
switch (code & ARCHIVE_FORMAT_BASE_MASK)
|
||||
{
|
||||
case ARCHIVE_FORMAT_7ZIP:
|
||||
strcpy(str, "7zip");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_AR:
|
||||
strcpy(str, "ar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_CAB:
|
||||
strcpy(str, "cab");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_CPIO:
|
||||
strcpy(str, "cpio");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ISO9660:
|
||||
strcpy(str, "iso9660");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_LHA:
|
||||
strcpy(str, "lha");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_MTREE:
|
||||
strcpy(str, "mtree");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAR:
|
||||
strcpy(str, "rar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_RAR_V5:
|
||||
strcpy(str, "rar5");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_TAR:
|
||||
strcpy(str, "tar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_XAR:
|
||||
strcpy(str, "xar");
|
||||
break;
|
||||
case ARCHIVE_FORMAT_ZIP:
|
||||
strcpy(str, "zip");
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Invalid format code specified");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
slots = sizeof(a->formats) / sizeof(a->formats[0]);
|
||||
a->format = &(a->formats[0]);
|
||||
for (i = 0; i < slots; i++, a->format++) {
|
||||
if (!a->format->name || !strcmp(a->format->name, str))
|
||||
break;
|
||||
}
|
||||
if (!a->format->name || strcmp(a->format->name, str))
|
||||
{
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||
"Internal error: Unable to set format");
|
||||
r1 = (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
return (r1 < r2) ? r1 : r2;
|
||||
}
|
262
dependencies/libarchive-3.4.2/libarchive/archive_read_set_options.3
vendored
Normal file
262
dependencies/libarchive-3.4.2/libarchive/archive_read_set_options.3
vendored
Normal file
|
@ -0,0 +1,262 @@
|
|||
.\" Copyright (c) 2011 Tim Kientzle
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 31, 2020
|
||||
.Dt ARCHIVE_READ_OPTIONS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm archive_read_set_filter_option ,
|
||||
.Nm archive_read_set_format_option ,
|
||||
.Nm archive_read_set_option ,
|
||||
.Nm archive_read_set_options
|
||||
.Nd functions controlling options for reading archives
|
||||
.\"
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
.Sh SYNOPSIS
|
||||
.Ft int
|
||||
.Fo archive_read_set_filter_option
|
||||
.Fa "struct archive *"
|
||||
.Fa "const char *module"
|
||||
.Fa "const char *option"
|
||||
.Fa "const char *value"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_read_set_format_option
|
||||
.Fa "struct archive *"
|
||||
.Fa "const char *module"
|
||||
.Fa "const char *option"
|
||||
.Fa "const char *value"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_read_set_option
|
||||
.Fa "struct archive *"
|
||||
.Fa "const char *module"
|
||||
.Fa "const char *option"
|
||||
.Fa "const char *value"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_read_set_options
|
||||
.Fa "struct archive *"
|
||||
.Fa "const char *options"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
These functions provide a way for libarchive clients to configure
|
||||
specific read modules.
|
||||
.Bl -tag -width indent
|
||||
.It Xo
|
||||
.Fn archive_read_set_filter_option ,
|
||||
.Fn archive_read_set_format_option
|
||||
.Xc
|
||||
Specifies an option that will be passed to currently-registered
|
||||
filters (including decompression filters) or format readers.
|
||||
.Pp
|
||||
If
|
||||
.Ar option
|
||||
and
|
||||
.Ar value
|
||||
are both
|
||||
.Dv NULL ,
|
||||
these functions will do nothing and
|
||||
.Cm ARCHIVE_OK
|
||||
will be returned.
|
||||
If
|
||||
.Ar option
|
||||
is
|
||||
.Dv NULL
|
||||
but
|
||||
.Ar value
|
||||
is not, these functions will do nothing and
|
||||
.Cm ARCHIVE_FAILED
|
||||
will be returned.
|
||||
.Pp
|
||||
If
|
||||
.Ar module
|
||||
is not
|
||||
.Dv NULL ,
|
||||
.Ar option
|
||||
and
|
||||
.Ar value
|
||||
will be provided to the filter or reader named
|
||||
.Ar module .
|
||||
The return value will be that of the module.
|
||||
If there is no such module,
|
||||
.Cm ARCHIVE_FAILED
|
||||
will be returned.
|
||||
.Pp
|
||||
If
|
||||
.Ar module
|
||||
is
|
||||
.Dv NULL ,
|
||||
.Ar option
|
||||
and
|
||||
.Ar value
|
||||
will be provided to every registered module.
|
||||
If any module returns
|
||||
.Cm ARCHIVE_FATAL ,
|
||||
this value will be returned immediately.
|
||||
Otherwise,
|
||||
.Cm ARCHIVE_OK
|
||||
will be returned if any module accepts the option, and
|
||||
.Cm ARCHIVE_FAILED
|
||||
in all other cases.
|
||||
.\"
|
||||
.It Xo
|
||||
.Fn archive_read_set_option
|
||||
.Xc
|
||||
Calls
|
||||
.Fn archive_read_set_format_option ,
|
||||
then
|
||||
.Fn archive_read_set_filter_option .
|
||||
If either function returns
|
||||
.Cm ARCHIVE_FATAL ,
|
||||
.Cm ARCHIVE_FATAL
|
||||
will be returned
|
||||
immediately.
|
||||
Otherwise, greater of the two values will be returned.
|
||||
.\"
|
||||
.It Xo
|
||||
.Fn archive_read_set_options
|
||||
.Xc
|
||||
.Ar options
|
||||
is a comma-separated list of options.
|
||||
If
|
||||
.Ar options
|
||||
is
|
||||
.Dv NULL
|
||||
or empty,
|
||||
.Cm ARCHIVE_OK
|
||||
will be returned immediately.
|
||||
.Pp
|
||||
Calls
|
||||
.Fn archive_read_set_option
|
||||
with each option in turn.
|
||||
If any
|
||||
.Fn archive_read_set_option
|
||||
call returns
|
||||
.Cm ARCHIVE_FATAL ,
|
||||
.Cm ARCHIVE_FATAL
|
||||
will be returned immediately.
|
||||
.Pp
|
||||
Individual options have one of the following forms:
|
||||
.Bl -tag -compact -width indent
|
||||
.It Ar option=value
|
||||
The option/value pair will be provided to every module.
|
||||
Modules that do not accept an option with this name will ignore it.
|
||||
.It Ar option
|
||||
The option will be provided to every module with a value of
|
||||
.Dq 1 .
|
||||
.It Ar !option
|
||||
The option will be provided to every module with a NULL value.
|
||||
.It Ar module:option=value , Ar module:option , Ar module:!option
|
||||
As above, but the corresponding option and value will be provided
|
||||
only to modules whose name matches
|
||||
.Ar module .
|
||||
.El
|
||||
.El
|
||||
.\"
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -compact -width indent
|
||||
.It Format cab
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating file names.
|
||||
.El
|
||||
.It Format cpio
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating file names.
|
||||
.El
|
||||
.It Format iso9660
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm joliet
|
||||
Support Joliet extensions.
|
||||
Defaults to enabled, use
|
||||
.Cm !joliet
|
||||
to disable.
|
||||
.It Cm rockridge
|
||||
Support RockRidge extensions.
|
||||
Defaults to enabled, use
|
||||
.Cm !rockridge
|
||||
to disable.
|
||||
.El
|
||||
.It Format lha
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating file names.
|
||||
.El
|
||||
.It Format mtree
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm checkfs
|
||||
Allow reading information missing from the mtree from the file system.
|
||||
Disabled by default.
|
||||
.El
|
||||
.It Format rar
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating file names.
|
||||
.El
|
||||
.It Format tar
|
||||
.Bl -tag -compact -width indent
|
||||
.It Cm compat-2x
|
||||
Libarchive 2.x incorrectly encoded Unicode filenames on
|
||||
some platforms.
|
||||
This option mimics the libarchive 2.x filename handling
|
||||
so that such archives can be read correctly.
|
||||
.It Cm hdrcharset
|
||||
The value is used as a character set name that will be
|
||||
used when translating file names.
|
||||
.It Cm mac-ext
|
||||
Support Mac OS metadata extension that records data in special
|
||||
files beginning with a period and underscore.
|
||||
Defaults to enabled on Mac OS, disabled on other platforms.
|
||||
Use
|
||||
.Cm !mac-ext
|
||||
to disable.
|
||||
.It Cm read_concatenated_archives
|
||||
Ignore zeroed blocks in the archive, which occurs when multiple tar archives
|
||||
have been concatenated together.
|
||||
Without this option, only the contents of
|
||||
the first concatenated archive would be read.
|
||||
.El
|
||||
.El
|
||||
.\"
|
||||
.Sh ERRORS
|
||||
Detailed error codes and textual descriptions are available from the
|
||||
.Fn archive_errno
|
||||
and
|
||||
.Fn archive_error_string
|
||||
functions.
|
||||
.\"
|
||||
.Sh SEE ALSO
|
||||
.Xr tar 1 ,
|
||||
.Xr archive_read 3 ,
|
||||
.Xr archive_write_set_options 3 ,
|
||||
.Xr libarchive 3
|
155
dependencies/libarchive-3.4.2/libarchive/archive_read_set_options.c
vendored
Normal file
155
dependencies/libarchive-3.4.2/libarchive/archive_read_set_options.c
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*-
|
||||
* Copyright (c) 2011 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "archive_read_private.h"
|
||||
#include "archive_options_private.h"
|
||||
|
||||
static int archive_set_format_option(struct archive *a,
|
||||
const char *m, const char *o, const char *v);
|
||||
static int archive_set_filter_option(struct archive *a,
|
||||
const char *m, const char *o, const char *v);
|
||||
static int archive_set_option(struct archive *a,
|
||||
const char *m, const char *o, const char *v);
|
||||
|
||||
int
|
||||
archive_read_set_format_option(struct archive *a, const char *m, const char *o,
|
||||
const char *v)
|
||||
{
|
||||
return _archive_set_option(a, m, o, v,
|
||||
ARCHIVE_READ_MAGIC, "archive_read_set_format_option",
|
||||
archive_set_format_option);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_set_filter_option(struct archive *a, const char *m, const char *o,
|
||||
const char *v)
|
||||
{
|
||||
return _archive_set_option(a, m, o, v,
|
||||
ARCHIVE_READ_MAGIC, "archive_read_set_filter_option",
|
||||
archive_set_filter_option);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_set_option(struct archive *a, const char *m, const char *o,
|
||||
const char *v)
|
||||
{
|
||||
return _archive_set_option(a, m, o, v,
|
||||
ARCHIVE_READ_MAGIC, "archive_read_set_option",
|
||||
archive_set_option);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_set_options(struct archive *a, const char *options)
|
||||
{
|
||||
return _archive_set_options(a, options,
|
||||
ARCHIVE_READ_MAGIC, "archive_read_set_options",
|
||||
archive_set_option);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_set_format_option(struct archive *_a, const char *m, const char *o,
|
||||
const char *v)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
size_t i;
|
||||
int r, rv = ARCHIVE_WARN, matched_modules = 0;
|
||||
|
||||
for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
|
||||
struct archive_format_descriptor *format = &a->formats[i];
|
||||
|
||||
if (format->options == NULL || format->name == NULL)
|
||||
/* This format does not support option. */
|
||||
continue;
|
||||
if (m != NULL) {
|
||||
if (strcmp(format->name, m) != 0)
|
||||
continue;
|
||||
++matched_modules;
|
||||
}
|
||||
|
||||
a->format = format;
|
||||
r = format->options(a, o, v);
|
||||
a->format = NULL;
|
||||
|
||||
if (r == ARCHIVE_FATAL)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
if (r == ARCHIVE_OK)
|
||||
rv = ARCHIVE_OK;
|
||||
}
|
||||
/* If the format name didn't match, return a special code for
|
||||
* _archive_set_option[s]. */
|
||||
if (m != NULL && matched_modules == 0)
|
||||
return ARCHIVE_WARN - 1;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_set_filter_option(struct archive *_a, const char *m, const char *o,
|
||||
const char *v)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter *filter;
|
||||
struct archive_read_filter_bidder *bidder;
|
||||
int r, rv = ARCHIVE_WARN, matched_modules = 0;
|
||||
|
||||
for (filter = a->filter; filter != NULL; filter = filter->upstream) {
|
||||
bidder = filter->bidder;
|
||||
if (bidder == NULL)
|
||||
continue;
|
||||
if (bidder->options == NULL)
|
||||
/* This bidder does not support option */
|
||||
continue;
|
||||
if (m != NULL) {
|
||||
if (strcmp(filter->name, m) != 0)
|
||||
continue;
|
||||
++matched_modules;
|
||||
}
|
||||
|
||||
r = bidder->options(bidder, o, v);
|
||||
|
||||
if (r == ARCHIVE_FATAL)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
if (r == ARCHIVE_OK)
|
||||
rv = ARCHIVE_OK;
|
||||
}
|
||||
/* If the filter name didn't match, return a special code for
|
||||
* _archive_set_option[s]. */
|
||||
if (m != NULL && matched_modules == 0)
|
||||
return ARCHIVE_WARN - 1;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_set_option(struct archive *a, const char *m, const char *o,
|
||||
const char *v)
|
||||
{
|
||||
return _archive_set_either_option(a, m, o, v,
|
||||
archive_set_format_option,
|
||||
archive_set_filter_option);
|
||||
}
|
85
dependencies/libarchive-3.4.2/libarchive/archive_read_support_filter_all.c
vendored
Normal file
85
dependencies/libarchive-3.4.2/libarchive/archive_read_support_filter_all.c
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2011 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(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"
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
/* Deprecated; remove in libarchive 4.0 */
|
||||
int
|
||||
archive_read_support_compression_all(struct archive *a)
|
||||
{
|
||||
return archive_read_support_filter_all(a);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
archive_read_support_filter_all(struct archive *a)
|
||||
{
|
||||
archive_check_magic(a, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_filter_all");
|
||||
|
||||
/* Bzip falls back to "bunzip2" command-line */
|
||||
archive_read_support_filter_bzip2(a);
|
||||
/* The decompress code doesn't use an outside library. */
|
||||
archive_read_support_filter_compress(a);
|
||||
/* Gzip decompress falls back to "gzip -d" command-line. */
|
||||
archive_read_support_filter_gzip(a);
|
||||
/* Lzip falls back to "unlzip" command-line program. */
|
||||
archive_read_support_filter_lzip(a);
|
||||
/* The LZMA file format has a very weak signature, so it
|
||||
* may not be feasible to keep this here, but we'll try.
|
||||
* This will come back out if there are problems. */
|
||||
/* Lzma falls back to "unlzma" command-line program. */
|
||||
archive_read_support_filter_lzma(a);
|
||||
/* Xz falls back to "unxz" command-line program. */
|
||||
archive_read_support_filter_xz(a);
|
||||
/* The decode code doesn't use an outside library. */
|
||||
archive_read_support_filter_uu(a);
|
||||
/* The decode code doesn't use an outside library. */
|
||||
archive_read_support_filter_rpm(a);
|
||||
/* The decode code always uses "lrzip -q -d" command-line. */
|
||||
archive_read_support_filter_lrzip(a);
|
||||
/* Lzop decompress falls back to "lzop -d" command-line. */
|
||||
archive_read_support_filter_lzop(a);
|
||||
/* The decode code always uses "grzip -d" command-line. */
|
||||
archive_read_support_filter_grzip(a);
|
||||
/* Lz4 falls back to "lz4 -d" command-line program. */
|
||||
archive_read_support_filter_lz4(a);
|
||||
/* Zstd falls back to "zstd -d" command-line program. */
|
||||
archive_read_support_filter_zstd(a);
|
||||
|
||||
/* Note: We always return ARCHIVE_OK here, even if some of the
|
||||
* above return ARCHIVE_WARN. The intent here is to enable
|
||||
* "as much as possible." Clients who need specific
|
||||
* compression should enable those individually so they can
|
||||
* verify the level of support. */
|
||||
/* Clear any warning messages set by the above functions. */
|
||||
archive_clear_error(a);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
371
dependencies/libarchive-3.4.2/libarchive/archive_read_support_filter_bzip2.c
vendored
Normal file
371
dependencies/libarchive-3.4.2/libarchive/archive_read_support_filter_bzip2.c
vendored
Normal file
|
@ -0,0 +1,371 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_BZLIB_H
|
||||
#include <bzlib.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
|
||||
struct private_data {
|
||||
bz_stream stream;
|
||||
char *out_block;
|
||||
size_t out_block_size;
|
||||
char valid; /* True = decompressor is initialized */
|
||||
char eof; /* True = found end of compressed data. */
|
||||
};
|
||||
|
||||
/* Bzip2 filter */
|
||||
static ssize_t bzip2_filter_read(struct archive_read_filter *, const void **);
|
||||
static int bzip2_filter_close(struct archive_read_filter *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note that we can detect bzip2 archives even if we can't decompress
|
||||
* them. (In fact, we like detecting them because we can give better
|
||||
* error messages.) So the bid framework here gets compiled even
|
||||
* if bzlib is unavailable.
|
||||
*/
|
||||
static int bzip2_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
|
||||
static int bzip2_reader_init(struct archive_read_filter *);
|
||||
static int bzip2_reader_free(struct archive_read_filter_bidder *);
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
/* Deprecated; remove in libarchive 4.0 */
|
||||
int
|
||||
archive_read_support_compression_bzip2(struct archive *a)
|
||||
{
|
||||
return archive_read_support_filter_bzip2(a);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
archive_read_support_filter_bzip2(struct archive *_a)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter_bidder *reader;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_filter_bzip2");
|
||||
|
||||
if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
reader->data = NULL;
|
||||
reader->name = "bzip2";
|
||||
reader->bid = bzip2_reader_bid;
|
||||
reader->init = bzip2_reader_init;
|
||||
reader->options = NULL;
|
||||
reader->free = bzip2_reader_free;
|
||||
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external bzip2 program");
|
||||
return (ARCHIVE_WARN);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
bzip2_reader_free(struct archive_read_filter_bidder *self){
|
||||
(void)self; /* UNUSED */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether we can handle this data.
|
||||
*
|
||||
* This logic returns zero if any part of the signature fails. It
|
||||
* also tries to Do The Right Thing if a very short buffer prevents us
|
||||
* from verifying as much as we would like.
|
||||
*/
|
||||
static int
|
||||
bzip2_reader_bid(struct archive_read_filter_bidder *self, struct archive_read_filter *filter)
|
||||
{
|
||||
const unsigned char *buffer;
|
||||
ssize_t avail;
|
||||
int bits_checked;
|
||||
|
||||
(void)self; /* UNUSED */
|
||||
|
||||
/* Minimal bzip2 archive is 14 bytes. */
|
||||
buffer = __archive_read_filter_ahead(filter, 14, &avail);
|
||||
if (buffer == NULL)
|
||||
return (0);
|
||||
|
||||
/* First three bytes must be "BZh" */
|
||||
bits_checked = 0;
|
||||
if (memcmp(buffer, "BZh", 3) != 0)
|
||||
return (0);
|
||||
bits_checked += 24;
|
||||
|
||||
/* Next follows a compression flag which must be an ASCII digit. */
|
||||
if (buffer[3] < '1' || buffer[3] > '9')
|
||||
return (0);
|
||||
bits_checked += 5;
|
||||
|
||||
/* After BZh[1-9], there must be either a data block
|
||||
* which begins with 0x314159265359 or an end-of-data
|
||||
* marker of 0x177245385090. */
|
||||
if (memcmp(buffer + 4, "\x31\x41\x59\x26\x53\x59", 6) == 0)
|
||||
bits_checked += 48;
|
||||
else if (memcmp(buffer + 4, "\x17\x72\x45\x38\x50\x90", 6) == 0)
|
||||
bits_checked += 48;
|
||||
else
|
||||
return (0);
|
||||
|
||||
return (bits_checked);
|
||||
}
|
||||
|
||||
#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
|
||||
|
||||
/*
|
||||
* If we don't have the library on this system, we can't actually do the
|
||||
* decompression. We can, however, still detect compressed archives
|
||||
* and emit a useful message.
|
||||
*/
|
||||
static int
|
||||
bzip2_reader_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "bzip2 -d");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_FILTER_BZIP2;
|
||||
self->name = "bzip2";
|
||||
return (r);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Setup the callbacks.
|
||||
*/
|
||||
static int
|
||||
bzip2_reader_init(struct archive_read_filter *self)
|
||||
{
|
||||
static const size_t out_block_size = 64 * 1024;
|
||||
void *out_block;
|
||||
struct private_data *state;
|
||||
|
||||
self->code = ARCHIVE_FILTER_BZIP2;
|
||||
self->name = "bzip2";
|
||||
|
||||
state = (struct private_data *)calloc(sizeof(*state), 1);
|
||||
out_block = (unsigned char *)malloc(out_block_size);
|
||||
if (state == NULL || out_block == NULL) {
|
||||
archive_set_error(&self->archive->archive, ENOMEM,
|
||||
"Can't allocate data for bzip2 decompression");
|
||||
free(out_block);
|
||||
free(state);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
self->data = state;
|
||||
state->out_block_size = out_block_size;
|
||||
state->out_block = out_block;
|
||||
self->read = bzip2_filter_read;
|
||||
self->skip = NULL; /* not supported */
|
||||
self->close = bzip2_filter_close;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the next block of decompressed data.
|
||||
*/
|
||||
static ssize_t
|
||||
bzip2_filter_read(struct archive_read_filter *self, const void **p)
|
||||
{
|
||||
struct private_data *state;
|
||||
size_t decompressed;
|
||||
const char *read_buf;
|
||||
ssize_t ret;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
|
||||
if (state->eof) {
|
||||
*p = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Empty our output buffer. */
|
||||
state->stream.next_out = state->out_block;
|
||||
state->stream.avail_out = state->out_block_size;
|
||||
|
||||
/* Try to fill the output buffer. */
|
||||
for (;;) {
|
||||
if (!state->valid) {
|
||||
if (bzip2_reader_bid(self->bidder, self->upstream) == 0) {
|
||||
state->eof = 1;
|
||||
*p = state->out_block;
|
||||
decompressed = state->stream.next_out
|
||||
- state->out_block;
|
||||
return (decompressed);
|
||||
}
|
||||
/* Initialize compression library. */
|
||||
ret = BZ2_bzDecompressInit(&(state->stream),
|
||||
0 /* library verbosity */,
|
||||
0 /* don't use low-mem algorithm */);
|
||||
|
||||
/* If init fails, try low-memory algorithm instead. */
|
||||
if (ret == BZ_MEM_ERROR)
|
||||
ret = BZ2_bzDecompressInit(&(state->stream),
|
||||
0 /* library verbosity */,
|
||||
1 /* do use low-mem algo */);
|
||||
|
||||
if (ret != BZ_OK) {
|
||||
const char *detail = NULL;
|
||||
int err = ARCHIVE_ERRNO_MISC;
|
||||
switch (ret) {
|
||||
case BZ_PARAM_ERROR:
|
||||
detail = "invalid setup parameter";
|
||||
break;
|
||||
case BZ_MEM_ERROR:
|
||||
err = ENOMEM;
|
||||
detail = "out of memory";
|
||||
break;
|
||||
case BZ_CONFIG_ERROR:
|
||||
detail = "mis-compiled library";
|
||||
break;
|
||||
}
|
||||
archive_set_error(&self->archive->archive, err,
|
||||
"Internal error initializing decompressor%s%s",
|
||||
detail == NULL ? "" : ": ",
|
||||
detail);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
state->valid = 1;
|
||||
}
|
||||
|
||||
/* stream.next_in is really const, but bzlib
|
||||
* doesn't declare it so. <sigh> */
|
||||
read_buf =
|
||||
__archive_read_filter_ahead(self->upstream, 1, &ret);
|
||||
if (read_buf == NULL) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"truncated bzip2 input");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
state->stream.next_in = (char *)(uintptr_t)read_buf;
|
||||
state->stream.avail_in = ret;
|
||||
/* There is no more data, return whatever we have. */
|
||||
if (ret == 0) {
|
||||
state->eof = 1;
|
||||
*p = state->out_block;
|
||||
decompressed = state->stream.next_out
|
||||
- state->out_block;
|
||||
return (decompressed);
|
||||
}
|
||||
|
||||
/* Decompress as much as we can in one pass. */
|
||||
ret = BZ2_bzDecompress(&(state->stream));
|
||||
__archive_read_filter_consume(self->upstream,
|
||||
state->stream.next_in - read_buf);
|
||||
|
||||
switch (ret) {
|
||||
case BZ_STREAM_END: /* Found end of stream. */
|
||||
switch (BZ2_bzDecompressEnd(&(state->stream))) {
|
||||
case BZ_OK:
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&(self->archive->archive),
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Failed to clean up decompressor");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
state->valid = 0;
|
||||
/* FALLTHROUGH */
|
||||
case BZ_OK: /* Decompressor made some progress. */
|
||||
/* If we filled our buffer, update stats and return. */
|
||||
if (state->stream.avail_out == 0) {
|
||||
*p = state->out_block;
|
||||
decompressed = state->stream.next_out
|
||||
- state->out_block;
|
||||
return (decompressed);
|
||||
}
|
||||
break;
|
||||
default: /* Return an error. */
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC, "bzip decompression failed");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up the decompressor.
|
||||
*/
|
||||
static int
|
||||
bzip2_filter_close(struct archive_read_filter *self)
|
||||
{
|
||||
struct private_data *state;
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
|
||||
if (state->valid) {
|
||||
switch (BZ2_bzDecompressEnd(&state->stream)) {
|
||||
case BZ_OK:
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Failed to clean up decompressor");
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
state->valid = 0;
|
||||
}
|
||||
|
||||
free(state->out_block);
|
||||
free(state);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */
|
465
dependencies/libarchive-3.4.2/libarchive/archive_read_support_filter_compress.c
vendored
Normal file
465
dependencies/libarchive-3.4.2/libarchive/archive_read_support_filter_compress.c
vendored
Normal file
|
@ -0,0 +1,465 @@
|
|||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code borrows heavily from "compress" source code, which is
|
||||
* protected by the following copyright. (Clause 3 dropped by request
|
||||
* of the Regents.)
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1985, 1986, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Diomidis Spinellis and James A. Woods, derived from original
|
||||
* work by Spencer Thomas and Joseph Orost.
|
||||
*
|
||||
* 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.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
/*
|
||||
* Because LZW decompression is pretty simple, I've just implemented
|
||||
* the whole decompressor here (cribbing from "compress" source code,
|
||||
* of course), rather than relying on an external library. I have
|
||||
* made an effort to clarify and simplify the algorithm, so the
|
||||
* names and structure here don't exactly match those used by compress.
|
||||
*/
|
||||
|
||||
struct private_data {
|
||||
/* Input variables. */
|
||||
const unsigned char *next_in;
|
||||
size_t avail_in;
|
||||
size_t consume_unnotified;
|
||||
int bit_buffer;
|
||||
int bits_avail;
|
||||
size_t bytes_in_section;
|
||||
|
||||
/* Output variables. */
|
||||
size_t out_block_size;
|
||||
void *out_block;
|
||||
|
||||
/* Decompression status variables. */
|
||||
int use_reset_code;
|
||||
int end_of_stream; /* EOF status. */
|
||||
int maxcode; /* Largest code. */
|
||||
int maxcode_bits; /* Length of largest code. */
|
||||
int section_end_code; /* When to increase bits. */
|
||||
int bits; /* Current code length. */
|
||||
int oldcode; /* Previous code. */
|
||||
int finbyte; /* Last byte of prev code. */
|
||||
|
||||
/* Dictionary. */
|
||||
int free_ent; /* Next dictionary entry. */
|
||||
unsigned char suffix[65536];
|
||||
uint16_t prefix[65536];
|
||||
|
||||
/*
|
||||
* Scratch area for expanding dictionary entries. Note:
|
||||
* "worst" case here comes from compressing /dev/zero: the
|
||||
* last code in the dictionary will code a sequence of
|
||||
* 65536-256 zero bytes. Thus, we need stack space to expand
|
||||
* a 65280-byte dictionary entry. (Of course, 32640:1
|
||||
* compression could also be considered the "best" case. ;-)
|
||||
*/
|
||||
unsigned char *stackp;
|
||||
unsigned char stack[65300];
|
||||
};
|
||||
|
||||
static int compress_bidder_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
|
||||
static int compress_bidder_init(struct archive_read_filter *);
|
||||
static int compress_bidder_free(struct archive_read_filter_bidder *);
|
||||
|
||||
static ssize_t compress_filter_read(struct archive_read_filter *, const void **);
|
||||
static int compress_filter_close(struct archive_read_filter *);
|
||||
|
||||
static int getbits(struct archive_read_filter *, int n);
|
||||
static int next_code(struct archive_read_filter *);
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
/* Deprecated; remove in libarchive 4.0 */
|
||||
int
|
||||
archive_read_support_compression_compress(struct archive *a)
|
||||
{
|
||||
return archive_read_support_filter_compress(a);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
archive_read_support_filter_compress(struct archive *_a)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter_bidder *bidder;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_filter_compress");
|
||||
|
||||
if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "compress (.Z)";
|
||||
bidder->bid = compress_bidder_bid;
|
||||
bidder->init = compress_bidder_init;
|
||||
bidder->options = NULL;
|
||||
bidder->free = compress_bidder_free;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether we can handle this data.
|
||||
* This logic returns zero if any part of the signature fails.
|
||||
*/
|
||||
static int
|
||||
compress_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
struct archive_read_filter *filter)
|
||||
{
|
||||
const unsigned char *buffer;
|
||||
ssize_t avail;
|
||||
int bits_checked;
|
||||
|
||||
(void)self; /* UNUSED */
|
||||
|
||||
/* Shortest valid compress file is 3 bytes. */
|
||||
buffer = __archive_read_filter_ahead(filter, 3, &avail);
|
||||
|
||||
if (buffer == NULL)
|
||||
return (0);
|
||||
|
||||
bits_checked = 0;
|
||||
/* First two bytes are the magic value */
|
||||
if (buffer[0] != 0x1F || buffer[1] != 0x9D)
|
||||
return (0);
|
||||
/* Third byte holds compression parameters. */
|
||||
if (buffer[2] & 0x20) /* Reserved bit, must be zero. */
|
||||
return (0);
|
||||
if (buffer[2] & 0x40) /* Reserved bit, must be zero. */
|
||||
return (0);
|
||||
bits_checked += 18;
|
||||
|
||||
return (bits_checked);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the callbacks.
|
||||
*/
|
||||
static int
|
||||
compress_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
struct private_data *state;
|
||||
static const size_t out_block_size = 64 * 1024;
|
||||
void *out_block;
|
||||
int code;
|
||||
|
||||
self->code = ARCHIVE_FILTER_COMPRESS;
|
||||
self->name = "compress (.Z)";
|
||||
|
||||
state = (struct private_data *)calloc(sizeof(*state), 1);
|
||||
out_block = malloc(out_block_size);
|
||||
if (state == NULL || out_block == NULL) {
|
||||
free(out_block);
|
||||
free(state);
|
||||
archive_set_error(&self->archive->archive, ENOMEM,
|
||||
"Can't allocate data for %s decompression",
|
||||
self->name);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
self->data = state;
|
||||
state->out_block_size = out_block_size;
|
||||
state->out_block = out_block;
|
||||
self->read = compress_filter_read;
|
||||
self->skip = NULL; /* not supported */
|
||||
self->close = compress_filter_close;
|
||||
|
||||
/* XXX MOVE THE FOLLOWING OUT OF INIT() XXX */
|
||||
|
||||
(void)getbits(self, 8); /* Skip first signature byte. */
|
||||
(void)getbits(self, 8); /* Skip second signature byte. */
|
||||
|
||||
/* Get compression parameters. */
|
||||
code = getbits(self, 8);
|
||||
if ((code & 0x1f) > 16) {
|
||||
archive_set_error(&self->archive->archive, -1,
|
||||
"Invalid compressed data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
state->maxcode_bits = code & 0x1f;
|
||||
state->maxcode = (1 << state->maxcode_bits);
|
||||
state->use_reset_code = code & 0x80;
|
||||
|
||||
/* Initialize decompressor. */
|
||||
state->free_ent = 256;
|
||||
state->stackp = state->stack;
|
||||
if (state->use_reset_code)
|
||||
state->free_ent++;
|
||||
state->bits = 9;
|
||||
state->section_end_code = (1<<state->bits) - 1;
|
||||
state->oldcode = -1;
|
||||
for (code = 255; code >= 0; code--) {
|
||||
state->prefix[code] = 0;
|
||||
state->suffix[code] = code;
|
||||
}
|
||||
next_code(self);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a block of data from the decompression buffer. Decompress more
|
||||
* as necessary.
|
||||
*/
|
||||
static ssize_t
|
||||
compress_filter_read(struct archive_read_filter *self, const void **pblock)
|
||||
{
|
||||
struct private_data *state;
|
||||
unsigned char *p, *start, *end;
|
||||
int ret;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
if (state->end_of_stream) {
|
||||
*pblock = NULL;
|
||||
return (0);
|
||||
}
|
||||
p = start = (unsigned char *)state->out_block;
|
||||
end = start + state->out_block_size;
|
||||
|
||||
while (p < end && !state->end_of_stream) {
|
||||
if (state->stackp > state->stack) {
|
||||
*p++ = *--state->stackp;
|
||||
} else {
|
||||
ret = next_code(self);
|
||||
if (ret == -1)
|
||||
state->end_of_stream = ret;
|
||||
else if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
*pblock = start;
|
||||
return (p - start);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up the reader.
|
||||
*/
|
||||
static int
|
||||
compress_bidder_free(struct archive_read_filter_bidder *self)
|
||||
{
|
||||
self->data = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close and release the filter.
|
||||
*/
|
||||
static int
|
||||
compress_filter_close(struct archive_read_filter *self)
|
||||
{
|
||||
struct private_data *state = (struct private_data *)self->data;
|
||||
|
||||
free(state->out_block);
|
||||
free(state);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the next code and fill the stack with the expansion
|
||||
* of the code. Returns ARCHIVE_FATAL if there is a fatal I/O or
|
||||
* format error, ARCHIVE_EOF if we hit end of data, ARCHIVE_OK otherwise.
|
||||
*/
|
||||
static int
|
||||
next_code(struct archive_read_filter *self)
|
||||
{
|
||||
struct private_data *state = (struct private_data *)self->data;
|
||||
int code, newcode;
|
||||
|
||||
static int debug_buff[1024];
|
||||
static unsigned debug_index;
|
||||
|
||||
code = newcode = getbits(self, state->bits);
|
||||
if (code < 0)
|
||||
return (code);
|
||||
|
||||
debug_buff[debug_index++] = code;
|
||||
if (debug_index >= sizeof(debug_buff)/sizeof(debug_buff[0]))
|
||||
debug_index = 0;
|
||||
|
||||
/* If it's a reset code, reset the dictionary. */
|
||||
if ((code == 256) && state->use_reset_code) {
|
||||
/*
|
||||
* The original 'compress' implementation blocked its
|
||||
* I/O in a manner that resulted in junk bytes being
|
||||
* inserted after every reset. The next section skips
|
||||
* this junk. (Yes, the number of *bytes* to skip is
|
||||
* a function of the current *bit* length.)
|
||||
*/
|
||||
int skip_bytes = state->bits -
|
||||
(state->bytes_in_section % state->bits);
|
||||
skip_bytes %= state->bits;
|
||||
state->bits_avail = 0; /* Discard rest of this byte. */
|
||||
while (skip_bytes-- > 0) {
|
||||
code = getbits(self, 8);
|
||||
if (code < 0)
|
||||
return (code);
|
||||
}
|
||||
/* Now, actually do the reset. */
|
||||
state->bytes_in_section = 0;
|
||||
state->bits = 9;
|
||||
state->section_end_code = (1 << state->bits) - 1;
|
||||
state->free_ent = 257;
|
||||
state->oldcode = -1;
|
||||
return (next_code(self));
|
||||
}
|
||||
|
||||
if (code > state->free_ent
|
||||
|| (code == state->free_ent && state->oldcode < 0)) {
|
||||
/* An invalid code is a fatal error. */
|
||||
archive_set_error(&(self->archive->archive), -1,
|
||||
"Invalid compressed data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Special case for KwKwK string. */
|
||||
if (code >= state->free_ent) {
|
||||
*state->stackp++ = state->finbyte;
|
||||
code = state->oldcode;
|
||||
}
|
||||
|
||||
/* Generate output characters in reverse order. */
|
||||
while (code >= 256) {
|
||||
*state->stackp++ = state->suffix[code];
|
||||
code = state->prefix[code];
|
||||
}
|
||||
*state->stackp++ = state->finbyte = code;
|
||||
|
||||
/* Generate the new entry. */
|
||||
code = state->free_ent;
|
||||
if (code < state->maxcode && state->oldcode >= 0) {
|
||||
state->prefix[code] = state->oldcode;
|
||||
state->suffix[code] = state->finbyte;
|
||||
++state->free_ent;
|
||||
}
|
||||
if (state->free_ent > state->section_end_code) {
|
||||
state->bits++;
|
||||
state->bytes_in_section = 0;
|
||||
if (state->bits == state->maxcode_bits)
|
||||
state->section_end_code = state->maxcode;
|
||||
else
|
||||
state->section_end_code = (1 << state->bits) - 1;
|
||||
}
|
||||
|
||||
/* Remember previous code. */
|
||||
state->oldcode = newcode;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return next 'n' bits from stream.
|
||||
*
|
||||
* -1 indicates end of available data.
|
||||
*/
|
||||
static int
|
||||
getbits(struct archive_read_filter *self, int n)
|
||||
{
|
||||
struct private_data *state = (struct private_data *)self->data;
|
||||
int code;
|
||||
ssize_t ret;
|
||||
static const int mask[] = {
|
||||
0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff,
|
||||
0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff
|
||||
};
|
||||
|
||||
while (state->bits_avail < n) {
|
||||
if (state->avail_in <= 0) {
|
||||
if (state->consume_unnotified) {
|
||||
__archive_read_filter_consume(self->upstream,
|
||||
state->consume_unnotified);
|
||||
state->consume_unnotified = 0;
|
||||
}
|
||||
state->next_in
|
||||
= __archive_read_filter_ahead(self->upstream,
|
||||
1, &ret);
|
||||
if (ret == 0)
|
||||
return (-1);
|
||||
if (ret < 0 || state->next_in == NULL)
|
||||
return (ARCHIVE_FATAL);
|
||||
state->consume_unnotified = state->avail_in = ret;
|
||||
}
|
||||
state->bit_buffer |= *state->next_in++ << state->bits_avail;
|
||||
state->avail_in--;
|
||||
state->bits_avail += 8;
|
||||
state->bytes_in_section++;
|
||||
}
|
||||
|
||||
code = state->bit_buffer;
|
||||
state->bit_buffer >>= n;
|
||||
state->bits_avail -= n;
|
||||
|
||||
return (code & mask[n]);
|
||||
}
|
121
dependencies/libarchive-3.4.2/libarchive/archive_read_support_filter_grzip.c
vendored
Normal file
121
dependencies/libarchive-3.4.2/libarchive/archive_read_support_filter_grzip.c
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*-
|
||||
* Copyright (c) 2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
static const unsigned char grzip_magic[] = {
|
||||
0x47, 0x52, 0x5a, 0x69, 0x70, 0x49, 0x49, 0x00,
|
||||
0x02, 0x04, 0x3a, 0x29 };
|
||||
|
||||
static int grzip_bidder_bid(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
static int grzip_bidder_init(struct archive_read_filter *);
|
||||
|
||||
|
||||
static int
|
||||
grzip_reader_free(struct archive_read_filter_bidder *self)
|
||||
{
|
||||
(void)self; /* UNUSED */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_support_filter_grzip(struct archive *_a)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter_bidder *reader;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_filter_grzip");
|
||||
|
||||
if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
reader->data = NULL;
|
||||
reader->bid = grzip_bidder_bid;
|
||||
reader->init = grzip_bidder_init;
|
||||
reader->options = NULL;
|
||||
reader->free = grzip_reader_free;
|
||||
/* This filter always uses an external program. */
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external grzip program for grzip decompression");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bidder just verifies the header and returns the number of verified bits.
|
||||
*/
|
||||
static int
|
||||
grzip_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
struct archive_read_filter *filter)
|
||||
{
|
||||
const unsigned char *p;
|
||||
ssize_t avail;
|
||||
|
||||
(void)self; /* UNUSED */
|
||||
|
||||
p = __archive_read_filter_ahead(filter, sizeof(grzip_magic), &avail);
|
||||
if (p == NULL || avail == 0)
|
||||
return (0);
|
||||
|
||||
if (memcmp(p, grzip_magic, sizeof(grzip_magic)))
|
||||
return (0);
|
||||
|
||||
return (sizeof(grzip_magic) * 8);
|
||||
}
|
||||
|
||||
static int
|
||||
grzip_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "grzip -d");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_FILTER_GRZIP;
|
||||
self->name = "grzip";
|
||||
return (r);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue