aboutsummaryrefslogtreecommitdiffstats
path: root/cpio
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2016-05-11 10:19:44 +0000
committerMartin Matuska <mm@FreeBSD.org>2016-05-11 10:19:44 +0000
commit4e579f6c9425c995106fbf72667f4ec7e5d5db85 (patch)
treed298bb9fa3cf4f58e328e696a77fadf758a534eb /cpio
parent8c8f03ca5b7f1f0d07c23e7c354a45b7c95335f0 (diff)
downloadsrc-4e579f6c9425c995106fbf72667f4ec7e5d5db85.tar.gz
src-4e579f6c9425c995106fbf72667f4ec7e5d5db85.zip
Update vendor/libarchive/dist to git commit 61c56e5 (post 3.2.0)vendor/libarchive/3.2.0
Notes
Notes: svn path=/vendor/libarchive/dist/; revision=299425 svn path=/vendor/libarchive/3.2.0/; revision=299528; tag=vendor/libarchive/3.2.0
Diffstat (limited to 'cpio')
-rw-r--r--cpio/CMakeLists.txt5
-rw-r--r--cpio/bsdcpio.125
-rw-r--r--cpio/cmdline.c2
-rw-r--r--cpio/cpio.c90
-rw-r--r--cpio/cpio.h4
-rw-r--r--cpio/cpio_platform.h8
-rw-r--r--cpio/cpio_windows.h7
-rw-r--r--cpio/test/CMakeLists.txt8
-rw-r--r--cpio/test/main.c155
-rw-r--r--cpio/test/test.h31
-rw-r--r--cpio/test/test_basic.c2
-rw-r--r--cpio/test/test_extract.cpio.lz4.uu7
-rw-r--r--cpio/test/test_extract_cpio_lz4.c48
-rw-r--r--cpio/test/test_extract_cpio_lzo.c2
-rw-r--r--cpio/test/test_option_c.c10
-rw-r--r--cpio/test/test_option_lz4.c74
-rw-r--r--cpio/test/test_option_passphrase.c43
-rw-r--r--cpio/test/test_option_passphrase.zip.uu12
-rw-r--r--cpio/test/test_option_version.c5
19 files changed, 478 insertions, 60 deletions
diff --git a/cpio/CMakeLists.txt b/cpio/CMakeLists.txt
index cc4aa14cb54b..85fda7782800 100644
--- a/cpio/CMakeLists.txt
+++ b/cpio/CMakeLists.txt
@@ -15,7 +15,10 @@ IF(ENABLE_CPIO)
../libarchive_fe/lafe_platform.h
../libarchive_fe/line_reader.c
../libarchive_fe/line_reader.h
+ ../libarchive_fe/passphrase.c
+ ../libarchive_fe/passphrase.h
)
+ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/test_utils)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
IF(WIN32 AND NOT CYGWIN)
LIST(APPEND bsdcpio_SOURCES cpio_windows.c)
@@ -34,8 +37,6 @@ IF(ENABLE_CPIO)
SET_TARGET_PROPERTIES(bsdcpio PROPERTIES COMPILE_DEFINITIONS
LIBARCHIVE_STATIC)
ENDIF(ENABLE_CPIO_SHARED)
- # Full path to the compiled executable (used by test suite)
- GET_TARGET_PROPERTY(BSDCPIO bsdcpio LOCATION)
# Installation rules
INSTALL(TARGETS bsdcpio RUNTIME DESTINATION bin)
diff --git a/cpio/bsdcpio.1 b/cpio/bsdcpio.1
index b3d0d40a21ad..e52546e6f761 100644
--- a/cpio/bsdcpio.1
+++ b/cpio/bsdcpio.1
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 7, 2012
+.Dd September 16, 2014
.Dt CPIO 1
.Os
.Sh NAME
@@ -32,17 +32,17 @@
.Nd copy files to and from archives
.Sh SYNOPSIS
.Nm
-.Brq Fl i
+.Fl i
.Op Ar options
.Op Ar pattern ...
.Op Ar < archive
.Nm
-.Brq Fl o
+.Fl o
.Op Ar options
.Ar < name-list
.Op Ar > archive
.Nm
-.Brq Fl p
+.Fl p
.Op Ar options
.Ar dest-dir
.Ar < name-list
@@ -156,7 +156,8 @@ See above for description.
.It Fl Fl insecure
(i and p mode only)
Disable security checks during extraction or copying.
-This allows extraction via symbolic links and path names containing
+This allows extraction via symbolic links, absolute paths,
+and path names containing
.Sq ..
in the name.
.It Fl J , Fl Fl xz
@@ -181,6 +182,11 @@ instead of copying.
Compress the resulting archive with
.Xr lrzip 1 .
In input mode, this option is ignored.
+.It Fl Fl lz4
+(o mode only)
+Compress the archive with lz4-compatible compression before writing it.
+In input mode, this option is ignored; lz4 compression is recognized
+automatically on input.
.It Fl Fl lzma
(o mode only)
Compress the file with lzma-compatible compression before writing it.
@@ -191,6 +197,15 @@ automatically on input.
Compress the resulting archive with
.Xr lzop 1 .
In input mode, this option is ignored.
+.It Fl Fl passphrase Ar passphrase
+The
+.Pa passphrase
+is used to extract or create an encrypted archive.
+Currently, zip is only a format that
+.Nm
+can handle encrypted archives.
+You shouldn't use this option unless you realize how insecure
+use of this option is.
.It Fl m , Fl Fl preserve-modification-time
(i and p modes)
Set file modification time on created files to match
diff --git a/cpio/cmdline.c b/cpio/cmdline.c
index 0121fd13937f..7e59536957a4 100644
--- a/cpio/cmdline.c
+++ b/cpio/cmdline.c
@@ -73,6 +73,7 @@ static const struct option {
{ "link", 0, 'l' },
{ "list", 0, 't' },
{ "lrzip", 0, OPTION_LRZIP },
+ { "lz4", 0, OPTION_LZ4 },
{ "lzma", 0, OPTION_LZMA },
{ "lzop", 0, OPTION_LZOP },
{ "make-directories", 0, 'd' },
@@ -80,6 +81,7 @@ static const struct option {
{ "null", 0, '0' },
{ "numeric-uid-gid", 0, 'n' },
{ "owner", 1, 'R' },
+ { "passphrase", 1, OPTION_PASSPHRASE },
{ "pass-through", 0, 'p' },
{ "preserve-modification-time", 0, 'm' },
{ "preserve-owner", 0, OPTION_PRESERVE_OWNER },
diff --git a/cpio/cpio.c b/cpio/cpio.c
index 6f57d95d616e..b267e9b8a744 100644
--- a/cpio/cpio.c
+++ b/cpio/cpio.c
@@ -82,6 +82,7 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.15 2008/12/06 07:30:40 kientzle
#include "cpio.h"
#include "err.h"
#include "line_reader.h"
+#include "passphrase.h"
/* Fixed size of uname/gname caches. */
#define name_cache_size 101
@@ -123,6 +124,8 @@ static int restore_time(struct cpio *, struct archive_entry *,
const char *, int fd);
static void usage(void);
static void version(void);
+static const char * passphrase_callback(struct archive *, void *);
+static void passphrase_free(char *);
int
main(int argc, char *argv[])
@@ -149,20 +152,9 @@ main(int argc, char *argv[])
}
#endif
- /* Need lafe_progname before calling lafe_warnc. */
- if (*argv == NULL)
- lafe_progname = "bsdcpio";
- else {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- lafe_progname = strrchr(*argv, '\\');
- if (strrchr(*argv, '/') > lafe_progname)
-#endif
- lafe_progname = strrchr(*argv, '/');
- if (lafe_progname != NULL)
- lafe_progname++;
- else
- lafe_progname = *argv;
- }
+ /* Set lafe_progname before calling lafe_warnc. */
+ lafe_setprogname(*argv, "bsdcpio");
+
#if HAVE_SETLOCALE
if (setlocale(LC_ALL, "") == NULL)
lafe_warnc(0, "Failed to set default locale");
@@ -179,6 +171,7 @@ main(int argc, char *argv[])
cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS;
cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT;
+ cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS;
cpio->extract_flags |= ARCHIVE_EXTRACT_PERM;
cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
cpio->extract_flags |= ARCHIVE_EXTRACT_ACL;
@@ -264,6 +257,7 @@ main(int argc, char *argv[])
case OPTION_INSECURE:
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS;
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
+ cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS;
break;
case 'L': /* GNU cpio */
cpio->option_follow_links = 1;
@@ -272,6 +266,7 @@ main(int argc, char *argv[])
cpio->option_link = 1;
break;
case OPTION_LRZIP:
+ case OPTION_LZ4:
case OPTION_LZMA: /* GNU tar, others */
case OPTION_LZOP: /* GNU tar, others */
cpio->compress = opt;
@@ -301,6 +296,9 @@ main(int argc, char *argv[])
cpio->mode = opt;
cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
break;
+ case OPTION_PASSPHRASE:
+ cpio->passphrase = cpio->argument;
+ break;
case OPTION_PRESERVE_OWNER:
cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER;
break;
@@ -429,6 +427,7 @@ main(int argc, char *argv[])
free_cache(cpio->gname_cache);
free_cache(cpio->uname_cache);
free(cpio->destdir);
+ passphrase_free(cpio->ppbuff);
return (cpio->return_value);
}
@@ -437,7 +436,7 @@ usage(void)
{
const char *p;
- p = lafe_progname;
+ p = lafe_getprogname();
fprintf(stderr, "Brief Usage:\n");
fprintf(stderr, " List: %s -it < archive\n", p);
@@ -475,7 +474,7 @@ long_help(void)
const char *prog;
const char *p;
- prog = lafe_progname;
+ prog = lafe_getprogname();
fflush(stderr);
@@ -500,7 +499,7 @@ version(void)
{
fprintf(stdout,"bsdcpio %s -- %s\n",
BSDCPIO_VERSION_STRING,
- archive_version_string());
+ archive_version_details());
exit(0);
}
@@ -537,6 +536,9 @@ mode_out(struct cpio *cpio)
case OPTION_LRZIP:
r = archive_write_add_filter_lrzip(cpio->archive);
break;
+ case OPTION_LZ4:
+ r = archive_write_add_filter_lz4(cpio->archive);
+ break;
case OPTION_LZMA:
r = archive_write_add_filter_lzma(cpio->archive);
break;
@@ -578,6 +580,14 @@ mode_out(struct cpio *cpio)
cpio->linkresolver = archive_entry_linkresolver_new();
archive_entry_linkresolver_set_strategy(cpio->linkresolver,
archive_format(cpio->archive));
+ if (cpio->passphrase != NULL)
+ r = archive_write_set_passphrase(cpio->archive,
+ cpio->passphrase);
+ else
+ r = archive_write_set_passphrase_callback(cpio->archive, cpio,
+ &passphrase_callback);
+ if (r != ARCHIVE_OK)
+ lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
/*
* The main loop: Copy each file into the output archive.
@@ -944,6 +954,13 @@ mode_in(struct cpio *cpio)
lafe_errc(1, 0, "Couldn't allocate archive object");
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
+ if (cpio->passphrase != NULL)
+ r = archive_read_add_passphrase(a, cpio->passphrase);
+ else
+ r = archive_read_set_passphrase_callback(a, cpio,
+ &passphrase_callback);
+ if (r != ARCHIVE_OK)
+ lafe_errc(1, 0, "%s", archive_error_string(a));
if (archive_read_open_filename(a, cpio->filename,
cpio->bytes_per_block))
@@ -1047,6 +1064,13 @@ mode_list(struct cpio *cpio)
lafe_errc(1, 0, "Couldn't allocate archive object");
archive_read_support_filter_all(a);
archive_read_support_format_all(a);
+ if (cpio->passphrase != NULL)
+ r = archive_read_add_passphrase(a, cpio->passphrase);
+ else
+ r = archive_read_set_passphrase_callback(a, cpio,
+ &passphrase_callback);
+ if (r != ARCHIVE_OK)
+ lafe_errc(1, 0, "%s", archive_error_string(a));
if (archive_read_open_filename(a, cpio->filename,
cpio->bytes_per_block))
@@ -1140,7 +1164,8 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
else
fmt = cpio->day_first ? "%d %b %H:%M" : "%b %d %H:%M";
#else
- if (abs(mtime - now) > (365/2)*86400)
+ if (mtime - now > 365*86400/2
+ || mtime - now < -365*86400/2)
fmt = cpio->day_first ? "%e %b %Y" : "%b %e %Y";
else
fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M";
@@ -1235,8 +1260,10 @@ cpio_rename(const char *name)
if (t == NULL)
return (name);
to = fopen("CONOUT$", "w");
- if (to == NULL)
+ if (to == NULL) {
+ fclose(t);
return (name);
+ }
fprintf(to, "%s (Enter/./(new name))? ", name);
fclose(to);
#else
@@ -1416,3 +1443,28 @@ cpio_i64toa(int64_t n0)
*--p = '-';
return p;
}
+
+#define PPBUFF_SIZE 1024
+static const char *
+passphrase_callback(struct archive *a, void *_client_data)
+{
+ struct cpio *cpio = (struct cpio *)_client_data;
+ (void)a; /* UNUSED */
+
+ if (cpio->ppbuff == NULL) {
+ cpio->ppbuff = malloc(PPBUFF_SIZE);
+ if (cpio->ppbuff == NULL)
+ lafe_errc(1, errno, "Out of memory");
+ }
+ return lafe_readpassphrase("Enter passphrase:",
+ cpio->ppbuff, PPBUFF_SIZE);
+}
+
+static void
+passphrase_free(char *ppbuff)
+{
+ if (ppbuff != NULL) {
+ memset(ppbuff, 0, PPBUFF_SIZE);
+ free(ppbuff);
+ }
+}
diff --git a/cpio/cpio.h b/cpio/cpio.h
index 3e951ce7403e..1036dece93b0 100644
--- a/cpio/cpio.h
+++ b/cpio/cpio.h
@@ -71,6 +71,7 @@ struct cpio {
int gid_override;
char *gname_override;
int day_first; /* true if locale prefers day/mon */
+ const char *passphrase;
/* If >= 0, then close this when done. */
int fd;
@@ -90,6 +91,7 @@ struct cpio {
struct archive *matching;
char *buff;
size_t buff_size;
+ char *ppbuff;
};
const char *owner_parse(const char *, int *, int *);
@@ -101,8 +103,10 @@ enum {
OPTION_GRZIP,
OPTION_INSECURE,
OPTION_LRZIP,
+ OPTION_LZ4,
OPTION_LZMA,
OPTION_LZOP,
+ OPTION_PASSPHRASE,
OPTION_NO_PRESERVE_OWNER,
OPTION_PRESERVE_OWNER,
OPTION_QUIET,
diff --git a/cpio/cpio_platform.h b/cpio/cpio_platform.h
index 31d9a738fcb0..58d2edbcd7a4 100644
--- a/cpio/cpio_platform.h
+++ b/cpio/cpio_platform.h
@@ -42,6 +42,10 @@
#include "config.h"
#endif
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include "cpio_windows.h"
+#endif
+
/* Get a real definition for __FBSDID if we can */
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
@@ -70,8 +74,4 @@
#define __LA_DEAD
#endif
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include "cpio_windows.h"
-#endif
-
#endif /* !CPIO_PLATFORM_H_INCLUDED */
diff --git a/cpio/cpio_windows.h b/cpio/cpio_windows.h
index 105bf69991de..970a63df663d 100644
--- a/cpio/cpio_windows.h
+++ b/cpio/cpio_windows.h
@@ -26,6 +26,7 @@
*/
#ifndef CPIO_WINDOWS_H
#define CPIO_WINDOWS_H 1
+#include <windows.h>
#include <io.h>
#include <string.h>
@@ -35,8 +36,10 @@
#define getpwnam(name) NULL
#define getpwuid(id) NULL
-#ifdef _MSC_VER
-#define snprintf sprintf_s
+#if defined(_MSC_VER)
+ #if _MSC_VER < 1900
+ #define snprintf sprintf_s
+ #endif // _MSC_VER < 1900
#define strdup _strdup
#define open _open
#define read _read
diff --git a/cpio/test/CMakeLists.txt b/cpio/test/CMakeLists.txt
index 09ca2c7d96b3..f2c27540813d 100644
--- a/cpio/test/CMakeLists.txt
+++ b/cpio/test/CMakeLists.txt
@@ -19,6 +19,7 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
test_extract_cpio_gz
test_extract_cpio_lrz
test_extract_cpio_lz
+ test_extract_cpio_lz4
test_extract_cpio_lzma
test_extract_cpio_lzo
test_extract_cpio_xz
@@ -39,9 +40,11 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
test_option_help.c
test_option_l.c
test_option_lrzip.c
+ test_option_lz4.c
test_option_lzma.c
test_option_lzop.c
test_option_m.c
+ test_option_passphrase.c
test_option_t.c
test_option_u.c
test_option_uuencode.c
@@ -82,11 +85,12 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
- INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/test_utils)
+ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/test_utils)
# Experimental new test handling
ADD_CUSTOM_TARGET(run_bsdcpio_test
- COMMAND bsdcpio_test -p ${BSDCPIO} -r ${CMAKE_CURRENT_SOURCE_DIR})
+ COMMAND bsdcpio_test -p $<TARGET_FILE:bsdcpio>
+ -r ${CMAKE_CURRENT_SOURCE_DIR})
ADD_DEPENDENCIES(run_bsdcpio_test bsdcpio)
ADD_DEPENDENCIES(run_all_tests run_bsdcpio_test)
ENDIF(ENABLE_CPIO AND ENABLE_TEST)
diff --git a/cpio/test/main.c b/cpio/test/main.c
index d4c6e5c3388c..fa22adfbc81a 100644
--- a/cpio/test/main.c
+++ b/cpio/test/main.c
@@ -130,6 +130,16 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/test/main.c,v 1.3 2008/08/24 04:58:22 kient
# include <crtdbg.h>
#endif
+/* Path to working directory for current test */
+const char *testworkdir;
+#ifdef PROGRAM
+/* Pathname of exe to be tested. */
+const char *testprogfile;
+/* Name of exe to use in printf-formatted command strings. */
+/* On Windows, this includes leading/trailing quotes. */
+const char *testprog;
+#endif
+
#if defined(_WIN32) && !defined(__CYGWIN__)
static void *GetFunctionKernel32(const char *);
static int my_CreateSymbolicLinkA(const char *, const char *, int);
@@ -194,7 +204,7 @@ my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi)
}
#endif
-#if defined(HAVE__CrtSetReportMode)
+#if defined(HAVE__CrtSetReportMode) && !defined(__WATCOMC__)
static void
invalid_parameter_handler(const wchar_t * expression,
const wchar_t * function, const wchar_t * file,
@@ -565,10 +575,10 @@ static void strdump(const char *e, const char *p, int ewidth, int utf8)
while (*p != '\0') {
unsigned int c = 0xff & *p++;
switch (c) {
- case '\a': printf("\a"); break;
- case '\b': printf("\b"); break;
- case '\n': printf("\n"); break;
- case '\r': printf("\r"); break;
+ case '\a': logprintf("\\a"); break;
+ case '\b': logprintf("\\b"); break;
+ case '\n': logprintf("\\n"); break;
+ case '\r': logprintf("\\r"); break;
default:
if (c >= 32 && c < 127)
logprintf("%c", c);
@@ -771,6 +781,34 @@ assertion_equal_mem(const char *file, int line,
return (0);
}
+/* Verify that a block of memory is filled with the specified byte. */
+int
+assertion_memory_filled_with(const char *file, int line,
+ const void *_v1, const char *vd,
+ size_t l, const char *ld,
+ char b, const char *bd, void *extra)
+{
+ const char *v1 = (const char *)_v1;
+ size_t c = 0;
+ size_t i;
+ (void)ld; /* UNUSED */
+
+ assertion_count(file, line);
+
+ for (i = 0; i < l; ++i) {
+ if (v1[i] == b) {
+ ++c;
+ }
+ }
+ if (c == l)
+ return (1);
+
+ failure_start(file, line, "%s (size %d) not filled with %s", vd, (int)l, bd);
+ logprintf(" Only %d bytes were correct\n", (int)c);
+ failure_finish(extra);
+ return (0);
+}
+
/* Verify that the named file exists and is empty. */
int
assertion_empty_file(const char *filename, int line, const char *f1)
@@ -1036,6 +1074,7 @@ assertion_file_contains_lines_any_order(const char *file, int line,
if (expected == NULL) {
failure_start(pathname, line, "Can't allocate memory");
failure_finish(NULL);
+ free(expected);
return (0);
}
for (i = 0; lines[i] != NULL; ++i) {
@@ -1060,7 +1099,8 @@ assertion_file_contains_lines_any_order(const char *file, int line,
free(expected);
return (0);
}
- for (j = 0, p = buff; p < buff + buff_size; p += 1 + strlen(p)) {
+ for (j = 0, p = buff; p < buff + buff_size;
+ p += 1 + strlen(p)) {
if (*p != '\0') {
actual[j] = p;
++j;
@@ -1912,6 +1952,18 @@ canGzip(void)
* Can this platform run the lrzip program?
*/
int
+canRunCommand(const char *cmd)
+{
+ static int tested = 0, value = 0;
+ if (!tested) {
+ tested = 1;
+ if (systemf("%s %s", cmd, redirectArgs) == 0)
+ value = 1;
+ }
+ return (value);
+}
+
+int
canLrzip(void)
{
static int tested = 0, value = 0;
@@ -1924,6 +1976,21 @@ canLrzip(void)
}
/*
+ * Can this platform run the lz4 program?
+ */
+int
+canLz4(void)
+{
+ static int tested = 0, value = 0;
+ if (!tested) {
+ tested = 1;
+ if (systemf("lz4 -V %s", redirectArgs) == 0)
+ value = 1;
+ }
+ return (value);
+}
+
+/*
* Can this platform run the lzip program?
*/
int
@@ -2135,8 +2202,31 @@ slurpfile(size_t * sizep, const char *fmt, ...)
return (p);
}
+/*
+ * Slurp a file into memory for ease of comparison and testing.
+ * Returns size of file in 'sizep' if non-NULL, null-terminates
+ * data in memory for ease of use.
+ */
+void
+dumpfile(const char *filename, void *data, size_t len)
+{
+ ssize_t bytes_written;
+ FILE *f;
+
+ f = fopen(filename, "wb");
+ if (f == NULL) {
+ logprintf("Can't open file %s for writing\n", filename);
+ return;
+ }
+ bytes_written = fwrite(data, 1, len, f);
+ if (bytes_written < (ssize_t)len)
+ logprintf("Can't write file %s\n", filename);
+ fclose(f);
+}
+
/* Read a uuencoded file from the reference directory, decode, and
* write the result into the current directory. */
+#define VALID_UUDECODE(c) (c >= 32 && c <= 96)
#define UUDECODE(c) (((c) - 0x20) & 0x3f)
void
extract_reference_file(const char *name)
@@ -2160,7 +2250,6 @@ extract_reference_file(const char *name)
break;
}
/* Now, decode the rest and write it. */
- /* Not a lot of error checking here; the input better be right. */
out = fopen(name, "wb");
while (fgets(buff, sizeof(buff), in) != NULL) {
char *p = buff;
@@ -2174,17 +2263,21 @@ extract_reference_file(const char *name)
int n = 0;
/* Write out 1-3 bytes from that. */
if (bytes > 0) {
+ assert(VALID_UUDECODE(p[0]));
+ assert(VALID_UUDECODE(p[1]));
n = UUDECODE(*p++) << 18;
n |= UUDECODE(*p++) << 12;
fputc(n >> 16, out);
--bytes;
}
if (bytes > 0) {
+ assert(VALID_UUDECODE(p[0]));
n |= UUDECODE(*p++) << 6;
fputc((n >> 8) & 0xFF, out);
--bytes;
}
if (bytes > 0) {
+ assert(VALID_UUDECODE(p[0]));
n |= UUDECODE(*p++);
fputc(n & 0xFF, out);
--bytes;
@@ -2195,6 +2288,32 @@ extract_reference_file(const char *name)
fclose(in);
}
+void
+copy_reference_file(const char *name)
+{
+ char buff[1024];
+ FILE *in, *out;
+ size_t rbytes;
+
+ sprintf(buff, "%s/%s", refdir, name);
+ in = fopen(buff, "rb");
+ failure("Couldn't open reference file %s", buff);
+ assert(in != NULL);
+ if (in == NULL)
+ return;
+ /* Now, decode the rest and write it. */
+ /* Not a lot of error checking here; the input better be right. */
+ out = fopen(name, "wb");
+ while ((rbytes = fread(buff, 1, sizeof(buff), in)) > 0) {
+ if (fwrite(buff, 1, rbytes, out) != rbytes) {
+ logprintf("Error: fwrite\n");
+ break;
+ }
+ }
+ fclose(out);
+ fclose(in);
+}
+
int
is_LargeInode(const char *file)
{
@@ -2216,6 +2335,14 @@ is_LargeInode(const char *file)
return (ino > 0xffffffff);
#endif
}
+
+void
+extract_reference_files(const char **names)
+{
+ while (names && *names)
+ extract_reference_file(*names++);
+}
+
/*
*
* TEST management
@@ -2245,7 +2372,7 @@ struct test_list_t tests[] = {
* Summarize repeated failures in the just-completed test.
*/
static void
-test_summarize(int failed)
+test_summarize(int failed, int skips_num)
{
unsigned int i;
@@ -2255,7 +2382,7 @@ test_summarize(int failed)
fflush(stdout);
break;
case VERBOSITY_PASSFAIL:
- printf(failed ? "FAIL\n" : "ok\n");
+ printf(failed ? "FAIL\n" : skips_num ? "ok (S)\n" : "ok\n");
break;
}
@@ -2280,13 +2407,14 @@ test_run(int i, const char *tmpdir)
char workdir[1024];
char logfilename[64];
int failures_before = failures;
+ int skips_before = skips;
int oldumask;
switch (verbosity) {
case VERBOSITY_SUMMARY_ONLY: /* No per-test reports at all */
break;
case VERBOSITY_PASSFAIL: /* rest of line will include ok/FAIL marker */
- printf("%3d: %-50s", i, tests[i].name);
+ printf("%3d: %-64s", i, tests[i].name);
fflush(stdout);
break;
default: /* Title of test, details will follow */
@@ -2336,7 +2464,7 @@ test_run(int i, const char *tmpdir)
}
/* Report per-test summaries. */
tests[i].failures = failures - failures_before;
- test_summarize(tests[i].failures);
+ test_summarize(tests[i].failures, skips - skips_before);
/* Close the per-test log file. */
fclose(logfile);
logfile = NULL;
@@ -2479,6 +2607,7 @@ get_refdir(const char *d)
failure:
printf("Unable to locate known reference file %s\n", KNOWNREF);
printf(" Checked following directories:\n%s\n", tried);
+ printf("Use -r option to specify full path to reference directory\n");
#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
DebugBreak();
#endif
@@ -2515,7 +2644,7 @@ main(int argc, char **argv)
while (pwd[strlen(pwd) - 1] == '\n')
pwd[strlen(pwd) - 1] = '\0';
-#if defined(HAVE__CrtSetReportMode)
+#if defined(HAVE__CrtSetReportMode) && !defined(__WATCOMC__)
/* To stop to run the default invalid parameter handler. */
_set_invalid_parameter_handler(invalid_parameter_handler);
/* Disable annoying assertion message box. */
@@ -2562,7 +2691,7 @@ main(int argc, char **argv)
exit(1);
}
memmove(testprogdir + strlen(pwd) + 1, testprogdir,
- strlen(testprogdir));
+ strlen(testprogdir) + 1);
memcpy(testprogdir, pwd, strlen(pwd));
testprogdir[strlen(pwd)] = '/';
}
diff --git a/cpio/test/test.h b/cpio/test/test.h
index 666bba0e8b30..606b121bba6e 100644
--- a/cpio/test/test.h
+++ b/cpio/test/test.h
@@ -66,6 +66,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -84,12 +85,14 @@
/* Windows (including Visual Studio and MinGW but not Cygwin) */
#if defined(_WIN32) && !defined(__CYGWIN__)
#if !defined(__BORLANDC__)
+#undef chdir
+#define chdir _chdir
#define strdup _strdup
#endif
#endif
/* Visual Studio */
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf sprintf_s
#endif
@@ -142,6 +145,9 @@
/* As above, but raw blocks of bytes. */
#define assertEqualMem(v1, v2, l) \
assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL)
+/* Assert that memory is full of a specified byte */
+#define assertMemoryFilledWith(v1, l, b) \
+ assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL)
/* Assert two files are the same. */
#define assertEqualFile(f1, f2) \
assertion_equal_file(__FILE__, __LINE__, (f1), (f2))
@@ -225,6 +231,7 @@ int assertion_empty_file(const char *, int, const char *);
int assertion_equal_file(const char *, int, const char *, const char *);
int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *);
int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *);
+int assertion_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *);
int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int);
int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *);
int assertion_file_atime(const char *, int, const char *, long, long);
@@ -275,9 +282,15 @@ int canGrzip(void);
/* Return true if this platform can run the "gzip" program. */
int canGzip(void);
+/* Return true if this platform can run the specified command. */
+int canRunCommand(const char *);
+
/* Return true if this platform can run the "lrzip" program. */
int canLrzip(void);
+/* Return true if this platform can run the "lz4" program. */
+int canLz4(void);
+
/* Return true if this platform can run the "lzip" program. */
int canLzip(void);
@@ -300,21 +313,31 @@ int is_LargeInode(const char *);
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
+/* Dump block of bytes to a file. */
+void dumpfile(const char *filename, void *, size_t);
+
/* Extracts named reference file to the current directory. */
void extract_reference_file(const char *);
+/* Copies named reference file to the current directory. */
+void copy_reference_file(const char *);
+
+/* Extracts a list of files to the current directory.
+ * List must be NULL terminated.
+ */
+void extract_reference_files(const char **);
/* Path to working directory for current test */
-const char *testworkdir;
+extern const char *testworkdir;
/*
* Special interfaces for program test harness.
*/
/* Pathname of exe to be tested. */
-const char *testprogfile;
+extern const char *testprogfile;
/* Name of exe to use in printf-formatted command strings. */
/* On Windows, this includes leading/trailing quotes. */
-const char *testprog;
+extern const char *testprog;
#ifdef USE_DMALLOC
#include <dmalloc.h>
diff --git a/cpio/test/test_basic.c b/cpio/test/test_basic.c
index 7213062e8d20..f3a048002a55 100644
--- a/cpio/test/test_basic.c
+++ b/cpio/test/test_basic.c
@@ -72,7 +72,7 @@ basic_cpio(const char *target,
return;
/* Use the cpio program to create an archive. */
- r = systemf("%s -o %s < filelist >%s/archive 2>%s/pack.err",
+ r = systemf("%s -R 1000:1000 -o %s < filelist >%s/archive 2>%s/pack.err",
testprog, pack_options, target, target);
failure("Error invoking %s -o %s", testprog, pack_options);
assertEqualInt(r, 0);
diff --git a/cpio/test/test_extract.cpio.lz4.uu b/cpio/test/test_extract.cpio.lz4.uu
new file mode 100644
index 000000000000..0adc7bbcc484
--- /dev/null
+++ b/cpio/test/test_extract.cpio.lz4.uu
@@ -0,0 +1,7 @@
+begin 644 test_extract.cpio.lz4
+M!")-&&1PN9$````A,#<"`&`P-#`P,3`!`&`Q,3`P-C8/`#0W-3`&```)``$&
+M`,$P,3(P,S(W-#`R,S01`!$V!@```@#Q!3(S9FEL93$`8V]N=&5N=',@;V8@
+M$@`A+@IC``AE`!\R90`4$#2#``YE`!TR90`6,F4`#P(`#@+H``P"`"<Q,Q(`
+=OU1204E,15(A(2$``0#'4````````````"BVD[$`
+`
+end
diff --git a/cpio/test/test_extract_cpio_lz4.c b/cpio/test/test_extract_cpio_lz4.c
new file mode 100644
index 000000000000..c16247be2bef
--- /dev/null
+++ b/cpio/test/test_extract_cpio_lz4.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2012,2014 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_extract_cpio_lz4)
+{
+ const char *reffile = "test_extract.cpio.lz4";
+ int f;
+
+ extract_reference_file(reffile);
+ f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile);
+ if (f == 0 || canLz4()) {
+ assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err",
+ testprog, reffile));
+
+ assertFileExists("file1");
+ assertTextFileContents("contents of file1.\n", "file1");
+ assertFileExists("file2");
+ assertTextFileContents("contents of file2.\n", "file2");
+ assertEmptyFile("test.out");
+ assertTextFileContents("1 block\n", "test.err");
+ } else {
+ skipping("It seems lz4 is not supported on this platform");
+ }
+}
diff --git a/cpio/test/test_extract_cpio_lzo.c b/cpio/test/test_extract_cpio_lzo.c
index f351ba7a79aa..99476af95318 100644
--- a/cpio/test/test_extract_cpio_lzo.c
+++ b/cpio/test/test_extract_cpio_lzo.c
@@ -27,7 +27,7 @@ __FBSDID("$FreeBSD$");
DEFINE_TEST(test_extract_cpio_lzo)
{
- const char *reffile = "test_extract.cpio.lrz";
+ const char *reffile = "test_extract.cpio.lzo";
int f;
extract_reference_file(reffile);
diff --git a/cpio/test/test_option_c.c b/cpio/test/test_option_c.c
index a634be10ba7c..fa47b7e277d8 100644
--- a/cpio/test/test_option_c.c
+++ b/cpio/test/test_option_c.c
@@ -65,18 +65,14 @@ DEFINE_TEST(test_option_c)
{
FILE *filelist;
int r;
- int uid = -1;
- int dev, ino, gid;
+ int uid = 1000;
+ int dev, ino, gid = 1000;
time_t t, now;
char *p, *e;
size_t s;
assertUmask(0);
-#if !defined(_WIN32)
- uid = getuid();
-#endif
-
/*
* Create an assortment of files.
* TODO: Extend this to cover more filetypes.
@@ -101,7 +97,7 @@ DEFINE_TEST(test_option_c)
/* Use the cpio program to create an archive. */
fclose(filelist);
- r = systemf("%s -oc <filelist >basic.out 2>basic.err", testprog);
+ r = systemf("%s -R 1000:1000 -oc <filelist >basic.out 2>basic.err", testprog);
/* Verify that nothing went to stderr. */
assertTextFileContents("1 block\n", "basic.err");
diff --git a/cpio/test/test_option_lz4.c b/cpio/test/test_option_lz4.c
new file mode 100644
index 000000000000..d430ac755f4f
--- /dev/null
+++ b/cpio/test/test_option_lz4.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2014 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_lz4)
+{
+ char *p;
+ int r;
+ size_t s;
+
+ /* Create a file. */
+ assertMakeFile("f", 0644, "a");
+
+ /* Archive it with lz4 compression. */
+ r = systemf("echo f | %s -o --lz4 >archive.out 2>archive.err",
+ testprog);
+ p = slurpfile(&s, "archive.err");
+ p[s] = '\0';
+ if (r != 0) {
+ if (strstr(p, "compression not available") != NULL) {
+ skipping("This version of bsdcpio was compiled "
+ "without lz4 support");
+ return;
+ }
+ /* POSIX permits different handling of the spawnp
+ * system call used to launch the subsidiary
+ * program: */
+ /* Some systems fail immediately to spawn the new process. */
+ if (strstr(p, "Can't launch") != NULL && !canLz4()) {
+ skipping("This version of bsdcpio uses an external lz4 program "
+ "but no such program is available on this system.");
+ return;
+ }
+ /* Some systems successfully spawn the new process,
+ * but fail to exec a program within that process.
+ * This results in failure at the first attempt to
+ * write. */
+ if (strstr(p, "Can't write") != NULL && !canLz4()) {
+ skipping("This version of bsdcpio uses an external lz4 program "
+ "but no such program is available on this system.");
+ return;
+ }
+ failure("--lz4 option is broken: %s", p);
+ assertEqualInt(r, 0);
+ return;
+ }
+ /* Check that the archive file has an lz4 signature. */
+ p = slurpfile(&s, "archive.out");
+ assert(s > 2);
+ assertEqualMem(p, "\x04\x22\x4d\x18", 4);
+}
diff --git a/cpio/test/test_option_passphrase.c b/cpio/test/test_option_passphrase.c
new file mode 100644
index 000000000000..ae77a23fcb74
--- /dev/null
+++ b/cpio/test/test_option_passphrase.c
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2014 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+DEFINE_TEST(test_option_passphrase)
+{
+ const char *reffile = "test_option_passphrase.zip";
+
+ extract_reference_file(reffile);
+ assertEqualInt(0,
+ systemf("%s -i --passphrase pass1 < %s >test.out 2>test.err",
+ testprog, reffile));
+
+ assertFileExists("file1");
+ assertTextFileContents("contents of file1.\n", "file1");
+ assertFileExists("file2");
+ assertTextFileContents("contents of file2.\n", "file2");
+ assertEmptyFile("test.out");
+ assertTextFileContents("1 block\n", "test.err");
+}
diff --git a/cpio/test/test_option_passphrase.zip.uu b/cpio/test/test_option_passphrase.zip.uu
new file mode 100644
index 000000000000..021ae8585fe8
--- /dev/null
+++ b/cpio/test/test_option_passphrase.zip.uu
@@ -0,0 +1,12 @@
+begin 644 test_option_passphrase.zip
+M4$L#!`H`"0```#B91$7D$C4,'P```!,````%`!P`9FEL93%55`D``VS'+U0"
+MQR]4=7@+``$$]0$```04````BHPD*"^*I04=XKI\_FQ*TE+#),TD7TTKSP/7
+MR6R35%!+!PCD$C4,'P```!,```!02P,$"@`)````09E$1;VL<PX?````$P``
+M``4`'`!F:6QE,E54"0`#><<O5`+'+U1U>`L``03U`0``!!0```!D#6Z\@CI8
+MV1GIJO5TISQF^I:7.;Y3<-G3$YOCL(C_4$L'"+VL<PX?````$P```%!+`0(>
+M`PH`"0```#B91$7D$C4,'P```!,````%`!@```````$```"D@0````!F:6QE
+M,554!0`#;,<O5'5X"P`!!/4!```$%````%!+`0(>`PH`"0```$&91$6]K',.
+M'P```!,````%`!@```````$```"D@6X```!F:6QE,E54!0`#><<O5'5X"P`!
+@!/4!```$%````%!+!08``````@`"`)8```#<````````
+`
+end
diff --git a/cpio/test/test_option_version.c b/cpio/test/test_option_version.c
index 7345da1e5157..2f2c40901700 100644
--- a/cpio/test/test_option_version.c
+++ b/cpio/test/test_option_version.c
@@ -74,6 +74,11 @@ verify(const char *p, size_t s)
/* Skip a single trailing a,b,c, or d. */
if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd')
++q;
+ /* Skip arbitrary third-party version numbers. */
+ while (s > 0 && (*q == ' ' || *q == '/' || *q == '.' || isalnum(*q))) {
+ ++q;
+ --s;
+ }
/* All terminated by end-of-line: \r, \r\n, or \n */
assert(s >= 1);
failure("Version: %s", p);