summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>2012-02-12 22:41:47 +0900
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>2012-02-12 22:41:47 +0900
commitae314ad8180bbd1127834d299bfa761f566eac8c (patch)
tree5ffea4ff68225b79f5494906bb76f74fdc87725f
parent75d9a70fc8ee5d4687f0ecd4186587cd281faa36 (diff)
downloadlibarchive-ae314ad8180bbd1127834d299bfa761f566eac8c.tar.gz
Introduce archive_match_exclude_pattern_from_file(_w) and
archive_match_include_pattern_from_file(_w) reading exclusion/inclusion patterns from a file. And so retire lafe_exclude_from_file() and lafe_include_from_file because we can use new APIs instead.
-rw-r--r--Makefile.am4
-rw-r--r--cpio/CMakeLists.txt2
-rw-r--r--cpio/cpio.c8
-rw-r--r--cpio/cpio.h2
-rw-r--r--cpio/test/main.c29
-rw-r--r--cpio/test/test.h6
-rw-r--r--libarchive/archive.h10
-rw-r--r--libarchive/archive_match.c169
-rw-r--r--libarchive/test/main.c29
-rw-r--r--libarchive/test/test.h6
-rw-r--r--libarchive/test/test_archive_match_path.c169
-rw-r--r--libarchive_fe/matching.c76
-rw-r--r--libarchive_fe/matching.h38
-rw-r--r--tar/CMakeLists.txt2
-rw-r--r--tar/bsdtar.c10
-rw-r--r--tar/bsdtar.h2
-rw-r--r--tar/read.c7
-rw-r--r--tar/test/main.c29
-rw-r--r--tar/test/test.h6
19 files changed, 436 insertions, 168 deletions
diff --git a/Makefile.am b/Makefile.am
index aa715bb1..69b3928f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -583,9 +583,7 @@ libarchive_fe_la_SOURCES= \
libarchive_fe/err.h \
libarchive_fe/lafe_platform.h \
libarchive_fe/line_reader.c \
- libarchive_fe/line_reader.h \
- libarchive_fe/matching.c \
- libarchive_fe/matching.h
+ libarchive_fe/line_reader.h
libarchive_fe_la_CPPFLAGS= -I$(top_srcdir)/libarchive
#
diff --git a/cpio/CMakeLists.txt b/cpio/CMakeLists.txt
index 98e34496..cc4aa14c 100644
--- a/cpio/CMakeLists.txt
+++ b/cpio/CMakeLists.txt
@@ -15,8 +15,6 @@ IF(ENABLE_CPIO)
../libarchive_fe/lafe_platform.h
../libarchive_fe/line_reader.c
../libarchive_fe/line_reader.h
- ../libarchive_fe/matching.c
- ../libarchive_fe/matching.h
)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
IF(WIN32 AND NOT CYGWIN)
diff --git a/cpio/cpio.c b/cpio/cpio.c
index 8acfae22..717476e2 100644
--- a/cpio/cpio.c
+++ b/cpio/cpio.c
@@ -82,7 +82,6 @@ __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 "matching.h"
/* Fixed size of uname/gname caches. */
#define name_cache_size 101
@@ -219,8 +218,11 @@ main(int argc, char *argv[])
cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR;
break;
case 'E': /* NetBSD/OpenBSD */
- lafe_include_from_file(cpio->matching,
- cpio->argument, cpio->option_null);
+ if (archive_match_include_pattern_from_file(
+ cpio->matching, cpio->argument,
+ cpio->option_null) != ARCHIVE_OK)
+ lafe_errc(1, 0, "Error : %s",
+ archive_error_string(cpio->matching));
break;
case 'F': /* NetBSD/OpenBSD/GNU cpio */
cpio->filename = cpio->argument;
diff --git a/cpio/cpio.h b/cpio/cpio.h
index 9e5af674..7e276bdb 100644
--- a/cpio/cpio.h
+++ b/cpio/cpio.h
@@ -31,8 +31,6 @@
#include "cpio_platform.h"
#include <stdio.h>
-#include "matching.h"
-
/*
* The internal state for the "cpio" program.
*
diff --git a/cpio/test/main.c b/cpio/test/main.c
index 915237a7..30d5ea77 100644
--- a/cpio/test/main.c
+++ b/cpio/test/main.c
@@ -1520,7 +1520,7 @@ assertion_make_dir(const char *file, int line, const char *dirname, int mode)
/* Create a file with the specified contents and report any failures. */
int
assertion_make_file(const char *file, int line,
- const char *path, int mode, const char *contents)
+ const char *path, int mode, int csize, const void *contents)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
/* TODO: Rework this to set file mode as well. */
@@ -1534,8 +1534,13 @@ assertion_make_file(const char *file, int line,
return (0);
}
if (contents != NULL) {
- if (strlen(contents)
- != fwrite(contents, 1, strlen(contents), f)) {
+ size_t wsize;
+
+ if (csize < 0)
+ wsize = strlen(contents);
+ else
+ wsize = (size_t)csize;
+ if (wsize != fwrite(contents, 1, wsize, f)) {
fclose(f);
failure_start(file, line,
"Could not write file %s", path);
@@ -1555,10 +1560,16 @@ assertion_make_file(const char *file, int line,
return (0);
}
if (contents != NULL) {
- if ((ssize_t)strlen(contents)
- != write(fd, contents, strlen(contents))) {
+ ssize_t wsize;
+
+ if (csize < 0)
+ wsize = (ssize_t)strlen(contents);
+ else
+ wsize = (ssize_t)csize;
+ if (wsize != write(fd, contents, wsize)) {
close(fd);
- failure_start(file, line, "Could not write to %s", path);
+ failure_start(file, line,
+ "Could not write to %s", path);
failure_finish(NULL);
return (0);
}
@@ -1803,7 +1814,7 @@ canSymlink(void)
return (value);
++tested;
- assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
+ assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, 1, "a");
/* Note: Cygwin has its own symlink() emulation that does not
* use the Win32 CreateSymbolicLink() function. */
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1863,7 +1874,7 @@ canNodump(void)
const char *path = "cannodumptest";
struct stat sb;
- assertion_make_file(__FILE__, __LINE__, path, 0644, NULL);
+ assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
if (chflags(path, UF_NODUMP) < 0)
return (0);
if (stat(path, &sb) < 0)
@@ -1882,7 +1893,7 @@ canNodump(void)
const char *path = "cannodumptest";
int fd, r, flags;
- assertion_make_file(__FILE__, __LINE__, path, 0644, NULL);
+ assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return (0);
diff --git a/cpio/test/test.h b/cpio/test/test.h
index 601ec938..d57a861d 100644
--- a/cpio/test/test.h
+++ b/cpio/test/test.h
@@ -194,7 +194,9 @@
#define assertMakeDir(dirname, mode) \
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
#define assertMakeFile(path, mode, contents) \
- assertion_make_file(__FILE__, __LINE__, path, mode, contents)
+ assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
+#define assertMakeBinFile(path, mode, csize, contents) \
+ assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
#define assertMakeHardlink(newfile, oldfile) \
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \
@@ -243,7 +245,7 @@ int assertion_is_not_hardlink(const char *, int, const char *, const char *);
int assertion_is_reg(const char *, int, const char *, int);
int assertion_is_symlink(const char *, int, const char *, const char *);
int assertion_make_dir(const char *, int, const char *, int);
-int assertion_make_file(const char *, int, const char *, int, const char *);
+int assertion_make_file(const char *, int, const char *, int, int, const void *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_nodump(const char *, int, const char *);
diff --git a/libarchive/archive.h b/libarchive/archive.h
index d141f4ae..0d2783f1 100644
--- a/libarchive/archive.h
+++ b/libarchive/archive.h
@@ -848,10 +848,20 @@ __LA_DECL int archive_match_path_excluded(struct archive *,
__LA_DECL int archive_match_exclude_pattern(struct archive *, const char *);
__LA_DECL int archive_match_exclude_pattern_w(struct archive *,
const wchar_t *);
+/* Add exclusion pathname pattern from file. */
+__LA_DECL int archive_match_exclude_pattern_from_file(struct archive *,
+ const char *, int _nullSeparator);
+__LA_DECL int archive_match_exclude_pattern_from_file_w(struct archive *,
+ const wchar_t *, int _nullSeparator);
/* Add inclusion pathname pattern. */
__LA_DECL int archive_match_include_pattern(struct archive *, const char *);
__LA_DECL int archive_match_include_pattern_w(struct archive *,
const wchar_t *);
+/* Add inclusion pathname pattern from file. */
+__LA_DECL int archive_match_include_pattern_from_file(struct archive *,
+ const char *, int _nullSeparator);
+__LA_DECL int archive_match_include_pattern_from_file_w(struct archive *,
+ const wchar_t *, int _nullSeparator);
/*
* How to get statistic information for inclusion patterns.
*/
diff --git a/libarchive/archive_match.c b/libarchive/archive_match.c
index c4dfd8b4..36ee043d 100644
--- a/libarchive/archive_match.c
+++ b/libarchive/archive_match.c
@@ -129,6 +129,8 @@ struct archive_match {
struct match_list inclusion_gnames;
};
+static int add_pattern_from_file(struct archive_match *,
+ struct match_list *, int, const void *, int);
static int add_entry(struct archive_match *, int,
struct archive_entry *);
static int add_owner_id(struct archive_match *, struct id_array *,
@@ -342,6 +344,34 @@ archive_match_exclude_pattern_w(struct archive *_a, const wchar_t *pattern)
}
int
+archive_match_exclude_pattern_from_file(struct archive *_a,
+ const char *pathname, int nullSeparator)
+{
+ struct archive_match *a;
+
+ archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file");
+ a = (struct archive_match *)_a;
+
+ return add_pattern_from_file(a, &(a->exclusions), 1, pathname,
+ nullSeparator);
+}
+
+int
+archive_match_exclude_pattern_from_file_w(struct archive *_a,
+ const wchar_t *pathname, int nullSeparator)
+{
+ struct archive_match *a;
+
+ archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file_w");
+ a = (struct archive_match *)_a;
+
+ return add_pattern_from_file(a, &(a->exclusions), 0, pathname,
+ nullSeparator);
+}
+
+int
archive_match_include_pattern(struct archive *_a, const char *pattern)
{
struct archive_match *a;
@@ -379,6 +409,34 @@ archive_match_include_pattern_w(struct archive *_a, const wchar_t *pattern)
return (ARCHIVE_OK);
}
+int
+archive_match_include_pattern_from_file(struct archive *_a,
+ const char *pathname, int nullSeparator)
+{
+ struct archive_match *a;
+
+ archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file");
+ a = (struct archive_match *)_a;
+
+ return add_pattern_from_file(a, &(a->inclusions), 1, pathname,
+ nullSeparator);
+}
+
+int
+archive_match_include_pattern_from_file_w(struct archive *_a,
+ const wchar_t *pathname, int nullSeparator)
+{
+ struct archive_match *a;
+
+ archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file_w");
+ a = (struct archive_match *)_a;
+
+ return add_pattern_from_file(a, &(a->inclusions), 0, pathname,
+ nullSeparator);
+}
+
/*
* Test functions for pathname patterns.
*
@@ -504,6 +562,117 @@ add_pattern_wcs(struct archive_match *a, struct match_list *list,
return (ARCHIVE_OK);
}
+static int
+add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
+ int mbs, const void *pathname, int nullSeparator)
+{
+ struct archive *ar;
+ struct archive_entry *ae;
+ struct archive_string as;
+ const void *buff;
+ size_t size;
+ int64_t offset;
+ int r;
+
+ ar = archive_read_new();
+ if (ar == NULL) {
+ archive_set_error(&(a->archive), ENOMEM, "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ r = archive_read_support_format_raw(ar);
+ if (r != ARCHIVE_OK) {
+ archive_copy_error(&(a->archive), ar);
+ archive_read_free(ar);
+ return (r);
+ }
+ if (mbs)
+ r = archive_read_open_filename(ar, pathname, 512*20);
+ else
+ r = archive_read_open_filename_w(ar, pathname, 512*20);
+ if (r != ARCHIVE_OK) {
+ archive_copy_error(&(a->archive), ar);
+ archive_read_free(ar);
+ return (r);
+ }
+ r = archive_read_next_header(ar, &ae);
+ if (r != ARCHIVE_OK) {
+ archive_copy_error(&(a->archive), ar);
+ archive_read_free(ar);
+ return (r);
+ }
+
+ archive_string_init(&as);
+
+ while ((r = archive_read_data_block(ar, &buff, &size, &offset))
+ == ARCHIVE_OK) {
+ const char *b = (const char *)buff;
+
+ while (size) {
+ const char *s = (const char *)b;
+ size_t length = 0;
+ int found_separator = 0;
+
+ while (length < size) {
+ if (nullSeparator) {
+ if (*b == '\0') {
+ found_separator = 1;
+ break;
+ }
+ } else {
+ if (*b == 0x0d || *b == 0x0a) {
+ found_separator = 1;
+ break;
+ }
+ }
+ b++;
+ length++;
+ }
+ if (!found_separator) {
+ archive_strncat(&as, s, length);
+ /* Read next data block. */
+ break;
+ }
+ b++;
+ size -= length + 1;
+ archive_strncat(&as, s, length);
+
+ /* If the line is not empty, add the pattern. */
+ if (archive_strlen(&as) > 0) {
+ /* Add pattern. */
+ r = add_pattern_mbs(a, mlist, as.s);
+ if (r != ARCHIVE_OK) {
+ archive_read_free(ar);
+ archive_string_free(&as);
+ return (r);
+ }
+ archive_string_empty(&as);
+ }
+ }
+ }
+
+ /* If something error happend, report it immediately. */
+ if (r < ARCHIVE_OK) {
+ archive_copy_error(&(a->archive), ar);
+ archive_read_free(ar);
+ archive_string_free(&as);
+ return (r);
+ }
+
+ /* If the line is not empty, add the pattern. */
+ if (r == ARCHIVE_EOF && archive_strlen(&as) > 0) {
+ /* Add pattern. */
+ r = add_pattern_mbs(a, mlist, as.s);
+ if (r != ARCHIVE_OK) {
+ archive_read_free(ar);
+ archive_string_free(&as);
+ return (r);
+ }
+ }
+ archive_read_free(ar);
+ archive_string_free(&as);
+ return (ARCHIVE_OK);
+}
+
/*
* Test if pathname is excluded by inclusion/exclusion patterns.
*/
diff --git a/libarchive/test/main.c b/libarchive/test/main.c
index f30018e6..b50ecc8e 100644
--- a/libarchive/test/main.c
+++ b/libarchive/test/main.c
@@ -1518,7 +1518,7 @@ assertion_make_dir(const char *file, int line, const char *dirname, int mode)
/* Create a file with the specified contents and report any failures. */
int
assertion_make_file(const char *file, int line,
- const char *path, int mode, const char *contents)
+ const char *path, int mode, int csize, const void *contents)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
/* TODO: Rework this to set file mode as well. */
@@ -1532,8 +1532,13 @@ assertion_make_file(const char *file, int line,
return (0);
}
if (contents != NULL) {
- if (strlen(contents)
- != fwrite(contents, 1, strlen(contents), f)) {
+ size_t wsize;
+
+ if (csize < 0)
+ wsize = strlen(contents);
+ else
+ wsize = (size_t)csize;
+ if (wsize != fwrite(contents, 1, wsize, f)) {
fclose(f);
failure_start(file, line,
"Could not write file %s", path);
@@ -1553,10 +1558,16 @@ assertion_make_file(const char *file, int line,
return (0);
}
if (contents != NULL) {
- if ((ssize_t)strlen(contents)
- != write(fd, contents, strlen(contents))) {
+ ssize_t wsize;
+
+ if (csize < 0)
+ wsize = (ssize_t)strlen(contents);
+ else
+ wsize = (ssize_t)csize;
+ if (wsize != write(fd, contents, wsize)) {
close(fd);
- failure_start(file, line, "Could not write to %s", path);
+ failure_start(file, line,
+ "Could not write to %s", path);
failure_finish(NULL);
return (0);
}
@@ -1801,7 +1812,7 @@ canSymlink(void)
return (value);
++tested;
- assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
+ assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, 1, "a");
/* Note: Cygwin has its own symlink() emulation that does not
* use the Win32 CreateSymbolicLink() function. */
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1861,7 +1872,7 @@ canNodump(void)
const char *path = "cannodumptest";
struct stat sb;
- assertion_make_file(__FILE__, __LINE__, path, 0644, NULL);
+ assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
if (chflags(path, UF_NODUMP) < 0)
return (0);
if (stat(path, &sb) < 0)
@@ -1880,7 +1891,7 @@ canNodump(void)
const char *path = "cannodumptest";
int fd, r, flags;
- assertion_make_file(__FILE__, __LINE__, path, 0644, NULL);
+ assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return (0);
diff --git a/libarchive/test/test.h b/libarchive/test/test.h
index e464612d..7d2f2082 100644
--- a/libarchive/test/test.h
+++ b/libarchive/test/test.h
@@ -194,7 +194,9 @@
#define assertMakeDir(dirname, mode) \
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
#define assertMakeFile(path, mode, contents) \
- assertion_make_file(__FILE__, __LINE__, path, mode, contents)
+ assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
+#define assertMakeBinFile(path, mode, csize, contents) \
+ assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
#define assertMakeHardlink(newfile, oldfile) \
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \
@@ -243,7 +245,7 @@ int assertion_is_not_hardlink(const char *, int, const char *, const char *);
int assertion_is_reg(const char *, int, const char *, int);
int assertion_is_symlink(const char *, int, const char *, const char *);
int assertion_make_dir(const char *, int, const char *, int);
-int assertion_make_file(const char *, int, const char *, int, const char *);
+int assertion_make_file(const char *, int, const char *, int, int, const void *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_nodump(const char *, int, const char *);
diff --git a/libarchive/test/test_archive_match_path.c b/libarchive/test/test_archive_match_path.c
index 8fcf512b..5e9b9a8c 100644
--- a/libarchive/test/test_archive_match_path.c
+++ b/libarchive/test/test_archive_match_path.c
@@ -113,6 +113,114 @@ test_exclusion_wcs(void)
}
static void
+exclusion_from_file(struct archive *m)
+{
+ struct archive_entry *ae;
+
+ if (!assert((ae = archive_entry_new()) != NULL)) {
+ archive_match_free(m);
+ return;
+ }
+
+ /* Test with 'first', which should not be excluded. */
+ archive_entry_copy_pathname(ae, "first");
+ failure("'first' should not be excluded");
+ assertEqualInt(0, archive_match_path_excluded(m, ae));
+ assertEqualInt(0, archive_match_excluded(m, ae));
+ archive_entry_clear(ae);
+ archive_entry_copy_pathname_w(ae, L"first");
+ failure("'first' should not be excluded");
+ assertEqualInt(0, archive_match_path_excluded(m, ae));
+ assertEqualInt(0, archive_match_excluded(m, ae));
+
+ /* Test with 'second', which should be excluded. */
+ archive_entry_copy_pathname(ae, "second");
+ failure("'second' should be excluded");
+ assertEqualInt(1, archive_match_path_excluded(m, ae));
+ assertEqualInt(1, archive_match_excluded(m, ae));
+ archive_entry_clear(ae);
+ archive_entry_copy_pathname_w(ae, L"second");
+ failure("'second' should be excluded");
+ assertEqualInt(1, archive_match_path_excluded(m, ae));
+ assertEqualInt(1, archive_match_excluded(m, ae));
+
+ /* Test with 'third', which should not be excluded. */
+ archive_entry_copy_pathname(ae, "third");
+ failure("'third' should not be excluded");
+ assertEqualInt(0, archive_match_path_excluded(m, ae));
+ assertEqualInt(0, archive_match_excluded(m, ae));
+ archive_entry_clear(ae);
+ archive_entry_copy_pathname_w(ae, L"third");
+ failure("'third' should not be excluded");
+ assertEqualInt(0, archive_match_path_excluded(m, ae));
+ assertEqualInt(0, archive_match_excluded(m, ae));
+
+ /* Test with 'four', which should be excluded. */
+ archive_entry_copy_pathname(ae, "four");
+ failure("'four' should be excluded");
+ assertEqualInt(1, archive_match_path_excluded(m, ae));
+ assertEqualInt(1, archive_match_excluded(m, ae));
+ archive_entry_clear(ae);
+ archive_entry_copy_pathname_w(ae, L"four");
+ failure("'four' should be excluded");
+ assertEqualInt(1, archive_match_path_excluded(m, ae));
+ assertEqualInt(1, archive_match_excluded(m, ae));
+
+ /* Clean up. */
+ archive_entry_free(ae);
+}
+
+static void
+test_exclusion_from_file_mbs(void)
+{
+ struct archive *m;
+
+ /* Test1: read exclusion patterns from file */
+ if (!assert((m = archive_match_new()) != NULL))
+ return;
+ assertEqualIntA(m, 0,
+ archive_match_exclude_pattern_from_file(m, "exclusion", 0));
+ exclusion_from_file(m);
+ /* Clean up. */
+ archive_match_free(m);
+
+ /* Test2: read exclusion patterns in a null separator from file */
+ if (!assert((m = archive_match_new()) != NULL))
+ return;
+ /* Test for pattern reading from file */
+ assertEqualIntA(m, 0,
+ archive_match_exclude_pattern_from_file(m, "exclusion_null", 1));
+ exclusion_from_file(m);
+ /* Clean up. */
+ archive_match_free(m);
+}
+
+static void
+test_exclusion_from_file_wcs(void)
+{
+ struct archive *m;
+
+ /* Test1: read exclusion patterns from file */
+ if (!assert((m = archive_match_new()) != NULL))
+ return;
+ assertEqualIntA(m, 0,
+ archive_match_exclude_pattern_from_file_w(m, L"exclusion", 0));
+ exclusion_from_file(m);
+ /* Clean up. */
+ archive_match_free(m);
+
+ /* Test2: read exclusion patterns in a null separator from file */
+ if (!assert((m = archive_match_new()) != NULL))
+ return;
+ /* Test for pattern reading from file */
+ assertEqualIntA(m, 0,
+ archive_match_exclude_pattern_from_file_w(m, L"exclusion_null", 1));
+ exclusion_from_file(m);
+ /* Clean up. */
+ archive_match_free(m);
+}
+
+static void
test_inclusion_mbs(void)
{
struct archive_entry *ae;
@@ -211,6 +319,56 @@ test_inclusion_wcs(void)
}
static void
+test_inclusion_from_file_mbs(void)
+{
+ struct archive *m;
+
+ /* Test1: read inclusion patterns from file */
+ if (!assert((m = archive_match_new()) != NULL))
+ return;
+ assertEqualIntA(m, 0,
+ archive_match_include_pattern_from_file(m, "inclusion", 0));
+ exclusion_from_file(m);
+ /* Clean up. */
+ archive_match_free(m);
+
+ /* Test2: read inclusion patterns in a null separator from file */
+ if (!assert((m = archive_match_new()) != NULL))
+ return;
+ assertEqualIntA(m, 0,
+ archive_match_include_pattern_from_file(m, "inclusion_null", 1));
+ exclusion_from_file(m);
+ /* Clean up. */
+ archive_match_free(m);
+}
+
+static void
+test_inclusion_from_file_wcs(void)
+{
+ struct archive *m;
+
+ /* Test1: read inclusion patterns from file */
+ if (!assert((m = archive_match_new()) != NULL))
+ return;
+ /* Test for pattern reading from file */
+ assertEqualIntA(m, 0,
+ archive_match_include_pattern_from_file_w(m, L"inclusion", 0));
+ exclusion_from_file(m);
+ /* Clean up. */
+ archive_match_free(m);
+
+ /* Test2: read inclusion patterns in a null separator from file */
+ if (!assert((m = archive_match_new()) != NULL))
+ return;
+ /* Test for pattern reading from file */
+ assertEqualIntA(m, 0,
+ archive_match_include_pattern_from_file_w(m, L"inclusion_null", 1));
+ exclusion_from_file(m);
+ /* Clean up. */
+ archive_match_free(m);
+}
+
+static void
test_exclusion_and_inclusion(void)
{
struct archive_entry *ae;
@@ -273,9 +431,20 @@ test_exclusion_and_inclusion(void)
DEFINE_TEST(test_archive_match_path)
{
+ /* Make exclusion sample files which contain exclusion patterns. */
+ assertMakeFile("exclusion", 0666, "second\nfour\n");
+ assertMakeBinFile("exclusion_null", 0666, 12, "second\0four\0");
+ /* Make inclusion sample files which contain inclusion patterns. */
+ assertMakeFile("inclusion", 0666, "first\nthird\n");
+ assertMakeBinFile("inclusion_null", 0666, 12, "first\0third\0");
+
test_exclusion_mbs();
test_exclusion_wcs();
+ test_exclusion_from_file_mbs();
+ test_exclusion_from_file_wcs();
test_inclusion_mbs();
test_inclusion_wcs();
+ test_inclusion_from_file_mbs();
+ test_inclusion_from_file_wcs();
test_exclusion_and_inclusion();
}
diff --git a/libarchive_fe/matching.c b/libarchive_fe/matching.c
deleted file mode 100644
index f416eae7..00000000
--- a/libarchive_fe/matching.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "lafe_platform.h"
-__FBSDID("$FreeBSD: src/usr.bin/cpio/matching.c,v 1.2 2008/06/21 02:20:20 kientzle Exp $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "archive.h"
-#include "err.h"
-#include "line_reader.h"
-#include "matching.h"
-
-/*
- * Utility functions to manage exclusion/inclusion patterns
- */
-
-int
-lafe_exclude_from_file(struct archive *matching, const char *pathname)
-{
- struct lafe_line_reader *lr;
- const char *p;
- int ret = 0;
-
- lr = lafe_line_reader(pathname, 0);
- while ((p = lafe_line_reader_next(lr)) != NULL) {
- ret = archive_match_exclude_pattern(matching, p);
- if (ret == ARCHIVE_FATAL)
- lafe_errc(1, errno, "Out of memory");
- }
- lafe_line_reader_free(lr);
- return (ret);
-}
-
-int
-lafe_include_from_file(struct archive *matching, const char *pathname,
- int nullSeparator)
-{
- struct lafe_line_reader *lr;
- const char *p;
- int ret = 0;
-
- lr = lafe_line_reader(pathname, nullSeparator);
- while ((p = lafe_line_reader_next(lr)) != NULL) {
- ret = archive_match_include_pattern(matching, p);
- if (ret == ARCHIVE_FATAL)
- lafe_errc(1, errno, "Out of memory");
- }
- lafe_line_reader_free(lr);
- return (ret);
-}
-
diff --git a/libarchive_fe/matching.h b/libarchive_fe/matching.h
deleted file mode 100644
index 4c174a84..00000000
--- a/libarchive_fe/matching.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef MATCHING_H
-#define MATCHING_H
-
-#include "archive.h"
-
-int lafe_exclude_from_file(struct archive *, const char *pathname);
-int lafe_include_from_file(struct archive *,
- const char *pathname, int nullSeparator);
-
-#endif
diff --git a/tar/CMakeLists.txt b/tar/CMakeLists.txt
index 983aa342..eddf7ecc 100644
--- a/tar/CMakeLists.txt
+++ b/tar/CMakeLists.txt
@@ -19,8 +19,6 @@ IF(ENABLE_TAR)
../libarchive_fe/lafe_platform.h
../libarchive_fe/line_reader.c
../libarchive_fe/line_reader.h
- ../libarchive_fe/matching.c
- ../libarchive_fe/matching.h
)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe)
IF(WIN32 AND NOT CYGWIN)
diff --git a/tar/bsdtar.c b/tar/bsdtar.c
index 0d723f3a..52b5c91b 100644
--- a/tar/bsdtar.c
+++ b/tar/bsdtar.c
@@ -555,11 +555,11 @@ main(int argc, char **argv)
bsdtar->option_interactive = 1;
break;
case 'X': /* GNU tar */
- if (lafe_exclude_from_file(bsdtar->matching,
- bsdtar->argument))
- lafe_errc(1, 0,
- "failed to process exclusions from file %s",
- bsdtar->argument);
+ if (archive_match_exclude_pattern_from_file(
+ bsdtar->matching, bsdtar->argument, 0)
+ != ARCHIVE_OK)
+ lafe_errc(1, 0, "Error : %s",
+ archive_error_string(bsdtar->matching));
break;
case 'x': /* SUSv2 */
set_mode(bsdtar, opt);
diff --git a/tar/bsdtar.h b/tar/bsdtar.h
index 1f7dd74a..2387c44a 100644
--- a/tar/bsdtar.h
+++ b/tar/bsdtar.h
@@ -28,8 +28,6 @@
#include "bsdtar_platform.h"
#include <stdio.h>
-#include "matching.h"
-
#define DEFAULT_BYTES_PER_BLOCK (20*512)
/*
diff --git a/tar/read.c b/tar/read.c
index 4fa6a547..676ea0aa 100644
--- a/tar/read.c
+++ b/tar/read.c
@@ -166,8 +166,11 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
}
if (bsdtar->names_from_file != NULL)
- lafe_include_from_file(bsdtar->matching,
- bsdtar->names_from_file, bsdtar->option_null);
+ if (archive_match_include_pattern_from_file(
+ bsdtar->matching, bsdtar->names_from_file,
+ bsdtar->option_null) != ARCHIVE_OK)
+ lafe_errc(1, 0, "Error inclusion pattern: %s",
+ archive_error_string(bsdtar->matching));
a = archive_read_new();
if (bsdtar->compress_program != NULL)
diff --git a/tar/test/main.c b/tar/test/main.c
index da49c725..81087d92 100644
--- a/tar/test/main.c
+++ b/tar/test/main.c
@@ -1520,7 +1520,7 @@ assertion_make_dir(const char *file, int line, const char *dirname, int mode)
/* Create a file with the specified contents and report any failures. */
int
assertion_make_file(const char *file, int line,
- const char *path, int mode, const char *contents)
+ const char *path, int mode, int csize, const void *contents)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
/* TODO: Rework this to set file mode as well. */
@@ -1534,8 +1534,13 @@ assertion_make_file(const char *file, int line,
return (0);
}
if (contents != NULL) {
- if (strlen(contents)
- != fwrite(contents, 1, strlen(contents), f)) {
+ size_t wsize;
+
+ if (csize < 0)
+ wsize = strlen(contents);
+ else
+ wsize = (size_t)csize;
+ if (wsize != fwrite(contents, 1, wsize, f)) {
fclose(f);
failure_start(file, line,
"Could not write file %s", path);
@@ -1555,10 +1560,16 @@ assertion_make_file(const char *file, int line,
return (0);
}
if (contents != NULL) {
- if ((ssize_t)strlen(contents)
- != write(fd, contents, strlen(contents))) {
+ ssize_t wsize;
+
+ if (csize < 0)
+ wsize = (ssize_t)strlen(contents);
+ else
+ wsize = (ssize_t)csize;
+ if (wsize != write(fd, contents, wsize)) {
close(fd);
- failure_start(file, line, "Could not write to %s", path);
+ failure_start(file, line,
+ "Could not write to %s", path);
failure_finish(NULL);
return (0);
}
@@ -1803,7 +1814,7 @@ canSymlink(void)
return (value);
++tested;
- assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a");
+ assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, 1, "a");
/* Note: Cygwin has its own symlink() emulation that does not
* use the Win32 CreateSymbolicLink() function. */
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1863,7 +1874,7 @@ canNodump(void)
const char *path = "cannodumptest";
struct stat sb;
- assertion_make_file(__FILE__, __LINE__, path, 0644, NULL);
+ assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
if (chflags(path, UF_NODUMP) < 0)
return (0);
if (stat(path, &sb) < 0)
@@ -1882,7 +1893,7 @@ canNodump(void)
const char *path = "cannodumptest";
int fd, r, flags;
- assertion_make_file(__FILE__, __LINE__, path, 0644, NULL);
+ assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL);
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return (0);
diff --git a/tar/test/test.h b/tar/test/test.h
index ccb14db4..46abb59e 100644
--- a/tar/test/test.h
+++ b/tar/test/test.h
@@ -196,7 +196,9 @@
#define assertMakeDir(dirname, mode) \
assertion_make_dir(__FILE__, __LINE__, dirname, mode)
#define assertMakeFile(path, mode, contents) \
- assertion_make_file(__FILE__, __LINE__, path, mode, contents)
+ assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents)
+#define assertMakeBinFile(path, mode, csize, contents) \
+ assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents)
#define assertMakeHardlink(newfile, oldfile) \
assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile)
#define assertMakeSymlink(newfile, linkto) \
@@ -245,7 +247,7 @@ int assertion_is_not_hardlink(const char *, int, const char *, const char *);
int assertion_is_reg(const char *, int, const char *, int);
int assertion_is_symlink(const char *, int, const char *, const char *);
int assertion_make_dir(const char *, int, const char *, int);
-int assertion_make_file(const char *, int, const char *, int, const char *);
+int assertion_make_file(const char *, int, const char *, int, int, const void *);
int assertion_make_hardlink(const char *, int, const char *newpath, const char *);
int assertion_make_symlink(const char *, int, const char *newpath, const char *);
int assertion_nodump(const char *, int, const char *);