extern int file_extra_cnt;
@@ -379,7 +380,7 @@ int push_pathname(const char *dir, int len)
- static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ndx)
+ static void send_file_entry(int f, const char *fname, struct file_struct *file, int ndx, int first_ndx)
{
- static time_t modtime;
+ static time_t modtime, atime;
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
-@@ -487,6 +488,13 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
+@@ -457,6 +458,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
xflags |= XMIT_SAME_TIME;
else
modtime = file->modtime;
#ifdef SUPPORT_HARD_LINKS
if (tmp_dev != 0) {
-@@ -559,6 +567,8 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
+@@ -529,6 +537,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
}
if (!(xflags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
if (protocol_version < 30)
write_int(f, uid);
-@@ -645,7 +655,7 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
+@@ -615,7 +625,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
static struct file_struct *recv_file_entry(struct file_list *flist,
int xflags, int f)
{
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
-@@ -778,6 +788,16 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -749,6 +759,16 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
}
if (!(xflags & XMIT_SAME_MODE))
mode = from_wire_mode(read_int(f));
if (chmod_modes && !S_ISLNK(mode))
mode = tweak_mode(mode, chmod_modes);
-@@ -907,6 +927,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -878,6 +898,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
F_GROUP(file) = gid;
file->flags |= gid_flags;
}
if (unsort_ndx)
F_NDX(file) = flist->used + flist->ndx_start;
-@@ -1244,6 +1266,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1215,6 +1237,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
F_OWNER(file) = st.st_uid;
if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
F_GROUP(file) = st.st_gid;
extern int verbose;
extern int dry_run;
-@@ -642,6 +643,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -645,6 +646,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
: iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
iflags |= ITEM_REPORT_TIME;
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
if (S_ISLNK(file->mode)) {
;
-@@ -999,6 +1003,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -1002,6 +1006,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
if (link_dest) {
if (!hard_link_one(file, fname, cmpbuf, 1))
goto try_a_copy;
if (preserve_hard_links && F_IS_HLINKED(file))
finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j);
if (!maybe_ATTRS_REPORT && (verbose > 1 || stdout_format_has_i > 1)) {
-@@ -1184,6 +1190,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+@@ -1187,6 +1193,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
static void list_file_entry(struct file_struct *f)
{
char permbuf[PERMSTRING_SIZE];
double len;
if (!F_IS_ACTIVE(f)) {
-@@ -1198,14 +1205,16 @@ static void list_file_entry(struct file_struct *f)
+@@ -1201,14 +1208,16 @@ static void list_file_entry(struct file_struct *f)
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
f_name(f, NULL));
}
}
-@@ -2009,7 +2018,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
+@@ -2017,7 +2026,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
STRUCT_STAT st;
if (link_stat(fname, &st, 0) == 0
&& cmp_time(st.st_mtime, file->modtime) != 0)
int push_pathname(const char *dir, int len)
{
if (dir == pathname)
-@@ -1039,7 +1284,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1010,7 +1255,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
STRUCT_STAT *stp, int flags, int filter_level)
{
static char *lastdir;
struct file_struct *file;
char thisname[MAXPATHLEN];
char linkname[MAXPATHLEN];
-@@ -1178,9 +1423,16 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1149,9 +1394,16 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
memcpy(lastdir, thisname, len);
lastdir[len] = '\0';
lastdir_len = len;
basename_len = strlen(basename) + 1; /* count the '\0' */
#ifdef SUPPORT_LINKS
-@@ -1253,14 +1505,18 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1224,14 +1476,18 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
memcpy(bp + basename_len, linkname, linkname_len);
#endif
/* This code is only used by the receiver when it is building
* a list of files for a delete pass. */
if (keep_dirlinks && linkname_len && flist) {
-@@ -2131,7 +2387,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2147,7 +2403,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
* file-list to check if this is a 1-file xfer. */
send_extra_file_list(f, 1);
}
return flist;
}
-@@ -2233,7 +2490,7 @@ struct file_list *recv_file_list(int f)
+@@ -2249,7 +2506,7 @@ struct file_list *recv_file_list(int f)
else if (f >= 0)
recv_id_list(f, flist);
if (protocol_version < 30) {
/* Recv the io_error flag */
-@@ -2431,7 +2688,7 @@ void flist_free(struct file_list *flist)
+@@ -2447,7 +2704,7 @@ void flist_free(struct file_list *flist)
/* This routine ensures we don't have any duplicate names in our file list.
* duplicate names can cause corruption because of the pipelining. */
{
char fbuf[MAXPATHLEN];
int i, prev_i;
-@@ -2482,7 +2739,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2498,7 +2755,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
/* If one is a dir and the other is not, we want to
* keep the dir because it might have contents in the
* list. Otherwise keep the first one. */
struct file_struct *fp = flist->sorted[j];
if (!S_ISDIR(fp->mode))
keep = i, drop = j;
-@@ -2498,8 +2755,8 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2514,8 +2771,8 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
} else
keep = j, drop = i;
rprintf(FINFO,
"removing duplicate name %s from file list (%d)\n",
f_name(file, fbuf), drop + flist->ndx_start);
-@@ -2521,7 +2778,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
+@@ -2537,7 +2794,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
}
flist->high = prev_i;
extern int remove_source_files;
extern int delay_updates;
extern int update_only;
-@@ -706,7 +707,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -709,7 +710,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
/* Perform our quick-check heuristic for determining if a file is unchanged. */
{
if (st->st_size != F_LENGTH(file))
return 0;
-@@ -715,7 +716,10 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+@@ -718,7 +719,10 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
of the file time to determine whether to sync */
if (always_checksum > 0 && S_ISREG(st->st_mode)) {
char sum[MAX_DIGEST_LEN];
return memcmp(sum, F_SUM(file), checksum_len) == 0;
}
-@@ -969,7 +973,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -972,7 +976,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
match_level = 1;
/* FALL THROUGH */
case 1:
continue;
best_match = j;
match_level = 2;
-@@ -1242,7 +1246,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1245,7 +1249,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
* --ignore-non-existing, daemon exclude, or mkdir failure. */
static struct file_struct *skip_dir = NULL;
static struct file_list *fuzzy_dirlist = NULL;
struct file_struct *fuzzy_file = NULL;
int fd = -1, f_copy = -1;
stat_x sx, real_sx;
-@@ -1331,8 +1335,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1334,8 +1338,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
flist_free(fuzzy_dirlist);
fuzzy_dirlist = NULL;
}
#ifdef SUPPORT_ACLS
if (!preserve_perms)
dflt_perms = default_perms_for_dir(dn);
-@@ -1340,10 +1344,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1343,10 +1347,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
}
parent_dirname = dn;
}
statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir);
-@@ -1768,7 +1777,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1776,7 +1785,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
;
else if (fnamecmp_type == FNAMECMP_FUZZY)
;
diff --git a/hlink.c b/hlink.c
--- a/hlink.c
+++ b/hlink.c
-@@ -388,7 +388,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
+@@ -384,7 +384,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
}
break;
}
}
int push_pathname(const char *dir, int len)
-@@ -1378,6 +1589,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1349,6 +1560,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
if (is_excluded(thisname, S_ISDIR(st.st_mode) != 0, filter_level)) {
if (ignore_perishable)
non_perishable_cnt++;
return NULL;
}
-@@ -1424,13 +1637,13 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1395,13 +1608,13 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
lastdir[len] = '\0';
lastdir_len = len;
if (checksum_files && am_sender && flist)
}
}
basename_len = strlen(basename) + 1; /* count the '\0' */
-@@ -1512,7 +1725,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1483,7 +1696,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
if (always_checksum && am_sender && S_ISREG(st.st_mode)) {
if (flist && checksum_files)
else
file_checksum(thisname, st.st_size, tmp_sum);
}
-@@ -1804,6 +2017,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
+@@ -1809,6 +2022,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
closedir(d);
if (f >= 0 && recurse && !divert_dirs) {
int i, end = flist->used - 1;
/* send_if_directory() bumps flist->used, so use "end". */
-@@ -2389,6 +2605,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2405,6 +2621,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
}
} else
flist_eof = 1;
static const char *solo_file = NULL;
/* For calling delete_item() and delete_dir_contents(). */
-@@ -717,7 +718,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot
+@@ -720,7 +721,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot
if (always_checksum > 0 && S_ISREG(st->st_mode)) {
char sum[MAX_DIGEST_LEN];
if (checksum_files && slot >= 0)
else
file_checksum(fn, st->st_size, sum);
return memcmp(sum, F_SUM(file), checksum_len) == 0;
-@@ -1350,7 +1351,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1353,7 +1354,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, 1);
}
if (checksum_files) {
}
need_new_dirscan = 0;
}
-@@ -1488,9 +1490,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
- DEV_MINOR(devp) = minor(real_sx.st.st_dev);
- }
+@@ -1499,6 +1501,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+ change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
+
}
-- else if (delete_during && f_out != -1 && !phase
-- && BITS_SETnUNSET(file->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR))
-- delete_in_dir(fname, file, &real_sx.st.st_dev);
-+ else if (file->flags & FLAG_CONTENT_DIR && f_out != -1) {
-+ if (delete_during && !phase && !(file->flags & FLAG_MISSING_DIR))
-+ delete_in_dir(fname, file, &real_sx.st.st_dev);
-+ upcoming_whole_dir = 1;
-+ } else
-+ upcoming_whole_dir = 0;
++ upcoming_whole_dir = file->flags & FLAG_CONTENT_DIR && f_out != -1 ? 1 : 0;
goto cleanup;
}
-@@ -1783,6 +1788,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1791,6 +1794,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
handle_partial_dir(partialptr, PDIR_DELETE);
}
set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
if (itemizing)
itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL);
#ifdef SUPPORT_HARD_LINKS
-@@ -2195,6 +2202,7 @@ void generate_files(int f_out, const char *local_name)
- delete_in_dir(f_name(fp, fbuf), fp, &dirdev);
- }
+@@ -2205,6 +2210,7 @@ void generate_files(int f_out, const char *local_name)
+ } else
+ change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
}
+ upcoming_whole_dir = fp->flags & FLAG_CONTENT_DIR ? 1 : 0;
}
for (i = cur_flist->low; i <= cur_flist->high; i++) {
struct file_struct *file = cur_flist->sorted[i];
-@@ -2275,6 +2283,9 @@ void generate_files(int f_out, const char *local_name)
+@@ -2285,6 +2291,9 @@ void generate_files(int f_out, const char *local_name)
wait_for_receiver();
}
diff --git a/flist.c b/flist.c
--- a/flist.c
+++ b/flist.c
-@@ -1253,7 +1253,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1224,7 +1224,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
memcpy(bp + basename_len, linkname, linkname_len);
#endif
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -715,7 +715,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+@@ -718,7 +718,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
of the file time to determine whether to sync */
if (always_checksum > 0 && S_ISREG(st->st_mode)) {
char sum[MAX_DIGEST_LEN];
extern int preserve_specials;
extern int preserve_hard_links;
extern int preserve_executability;
-@@ -1663,7 +1664,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1671,7 +1672,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
extern int file_extra_cnt;
@@ -380,7 +381,7 @@ int push_pathname(const char *dir, int len)
- static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ndx)
+ static void send_file_entry(int f, const char *fname, struct file_struct *file, int ndx, int first_ndx)
{
- static time_t modtime;
+ static time_t modtime, crtime;
static mode_t mode;
#ifdef SUPPORT_FILEFLAGS
static uint32 fileflags;
-@@ -499,6 +500,13 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
+@@ -469,6 +470,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
xflags |= XMIT_SAME_TIME;
else
modtime = file->modtime;
#ifdef SUPPORT_HARD_LINKS
if (tmp_dev != 0) {
-@@ -569,6 +577,8 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
+@@ -539,6 +547,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
else
write_int(f, modtime);
}
if (!(xflags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
#ifdef SUPPORT_FILEFLAGS
-@@ -661,7 +671,7 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
+@@ -631,7 +641,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
static struct file_struct *recv_file_entry(struct file_list *flist,
int xflags, int f)
{
static mode_t mode;
#ifdef SUPPORT_FILEFLAGS
static uint32 fileflags;
-@@ -795,6 +805,19 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -766,6 +776,19 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
} else
modtime = read_int(f);
}
if (!(xflags & XMIT_SAME_MODE))
mode = from_wire_mode(read_int(f));
-@@ -934,6 +957,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -905,6 +928,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
F_GROUP(file) = gid;
file->flags |= gid_flags;
}
if (unsort_ndx)
F_NDX(file) = flist->used + flist->ndx_start;
-@@ -1275,6 +1300,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1246,6 +1271,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
F_OWNER(file) = st.st_uid;
if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
F_GROUP(file) = st.st_gid;
extern int preserve_hard_links;
extern int preserve_executability;
extern int preserve_fileflags;
-@@ -617,6 +619,13 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
+@@ -620,6 +622,13 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file))
return 0;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
if (!ACL_READY(*sxp))
-@@ -660,6 +669,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -663,6 +672,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
: iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
iflags |= ITEM_REPORT_TIME;
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
if (S_ISLNK(file->mode)) {
;
-@@ -1207,6 +1222,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+@@ -1210,6 +1225,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
static void list_file_entry(struct file_struct *f)
{
char permbuf[PERMSTRING_SIZE];
double len;
if (!F_IS_ACTIVE(f)) {
-@@ -1221,14 +1237,16 @@ static void list_file_entry(struct file_struct *f)
+@@ -1224,14 +1240,16 @@ static void list_file_entry(struct file_struct *f)
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
f_name(f, NULL));
}
}
-@@ -1320,6 +1338,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1323,6 +1341,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
return;
}
}
if (asprintf(&lp->debug_type, " [per-dir %s]", cp) < 0)
out_of_memory("add_rule");
ret->u.mergelist = lp;
-@@ -469,6 +471,14 @@ void *push_local_filters(const char *dir, unsigned int dirlen)
+@@ -470,6 +472,14 @@ void *push_local_filters(const char *dir, unsigned int dirlen)
set_filter_dir(dir, dirlen);
}
if (strlcpy(dirbuf + dirbuf_len, ex->pattern,
MAXPATHLEN - dirbuf_len) < MAXPATHLEN - dirbuf_len) {
parse_filter_file(lp, dirbuf, ex->match_flags,
-@@ -1029,6 +1039,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
+@@ -1030,6 +1040,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
char line[BIGPATHBUFLEN];
char *eob = line + sizeof line - 1;
int word_split = mflags & MATCHFLG_WORD_SPLIT;
if (!fname || !*fname)
return;
-@@ -1075,6 +1086,24 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
+@@ -1076,6 +1087,24 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
}
break;
}
if (word_split && isspace(ch))
break;
if (eol_nulls? !ch : (ch == '\n' || ch == '\r'))
-@@ -1084,13 +1113,15 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
+@@ -1085,13 +1114,15 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
else
overflow = 1;
}
extern int size_only;
extern OFF_T max_size;
extern OFF_T min_size;
-@@ -708,6 +709,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -711,6 +712,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
/* Perform our quick-check heuristic for determining if a file is unchanged. */
int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
{
diff = u_strcmp(fmid->basename, f->basename);
if (diff == 0) {
good_match = mid;
-@@ -1961,6 +1963,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1968,6 +1970,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
fnamecmp = partialptr;
fnamecmp_type = FNAMECMP_PARTIAL_DIR;
statret = 0;
static void send_directory(int f, struct file_list *flist,
char *fbuf, int len, int flags);
-@@ -2235,6 +2277,25 @@ struct file_list *recv_file_list(int f)
+@@ -2251,6 +2293,25 @@ struct file_list *recv_file_list(int f)
flist_sort_and_clean(flist, relative_paths);
flist_free(dirlist);
if (!save_uid_ndx) {
-@@ -568,9 +716,9 @@ static void do_delete_pass(void)
+@@ -571,9 +719,9 @@ static void do_delete_pass(void)
|| !S_ISDIR(st.st_mode))
continue;
if (do_progress && !am_server)
rprintf(FINFO, " \r");
-@@ -1210,6 +1358,7 @@ static void list_file_entry(struct file_struct *f)
+@@ -1213,6 +1361,7 @@ static void list_file_entry(struct file_struct *f)
}
}
static int phase = 0;
static int dflt_perms;
-@@ -1480,8 +1629,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
- }
+@@ -1484,9 +1633,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
}
else if (delete_during && f_out != -1 && !phase
-- && BITS_SETnUNSET(file->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR))
-- delete_in_dir(fname, file, &real_sx.st.st_dev);
-+ && BITS_SETnUNSET(file->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR)) {
-+ if (detect_renamed && real_ret != 0)
-+ unexplored_dirs++;
-+ delete_in_dir(fname, file, &real_sx.st.st_dev,
-+ delete_during < 0 ? DEL_NO_DELETIONS : 0);
-+ }
- goto cleanup;
- }
+ && !(file->flags & FLAG_MISSING_DIR)) {
+- if (file->flags & FLAG_CONTENT_DIR)
+- delete_in_dir(fname, file, &real_sx.st.st_dev);
+- else
++ if (file->flags & FLAG_CONTENT_DIR) {
++ if (detect_renamed && real_ret != 0)
++ unexplored_dirs++;
++ delete_in_dir(fname, file, &real_sx.st.st_dev,
++ delete_during < 0 ? DEL_NO_DELETIONS : 0);
++ } else
+ change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
-@@ -1757,8 +1910,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+ }
+@@ -1765,8 +1917,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
#endif
rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s",
full_fname(fname));
goto cleanup;
-@@ -2135,6 +2294,12 @@ void generate_files(int f_out, const char *local_name)
+@@ -2143,6 +2301,12 @@ void generate_files(int f_out, const char *local_name)
if (verbose > 2)
rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid());
if (delete_before && !solo_file && cur_flist->used > 0)
do_delete_pass();
if (delete_during == 2) {
-@@ -2145,7 +2310,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2153,7 +2317,7 @@ void generate_files(int f_out, const char *local_name)
}
do_progress = 0;
whole_file = 0;
if (verbose >= 2) {
rprintf(FINFO, "delta-transmission %s\n",
-@@ -2183,7 +2348,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2192,7 +2356,7 @@ void generate_files(int f_out, const char *local_name)
dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
} else
dirdev = MAKEDEV(0, 0);
-- delete_in_dir(f_name(fp, fbuf), fp, &dirdev);
-+ delete_in_dir(f_name(fp, fbuf), fp, &dirdev, 0);
- }
+- delete_in_dir(fbuf, fp, &dirdev);
++ delete_in_dir(fbuf, fp, &dirdev, 0);
+ } else
+ change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
}
- }
-@@ -2226,7 +2391,21 @@ void generate_files(int f_out, const char *local_name)
+@@ -2236,7 +2400,21 @@ void generate_files(int f_out, const char *local_name)
} while ((cur_flist = cur_flist->next) != NULL);
if (delete_during)
extern int ignore_existing;
extern int ignore_non_existing;
extern int inplace;
-@@ -1698,6 +1699,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1706,6 +1707,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
fnamecmp = fname;
fnamecmp_type = FNAMECMP_FNAME;
-@@ -2045,6 +2053,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
+@@ -2053,6 +2061,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
ignore_existing = -ignore_existing;
ignore_non_existing = -ignore_non_existing;
update_only = -update_only;
always_checksum = -always_checksum;
size_only = -size_only;
append_mode = -append_mode;
-@@ -2070,6 +2079,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
+@@ -2078,6 +2087,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
ignore_existing = -ignore_existing;
ignore_non_existing = -ignore_non_existing;
update_only = -update_only;
extern int uid_ndx;
extern int gid_ndx;
extern int eol_nulls;
-@@ -381,6 +382,9 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
+@@ -381,6 +382,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
{
static time_t modtime;
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
#endif
-@@ -440,6 +444,14 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
+@@ -410,6 +414,14 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
xflags |= XMIT_SAME_MODE;
else
mode = file->mode;
if ((preserve_devices && IS_DEVICE(mode))
|| (preserve_specials && IS_SPECIAL(mode))) {
-@@ -559,6 +571,10 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
+@@ -529,6 +541,10 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
}
if (!(xflags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
if (protocol_version < 30)
write_int(f, uid);
-@@ -647,6 +663,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -617,6 +633,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
{
static int64 modtime;
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
#endif
-@@ -781,6 +800,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -752,6 +771,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
if (chmod_modes && !S_ISLNK(mode))
mode = tweak_mode(mode, chmod_modes);
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
if (protocol_version < 30)
-@@ -901,6 +924,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -872,6 +895,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
OPT_EXTRA(file, 0)->unum = (uint32)(file_length >> 32);
}
file->mode = mode;
if (preserve_uid)
F_OWNER(file) = uid;
if (preserve_gid) {
-@@ -1240,6 +1267,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+@@ -1211,6 +1238,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
OPT_EXTRA(file, 0)->unum = (uint32)(st.st_size >> 32);
}
file->mode = st.st_mode;
/* Save stack by recursing to ourself directly. */
if (S_ISDIR(fp->mode)) {
if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS)
-@@ -593,6 +606,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
+@@ -596,6 +609,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
&& ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
return 0;
if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file))
return 0;
-@@ -658,6 +676,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -661,6 +679,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP)
&& sxp->st.st_gid != (gid_t)F_GROUP(file))
iflags |= ITEM_REPORT_GROUP;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
if (!ACL_READY(*sxp))
-@@ -1423,6 +1446,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1426,6 +1449,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
file->mode = dest_mode(file->mode, sx.st.st_mode,
dflt_perms, statret == 0);
}
if (statret != 0 && basis_dir[0] != NULL) {
int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
itemizing, code);
-@@ -1458,10 +1485,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1461,10 +1488,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
/* We need to ensure that the dirs in the transfer have writable
* permissions during the time we are putting files within them.
* This is then fixed after the transfer is done. */
rsyserr(FERROR_XFER, errno,
"failed to modify permissions on %s",
full_fname(fname));
-@@ -1492,6 +1524,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1500,6 +1532,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms,
exists);
}
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && F_HLINK_NOT_FIRST(file)
-@@ -2004,13 +2040,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
+@@ -2012,13 +2048,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
continue;
fname = f_name(file, NULL);
if (!(file->mode & S_IWUSR))
extern int verbose;
extern int am_server;
-@@ -604,16 +605,15 @@ static int rule_matches(const char *fname, struct filter_struct *ex, int name_is
+@@ -605,16 +606,15 @@ static int rule_matches(const char *fname, struct filter_struct *ex, int name_is
if (litmatch_array(pattern, strings, slash_handling))
return ret_match;
} else if (anchored_match) {
extern int ignore_errors;
extern int numeric_ids;
extern int recurse;
-@@ -2672,6 +2673,7 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
+@@ -2688,6 +2689,7 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
{
int dif;
const uchar *c1, *c2;
enum fnc_state state1, state2;
enum fnc_type type1, type2;
enum fnc_type t_path = protocol_version >= 29 ? t_PATH : t_ITEM;
-@@ -2782,7 +2784,15 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
+@@ -2798,7 +2800,15 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2)
if (type1 != type2)
return type1 == t_PATH ? 1 : -1;
}
extern char curr_dir[MAXPATHLEN];
-@@ -859,7 +860,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -830,7 +831,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
extra_len += EXTRA_LEN;
#endif
extern int uid_ndx;
extern int gid_ndx;
extern int delete_mode;
-@@ -624,6 +625,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -627,6 +628,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
const char *xname)
{
if (statret >= 0) { /* A from-dest-dir statret can == 1! */
int keep_time = !preserve_times ? 0
: S_ISDIR(file->mode) ? preserve_times > 1 :
#if defined HAVE_LUTIMES && defined HAVE_UTIMES
-@@ -653,10 +655,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -656,10 +658,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
} else if (preserve_executability
&& ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
iflags |= ITEM_REPORT_PERMS;
iflags |= ITEM_REPORT_GROUP;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
-@@ -1419,7 +1422,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1422,7 +1425,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
real_sx = sx;
if (file->flags & FLAG_DIR_CREATED)
statret = -1;
extern struct stats stats;
extern char *filesfrom_host;
-@@ -1537,6 +1538,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
+@@ -1542,6 +1543,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
}
send_file_name(f, flist, fbuf, NULL, flags, filter_level);
extern int size_only;
extern OFF_T max_size;
extern OFF_T min_size;
-@@ -708,7 +709,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -711,7 +712,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
/* Perform our quick-check heuristic for determining if a file is unchanged. */
int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
{
#define PTR_SIZE (sizeof (struct file_struct *))
int io_error;
-@@ -642,6 +645,24 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
+@@ -612,6 +615,24 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
stats.total_size += F_LENGTH(file);
}
static struct file_struct *recv_file_entry(struct file_list *flist,
int xflags, int f)
{
-@@ -710,6 +731,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -680,6 +701,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
}
#endif
+ if (tr_opt)
+ transliterate(thisname);
+
- clean_fname(thisname, 0);
+ if (*thisname)
+ clean_fname(thisname, 0);
- if (sanitize_paths)
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
extern char curr_dir[MAXPATHLEN];
-@@ -789,7 +790,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -760,7 +761,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
uid = (uid_t)read_varint(f);
if (xflags & XMIT_USER_NAME_FOLLOWS)
uid = recv_user_name(f, uid);
uid = match_uid(uid);
}
}
-@@ -801,7 +802,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
+@@ -772,7 +773,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
gid_flags = 0;
if (xflags & XMIT_GROUP_NAME_FOLLOWS)
gid = recv_group_name(f, gid, &gid_flags);
gid = match_gid(gid, &gid_flags);
}
}
-@@ -2142,8 +2143,13 @@ struct file_list *recv_file_list(int f)
+@@ -2158,8 +2159,13 @@ struct file_list *recv_file_list(int f)
int dstart, flags;
int64 start_read;