extern struct stats stats;
extern dev_t filesystem_dev;
extern char *backup_dir;
-@@ -320,22 +322,27 @@ static void do_delete_pass(struct file_l
+@@ -348,22 +350,27 @@ static void do_delete_pass(struct file_l
rprintf(FINFO, " \r");
}
int32 iflags, uchar fnamecmp_type, char *xname)
{
if (statret >= 0) { /* A from-dest-dir statret can == 1! */
-@@ -343,20 +350,24 @@ void itemize(struct file_struct *file, i
+@@ -371,20 +378,24 @@ void itemize(struct file_struct *file, i
: S_ISDIR(file->mode) ? !omit_dir_times
: !S_ISLNK(file->mode);
} else
iflags |= ITEM_IS_NEW;
-@@ -609,7 +620,7 @@ void check_for_finished_hlinks(int itemi
+@@ -637,7 +648,7 @@ void check_for_finished_hlinks(int itemi
* handling the file, -1 if no dest-linking occurred, or a non-negative
* value if we found an alternate basis file. */
static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
int maybe_ATTRS_REPORT, enum logcode code)
{
int best_match = -1;
-@@ -618,7 +629,7 @@ static int try_dests_reg(struct file_str
+@@ -646,7 +657,7 @@ static int try_dests_reg(struct file_str
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
continue;
switch (match_level) {
case 0:
-@@ -626,16 +637,20 @@ static int try_dests_reg(struct file_str
+@@ -654,16 +665,20 @@ static int try_dests_reg(struct file_str
match_level = 1;
/* FALL THROUGH */
case 1:
continue;
best_match = j;
match_level = 3;
-@@ -650,7 +665,7 @@ static int try_dests_reg(struct file_str
+@@ -678,7 +693,7 @@ static int try_dests_reg(struct file_str
if (j != best_match) {
j = best_match;
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
return -1;
}
-@@ -658,7 +673,7 @@ static int try_dests_reg(struct file_str
+@@ -686,7 +701,7 @@ static int try_dests_reg(struct file_str
#ifdef SUPPORT_HARD_LINKS
if (link_dest) {
int i = itemizing && (verbose > 1 || stdout_format_has_i > 1);
cmpbuf, 1, i, code) < 0)
goto try_a_copy;
if (preserve_hard_links && file->link_u.links) {
-@@ -668,8 +683,13 @@ static int try_dests_reg(struct file_str
+@@ -696,8 +711,13 @@ static int try_dests_reg(struct file_str
}
} else
#endif
if (verbose > 1 && maybe_ATTRS_REPORT) {
rprintf(FCLIENT, "%s is uptodate\n", fname);
}
-@@ -685,8 +705,13 @@ static int try_dests_reg(struct file_str
+@@ -713,8 +733,13 @@ static int try_dests_reg(struct file_str
}
return -1;
}
set_file_attrs(fname, file, NULL, 0);
if (maybe_ATTRS_REPORT
&& ((!itemizing && verbose && match_level == 2)
-@@ -707,7 +732,7 @@ static int try_dests_reg(struct file_str
+@@ -735,7 +760,7 @@ static int try_dests_reg(struct file_str
* handling the file, or -1 if no dest-linking occurred, or a non-negative
* value if we found an alternate basis file. */
static int try_dests_non(struct file_struct *file, char *fname, int ndx,
int maybe_ATTRS_REPORT, enum logcode code)
{
char lnk[MAXPATHLEN];
-@@ -739,24 +764,24 @@ static int try_dests_non(struct file_str
+@@ -767,24 +792,24 @@ static int try_dests_non(struct file_str
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
continue;
break;
#endif
-@@ -770,7 +795,7 @@ static int try_dests_non(struct file_str
+@@ -798,7 +823,7 @@ static int try_dests_non(struct file_str
break;
case TYPE_SPECIAL:
case TYPE_DEVICE:
continue;
break;
#ifdef SUPPORT_LINKS
-@@ -787,7 +812,11 @@ static int try_dests_non(struct file_str
+@@ -815,7 +840,11 @@ static int try_dests_non(struct file_str
match_level = 2;
best_match = j;
}
match_level = 3;
best_match = j;
break;
-@@ -800,7 +829,7 @@ static int try_dests_non(struct file_str
+@@ -828,7 +857,7 @@ static int try_dests_non(struct file_str
if (j != best_match) {
j = best_match;
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
return -1;
}
-@@ -831,7 +860,15 @@ static int try_dests_non(struct file_str
+@@ -859,7 +888,15 @@ static int try_dests_non(struct file_str
: ITEM_LOCAL_CHANGE
+ (match_level == 3 ? ITEM_XNAME_FOLLOWS : 0);
char *lp = match_level == 3 ? "" : NULL;
}
if (verbose > 1 && maybe_ATTRS_REPORT) {
rprintf(FCLIENT, "%s%s is uptodate\n",
-@@ -844,6 +881,7 @@ static int try_dests_non(struct file_str
+@@ -872,6 +909,7 @@ static int try_dests_non(struct file_str
}
static int phase = 0;
/* Acts on the_file_list->file's ndx'th item, whose name is fname. If a dir,
* make sure it exists, and has the right permissions/timestamp info. For
-@@ -865,7 +903,8 @@ static void recv_generator(char *fname,
+@@ -893,7 +931,8 @@ static void recv_generator(char *fname,
static int need_fuzzy_dirlist = 0;
struct file_struct *fuzzy_file = NULL;
int fd = -1, f_copy = -1;
struct file_struct *back_file = NULL;
int statret, real_ret, stat_errno;
char *fnamecmp, *partialptr, *backupptr = NULL;
-@@ -921,6 +960,9 @@ static void recv_generator(char *fname,
+@@ -949,6 +988,9 @@ static void recv_generator(char *fname,
} else if (!dry_run)
return;
}
if (dry_run > 1) {
statret = -1;
stat_errno = ENOENT;
-@@ -928,7 +970,7 @@ static void recv_generator(char *fname,
+@@ -956,7 +998,7 @@ static void recv_generator(char *fname,
char *dn = file->dirname ? file->dirname : ".";
if (parent_dirname != dn && strcmp(parent_dirname, dn) != 0) {
if (relative_paths && !implied_dirs
&& create_directory_path(fname) < 0) {
rsyserr(FERROR, errno,
"recv_generator: mkdir %s failed",
-@@ -940,6 +982,10 @@ static void recv_generator(char *fname,
+@@ -968,6 +1010,10 @@ static void recv_generator(char *fname,
}
if (fuzzy_basis)
need_fuzzy_dirlist = 1;
}
parent_dirname = dn;
-@@ -948,7 +994,7 @@ static void recv_generator(char *fname,
+@@ -976,7 +1022,7 @@ static void recv_generator(char *fname,
need_fuzzy_dirlist = 0;
}
keep_dirlinks && S_ISDIR(file->mode));
stat_errno = errno;
}
-@@ -966,8 +1012,9 @@ static void recv_generator(char *fname,
+@@ -994,8 +1040,9 @@ static void recv_generator(char *fname,
* mode based on the local permissions and some heuristics. */
if (!preserve_perms) {
int exists = statret == 0
}
if (S_ISDIR(file->mode)) {
-@@ -976,8 +1023,8 @@ static void recv_generator(char *fname,
+@@ -1004,8 +1051,8 @@ static void recv_generator(char *fname,
* file of that name and it is *not* a directory, then
* we need to delete it. If it doesn't exist, then
* (perhaps recursively) create it. */
- if (statret == 0 && !S_ISDIR(st.st_mode)) {
-- if (delete_item(fname, st.st_mode, del_opts) < 0)
+- if (delete_item(fname, st.st_mode, "directory", del_opts) != 0)
+ if (statret == 0 && !S_ISDIR(sx.st.st_mode)) {
-+ if (delete_item(fname, sx.st.st_mode, del_opts) < 0)
++ if (delete_item(fname, sx.st.st_mode, "directory", del_opts) != 0)
return;
statret = -1;
}
-@@ -986,14 +1033,14 @@ static void recv_generator(char *fname,
+@@ -1014,14 +1061,14 @@ static void recv_generator(char *fname,
dry_run++;
}
real_ret = statret;
itemizing, maybe_ATTRS_REPORT, code);
if (j == -2) {
itemizing = 0;
-@@ -1002,7 +1049,11 @@ static void recv_generator(char *fname,
+@@ -1030,7 +1077,11 @@ static void recv_generator(char *fname,
statret = 1;
}
if (itemizing && f_out != -1) {
statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
}
if (real_ret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
-@@ -1022,21 +1073,21 @@ static void recv_generator(char *fname,
+@@ -1050,21 +1101,21 @@ static void recv_generator(char *fname,
return;
}
}
if (preserve_links && S_ISLNK(file->mode)) {
#ifdef SUPPORT_LINKS
-@@ -1054,15 +1105,15 @@ static void recv_generator(char *fname,
+@@ -1082,15 +1133,15 @@ static void recv_generator(char *fname,
char lnk[MAXPATHLEN];
int len;
if (preserve_hard_links && file->link_u.links)
hard_link_cluster(file, ndx, itemizing, code);
if (remove_source_files == 1)
-@@ -1071,10 +1122,10 @@ static void recv_generator(char *fname,
+@@ -1099,10 +1150,10 @@ static void recv_generator(char *fname,
}
/* Not the right symlink (or not a symlink), so
* delete it. */
-- if (delete_item(fname, st.st_mode, del_opts) < 0)
-+ if (delete_item(fname, sx.st.st_mode, del_opts) < 0)
+- if (delete_item(fname, st.st_mode, "symlink", del_opts) != 0)
++ if (delete_item(fname, sx.st.st_mode, "symlink", del_opts) != 0)
return;
} else if (basis_dir[0] != NULL) {
- int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &st,
itemizing, maybe_ATTRS_REPORT, code);
if (j == -2) {
#ifndef CAN_HARDLINK_SYMLINK
-@@ -1090,7 +1141,7 @@ static void recv_generator(char *fname,
+@@ -1118,7 +1169,7 @@ static void recv_generator(char *fname,
statret = 1;
}
if (preserve_hard_links && file->link_u.links
itemizing, code, HL_SKIP))
return;
if (do_symlink(file->u.link, fname) != 0) {
-@@ -1099,7 +1150,7 @@ static void recv_generator(char *fname,
+@@ -1127,7 +1178,7 @@ static void recv_generator(char *fname,
} else {
set_file_attrs(fname, file, NULL, 0);
if (itemizing) {
ITEM_LOCAL_CHANGE, 0, NULL);
}
if (code != FNONE && verbose)
-@@ -1119,25 +1170,30 @@ static void recv_generator(char *fname,
- if ((am_root && preserve_devices && IS_DEVICE(file->mode))
- || (preserve_specials && IS_SPECIAL(file->mode))) {
+@@ -1149,31 +1200,36 @@ static void recv_generator(char *fname,
if (statret == 0) {
-- if ((IS_DEVICE(file->mode) && !IS_DEVICE(st.st_mode))
-- || (IS_SPECIAL(file->mode) && !IS_SPECIAL(st.st_mode)))
-+ if ((IS_DEVICE(file->mode) && !IS_DEVICE(sx.st.st_mode))
-+ || (IS_SPECIAL(file->mode) && !IS_SPECIAL(sx.st.st_mode)))
- statret = -1;
-- else if ((st.st_mode & ~CHMOD_BITS) == (file->mode & ~CHMOD_BITS)
-- && st.st_rdev == file->u.rdev) {
-+ else if ((sx.st.st_mode & ~CHMOD_BITS) == (file->mode & ~CHMOD_BITS)
-+ && sx.st.st_rdev == file->u.rdev) {
+ char *t;
+ if (IS_DEVICE(file->mode)) {
+- if (!IS_DEVICE(st.st_mode))
++ if (!IS_DEVICE(sx.st.st_mode))
+ statret = -1;
+ t = "device file";
+ } else {
+- if (!IS_SPECIAL(st.st_mode))
++ if (!IS_SPECIAL(sx.st.st_mode))
+ statret = -1;
+ t = "special file";
+ }
+ if (statret == 0
+- && (st.st_mode & ~CHMOD_BITS) == (file->mode & ~CHMOD_BITS)
+- && st.st_rdev == file->u.rdev) {
++ && (sx.st.st_mode & ~CHMOD_BITS) == (file->mode & ~CHMOD_BITS)
++ && sx.st.st_rdev == file->u.rdev) {
/* The device or special file is identical. */
- if (itemizing)
- itemize(file, ndx, 0, &st, 0, 0, NULL);
- return;
+ goto cleanup;
}
-- if (delete_item(fname, st.st_mode, del_opts) < 0)
-+ if (delete_item(fname, sx.st.st_mode, del_opts) < 0)
+- if (delete_item(fname, st.st_mode, t, del_opts) != 0)
++ if (delete_item(fname, sx.st.st_mode, t, del_opts) != 0)
return;
} else if (basis_dir[0] != NULL) {
- int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &st,
itemizing, maybe_ATTRS_REPORT, code);
if (j == -2) {
#ifndef CAN_HARDLINK_SPECIAL
-@@ -1153,7 +1209,7 @@ static void recv_generator(char *fname,
+@@ -1189,7 +1245,7 @@ static void recv_generator(char *fname,
statret = 1;
}
if (preserve_hard_links && file->link_u.links
itemizing, code, HL_SKIP))
return;
if (verbose > 2) {
-@@ -1166,7 +1222,11 @@ static void recv_generator(char *fname,
+@@ -1202,7 +1258,11 @@ static void recv_generator(char *fname,
} else {
set_file_attrs(fname, file, NULL, 0);
if (itemizing) {
ITEM_LOCAL_CHANGE, 0, NULL);
}
if (code != FNONE && verbose)
-@@ -1176,7 +1236,7 @@ static void recv_generator(char *fname,
+@@ -1212,7 +1272,7 @@ static void recv_generator(char *fname,
if (remove_source_files == 1)
goto return_with_success;
}
}
if (!S_ISREG(file->mode)) {
-@@ -1210,7 +1270,7 @@ static void recv_generator(char *fname,
+@@ -1246,7 +1306,7 @@ static void recv_generator(char *fname,
}
if (update_only && statret == 0
if (verbose > 1)
rprintf(FINFO, "%s is newer\n", fname);
return;
-@@ -1219,20 +1279,20 @@ static void recv_generator(char *fname,
+@@ -1255,20 +1315,20 @@ static void recv_generator(char *fname,
fnamecmp = fname;
fnamecmp_type = FNAMECMP_FNAME;
- if (statret == 0 && !S_ISREG(st.st_mode)) {
-- if (delete_item(fname, st.st_mode, del_opts) != 0)
+- if (delete_item(fname, st.st_mode, "regular file", del_opts) != 0)
+ if (statret == 0 && !S_ISREG(sx.st.st_mode)) {
-+ if (delete_item(fname, sx.st.st_mode, del_opts) != 0)
++ if (delete_item(fname, sx.st.st_mode, "regular file", del_opts) != 0)
return;
statret = -1;
stat_errno = ENOENT;
}
if (j >= 0) {
fnamecmp = fnamecmpbuf;
-@@ -1242,7 +1302,7 @@ static void recv_generator(char *fname,
+@@ -1278,7 +1338,7 @@ static void recv_generator(char *fname,
}
real_ret = statret;
if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL
&& link_stat(partialptr, &partial_st, 0) == 0
-@@ -1261,7 +1321,7 @@ static void recv_generator(char *fname,
+@@ -1297,7 +1357,7 @@ static void recv_generator(char *fname,
rprintf(FINFO, "fuzzy basis selected for %s: %s\n",
fname, fnamecmpbuf);
}
statret = 0;
fnamecmp = fnamecmpbuf;
fnamecmp_type = FNAMECMP_FUZZY;
-@@ -1270,7 +1330,7 @@ static void recv_generator(char *fname,
+@@ -1306,7 +1366,7 @@ static void recv_generator(char *fname,
if (statret != 0) {
if (preserve_hard_links && file->link_u.links
itemizing, code, HL_SKIP))
return;
if (stat_errno == ENOENT)
-@@ -1280,39 +1340,52 @@ static void recv_generator(char *fname,
+@@ -1316,39 +1376,52 @@ static void recv_generator(char *fname,
return;
}
fnamecmp = partialptr;
fnamecmp_type = FNAMECMP_PARTIAL_DIR;
statret = 0;
-@@ -1336,17 +1409,21 @@ static void recv_generator(char *fname,
+@@ -1372,17 +1445,21 @@ static void recv_generator(char *fname,
pretend_missing:
/* pretend the file didn't exist */
if (preserve_hard_links && file->link_u.links
}
if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) {
close(fd);
-@@ -1357,7 +1434,7 @@ static void recv_generator(char *fname,
+@@ -1393,7 +1470,7 @@ static void recv_generator(char *fname,
full_fname(backupptr));
free(back_file);
close(fd);
}
if ((f_copy = do_open(backupptr,
O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
-@@ -1365,14 +1442,14 @@ static void recv_generator(char *fname,
+@@ -1401,14 +1478,14 @@ static void recv_generator(char *fname,
full_fname(backupptr));
free(back_file);
close(fd);
}
if (verbose > 2)
-@@ -1390,24 +1467,32 @@ static void recv_generator(char *fname,
+@@ -1426,24 +1503,32 @@ static void recv_generator(char *fname,
iflags |= ITEM_BASIS_TYPE_FOLLOWS;
if (fnamecmp_type == FNAMECMP_FUZZY)
iflags |= ITEM_XNAME_FOLLOWS;
if (f_copy >= 0) {
close(f_copy);
-@@ -1420,6 +1505,13 @@ static void recv_generator(char *fname,
+@@ -1456,6 +1541,13 @@ static void recv_generator(char *fname,
}
close(fd);
}
void generate_files(int f_out, struct file_list *flist, char *local_name)
-@@ -1479,6 +1571,8 @@ void generate_files(int f_out, struct fi
+@@ -1515,6 +1607,8 @@ void generate_files(int f_out, struct fi
* notice that and let us know via the redo pipe (or its closing). */
ignore_timeout = 1;
dit(bf(--chmod)) This option tells rsync to apply one or more
comma-separated "chmod" strings to the permission of the files in the
transfer. The resulting value is treated as though it was the permissions
-@@ -1389,8 +1403,8 @@ if the receiving rsync is at least versi
+@@ -1394,8 +1408,8 @@ if the receiving rsync is at least versi
with older versions of rsync, but that also turns on the output of other
verbose messages).
type of update being done, bf(X) is replaced by the file-type, and the
other letters represent attributes that may be output if they are being
modified.
-@@ -1439,7 +1453,11 @@ quote(itemization(
+@@ -1444,7 +1458,11 @@ quote(itemization(
sender's value (requires bf(--owner) and super-user privileges).
it() A bf(g) means the group is different and is being updated to the
sender's value (requires bf(--group) and the authority to set the group).
extern struct file_list *the_file_list;
extern struct filter_list_struct server_filter_list;
-@@ -185,7 +187,7 @@ static int delete_item(char *fname, int
+@@ -210,7 +212,7 @@ static enum delret delete_dir_contents(c
for (j = dirlist->count; j--; ) {
struct file_struct *fp = dirlist->files[j];
-- if (fp->flags & FLAG_MOUNT_POINT)
-+ if (FFLAGS(fp) & FLAG_MOUNT_POINT)
- continue;
-
- strlcpy(p, fp->basename, remainder);
-@@ -263,7 +265,7 @@ static void delete_in_dir(struct file_li
+- if (fp->flags & FLAG_MOUNT_POINT) {
++ if (FFLAGS(fp) & FLAG_MOUNT_POINT) {
+ if (verbose > 1) {
+ rprintf(FINFO,
+ "mount point, %s, pins parent directory\n",
+@@ -285,7 +287,7 @@ static void delete_in_dir(struct file_li
filt_array[cur_depth] = push_local_filters(fbuf, dlen);
if (one_file_system) {
filesystem_dev = stp->st_dev;
else if (filesystem_dev != stp->st_dev)
return;
-@@ -275,7 +277,7 @@ static void delete_in_dir(struct file_li
- * from the filesystem. */
- for (i = dirlist->count; i--; ) {
+@@ -299,7 +301,7 @@ static void delete_in_dir(struct file_li
struct file_struct *fp = dirlist->files[i];
-- if (!fp->basename || fp->flags & FLAG_MOUNT_POINT)
-+ if (!fp->basename || FFLAGS(fp) & FLAG_MOUNT_POINT)
+ if (!fp->basename)
continue;
- if (flist_find(flist, fp) < 0) {
- f_name(fp, delbuf);
-@@ -301,11 +303,11 @@ static void do_delete_pass(struct file_l
+- if (fp->flags & FLAG_MOUNT_POINT) {
++ if (FLAGS(fp) & FLAG_MOUNT_POINT) {
+ if (verbose > 1)
+ rprintf(FINFO, "mount point %s not deleted\n",
+ f_name(fp, NULL));
+@@ -329,11 +331,11 @@ static void do_delete_pass(struct file_l
for (j = 0; j < flist->count; j++) {
struct file_struct *file = flist->files[j];
rprintf(FINFO, "deleting in %s\n", fbuf);
if (link_stat(fbuf, &st, keep_dirlinks) < 0
-@@ -350,6 +352,9 @@ void itemize(struct file_struct *file, i
+@@ -378,6 +380,9 @@ void itemize(struct file_struct *file, i
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
|| (keep_time && cmp_time(file->modtime, st->st_mtime) != 0))
iflags |= ITEM_REPORT_TIME;
if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
iflags |= ITEM_REPORT_PERMS;
if (preserve_uid && am_root && file->uid != st->st_uid)
-@@ -553,7 +558,7 @@ static int find_fuzzy(struct file_struct
+@@ -581,7 +586,7 @@ static int find_fuzzy(struct file_struct
uint32 dist;
if (!S_ISREG(fp->mode) || !fp->length
continue;
name = fp->basename;
-@@ -661,6 +666,8 @@ static int try_dests_reg(struct file_str
+@@ -689,6 +694,8 @@ static int try_dests_reg(struct file_str
if (hard_link_one(file, ndx, fname, 0, stp,
cmpbuf, 1, i, code) < 0)
goto try_a_copy;
if (preserve_hard_links && file->link_u.links) {
if (dry_run)
file->link_u.links->link_dest_used = j + 1;
-@@ -1012,7 +1019,7 @@ static void recv_generator(char *fname,
+@@ -1040,7 +1047,7 @@ static void recv_generator(char *fname,
rsyserr(FERROR, errno,
"recv_generator: mkdir %s failed",
full_fname(fname));
if (ndx+1 < the_file_list->count
&& the_file_list->files[ndx+1]->dir.depth > file->dir.depth) {
rprintf(FERROR,
-@@ -1028,7 +1035,7 @@ static void recv_generator(char *fname,
+@@ -1056,7 +1063,7 @@ static void recv_generator(char *fname,
if (real_ret != 0 && one_file_system)
real_st.st_dev = filesystem_dev;
if (delete_during && f_out != -1 && !phase && dry_run < 2
delete_in_dir(the_file_list, fname, file, &real_st);
return;
}
-@@ -1324,7 +1331,7 @@ static void recv_generator(char *fname,
+@@ -1360,7 +1367,7 @@ static void recv_generator(char *fname,
if (fuzzy_dirlist) {
int j = flist_find(fuzzy_dirlist, file);
if (j >= 0) /* don't use changing file as future fuzzy basis */
}
/* open the file */
-@@ -1589,7 +1596,7 @@ void generate_files(int f_out, struct fi
+@@ -1625,7 +1632,7 @@ void generate_files(int f_out, struct fi
continue;
if (!need_retouch_dir_times && file->mode & S_IWUSR)
continue;
dit(bf(--super)) This tells the receiving side to attempt super-user
activities even if the receiving rsync wasn't run by the super-user. These
activities include: preserving users via the bf(--owner) option, preserving
-@@ -1390,7 +1397,7 @@ with older versions of rsync, but that a
+@@ -1395,7 +1402,7 @@ with older versions of rsync, but that a
verbose messages).
The "%i" escape has a cryptic output that is 9 letters long. The general
type of update being done, bf(X) is replaced by the file-type, and the
other letters represent attributes that may be output if they are being
modified.
-@@ -1430,7 +1437,7 @@ quote(itemization(
+@@ -1435,7 +1442,7 @@ quote(itemization(
by the file transfer.
it() A bf(t) means the modification time is different and is being updated
to the sender's value (requires bf(--times)). An alternate value of bf(T)
anytime a symlink is transferred, or when a file or device is transferred
without bf(--times).
it() A bf(p) means the permissions are different and are being updated to
-@@ -1439,7 +1446,10 @@ quote(itemization(
+@@ -1444,7 +1451,10 @@ quote(itemization(
sender's value (requires bf(--owner) and super-user privileges).
it() A bf(g) means the group is different and is being updated to the
sender's value (requires bf(--group) and the authority to set the group).
extern struct file_list *the_file_list;
extern struct filter_list_struct server_filter_list;
-@@ -100,10 +103,14 @@ static int deletion_count = 0; /* used t
- #define DEL_TERSE (1<<3)
+@@ -110,10 +113,14 @@ enum delret {
+ static enum delret delete_dir_contents(char *fname, int flags);
+/* Function now compares both backup_suffix and backup_suffix_dels. */
+ return k > 0 && strcmp(fn+k, backup_suffix_dels) == 0;
}
-
-@@ -124,8 +131,8 @@ static int delete_item(char *fname, int
- if (!S_ISDIR(mode)) {
- if (max_delete && ++deletion_count > max_delete)
- return 0;
-- if (make_backups && (backup_dir || !is_backup_file(fname)))
-- ok = make_backup(fname);
-+ if (make_backups && (backup_dir_dels || !is_backup_file(fname)))
-+ ok = safe_delete(fname);
- else
- ok = robust_unlink(fname) == 0;
- if (ok) {
-@@ -147,9 +154,9 @@ static int delete_item(char *fname, int
- || (dry_run && zap_dir)) {
- ok = 0;
- errno = ENOTEMPTY;
-- } else if (make_backups && !backup_dir && !is_backup_file(fname)
-+ } else if (make_backups && !backup_dir_dels && !is_backup_file(fname)
- && !(flags & DEL_FORCE_RECURSE))
+ /* Delete a file or directory. If DEL_RECURSE is set in the flags, this will
+@@ -147,9 +154,9 @@ static enum delret delete_item(char *fna
+ if (S_ISDIR(mode)) {
+ what = "rmdir";
+ ok = do_rmdir(fname) == 0;
+- } else if (make_backups && (backup_dir || !is_backup_file(fname))) {
++ } else if (make_backups && (backup_dir_dels || !is_backup_file(fname))) {
+ what = "make_backup";
- ok = make_backup(fname);
+ ok = safe_delete(fname);
- else
- ok = do_rmdir(fname) == 0;
- if (ok) {
+ } else {
+ what = "unlink";
+ ok = robust_unlink(fname) == 0;
--- old/options.c
+++ new/options.c
@@ -138,10 +138,14 @@ int no_detach
static int deletion_count = 0; /* used to implement --max-delete */
+static int unexplored_dirs = 1;
--/* For calling delete_file() */
+-/* For calling delete_item() */
+/* For calling delete_item() and delete_in_dir() */
- #define DEL_FORCE_RECURSE (1<<1) /* recurse even w/o --force */
+ #define DEL_RECURSE (1<<1) /* recurse */
+#define DEL_NO_DELETIONS (1<<2)
- #define DEL_TERSE (1<<3)
enum nonregtype {
-@@ -109,12 +113,120 @@ static int is_backup_file(char *fn)
+ TYPE_DIR, TYPE_SPECIAL, TYPE_DEVICE, TYPE_SYMLINK
+@@ -116,6 +120,113 @@ static int is_backup_file(char *fn)
return k > 0 && strcmp(fn+k, backup_suffix) == 0;
}
+ if (errno != EEXIST)
+ handle_partial_dir(partialptr, PDIR_DELETE);
+}
-
- /* Delete a file or directory. If DEL_FORCE_RECURSE is set in the flags, or if
- * force_delete is set, this will delete recursively.
++
+ /* Delete a file or directory. If DEL_RECURSE is set in the flags, this will
+ * delete recursively.
*
- * Note that fname must point to a MAXPATHLEN buffer if the mode indicates it's
- * a directory! (The buffer is used for recursion, but returned unchanged.)
+@@ -185,6 +296,8 @@ static enum delret delete_item(char *fna
+ /* Prep directory is to be deleted, so delete all its contents. Note
+ * that fname must point to a MAXPATHLEN buffer! (The buffer is used
+ * for recursion, but returned unchanged.)
+ *
-+ * Also Note: --detect-rename may use this routine with DEL_NO_DELETIONS set!
++ * Note: --detect-rename may use this routine with DEL_NO_DELETIONS set!
*/
- static int delete_item(char *fname, int mode, int flags)
+ static enum delret delete_dir_contents(char *fname, int flags)
{
-@@ -125,6 +237,8 @@ static int delete_item(char *fname, int
- char *p;
-
- if (!S_ISDIR(mode)) {
-+ if (flags & DEL_NO_DELETIONS)
-+ return 0;
- if (max_delete && ++deletion_count > max_delete)
- return 0;
- if (make_backups && (backup_dir || !is_backup_file(fname)))
-@@ -147,6 +261,7 @@ static int delete_item(char *fname, int
-
- zap_dir = flags & DEL_FORCE_RECURSE || force_delete;
- if ((max_delete && ++deletion_count > max_delete)
-+ || flags & DEL_NO_DELETIONS
- || (dry_run && zap_dir)) {
- ok = 0;
- errno = ENOTEMPTY;
-@@ -189,6 +304,8 @@ static int delete_item(char *fname, int
- continue;
+@@ -221,6 +334,16 @@ static enum delret delete_dir_contents(c
+ }
strlcpy(p, fp->basename, remainder);
-+ if (detect_renamed && S_ISREG(fp->mode))
-+ look_for_rename(fp, fname, dirlist->file_pool);
- delete_item(fname, fp->mode, flags & ~DEL_TERSE);
- }
- flist_free(dirlist);
-@@ -197,7 +314,8 @@ static int delete_item(char *fname, int
-
- pop_local_filters(save_filters);
-
-- if (max_delete && ++deletion_count > max_delete)
-+ if (flags & DEL_NO_DELETIONS
-+ || (max_delete && ++deletion_count > max_delete))
- return 0;
-
- if (do_rmdir(fname) == 0) {
-@@ -217,15 +335,19 @@ static int delete_item(char *fname, int
++ if (detect_renamed) {
++ if (S_ISDIR(fp->mode) && flags & DEL_NO_DELETIONS) {
++ delete_dir_contents(fname, flags);
++ continue;
++ }
++ if (S_ISREG(fp->mode))
++ look_for_rename(fp, fname, dirlist->file_pool);
++ if (flags & DEL_NO_DELETIONS)
++ continue;
++ }
+ result = delete_item(fname, fp->mode, NULL, flags);
+ if (result != DR_SUCCESS && ret == DR_SUCCESS)
+ ret = result == DR_PINNED ? result : DR_NOT_EMPTY;
+@@ -239,15 +362,19 @@ static enum delret delete_dir_contents(c
* all the --delete-WHEN options. Note that the fbuf pointer must point to a
* MAXPATHLEN buffer with the name of the directory in it (the functions we
* call will append names onto the end, but the old dir value will be restored
int dlen, i;
if (!flist) {
-@@ -239,6 +361,8 @@ static void delete_in_dir(struct file_li
+@@ -261,6 +388,8 @@ static void delete_in_dir(struct file_li
if (verbose > 2)
rprintf(FINFO, "delete_in_dir(%s)\n", fbuf);
-+ flags |= DEL_FORCE_RECURSE;
++ flags |= DEL_RECURSE;
+
if (allowed_lull)
maybe_send_keepalive();
-@@ -246,12 +370,14 @@ static void delete_in_dir(struct file_li
+@@ -268,12 +397,14 @@ static void delete_in_dir(struct file_li
return; /* Impossible... */
if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
}
while (cur_depth >= file->dir.depth && cur_depth >= min_depth)
-@@ -262,6 +388,9 @@ static void delete_in_dir(struct file_li
+@@ -284,6 +415,9 @@ static void delete_in_dir(struct file_li
dlen = strlen(fbuf);
filt_array[cur_depth] = push_local_filters(fbuf, dlen);
if (one_file_system) {
if (file->flags & FLAG_TOP_DIR)
filesystem_dev = stp->st_dev;
-@@ -271,18 +400,30 @@ static void delete_in_dir(struct file_li
+@@ -293,6 +427,11 @@ static void delete_in_dir(struct file_li
dirlist = get_dirlist(fbuf, dlen, 0);
/* If an item in dirlist is not found in flist, delete it
* from the filesystem. */
for (i = dirlist->count; i--; ) {
- struct file_struct *fp = dirlist->files[i];
- if (!fp->basename || fp->flags & FLAG_MOUNT_POINT)
+@@ -305,12 +444,19 @@ static void delete_in_dir(struct file_li
+ f_name(fp, NULL));
continue;
+ }
+ if (detect_renamed && S_ISREG(fp->mode)) {
+ strlcpy(p, fp->basename, remainder);
+ look_for_rename(fp, fbuf, dirlist->file_pool);
+ }
if (flist_find(flist, fp) < 0) {
f_name(fp, delbuf);
-- delete_item(delbuf, fp->mode, DEL_FORCE_RECURSE);
+- delete_item(delbuf, fp->mode, NULL, DEL_RECURSE);
- }
-+ delete_item(delbuf, fp->mode, flags);
++ delete_item(delbuf, fp->mode, NULL, flags);
+ } else if (detect_renamed && S_ISDIR(fp->mode))
+ unexplored_dirs++;
}
flist_free(dirlist);
}
-@@ -312,9 +453,9 @@ static void do_delete_pass(struct file_l
+@@ -340,9 +486,9 @@ static void do_delete_pass(struct file_l
|| !S_ISDIR(st.st_mode))
continue;
if (do_progress && !am_server)
rprintf(FINFO, " \r");
-@@ -843,6 +984,7 @@ static int try_dests_non(struct file_str
+@@ -871,6 +1017,7 @@ static int try_dests_non(struct file_str
return j;
}
static int phase = 0;
/* Acts on the_file_list->file's ndx'th item, whose name is fname. If a dir,
-@@ -1028,8 +1170,12 @@ static void recv_generator(char *fname,
+@@ -1056,8 +1203,12 @@ static void recv_generator(char *fname,
if (real_ret != 0 && one_file_system)
real_st.st_dev = filesystem_dev;
if (delete_during && f_out != -1 && !phase && dry_run < 2
return;
}
-@@ -1273,8 +1419,14 @@ static void recv_generator(char *fname,
+@@ -1309,8 +1460,14 @@ static void recv_generator(char *fname,
&& hard_link_check(file, ndx, fname, statret, &st,
itemizing, code, HL_SKIP))
return;
rsyserr(FERROR, stat_errno, "recv_generator: failed to stat %s",
full_fname(fname));
return;
-@@ -1460,11 +1612,17 @@ void generate_files(int f_out, struct fi
+@@ -1496,11 +1653,17 @@ void generate_files(int f_out, struct fi
(long)getpid(), flist->count);
}
whole_file = 0;
if (verbose >= 2) {
rprintf(FINFO, "delta-transmission %s\n",
-@@ -1519,7 +1677,23 @@ void generate_files(int f_out, struct fi
+@@ -1555,7 +1718,23 @@ void generate_files(int f_out, struct fi
}
recv_generator(NULL, NULL, 0, 0, 0, code, -1);
if (delete_during)
--compare-dest=DIR also compare received files relative to DIR
--copy-dest=DIR ... and include copies of unchanged files
--link-dest=DIR hardlink to files in DIR when unchanged
-@@ -1259,6 +1260,15 @@ Note that the use of the bf(--delete) op
+@@ -1264,6 +1265,15 @@ Note that the use of the bf(--delete) op
fuzzy-match files, so either use bf(--delete-after) or specify some
filename exclusions if you need to prevent this.
--- old/generator.c
+++ new/generator.c
-@@ -109,6 +109,12 @@ static int is_backup_file(char *fn)
- return k > 0 && strcmp(fn+k, backup_suffix) == 0;
- }
+@@ -95,6 +95,12 @@ extern struct filter_list_struct server_
+
+ static int deletion_count = 0; /* used to implement --max-delete */
+#ifdef SUPPORT_FLAGS
+#define FILEFLAGS(ff) ff
+#define FILEFLAGS(ff) 0
+#endif
+
+ /* For calling delete_item() */
+ #define DEL_RECURSE (1<<1) /* recurse */
- /* Delete a file or directory. If DEL_FORCE_RECURSE is set in the flags, or if
- * force_delete is set, this will delete recursively.
-@@ -116,7 +122,7 @@ static int is_backup_file(char *fn)
+@@ -109,7 +115,6 @@ enum delret {
+ /* Forward declaration for delete_item(). */
+ static enum delret delete_dir_contents(char *fname, int flags);
+
+-
+ static int is_backup_file(char *fn)
+ {
+ int k = strlen(fn) - backup_suffix_len;
+@@ -122,17 +127,20 @@ static int is_backup_file(char *fn)
* Note that fname must point to a MAXPATHLEN buffer if the mode indicates it's
* a directory! (The buffer is used for recursion, but returned unchanged.)
*/
--static int delete_item(char *fname, int mode, int flags)
-+static int delete_item(char *fname, int mode, uint32 fileflags, int flags)
+-static enum delret delete_item(char *fname, int mode, char *replace, int flags)
++static enum delret delete_item(char *fname, int mode, uint32 fileflags, char *replace, int flags)
{
- struct file_list *dirlist;
- int j, dlen, zap_dir, ok;
-@@ -127,6 +133,9 @@ static int delete_item(char *fname, int
- if (!S_ISDIR(mode)) {
- if (max_delete && ++deletion_count > max_delete)
- return 0;
-+#ifdef SUPPORT_FLAGS
-+ make_mutable(fname, mode, fileflags);
-+#endif
- if (make_backups && (backup_dir || !is_backup_file(fname)))
- ok = make_backup(fname);
- else
-@@ -151,10 +160,17 @@ static int delete_item(char *fname, int
- ok = 0;
- errno = ENOTEMPTY;
- } else if (make_backups && !backup_dir && !is_backup_file(fname)
-- && !(flags & DEL_FORCE_RECURSE))
-+ && !(flags & DEL_FORCE_RECURSE)) {
-+#ifdef SUPPORT_FLAGS
-+ make_mutable(fname, mode, fileflags);
-+#endif
- ok = make_backup(fname);
-- else
-+ } else {
+ enum delret ret;
+ char *what;
+ int ok;
+
+ if (verbose > 2) {
+- rprintf(FINFO, "delete_item(%s) mode=%o flags=%d\n",
+- fname, mode, flags);
++ rprintf(FINFO, "delete_item(%s) mode=%o fileflags=%o flags=%d\n",
++ fname, mode, fileflags, flags);
+ }
+
+#ifdef SUPPORT_FLAGS
-+ make_mutable(fname, mode, fileflags);
++ make_mutable(fname, mode, fileflags);
+#endif
- ok = do_rmdir(fname) == 0;
-+ }
- if (ok) {
- if (!(flags & DEL_TERSE))
- log_delete(fname, mode);
-@@ -189,7 +205,7 @@ static int delete_item(char *fname, int
- continue;
+ if (S_ISDIR(mode) && flags & DEL_RECURSE) {
+ ret = delete_dir_contents(fname, flags);
+ if (ret == DR_PINNED || ret == DR_NOT_EMPTY
+@@ -221,7 +229,7 @@ static enum delret delete_dir_contents(c
+ }
strlcpy(p, fp->basename, remainder);
-- delete_item(fname, fp->mode, flags & ~DEL_TERSE);
-+ delete_item(fname, fp->mode, FILEFLAGS(fp->fileflags), flags & ~DEL_TERSE);
+- result = delete_item(fname, fp->mode, NULL, flags);
++ result = delete_item(fname, fp->mode, FILEFLAGS(fp->fileflags), NULL, flags);
+ if (result != DR_SUCCESS && ret == DR_SUCCESS)
+ ret = result == DR_PINNED ? result : DR_NOT_EMPTY;
}
- flist_free(dirlist);
-
-@@ -279,7 +295,7 @@ static void delete_in_dir(struct file_li
- continue;
+@@ -307,7 +315,7 @@ static void delete_in_dir(struct file_li
+ }
if (flist_find(flist, fp) < 0) {
f_name(fp, delbuf);
-- delete_item(delbuf, fp->mode, DEL_FORCE_RECURSE);
-+ delete_item(delbuf, fp->mode, FILEFLAGS(fp->fileflags), DEL_FORCE_RECURSE);
+- delete_item(delbuf, fp->mode, NULL, DEL_RECURSE);
++ delete_item(delbuf, fp->mode, FILEFLAGS(fp->fileflags), NULL, DEL_RECURSE);
}
}
-@@ -977,7 +993,7 @@ static void recv_generator(char *fname,
+@@ -1005,7 +1013,7 @@ static void recv_generator(char *fname,
* we need to delete it. If it doesn't exist, then
* (perhaps recursively) create it. */
if (statret == 0 && !S_ISDIR(st.st_mode)) {
-- if (delete_item(fname, st.st_mode, del_opts) < 0)
-+ if (delete_item(fname, st.st_mode, FILEFLAGS(st.st_flags), del_opts) < 0)
+- if (delete_item(fname, st.st_mode, "directory", del_opts) != 0)
++ if (delete_item(fname, st.st_mode, FILEFLAGS(st.st_flags), "directory", del_opts) != 0)
return;
statret = -1;
}
-@@ -1071,7 +1087,7 @@ static void recv_generator(char *fname,
+@@ -1099,7 +1107,7 @@ static void recv_generator(char *fname,
}
/* Not the right symlink (or not a symlink), so
* delete it. */
-- if (delete_item(fname, st.st_mode, del_opts) < 0)
-+ if (delete_item(fname, st.st_mode, FILEFLAGS(st.st_flags), del_opts) < 0)
+- if (delete_item(fname, st.st_mode, "symlink", del_opts) != 0)
++ if (delete_item(fname, st.st_mode, FILEFLAGS(st.st_flags), "symlink", del_opts) != 0)
return;
} else if (basis_dir[0] != NULL) {
int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &st,
-@@ -1134,7 +1150,7 @@ static void recv_generator(char *fname,
+@@ -1170,7 +1178,7 @@ static void recv_generator(char *fname,
goto return_with_success;
return;
}
-- if (delete_item(fname, st.st_mode, del_opts) < 0)
-+ if (delete_item(fname, st.st_mode, FILEFLAGS(st.st_flags), del_opts) < 0)
+- if (delete_item(fname, st.st_mode, t, del_opts) != 0)
++ if (delete_item(fname, st.st_mode, FILEFLAGS(st.st_flags), t, del_opts) != 0)
return;
} else if (basis_dir[0] != NULL) {
int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &st,
-@@ -1220,7 +1236,7 @@ static void recv_generator(char *fname,
+@@ -1256,7 +1264,7 @@ static void recv_generator(char *fname,
fnamecmp_type = FNAMECMP_FNAME;
if (statret == 0 && !S_ISREG(st.st_mode)) {
-- if (delete_item(fname, st.st_mode, del_opts) != 0)
-+ if (delete_item(fname, st.st_mode, FILEFLAGS(st.st_flags), del_opts) != 0)
+- if (delete_item(fname, st.st_mode, "regular file", del_opts) != 0)
++ if (delete_item(fname, st.st_mode, FILEFLAGS(st.st_flags), "regular file", del_opts) != 0)
return;
statret = -1;
stat_errno = ENOENT;
+static int GEN_make_backups;
+static int GEN_csum_length;
+
- /* For calling delete_file() */
- #define DEL_FORCE_RECURSE (1<<1) /* recurse even w/o --force */
- #define DEL_TERSE (1<<3)
-@@ -445,8 +449,8 @@ static void sum_sizes_sqroot(struct sum_
+ /* For calling delete_item() */
+ #define DEL_RECURSE (1<<1) /* recurse */
+
+@@ -477,8 +481,8 @@ static void sum_sizes_sqroot(struct sum_
}
if (protocol_version < 27) {
s2length = SUM_LENGTH;
} else {
int32 c;
-@@ -456,7 +460,7 @@ static void sum_sizes_sqroot(struct sum_
+@@ -488,7 +492,7 @@ static void sum_sizes_sqroot(struct sum_
for (c = blength; (c >>= 1) && b; b--) {}
/* add a bit, subtract rollsum, round up. */
s2length = (b + 1 - 32 + 7) / 8; /* --optimize in compiler-- */
s2length = MIN(s2length, SUM_LENGTH);
}
-@@ -490,7 +494,7 @@ static void generate_and_send_sums(int f
+@@ -522,7 +526,7 @@ static void generate_and_send_sums(int f
sum_sizes_sqroot(&sum, len);
write_sum_head(f_out, &sum);
return;
if (len > 0)
-@@ -509,7 +513,7 @@ static void generate_and_send_sums(int f
+@@ -541,7 +545,7 @@ static void generate_and_send_sums(int f
if (f_copy >= 0) {
full_write(f_copy, map, n1);
continue;
}
-@@ -1208,7 +1212,7 @@ static void recv_generator(char *fname,
+@@ -1316,7 +1320,7 @@ static void recv_generator(char *fname,
return;
}
return;
if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
-@@ -1271,7 +1275,7 @@ static void recv_generator(char *fname,
+@@ -1379,7 +1383,7 @@ static void recv_generator(char *fname,
goto notify_others;
}
if (!(backupptr = get_backup_name(fname))) {
close(fd);
return;
-@@ -1362,9 +1366,12 @@ void generate_files(int f_out, struct fi
+@@ -1470,9 +1474,12 @@ void generate_files(int f_out, struct fi
int save_ignore_existing = ignore_existing;
int save_ignore_non_existing = ignore_non_existing;
int save_do_progress = do_progress;
if (protocol_version >= 29) {
itemizing = 1;
maybe_ATTRS_REPORT = stdout_format_has_i ? 0 : ATTRS_REPORT;
-@@ -1392,7 +1399,7 @@ void generate_files(int f_out, struct fi
+@@ -1500,7 +1507,7 @@ void generate_files(int f_out, struct fi
do_delete_pass(flist);
do_progress = 0;
whole_file = 0;
if (verbose >= 2) {
rprintf(FINFO, "delta-transmission %s\n",
-@@ -1401,12 +1408,6 @@ void generate_files(int f_out, struct fi
+@@ -1509,12 +1516,6 @@ void generate_files(int f_out, struct fi
: "enabled");
}
for (i = 0; i < flist->count; i++) {
struct file_struct *file = flist->files[i];
-@@ -1450,23 +1451,34 @@ void generate_files(int f_out, struct fi
+@@ -1558,23 +1559,34 @@ void generate_files(int f_out, struct fi
delete_in_dir(NULL, NULL, NULL, NULL);
phase++;
if (local_name)
strlcpy(fbuf, local_name, sizeof fbuf);
else
-@@ -1478,27 +1490,43 @@ void generate_files(int f_out, struct fi
+@@ -1586,27 +1598,43 @@ void generate_files(int f_out, struct fi
phase++;
ignore_non_existing = save_ignore_non_existing;
ignore_existing = save_ignore_existing;
}
--- old/rsync.h
+++ new/rsync.h
-@@ -169,10 +169,8 @@ enum msgcode {
+@@ -170,10 +170,8 @@ enum msgcode {
MSG_DATA=0, /* raw data on the multiplexed stream */
MSG_ERROR=FERROR, MSG_INFO=FINFO, /* remote logging */
MSG_LOG=FLOG, MSG_SOCKERR=FSOCKERR, /* sibling logging */
};
#include "errcode.h"
-@@ -329,6 +327,7 @@ enum msgcode {
+@@ -330,6 +328,7 @@ enum msgcode {
#endif
#include <assert.h>