mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
MFhead@r324148
This commit is contained in:
commit
d5db4328ad
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/runtime-coverage/; revision=324149
@ -180,10 +180,12 @@ build${libcompat}: .PHONY
|
||||
.endfor
|
||||
${_+_}cd ${.CURDIR}; \
|
||||
${LIBCOMPATWMAKE} -f Makefile.inc1 -DNO_FSCHG libraries
|
||||
.if ${libcompat} == "32" && !defined(NO_RTLD)
|
||||
.if ${libcompat} == "32"
|
||||
.for _t in ${_obj} all
|
||||
.if !defined(NO_RTLD)
|
||||
${_+_}cd ${.CURDIR}/libexec/rtld-elf; PROG=ld-elf32.so.1 ${LIBCOMPATWMAKE} \
|
||||
-DNO_FSCHG DIRPRFX=libexec/rtld-elf/ ${_t}
|
||||
.endif
|
||||
${_+_}cd ${.CURDIR}/usr.bin/ldd; PROG=ldd32 ${LIBCOMPATWMAKE} \
|
||||
DIRPRFX=usr.bin/ldd ${_t}
|
||||
.endfor
|
||||
@ -193,9 +195,11 @@ distribute${libcompat} install${libcompat}: .PHONY
|
||||
.for _dir in ${_LC_LIBDIRS.yes}
|
||||
${_+_}cd ${.CURDIR}/${_dir}; ${LIBCOMPATIMAKE} ${.TARGET:S/${libcompat}$//}
|
||||
.endfor
|
||||
.if ${libcompat} == "32" && !defined(NO_RTLD)
|
||||
.if ${libcompat} == "32"
|
||||
.if !defined(NO_RTLD)
|
||||
${_+_}cd ${.CURDIR}/libexec/rtld-elf; \
|
||||
PROG=ld-elf32.so.1 ${LIBCOMPATIMAKE} ${.TARGET:S/32$//}
|
||||
.endif
|
||||
${_+_}cd ${.CURDIR}/usr.bin/ldd; PROG=ldd32 ${LIBCOMPATIMAKE} \
|
||||
${.TARGET:S/32$//}
|
||||
.endif
|
||||
|
@ -1,6 +1,8 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PACKAGE=runtime
|
||||
PROG= chflags
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PACKAGE=runtime
|
||||
PROG= mkdir
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 7/19/93
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PACKAGE=rcmds
|
||||
PROG= rcp
|
||||
SRCS= rcp.c util.c
|
||||
|
@ -1,9 +1,10 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
# $FreeBSD$
|
||||
|
||||
.include <src.opts.mk>
|
||||
|
||||
PACKAGE=runtime
|
||||
PROG= rmdir
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
|
4
contrib/libarchive/cat/test/test_empty.zst.uu
Normal file
4
contrib/libarchive/cat/test/test_empty.zst.uu
Normal file
@ -0,0 +1,4 @@
|
||||
begin 644 test_empty.zst
|
||||
-*+4O_010`0``F>G840``
|
||||
`
|
||||
end
|
41
contrib/libarchive/cat/test/test_empty_zstd.c
Normal file
41
contrib/libarchive/cat/test/test_empty_zstd.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Sean Purcell
|
||||
* 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_zstd)
|
||||
{
|
||||
const char *reffile = "test_empty.zst";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canZstd()) {
|
||||
assertEqualInt(0, f);
|
||||
assertEmptyFile("test.out");
|
||||
assertEmptyFile("test.err");
|
||||
} else {
|
||||
skipping("It seems zstd is not supported on this platform");
|
||||
}
|
||||
}
|
4
contrib/libarchive/cat/test/test_expand.zst.uu
Normal file
4
contrib/libarchive/cat/test/test_expand.zst.uu
Normal file
@ -0,0 +1,4 @@
|
||||
begin 644 test_expand.zst
|
||||
J*+4O_010Z0``8V]N=&5N=',@;V8@=&5S=%]E>'!A;F0N>G-T+@J;23#F
|
||||
`
|
||||
end
|
41
contrib/libarchive/cat/test/test_expand_zstd.c
Normal file
41
contrib/libarchive/cat/test/test_expand_zstd.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Sean Purcell
|
||||
* 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_zstd)
|
||||
{
|
||||
const char *reffile = "test_expand.zst";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canZstd()) {
|
||||
assertEqualInt(0, f);
|
||||
assertTextFileContents("contents of test_expand.zst.\n", "test.out");
|
||||
assertEmptyFile("test.err");
|
||||
} else {
|
||||
skipping("It seems zstd is not supported on this platform");
|
||||
}
|
||||
}
|
@ -187,6 +187,11 @@ In input mode, this option is ignored.
|
||||
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 zstd
|
||||
(o mode only)
|
||||
Compress the archive with zstd-compatible compression before writing it.
|
||||
In input mode, this option is ignored; zstd compression is recognized
|
||||
automatically on input.
|
||||
.It Fl Fl lzma
|
||||
(o mode only)
|
||||
Compress the file with lzma-compatible compression before writing it.
|
||||
|
@ -92,6 +92,7 @@ static const struct option {
|
||||
{ "verbose", 0, 'v' },
|
||||
{ "version", 0, OPTION_VERSION },
|
||||
{ "xz", 0, 'J' },
|
||||
{ "zstd", 0, OPTION_ZSTD },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -269,6 +269,7 @@ main(int argc, char *argv[])
|
||||
case OPTION_LZ4:
|
||||
case OPTION_LZMA: /* GNU tar, others */
|
||||
case OPTION_LZOP: /* GNU tar, others */
|
||||
case OPTION_ZSTD:
|
||||
cpio->compress = opt;
|
||||
break;
|
||||
case 'm': /* POSIX 1997 */
|
||||
@ -546,6 +547,9 @@ mode_out(struct cpio *cpio)
|
||||
case OPTION_LZOP:
|
||||
r = archive_write_add_filter_lzop(cpio->archive);
|
||||
break;
|
||||
case OPTION_ZSTD:
|
||||
r = archive_write_add_filter_zstd(cpio->archive);
|
||||
break;
|
||||
case 'j': case 'y':
|
||||
r = archive_write_add_filter_bzip2(cpio->archive);
|
||||
break;
|
||||
|
@ -111,7 +111,8 @@ enum {
|
||||
OPTION_PRESERVE_OWNER,
|
||||
OPTION_QUIET,
|
||||
OPTION_UUENCODE,
|
||||
OPTION_VERSION
|
||||
OPTION_VERSION,
|
||||
OPTION_ZSTD,
|
||||
};
|
||||
|
||||
int cpio_getopt(struct cpio *cpio);
|
||||
|
6
contrib/libarchive/cpio/test/test_extract.cpio.zst.uu
Normal file
6
contrib/libarchive/cpio/test/test_extract.cpio.zst.uu
Normal file
@ -0,0 +1,6 @@
|
||||
begin 644 test_extract.cpio.zst
|
||||
M*+4O_01090,`,@41%X")&@#'G6T\K16_MR)#=DK)5:.1,2J0HY2"!(1!`!7R
|
||||
M$(UB`2"*D41;J2UF&)<0!Y7X'TU<%W.\W^R]GO-WW^OO^QX0`%P<]30-!#U`
|
||||
?!KD!`#XP,_`U4`HT3+RF:#!7Y\V@R)5"7P"^;WEUK@``
|
||||
`
|
||||
end
|
48
contrib/libarchive/cpio/test/test_extract_cpio_zstd.c
Normal file
48
contrib/libarchive/cpio/test/test_extract_cpio_zstd.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Sean Purcell
|
||||
* 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_zstd)
|
||||
{
|
||||
const char *reffile = "test_extract.cpio.zst";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canZstd()) {
|
||||
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 zstd is not supported on this platform");
|
||||
}
|
||||
}
|
85
contrib/libarchive/cpio/test/test_option_zstd.c
Normal file
85
contrib/libarchive/cpio/test/test_option_zstd.c
Normal file
@ -0,0 +1,85 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Sean Purcell
|
||||
* 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_zstd)
|
||||
{
|
||||
char *p;
|
||||
int r;
|
||||
size_t s;
|
||||
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with zstd compression. */
|
||||
r = systemf("echo f | %s -o --zstd >archive.out 2>archive.err",
|
||||
testprog);
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (r != 0) {
|
||||
if (strstr(p, "Unsupported compression") != NULL) {
|
||||
skipping("This version of bsdcpio was compiled "
|
||||
"without zstd support");
|
||||
goto done;
|
||||
}
|
||||
/* 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 && !canZstd()) {
|
||||
skipping("This version of bsdcpio uses an external zstd program "
|
||||
"but no such program is available on this system.");
|
||||
goto done;
|
||||
}
|
||||
/* 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 && !canZstd()) {
|
||||
skipping("This version of bsdcpio uses an external zstd program "
|
||||
"but no such program is available on this system.");
|
||||
goto done;
|
||||
}
|
||||
/* On some systems the error won't be detected until closing
|
||||
time, by a 127 exit error returned by waitpid. */
|
||||
if (strstr(p, "Error closing") != NULL && !canZstd()) {
|
||||
skipping("This version of bsdcpio uses an external zstd program "
|
||||
"but no such program is available on this system.");
|
||||
return;
|
||||
}
|
||||
failure("--zstd option is broken: %s", p);
|
||||
assertEqualInt(r, 0);
|
||||
goto done;
|
||||
}
|
||||
free(p);
|
||||
/* Check that the archive file has an zstd signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\x28\xb5\x2f\xfd", 4);
|
||||
|
||||
done:
|
||||
free(p);
|
||||
}
|
@ -177,6 +177,7 @@ __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);
|
||||
__LA_DECL const char * archive_libzstd_version(void);
|
||||
|
||||
/* Declare our basic types. */
|
||||
struct archive;
|
||||
@ -276,6 +277,7 @@ typedef const char *archive_passphrase_callback(struct archive *,
|
||||
#define ARCHIVE_FILTER_LZOP 11
|
||||
#define ARCHIVE_FILTER_GRZIP 12
|
||||
#define ARCHIVE_FILTER_LZ4 13
|
||||
#define ARCHIVE_FILTER_ZSTD 14
|
||||
|
||||
#if ARCHIVE_VERSION_NUMBER < 4000000
|
||||
#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE
|
||||
@ -433,6 +435,7 @@ __LA_DECL int archive_read_support_filter_program_signature
|
||||
__LA_DECL int archive_read_support_filter_rpm(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_uu(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_xz(struct archive *);
|
||||
__LA_DECL int archive_read_support_filter_zstd(struct archive *);
|
||||
|
||||
__LA_DECL int archive_read_support_format_7zip(struct archive *);
|
||||
__LA_DECL int archive_read_support_format_all(struct archive *);
|
||||
@ -778,6 +781,7 @@ __LA_DECL int archive_write_add_filter_program(struct archive *,
|
||||
const char *cmd);
|
||||
__LA_DECL int archive_write_add_filter_uuencode(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_xz(struct archive *);
|
||||
__LA_DECL int archive_write_add_filter_zstd(struct archive *);
|
||||
|
||||
|
||||
/* A convenience function to set the format based on the code or name. */
|
||||
|
@ -100,10 +100,10 @@ get_argument(struct archive_string *as, const char *p)
|
||||
|
||||
/*
|
||||
* Set up command line arguments.
|
||||
* Returns ARChIVE_OK if everything okey.
|
||||
* Returns ARChIVE_FAILED if there is a lack of the `"' terminator or an
|
||||
* Returns ARCHIVE_OK if everything okey.
|
||||
* Returns ARCHIVE_FAILED if there is a lack of the `"' terminator or an
|
||||
* empty command line.
|
||||
* Returns ARChIVE_FATAL if no memory.
|
||||
* Returns ARCHIVE_FATAL if no memory.
|
||||
*/
|
||||
int
|
||||
__archive_cmdline_parse(struct archive_cmdline *data, const char *cmd)
|
||||
|
@ -52,6 +52,17 @@
|
||||
#error Oops: No config.h and no pre-built configuration in archive_platform.h.
|
||||
#endif
|
||||
|
||||
/* On macOS check for some symbols based on the deployment target version. */
|
||||
#if defined(__APPLE__)
|
||||
# undef HAVE_FUTIMENS
|
||||
# undef HAVE_UTIMENSAT
|
||||
# include <AvailabilityMacros.h>
|
||||
# if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
|
||||
# define HAVE_FUTIMENS 1
|
||||
# define HAVE_UTIMENSAT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* It should be possible to get rid of this by extending the feature-test
|
||||
* macros to cover Windows API functions, probably along with non-trivial
|
||||
* refactoring of code to find structures that sit more cleanly on top of
|
||||
|
@ -89,6 +89,10 @@ archive_read_append_filter(struct archive *_a, int code)
|
||||
strcpy(str, "lz4");
|
||||
r1 = archive_read_support_filter_lz4(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_ZSTD:
|
||||
strcpy(str, "zstd");
|
||||
r1 = archive_read_support_filter_zstd(_a);
|
||||
break;
|
||||
case ARCHIVE_FILTER_LZIP:
|
||||
strcpy(str, "lzip");
|
||||
r1 = archive_read_support_filter_lzip(_a);
|
||||
|
@ -127,7 +127,7 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
|
||||
/*
|
||||
* Enter working directory and return working pathname of archive_entry.
|
||||
* If a pointer to an integer is provided and its value is below zero
|
||||
* open a file descriptor on this pahtname.
|
||||
* open a file descriptor on this pathname.
|
||||
*/
|
||||
const char *
|
||||
archive_read_disk_entry_setup_path(struct archive_read_disk *a,
|
||||
|
@ -38,6 +38,7 @@
|
||||
.Nm archive_read_support_filter_rpm ,
|
||||
.Nm archive_read_support_filter_uu ,
|
||||
.Nm archive_read_support_filter_xz ,
|
||||
.Nm archive_read_support_filter_zstd ,
|
||||
.Nm archive_read_support_filter_program ,
|
||||
.Nm archive_read_support_filter_program_signature
|
||||
.Nd functions for reading streaming archives
|
||||
@ -73,6 +74,8 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_xz "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_read_support_filter_zstd "struct archive *"
|
||||
.Ft int
|
||||
.Fo archive_read_support_filter_program
|
||||
.Fa "struct archive *"
|
||||
.Fa "const char *cmd"
|
||||
@ -99,7 +102,8 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.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 ,
|
||||
.Fn archive_read_support_filter_zstd ,
|
||||
.Xc
|
||||
Enables auto-detection code and decompression support for the
|
||||
specified compression.
|
||||
|
@ -71,6 +71,8 @@ archive_read_support_filter_all(struct archive *a)
|
||||
archive_read_support_filter_grzip(a);
|
||||
/* Lz4 falls back to "lz4 -d" command-line program. */
|
||||
archive_read_support_filter_lz4(a);
|
||||
/* Zstd falls back to "zstd -d" command-line program. */
|
||||
archive_read_support_filter_zstd(a);
|
||||
|
||||
/* Note: We always return ARCHIVE_OK here, even if some of the
|
||||
* above return ARCHIVE_WARN. The intent here is to enable
|
||||
|
292
contrib/libarchive/libarchive/archive_read_support_filter_zstd.c
Normal file
292
contrib/libarchive/libarchive/archive_read_support_filter_zstd.c
Normal file
@ -0,0 +1,292 @@
|
||||
/*-
|
||||
* Copyright (c) 2009-2011 Sean Purcell
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if HAVE_ZSTD_H
|
||||
#include <zstd.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_endian.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_private.h"
|
||||
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
|
||||
struct private_data {
|
||||
ZSTD_DStream *dstream;
|
||||
unsigned char *out_block;
|
||||
size_t out_block_size;
|
||||
int64_t total_out;
|
||||
char in_frame; /* True = in the middle of a zstd frame. */
|
||||
char eof; /* True = found end of compressed data. */
|
||||
};
|
||||
|
||||
/* Zstd Filter. */
|
||||
static ssize_t zstd_filter_read(struct archive_read_filter *, const void**);
|
||||
static int zstd_filter_close(struct archive_read_filter *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note that we can detect zstd compressed files even if we can't decompress
|
||||
* them. (In fact, we like detecting them because we can give better error
|
||||
* messages.) So the bid framework here gets compiled even if no zstd library
|
||||
* is available.
|
||||
*/
|
||||
static int zstd_bidder_bid(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
static int zstd_bidder_init(struct archive_read_filter *);
|
||||
|
||||
int
|
||||
archive_read_support_filter_zstd(struct archive *_a)
|
||||
{
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter_bidder *bidder;
|
||||
|
||||
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_read_support_filter_zstd");
|
||||
|
||||
if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "zstd";
|
||||
bidder->bid = zstd_bidder_bid;
|
||||
bidder->init = zstd_bidder_init;
|
||||
bidder->options = NULL;
|
||||
bidder->free = NULL;
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external zstd program for zstd decompression");
|
||||
return (ARCHIVE_WARN);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether we can handle this data.
|
||||
*/
|
||||
static int
|
||||
zstd_bidder_bid(struct archive_read_filter_bidder *self,
|
||||
struct archive_read_filter *filter)
|
||||
{
|
||||
const unsigned char *buffer;
|
||||
ssize_t avail;
|
||||
unsigned prefix;
|
||||
|
||||
/* Zstd frame magic values */
|
||||
const unsigned zstd_magic = 0xFD2FB528U;
|
||||
|
||||
(void) self; /* UNUSED */
|
||||
|
||||
buffer = __archive_read_filter_ahead(filter, 4, &avail);
|
||||
if (buffer == NULL)
|
||||
return (0);
|
||||
|
||||
prefix = archive_le32dec(buffer);
|
||||
if (prefix == zstd_magic)
|
||||
return (32);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if !(HAVE_ZSTD_H && HAVE_LIBZSTD)
|
||||
|
||||
/*
|
||||
* If we don't have the library on this system, we can't do the
|
||||
* decompression directly. We can, however, try to run "zstd -d"
|
||||
* in case that's available.
|
||||
*/
|
||||
static int
|
||||
zstd_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = __archive_read_program(self, "zstd -d -qq");
|
||||
/* Note: We set the format here even if __archive_read_program()
|
||||
* above fails. We do, after all, know what the format is
|
||||
* even if we weren't able to read it. */
|
||||
self->code = ARCHIVE_FILTER_ZSTD;
|
||||
self->name = "zstd";
|
||||
return (r);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Initialize the filter object
|
||||
*/
|
||||
static int
|
||||
zstd_bidder_init(struct archive_read_filter *self)
|
||||
{
|
||||
struct private_data *state;
|
||||
const size_t out_block_size = ZSTD_DStreamOutSize();
|
||||
void *out_block;
|
||||
ZSTD_DStream *dstream;
|
||||
|
||||
self->code = ARCHIVE_FILTER_ZSTD;
|
||||
self->name = "zstd";
|
||||
|
||||
state = (struct private_data *)calloc(sizeof(*state), 1);
|
||||
out_block = (unsigned char *)malloc(out_block_size);
|
||||
dstream = ZSTD_createDStream();
|
||||
|
||||
if (state == NULL || out_block == NULL || dstream == NULL) {
|
||||
free(out_block);
|
||||
free(state);
|
||||
ZSTD_freeDStream(dstream); /* supports free on NULL */
|
||||
archive_set_error(&self->archive->archive, ENOMEM,
|
||||
"Can't allocate data for zstd decompression");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
self->data = state;
|
||||
|
||||
state->out_block_size = out_block_size;
|
||||
state->out_block = out_block;
|
||||
state->dstream = dstream;
|
||||
self->read = zstd_filter_read;
|
||||
self->skip = NULL; /* not supported */
|
||||
self->close = zstd_filter_close;
|
||||
|
||||
state->eof = 0;
|
||||
state->in_frame = 0;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
zstd_filter_read(struct archive_read_filter *self, const void **p)
|
||||
{
|
||||
struct private_data *state;
|
||||
size_t decompressed;
|
||||
ssize_t avail_in;
|
||||
ZSTD_outBuffer out;
|
||||
ZSTD_inBuffer in;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
|
||||
out = (ZSTD_outBuffer) { state->out_block, state->out_block_size, 0 };
|
||||
|
||||
/* Try to fill the output buffer. */
|
||||
while (out.pos < out.size && !state->eof) {
|
||||
if (!state->in_frame) {
|
||||
const size_t ret = ZSTD_initDStream(state->dstream);
|
||||
if (ZSTD_isError(ret)) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Error initializing zstd decompressor: %s",
|
||||
ZSTD_getErrorName(ret));
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
in.src = __archive_read_filter_ahead(self->upstream, 1,
|
||||
&avail_in);
|
||||
if (avail_in < 0) {
|
||||
return avail_in;
|
||||
}
|
||||
if (in.src == NULL && avail_in == 0) {
|
||||
if (!state->in_frame) {
|
||||
/* end of stream */
|
||||
state->eof = 1;
|
||||
break;
|
||||
} else {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Truncated zstd input");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
in.size = avail_in;
|
||||
in.pos = 0;
|
||||
|
||||
{
|
||||
const size_t ret =
|
||||
ZSTD_decompressStream(state->dstream, &out, &in);
|
||||
|
||||
if (ZSTD_isError(ret)) {
|
||||
archive_set_error(&self->archive->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Zstd decompression failed: %s",
|
||||
ZSTD_getErrorName(ret));
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* Decompressor made some progress */
|
||||
__archive_read_filter_consume(self->upstream, in.pos);
|
||||
|
||||
/* ret guaranteed to be > 0 if frame isn't done yet */
|
||||
state->in_frame = (ret != 0);
|
||||
}
|
||||
}
|
||||
|
||||
decompressed = out.pos;
|
||||
state->total_out += decompressed;
|
||||
if (decompressed == 0)
|
||||
*p = NULL;
|
||||
else
|
||||
*p = state->out_block;
|
||||
return (decompressed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up the decompressor.
|
||||
*/
|
||||
static int
|
||||
zstd_filter_close(struct archive_read_filter *self)
|
||||
{
|
||||
struct private_data *state;
|
||||
|
||||
state = (struct private_data *)self->data;
|
||||
|
||||
ZSTD_freeDStream(state->dstream);
|
||||
free(state->out_block);
|
||||
free(state);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#endif /* HAVE_ZLIB_H && HAVE_LIBZSTD */
|
@ -633,6 +633,13 @@ header_newc(struct archive_read *a, struct cpio *cpio,
|
||||
/* Pad name to 2 more than a multiple of 4. */
|
||||
*name_pad = (2 - *namelength) & 3;
|
||||
|
||||
/* Make sure that the padded name length fits into size_t. */
|
||||
if (*name_pad > SIZE_MAX - *namelength) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"cpio archive has invalid namelength");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: entry_bytes_remaining is at least 64 bits and
|
||||
* therefore guaranteed to be big enough for a 33-bit file
|
||||
|
@ -77,6 +77,8 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define MTREE_HASHTABLE_SIZE 1024
|
||||
|
||||
#define MAX_LINE_LEN (1024 * 1024)
|
||||
|
||||
struct mtree_option {
|
||||
struct mtree_option *next;
|
||||
char *value;
|
||||
@ -334,6 +336,14 @@ next_line(struct archive_read *a,
|
||||
size_t nbytes_req = (*ravail+1023) & ~1023U;
|
||||
ssize_t tested;
|
||||
|
||||
/*
|
||||
* Place an arbitrary limit on the line length.
|
||||
* mtree is almost free-form input and without line length limits,
|
||||
* it can consume a lot of memory.
|
||||
*/
|
||||
if (len >= MAX_LINE_LEN)
|
||||
return (-1);
|
||||
|
||||
/* Increase reading bytes if it is not enough to at least
|
||||
* new two lines. */
|
||||
if (nbytes_req < (size_t)*ravail + 160)
|
||||
|
@ -1496,7 +1496,11 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
filename[filename_size++] = '\0';
|
||||
filename[filename_size++] = '\0';
|
||||
/*
|
||||
* Do not increment filename_size here as the computations below
|
||||
* add the space for the terminating NUL explicitly.
|
||||
*/
|
||||
filename[filename_size] = '\0';
|
||||
|
||||
/* Decoded unicode form is UTF-16BE, so we have to update a string
|
||||
* conversion object for it. */
|
||||
|
@ -2243,7 +2243,7 @@ gnu_add_sparse_entry(struct archive_read *a, struct tar *tar,
|
||||
else
|
||||
tar->sparse_list = p;
|
||||
tar->sparse_last = p;
|
||||
if (remaining < 0 || offset < 0) {
|
||||
if (remaining < 0 || offset < 0 || offset > INT64_MAX - remaining) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Malformed sparse map data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
@ -1040,6 +1040,9 @@ atol10(const char *p, size_t char_cnt)
|
||||
uint64_t l;
|
||||
int digit;
|
||||
|
||||
if (char_cnt == 0)
|
||||
return (0);
|
||||
|
||||
l = 0;
|
||||
digit = *p - '0';
|
||||
while (digit >= 0 && digit < 10 && char_cnt-- > 0) {
|
||||
@ -1054,7 +1057,10 @@ atol8(const char *p, size_t char_cnt)
|
||||
{
|
||||
int64_t l;
|
||||
int digit;
|
||||
|
||||
|
||||
if (char_cnt == 0)
|
||||
return (0);
|
||||
|
||||
l = 0;
|
||||
while (char_cnt-- > 0) {
|
||||
if (*p >= '0' && *p <= '7')
|
||||
@ -2623,6 +2629,14 @@ strappend_base64(struct xar *xar,
|
||||
archive_strncat(as, (const char *)buff, len);
|
||||
}
|
||||
|
||||
static int
|
||||
is_string(const char *known, const char *data, size_t len)
|
||||
{
|
||||
if (strlen(known) != len)
|
||||
return -1;
|
||||
return memcmp(data, known, len);
|
||||
}
|
||||
|
||||
static void
|
||||
xml_data(void *userData, const char *s, int len)
|
||||
{
|
||||
@ -2674,26 +2688,26 @@ xml_data(void *userData, const char *s, int len)
|
||||
archive_strncpy(&(xar->file->symlink), s, len);
|
||||
break;
|
||||
case FILE_TYPE:
|
||||
if (strncmp("file", s, len) == 0 ||
|
||||
strncmp("hardlink", s, len) == 0)
|
||||
if (is_string("file", s, len) == 0 ||
|
||||
is_string("hardlink", s, len) == 0)
|
||||
xar->file->mode =
|
||||
(xar->file->mode & ~AE_IFMT) | AE_IFREG;
|
||||
if (strncmp("directory", s, len) == 0)
|
||||
if (is_string("directory", s, len) == 0)
|
||||
xar->file->mode =
|
||||
(xar->file->mode & ~AE_IFMT) | AE_IFDIR;
|
||||
if (strncmp("symlink", s, len) == 0)
|
||||
if (is_string("symlink", s, len) == 0)
|
||||
xar->file->mode =
|
||||
(xar->file->mode & ~AE_IFMT) | AE_IFLNK;
|
||||
if (strncmp("character special", s, len) == 0)
|
||||
if (is_string("character special", s, len) == 0)
|
||||
xar->file->mode =
|
||||
(xar->file->mode & ~AE_IFMT) | AE_IFCHR;
|
||||
if (strncmp("block special", s, len) == 0)
|
||||
if (is_string("block special", s, len) == 0)
|
||||
xar->file->mode =
|
||||
(xar->file->mode & ~AE_IFMT) | AE_IFBLK;
|
||||
if (strncmp("socket", s, len) == 0)
|
||||
if (is_string("socket", s, len) == 0)
|
||||
xar->file->mode =
|
||||
(xar->file->mode & ~AE_IFMT) | AE_IFSOCK;
|
||||
if (strncmp("fifo", s, len) == 0)
|
||||
if (is_string("fifo", s, len) == 0)
|
||||
xar->file->mode =
|
||||
(xar->file->mode & ~AE_IFMT) | AE_IFIFO;
|
||||
xar->file->has |= HAS_TYPE;
|
||||
|
@ -723,6 +723,11 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct
|
||||
}
|
||||
case 0x9901:
|
||||
/* WinZip AES extra data field. */
|
||||
if (datasize < 6) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Incomplete AES field");
|
||||
return ARCHIVE_FAILED;
|
||||
}
|
||||
if (p[offset + 2] == 'A' && p[offset + 3] == 'E') {
|
||||
/* Vendor version. */
|
||||
zip_entry->aes_extra.vendor =
|
||||
|
@ -214,7 +214,8 @@ archive_wstring_append(struct archive_wstring *as, const wchar_t *p, size_t s)
|
||||
{
|
||||
if (archive_wstring_ensure(as, as->length + s + 1) == NULL)
|
||||
return (NULL);
|
||||
wmemmove(as->s + as->length, p, s);
|
||||
if (s)
|
||||
wmemmove(as->s + as->length, p, s);
|
||||
as->length += s;
|
||||
as->s[as->length] = 0;
|
||||
return (as);
|
||||
|
@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef HAVE_LZ4_H
|
||||
#include <lz4.h>
|
||||
#endif
|
||||
#ifdef HAVE_ZSTD_H
|
||||
#include <zstd.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
@ -59,6 +62,7 @@ archive_version_details(void)
|
||||
const char *liblzma = archive_liblzma_version();
|
||||
const char *bzlib = archive_bzlib_version();
|
||||
const char *liblz4 = archive_liblz4_version();
|
||||
const char *libzstd = archive_libzstd_version();
|
||||
|
||||
if (!init) {
|
||||
archive_string_init(&str);
|
||||
@ -84,6 +88,10 @@ archive_version_details(void)
|
||||
archive_strcat(&str, " liblz4/");
|
||||
archive_strcat(&str, liblz4);
|
||||
}
|
||||
if (libzstd) {
|
||||
archive_strcat(&str, " libzstd/");
|
||||
archive_strcat(&str, libzstd);
|
||||
}
|
||||
}
|
||||
return str.s;
|
||||
}
|
||||
@ -131,3 +139,13 @@ archive_liblz4_version(void)
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_libzstd_version(void)
|
||||
{
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
return ZSTD_VERSION_STRING;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ support.
|
||||
.\"
|
||||
.Ss Set options
|
||||
See
|
||||
.Xr archive_read_set_options 3 .
|
||||
.Xr archive_write_set_options 3 .
|
||||
.\"
|
||||
.Ss Open archive
|
||||
See
|
||||
|
@ -53,6 +53,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
|
||||
{ ARCHIVE_FILTER_LZOP, archive_write_add_filter_lzip },
|
||||
{ ARCHIVE_FILTER_UU, archive_write_add_filter_uuencode },
|
||||
{ ARCHIVE_FILTER_XZ, archive_write_add_filter_xz },
|
||||
{ ARCHIVE_FILTER_ZSTD, archive_write_add_filter_zstd },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
|
@ -57,6 +57,7 @@ struct { const char *name; int (*setter)(struct archive *); } names[] =
|
||||
{ "lzop", archive_write_add_filter_lzop },
|
||||
{ "uuencode", archive_write_add_filter_uuencode },
|
||||
{ "xz", archive_write_add_filter_xz },
|
||||
{ "zstd", archive_write_add_filter_zstd },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
335
contrib/libarchive/libarchive/archive_write_add_filter_zstd.c
Normal file
335
contrib/libarchive/libarchive/archive_write_add_filter_zstd.c
Normal file
@ -0,0 +1,335 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Sean Purcell
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_ZSTD_H
|
||||
#include <zstd.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_string.h"
|
||||
#include "archive_write_private.h"
|
||||
|
||||
/* Don't compile this if we don't have zstd.h */
|
||||
|
||||
struct private_data {
|
||||
int compression_level;
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
ZSTD_CStream *cstream;
|
||||
int64_t total_in;
|
||||
ZSTD_outBuffer out;
|
||||
#else
|
||||
struct archive_write_program_data *pdata;
|
||||
#endif
|
||||
};
|
||||
|
||||
static int archive_compressor_zstd_options(struct archive_write_filter *,
|
||||
const char *, const char *);
|
||||
static int archive_compressor_zstd_open(struct archive_write_filter *);
|
||||
static int archive_compressor_zstd_write(struct archive_write_filter *,
|
||||
const void *, size_t);
|
||||
static int archive_compressor_zstd_close(struct archive_write_filter *);
|
||||
static int archive_compressor_zstd_free(struct archive_write_filter *);
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
static int drive_compressor(struct archive_write_filter *,
|
||||
struct private_data *, int, const void *, size_t);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Add a zstd compression filter to this write handle.
|
||||
*/
|
||||
int
|
||||
archive_write_add_filter_zstd(struct archive *_a)
|
||||
{
|
||||
struct archive_write *a = (struct archive_write *)_a;
|
||||
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
|
||||
struct private_data *data;
|
||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
|
||||
ARCHIVE_STATE_NEW, "archive_write_add_filter_zstd");
|
||||
|
||||
data = calloc(1, sizeof(*data));
|
||||
if (data == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
f->data = data;
|
||||
f->open = &archive_compressor_zstd_open;
|
||||
f->options = &archive_compressor_zstd_options;
|
||||
f->close = &archive_compressor_zstd_close;
|
||||
f->free = &archive_compressor_zstd_free;
|
||||
f->code = ARCHIVE_FILTER_ZSTD;
|
||||
f->name = "zstd";
|
||||
data->compression_level = 3; /* Default level used by the zstd CLI */
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
data->cstream = ZSTD_createCStream();
|
||||
if (data->cstream == NULL) {
|
||||
free(data);
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Failed to allocate zstd compressor object");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
data->pdata = __archive_write_program_allocate("zstd");
|
||||
if (data->pdata == NULL) {
|
||||
free(data);
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Using external zstd program");
|
||||
return (ARCHIVE_WARN);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
archive_compressor_zstd_free(struct archive_write_filter *f)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
ZSTD_freeCStream(data->cstream);
|
||||
free(data->out.dst);
|
||||
#else
|
||||
__archive_write_program_free(data->pdata);
|
||||
#endif
|
||||
free(data);
|
||||
f->data = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set write options.
|
||||
*/
|
||||
static int
|
||||
archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
|
||||
const char *value)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
|
||||
if (strcmp(key, "compression-level") == 0) {
|
||||
int level = atoi(value);
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
if (level < 1 || level > ZSTD_maxCLevel()) {
|
||||
#else
|
||||
/* If we don't have the library, hard-code the max level */
|
||||
if (level < 1 || level > 22) {
|
||||
#endif
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
data->compression_level = level;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
/*
|
||||
* Setup callback.
|
||||
*/
|
||||
static int
|
||||
archive_compressor_zstd_open(struct archive_write_filter *f)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
int ret;
|
||||
|
||||
ret = __archive_write_open_filter(f->next_filter);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
|
||||
if (data->out.dst == NULL) {
|
||||
size_t bs = ZSTD_CStreamOutSize(), bpb;
|
||||
if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
|
||||
/* Buffer size should be a multiple number of
|
||||
* the of bytes per block for performance. */
|
||||
bpb = archive_write_get_bytes_per_block(f->archive);
|
||||
if (bpb > bs)
|
||||
bs = bpb;
|
||||
else if (bpb != 0)
|
||||
bs -= bs % bpb;
|
||||
}
|
||||
data->out.size = bs;
|
||||
data->out.pos = 0;
|
||||
data->out.dst
|
||||
= (unsigned char *)malloc(data->out.size);
|
||||
if (data->out.dst == NULL) {
|
||||
archive_set_error(f->archive, ENOMEM,
|
||||
"Can't allocate data for compression buffer");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
f->write = archive_compressor_zstd_write;
|
||||
|
||||
if (ZSTD_isError(ZSTD_initCStream(data->cstream,
|
||||
data->compression_level))) {
|
||||
archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Internal error initializing zstd compressor object");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to the compressed stream.
|
||||
*/
|
||||
static int
|
||||
archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
|
||||
size_t length)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
int ret;
|
||||
|
||||
/* Update statistics */
|
||||
data->total_in += length;
|
||||
|
||||
if ((ret = drive_compressor(f, data, 0, buff, length)) != ARCHIVE_OK)
|
||||
return (ret);
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish the compression...
|
||||
*/
|
||||
static int
|
||||
archive_compressor_zstd_close(struct archive_write_filter *f)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
int r1, r2;
|
||||
|
||||
/* Finish zstd frame */
|
||||
r1 = drive_compressor(f, data, 1, NULL, 0);
|
||||
|
||||
r2 = __archive_write_close_filter(f->next_filter);
|
||||
|
||||
return r1 < r2 ? r1 : r2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function to push input data through compressor,
|
||||
* writing full output blocks as necessary.
|
||||
*
|
||||
* Note that this handles both the regular write case (finishing ==
|
||||
* false) and the end-of-archive case (finishing == true).
|
||||
*/
|
||||
static int
|
||||
drive_compressor(struct archive_write_filter *f,
|
||||
struct private_data *data, int finishing, const void *src, size_t length)
|
||||
{
|
||||
ZSTD_inBuffer in = (ZSTD_inBuffer) { src, length, 0 };
|
||||
|
||||
for (;;) {
|
||||
if (data->out.pos == data->out.size) {
|
||||
const int ret = __archive_write_filter(f->next_filter,
|
||||
data->out.dst, data->out.size);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
data->out.pos = 0;
|
||||
}
|
||||
|
||||
/* If there's nothing to do, we're done. */
|
||||
if (!finishing && in.pos == in.size)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
{
|
||||
const size_t zstdret = !finishing ?
|
||||
ZSTD_compressStream(data->cstream, &data->out, &in)
|
||||
: ZSTD_endStream(data->cstream, &data->out);
|
||||
|
||||
if (ZSTD_isError(zstdret)) {
|
||||
archive_set_error(f->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Zstd compression failed: %s",
|
||||
ZSTD_getErrorName(zstdret));
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
/* If we're finishing, 0 means nothing left to flush */
|
||||
if (finishing && zstdret == 0) {
|
||||
const int ret = __archive_write_filter(f->next_filter,
|
||||
data->out.dst, data->out.pos);
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else /* HAVE_ZSTD_H && HAVE_LIBZSTD */
|
||||
|
||||
static int
|
||||
archive_compressor_zstd_open(struct archive_write_filter *f)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
struct archive_string as;
|
||||
int r;
|
||||
|
||||
archive_string_init(&as);
|
||||
archive_string_sprintf(&as, "zstd -%d", data->compression_level);
|
||||
|
||||
f->write = archive_compressor_zstd_write;
|
||||
r = __archive_write_program_open(f, data->pdata, as.s);
|
||||
archive_string_free(&as);
|
||||
return (r);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff,
|
||||
size_t length)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
|
||||
return __archive_write_program_write(f, data->pdata, buff, length);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_compressor_zstd_close(struct archive_write_filter *f)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)f->data;
|
||||
|
||||
return __archive_write_program_close(f, data->pdata);
|
||||
}
|
||||
|
||||
#endif /* HAVE_ZSTD_H && HAVE_LIBZSTD */
|
@ -42,7 +42,8 @@
|
||||
.Nm archive_write_add_filter_none ,
|
||||
.Nm archive_write_add_filter_program ,
|
||||
.Nm archive_write_add_filter_uuencode ,
|
||||
.Nm archive_write_add_filter_xz
|
||||
.Nm archive_write_add_filter_xz ,
|
||||
.Nm archive_write_add_filter_zstd ,
|
||||
.Nd functions enabling output filters
|
||||
.Sh LIBRARY
|
||||
Streaming Archive Library (libarchive, -larchive)
|
||||
@ -76,6 +77,8 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Fn archive_write_add_filter_uuencode "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_write_add_filter_xz "struct archive *"
|
||||
.Ft int
|
||||
.Fn archive_write_add_filter_zstd "struct archive *"
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -width indent
|
||||
.It Xo
|
||||
@ -89,6 +92,7 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Fn archive_write_add_filter_lzma ,
|
||||
.Fn archive_write_add_filter_lzop ,
|
||||
.Fn archive_write_add_filter_xz ,
|
||||
.Fn archive_write_add_filter_zstd ,
|
||||
.Xc
|
||||
The resulting archive will be compressed as specified.
|
||||
Note that the compressed output is always properly blocked.
|
||||
|
@ -1654,7 +1654,7 @@ build_pax_attribute_name(char *dest, const char *src)
|
||||
* GNU PAX Format 1.0 requires the special name, which pattern is:
|
||||
* <dir>/GNUSparseFile.<pid>/<original file name>
|
||||
*
|
||||
* Since reproducable archives are more important, use 0 as pid.
|
||||
* Since reproducible archives are more important, use 0 as pid.
|
||||
*
|
||||
* This function is used for only Sparse file, a file type of which
|
||||
* is regular file.
|
||||
|
@ -207,3 +207,8 @@ DEFINE_TEST(test_archive_write_add_filter_by_name_xz)
|
||||
{
|
||||
test_filter_by_name("xz", ARCHIVE_FILTER_XZ, cannot);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_archive_write_add_filter_by_name_zstd)
|
||||
{
|
||||
test_filter_by_name("zstd", ARCHIVE_FILTER_ZSTD, canZstd);
|
||||
}
|
||||
|
82
contrib/libarchive/libarchive/test/test_compat_zstd.c
Normal file
82
contrib/libarchive/libarchive/test/test_compat_zstd.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Sean Purcell
|
||||
* 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$");
|
||||
|
||||
/*
|
||||
* Verify our ability to read sample files compatibly with 'zstd -d'.
|
||||
*
|
||||
* In particular:
|
||||
* * zstd -d will read multiple zstd streams, concatenating the output
|
||||
* * zstd -d will skip over zstd skippable frames
|
||||
*/
|
||||
|
||||
static void
|
||||
compat_zstd(const char *name)
|
||||
{
|
||||
const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL };
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
int i, r;
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
r = archive_read_support_filter_zstd(a);
|
||||
if (r == ARCHIVE_WARN) {
|
||||
skipping("zstd reading not fully supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
extract_reference_file(name);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2));
|
||||
|
||||
/* Read entries, match up names with list above. */
|
||||
for (i = 0; i < 6; ++i) {
|
||||
failure("Could not read file %d (%s) from %s", i, n[i], name);
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_next_header(a, &ae));
|
||||
assertEqualString(n[i], archive_entry_pathname(ae));
|
||||
}
|
||||
|
||||
/* Verify the end-of-archive. */
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
|
||||
/* Verify that the format detection worked. */
|
||||
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_ZSTD);
|
||||
assertEqualString(archive_filter_name(a, 0), "zstd");
|
||||
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
|
||||
DEFINE_TEST(test_compat_zstd)
|
||||
{
|
||||
/* This sample was compressed as 3 separate streams with a zstd skippable
|
||||
* frame placed in the middle */
|
||||
compat_zstd("test_compat_zstd_1.tar.zst");
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
begin 644 test_compat_zstd_1.tar.zst
|
||||
M*+4O_010)0,`HL0.%;`Q&>>\/$2[#IQF[<1+Z3T<0CX]!77&0@R.6+/F,0+I
|
||||
M.$1A$QE2`J!+*_6[_YT9_W_M1KC-EG*V>10.`,M`%3*@#F#\`-FT#J:1#U1"
|
||||
M`H1!&R#<!.<"@#3@M58XY1,8`DMMD\@HM2_]!%!=`P`B!1`5H#D!0!.SELJ"
|
||||
M5#509I*T/YQ^]?H/3T1D>A5\*'"JYIJ;C&4=B2CL(L)*E-IJT/RV?.:A_]_N
|
||||
MB&[7SDG;/=4&#P";0!5D0`=8T0&R&19,)1^HA`0(@S9`N`G.!0!IP&NM<,K!
|
||||
M-#8!%A]U]K10*DT8!`````$"`P0HM2_]!%!]`P`B11`6H+$)"%]@,Z6OH`"L
|
||||
MM$R2MAN&*MSG`W?OJ7+4P*B::VXR`NM(1&$7&58"J*U'_&V^S$/_O]U1N%T[
|
||||
M)VW7J'+4!A``_4$%^T`],J`8P.0!L@D63"4?J(0$"(,V0+@)S@4`:<!KK7!J
|
||||
)P51V`E@!9CD#
|
||||
`
|
||||
end
|
@ -412,6 +412,12 @@ DEFINE_TEST(test_fuzz_tar)
|
||||
"test_compat_lzop_1.tar.lzo",
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
static const char *fileset10[] = {
|
||||
"test_compat_zstd_1.tar.zst",
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
static const struct files filesets[] = {
|
||||
{0, fileset1}, /* Exercise bzip2 decompressor. */
|
||||
@ -425,6 +431,9 @@ DEFINE_TEST(test_fuzz_tar)
|
||||
{0, fileset8},
|
||||
#if HAVE_LIBLZO2 && HAVE_LZO_LZO1X_H && HAVE_LZO_LZOCONF_H
|
||||
{0, fileset9}, /* Exercise lzo decompressor. */
|
||||
#endif
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
{0, fileset10}, /* Excercise zstd decompressor. */
|
||||
#endif
|
||||
{1, NULL}
|
||||
};
|
||||
|
201
contrib/libarchive/libarchive/test/test_write_filter_zstd.c
Normal file
201
contrib/libarchive/libarchive/test/test_write_filter_zstd.c
Normal file
@ -0,0 +1,201 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Sean Purcell
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
DEFINE_TEST(test_write_filter_zstd)
|
||||
{
|
||||
struct archive_entry *ae;
|
||||
struct archive *a;
|
||||
char *buff, *data;
|
||||
size_t buffsize, datasize;
|
||||
char path[16];
|
||||
size_t used1, used2;
|
||||
int i, r;
|
||||
|
||||
buffsize = 2000000;
|
||||
assert(NULL != (buff = (char *)malloc(buffsize)));
|
||||
if (buff == NULL)
|
||||
return;
|
||||
|
||||
datasize = 10000;
|
||||
assert(NULL != (data = (char *)malloc(datasize)));
|
||||
if (data == NULL) {
|
||||
free(buff);
|
||||
return;
|
||||
}
|
||||
memset(data, 0, datasize);
|
||||
|
||||
/*
|
||||
* Write a 100 files and read them all back.
|
||||
*/
|
||||
assert((a = archive_write_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
|
||||
r = archive_write_add_filter_zstd(a);
|
||||
if (r != ARCHIVE_OK) {
|
||||
skipping("zstd writing not supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
free(buff);
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_write_set_bytes_per_block(a, 10));
|
||||
assertEqualInt(ARCHIVE_FILTER_ZSTD, archive_filter_code(a, 0));
|
||||
assertEqualString("zstd", archive_filter_name(a, 0));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used1));
|
||||
assertEqualInt(ARCHIVE_FILTER_ZSTD, archive_filter_code(a, 0));
|
||||
assertEqualString("zstd", archive_filter_name(a, 0));
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_set_filetype(ae, AE_IFREG);
|
||||
archive_entry_set_size(ae, datasize);
|
||||
for (i = 0; i < 100; i++) {
|
||||
sprintf(path, "file%03d", i);
|
||||
archive_entry_copy_pathname(ae, path);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
|
||||
assertA(datasize
|
||||
== (size_t)archive_write_data(a, data, datasize));
|
||||
}
|
||||
archive_entry_free(ae);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
r = archive_read_support_filter_zstd(a);
|
||||
if (r == ARCHIVE_WARN) {
|
||||
skipping("Can't verify zstd writing by reading back;"
|
||||
" zstd reading not fully supported on this platform");
|
||||
} else {
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_open_memory(a, buff, used1));
|
||||
for (i = 0; i < 100; i++) {
|
||||
sprintf(path, "file%03d", i);
|
||||
if (!assertEqualInt(ARCHIVE_OK,
|
||||
archive_read_next_header(a, &ae)))
|
||||
break;
|
||||
assertEqualString(path, archive_entry_pathname(ae));
|
||||
assertEqualInt((int)datasize, archive_entry_size(ae));
|
||||
}
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
}
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
/*
|
||||
* Repeat the cycle again, this time setting some compression
|
||||
* options.
|
||||
*/
|
||||
assert((a = archive_write_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_write_set_bytes_per_block(a, 10));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a));
|
||||
assertEqualIntA(a, ARCHIVE_FAILED,
|
||||
archive_write_set_filter_option(a, NULL, "nonexistent-option", "0"));
|
||||
assertEqualIntA(a, ARCHIVE_FAILED,
|
||||
archive_write_set_filter_option(a, NULL, "compression-level", "abc"));
|
||||
assertEqualIntA(a, ARCHIVE_FAILED,
|
||||
archive_write_set_filter_option(a, NULL, "compression-level", "25")); /* too big */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_write_set_filter_option(a, NULL, "compression-level", "9"));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_write_set_filter_option(a, NULL, "compression-level", "15"));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
|
||||
for (i = 0; i < 100; i++) {
|
||||
sprintf(path, "file%03d", i);
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_copy_pathname(ae, path);
|
||||
archive_entry_set_size(ae, datasize);
|
||||
archive_entry_set_filetype(ae, AE_IFREG);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
|
||||
assertA(datasize == (size_t)archive_write_data(a, data, datasize));
|
||||
archive_entry_free(ae);
|
||||
}
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
failure("compression-level=15 wrote %d bytes, default wrote %d bytes",
|
||||
(int)used2, (int)used1);
|
||||
assert(used2 < used1);
|
||||
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
r = archive_read_support_filter_zstd(a);
|
||||
if (r == ARCHIVE_WARN) {
|
||||
skipping("zstd reading not fully supported on this platform");
|
||||
} else {
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_open_memory(a, buff, used2));
|
||||
for (i = 0; i < 100; i++) {
|
||||
sprintf(path, "file%03d", i);
|
||||
failure("Trying to read %s", path);
|
||||
if (!assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_next_header(a, &ae)))
|
||||
break;
|
||||
assertEqualString(path, archive_entry_pathname(ae));
|
||||
assertEqualInt((int)datasize, archive_entry_size(ae));
|
||||
}
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
}
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
/*
|
||||
* Test various premature shutdown scenarios to make sure we
|
||||
* don't crash or leak memory.
|
||||
*/
|
||||
assert((a = archive_write_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
assert((a = archive_write_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
assert((a = archive_write_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
assert((a = archive_write_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/*
|
||||
* Clean up.
|
||||
*/
|
||||
free(data);
|
||||
free(buff);
|
||||
}
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 25, 2017
|
||||
.Dd October 1, 2017
|
||||
.Dt TAR 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -302,19 +302,18 @@ containing the string
|
||||
Compress the resulting archive with
|
||||
.Xr xz 1 .
|
||||
In extract or list modes, this option is ignored.
|
||||
Note that, unlike other
|
||||
Note that this
|
||||
.Nm tar
|
||||
implementations, this implementation recognizes XZ compression
|
||||
automatically when reading archives.
|
||||
implementation recognizes XZ compression automatically when reading archives.
|
||||
.It Fl j , Fl Fl bzip , Fl Fl bzip2 , Fl Fl bunzip2
|
||||
(c mode only)
|
||||
Compress the resulting archive with
|
||||
.Xr bzip2 1 .
|
||||
In extract or list modes, this option is ignored.
|
||||
Note that, unlike other
|
||||
Note that this
|
||||
.Nm tar
|
||||
implementations, this implementation recognizes bzip2 compression
|
||||
automatically when reading archives.
|
||||
implementation recognizes bzip2 compression automatically when reading
|
||||
archives.
|
||||
.It Fl k , Fl Fl keep-old-files
|
||||
(x mode only)
|
||||
Do not overwrite existing files.
|
||||
@ -337,25 +336,41 @@ Issue a warning message unless all links to each file are archived.
|
||||
Compress the resulting archive with
|
||||
.Xr lrzip 1 .
|
||||
In extract or list modes, this option is ignored.
|
||||
Note that this
|
||||
.Nm tar
|
||||
implementation recognizes lrzip compression automatically when reading
|
||||
archives.
|
||||
.It Fl Fl lz4
|
||||
(c 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.
|
||||
In extract or list modes, this option is ignored.
|
||||
Note that this
|
||||
.Nm tar
|
||||
implementation recognizes lz4 compression automatically when reading archives.
|
||||
.It Fl Fl zstd
|
||||
(c mode only)
|
||||
Compress the archive with zstd-compatible compression before writing it.
|
||||
In extract or list modes, this option is ignored.
|
||||
Note that this
|
||||
.Nm tar
|
||||
implementation recognizes zstd compression automatically when reading archives.
|
||||
.It Fl Fl lzma
|
||||
(c mode only) Compress the resulting archive with the original LZMA algorithm.
|
||||
In extract or list modes, this option is ignored.
|
||||
Use of this option is discouraged and new archives should be created with
|
||||
.Fl Fl xz
|
||||
instead.
|
||||
Note that, unlike other
|
||||
Note that this
|
||||
.Nm tar
|
||||
implementations, this implementation recognizes LZMA compression
|
||||
automatically when reading archives.
|
||||
implementation recognizes LZMA compression automatically when reading archives.
|
||||
.It Fl Fl lzop
|
||||
(c mode only)
|
||||
Compress the resulting archive with
|
||||
.Xr lzop 1 .
|
||||
In extract or list modes, this option is ignored.
|
||||
Note that this
|
||||
.Nm tar
|
||||
implementation recognizes LZO compression automatically when reading archives.
|
||||
.It Fl m , Fl Fl modification-time
|
||||
(x mode only)
|
||||
Do not extract modification time.
|
||||
@ -577,6 +592,8 @@ A decimal integer from 4 to 7 specifying the lz4 compression block size
|
||||
.It Cm lz4:block-dependence
|
||||
Use the previous block of the block being compressed for
|
||||
a compression dictionary to improve compression ratio.
|
||||
.It Cm zstd:compression-level
|
||||
A decimal integer from 1 to 22 specifying the zstd compression level.
|
||||
.It Cm lzop:compression-level
|
||||
A decimal integer from 1 to 9 specifying the lzop compression level.
|
||||
.It Cm xz:compression-level
|
||||
@ -826,28 +843,28 @@ is run in x mode as root.
|
||||
Compress the resulting archive with
|
||||
.Xr bzip2 1 .
|
||||
In extract or list modes, this option is ignored.
|
||||
Note that, unlike other
|
||||
Note that this
|
||||
.Nm tar
|
||||
implementations, this implementation recognizes bzip2 compression
|
||||
automatically when reading archives.
|
||||
implementation recognizes bzip2 compression automatically when reading
|
||||
archives.
|
||||
.It Fl Z , Fl Fl compress , Fl Fl uncompress
|
||||
(c mode only)
|
||||
Compress the resulting archive with
|
||||
.Xr compress 1 .
|
||||
In extract or list modes, this option is ignored.
|
||||
Note that, unlike other
|
||||
Note that this
|
||||
.Nm tar
|
||||
implementations, this implementation recognizes compress compression
|
||||
automatically when reading archives.
|
||||
implementation recognizes compress compression automatically when reading
|
||||
archives.
|
||||
.It Fl z , Fl Fl gunzip , Fl Fl gzip
|
||||
(c mode only)
|
||||
Compress the resulting archive with
|
||||
.Xr gzip 1 .
|
||||
In extract or list modes, this option is ignored.
|
||||
Note that, unlike other
|
||||
Note that this
|
||||
.Nm tar
|
||||
implementations, this implementation recognizes gzip compression
|
||||
automatically when reading archives.
|
||||
implementation recognizes gzip compression automatically when reading
|
||||
archives.
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
The following environment variables affect the execution of
|
||||
|
@ -419,6 +419,7 @@ main(int argc, char **argv)
|
||||
case OPTION_LZIP: /* GNU tar beginning with 1.23 */
|
||||
case OPTION_LZMA: /* GNU tar beginning with 1.20 */
|
||||
case OPTION_LZOP: /* GNU tar beginning with 1.21 */
|
||||
case OPTION_ZSTD:
|
||||
if (compression != '\0')
|
||||
lafe_errc(1, 0,
|
||||
"Can't specify both -%c and -%c", opt,
|
||||
@ -427,9 +428,10 @@ main(int argc, char **argv)
|
||||
switch (opt) {
|
||||
case OPTION_LRZIP: compression_name = "lrzip"; break;
|
||||
case OPTION_LZ4: compression_name = "lz4"; break;
|
||||
case OPTION_LZIP: compression_name = "lzip"; break;
|
||||
case OPTION_LZMA: compression_name = "lzma"; break;
|
||||
case OPTION_LZOP: compression_name = "lzop"; break;
|
||||
case OPTION_LZIP: compression_name = "lzip"; break;
|
||||
case OPTION_LZMA: compression_name = "lzma"; break;
|
||||
case OPTION_LZOP: compression_name = "lzop"; break;
|
||||
case OPTION_ZSTD: compression_name = "zstd"; break;
|
||||
}
|
||||
break;
|
||||
case 'm': /* SUSv2 */
|
||||
|
@ -181,7 +181,8 @@ enum {
|
||||
OPTION_USE_COMPRESS_PROGRAM,
|
||||
OPTION_UUENCODE,
|
||||
OPTION_VERSION,
|
||||
OPTION_XATTRS
|
||||
OPTION_XATTRS,
|
||||
OPTION_ZSTD,
|
||||
};
|
||||
|
||||
int bsdtar_getopt(struct bsdtar *);
|
||||
|
@ -160,6 +160,7 @@ static const struct bsdtar_option {
|
||||
{ "version", 0, OPTION_VERSION },
|
||||
{ "xattrs", 0, OPTION_XATTRS },
|
||||
{ "xz", 0, 'J' },
|
||||
{ "zstd", 0, OPTION_ZSTD },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -80,9 +80,10 @@ get_filter_code(const char *suffix)
|
||||
{ ".lzma", "lzma" },
|
||||
{ ".uu", "uuencode" },
|
||||
{ ".xz", "xz" },
|
||||
{ ".zst", "zstd"},
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
return get_suffix_code(filters, suffix);
|
||||
}
|
||||
|
||||
@ -121,6 +122,7 @@ decompose_alias(const char *suffix)
|
||||
{ ".tzo", ".tar.lzo" },
|
||||
{ ".taZ", ".tar.Z" },
|
||||
{ ".tZ", ".tar.Z" },
|
||||
{ ".tzst", ".tar.zst" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
6
contrib/libarchive/tar/test/test_extract.tar.zst.uu
Normal file
6
contrib/libarchive/tar/test/test_extract.tar.zst.uu
Normal file
@ -0,0 +1,6 @@
|
||||
begin 644 test_extract.tar.zst
|
||||
M*+4O_010S0,`<L40$Z`5.(2U_RNV_[]L4V;Z_/R@1:7Y$3;9E`8$D$WI:W1)
|
||||
M'58'D3->Y+>!0*5E/PM"$7^K^1VI3SS-AX&_W0KQWY!-Z1(`_4$%[$"]<T!A
|
||||
L(*`#I!DXC4[J!6J8$!DJ$D"9$T*L]#G-$$/A`#`I`-(`UUKAU$Z@"`UXII``
|
||||
`
|
||||
end
|
48
contrib/libarchive/tar/test/test_extract_tar_zstd.c
Normal file
48
contrib/libarchive/tar/test/test_extract_tar_zstd.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Sean Purcell
|
||||
* 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_tar_zstd)
|
||||
{
|
||||
const char *reffile = "test_extract.tar.zst";
|
||||
int f;
|
||||
|
||||
extract_reference_file(reffile);
|
||||
f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile);
|
||||
if (f == 0 || canZstd()) {
|
||||
assertEqualInt(0, systemf("%s -xf %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");
|
||||
assertEmptyFile("test.err");
|
||||
} else {
|
||||
skipping("It seems zstd is not supported on this platform");
|
||||
}
|
||||
}
|
@ -483,7 +483,7 @@ DEFINE_TEST(test_option_acls)
|
||||
r = compare_acls("f", "acls_acls/f");
|
||||
assertEqualInt(r, 1);
|
||||
|
||||
/* Extractl acls without acls */
|
||||
/* Extract acls without acls */
|
||||
assertMakeDir("acls_noacls", 0755);
|
||||
clear_inheritance_flags("acls_noacls", acltype);
|
||||
r = systemf("%s -x -C acls_noacls -p --no-acls -f acls.tar >acls_noacls.out 2>acls_noacls.err", testprog);
|
||||
|
85
contrib/libarchive/tar/test/test_option_zstd.c
Normal file
85
contrib/libarchive/tar/test/test_option_zstd.c
Normal file
@ -0,0 +1,85 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Sean Purcell
|
||||
* 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_zstd)
|
||||
{
|
||||
char *p;
|
||||
int r;
|
||||
size_t s;
|
||||
|
||||
/* Create a file. */
|
||||
assertMakeFile("f", 0644, "a");
|
||||
|
||||
/* Archive it with lz4 compression. */
|
||||
r = systemf("%s -cf - --zstd f >archive.out 2>archive.err",
|
||||
testprog);
|
||||
p = slurpfile(&s, "archive.err");
|
||||
p[s] = '\0';
|
||||
if (r != 0) {
|
||||
if (strstr(p, "Unsupported compression") != NULL) {
|
||||
skipping("This version of bsdtar was compiled "
|
||||
"without zstd support");
|
||||
goto done;
|
||||
}
|
||||
/* 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 && !canZstd()) {
|
||||
skipping("This version of bsdtar uses an external zstd program "
|
||||
"but no such program is available on this system.");
|
||||
goto done;
|
||||
}
|
||||
/* 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 && !canZstd()) {
|
||||
skipping("This version of bsdtar uses an external zstd program "
|
||||
"but no such program is available on this system.");
|
||||
goto done;
|
||||
}
|
||||
/* On some systems the error won't be detected until closing
|
||||
time, by a 127 exit error returned by waitpid. */
|
||||
if (strstr(p, "Error closing") != NULL && !canZstd()) {
|
||||
skipping("This version of bsdcpio uses an external zstd program "
|
||||
"but no such program is available on this system.");
|
||||
return;
|
||||
}
|
||||
failure("--zstd option is broken: %s", p);
|
||||
assertEqualInt(r, 0);
|
||||
goto done;
|
||||
}
|
||||
free(p);
|
||||
/* Check that the archive file has an lz4 signature. */
|
||||
p = slurpfile(&s, "archive.out");
|
||||
assert(s > 2);
|
||||
assertEqualMem(p, "\x28\xb5\x2f\xfd", 4);
|
||||
|
||||
done:
|
||||
free(p);
|
||||
}
|
@ -329,6 +329,9 @@ int canLrzip(void);
|
||||
/* Return true if this platform can run the "lz4" program. */
|
||||
int canLz4(void);
|
||||
|
||||
/* Return true if this platform can run the "zstd" program. */
|
||||
int canZstd(void);
|
||||
|
||||
/* Return true if this platform can run the "lzip" program. */
|
||||
int canLzip(void);
|
||||
|
||||
|
@ -2318,6 +2318,21 @@ canLz4(void)
|
||||
return (value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this platform run the zstd program?
|
||||
*/
|
||||
int
|
||||
canZstd(void)
|
||||
{
|
||||
static int tested = 0, value = 0;
|
||||
if (!tested) {
|
||||
tested = 1;
|
||||
if (systemf("zstd -V %s", redirectArgs) == 0)
|
||||
value = 1;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can this platform run the lzip program?
|
||||
*/
|
||||
|
@ -53,6 +53,7 @@ tmpmfs_flags="-S" # Extra mdmfs options for the mfs /tmp
|
||||
varmfs="AUTO" # Set to YES to always create an mfs /var, NO to never
|
||||
varsize="32m" # Size of mfs /var if created
|
||||
varmfs_flags="-S" # Extra mount options for the mfs /var
|
||||
mfs_type="auto" # "md", "tmpfs", "auto" to prefer tmpfs with md as fallback
|
||||
populate_var="AUTO" # Set to YES to always (re)populate /var, NO to never
|
||||
cleanvar_enable="YES" # Clean the /var directory
|
||||
local_startup="/usr/local/etc/rc.d" # startup script dirs.
|
||||
|
@ -195,10 +195,11 @@ handle_remount() { # $1 = mount point
|
||||
to_umount="$b ${to_umount}"
|
||||
}
|
||||
|
||||
# Create a generic memory disk (using tmpfs)
|
||||
#
|
||||
# Create a generic memory disk.
|
||||
# The 'auto' parameter will attempt to use tmpfs(5), falls back to md(4).
|
||||
# $1 is size in 512-byte sectors, $2 is the mount point.
|
||||
mount_md() {
|
||||
mount -t tmpfs -o size=$(($1 * 512)) tmpfs $2
|
||||
/sbin/mdmfs -s $1 auto $2
|
||||
}
|
||||
|
||||
# Create the memory filesystem if it has not already been created
|
||||
|
@ -1790,7 +1790,7 @@ mount_md()
|
||||
if [ -n "$3" ]; then
|
||||
flags="$3"
|
||||
fi
|
||||
/sbin/mdmfs $flags -s $1 md $2
|
||||
/sbin/mdmfs $flags -s $1 ${mfs_type} $2
|
||||
}
|
||||
|
||||
# Code common to scripts that need to load a kernel module
|
||||
|
@ -94,6 +94,7 @@ SRCS= archive_acl.c \
|
||||
archive_read_support_filter_rpm.c \
|
||||
archive_read_support_filter_uu.c \
|
||||
archive_read_support_filter_xz.c \
|
||||
archive_read_support_filter_zstd.c \
|
||||
archive_read_support_format_7zip.c \
|
||||
archive_read_support_format_all.c \
|
||||
archive_read_support_format_ar.c \
|
||||
@ -136,6 +137,7 @@ SRCS= archive_acl.c \
|
||||
archive_write_add_filter_program.c \
|
||||
archive_write_add_filter_uuencode.c \
|
||||
archive_write_add_filter_xz.c \
|
||||
archive_write_add_filter_zstd.c \
|
||||
archive_write_set_format.c \
|
||||
archive_write_set_format_7zip.c \
|
||||
archive_write_set_format_ar.c \
|
||||
|
@ -83,6 +83,7 @@ TESTS_SRCS= \
|
||||
test_compat_uudecode_large.c \
|
||||
test_compat_xz.c \
|
||||
test_compat_zip.c \
|
||||
test_compat_zstd.c \
|
||||
test_empty_write.c \
|
||||
test_entry.c \
|
||||
test_entry_strmode.c \
|
||||
@ -240,6 +241,7 @@ TESTS_SRCS= \
|
||||
test_write_filter_program.c \
|
||||
test_write_filter_uuencode.c \
|
||||
test_write_filter_xz.c \
|
||||
test_write_filter_zstd.c \
|
||||
test_write_format_7zip.c \
|
||||
test_write_format_7zip_empty.c \
|
||||
test_write_format_7zip_large.c \
|
||||
@ -373,6 +375,7 @@ ${PACKAGE}FILES+= test_compat_zip_4.zip.uu
|
||||
${PACKAGE}FILES+= test_compat_zip_5.zip.uu
|
||||
${PACKAGE}FILES+= test_compat_zip_6.zip.uu
|
||||
${PACKAGE}FILES+= test_compat_zip_7.xps.uu
|
||||
${PACKAGE}FILES+= test_compat_zstd_1.tar.zst.uu
|
||||
${PACKAGE}FILES+= test_fuzz.cab.uu
|
||||
${PACKAGE}FILES+= test_fuzz.lzh.uu
|
||||
${PACKAGE}FILES+= test_fuzz_1.iso.Z.uu
|
||||
|
@ -125,8 +125,7 @@ __collate_load_tables_l(const char *encoding, struct xlocale_collate *table)
|
||||
return (_LDP_CACHE);
|
||||
}
|
||||
|
||||
asprintf(&buf, "%s/%s/LC_COLLATE", _PathLocale, encoding);
|
||||
if (buf == NULL)
|
||||
if (asprintf(&buf, "%s/%s/LC_COLLATE", _PathLocale, encoding) == -1)
|
||||
return (_LDP_ERROR);
|
||||
|
||||
if ((fd = _open(buf, O_RDONLY)) < 0) {
|
||||
|
@ -110,9 +110,8 @@ __setrunelocale(struct xlocale_ctype *l, const char *encoding)
|
||||
}
|
||||
|
||||
/* Range checking not needed, encoding length already checked before */
|
||||
asprintf(&path, "%s/%s/LC_CTYPE", _PathLocale, encoding);
|
||||
if (path == NULL)
|
||||
return (0);
|
||||
if (asprintf(&path, "%s/%s/LC_CTYPE", _PathLocale, encoding) == -1)
|
||||
return (errno);
|
||||
|
||||
if ((rl = _Read_RuneMagi(path)) == NULL) {
|
||||
free(path);
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 9, 2016
|
||||
.Dd September 9, 2017
|
||||
.Dt MDMFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -33,7 +33,9 @@
|
||||
.Nm mount_mfs
|
||||
.Nd configure and mount an in-memory file system using the
|
||||
.Xr md 4
|
||||
driver
|
||||
driver or the
|
||||
.Xr tmpfs 5
|
||||
filesystem
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl DLlMNnPStTUX
|
||||
@ -63,9 +65,13 @@ utility is designed to be a work-alike and look-alike of the deprecated
|
||||
.Xr mount_mfs 8 .
|
||||
The end result is essentially the same,
|
||||
but is accomplished in a completely different way.
|
||||
The
|
||||
Based on
|
||||
.Ar md-device ,
|
||||
the
|
||||
.Nm
|
||||
utility configures an
|
||||
utility either creates a
|
||||
.Xr tmpfs 5
|
||||
filesystem, or it configures an
|
||||
.Xr md 4
|
||||
disk using
|
||||
.Xr mdconfig 8 ,
|
||||
@ -81,6 +87,44 @@ compressed disk images, as long as the kernel supports this GEOM class.
|
||||
All the command line options are passed to the appropriate program
|
||||
at the appropriate stage in order to achieve the desired effect.
|
||||
.Pp
|
||||
When
|
||||
.Ar md-device
|
||||
is `auto',
|
||||
.Nm
|
||||
uses
|
||||
.Xr tmpfs 5
|
||||
if it is present in the kernel or can be loaded as a module,
|
||||
otherwise it falls back to using
|
||||
.Xr md 4
|
||||
auto-unit as if `md' had been specified.
|
||||
.Pp
|
||||
When
|
||||
.Ar md-device
|
||||
is `tmpfs',
|
||||
.Nm
|
||||
mounts a
|
||||
.Xr tmpfs 5
|
||||
filesystem, translating the
|
||||
.Fl s
|
||||
size option, if present, into a `-o size=' mount option.
|
||||
Any
|
||||
.Fl o
|
||||
options on the command line are passed through to the
|
||||
.Xr tmpfs 5
|
||||
mount.
|
||||
Options specific to
|
||||
.Xr mdconfig 8
|
||||
or
|
||||
.Xr newfs 8
|
||||
are ignored.
|
||||
.Pp
|
||||
When
|
||||
.Ar md-device
|
||||
does not result in
|
||||
.Xr tmpfs 5
|
||||
being used, then an
|
||||
.Xr md 4
|
||||
device is configured instead.
|
||||
By default,
|
||||
.Nm
|
||||
creates a swap-based
|
||||
@ -219,14 +263,10 @@ is
|
||||
.Em not
|
||||
specified.
|
||||
That is,
|
||||
this will work for the default swap-backed
|
||||
.Pq Dv MD_SWAP
|
||||
disks,
|
||||
and the optional
|
||||
.Pq Fl M
|
||||
.Xr malloc 9
|
||||
backed disks
|
||||
.Pq Dv MD_MALLOC .
|
||||
this will work when the backing storage is some form of
|
||||
memory, as opposed to a fixed-size file.
|
||||
The size may include the usual SI suffixes (k, m, g, t, p).
|
||||
A number without a suffix is interpreted as a count of 512-byte sectors.
|
||||
.It Fl t
|
||||
Turn on the TRIM enable flag for
|
||||
.Xr newfs 8 .
|
||||
@ -392,6 +432,7 @@ was given on the command line.
|
||||
.Sh SEE ALSO
|
||||
.Xr md 4 ,
|
||||
.Xr fstab 5 ,
|
||||
.Xr tmpfs 5 ,
|
||||
.Xr mdconfig 8 ,
|
||||
.Xr mount 8 ,
|
||||
.Xr newfs 8
|
||||
|
@ -34,15 +34,19 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/mdioctl.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <inttypes.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
@ -78,7 +82,8 @@ static void debugprintf(const char *, ...) __printflike(1, 2);
|
||||
static void do_mdconfig_attach(const char *, const enum md_types);
|
||||
static void do_mdconfig_attach_au(const char *, const enum md_types);
|
||||
static void do_mdconfig_detach(void);
|
||||
static void do_mount(const char *, const char *);
|
||||
static void do_mount_md(const char *, const char *);
|
||||
static void do_mount_tmpfs(const char *, const char *);
|
||||
static void do_mtptsetup(const char *, struct mtpt_info *);
|
||||
static void do_newfs(const char *);
|
||||
static void extract_ugid(const char *, struct mtpt_info *);
|
||||
@ -89,14 +94,15 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct mtpt_info mi; /* Mountpoint info. */
|
||||
intmax_t mdsize;
|
||||
char *mdconfig_arg, *newfs_arg, /* Args to helper programs. */
|
||||
*mount_arg;
|
||||
enum md_types mdtype; /* The type of our memory disk. */
|
||||
bool have_mdtype;
|
||||
bool have_mdtype, mlmac;
|
||||
bool detach, softdep, autounit, newfs;
|
||||
char *mtpoint, *unitstr;
|
||||
const char *mtpoint, *size_arg, *unitstr;
|
||||
char *p;
|
||||
int ch;
|
||||
int ch, idx;
|
||||
void *set;
|
||||
unsigned long ul;
|
||||
|
||||
@ -105,11 +111,13 @@ main(int argc, char **argv)
|
||||
detach = true;
|
||||
softdep = true;
|
||||
autounit = false;
|
||||
mlmac = false;
|
||||
newfs = true;
|
||||
have_mdtype = false;
|
||||
mdtype = MD_SWAP;
|
||||
mdname = MD_NAME;
|
||||
mdnamelen = strlen(mdname);
|
||||
mdsize = 0;
|
||||
/*
|
||||
* Can't set these to NULL. They may be passed to the
|
||||
* respective programs without modification. I.e., we may not
|
||||
@ -119,6 +127,7 @@ main(int argc, char **argv)
|
||||
mdconfig_arg = strdup("");
|
||||
newfs_arg = strdup("");
|
||||
mount_arg = strdup("");
|
||||
size_arg = NULL;
|
||||
|
||||
/* If we were started as mount_mfs or mfs, imply -C. */
|
||||
if (strcmp(getprogname(), "mount_mfs") == 0 ||
|
||||
@ -175,6 +184,7 @@ main(int argc, char **argv)
|
||||
loudsubs = true;
|
||||
break;
|
||||
case 'l':
|
||||
mlmac = true;
|
||||
argappend(&newfs_arg, "-l");
|
||||
break;
|
||||
case 'M':
|
||||
@ -213,7 +223,7 @@ main(int argc, char **argv)
|
||||
softdep = false;
|
||||
break;
|
||||
case 's':
|
||||
argappend(&mdconfig_arg, "-s %s", optarg);
|
||||
size_arg = optarg;
|
||||
break;
|
||||
case 't':
|
||||
argappend(&newfs_arg, "-t");
|
||||
@ -242,42 +252,107 @@ main(int argc, char **argv)
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
/* Derive 'unit' (global). */
|
||||
unitstr = argv[0];
|
||||
if (strncmp(unitstr, "/dev/", 5) == 0)
|
||||
unitstr += 5;
|
||||
if (strncmp(unitstr, mdname, mdnamelen) == 0)
|
||||
unitstr += mdnamelen;
|
||||
if (!isdigit(*unitstr)) {
|
||||
autounit = true;
|
||||
unit = -1;
|
||||
mdsuffix = unitstr;
|
||||
} else {
|
||||
ul = strtoul(unitstr, &p, 10);
|
||||
if (ul == ULONG_MAX)
|
||||
errx(1, "bad device unit: %s", unitstr);
|
||||
unit = ul;
|
||||
mdsuffix = p; /* can be empty */
|
||||
/*
|
||||
* Historically our size arg was passed directly to mdconfig, which
|
||||
* treats a number without a suffix as a count of 512-byte sectors;
|
||||
* tmpfs would treat it as a count of bytes. To get predictable
|
||||
* behavior for 'auto' we document that the size always uses mdconfig
|
||||
* rules. To make that work, decode the size here so it can be passed
|
||||
* to either tmpfs or mdconfig as a count of bytes.
|
||||
*/
|
||||
if (size_arg != NULL) {
|
||||
mdsize = (intmax_t)strtoumax(size_arg, &p, 0);
|
||||
if (p == size_arg || (p[0] != 0 && p[1] != 0) || mdsize < 0)
|
||||
errx(1, "invalid size '%s'", size_arg);
|
||||
switch (*p) {
|
||||
case 'p':
|
||||
case 'P':
|
||||
mdsize *= 1024;
|
||||
case 't':
|
||||
case 'T':
|
||||
mdsize *= 1024;
|
||||
case 'g':
|
||||
case 'G':
|
||||
mdsize *= 1024;
|
||||
case 'm':
|
||||
case 'M':
|
||||
mdsize *= 1024;
|
||||
case 'k':
|
||||
case 'K':
|
||||
mdsize *= 1024;
|
||||
case 'b':
|
||||
case 'B':
|
||||
break;
|
||||
case '\0':
|
||||
mdsize *= 512;
|
||||
break;
|
||||
default:
|
||||
errx(1, "invalid size suffix on '%s'", size_arg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Based on the command line 'md-device' either mount a tmpfs filesystem
|
||||
* or configure the md device then format and mount a filesystem on it.
|
||||
* If the device is 'auto' use tmpfs if it is available and there is no
|
||||
* request for multilabel MAC (which tmpfs does not support).
|
||||
*/
|
||||
unitstr = argv[0];
|
||||
mtpoint = argv[1];
|
||||
if (!have_mdtype)
|
||||
mdtype = MD_SWAP;
|
||||
if (softdep)
|
||||
argappend(&newfs_arg, "-U");
|
||||
if (mdtype != MD_VNODE && !newfs)
|
||||
errx(1, "-P requires a vnode-backed disk");
|
||||
|
||||
/* Do the work. */
|
||||
if (detach && !autounit)
|
||||
do_mdconfig_detach();
|
||||
if (autounit)
|
||||
do_mdconfig_attach_au(mdconfig_arg, mdtype);
|
||||
else
|
||||
do_mdconfig_attach(mdconfig_arg, mdtype);
|
||||
if (newfs)
|
||||
do_newfs(newfs_arg);
|
||||
do_mount(mount_arg, mtpoint);
|
||||
if (strcmp(unitstr, "auto") == 0) {
|
||||
if (mlmac)
|
||||
idx = -1; /* Must use md for mlmac. */
|
||||
else if ((idx = modfind("tmpfs")) == -1)
|
||||
idx = kldload("tmpfs");
|
||||
if (idx == -1)
|
||||
unitstr = "md";
|
||||
else
|
||||
unitstr = "tmpfs";
|
||||
}
|
||||
|
||||
if (strcmp(unitstr, "tmpfs") == 0) {
|
||||
if (size_arg != NULL && mdsize != 0)
|
||||
argappend(&mount_arg, "-o size=%jd", mdsize);
|
||||
do_mount_tmpfs(mount_arg, mtpoint);
|
||||
} else {
|
||||
if (size_arg != NULL)
|
||||
argappend(&mdconfig_arg, "-s %jdB", mdsize);
|
||||
if (strncmp(unitstr, "/dev/", 5) == 0)
|
||||
unitstr += 5;
|
||||
if (strncmp(unitstr, mdname, mdnamelen) == 0)
|
||||
unitstr += mdnamelen;
|
||||
if (!isdigit(*unitstr)) {
|
||||
autounit = true;
|
||||
unit = -1;
|
||||
mdsuffix = unitstr;
|
||||
} else {
|
||||
ul = strtoul(unitstr, &p, 10);
|
||||
if (ul == ULONG_MAX)
|
||||
errx(1, "bad device unit: %s", unitstr);
|
||||
unit = ul;
|
||||
mdsuffix = p; /* can be empty */
|
||||
}
|
||||
|
||||
if (!have_mdtype)
|
||||
mdtype = MD_SWAP;
|
||||
if (softdep)
|
||||
argappend(&newfs_arg, "-U");
|
||||
if (mdtype != MD_VNODE && !newfs)
|
||||
errx(1, "-P requires a vnode-backed disk");
|
||||
|
||||
/* Do the work. */
|
||||
if (detach && !autounit)
|
||||
do_mdconfig_detach();
|
||||
if (autounit)
|
||||
do_mdconfig_attach_au(mdconfig_arg, mdtype);
|
||||
else
|
||||
do_mdconfig_attach(mdconfig_arg, mdtype);
|
||||
if (newfs)
|
||||
do_newfs(newfs_arg);
|
||||
do_mount_md(mount_arg, mtpoint);
|
||||
}
|
||||
|
||||
do_mtptsetup(mtpoint, &mi);
|
||||
|
||||
return (0);
|
||||
@ -434,7 +509,7 @@ do_mdconfig_detach(void)
|
||||
* Mount the configured memory disk.
|
||||
*/
|
||||
static void
|
||||
do_mount(const char *args, const char *mtpoint)
|
||||
do_mount_md(const char *args, const char *mtpoint)
|
||||
{
|
||||
int rv;
|
||||
|
||||
@ -444,6 +519,19 @@ do_mount(const char *args, const char *mtpoint)
|
||||
errx(1, "mount exited with error code %d", rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mount the configured tmpfs.
|
||||
*/
|
||||
static void
|
||||
do_mount_tmpfs(const char *args, const char *mtpoint)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = run(NULL, "%s -t tmpfs %s tmp %s", _PATH_MOUNT, args, mtpoint);
|
||||
if (rv)
|
||||
errx(1, "tmpfs mount exited with error code %d", rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Various configuration of the mountpoint. Mostly, enact 'mip'.
|
||||
*/
|
||||
|
@ -180,6 +180,7 @@ __DEFAULT_NO_OPTIONS = \
|
||||
GNU_GREP_COMPAT \
|
||||
HESIOD \
|
||||
LIBSOFT \
|
||||
LOADER_FORCE_LE \
|
||||
NAND \
|
||||
OFED \
|
||||
OPENLDAP \
|
||||
|
@ -1041,10 +1041,10 @@ awg_ioctl(if_t ifp, u_long cmd, caddr_t data)
|
||||
if_togglecapenable(ifp, IFCAP_RXCSUM);
|
||||
if (mask & IFCAP_TXCSUM)
|
||||
if_togglecapenable(ifp, IFCAP_TXCSUM);
|
||||
if ((if_getcapenable(ifp) & (IFCAP_RXCSUM|IFCAP_TXCSUM)) != 0)
|
||||
if_sethwassistbits(ifp, CSUM_IP, 0);
|
||||
if ((if_getcapenable(ifp) & IFCAP_TXCSUM) != 0)
|
||||
if_sethwassistbits(ifp, CSUM_IP | CSUM_UDP | CSUM_TCP, 0);
|
||||
else
|
||||
if_sethwassistbits(ifp, 0, CSUM_IP);
|
||||
if_sethwassistbits(ifp, 0, CSUM_IP | CSUM_UDP | CSUM_TCP);
|
||||
break;
|
||||
default:
|
||||
error = ether_ioctl(ifp, cmd, data);
|
||||
|
@ -115,9 +115,9 @@
|
||||
#define EMAC_MII_DATA 0x4c
|
||||
#define EMAC_ADDR_HIGH(n) (0x50 + (n) * 8)
|
||||
#define EMAC_ADDR_LOW(n) (0x54 + (n) * 8)
|
||||
#define EMAC_TX_DMA_STA 0x80
|
||||
#define EMAC_TX_DMA_CUR_DESC 0x84
|
||||
#define EMAC_TX_DMA_CUR_BUF 0x88
|
||||
#define EMAC_TX_DMA_STA 0xb0
|
||||
#define EMAC_TX_DMA_CUR_DESC 0xb4
|
||||
#define EMAC_TX_DMA_CUR_BUF 0xb8
|
||||
#define EMAC_RX_DMA_STA 0xc0
|
||||
#define EMAC_RX_DMA_CUR_DESC 0xc4
|
||||
#define EMAC_RX_DMA_CUR_BUF 0xc8
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <bsd.own.mk>
|
||||
.include <src.opts.mk>
|
||||
|
||||
SSP_CFLAGS=
|
||||
|
||||
@ -22,3 +22,11 @@ CFLAGS.clang+= -mfpu=none
|
||||
# when this test succeeds rather than require dd to be a bootstrap tool.
|
||||
DD_NOSTATUS!=(dd status=none count=0 2> /dev/null && echo status=none) || true
|
||||
DD=dd ${DD_NOSTATUS}
|
||||
|
||||
.if ${MK_LOADER_FORCE_LE} != "no"
|
||||
|
||||
.if ${MACHINE_ARCH} == "powerpc64"
|
||||
CFLAGS+= -mlittle-endian
|
||||
.endif
|
||||
|
||||
.endif
|
||||
|
@ -40,8 +40,6 @@
|
||||
* Author: Ken Merry <ken@FreeBSD.org>
|
||||
*/
|
||||
|
||||
#define _CTL_C
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
@ -410,6 +408,11 @@ SYSCTL_INT(_kern_cam_ctl, OID_AUTO, debug, CTLFLAG_RWTUN,
|
||||
static int ctl_lun_map_size = 1024;
|
||||
SYSCTL_INT(_kern_cam_ctl, OID_AUTO, lun_map_size, CTLFLAG_RWTUN,
|
||||
&ctl_lun_map_size, 0, "Size of per-port LUN map (max LUN + 1)");
|
||||
#ifdef CTL_TIME_IO
|
||||
static int ctl_time_io_secs = CTL_TIME_IO_DEFAULT_SECS;
|
||||
SYSCTL_INT(_kern_cam_ctl, OID_AUTO, time_io_secs, CTLFLAG_RWTUN,
|
||||
&ctl_time_io_secs, 0, "Log requests taking more seconds");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Supported pages (0x00), Serial number (0x80), Device ID (0x83),
|
||||
|
@ -40,12 +40,6 @@
|
||||
#ifndef _CTL_IO_H_
|
||||
#define _CTL_IO_H_
|
||||
|
||||
#ifdef _CTL_C
|
||||
#define EXTERN(__var,__val) __var = __val
|
||||
#else
|
||||
#define EXTERN(__var,__val) extern __var
|
||||
#endif
|
||||
|
||||
#define CTL_MAX_CDBLEN 32
|
||||
/*
|
||||
* Uncomment this next line to enable printing out times for I/Os
|
||||
@ -55,7 +49,6 @@
|
||||
#define CTL_TIME_IO
|
||||
#ifdef CTL_TIME_IO
|
||||
#define CTL_TIME_IO_DEFAULT_SECS 90
|
||||
EXTERN(int ctl_time_io_secs, CTL_TIME_IO_DEFAULT_SECS);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -59,10 +59,11 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
#include <crypto/aesni/aesni_os.h>
|
||||
#include <crypto/aesni/sha_sse.h>
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
void intel_sha1_step(uint32_t *digest, const char *data, uint32_t num_blks) {
|
||||
__m128i abcd, e0, e1;
|
||||
__m128i abcd_save, e_save;
|
||||
|
@ -59,10 +59,11 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
#include <crypto/aesni/aesni_os.h>
|
||||
#include <crypto/aesni/sha_sse.h>
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
void intel_sha256_step(uint32_t *digest, const char *data, uint32_t num_blks) {
|
||||
__m128i state0, state1;
|
||||
__m128i msg;
|
||||
|
@ -1723,8 +1723,8 @@ mpr_setup_sysctl(struct mpr_softc *sc)
|
||||
}
|
||||
|
||||
SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||
OID_AUTO, "debug_level", CTLTYPE_STRING | CTLFLAG_RW, sc, 0,
|
||||
mpr_debug_sysctl, "A", "mpr debug level");
|
||||
OID_AUTO, "debug_level", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
|
||||
sc, 0, mpr_debug_sysctl, "A", "mpr debug level");
|
||||
|
||||
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||
OID_AUTO, "disable_msix", CTLFLAG_RD, &sc->disable_msix, 0,
|
||||
@ -1839,7 +1839,7 @@ mpr_debug_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct mpr_softc *sc;
|
||||
struct mpr_debug_string *string;
|
||||
struct sbuf sbuf;
|
||||
struct sbuf *sbuf;
|
||||
char *buffer;
|
||||
size_t sz;
|
||||
int i, len, debug, error;
|
||||
@ -1850,20 +1850,20 @@ mpr_debug_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
|
||||
sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
|
||||
debug = sc->mpr_debug;
|
||||
|
||||
sbuf_printf(&sbuf, "%#x", debug);
|
||||
sbuf_printf(sbuf, "%#x", debug);
|
||||
|
||||
sz = sizeof(mpr_debug_strings) / sizeof(mpr_debug_strings[0]);
|
||||
for (i = 0; i < sz; i++) {
|
||||
string = &mpr_debug_strings[i];
|
||||
if (debug & string->flag)
|
||||
sbuf_printf(&sbuf, ",%s", string->name);
|
||||
sbuf_printf(sbuf, ",%s", string->name);
|
||||
}
|
||||
|
||||
error = sbuf_finish(&sbuf);
|
||||
sbuf_delete(&sbuf);
|
||||
error = sbuf_finish(sbuf);
|
||||
sbuf_delete(sbuf);
|
||||
|
||||
if (error || req->newptr == NULL)
|
||||
return (error);
|
||||
|
@ -1585,8 +1585,8 @@ mps_setup_sysctl(struct mps_softc *sc)
|
||||
}
|
||||
|
||||
SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||
OID_AUTO, "debug_level", CTLTYPE_STRING | CTLFLAG_RW, sc, 0,
|
||||
mps_debug_sysctl, "A", "mps debug level");
|
||||
OID_AUTO, "debug_level", CTLTYPE_STRING | CTLFLAG_RW |CTLFLAG_MPSAFE,
|
||||
sc, 0, mps_debug_sysctl, "A", "mps debug level");
|
||||
|
||||
SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
|
||||
OID_AUTO, "disable_msix", CTLFLAG_RD, &sc->disable_msix, 0,
|
||||
@ -1679,7 +1679,7 @@ mps_setup_sysctl(struct mps_softc *sc)
|
||||
"Use the phy number for enumeration");
|
||||
}
|
||||
|
||||
struct mps_debug_string {
|
||||
static struct mps_debug_string {
|
||||
char *name;
|
||||
int flag;
|
||||
} mps_debug_strings[] = {
|
||||
@ -1701,7 +1701,7 @@ mps_debug_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct mps_softc *sc;
|
||||
struct mps_debug_string *string;
|
||||
struct sbuf sbuf;
|
||||
struct sbuf *sbuf;
|
||||
char *buffer;
|
||||
size_t sz;
|
||||
int i, len, debug, error;
|
||||
@ -1712,20 +1712,20 @@ mps_debug_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
|
||||
sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
|
||||
debug = sc->mps_debug;
|
||||
|
||||
sbuf_printf(&sbuf, "%#x", debug);
|
||||
sbuf_printf(sbuf, "%#x", debug);
|
||||
|
||||
sz = sizeof(mps_debug_strings) / sizeof(mps_debug_strings[0]);
|
||||
for (i = 0; i < sz; i++) {
|
||||
string = &mps_debug_strings[i];
|
||||
if (debug & string->flag)
|
||||
sbuf_printf(&sbuf, ",%s", string->name);
|
||||
sbuf_printf(sbuf, ",%s", string->name);
|
||||
}
|
||||
|
||||
error = sbuf_finish(&sbuf);
|
||||
sbuf_delete(&sbuf);
|
||||
error = sbuf_finish(sbuf);
|
||||
sbuf_delete(sbuf);
|
||||
|
||||
if (error || req->newptr == NULL)
|
||||
return (error);
|
||||
|
@ -2201,17 +2201,19 @@ uath_sysctl_node(struct uath_softc *sc)
|
||||
|
||||
#undef UATH_SYSCTL_STAT_ADD32
|
||||
|
||||
CTASSERT(sizeof(u_int) >= sizeof(uint32_t));
|
||||
|
||||
static void
|
||||
uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
|
||||
{
|
||||
struct uath_cmd_hdr *hdr;
|
||||
int dlen;
|
||||
uint32_t dlen;
|
||||
|
||||
hdr = (struct uath_cmd_hdr *)cmd->buf;
|
||||
/* NB: msgid is passed thru w/o byte swapping */
|
||||
#ifdef UATH_DEBUG
|
||||
if (sc->sc_debug & UATH_DEBUG_CMDS) {
|
||||
int len = be32toh(hdr->len);
|
||||
uint32_t len = be32toh(hdr->len);
|
||||
printf("%s: %s [ix %u] len %u status %u\n",
|
||||
__func__, uath_codename(be32toh(hdr->code)),
|
||||
hdr->msgid, len, be32toh(hdr->magic));
|
||||
@ -2227,15 +2229,9 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
|
||||
switch (hdr->code & 0xff) {
|
||||
/* reply to a read command */
|
||||
default:
|
||||
dlen = hdr->len - sizeof(*hdr);
|
||||
if (dlen < 0) {
|
||||
device_printf(sc->sc_dev,
|
||||
"Invalid header length %d\n", dlen);
|
||||
return;
|
||||
}
|
||||
DPRINTF(sc, UATH_DEBUG_RX_PROC | UATH_DEBUG_RECV_ALL,
|
||||
"%s: code %d data len %u\n",
|
||||
__func__, hdr->code & 0xff, dlen);
|
||||
"%s: code %d hdr len %u\n",
|
||||
__func__, hdr->code & 0xff, hdr->len);
|
||||
/*
|
||||
* The first response from the target after the
|
||||
* HOST_AVAILABLE has an invalid msgid so we must
|
||||
@ -2245,8 +2241,8 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
|
||||
uint32_t *rp = (uint32_t *)(hdr+1);
|
||||
u_int olen;
|
||||
|
||||
if (!(sizeof(*hdr) <= hdr->len &&
|
||||
hdr->len < UATH_MAX_CMDSZ)) {
|
||||
if (sizeof(*hdr) > hdr->len ||
|
||||
hdr->len >= UATH_MAX_CMDSZ) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: invalid WDC msg length %u; "
|
||||
"msg ignored\n", __func__, hdr->len);
|
||||
@ -2258,7 +2254,8 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
|
||||
* number of bytes--unless it's 0 in which
|
||||
* case a single 32-bit word should be present.
|
||||
*/
|
||||
if (dlen >= (int)sizeof(uint32_t)) {
|
||||
dlen = hdr->len - sizeof(*hdr);
|
||||
if (dlen >= sizeof(uint32_t)) {
|
||||
olen = be32toh(rp[0]);
|
||||
dlen -= sizeof(uint32_t);
|
||||
if (olen == 0) {
|
||||
@ -2278,7 +2275,7 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
|
||||
cmd->olen);
|
||||
olen = cmd->olen;
|
||||
}
|
||||
if (olen > (u_int)dlen) {
|
||||
if (olen > dlen) {
|
||||
/* XXX complain, shouldn't happen */
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: cmd 0x%x olen %u dlen %u\n",
|
||||
@ -2300,8 +2297,10 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd)
|
||||
return;
|
||||
}
|
||||
dlen = hdr->len - sizeof(*hdr);
|
||||
if (dlen != (int)sizeof(uint32_t)) {
|
||||
/* XXX something wrong */
|
||||
if (dlen != sizeof(uint32_t)) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: dlen (%u) != %zu!\n",
|
||||
__func__, dlen, sizeof(uint32_t));
|
||||
return;
|
||||
}
|
||||
/* XXX have submitter do this */
|
||||
@ -2330,6 +2329,7 @@ uath_intr_rx_callback(struct usb_xfer *xfer, usb_error_t error)
|
||||
{
|
||||
struct uath_softc *sc = usbd_xfer_softc(xfer);
|
||||
struct uath_cmd *cmd;
|
||||
struct uath_cmd_hdr *hdr;
|
||||
struct usb_page_cache *pc;
|
||||
int actlen;
|
||||
|
||||
@ -2347,10 +2347,25 @@ uath_intr_rx_callback(struct usb_xfer *xfer, usb_error_t error)
|
||||
STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, cmd, next);
|
||||
UATH_STAT_INC(sc, st_cmd_inactive);
|
||||
|
||||
KASSERT(actlen >= (int)sizeof(struct uath_cmd_hdr),
|
||||
("short xfer error"));
|
||||
if (actlen < sizeof(struct uath_cmd_hdr)) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: short xfer error (actlen %d)\n",
|
||||
__func__, actlen);
|
||||
goto setup;
|
||||
}
|
||||
|
||||
pc = usbd_xfer_get_frame(xfer, 0);
|
||||
usbd_copy_out(pc, 0, cmd->buf, actlen);
|
||||
|
||||
hdr = (struct uath_cmd_hdr *)cmd->buf;
|
||||
hdr->len = be32toh(hdr->len);
|
||||
if (hdr->len > (uint32_t)actlen) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: truncated xfer (len %u, actlen %d)\n",
|
||||
__func__, hdr->len, actlen);
|
||||
goto setup;
|
||||
}
|
||||
|
||||
uath_cmdeof(sc, cmd);
|
||||
case USB_ST_SETUP:
|
||||
setup:
|
||||
@ -2451,6 +2466,8 @@ uath_update_rxstat(struct uath_softc *sc, uint32_t status)
|
||||
}
|
||||
}
|
||||
|
||||
CTASSERT(UATH_MIN_RXBUFSZ >= sizeof(struct uath_chunk));
|
||||
|
||||
static struct mbuf *
|
||||
uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
|
||||
struct uath_rx_desc **pdesc)
|
||||
@ -2473,13 +2490,24 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
|
||||
}
|
||||
|
||||
chunk = (struct uath_chunk *)data->buf;
|
||||
if (chunk->seqnum == 0 && chunk->flags == 0 && chunk->length == 0) {
|
||||
chunklen = be16toh(chunk->length);
|
||||
if (chunk->seqnum == 0 && chunk->flags == 0 && chunklen == 0) {
|
||||
device_printf(sc->sc_dev, "%s: strange response\n", __func__);
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
UATH_RESET_INTRX(sc);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (chunklen > actlen) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: invalid chunk length (len %u > actlen %d)\n",
|
||||
__func__, chunklen, actlen);
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
/* XXX cleanup? */
|
||||
UATH_RESET_INTRX(sc);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (chunk->seqnum != sc->sc_intrx_nextnum) {
|
||||
DPRINTF(sc, UATH_DEBUG_XMIT, "invalid seqnum %d, expected %d\n",
|
||||
chunk->seqnum, sc->sc_intrx_nextnum);
|
||||
@ -2496,9 +2524,19 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
|
||||
chunk->flags & UATH_CFLAGS_RXMSG)
|
||||
UATH_STAT_INC(sc, st_multichunk);
|
||||
|
||||
chunklen = be16toh(chunk->length);
|
||||
if (chunk->flags & UATH_CFLAGS_FINAL)
|
||||
if (chunk->flags & UATH_CFLAGS_FINAL) {
|
||||
if (chunklen < sizeof(struct uath_rx_desc)) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: invalid chunk length %d\n",
|
||||
__func__, chunklen);
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
if (sc->sc_intrx_head != NULL)
|
||||
m_freem(sc->sc_intrx_head);
|
||||
UATH_RESET_INTRX(sc);
|
||||
return (NULL);
|
||||
}
|
||||
chunklen -= sizeof(struct uath_rx_desc);
|
||||
}
|
||||
|
||||
if (chunklen > 0 &&
|
||||
(!(chunk->flags & UATH_CFLAGS_FINAL) || !(chunk->seqnum == 0))) {
|
||||
@ -2559,6 +2597,19 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
|
||||
(struct uath_rx_desc *)(((uint8_t *)chunk) +
|
||||
sizeof(struct uath_chunk) + be16toh(chunk->length) -
|
||||
sizeof(struct uath_rx_desc));
|
||||
if ((uint8_t *)chunk + actlen - sizeof(struct uath_rx_desc) <
|
||||
(uint8_t *)desc) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: wrong Rx descriptor pointer "
|
||||
"(desc %p chunk %p actlen %d)\n",
|
||||
__func__, desc, chunk, actlen);
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
if (sc->sc_intrx_head != NULL)
|
||||
m_freem(sc->sc_intrx_head);
|
||||
UATH_RESET_INTRX(sc);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
*pdesc = desc;
|
||||
|
||||
DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
|
||||
@ -2586,8 +2637,33 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
|
||||
|
||||
/* finalize mbuf */
|
||||
if (sc->sc_intrx_head == NULL) {
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
be32toh(desc->framelen) - UATH_RX_DUMMYSIZE;
|
||||
uint32_t framelen;
|
||||
|
||||
if (be32toh(desc->framelen) < UATH_RX_DUMMYSIZE) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: framelen too small (%u)\n",
|
||||
__func__, be32toh(desc->framelen));
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
if (sc->sc_intrx_head != NULL)
|
||||
m_freem(sc->sc_intrx_head);
|
||||
UATH_RESET_INTRX(sc);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
framelen = be32toh(desc->framelen) - UATH_RX_DUMMYSIZE;
|
||||
if (framelen > actlen - sizeof(struct uath_chunk) ||
|
||||
framelen < sizeof(struct ieee80211_frame_ack)) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: wrong frame length (%u, actlen %d)!\n",
|
||||
__func__, framelen, actlen);
|
||||
counter_u64_add(ic->ic_ierrors, 1);
|
||||
if (sc->sc_intrx_head != NULL)
|
||||
m_freem(sc->sc_intrx_head);
|
||||
UATH_RESET_INTRX(sc);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
m->m_pkthdr.len = m->m_len = framelen;
|
||||
m->m_data += sizeof(struct uath_chunk);
|
||||
} else {
|
||||
mp = sc->sc_intrx_head;
|
||||
|
@ -258,9 +258,24 @@ struct nfscllayout {
|
||||
#define NFSLY_RECALLALL 0x0040
|
||||
#define NFSLY_RETONCLOSE 0x0080
|
||||
#define NFSLY_WRITTEN 0x0100 /* Has been used to write to a DS. */
|
||||
#define NFSLY_FLEXFILE 0x0200
|
||||
|
||||
/*
|
||||
* MALLOC'd to the correct length to accommodate the file handle list.
|
||||
* Flex file layout mirror specific stuff for nfsclflayout.
|
||||
*/
|
||||
struct nfsffm {
|
||||
nfsv4stateid_t st;
|
||||
char dev[NFSX_V4DEVICEID];
|
||||
uint32_t eff;
|
||||
uid_t user;
|
||||
gid_t group;
|
||||
struct nfsfh *fh[NFSDEV_MAXVERS];
|
||||
uint16_t fhcnt;
|
||||
};
|
||||
|
||||
/*
|
||||
* MALLOC'd to the correct length to accommodate the file handle list for File
|
||||
* layout and the list of mirrors for the Flex File Layout.
|
||||
* These hang off of nfsly_flayread and nfsly_flayrw, sorted in increasing
|
||||
* offset order.
|
||||
* The nfsly_flayread list holds the ones with iomode == NFSLAYOUTIOMODE_READ,
|
||||
@ -268,23 +283,49 @@ struct nfscllayout {
|
||||
*/
|
||||
struct nfsclflayout {
|
||||
LIST_ENTRY(nfsclflayout) nfsfl_list;
|
||||
uint8_t nfsfl_dev[NFSX_V4DEVICEID];
|
||||
uint64_t nfsfl_off;
|
||||
uint64_t nfsfl_end;
|
||||
uint64_t nfsfl_patoff;
|
||||
struct nfscldevinfo *nfsfl_devp;
|
||||
uint32_t nfsfl_iomode;
|
||||
uint32_t nfsfl_util;
|
||||
uint32_t nfsfl_stripe1;
|
||||
struct nfscldevinfo *nfsfl_devp;
|
||||
uint16_t nfsfl_flags;
|
||||
uint16_t nfsfl_fhcnt;
|
||||
struct nfsfh *nfsfl_fh[1]; /* FH list for DS */
|
||||
union {
|
||||
struct {
|
||||
uint64_t patoff;
|
||||
uint32_t util;
|
||||
uint32_t stripe1;
|
||||
uint8_t dev[NFSX_V4DEVICEID];
|
||||
uint16_t fhcnt;
|
||||
} fl;
|
||||
struct {
|
||||
uint64_t stripeunit;
|
||||
uint32_t fflags;
|
||||
uint32_t statshint;
|
||||
uint16_t mirrorcnt;
|
||||
} ff;
|
||||
} nfsfl_un;
|
||||
union {
|
||||
struct nfsfh *fh[0]; /* FH list for DS File layout */
|
||||
struct nfsffm ffm[0]; /* Mirror list for Flex File */
|
||||
} nfsfl_un2; /* Must be last. Malloc'd to correct array length */
|
||||
};
|
||||
#define nfsfl_patoff nfsfl_un.fl.patoff
|
||||
#define nfsfl_util nfsfl_un.fl.util
|
||||
#define nfsfl_stripe1 nfsfl_un.fl.stripe1
|
||||
#define nfsfl_dev nfsfl_un.fl.dev
|
||||
#define nfsfl_fhcnt nfsfl_un.fl.fhcnt
|
||||
#define nfsfl_stripeunit nfsfl_un.ff.stripeunit
|
||||
#define nfsfl_fflags nfsfl_un.ff.fflags
|
||||
#define nfsfl_statshint nfsfl_un.ff.statshint
|
||||
#define nfsfl_mirrorcnt nfsfl_un.ff.mirrorcnt
|
||||
#define nfsfl_fh nfsfl_un2.fh
|
||||
#define nfsfl_ffm nfsfl_un2.ffm
|
||||
|
||||
/*
|
||||
* Flags for nfsfl_flags.
|
||||
*/
|
||||
#define NFSFL_RECALL 0x0001 /* File layout has been recalled */
|
||||
#define NFSFL_FILE 0x0002 /* File layout */
|
||||
#define NFSFL_FLEXFILE 0x0004 /* Flex File layout */
|
||||
|
||||
/*
|
||||
* Structure that is used to store a LAYOUTRECALL.
|
||||
@ -306,6 +347,7 @@ struct nfsclrecalllayout {
|
||||
* - stripe indices, each stored as one byte, since there can be many
|
||||
* of them. (This implies a limit of 256 on nfsdi_addrcnt, since the
|
||||
* indices select which address.)
|
||||
* For Flex File, the addrcnt is always one and no stripe indices exist.
|
||||
*/
|
||||
struct nfscldevinfo {
|
||||
LIST_ENTRY(nfscldevinfo) nfsdi_list;
|
||||
@ -313,10 +355,33 @@ struct nfscldevinfo {
|
||||
struct nfsclclient *nfsdi_clp;
|
||||
uint32_t nfsdi_refcnt;
|
||||
uint32_t nfsdi_layoutrefs;
|
||||
uint16_t nfsdi_stripecnt;
|
||||
union {
|
||||
struct {
|
||||
uint16_t stripecnt;
|
||||
} fl;
|
||||
struct {
|
||||
int versindex;
|
||||
uint32_t vers;
|
||||
uint32_t minorvers;
|
||||
uint32_t rsize;
|
||||
uint32_t wsize;
|
||||
} ff;
|
||||
} nfsdi_un;
|
||||
uint16_t nfsdi_addrcnt;
|
||||
uint16_t nfsdi_flags;
|
||||
struct nfsclds *nfsdi_data[0];
|
||||
};
|
||||
#define nfsdi_stripecnt nfsdi_un.fl.stripecnt
|
||||
#define nfsdi_versindex nfsdi_un.ff.versindex
|
||||
#define nfsdi_vers nfsdi_un.ff.vers
|
||||
#define nfsdi_minorvers nfsdi_un.ff.minorvers
|
||||
#define nfsdi_rsize nfsdi_un.ff.rsize
|
||||
#define nfsdi_wsize nfsdi_un.ff.wsize
|
||||
|
||||
/* Flags for nfsdi_flags. */
|
||||
#define NFSDI_FILELAYOUT 0x0001
|
||||
#define NFSDI_FLEXFILE 0x0002
|
||||
#define NFSDI_TIGHTCOUPLED 0X0004
|
||||
|
||||
/* These inline functions return values from nfsdi_data[]. */
|
||||
/*
|
||||
|
@ -350,7 +350,8 @@ tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node,
|
||||
case VREG:
|
||||
uobj = node->tn_reg.tn_aobj;
|
||||
if (uobj != NULL) {
|
||||
atomic_subtract_long(&tmp->tm_pages_used, uobj->size);
|
||||
if (uobj->size != 0)
|
||||
atomic_subtract_long(&tmp->tm_pages_used, uobj->size);
|
||||
KASSERT((uobj->flags & OBJ_TMPFS) == 0,
|
||||
("leaked OBJ_TMPFS node %p vm_obj %p", node, uobj));
|
||||
vm_object_deallocate(uobj);
|
||||
@ -1375,6 +1376,12 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize, boolean_t ignerr)
|
||||
oldpages = OFF_TO_IDX(oldsize + PAGE_MASK);
|
||||
MPASS(oldpages == uobj->size);
|
||||
newpages = OFF_TO_IDX(newsize + PAGE_MASK);
|
||||
|
||||
if (__predict_true(newpages == oldpages && newsize >= oldsize)) {
|
||||
node->tn_size = newsize;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (newpages > oldpages &&
|
||||
tmpfs_pages_check_avail(tmp, newpages - oldpages) == 0)
|
||||
return (ENOSPC);
|
||||
|
@ -209,12 +209,10 @@ uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio)
|
||||
}
|
||||
vm_page_lock(m);
|
||||
vm_page_hold(m);
|
||||
if (m->queue == PQ_NONE) {
|
||||
vm_page_deactivate(m);
|
||||
} else {
|
||||
/* Requeue to maintain LRU ordering. */
|
||||
vm_page_requeue(m);
|
||||
}
|
||||
if (m->queue != PQ_ACTIVE)
|
||||
vm_page_activate(m);
|
||||
else
|
||||
vm_page_reference(m);
|
||||
vm_page_unlock(m);
|
||||
VM_OBJECT_WUNLOCK(obj);
|
||||
error = uiomove_fromphys(&m, offset, tlen, uio);
|
||||
|
@ -185,17 +185,14 @@ kmod_icmpstat_inc(int statnum)
|
||||
void
|
||||
icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
|
||||
{
|
||||
struct ip *oip = mtod(n, struct ip *), *nip;
|
||||
unsigned oiphlen = oip->ip_hl << 2;
|
||||
struct ip *oip, *nip;
|
||||
struct icmp *icp;
|
||||
struct mbuf *m;
|
||||
unsigned icmplen, icmpelen, nlen;
|
||||
unsigned icmplen, icmpelen, nlen, oiphlen;
|
||||
|
||||
KASSERT((u_int)type <= ICMP_MAXTYPE, ("%s: illegal ICMP type",
|
||||
__func__));
|
||||
|
||||
KASSERT((u_int)type <= ICMP_MAXTYPE, ("%s: illegal ICMP type", __func__));
|
||||
#ifdef ICMPPRINTFS
|
||||
if (icmpprintfs)
|
||||
printf("icmp_error(%p, %x, %d)\n", oip, type, code);
|
||||
#endif
|
||||
if (type != ICMP_REDIRECT)
|
||||
ICMPSTAT_INC(icps_error);
|
||||
/*
|
||||
@ -207,19 +204,28 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
|
||||
*/
|
||||
if (n->m_flags & M_DECRYPTED)
|
||||
goto freeit;
|
||||
if (oip->ip_off & htons(~(IP_MF|IP_DF)))
|
||||
goto freeit;
|
||||
if (n->m_flags & (M_BCAST|M_MCAST))
|
||||
goto freeit;
|
||||
|
||||
/* Drop if IP header plus 8 bytes is not contiguous in first mbuf. */
|
||||
if (n->m_len < sizeof(struct ip) + ICMP_MINLEN)
|
||||
goto freeit;
|
||||
oip = mtod(n, struct ip *);
|
||||
oiphlen = oip->ip_hl << 2;
|
||||
if (n->m_len < oiphlen + ICMP_MINLEN)
|
||||
goto freeit;
|
||||
#ifdef ICMPPRINTFS
|
||||
if (icmpprintfs)
|
||||
printf("icmp_error(%p, %x, %d)\n", oip, type, code);
|
||||
#endif
|
||||
if (oip->ip_off & htons(~(IP_MF|IP_DF)))
|
||||
goto freeit;
|
||||
if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT &&
|
||||
n->m_len >= oiphlen + ICMP_MINLEN &&
|
||||
!ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip + oiphlen))->icmp_type)) {
|
||||
!ICMP_INFOTYPE(((struct icmp *)((caddr_t)oip +
|
||||
oiphlen))->icmp_type)) {
|
||||
ICMPSTAT_INC(icps_oldicmp);
|
||||
goto freeit;
|
||||
}
|
||||
/* Drop if IP header plus 8 bytes is not contignous in first mbuf. */
|
||||
if (oiphlen + 8 > n->m_len)
|
||||
goto freeit;
|
||||
/*
|
||||
* Calculate length to quote from original packet and
|
||||
* prevent the ICMP mbuf from overflowing.
|
||||
@ -235,9 +241,10 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
|
||||
n->m_next == NULL)
|
||||
goto stdreply;
|
||||
if (n->m_len < oiphlen + sizeof(struct tcphdr) &&
|
||||
((n = m_pullup(n, oiphlen + sizeof(struct tcphdr))) == NULL))
|
||||
(n = m_pullup(n, oiphlen + sizeof(struct tcphdr))) == NULL)
|
||||
goto freeit;
|
||||
th = (struct tcphdr *)((caddr_t)oip + oiphlen);
|
||||
oip = mtod(n, struct ip *);
|
||||
th = mtodo(n, oiphlen);
|
||||
tcphlen = th->th_off << 2;
|
||||
if (tcphlen < sizeof(struct tcphdr))
|
||||
goto freeit;
|
||||
@ -245,8 +252,8 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
|
||||
goto freeit;
|
||||
if (oiphlen + tcphlen > n->m_len && n->m_next == NULL)
|
||||
goto stdreply;
|
||||
if (n->m_len < oiphlen + tcphlen &&
|
||||
((n = m_pullup(n, oiphlen + tcphlen)) == NULL))
|
||||
if (n->m_len < oiphlen + tcphlen &&
|
||||
(n = m_pullup(n, oiphlen + tcphlen)) == NULL)
|
||||
goto freeit;
|
||||
icmpelen = max(tcphlen, min(V_icmp_quotelen,
|
||||
ntohs(oip->ip_len) - oiphlen));
|
||||
@ -262,24 +269,31 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
|
||||
if (n->m_len < oiphlen + sizeof(struct sctphdr) &&
|
||||
(n = m_pullup(n, oiphlen + sizeof(struct sctphdr))) == NULL)
|
||||
goto freeit;
|
||||
oip = mtod(n, struct ip *);
|
||||
icmpelen = max(sizeof(struct sctphdr),
|
||||
min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
|
||||
sh = (struct sctphdr *)((caddr_t)oip + oiphlen);
|
||||
sh = mtodo(n, oiphlen);
|
||||
if (ntohl(sh->v_tag) == 0 &&
|
||||
ntohs(oip->ip_len) >= oiphlen + sizeof(struct sctphdr) + 8 &&
|
||||
ntohs(oip->ip_len) >= oiphlen +
|
||||
sizeof(struct sctphdr) + 8 &&
|
||||
(n->m_len >= oiphlen + sizeof(struct sctphdr) + 8 ||
|
||||
n->m_next != NULL)) {
|
||||
if (n->m_len < oiphlen + sizeof(struct sctphdr) + 8 &&
|
||||
(n = m_pullup(n, oiphlen + sizeof(struct sctphdr) + 8)) == NULL)
|
||||
(n = m_pullup(n, oiphlen +
|
||||
sizeof(struct sctphdr) + 8)) == NULL)
|
||||
goto freeit;
|
||||
oip = mtod(n, struct ip *);
|
||||
sh = mtodo(n, oiphlen);
|
||||
ch = (struct sctp_chunkhdr *)(sh + 1);
|
||||
if (ch->chunk_type == SCTP_INITIATION) {
|
||||
icmpelen = max(sizeof(struct sctphdr) + 8,
|
||||
min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
|
||||
min(V_icmp_quotelen, ntohs(oip->ip_len) -
|
||||
oiphlen));
|
||||
}
|
||||
}
|
||||
} else
|
||||
stdreply: icmpelen = max(8, min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
|
||||
stdreply: icmpelen = max(8, min(V_icmp_quotelen, ntohs(oip->ip_len) -
|
||||
oiphlen));
|
||||
|
||||
icmplen = min(oiphlen + icmpelen, nlen);
|
||||
if (icmplen < sizeof(struct ip))
|
||||
@ -294,7 +308,8 @@ stdreply: icmpelen = max(8, min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
|
||||
#ifdef MAC
|
||||
mac_netinet_icmp_reply(n, m);
|
||||
#endif
|
||||
icmplen = min(icmplen, M_TRAILINGSPACE(m) - sizeof(struct ip) - ICMP_MINLEN);
|
||||
icmplen = min(icmplen, M_TRAILINGSPACE(m) -
|
||||
sizeof(struct ip) - ICMP_MINLEN);
|
||||
m_align(m, ICMP_MINLEN + icmplen);
|
||||
m->m_len = ICMP_MINLEN + icmplen;
|
||||
|
||||
|
@ -110,22 +110,11 @@ smb_strdup(const char *s)
|
||||
char *
|
||||
smb_strdupin(char *s, size_t maxlen)
|
||||
{
|
||||
char *p, bt;
|
||||
char *p;
|
||||
int error;
|
||||
size_t len;
|
||||
|
||||
len = 0;
|
||||
for (p = s; ;p++) {
|
||||
if (copyin(p, &bt, 1))
|
||||
return NULL;
|
||||
len++;
|
||||
if (maxlen && len > maxlen)
|
||||
return NULL;
|
||||
if (bt == 0)
|
||||
break;
|
||||
}
|
||||
p = malloc(len, M_SMBSTR, M_WAITOK);
|
||||
error = copyin(s, p, len);
|
||||
p = malloc(maxlen + 1, M_SMBSTR, M_WAITOK);
|
||||
error = copyinstr(s, p, maxlen + 1, NULL);
|
||||
if (error) {
|
||||
free(p, M_SMBSTR);
|
||||
return (NULL);
|
||||
|
@ -28,6 +28,7 @@ TESTS_SRCS= \
|
||||
test_empty_gz.c \
|
||||
test_empty_lz4.c \
|
||||
test_empty_xz.c \
|
||||
test_empty_zstd.c \
|
||||
test_error.c \
|
||||
test_error_mixed.c \
|
||||
test_expand_Z.c \
|
||||
@ -37,6 +38,7 @@ TESTS_SRCS= \
|
||||
test_expand_mixed.c \
|
||||
test_expand_plain.c \
|
||||
test_expand_xz.c \
|
||||
test_expand_zstd.c \
|
||||
test_help.c \
|
||||
test_version.c
|
||||
|
||||
@ -59,11 +61,13 @@ CLEANFILES+= list.h list.h.tmp
|
||||
${PACKAGE}FILES+= test_empty.gz.uu
|
||||
${PACKAGE}FILES+= test_empty.lz4.uu
|
||||
${PACKAGE}FILES+= test_empty.xz.uu
|
||||
${PACKAGE}FILES+= test_empty.zst.uu
|
||||
${PACKAGE}FILES+= test_expand.Z.uu
|
||||
${PACKAGE}FILES+= test_expand.bz2.uu
|
||||
${PACKAGE}FILES+= test_expand.gz.uu
|
||||
${PACKAGE}FILES+= test_expand.lz4.uu
|
||||
${PACKAGE}FILES+= test_expand.plain.uu
|
||||
${PACKAGE}FILES+= test_expand.xz.uu
|
||||
${PACKAGE}FILES+= test_expand.zst.uu
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
@ -43,6 +43,7 @@ TESTS_SRCS= \
|
||||
test_extract_cpio_lzma.c \
|
||||
test_extract_cpio_lzo.c \
|
||||
test_extract_cpio_xz.c \
|
||||
test_extract_cpio_zstd.c \
|
||||
test_format_newc.c \
|
||||
test_gcpio_compat.c \
|
||||
test_missing_file.c \
|
||||
@ -73,6 +74,7 @@ TESTS_SRCS= \
|
||||
test_option_xz.c \
|
||||
test_option_y.c \
|
||||
test_option_z.c \
|
||||
test_option_zstd.c \
|
||||
test_owner_parse.c \
|
||||
test_passthrough_dotdot.c \
|
||||
test_passthrough_reverse.c
|
||||
@ -104,6 +106,7 @@ ${PACKAGE}FILES+= test_extract.cpio.lz4.uu
|
||||
${PACKAGE}FILES+= test_extract.cpio.lzma.uu
|
||||
${PACKAGE}FILES+= test_extract.cpio.lzo.uu
|
||||
${PACKAGE}FILES+= test_extract.cpio.xz.uu
|
||||
${PACKAGE}FILES+= test_extract.cpio.zst.uu
|
||||
${PACKAGE}FILES+= test_gcpio_compat_ref.bin.uu
|
||||
${PACKAGE}FILES+= test_gcpio_compat_ref.crc.uu
|
||||
${PACKAGE}FILES+= test_gcpio_compat_ref.newc.uu
|
||||
|
@ -333,7 +333,7 @@ man_display_page() {
|
||||
if [ -n "$use_width" ]; then
|
||||
mandoc_args="-O width=${use_width}"
|
||||
fi
|
||||
testline="mandoc -Tlint -Wunsupp 2>/dev/null"
|
||||
testline="mandoc -Tlint -Wunsupp >/dev/null 2>&1"
|
||||
if [ -n "$tflag" ]; then
|
||||
pipeline="mandoc -Tps $mandoc_args"
|
||||
else
|
||||
|
@ -35,6 +35,7 @@ TESTS_SRCS= \
|
||||
test_extract_tar_lzma.c \
|
||||
test_extract_tar_lzo.c \
|
||||
test_extract_tar_xz.c \
|
||||
test_extract_tar_zstd.c \
|
||||
test_format_newc.c \
|
||||
test_help.c \
|
||||
test_leading_slash.c \
|
||||
@ -74,6 +75,7 @@ TESTS_SRCS= \
|
||||
test_option_xattrs.c \
|
||||
test_option_xz.c \
|
||||
test_option_z.c \
|
||||
test_option_zstd.c \
|
||||
test_patterns.c \
|
||||
test_print_longpath.c \
|
||||
test_stdio.c \
|
||||
@ -108,6 +110,7 @@ ${PACKAGE}FILES+= test_extract.tar.lz4.uu
|
||||
${PACKAGE}FILES+= test_extract.tar.lzma.uu
|
||||
${PACKAGE}FILES+= test_extract.tar.lzo.uu
|
||||
${PACKAGE}FILES+= test_extract.tar.xz.uu
|
||||
${PACKAGE}FILES+= test_extract.tar.zst.uu
|
||||
${PACKAGE}FILES+= test_leading_slash.tar.uu
|
||||
${PACKAGE}FILES+= test_option_keep_newer_files.tar.Z.uu
|
||||
${PACKAGE}FILES+= test_option_passphrase.zip.uu
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 30, 2009
|
||||
.Dd September 30, 2017
|
||||
.Dt CPUCONTROL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -34,43 +34,43 @@
|
||||
device
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl vh
|
||||
.Op Fl v
|
||||
.Fl m Ar msr
|
||||
.Bk
|
||||
.Ar device
|
||||
.Ek
|
||||
.Nm
|
||||
.Op Fl vh
|
||||
.Op Fl v
|
||||
.Fl m Ar msr Ns = Ns Ar value
|
||||
.Bk
|
||||
.Ar device
|
||||
.Ek
|
||||
.Nm
|
||||
.Op Fl vh
|
||||
.Op Fl v
|
||||
.Fl m Ar msr Ns &= Ns Ar mask
|
||||
.Bk
|
||||
.Ar device
|
||||
.Ek
|
||||
.Nm
|
||||
.Op Fl vh
|
||||
.Op Fl v
|
||||
.Fl m Ar msr Ns |= Ns Ar mask
|
||||
.Bk
|
||||
.Ar device
|
||||
.Ek
|
||||
.Nm
|
||||
.Op Fl vh
|
||||
.Op Fl v
|
||||
.Fl i Ar level
|
||||
.Bk
|
||||
.Ar device
|
||||
.Ek
|
||||
.Nm
|
||||
.Op Fl vh
|
||||
.Op Fl v
|
||||
.Fl i Ar level,level_type
|
||||
.Bk
|
||||
.Ar device
|
||||
.Ek
|
||||
.Nm
|
||||
.Op Fl vh
|
||||
.Op Fl vn
|
||||
.Op Fl d Ar datadir
|
||||
.Fl u
|
||||
.Bk
|
||||
@ -88,8 +88,14 @@ It can also be used to apply CPU firmware updates.
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl d Ar datadir
|
||||
Where to look for microcode images.
|
||||
Directory paths where to look for microcode images.
|
||||
The option can be specified multiple times.
|
||||
The paths are added in order of the options appearance on the command
|
||||
line, default directories are appended after the user-supplied paths.
|
||||
.It Fl n
|
||||
Do not look for the microcode images in the standard directories.
|
||||
Currently standard directory to look for the microcode update files is
|
||||
.Pa /usr/local/share/cpucontrol .
|
||||
.It Fl m Ar msr
|
||||
Show value of the specified MSR.
|
||||
MSR register number should be given as a hexadecimal number.
|
||||
@ -163,10 +169,10 @@ The command
|
||||
will retrieve the CPUID level 0x1 from CPU 1.
|
||||
.Pp
|
||||
To perform firmware updates on CPU 0 from images located at
|
||||
.Pa /usr/local/share/cpuctl/
|
||||
.Pa /usr/local/share/cpuctl
|
||||
use the following command:
|
||||
.Pp
|
||||
.Dq Li "cpucontrol -d /usr/local/share/cpuctl/ -u /dev/cpuctl0"
|
||||
.Dq Li "cpucontrol -nd /usr/local/share/cpuctl -u /dev/cpuctl0"
|
||||
.Sh SEE ALSO
|
||||
.Xr cpuctl 4
|
||||
.Sh HISTORY
|
||||
@ -179,5 +185,3 @@ The
|
||||
.Nm
|
||||
utility and this manual page was written by
|
||||
.An Stanislav Sedov Aq Mt stas@FreeBSD.org .
|
||||
.Sh BUGS
|
||||
Yes, probably, report if any.
|
||||
|
@ -60,6 +60,7 @@ int verbosity_level = 0;
|
||||
#define FLAG_I 0x01
|
||||
#define FLAG_M 0x02
|
||||
#define FLAG_U 0x04
|
||||
#define FLAG_N 0x08
|
||||
|
||||
#define OP_INVAL 0x00
|
||||
#define OP_READ 0x01
|
||||
@ -427,11 +428,7 @@ main(int argc, char *argv[])
|
||||
error = 0;
|
||||
cmdarg = ""; /* To keep gcc3 happy. */
|
||||
|
||||
/*
|
||||
* Add all default data dirs to the list first.
|
||||
*/
|
||||
datadir_add(DEFAULT_DATADIR);
|
||||
while ((c = getopt(argc, argv, "d:hi:m:uv")) != -1) {
|
||||
while ((c = getopt(argc, argv, "d:hi:m:nuv")) != -1) {
|
||||
switch (c) {
|
||||
case 'd':
|
||||
datadir_add(optarg);
|
||||
@ -444,6 +441,9 @@ main(int argc, char *argv[])
|
||||
flags |= FLAG_M;
|
||||
cmdarg = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
flags |= FLAG_N;
|
||||
break;
|
||||
case 'u':
|
||||
flags |= FLAG_U;
|
||||
break;
|
||||
@ -463,6 +463,8 @@ main(int argc, char *argv[])
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if ((flags & FLAG_N) == 0)
|
||||
datadir_add(DEFAULT_DATADIR);
|
||||
dev = argv[0];
|
||||
c = flags & (FLAG_I | FLAG_M | FLAG_U);
|
||||
switch (c) {
|
||||
|
@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 24, 2009
|
||||
.Dd September 30, 2017
|
||||
.Dt TRACEROUTE6 8
|
||||
.Os
|
||||
.\"
|
||||
@ -40,7 +40,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Bk -words
|
||||
.Op Fl adIlnNrvU
|
||||
.Op Fl adIlnNrSTUv
|
||||
.Ek
|
||||
.Bk -words
|
||||
.Op Fl f Ar firsthop
|
||||
@ -79,7 +79,7 @@ uses the IPv6 protocol hop limit field to elicit an ICMPv6 TIME_EXCEEDED
|
||||
response from each gateway along the path to some host.
|
||||
.Pp
|
||||
The only mandatory parameter is the destination host name or IPv6 address.
|
||||
The default probe datagram carries 12 bytes of payload,
|
||||
The default probe datagram carries 20 bytes of payload,
|
||||
in addition to the IPv6 header.
|
||||
The size of the payload can be specified by giving a length
|
||||
(in bytes)
|
||||
@ -96,9 +96,9 @@ Debug mode.
|
||||
.It Fl f Ar firsthop
|
||||
Specify how many hops to skip in trace.
|
||||
.It Fl g Ar gateway
|
||||
Specify intermediate gateway
|
||||
.Nm (
|
||||
uses routing header).
|
||||
Specify intermediate gateway. Please note that
|
||||
.Nm
|
||||
tries to use routing headers.
|
||||
.It Fl I
|
||||
Use ICMP6 ECHO instead of UDP datagrams.
|
||||
.It Fl l
|
||||
@ -119,7 +119,7 @@ Do not resolve numeric address to hostname.
|
||||
Use a packet with no upper layer header for the probes,
|
||||
instead of UDP datagrams.
|
||||
.It Fl p Ar port
|
||||
Set UDP port number to
|
||||
Set SCTP/TCP/UDP port number to
|
||||
.Ar port .
|
||||
.It Fl q Ar probes
|
||||
Set the number of probe per hop count to
|
||||
@ -138,6 +138,10 @@ that has no route through it
|
||||
.It Fl s Ar src
|
||||
.Ar Src
|
||||
specifies the source IPv6 address to be used.
|
||||
.It Fl S
|
||||
Use SCTP packets for the probes.
|
||||
.It Fl T
|
||||
Use TCP segments for the probes.
|
||||
.It Fl U
|
||||
Use UDP datagrams for the probes.
|
||||
This is the default.
|
||||
|
@ -271,6 +271,8 @@ static const char rcsid[] =
|
||||
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/icmp6.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
#ifdef IPSEC
|
||||
@ -289,23 +291,8 @@ static const char rcsid[] =
|
||||
#define freehostent(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* format of a (udp) probe packet.
|
||||
*/
|
||||
struct tv32 {
|
||||
u_int32_t tv32_sec;
|
||||
u_int32_t tv32_usec;
|
||||
};
|
||||
|
||||
struct opacket {
|
||||
u_char seq; /* sequence number of this packet */
|
||||
u_char hops; /* hop limit of the packet */
|
||||
u_char pad[2];
|
||||
struct tv32 tv; /* time packet left */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
u_char packet[512]; /* last inbound (icmp) packet */
|
||||
struct opacket *outpacket; /* last output (udp) packet */
|
||||
char *outpacket; /* last output packet */
|
||||
|
||||
int main(int, char *[]);
|
||||
int wait_for_reply(int, struct msghdr *);
|
||||
@ -322,10 +309,14 @@ const char *pr_type(int);
|
||||
int packet_ok(struct msghdr *, int, int);
|
||||
void print(struct msghdr *, int);
|
||||
const char *inetname(struct sockaddr *);
|
||||
u_int32_t sctp_crc32c(void *, u_int32_t);
|
||||
u_int16_t in_cksum(u_int16_t *addr, int);
|
||||
u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
|
||||
void *, u_int32_t);
|
||||
void usage(void);
|
||||
|
||||
int rcvsock; /* receive (icmp) socket file descriptor */
|
||||
int sndsock; /* send (udp) socket file descriptor */
|
||||
int sndsock; /* send (raw/udp) socket file descriptor */
|
||||
|
||||
struct msghdr rcvmhdr;
|
||||
struct iovec rcviov[2];
|
||||
@ -333,7 +324,7 @@ int rcvhlim;
|
||||
struct in6_pktinfo *rcvpktinfo;
|
||||
|
||||
struct sockaddr_in6 Src, Dst, Rcv;
|
||||
u_long datalen; /* How much data */
|
||||
u_long datalen = 20; /* How much data */
|
||||
#define ICMP6ECHOLEN 8
|
||||
/* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */
|
||||
char rtbuf[2064];
|
||||
@ -362,9 +353,7 @@ char *as_server = NULL;
|
||||
void *asn;
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
|
||||
char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
|
||||
@ -411,8 +400,9 @@ main(argc, argv)
|
||||
#endif
|
||||
|
||||
seq = 0;
|
||||
ident = htons(getpid() & 0xffff); /* same as ping6 */
|
||||
|
||||
while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:Uvw:")) != -1)
|
||||
while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:STUvw:")) != -1)
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
as_path = 1;
|
||||
@ -472,7 +462,6 @@ main(argc, argv)
|
||||
break;
|
||||
case 'I':
|
||||
useproto = IPPROTO_ICMPV6;
|
||||
ident = htons(getpid() & 0xffff); /* same as ping6 */
|
||||
break;
|
||||
case 'l':
|
||||
lflag++;
|
||||
@ -533,12 +522,18 @@ main(argc, argv)
|
||||
*/
|
||||
source = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
case 'S':
|
||||
useproto = IPPROTO_SCTP;
|
||||
break;
|
||||
case 'T':
|
||||
useproto = IPPROTO_TCP;
|
||||
break;
|
||||
case 'U':
|
||||
useproto = IPPROTO_UDP;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'w':
|
||||
ep = NULL;
|
||||
errno = 0;
|
||||
@ -574,13 +569,15 @@ main(argc, argv)
|
||||
}
|
||||
break;
|
||||
case IPPROTO_NONE:
|
||||
if ((sndsock = socket(AF_INET6, SOCK_RAW, IPPROTO_NONE)) < 0) {
|
||||
case IPPROTO_SCTP:
|
||||
case IPPROTO_TCP:
|
||||
if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) {
|
||||
perror("socket(SOCK_RAW)");
|
||||
exit(5);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "traceroute6: unknown probe protocol %d",
|
||||
fprintf(stderr, "traceroute6: unknown probe protocol %d\n",
|
||||
useproto);
|
||||
exit(5);
|
||||
}
|
||||
@ -641,7 +638,7 @@ main(argc, argv)
|
||||
ep = NULL;
|
||||
errno = 0;
|
||||
datalen = strtoul(*argv, &ep, 0);
|
||||
if (errno || !*argv || *ep) {
|
||||
if (errno || *ep) {
|
||||
fprintf(stderr,
|
||||
"traceroute6: invalid packet length.\n");
|
||||
exit(1);
|
||||
@ -649,15 +646,21 @@ main(argc, argv)
|
||||
}
|
||||
switch (useproto) {
|
||||
case IPPROTO_ICMPV6:
|
||||
minlen = ICMP6ECHOLEN + sizeof(struct tv32);
|
||||
minlen = ICMP6ECHOLEN;
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
minlen = sizeof(struct opacket);
|
||||
minlen = sizeof(struct udphdr);
|
||||
break;
|
||||
case IPPROTO_NONE:
|
||||
minlen = 0;
|
||||
datalen = 0;
|
||||
break;
|
||||
case IPPROTO_SCTP:
|
||||
minlen = sizeof(struct sctphdr);
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
minlen = sizeof(struct tcphdr);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
|
||||
useproto);
|
||||
@ -671,6 +674,8 @@ main(argc, argv)
|
||||
minlen, MAXPACKET);
|
||||
exit(1);
|
||||
}
|
||||
if (useproto == IPPROTO_UDP)
|
||||
datalen -= sizeof(struct udphdr);
|
||||
outpacket = malloc(datalen);
|
||||
if (!outpacket) {
|
||||
perror("malloc");
|
||||
@ -735,8 +740,10 @@ main(argc, argv)
|
||||
|
||||
#ifdef SO_SNDBUF
|
||||
i = datalen;
|
||||
if (i == 0)
|
||||
i = 1;
|
||||
if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
|
||||
sizeof(i)) < 0 && useproto != IPPROTO_NONE) {
|
||||
sizeof(i)) < 0) {
|
||||
perror("setsockopt(SO_SNDBUF)");
|
||||
exit(6);
|
||||
}
|
||||
@ -897,7 +904,8 @@ main(argc, argv)
|
||||
if (source)
|
||||
fprintf(stderr, " from %s", source);
|
||||
fprintf(stderr, ", %lu hops max, %lu byte packets\n",
|
||||
max_hops, datalen);
|
||||
max_hops,
|
||||
datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
|
||||
(void) fflush(stderr);
|
||||
|
||||
if (first_hop > 1)
|
||||
@ -977,9 +985,7 @@ main(argc, argv)
|
||||
}
|
||||
|
||||
int
|
||||
wait_for_reply(sock, mhdr)
|
||||
int sock;
|
||||
struct msghdr *mhdr;
|
||||
wait_for_reply(int sock, struct msghdr *mhdr)
|
||||
{
|
||||
#ifdef HAVE_POLL
|
||||
struct pollfd pfd[1];
|
||||
@ -1038,14 +1044,12 @@ setpolicy(so, policy)
|
||||
#endif
|
||||
|
||||
void
|
||||
send_probe(seq, hops)
|
||||
int seq;
|
||||
u_long hops;
|
||||
send_probe(int seq, u_long hops)
|
||||
{
|
||||
struct icmp6_hdr *icp;
|
||||
struct opacket *op;
|
||||
struct timeval tv;
|
||||
struct tv32 tv32;
|
||||
struct sctphdr *sctp;
|
||||
struct sctp_chunkhdr *chk;
|
||||
struct tcphdr *tcp;
|
||||
int i;
|
||||
|
||||
i = hops;
|
||||
@ -1055,9 +1059,6 @@ send_probe(seq, hops)
|
||||
}
|
||||
|
||||
Dst.sin6_port = htons(port + seq);
|
||||
(void) gettimeofday(&tv, NULL);
|
||||
tv32.tv32_sec = htonl(tv.tv_sec);
|
||||
tv32.tv32_usec = htonl(tv.tv_usec);
|
||||
|
||||
switch (useproto) {
|
||||
case IPPROTO_ICMPV6:
|
||||
@ -1068,19 +1069,49 @@ send_probe(seq, hops)
|
||||
icp->icmp6_cksum = 0;
|
||||
icp->icmp6_id = ident;
|
||||
icp->icmp6_seq = htons(seq);
|
||||
bcopy(&tv32, ((u_int8_t *)outpacket + ICMP6ECHOLEN),
|
||||
sizeof(tv32));
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
op = outpacket;
|
||||
|
||||
op->seq = seq;
|
||||
op->hops = hops;
|
||||
bcopy(&tv32, &op->tv, sizeof tv32);
|
||||
break;
|
||||
case IPPROTO_NONE:
|
||||
/* No space for anything. No harm as seq/tv32 are decorative. */
|
||||
break;
|
||||
case IPPROTO_SCTP:
|
||||
sctp = (struct sctphdr *)outpacket;
|
||||
|
||||
sctp->src_port = htons(ident);
|
||||
sctp->dest_port = htons(port + seq);
|
||||
sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
|
||||
sctp->checksum = htonl(0);
|
||||
if (datalen >= (u_long)(sizeof(struct sctphdr) +
|
||||
sizeof(struct sctp_chunkhdr))) {
|
||||
chk = (struct sctp_chunkhdr *)(sctp + 1);
|
||||
chk->chunk_type = SCTP_SHUTDOWN_ACK;
|
||||
chk->chunk_flags = 0;
|
||||
chk->chunk_length = htons(4);
|
||||
}
|
||||
if (datalen >= (u_long)(sizeof(struct sctphdr) +
|
||||
2 * sizeof(struct sctp_chunkhdr))) {
|
||||
chk = chk + 1;
|
||||
chk->chunk_type = SCTP_PAD_CHUNK;
|
||||
chk->chunk_flags = 0;
|
||||
chk->chunk_length = htons((u_int16_t)(datalen -
|
||||
sizeof(struct sctphdr) -
|
||||
sizeof(struct sctp_chunkhdr)));
|
||||
}
|
||||
sctp->checksum = sctp_crc32c(outpacket, datalen);
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
tcp = (struct tcphdr *)outpacket;
|
||||
|
||||
tcp->th_sport = htons(ident);
|
||||
tcp->th_dport = htons(port + seq);
|
||||
tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
|
||||
tcp->th_ack = 0;
|
||||
tcp->th_off = 5;
|
||||
tcp->th_flags = TH_SYN;
|
||||
tcp->th_sum = 0;
|
||||
tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
|
||||
exit(1);
|
||||
@ -1098,8 +1129,7 @@ send_probe(seq, hops)
|
||||
}
|
||||
|
||||
int
|
||||
get_hoplim(mhdr)
|
||||
struct msghdr *mhdr;
|
||||
get_hoplim(struct msghdr *mhdr)
|
||||
{
|
||||
struct cmsghdr *cm;
|
||||
|
||||
@ -1115,8 +1145,7 @@ get_hoplim(mhdr)
|
||||
}
|
||||
|
||||
double
|
||||
deltaT(t1p, t2p)
|
||||
struct timeval *t1p, *t2p;
|
||||
deltaT(struct timeval *t1p, struct timeval *t2p)
|
||||
{
|
||||
double dt;
|
||||
|
||||
@ -1185,10 +1214,7 @@ pr_type(int t0)
|
||||
}
|
||||
|
||||
int
|
||||
packet_ok(mhdr, cc, seq)
|
||||
struct msghdr *mhdr;
|
||||
int cc;
|
||||
int seq;
|
||||
packet_ok(struct msghdr *mhdr, int cc, int seq)
|
||||
{
|
||||
struct icmp6_hdr *icp;
|
||||
struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
|
||||
@ -1262,6 +1288,10 @@ packet_ok(mhdr, cc, seq)
|
||||
if ((type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT)
|
||||
|| type == ICMP6_DST_UNREACH) {
|
||||
struct ip6_hdr *hip;
|
||||
struct icmp6_hdr *icmp;
|
||||
struct sctphdr *sctp;
|
||||
struct tcphdr *tcp;
|
||||
struct udphdr *udp;
|
||||
void *up;
|
||||
|
||||
hip = (struct ip6_hdr *)(icp + 1);
|
||||
@ -1272,14 +1302,34 @@ packet_ok(mhdr, cc, seq)
|
||||
}
|
||||
switch (useproto) {
|
||||
case IPPROTO_ICMPV6:
|
||||
if (((struct icmp6_hdr *)up)->icmp6_id == ident &&
|
||||
((struct icmp6_hdr *)up)->icmp6_seq == htons(seq))
|
||||
icmp = (struct icmp6_hdr *)up;
|
||||
if (icmp->icmp6_id == ident &&
|
||||
icmp->icmp6_seq == htons(seq))
|
||||
return (type == ICMP6_TIME_EXCEEDED ?
|
||||
-1 : code + 1);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
if (((struct udphdr *)up)->uh_sport == htons(srcport) &&
|
||||
((struct udphdr *)up)->uh_dport == htons(port + seq))
|
||||
udp = (struct udphdr *)up;
|
||||
if (udp->uh_sport == htons(srcport) &&
|
||||
udp->uh_dport == htons(port + seq))
|
||||
return (type == ICMP6_TIME_EXCEEDED ?
|
||||
-1 : code + 1);
|
||||
break;
|
||||
case IPPROTO_SCTP:
|
||||
sctp = (struct sctphdr *)up;
|
||||
if (sctp->src_port == htons(ident) &&
|
||||
sctp->dest_port == htons(port + seq) &&
|
||||
sctp->v_tag ==
|
||||
(u_int32_t)((sctp->src_port << 16) | sctp->dest_port))
|
||||
return (type == ICMP6_TIME_EXCEEDED ?
|
||||
-1 : code + 1);
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
tcp = (struct tcphdr *)up;
|
||||
if (tcp->th_sport == htons(ident) &&
|
||||
tcp->th_dport == htons(port + seq) &&
|
||||
tcp->th_seq ==
|
||||
(tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
|
||||
return (type == ICMP6_TIME_EXCEEDED ?
|
||||
-1 : code + 1);
|
||||
break;
|
||||
@ -1328,9 +1378,7 @@ packet_ok(mhdr, cc, seq)
|
||||
* Increment pointer until find the UDP or ICMP header.
|
||||
*/
|
||||
void *
|
||||
get_uphdr(ip6, lim)
|
||||
struct ip6_hdr *ip6;
|
||||
u_char *lim;
|
||||
get_uphdr(struct ip6_hdr *ip6, u_char *lim)
|
||||
{
|
||||
u_char *cp = (u_char *)ip6, nh;
|
||||
int hlen;
|
||||
@ -1345,10 +1393,11 @@ get_uphdr(ip6, lim)
|
||||
while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
|
||||
switch (nh) {
|
||||
case IPPROTO_ESP:
|
||||
case IPPROTO_TCP:
|
||||
return(NULL);
|
||||
case IPPROTO_ICMPV6:
|
||||
return(useproto == nh ? cp : NULL);
|
||||
case IPPROTO_SCTP:
|
||||
case IPPROTO_TCP:
|
||||
case IPPROTO_UDP:
|
||||
return(useproto == nh ? cp : NULL);
|
||||
case IPPROTO_NONE:
|
||||
@ -1374,9 +1423,7 @@ get_uphdr(ip6, lim)
|
||||
}
|
||||
|
||||
void
|
||||
print(mhdr, cc)
|
||||
struct msghdr *mhdr;
|
||||
int cc;
|
||||
print(struct msghdr *mhdr, int cc)
|
||||
{
|
||||
struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
|
||||
char hbuf[NI_MAXHOST];
|
||||
@ -1412,8 +1459,7 @@ print(mhdr, cc)
|
||||
* numeric value, otherwise try for symbolic name.
|
||||
*/
|
||||
const char *
|
||||
inetname(sa)
|
||||
struct sockaddr *sa;
|
||||
inetname(struct sockaddr *sa)
|
||||
{
|
||||
static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
|
||||
static int first = 1;
|
||||
@ -1446,12 +1492,163 @@ inetname(sa)
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
* CRC32C routine for the Stream Control Transmission Protocol
|
||||
*/
|
||||
|
||||
#define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
|
||||
|
||||
static u_int32_t crc_c[256] = {
|
||||
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
|
||||
0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
|
||||
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
|
||||
0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
|
||||
0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
|
||||
0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
|
||||
0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
|
||||
0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
|
||||
0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
|
||||
0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
|
||||
0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
|
||||
0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
|
||||
0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
|
||||
0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
|
||||
0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
|
||||
0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
|
||||
0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
|
||||
0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
|
||||
0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
|
||||
0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
|
||||
0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
|
||||
0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
|
||||
0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
|
||||
0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
|
||||
0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
|
||||
0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
|
||||
0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
|
||||
0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
|
||||
0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
|
||||
0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
|
||||
0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
|
||||
0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
|
||||
0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
|
||||
0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
|
||||
0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
|
||||
0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
|
||||
0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
|
||||
0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
|
||||
0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
|
||||
0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
|
||||
0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
|
||||
0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
|
||||
0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
|
||||
0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
|
||||
0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
|
||||
0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
|
||||
0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
|
||||
0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
|
||||
0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
|
||||
0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
|
||||
0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
|
||||
0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
|
||||
0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
|
||||
0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
|
||||
0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
|
||||
0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
|
||||
0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
|
||||
0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
|
||||
0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
|
||||
0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
|
||||
0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
|
||||
0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
|
||||
0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
|
||||
0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
|
||||
};
|
||||
|
||||
u_int32_t
|
||||
sctp_crc32c(void *packet, u_int32_t len)
|
||||
{
|
||||
u_int32_t i, crc32c;
|
||||
u_int8_t byte0, byte1, byte2, byte3;
|
||||
u_int8_t *buf = (u_int8_t *)packet;
|
||||
|
||||
crc32c = ~0;
|
||||
for (i = 0; i < len; i++)
|
||||
CRC32C(crc32c, buf[i]);
|
||||
crc32c = ~crc32c;
|
||||
byte0 = crc32c & 0xff;
|
||||
byte1 = (crc32c>>8) & 0xff;
|
||||
byte2 = (crc32c>>16) & 0xff;
|
||||
byte3 = (crc32c>>24) & 0xff;
|
||||
crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
|
||||
return htonl(crc32c);
|
||||
}
|
||||
|
||||
u_int16_t
|
||||
in_cksum(u_int16_t *addr, int len)
|
||||
{
|
||||
int nleft = len;
|
||||
u_int16_t *w = addr;
|
||||
u_int16_t answer;
|
||||
int sum = 0;
|
||||
|
||||
/*
|
||||
* Our algorithm is simple, using a 32 bit accumulator (sum),
|
||||
* we add sequential 16 bit words to it, and at the end, fold
|
||||
* back all the carry bits from the top 16 bits into the lower
|
||||
* 16 bits.
|
||||
*/
|
||||
while (nleft > 1) {
|
||||
sum += *w++;
|
||||
nleft -= 2;
|
||||
}
|
||||
|
||||
/* mop up an odd byte, if necessary */
|
||||
if (nleft == 1)
|
||||
sum += *(u_char *)w;
|
||||
|
||||
/*
|
||||
* add back carry outs from top 16 bits to low 16 bits
|
||||
*/
|
||||
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
|
||||
sum += (sum >> 16); /* add carry */
|
||||
answer = ~sum; /* truncate to 16 bits */
|
||||
return (answer);
|
||||
}
|
||||
|
||||
u_int16_t
|
||||
tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
|
||||
void *payload, u_int32_t len)
|
||||
{
|
||||
struct {
|
||||
struct in6_addr src;
|
||||
struct in6_addr dst;
|
||||
u_int32_t len;
|
||||
u_int8_t zero[3];
|
||||
u_int8_t next;
|
||||
} pseudo_hdr;
|
||||
u_int16_t sum[2];
|
||||
|
||||
pseudo_hdr.src = src->sin6_addr;
|
||||
pseudo_hdr.dst = dst->sin6_addr;
|
||||
pseudo_hdr.len = htonl(len);
|
||||
pseudo_hdr.zero[0] = 0;
|
||||
pseudo_hdr.zero[1] = 0;
|
||||
pseudo_hdr.zero[2] = 0;
|
||||
pseudo_hdr.next = IPPROTO_TCP;
|
||||
|
||||
sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
|
||||
sum[0] = in_cksum(payload, len);
|
||||
|
||||
return (~in_cksum(sum, sizeof(sum)));
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: traceroute6 [-adIlnNrUv] [-A as_server] [-f firsthop] [-g gateway]\n"
|
||||
"usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
|
||||
" [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"
|
||||
" [datalen]\n");
|
||||
exit(1);
|
||||
|
Loading…
Reference in New Issue
Block a user