MFV r299425:
Update libarchive to 3.2.0 New features: - new bsdcat command-line utility - LZ4 compression (in src only via external utility from ports) - Warc format support - 'Raw' format writer - Zip: Support archives >4GB, entries >4GB - Zip: Support encrypting and decrypting entries - Zip: Support experimental streaming extension - Identify encrypted entries in several formats - New --clear-nochange-flags option to bsdtar tries to remove noschg and similar flags before deleting files - New --ignore-zeros option to bsdtar to handle concatenated tar archives - Use multi-threaded LZMA decompression if liblzma supports it - Expose version info for libraries used by libarchive Patched files (fixed compiler warnings): contrib/libarchive/cat/bsdcat.c (vendor PR #702) contrib/libarchive/cat/bsdcat.h (vendor PR #702) contrib/libarchive/libarchive/archive_read_support_format_mtree.c (PR #701) contrib/libarchive/libarchive_fe/err.c (vendor PR #703) MFC after: 1 month Relnotes: yes
This commit is contained in:
commit
cdf63a700c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=299529
@ -17,12 +17,11 @@ the actual statements in the files are controlling.
|
|||||||
files for details:
|
files for details:
|
||||||
libarchive/archive_entry.c
|
libarchive/archive_entry.c
|
||||||
libarchive/archive_read_support_filter_compress.c
|
libarchive/archive_read_support_filter_compress.c
|
||||||
libarchive/archive_write_set_filter_compress.c
|
libarchive/archive_write_add_filter_compress.c
|
||||||
libarchive/mtree.5
|
libarchive/mtree.5
|
||||||
tar/matching.c
|
|
||||||
|
|
||||||
* The following source files are in the public domain:
|
* The following source files are in the public domain:
|
||||||
tar/getdate.c
|
libarchive/archive_getdate.c
|
||||||
|
|
||||||
* The build files---including Makefiles, configure scripts,
|
* The build files---including Makefiles, configure scripts,
|
||||||
and auxiliary scripts used as part of the compile process---have
|
and auxiliary scripts used as part of the compile process---have
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
.git
|
.git
|
||||||
.gitattributes
|
.gitattributes
|
||||||
.gitignore
|
.gitignore
|
||||||
|
.travis.yml
|
||||||
CMakeLists.txt
|
CMakeLists.txt
|
||||||
|
CONTRIBUTING.md
|
||||||
CTestConfig.cmake
|
CTestConfig.cmake
|
||||||
INSTALL
|
INSTALL
|
||||||
Makefile.am
|
Makefile.am
|
||||||
build
|
build
|
||||||
|
cat/CMakeLists.txt
|
||||||
|
cat/test/CMakeLists.txt
|
||||||
configure.ac
|
configure.ac
|
||||||
contrib
|
contrib
|
||||||
cpio/CMakeLists.txt
|
cpio/CMakeLists.txt
|
||||||
|
@ -4,13 +4,14 @@ libarchive
|
|||||||
|
|
||||||
The source code is pulled with git:
|
The source code is pulled with git:
|
||||||
|
|
||||||
git clone -b release git://github.com/libarchive/libarchive.git
|
git clone git://github.com/libarchive/libarchive.git
|
||||||
|
|
||||||
For the contrib directory files and directories were pruned by:
|
For the contrib directory files and directories were pruned by:
|
||||||
|
|
||||||
sh -c 'for F in `cat FREEBSD-Xlist | grep -v FreeBSD`; do rm -rf ./$F ; done'
|
sh -c 'for F in `cat FREEBSD-Xlist | grep -v FreeBSD`; do rm -rf ./$F ; done'
|
||||||
|
|
||||||
You may check if there are any new files that we don't need.
|
You may check if there are any new files that we don't need and add them to
|
||||||
|
FREEBSD-Xlist.
|
||||||
|
|
||||||
The instructions for importing new release and merging to HEAD can be found
|
The instructions for importing new release and merging to HEAD can be found
|
||||||
at FreeBSD wiki:
|
at FreeBSD wiki:
|
||||||
|
@ -1,3 +1,35 @@
|
|||||||
|
Apr 09, 2016: libarchive 3.1.901a released
|
||||||
|
Another test release in preparation for 3.2.0
|
||||||
|
|
||||||
|
Feb 13, 2016: libarchive 3.1.900a released
|
||||||
|
This is a test release in preparation for 3.2.0
|
||||||
|
|
||||||
|
Oct 21, 2015: Preliminary port to OSF
|
||||||
|
|
||||||
|
Apr 11, 2015: libarchive's issue tracker is now hosted at GitHub.
|
||||||
|
https://github.com/libarchive/libarchive/issues
|
||||||
|
|
||||||
|
Early 2015: Many fixes to crash and overflow bugs thanks to Hanno Boeck
|
||||||
|
|
||||||
|
Oct 13, 2014: Zip encryption and decryption support
|
||||||
|
|
||||||
|
Aug 13, 2014: Add support for lz4 compression.
|
||||||
|
|
||||||
|
Jun 10, 2014: Add warc format support
|
||||||
|
|
||||||
|
May 3, 2014: Add experimental Zip streaming extension
|
||||||
|
|
||||||
|
Apr 6, 2014: Add bsdcat command-line tool
|
||||||
|
|
||||||
|
Jan 12, 2014: Add Zip64 support
|
||||||
|
|
||||||
|
Dec 1, 2013: Rewrite Zip write logic
|
||||||
|
|
||||||
|
Jul 1, 2013: Add ability to detect encrypted entries for many formats
|
||||||
|
(This does not add the ability to *decrypt* those entries, however)
|
||||||
|
|
||||||
|
Feb 23, 2013: "raw" write support added
|
||||||
|
|
||||||
Feb 09, 2013: libarchive 3.1.2 released
|
Feb 09, 2013: libarchive 3.1.2 released
|
||||||
|
|
||||||
Jan 28, 2013: libarchive's new website moved to http://www.libarchive.org.
|
Jan 28, 2013: libarchive's new website moved to http://www.libarchive.org.
|
||||||
|
@ -5,7 +5,7 @@ Questions? Issues?
|
|||||||
libarchive development, including documentation, and
|
libarchive development, including documentation, and
|
||||||
links to the libarchive mailing lists.
|
links to the libarchive mailing lists.
|
||||||
* To report an issue, use the issue tracker at
|
* To report an issue, use the issue tracker at
|
||||||
http://code.google.com/p/libarchive/issues/list
|
https://github.com/libarchive/libarchive/issues
|
||||||
* To submit an enhancement to libarchive, please submit
|
* To submit an enhancement to libarchive, please submit
|
||||||
a pull request via GitHub.
|
a pull request via GitHub.
|
||||||
https://github.com/libarchive/libarchive/pulls
|
https://github.com/libarchive/libarchive/pulls
|
||||||
@ -13,9 +13,11 @@ Questions? Issues?
|
|||||||
This distribution bundle includes the following components:
|
This distribution bundle includes the following components:
|
||||||
* libarchive: a library for reading and writing streaming archives
|
* libarchive: a library for reading and writing streaming archives
|
||||||
* tar: the 'bsdtar' program is a full-featured 'tar'
|
* tar: the 'bsdtar' program is a full-featured 'tar'
|
||||||
replacement built on libarchive
|
implementation built on libarchive
|
||||||
* cpio: the 'bsdcpio' program is a different interface to
|
* cpio: the 'bsdcpio' program is a different interface to
|
||||||
essentially the same functionality
|
essentially the same functionality
|
||||||
|
* cat: the 'bsdcat' program is a simple replacement tool for
|
||||||
|
zcat, bzcat, xzcat, and such
|
||||||
* examples: Some small example programs that you may find useful.
|
* examples: Some small example programs that you may find useful.
|
||||||
* examples/minitar: a compact sample demonstrating use of libarchive.
|
* examples/minitar: a compact sample demonstrating use of libarchive.
|
||||||
* contrib: Various items sent to me by third parties;
|
* contrib: Various items sent to me by third parties;
|
||||||
@ -39,6 +41,7 @@ The following files in the top-level directory are used by the
|
|||||||
Guide to Documentation installed by this system:
|
Guide to Documentation installed by this system:
|
||||||
* bsdtar.1 explains the use of the bsdtar program
|
* bsdtar.1 explains the use of the bsdtar program
|
||||||
* bsdcpio.1 explains the use of the bsdcpio program
|
* bsdcpio.1 explains the use of the bsdcpio program
|
||||||
|
* bsdcat.1 explains the use of the bsdcat program
|
||||||
* libarchive.3 gives an overview of the library as a whole
|
* libarchive.3 gives an overview of the library as a whole
|
||||||
* archive_read.3, archive_write.3, archive_write_disk.3, and
|
* archive_read.3, archive_write.3, archive_write_disk.3, and
|
||||||
archive_read_disk.3 provide detailed calling sequences for the read
|
archive_read_disk.3 provide detailed calling sequences for the read
|
||||||
@ -84,6 +87,8 @@ The library also detects and handles any of the following before evaluating the
|
|||||||
* bzip2 compression
|
* bzip2 compression
|
||||||
* compress/LZW compression
|
* compress/LZW compression
|
||||||
* lzma, lzip, and xz compression
|
* lzma, lzip, and xz compression
|
||||||
|
* lz4 compression
|
||||||
|
* lzop compression
|
||||||
|
|
||||||
The library can create archives in any of the following formats:
|
The library can create archives in any of the following formats:
|
||||||
* POSIX ustar
|
* POSIX ustar
|
||||||
@ -91,6 +96,7 @@ The library can create archives in any of the following formats:
|
|||||||
* "restricted" pax format, which will create ustar archives except for
|
* "restricted" pax format, which will create ustar archives except for
|
||||||
entries that require pax extensions (for long filenames, ACLs, etc).
|
entries that require pax extensions (for long filenames, ACLs, etc).
|
||||||
* Old GNU tar format
|
* Old GNU tar format
|
||||||
|
* Old V7 tar format
|
||||||
* POSIX octet-oriented cpio
|
* POSIX octet-oriented cpio
|
||||||
* SVR4 "newc" cpio
|
* SVR4 "newc" cpio
|
||||||
* shar archives
|
* shar archives
|
||||||
@ -107,6 +113,8 @@ When creating archives, the result can be filtered with any of the following:
|
|||||||
* bzip2 compression
|
* bzip2 compression
|
||||||
* compress/LZW compression
|
* compress/LZW compression
|
||||||
* lzma, lzip, and xz compression
|
* lzma, lzip, and xz compression
|
||||||
|
* lz4 compression
|
||||||
|
* lzop compression
|
||||||
|
|
||||||
Notes about the library architecture:
|
Notes about the library architecture:
|
||||||
|
|
||||||
@ -123,12 +131,12 @@ Notes about the library architecture:
|
|||||||
|
|
||||||
* I've attempted to minimize static link pollution. If you don't
|
* I've attempted to minimize static link pollution. If you don't
|
||||||
explicitly invoke a particular feature (such as support for a
|
explicitly invoke a particular feature (such as support for a
|
||||||
particular compression or format), it won't get pulled in.
|
particular compression or format), it won't get pulled in to
|
||||||
In particular, if you don't explicitly enable a particular
|
statically-linked programs. In particular, if you don't explicitly
|
||||||
compression or decompression support, you won't need to link
|
enable a particular compression or decompression support, you won't
|
||||||
against the corresponding compression or decompression libraries.
|
need to link against the corresponding compression or decompression
|
||||||
This also reduces the size of statically-linked binaries in
|
libraries. This also reduces the size of statically-linked
|
||||||
environments where that matters.
|
binaries in environments where that matters.
|
||||||
|
|
||||||
* On read, the library accepts whatever blocks you hand it.
|
* On read, the library accepts whatever blocks you hand it.
|
||||||
Your read callback is free to pass the library a byte at a time
|
Your read callback is free to pass the library a byte at a time
|
||||||
|
62
contrib/libarchive/cat/bsdcat.1
Normal file
62
contrib/libarchive/cat/bsdcat.1
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
.\" Copyright (c) 2011-2014, Mike Kazantsev
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.\"
|
||||||
|
.Dd March 1, 2014
|
||||||
|
.Dt BSDCAT 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm bsdcat
|
||||||
|
.Nd expand files to standard output
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op options
|
||||||
|
.Op files
|
||||||
|
.Pp
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Nm
|
||||||
|
expands files to standard output.
|
||||||
|
.Sh OPTIONS
|
||||||
|
.Nm
|
||||||
|
typically takes a filename as an argument or reads standard input when used in a
|
||||||
|
pipe. In both cases decompressed data it written to standard output.
|
||||||
|
.Sh EXAMPLES
|
||||||
|
.Pp
|
||||||
|
To decompress a file:
|
||||||
|
.Pp
|
||||||
|
.Dl bsdcat example.txt.gz > example.txt
|
||||||
|
.Pp
|
||||||
|
To decompress standard input in a pipe:
|
||||||
|
.Pp
|
||||||
|
.Dl cat example.txt.gz | bsdcat > example.txt
|
||||||
|
.Pp
|
||||||
|
Both examples achieve the same results - a decompressed file by redirecting
|
||||||
|
output.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr uncompress 1 ,
|
||||||
|
.Xr zcat 1 ,
|
||||||
|
.Xr bzcat 1 ,
|
||||||
|
.Xr xzcat 1 ,
|
||||||
|
.Xr libarchive-formats 5 ,
|
146
contrib/libarchive/cat/bsdcat.c
Normal file
146
contrib/libarchive/cat/bsdcat.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2011-2014, Mike Kazantsev
|
||||||
|
* 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 "bsdcat_platform.h"
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifdef HAVE_STDLIB_H
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bsdcat.h"
|
||||||
|
#include "err.h"
|
||||||
|
|
||||||
|
#define BYTES_PER_BLOCK (20*512)
|
||||||
|
|
||||||
|
static struct archive *a;
|
||||||
|
static struct archive_entry *ae;
|
||||||
|
static const char *bsdcat_current_path;
|
||||||
|
static int exit_status = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
usage(FILE *stream, int eval)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
p = lafe_getprogname();
|
||||||
|
fprintf(stream,
|
||||||
|
"Usage: %s [-h] [--help] [--version] [--] [filenames...]\n", p);
|
||||||
|
exit(eval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
version(void)
|
||||||
|
{
|
||||||
|
printf("bsdcat %s - %s\n",
|
||||||
|
BSDCAT_VERSION_STRING,
|
||||||
|
archive_version_details());
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bsdcat_next(void)
|
||||||
|
{
|
||||||
|
a = archive_read_new();
|
||||||
|
archive_read_support_filter_all(a);
|
||||||
|
archive_read_support_format_empty(a);
|
||||||
|
archive_read_support_format_raw(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bsdcat_print_error(void)
|
||||||
|
{
|
||||||
|
lafe_warnc(0, "%s: %s",
|
||||||
|
bsdcat_current_path, archive_error_string(a));
|
||||||
|
exit_status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bsdcat_read_to_stdout(const char* filename)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (archive_read_open_filename(a, filename, BYTES_PER_BLOCK)
|
||||||
|
!= ARCHIVE_OK)
|
||||||
|
bsdcat_print_error();
|
||||||
|
else if (r = archive_read_next_header(a, &ae),
|
||||||
|
r != ARCHIVE_OK && r != ARCHIVE_EOF)
|
||||||
|
bsdcat_print_error();
|
||||||
|
else if (r == ARCHIVE_EOF)
|
||||||
|
/* for empty payloads don't try and read data */
|
||||||
|
;
|
||||||
|
else if (archive_read_data_into_fd(a, 1) != ARCHIVE_OK)
|
||||||
|
bsdcat_print_error();
|
||||||
|
if (archive_read_free(a) != ARCHIVE_OK)
|
||||||
|
bsdcat_print_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct bsdcat *bsdcat, bsdcat_storage;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
bsdcat = &bsdcat_storage;
|
||||||
|
memset(bsdcat, 0, sizeof(*bsdcat));
|
||||||
|
|
||||||
|
lafe_setprogname(*argv, "bsdcat");
|
||||||
|
|
||||||
|
bsdcat->argv = argv;
|
||||||
|
bsdcat->argc = argc;
|
||||||
|
|
||||||
|
while ((c = bsdcat_getopt(bsdcat)) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'h':
|
||||||
|
usage(stdout, 0);
|
||||||
|
break;
|
||||||
|
case OPTION_VERSION:
|
||||||
|
version();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(stderr, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bsdcat_next();
|
||||||
|
if (*bsdcat->argv == NULL) {
|
||||||
|
bsdcat_current_path = "<stdin>";
|
||||||
|
bsdcat_read_to_stdout(NULL);
|
||||||
|
} else
|
||||||
|
while (*bsdcat->argv) {
|
||||||
|
bsdcat_current_path = *bsdcat->argv++;
|
||||||
|
bsdcat_read_to_stdout(bsdcat_current_path);
|
||||||
|
bsdcat_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(exit_status);
|
||||||
|
}
|
56
contrib/libarchive/cat/bsdcat.h
Normal file
56
contrib/libarchive/cat/bsdcat.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014, Mike Kazantsev
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(PLATFORM_CONFIG_H)
|
||||||
|
/* Use hand-built config.h in environments that need it. */
|
||||||
|
#include PLATFORM_CONFIG_H
|
||||||
|
#else
|
||||||
|
/* Not having a config.h of some sort is a serious problem. */
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <archive.h>
|
||||||
|
#include <archive_entry.h>
|
||||||
|
|
||||||
|
struct bsdcat {
|
||||||
|
/* Option parser state */
|
||||||
|
int getopt_state;
|
||||||
|
char *getopt_word;
|
||||||
|
|
||||||
|
/* Miscellaneous state information */
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
const char *argument;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
OPTION_VERSION
|
||||||
|
};
|
||||||
|
|
||||||
|
int bsdcat_getopt(struct bsdcat *);
|
||||||
|
void usage(FILE *stream, int eval);
|
||||||
|
void bsdcat_next(void);
|
||||||
|
void bsdcat_print_error(void);
|
||||||
|
void bsdcat_read_to_stdout(const char* filename);
|
75
contrib/libarchive/cat/bsdcat_platform.h
Normal file
75
contrib/libarchive/cat/bsdcat_platform.h
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.
|
||||||
|
*
|
||||||
|
* $FreeBSD$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This header is the first thing included in any of the bsdtar
|
||||||
|
* source files. As far as possible, platform-specific issues should
|
||||||
|
* be dealt with here and not within individual source files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BSDCAT_PLATFORM_H_INCLUDED
|
||||||
|
#define BSDCAT_PLATFORM_H_INCLUDED
|
||||||
|
|
||||||
|
#if defined(PLATFORM_CONFIG_H)
|
||||||
|
/* Use hand-built config.h in environments that need it. */
|
||||||
|
#include PLATFORM_CONFIG_H
|
||||||
|
#else
|
||||||
|
/* Not having a config.h of some sort is a serious problem. */
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get a real definition for __FBSDID if we can */
|
||||||
|
#if HAVE_SYS_CDEFS_H
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If not, define it so as to avoid dangling semicolons. */
|
||||||
|
#ifndef __FBSDID
|
||||||
|
#define __FBSDID(a) struct _undefined_hack
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBARCHIVE
|
||||||
|
/* If we're using the platform libarchive, include system headers. */
|
||||||
|
#include <archive.h>
|
||||||
|
#include <archive_entry.h>
|
||||||
|
#else
|
||||||
|
/* Otherwise, include user headers. */
|
||||||
|
#include "archive.h"
|
||||||
|
#include "archive_entry.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* How to mark functions that don't return. */
|
||||||
|
/* This facilitates use of some newer static code analysis tools. */
|
||||||
|
#undef __LA_DEAD
|
||||||
|
#if defined(__GNUC__) && (__GNUC__ > 2 || \
|
||||||
|
(__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
|
||||||
|
#define __LA_DEAD __attribute__((__noreturn__))
|
||||||
|
#else
|
||||||
|
#define __LA_DEAD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !BSDCAT_PLATFORM_H_INCLUDED */
|
283
contrib/libarchive/cat/cmdline.c
Normal file
283
contrib/libarchive/cat/cmdline.c
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2003-2008 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command line parser for tar.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bsdcat_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
|
||||||
|
|
||||||
|
#include "bsdcat.h"
|
||||||
|
#include "err.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Short options for tar. Please keep this sorted.
|
||||||
|
*/
|
||||||
|
static const char *short_options = "h";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Long options for tar. Please keep this list sorted.
|
||||||
|
*
|
||||||
|
* The symbolic names for options that lack a short equivalent are
|
||||||
|
* defined in bsdcat.h. Also note that so far I've found no need
|
||||||
|
* to support optional arguments to long options. That would be
|
||||||
|
* a small change to the code below.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const struct bsdcat_option {
|
||||||
|
const char *name;
|
||||||
|
int required; /* 1 if this option requires an argument. */
|
||||||
|
int equivalent; /* Equivalent short option. */
|
||||||
|
} tar_longopts[] = {
|
||||||
|
{ "help", 0, 'h' },
|
||||||
|
{ "version", 0, OPTION_VERSION },
|
||||||
|
{ NULL, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This getopt implementation has two key features that common
|
||||||
|
* getopt_long() implementations lack. Apart from those, it's a
|
||||||
|
* straightforward option parser, considerably simplified by not
|
||||||
|
* needing to support the wealth of exotic getopt_long() features. It
|
||||||
|
* has, of course, been shamelessly tailored for bsdcat. (If you're
|
||||||
|
* looking for a generic getopt_long() implementation for your
|
||||||
|
* project, I recommend Gregory Pietsch's public domain getopt_long()
|
||||||
|
* implementation.) The two additional features are:
|
||||||
|
*
|
||||||
|
* Old-style tar arguments: The original tar implementation treated
|
||||||
|
* the first argument word as a list of single-character option
|
||||||
|
* letters. All arguments follow as separate words. For example,
|
||||||
|
* tar xbf 32 /dev/tape
|
||||||
|
* Here, the "xbf" is three option letters, "32" is the argument for
|
||||||
|
* "b" and "/dev/tape" is the argument for "f". We support this usage
|
||||||
|
* if the first command-line argument does not begin with '-'. We
|
||||||
|
* also allow regular short and long options to follow, e.g.,
|
||||||
|
* tar xbf 32 /dev/tape -P --format=pax
|
||||||
|
*
|
||||||
|
* -W long options: There's an obscure GNU convention (only rarely
|
||||||
|
* supported even there) that allows "-W option=argument" as an
|
||||||
|
* alternative way to support long options. This was supported in
|
||||||
|
* early bsdcat as a way to access long options on platforms that did
|
||||||
|
* not support getopt_long() and is preserved here for backwards
|
||||||
|
* compatibility. (Of course, if I'd started with a custom
|
||||||
|
* command-line parser from the beginning, I would have had normal
|
||||||
|
* long option support on every platform so that hack wouldn't have
|
||||||
|
* been necessary. Oh, well. Some mistakes you just have to live
|
||||||
|
* with.)
|
||||||
|
*
|
||||||
|
* TODO: We should be able to use this to pull files and intermingled
|
||||||
|
* options (such as -C) from the command line in write mode. That
|
||||||
|
* will require a little rethinking of the argument handling in
|
||||||
|
* bsdcat.c.
|
||||||
|
*
|
||||||
|
* TODO: If we want to support arbitrary command-line options from -T
|
||||||
|
* input (as GNU tar does), we may need to extend this to handle option
|
||||||
|
* words from sources other than argv/argc. I'm not really sure if I
|
||||||
|
* like that feature of GNU tar, so it's certainly not a priority.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
bsdcat_getopt(struct bsdcat *bsdcat)
|
||||||
|
{
|
||||||
|
enum { state_start = 0, state_old_tar, state_next_word,
|
||||||
|
state_short, state_long };
|
||||||
|
|
||||||
|
const struct bsdcat_option *popt, *match = NULL, *match2 = NULL;
|
||||||
|
const char *p, *long_prefix = "--";
|
||||||
|
size_t optlength;
|
||||||
|
int opt = '?';
|
||||||
|
int required = 0;
|
||||||
|
|
||||||
|
bsdcat->argument = NULL;
|
||||||
|
|
||||||
|
/* First time through, initialize everything. */
|
||||||
|
if (bsdcat->getopt_state == state_start) {
|
||||||
|
/* Skip program name. */
|
||||||
|
++bsdcat->argv;
|
||||||
|
--bsdcat->argc;
|
||||||
|
if (*bsdcat->argv == NULL)
|
||||||
|
return (-1);
|
||||||
|
/* Decide between "new style" and "old style" arguments. */
|
||||||
|
bsdcat->getopt_state = state_next_word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're ready to look at the next word in argv.
|
||||||
|
*/
|
||||||
|
if (bsdcat->getopt_state == state_next_word) {
|
||||||
|
/* No more arguments, so no more options. */
|
||||||
|
if (bsdcat->argv[0] == NULL)
|
||||||
|
return (-1);
|
||||||
|
/* Doesn't start with '-', so no more options. */
|
||||||
|
if (bsdcat->argv[0][0] != '-')
|
||||||
|
return (-1);
|
||||||
|
/* "--" marks end of options; consume it and return. */
|
||||||
|
if (strcmp(bsdcat->argv[0], "--") == 0) {
|
||||||
|
++bsdcat->argv;
|
||||||
|
--bsdcat->argc;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
/* Get next word for parsing. */
|
||||||
|
bsdcat->getopt_word = *bsdcat->argv++;
|
||||||
|
--bsdcat->argc;
|
||||||
|
if (bsdcat->getopt_word[1] == '-') {
|
||||||
|
/* Set up long option parser. */
|
||||||
|
bsdcat->getopt_state = state_long;
|
||||||
|
bsdcat->getopt_word += 2; /* Skip leading '--' */
|
||||||
|
} else {
|
||||||
|
/* Set up short option parser. */
|
||||||
|
bsdcat->getopt_state = state_short;
|
||||||
|
++bsdcat->getopt_word; /* Skip leading '-' */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're parsing a group of POSIX-style single-character options.
|
||||||
|
*/
|
||||||
|
if (bsdcat->getopt_state == state_short) {
|
||||||
|
/* Peel next option off of a group of short options. */
|
||||||
|
opt = *bsdcat->getopt_word++;
|
||||||
|
if (opt == '\0') {
|
||||||
|
/* End of this group; recurse to get next option. */
|
||||||
|
bsdcat->getopt_state = state_next_word;
|
||||||
|
return bsdcat_getopt(bsdcat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Does this option take an argument? */
|
||||||
|
p = strchr(short_options, opt);
|
||||||
|
if (p == NULL)
|
||||||
|
return ('?');
|
||||||
|
if (p[1] == ':')
|
||||||
|
required = 1;
|
||||||
|
|
||||||
|
/* If it takes an argument, parse that. */
|
||||||
|
if (required) {
|
||||||
|
/* If arg is run-in, bsdcat->getopt_word already points to it. */
|
||||||
|
if (bsdcat->getopt_word[0] == '\0') {
|
||||||
|
/* Otherwise, pick up the next word. */
|
||||||
|
bsdcat->getopt_word = *bsdcat->argv;
|
||||||
|
if (bsdcat->getopt_word == NULL) {
|
||||||
|
lafe_warnc(0,
|
||||||
|
"Option -%c requires an argument",
|
||||||
|
opt);
|
||||||
|
return ('?');
|
||||||
|
}
|
||||||
|
++bsdcat->argv;
|
||||||
|
--bsdcat->argc;
|
||||||
|
}
|
||||||
|
if (opt == 'W') {
|
||||||
|
bsdcat->getopt_state = state_long;
|
||||||
|
long_prefix = "-W "; /* For clearer errors. */
|
||||||
|
} else {
|
||||||
|
bsdcat->getopt_state = state_next_word;
|
||||||
|
bsdcat->argument = bsdcat->getopt_word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're reading a long option, including -W long=arg convention. */
|
||||||
|
if (bsdcat->getopt_state == state_long) {
|
||||||
|
/* After this long option, we'll be starting a new word. */
|
||||||
|
bsdcat->getopt_state = state_next_word;
|
||||||
|
|
||||||
|
/* Option name ends at '=' if there is one. */
|
||||||
|
p = strchr(bsdcat->getopt_word, '=');
|
||||||
|
if (p != NULL) {
|
||||||
|
optlength = (size_t)(p - bsdcat->getopt_word);
|
||||||
|
bsdcat->argument = (char *)(uintptr_t)(p + 1);
|
||||||
|
} else {
|
||||||
|
optlength = strlen(bsdcat->getopt_word);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search the table for an unambiguous match. */
|
||||||
|
for (popt = tar_longopts; popt->name != NULL; popt++) {
|
||||||
|
/* Short-circuit if first chars don't match. */
|
||||||
|
if (popt->name[0] != bsdcat->getopt_word[0])
|
||||||
|
continue;
|
||||||
|
/* If option is a prefix of name in table, record it.*/
|
||||||
|
if (strncmp(bsdcat->getopt_word, popt->name, optlength) == 0) {
|
||||||
|
match2 = match; /* Record up to two matches. */
|
||||||
|
match = popt;
|
||||||
|
/* If it's an exact match, we're done. */
|
||||||
|
if (strlen(popt->name) == optlength) {
|
||||||
|
match2 = NULL; /* Forget the others. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fail if there wasn't a unique match. */
|
||||||
|
if (match == NULL) {
|
||||||
|
lafe_warnc(0,
|
||||||
|
"Option %s%s is not supported",
|
||||||
|
long_prefix, bsdcat->getopt_word);
|
||||||
|
return ('?');
|
||||||
|
}
|
||||||
|
if (match2 != NULL) {
|
||||||
|
lafe_warnc(0,
|
||||||
|
"Ambiguous option %s%s (matches --%s and --%s)",
|
||||||
|
long_prefix, bsdcat->getopt_word, match->name, match2->name);
|
||||||
|
return ('?');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We've found a unique match; does it need an argument? */
|
||||||
|
if (match->required) {
|
||||||
|
/* Argument required: get next word if necessary. */
|
||||||
|
if (bsdcat->argument == NULL) {
|
||||||
|
bsdcat->argument = *bsdcat->argv;
|
||||||
|
if (bsdcat->argument == NULL) {
|
||||||
|
lafe_warnc(0,
|
||||||
|
"Option %s%s requires an argument",
|
||||||
|
long_prefix, match->name);
|
||||||
|
return ('?');
|
||||||
|
}
|
||||||
|
++bsdcat->argv;
|
||||||
|
--bsdcat->argc;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Argument forbidden: fail if there is one. */
|
||||||
|
if (bsdcat->argument != NULL) {
|
||||||
|
lafe_warnc(0,
|
||||||
|
"Option %s%s does not allow an argument",
|
||||||
|
long_prefix, match->name);
|
||||||
|
return ('?');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (match->equivalent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (opt);
|
||||||
|
}
|
2969
contrib/libarchive/cat/test/main.c
Normal file
2969
contrib/libarchive/cat/test/main.c
Normal file
File diff suppressed because it is too large
Load Diff
344
contrib/libarchive/cat/test/test.h
Normal file
344
contrib/libarchive/cat/test/test.h
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2006 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$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Every test program should #include "test.h" as the first thing. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The goal of this file (and the matching test.c) is to
|
||||||
|
* simplify the very repetitive test-*.c test programs.
|
||||||
|
*/
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
/* Most POSIX platforms use the 'configure' script to build config.h */
|
||||||
|
#include "config.h"
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
/* Building as part of FreeBSD system requires a pre-built config.h. */
|
||||||
|
#include "config_freebsd.h"
|
||||||
|
#elif defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
/* Win32 can't run the 'configure' script. */
|
||||||
|
#include "config_windows.h"
|
||||||
|
#else
|
||||||
|
/* Warn if the library hasn't been (automatically or manually) configured. */
|
||||||
|
#error Oops: No config.h and no pre-built configuration in test.h.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h> /* Windows requires this before sys/stat.h */
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#if HAVE_DIRENT_H
|
||||||
|
#include <dirent.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DIRECT_H
|
||||||
|
#include <direct.h>
|
||||||
|
#define dirent direct
|
||||||
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#ifdef HAVE_IO_H
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <wchar.h>
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System-specific tweaks. We really want to minimize these
|
||||||
|
* as much as possible, since they make it harder to understand
|
||||||
|
* the mainline code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Windows (including Visual Studio and MinGW but not Cygwin) */
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
#if !defined(__BORLANDC__)
|
||||||
|
#undef chdir
|
||||||
|
#define chdir _chdir
|
||||||
|
#define strdup _strdup
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Visual Studio */
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
|
#define snprintf sprintf_s
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__BORLANDC__)
|
||||||
|
#pragma warn -8068 /* Constant out of range in comparison. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Haiku OS and QNX */
|
||||||
|
#if defined(__HAIKU__) || defined(__QNXNTO__)
|
||||||
|
/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get a real definition for __FBSDID if we can */
|
||||||
|
#if HAVE_SYS_CDEFS_H
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If not, define it so as to avoid dangling semicolons. */
|
||||||
|
#ifndef __FBSDID
|
||||||
|
#define __FBSDID(a) struct _undefined_hack
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redefine DEFINE_TEST for use in defining the test functions.
|
||||||
|
*/
|
||||||
|
#undef DEFINE_TEST
|
||||||
|
#define DEFINE_TEST(name) void name(void); void name(void)
|
||||||
|
|
||||||
|
/* An implementation of the standard assert() macro */
|
||||||
|
#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL)
|
||||||
|
/* chdir() and error if it fails */
|
||||||
|
#define assertChdir(path) \
|
||||||
|
assertion_chdir(__FILE__, __LINE__, path)
|
||||||
|
/* Assert two integers are the same. Reports value of each one if not. */
|
||||||
|
#define assertEqualInt(v1,v2) \
|
||||||
|
assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
|
||||||
|
/* Assert two strings are the same. Reports value of each one if not. */
|
||||||
|
#define assertEqualString(v1,v2) \
|
||||||
|
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0)
|
||||||
|
#define assertEqualUTF8String(v1,v2) \
|
||||||
|
assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1)
|
||||||
|
/* As above, but v1 and v2 are wchar_t * */
|
||||||
|
#define assertEqualWString(v1,v2) \
|
||||||
|
assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL)
|
||||||
|
/* As above, but raw blocks of bytes. */
|
||||||
|
#define assertEqualMem(v1, v2, l) \
|
||||||
|
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
|
||||||
|
/* Assert that memory is full of a specified byte */
|
||||||
|
#define assertMemoryFilledWith(v1, l, b) \
|
||||||
|
assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
|
||||||
|
/* Assert two files are the same. */
|
||||||
|
#define assertEqualFile(f1, f2) \
|
||||||
|
assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
|
||||||
|
/* Assert that a file is empty. */
|
||||||
|
#define assertEmptyFile(pathname) \
|
||||||
|
assertion_empty_file(__FILE__, __LINE__, (pathname))
|
||||||
|
/* Assert that a file is not empty. */
|
||||||
|
#define assertNonEmptyFile(pathname) \
|
||||||
|
assertion_non_empty_file(__FILE__, __LINE__, (pathname))
|
||||||
|
#define assertFileAtime(pathname, sec, nsec) \
|
||||||
|
assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec)
|
||||||
|
#define assertFileAtimeRecent(pathname) \
|
||||||
|
assertion_file_atime_recent(__FILE__, __LINE__, pathname)
|
||||||
|
#define assertFileBirthtime(pathname, sec, nsec) \
|
||||||
|
assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec)
|
||||||
|
#define assertFileBirthtimeRecent(pathname) \
|
||||||
|
assertion_file_birthtime_recent(__FILE__, __LINE__, pathname)
|
||||||
|
/* Assert that a file exists; supports printf-style arguments. */
|
||||||
|
#define assertFileExists(pathname) \
|
||||||
|
assertion_file_exists(__FILE__, __LINE__, pathname)
|
||||||
|
/* Assert that a file exists. */
|
||||||
|
#define assertFileNotExists(pathname) \
|
||||||
|
assertion_file_not_exists(__FILE__, __LINE__, pathname)
|
||||||
|
/* Assert that file contents match a string. */
|
||||||
|
#define assertFileContents(data, data_size, pathname) \
|
||||||
|
assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
|
||||||
|
#define assertFileMtime(pathname, sec, nsec) \
|
||||||
|
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
|
||||||
|
#define assertFileMtimeRecent(pathname) \
|
||||||
|
assertion_file_mtime_recent(__FILE__, __LINE__, pathname)
|
||||||
|
#define assertFileNLinks(pathname, nlinks) \
|
||||||
|
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
|
||||||
|
#define assertFileSize(pathname, size) \
|
||||||
|
assertion_file_size(__FILE__, __LINE__, pathname, size)
|
||||||
|
#define assertTextFileContents(text, pathname) \
|
||||||
|
assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
|
||||||
|
#define assertFileContainsLinesAnyOrder(pathname, lines) \
|
||||||
|
assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines)
|
||||||
|
#define assertIsDir(pathname, mode) \
|
||||||
|
assertion_is_dir(__FILE__, __LINE__, pathname, mode)
|
||||||
|
#define assertIsHardlink(path1, path2) \
|
||||||
|
assertion_is_hardlink(__FILE__, __LINE__, path1, path2)
|
||||||
|
#define assertIsNotHardlink(path1, path2) \
|
||||||
|
assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2)
|
||||||
|
#define assertIsReg(pathname, mode) \
|
||||||
|
assertion_is_reg(__FILE__, __LINE__, pathname, mode)
|
||||||
|
#define assertIsSymlink(pathname, contents) \
|
||||||
|
assertion_is_symlink(__FILE__, __LINE__, pathname, contents)
|
||||||
|
/* Create a directory, report error if it fails. */
|
||||||
|
#define assertMakeDir(dirname, mode) \
|
||||||
|
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
|
||||||
|
#define assertMakeFile(path, mode, contents) \
|
||||||
|
assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
|
||||||
|
#define assertMakeBinFile(path, mode, csize, contents) \
|
||||||
|
assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
|
||||||
|
#define assertMakeHardlink(newfile, oldfile) \
|
||||||
|
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
|
||||||
|
#define assertMakeSymlink(newfile, linkto) \
|
||||||
|
assertion_make_symlink(__FILE__, __LINE__, newfile, linkto)
|
||||||
|
#define assertNodump(path) \
|
||||||
|
assertion_nodump(__FILE__, __LINE__, path)
|
||||||
|
#define assertUmask(mask) \
|
||||||
|
assertion_umask(__FILE__, __LINE__, mask)
|
||||||
|
#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \
|
||||||
|
assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This would be simple with C99 variadic macros, but I don't want to
|
||||||
|
* require that. Instead, I insert a function call before each
|
||||||
|
* skipping() call to pass the file and line information down. Crude,
|
||||||
|
* but effective.
|
||||||
|
*/
|
||||||
|
#define skipping \
|
||||||
|
skipping_setup(__FILE__, __LINE__);test_skipping
|
||||||
|
|
||||||
|
/* Function declarations. These are defined in test_utility.c. */
|
||||||
|
void failure(const char *fmt, ...);
|
||||||
|
int assertion_assert(const char *, int, int, const char *, void *);
|
||||||
|
int assertion_chdir(const char *, int, const char *);
|
||||||
|
int assertion_empty_file(const char *, int, const char *);
|
||||||
|
int assertion_equal_file(const char *, int, const char *, const char *);
|
||||||
|
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
|
||||||
|
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
|
||||||
|
int assertion_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
|
||||||
|
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
|
||||||
|
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
|
||||||
|
int assertion_file_atime(const char *, int, const char *, long, long);
|
||||||
|
int assertion_file_atime_recent(const char *, int, const char *);
|
||||||
|
int assertion_file_birthtime(const char *, int, const char *, long, long);
|
||||||
|
int assertion_file_birthtime_recent(const char *, int, const char *);
|
||||||
|
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
|
||||||
|
int assertion_file_contents(const char *, int, const void *, int, const char *);
|
||||||
|
int assertion_file_exists(const char *, int, const char *);
|
||||||
|
int assertion_file_mtime(const char *, int, const char *, long, long);
|
||||||
|
int assertion_file_mtime_recent(const char *, int, const char *);
|
||||||
|
int assertion_file_nlinks(const char *, int, const char *, int);
|
||||||
|
int assertion_file_not_exists(const char *, int, const char *);
|
||||||
|
int assertion_file_size(const char *, int, const char *, long);
|
||||||
|
int assertion_is_dir(const char *, int, const char *, int);
|
||||||
|
int assertion_is_hardlink(const char *, int, const char *, const char *);
|
||||||
|
int assertion_is_not_hardlink(const char *, int, const char *, const char *);
|
||||||
|
int assertion_is_reg(const char *, int, const char *, int);
|
||||||
|
int assertion_is_symlink(const char *, int, const char *, const char *);
|
||||||
|
int assertion_make_dir(const char *, int, const char *, int);
|
||||||
|
int assertion_make_file(const char *, int, const char *, int, int, const void *);
|
||||||
|
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
|
||||||
|
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
|
||||||
|
int assertion_nodump(const char *, int, const char *);
|
||||||
|
int assertion_non_empty_file(const char *, int, const char *);
|
||||||
|
int assertion_text_file_contents(const char *, int, const char *buff, const char *f);
|
||||||
|
int assertion_umask(const char *, int, int);
|
||||||
|
int assertion_utimes(const char *, int, const char *, long, long, long, long );
|
||||||
|
|
||||||
|
void skipping_setup(const char *, int);
|
||||||
|
void test_skipping(const char *fmt, ...);
|
||||||
|
|
||||||
|
/* Like sprintf, then system() */
|
||||||
|
int systemf(const char * fmt, ...);
|
||||||
|
|
||||||
|
/* Delay until time() returns a value after this. */
|
||||||
|
void sleepUntilAfter(time_t);
|
||||||
|
|
||||||
|
/* Return true if this platform can create symlinks. */
|
||||||
|
int canSymlink(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the "bzip2" program. */
|
||||||
|
int canBzip2(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the "grzip" program. */
|
||||||
|
int canGrzip(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the "gzip" program. */
|
||||||
|
int canGzip(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the specified command. */
|
||||||
|
int canRunCommand(const char *);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the "lrzip" program. */
|
||||||
|
int canLrzip(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the "lz4" program. */
|
||||||
|
int canLz4(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the "lzip" program. */
|
||||||
|
int canLzip(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the "lzma" program. */
|
||||||
|
int canLzma(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the "lzop" program. */
|
||||||
|
int canLzop(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the "xz" program. */
|
||||||
|
int canXz(void);
|
||||||
|
|
||||||
|
/* Return true if this filesystem can handle nodump flags. */
|
||||||
|
int canNodump(void);
|
||||||
|
|
||||||
|
/* Return true if the file has large i-node number(>0xffffffff). */
|
||||||
|
int is_LargeInode(const char *);
|
||||||
|
|
||||||
|
/* Suck file into string allocated via malloc(). Call free() when done. */
|
||||||
|
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
|
||||||
|
char *slurpfile(size_t *, const char *fmt, ...);
|
||||||
|
|
||||||
|
/* Dump block of bytes to a file. */
|
||||||
|
void dumpfile(const char *filename, void *, size_t);
|
||||||
|
|
||||||
|
/* Extracts named reference file to the current directory. */
|
||||||
|
void extract_reference_file(const char *);
|
||||||
|
/* Copies named reference file to the current directory. */
|
||||||
|
void copy_reference_file(const char *);
|
||||||
|
|
||||||
|
/* Extracts a list of files to the current directory.
|
||||||
|
* List must be NULL terminated.
|
||||||
|
*/
|
||||||
|
void extract_reference_files(const char **);
|
||||||
|
|
||||||
|
/* Path to working directory for current test */
|
||||||
|
extern const char *testworkdir;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special interfaces for program test harness.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Pathname of exe to be tested. */
|
||||||
|
extern const char *testprogfile;
|
||||||
|
/* Name of exe to use in printf-formatted command strings. */
|
||||||
|
/* On Windows, this includes leading/trailing quotes. */
|
||||||
|
extern const char *testprog;
|
||||||
|
|
||||||
|
#ifdef USE_DMALLOC
|
||||||
|
#include <dmalloc.h>
|
||||||
|
#endif
|
67
contrib/libarchive/cat/test/test_0.c
Normal file
67
contrib/libarchive/cat/test/test_0.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*-
|
||||||
|
* 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 "test.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This first test does basic sanity checks on the environment. For
|
||||||
|
* most of these, we just exit on failure.
|
||||||
|
*/
|
||||||
|
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
#define DEV_NULL "/dev/null"
|
||||||
|
#else
|
||||||
|
#define DEV_NULL "NUL"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEFINE_TEST(test_0)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
failure("File %s does not exist?!", testprog);
|
||||||
|
if (!assertEqualInt(0, stat(testprogfile, &st))) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\nFile %s does not exist; aborting test.\n\n",
|
||||||
|
testprog);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
failure("%s is not executable?!", testprog);
|
||||||
|
if (!assert((st.st_mode & 0111) != 0)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\nFile %s not executable; aborting test.\n\n",
|
||||||
|
testprog);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to successfully run the program; this requires that
|
||||||
|
* we know some option that will succeed.
|
||||||
|
*/
|
||||||
|
if (0 != systemf("%s --version >" DEV_NULL, testprog)) {
|
||||||
|
failure("Unable to successfully run: %s --version\n", testprog, testprog);
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Ensure that our reference files are available. */
|
||||||
|
}
|
4
contrib/libarchive/cat/test/test_empty.gz.uu
Normal file
4
contrib/libarchive/cat/test/test_empty.gz.uu
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
begin 644 test_empty.gz
|
||||||
|
?'XL(""\MZE,``W1E<W1?96UP='D``P``````````````
|
||||||
|
`
|
||||||
|
end
|
4
contrib/libarchive/cat/test/test_empty.lz4.uu
Normal file
4
contrib/libarchive/cat/test/test_empty.lz4.uu
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
begin 644 test_empty.lz4
|
||||||
|
/!")-&&1PN0`````%7<P"
|
||||||
|
`
|
||||||
|
end
|
4
contrib/libarchive/cat/test/test_empty.xz.uu
Normal file
4
contrib/libarchive/cat/test/test_empty.xz.uu
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
begin 644 test_empty.xz
|
||||||
|
@_3=Z6%H```3FUK1&`````!S?1"$?MO-]`0`````$65H`
|
||||||
|
`
|
||||||
|
end
|
41
contrib/libarchive/cat/test/test_empty_gz.c
Normal file
41
contrib/libarchive/cat/test/test_empty_gz.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Sebastian Freundt
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_empty_gz)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_empty.gz";
|
||||||
|
int f;
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
|
||||||
|
if (f == 0 || canGzip()) {
|
||||||
|
assertEqualInt(0, f);
|
||||||
|
assertEmptyFile("test.out");
|
||||||
|
assertEmptyFile("test.err");
|
||||||
|
} else {
|
||||||
|
skipping("It seems gzip is not supported on this platform");
|
||||||
|
}
|
||||||
|
}
|
41
contrib/libarchive/cat/test/test_empty_lz4.c
Normal file
41
contrib/libarchive/cat/test/test_empty_lz4.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Sebastian Freundt
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_empty_lz4)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_empty.lz4";
|
||||||
|
int f;
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
|
||||||
|
if (f == 0 || canLz4()) {
|
||||||
|
assertEqualInt(0, f);
|
||||||
|
assertEmptyFile("test.out");
|
||||||
|
assertEmptyFile("test.err");
|
||||||
|
} else {
|
||||||
|
skipping("It seems lz4 is not supported on this platform");
|
||||||
|
}
|
||||||
|
}
|
41
contrib/libarchive/cat/test/test_empty_xz.c
Normal file
41
contrib/libarchive/cat/test/test_empty_xz.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Sebastian Freundt
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_empty_xz)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_empty.xz";
|
||||||
|
int f;
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
|
||||||
|
if (f == 0 || canXz()) {
|
||||||
|
assertEqualInt(0, f);
|
||||||
|
assertEmptyFile("test.out");
|
||||||
|
assertEmptyFile("test.err");
|
||||||
|
} else {
|
||||||
|
skipping("It seems xz is not supported on this platform");
|
||||||
|
}
|
||||||
|
}
|
36
contrib/libarchive/cat/test/test_error.c
Normal file
36
contrib/libarchive/cat/test/test_error.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Mike Kazantsev
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_error)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_expand.error";
|
||||||
|
|
||||||
|
assertFileNotExists(reffile);
|
||||||
|
assert(0 != systemf("%s %s >test.out 2>test.err", testprog, reffile));
|
||||||
|
|
||||||
|
assertEmptyFile("test.out");
|
||||||
|
assertNonEmptyFile("test.err");
|
||||||
|
}
|
43
contrib/libarchive/cat/test/test_error_mixed.c
Normal file
43
contrib/libarchive/cat/test/test_error_mixed.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Mike Kazantsev
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_error_mixed)
|
||||||
|
{
|
||||||
|
const char *reffile1 = "test_expand.plain";
|
||||||
|
const char *reffile2 = "test_expand.error";
|
||||||
|
const char *reffile3 = "test_expand.Z";
|
||||||
|
|
||||||
|
assertFileNotExists(reffile2);
|
||||||
|
extract_reference_file(reffile1);
|
||||||
|
extract_reference_file(reffile3);
|
||||||
|
assert(0 != systemf("%s %s %s %s >test.out 2>test.err",
|
||||||
|
testprog, reffile1, reffile2, reffile3));
|
||||||
|
|
||||||
|
assertTextFileContents(
|
||||||
|
"contents of test_expand.plain.\n"
|
||||||
|
"contents of test_expand.Z.\n", "test.out");
|
||||||
|
assertNonEmptyFile("test.err");
|
||||||
|
}
|
3
contrib/libarchive/cat/test/test_expand.Z.uu
Normal file
3
contrib/libarchive/cat/test/test_expand.Z.uu
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
begin 664 test_expand.Z
|
||||||
|
@'YV08]ZXH5-FX!P0;\R`(#B'SI<R>."$<4/&A187"@`
|
||||||
|
end
|
5
contrib/libarchive/cat/test/test_expand.bz2.uu
Normal file
5
contrib/libarchive/cat/test/test_expand.bz2.uu
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
begin 664 test_expand.bz2
|
||||||
|
M0EIH.3%!62936=[T@^L [__N000(!!(#!@\P+(, !@4 1 @$" (0 80$
|
||||||
|
M(!D0 " 5%)D::#( #0]0 9J%1Z@>H :!B:&33(!"X";"%C@I$+32H/(0MXG
|
||||||
|
J,EA1G51 WG-"6JV7JKA;/&]$X 6MNH 8'N@3[\XCA_%W)%.%"0WO2#ZP
|
||||||
|
end
|
4
contrib/libarchive/cat/test/test_expand.gz.uu
Normal file
4
contrib/libarchive/cat/test/test_expand.gz.uu
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
begin 664 test_expand.gz
|
||||||
|
M'XL("-UD1%,``V%S9`!+SL\K2<TK*5;(3U,H22TNB4^M*$C,2]%+K]+C`@`Z
|
||||||
|
'PQU''```````
|
||||||
|
end
|
5
contrib/libarchive/cat/test/test_expand.lz4.uu
Normal file
5
contrib/libarchive/cat/test/test_expand.lz4.uu
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
begin 644 test_expand.lz4
|
||||||
|
M!")-&&1PN1T``(!C;VYT96YT<R!O9B!T97-T7V5X<&%N9"YL>C0N"@`````Y
|
||||||
|
#!E9+
|
||||||
|
`
|
||||||
|
end
|
3
contrib/libarchive/cat/test/test_expand.plain.uu
Normal file
3
contrib/libarchive/cat/test/test_expand.plain.uu
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
begin 664 test_expand.plain
|
||||||
|
?8V]N=&5N=',@;V8@=&5S=%]E>'!A;F0N<&QA:6XN"@
|
||||||
|
end
|
4
contrib/libarchive/cat/test/test_expand.xz.uu
Normal file
4
contrib/libarchive/cat/test/test_expand.xz.uu
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
begin 664 test_expand.xz
|
||||||
|
M_3=Z6%H 3FUK1& @ A 18 !T+^6C 0 ;8V]N=&5N=',@;V8@=&5S=%]E
|
||||||
|
G>'!A;F0N>'HN"@!S;^LVAO^3[ !-!R3&JV/'[;S?0$ !%E:
|
||||||
|
end
|
36
contrib/libarchive/cat/test/test_expand_Z.c
Normal file
36
contrib/libarchive/cat/test/test_expand_Z.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Mike Kazantsev
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_expand_Z)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_expand.Z";
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
assertEqualInt(0, systemf("%s %s >test.out 2>test.err", testprog, reffile));
|
||||||
|
|
||||||
|
assertTextFileContents("contents of test_expand.Z.\n", "test.out");
|
||||||
|
assertEmptyFile("test.err");
|
||||||
|
}
|
42
contrib/libarchive/cat/test/test_expand_bz2.c
Normal file
42
contrib/libarchive/cat/test/test_expand_bz2.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Mike Kazantsev
|
||||||
|
* 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 "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_expand_bz2)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_expand.bz2";
|
||||||
|
int f;
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
|
||||||
|
if (f == 0 || canBzip2()) {
|
||||||
|
assertEqualInt(0, f);
|
||||||
|
assertTextFileContents("contents of test_expand.bz2.\n", "test.out");
|
||||||
|
assertEmptyFile("test.err");
|
||||||
|
} else {
|
||||||
|
skipping("It seems bzip2 is not supported on this platform");
|
||||||
|
}
|
||||||
|
}
|
42
contrib/libarchive/cat/test/test_expand_gz.c
Normal file
42
contrib/libarchive/cat/test/test_expand_gz.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Mike Kazantsev
|
||||||
|
* 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 "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_expand_gz)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_expand.gz";
|
||||||
|
int f;
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
|
||||||
|
if (f == 0 || canGzip()) {
|
||||||
|
assertEqualInt(0, f);
|
||||||
|
assertTextFileContents("contents of test_expand.gz.\n", "test.out");
|
||||||
|
assertEmptyFile("test.err");
|
||||||
|
} else {
|
||||||
|
skipping("It seems gzip is not supported on this platform");
|
||||||
|
}
|
||||||
|
}
|
42
contrib/libarchive/cat/test/test_expand_lz4.c
Normal file
42
contrib/libarchive/cat/test/test_expand_lz4.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Mike Kazantsev
|
||||||
|
* Copyright (c) 2012, 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 "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_expand_lz4)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_expand.lz4";
|
||||||
|
int f;
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
|
||||||
|
if (f == 0 || canLz4()) {
|
||||||
|
assertEqualInt(0, f);
|
||||||
|
assertTextFileContents("contents of test_expand.lz4.\n", "test.out");
|
||||||
|
assertEmptyFile("test.err");
|
||||||
|
} else {
|
||||||
|
skipping("It seems lz4 is not supported on this platform");
|
||||||
|
}
|
||||||
|
}
|
41
contrib/libarchive/cat/test/test_expand_mixed.c
Normal file
41
contrib/libarchive/cat/test/test_expand_mixed.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Mike Kazantsev
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_expand_mixed)
|
||||||
|
{
|
||||||
|
const char *reffile1 = "test_expand.Z";
|
||||||
|
const char *reffile2 = "test_expand.plain";
|
||||||
|
|
||||||
|
extract_reference_file(reffile1);
|
||||||
|
extract_reference_file(reffile2);
|
||||||
|
assertEqualInt(0, systemf("%s %s %s >test.out 2>test.err",
|
||||||
|
testprog, reffile1, reffile2));
|
||||||
|
|
||||||
|
assertTextFileContents(
|
||||||
|
"contents of test_expand.Z.\n"
|
||||||
|
"contents of test_expand.plain.\n", "test.out");
|
||||||
|
assertEmptyFile("test.err");
|
||||||
|
}
|
36
contrib/libarchive/cat/test/test_expand_plain.c
Normal file
36
contrib/libarchive/cat/test/test_expand_plain.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Mike Kazantsev
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_expand_plain)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_expand.plain";
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
assertEqualInt(0, systemf("%s %s >test.out 2>test.err", testprog, reffile));
|
||||||
|
|
||||||
|
assertTextFileContents("contents of test_expand.plain.\n", "test.out");
|
||||||
|
assertEmptyFile("test.err");
|
||||||
|
}
|
42
contrib/libarchive/cat/test/test_expand_xz.c
Normal file
42
contrib/libarchive/cat/test/test_expand_xz.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Mike Kazantsev
|
||||||
|
* 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 "test.h"
|
||||||
|
|
||||||
|
DEFINE_TEST(test_expand_xz)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_expand.xz";
|
||||||
|
int f;
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
|
||||||
|
if (f == 0 || canXz()) {
|
||||||
|
assertEqualInt(0, f);
|
||||||
|
assertTextFileContents("contents of test_expand.xz.\n", "test.out");
|
||||||
|
assertEmptyFile("test.err");
|
||||||
|
} else {
|
||||||
|
skipping("It seems xz is not supported on this platform");
|
||||||
|
}
|
||||||
|
}
|
75
contrib/libarchive/cat/test/test_help.c
Normal file
75
contrib/libarchive/cat/test/test_help.c
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 "test.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that "--help", "-h", and "-W help" options all work and
|
||||||
|
* generate reasonable output.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
in_first_line(const char *p, const char *substring)
|
||||||
|
{
|
||||||
|
size_t l = strlen(substring);
|
||||||
|
|
||||||
|
while (*p != '\0' && *p != '\n') {
|
||||||
|
if (memcmp(p, substring, l) == 0)
|
||||||
|
return (1);
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_TEST(test_help)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
char *p;
|
||||||
|
size_t plen;
|
||||||
|
|
||||||
|
/* Exercise --help option. */
|
||||||
|
r = systemf("%s --help >help.stdout 2>help.stderr", testprog);
|
||||||
|
assertEqualInt(r, 0);
|
||||||
|
failure("--help should generate nothing to stderr.");
|
||||||
|
assertEmptyFile("help.stderr");
|
||||||
|
/* Help message should start with name of program. */
|
||||||
|
p = slurpfile(&plen, "help.stdout");
|
||||||
|
failure("Help output should be long enough.");
|
||||||
|
assert(plen >= 6);
|
||||||
|
failure("First line of help output should contain 'bsdcat': %s", p);
|
||||||
|
assert(in_first_line(p, "bsdcat"));
|
||||||
|
/*
|
||||||
|
* TODO: Extend this check to further verify that --help output
|
||||||
|
* looks approximately right.
|
||||||
|
*/
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
/* -h option should generate the same output. */
|
||||||
|
r = systemf("%s -h >h.stdout 2>h.stderr", testprog);
|
||||||
|
assertEqualInt(r, 0);
|
||||||
|
failure("-h should generate nothing to stderr.");
|
||||||
|
assertEmptyFile("h.stderr");
|
||||||
|
failure("stdout should be same for -h and --help");
|
||||||
|
assertEqualFile("h.stdout", "help.stdout");
|
||||||
|
}
|
97
contrib/libarchive/cat/test/test_version.c
Normal file
97
contrib/libarchive/cat/test/test_version.c
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*-
|
||||||
|
* 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 "test.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that --version option works and generates reasonable output.
|
||||||
|
*/
|
||||||
|
|
||||||
|
DEFINE_TEST(test_version)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
char *p, *q;
|
||||||
|
size_t s;
|
||||||
|
|
||||||
|
|
||||||
|
r = systemf("%s --version >version.stdout 2>version.stderr", testprog);
|
||||||
|
failure("Unable to run %s --version", testprog);
|
||||||
|
if (!assert(r == 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* --version should generate nothing to stdout. */
|
||||||
|
assertEmptyFile("version.stderr");
|
||||||
|
/* Verify format of version message. */
|
||||||
|
q = p = slurpfile(&s, "version.stdout");
|
||||||
|
/* Version message should start with name of program, then space. */
|
||||||
|
assert(s > 6);
|
||||||
|
failure("Version must start with 'bsdcat': ``%s''", p);
|
||||||
|
if (!assertEqualMem(q, "bsdcat ", 7))
|
||||||
|
return;
|
||||||
|
q += 7; s -= 7;
|
||||||
|
/* Version number is a series of digits and periods. */
|
||||||
|
while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
|
||||||
|
++q;
|
||||||
|
--s;
|
||||||
|
}
|
||||||
|
/* Version number terminated by space. */
|
||||||
|
failure("No space after bsdcat version: ``%s''", p);
|
||||||
|
assert(s > 1);
|
||||||
|
/* Skip a single trailing a,b,c, or d. */
|
||||||
|
if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
|
||||||
|
++q;
|
||||||
|
failure("No space after bsdcat version: ``%s''", p);
|
||||||
|
assert(*q == ' ');
|
||||||
|
++q; --s;
|
||||||
|
/* Separator. */
|
||||||
|
failure("No `-' between bsdcat and libarchive versions: ``%s''", p);
|
||||||
|
assertEqualMem(q, "- ", 2);
|
||||||
|
q += 2; s -= 2;
|
||||||
|
/* libarchive name and version number */
|
||||||
|
failure("Not long enough for libarchive version: ``%s''", p);
|
||||||
|
assert(s > 11);
|
||||||
|
failure("Libarchive version must start with `libarchive': ``%s''", p);
|
||||||
|
assertEqualMem(q, "libarchive ", 11);
|
||||||
|
q += 11; s -= 11;
|
||||||
|
/* Version number is a series of digits and periods. */
|
||||||
|
while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) {
|
||||||
|
++q;
|
||||||
|
--s;
|
||||||
|
}
|
||||||
|
/* Skip a single trailing a,b,c, or d. */
|
||||||
|
if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
|
||||||
|
++q;
|
||||||
|
/* Skip arbitrary third-party version numbers. */
|
||||||
|
while (s > 0 && (*q == ' ' || *q == '/' || *q == '.' || isalnum(*q))) {
|
||||||
|
++q;
|
||||||
|
--s;
|
||||||
|
}
|
||||||
|
/* All terminated by end-of-line. */
|
||||||
|
assert(s >= 1);
|
||||||
|
/* Skip an optional CR character (e.g., Windows) */
|
||||||
|
failure("Version output must end with \\n or \\r\\n");
|
||||||
|
if (*q == '\r') { ++q; --s; }
|
||||||
|
assertEqualMem(q, "\n", 1);
|
||||||
|
free(p);
|
||||||
|
}
|
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd October 7, 2012
|
.Dd September 16, 2014
|
||||||
.Dt CPIO 1
|
.Dt CPIO 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -32,17 +32,17 @@
|
|||||||
.Nd copy files to and from archives
|
.Nd copy files to and from archives
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Brq Fl i
|
.Fl i
|
||||||
.Op Ar options
|
.Op Ar options
|
||||||
.Op Ar pattern ...
|
.Op Ar pattern ...
|
||||||
.Op Ar < archive
|
.Op Ar < archive
|
||||||
.Nm
|
.Nm
|
||||||
.Brq Fl o
|
.Fl o
|
||||||
.Op Ar options
|
.Op Ar options
|
||||||
.Ar < name-list
|
.Ar < name-list
|
||||||
.Op Ar > archive
|
.Op Ar > archive
|
||||||
.Nm
|
.Nm
|
||||||
.Brq Fl p
|
.Fl p
|
||||||
.Op Ar options
|
.Op Ar options
|
||||||
.Ar dest-dir
|
.Ar dest-dir
|
||||||
.Ar < name-list
|
.Ar < name-list
|
||||||
@ -156,7 +156,8 @@ See above for description.
|
|||||||
.It Fl Fl insecure
|
.It Fl Fl insecure
|
||||||
(i and p mode only)
|
(i and p mode only)
|
||||||
Disable security checks during extraction or copying.
|
Disable security checks during extraction or copying.
|
||||||
This allows extraction via symbolic links and path names containing
|
This allows extraction via symbolic links, absolute paths,
|
||||||
|
and path names containing
|
||||||
.Sq ..
|
.Sq ..
|
||||||
in the name.
|
in the name.
|
||||||
.It Fl J , Fl Fl xz
|
.It Fl J , Fl Fl xz
|
||||||
@ -181,6 +182,11 @@ instead of copying.
|
|||||||
Compress the resulting archive with
|
Compress the resulting archive with
|
||||||
.Xr lrzip 1 .
|
.Xr lrzip 1 .
|
||||||
In input mode, this option is ignored.
|
In input mode, this option is ignored.
|
||||||
|
.It Fl Fl lz4
|
||||||
|
(o mode only)
|
||||||
|
Compress the archive with lz4-compatible compression before writing it.
|
||||||
|
In input mode, this option is ignored; lz4 compression is recognized
|
||||||
|
automatically on input.
|
||||||
.It Fl Fl lzma
|
.It Fl Fl lzma
|
||||||
(o mode only)
|
(o mode only)
|
||||||
Compress the file with lzma-compatible compression before writing it.
|
Compress the file with lzma-compatible compression before writing it.
|
||||||
@ -191,6 +197,15 @@ automatically on input.
|
|||||||
Compress the resulting archive with
|
Compress the resulting archive with
|
||||||
.Xr lzop 1 .
|
.Xr lzop 1 .
|
||||||
In input mode, this option is ignored.
|
In input mode, this option is ignored.
|
||||||
|
.It Fl Fl passphrase Ar passphrase
|
||||||
|
The
|
||||||
|
.Pa passphrase
|
||||||
|
is used to extract or create an encrypted archive.
|
||||||
|
Currently, zip is only a format that
|
||||||
|
.Nm
|
||||||
|
can handle encrypted archives.
|
||||||
|
You shouldn't use this option unless you realize how insecure
|
||||||
|
use of this option is.
|
||||||
.It Fl m , Fl Fl preserve-modification-time
|
.It Fl m , Fl Fl preserve-modification-time
|
||||||
(i and p modes)
|
(i and p modes)
|
||||||
Set file modification time on created files to match
|
Set file modification time on created files to match
|
||||||
|
@ -73,6 +73,7 @@ static const struct option {
|
|||||||
{ "link", 0, 'l' },
|
{ "link", 0, 'l' },
|
||||||
{ "list", 0, 't' },
|
{ "list", 0, 't' },
|
||||||
{ "lrzip", 0, OPTION_LRZIP },
|
{ "lrzip", 0, OPTION_LRZIP },
|
||||||
|
{ "lz4", 0, OPTION_LZ4 },
|
||||||
{ "lzma", 0, OPTION_LZMA },
|
{ "lzma", 0, OPTION_LZMA },
|
||||||
{ "lzop", 0, OPTION_LZOP },
|
{ "lzop", 0, OPTION_LZOP },
|
||||||
{ "make-directories", 0, 'd' },
|
{ "make-directories", 0, 'd' },
|
||||||
@ -80,6 +81,7 @@ static const struct option {
|
|||||||
{ "null", 0, '0' },
|
{ "null", 0, '0' },
|
||||||
{ "numeric-uid-gid", 0, 'n' },
|
{ "numeric-uid-gid", 0, 'n' },
|
||||||
{ "owner", 1, 'R' },
|
{ "owner", 1, 'R' },
|
||||||
|
{ "passphrase", 1, OPTION_PASSPHRASE },
|
||||||
{ "pass-through", 0, 'p' },
|
{ "pass-through", 0, 'p' },
|
||||||
{ "preserve-modification-time", 0, 'm' },
|
{ "preserve-modification-time", 0, 'm' },
|
||||||
{ "preserve-owner", 0, OPTION_PRESERVE_OWNER },
|
{ "preserve-owner", 0, OPTION_PRESERVE_OWNER },
|
||||||
|
@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include "cpio.h"
|
#include "cpio.h"
|
||||||
#include "err.h"
|
#include "err.h"
|
||||||
#include "line_reader.h"
|
#include "line_reader.h"
|
||||||
|
#include "passphrase.h"
|
||||||
|
|
||||||
/* Fixed size of uname/gname caches. */
|
/* Fixed size of uname/gname caches. */
|
||||||
#define name_cache_size 101
|
#define name_cache_size 101
|
||||||
@ -123,6 +124,8 @@ static int restore_time(struct cpio *, struct archive_entry *,
|
|||||||
const char *, int fd);
|
const char *, int fd);
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
static void version(void);
|
static void version(void);
|
||||||
|
static const char * passphrase_callback(struct archive *, void *);
|
||||||
|
static void passphrase_free(char *);
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
@ -149,20 +152,9 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Need lafe_progname before calling lafe_warnc. */
|
/* Set lafe_progname before calling lafe_warnc. */
|
||||||
if (*argv == NULL)
|
lafe_setprogname(*argv, "bsdcpio");
|
||||||
lafe_progname = "bsdcpio";
|
|
||||||
else {
|
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
||||||
lafe_progname = strrchr(*argv, '\\');
|
|
||||||
if (strrchr(*argv, '/') > lafe_progname)
|
|
||||||
#endif
|
|
||||||
lafe_progname = strrchr(*argv, '/');
|
|
||||||
if (lafe_progname != NULL)
|
|
||||||
lafe_progname++;
|
|
||||||
else
|
|
||||||
lafe_progname = *argv;
|
|
||||||
}
|
|
||||||
#if HAVE_SETLOCALE
|
#if HAVE_SETLOCALE
|
||||||
if (setlocale(LC_ALL, "") == NULL)
|
if (setlocale(LC_ALL, "") == NULL)
|
||||||
lafe_warnc(0, "Failed to set default locale");
|
lafe_warnc(0, "Failed to set default locale");
|
||||||
@ -179,6 +171,7 @@ main(int argc, char *argv[])
|
|||||||
cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
|
cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
|
||||||
cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS;
|
cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS;
|
||||||
cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT;
|
cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT;
|
||||||
|
cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS;
|
||||||
cpio->extract_flags |= ARCHIVE_EXTRACT_PERM;
|
cpio->extract_flags |= ARCHIVE_EXTRACT_PERM;
|
||||||
cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
|
cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
|
||||||
cpio->extract_flags |= ARCHIVE_EXTRACT_ACL;
|
cpio->extract_flags |= ARCHIVE_EXTRACT_ACL;
|
||||||
@ -264,6 +257,7 @@ main(int argc, char *argv[])
|
|||||||
case OPTION_INSECURE:
|
case OPTION_INSECURE:
|
||||||
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS;
|
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS;
|
||||||
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
|
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
|
||||||
|
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS;
|
||||||
break;
|
break;
|
||||||
case 'L': /* GNU cpio */
|
case 'L': /* GNU cpio */
|
||||||
cpio->option_follow_links = 1;
|
cpio->option_follow_links = 1;
|
||||||
@ -272,6 +266,7 @@ main(int argc, char *argv[])
|
|||||||
cpio->option_link = 1;
|
cpio->option_link = 1;
|
||||||
break;
|
break;
|
||||||
case OPTION_LRZIP:
|
case OPTION_LRZIP:
|
||||||
|
case OPTION_LZ4:
|
||||||
case OPTION_LZMA: /* GNU tar, others */
|
case OPTION_LZMA: /* GNU tar, others */
|
||||||
case OPTION_LZOP: /* GNU tar, others */
|
case OPTION_LZOP: /* GNU tar, others */
|
||||||
cpio->compress = opt;
|
cpio->compress = opt;
|
||||||
@ -301,6 +296,9 @@ main(int argc, char *argv[])
|
|||||||
cpio->mode = opt;
|
cpio->mode = opt;
|
||||||
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
|
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
|
||||||
break;
|
break;
|
||||||
|
case OPTION_PASSPHRASE:
|
||||||
|
cpio->passphrase = cpio->argument;
|
||||||
|
break;
|
||||||
case OPTION_PRESERVE_OWNER:
|
case OPTION_PRESERVE_OWNER:
|
||||||
cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER;
|
cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER;
|
||||||
break;
|
break;
|
||||||
@ -429,6 +427,7 @@ main(int argc, char *argv[])
|
|||||||
free_cache(cpio->gname_cache);
|
free_cache(cpio->gname_cache);
|
||||||
free_cache(cpio->uname_cache);
|
free_cache(cpio->uname_cache);
|
||||||
free(cpio->destdir);
|
free(cpio->destdir);
|
||||||
|
passphrase_free(cpio->ppbuff);
|
||||||
return (cpio->return_value);
|
return (cpio->return_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,7 +436,7 @@ usage(void)
|
|||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
p = lafe_progname;
|
p = lafe_getprogname();
|
||||||
|
|
||||||
fprintf(stderr, "Brief Usage:\n");
|
fprintf(stderr, "Brief Usage:\n");
|
||||||
fprintf(stderr, " List: %s -it < archive\n", p);
|
fprintf(stderr, " List: %s -it < archive\n", p);
|
||||||
@ -475,7 +474,7 @@ long_help(void)
|
|||||||
const char *prog;
|
const char *prog;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
prog = lafe_progname;
|
prog = lafe_getprogname();
|
||||||
|
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
@ -500,7 +499,7 @@ version(void)
|
|||||||
{
|
{
|
||||||
fprintf(stdout,"bsdcpio %s -- %s\n",
|
fprintf(stdout,"bsdcpio %s -- %s\n",
|
||||||
BSDCPIO_VERSION_STRING,
|
BSDCPIO_VERSION_STRING,
|
||||||
archive_version_string());
|
archive_version_details());
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,6 +536,9 @@ mode_out(struct cpio *cpio)
|
|||||||
case OPTION_LRZIP:
|
case OPTION_LRZIP:
|
||||||
r = archive_write_add_filter_lrzip(cpio->archive);
|
r = archive_write_add_filter_lrzip(cpio->archive);
|
||||||
break;
|
break;
|
||||||
|
case OPTION_LZ4:
|
||||||
|
r = archive_write_add_filter_lz4(cpio->archive);
|
||||||
|
break;
|
||||||
case OPTION_LZMA:
|
case OPTION_LZMA:
|
||||||
r = archive_write_add_filter_lzma(cpio->archive);
|
r = archive_write_add_filter_lzma(cpio->archive);
|
||||||
break;
|
break;
|
||||||
@ -578,6 +580,14 @@ mode_out(struct cpio *cpio)
|
|||||||
cpio->linkresolver = archive_entry_linkresolver_new();
|
cpio->linkresolver = archive_entry_linkresolver_new();
|
||||||
archive_entry_linkresolver_set_strategy(cpio->linkresolver,
|
archive_entry_linkresolver_set_strategy(cpio->linkresolver,
|
||||||
archive_format(cpio->archive));
|
archive_format(cpio->archive));
|
||||||
|
if (cpio->passphrase != NULL)
|
||||||
|
r = archive_write_set_passphrase(cpio->archive,
|
||||||
|
cpio->passphrase);
|
||||||
|
else
|
||||||
|
r = archive_write_set_passphrase_callback(cpio->archive, cpio,
|
||||||
|
&passphrase_callback);
|
||||||
|
if (r != ARCHIVE_OK)
|
||||||
|
lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The main loop: Copy each file into the output archive.
|
* The main loop: Copy each file into the output archive.
|
||||||
@ -944,6 +954,13 @@ mode_in(struct cpio *cpio)
|
|||||||
lafe_errc(1, 0, "Couldn't allocate archive object");
|
lafe_errc(1, 0, "Couldn't allocate archive object");
|
||||||
archive_read_support_filter_all(a);
|
archive_read_support_filter_all(a);
|
||||||
archive_read_support_format_all(a);
|
archive_read_support_format_all(a);
|
||||||
|
if (cpio->passphrase != NULL)
|
||||||
|
r = archive_read_add_passphrase(a, cpio->passphrase);
|
||||||
|
else
|
||||||
|
r = archive_read_set_passphrase_callback(a, cpio,
|
||||||
|
&passphrase_callback);
|
||||||
|
if (r != ARCHIVE_OK)
|
||||||
|
lafe_errc(1, 0, "%s", archive_error_string(a));
|
||||||
|
|
||||||
if (archive_read_open_filename(a, cpio->filename,
|
if (archive_read_open_filename(a, cpio->filename,
|
||||||
cpio->bytes_per_block))
|
cpio->bytes_per_block))
|
||||||
@ -1047,6 +1064,13 @@ mode_list(struct cpio *cpio)
|
|||||||
lafe_errc(1, 0, "Couldn't allocate archive object");
|
lafe_errc(1, 0, "Couldn't allocate archive object");
|
||||||
archive_read_support_filter_all(a);
|
archive_read_support_filter_all(a);
|
||||||
archive_read_support_format_all(a);
|
archive_read_support_format_all(a);
|
||||||
|
if (cpio->passphrase != NULL)
|
||||||
|
r = archive_read_add_passphrase(a, cpio->passphrase);
|
||||||
|
else
|
||||||
|
r = archive_read_set_passphrase_callback(a, cpio,
|
||||||
|
&passphrase_callback);
|
||||||
|
if (r != ARCHIVE_OK)
|
||||||
|
lafe_errc(1, 0, "%s", archive_error_string(a));
|
||||||
|
|
||||||
if (archive_read_open_filename(a, cpio->filename,
|
if (archive_read_open_filename(a, cpio->filename,
|
||||||
cpio->bytes_per_block))
|
cpio->bytes_per_block))
|
||||||
@ -1236,8 +1260,10 @@ cpio_rename(const char *name)
|
|||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return (name);
|
return (name);
|
||||||
to = fopen("CONOUT$", "w");
|
to = fopen("CONOUT$", "w");
|
||||||
if (to == NULL)
|
if (to == NULL) {
|
||||||
|
fclose(t);
|
||||||
return (name);
|
return (name);
|
||||||
|
}
|
||||||
fprintf(to, "%s (Enter/./(new name))? ", name);
|
fprintf(to, "%s (Enter/./(new name))? ", name);
|
||||||
fclose(to);
|
fclose(to);
|
||||||
#else
|
#else
|
||||||
@ -1417,3 +1443,28 @@ cpio_i64toa(int64_t n0)
|
|||||||
*--p = '-';
|
*--p = '-';
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PPBUFF_SIZE 1024
|
||||||
|
static const char *
|
||||||
|
passphrase_callback(struct archive *a, void *_client_data)
|
||||||
|
{
|
||||||
|
struct cpio *cpio = (struct cpio *)_client_data;
|
||||||
|
(void)a; /* UNUSED */
|
||||||
|
|
||||||
|
if (cpio->ppbuff == NULL) {
|
||||||
|
cpio->ppbuff = malloc(PPBUFF_SIZE);
|
||||||
|
if (cpio->ppbuff == NULL)
|
||||||
|
lafe_errc(1, errno, "Out of memory");
|
||||||
|
}
|
||||||
|
return lafe_readpassphrase("Enter passphrase:",
|
||||||
|
cpio->ppbuff, PPBUFF_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
passphrase_free(char *ppbuff)
|
||||||
|
{
|
||||||
|
if (ppbuff != NULL) {
|
||||||
|
memset(ppbuff, 0, PPBUFF_SIZE);
|
||||||
|
free(ppbuff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -71,6 +71,7 @@ struct cpio {
|
|||||||
int gid_override;
|
int gid_override;
|
||||||
char *gname_override;
|
char *gname_override;
|
||||||
int day_first; /* true if locale prefers day/mon */
|
int day_first; /* true if locale prefers day/mon */
|
||||||
|
const char *passphrase;
|
||||||
|
|
||||||
/* If >= 0, then close this when done. */
|
/* If >= 0, then close this when done. */
|
||||||
int fd;
|
int fd;
|
||||||
@ -90,6 +91,7 @@ struct cpio {
|
|||||||
struct archive *matching;
|
struct archive *matching;
|
||||||
char *buff;
|
char *buff;
|
||||||
size_t buff_size;
|
size_t buff_size;
|
||||||
|
char *ppbuff;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *owner_parse(const char *, int *, int *);
|
const char *owner_parse(const char *, int *, int *);
|
||||||
@ -101,8 +103,10 @@ enum {
|
|||||||
OPTION_GRZIP,
|
OPTION_GRZIP,
|
||||||
OPTION_INSECURE,
|
OPTION_INSECURE,
|
||||||
OPTION_LRZIP,
|
OPTION_LRZIP,
|
||||||
|
OPTION_LZ4,
|
||||||
OPTION_LZMA,
|
OPTION_LZMA,
|
||||||
OPTION_LZOP,
|
OPTION_LZOP,
|
||||||
|
OPTION_PASSPHRASE,
|
||||||
OPTION_NO_PRESERVE_OWNER,
|
OPTION_NO_PRESERVE_OWNER,
|
||||||
OPTION_PRESERVE_OWNER,
|
OPTION_PRESERVE_OWNER,
|
||||||
OPTION_QUIET,
|
OPTION_QUIET,
|
||||||
|
@ -42,6 +42,10 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
#include "cpio_windows.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get a real definition for __FBSDID if we can */
|
/* Get a real definition for __FBSDID if we can */
|
||||||
#if HAVE_SYS_CDEFS_H
|
#if HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
@ -70,8 +74,4 @@
|
|||||||
#define __LA_DEAD
|
#define __LA_DEAD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
||||||
#include "cpio_windows.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !CPIO_PLATFORM_H_INCLUDED */
|
#endif /* !CPIO_PLATFORM_H_INCLUDED */
|
||||||
|
@ -130,6 +130,16 @@ __FBSDID("$FreeBSD$");
|
|||||||
# include <crtdbg.h>
|
# include <crtdbg.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Path to working directory for current test */
|
||||||
|
const char *testworkdir;
|
||||||
|
#ifdef PROGRAM
|
||||||
|
/* Pathname of exe to be tested. */
|
||||||
|
const char *testprogfile;
|
||||||
|
/* Name of exe to use in printf-formatted command strings. */
|
||||||
|
/* On Windows, this includes leading/trailing quotes. */
|
||||||
|
const char *testprog;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
static void *GetFunctionKernel32(const char *);
|
static void *GetFunctionKernel32(const char *);
|
||||||
static int my_CreateSymbolicLinkA(const char *, const char *, int);
|
static int my_CreateSymbolicLinkA(const char *, const char *, int);
|
||||||
@ -194,7 +204,7 @@ my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE__CrtSetReportMode)
|
#if defined(HAVE__CrtSetReportMode) && !defined(__WATCOMC__)
|
||||||
static void
|
static void
|
||||||
invalid_parameter_handler(const wchar_t * expression,
|
invalid_parameter_handler(const wchar_t * expression,
|
||||||
const wchar_t * function, const wchar_t * file,
|
const wchar_t * function, const wchar_t * file,
|
||||||
@ -565,10 +575,10 @@ static void strdump(const char *e, const char *p, int ewidth, int utf8)
|
|||||||
while (*p != '\0') {
|
while (*p != '\0') {
|
||||||
unsigned int c = 0xff & *p++;
|
unsigned int c = 0xff & *p++;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\a': printf("\a"); break;
|
case '\a': logprintf("\\a"); break;
|
||||||
case '\b': printf("\b"); break;
|
case '\b': logprintf("\\b"); break;
|
||||||
case '\n': printf("\n"); break;
|
case '\n': logprintf("\\n"); break;
|
||||||
case '\r': printf("\r"); break;
|
case '\r': logprintf("\\r"); break;
|
||||||
default:
|
default:
|
||||||
if (c >= 32 && c < 127)
|
if (c >= 32 && c < 127)
|
||||||
logprintf("%c", c);
|
logprintf("%c", c);
|
||||||
@ -771,6 +781,34 @@ assertion_equal_mem(const char *file, int line,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Verify that a block of memory is filled with the specified byte. */
|
||||||
|
int
|
||||||
|
assertion_memory_filled_with(const char *file, int line,
|
||||||
|
const void *_v1, const char *vd,
|
||||||
|
size_t l, const char *ld,
|
||||||
|
char b, const char *bd, void *extra)
|
||||||
|
{
|
||||||
|
const char *v1 = (const char *)_v1;
|
||||||
|
size_t c = 0;
|
||||||
|
size_t i;
|
||||||
|
(void)ld; /* UNUSED */
|
||||||
|
|
||||||
|
assertion_count(file, line);
|
||||||
|
|
||||||
|
for (i = 0; i < l; ++i) {
|
||||||
|
if (v1[i] == b) {
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c == l)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
failure_start(file, line, "%s (size %d) not filled with %s", vd, (int)l, bd);
|
||||||
|
logprintf(" Only %d bytes were correct\n", (int)c);
|
||||||
|
failure_finish(extra);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Verify that the named file exists and is empty. */
|
/* Verify that the named file exists and is empty. */
|
||||||
int
|
int
|
||||||
assertion_empty_file(const char *filename, int line, const char *f1)
|
assertion_empty_file(const char *filename, int line, const char *f1)
|
||||||
@ -1036,6 +1074,7 @@ assertion_file_contains_lines_any_order(const char *file, int line,
|
|||||||
if (expected == NULL) {
|
if (expected == NULL) {
|
||||||
failure_start(pathname, line, "Can't allocate memory");
|
failure_start(pathname, line, "Can't allocate memory");
|
||||||
failure_finish(NULL);
|
failure_finish(NULL);
|
||||||
|
free(expected);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
for (i = 0; lines[i] != NULL; ++i) {
|
for (i = 0; lines[i] != NULL; ++i) {
|
||||||
@ -1060,7 +1099,8 @@ assertion_file_contains_lines_any_order(const char *file, int line,
|
|||||||
free(expected);
|
free(expected);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
for (j = 0, p = buff; p < buff + buff_size; p += 1 + strlen(p)) {
|
for (j = 0, p = buff; p < buff + buff_size;
|
||||||
|
p += 1 + strlen(p)) {
|
||||||
if (*p != '\0') {
|
if (*p != '\0') {
|
||||||
actual[j] = p;
|
actual[j] = p;
|
||||||
++j;
|
++j;
|
||||||
@ -1911,6 +1951,18 @@ canGzip(void)
|
|||||||
/*
|
/*
|
||||||
* Can this platform run the lrzip program?
|
* Can this platform run the lrzip program?
|
||||||
*/
|
*/
|
||||||
|
int
|
||||||
|
canRunCommand(const char *cmd)
|
||||||
|
{
|
||||||
|
static int tested = 0, value = 0;
|
||||||
|
if (!tested) {
|
||||||
|
tested = 1;
|
||||||
|
if (systemf("%s %s", cmd, redirectArgs) == 0)
|
||||||
|
value = 1;
|
||||||
|
}
|
||||||
|
return (value);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
canLrzip(void)
|
canLrzip(void)
|
||||||
{
|
{
|
||||||
@ -1923,6 +1975,21 @@ canLrzip(void)
|
|||||||
return (value);
|
return (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Can this platform run the lz4 program?
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
canLz4(void)
|
||||||
|
{
|
||||||
|
static int tested = 0, value = 0;
|
||||||
|
if (!tested) {
|
||||||
|
tested = 1;
|
||||||
|
if (systemf("lz4 -V %s", redirectArgs) == 0)
|
||||||
|
value = 1;
|
||||||
|
}
|
||||||
|
return (value);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Can this platform run the lzip program?
|
* Can this platform run the lzip program?
|
||||||
*/
|
*/
|
||||||
@ -2135,8 +2202,31 @@ slurpfile(size_t * sizep, const char *fmt, ...)
|
|||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Slurp a file into memory for ease of comparison and testing.
|
||||||
|
* Returns size of file in 'sizep' if non-NULL, null-terminates
|
||||||
|
* data in memory for ease of use.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dumpfile(const char *filename, void *data, size_t len)
|
||||||
|
{
|
||||||
|
ssize_t bytes_written;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
f = fopen(filename, "wb");
|
||||||
|
if (f == NULL) {
|
||||||
|
logprintf("Can't open file %s for writing\n", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bytes_written = fwrite(data, 1, len, f);
|
||||||
|
if (bytes_written < (ssize_t)len)
|
||||||
|
logprintf("Can't write file %s\n", filename);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
/* Read a uuencoded file from the reference directory, decode, and
|
/* Read a uuencoded file from the reference directory, decode, and
|
||||||
* write the result into the current directory. */
|
* write the result into the current directory. */
|
||||||
|
#define VALID_UUDECODE(c) (c >= 32 && c <= 96)
|
||||||
#define UUDECODE(c) (((c) - 0x20) & 0x3f)
|
#define UUDECODE(c) (((c) - 0x20) & 0x3f)
|
||||||
void
|
void
|
||||||
extract_reference_file(const char *name)
|
extract_reference_file(const char *name)
|
||||||
@ -2160,7 +2250,6 @@ extract_reference_file(const char *name)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Now, decode the rest and write it. */
|
/* Now, decode the rest and write it. */
|
||||||
/* Not a lot of error checking here; the input better be right. */
|
|
||||||
out = fopen(name, "wb");
|
out = fopen(name, "wb");
|
||||||
while (fgets(buff, sizeof(buff), in) != NULL) {
|
while (fgets(buff, sizeof(buff), in) != NULL) {
|
||||||
char *p = buff;
|
char *p = buff;
|
||||||
@ -2174,17 +2263,21 @@ extract_reference_file(const char *name)
|
|||||||
int n = 0;
|
int n = 0;
|
||||||
/* Write out 1-3 bytes from that. */
|
/* Write out 1-3 bytes from that. */
|
||||||
if (bytes > 0) {
|
if (bytes > 0) {
|
||||||
|
assert(VALID_UUDECODE(p[0]));
|
||||||
|
assert(VALID_UUDECODE(p[1]));
|
||||||
n = UUDECODE(*p++) << 18;
|
n = UUDECODE(*p++) << 18;
|
||||||
n |= UUDECODE(*p++) << 12;
|
n |= UUDECODE(*p++) << 12;
|
||||||
fputc(n >> 16, out);
|
fputc(n >> 16, out);
|
||||||
--bytes;
|
--bytes;
|
||||||
}
|
}
|
||||||
if (bytes > 0) {
|
if (bytes > 0) {
|
||||||
|
assert(VALID_UUDECODE(p[0]));
|
||||||
n |= UUDECODE(*p++) << 6;
|
n |= UUDECODE(*p++) << 6;
|
||||||
fputc((n >> 8) & 0xFF, out);
|
fputc((n >> 8) & 0xFF, out);
|
||||||
--bytes;
|
--bytes;
|
||||||
}
|
}
|
||||||
if (bytes > 0) {
|
if (bytes > 0) {
|
||||||
|
assert(VALID_UUDECODE(p[0]));
|
||||||
n |= UUDECODE(*p++);
|
n |= UUDECODE(*p++);
|
||||||
fputc(n & 0xFF, out);
|
fputc(n & 0xFF, out);
|
||||||
--bytes;
|
--bytes;
|
||||||
@ -2195,6 +2288,32 @@ extract_reference_file(const char *name)
|
|||||||
fclose(in);
|
fclose(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
copy_reference_file(const char *name)
|
||||||
|
{
|
||||||
|
char buff[1024];
|
||||||
|
FILE *in, *out;
|
||||||
|
size_t rbytes;
|
||||||
|
|
||||||
|
sprintf(buff, "%s/%s", refdir, name);
|
||||||
|
in = fopen(buff, "rb");
|
||||||
|
failure("Couldn't open reference file %s", buff);
|
||||||
|
assert(in != NULL);
|
||||||
|
if (in == NULL)
|
||||||
|
return;
|
||||||
|
/* Now, decode the rest and write it. */
|
||||||
|
/* Not a lot of error checking here; the input better be right. */
|
||||||
|
out = fopen(name, "wb");
|
||||||
|
while ((rbytes = fread(buff, 1, sizeof(buff), in)) > 0) {
|
||||||
|
if (fwrite(buff, 1, rbytes, out) != rbytes) {
|
||||||
|
logprintf("Error: fwrite\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(out);
|
||||||
|
fclose(in);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
is_LargeInode(const char *file)
|
is_LargeInode(const char *file)
|
||||||
{
|
{
|
||||||
@ -2216,6 +2335,14 @@ is_LargeInode(const char *file)
|
|||||||
return (ino > 0xffffffff);
|
return (ino > 0xffffffff);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
extract_reference_files(const char **names)
|
||||||
|
{
|
||||||
|
while (names && *names)
|
||||||
|
extract_reference_file(*names++);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* TEST management
|
* TEST management
|
||||||
@ -2245,7 +2372,7 @@ struct test_list_t tests[] = {
|
|||||||
* Summarize repeated failures in the just-completed test.
|
* Summarize repeated failures in the just-completed test.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
test_summarize(int failed)
|
test_summarize(int failed, int skips_num)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@ -2255,7 +2382,7 @@ test_summarize(int failed)
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
break;
|
break;
|
||||||
case VERBOSITY_PASSFAIL:
|
case VERBOSITY_PASSFAIL:
|
||||||
printf(failed ? "FAIL\n" : "ok\n");
|
printf(failed ? "FAIL\n" : skips_num ? "ok (S)\n" : "ok\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2280,13 +2407,14 @@ test_run(int i, const char *tmpdir)
|
|||||||
char workdir[1024];
|
char workdir[1024];
|
||||||
char logfilename[64];
|
char logfilename[64];
|
||||||
int failures_before = failures;
|
int failures_before = failures;
|
||||||
|
int skips_before = skips;
|
||||||
int oldumask;
|
int oldumask;
|
||||||
|
|
||||||
switch (verbosity) {
|
switch (verbosity) {
|
||||||
case VERBOSITY_SUMMARY_ONLY: /* No per-test reports at all */
|
case VERBOSITY_SUMMARY_ONLY: /* No per-test reports at all */
|
||||||
break;
|
break;
|
||||||
case VERBOSITY_PASSFAIL: /* rest of line will include ok/FAIL marker */
|
case VERBOSITY_PASSFAIL: /* rest of line will include ok/FAIL marker */
|
||||||
printf("%3d: %-50s", i, tests[i].name);
|
printf("%3d: %-64s", i, tests[i].name);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
break;
|
break;
|
||||||
default: /* Title of test, details will follow */
|
default: /* Title of test, details will follow */
|
||||||
@ -2336,7 +2464,7 @@ test_run(int i, const char *tmpdir)
|
|||||||
}
|
}
|
||||||
/* Report per-test summaries. */
|
/* Report per-test summaries. */
|
||||||
tests[i].failures = failures - failures_before;
|
tests[i].failures = failures - failures_before;
|
||||||
test_summarize(tests[i].failures);
|
test_summarize(tests[i].failures, skips - skips_before);
|
||||||
/* Close the per-test log file. */
|
/* Close the per-test log file. */
|
||||||
fclose(logfile);
|
fclose(logfile);
|
||||||
logfile = NULL;
|
logfile = NULL;
|
||||||
@ -2479,6 +2607,7 @@ get_refdir(const char *d)
|
|||||||
failure:
|
failure:
|
||||||
printf("Unable to locate known reference file %s\n", KNOWNREF);
|
printf("Unable to locate known reference file %s\n", KNOWNREF);
|
||||||
printf(" Checked following directories:\n%s\n", tried);
|
printf(" Checked following directories:\n%s\n", tried);
|
||||||
|
printf("Use -r option to specify full path to reference directory\n");
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
|
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
#endif
|
#endif
|
||||||
@ -2515,7 +2644,7 @@ main(int argc, char **argv)
|
|||||||
while (pwd[strlen(pwd) - 1] == '\n')
|
while (pwd[strlen(pwd) - 1] == '\n')
|
||||||
pwd[strlen(pwd) - 1] = '\0';
|
pwd[strlen(pwd) - 1] = '\0';
|
||||||
|
|
||||||
#if defined(HAVE__CrtSetReportMode)
|
#if defined(HAVE__CrtSetReportMode) && !defined(__WATCOMC__)
|
||||||
/* To stop to run the default invalid parameter handler. */
|
/* To stop to run the default invalid parameter handler. */
|
||||||
_set_invalid_parameter_handler(invalid_parameter_handler);
|
_set_invalid_parameter_handler(invalid_parameter_handler);
|
||||||
/* Disable annoying assertion message box. */
|
/* Disable annoying assertion message box. */
|
||||||
@ -2562,7 +2691,7 @@ main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
memmove(testprogdir + strlen(pwd) + 1, testprogdir,
|
memmove(testprogdir + strlen(pwd) + 1, testprogdir,
|
||||||
strlen(testprogdir));
|
strlen(testprogdir) + 1);
|
||||||
memcpy(testprogdir, pwd, strlen(pwd));
|
memcpy(testprogdir, pwd, strlen(pwd));
|
||||||
testprogdir[strlen(pwd)] = '/';
|
testprogdir[strlen(pwd)] = '/';
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -84,12 +85,14 @@
|
|||||||
/* Windows (including Visual Studio and MinGW but not Cygwin) */
|
/* Windows (including Visual Studio and MinGW but not Cygwin) */
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
#if !defined(__BORLANDC__)
|
#if !defined(__BORLANDC__)
|
||||||
|
#undef chdir
|
||||||
|
#define chdir _chdir
|
||||||
#define strdup _strdup
|
#define strdup _strdup
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Visual Studio */
|
/* Visual Studio */
|
||||||
#ifdef _MSC_VER
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
#define snprintf sprintf_s
|
#define snprintf sprintf_s
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -142,6 +145,9 @@
|
|||||||
/* As above, but raw blocks of bytes. */
|
/* As above, but raw blocks of bytes. */
|
||||||
#define assertEqualMem(v1, v2, l) \
|
#define assertEqualMem(v1, v2, l) \
|
||||||
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
|
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
|
||||||
|
/* Assert that memory is full of a specified byte */
|
||||||
|
#define assertMemoryFilledWith(v1, l, b) \
|
||||||
|
assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
|
||||||
/* Assert two files are the same. */
|
/* Assert two files are the same. */
|
||||||
#define assertEqualFile(f1, f2) \
|
#define assertEqualFile(f1, f2) \
|
||||||
assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
|
assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
|
||||||
@ -225,6 +231,7 @@ int assertion_empty_file(const char *, int, const char *);
|
|||||||
int assertion_equal_file(const char *, int, const char *, const char *);
|
int assertion_equal_file(const char *, int, const char *, const char *);
|
||||||
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
|
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
|
||||||
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
|
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
|
||||||
|
int assertion_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
|
||||||
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
|
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
|
||||||
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
|
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
|
||||||
int assertion_file_atime(const char *, int, const char *, long, long);
|
int assertion_file_atime(const char *, int, const char *, long, long);
|
||||||
@ -275,9 +282,15 @@ int canGrzip(void);
|
|||||||
/* Return true if this platform can run the "gzip" program. */
|
/* Return true if this platform can run the "gzip" program. */
|
||||||
int canGzip(void);
|
int canGzip(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the specified command. */
|
||||||
|
int canRunCommand(const char *);
|
||||||
|
|
||||||
/* Return true if this platform can run the "lrzip" program. */
|
/* Return true if this platform can run the "lrzip" program. */
|
||||||
int canLrzip(void);
|
int canLrzip(void);
|
||||||
|
|
||||||
|
/* Return true if this platform can run the "lz4" program. */
|
||||||
|
int canLz4(void);
|
||||||
|
|
||||||
/* Return true if this platform can run the "lzip" program. */
|
/* Return true if this platform can run the "lzip" program. */
|
||||||
int canLzip(void);
|
int canLzip(void);
|
||||||
|
|
||||||
@ -300,21 +313,31 @@ int is_LargeInode(const char *);
|
|||||||
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
|
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
|
||||||
char *slurpfile(size_t *, const char *fmt, ...);
|
char *slurpfile(size_t *, const char *fmt, ...);
|
||||||
|
|
||||||
|
/* Dump block of bytes to a file. */
|
||||||
|
void dumpfile(const char *filename, void *, size_t);
|
||||||
|
|
||||||
/* Extracts named reference file to the current directory. */
|
/* Extracts named reference file to the current directory. */
|
||||||
void extract_reference_file(const char *);
|
void extract_reference_file(const char *);
|
||||||
|
/* Copies named reference file to the current directory. */
|
||||||
|
void copy_reference_file(const char *);
|
||||||
|
|
||||||
|
/* Extracts a list of files to the current directory.
|
||||||
|
* List must be NULL terminated.
|
||||||
|
*/
|
||||||
|
void extract_reference_files(const char **);
|
||||||
|
|
||||||
/* Path to working directory for current test */
|
/* Path to working directory for current test */
|
||||||
const char *testworkdir;
|
extern const char *testworkdir;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special interfaces for program test harness.
|
* Special interfaces for program test harness.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Pathname of exe to be tested. */
|
/* Pathname of exe to be tested. */
|
||||||
const char *testprogfile;
|
extern const char *testprogfile;
|
||||||
/* Name of exe to use in printf-formatted command strings. */
|
/* Name of exe to use in printf-formatted command strings. */
|
||||||
/* On Windows, this includes leading/trailing quotes. */
|
/* On Windows, this includes leading/trailing quotes. */
|
||||||
const char *testprog;
|
extern const char *testprog;
|
||||||
|
|
||||||
#ifdef USE_DMALLOC
|
#ifdef USE_DMALLOC
|
||||||
#include <dmalloc.h>
|
#include <dmalloc.h>
|
||||||
|
@ -72,7 +72,7 @@ basic_cpio(const char *target,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Use the cpio program to create an archive. */
|
/* Use the cpio program to create an archive. */
|
||||||
r = systemf("%s -o %s < filelist >%s/archive 2>%s/pack.err",
|
r = systemf("%s -R 1000:1000 -o %s < filelist >%s/archive 2>%s/pack.err",
|
||||||
testprog, pack_options, target, target);
|
testprog, pack_options, target, target);
|
||||||
failure("Error invoking %s -o %s", testprog, pack_options);
|
failure("Error invoking %s -o %s", testprog, pack_options);
|
||||||
assertEqualInt(r, 0);
|
assertEqualInt(r, 0);
|
||||||
|
7
contrib/libarchive/cpio/test/test_extract.cpio.lz4.uu
Normal file
7
contrib/libarchive/cpio/test/test_extract.cpio.lz4.uu
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
begin 644 test_extract.cpio.lz4
|
||||||
|
M!")-&&1PN9$````A,#<"`&`P-#`P,3`!`&`Q,3`P-C8/`#0W-3`&```)``$&
|
||||||
|
M`,$P,3(P,S(W-#`R,S01`!$V!@```@#Q!3(S9FEL93$`8V]N=&5N=',@;V8@
|
||||||
|
M$@`A+@IC``AE`!\R90`4$#2#``YE`!TR90`6,F4`#P(`#@+H``P"`"<Q,Q(`
|
||||||
|
=OU1204E,15(A(2$``0#'4````````````"BVD[$`
|
||||||
|
`
|
||||||
|
end
|
48
contrib/libarchive/cpio/test/test_extract_cpio_lz4.c
Normal file
48
contrib/libarchive/cpio/test/test_extract_cpio_lz4.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2012,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 "test.h"
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
DEFINE_TEST(test_extract_cpio_lz4)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_extract.cpio.lz4";
|
||||||
|
int f;
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
|
||||||
|
if (f == 0 || canLz4()) {
|
||||||
|
assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
|
||||||
|
testprog, reffile));
|
||||||
|
|
||||||
|
assertFileExists("file1");
|
||||||
|
assertTextFileContents("contents of file1.\n", "file1");
|
||||||
|
assertFileExists("file2");
|
||||||
|
assertTextFileContents("contents of file2.\n", "file2");
|
||||||
|
assertEmptyFile("test.out");
|
||||||
|
assertTextFileContents("1 block\n", "test.err");
|
||||||
|
} else {
|
||||||
|
skipping("It seems lz4 is not supported on this platform");
|
||||||
|
}
|
||||||
|
}
|
@ -27,7 +27,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
DEFINE_TEST(test_extract_cpio_lzo)
|
DEFINE_TEST(test_extract_cpio_lzo)
|
||||||
{
|
{
|
||||||
const char *reffile = "test_extract.cpio.lrz";
|
const char *reffile = "test_extract.cpio.lzo";
|
||||||
int f;
|
int f;
|
||||||
|
|
||||||
extract_reference_file(reffile);
|
extract_reference_file(reffile);
|
||||||
|
@ -65,18 +65,14 @@ DEFINE_TEST(test_option_c)
|
|||||||
{
|
{
|
||||||
FILE *filelist;
|
FILE *filelist;
|
||||||
int r;
|
int r;
|
||||||
int uid = -1;
|
int uid = 1000;
|
||||||
int dev, ino, gid;
|
int dev, ino, gid = 1000;
|
||||||
time_t t, now;
|
time_t t, now;
|
||||||
char *p, *e;
|
char *p, *e;
|
||||||
size_t s;
|
size_t s;
|
||||||
|
|
||||||
assertUmask(0);
|
assertUmask(0);
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
uid = getuid();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create an assortment of files.
|
* Create an assortment of files.
|
||||||
* TODO: Extend this to cover more filetypes.
|
* TODO: Extend this to cover more filetypes.
|
||||||
@ -101,7 +97,7 @@ DEFINE_TEST(test_option_c)
|
|||||||
|
|
||||||
/* Use the cpio program to create an archive. */
|
/* Use the cpio program to create an archive. */
|
||||||
fclose(filelist);
|
fclose(filelist);
|
||||||
r = systemf("%s -oc <filelist >basic.out 2>basic.err", testprog);
|
r = systemf("%s -R 1000:1000 -oc <filelist >basic.out 2>basic.err", testprog);
|
||||||
/* Verify that nothing went to stderr. */
|
/* Verify that nothing went to stderr. */
|
||||||
assertTextFileContents("1 block\n", "basic.err");
|
assertTextFileContents("1 block\n", "basic.err");
|
||||||
|
|
||||||
|
74
contrib/libarchive/cpio/test/test_option_lz4.c
Normal file
74
contrib/libarchive/cpio/test/test_option_lz4.c
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(S) ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "test.h"
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
DEFINE_TEST(test_option_lz4)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
int r;
|
||||||
|
size_t s;
|
||||||
|
|
||||||
|
/* Create a file. */
|
||||||
|
assertMakeFile("f", 0644, "a");
|
||||||
|
|
||||||
|
/* Archive it with lz4 compression. */
|
||||||
|
r = systemf("echo f | %s -o --lz4 >archive.out 2>archive.err",
|
||||||
|
testprog);
|
||||||
|
p = slurpfile(&s, "archive.err");
|
||||||
|
p[s] = '\0';
|
||||||
|
if (r != 0) {
|
||||||
|
if (strstr(p, "compression not available") != NULL) {
|
||||||
|
skipping("This version of bsdcpio was compiled "
|
||||||
|
"without lz4 support");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* POSIX permits different handling of the spawnp
|
||||||
|
* system call used to launch the subsidiary
|
||||||
|
* program: */
|
||||||
|
/* Some systems fail immediately to spawn the new process. */
|
||||||
|
if (strstr(p, "Can't launch") != NULL && !canLz4()) {
|
||||||
|
skipping("This version of bsdcpio uses an external lz4 program "
|
||||||
|
"but no such program is available on this system.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Some systems successfully spawn the new process,
|
||||||
|
* but fail to exec a program within that process.
|
||||||
|
* This results in failure at the first attempt to
|
||||||
|
* write. */
|
||||||
|
if (strstr(p, "Can't write") != NULL && !canLz4()) {
|
||||||
|
skipping("This version of bsdcpio uses an external lz4 program "
|
||||||
|
"but no such program is available on this system.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
failure("--lz4 option is broken: %s", p);
|
||||||
|
assertEqualInt(r, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Check that the archive file has an lz4 signature. */
|
||||||
|
p = slurpfile(&s, "archive.out");
|
||||||
|
assert(s > 2);
|
||||||
|
assertEqualMem(p, "\x04\x22\x4d\x18", 4);
|
||||||
|
}
|
43
contrib/libarchive/cpio/test/test_option_passphrase.c
Normal file
43
contrib/libarchive/cpio/test/test_option_passphrase.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*-
|
||||||
|
* 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 "test.h"
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
DEFINE_TEST(test_option_passphrase)
|
||||||
|
{
|
||||||
|
const char *reffile = "test_option_passphrase.zip";
|
||||||
|
|
||||||
|
extract_reference_file(reffile);
|
||||||
|
assertEqualInt(0,
|
||||||
|
systemf("%s -i --passphrase pass1 < %s >test.out 2>test.err",
|
||||||
|
testprog, reffile));
|
||||||
|
|
||||||
|
assertFileExists("file1");
|
||||||
|
assertTextFileContents("contents of file1.\n", "file1");
|
||||||
|
assertFileExists("file2");
|
||||||
|
assertTextFileContents("contents of file2.\n", "file2");
|
||||||
|
assertEmptyFile("test.out");
|
||||||
|
assertTextFileContents("1 block\n", "test.err");
|
||||||
|
}
|
12
contrib/libarchive/cpio/test/test_option_passphrase.zip.uu
Normal file
12
contrib/libarchive/cpio/test/test_option_passphrase.zip.uu
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
begin 644 test_option_passphrase.zip
|
||||||
|
M4$L#!`H`"0```#B91$7D$C4,'P```!,````%`!P`9FEL93%55`D``VS'+U0"
|
||||||
|
MQR]4=7@+``$$]0$```04````BHPD*"^*I04=XKI\_FQ*TE+#),TD7TTKSP/7
|
||||||
|
MR6R35%!+!PCD$C4,'P```!,```!02P,$"@`)````09E$1;VL<PX?````$P``
|
||||||
|
M``4`'`!F:6QE,E54"0`#><<O5`+'+U1U>`L``03U`0``!!0```!D#6Z\@CI8
|
||||||
|
MV1GIJO5TISQF^I:7.;Y3<-G3$YOCL(C_4$L'"+VL<PX?````$P```%!+`0(>
|
||||||
|
M`PH`"0```#B91$7D$C4,'P```!,````%`!@```````$```"D@0````!F:6QE
|
||||||
|
M,554!0`#;,<O5'5X"P`!!/4!```$%````%!+`0(>`PH`"0```$&91$6]K',.
|
||||||
|
M'P```!,````%`!@```````$```"D@6X```!F:6QE,E54!0`#><<O5'5X"P`!
|
||||||
|
@!/4!```$%````%!+!08``````@`"`)8```#<````````
|
||||||
|
`
|
||||||
|
end
|
@ -74,6 +74,11 @@ verify(const char *p, size_t s)
|
|||||||
/* Skip a single trailing a,b,c, or d. */
|
/* Skip a single trailing a,b,c, or d. */
|
||||||
if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
|
if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
|
||||||
++q;
|
++q;
|
||||||
|
/* Skip arbitrary third-party version numbers. */
|
||||||
|
while (s > 0 && (*q == ' ' || *q == '/' || *q == '.' || isalnum(*q))) {
|
||||||
|
++q;
|
||||||
|
--s;
|
||||||
|
}
|
||||||
/* All terminated by end-of-line: \r, \r\n, or \n */
|
/* All terminated by end-of-line: \r, \r\n, or \n */
|
||||||
assert(s >= 1);
|
assert(s >= 1);
|
||||||
failure("Version: %s", p);
|
failure("Version: %s", p);
|
||||||
|
@ -28,9 +28,20 @@
|
|||||||
#ifndef ARCHIVE_H_INCLUDED
|
#ifndef ARCHIVE_H_INCLUDED
|
||||||
#define ARCHIVE_H_INCLUDED
|
#define ARCHIVE_H_INCLUDED
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The version number is expressed as a single integer that makes it
|
||||||
|
* easy to compare versions at build time: for version a.b.c, the
|
||||||
|
* version number is printf("%d%03d%03d",a,b,c). For example, if you
|
||||||
|
* know your application requires version 2.12.108 or later, you can
|
||||||
|
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
||||||
|
*/
|
||||||
|
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
||||||
|
#define ARCHIVE_VERSION_NUMBER 3002000
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stddef.h> /* for wchar_t */
|
#include <stddef.h> /* for wchar_t */
|
||||||
#include <stdio.h> /* For FILE * */
|
#include <stdio.h> /* For FILE * */
|
||||||
|
#include <time.h> /* For time_t */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: archive.h is for use outside of libarchive; the configuration
|
* Note: archive.h is for use outside of libarchive; the configuration
|
||||||
@ -41,29 +52,53 @@
|
|||||||
*/
|
*/
|
||||||
#if defined(__BORLANDC__) && __BORLANDC__ >= 0x560
|
#if defined(__BORLANDC__) && __BORLANDC__ >= 0x560
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS)
|
#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS) && !defined(__osf__)
|
||||||
# include <inttypes.h>
|
# include <inttypes.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get appropriate definitions of standard POSIX-style types. */
|
/* Get appropriate definitions of 64-bit integer */
|
||||||
/* These should match the types used in 'struct stat' */
|
#if !defined(__LA_INT64_T_DEFINED)
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
/* Older code relied on the __LA_INT64_T macro; after 4.0 we'll switch to the typedef exclusively. */
|
||||||
# define __LA_INT64_T __int64
|
# if ARCHIVE_VERSION_NUMBER < 4000000
|
||||||
# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
|
#define __LA_INT64_T la_int64_t
|
||||||
# define __LA_SSIZE_T ssize_t
|
# endif
|
||||||
# elif defined(_WIN64)
|
#define __LA_INT64_T_DEFINED
|
||||||
# define __LA_SSIZE_T __int64
|
# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
|
||||||
|
typedef __int64 la_int64_t;
|
||||||
# else
|
# else
|
||||||
# define __LA_SSIZE_T long
|
# include <unistd.h> /* ssize_t */
|
||||||
|
# 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
|
# endif
|
||||||
# else
|
# else
|
||||||
# include <unistd.h> /* ssize_t */
|
# include <unistd.h> /* ssize_t */
|
||||||
# if defined(_SCO_DS)
|
typedef ssize_t la_ssize_t;
|
||||||
# define __LA_INT64_T long long
|
|
||||||
# else
|
|
||||||
# define __LA_INT64_T int64_t
|
|
||||||
# endif
|
# endif
|
||||||
# define __LA_SSIZE_T ssize_t
|
#endif
|
||||||
|
|
||||||
|
/* Large file support for Android */
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include "android_lf.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -115,24 +150,34 @@ extern "C" {
|
|||||||
* header and library are very different, you should expect some
|
* header and library are very different, you should expect some
|
||||||
* strangeness. Don't do that.
|
* strangeness. Don't do that.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* The version number is expressed as a single integer that makes it
|
|
||||||
* easy to compare versions at build time: for version a.b.c, the
|
|
||||||
* version number is printf("%d%03d%03d",a,b,c). For example, if you
|
|
||||||
* know your application requires version 2.12.108 or later, you can
|
|
||||||
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
|
|
||||||
*/
|
|
||||||
/* Note: Compiler will complain if this does not match archive_entry.h! */
|
|
||||||
#define ARCHIVE_VERSION_NUMBER 3001002
|
|
||||||
__LA_DECL int archive_version_number(void);
|
__LA_DECL int archive_version_number(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Textual name/version of the library, useful for version displays.
|
* Textual name/version of the library, useful for version displays.
|
||||||
*/
|
*/
|
||||||
#define ARCHIVE_VERSION_STRING "libarchive 3.1.2"
|
#define ARCHIVE_VERSION_ONLY_STRING "3.2.0"
|
||||||
|
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
|
||||||
__LA_DECL const char * archive_version_string(void);
|
__LA_DECL const char * archive_version_string(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Detailed textual name/version of the library and its dependencies.
|
||||||
|
* This has the form:
|
||||||
|
* "libarchive x.y.z zlib/a.b.c liblzma/d.e.f ... etc ..."
|
||||||
|
* the list of libraries described here will vary depending on how
|
||||||
|
* libarchive was compiled.
|
||||||
|
*/
|
||||||
|
__LA_DECL const char * archive_version_details(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns NULL if libarchive was compiled without the associated library.
|
||||||
|
* Otherwise, returns the version number that libarchive was compiled
|
||||||
|
* against.
|
||||||
|
*/
|
||||||
|
__LA_DECL const char * archive_zlib_version(void);
|
||||||
|
__LA_DECL const char * archive_liblzma_version(void);
|
||||||
|
__LA_DECL const char * archive_bzlib_version(void);
|
||||||
|
__LA_DECL const char * archive_liblz4_version(void);
|
||||||
|
|
||||||
/* Declare our basic types. */
|
/* Declare our basic types. */
|
||||||
struct archive;
|
struct archive;
|
||||||
struct archive_entry;
|
struct archive_entry;
|
||||||
@ -173,7 +218,7 @@ struct archive_entry;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Returns pointer and size of next block of data from archive. */
|
/* Returns pointer and size of next block of data from archive. */
|
||||||
typedef __LA_SSIZE_T archive_read_callback(struct archive *,
|
typedef la_ssize_t archive_read_callback(struct archive *,
|
||||||
void *_client_data, const void **_buffer);
|
void *_client_data, const void **_buffer);
|
||||||
|
|
||||||
/* Skips at most request bytes from archive and returns the skipped amount.
|
/* Skips at most request bytes from archive and returns the skipped amount.
|
||||||
@ -181,18 +226,18 @@ typedef __LA_SSIZE_T archive_read_callback(struct archive *,
|
|||||||
* If you do skip fewer bytes than requested, libarchive will invoke your
|
* If you do skip fewer bytes than requested, libarchive will invoke your
|
||||||
* read callback and discard data as necessary to make up the full skip.
|
* read callback and discard data as necessary to make up the full skip.
|
||||||
*/
|
*/
|
||||||
typedef __LA_INT64_T archive_skip_callback(struct archive *,
|
typedef la_int64_t archive_skip_callback(struct archive *,
|
||||||
void *_client_data, __LA_INT64_T request);
|
void *_client_data, la_int64_t request);
|
||||||
|
|
||||||
/* Seeks to specified location in the file and returns the position.
|
/* Seeks to specified location in the file and returns the position.
|
||||||
* Whence values are SEEK_SET, SEEK_CUR, SEEK_END from stdio.h.
|
* Whence values are SEEK_SET, SEEK_CUR, SEEK_END from stdio.h.
|
||||||
* Return ARCHIVE_FATAL if the seek fails for any reason.
|
* Return ARCHIVE_FATAL if the seek fails for any reason.
|
||||||
*/
|
*/
|
||||||
typedef __LA_INT64_T archive_seek_callback(struct archive *,
|
typedef la_int64_t archive_seek_callback(struct archive *,
|
||||||
void *_client_data, __LA_INT64_T offset, int whence);
|
void *_client_data, la_int64_t offset, int whence);
|
||||||
|
|
||||||
/* Returns size actually written, zero on EOF, -1 on error. */
|
/* Returns size actually written, zero on EOF, -1 on error. */
|
||||||
typedef __LA_SSIZE_T archive_write_callback(struct archive *,
|
typedef la_ssize_t archive_write_callback(struct archive *,
|
||||||
void *_client_data,
|
void *_client_data,
|
||||||
const void *_buffer, size_t _length);
|
const void *_buffer, size_t _length);
|
||||||
|
|
||||||
@ -207,6 +252,13 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
|
|||||||
typedef int archive_switch_callback(struct archive *, void *_client_data1,
|
typedef int archive_switch_callback(struct archive *, void *_client_data1,
|
||||||
void *_client_data2);
|
void *_client_data2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a passphrase used for encryption or decryption, NULL on nothing
|
||||||
|
* to do and give it up.
|
||||||
|
*/
|
||||||
|
typedef const char *archive_passphrase_callback(struct archive *,
|
||||||
|
void *_client_data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Codes to identify various stream filters.
|
* Codes to identify various stream filters.
|
||||||
*/
|
*/
|
||||||
@ -223,6 +275,7 @@ typedef int archive_switch_callback(struct archive *, void *_client_data1,
|
|||||||
#define ARCHIVE_FILTER_LRZIP 10
|
#define ARCHIVE_FILTER_LRZIP 10
|
||||||
#define ARCHIVE_FILTER_LZOP 11
|
#define ARCHIVE_FILTER_LZOP 11
|
||||||
#define ARCHIVE_FILTER_GRZIP 12
|
#define ARCHIVE_FILTER_GRZIP 12
|
||||||
|
#define ARCHIVE_FILTER_LZ4 13
|
||||||
|
|
||||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||||
#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE
|
#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE
|
||||||
@ -284,6 +337,31 @@ typedef int archive_switch_callback(struct archive *, void *_client_data1,
|
|||||||
#define ARCHIVE_FORMAT_CAB 0xC0000
|
#define ARCHIVE_FORMAT_CAB 0xC0000
|
||||||
#define ARCHIVE_FORMAT_RAR 0xD0000
|
#define ARCHIVE_FORMAT_RAR 0xD0000
|
||||||
#define ARCHIVE_FORMAT_7ZIP 0xE0000
|
#define ARCHIVE_FORMAT_7ZIP 0xE0000
|
||||||
|
#define ARCHIVE_FORMAT_WARC 0xF0000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Codes returned by archive_read_format_capabilities().
|
||||||
|
*
|
||||||
|
* This list can be extended with values between 0 and 0xffff.
|
||||||
|
* The original purpose of this list was to let different archive
|
||||||
|
* format readers expose their general capabilities in terms of
|
||||||
|
* encryption.
|
||||||
|
*/
|
||||||
|
#define ARCHIVE_READ_FORMAT_CAPS_NONE (0) /* no special capabilities */
|
||||||
|
#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA (1<<0) /* reader can detect encrypted data */
|
||||||
|
#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA (1<<1) /* reader can detect encryptable metadata (pathname, mtime, etc.) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Codes returned by archive_read_has_encrypted_entries().
|
||||||
|
*
|
||||||
|
* In case the archive does not support encryption detection at all
|
||||||
|
* ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned. If the reader
|
||||||
|
* for some other reason (e.g. not enough bytes read) cannot say if
|
||||||
|
* there are encrypted entries, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW
|
||||||
|
* is returned.
|
||||||
|
*/
|
||||||
|
#define ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED -2
|
||||||
|
#define ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW -1
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Basic outline for reading an archive:
|
* Basic outline for reading an archive:
|
||||||
@ -342,6 +420,7 @@ __LA_DECL int archive_read_support_filter_compress(struct archive *);
|
|||||||
__LA_DECL int archive_read_support_filter_gzip(struct archive *);
|
__LA_DECL int archive_read_support_filter_gzip(struct archive *);
|
||||||
__LA_DECL int archive_read_support_filter_grzip(struct archive *);
|
__LA_DECL int archive_read_support_filter_grzip(struct archive *);
|
||||||
__LA_DECL int archive_read_support_filter_lrzip(struct archive *);
|
__LA_DECL int archive_read_support_filter_lrzip(struct archive *);
|
||||||
|
__LA_DECL int archive_read_support_filter_lz4(struct archive *);
|
||||||
__LA_DECL int archive_read_support_filter_lzip(struct archive *);
|
__LA_DECL int archive_read_support_filter_lzip(struct archive *);
|
||||||
__LA_DECL int archive_read_support_filter_lzma(struct archive *);
|
__LA_DECL int archive_read_support_filter_lzma(struct archive *);
|
||||||
__LA_DECL int archive_read_support_filter_lzop(struct archive *);
|
__LA_DECL int archive_read_support_filter_lzop(struct archive *);
|
||||||
@ -369,8 +448,17 @@ __LA_DECL int archive_read_support_format_mtree(struct archive *);
|
|||||||
__LA_DECL int archive_read_support_format_rar(struct archive *);
|
__LA_DECL int archive_read_support_format_rar(struct archive *);
|
||||||
__LA_DECL int archive_read_support_format_raw(struct archive *);
|
__LA_DECL int archive_read_support_format_raw(struct archive *);
|
||||||
__LA_DECL int archive_read_support_format_tar(struct archive *);
|
__LA_DECL int archive_read_support_format_tar(struct archive *);
|
||||||
|
__LA_DECL int archive_read_support_format_warc(struct archive *);
|
||||||
__LA_DECL int archive_read_support_format_xar(struct archive *);
|
__LA_DECL int archive_read_support_format_xar(struct archive *);
|
||||||
|
/* archive_read_support_format_zip() enables both streamable and seekable
|
||||||
|
* zip readers. */
|
||||||
__LA_DECL int archive_read_support_format_zip(struct archive *);
|
__LA_DECL int archive_read_support_format_zip(struct archive *);
|
||||||
|
/* Reads Zip archives as stream from beginning to end. Doesn't
|
||||||
|
* correctly handle SFX ZIP files or ZIP archives that have been modified
|
||||||
|
* in-place. */
|
||||||
|
__LA_DECL int archive_read_support_format_zip_streamable(struct archive *);
|
||||||
|
/* Reads starting from central directory; requires seekable input. */
|
||||||
|
__LA_DECL int archive_read_support_format_zip_seekable(struct archive *);
|
||||||
|
|
||||||
/* Functions to manually set the format and filters to be used. This is
|
/* Functions to manually set the format and filters to be used. This is
|
||||||
* useful to bypass the bidding process when the format and filters to use
|
* useful to bypass the bidding process when the format and filters to use
|
||||||
@ -441,9 +529,9 @@ __LA_DECL int archive_read_open_file(struct archive *,
|
|||||||
const char *_filename, size_t _block_size) __LA_DEPRECATED;
|
const char *_filename, size_t _block_size) __LA_DEPRECATED;
|
||||||
/* Read an archive that's stored in memory. */
|
/* Read an archive that's stored in memory. */
|
||||||
__LA_DECL int archive_read_open_memory(struct archive *,
|
__LA_DECL int archive_read_open_memory(struct archive *,
|
||||||
void * buff, size_t size);
|
const void * buff, size_t size);
|
||||||
/* A more involved version that is only used for internal testing. */
|
/* A more involved version that is only used for internal testing. */
|
||||||
__LA_DECL int archive_read_open_memory2(struct archive *a, void *buff,
|
__LA_DECL int archive_read_open_memory2(struct archive *a, const void *buff,
|
||||||
size_t size, size_t read_size);
|
size_t size, size_t read_size);
|
||||||
/* Read an archive that's already open, using the file descriptor. */
|
/* Read an archive that's already open, using the file descriptor. */
|
||||||
__LA_DECL int archive_read_open_fd(struct archive *, int _fd,
|
__LA_DECL int archive_read_open_fd(struct archive *, int _fd,
|
||||||
@ -464,14 +552,40 @@ __LA_DECL int archive_read_next_header2(struct archive *,
|
|||||||
* Retrieve the byte offset in UNCOMPRESSED data where last-read
|
* Retrieve the byte offset in UNCOMPRESSED data where last-read
|
||||||
* header started.
|
* header started.
|
||||||
*/
|
*/
|
||||||
__LA_DECL __LA_INT64_T archive_read_header_position(struct archive *);
|
__LA_DECL la_int64_t archive_read_header_position(struct archive *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if the archive contains at least one encrypted entry.
|
||||||
|
* If the archive format not support encryption at all
|
||||||
|
* ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
|
||||||
|
* If for any other reason (e.g. not enough data read so far)
|
||||||
|
* we cannot say whether there are encrypted entries, then
|
||||||
|
* ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
|
||||||
|
* In general, this function will return values below zero when the
|
||||||
|
* reader is uncertain or totally uncapable of encryption support.
|
||||||
|
* When this function returns 0 you can be sure that the reader
|
||||||
|
* supports encryption detection but no encrypted entries have
|
||||||
|
* been found yet.
|
||||||
|
*
|
||||||
|
* NOTE: If the metadata/header of an archive is also encrypted, you
|
||||||
|
* cannot rely on the number of encrypted entries. That is why this
|
||||||
|
* function does not return the number of encrypted entries but#
|
||||||
|
* just shows that there are some.
|
||||||
|
*/
|
||||||
|
__LA_DECL int archive_read_has_encrypted_entries(struct archive *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a bitmask of capabilities that are supported by the archive format reader.
|
||||||
|
* If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
|
||||||
|
*/
|
||||||
|
__LA_DECL int archive_read_format_capabilities(struct archive *);
|
||||||
|
|
||||||
/* Read data from the body of an entry. Similar to read(2). */
|
/* Read data from the body of an entry. Similar to read(2). */
|
||||||
__LA_DECL __LA_SSIZE_T archive_read_data(struct archive *,
|
__LA_DECL la_ssize_t archive_read_data(struct archive *,
|
||||||
void *, size_t);
|
void *, size_t);
|
||||||
|
|
||||||
/* Seek within the body of an entry. Similar to lseek(2). */
|
/* Seek within the body of an entry. Similar to lseek(2). */
|
||||||
__LA_DECL __LA_INT64_T archive_seek_data(struct archive *, __LA_INT64_T, int);
|
__LA_DECL la_int64_t archive_seek_data(struct archive *, la_int64_t, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A zero-copy version of archive_read_data that also exposes the file offset
|
* A zero-copy version of archive_read_data that also exposes the file offset
|
||||||
@ -480,7 +594,7 @@ __LA_DECL __LA_INT64_T archive_seek_data(struct archive *, __LA_INT64_T, int);
|
|||||||
* be strictly increasing and that returned blocks will not overlap.
|
* be strictly increasing and that returned blocks will not overlap.
|
||||||
*/
|
*/
|
||||||
__LA_DECL int archive_read_data_block(struct archive *a,
|
__LA_DECL int archive_read_data_block(struct archive *a,
|
||||||
const void **buff, size_t *size, __LA_INT64_T *offset);
|
const void **buff, size_t *size, la_int64_t *offset);
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Some convenience functions that are built on archive_read_data:
|
* Some convenience functions that are built on archive_read_data:
|
||||||
@ -510,6 +624,14 @@ __LA_DECL int archive_read_set_option(struct archive *_a,
|
|||||||
__LA_DECL int archive_read_set_options(struct archive *_a,
|
__LA_DECL int archive_read_set_options(struct archive *_a,
|
||||||
const char *opts);
|
const char *opts);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a decryption passphrase.
|
||||||
|
*/
|
||||||
|
__LA_DECL int archive_read_add_passphrase(struct archive *, const char *);
|
||||||
|
__LA_DECL int archive_read_set_passphrase_callback(struct archive *,
|
||||||
|
void *client_data, archive_passphrase_callback *);
|
||||||
|
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Convenience function to recreate the current entry (whose header
|
* Convenience function to recreate the current entry (whose header
|
||||||
* has just been read) on disk.
|
* has just been read) on disk.
|
||||||
@ -562,6 +684,10 @@ __LA_DECL int archive_read_set_options(struct archive *_a,
|
|||||||
/* Default: Do not use HFS+ compression if it was not compressed. */
|
/* Default: Do not use HFS+ compression if it was not compressed. */
|
||||||
/* This has no effect except on Mac OS v10.6 or later. */
|
/* This has no effect except on Mac OS v10.6 or later. */
|
||||||
#define ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED (0x8000)
|
#define ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED (0x8000)
|
||||||
|
/* Default: Do not reject entries with absolute paths */
|
||||||
|
#define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000)
|
||||||
|
/* Default: Do not clear no-change flags when unlinking object */
|
||||||
|
#define ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS (0x20000)
|
||||||
|
|
||||||
__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
|
__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
|
||||||
int flags);
|
int flags);
|
||||||
@ -573,7 +699,7 @@ __LA_DECL void archive_read_extract_set_progress_callback(struct archive *,
|
|||||||
/* Record the dev/ino of a file that will not be written. This is
|
/* Record the dev/ino of a file that will not be written. This is
|
||||||
* generally set to the dev/ino of the archive being read. */
|
* generally set to the dev/ino of the archive being read. */
|
||||||
__LA_DECL void archive_read_extract_set_skip_file(struct archive *,
|
__LA_DECL void archive_read_extract_set_skip_file(struct archive *,
|
||||||
__LA_INT64_T, __LA_INT64_T);
|
la_int64_t, la_int64_t);
|
||||||
|
|
||||||
/* Close the file and release most resources. */
|
/* Close the file and release most resources. */
|
||||||
__LA_DECL int archive_read_close(struct archive *);
|
__LA_DECL int archive_read_close(struct archive *);
|
||||||
@ -612,7 +738,7 @@ __LA_DECL int archive_write_get_bytes_in_last_block(struct archive *);
|
|||||||
/* The dev/ino of a file that won't be archived. This is used
|
/* The dev/ino of a file that won't be archived. This is used
|
||||||
* to avoid recursively adding an archive to itself. */
|
* to avoid recursively adding an archive to itself. */
|
||||||
__LA_DECL int archive_write_set_skip_file(struct archive *,
|
__LA_DECL int archive_write_set_skip_file(struct archive *,
|
||||||
__LA_INT64_T, __LA_INT64_T);
|
la_int64_t, la_int64_t);
|
||||||
|
|
||||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||||
__LA_DECL int archive_write_set_compression_bzip2(struct archive *)
|
__LA_DECL int archive_write_set_compression_bzip2(struct archive *)
|
||||||
@ -643,6 +769,7 @@ __LA_DECL int archive_write_add_filter_compress(struct archive *);
|
|||||||
__LA_DECL int archive_write_add_filter_grzip(struct archive *);
|
__LA_DECL int archive_write_add_filter_grzip(struct archive *);
|
||||||
__LA_DECL int archive_write_add_filter_gzip(struct archive *);
|
__LA_DECL int archive_write_add_filter_gzip(struct archive *);
|
||||||
__LA_DECL int archive_write_add_filter_lrzip(struct archive *);
|
__LA_DECL int archive_write_add_filter_lrzip(struct archive *);
|
||||||
|
__LA_DECL int archive_write_add_filter_lz4(struct archive *);
|
||||||
__LA_DECL int archive_write_add_filter_lzip(struct archive *);
|
__LA_DECL int archive_write_add_filter_lzip(struct archive *);
|
||||||
__LA_DECL int archive_write_add_filter_lzma(struct archive *);
|
__LA_DECL int archive_write_add_filter_lzma(struct archive *);
|
||||||
__LA_DECL int archive_write_add_filter_lzop(struct archive *);
|
__LA_DECL int archive_write_add_filter_lzop(struct archive *);
|
||||||
@ -670,12 +797,16 @@ __LA_DECL int archive_write_set_format_mtree_classic(struct archive *);
|
|||||||
/* TODO: int archive_write_set_format_old_tar(struct archive *); */
|
/* TODO: int archive_write_set_format_old_tar(struct archive *); */
|
||||||
__LA_DECL int archive_write_set_format_pax(struct archive *);
|
__LA_DECL int archive_write_set_format_pax(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
|
__LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
|
||||||
|
__LA_DECL int archive_write_set_format_raw(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_shar(struct archive *);
|
__LA_DECL int archive_write_set_format_shar(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_shar_dump(struct archive *);
|
__LA_DECL int archive_write_set_format_shar_dump(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_ustar(struct archive *);
|
__LA_DECL int archive_write_set_format_ustar(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_v7tar(struct archive *);
|
__LA_DECL int archive_write_set_format_v7tar(struct archive *);
|
||||||
|
__LA_DECL int archive_write_set_format_warc(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_xar(struct archive *);
|
__LA_DECL int archive_write_set_format_xar(struct archive *);
|
||||||
__LA_DECL int archive_write_set_format_zip(struct archive *);
|
__LA_DECL int archive_write_set_format_zip(struct archive *);
|
||||||
|
__LA_DECL int archive_write_set_format_filter_by_ext(struct archive *a, const char *filename);
|
||||||
|
__LA_DECL int archive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext);
|
||||||
__LA_DECL int archive_write_zip_set_compression_deflate(struct archive *);
|
__LA_DECL int archive_write_zip_set_compression_deflate(struct archive *);
|
||||||
__LA_DECL int archive_write_zip_set_compression_store(struct archive *);
|
__LA_DECL int archive_write_zip_set_compression_store(struct archive *);
|
||||||
__LA_DECL int archive_write_open(struct archive *, void *,
|
__LA_DECL int archive_write_open(struct archive *, void *,
|
||||||
@ -700,12 +831,12 @@ __LA_DECL int archive_write_open_memory(struct archive *,
|
|||||||
*/
|
*/
|
||||||
__LA_DECL int archive_write_header(struct archive *,
|
__LA_DECL int archive_write_header(struct archive *,
|
||||||
struct archive_entry *);
|
struct archive_entry *);
|
||||||
__LA_DECL __LA_SSIZE_T archive_write_data(struct archive *,
|
__LA_DECL la_ssize_t archive_write_data(struct archive *,
|
||||||
const void *, size_t);
|
const void *, size_t);
|
||||||
|
|
||||||
/* This interface is currently only available for archive_write_disk handles. */
|
/* This interface is currently only available for archive_write_disk handles. */
|
||||||
__LA_DECL __LA_SSIZE_T archive_write_data_block(struct archive *,
|
__LA_DECL la_ssize_t archive_write_data_block(struct archive *,
|
||||||
const void *, size_t, __LA_INT64_T);
|
const void *, size_t, la_int64_t);
|
||||||
|
|
||||||
__LA_DECL int archive_write_finish_entry(struct archive *);
|
__LA_DECL int archive_write_finish_entry(struct archive *);
|
||||||
__LA_DECL int archive_write_close(struct archive *);
|
__LA_DECL int archive_write_close(struct archive *);
|
||||||
@ -740,6 +871,13 @@ __LA_DECL int archive_write_set_option(struct archive *_a,
|
|||||||
__LA_DECL int archive_write_set_options(struct archive *_a,
|
__LA_DECL int archive_write_set_options(struct archive *_a,
|
||||||
const char *opts);
|
const char *opts);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a encryption passphrase.
|
||||||
|
*/
|
||||||
|
__LA_DECL int archive_write_set_passphrase(struct archive *_a, const char *p);
|
||||||
|
__LA_DECL int archive_write_set_passphrase_callback(struct archive *,
|
||||||
|
void *client_data, archive_passphrase_callback *);
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* ARCHIVE_WRITE_DISK API
|
* ARCHIVE_WRITE_DISK API
|
||||||
*
|
*
|
||||||
@ -759,7 +897,7 @@ __LA_DECL int archive_write_set_options(struct archive *_a,
|
|||||||
__LA_DECL struct archive *archive_write_disk_new(void);
|
__LA_DECL struct archive *archive_write_disk_new(void);
|
||||||
/* This file will not be overwritten. */
|
/* This file will not be overwritten. */
|
||||||
__LA_DECL int archive_write_disk_set_skip_file(struct archive *,
|
__LA_DECL int archive_write_disk_set_skip_file(struct archive *,
|
||||||
__LA_INT64_T, __LA_INT64_T);
|
la_int64_t, la_int64_t);
|
||||||
/* Set flags to control how the next item gets created.
|
/* Set flags to control how the next item gets created.
|
||||||
* This accepts a bitmask of ARCHIVE_EXTRACT_XXX flags defined above. */
|
* This accepts a bitmask of ARCHIVE_EXTRACT_XXX flags defined above. */
|
||||||
__LA_DECL int archive_write_disk_set_options(struct archive *,
|
__LA_DECL int archive_write_disk_set_options(struct archive *,
|
||||||
@ -789,14 +927,14 @@ __LA_DECL int archive_write_disk_set_standard_lookup(struct archive *);
|
|||||||
*/
|
*/
|
||||||
__LA_DECL int archive_write_disk_set_group_lookup(struct archive *,
|
__LA_DECL int archive_write_disk_set_group_lookup(struct archive *,
|
||||||
void * /* private_data */,
|
void * /* private_data */,
|
||||||
__LA_INT64_T (*)(void *, const char *, __LA_INT64_T),
|
la_int64_t (*)(void *, const char *, la_int64_t),
|
||||||
void (* /* cleanup */)(void *));
|
void (* /* cleanup */)(void *));
|
||||||
__LA_DECL int archive_write_disk_set_user_lookup(struct archive *,
|
__LA_DECL int archive_write_disk_set_user_lookup(struct archive *,
|
||||||
void * /* private_data */,
|
void * /* private_data */,
|
||||||
__LA_INT64_T (*)(void *, const char *, __LA_INT64_T),
|
la_int64_t (*)(void *, const char *, la_int64_t),
|
||||||
void (* /* cleanup */)(void *));
|
void (* /* cleanup */)(void *));
|
||||||
__LA_DECL __LA_INT64_T archive_write_disk_gid(struct archive *, const char *, __LA_INT64_T);
|
__LA_DECL la_int64_t archive_write_disk_gid(struct archive *, const char *, la_int64_t);
|
||||||
__LA_DECL __LA_INT64_T archive_write_disk_uid(struct archive *, const char *, __LA_INT64_T);
|
__LA_DECL la_int64_t archive_write_disk_uid(struct archive *, const char *, la_int64_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ARCHIVE_READ_DISK API
|
* ARCHIVE_READ_DISK API
|
||||||
@ -817,19 +955,19 @@ __LA_DECL int archive_read_disk_entry_from_file(struct archive *,
|
|||||||
struct archive_entry *, int /* fd */, const struct stat *);
|
struct archive_entry *, int /* fd */, const struct stat *);
|
||||||
/* Look up gname for gid or uname for uid. */
|
/* Look up gname for gid or uname for uid. */
|
||||||
/* Default implementations are very, very stupid. */
|
/* Default implementations are very, very stupid. */
|
||||||
__LA_DECL const char *archive_read_disk_gname(struct archive *, __LA_INT64_T);
|
__LA_DECL const char *archive_read_disk_gname(struct archive *, la_int64_t);
|
||||||
__LA_DECL const char *archive_read_disk_uname(struct archive *, __LA_INT64_T);
|
__LA_DECL const char *archive_read_disk_uname(struct archive *, la_int64_t);
|
||||||
/* "Standard" implementation uses getpwuid_r, getgrgid_r and caches the
|
/* "Standard" implementation uses getpwuid_r, getgrgid_r and caches the
|
||||||
* results for performance. */
|
* results for performance. */
|
||||||
__LA_DECL int archive_read_disk_set_standard_lookup(struct archive *);
|
__LA_DECL int archive_read_disk_set_standard_lookup(struct archive *);
|
||||||
/* You can install your own lookups if you like. */
|
/* You can install your own lookups if you like. */
|
||||||
__LA_DECL int archive_read_disk_set_gname_lookup(struct archive *,
|
__LA_DECL int archive_read_disk_set_gname_lookup(struct archive *,
|
||||||
void * /* private_data */,
|
void * /* private_data */,
|
||||||
const char *(* /* lookup_fn */)(void *, __LA_INT64_T),
|
const char *(* /* lookup_fn */)(void *, la_int64_t),
|
||||||
void (* /* cleanup_fn */)(void *));
|
void (* /* cleanup_fn */)(void *));
|
||||||
__LA_DECL int archive_read_disk_set_uname_lookup(struct archive *,
|
__LA_DECL int archive_read_disk_set_uname_lookup(struct archive *,
|
||||||
void * /* private_data */,
|
void * /* private_data */,
|
||||||
const char *(* /* lookup_fn */)(void *, __LA_INT64_T),
|
const char *(* /* lookup_fn */)(void *, la_int64_t),
|
||||||
void (* /* cleanup_fn */)(void *));
|
void (* /* cleanup_fn */)(void *));
|
||||||
/* Start traversal. */
|
/* Start traversal. */
|
||||||
__LA_DECL int archive_read_disk_open(struct archive *, const char *);
|
__LA_DECL int archive_read_disk_open(struct archive *, const char *);
|
||||||
@ -859,8 +997,10 @@ __LA_DECL int archive_read_disk_set_atime_restored(struct archive *);
|
|||||||
/* Default: Skip a mac resource fork file whose prefix is "._" because of
|
/* Default: Skip a mac resource fork file whose prefix is "._" because of
|
||||||
* using copyfile. */
|
* using copyfile. */
|
||||||
#define ARCHIVE_READDISK_MAC_COPYFILE (0x0004)
|
#define ARCHIVE_READDISK_MAC_COPYFILE (0x0004)
|
||||||
/* Default: Do not traverse mount points. */
|
/* Default: Traverse mount points. */
|
||||||
#define ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS (0x0008)
|
#define ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS (0x0008)
|
||||||
|
/* Default: Xattrs are read from disk. */
|
||||||
|
#define ARCHIVE_READDISK_NO_XATTR (0x0010)
|
||||||
|
|
||||||
__LA_DECL int archive_read_disk_set_behavior(struct archive *,
|
__LA_DECL int archive_read_disk_set_behavior(struct archive *,
|
||||||
int flags);
|
int flags);
|
||||||
@ -879,6 +1019,10 @@ __LA_DECL int archive_read_disk_set_metadata_filter_callback(struct archive *,
|
|||||||
int (*_metadata_filter_func)(struct archive *, void *,
|
int (*_metadata_filter_func)(struct archive *, void *,
|
||||||
struct archive_entry *), void *_client_data);
|
struct archive_entry *), void *_client_data);
|
||||||
|
|
||||||
|
/* Simplified cleanup interface;
|
||||||
|
* This calls archive_read_free() or archive_write_free() as needed. */
|
||||||
|
__LA_DECL int archive_free(struct archive *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accessor functions to read/set various information in
|
* Accessor functions to read/set various information in
|
||||||
* the struct archive object:
|
* the struct archive object:
|
||||||
@ -889,7 +1033,7 @@ __LA_DECL int archive_read_disk_set_metadata_filter_callback(struct archive *,
|
|||||||
* last filter, which is always the pseudo-filter that wraps the
|
* last filter, which is always the pseudo-filter that wraps the
|
||||||
* client callbacks. */
|
* client callbacks. */
|
||||||
__LA_DECL int archive_filter_count(struct archive *);
|
__LA_DECL int archive_filter_count(struct archive *);
|
||||||
__LA_DECL __LA_INT64_T archive_filter_bytes(struct archive *, int);
|
__LA_DECL la_int64_t archive_filter_bytes(struct archive *, int);
|
||||||
__LA_DECL int archive_filter_code(struct archive *, int);
|
__LA_DECL int archive_filter_code(struct archive *, int);
|
||||||
__LA_DECL const char * archive_filter_name(struct archive *, int);
|
__LA_DECL const char * archive_filter_name(struct archive *, int);
|
||||||
|
|
||||||
@ -897,10 +1041,10 @@ __LA_DECL const char * archive_filter_name(struct archive *, int);
|
|||||||
/* These don't properly handle multiple filters, so are deprecated and
|
/* These don't properly handle multiple filters, so are deprecated and
|
||||||
* will eventually be removed. */
|
* will eventually be removed. */
|
||||||
/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, -1); */
|
/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, -1); */
|
||||||
__LA_DECL __LA_INT64_T archive_position_compressed(struct archive *)
|
__LA_DECL la_int64_t archive_position_compressed(struct archive *)
|
||||||
__LA_DEPRECATED;
|
__LA_DEPRECATED;
|
||||||
/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, 0); */
|
/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, 0); */
|
||||||
__LA_DECL __LA_INT64_T archive_position_uncompressed(struct archive *)
|
__LA_DECL la_int64_t archive_position_uncompressed(struct archive *)
|
||||||
__LA_DEPRECATED;
|
__LA_DEPRECATED;
|
||||||
/* As of libarchive 3.0, this is an alias for archive_filter_name(a, 0); */
|
/* As of libarchive 3.0, this is an alias for archive_filter_name(a, 0); */
|
||||||
__LA_DECL const char *archive_compression_name(struct archive *)
|
__LA_DECL const char *archive_compression_name(struct archive *)
|
||||||
@ -1016,8 +1160,8 @@ __LA_DECL int archive_match_exclude_entry(struct archive *,
|
|||||||
__LA_DECL int archive_match_owner_excluded(struct archive *,
|
__LA_DECL int archive_match_owner_excluded(struct archive *,
|
||||||
struct archive_entry *);
|
struct archive_entry *);
|
||||||
/* Add inclusion uid, gid, uname and gname. */
|
/* Add inclusion uid, gid, uname and gname. */
|
||||||
__LA_DECL int archive_match_include_uid(struct archive *, __LA_INT64_T);
|
__LA_DECL int archive_match_include_uid(struct archive *, la_int64_t);
|
||||||
__LA_DECL int archive_match_include_gid(struct archive *, __LA_INT64_T);
|
__LA_DECL int archive_match_include_gid(struct archive *, la_int64_t);
|
||||||
__LA_DECL int archive_match_include_uname(struct archive *, const char *);
|
__LA_DECL int archive_match_include_uname(struct archive *, const char *);
|
||||||
__LA_DECL int archive_match_include_uname_w(struct archive *,
|
__LA_DECL int archive_match_include_uname_w(struct archive *,
|
||||||
const wchar_t *);
|
const wchar_t *);
|
||||||
@ -1025,6 +1169,10 @@ __LA_DECL int archive_match_include_gname(struct archive *, const char *);
|
|||||||
__LA_DECL int archive_match_include_gname_w(struct archive *,
|
__LA_DECL int archive_match_include_gname_w(struct archive *,
|
||||||
const wchar_t *);
|
const wchar_t *);
|
||||||
|
|
||||||
|
/* Utility functions */
|
||||||
|
/* Convenience function to sort a NULL terminated list of strings */
|
||||||
|
__LA_DECL int archive_utility_string_sort(char **);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1032,9 +1180,4 @@ __LA_DECL int archive_match_include_gname_w(struct archive *,
|
|||||||
/* These are meaningless outside of this header. */
|
/* These are meaningless outside of this header. */
|
||||||
#undef __LA_DECL
|
#undef __LA_DECL
|
||||||
|
|
||||||
/* These need to remain defined because they're used in the
|
|
||||||
* callback type definitions. XXX Fix this. This is ugly. XXX */
|
|
||||||
/* #undef __LA_INT64_T */
|
|
||||||
/* #undef __LA_SSIZE_T */
|
|
||||||
|
|
||||||
#endif /* !ARCHIVE_H_INCLUDED */
|
#endif /* !ARCHIVE_H_INCLUDED */
|
||||||
|
448
contrib/libarchive/libarchive/archive_cryptor.c
Normal file
448
contrib/libarchive/libarchive/archive_cryptor.c
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
/*-
|
||||||
|
* 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_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)
|
||||||
|
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_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)
|
||||||
|
{
|
||||||
|
|
||||||
|
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;
|
||||||
|
EVP_CIPHER_CTX_init(&ctx->ctx);
|
||||||
|
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_cleanup(&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,
|
||||||
|
};
|
163
contrib/libarchive/libarchive/archive_cryptor_private.h
Normal file
163
contrib/libarchive/libarchive/archive_cryptor_private.h
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*-
|
||||||
|
* 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 __LIBARCHIVE_BUILD
|
||||||
|
#error This header is only to be used internally to libarchive.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
|
||||||
|
#define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On systems that do not support any recognized crypto libraries,
|
||||||
|
* the archive_cryptor.c file will normally define no usable symbols.
|
||||||
|
*
|
||||||
|
* But some compilers and linkers choke on empty object files, so
|
||||||
|
* define a public symbol that will always exist. This could
|
||||||
|
* be removed someday if this file gains another always-present
|
||||||
|
* symbol definition.
|
||||||
|
*/
|
||||||
|
int __libarchive_cryptor_build_hack(void);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
# include <AvailabilityMacros.h>
|
||||||
|
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||||
|
# 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_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 <openssl/evp.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
|
@ -28,7 +28,7 @@
|
|||||||
#include "archive_platform.h"
|
#include "archive_platform.h"
|
||||||
|
|
||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
#include "archive_crypto_private.h"
|
#include "archive_digest_private.h"
|
||||||
|
|
||||||
/* In particular, force the configure probe to break if it tries
|
/* In particular, force the configure probe to break if it tries
|
||||||
* to test a combination of OpenSSL and libmd. */
|
* to test a combination of OpenSSL and libmd. */
|
||||||
@ -1216,8 +1216,8 @@ __archive_stub_sha512final(archive_sha512_ctx *ctx, void *md)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* NOTE: Crypto functions are set based on availability and by the following
|
/* NOTE: Message Digest functions are set based on availability and by the
|
||||||
* order of preference.
|
* following order of preference.
|
||||||
* 1. libc
|
* 1. libc
|
||||||
* 2. libc2
|
* 2. libc2
|
||||||
* 3. libc3
|
* 3. libc3
|
||||||
@ -1227,7 +1227,7 @@ __archive_stub_sha512final(archive_sha512_ctx *ctx, void *md)
|
|||||||
* 7. libmd
|
* 7. libmd
|
||||||
* 8. Windows API
|
* 8. Windows API
|
||||||
*/
|
*/
|
||||||
const struct archive_crypto __archive_crypto =
|
const struct archive_digest __archive_digest =
|
||||||
{
|
{
|
||||||
/* MD5 */
|
/* MD5 */
|
||||||
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
|
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
|
||||||
@ -1412,7 +1412,7 @@ const struct archive_crypto __archive_crypto =
|
|||||||
#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
|
#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
|
||||||
&__archive_nettle_sha512init,
|
&__archive_nettle_sha512init,
|
||||||
&__archive_nettle_sha512update,
|
&__archive_nettle_sha512update,
|
||||||
&__archive_nettle_sha512final,
|
&__archive_nettle_sha512final
|
||||||
#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
|
#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
|
||||||
&__archive_openssl_sha512init,
|
&__archive_openssl_sha512init,
|
||||||
&__archive_openssl_sha512update,
|
&__archive_openssl_sha512update,
|
@ -264,11 +264,11 @@ typedef unsigned char archive_sha512_ctx;
|
|||||||
#define ARCHIVE_HAS_MD5
|
#define ARCHIVE_HAS_MD5
|
||||||
#endif
|
#endif
|
||||||
#define archive_md5_init(ctx)\
|
#define archive_md5_init(ctx)\
|
||||||
__archive_crypto.md5init(ctx)
|
__archive_digest.md5init(ctx)
|
||||||
#define archive_md5_final(ctx, md)\
|
#define archive_md5_final(ctx, md)\
|
||||||
__archive_crypto.md5final(ctx, md)
|
__archive_digest.md5final(ctx, md)
|
||||||
#define archive_md5_update(ctx, buf, n)\
|
#define archive_md5_update(ctx, buf, n)\
|
||||||
__archive_crypto.md5update(ctx, buf, n)
|
__archive_digest.md5update(ctx, buf, n)
|
||||||
|
|
||||||
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
|
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
|
||||||
defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
|
defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
|
||||||
@ -276,11 +276,11 @@ typedef unsigned char archive_sha512_ctx;
|
|||||||
#define ARCHIVE_HAS_RMD160
|
#define ARCHIVE_HAS_RMD160
|
||||||
#endif
|
#endif
|
||||||
#define archive_rmd160_init(ctx)\
|
#define archive_rmd160_init(ctx)\
|
||||||
__archive_crypto.rmd160init(ctx)
|
__archive_digest.rmd160init(ctx)
|
||||||
#define archive_rmd160_final(ctx, md)\
|
#define archive_rmd160_final(ctx, md)\
|
||||||
__archive_crypto.rmd160final(ctx, md)
|
__archive_digest.rmd160final(ctx, md)
|
||||||
#define archive_rmd160_update(ctx, buf, n)\
|
#define archive_rmd160_update(ctx, buf, n)\
|
||||||
__archive_crypto.rmd160update(ctx, buf, n)
|
__archive_digest.rmd160update(ctx, buf, n)
|
||||||
|
|
||||||
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
|
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
|
||||||
defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \
|
defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \
|
||||||
@ -291,11 +291,11 @@ typedef unsigned char archive_sha512_ctx;
|
|||||||
#define ARCHIVE_HAS_SHA1
|
#define ARCHIVE_HAS_SHA1
|
||||||
#endif
|
#endif
|
||||||
#define archive_sha1_init(ctx)\
|
#define archive_sha1_init(ctx)\
|
||||||
__archive_crypto.sha1init(ctx)
|
__archive_digest.sha1init(ctx)
|
||||||
#define archive_sha1_final(ctx, md)\
|
#define archive_sha1_final(ctx, md)\
|
||||||
__archive_crypto.sha1final(ctx, md)
|
__archive_digest.sha1final(ctx, md)
|
||||||
#define archive_sha1_update(ctx, buf, n)\
|
#define archive_sha1_update(ctx, buf, n)\
|
||||||
__archive_crypto.sha1update(ctx, buf, n)
|
__archive_digest.sha1update(ctx, buf, n)
|
||||||
|
|
||||||
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
|
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\
|
||||||
defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
|
defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\
|
||||||
@ -308,11 +308,11 @@ typedef unsigned char archive_sha512_ctx;
|
|||||||
#define ARCHIVE_HAS_SHA256
|
#define ARCHIVE_HAS_SHA256
|
||||||
#endif
|
#endif
|
||||||
#define archive_sha256_init(ctx)\
|
#define archive_sha256_init(ctx)\
|
||||||
__archive_crypto.sha256init(ctx)
|
__archive_digest.sha256init(ctx)
|
||||||
#define archive_sha256_final(ctx, md)\
|
#define archive_sha256_final(ctx, md)\
|
||||||
__archive_crypto.sha256final(ctx, md)
|
__archive_digest.sha256final(ctx, md)
|
||||||
#define archive_sha256_update(ctx, buf, n)\
|
#define archive_sha256_update(ctx, buf, n)\
|
||||||
__archive_crypto.sha256update(ctx, buf, n)
|
__archive_digest.sha256update(ctx, buf, n)
|
||||||
|
|
||||||
#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
|
#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\
|
||||||
defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
|
defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
|
||||||
@ -324,11 +324,11 @@ typedef unsigned char archive_sha512_ctx;
|
|||||||
#define ARCHIVE_HAS_SHA384
|
#define ARCHIVE_HAS_SHA384
|
||||||
#endif
|
#endif
|
||||||
#define archive_sha384_init(ctx)\
|
#define archive_sha384_init(ctx)\
|
||||||
__archive_crypto.sha384init(ctx)
|
__archive_digest.sha384init(ctx)
|
||||||
#define archive_sha384_final(ctx, md)\
|
#define archive_sha384_final(ctx, md)\
|
||||||
__archive_crypto.sha384final(ctx, md)
|
__archive_digest.sha384final(ctx, md)
|
||||||
#define archive_sha384_update(ctx, buf, n)\
|
#define archive_sha384_update(ctx, buf, n)\
|
||||||
__archive_crypto.sha384update(ctx, buf, n)
|
__archive_digest.sha384update(ctx, buf, n)
|
||||||
|
|
||||||
#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
|
#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\
|
||||||
defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
|
defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\
|
||||||
@ -341,14 +341,14 @@ typedef unsigned char archive_sha512_ctx;
|
|||||||
#define ARCHIVE_HAS_SHA512
|
#define ARCHIVE_HAS_SHA512
|
||||||
#endif
|
#endif
|
||||||
#define archive_sha512_init(ctx)\
|
#define archive_sha512_init(ctx)\
|
||||||
__archive_crypto.sha512init(ctx)
|
__archive_digest.sha512init(ctx)
|
||||||
#define archive_sha512_final(ctx, md)\
|
#define archive_sha512_final(ctx, md)\
|
||||||
__archive_crypto.sha512final(ctx, md)
|
__archive_digest.sha512final(ctx, md)
|
||||||
#define archive_sha512_update(ctx, buf, n)\
|
#define archive_sha512_update(ctx, buf, n)\
|
||||||
__archive_crypto.sha512update(ctx, buf, n)
|
__archive_digest.sha512update(ctx, buf, n)
|
||||||
|
|
||||||
/* Minimal interface to crypto functionality for internal use in libarchive */
|
/* Minimal interface to digest functionality for internal use in libarchive */
|
||||||
struct archive_crypto
|
struct archive_digest
|
||||||
{
|
{
|
||||||
/* Message Digest */
|
/* Message Digest */
|
||||||
int (*md5init)(archive_md5_ctx *ctx);
|
int (*md5init)(archive_md5_ctx *ctx);
|
||||||
@ -371,6 +371,6 @@ struct archive_crypto
|
|||||||
int (*sha512final)(archive_sha512_ctx *, void *);
|
int (*sha512final)(archive_sha512_ctx *, void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct archive_crypto __archive_crypto;
|
extern const struct archive_digest __archive_digest;
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -44,10 +44,16 @@
|
|||||||
* - Watcom C++ in C code. (For any version?)
|
* - Watcom C++ in C code. (For any version?)
|
||||||
* - SGI MIPSpro
|
* - SGI MIPSpro
|
||||||
* - Microsoft Visual C++ 6.0 (supposedly newer versions too)
|
* - 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__)
|
#if defined(__WATCOMC__) || defined(__sgi) || defined(__hpux) || defined(__BORLANDC__)
|
||||||
#define inline
|
#define inline
|
||||||
#elif defined(_MSC_VER)
|
#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
|
#define inline __inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -58,7 +64,13 @@ archive_be16dec(const void *pp)
|
|||||||
{
|
{
|
||||||
unsigned char const *p = (unsigned char const *)pp;
|
unsigned char const *p = (unsigned char const *)pp;
|
||||||
|
|
||||||
return ((p[0] << 8) | p[1]);
|
/* 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
|
static inline uint32_t
|
||||||
@ -66,7 +78,15 @@ archive_be32dec(const void *pp)
|
|||||||
{
|
{
|
||||||
unsigned char const *p = (unsigned char const *)pp;
|
unsigned char const *p = (unsigned char const *)pp;
|
||||||
|
|
||||||
return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
|
/* 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
|
static inline uint64_t
|
||||||
@ -82,7 +102,13 @@ archive_le16dec(const void *pp)
|
|||||||
{
|
{
|
||||||
unsigned char const *p = (unsigned char const *)pp;
|
unsigned char const *p = (unsigned char const *)pp;
|
||||||
|
|
||||||
return ((p[1] << 8) | p[0]);
|
/* 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
|
static inline uint32_t
|
||||||
@ -90,7 +116,15 @@ archive_le32dec(const void *pp)
|
|||||||
{
|
{
|
||||||
unsigned char const *p = (unsigned char const *)pp;
|
unsigned char const *p = (unsigned char const *)pp;
|
||||||
|
|
||||||
return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
|
/* 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
|
static inline uint64_t
|
||||||
|
@ -131,11 +131,11 @@ be discarded in favor of the new data.
|
|||||||
.\" .Sh RETURN VALUES
|
.\" .Sh RETURN VALUES
|
||||||
.\" .Sh ERRORS
|
.\" .Sh ERRORS
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr archive 3 ,
|
|
||||||
.Xr archive_entry_acl 3 ,
|
.Xr archive_entry_acl 3 ,
|
||||||
.Xr archive_entry_paths 3 ,
|
.Xr archive_entry_paths 3 ,
|
||||||
.Xr archive_entry_perms 3 ,
|
.Xr archive_entry_perms 3 ,
|
||||||
.Xr archive_entry_time 3
|
.Xr archive_entry_time 3
|
||||||
|
.Xr libarchive 3 ,
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The
|
The
|
||||||
.Nm libarchive
|
.Nm libarchive
|
||||||
|
@ -201,6 +201,9 @@ archive_entry_clone(struct archive_entry *entry)
|
|||||||
entry2->ae_set = entry->ae_set;
|
entry2->ae_set = entry->ae_set;
|
||||||
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
|
archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
|
||||||
|
|
||||||
|
/* Copy encryption status */
|
||||||
|
entry2->encryption = entry->encryption;
|
||||||
|
|
||||||
/* Copy ACL data over. */
|
/* Copy ACL data over. */
|
||||||
archive_acl_copy(&entry2->acl, &entry->acl);
|
archive_acl_copy(&entry2->acl, &entry->acl);
|
||||||
|
|
||||||
@ -415,6 +418,18 @@ archive_entry_gname(struct archive_entry *entry)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
archive_entry_gname_utf8(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
if (archive_mstring_get_utf8(entry->archive, &entry->ae_gname, &p) == 0)
|
||||||
|
return (p);
|
||||||
|
if (errno == ENOMEM)
|
||||||
|
__archive_errx(1, "No memory");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const wchar_t *
|
const wchar_t *
|
||||||
archive_entry_gname_w(struct archive_entry *entry)
|
archive_entry_gname_w(struct archive_entry *entry)
|
||||||
{
|
{
|
||||||
@ -447,6 +462,20 @@ archive_entry_hardlink(struct archive_entry *entry)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
archive_entry_hardlink_utf8(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
if ((entry->ae_set & AE_SET_HARDLINK) == 0)
|
||||||
|
return (NULL);
|
||||||
|
if (archive_mstring_get_utf8(
|
||||||
|
entry->archive, &entry->ae_hardlink, &p) == 0)
|
||||||
|
return (p);
|
||||||
|
if (errno == ENOMEM)
|
||||||
|
__archive_errx(1, "No memory");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
const wchar_t *
|
const wchar_t *
|
||||||
archive_entry_hardlink_w(struct archive_entry *entry)
|
archive_entry_hardlink_w(struct archive_entry *entry)
|
||||||
{
|
{
|
||||||
@ -533,6 +562,18 @@ archive_entry_pathname(struct archive_entry *entry)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
archive_entry_pathname_utf8(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
if (archive_mstring_get_utf8(
|
||||||
|
entry->archive, &entry->ae_pathname, &p) == 0)
|
||||||
|
return (p);
|
||||||
|
if (errno == ENOMEM)
|
||||||
|
__archive_errx(1, "No memory");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
const wchar_t *
|
const wchar_t *
|
||||||
archive_entry_pathname_w(struct archive_entry *entry)
|
archive_entry_pathname_w(struct archive_entry *entry)
|
||||||
{
|
{
|
||||||
@ -634,6 +675,20 @@ archive_entry_symlink(struct archive_entry *entry)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
archive_entry_symlink_utf8(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
if ((entry->ae_set & AE_SET_SYMLINK) == 0)
|
||||||
|
return (NULL);
|
||||||
|
if (archive_mstring_get_utf8(
|
||||||
|
entry->archive, &entry->ae_symlink, &p) == 0)
|
||||||
|
return (p);
|
||||||
|
if (errno == ENOMEM)
|
||||||
|
__archive_errx(1, "No memory");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
const wchar_t *
|
const wchar_t *
|
||||||
archive_entry_symlink_w(struct archive_entry *entry)
|
archive_entry_symlink_w(struct archive_entry *entry)
|
||||||
{
|
{
|
||||||
@ -677,6 +732,17 @@ archive_entry_uname(struct archive_entry *entry)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
archive_entry_uname_utf8(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
if (archive_mstring_get_utf8(entry->archive, &entry->ae_uname, &p) == 0)
|
||||||
|
return (p);
|
||||||
|
if (errno == ENOMEM)
|
||||||
|
__archive_errx(1, "No memory");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
const wchar_t *
|
const wchar_t *
|
||||||
archive_entry_uname_w(struct archive_entry *entry)
|
archive_entry_uname_w(struct archive_entry *entry)
|
||||||
{
|
{
|
||||||
@ -695,6 +761,24 @@ _archive_entry_uname_l(struct archive_entry *entry,
|
|||||||
return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
|
return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
archive_entry_is_data_encrypted(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
return ((entry->encryption & AE_ENCRYPTION_DATA) == AE_ENCRYPTION_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
archive_entry_is_metadata_encrypted(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
return ((entry->encryption & AE_ENCRYPTION_METADATA) == AE_ENCRYPTION_METADATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
archive_entry_is_encrypted(struct archive_entry *entry)
|
||||||
|
{
|
||||||
|
return (entry->encryption & (AE_ENCRYPTION_DATA|AE_ENCRYPTION_METADATA));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions to set archive_entry properties.
|
* Functions to set archive_entry properties.
|
||||||
*/
|
*/
|
||||||
@ -747,6 +831,12 @@ archive_entry_set_gname(struct archive_entry *entry, const char *name)
|
|||||||
archive_mstring_copy_mbs(&entry->ae_gname, name);
|
archive_mstring_copy_mbs(&entry->ae_gname, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
archive_entry_set_gname_utf8(struct archive_entry *entry, const char *name)
|
||||||
|
{
|
||||||
|
archive_mstring_copy_utf8(&entry->ae_gname, name);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
archive_entry_copy_gname(struct archive_entry *entry, const char *name)
|
archive_entry_copy_gname(struct archive_entry *entry, const char *name)
|
||||||
{
|
{
|
||||||
@ -803,6 +893,16 @@ archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
|
|||||||
entry->ae_set &= ~AE_SET_HARDLINK;
|
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target)
|
||||||
|
{
|
||||||
|
archive_mstring_copy_utf8(&entry->ae_hardlink, target);
|
||||||
|
if (target != NULL)
|
||||||
|
entry->ae_set |= AE_SET_HARDLINK;
|
||||||
|
else
|
||||||
|
entry->ae_set &= ~AE_SET_HARDLINK;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
|
archive_entry_copy_hardlink(struct archive_entry *entry, const char *target)
|
||||||
{
|
{
|
||||||
@ -941,6 +1041,15 @@ archive_entry_set_link(struct archive_entry *entry, const char *target)
|
|||||||
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
|
archive_mstring_copy_mbs(&entry->ae_hardlink, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
archive_entry_set_link_utf8(struct archive_entry *entry, const char *target)
|
||||||
|
{
|
||||||
|
if (entry->ae_set & AE_SET_SYMLINK)
|
||||||
|
archive_mstring_copy_utf8(&entry->ae_symlink, target);
|
||||||
|
else
|
||||||
|
archive_mstring_copy_utf8(&entry->ae_hardlink, target);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set symlink if symlink is already set, else set hardlink. */
|
/* Set symlink if symlink is already set, else set hardlink. */
|
||||||
void
|
void
|
||||||
archive_entry_copy_link(struct archive_entry *entry, const char *target)
|
archive_entry_copy_link(struct archive_entry *entry, const char *target)
|
||||||
@ -1030,6 +1139,12 @@ archive_entry_set_pathname(struct archive_entry *entry, const char *name)
|
|||||||
archive_mstring_copy_mbs(&entry->ae_pathname, name);
|
archive_mstring_copy_mbs(&entry->ae_pathname, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
archive_entry_set_pathname_utf8(struct archive_entry *entry, const char *name)
|
||||||
|
{
|
||||||
|
archive_mstring_copy_utf8(&entry->ae_pathname, name);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
archive_entry_copy_pathname(struct archive_entry *entry, const char *name)
|
archive_entry_copy_pathname(struct archive_entry *entry, const char *name)
|
||||||
{
|
{
|
||||||
@ -1130,6 +1245,16 @@ archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
|
|||||||
entry->ae_set &= ~AE_SET_SYMLINK;
|
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
|
||||||
|
{
|
||||||
|
archive_mstring_copy_utf8(&entry->ae_symlink, linkname);
|
||||||
|
if (linkname != NULL)
|
||||||
|
entry->ae_set |= AE_SET_SYMLINK;
|
||||||
|
else
|
||||||
|
entry->ae_set &= ~AE_SET_SYMLINK;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
|
archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname)
|
||||||
{
|
{
|
||||||
@ -1193,6 +1318,12 @@ archive_entry_set_uname(struct archive_entry *entry, const char *name)
|
|||||||
archive_mstring_copy_mbs(&entry->ae_uname, name);
|
archive_mstring_copy_mbs(&entry->ae_uname, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
archive_entry_set_uname_utf8(struct archive_entry *entry, const char *name)
|
||||||
|
{
|
||||||
|
archive_mstring_copy_utf8(&entry->ae_uname, name);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
archive_entry_copy_uname(struct archive_entry *entry, const char *name)
|
archive_entry_copy_uname(struct archive_entry *entry, const char *name)
|
||||||
{
|
{
|
||||||
@ -1216,6 +1347,26 @@ archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
archive_entry_set_is_data_encrypted(struct archive_entry *entry, char is_encrypted)
|
||||||
|
{
|
||||||
|
if (is_encrypted) {
|
||||||
|
entry->encryption |= AE_ENCRYPTION_DATA;
|
||||||
|
} else {
|
||||||
|
entry->encryption &= ~AE_ENCRYPTION_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
archive_entry_set_is_metadata_encrypted(struct archive_entry *entry, char is_encrypted)
|
||||||
|
{
|
||||||
|
if (is_encrypted) {
|
||||||
|
entry->encryption |= AE_ENCRYPTION_METADATA;
|
||||||
|
} else {
|
||||||
|
entry->encryption &= ~AE_ENCRYPTION_METADATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_archive_entry_copy_uname_l(struct archive_entry *entry,
|
_archive_entry_copy_uname_l(struct archive_entry *entry,
|
||||||
const char *name, size_t len, struct archive_string_conv *sc)
|
const char *name, size_t len, struct archive_string_conv *sc)
|
||||||
@ -1588,19 +1739,23 @@ ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
|
|||||||
while (*start == '\t' || *start == ' ' || *start == ',')
|
while (*start == '\t' || *start == ' ' || *start == ',')
|
||||||
start++;
|
start++;
|
||||||
while (*start != '\0') {
|
while (*start != '\0') {
|
||||||
|
size_t length;
|
||||||
/* Locate end of token. */
|
/* Locate end of token. */
|
||||||
end = start;
|
end = start;
|
||||||
while (*end != '\0' && *end != '\t' &&
|
while (*end != '\0' && *end != '\t' &&
|
||||||
*end != ' ' && *end != ',')
|
*end != ' ' && *end != ',')
|
||||||
end++;
|
end++;
|
||||||
|
length = end - start;
|
||||||
for (flag = flags; flag->name != NULL; flag++) {
|
for (flag = flags; flag->name != NULL; flag++) {
|
||||||
if (memcmp(start, flag->name, end - start) == 0) {
|
size_t flag_length = strlen(flag->name);
|
||||||
|
if (length == flag_length
|
||||||
|
&& memcmp(start, flag->name, length) == 0) {
|
||||||
/* Matched "noXXXX", so reverse the sense. */
|
/* Matched "noXXXX", so reverse the sense. */
|
||||||
clear |= flag->set;
|
clear |= flag->set;
|
||||||
set |= flag->clear;
|
set |= flag->clear;
|
||||||
break;
|
break;
|
||||||
} else if (memcmp(start, flag->name + 2, end - start)
|
} else if (length == flag_length - 2
|
||||||
== 0) {
|
&& memcmp(start, flag->name + 2, length) == 0) {
|
||||||
/* Matched "XXXX", so don't reverse. */
|
/* Matched "XXXX", so don't reverse. */
|
||||||
set |= flag->set;
|
set |= flag->set;
|
||||||
clear |= flag->clear;
|
clear |= flag->clear;
|
||||||
@ -1652,19 +1807,23 @@ ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp)
|
|||||||
while (*start == L'\t' || *start == L' ' || *start == L',')
|
while (*start == L'\t' || *start == L' ' || *start == L',')
|
||||||
start++;
|
start++;
|
||||||
while (*start != L'\0') {
|
while (*start != L'\0') {
|
||||||
|
size_t length;
|
||||||
/* Locate end of token. */
|
/* Locate end of token. */
|
||||||
end = start;
|
end = start;
|
||||||
while (*end != L'\0' && *end != L'\t' &&
|
while (*end != L'\0' && *end != L'\t' &&
|
||||||
*end != L' ' && *end != L',')
|
*end != L' ' && *end != L',')
|
||||||
end++;
|
end++;
|
||||||
|
length = end - start;
|
||||||
for (flag = flags; flag->wname != NULL; flag++) {
|
for (flag = flags; flag->wname != NULL; flag++) {
|
||||||
if (wmemcmp(start, flag->wname, end - start) == 0) {
|
size_t flag_length = wcslen(flag->wname);
|
||||||
|
if (length == flag_length
|
||||||
|
&& wmemcmp(start, flag->wname, length) == 0) {
|
||||||
/* Matched "noXXXX", so reverse the sense. */
|
/* Matched "noXXXX", so reverse the sense. */
|
||||||
clear |= flag->set;
|
clear |= flag->set;
|
||||||
set |= flag->clear;
|
set |= flag->clear;
|
||||||
break;
|
break;
|
||||||
} else if (wmemcmp(start, flag->wname + 2, end - start)
|
} else if (length == flag_length - 2
|
||||||
== 0) {
|
&& wmemcmp(start, flag->wname + 2, length) == 0) {
|
||||||
/* Matched "XXXX", so don't reverse. */
|
/* Matched "XXXX", so don't reverse. */
|
||||||
set |= flag->set;
|
set |= flag->set;
|
||||||
clear |= flag->clear;
|
clear |= flag->clear;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#define ARCHIVE_ENTRY_H_INCLUDED
|
#define ARCHIVE_ENTRY_H_INCLUDED
|
||||||
|
|
||||||
/* Note: Compiler will complain if this does not match archive.h! */
|
/* Note: Compiler will complain if this does not match archive.h! */
|
||||||
#define ARCHIVE_VERSION_NUMBER 3001002
|
#define ARCHIVE_VERSION_NUMBER 3002000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: archive_entry.h is for use outside of libarchive; the
|
* Note: archive_entry.h is for use outside of libarchive; the
|
||||||
@ -48,14 +48,20 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get a suitable 64-bit integer type. */
|
/* Get a suitable 64-bit integer type. */
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if !defined(__LA_INT64_T_DEFINED)
|
||||||
# define __LA_INT64_T __int64
|
# 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
|
# else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
# if defined(_SCO_DS)
|
# if defined(_SCO_DS) || defined(__osf__)
|
||||||
# define __LA_INT64_T long long
|
typedef long long la_int64_t;
|
||||||
# else
|
# else
|
||||||
# define __LA_INT64_T int64_t
|
typedef int64_t la_int64_t;
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -63,12 +69,17 @@
|
|||||||
#if ARCHIVE_VERSION_NUMBER >= 3999000
|
#if ARCHIVE_VERSION_NUMBER >= 3999000
|
||||||
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
|
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
|
||||||
# define __LA_MODE_T int
|
# define __LA_MODE_T int
|
||||||
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__)
|
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
|
||||||
# define __LA_MODE_T unsigned short
|
# define __LA_MODE_T unsigned short
|
||||||
#else
|
#else
|
||||||
# define __LA_MODE_T mode_t
|
# define __LA_MODE_T mode_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Large file support for Android */
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include "android_lf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On Windows, define LIBARCHIVE_STATIC if you're building or using a
|
* On Windows, define LIBARCHIVE_STATIC if you're building or using a
|
||||||
* .lib. The default here assumes you're building a DLL. Only
|
* .lib. The default here assumes you're building a DLL. Only
|
||||||
@ -206,13 +217,15 @@ __LA_DECL void archive_entry_fflags(struct archive_entry *,
|
|||||||
unsigned long * /* set */,
|
unsigned long * /* set */,
|
||||||
unsigned long * /* clear */);
|
unsigned long * /* clear */);
|
||||||
__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
|
__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
|
||||||
__LA_DECL __LA_INT64_T archive_entry_gid(struct archive_entry *);
|
__LA_DECL la_int64_t archive_entry_gid(struct archive_entry *);
|
||||||
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
|
__LA_DECL const 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 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(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 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_ino(struct archive_entry *);
|
||||||
__LA_DECL __LA_INT64_T archive_entry_ino64(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 int archive_entry_ino_is_set(struct archive_entry *);
|
||||||
__LA_DECL __LA_MODE_T archive_entry_mode(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 time_t archive_entry_mtime(struct archive_entry *);
|
||||||
@ -220,6 +233,7 @@ __LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
|
|||||||
__LA_DECL int archive_entry_mtime_is_set(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 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(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 const wchar_t *archive_entry_pathname_w(struct archive_entry *);
|
||||||
__LA_DECL __LA_MODE_T archive_entry_perm(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_rdev(struct archive_entry *);
|
||||||
@ -227,14 +241,19 @@ __LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
|
|||||||
__LA_DECL dev_t archive_entry_rdevminor(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 char *archive_entry_sourcepath(struct archive_entry *);
|
||||||
__LA_DECL const wchar_t *archive_entry_sourcepath_w(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 la_int64_t archive_entry_size(struct archive_entry *);
|
||||||
__LA_DECL int archive_entry_size_is_set(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_strmode(struct archive_entry *);
|
||||||
__LA_DECL const char *archive_entry_symlink(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 const wchar_t *archive_entry_symlink_w(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 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(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 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.
|
* Set fields in an archive_entry.
|
||||||
@ -266,18 +285,21 @@ __LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
|
|||||||
const char *);
|
const char *);
|
||||||
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
|
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
|
||||||
const wchar_t *);
|
const wchar_t *);
|
||||||
__LA_DECL void archive_entry_set_gid(struct archive_entry *, __LA_INT64_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(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(struct archive_entry *, const char *);
|
||||||
__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
|
__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 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(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(struct archive_entry *, const char *);
|
||||||
__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
|
__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 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_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_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(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(struct archive_entry *, const char *);
|
||||||
__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *);
|
__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 int archive_entry_update_link_utf8(struct archive_entry *, const char *);
|
||||||
@ -286,6 +308,7 @@ __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_unset_mtime(struct archive_entry *);
|
||||||
__LA_DECL void archive_entry_set_nlink(struct archive_entry *, unsigned int);
|
__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(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(struct archive_entry *, const char *);
|
||||||
__LA_DECL void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
|
__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 int archive_entry_update_pathname_utf8(struct archive_entry *, const char *);
|
||||||
@ -293,19 +316,23 @@ __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_rdev(struct archive_entry *, dev_t);
|
||||||
__LA_DECL void archive_entry_set_rdevmajor(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_rdevminor(struct archive_entry *, dev_t);
|
||||||
__LA_DECL void archive_entry_set_size(struct archive_entry *, __LA_INT64_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_unset_size(struct archive_entry *);
|
||||||
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
|
__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_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(struct archive_entry *, const char *);
|
||||||
|
__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(struct archive_entry *, const char *);
|
||||||
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
|
__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 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_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(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(struct archive_entry *, const char *);
|
||||||
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
|
__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 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
|
* Routines to bulk copy fields to/from a platform-native "struct
|
||||||
* stat." Libarchive used to just store a struct stat inside of each
|
* stat." Libarchive used to just store a struct stat inside of each
|
||||||
@ -514,7 +541,7 @@ __LA_DECL int archive_entry_xattr_next(struct archive_entry *,
|
|||||||
|
|
||||||
__LA_DECL void archive_entry_sparse_clear(struct archive_entry *);
|
__LA_DECL void archive_entry_sparse_clear(struct archive_entry *);
|
||||||
__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
|
__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
|
||||||
__LA_INT64_T /* offset */, __LA_INT64_T /* length */);
|
la_int64_t /* offset */, la_int64_t /* length */);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To retrieve the xattr list, first "reset", then repeatedly ask for the
|
* To retrieve the xattr list, first "reset", then repeatedly ask for the
|
||||||
@ -524,7 +551,7 @@ __LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
|
|||||||
__LA_DECL int archive_entry_sparse_count(struct archive_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_reset(struct archive_entry *);
|
||||||
__LA_DECL int archive_entry_sparse_next(struct archive_entry *,
|
__LA_DECL int archive_entry_sparse_next(struct archive_entry *,
|
||||||
__LA_INT64_T * /* offset */, __LA_INT64_T * /* length */);
|
la_int64_t * /* offset */, la_int64_t * /* length */);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility to match up hardlinks.
|
* Utility to match up hardlinks.
|
||||||
|
@ -226,8 +226,8 @@ The returned long string is valid until the next call to
|
|||||||
or
|
or
|
||||||
.Fn archive_entry_acl_text_w .
|
.Fn archive_entry_acl_text_w .
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr archive 3 ,
|
|
||||||
.Xr archive_entry 3
|
.Xr archive_entry 3
|
||||||
|
.Xr libarchive 3 ,
|
||||||
.Sh BUGS
|
.Sh BUGS
|
||||||
.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
|
.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
|
||||||
and
|
and
|
||||||
|
@ -44,6 +44,10 @@ archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st)
|
|||||||
archive_entry_set_atime(entry, st->st_atime, st->st_atim.tv_nsec);
|
archive_entry_set_atime(entry, st->st_atime, st->st_atim.tv_nsec);
|
||||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctim.tv_nsec);
|
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctim.tv_nsec);
|
||||||
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtim.tv_nsec);
|
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtim.tv_nsec);
|
||||||
|
#elif HAVE_STRUCT_STAT_ST_MTIME_NSEC
|
||||||
|
archive_entry_set_atime(entry, st->st_atime, st->st_atime_nsec);
|
||||||
|
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_nsec);
|
||||||
|
archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_nsec);
|
||||||
#elif HAVE_STRUCT_STAT_ST_MTIME_N
|
#elif HAVE_STRUCT_STAT_ST_MTIME_N
|
||||||
archive_entry_set_atime(entry, st->st_atime, st->st_atime_n);
|
archive_entry_set_atime(entry, st->st_atime, st->st_atime_n);
|
||||||
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_n);
|
archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_n);
|
||||||
|
@ -149,5 +149,5 @@ It doesn't have a corresponding get accessor function.
|
|||||||
is an alias for
|
is an alias for
|
||||||
.Fn archive_entry_copy_XXX .
|
.Fn archive_entry_copy_XXX .
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr archive 3 ,
|
|
||||||
.Xr archive_entry 3
|
.Xr archive_entry 3
|
||||||
|
.Xr libarchive 3 ,
|
||||||
|
@ -194,11 +194,11 @@ every name that is recognized.
|
|||||||
.Xr strtofflags 3 ,
|
.Xr strtofflags 3 ,
|
||||||
which stops parsing at the first unrecognized name.)
|
which stops parsing at the first unrecognized name.)
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr archive 3 ,
|
|
||||||
.Xr archive_entry 3 ,
|
.Xr archive_entry 3 ,
|
||||||
.Xr archive_entry_acl 3 ,
|
.Xr archive_entry_acl 3 ,
|
||||||
.Xr archive_read_disk 3 ,
|
.Xr archive_read_disk 3 ,
|
||||||
.Xr archive_write_disk 3
|
.Xr archive_write_disk 3
|
||||||
|
.Xr libarchive 3 ,
|
||||||
.Sh BUGS
|
.Sh BUGS
|
||||||
The platform types
|
The platform types
|
||||||
.Vt uid_t
|
.Vt uid_t
|
||||||
|
@ -154,6 +154,11 @@ struct archive_entry {
|
|||||||
/* Not used within libarchive; useful for some clients. */
|
/* Not used within libarchive; useful for some clients. */
|
||||||
struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */
|
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;
|
void *mac_metadata;
|
||||||
size_t mac_metadata_size;
|
size_t mac_metadata_size;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ archive_entry_sparse_add_entry(struct archive_entry *entry,
|
|||||||
if (offset < 0 || length < 0)
|
if (offset < 0 || length < 0)
|
||||||
/* Invalid value */
|
/* Invalid value */
|
||||||
return;
|
return;
|
||||||
if (offset + length < 0 ||
|
if (offset > INT64_MAX - length ||
|
||||||
offset + length > archive_entry_size(entry))
|
offset + length > archive_entry_size(entry))
|
||||||
/* A value of "length" parameter is too large. */
|
/* A value of "length" parameter is too large. */
|
||||||
return;
|
return;
|
||||||
|
@ -226,7 +226,7 @@ and
|
|||||||
are used by
|
are used by
|
||||||
.Xr archive_entry_linkify 3
|
.Xr archive_entry_linkify 3
|
||||||
to find hardlinks.
|
to find hardlinks.
|
||||||
The pair of device and inode is suppossed to identify hardlinked files.
|
The pair of device and inode is supposed to identify hardlinked files.
|
||||||
.Pp
|
.Pp
|
||||||
The device major and minor number can be obtained independently using
|
The device major and minor number can be obtained independently using
|
||||||
.Fn archive_entry_devmajor
|
.Fn archive_entry_devmajor
|
||||||
@ -267,8 +267,8 @@ platforms.
|
|||||||
Some archive formats use the combined form, while other formats use
|
Some archive formats use the combined form, while other formats use
|
||||||
the split form.
|
the split form.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr archive 3 ,
|
|
||||||
.Xr archive_entry_acl 3 ,
|
.Xr archive_entry_acl 3 ,
|
||||||
.Xr archive_entry_perms 3 ,
|
.Xr archive_entry_perms 3 ,
|
||||||
.Xr archive_entry_time 3 ,
|
.Xr archive_entry_time 3 ,
|
||||||
|
.Xr libarchive 3 ,
|
||||||
.Xr stat 2
|
.Xr stat 2
|
||||||
|
@ -113,8 +113,8 @@ The current state can be queried using
|
|||||||
.Fn XXX_is_set .
|
.Fn XXX_is_set .
|
||||||
Unset time fields have a second and nanosecond field of 0.
|
Unset time fields have a second and nanosecond field of 0.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr archive 3 ,
|
|
||||||
.Xr archive_entry 3
|
.Xr archive_entry 3
|
||||||
|
.Xr libarchive 3 ,
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The
|
The
|
||||||
.Nm libarchive
|
.Nm libarchive
|
||||||
|
@ -98,7 +98,10 @@ archive_entry_xattr_add_entry(struct archive_entry *entry,
|
|||||||
/* XXX Error XXX */
|
/* XXX Error XXX */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xp->name = strdup(name);
|
if ((xp->name = strdup(name)) == NULL)
|
||||||
|
/* XXX Error XXX */
|
||||||
|
return;
|
||||||
|
|
||||||
if ((xp->value = malloc(size)) != NULL) {
|
if ((xp->value = malloc(size)) != NULL) {
|
||||||
memcpy(xp->value, value, size);
|
memcpy(xp->value, value, size);
|
||||||
xp->size = size;
|
xp->size = size;
|
||||||
|
@ -38,8 +38,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
/* This file defines a single public function. */
|
#define __LIBARCHIVE_BUILD 1
|
||||||
time_t __archive_get_date(time_t now, char *);
|
#include "archive_getdate.h"
|
||||||
|
|
||||||
/* Basic time units. */
|
/* Basic time units. */
|
||||||
#define EPOCH 1970
|
#define EPOCH 1970
|
||||||
@ -782,7 +782,7 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth)
|
|||||||
* Tokenizer.
|
* Tokenizer.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
nexttoken(char **in, time_t *value)
|
nexttoken(const char **in, time_t *value)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
char buff[64];
|
char buff[64];
|
||||||
@ -809,7 +809,7 @@ nexttoken(char **in, time_t *value)
|
|||||||
/* Try the next token in the word table first. */
|
/* Try the next token in the word table first. */
|
||||||
/* This allows us to match "2nd", for example. */
|
/* This allows us to match "2nd", for example. */
|
||||||
{
|
{
|
||||||
char *src = *in;
|
const char *src = *in;
|
||||||
const struct LEXICON *tp;
|
const struct LEXICON *tp;
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
|
|
||||||
@ -894,7 +894,7 @@ difftm (struct tm *a, struct tm *b)
|
|||||||
* TODO: tokens[] array should be dynamically sized.
|
* TODO: tokens[] array should be dynamically sized.
|
||||||
*/
|
*/
|
||||||
time_t
|
time_t
|
||||||
__archive_get_date(time_t now, char *p)
|
__archive_get_date(time_t now, const char *p)
|
||||||
{
|
{
|
||||||
struct token tokens[256];
|
struct token tokens[256];
|
||||||
struct gdstate _gds;
|
struct gdstate _gds;
|
||||||
|
39
contrib/libarchive/libarchive/archive_getdate.h
Normal file
39
contrib/libarchive/libarchive/archive_getdate.h
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 __LIBARCHIVE_BUILD
|
||||||
|
#error This header is only to be used internally to libarchive.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARCHIVE_GETDATE_H_INCLUDED
|
||||||
|
#define ARCHIVE_GETDATE_H_INCLUDED
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
time_t __archive_get_date(time_t now, const char *);
|
||||||
|
|
||||||
|
#endif
|
248
contrib/libarchive/libarchive/archive_hmac.c
Normal file
248
contrib/libarchive/libarchive/archive_hmac.c
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
/*-
|
||||||
|
* 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)
|
||||||
|
|
||||||
|
static int
|
||||||
|
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
|
||||||
|
{
|
||||||
|
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_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)
|
||||||
|
{
|
||||||
|
HMAC_CTX_init(ctx);
|
||||||
|
HMAC_Init(ctx, key, key_len, EVP_sha1());
|
||||||
|
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_cleanup(ctx);
|
||||||
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
#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,
|
||||||
|
};
|
106
contrib/libarchive/libarchive/archive_hmac_private.h
Normal file
106
contrib/libarchive/libarchive/archive_hmac_private.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*-
|
||||||
|
* 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 __LIBARCHIVE_BUILD
|
||||||
|
#error This header is only to be used internally to libarchive.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED
|
||||||
|
#define ARCHIVE_HMAC_PRIVATE_H_INCLUDED
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On systems that do not support any recognized crypto libraries,
|
||||||
|
* the archive_hmac.c file is expected to define no usable symbols.
|
||||||
|
*
|
||||||
|
* But some compilers and linkers choke on empty object files, so
|
||||||
|
* define a public symbol that will always exist. This could
|
||||||
|
* be removed someday if this file gains another always-present
|
||||||
|
* symbol definition.
|
||||||
|
*/
|
||||||
|
int __libarchive_hmac_build_hack(void);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
# include <AvailabilityMacros.h>
|
||||||
|
# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||||
|
# 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_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
|
||||||
|
#include <nettle/hmac.h>
|
||||||
|
|
||||||
|
typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
|
||||||
|
|
||||||
|
#elif defined(HAVE_LIBCRYPTO)
|
||||||
|
#include <openssl/hmac.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 */
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
#include "archive_private.h"
|
#include "archive_private.h"
|
||||||
#include "archive_entry.h"
|
#include "archive_entry.h"
|
||||||
|
#include "archive_getdate.h"
|
||||||
#include "archive_pathmatch.h"
|
#include "archive_pathmatch.h"
|
||||||
#include "archive_rb.h"
|
#include "archive_rb.h"
|
||||||
#include "archive_string.h"
|
#include "archive_string.h"
|
||||||
@ -184,7 +185,6 @@ static int time_excluded(struct archive_match *,
|
|||||||
struct archive_entry *);
|
struct archive_entry *);
|
||||||
static int validate_time_flag(struct archive *, int, const char *);
|
static int validate_time_flag(struct archive *, int, const char *);
|
||||||
|
|
||||||
time_t __archive_get_date(time_t now, const char *);
|
|
||||||
#define get_date __archive_get_date
|
#define get_date __archive_get_date
|
||||||
|
|
||||||
static const struct archive_rb_tree_ops rb_ops_mbs = {
|
static const struct archive_rb_tree_ops rb_ops_mbs = {
|
||||||
@ -580,6 +580,7 @@ add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
|
|||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
r = archive_read_support_format_raw(ar);
|
r = archive_read_support_format_raw(ar);
|
||||||
|
r = archive_read_support_format_empty(ar);
|
||||||
if (r != ARCHIVE_OK) {
|
if (r != ARCHIVE_OK) {
|
||||||
archive_copy_error(&(a->archive), ar);
|
archive_copy_error(&(a->archive), ar);
|
||||||
archive_read_free(ar);
|
archive_read_free(ar);
|
||||||
@ -596,10 +597,14 @@ add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
|
|||||||
}
|
}
|
||||||
r = archive_read_next_header(ar, &ae);
|
r = archive_read_next_header(ar, &ae);
|
||||||
if (r != ARCHIVE_OK) {
|
if (r != ARCHIVE_OK) {
|
||||||
archive_copy_error(&(a->archive), ar);
|
|
||||||
archive_read_free(ar);
|
archive_read_free(ar);
|
||||||
|
if (r == ARCHIVE_EOF) {
|
||||||
|
return (ARCHIVE_OK);
|
||||||
|
} else {
|
||||||
|
archive_copy_error(&(a->archive), ar);
|
||||||
return (r);
|
return (r);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
archive_string_init(&as);
|
archive_string_init(&as);
|
||||||
|
|
||||||
@ -1152,7 +1157,7 @@ set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
|
|||||||
{
|
{
|
||||||
/* NOTE: stat() on Windows cannot handle nano seconds. */
|
/* NOTE: stat() on Windows cannot handle nano seconds. */
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
WIN32_FIND_DATA d;
|
WIN32_FIND_DATAA d;
|
||||||
|
|
||||||
if (path == NULL || *path == '\0') {
|
if (path == NULL || *path == '\0') {
|
||||||
archive_set_error(&(a->archive), EINVAL, "pathname is empty");
|
archive_set_error(&(a->archive), EINVAL, "pathname is empty");
|
||||||
|
@ -42,9 +42,9 @@ _archive_set_option(struct archive *a,
|
|||||||
|
|
||||||
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
|
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
|
||||||
|
|
||||||
mp = m != NULL && m[0] == '\0' ? NULL : m;
|
mp = (m != NULL && m[0] != '\0') ? m : NULL;
|
||||||
op = o != NULL && o[0] == '\0' ? NULL : o;
|
op = (o != NULL && o[0] != '\0') ? o : NULL;
|
||||||
vp = v != NULL && v[0] == '\0' ? NULL : v;
|
vp = (v != NULL && v[0] != '\0') ? v : NULL;
|
||||||
|
|
||||||
if (op == NULL && vp == NULL)
|
if (op == NULL && vp == NULL)
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
|
329
contrib/libarchive/libarchive/archive_pack_dev.c
Normal file
329
contrib/libarchive/libarchive/archive_pack_dev.c
Normal file
@ -0,0 +1,329 @@
|
|||||||
|
/* $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
|
||||||
|
#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 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
contrib/libarchive/libarchive/archive_pack_dev.h
Normal file
49
contrib/libarchive/libarchive/archive_pack_dev.h
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 _PACK_DEV_H
|
||||||
|
#define _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 /* _PACK_DEV_H */
|
@ -394,8 +394,8 @@ __archive_pathmatch(const char *p, const char *s, int flags)
|
|||||||
if (*p == '/' && *s != '/')
|
if (*p == '/' && *s != '/')
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/* Certain patterns and file names anchor implicitly. */
|
/* Certain patterns anchor implicitly. */
|
||||||
if (*p == '*' || *p == '/' || *p == '/') {
|
if (*p == '*' || *p == '/') {
|
||||||
while (*p == '/')
|
while (*p == '/')
|
||||||
++p;
|
++p;
|
||||||
while (*s == '/')
|
while (*s == '/')
|
||||||
@ -434,8 +434,8 @@ __archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags)
|
|||||||
if (*p == L'/' && *s != L'/')
|
if (*p == L'/' && *s != L'/')
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/* Certain patterns and file names anchor implicitly. */
|
/* Certain patterns anchor implicitly. */
|
||||||
if (*p == L'*' || *p == L'/' || *p == L'/') {
|
if (*p == L'*' || *p == L'/') {
|
||||||
while (*p == L'/')
|
while (*p == L'/')
|
||||||
++p;
|
++p;
|
||||||
while (*s == L'/')
|
while (*s == L'/')
|
||||||
|
@ -66,15 +66,18 @@
|
|||||||
* headers as required.
|
* headers as required.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Get a real definition for __FBSDID if we can */
|
/* Get a real definition for __FBSDID or __RCSID if we can */
|
||||||
#if HAVE_SYS_CDEFS_H
|
#if HAVE_SYS_CDEFS_H
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If not, define it so as to avoid dangling semicolons. */
|
/* If not, define them so as to avoid dangling semicolons. */
|
||||||
#ifndef __FBSDID
|
#ifndef __FBSDID
|
||||||
#define __FBSDID(a) struct _undefined_hack
|
#define __FBSDID(a) struct _undefined_hack
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef __RCSID
|
||||||
|
#define __RCSID(a) struct _undefined_hack
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Try to get standard C99-style integer type definitions. */
|
/* Try to get standard C99-style integer type definitions. */
|
||||||
#if HAVE_INTTYPES_H
|
#if HAVE_INTTYPES_H
|
||||||
@ -114,6 +117,12 @@
|
|||||||
#if !HAVE_DECL_UINT32_MAX
|
#if !HAVE_DECL_UINT32_MAX
|
||||||
#define UINT32_MAX (~(uint32_t)0)
|
#define UINT32_MAX (~(uint32_t)0)
|
||||||
#endif
|
#endif
|
||||||
|
#if !HAVE_DECL_INT32_MAX
|
||||||
|
#define INT32_MAX ((int32_t)(UINT32_MAX >> 1))
|
||||||
|
#endif
|
||||||
|
#if !HAVE_DECL_INT32_MIN
|
||||||
|
#define INT32_MIN ((int32_t)(~INT32_MAX))
|
||||||
|
#endif
|
||||||
#if !HAVE_DECL_UINT64_MAX
|
#if !HAVE_DECL_UINT64_MAX
|
||||||
#define UINT64_MAX (~(uint64_t)0)
|
#define UINT64_MAX (~(uint64_t)0)
|
||||||
#endif
|
#endif
|
||||||
@ -123,6 +132,15 @@
|
|||||||
#if !HAVE_DECL_INT64_MIN
|
#if !HAVE_DECL_INT64_MIN
|
||||||
#define INT64_MIN ((int64_t)(~INT64_MAX))
|
#define INT64_MIN ((int64_t)(~INT64_MAX))
|
||||||
#endif
|
#endif
|
||||||
|
#if !HAVE_DECL_UINTMAX_MAX
|
||||||
|
#define UINTMAX_MAX (~(uintmax_t)0)
|
||||||
|
#endif
|
||||||
|
#if !HAVE_DECL_INTMAX_MAX
|
||||||
|
#define INTMAX_MAX ((intmax_t)(UINTMAX_MAX >> 1))
|
||||||
|
#endif
|
||||||
|
#if !HAVE_DECL_INTMAX_MIN
|
||||||
|
#define INTMAX_MIN ((intmax_t)(~INTMAX_MAX))
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
|
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
|
||||||
|
@ -119,6 +119,23 @@ struct archive {
|
|||||||
unsigned current_codepage; /* Current ACP(ANSI CodePage). */
|
unsigned current_codepage; /* Current ACP(ANSI CodePage). */
|
||||||
unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */
|
unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */
|
||||||
struct archive_string_conv *sconv;
|
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. */
|
/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
|
||||||
@ -139,6 +156,8 @@ int __archive_mktemp(const char *tmpdir);
|
|||||||
|
|
||||||
int __archive_clean(struct archive *);
|
int __archive_clean(struct archive *);
|
||||||
|
|
||||||
|
void __archive_reset_read_data(struct archive *);
|
||||||
|
|
||||||
#define err_combine(a,b) ((a) < (b) ? (a) : (b))
|
#define err_combine(a,b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER <= 1300)
|
#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER <= 1300)
|
||||||
|
269
contrib/libarchive/libarchive/archive_random.c
Normal file
269
contrib/libarchive/libarchive/archive_random.c
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
/*-
|
||||||
|
* 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() == 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.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 1024; 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
contrib/libarchive/libarchive/archive_random_private.h
Normal file
36
contrib/libarchive/libarchive/archive_random_private.h
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 __LIBARCHIVE_BUILD
|
||||||
|
#error This header is only to be used internally to libarchive.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
|
||||||
|
#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
|
||||||
|
|
||||||
|
/* Random number generator. */
|
||||||
|
int archive_random(void *buf, size_t nbytes);
|
||||||
|
|
||||||
|
#endif /* ARCHIVE_RANDOM_PRIVATE_H_INCLUDED */
|
@ -130,7 +130,7 @@ which provides a slightly more efficient interface.
|
|||||||
You may prefer to use the higher-level
|
You may prefer to use the higher-level
|
||||||
.Fn archive_read_data_skip ,
|
.Fn archive_read_data_skip ,
|
||||||
which reads and discards the data for this entry,
|
which reads and discards the data for this entry,
|
||||||
.Fn archive_read_data_to_file ,
|
.Fn archive_read_data_into_fd ,
|
||||||
which copies the data to the provided file descriptor, or
|
which copies the data to the provided file descriptor, or
|
||||||
.Fn archive_read_extract ,
|
.Fn archive_read_extract ,
|
||||||
which recreates the specified entry on disk and copies data
|
which recreates the specified entry on disk and copies data
|
||||||
@ -186,7 +186,7 @@ list_archive(const char *name)
|
|||||||
free(mydata);
|
free(mydata);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
la_ssize_t
|
||||||
myread(struct archive *a, void *client_data, const void **buff)
|
myread(struct archive *a, void *client_data, const void **buff)
|
||||||
{
|
{
|
||||||
struct mydata *mydata = client_data;
|
struct mydata *mydata = client_data;
|
||||||
|
@ -101,16 +101,17 @@ archive_read_new(void)
|
|||||||
{
|
{
|
||||||
struct archive_read *a;
|
struct archive_read *a;
|
||||||
|
|
||||||
a = (struct archive_read *)malloc(sizeof(*a));
|
a = (struct archive_read *)calloc(1, sizeof(*a));
|
||||||
if (a == NULL)
|
if (a == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
memset(a, 0, sizeof(*a));
|
|
||||||
a->archive.magic = ARCHIVE_READ_MAGIC;
|
a->archive.magic = ARCHIVE_READ_MAGIC;
|
||||||
|
|
||||||
a->archive.state = ARCHIVE_STATE_NEW;
|
a->archive.state = ARCHIVE_STATE_NEW;
|
||||||
a->entry = archive_entry_new2(&a->archive);
|
a->entry = archive_entry_new2(&a->archive);
|
||||||
a->archive.vtable = archive_read_vtable();
|
a->archive.vtable = archive_read_vtable();
|
||||||
|
|
||||||
|
a->passphrases.last = &a->passphrases.first;
|
||||||
|
|
||||||
return (&a->archive);
|
return (&a->archive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,10 +195,12 @@ client_skip_proxy(struct archive_read_filter *self, int64_t request)
|
|||||||
ask = skip_limit;
|
ask = skip_limit;
|
||||||
get = (self->archive->client.skipper)
|
get = (self->archive->client.skipper)
|
||||||
(&self->archive->archive, self->data, ask);
|
(&self->archive->archive, self->data, ask);
|
||||||
if (get == 0)
|
|
||||||
return (total);
|
|
||||||
request -= get;
|
|
||||||
total += get;
|
total += get;
|
||||||
|
if (get == 0 || get == request)
|
||||||
|
return (total);
|
||||||
|
if (get > request)
|
||||||
|
return ARCHIVE_FATAL;
|
||||||
|
request -= get;
|
||||||
}
|
}
|
||||||
} else if (self->archive->client.seeker != NULL
|
} else if (self->archive->client.seeker != NULL
|
||||||
&& request > 64 * 1024) {
|
&& request > 64 * 1024) {
|
||||||
@ -230,8 +233,11 @@ client_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence)
|
|||||||
* other libarchive code that assumes a successful forward
|
* other libarchive code that assumes a successful forward
|
||||||
* seek means it can also seek backwards.
|
* seek means it can also seek backwards.
|
||||||
*/
|
*/
|
||||||
if (self->archive->client.seeker == NULL)
|
if (self->archive->client.seeker == NULL) {
|
||||||
|
archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
|
||||||
|
"Current client reader does not support seeking a device");
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
|
}
|
||||||
return (self->archive->client.seeker)(&self->archive->archive,
|
return (self->archive->client.seeker)(&self->archive->archive,
|
||||||
self->data, offset, whence);
|
self->data, offset, whence);
|
||||||
}
|
}
|
||||||
@ -454,8 +460,7 @@ archive_read_open1(struct archive *_a)
|
|||||||
{
|
{
|
||||||
struct archive_read *a = (struct archive_read *)_a;
|
struct archive_read *a = (struct archive_read *)_a;
|
||||||
struct archive_read_filter *filter, *tmp;
|
struct archive_read_filter *filter, *tmp;
|
||||||
int slot;
|
int slot, e = ARCHIVE_OK;
|
||||||
int e = 0;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
||||||
@ -542,16 +547,20 @@ archive_read_open1(struct archive *_a)
|
|||||||
* it wants to handle this stream. Repeat until we've finished
|
* it wants to handle this stream. Repeat until we've finished
|
||||||
* building the pipeline.
|
* building the pipeline.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* We won't build a filter pipeline with more stages than this. */
|
||||||
|
#define MAX_NUMBER_FILTERS 25
|
||||||
|
|
||||||
static int
|
static int
|
||||||
choose_filters(struct archive_read *a)
|
choose_filters(struct archive_read *a)
|
||||||
{
|
{
|
||||||
int number_bidders, i, bid, best_bid, n;
|
int number_bidders, i, bid, best_bid, number_filters;
|
||||||
struct archive_read_filter_bidder *bidder, *best_bidder;
|
struct archive_read_filter_bidder *bidder, *best_bidder;
|
||||||
struct archive_read_filter *filter;
|
struct archive_read_filter *filter;
|
||||||
ssize_t avail;
|
ssize_t avail;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
for (n = 0; n < 25; ++n) {
|
for (number_filters = 0; number_filters < MAX_NUMBER_FILTERS; ++number_filters) {
|
||||||
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
|
number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
|
||||||
|
|
||||||
best_bid = 0;
|
best_bid = 0;
|
||||||
@ -662,16 +671,14 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
a->read_data_output_offset = 0;
|
__archive_reset_read_data(&a->archive);
|
||||||
a->read_data_remaining = 0;
|
|
||||||
a->read_data_is_posix_read = 0;
|
|
||||||
a->read_data_requested = 0;
|
|
||||||
a->data_start_node = a->client.cursor;
|
a->data_start_node = a->client.cursor;
|
||||||
/* EOF always wins; otherwise return the worst error. */
|
/* EOF always wins; otherwise return the worst error. */
|
||||||
return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1;
|
return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
|
_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -750,6 +757,59 @@ archive_read_header_position(struct archive *_a)
|
|||||||
return (a->header_position);
|
return (a->header_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if the archive contains at least one encrypted entry.
|
||||||
|
* If the archive format not support encryption at all
|
||||||
|
* ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned.
|
||||||
|
* If for any other reason (e.g. not enough data read so far)
|
||||||
|
* we cannot say whether there are encrypted entries, then
|
||||||
|
* ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned.
|
||||||
|
* In general, this function will return values below zero when the
|
||||||
|
* reader is uncertain or totally uncapable of encryption support.
|
||||||
|
* When this function returns 0 you can be sure that the reader
|
||||||
|
* supports encryption detection but no encrypted entries have
|
||||||
|
* been found yet.
|
||||||
|
*
|
||||||
|
* NOTE: If the metadata/header of an archive is also encrypted, you
|
||||||
|
* cannot rely on the number of encrypted entries. That is why this
|
||||||
|
* function does not return the number of encrypted entries but#
|
||||||
|
* just shows that there are some.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
archive_read_has_encrypted_entries(struct archive *_a)
|
||||||
|
{
|
||||||
|
struct archive_read *a = (struct archive_read *)_a;
|
||||||
|
int format_supports_encryption = archive_read_format_capabilities(_a)
|
||||||
|
& (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
|
||||||
|
|
||||||
|
if (!_a || !format_supports_encryption) {
|
||||||
|
/* Format in general doesn't support encryption */
|
||||||
|
return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A reader potentially has read enough data now. */
|
||||||
|
if (a->format && a->format->has_encrypted_entries) {
|
||||||
|
return (a->format->has_encrypted_entries)(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For any other reason we cannot say how many entries are there. */
|
||||||
|
return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a bitmask of capabilities that are supported by the archive format reader.
|
||||||
|
* If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
archive_read_format_capabilities(struct archive *_a)
|
||||||
|
{
|
||||||
|
struct archive_read *a = (struct archive_read *)_a;
|
||||||
|
if (a && a->format && a->format->format_capabilties) {
|
||||||
|
return (a->format->format_capabilties)(a);
|
||||||
|
}
|
||||||
|
return ARCHIVE_READ_FORMAT_CAPS_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read data from an archive entry, using a read(2)-style interface.
|
* Read data from an archive entry, using a read(2)-style interface.
|
||||||
* This is a convenience routine that just calls
|
* This is a convenience routine that just calls
|
||||||
@ -764,7 +824,7 @@ archive_read_header_position(struct archive *_a)
|
|||||||
ssize_t
|
ssize_t
|
||||||
archive_read_data(struct archive *_a, void *buff, size_t s)
|
archive_read_data(struct archive *_a, void *buff, size_t s)
|
||||||
{
|
{
|
||||||
struct archive_read *a = (struct archive_read *)_a;
|
struct archive *a = (struct archive *)_a;
|
||||||
char *dest;
|
char *dest;
|
||||||
const void *read_buf;
|
const void *read_buf;
|
||||||
size_t bytes_read;
|
size_t bytes_read;
|
||||||
@ -779,7 +839,7 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
|
|||||||
read_buf = a->read_data_block;
|
read_buf = a->read_data_block;
|
||||||
a->read_data_is_posix_read = 1;
|
a->read_data_is_posix_read = 1;
|
||||||
a->read_data_requested = s;
|
a->read_data_requested = s;
|
||||||
r = _archive_read_data_block(&a->archive, &read_buf,
|
r = archive_read_data_block(a, &read_buf,
|
||||||
&a->read_data_remaining, &a->read_data_offset);
|
&a->read_data_remaining, &a->read_data_offset);
|
||||||
a->read_data_block = read_buf;
|
a->read_data_block = read_buf;
|
||||||
if (r == ARCHIVE_EOF)
|
if (r == ARCHIVE_EOF)
|
||||||
@ -794,7 +854,7 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (a->read_data_offset < a->read_data_output_offset) {
|
if (a->read_data_offset < a->read_data_output_offset) {
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
"Encountered out-of-order sparse blocks");
|
"Encountered out-of-order sparse blocks");
|
||||||
return (ARCHIVE_RETRY);
|
return (ARCHIVE_RETRY);
|
||||||
}
|
}
|
||||||
@ -837,6 +897,21 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
|
|||||||
return (bytes_read);
|
return (bytes_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset the read_data_* variables, used for starting a new entry.
|
||||||
|
*/
|
||||||
|
void __archive_reset_read_data(struct archive * a)
|
||||||
|
{
|
||||||
|
a->read_data_output_offset = 0;
|
||||||
|
a->read_data_remaining = 0;
|
||||||
|
a->read_data_is_posix_read = 0;
|
||||||
|
a->read_data_requested = 0;
|
||||||
|
|
||||||
|
/* extra resets, from rar.c */
|
||||||
|
a->read_data_block = NULL;
|
||||||
|
a->read_data_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip over all remaining data in this entry.
|
* Skip over all remaining data in this entry.
|
||||||
*/
|
*/
|
||||||
@ -904,7 +979,7 @@ _archive_read_data_block(struct archive *_a,
|
|||||||
if (a->format->read_data == NULL) {
|
if (a->format->read_data == NULL) {
|
||||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
||||||
"Internal error: "
|
"Internal error: "
|
||||||
"No format_read_data_block function registered");
|
"No format->read_data function registered");
|
||||||
return (ARCHIVE_FATAL);
|
return (ARCHIVE_FATAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -991,6 +1066,7 @@ static int
|
|||||||
_archive_read_free(struct archive *_a)
|
_archive_read_free(struct archive *_a)
|
||||||
{
|
{
|
||||||
struct archive_read *a = (struct archive_read *)_a;
|
struct archive_read *a = (struct archive_read *)_a;
|
||||||
|
struct archive_read_passphrase *p;
|
||||||
int i, n;
|
int i, n;
|
||||||
int slots;
|
int slots;
|
||||||
int r = ARCHIVE_OK;
|
int r = ARCHIVE_OK;
|
||||||
@ -1028,8 +1104,19 @@ _archive_read_free(struct archive *_a)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release passphrase list. */
|
||||||
|
p = a->passphrases.first;
|
||||||
|
while (p != NULL) {
|
||||||
|
struct archive_read_passphrase *np = p->next;
|
||||||
|
|
||||||
|
/* A passphrase should be cleaned. */
|
||||||
|
memset(p->passphrase, 0, strlen(p->passphrase));
|
||||||
|
free(p->passphrase);
|
||||||
|
free(p);
|
||||||
|
p = np;
|
||||||
|
}
|
||||||
|
|
||||||
archive_string_free(&a->archive.error_string);
|
archive_string_free(&a->archive.error_string);
|
||||||
if (a->entry)
|
|
||||||
archive_entry_free(a->entry);
|
archive_entry_free(a->entry);
|
||||||
a->archive.magic = 0;
|
a->archive.magic = 0;
|
||||||
__archive_clean(&a->archive);
|
__archive_clean(&a->archive);
|
||||||
@ -1074,7 +1161,7 @@ static const char *
|
|||||||
_archive_filter_name(struct archive *_a, int n)
|
_archive_filter_name(struct archive *_a, int n)
|
||||||
{
|
{
|
||||||
struct archive_read_filter *f = get_filter(_a, n);
|
struct archive_read_filter *f = get_filter(_a, n);
|
||||||
return f == NULL ? NULL : f->name;
|
return f != NULL ? f->name : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t
|
static int64_t
|
||||||
@ -1098,7 +1185,9 @@ __archive_read_register_format(struct archive_read *a,
|
|||||||
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
|
int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
|
||||||
int (*read_data_skip)(struct archive_read *),
|
int (*read_data_skip)(struct archive_read *),
|
||||||
int64_t (*seek_data)(struct archive_read *, int64_t, int),
|
int64_t (*seek_data)(struct archive_read *, int64_t, int),
|
||||||
int (*cleanup)(struct archive_read *))
|
int (*cleanup)(struct archive_read *),
|
||||||
|
int (*format_capabilities)(struct archive_read *),
|
||||||
|
int (*has_encrypted_entries)(struct archive_read *))
|
||||||
{
|
{
|
||||||
int i, number_slots;
|
int i, number_slots;
|
||||||
|
|
||||||
@ -1121,6 +1210,8 @@ __archive_read_register_format(struct archive_read *a,
|
|||||||
a->formats[i].cleanup = cleanup;
|
a->formats[i].cleanup = cleanup;
|
||||||
a->formats[i].data = format_data;
|
a->formats[i].data = format_data;
|
||||||
a->formats[i].name = name;
|
a->formats[i].name = name;
|
||||||
|
a->formats[i].format_capabilties = format_capabilities;
|
||||||
|
a->formats[i].has_encrypted_entries = has_encrypted_entries;
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1563,10 +1654,9 @@ __archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset,
|
|||||||
client->dataset[++cursor].begin_position = r;
|
client->dataset[++cursor].begin_position = r;
|
||||||
}
|
}
|
||||||
offset -= client->dataset[cursor].begin_position;
|
offset -= client->dataset[cursor].begin_position;
|
||||||
if (offset < 0)
|
if (offset < 0
|
||||||
offset = 0;
|
|| offset > client->dataset[cursor].total_size)
|
||||||
else if (offset > client->dataset[cursor].total_size - 1)
|
return ARCHIVE_FATAL;
|
||||||
offset = client->dataset[cursor].total_size - 1;
|
|
||||||
if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0)
|
if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
|
74
contrib/libarchive/libarchive/archive_read_add_passphrase.3
Normal file
74
contrib/libarchive/libarchive/archive_read_add_passphrase.3
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 callback function that will be invoked to get a passphrase
|
||||||
|
for decrption after trying all passphrases registered by the
|
||||||
|
.Fn archive_read_add_passphrase
|
||||||
|
function failed.
|
||||||
|
.El
|
||||||
|
.\" .Sh ERRORS
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr tar 1 ,
|
||||||
|
.Xr libarchive 3 ,
|
||||||
|
.Xr archive_read 3 ,
|
||||||
|
.Xr archive_read_set_options 3
|
186
contrib/libarchive/libarchive/archive_read_add_passphrase.c
Normal file
186
contrib/libarchive/libarchive/archive_read_add_passphrase.c
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.candiate = -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.candiate < 0) {
|
||||||
|
/* Count out how many passphrases we have. */
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
for (p = a->passphrases.first; p != NULL; p = p->next)
|
||||||
|
cnt++;
|
||||||
|
a->passphrases.candiate = cnt;
|
||||||
|
p = a->passphrases.first;
|
||||||
|
} else if (a->passphrases.candiate > 1) {
|
||||||
|
/* Rotate a passphrase list. */
|
||||||
|
a->passphrases.candiate--;
|
||||||
|
p = remove_passphrases_from_head(a);
|
||||||
|
add_passphrase_to_tail(a, p);
|
||||||
|
/* Pick a new passphrase candiate up. */
|
||||||
|
p = a->passphrases.first;
|
||||||
|
} else if (a->passphrases.candiate == 1) {
|
||||||
|
/* This case is that all cadiates failed to decryption. */
|
||||||
|
a->passphrases.candiate = 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 candaite. */
|
||||||
|
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.candiate = 1;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
passphrase = NULL;
|
||||||
|
|
||||||
|
return (passphrase);
|
||||||
|
}
|
@ -43,7 +43,7 @@ archive_read_append_filter(struct archive *_a, int code)
|
|||||||
struct archive_read_filter *filter;
|
struct archive_read_filter *filter;
|
||||||
struct archive_read *a = (struct archive_read *)_a;
|
struct archive_read *a = (struct archive_read *)_a;
|
||||||
|
|
||||||
r1 = r2 = (ARCHIVE_OK);
|
r2 = (ARCHIVE_OK);
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case ARCHIVE_FILTER_NONE:
|
case ARCHIVE_FILTER_NONE:
|
||||||
@ -85,6 +85,10 @@ archive_read_append_filter(struct archive *_a, int code)
|
|||||||
strcpy(str, "rpm");
|
strcpy(str, "rpm");
|
||||||
r1 = archive_read_support_filter_rpm(_a);
|
r1 = archive_read_support_filter_rpm(_a);
|
||||||
break;
|
break;
|
||||||
|
case ARCHIVE_FILTER_LZ4:
|
||||||
|
strcpy(str, "lz4");
|
||||||
|
r1 = archive_read_support_filter_lz4(_a);
|
||||||
|
break;
|
||||||
case ARCHIVE_FILTER_LZIP:
|
case ARCHIVE_FILTER_LZIP:
|
||||||
strcpy(str, "lzip");
|
strcpy(str, "lzip");
|
||||||
r1 = archive_read_support_filter_lzip(_a);
|
r1 = archive_read_support_filter_lzip(_a);
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
Streaming Archive Library (libarchive, -larchive)
|
Streaming Archive Library (libarchive, -larchive)
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.In archive.h
|
.In archive.h
|
||||||
.Ft ssize_t
|
.Ft la_ssize_t
|
||||||
.Fn archive_read_data "struct archive *" "void *buff" "size_t len"
|
.Fn archive_read_data "struct archive *" "void *buff" "size_t len"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fo archive_read_data_block
|
.Fo archive_read_data_block
|
||||||
|
@ -251,9 +251,11 @@ archive_read_disk_entry_from_file(struct archive *_a,
|
|||||||
#endif /* HAVE_READLINK || HAVE_READLINKAT */
|
#endif /* HAVE_READLINK || HAVE_READLINKAT */
|
||||||
|
|
||||||
r = setup_acls(a, entry, &fd);
|
r = setup_acls(a, entry, &fd);
|
||||||
|
if (!a->suppress_xattr) {
|
||||||
r1 = setup_xattrs(a, entry, &fd);
|
r1 = setup_xattrs(a, entry, &fd);
|
||||||
if (r1 < r)
|
if (r1 < r)
|
||||||
r = r1;
|
r = r1;
|
||||||
|
}
|
||||||
if (a->enable_copyfile) {
|
if (a->enable_copyfile) {
|
||||||
r1 = setup_mac_metadata(a, entry, &fd);
|
r1 = setup_mac_metadata(a, entry, &fd);
|
||||||
if (r1 < r)
|
if (r1 < r)
|
||||||
@ -399,7 +401,7 @@ setup_mac_metadata(struct archive_read_disk *a,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_POSIX_ACL) && defined(ACL_TYPE_NFS4)
|
#ifdef HAVE_POSIX_ACL
|
||||||
static int translate_acl(struct archive_read_disk *a,
|
static int translate_acl(struct archive_read_disk *a,
|
||||||
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
|
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
|
||||||
|
|
||||||
@ -419,6 +421,7 @@ setup_acls(struct archive_read_disk *a,
|
|||||||
|
|
||||||
archive_entry_acl_clear(entry);
|
archive_entry_acl_clear(entry);
|
||||||
|
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
/* Try NFS4 ACL first. */
|
/* Try NFS4 ACL first. */
|
||||||
if (*fd >= 0)
|
if (*fd >= 0)
|
||||||
acl = acl_get_fd(*fd);
|
acl = acl_get_fd(*fd);
|
||||||
@ -447,6 +450,7 @@ setup_acls(struct archive_read_disk *a,
|
|||||||
acl_free(acl);
|
acl_free(acl);
|
||||||
return (ARCHIVE_OK);
|
return (ARCHIVE_OK);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Retrieve access ACL from file. */
|
/* Retrieve access ACL from file. */
|
||||||
if (*fd >= 0)
|
if (*fd >= 0)
|
||||||
@ -492,6 +496,7 @@ static struct {
|
|||||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||||
@ -508,8 +513,10 @@ static struct {
|
|||||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
||||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
static struct {
|
static struct {
|
||||||
int archive_inherit;
|
int archive_inherit;
|
||||||
int platform_inherit;
|
int platform_inherit;
|
||||||
@ -519,20 +526,24 @@ static struct {
|
|||||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_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_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
static int
|
static int
|
||||||
translate_acl(struct archive_read_disk *a,
|
translate_acl(struct archive_read_disk *a,
|
||||||
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
|
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
|
||||||
{
|
{
|
||||||
acl_tag_t acl_tag;
|
acl_tag_t acl_tag;
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
acl_entry_type_t acl_type;
|
acl_entry_type_t acl_type;
|
||||||
acl_flagset_t acl_flagset;
|
acl_flagset_t acl_flagset;
|
||||||
|
int brand, r;
|
||||||
|
#endif
|
||||||
acl_entry_t acl_entry;
|
acl_entry_t acl_entry;
|
||||||
acl_permset_t acl_permset;
|
acl_permset_t acl_permset;
|
||||||
int brand, i, r, entry_acl_type;
|
int i, entry_acl_type;
|
||||||
int s, ae_id, ae_tag, ae_perm;
|
int s, ae_id, ae_tag, ae_perm;
|
||||||
const char *ae_name;
|
const char *ae_name;
|
||||||
|
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
|
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
|
||||||
// Make sure the "brand" on this ACL is consistent
|
// Make sure the "brand" on this ACL is consistent
|
||||||
// with the default_entry_acl_type bits provided.
|
// with the default_entry_acl_type bits provided.
|
||||||
@ -559,6 +570,7 @@ translate_acl(struct archive_read_disk *a,
|
|||||||
return ARCHIVE_FAILED;
|
return ARCHIVE_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
||||||
@ -591,9 +603,11 @@ translate_acl(struct archive_read_disk *a,
|
|||||||
case ACL_OTHER:
|
case ACL_OTHER:
|
||||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||||
break;
|
break;
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
case ACL_EVERYONE:
|
case ACL_EVERYONE:
|
||||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
/* Skip types that libarchive can't support. */
|
/* Skip types that libarchive can't support. */
|
||||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||||
@ -604,6 +618,7 @@ translate_acl(struct archive_read_disk *a,
|
|||||||
// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
|
// XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
|
||||||
// non-NFSv4 ACLs
|
// non-NFSv4 ACLs
|
||||||
entry_acl_type = default_entry_acl_type;
|
entry_acl_type = default_entry_acl_type;
|
||||||
|
#ifdef ACL_TYPE_NFS4
|
||||||
r = acl_get_entry_type_np(acl_entry, &acl_type);
|
r = acl_get_entry_type_np(acl_entry, &acl_type);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
switch (acl_type) {
|
switch (acl_type) {
|
||||||
@ -633,6 +648,7 @@ translate_acl(struct archive_read_disk *a,
|
|||||||
ae_perm |= acl_inherit_map[i].archive_inherit;
|
ae_perm |= acl_inherit_map[i].archive_inherit;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
acl_get_permset(acl_entry, &acl_permset);
|
acl_get_permset(acl_entry, &acl_permset);
|
||||||
for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
|
for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
|
||||||
@ -1029,7 +1045,7 @@ setup_sparse(struct archive_read_disk *a,
|
|||||||
struct fiemap *fm;
|
struct fiemap *fm;
|
||||||
struct fiemap_extent *fe;
|
struct fiemap_extent *fe;
|
||||||
int64_t size;
|
int64_t size;
|
||||||
int count, do_fiemap;
|
int count, do_fiemap, iters;
|
||||||
int exit_sts = ARCHIVE_OK;
|
int exit_sts = ARCHIVE_OK;
|
||||||
|
|
||||||
if (archive_entry_filetype(entry) != AE_IFREG
|
if (archive_entry_filetype(entry) != AE_IFREG
|
||||||
@ -1066,7 +1082,7 @@ setup_sparse(struct archive_read_disk *a,
|
|||||||
fm->fm_extent_count = count;
|
fm->fm_extent_count = count;
|
||||||
do_fiemap = 1;
|
do_fiemap = 1;
|
||||||
size = archive_entry_size(entry);
|
size = archive_entry_size(entry);
|
||||||
for (;;) {
|
for (iters = 0; ; ++iters) {
|
||||||
int i, r;
|
int i, r;
|
||||||
|
|
||||||
r = ioctl(*fd, FS_IOC_FIEMAP, fm);
|
r = ioctl(*fd, FS_IOC_FIEMAP, fm);
|
||||||
@ -1076,8 +1092,13 @@ setup_sparse(struct archive_read_disk *a,
|
|||||||
* version(<2.6.28) cannot perfom FS_IOC_FIEMAP. */
|
* version(<2.6.28) cannot perfom FS_IOC_FIEMAP. */
|
||||||
goto exit_setup_sparse;
|
goto exit_setup_sparse;
|
||||||
}
|
}
|
||||||
if (fm->fm_mapped_extents == 0)
|
if (fm->fm_mapped_extents == 0) {
|
||||||
|
if (iters == 0) {
|
||||||
|
/* Fully sparse file; insert a zero-length "data" entry */
|
||||||
|
archive_entry_sparse_add_entry(entry, 0, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
fe = fm->fm_extents;
|
fe = fm->fm_extents;
|
||||||
for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) {
|
for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) {
|
||||||
if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
|
if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
|
||||||
@ -1122,6 +1143,7 @@ setup_sparse(struct archive_read_disk *a,
|
|||||||
off_t initial_off; /* FreeBSD/Solaris only, so off_t okay here */
|
off_t initial_off; /* FreeBSD/Solaris only, so off_t okay here */
|
||||||
off_t off_s, off_e; /* FreeBSD/Solaris only, so off_t okay here */
|
off_t off_s, off_e; /* FreeBSD/Solaris only, so off_t okay here */
|
||||||
int exit_sts = ARCHIVE_OK;
|
int exit_sts = ARCHIVE_OK;
|
||||||
|
int check_fully_sparse = 0;
|
||||||
|
|
||||||
if (archive_entry_filetype(entry) != AE_IFREG
|
if (archive_entry_filetype(entry) != AE_IFREG
|
||||||
|| archive_entry_size(entry) <= 0
|
|| archive_entry_size(entry) <= 0
|
||||||
@ -1174,8 +1196,14 @@ setup_sparse(struct archive_read_disk *a,
|
|||||||
while (off_s < size) {
|
while (off_s < size) {
|
||||||
off_s = lseek(*fd, off_s, SEEK_DATA);
|
off_s = lseek(*fd, off_s, SEEK_DATA);
|
||||||
if (off_s == (off_t)-1) {
|
if (off_s == (off_t)-1) {
|
||||||
if (errno == ENXIO)
|
if (errno == ENXIO) {
|
||||||
break;/* no more hole */
|
/* no more hole */
|
||||||
|
if (archive_entry_sparse_count(entry) == 0) {
|
||||||
|
/* Potentially a fully-sparse file. */
|
||||||
|
check_fully_sparse = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
archive_set_error(&a->archive, errno,
|
archive_set_error(&a->archive, errno,
|
||||||
"lseek(SEEK_HOLE) failed");
|
"lseek(SEEK_HOLE) failed");
|
||||||
exit_sts = ARCHIVE_FAILED;
|
exit_sts = ARCHIVE_FAILED;
|
||||||
@ -1199,6 +1227,14 @@ setup_sparse(struct archive_read_disk *a,
|
|||||||
off_e - off_s);
|
off_e - off_s);
|
||||||
off_s = off_e;
|
off_s = off_e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (check_fully_sparse) {
|
||||||
|
if (lseek(*fd, 0, SEEK_HOLE) == 0 &&
|
||||||
|
lseek(*fd, 0, SEEK_END) == size) {
|
||||||
|
/* Fully sparse file; insert a zero-length "data" entry */
|
||||||
|
archive_entry_sparse_add_entry(entry, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
exit_setup_sparse:
|
exit_setup_sparse:
|
||||||
lseek(*fd, initial_off, SEEK_SET);
|
lseek(*fd, initial_off, SEEK_SET);
|
||||||
return (exit_sts);
|
return (exit_sts);
|
||||||
|
@ -356,6 +356,8 @@ static int _archive_read_free(struct archive *);
|
|||||||
static int _archive_read_close(struct archive *);
|
static int _archive_read_close(struct archive *);
|
||||||
static int _archive_read_data_block(struct archive *,
|
static int _archive_read_data_block(struct archive *,
|
||||||
const void **, size_t *, int64_t *);
|
const void **, size_t *, int64_t *);
|
||||||
|
static int _archive_read_next_header(struct archive *,
|
||||||
|
struct archive_entry **);
|
||||||
static int _archive_read_next_header2(struct archive *,
|
static int _archive_read_next_header2(struct archive *,
|
||||||
struct archive_entry *);
|
struct archive_entry *);
|
||||||
static const char *trivial_lookup_gname(void *, int64_t gid);
|
static const char *trivial_lookup_gname(void *, int64_t gid);
|
||||||
@ -377,6 +379,7 @@ archive_read_disk_vtable(void)
|
|||||||
av.archive_free = _archive_read_free;
|
av.archive_free = _archive_read_free;
|
||||||
av.archive_close = _archive_read_close;
|
av.archive_close = _archive_read_close;
|
||||||
av.archive_read_data_block = _archive_read_data_block;
|
av.archive_read_data_block = _archive_read_data_block;
|
||||||
|
av.archive_read_next_header = _archive_read_next_header;
|
||||||
av.archive_read_next_header2 = _archive_read_next_header2;
|
av.archive_read_next_header2 = _archive_read_next_header2;
|
||||||
inited = 1;
|
inited = 1;
|
||||||
}
|
}
|
||||||
@ -459,6 +462,7 @@ archive_read_disk_new(void)
|
|||||||
a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
|
a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
|
||||||
a->archive.state = ARCHIVE_STATE_NEW;
|
a->archive.state = ARCHIVE_STATE_NEW;
|
||||||
a->archive.vtable = archive_read_disk_vtable();
|
a->archive.vtable = archive_read_disk_vtable();
|
||||||
|
a->entry = archive_entry_new2(&a->archive);
|
||||||
a->lookup_uname = trivial_lookup_uname;
|
a->lookup_uname = trivial_lookup_uname;
|
||||||
a->lookup_gname = trivial_lookup_gname;
|
a->lookup_gname = trivial_lookup_gname;
|
||||||
a->enable_copyfile = 1;
|
a->enable_copyfile = 1;
|
||||||
@ -491,6 +495,7 @@ _archive_read_free(struct archive *_a)
|
|||||||
if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
|
if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
|
||||||
(a->cleanup_uname)(a->lookup_uname_data);
|
(a->cleanup_uname)(a->lookup_uname_data);
|
||||||
archive_string_free(&a->archive.error_string);
|
archive_string_free(&a->archive.error_string);
|
||||||
|
archive_entry_free(a->entry);
|
||||||
a->archive.magic = 0;
|
a->archive.magic = 0;
|
||||||
__archive_clean(&a->archive);
|
__archive_clean(&a->archive);
|
||||||
free(a);
|
free(a);
|
||||||
@ -609,6 +614,10 @@ archive_read_disk_set_behavior(struct archive *_a, int flags)
|
|||||||
a->traverse_mount_points = 0;
|
a->traverse_mount_points = 0;
|
||||||
else
|
else
|
||||||
a->traverse_mount_points = 1;
|
a->traverse_mount_points = 1;
|
||||||
|
if (flags & ARCHIVE_READDISK_NO_XATTR)
|
||||||
|
a->suppress_xattr = 1;
|
||||||
|
else
|
||||||
|
a->suppress_xattr = 0;
|
||||||
return (r);
|
return (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,6 +717,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
|||||||
int r;
|
int r;
|
||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
size_t buffbytes;
|
size_t buffbytes;
|
||||||
|
int empty_sparse_region = 0;
|
||||||
|
|
||||||
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
|
archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
|
||||||
"archive_read_data_block");
|
"archive_read_data_block");
|
||||||
@ -789,6 +799,9 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
|||||||
if ((int64_t)buffbytes > t->current_sparse->length)
|
if ((int64_t)buffbytes > t->current_sparse->length)
|
||||||
buffbytes = t->current_sparse->length;
|
buffbytes = t->current_sparse->length;
|
||||||
|
|
||||||
|
if (t->current_sparse->length == 0)
|
||||||
|
empty_sparse_region = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip hole.
|
* Skip hole.
|
||||||
* TODO: Should we consider t->current_filesystem->xfer_align?
|
* TODO: Should we consider t->current_filesystem->xfer_align?
|
||||||
@ -819,7 +832,11 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
if (bytes == 0) {
|
/*
|
||||||
|
* Return an EOF unless we've read a leading empty sparse region, which
|
||||||
|
* is used to represent fully-sparse files.
|
||||||
|
*/
|
||||||
|
if (bytes == 0 && !empty_sparse_region) {
|
||||||
/* Get EOF */
|
/* Get EOF */
|
||||||
t->entry_eof = 1;
|
t->entry_eof = 1;
|
||||||
r = ARCHIVE_EOF;
|
r = ARCHIVE_EOF;
|
||||||
@ -1080,6 +1097,17 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
|||||||
return (r);
|
return (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct archive_read_disk *a = (struct archive_read_disk *)_a;
|
||||||
|
*entryp = NULL;
|
||||||
|
ret = _archive_read_next_header2(_a, a->entry);
|
||||||
|
*entryp = a->entry;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
|
_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
|
||||||
{
|
{
|
||||||
@ -1148,6 +1176,7 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__archive_reset_read_data(&a->archive);
|
||||||
return (r);
|
return (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1555,6 +1584,7 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||||||
#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
|
#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
|
||||||
t->current_filesystem->name_max = sfs.f_namemax;
|
t->current_filesystem->name_max = sfs.f_namemax;
|
||||||
#else
|
#else
|
||||||
|
# if defined(_PC_NAME_MAX)
|
||||||
/* Mac OS X does not have f_namemax in struct statfs. */
|
/* Mac OS X does not have f_namemax in struct statfs. */
|
||||||
if (tree_current_is_symblic_link_target(t)) {
|
if (tree_current_is_symblic_link_target(t)) {
|
||||||
if (tree_enter_working_dir(t) != 0) {
|
if (tree_enter_working_dir(t) != 0) {
|
||||||
@ -1564,6 +1594,9 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||||||
nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
|
nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
|
||||||
} else
|
} else
|
||||||
nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
|
nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
|
||||||
|
# else
|
||||||
|
nm = -1;
|
||||||
|
# endif
|
||||||
if (nm == -1)
|
if (nm == -1)
|
||||||
t->current_filesystem->name_max = NAME_MAX;
|
t->current_filesystem->name_max = NAME_MAX;
|
||||||
else
|
else
|
||||||
@ -1660,7 +1693,9 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||||||
{
|
{
|
||||||
struct tree *t = a->tree;
|
struct tree *t = a->tree;
|
||||||
struct statfs sfs;
|
struct statfs sfs;
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
struct statvfs svfs;
|
struct statvfs svfs;
|
||||||
|
#endif
|
||||||
int r, vr = 0, xr = 0;
|
int r, vr = 0, xr = 0;
|
||||||
|
|
||||||
if (tree_current_is_symblic_link_target(t)) {
|
if (tree_current_is_symblic_link_target(t)) {
|
||||||
@ -1677,7 +1712,9 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||||||
"openat failed");
|
"openat failed");
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
}
|
}
|
||||||
|
#if defined(HAVE_FSTATVFS)
|
||||||
vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */
|
vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */
|
||||||
|
#endif
|
||||||
r = fstatfs(fd, &sfs);
|
r = fstatfs(fd, &sfs);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
xr = get_xfer_size(t, fd, NULL);
|
xr = get_xfer_size(t, fd, NULL);
|
||||||
@ -1687,14 +1724,18 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||||||
archive_set_error(&a->archive, errno, "fchdir failed");
|
archive_set_error(&a->archive, errno, "fchdir failed");
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
}
|
}
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
vr = statvfs(tree_current_access_path(t), &svfs);
|
vr = statvfs(tree_current_access_path(t), &svfs);
|
||||||
|
#endif
|
||||||
r = statfs(tree_current_access_path(t), &sfs);
|
r = statfs(tree_current_access_path(t), &sfs);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
xr = get_xfer_size(t, -1, tree_current_access_path(t));
|
xr = get_xfer_size(t, -1, tree_current_access_path(t));
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef HAVE_FSTATFS
|
#ifdef HAVE_FSTATFS
|
||||||
|
#if defined(HAVE_FSTATVFS)
|
||||||
vr = fstatvfs(tree_current_dir_fd(t), &svfs);
|
vr = fstatvfs(tree_current_dir_fd(t), &svfs);
|
||||||
|
#endif
|
||||||
r = fstatfs(tree_current_dir_fd(t), &sfs);
|
r = fstatfs(tree_current_dir_fd(t), &sfs);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
|
xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
|
||||||
@ -1703,7 +1744,9 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||||||
archive_set_error(&a->archive, errno, "fchdir failed");
|
archive_set_error(&a->archive, errno, "fchdir failed");
|
||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
}
|
}
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
vr = statvfs(".", &svfs);
|
vr = statvfs(".", &svfs);
|
||||||
|
#endif
|
||||||
r = statfs(".", &sfs);
|
r = statfs(".", &sfs);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
xr = get_xfer_size(t, -1, ".");
|
xr = get_xfer_size(t, -1, ".");
|
||||||
@ -1716,10 +1759,17 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||||||
return (ARCHIVE_FAILED);
|
return (ARCHIVE_FAILED);
|
||||||
} else if (xr == 1) {
|
} else if (xr == 1) {
|
||||||
/* pathconf(_PC_REX_*) operations are not supported. */
|
/* pathconf(_PC_REX_*) operations are not supported. */
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
t->current_filesystem->xfer_align = svfs.f_frsize;
|
t->current_filesystem->xfer_align = svfs.f_frsize;
|
||||||
t->current_filesystem->max_xfer_size = -1;
|
t->current_filesystem->max_xfer_size = -1;
|
||||||
t->current_filesystem->min_xfer_size = svfs.f_bsize;
|
t->current_filesystem->min_xfer_size = svfs.f_bsize;
|
||||||
t->current_filesystem->incr_xfer_size = svfs.f_bsize;
|
t->current_filesystem->incr_xfer_size = svfs.f_bsize;
|
||||||
|
#else
|
||||||
|
t->current_filesystem->xfer_align = sfs.f_frsize;
|
||||||
|
t->current_filesystem->max_xfer_size = -1;
|
||||||
|
t->current_filesystem->min_xfer_size = sfs.f_bsize;
|
||||||
|
t->current_filesystem->incr_xfer_size = sfs.f_bsize;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
switch (sfs.f_type) {
|
switch (sfs.f_type) {
|
||||||
case AFS_SUPER_MAGIC:
|
case AFS_SUPER_MAGIC:
|
||||||
@ -1744,7 +1794,11 @@ setup_current_filesystem(struct archive_read_disk *a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ST_NOATIME)
|
#if defined(ST_NOATIME)
|
||||||
|
#if defined(HAVE_STATVFS)
|
||||||
if (svfs.f_flag & ST_NOATIME)
|
if (svfs.f_flag & ST_NOATIME)
|
||||||
|
#else
|
||||||
|
if (sfs.f_flag & ST_NOATIME)
|
||||||
|
#endif
|
||||||
t->current_filesystem->noatime = 1;
|
t->current_filesystem->noatime = 1;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -1973,7 +2027,7 @@ tree_dup(int fd)
|
|||||||
static volatile int can_dupfd_cloexec = 1;
|
static volatile int can_dupfd_cloexec = 1;
|
||||||
|
|
||||||
if (can_dupfd_cloexec) {
|
if (can_dupfd_cloexec) {
|
||||||
new_fd = fcntl(fd, F_DUPFD_CLOEXEC);
|
new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
|
||||||
if (new_fd != -1)
|
if (new_fd != -1)
|
||||||
return (new_fd);
|
return (new_fd);
|
||||||
/* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,
|
/* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,
|
||||||
|
@ -39,6 +39,9 @@ struct archive_entry;
|
|||||||
struct archive_read_disk {
|
struct archive_read_disk {
|
||||||
struct archive archive;
|
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,
|
* Symlink mode is one of 'L'ogical, 'P'hysical, or 'H'ybrid,
|
||||||
* following an old BSD convention. 'L' follows all symlinks,
|
* following an old BSD convention. 'L' follows all symlinks,
|
||||||
@ -68,6 +71,8 @@ struct archive_read_disk {
|
|||||||
int enable_copyfile;
|
int enable_copyfile;
|
||||||
/* Set 1 if users request to traverse mount points. */
|
/* Set 1 if users request to traverse mount points. */
|
||||||
int traverse_mount_points;
|
int traverse_mount_points;
|
||||||
|
/* Set 1 if users want to suppress xattr information. */
|
||||||
|
int suppress_xattr;
|
||||||
|
|
||||||
const char * (*lookup_gname)(void *private, int64_t gid);
|
const char * (*lookup_gname)(void *private, int64_t gid);
|
||||||
void (*cleanup_gname)(void *private);
|
void (*cleanup_gname)(void *private);
|
||||||
|
@ -83,7 +83,7 @@ static const char * lookup_uname_helper(struct name_cache *, id_t uid);
|
|||||||
* a simple cache to accelerate such lookups---into the archive_read_disk
|
* a simple cache to accelerate such lookups---into the archive_read_disk
|
||||||
* object. This is in a separate file because getpwuid()/getgrgid()
|
* object. This is in a separate file because getpwuid()/getgrgid()
|
||||||
* can pull in a LOT of library code (including NIS/LDAP functions, which
|
* can pull in a LOT of library code (including NIS/LDAP functions, which
|
||||||
* pull in DNS resolveers, etc). This can easily top 500kB, which makes
|
* pull in DNS resolvers, etc). This can easily top 500kB, which makes
|
||||||
* it inappropriate for some space-constrained applications.
|
* it inappropriate for some space-constrained applications.
|
||||||
*
|
*
|
||||||
* Applications that are size-sensitive may want to just use the
|
* Applications that are size-sensitive may want to just use the
|
||||||
|
@ -26,158 +26,35 @@
|
|||||||
#include "archive_platform.h"
|
#include "archive_platform.h"
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ERRNO_H
|
#ifdef HAVE_ERRNO_H
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_STDLIB_H
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
#include "archive_entry.h"
|
#include "archive_entry.h"
|
||||||
#include "archive_private.h"
|
#include "archive_private.h"
|
||||||
#include "archive_read_private.h"
|
#include "archive_read_private.h"
|
||||||
#include "archive_write_disk_private.h"
|
|
||||||
|
|
||||||
struct extract {
|
|
||||||
struct archive *ad; /* archive_write_disk object */
|
|
||||||
|
|
||||||
/* Progress function invoked during extract. */
|
|
||||||
void (*extract_progress)(void *);
|
|
||||||
void *extract_progress_user_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int archive_read_extract_cleanup(struct archive_read *);
|
|
||||||
static int copy_data(struct archive *ar, struct archive *aw);
|
|
||||||
static struct extract *get_extract(struct archive_read *);
|
|
||||||
|
|
||||||
static struct extract *
|
|
||||||
get_extract(struct archive_read *a)
|
|
||||||
{
|
|
||||||
/* If we haven't initialized, do it now. */
|
|
||||||
/* This also sets up a lot of global state. */
|
|
||||||
if (a->extract == NULL) {
|
|
||||||
a->extract = (struct extract *)malloc(sizeof(*a->extract));
|
|
||||||
if (a->extract == NULL) {
|
|
||||||
archive_set_error(&a->archive, ENOMEM, "Can't extract");
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
memset(a->extract, 0, sizeof(*a->extract));
|
|
||||||
a->extract->ad = archive_write_disk_new();
|
|
||||||
if (a->extract->ad == NULL) {
|
|
||||||
archive_set_error(&a->archive, ENOMEM, "Can't extract");
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
archive_write_disk_set_standard_lookup(a->extract->ad);
|
|
||||||
a->cleanup_archive_extract = archive_read_extract_cleanup;
|
|
||||||
}
|
|
||||||
return (a->extract);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
archive_read_extract(struct archive *_a, struct archive_entry *entry, int flags)
|
archive_read_extract(struct archive *_a, struct archive_entry *entry, int flags)
|
||||||
{
|
{
|
||||||
struct extract *extract;
|
struct archive_read_extract *extract;
|
||||||
|
struct archive_read * a = (struct archive_read *)_a;
|
||||||
|
|
||||||
extract = get_extract((struct archive_read *)_a);
|
extract = __archive_read_get_extract(a);
|
||||||
if (extract == NULL)
|
if (extract == NULL)
|
||||||
return (ARCHIVE_FATAL);
|
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);
|
archive_write_disk_set_options(extract->ad, flags);
|
||||||
return (archive_read_extract2(_a, entry, extract->ad));
|
return (archive_read_extract2(&a->archive, entry, extract->ad));
|
||||||
}
|
|
||||||
|
|
||||||
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 extract *extract = 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 extract *extract;
|
|
||||||
size_t size;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
extract = 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Cleanup function for archive_extract.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
archive_read_extract_cleanup(struct archive_read *a)
|
|
||||||
{
|
|
||||||
int ret = ARCHIVE_OK;
|
|
||||||
|
|
||||||
ret = archive_write_free(a->extract->ad);
|
|
||||||
free(a->extract);
|
|
||||||
a->extract = NULL;
|
|
||||||
return (ret);
|
|
||||||
}
|
}
|
||||||
|
156
contrib/libarchive/libarchive/archive_read_extract2.c
Normal file
156
contrib/libarchive/libarchive/archive_read_extract2.c
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$");
|
||||||
|
|
||||||
|
#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 *)malloc(sizeof(*a->extract));
|
||||||
|
if (a->extract == NULL) {
|
||||||
|
archive_set_error(&a->archive, ENOMEM, "Can't extract");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
memset(a->extract, 0, sizeof(*a->extract));
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd February 2, 2012
|
.Dd August 14, 2014
|
||||||
.Dt ARCHIVE_READ_FILTER 3
|
.Dt ARCHIVE_READ_FILTER 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -32,8 +32,11 @@
|
|||||||
.Nm archive_read_support_filter_bzip2 ,
|
.Nm archive_read_support_filter_bzip2 ,
|
||||||
.Nm archive_read_support_filter_compress ,
|
.Nm archive_read_support_filter_compress ,
|
||||||
.Nm archive_read_support_filter_gzip ,
|
.Nm archive_read_support_filter_gzip ,
|
||||||
|
.Nm archive_read_support_filter_lz4 ,
|
||||||
.Nm archive_read_support_filter_lzma ,
|
.Nm archive_read_support_filter_lzma ,
|
||||||
.Nm archive_read_support_filter_none ,
|
.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_xz ,
|
||||||
.Nm archive_read_support_filter_program ,
|
.Nm archive_read_support_filter_program ,
|
||||||
.Nm archive_read_support_filter_program_signature
|
.Nm archive_read_support_filter_program_signature
|
||||||
@ -50,12 +53,24 @@ Streaming Archive Library (libarchive, -larchive)
|
|||||||
.Ft int
|
.Ft int
|
||||||
.Fn archive_read_support_filter_compress "struct archive *"
|
.Fn archive_read_support_filter_compress "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn archive_read_support_filter_grzip "struct archive *"
|
||||||
|
.Ft int
|
||||||
.Fn archive_read_support_filter_gzip "struct archive *"
|
.Fn archive_read_support_filter_gzip "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn archive_read_support_filter_lrzip "struct archive *"
|
||||||
|
.Ft int
|
||||||
|
.Fn archive_read_support_filter_lz4 "struct archive *"
|
||||||
|
.Ft int
|
||||||
.Fn archive_read_support_filter_lzma "struct archive *"
|
.Fn archive_read_support_filter_lzma "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn archive_read_support_filter_lzop "struct archive *"
|
||||||
|
.Ft int
|
||||||
.Fn archive_read_support_filter_none "struct archive *"
|
.Fn archive_read_support_filter_none "struct archive *"
|
||||||
.Ft int
|
.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 *"
|
.Fn archive_read_support_filter_xz "struct archive *"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fo archive_read_support_filter_program
|
.Fo archive_read_support_filter_program
|
||||||
@ -75,9 +90,15 @@ Streaming Archive Library (libarchive, -larchive)
|
|||||||
.It Xo
|
.It Xo
|
||||||
.Fn archive_read_support_filter_bzip2 ,
|
.Fn archive_read_support_filter_bzip2 ,
|
||||||
.Fn archive_read_support_filter_compress ,
|
.Fn archive_read_support_filter_compress ,
|
||||||
|
.Fn archive_read_support_filter_grzip ,
|
||||||
.Fn archive_read_support_filter_gzip ,
|
.Fn archive_read_support_filter_gzip ,
|
||||||
|
.Fn archive_read_support_filter_lrzip ,
|
||||||
|
.Fn archive_read_support_filter_lz4 ,
|
||||||
.Fn archive_read_support_filter_lzma ,
|
.Fn archive_read_support_filter_lzma ,
|
||||||
|
.Fn archive_read_support_filter_lzop ,
|
||||||
.Fn archive_read_support_filter_none ,
|
.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_xz
|
||||||
.Xc
|
.Xc
|
||||||
Enables auto-detection code and decompression support for the
|
Enables auto-detection code and decompression support for the
|
||||||
|
@ -130,14 +130,14 @@ objects can be found in the overview manual page for
|
|||||||
The callback functions must match the following prototypes:
|
The callback functions must match the following prototypes:
|
||||||
.Bl -item -offset indent
|
.Bl -item -offset indent
|
||||||
.It
|
.It
|
||||||
.Ft typedef ssize_t
|
.Ft typedef la_ssize_t
|
||||||
.Fo archive_read_callback
|
.Fo archive_read_callback
|
||||||
.Fa "struct archive *"
|
.Fa "struct archive *"
|
||||||
.Fa "void *client_data"
|
.Fa "void *client_data"
|
||||||
.Fa "const void **buffer"
|
.Fa "const void **buffer"
|
||||||
.Fc
|
.Fc
|
||||||
.It
|
.It
|
||||||
.Ft typedef off_t
|
.Ft typedef la_int64_t
|
||||||
.Fo archive_skip_callback
|
.Fo archive_skip_callback
|
||||||
.Fa "struct archive *"
|
.Fa "struct archive *"
|
||||||
.Fa "void *client_data"
|
.Fa "void *client_data"
|
||||||
|
@ -59,6 +59,7 @@ struct read_fd_data {
|
|||||||
|
|
||||||
static int file_close(struct archive *, void *);
|
static int file_close(struct archive *, void *);
|
||||||
static ssize_t file_read(struct archive *, void *, const void **buff);
|
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(struct archive *, void *, int64_t request);
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -102,6 +103,7 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size)
|
|||||||
|
|
||||||
archive_read_set_read_callback(a, file_read);
|
archive_read_set_read_callback(a, file_read);
|
||||||
archive_read_set_skip_callback(a, file_skip);
|
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_close_callback(a, file_close);
|
||||||
archive_read_set_callback_data(a, mine);
|
archive_read_set_callback_data(a, mine);
|
||||||
return (archive_read_open1(a));
|
return (archive_read_open1(a));
|
||||||
@ -170,6 +172,33 @@ file_skip(struct archive *a, void *client_data, int64_t request)
|
|||||||
return (-1);
|
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
|
static int
|
||||||
file_close(struct archive *a, void *client_data)
|
file_close(struct archive *a, void *client_data)
|
||||||
{
|
{
|
||||||
|
@ -83,8 +83,9 @@ archive_read_open_FILE(struct archive *a, FILE *f)
|
|||||||
mine->f = f;
|
mine->f = f;
|
||||||
/*
|
/*
|
||||||
* If we can't fstat() the file, it may just be that it's not
|
* If we can't fstat() the file, it may just be that it's not
|
||||||
* a file. (FILE * objects can wrap many kinds of I/O
|
* a file. (On some platforms, FILE * objects can wrap I/O
|
||||||
* streams, some of which don't support fileno()).)
|
* streams that don't support fileno()). As a result, fileno()
|
||||||
|
* should be used cautiously.)
|
||||||
*/
|
*/
|
||||||
if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
|
if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
|
||||||
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
|
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
|
||||||
@ -150,7 +151,10 @@ file_skip(struct archive *a, void *client_data, int64_t request)
|
|||||||
skip = max_skip;
|
skip = max_skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_FSEEKO
|
#ifdef __ANDROID__
|
||||||
|
/* fileno() isn't safe on all platforms ... see above. */
|
||||||
|
if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
|
||||||
|
#elif HAVE_FSEEKO
|
||||||
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
|
if (fseeko(mine->f, skip, SEEK_CUR) != 0)
|
||||||
#elif HAVE__FSEEKI64
|
#elif HAVE__FSEEKI64
|
||||||
if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
|
if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
|
||||||
|
@ -103,7 +103,9 @@ int
|
|||||||
archive_read_open_filename(struct archive *a, const char *filename,
|
archive_read_open_filename(struct archive *a, const char *filename,
|
||||||
size_t block_size)
|
size_t block_size)
|
||||||
{
|
{
|
||||||
const char *filenames[2] = { filename, NULL };
|
const char *filenames[2];
|
||||||
|
filenames[0] = filename;
|
||||||
|
filenames[1] = NULL;
|
||||||
return archive_read_open_filenames(a, filenames, block_size);
|
return archive_read_open_filenames(a, filenames, block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +178,7 @@ archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
|
|||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* POSIX system does not support a wchar_t interface for
|
* POSIX system does not support a wchar_t interface for
|
||||||
* open() system call, so we have to translate a whcar_t
|
* open() system call, so we have to translate a wchar_t
|
||||||
* filename to multi-byte one and use it.
|
* filename to multi-byte one and use it.
|
||||||
*/
|
*/
|
||||||
struct archive_string fn;
|
struct archive_string fn;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user