diff --git a/HISTORY b/HISTORY index f19539fb..94006c67 100644 --- a/HISTORY +++ b/HISTORY @@ -3,6 +3,8 @@ SnapRAID HISTORY 1.10 2012/4 =========== + * If a file is excluded prints explicitely which file attribute caused the + exclusion. 1.9 2012/3 ========== diff --git a/TODO b/TODO index fcf5e226..d9538489 100644 --- a/TODO +++ b/TODO @@ -5,9 +5,6 @@ This is the list of TODO items for SnapRAID. - v1.10 -* If a file is excluded, tell more about the reason. For example print if it's a Windows system file, -or if it has other special attributes. - * In Windows it's possible to workaround the 260 char path length using wide char functions and prepending "\\?\". Like "\\?\D:\very long path" diff --git a/elem.h b/elem.h index f8923456..88fb39e0 100644 --- a/elem.h +++ b/elem.h @@ -223,7 +223,7 @@ void filter_free(struct snapraid_filter* filter); */ static inline int filter_hidden(int enable, struct dirent* dd, struct stat* st) { - if (enable && ishidden(dd, st)) { + if (enable && stat_hidden(dd, st)) { return 1; /* filter out */ } diff --git a/mingw.c b/mingw.c index 95639424..0a6e629a 100644 --- a/mingw.c +++ b/mingw.c @@ -82,24 +82,32 @@ static char* u16tou8(const wchar_t* src) */ static void windows_info2stat(const BY_HANDLE_FILE_INFORMATION* info, struct windows_stat* st) { - /* Convert special attributes to a char device */ + /* Convert special attributes */ if ((info->dwFileAttributes & FILE_ATTRIBUTE_DEVICE) != 0) { st->st_mode = S_IFBLK; - } else if ((info->dwFileAttributes & ( - FILE_ATTRIBUTE_SYSTEM /* System files */ - | FILE_ATTRIBUTE_TEMPORARY /* Files going to be deleted on close */ - | FILE_ATTRIBUTE_OFFLINE - | FILE_ATTRIBUTE_REPARSE_POINT /* Symbolic links */ - )) != 0) { + st->st_desc = "device"; + } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0) { /* System files */ st->st_mode = S_IFCHR; + st->st_desc = "system"; + } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { /* Symbolic links */ + st->st_mode = S_IFCHR; + st->st_desc = "reparse-point"; + } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) != 0) { + st->st_mode = S_IFCHR; + st->st_desc = "offline"; + } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) != 0) { /* Files going to be deleted on close */ + st->st_mode = S_IFCHR; + st->st_desc = "temporary"; } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { st->st_mode = S_IFDIR; + st->st_desc = "directory"; } else { st->st_mode = S_IFREG; + st->st_desc = "regular"; } /* Store the HIDDEN attribute in a separate field */ - st->st_ishidden = (info->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0; + st->st_hidden = (info->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0; st->st_size = info->nFileSizeHigh; st->st_size <<= 32; @@ -134,21 +142,29 @@ static void windows_finddata2stat(const WIN32_FIND_DATAW* info, struct windows_s /* Convert special attributes */ if ((info->dwFileAttributes & FILE_ATTRIBUTE_DEVICE) != 0) { st->st_mode = S_IFBLK; - } else if ((info->dwFileAttributes & ( - FILE_ATTRIBUTE_SYSTEM /* System files */ - | FILE_ATTRIBUTE_TEMPORARY /* Files going to be deleted on close */ - | FILE_ATTRIBUTE_OFFLINE - | FILE_ATTRIBUTE_REPARSE_POINT /* Symbolic links, not supported so return a character file */ - )) != 0) { + st->st_desc = "device"; + } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0) { /* System files */ st->st_mode = S_IFCHR; + st->st_desc = "system"; + } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { /* Symbolic links */ + st->st_mode = S_IFCHR; + st->st_desc = "reparse-point"; + } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) != 0) { + st->st_mode = S_IFCHR; + st->st_desc = "offline"; + } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) != 0) { /* Files going to be deleted on close */ + st->st_mode = S_IFCHR; + st->st_desc = "temporary"; } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { st->st_mode = S_IFDIR; + st->st_desc = "directory"; } else { st->st_mode = S_IFREG; + st->st_desc = "regular"; } /* Store the HIDDEN attribute in a separate field */ - st->st_ishidden = (info->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0; + st->st_hidden = (info->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0; st->st_size = info->nFileSizeHigh; st->st_size <<= 32; @@ -544,10 +560,15 @@ int windows_closedir(windows_dir* dirstream) return 0; } -int windows_ishidden(struct dirent* dd, struct windows_stat* st) +int windows_stat_hidden(struct dirent* dd, struct windows_stat* st) { (void)dd; - return st->st_ishidden; + return st->st_hidden; +} + +const char* windows_stat_desc(struct stat* st) +{ + return st->st_desc; } #endif diff --git a/mingw.h b/mingw.h index 5309bd72..ee62a1b3 100644 --- a/mingw.h +++ b/mingw.h @@ -51,7 +51,8 @@ #define closedir windows_closedir #define futimes windows_futimes #define O_NOFOLLOW 0 -#define ishidden windows_ishidden +#define stat_hidden windows_stat_hidden +#define stat_desc windows_stat_desc /* In Windows symbolic links are not supported */ #define S_ISLNK(mode) 0 #define readlink(a,b,c) -1 @@ -67,7 +68,8 @@ struct windows_stat { uint32_t st_mode; uint32_t st_nlink; uint32_t st_dev; - int st_ishidden; + int st_hidden; + const char* st_desc; }; /** @@ -167,9 +169,14 @@ struct windows_dirent* windows_readdir(windows_dir* dirstream); int windows_closedir(windows_dir* dirstream); /** - * Like ishidden(). + * Like stat_hidden(). */ -int windows_ishidden(struct dirent* dd, struct windows_stat* st); +int windows_stat_hidden(struct dirent* dd, struct windows_stat* st); + +/** + * Like stat_desc(). + */ +const char* windows_stat_desc(struct stat* st); #endif #endif diff --git a/portable.h b/portable.h index a700f34c..27fb8d5a 100644 --- a/portable.h +++ b/portable.h @@ -119,11 +119,35 @@ /** * Check if the specified file is hidden. */ -static inline int ishidden(struct dirent* dd, struct stat* st) +static inline int stat_hidden(struct dirent* dd, struct stat* st) { (void)st; return dd->d_name[0] == '.'; } + +/** + * Return a description of the file type. + */ +static inline const char* stat_desc(struct stat* st) +{ + if (S_ISREG(st.st_mode)) + return "regular"; + if (S_ISDIR(st.st_mode)) + return "directory"; + if (S_ISCHR(st.st_mode)) + return "character"; + if (S_ISBLK(st.st_mode)) + return "block-device"; + if (S_ISFIFO(st.st_mode)) + return "fifo"; + if (S_ISLNK(st.st_mode)) + return "link"; + if (S_ISLNK(st.st_mode)) + return "symbolic-link"; + if (S_ISSOCK(st.st_mode)) + return "socket"; + return "unknown"; +} #endif #endif diff --git a/scan.c b/scan.c index ea378945..d1cddb75 100644 --- a/scan.c +++ b/scan.c @@ -537,10 +537,10 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, i && filter_content(&state->contentlist, path_next) == 0 && filter_path(&state->filterlist, sub_next) == 0 ) { - fprintf(stderr, "warning: Ignoring special file '%s'\n", path_next); + fprintf(stderr, "warning: Ignoring special '%s' file '%s'\n", stat_desc(&st), path_next); } else { if (state->verbose) { - printf("Excluding special file '%s'\n", path_next); + printf("Excluding special '%s' file '%s'\n", stat_desc(&st), path_next); } } }