From fb06397fd380bcd5418c5b67413abe9525958158 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Thu, 19 Apr 2018 11:51:28 +0200 Subject: [PATCH] new --exclude-from=FILE option Exclude files matching patterns listed in FILE. Signed-off-by: Dietmar Maurer --- src/caencoder.c | 24 ++++++++++++++++++++++++ src/caencoder.h | 3 +++ src/casync-tool.c | 15 ++++++++++++++- src/casync.c | 24 ++++++++++++++++++++++++ src/casync.h | 3 +++ 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/caencoder.c b/src/caencoder.c index a996e4a1..117348fb 100644 --- a/src/caencoder.c +++ b/src/caencoder.c @@ -526,6 +526,30 @@ static int dirent_bsearch_func(const void *key, const void *member) { return strcmp(k, (*m)->d_name); } +int ca_encoder_set_exclude_from(CaEncoder *e, const char *path) { + CaEncoderNode *root; + _cleanup_(ca_match_unrefp) CaMatch *match = NULL; + int r; + + if (!e) + return -EINVAL; + + if (!path) + return -EINVAL; + + root = ca_encoder_current_node(e); + + r = ca_match_new_from_file(root->fd, path, &match); + if (r < 0) + return r; + + r = ca_match_merge(&root->exclude_match, match); + if (r < 0) + return r; + + return 0; +} + static int ca_encoder_node_load_exclude_file(CaEncoderNode *n) { int r; assert(n); diff --git a/src/caencoder.h b/src/caencoder.h index 7ecd4179..46cff9a6 100644 --- a/src/caencoder.h +++ b/src/caencoder.h @@ -36,6 +36,9 @@ int ca_encoder_set_uid_range(CaEncoder *e, uid_t u); int ca_encoder_set_base_fd(CaEncoder *e, int fd); int ca_encoder_get_base_fd(CaEncoder *e); +/* Path to exclude filter */ +int ca_encoder_set_exclude_from(CaEncoder *e, const char *path); + int ca_encoder_step(CaEncoder *e); /* Output: archive stream data */ diff --git a/src/casync-tool.c b/src/casync-tool.c index 18c68c84..0562077f 100644 --- a/src/casync-tool.c +++ b/src/casync-tool.c @@ -47,6 +47,7 @@ static bool arg_dry_run = false; static bool arg_exclude_nodump = true; static bool arg_exclude_submounts = false; static bool arg_exclude_file = true; +static char *arg_exclude_from = NULL; static bool arg_reflink = true; static bool arg_hardlink = false; static bool arg_punch_holes = true; @@ -328,6 +329,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_EXCLUDE_NODUMP, ARG_EXCLUDE_SUBMOUNTS, ARG_EXCLUDE_FILE, + ARG_EXCLUDE_FROM, ARG_UNDO_IMMUTABLE, ARG_PUNCH_HOLES, ARG_REFLINK, @@ -361,6 +363,7 @@ static int parse_argv(int argc, char *argv[]) { { "exclude-nodump", required_argument, NULL, ARG_EXCLUDE_NODUMP }, { "exclude-submounts", required_argument, NULL, ARG_EXCLUDE_SUBMOUNTS }, { "exclude-file", required_argument, NULL, ARG_EXCLUDE_FILE }, + { "exclude-from", required_argument, NULL, ARG_EXCLUDE_FROM }, { "undo-immutable", required_argument, NULL, ARG_UNDO_IMMUTABLE }, { "delete", required_argument, NULL, ARG_DELETE }, { "punch-holes", required_argument, NULL, ARG_PUNCH_HOLES }, @@ -521,7 +524,11 @@ static int parse_argv(int argc, char *argv[]) { arg_exclude_file = r; break; - case ARG_UNDO_IMMUTABLE: + case ARG_EXCLUDE_FROM: + arg_exclude_from = strdup(optarg); + break; + + case ARG_UNDO_IMMUTABLE: r = parse_boolean(optarg); if (r < 0) { log_error("Failed to parse --undo-immutable= parameter: %s", optarg); @@ -1294,6 +1301,12 @@ static int verb_make(int argc, char *argv[]) { return log_error_errno(r, "Failed to set cache: %m"); } + if (IN_SET(operation, MAKE_ARCHIVE_INDEX, MAKE_ARCHIVE) && arg_exclude_from) { + r = ca_sync_set_exclude_from(s, arg_exclude_from); + if (r < 0) + return log_error_errno(r, "Failed to set exclude-from: %m"); + } + (void) send_notify("READY=1"); for (;;) { diff --git a/src/casync.c b/src/casync.c index bc484d24..9f48d564 100644 --- a/src/casync.c +++ b/src/casync.c @@ -93,6 +93,7 @@ typedef struct CaSync { char *base_path, *temporary_base_path; char *boundary_path; char *archive_path, *temporary_archive_path; + char *exclude_from; mode_t base_mode; mode_t make_mode; @@ -200,6 +201,21 @@ CaSync *ca_sync_new_decode(void) { return s; } +int ca_sync_set_exclude_from(CaSync *s, const char *path) { + + if (!s) + return -EINVAL; + + if (s->direction != CA_SYNC_ENCODE) + return -EINVAL; + + s->exclude_from = strdup(path); + if (!s->exclude_from) + return -ENOMEM; + + return 0; +} + int ca_sync_set_chunk_size_min(CaSync *s, uint64_t v) { int r; @@ -1319,6 +1335,14 @@ static int ca_sync_start(CaSync *s) { return r; } + if (s->exclude_from) { + r = ca_encoder_set_exclude_from(s->encoder, s->exclude_from); + if (r < 0) { + s->encoder = ca_encoder_unref(s->encoder); + return r; + } + } + s->base_fd = -1; r = ca_encoder_set_uid_shift(s->encoder, s->uid_shift); diff --git a/src/casync.h b/src/casync.h index b54bbd43..16139373 100644 --- a/src/casync.h +++ b/src/casync.h @@ -92,6 +92,9 @@ int ca_sync_add_seed_path(CaSync *sync, const char *path); int ca_sync_set_cache_fd(CaSync *sync, int fd); int ca_sync_set_cache_path(CaSync *sync, const char *path); +/* Path to exclude filter */ +int ca_sync_set_exclude_from(CaSync *s, const char *path); + int ca_sync_step(CaSync *sync); int ca_sync_poll(CaSync *s, uint64_t timeout_nsec, const sigset_t *ss);