{
static time_t modtime;
static mode_t mode;
+#ifdef SUPPORT_HARD_LINKS
static int64 dev;
+#endif
static dev_t rdev;
static uint32 rdev_major;
static uid_t uid;
#endif
f_name(file, fname);
- xflags = file->flags & FLAG_TOP_DIR; /* FLAG_TOP_DIR == XMIT_TOP_DIR */
+ /* Initialize starting value of xflags. */
+ if (protocol_version >= 30 && S_ISDIR(file->mode)) {
+ if (file->flags & FLAG_CONTENT_DIR)
+ xflags = file->flags & FLAG_TOP_DIR;
+ else if (file->flags & FLAG_IMPLIED_DIR)
+ xflags = XMIT_TOP_DIR | XMIT_NO_CONTENT_DIR;
+ else
+ xflags = XMIT_NO_CONTENT_DIR;
+ } else
+ xflags = file->flags & FLAG_TOP_DIR; /* FLAG_TOP_DIR == XMIT_TOP_DIR */
if (file->mode == mode)
xflags |= XMIT_SAME_MODE;
else
mode = file->mode;
- if (protocol_version >= 30 && S_ISDIR(mode) && !(file->flags & FLAG_XFER_DIR))
- xflags |= XMIT_NON_XFER_DIR;
-
if ((preserve_devices && IS_DEVICE(mode))
|| (preserve_specials && IS_SPECIAL(mode))) {
if (protocol_version < 28) {
{
static int64 modtime;
static mode_t mode;
+#ifdef SUPPORT_HARD_LINKS
static int64 dev;
+#endif
static dev_t rdev;
static uint32 rdev_major;
static uid_t uid;
if (S_ISDIR(mode)) {
if (basename_len == 1+1 && *basename == '.') /* +1 for '\0' */
F_DEPTH(file)--;
- if (xflags & XMIT_TOP_DIR) {
+ if (protocol_version >= 30) {
+ if (!(xflags & XMIT_NO_CONTENT_DIR)) {
+ if (xflags & XMIT_TOP_DIR)
+ file->flags |= FLAG_TOP_DIR;
+ file->flags |= FLAG_CONTENT_DIR;
+ } else if (xflags & XMIT_TOP_DIR)
+ file->flags |= FLAG_IMPLIED_DIR;
+ } else if (xflags & XMIT_TOP_DIR) {
in_del_hier = recurse;
del_hier_name_len = F_DEPTH(file) == 0 ? 0 : l1 + l2;
if (relative_paths && del_hier_name_len > 2
&& lastname[del_hier_name_len-1] == '.'
&& lastname[del_hier_name_len-2] == '/')
del_hier_name_len -= 2;
- file->flags |= FLAG_TOP_DIR | FLAG_XFER_DIR;
- } else if (protocol_version >= 30) {
- if (!(xflags & XMIT_NON_XFER_DIR))
- file->flags |= FLAG_XFER_DIR;
+ file->flags |= FLAG_TOP_DIR | FLAG_CONTENT_DIR;
} else if (in_del_hier) {
if (!relative_paths || !del_hier_name_len
|| (l1 >= del_hier_name_len
&& lastname[del_hier_name_len] == '/'))
- file->flags |= FLAG_XFER_DIR;
+ file->flags |= FLAG_CONTENT_DIR;
else
in_del_hier = 0;
}
/* -x only affects dirs because we need to avoid recursing
* into a mount-point directory, not to avoid copying a
* symlinked file if -L (or similar) was specified. */
- if (one_file_system && flags & FLAG_XFER_DIR) {
+ if (one_file_system && flags & FLAG_CONTENT_DIR) {
if (flags & FLAG_TOP_DIR)
filesystem_dev = st.st_dev;
else if (st.st_dev != filesystem_dev) {
if (one_file_system > 1) {
- if (verbose > 2) {
+ if (verbose > 1) {
rprintf(FINFO,
- "skipping mount-point dir %s\n",
- thisname);
+ "[%s] skipping mount-point dir %s\n",
+ who_am_i(), thisname);
}
return NULL;
}
}
}
} else
- flags &= ~FLAG_XFER_DIR;
+ flags &= ~FLAG_CONTENT_DIR;
if (is_excluded(thisname, S_ISDIR(st.st_mode) != 0, filter_level)) {
if (ignore_perishable)
{
struct file_struct *file;
#if defined SUPPORT_ACLS || defined SUPPORT_XATTRS
- statx sx;
+ stat_x sx;
#endif
file = make_file(fname, flist, stp, flags, filter_level);
dir_flist->files[dir_flist->used++] = file;
dir_cnt--;
- if (file->flags & FLAG_MOUNT_DIR)
- continue;
-
if (dp)
DIR_NEXT_SIBLING(dp) = dir_flist->used - 1;
else if (parent_dp)
char *slash;
int len, need_new_dir;
- flags &= ~FLAG_XFER_DIR;
+ flags = (flags | FLAG_IMPLIED_DIR) & ~(FLAG_TOP_DIR | FLAG_CONTENT_DIR);
if (inc_recurse) {
if (lastpath_struct && F_PATHNAME(lastpath_struct) == pathname
{
char fbuf[MAXPATHLEN];
item_list *relname_list;
- int len, dlen, flags = FLAG_DIVERT_DIRS | FLAG_XFER_DIR;
+ int len, dlen, flags = FLAG_DIVERT_DIRS | FLAG_CONTENT_DIR;
size_t j;
f_name(file, fbuf);
change_local_filter_dir(fbuf, dlen, send_dir_depth);
- if (file->flags & FLAG_XFER_DIR)
+ if (BITS_SETnUNSET(file->flags, FLAG_CONTENT_DIR, FLAG_MOUNT_DIR))
send_directory(f, flist, fbuf, dlen, flags);
if (!relative_paths)
full_fname(fbuf));
continue;
}
- send_file_name(f, flist, fbuf, &st,
- recurse || xfer_dirs ? FLAG_TOP_DIR | flags : flags,
- ALL_FILTERS);
- } else {
- send_file_name(f, flist, fbuf, NULL,
- recurse ? FLAG_TOP_DIR | flags : flags,
- ALL_FILTERS);
- }
+ send_file_name(f, flist, fbuf, &st, FLAG_TOP_DIR | flags, ALL_FILTERS);
+ } else
+ send_file_name(f, flist, fbuf, NULL, FLAG_TOP_DIR | flags, ALL_FILTERS);
}
free(relname_list);
send_dir_ndx = dir_ndx;
file = dir_flist->sorted[dir_ndx];
/* Try to avoid some duplicate scanning of identical dirs. */
- if (F_PATHNAME(file) == pathname && prev_flags & FLAG_XFER_DIR)
- file->flags &= ~FLAG_XFER_DIR;
+ if (F_PATHNAME(file) == pathname && prev_flags & FLAG_CONTENT_DIR)
+ file->flags &= ~FLAG_CONTENT_DIR;
send1extra(f, file, flist);
prev_flags = file->flags;
dp = F_DIR_NODE_P(file);
struct timeval start_tv, end_tv;
int64 start_write;
int use_ff_fd = 0;
- int flags, disable_buffering;
+ int disable_buffering;
+ 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 (relative_paths && protocol_version >= 30)
+ implied_dirs = 1; /* We send flagged implied dirs */
+
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && protocol_version >= 30 && !cur_flist)
init_hard_links();
flist = cur_flist = flist_new(0, "send_file_list");
if (inc_recurse) {
dir_flist = flist_new(FLIST_TEMP, "send_file_list");
- flags = FLAG_DIVERT_DIRS | FLAG_XFER_DIR;
- } else {
+ flags |= FLAG_DIVERT_DIRS;
+ } else
dir_flist = cur_flist;
- flags = FLAG_XFER_DIR;
- }
disable_buffering = io_start_buffering_out(f);
if (filesfrom_fd >= 0) {
} else
break;
}
- if (len == 1 && fn[0] == '/')
- fn[len++] = '.';
fn[len] = '\0';
+ if (len == 1) {
+ if (fn[0] == '/') {
+ fn = "/.";
+ len = 2;
+ } else if (fn[0] == '.')
+ is_dot_dir = 1;
+ }
/* Reject a ".." dir in the active part of the path. */
for (p = fn; (p = strstr(p, "..")) != NULL; p += 2) {
if ((p[2] == '/' || p[2] == '\0')
if (!*fn) {
len = 1;
fn = ".";
+ is_dot_dir = 1;
}
dirlen = dir ? strlen(dir) : 0;
if (recurse || (xfer_dirs && is_dot_dir)) {
struct file_struct *file;
- int top_flags = FLAG_TOP_DIR | flags;
+ int top_flags = FLAG_TOP_DIR | FLAG_CONTENT_DIR | flags;
file = send_file_name(f, flist, fbuf, &st,
top_flags, ALL_FILTERS);
if (file && !inc_recurse)
else {
if (am_sender)
file->flags |= FLAG_DUPLICATE;
+ else { /* Make sure we merge our vital flags. */
+ fp->flags |= file->flags & (FLAG_TOP_DIR|FLAG_CONTENT_DIR);
+ fp->flags &= file->flags | ~FLAG_IMPLIED_DIR;
+ }
keep = j, drop = i;
}
} else
"removing duplicate name %s from file list (%d)\n",
f_name(file, fbuf), drop + flist->ndx_start);
}
- /* Make sure we don't lose track of a user-specified
- * top directory. */
- flist->sorted[keep]->flags |= flist->sorted[drop]->flags
- & (FLAG_TOP_DIR|FLAG_XFER_DIR);
-
clear_file(flist->sorted[drop]);
}