X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/40e383765a972e4cbfc4d0091f472542e04e453c..ff0284ddc4bd7a1942033665e3d1dfa1ac4df4ff:/flist.c diff --git a/flist.c b/flist.c index aef150d8..6af7bfa2 100644 --- a/flist.c +++ b/flist.c @@ -864,7 +864,12 @@ static struct file_struct *recv_file_entry(struct file_list *flist, 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_NON_XFER_DIR)) + file->flags |= FLAG_XFER_DIR; + if (xflags & XMIT_TOP_DIR) + file->flags |= FLAG_TOP_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 @@ -872,9 +877,6 @@ static struct file_struct *recv_file_entry(struct file_list *flist, && 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; } else if (in_del_hier) { if (!relative_paths || !del_hier_name_len || (l1 >= del_hier_name_len @@ -1049,10 +1051,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, 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; } @@ -1235,7 +1237,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, { 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); @@ -1399,9 +1401,6 @@ static void add_dirs_to_tree(int parent_ndx, struct file_list *from_flist, 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) @@ -1579,7 +1578,7 @@ static void send1extra(int f, struct file_struct *file, struct file_list *flist) change_local_filter_dir(fbuf, dlen, send_dir_depth); - if (file->flags & FLAG_XFER_DIR) + if (BITS_SETnUNSET(file->flags, FLAG_XFER_DIR, FLAG_MOUNT_DIR)) send_directory(f, flist, fbuf, dlen, flags); if (!relative_paths) @@ -1608,20 +1607,15 @@ static void send1extra(int f, struct file_struct *file, struct file_list *flist) if (is_dot_dir) { STRUCT_STAT st; - if (link_stat(fbuf, &st, copy_dirlinks) != 0) { + if (link_stat(fbuf, &st, 1) != 0) { io_error |= IOERR_GENERAL; rsyserr(FERROR, errno, "link_stat %s failed", 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); @@ -1743,7 +1737,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) 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_XFER_DIR : 0; int reading_remotely = filesfrom_host != NULL; int rl_flags = (reading_remotely ? 0 : RL_DUMP_COMMENTS) #ifdef ICONV_OPTION @@ -1768,11 +1763,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) 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) { @@ -1873,9 +1866,14 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) } 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') @@ -1891,6 +1889,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) if (!*fn) { len = 1; fn = "."; + is_dot_dir = 1; } dirlen = dir ? strlen(dir) : 0; @@ -1905,7 +1904,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) if (fn != fbuf) memmove(fbuf, fn, len + 1); - if (link_stat(fbuf, &st, copy_dirlinks) != 0) { + if (link_stat(fbuf, &st, copy_dirlinks || is_dot_dir) != 0) { io_error |= IOERR_GENERAL; rsyserr(FERROR, errno, "link_stat %s failed", full_fname(fbuf)); @@ -1940,7 +1939,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) 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_XFER_DIR | flags; file = send_file_name(f, flist, fbuf, &st, top_flags, ALL_FILTERS); if (file && !inc_recurse) @@ -2392,6 +2391,8 @@ static void clean_flist(struct file_list *flist, int strip_root) else { if (am_sender) file->flags |= FLAG_DUPLICATE; + else /* Make sure we don't lose vital flags. */ + fp->flags |= file->flags & (FLAG_TOP_DIR|FLAG_XFER_DIR); keep = j, drop = i; } } else @@ -2403,11 +2404,6 @@ static void clean_flist(struct file_list *flist, int strip_root) "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]); }