Doesn't apply file filter rules to directory.

In Windows uses the information reported by FindFirstFile instead of calling lstat().
This commit is contained in:
Andrea Mazzoleni 2013-01-18 00:15:55 +01:00
parent 5171e93ee5
commit 8204dfad6a
6 changed files with 55 additions and 33 deletions

View file

@ -1,9 +1,10 @@
SnapRAID HISTORY
================
2.1 2012/12
===========
2.1 2013/1
==========
* Checks for wrong empty fields in the configuration file.
* Filter rules for files are not anymore applied to directories.
2.0 2012/12
===========

4
elem.h
View file

@ -234,9 +234,9 @@ void filter_free(struct snapraid_filter* filter);
* Filter hidden files.
* Return !=0 if it matches and it should be excluded.
*/
static inline int filter_hidden(int enable, struct dirent* dd, struct stat* st)
static inline int filter_hidden(int enable, struct dirent* dd)
{
if (enable && stat_hidden(dd, st)) {
if (enable && dirent_hidden(dd)) {
return 1; /* filter out */
}

21
mingw.c
View file

@ -401,6 +401,9 @@ static void windows_finddata2dirent(const WIN32_FIND_DATAW* info, struct windows
}
memcpy(dirent->d_name, name, len + 1);
/* Store the HIDDEN attribute in a separate field */
dirent->d_hidden = (info->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0;
}
/**
@ -479,6 +482,11 @@ int windows_lstat(const char* file, struct windows_stat* st)
return 0;
}
void windows_dirent_lstat(const struct windows_dirent* dd, struct windows_stat* st)
{
windows_finddata2stat(&dd->d_data, st);
}
int windows_access(const char* file, int mode)
{
return _waccess(convert(file), mode);
@ -709,7 +717,7 @@ windows_dir* windows_opendir(const char* dir)
wdir[len++] = L'*';
wdir[len++] = 0;
dirstream->h = FindFirstFileW(wdir, &dirstream->data);
dirstream->h = FindFirstFileW(wdir, &dirstream->buffer.d_data);
if (dirstream->h == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
@ -725,7 +733,7 @@ windows_dir* windows_opendir(const char* dir)
dirstream->flags = 1;
windows_finddata2dirent(&dirstream->data, &dirstream->buffer);
windows_finddata2dirent(&dirstream->buffer.d_data, &dirstream->buffer);
return dirstream;
}
@ -742,7 +750,7 @@ struct windows_dirent* windows_readdir(windows_dir* dirstream)
return &dirstream->buffer;
}
if (!FindNextFileW(dirstream->h, &dirstream->data)) {
if (!FindNextFileW(dirstream->h, &dirstream->buffer.d_data)) {
DWORD error = GetLastError();
if (error == ERROR_NO_MORE_FILES) {
@ -754,7 +762,7 @@ struct windows_dirent* windows_readdir(windows_dir* dirstream)
return 0;
}
windows_finddata2dirent(&dirstream->data, &dirstream->buffer);
windows_finddata2dirent(&dirstream->buffer.d_data, &dirstream->buffer);
return &dirstream->buffer;
}
@ -776,10 +784,9 @@ int windows_closedir(windows_dir* dirstream)
return 0;
}
int windows_stat_hidden(struct dirent* dd, struct windows_stat* st)
int windows_dirent_hidden(struct dirent* dd)
{
(void)dd;
return st->st_hidden;
return dd->d_hidden;
}
const char* windows_stat_desc(struct stat* st)

17
mingw.h
View file

@ -53,7 +53,9 @@
#define HAVE_FUTIMENS 1
#define futimens windows_futimens
#define O_NOFOLLOW 0
#define stat_hidden windows_stat_hidden
#define dirent_hidden windows_dirent_hidden
#define HAVE_DIRENT_LSTAT 1
#define dirent_lstat windows_dirent_lstat
#define stat_desc windows_stat_desc
#define sleep windows_sleep
/* In Windows symbolic links are not supported */
@ -173,13 +175,14 @@ int windows_open(const char* file, int flags, ...);
*/
struct windows_dirent {
char d_name[PATH_MAX];
int d_hidden;
WIN32_FIND_DATAW d_data;
};
/**
* Like the C DIR.
*/
struct windows_dir_struct {
WIN32_FIND_DATAW data;
HANDLE h;
struct windows_dirent buffer;
int flags;
@ -202,9 +205,15 @@ struct windows_dirent* windows_readdir(windows_dir* dirstream);
int windows_closedir(windows_dir* dirstream);
/**
* Like stat_hidden().
* Convert a dirent record to a lstat record.
* Just like the one obtained calling lstat().
*/
int windows_stat_hidden(struct dirent* dd, struct windows_stat* st);
void windows_dirent_lstat(const struct windows_dirent* dd, struct windows_stat* st);
/**
* Like dirent_hidden().
*/
int windows_dirent_hidden(struct dirent* dd);
/**
* Like stat_desc().

View file

@ -155,9 +155,8 @@ static inline int open_noatime(const char* file, int flags)
/**
* Check if the specified file is hidden.
*/
static inline int stat_hidden(struct dirent* dd, struct stat* st)
static inline int dirent_hidden(struct dirent* dd)
{
(void)st;
return dd->d_name[0] == '.';
}

38
scan.c
View file

@ -480,24 +480,35 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, i
exit(EXIT_FAILURE);
}
/* exclude files before doing any check on them */
if (filter_path(&state->filterlist, disk->name, sub_next) != 0) {
/* exclude hidden stuff even beforer calling lstat() */
if (filter_hidden(state->filter_hidden, dd) != 0) {
if (state->verbose) {
printf("Excluding file '%s'\n", path_next);
printf("Excluding hidden '%s'\n", path_next);
}
continue;
}
/* get info about the file */
/* exclude content files even beforer calling lstat() */
if (filter_content(&state->contentlist, path_next) != 0) {
if (state->verbose) {
printf("Excluding content '%s'\n", path_next);
}
continue;
}
#if HAVE_DIRENT_LSTAT
/* convert dirent to lstat result */
dirent_lstat(dd, &st);
#else
/* get lstat info about the file */
if (lstat(path_next, &st) != 0) {
fprintf(stderr, "Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
}
#endif
if (S_ISREG(st.st_mode)) {
if (filter_hidden(state->filter_hidden, dd, &st) == 0
&& filter_content(&state->contentlist, path_next) == 0
) {
if (filter_path(&state->filterlist, disk->name, sub_next) == 0) {
/* check for read permission */
if (access(path_next, R_OK) != 0) {
fprintf(stderr, "warning: Ignoring, for missing read permission, file '%s'\n", path_next);
@ -520,8 +531,7 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, i
}
}
} else if (S_ISLNK(st.st_mode)) {
if (filter_hidden(state->filter_hidden, dd, &st) == 0
) {
if (filter_path(&state->filterlist, disk->name, sub_next) == 0) {
char subnew[PATH_MAX];
int ret;
@ -541,13 +551,11 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, i
scan_link(scan, state, output, disk, sub_next, subnew);
} else {
if (state->verbose) {
printf("Excluding file '%s'\n", path_next);
printf("Excluding link '%s'\n", path_next);
}
}
} else if (S_ISDIR(st.st_mode)) {
if (filter_hidden(state->filter_hidden, dd, &st) == 0
&& filter_dir(&state->filterlist, disk->name, sub_next) == 0
) {
if (filter_dir(&state->filterlist, disk->name, sub_next) == 0) {
pathslash(path_next, sizeof(path_next));
pathslash(sub_next, sizeof(sub_next));
scan_dir(scan, state, output, disk, path_next, sub_next);
@ -557,9 +565,7 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, i
}
}
} else {
if (filter_hidden(state->filter_hidden, dd, &st) == 0
&& filter_content(&state->contentlist, path_next) == 0
) {
if (filter_path(&state->filterlist, disk->name, sub_next) == 0) {
fprintf(stderr, "warning: Ignoring special '%s' file '%s'\n", stat_desc(&st), path_next);
} else {
if (state->verbose) {