--- old/Makefile.in
+++ new/Makefile.in
-@@ -25,15 +25,15 @@ VERSION=@VERSION@
+@@ -26,15 +26,15 @@ VERSION=@VERSION@
.SUFFIXES:
.SUFFIXES: .c .o
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
--- old/acls.c
+++ new/acls.c
-@@ -0,0 +1,1093 @@
+@@ -0,0 +1,1092 @@
+/*
+ * Handle passing Access Control Lists between systems.
+ *
+ const char *errfun;
+ int rc;
+
-+ *racl = empty_rsync_acl;
+ errfun = "sys_acl_get_entry";
+ for (rc = sys_acl_get_entry(sacl, SMB_ACL_FIRST_ENTRY, &entry);
+ rc == 1;
+
+ if (!racl)
+ out_of_memory("get_acl");
++ *racl = empty_rsync_acl;
+ if (type == SMB_ACL_TYPE_ACCESS)
+ sxp->acc_acl = racl;
+ else
+ }
+ } else if (errno == ENOTSUP) {
+ /* ACLs are not supported, so pretend we have a basic ACL. */
-+ *racl = empty_rsync_acl;
+ if (type == SMB_ACL_TYPE_ACCESS)
+ rsync_acl_fake_perms(racl, sxp->st.st_mode);
+ } else {
+ id_access *ida;
+ size_t count;
+
-+ *racl = empty_rsync_acl;
-+
+ if (!(count = read_int(f)))
+ return;
+
+ acl_duo *duo_item;
+ ndx = racl_list->count;
+ duo_item = EXPAND_ITEM_LIST(racl_list, acl_duo, 1000);
++ duo_item->racl = empty_rsync_acl;
+ receive_rsync_acl(&duo_item->racl, f, type);
+ duo_item->sacl = NULL;
+ } else {
+ rsyserr(FERROR, errno, "change_sacl_perms: %s()",
+ errfun);
+ }
-+ return ~0u;
++ return (mode_t)~0;
+ }
+
+#ifdef SMB_ACL_LOSES_SPECIAL_MODE_BITS
+ if (type == SMB_ACL_TYPE_ACCESS) {
+ cur_mode = change_sacl_perms(duo_item->sacl, &duo_item->racl,
+ cur_mode, file->mode);
-+ if (cur_mode == ~0u)
++ if (cur_mode == (mode_t)~0)
+ continue;
+ }
+ if (sys_acl_set_file(fname, type, duo_item->sacl) < 0) {
+ }
+
+ /* Convert it. */
++ racl = empty_rsync_acl;
+ ok = unpack_smb_acl(&racl, sacl);
+ sys_acl_free_acl(sacl);
+ if (!ok) {
robust_unlink(fname); /* Just in case... */
--- old/configure.in
+++ new/configure.in
-@@ -482,6 +482,11 @@ if test x"$ac_cv_func_strcasecmp" = x"no
+@@ -515,6 +515,11 @@ if test x"$ac_cv_func_strcasecmp" = x"no
AC_CHECK_LIB(resolv, strcasecmp)
fi
dnl At the moment we don't test for a broken memcmp(), because all we
dnl need to do is test for equality, not comparison, and it seems that
dnl every platform has a memcmp that can do at least that.
-@@ -746,6 +751,78 @@ AC_SUBST(OBJ_RESTORE)
+@@ -779,6 +784,78 @@ AC_SUBST(OBJ_RESTORE)
AC_SUBST(CC_SHOBJ_FLAG)
AC_SUBST(BUILD_POPT)
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
-@@ -491,6 +494,9 @@ static struct file_struct *receive_file_
+@@ -495,6 +498,9 @@ static struct file_struct *receive_file_
char thisname[MAXPATHLEN];
unsigned int l1 = 0, l2 = 0;
int alloc_len, basename_len, dirname_len, linkname_len, sum_len;
OFF_T file_length;
char *basename, *dirname, *bp;
struct file_struct *file;
-@@ -594,13 +600,27 @@ static struct file_struct *receive_file_
+@@ -598,13 +604,27 @@ static struct file_struct *receive_file_
sum_len = always_checksum && S_ISREG(mode) ? MD4_SUM_LENGTH : 0;
file->modtime = modtime;
file->length = file_length;
-@@ -693,6 +713,11 @@ static struct file_struct *receive_file_
+@@ -699,6 +719,11 @@ static struct file_struct *receive_file_
read_buf(f, sum, checksum_len);
}
return file;
}
-@@ -942,6 +967,9 @@ static struct file_struct *send_file_nam
+@@ -949,6 +974,9 @@ static struct file_struct *send_file_nam
unsigned short flags)
{
struct file_struct *file;
file = make_file(fname, flist, stp, flags,
f == -2 ? SERVER_FILTERS : ALL_FILTERS);
-@@ -951,6 +979,15 @@ static struct file_struct *send_file_nam
+@@ -958,6 +986,15 @@ static struct file_struct *send_file_nam
if (chmod_modes && !S_ISLNK(file->mode))
file->mode = tweak_mode(file->mode, chmod_modes);
maybe_emit_filelist_progress(flist->count + flist_count_offset);
flist_expand(flist);
-@@ -958,6 +995,15 @@ static struct file_struct *send_file_nam
+@@ -965,6 +1002,15 @@ static struct file_struct *send_file_nam
if (file->basename[0]) {
flist->files[flist->count++] = file;
send_file_entry(file, f);
extern int preserve_links;
extern int preserve_devices;
extern int preserve_specials;
-@@ -84,6 +85,7 @@ extern long block_size; /* "long" becaus
+@@ -85,6 +86,7 @@ extern long block_size; /* "long" becaus
extern int max_delete;
extern int force_delete;
extern int one_file_system;
extern struct stats stats;
extern dev_t filesystem_dev;
extern char *backup_dir;
-@@ -316,22 +318,27 @@ static void do_delete_pass(struct file_l
+@@ -317,22 +319,27 @@ static void do_delete_pass(struct file_l
rprintf(FINFO, " \r");
}
- if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid)
+ if (preserve_gid && file->gid != GID_NONE && sxp->st.st_gid != file->gid)
- return 0;
-
++ return 0;
++
+#ifdef SUPPORT_ACLS
+ if (preserve_acls && set_acl(NULL, file, sxp) == 0)
-+ return 0;
+ return 0;
+#endif
-+
+
return 1;
}
int32 iflags, uchar fnamecmp_type, char *xname)
{
if (statret >= 0) { /* A from-dest-dir statret can == 1! */
-@@ -339,19 +346,23 @@ void itemize(struct file_struct *file, i
+@@ -340,19 +347,23 @@ void itemize(struct file_struct *file, i
: S_ISDIR(file->mode) ? !omit_dir_times
: !S_ISLNK(file->mode);
} else
iflags |= ITEM_IS_NEW;
-@@ -604,7 +615,7 @@ void check_for_finished_hlinks(int itemi
+@@ -605,7 +616,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,
+ char *cmpbuf, statx *sxp, int itemizing,
int maybe_ATTRS_REPORT, enum logcode code)
{
- int save_ignore_times = ignore_times;
-@@ -618,7 +629,7 @@ static int try_dests_reg(struct file_str
+ int best_match = -1;
+@@ -614,7 +625,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
+@@ -622,16 +633,20 @@ static int try_dests_reg(struct file_str
match_level = 1;
/* FALL THROUGH */
case 1:
continue;
best_match = j;
match_level = 3;
-@@ -652,14 +667,14 @@ static int try_dests_reg(struct file_str
+@@ -646,14 +661,14 @@ static int try_dests_reg(struct file_str
if (j != best_match) {
j = best_match;
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
- if (link_stat(cmpbuf, stp, 0) < 0)
+ if (link_stat(cmpbuf, &sxp->st, 0) < 0)
- match_level = 0;
+ return -1;
}
if (match_level == 3 && !copy_dest) {
cmpbuf, 1,
itemizing && verbose > 1,
code) < 0)
-@@ -668,8 +683,13 @@ static int try_dests_reg(struct file_str
- hard_link_cluster(file, ndx, itemizing, code);
+@@ -665,8 +680,13 @@ static int try_dests_reg(struct file_str
+ }
} else
#endif
- if (itemizing)
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
+@@ -682,8 +702,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)
-@@ -710,13 +735,18 @@ static int try_dests_non(struct file_str
+@@ -707,13 +732,18 @@ static int try_dests_non(struct file_str
enum logcode code)
{
char fnamebuf[MAXPATHLEN];
continue;
if (S_ISLNK(file->mode)) {
#ifdef SUPPORT_LINKS
-@@ -729,10 +759,10 @@ static int try_dests_non(struct file_str
+@@ -726,10 +756,10 @@ static int try_dests_non(struct file_str
#endif
continue;
} else if (IS_SPECIAL(file->mode)) {
continue;
} else {
rprintf(FERROR,
-@@ -763,7 +793,15 @@ static int try_dests_non(struct file_str
+@@ -760,7 +790,15 @@ static int try_dests_non(struct file_str
int changes = compare_dest ? 0 : ITEM_LOCAL_CHANGE
+ (link_dest ? ITEM_XNAME_FOLLOWS : 0);
char *lp = link_dest ? "" : NULL;
}
if (verbose > 1 && maybe_ATTRS_REPORT) {
rprintf(FCLIENT, "%s is uptodate\n", fname);
-@@ -775,6 +813,7 @@ static int try_dests_non(struct file_str
+@@ -772,6 +810,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
-@@ -796,7 +835,8 @@ static void recv_generator(char *fname,
+@@ -793,7 +832,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;
-@@ -852,6 +892,9 @@ static void recv_generator(char *fname,
+@@ -849,6 +889,9 @@ static void recv_generator(char *fname,
} else if (!dry_run)
return;
}
if (dry_run > 1) {
statret = -1;
stat_errno = ENOENT;
-@@ -859,7 +902,7 @@ static void recv_generator(char *fname,
+@@ -856,7 +899,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
-- && safe_stat(dn, &st) < 0
-+ && safe_stat(dn, &sx.st) < 0
+- && do_stat(dn, &st) < 0
++ && do_stat(dn, &sx.st) < 0
&& create_directory_path(fname) < 0) {
rsyserr(FERROR, errno,
"recv_generator: mkdir %s failed",
-@@ -871,6 +914,10 @@ static void recv_generator(char *fname,
+@@ -868,6 +911,10 @@ static void recv_generator(char *fname,
}
if (fuzzy_basis)
need_fuzzy_dirlist = 1;
}
parent_dirname = dn;
-@@ -879,7 +926,7 @@ static void recv_generator(char *fname,
+@@ -876,7 +923,7 @@ static void recv_generator(char *fname,
need_fuzzy_dirlist = 0;
}
keep_dirlinks && S_ISDIR(file->mode));
stat_errno = errno;
}
-@@ -897,8 +944,9 @@ static void recv_generator(char *fname,
+@@ -894,8 +941,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)) {
-@@ -907,8 +955,8 @@ static void recv_generator(char *fname,
+@@ -904,8 +952,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. */
return;
statret = -1;
}
-@@ -917,7 +965,11 @@ static void recv_generator(char *fname,
- dry_run++;
- }
- if (itemizing && f_out != -1) {
-- itemize(file, ndx, statret, &st,
+@@ -920,7 +968,11 @@ static void recv_generator(char *fname,
+ sr = -1;
+ new_root_dir = 0;
+ }
+- itemize(file, ndx, sr, &st,
+#ifdef SUPPORT_ACLS
-+ if (preserve_acls && statret == 0)
++ if (preserve_acls && sr == 0)
+ get_acl(fname, &sx);
+#endif
-+ itemize(file, ndx, statret, &sx,
- statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
++ itemize(file, ndx, sr, &sx,
+ sr ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
}
if (statret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
-@@ -937,19 +989,19 @@ static void recv_generator(char *fname,
+@@ -940,19 +992,19 @@ static void recv_generator(char *fname,
return;
}
}
- if (set_file_attrs(fname, file, statret ? NULL : &st, 0)
+ if (set_file_attrs(fname, file, statret ? NULL : &sx, 0)
- && verbose && code && f_out != -1)
+ && verbose && code != FNONE && f_out != -1)
rprintf(code, "%s/\n", fname);
if (delete_during && f_out != -1 && !phase && dry_run < 2
&& (file->flags & FLAG_DEL_HERE))
if (preserve_links && S_ISLNK(file->mode)) {
#ifdef SUPPORT_LINKS
-@@ -967,7 +1019,7 @@ static void recv_generator(char *fname,
+@@ -970,7 +1022,7 @@ static void recv_generator(char *fname,
char lnk[MAXPATHLEN];
int len;
&& (len = readlink(fname, lnk, MAXPATHLEN-1)) > 0) {
lnk[len] = 0;
/* A link already pointing to the
-@@ -975,10 +1027,10 @@ static void recv_generator(char *fname,
+@@ -978,10 +1030,10 @@ static void recv_generator(char *fname,
* required. */
if (strcmp(lnk, file->u.link) == 0) {
if (itemizing) {
maybe_ATTRS_REPORT);
if (preserve_hard_links
&& file->link_u.links) {
-@@ -991,9 +1043,9 @@ static void recv_generator(char *fname,
+@@ -996,9 +1048,9 @@ static void recv_generator(char *fname,
}
/* Not the right symlink (or not a symlink), so
* delete it. */
statret = -1;
} else if (basis_dir[0] != NULL) {
if (try_dests_non(file, fname, ndx, itemizing,
-@@ -1009,7 +1061,7 @@ static void recv_generator(char *fname,
+@@ -1015,7 +1067,7 @@ static void recv_generator(char *fname,
}
}
if (preserve_hard_links && file->link_u.links
itemizing, code, HL_SKIP))
return;
if (do_symlink(file->u.link,fname) != 0) {
-@@ -1018,7 +1070,7 @@ static void recv_generator(char *fname,
+@@ -1024,7 +1076,7 @@ static void recv_generator(char *fname,
} else {
set_file_attrs(fname, file, NULL, 0);
if (itemizing) {
+ itemize(file, ndx, statret, &sx,
ITEM_LOCAL_CHANGE, 0, NULL);
}
- if (code && verbose) {
-@@ -1052,18 +1104,22 @@ static void recv_generator(char *fname,
- itemizing = code = 0;
+ if (code != FNONE && verbose) {
+@@ -1059,18 +1111,22 @@ static void recv_generator(char *fname,
+ code = FNONE;
}
}
+#ifdef SUPPORT_ACLS
statret = -1;
if (verbose > 2) {
rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
-@@ -1076,7 +1132,7 @@ static void recv_generator(char *fname,
+@@ -1083,7 +1139,7 @@ static void recv_generator(char *fname,
} else {
set_file_attrs(fname, file, NULL, 0);
if (itemizing) {
+ itemize(file, ndx, statret, &sx,
ITEM_LOCAL_CHANGE, 0, NULL);
}
- if (code && verbose)
-@@ -1088,12 +1144,12 @@ static void recv_generator(char *fname,
+ if (code != FNONE && verbose)
+@@ -1097,14 +1153,14 @@ static void recv_generator(char *fname,
}
} else {
if (itemizing)
+ set_file_attrs(fname, file, &sx, maybe_ATTRS_REPORT);
if (preserve_hard_links && file->link_u.links)
hard_link_cluster(file, ndx, itemizing, code);
+ if (remove_source_files == 1)
+ goto return_with_success;
}
- return;
+ goto cleanup;
}
if (!S_ISREG(file->mode)) {
-@@ -1127,7 +1183,7 @@ static void recv_generator(char *fname,
+@@ -1138,7 +1194,7 @@ static void recv_generator(char *fname,
}
if (update_only && statret == 0
if (verbose > 1)
rprintf(FINFO, "%s is newer\n", fname);
return;
-@@ -1136,18 +1192,18 @@ static void recv_generator(char *fname,
+@@ -1147,20 +1203,20 @@ static void recv_generator(char *fname,
fnamecmp = fname;
fnamecmp_type = FNAMECMP_FNAME;
- int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &st,
+ int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &sx,
itemizing, maybe_ATTRS_REPORT, code);
- if (j == -2)
+ if (j == -2) {
+ if (remove_source_files == 1)
+ goto return_with_success;
- return;
+ goto cleanup;
- if (j != -1) {
+ }
+ if (j >= 0) {
fnamecmp = fnamecmpbuf;
- fnamecmp_type = j;
-@@ -1156,7 +1212,7 @@ static void recv_generator(char *fname,
+@@ -1170,7 +1226,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
-@@ -1175,7 +1231,7 @@ static void recv_generator(char *fname,
+@@ -1189,7 +1245,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;
-@@ -1184,7 +1240,7 @@ static void recv_generator(char *fname,
+@@ -1198,7 +1254,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)
-@@ -1194,31 +1250,44 @@ static void recv_generator(char *fname,
+@@ -1208,39 +1264,52 @@ static void recv_generator(char *fname,
return;
}
- itemize(file, ndx, real_ret, &real_st,
+#ifdef SUPPORT_ACLS
+ if (preserve_acls && real_ret == 0)
-+ get_acl(fname, &real_sx);
++ get_acl(fnamecmp, &real_sx);
+#endif
+ itemize(file, ndx, real_ret, &real_sx,
0, 0, NULL);
+ set_file_attrs(fname, file, &sx, maybe_ATTRS_REPORT);
if (preserve_hard_links && file->link_u.links)
hard_link_cluster(file, ndx, itemizing, code);
+ if (remove_source_files != 1)
+- return;
++ goto cleanup;
+ return_with_success:
+ if (!dry_run) {
+ char numbuf[4];
+ SIVAL(numbuf, 0, ndx);
+ send_msg(MSG_SUCCESS, numbuf, 4);
+ }
- return;
+ goto cleanup;
}
fnamecmp = partialptr;
fnamecmp_type = FNAMECMP_PARTIAL_DIR;
statret = 0;
-@@ -1242,17 +1311,21 @@ static void recv_generator(char *fname,
+@@ -1264,17 +1333,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);
-@@ -1263,7 +1336,7 @@ static void recv_generator(char *fname,
+@@ -1285,7 +1358,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) {
-@@ -1271,14 +1344,14 @@ static void recv_generator(char *fname,
+@@ -1293,14 +1366,14 @@ static void recv_generator(char *fname,
full_fname(backupptr));
free(back_file);
close(fd);
}
if (verbose > 2)
-@@ -1296,24 +1369,32 @@ static void recv_generator(char *fname,
+@@ -1318,24 +1391,32 @@ static void recv_generator(char *fname,
iflags |= ITEM_BASIS_TYPE_FOLLOWS;
if (fnamecmp_type == FNAMECMP_FUZZY)
iflags |= ITEM_XNAME_FOLLOWS;
- itemize(file, -1, real_ret, &real_st, iflags, fnamecmp_type,
+#ifdef SUPPORT_ACLS
+ if (preserve_acls && real_ret == 0)
-+ get_acl(fname, &real_sx);
++ get_acl(fnamecmp, &real_sx);
+#endif
+ itemize(file, -1, real_ret, &real_sx, iflags, fnamecmp_type,
fuzzy_file ? fuzzy_file->basename : NULL);
if (f_copy >= 0) {
close(f_copy);
-@@ -1326,6 +1407,13 @@ static void recv_generator(char *fname,
+@@ -1348,6 +1429,13 @@ static void recv_generator(char *fname,
}
close(fd);
}
void generate_files(int f_out, struct file_list *flist, char *local_name)
-@@ -1385,6 +1473,8 @@ void generate_files(int f_out, struct fi
+@@ -1407,6 +1495,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;
--- old/hlink.c
+++ new/hlink.c
-@@ -25,6 +25,7 @@
-
+@@ -26,6 +26,7 @@
extern int verbose;
+ extern int do_xfers;
extern int link_dest;
+extern int preserve_acls;
extern int make_backups;
+ extern int remove_source_files;
extern int stdout_format_has_i;
- extern char *basis_dir[];
-@@ -143,15 +144,19 @@ void init_hard_links(void)
+@@ -147,15 +148,19 @@ void init_hard_links(void)
#ifdef SUPPORT_HARD_LINKS
static int maybe_hard_link(struct file_struct *file, int ndx,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
0, "");
}
-@@ -166,13 +171,13 @@ static int maybe_hard_link(struct file_s
+@@ -170,13 +175,13 @@ static int maybe_hard_link(struct file_s
return -1;
}
}
enum logcode code, int skip)
{
#ifdef SUPPORT_HARD_LINKS
-@@ -207,7 +212,7 @@ int hard_link_check(struct file_struct *
+@@ -217,7 +222,7 @@ int hard_link_check(struct file_struct *
|| st2.st_ino != st3.st_ino)
continue;
statret = 1;
- st = &st3;
+ sxp->st = st3;
- if (verbose < 2 || !stdout_format_has_i)
- itemizing = code = 0;
- break;
-@@ -215,12 +220,16 @@ int hard_link_check(struct file_struct *
+ if (verbose < 2 || !stdout_format_has_i) {
+ itemizing = 0;
+ code = FNONE;
+@@ -227,12 +232,16 @@ int hard_link_check(struct file_struct *
if (!unchanged_file(cmpbuf, file, &st3))
continue;
statret = 1;
- maybe_hard_link(file, ndx, fname, statret, st,
+ maybe_hard_link(file, ndx, fname, statret, sxp,
toname, &st2, itemizing, code);
- file->F_HLINDEX = FINISHED_LINK;
- } else
-@@ -233,7 +242,7 @@ int hard_link_check(struct file_struct *
+ if (remove_source_files == 1 && do_xfers) {
+ char numbuf[4];
+@@ -250,7 +259,7 @@ int hard_link_check(struct file_struct *
#ifdef SUPPORT_HARD_LINKS
int hard_link_one(struct file_struct *file, int ndx, char *fname,
int itemizing, enum logcode code)
{
if (do_link(toname, fname)) {
-@@ -249,7 +258,11 @@ int hard_link_one(struct file_struct *fi
+@@ -266,7 +275,11 @@ int hard_link_one(struct file_struct *fi
}
if (itemizing) {
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
terse ? "" : toname);
}
-@@ -266,11 +279,12 @@ void hard_link_cluster(struct file_struc
+@@ -283,11 +296,12 @@ void hard_link_cluster(struct file_struc
#ifdef SUPPORT_HARD_LINKS
char hlink1[MAXPATHLEN];
char *hlink2;
return;
if (!(file->flags & FLAG_HLINK_TOL)) {
while (!(file->flags & FLAG_HLINK_EOL)) {
-@@ -284,9 +298,13 @@ void hard_link_cluster(struct file_struc
+@@ -301,9 +315,13 @@ void hard_link_cluster(struct file_struc
if (file->F_HLINDEX != SKIPPED_LINK)
continue;
hlink2 = f_name(file, NULL);
+ if (preserve_acls)
+ free_acl(&sx);
+#endif
- file->F_HLINDEX = FINISHED_LINK;
- } while (!(file->flags & FLAG_HLINK_EOL));
- #endif
+ if (remove_source_files == 1 && do_xfers) {
+ char numbuf[4];
+ SIVAL(numbuf, 0, ndx);
--- old/lib/sysacls.c
+++ new/lib/sysacls.c
-@@ -0,0 +1,3240 @@
+@@ -0,0 +1,3247 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba system utilities for ACL support.
+#include "sysacls.h" /****** ADDED ******/
+
+/****** EXTRAS -- THESE ITEMS ARE NOT FROM THE SAMBA SOURCE ******/
++#ifdef DEBUG
++#undef DEBUG
++#endif
++#define DEBUG(x,y)
++
+void SAFE_FREE(void *mem)
+{
+ if (mem)
+ uid_t user_id;
+
+ /* AIX has no DEFAULT */
-+ if ( type == SMB_ACL_TYPE_DEFAULT )
++ if ( type == SMB_ACL_TYPE_DEFAULT ) {
++ errno = ENOTSUP;
+ return NULL;
++ }
+
+ /* Get the acl using statacl */
+
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
--- old/log.c
+++ new/log.c
-@@ -582,8 +582,10 @@ static void log_formatted(enum logcode c
+@@ -606,8 +606,10 @@ static void log_formatted(enum logcode c
n[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
n[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
n[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
char ch = iflags & ITEM_IS_NEW ? '+' : '?';
---- old/mkproto.awk
-+++ new/mkproto.awk
-@@ -58,7 +58,7 @@ BEGIN {
- next;
- }
-
--!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^uchar|^short|^struct|^BOOL|^void|^time|^const|^RETSIGTYPE/ {
-+!/^OFF_T|^size_t|^off_t|^pid_t|^id_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^uchar|^short|^struct|^BOOL|^void|^time|^const|^RETSIGTYPE/ {
- next;
- }
-
--- old/options.c
+++ new/options.c
@@ -47,6 +47,7 @@ int copy_dirlinks = 0;
int preserve_perms = 0;
int preserve_executability = 0;
int preserve_devices = 0;
-@@ -198,6 +199,7 @@ static void print_rsync_version(enum log
+@@ -199,6 +200,7 @@ static void print_rsync_version(enum log
char const *got_socketpair = "no ";
char const *have_inplace = "no ";
char const *hardlinks = "no ";
char const *links = "no ";
char const *ipv6 = "no ";
STRUCT_STAT *dumstat;
-@@ -214,6 +216,10 @@ static void print_rsync_version(enum log
+@@ -215,6 +217,10 @@ static void print_rsync_version(enum log
hardlinks = "";
#endif
#ifdef SUPPORT_LINKS
links = "";
#endif
-@@ -227,9 +233,9 @@ static void print_rsync_version(enum log
+@@ -228,9 +234,9 @@ static void print_rsync_version(enum log
rprintf(f, "Copyright (C) 1996-2006 by Andrew Tridgell, Wayne Davison, and others.\n");
rprintf(f, "<http://rsync.samba.org/>\n");
rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
/* Note that this field may not have type ino_t. It depends
* on the complicated interaction between largefile feature
-@@ -282,7 +288,7 @@ void usage(enum logcode F)
- rprintf(F," -v, --verbose increase verbosity\n");
+@@ -284,7 +290,7 @@ void usage(enum logcode F)
rprintf(F," -q, --quiet suppress non-error messages\n");
+ rprintf(F," --no-motd suppress daemon-mode MOTD (see manpage caveat)\n");
rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n");
- rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H)\n");
+ rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H, -A)\n");
rprintf(F," --no-OPTION turn off an implied OPTION (e.g. --no-D)\n");
rprintf(F," -r, --recursive recurse into directories\n");
rprintf(F," -R, --relative use relative path names\n");
-@@ -303,6 +309,9 @@ void usage(enum logcode F)
- rprintf(F," -H, --hard-links preserve hard links\n");
+@@ -306,6 +312,9 @@ void usage(enum logcode F)
rprintf(F," -p, --perms preserve permissions\n");
rprintf(F," -E, --executability preserve the file's executability\n");
+ rprintf(F," --chmod=CHMOD affect file and/or directory permissions\n");
+#ifdef SUPPORT_ACLS
+ rprintf(F," -A, --acls preserve ACLs (implies --perms)\n");
+#endif
- rprintf(F," --chmod=CHMOD change destination permissions\n");
rprintf(F," -o, --owner preserve owner (super-user only)\n");
rprintf(F," -g, --group preserve group\n");
-@@ -421,6 +430,9 @@ static struct poptOption long_options[]
+ rprintf(F," --devices preserve device files (super-user only)\n");
+@@ -425,6 +434,9 @@ static struct poptOption long_options[]
{"no-perms", 0, POPT_ARG_VAL, &preserve_perms, 0, 0, 0 },
{"no-p", 0, POPT_ARG_VAL, &preserve_perms, 0, 0, 0 },
{"executability", 'E', POPT_ARG_NONE, &preserve_executability, 0, 0, 0 },
{"times", 't', POPT_ARG_VAL, &preserve_times, 1, 0, 0 },
{"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
{"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
-@@ -1083,6 +1095,24 @@ int parse_arguments(int *argc, const cha
+@@ -1089,6 +1101,24 @@ int parse_arguments(int *argc, const cha
usage(FINFO);
exit_cleanup(0);
default:
/* A large opt value means that set_refuse_options()
* turned this option off. */
-@@ -1528,6 +1558,10 @@ void server_options(char **args,int *arg
+@@ -1530,6 +1560,10 @@ void server_options(char **args,int *arg
if (preserve_hard_links)
argstr[x++] = 'H';
extern struct stats stats;
extern char *stdout_format;
extern char *tmpdir;
-@@ -347,6 +348,10 @@ int recv_files(int f_in, struct file_lis
+@@ -350,6 +351,10 @@ int recv_files(int f_in, struct file_lis
int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i;
enum logcode log_code = log_before_transfer ? FLOG : FINFO;
int max_phase = protocol_version >= 29 ? 2 : 1;
int i, recv_ok;
if (verbose > 2)
-@@ -543,7 +548,16 @@ int recv_files(int f_in, struct file_lis
+@@ -553,7 +558,16 @@ int recv_files(int f_in, struct file_lis
* mode based on the local permissions and some heuristics. */
if (!preserve_perms) {
int exists = fd1 != -1;
+ dflt_perms, exists);
}
- /* We now check to see if we are writing file "inplace" */
+ /* We now check to see if we are writing the file "inplace" */
--- old/rsync.c
+++ new/rsync.c
@@ -32,6 +32,7 @@
/* This is only called when we aren't preserving permissions. Figure out what
* the permissions should be and return them merged back into the mode. */
--mode_t dest_mode(mode_t flist_mode, mode_t cur_mode, int exists)
-+mode_t dest_mode(mode_t flist_mode, mode_t cur_mode, int dflt_perms,
+-mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int exists)
++mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms,
+ int exists)
{
+ int new_mode;
/* If the file already exists, we'll return the local permissions,
- * possibly tweaked by the --executability option. */
-@@ -115,55 +117,63 @@ mode_t dest_mode(mode_t flist_mode, mode
- cur_mode |= (cur_mode & 0444) >> 2;
+@@ -117,56 +119,65 @@ mode_t dest_mode(mode_t flist_mode, mode
+ new_mode |= (new_mode & 0444) >> 2;
}
- } else
-- cur_mode = flist_mode & ACCESSPERMS & ~orig_umask;
-+ cur_mode = flist_mode & ACCESSPERMS & dflt_perms;
- if (daemon_chmod_modes && !S_ISLNK(flist_mode))
- cur_mode = tweak_mode(cur_mode, daemon_chmod_modes);
- return (flist_mode & ~CHMOD_BITS) | (cur_mode & CHMOD_BITS);
+ } else {
+- /* Apply the umask and turn off special permissions. */
+- new_mode = flist_mode & (~CHMOD_BITS | (ACCESSPERMS & ~orig_umask));
++ /* Apply destination default permissions and turn
++ * off special permissions. */
++ new_mode = flist_mode & (~CHMOD_BITS | dflt_perms);
+ }
+ return new_mode;
}
-int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
- STRUCT_STAT st2;
+ statx sx2;
int change_uid, change_gid;
+ mode_t new_mode = file->mode;
- if (!st) {
+ if (!sxp) {
+#ifdef SUPPORT_ACLS
+ sx2.acc_acl = sx2.def_acl = NULL;
+#endif
- if (!preserve_perms && S_ISDIR(file->mode)
+ if (!preserve_perms && S_ISDIR(new_mode)
- && st->st_mode & S_ISGID) {
+ && sx2.st.st_mode & S_ISGID) {
/* We just created this directory and its setgid
* bit is on, so make sure it stays on. */
- file->mode |= S_ISGID;
+ new_mode |= S_ISGID;
}
+ sxp = &sx2;
}
;
else
#endif
-@@ -173,43 +183,55 @@ int set_file_attrs(char *fname, struct f
+@@ -176,45 +187,57 @@ int set_file_attrs(char *fname, struct f
rprintf(FINFO,
"set uid of %s from %ld to %ld\n",
fname,
updated = 1;
}
+ if (daemon_chmod_modes && !S_ISLNK(new_mode))
+ new_mode = tweak_mode(new_mode, daemon_chmod_modes);
++
+#ifdef SUPPORT_ACLS
+ /* It's OK to call set_acl() now, even for a dir, as the generator
+ * will enable owner-writability using chmod, if necessary.
+#endif
+
#ifdef HAVE_CHMOD
-- if ((st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
-- int ret = do_chmod(fname, file->mode);
-+ if ((sxp->st.st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
-+ mode_t mode = file->mode;
-+ int ret = do_chmod(fname, mode);
+- if ((st->st_mode & CHMOD_BITS) != (new_mode & CHMOD_BITS)) {
++ if ((sxp->st.st_mode & CHMOD_BITS) != (new_mode & CHMOD_BITS)) {
+ int ret = do_chmod(fname, new_mode);
if (ret < 0) {
rsyserr(FERROR, errno,
"failed to set permissions on %s",
}
if (ret == 0) /* ret == 1 if symlink could not be set */
updated = 1;
-@@ -222,6 +244,11 @@ int set_file_attrs(char *fname, struct f
+@@ -227,6 +250,11 @@ int set_file_attrs(char *fname, struct f
else
rprintf(FCLIENT, "%s is uptodate\n", fname);
}
--- old/rsync.h
+++ new/rsync.h
-@@ -486,6 +486,15 @@ struct idev {
+@@ -492,6 +492,15 @@ struct idev {
#define IN_LOOPBACKNET 127
#endif
#define GID_NONE ((gid_t)-1)
#define HL_CHECK_MASTER 0
-@@ -646,6 +655,17 @@ struct stats {
+@@ -653,6 +662,17 @@ struct stats {
struct chmod_mode_struct;
#include "byteorder.h"
#include "lib/mdfour.h"
#include "lib/wildmatch.h"
-@@ -661,6 +681,16 @@ struct chmod_mode_struct;
-
+@@ -669,6 +689,16 @@ struct chmod_mode_struct;
#define UNUSED(x) x __attribute__((__unused__))
+ #define NORETURN __attribute__((__noreturn__))
+typedef struct {
+ STRUCT_STAT st;
/* We have replacement versions of these if they're missing. */
--- old/rsync.yo
+++ new/rsync.yo
-@@ -300,7 +300,7 @@ to the detailed description below for a
- -v, --verbose increase verbosity
+@@ -301,7 +301,7 @@ to the detailed description below for a
-q, --quiet suppress non-error messages
+ --no-motd suppress daemon-mode MOTD (see caveat)
-c, --checksum skip based on checksum, not mod-time & size
- -a, --archive archive mode; same as -rlptgoD (no -H)
+ -a, --archive archive mode; same as -rlptgoD (no -H, -A)
--no-OPTION turn off an implied OPTION (e.g. --no-D)
-r, --recursive recurse into directories
-R, --relative use relative path names
-@@ -321,6 +321,7 @@ to the detailed description below for a
- -H, --hard-links preserve hard links
+@@ -323,6 +323,7 @@ to the detailed description below for a
-p, --perms preserve permissions
-E, --executability preserve executability
+ --chmod=CHMOD affect file and/or directory permissions
+ -A, --acls preserve ACLs (implies -p) [non-standard]
- --chmod=CHMOD change destination permissions
-o, --owner preserve owner (super-user only)
-g, --group preserve group
-@@ -746,7 +747,9 @@ quote(itemize(
+ --devices preserve device files (super-user only)
+@@ -753,7 +754,9 @@ quote(itemization(
permissions, though the bf(--executability) option might change just
the execute permission for the file.
it() New files get their "normal" permission bits set to the source
their special permission bits disabled except in the case where a new
directory inherits a setgid bit from its parent directory.
))
-@@ -777,9 +780,11 @@ The preservation of the destination's se
+@@ -784,9 +787,11 @@ The preservation of the destination's se
directories when bf(--perms) is off was added in rsync 2.6.7. Older rsync
versions erroneously preserved the three special permission bits for
newly-created files when bf(--perms) was off, while overriding the
dit(bf(-E, --executability)) This option causes rsync to preserve the
executability (or non-executability) of regular files when bf(--perms) is
-@@ -797,6 +802,15 @@ quote(itemize(
+@@ -804,6 +809,15 @@ quote(itemization(
If bf(--perms) is enabled, this option is ignored.
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
-@@ -1378,8 +1392,8 @@ if the receiving rsync is at least versi
+@@ -1389,8 +1403,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.
-@@ -1428,7 +1442,11 @@ quote(itemize(
+@@ -1439,7 +1453,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).
+
+#endif /* No ACLs. */
+#endif /* _SMB_ACLS_H */
---- old/t_stub.c
-+++ new/t_stub.c
-@@ -79,3 +79,7 @@ struct filter_list_struct server_filter_
- return NULL;
- }
-
-+ const char *who_am_i(void)
-+{
-+ return "test";
-+}
--- old/testsuite/acls.test
+++ new/testsuite/acls.test
@@ -0,0 +1,34 @@
sed -e '/block2\.5/d' \
--- old/testsuite/itemize.test
+++ new/testsuite/itemize.test
-@@ -29,14 +29,14 @@ ln "$fromdir/foo/config1" "$fromdir/foo/
+@@ -29,15 +29,15 @@ ln "$fromdir/foo/config1" "$fromdir/foo/
$RSYNC -iplr "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
+-cd+++++++ ./
-cd+++++++ bar/
-cd+++++++ bar/baz/
->f+++++++ bar/baz/rsync
->f+++++++ foo/config2
->f+++++++ foo/extra
-cL+++++++ foo/sym -> ../bar/baz/rsync
++cd+++++++++ ./
+cd+++++++++ bar/
+cd+++++++++ bar/baz/
+>f+++++++++ bar/baz/rsync
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
-@@ -48,10 +48,10 @@ chmod 601 "$fromdir/foo/config2"
+@@ -49,10 +49,10 @@ chmod 601 "$fromdir/foo/config2"
$RSYNC -iplrH "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
-@@ -68,11 +68,11 @@ chmod 777 "$todir/bar/baz/rsync"
+@@ -69,11 +69,11 @@ chmod 777 "$todir/bar/baz/rsync"
$RSYNC -iplrtc "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
-@@ -97,15 +97,15 @@ $RSYNC -ivvplrtH "$fromdir/" "$todir/" \
+@@ -98,15 +98,15 @@ $RSYNC -ivvplrtH "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed"
-@@ -124,8 +124,8 @@ touch "$todir/foo/config2"
+@@ -125,8 +125,8 @@ touch "$todir/foo/config2"
$RSYNC -iplrtH "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 7 failed"
-@@ -134,15 +134,15 @@ $RSYNC -ivvplrtH --copy-dest="$lddir" "$
+@@ -135,15 +135,15 @@ $RSYNC -ivvplrtH --copy-dest=../ld "$fro
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
--.d..t.... ./
+-cd+++++++ ./
-cd+++++++ bar/
-cd+++++++ bar/baz/
-cf bar/baz/rsync
-cf foo/config2
-hf foo/extra => foo/config1
-cL..T.... foo/sym -> ../bar/baz/rsync
-+.d..t...... ./
++cd+++++++++ ./
+cd+++++++++ bar/
+cd+++++++++ bar/baz/
+cf bar/baz/rsync
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
-@@ -150,11 +150,11 @@ rm -rf "$todir"
- $RSYNC -iplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
+@@ -151,11 +151,11 @@ rm -rf "$todir"
+ $RSYNC -iplrtH --copy-dest=../ld "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
--.d..t.... ./
+-cd+++++++ ./
-cd+++++++ bar/
-cd+++++++ bar/baz/
-cd+++++++ foo/
-hf foo/extra => foo/config1
-+.d..t...... ./
++cd+++++++++ ./
+cd+++++++++ bar/
+cd+++++++++ bar/baz/
+cd+++++++++ foo/
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 9 failed"
-@@ -181,15 +181,15 @@ $RSYNC -ivvplrtH --link-dest="$lddir" "$
+@@ -182,15 +182,15 @@ $RSYNC -ivvplrtH --link-dest="$lddir" "$
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
--.d..t.... ./
+-cd+++++++ ./
-cd+++++++ bar/
-cd+++++++ bar/baz/
-hf bar/baz/rsync
-hf foo/config2
-hf foo/extra => foo/config1
-hL foo/sym -> ../bar/baz/rsync
-+.d..t...... ./
++cd+++++++++ ./
+cd+++++++++ bar/
+cd+++++++++ bar/baz/
+hf bar/baz/rsync
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 11 failed"
-@@ -197,10 +197,10 @@ rm -rf "$todir"
- $RSYNC -iplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
+@@ -198,10 +198,10 @@ rm -rf "$todir"
+ $RSYNC -iplrtH --dry-run --link-dest=../ld "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
--.d..t.... ./
+-cd+++++++ ./
-cd+++++++ bar/
-cd+++++++ bar/baz/
-cd+++++++ foo/
-+.d..t...... ./
++cd+++++++++ ./
+cd+++++++++ bar/
+cd+++++++++ bar/baz/
+cd+++++++++ foo/
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 12 failed"
-@@ -228,14 +228,14 @@ filter_outfile
+@@ -209,10 +209,10 @@ rm -rf "$todir"
+ $RSYNC -iplrtH --link-dest=../ld "$fromdir/" "$todir/" \
+ | tee "$outfile"
+ cat <<EOT >"$chkfile"
+-cd+++++++ ./
+-cd+++++++ bar/
+-cd+++++++ bar/baz/
+-cd+++++++ foo/
++cd+++++++++ ./
++cd+++++++++ bar/
++cd+++++++++ bar/baz/
++cd+++++++++ foo/
+ EOT
+ diff $diffopt "$chkfile" "$outfile" || test_fail "test 13 failed"
+
+@@ -240,14 +240,14 @@ filter_outfile
# TODO fix really-old problem when combining -H with --compare-dest:
# missing output for foo/extra hard-link (and it might not be updated)!
cat <<EOT >"$chkfile"
--.d..t.... ./
+-cd+++++++ ./
-cd+++++++ bar/
-cd+++++++ bar/baz/
-.f bar/baz/rsync
-.f foo/config1
-.f foo/config2
-.L foo/sym -> ../bar/baz/rsync
-+.d..t...... ./
++cd+++++++++ ./
+cd+++++++++ bar/
+cd+++++++++ bar/baz/
+.f bar/baz/rsync
+.f foo/config2
+.L foo/sym -> ../bar/baz/rsync
EOT
- diff $diffopt "$chkfile" "$outfile" || test_fail "test 14 failed"
+ diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
-@@ -243,10 +243,10 @@ rm -rf "$todir"
+@@ -255,10 +255,10 @@ rm -rf "$todir"
$RSYNC -iplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
--.d..t.... ./
+-cd+++++++ ./
-cd+++++++ bar/
-cd+++++++ bar/baz/
-cd+++++++ foo/
-+.d..t...... ./
++cd+++++++++ ./
+cd+++++++++ bar/
+cd+++++++++ bar/baz/
+cd+++++++++ foo/
EOT
- diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
+ diff $diffopt "$chkfile" "$outfile" || test_fail "test 16 failed"
--- old/uidlist.c
+++ new/uidlist.c
extern int numeric_ids;
extern int am_root;
-@@ -275,7 +276,7 @@ void send_uid_list(int f)
+@@ -273,7 +274,7 @@ void send_uid_list(int f)
if (numeric_ids)
return;
int len;
/* we send sequences of uid/byte-length/name */
for (list = uidlist; list; list = list->next) {
-@@ -292,7 +293,7 @@ void send_uid_list(int f)
+@@ -290,7 +291,7 @@ void send_uid_list(int f)
write_int(f, 0);
}
int len;
for (list = gidlist; list; list = list->next) {
if (!list->name)
-@@ -313,7 +314,7 @@ void recv_uid_list(int f, struct file_li
+@@ -311,7 +312,7 @@ void recv_uid_list(int f, struct file_li
int id, i;
char *name;
/* read the uid list */
while ((id = read_int(f)) != 0) {
int len = read_byte(f);
-@@ -325,7 +326,7 @@ void recv_uid_list(int f, struct file_li
+@@ -323,7 +324,7 @@ void recv_uid_list(int f, struct file_li
}
}
/* read the gid list */
while ((id = read_int(f)) != 0) {
int len = read_byte(f);
-@@ -337,6 +338,16 @@ void recv_uid_list(int f, struct file_li
+@@ -335,6 +336,16 @@ void recv_uid_list(int f, struct file_li
}
}
for (i = 0; i < flist->count; i++)
--- old/util.c
+++ new/util.c
-@@ -1555,3 +1555,31 @@ int bitbag_next_bit(struct bitbag *bb, i
+@@ -1468,3 +1468,31 @@ int bitbag_next_bit(struct bitbag *bb, i
return -1;
}