From 0365488ce9d1bd4305825d4ae0c5faa5fbda5b25 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sat, 11 Jun 2011 10:19:34 +0200 Subject: [PATCH] Using lstat also in Windows. --- HISTORY | 1 + mingw.c | 22 +++++++++++++++++----- mingw.h | 11 ++++++----- scan.c | 4 ++-- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/HISTORY b/HISTORY index 9c578a9b..923c526c 100644 --- a/HISTORY +++ b/HISTORY @@ -9,6 +9,7 @@ SnapRAID HISTORY to remove the warning. * In fixing, if a file cannot be written for missing permission, an error is reported only if a write is effectively required. +* Ignores any symbolic links. They are not backuped. 1.3 2011/5 ========== diff --git a/mingw.c b/mingw.c index d70ace4d..00776ab8 100644 --- a/mingw.c +++ b/mingw.c @@ -121,10 +121,16 @@ static void windows_info2stat(const BY_HANDLE_FILE_INFORMATION* info, struct win */ static void windows_finddata2stat(const WIN32_FIND_DATAW* 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 | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_REPARSE_POINT)) != 0) { + } else if ((info->dwFileAttributes & ( + FILE_ATTRIBUTE_SYSTEM /* System files */ + | FILE_ATTRIBUTE_HIDDEN /* Hidden files */ + | FILE_ATTRIBUTE_TEMPORARY /* Files going to be deleted on close */ + | FILE_ATTRIBUTE_OFFLINE + | FILE_ATTRIBUTE_REPARSE_POINT /* Symbolic links */ + )) != 0) { st->st_mode = S_IFCHR; } else if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { st->st_mode = S_IFDIR; @@ -214,7 +220,7 @@ int windows_fstat(int fd, struct windows_stat* st) return 0; } -int windows_stat(const char* file, struct windows_stat* st) +int windows_lstat(const char* file, struct windows_stat* st) { HANDLE h; WIN32_FIND_DATAW data; @@ -245,12 +251,18 @@ int windows_mkdir(const char* file) return _wmkdir(u8tou16(file)); } -int stat_inode(const char* file, struct windows_stat* st) +int lstat_inode(const char* file, struct windows_stat* st) { BY_HANDLE_FILE_INFORMATION info; HANDLE h; - h = CreateFileW(u8tou16(file), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + /* + * Open the handle of the file. + * + * Use FILE_FLAG_BACKUP_SEMANTICS to open directories and to override the file security checks. + * Use FILE_FLAG_OPEN_REPARSE_POINT to open symbolic links and not the their target. + */ + h = CreateFileW(u8tou16(file), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0); if (h == INVALID_HANDLE_VALUE) { windows_errno(GetLastError()); return -1; diff --git a/mingw.h b/mingw.h index bfb1cd32..be84512e 100644 --- a/mingw.h +++ b/mingw.h @@ -32,6 +32,7 @@ #define fopen windows_fopen #define open windows_open #define stat windows_stat +#define lstat windows_lstat #define access windows_access #define off_t off64_t #define lseek lseek64 @@ -67,7 +68,7 @@ int windows_fstat(int fd, struct windows_stat* st); /** * Like the C stat() but without inode information. */ -int windows_stat(const char* file, struct windows_stat* st); +int windows_lstat(const char* file, struct windows_stat* st); /** * Like the C access(). @@ -80,12 +81,12 @@ int windows_access(const char* file, int mode); int windows_mkdir(const char* file); /** - * Like the C stat() with inode information. + * Like the C lstat() with inode information. * It doesn't work for all kind of files and directories. For example "\System Volume Information" cannot be opened. - * Note that instead stat() works for all the files. + * Note that instead lstat() works for all the files. */ -#define HAVE_STAT_INODE 1 -int stat_inode(const char* file, struct windows_stat* st); +#define HAVE_LSTAT_INODE 1 +int lstat_inode(const char* file, struct windows_stat* st); /** * Like the C ftruncate(). diff --git a/scan.c b/scan.c index 7f06d06a..0cd7d1d0 100644 --- a/scan.c +++ b/scan.c @@ -258,9 +258,9 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, s continue; } -#if HAVE_STAT_INODE +#if HAVE_LSTAT_INODE /* get inode info about the file, Windows needs an additional step */ - if (stat_inode(path_next, &st) != 0) { + if (lstat_inode(path_next, &st) != 0) { fprintf(stderr, "Error in stat_inode file '%s'. %s.\n", path_next, strerror(errno)); exit(EXIT_FAILURE); }