mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-10-22 22:04:15 -04:00
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).
This commit is contained in:
1 parent
f5aeb6ff9b
commit
b5daf5300f
2 files changed
+41
-15
No files matched your search
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user