Made the filename arg-parsing code skip args that have excluded path
authorWayne Davison <wayned@samba.org>
Sat, 22 Mar 2008 22:29:34 +0000 (15:29 -0700)
committerWayne Davison <wayned@samba.org>
Sat, 22 Mar 2008 22:33:18 +0000 (15:33 -0700)
components, returning the same errors that would occur if the path
elements didn't actually exist.  The glob_match() code was also
changed to no longer truncate an arg with an excluded path element
(it just omits excluded items from glob matching).

flist.c
util.c

diff --git a/flist.c b/flist.c
index dce55c7..0a8ace9 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -242,6 +242,32 @@ static inline int is_daemon_excluded(const char *fname, int is_dir)
        return 0;
 }
 
        return 0;
 }
 
+static inline int path_is_daemon_excluded(char *path, int ignore_filename)
+{
+       if (daemon_filter_list.head && path) {
+               char *slash = path;
+
+               while ((slash = strchr(slash+1, '/')) != NULL) {
+                       int ret;
+                       *slash = '\0';
+                       ret = check_filter(&daemon_filter_list, path, 1);
+                       *slash = '/';
+                       if (ret < 0) {
+                               errno = ENOENT;
+                               return 1;
+                       }
+               }
+
+               if (!ignore_filename
+                && check_filter(&daemon_filter_list, path, 1) < 0) {
+                       errno = ENOENT;
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 /* This function is used to check if a file should be included/excluded
  * from the list of files based on its name and type etc.  The value of
  * filter_level is set to either SERVER_FILTERS or ALL_FILTERS. */
 /* This function is used to check if a file should be included/excluded
  * from the list of files based on its name and type etc.  The value of
  * filter_level is set to either SERVER_FILTERS or ALL_FILTERS. */
@@ -1948,6 +1974,12 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
 
                dirlen = dir ? strlen(dir) : 0;
                if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
 
                dirlen = dir ? strlen(dir) : 0;
                if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
+                       if (path_is_daemon_excluded(dir, 0)) {
+                               io_error |= IOERR_GENERAL;
+                               rsyserr(FERROR, errno, "push_dir %s failed in %s",
+                                       full_fname(dir), curr_dir);
+                               continue;
+                       }
                        if (!push_pathname(dir ? strdup(dir) : NULL, dirlen))
                                continue;
                        lastdir = pathname;
                        if (!push_pathname(dir ? strdup(dir) : NULL, dirlen))
                                continue;
                        lastdir = pathname;
@@ -1959,7 +1991,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
                        memmove(fbuf, fn, len + 1);
 
                if (link_stat(fbuf, &st, copy_dirlinks || name_type != NORMAL_NAME) != 0
                        memmove(fbuf, fn, len + 1);
 
                if (link_stat(fbuf, &st, copy_dirlinks || name_type != NORMAL_NAME) != 0
-                || is_daemon_excluded(fbuf, S_ISDIR(st.st_mode) != 0)) {
+                || is_daemon_excluded(fbuf, S_ISDIR(st.st_mode) != 0)
+                || (relative_paths && path_is_daemon_excluded(fbuf, 1))) {
                        io_error |= IOERR_GENERAL;
                        rsyserr(FERROR_XFER, errno, "link_stat %s failed",
                                full_fname(fbuf));
                        io_error |= IOERR_GENERAL;
                        rsyserr(FERROR_XFER, errno, "link_stat %s failed",
                                full_fname(fbuf));
diff --git a/util.c b/util.c
index a4a08e7..6f5bfc5 100644 (file)
--- a/util.c
+++ b/util.c
@@ -586,22 +586,15 @@ static inline void call_glob_match(const char *name, int len, int from_glob,
                STRUCT_STAT st;
                int is_dir;
 
                STRUCT_STAT st;
                int is_dir;
 
-               if (do_stat(glob.arg_buf, &st) != 0) {
-                       if (from_glob)
-                               return;
-                       is_dir = 0;
-               } else {
-                       is_dir = S_ISDIR(st.st_mode) != 0;
-                       if (arg && !is_dir)
-                               return;
-               }
+               if (do_stat(glob.arg_buf, &st) != 0)
+                       return;
+               is_dir = S_ISDIR(st.st_mode) != 0;
+               if (arg && !is_dir)
+                       return;
 
                if (daemon_filter_list.head
 
                if (daemon_filter_list.head
-                && check_filter(&daemon_filter_list, use_buf, is_dir) < 0) {
-                       if (from_glob)
-                               return;
-                       arg = NULL;
-               }
+                && check_filter(&daemon_filter_list, use_buf, is_dir) < 0)
+                       return;
        }
 
        if (arg) {
        }
 
        if (arg) {