diff options
author | Michihiro NAKAJIMA <ggcueroad@gmail.com> | 2012-02-12 22:41:47 +0900 |
---|---|---|
committer | Michihiro NAKAJIMA <ggcueroad@gmail.com> | 2012-02-12 22:41:47 +0900 |
commit | ae314ad8180bbd1127834d299bfa761f566eac8c (patch) | |
tree | 5ffea4ff68225b79f5494906bb76f74fdc87725f | |
parent | 75d9a70fc8ee5d4687f0ecd4186587cd281faa36 (diff) | |
download | libarchive-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.am | 4 | ||||
-rw-r--r-- | cpio/CMakeLists.txt | 2 | ||||
-rw-r--r-- | cpio/cpio.c | 8 | ||||
-rw-r--r-- | cpio/cpio.h | 2 | ||||
-rw-r--r-- | cpio/test/main.c | 29 | ||||
-rw-r--r-- | cpio/test/test.h | 6 | ||||
-rw-r--r-- | libarchive/archive.h | 10 | ||||
-rw-r--r-- | libarchive/archive_match.c | 169 | ||||
-rw-r--r-- | libarchive/test/main.c | 29 | ||||
-rw-r--r-- | libarchive/test/test.h | 6 | ||||
-rw-r--r-- | libarchive/test/test_archive_match_path.c | 169 | ||||
-rw-r--r-- | libarchive_fe/matching.c | 76 | ||||
-rw-r--r-- | libarchive_fe/matching.h | 38 | ||||
-rw-r--r-- | tar/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tar/bsdtar.c | 10 | ||||
-rw-r--r-- | tar/bsdtar.h | 2 | ||||
-rw-r--r-- | tar/read.c | 7 | ||||
-rw-r--r-- | tar/test/main.c | 29 | ||||
-rw-r--r-- | tar/test/test.h | 6 |
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) /* @@ -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 *); |