to effectively call archive_matching_*_excluded_ae function in archive_read_disk.
SVN-Revision: 4175
* you invoke this on every returned path, you'll get a full logical
* traversal.
*/
-__LA_DECL int archive_read_disk_can_descend(struct archive *);
__LA_DECL int archive_read_disk_descend(struct archive *);
+__LA_DECL int archive_read_disk_can_descend(struct archive *);
__LA_DECL int archive_read_disk_current_filesystem(struct archive *);
__LA_DECL int archive_read_disk_current_filesystem_is_synthetic(struct archive *);
__LA_DECL int archive_read_disk_current_filesystem_is_remote(struct archive *);
__LA_DECL int archive_read_disk_set_atime_restored(struct archive *);
__LA_DECL int archive_read_disk_honor_nodump(struct archive *);
__LA_DECL int archive_read_disk_disable_mac_copyfile(struct archive *);
-
-__LA_DECL int archive_read_disk_set_name_filter_callback(struct archive *,
- int (*_name_filter_func)(struct archive *, void *,
- struct archive_entry *), void *_client_data);
+/*
+ * Set archive_matching object that will be used in archive_read_disk to
+ * know whether an entry should be skipped. The callback function
+ * _excluded_func will be invoked when an entry is skipped by the result
+ * of archive_matching.
+ */
+__LA_DECL int archive_read_disk_set_matching(struct archive *,
+ struct archive *_matching, void (*_excluded_func)
+ (struct archive *, void *, struct archive_entry *),
+ void *_client_data);
__LA_DECL int archive_read_disk_set_metadata_filter_callback(struct archive *,
int (*_metadata_filter_func)(struct archive *, void *,
struct archive_entry *), void *_client_data);
goto next_entry;
}
#endif
- archive_entry_copy_pathname(entry, tree_current_path(t));
+ archive_entry_copy_pathname(entry, tree_current_path(t));
/*
- * Invoke a name filter callback.
+ * Perform path matching.
*/
- if (a->name_filter_func) {
- if (!a->name_filter_func(_a, a->name_filter_data, entry))
+ if (a->matching) {
+ r = archive_matching_path_excluded_w(a->matching,
+ tree_current_path(t));
+ if (r < 0) {
+ archive_set_error(&(a->archive), errno,
+ "Faild : %s", archive_error_string(a->matching));
+ return (r);
+ }
+ if (r) {
+ if (a->excluded_cb_func)
+ a->excluded_cb_func(&(a->archive),
+ a->excluded_cb_data, entry);
+ archive_entry_clear(entry);
goto next_entry;
+ }
}
/*
fd = -1;
if (a->honor_nodump) {
#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
- if (st->st_flags & UF_NODUMP) {
- archive_entry_clear(entry);
+ if (st->st_flags & UF_NODUMP)
goto next_entry;
- }
#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) &&\
defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
if (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) {
r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
if (r == 0 && (stflags & EXT2_NODUMP_FL) != 0) {
close(fd);
- archive_entry_clear(entry);
goto next_entry;
}
}
}
archive_entry_copy_stat(entry, st);
+
/* Save the times to be restored. This must be in before
* calling archive_read_disk_descend() or any chance of it,
* especially, invokng a callback. */
t->restore_time.filetype = archive_entry_filetype(entry);
t->restore_time.noatime = t->current_filesystem->noatime;
+ /*
+ * Perform time matching.
+ */
+ if (a->matching) {
+ r = archive_matching_time_excluded_ae(a->matching, entry);
+ if (r < 0) {
+ archive_set_error(&(a->archive), errno,
+ "Faild : %s", archive_error_string(a->matching));
+ return (r);
+ }
+ if (r) {
+ if (a->excluded_cb_func)
+ a->excluded_cb_func(&(a->archive),
+ a->excluded_cb_data, entry);
+ archive_entry_clear(entry);
+ goto next_entry;
+ }
+ }
+
/* Lookup uname/gname */
name = archive_read_disk_uname(_a, archive_entry_uid(entry));
if (name != NULL)
if (name != NULL)
archive_entry_copy_gname(entry, name);
+ /*
+ * Perform owner matching.
+ */
+ if (a->matching) {
+ r = archive_matching_owner_excluded_ae(a->matching, entry);
+ if (r < 0) {
+ archive_set_error(&(a->archive), errno,
+ "Faild : %s", archive_error_string(a->matching));
+ return (r);
+ }
+ if (r) {
+ if (a->excluded_cb_func)
+ a->excluded_cb_func(&(a->archive),
+ a->excluded_cb_data, entry);
+ archive_entry_clear(entry);
+ goto next_entry;
+ }
+ }
+
/*
* Invoke a meta data filter callback.
*/
}
int
-archive_read_disk_set_name_filter_callback(struct archive *_a,
- int (*_name_filter_func)(struct archive *, void *, struct archive_entry *),
+archive_read_disk_set_matching(struct archive *_a, struct archive *_ma,
+ void (*_excluded_func)(struct archive *, void *, struct archive_entry *),
void *_client_data)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_disk_set_name_filter_callback");
-
- a->name_filter_func = _name_filter_func;
- a->name_filter_data = _client_data;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_matching");
+ a->matching = _ma;
+ a->excluded_cb_func = _excluded_func;
+ a->excluded_cb_data = _client_data;
return (ARCHIVE_OK);
}
void (*cleanup_uname)(void *private);
void *lookup_uname_data;
- int (*name_filter_func)(struct archive *, void *,
- struct archive_entry *);
- void *name_filter_data;
int (*metadata_filter_func)(struct archive *, void *,
struct archive_entry *);
void *metadata_filter_data;
+ /* ARCHIVE_MATCHING object. */
+ struct archive *matching;
+ /* Callback function, this will be invoked when ARCHIVE_MATCHING
+ * archive_matching_*_excluded_ae return true. */
+ void (*excluded_cb_func)(struct archive *, void *,
+ struct archive_entry *);
+ void *excluded_cb_data;
};
#endif
} while (lst == NULL);
archive_entry_copy_pathname_w(entry, tree_current_path(t));
- if (a->name_filter_func) {
- if (!a->name_filter_func(_a, a->name_filter_data, entry))
+
+ /*
+ * Perform path matching.
+ */
+ if (a->matching) {
+ r = archive_matching_path_excluded_w(a->matching,
+ tree_current_path(t));
+ if (r < 0) {
+ archive_set_error(&(a->archive), errno,
+ "Faild : %s", archive_error_string(a->matching));
+ return (r);
+ }
+ if (r) {
+ if (a->excluded_cb_func)
+ a->excluded_cb_func(&(a->archive),
+ a->excluded_cb_data, entry);
+ archive_entry_clear(entry);
goto next_entry;
+ }
}
/*
t->descend = descend;
tree_archive_entry_copy_bhfi(entry, t, st);
+
+ /* Save the times to be restored. This must be in before
+ * calling archive_read_disk_descend() or any chance of it,
+ * especially, invokng a callback. */
+ t->restore_time.lastWriteTime = st->ftLastWriteTime;
+ t->restore_time.lastAccessTime = st->ftLastAccessTime;
+ t->restore_time.filetype = archive_entry_filetype(entry);
+
+ /*
+ * Perform time matching.
+ */
+ if (a->matching) {
+ r = archive_matching_time_excluded_ae(a->matching, entry);
+ if (r < 0) {
+ archive_set_error(&(a->archive), errno,
+ "Faild : %s", archive_error_string(a->matching));
+ return (r);
+ }
+ if (r) {
+ if (a->excluded_cb_func)
+ a->excluded_cb_func(&(a->archive),
+ a->excluded_cb_data, entry);
+ archive_entry_clear(entry);
+ goto next_entry;
+ }
+ }
+
/* Lookup uname/gname */
name = archive_read_disk_uname(_a, archive_entry_uid(entry));
if (name != NULL)
name = archive_read_disk_gname(_a, archive_entry_gid(entry));
if (name != NULL)
archive_entry_copy_gname(entry, name);
- /* Invoke a filter callback. */
+
+ /*
+ * Perform owner matching.
+ */
+ if (a->matching) {
+ r = archive_matching_owner_excluded_ae(a->matching, entry);
+ if (r < 0) {
+ archive_set_error(&(a->archive), errno,
+ "Faild : %s", archive_error_string(a->matching));
+ return (r);
+ }
+ if (r) {
+ if (a->excluded_cb_func)
+ a->excluded_cb_func(&(a->archive),
+ a->excluded_cb_data, entry);
+ archive_entry_clear(entry);
+ goto next_entry;
+ }
+ }
+
+ /*
+ * Invoke a meta data filter callback.
+ */
if (a->metadata_filter_func) {
if (!a->metadata_filter_func(_a,
a->metadata_filter_data, entry)) {
}
archive_entry_copy_sourcepath_w(entry, tree_current_access_path(t));
- /* Save the times to be restored. */
- t->restore_time.lastWriteTime = st->ftLastWriteTime;
- t->restore_time.lastAccessTime = st->ftLastAccessTime;
- t->restore_time.filetype = archive_entry_filetype(entry);
-
r = ARCHIVE_OK;
if (archive_entry_filetype(entry) == AE_IFREG &&
archive_entry_size(entry) > 0) {
}
int
-archive_read_disk_set_name_filter_callback(struct archive *_a,
- int (*_name_filter_func)(struct archive *, void *, struct archive_entry *),
+archive_read_disk_set_matching(struct archive *_a, struct archive *_ma,
+ void (*_excluded_func)(struct archive *, void *, struct archive_entry *),
void *_client_data)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
-
- archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_disk_set_name_filter_callback");
-
- a->name_filter_func = _name_filter_func;
- a->name_filter_data = _client_data;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_matching");
+ a->matching = _ma;
+ a->excluded_cb_func = _excluded_func;
+ a->excluded_cb_data = _client_data;
return (ARCHIVE_OK);
}
archive_entry_free(ae);
}
-static int
-name_filter(struct archive *a, void *data, struct archive_entry *ae)
-{
- failure("ATime should not be set");
- assertEqualInt(0, archive_entry_atime_is_set(ae));
- failure("BirthTime should not be set");
- assertEqualInt(0, archive_entry_birthtime_is_set(ae));
- failure("CTime should not be set");
- assertEqualInt(0, archive_entry_ctime_is_set(ae));
- failure("MTime should not be set");
- assertEqualInt(0, archive_entry_mtime_is_set(ae));
-
- if (strcmp(archive_entry_pathname(ae), "cb/f2") == 0)
- return (0);
- return (1);
-}
-
static int
metadata_filter(struct archive *a, void *data, struct archive_entry *ae)
{
test_callbacks(void)
{
struct archive *a;
+ struct archive *m;
struct archive_entry *ae;
const void *p;
size_t size;
assertUtimes("cb", 886622, 0, 886622, 0);
assert((ae = archive_entry_new()) != NULL);
- assert((a = archive_read_disk_new()) != NULL);
+ if (assert((a = archive_read_disk_new()) != NULL)) {
+ archive_entry_free(ae);
+ return;
+ }
+ if (assert((m = archive_matching_new()) != NULL)) {
+ archive_entry_free(ae);
+ archive_read_free(a);
+ return;
+ }
/*
* Test1: Traversals with a name filter.
*/
file_count = 3;
+ assertEqualIntA(m, ARCHIVE_OK,
+ archive_matching_exclude_pattern(m, "cb/f2"));
assertEqualIntA(a, ARCHIVE_OK,
- archive_read_disk_set_name_filter_callback(a, name_filter, NULL));
+ archive_read_disk_set_matching(a, m, NULL, NULL));
failure("Directory traversals should work as well");
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb"));
while (file_count--) {
assertUtimes("cb/fe", 886611, 0, 886611, 0);
assertUtimes("cb", 886622, 0, 886622, 0);
file_count = 3;
- assertEqualIntA(a, ARCHIVE_OK,
- archive_read_disk_set_name_filter_callback(a, NULL, NULL));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_disk_set_metadata_filter_callback(a, metadata_filter,
NULL));
/* Destroy the disk object. */
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ assertEqualInt(ARCHIVE_OK, archive_matching_free(m));
archive_entry_free(ae);
}
static int copy_file_data_block(struct bsdtar *,
struct archive *a, struct archive *,
struct archive_entry *);
-static int name_filter(struct archive *, void *,
+static void excluded_callback(struct archive *, void *,
struct archive_entry *);
static void report_write(struct bsdtar *, struct archive *,
struct archive_entry *, int64_t progress);
break;
}
/* Register entry filters. */
- archive_read_disk_set_name_filter_callback(bsdtar->diskreader,
- name_filter, bsdtar);
+ archive_read_disk_set_matching(bsdtar->diskreader,
+ bsdtar->matching, excluded_callback, bsdtar);
archive_read_disk_set_metadata_filter_callback(
bsdtar->diskreader, metadata_filter, bsdtar);
/* Skip a file if it has nodump flag. */
return (0);
}
-static int
-name_filter(struct archive *a, void *_data, struct archive_entry *entry)
+static void
+excluded_callback(struct archive *a, void *_data, struct archive_entry *entry)
{
struct bsdtar *bsdtar = (struct bsdtar *)_data;
- /*
- * If this file/dir is excluded by a filename
- * pattern, skip it.
- */
- if (archive_matching_path_excluded_ae(bsdtar->matching, entry))
- return (0);
- return (1);
+ if (bsdtar->option_no_subdirs)
+ return;
+ if (!archive_read_disk_can_descend(a))
+ return;
+ if (bsdtar->option_dont_traverse_mounts) {
+ if (bsdtar->first_fs == -1)
+ bsdtar->first_fs =
+ archive_read_disk_current_filesystem(a);
+ else if (bsdtar->first_fs !=
+ archive_read_disk_current_filesystem(a))
+ return;
+ }
+ if (bsdtar->option_interactive &&
+ !yes("add '%s'", archive_entry_pathname(entry)))
+ return;
+ archive_read_disk_descend(a);
}
static int
{
struct bsdtar *bsdtar = (struct bsdtar *)_data;
- /*
- * In -u mode, check that the file is newer than what's
- * already in the archive; in all modes, obey --newerXXX flags.
- */
- if (archive_matching_time_excluded_ae(bsdtar->matching, entry)) {
- if (bsdtar->option_no_subdirs)
- return (0);
- if (!archive_read_disk_can_descend(a))
- return (0);
- if (bsdtar->option_interactive &&
- !yes("add '%s'", archive_entry_pathname(entry)))
- return (0);
- archive_read_disk_descend(a);
- return (0);
- }
-
if (bsdtar->option_dont_traverse_mounts) {
if (bsdtar->first_fs == -1)
bsdtar->first_fs =