diff options
author | Wayne Davison <wayned@samba.org> | 2008-03-22 15:29:34 -0700 |
---|---|---|
committer | Wayne Davison <wayned@samba.org> | 2008-03-22 15:33:18 -0700 |
commit | b5daf5300fe83e2be5a9c0f3f981d52069189bfa (patch) | |
tree | 176483cce592b7b0a277c811c1034ef5553ce162 | |
parent | f5aeb6ff9b04432a84b5c79f5baac26be1f3f4e9 (diff) | |
download | rsync-b5daf5300fe83e2be5a9c0f3f981d52069189bfa.tar.gz |
Made the filename arg-parsing code skip args that have excluded path
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).
-rw-r--r-- | flist.c | 35 | ||||
-rw-r--r-- | util.c | 21 |
2 files changed, 41 insertions, 15 deletions
@@ -242,6 +242,32 @@ static inline int is_daemon_excluded(const char *fname, int is_dir) 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. */ @@ -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) { + 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; @@ -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 - || 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)); @@ -586,22 +586,15 @@ static inline void call_glob_match(const char *name, int len, int from_glob, 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 - && 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) { |