summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2008-03-22 15:29:34 -0700
committerWayne Davison <wayned@samba.org>2008-03-22 15:33:18 -0700
commitb5daf5300fe83e2be5a9c0f3f981d52069189bfa (patch)
tree176483cce592b7b0a277c811c1034ef5553ce162
parentf5aeb6ff9b04432a84b5c79f5baac26be1f3f4e9 (diff)
downloadrsync-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.c35
-rw-r--r--util.c21
2 files changed, 41 insertions, 15 deletions
diff --git a/flist.c b/flist.c
index dce55c7b..0a8ace99 100644
--- a/flist.c
+++ b/flist.c
@@ -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));
diff --git a/util.c b/util.c
index a4a08e7c..6f5bfc55 100644
--- 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;
- 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) {