diff --git a/cmdline/elem.c b/cmdline/elem.c index 0e82f214..9f1ee5f9 100644 --- a/cmdline/elem.c +++ b/cmdline/elem.c @@ -228,7 +228,7 @@ static int filter_recurse(struct snapraid_filter* filter, struct snapraid_filter return 0; } -static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir) +static int filter_element(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub, int is_dir, int is_def_include) { tommy_node* i; @@ -267,7 +267,7 @@ static int filter_element(tommy_list* filterlist, struct snapraid_filter** reaso /* directories are always included by default, otherwise we cannot apply rules */ /* to the contained files */ - if (is_dir) + if (is_def_include) return 0; /* files are excluded/included depending of the last rule processed */ @@ -279,12 +279,17 @@ static int filter_element(tommy_list* filterlist, struct snapraid_filter** reaso int filter_path(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub) { - return filter_element(filterlist, reason, disk, sub, 0); + return filter_element(filterlist, reason, disk, sub, 0, 0); } -int filter_dir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub) +int filter_subdir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub) { - return filter_element(filterlist, reason, disk, sub, 1); + return filter_element(filterlist, reason, disk, sub, 1, 1); +} + +int filter_emptydir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub) +{ + return filter_element(filterlist, reason, disk, sub, 1, 0); } int filter_existence(int filter_missing, const char* dir, const char* sub) diff --git a/cmdline/elem.h b/cmdline/elem.h index ebbe78c0..fefabaae 100644 --- a/cmdline/elem.h +++ b/cmdline/elem.h @@ -412,8 +412,8 @@ struct snapraid_disk { tommy_hashdyn stampset; /**< Hashtable by stamp (size and time) of all the files. */ tommy_list linklist; /**< List of all the links. */ tommy_hashdyn linkset; /**< Hashtable by name of all the links. */ - tommy_list dirlist; /**< List of all the dirs. */ - tommy_hashdyn dirset; /**< Hashtable by name of all the dirs. */ + tommy_list dirlist; /**< List of all the empty dirs. */ + tommy_hashdyn dirset; /**< Hashtable by name of all the empty dirs. */ /* nodes for data structures */ tommy_node node; @@ -554,9 +554,17 @@ int filter_correctness(int filter_error, tommy_arrayblkof* infoarr, struct snapr /** * Filter a dir using a list of filters. * For each element of the path all the filters are applied, until the first one that matches. + * Thesesdir are always by included by default, to allow to apply rules at the contained files. * Return !=0 if should be excluded. */ -int filter_dir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub); +int filter_subdir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub); + +/** + * Filter a dir using a list of filters. + * For each element of the path all the filters are applied, until the first one that matches. + * Return !=0 if should be excluded. + */ +int filter_emptydir(tommy_list* filterlist, struct snapraid_filter** reason, const char* disk, const char* sub); /** * Filter a path if it's a content file. diff --git a/cmdline/scan.c b/cmdline/scan.c index df9dc1d3..37f28876 100644 --- a/cmdline/scan.c +++ b/cmdline/scan.c @@ -1369,7 +1369,7 @@ static int scan_dir(struct snapraid_scan* scan, int level, int is_diff, const ch msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); } } else if (type == 2) { /* DIR */ - if (filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) { + if (filter_subdir(&state->filterlist, &reason, disk->name, sub_next) == 0) { #ifndef _WIN32 /* late stat, if not yet called */ if (!st) diff --git a/cmdline/search.c b/cmdline/search.c index 82a1c5bc..3d543faf 100644 --- a/cmdline/search.c +++ b/cmdline/search.c @@ -236,7 +236,7 @@ static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk, msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); } } else if (S_ISDIR(st.st_mode)) { - if (disk == 0 || filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) { + if (disk == 0 || filter_subdir(&state->filterlist, &reason, disk->name, sub_next) == 0) { pathslash(path_next, sizeof(path_next)); pathslash(sub_next, sizeof(sub_next)); search_dir(state, disk, path_next, sub_next); diff --git a/cmdline/state.c b/cmdline/state.c index 353d7d71..0c54b600 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -3971,12 +3971,12 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tom } } - /* for each dir */ + /* for each empty dir */ for (j = tommy_list_head(&disk->dirlist); j != 0; j = j->next) { struct snapraid_dir* dir = j->data; - if (filter_dir(filterlist_disk, 0, disk->name, dir->sub) != 0 - || filter_dir(filterlist_file, 0, disk->name, dir->sub) != 0 + if (filter_emptydir(filterlist_disk, 0, disk->name, dir->sub) != 0 + || filter_emptydir(filterlist_file, 0, disk->name, dir->sub) != 0 || filter_existence(filter_missing, disk->dir, dir->sub) != 0 ) { dir_flag_set(dir, FILE_IS_EXCLUDED);