return 0;
}
-static inline int path_is_daemon_excluded(const char *path, int ignore_filename)
+static inline int path_is_daemon_excluded(char *path, int ignore_filename)
{
if (daemon_filter_list.head) {
- char *slash = (char*)path;
+ char *slash = path;
while ((slash = strchr(slash+1, '/')) != NULL) {
int ret;
static const char *pathname, *orig_dir;
static int pathname_len;
-
/* Make sure flist can hold at least flist->used + extra entries. */
static void flist_expand(struct file_list *flist, int extra)
{
flist->pool_boundary = ptr;
}
-int push_pathname(const char *dir, int len)
+/* Call this with EITHER (1) "file, NULL, 0" to chdir() to the file's
+ * F_PATHNAME(), or (2) "NULL, dir, dirlen" to chdir() to the supplied dir,
+ * with dir == NULL taken to be the starting directory, and dirlen < 0
+ * indicating that strdup(dir) should be called and then the -dirlen length
+ * value checked to ensure that it is not daemon-excluded. */
+int change_pathname(struct file_struct *file, const char *dir, int dirlen)
{
- if (dir == pathname)
- return 1;
+ if (dirlen < 0) {
+ char *cpy = strdup(dir);
+ if (*cpy != '/')
+ change_dir(orig_dir, CD_SKIP_CHDIR);
+ if (path_is_daemon_excluded(cpy, 0))
+ goto chdir_error;
+ dir = cpy;
+ dirlen = -dirlen;
+ } else {
+ if (file) {
+ if (pathname == F_PATHNAME(file))
+ return 1;
+ dir = F_PATHNAME(file);
+ if (dir)
+ dirlen = strlen(dir);
+ } else if (pathname == dir)
+ return 1;
+ if (dir && *dir != '/')
+ change_dir(orig_dir, CD_SKIP_CHDIR);
+ }
- if (!orig_dir)
- orig_dir = strdup(curr_dir);
+ pathname = dir;
+ pathname_len = dirlen;
- if (pathname && !pop_dir(orig_dir)) {
- rsyserr(FERROR, errno, "pop_dir %s failed",
- full_fname(orig_dir));
- exit_cleanup(RERR_FILESELECT);
- }
+ if (!dir)
+ dir = orig_dir;
- if (dir && (path_is_daemon_excluded(dir, 0) || !push_dir(dir, 0))) {
+ if (!change_dir(dir, CD_NORMAL)) {
+ chdir_error:
io_error |= IOERR_GENERAL;
- rsyserr(FERROR, errno, "push_dir %s failed", full_fname(dir));
+ rsyserr(FERROR, errno, "change_dir %s failed", full_fname(dir));
+ if (dir != orig_dir)
+ change_dir(orig_dir, CD_NORMAL);
+ pathname = NULL;
+ pathname_len = 0;
return 0;
}
- pathname = dir;
- pathname_len = len >= 0 ? len : dir ? (int)strlen(dir) : 0;
-
return 1;
}
const char *basename;
alloc_pool_t *pool;
STRUCT_STAT st;
- int excl_ret;
char *bp;
if (strlcpy(thisname, fname, sizeof thisname) >= sizeof thisname) {
return NULL;
}
- /* backup.c calls us with filter_level set to NO_FILTERS. */
if (filter_level == NO_FILTERS)
goto skip_filters;
} else
flags &= ~FLAG_CONTENT_DIR;
- if (S_ISDIR(st.st_mode)) {
- if (flags & FLAG_DOTDIR_NAME) {
- /* A "." fname (or "/." fname in relative mode) is
- * never excluded. No other trailing-dotdir names
- * are possible. */
- excl_ret = 0;
- } else
- excl_ret = is_excluded(thisname, 1, filter_level);
- } else
- excl_ret = is_excluded(thisname, 0, filter_level);
- if (excl_ret) {
+ if (is_excluded(thisname, S_ISDIR(st.st_mode) != 0, filter_level)) {
if (ignore_perishable)
non_perishable_cnt++;
return NULL;
f_name(file, fbuf);
dlen = strlen(fbuf);
- if (F_PATHNAME(file) != pathname) {
- if (!push_pathname(F_PATHNAME(file), -1))
- exit_cleanup(RERR_FILESELECT);
- }
+ if (!change_pathname(file, NULL, 0))
+ exit_cleanup(RERR_FILESELECT);
change_local_filter_dir(fbuf, dlen, send_dir_depth);
int64 start_write;
int use_ff_fd = 0;
int disable_buffering;
- int arg_flags, flags = recurse ? FLAG_CONTENT_DIR : 0;
+ int flags = recurse ? FLAG_CONTENT_DIR : 0;
int reading_remotely = filesfrom_host != NULL;
int rl_flags = (reading_remotely ? 0 : RL_DUMP_COMMENTS)
#ifdef ICONV_OPTION
start_write = stats.total_written;
gettimeofday(&start_tv, NULL);
+ if (!orig_dir)
+ orig_dir = strdup(curr_dir);
+
if (relative_paths && protocol_version >= 30)
implied_dirs = 1; /* We send flagged implied dirs */
disable_buffering = io_start_buffering_out(f);
if (filesfrom_fd >= 0) {
- if (argv[0] && !push_dir(argv[0], 0)) {
- rsyserr(FERROR_XFER, errno, "push_dir %s failed",
+ if (argv[0] && !change_dir(argv[0], CD_NORMAL)) {
+ rsyserr(FERROR_XFER, errno, "change_dir %s failed",
full_fname(argv[0]));
exit_cleanup(RERR_FILESELECT);
}
dirlen = dir ? strlen(dir) : 0;
if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
- if (!push_pathname(dir ? strdup(dir) : NULL, dirlen))
+ if (!change_pathname(NULL, dir, -dirlen))
continue;
lastdir = pathname;
lastdir_len = pathname_len;
- } else if (!push_pathname(lastdir, lastdir_len))
+ } else if (!change_pathname(NULL, lastdir, lastdir_len))
continue;
if (fn != fbuf)
continue;
}
+ /* A dot-dir should not be excluded! */
+ if (name_type != DOTDIR_NAME
+ && is_excluded(fbuf, S_ISDIR(st.st_mode) != 0, ALL_FILTERS))
+ continue;
+
if (S_ISDIR(st.st_mode) && !xfer_dirs) {
rprintf(FINFO, "skipping directory %s\n", fbuf);
continue;
if (one_file_system)
filesystem_dev = st.st_dev;
- arg_flags = name_type == DOTDIR_NAME ? FLAG_DOTDIR_NAME : 0;
-
if (recurse || (xfer_dirs && name_type != NORMAL_NAME)) {
struct file_struct *file;
- arg_flags |= FLAG_TOP_DIR | FLAG_CONTENT_DIR;
file = send_file_name(f, flist, fbuf, &st,
- arg_flags | flags, ALL_FILTERS);
+ FLAG_TOP_DIR | FLAG_CONTENT_DIR | flags,
+ NO_FILTERS);
if (!file)
continue;
if (inc_recurse) {
} else
send_if_directory(f, flist, file, fbuf, len, flags);
} else
- send_file_name(f, flist, fbuf, &st, arg_flags | flags, ALL_FILTERS);
+ send_file_name(f, flist, fbuf, &st, flags, NO_FILTERS);
}
gettimeofday(&end_tv, NULL);