diff --git a/elem.c b/elem.c index 0db0d212..785a1a23 100644 --- a/elem.c +++ b/elem.c @@ -230,9 +230,27 @@ int filter_dir(tommy_list* filterlist, const char* disk, const char* sub) return filter_element(filterlist, disk, sub, 1); } -int filter_existence(int filter_missing, unsigned flag) +int filter_existence(int filter_missing, const char* dir, const char* sub) { - return filter_missing && (flag & FILE_IS_PRESENT) == FILE_IS_PRESENT; + char path[PATH_MAX]; + struct stat st; + + if (!filter_missing) + return 0; + + /* we directly check if in the disk the file is present or not */ + pathprint(path, sizeof(path), "%s%s", dir, sub); + + if (lstat(path, &st) != 0) { + /* if the file doesn't exist, we don't filter it out */ + if (errno == ENOENT) + return 0; + fprintf(stderr, "Error in stat file '%s'. %s.\n", path, strerror(errno)); + exit(EXIT_FAILURE); + } + + /* the file is presen, so we filter it out */ + return 1; } int filter_content(tommy_list* contentlist, const char* path) diff --git a/elem.h b/elem.h index 3722cf31..40d60665 100644 --- a/elem.h +++ b/elem.h @@ -304,26 +304,27 @@ static inline int filter_hidden(int enable, struct dirent* dd) /** * Filters a path 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 it matches and it should be excluded. + * Return !=0 if it should be excluded. */ int filter_path(tommy_list* filterlist, const char* disk, const char* sub); /** * Filter a file/link/dir if missing. - * Return !=0 if it matches and it should be excluded. + * This call imply a disk check for the file presence. + * Return !=0 if the file is present and it should be excluded. */ -int filter_existence(int filter_missing, unsigned flag); +int filter_existence(int filter_missing, const char* dir, const char* sub); /** * Filters 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 it matches and it should be excluded. + * Return !=0 if should be excluded. */ int filter_dir(tommy_list* filterlist, const char* disk, const char* sub); /** * Filters a path if it's a content file. - * Return !=0 if it matches and it should be excluded. + * Return !=0 if should be excluded. */ int filter_content(tommy_list* contentlist, const char* path); diff --git a/state.c b/state.c index bd5d8bce..2548d64e 100644 --- a/state.c +++ b/state.c @@ -1837,13 +1837,17 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tom tommy_node* j; struct snapraid_disk* disk = i->data; + /* if we filter for presence, we have to access the disk, so better to print something */ + if (filter_missing) + printf("Scanning disk %s...\n", disk->name); + /* for each file */ for(j=tommy_list_head(&disk->filelist);j!=0;j=j->next) { struct snapraid_file* file = j->data; - if (filter_existence(filter_missing, file->flag) != 0 - || filter_path(filterlist_disk, disk->name, file->sub) != 0 + if (filter_path(filterlist_disk, disk->name, file->sub) != 0 || filter_path(filterlist_file, disk->name, file->sub) != 0 + || filter_existence(filter_missing, disk->dir, file->sub) != 0 ) { file_flag_set(file, FILE_IS_EXCLUDED); } @@ -1857,9 +1861,9 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tom for(j=tommy_list_head(&disk->linklist);j!=0;j=j->next) { struct snapraid_link* link = j->data; - if (filter_existence(filter_missing, link->flag) != 0 - || filter_path(filterlist_disk, disk->name, link->sub) != 0 + if (filter_path(filterlist_disk, disk->name, link->sub) != 0 || filter_path(filterlist_file, disk->name, link->sub) != 0 + || filter_existence(filter_missing, disk->dir, link->sub) != 0 ) { link_flag_set(link, FILE_IS_EXCLUDED); } @@ -1873,9 +1877,9 @@ void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tom for(j=tommy_list_head(&disk->dirlist);j!=0;j=j->next) { struct snapraid_dir* dir = j->data; - if (filter_existence(filter_missing, dir->flag) != 0 - || filter_dir(filterlist_disk, disk->name, dir->sub) != 0 + if (filter_dir(filterlist_disk, disk->name, dir->sub) != 0 || filter_dir(filterlist_file, disk->name, dir->sub) != 0 + || filter_existence(filter_missing, disk->dir, dir->sub) != 0 ) { dir_flag_set(dir, FILE_IS_EXCLUDED); }