+ lib/permstring.o lib/pool_alloc.o lib/sysacls.o @LIBOBJS@
ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
- OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \
- main.o checksum.o match.o syscall.o log.o backup.o
- OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
+ OBJS1=flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o \
+ util.o main.o checksum.o match.o syscall.o log.o backup.o
+ OBJS2=options.o io.o compat.o hlink.o token.o uidlist.o socket.o \
- fileio.o batch.o clientname.o chmod.o
+ fileio.o batch.o clientname.o chmod.o acls.o
OBJS3=progress.o pipe.o
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
--- old/acls.c
+++ new/acls.c
-@@ -0,0 +1,1096 @@
+@@ -0,0 +1,1093 @@
+/*
+ * Handle passing Access Control Lists between systems.
+ *
+extern int read_only;
+extern int list_only;
+extern int orig_umask;
-+extern int preserve_acls;
-+extern int flist_extra_ndx;
-+extern unsigned int file_struct_len;
+
+/* === ACL structures === */
+
+#ifdef SMB_ACL_LOSES_SPECIAL_MODE_BITS
+ /* Ensure that chmod() will be called to restore any lost setid bits. */
+ if (old_mode & (S_ISUID | S_ISGID | S_ISVTX)
-+ && (old_mode & CHMOD_BITS) == (mode & CHMOD_BITS))
++ && BITS_EQUAL(old_mode, mode, CHMOD_BITS))
+ old_mode &= ~(S_ISUID | S_ISGID | S_ISVTX);
+#endif
+
/* If someone has hard-linked the file into the backup
* dir, rename() might return success but do nothing! */
robust_unlink(fname); /* Just in case... */
+--- old/compat.c
++++ new/compat.c
+@@ -50,6 +50,8 @@ void setup_protocol(int f_out,int f_in)
+ preserve_uid = ++file_extra_cnt;
+ if (preserve_gid)
+ preserve_gid = ++file_extra_cnt;
++ if (preserve_acls && !am_sender)
++ preserve_acls = ++file_extra_cnt;
+
+ if (remote_protocol == 0) {
+ if (!read_batch)
--- old/configure.in
+++ new/configure.in
-@@ -537,6 +537,11 @@ if test x"$ac_cv_func_strcasecmp" = x"no
+@@ -542,6 +542,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.
-@@ -801,6 +806,78 @@ AC_SUBST(OBJ_RESTORE)
+@@ -806,6 +811,78 @@ AC_SUBST(OBJ_RESTORE)
AC_SUBST(CC_SHOBJ_FLAG)
AC_SUBST(BUILD_POPT)
--- old/flist.c
+++ new/flist.c
-@@ -40,6 +40,7 @@ extern int filesfrom_fd;
+@@ -41,6 +41,7 @@ extern int filesfrom_fd;
extern int one_file_system;
extern int copy_dirlinks;
extern int keep_dirlinks;
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
-@@ -624,6 +627,12 @@ static struct file_struct *recv_file_ent
+@@ -662,6 +665,12 @@ static struct file_struct *recv_file_ent
}
#endif
+#ifdef SUPPORT_ACLS
+ /* We need one or two index int32s when we're preserving ACLs. */
+ if (preserve_acls)
-+ extra_len += (S_ISDIR(mode) ? 2 : 1) * sizeof (union flist_extras);
++ extra_len += (S_ISDIR(mode) ? 2 : 1) * EXTRA_LEN;
+#endif
+
if (always_checksum && S_ISREG(mode))
extra_len += SUM_EXTRA_CNT * EXTRA_LEN;
-@@ -736,6 +745,11 @@ static struct file_struct *recv_file_ent
- read_buf(f, bp, checksum_len);
+@@ -799,6 +808,11 @@ static struct file_struct *recv_file_ent
+ read_buf(f, bp, checksum_len);
}
+#ifdef SUPPORT_ACLS
return file;
}
-@@ -996,6 +1010,9 @@ static struct file_struct *send_file_nam
- unsigned short flags)
+@@ -1068,6 +1082,9 @@ static struct file_struct *send_file_nam
+ int flags)
{
struct file_struct *file;
+#ifdef SUPPORT_ACLS
file = make_file(fname, flist, stp, flags,
f == -2 ? SERVER_FILTERS : ALL_FILTERS);
-@@ -1005,11 +1022,24 @@ static struct file_struct *send_file_nam
+@@ -1077,12 +1094,26 @@ static struct file_struct *send_file_nam
if (chmod_modes && !S_ISLNK(file->mode))
file->mode = tweak_mode(file->mode, chmod_modes);
flist_expand(flist);
flist->files[flist->count++] = file;
- send_file_entry(file, f);
+- if (f >= 0)
++ if (f >= 0) {
+ send_file_entry(file, f, flist->count - 1);
+#ifdef SUPPORT_ACLS
-+ if (preserve_acls && f >= 0)
-+ send_acl(&sx, f);
++ if (preserve_acls)
++ send_acl(&sx, f);
+#endif
++ }
return file;
}
extern char *backup_dir;
extern char *backup_suffix;
extern int backup_suffix_len;
-@@ -518,22 +520,27 @@ static void do_delete_pass(struct file_l
+@@ -518,21 +520,26 @@ static void do_delete_pass(struct file_l
rprintf(FINFO, " \r");
}
-int unchanged_attrs(struct file_struct *file, STRUCT_STAT *st)
+int unchanged_attrs(struct file_struct *file, statx *sxp)
{
- if (preserve_perms
-- && (unsigned)(st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
-+ && (unsigned)(sxp->st.st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
+- if (preserve_perms && !BITS_EQUAL(st->st_mode, file->mode, CHMOD_BITS))
++ if (preserve_perms && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
return 0;
- if (am_root && preserve_uid && st->st_uid != F_UID(file))
int32 iflags, uchar fnamecmp_type, const char *xname)
{
if (statret >= 0) { /* A from-dest-dir statret can == 1! */
-@@ -541,20 +548,24 @@ void itemize(struct file_struct *file, i
+@@ -540,20 +547,24 @@ void itemize(struct file_struct *file, i
: S_ISDIR(file->mode) ? !omit_dir_times
: !S_ISLNK(file->mode);
- || (keep_time && cmp_time(file->modtime, st->st_mtime) != 0))
+ || (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0))
iflags |= ITEM_REPORT_TIME;
-- if ((unsigned)(st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
-+ if ((unsigned)(sxp->st.st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
+- if (!BITS_EQUAL(st->st_mode, file->mode, CHMOD_BITS))
++ if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
iflags |= ITEM_REPORT_PERMS;
- if (preserve_uid && am_root && F_UID(file) != st->st_uid)
+ if (preserve_uid && am_root && F_UID(file) != sxp->st.st_uid)
} else
iflags |= ITEM_IS_NEW;
-@@ -809,7 +820,7 @@ void check_for_finished_hlinks(int itemi
+@@ -808,7 +819,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,
enum logcode code)
{
int best_match = -1;
-@@ -818,7 +829,7 @@ static int try_dests_reg(struct file_str
+@@ -817,7 +828,7 @@ static int try_dests_reg(struct file_str
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
continue;
switch (match_level) {
case 0:
-@@ -826,16 +837,20 @@ static int try_dests_reg(struct file_str
+@@ -825,16 +836,20 @@ static int try_dests_reg(struct file_str
match_level = 1;
/* FALL THROUGH */
case 1:
continue;
best_match = j;
match_level = 3;
-@@ -850,7 +865,7 @@ static int try_dests_reg(struct file_str
+@@ -849,7 +864,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;
}
-@@ -860,16 +875,25 @@ static int try_dests_reg(struct file_str
+@@ -859,16 +874,25 @@ static int try_dests_reg(struct file_str
if (!hard_link_one(file, fname, cmpbuf, 1))
goto try_a_copy;
if (preserve_hard_links && F_IS_HLINKED(file))
if (verbose > 1 && maybe_ATTRS_REPORT)
rprintf(FCLIENT, "%s is uptodate\n", fname);
return -2;
-@@ -886,8 +910,13 @@ static int try_dests_reg(struct file_str
+@@ -885,8 +909,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)
-@@ -898,7 +927,7 @@ static int try_dests_reg(struct file_str
+@@ -897,7 +926,7 @@ static int try_dests_reg(struct file_str
}
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && F_IS_HLINKED(file))
#endif
return -2;
}
-@@ -910,7 +939,7 @@ static int try_dests_reg(struct file_str
+@@ -909,7 +938,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,
enum logcode code)
{
char lnk[MAXPATHLEN];
-@@ -943,24 +972,24 @@ static int try_dests_non(struct file_str
+@@ -942,24 +971,24 @@ static int try_dests_non(struct file_str
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
continue;
break;
#endif
-@@ -975,7 +1004,7 @@ static int try_dests_non(struct file_str
+@@ -974,7 +1003,7 @@ static int try_dests_non(struct file_str
case TYPE_SPECIAL:
case TYPE_DEVICE:
devp = F_RDEV_P(file);
continue;
break;
#ifdef SUPPORT_LINKS
-@@ -992,7 +1021,11 @@ static int try_dests_non(struct file_str
+@@ -991,7 +1020,11 @@ static int try_dests_non(struct file_str
match_level = 2;
best_match = j;
}
match_level = 3;
best_match = j;
break;
-@@ -1005,7 +1038,7 @@ static int try_dests_non(struct file_str
+@@ -1004,7 +1037,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;
}
-@@ -1036,7 +1069,15 @@ static int try_dests_non(struct file_str
+@@ -1035,7 +1068,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",
-@@ -1049,6 +1090,7 @@ static int try_dests_non(struct file_str
+@@ -1048,6 +1089,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
-@@ -1069,7 +1111,8 @@ static void recv_generator(char *fname,
+@@ -1068,7 +1110,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;
-@@ -1125,6 +1168,9 @@ static void recv_generator(char *fname,
+@@ -1124,6 +1167,9 @@ static void recv_generator(char *fname,
} else if (!dry_run)
return;
}
if (dry_run > 1) {
statret = -1;
stat_errno = ENOENT;
-@@ -1132,7 +1178,7 @@ static void recv_generator(char *fname,
+@@ -1131,7 +1177,7 @@ static void recv_generator(char *fname,
const 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",
-@@ -1144,6 +1190,10 @@ static void recv_generator(char *fname,
+@@ -1143,6 +1189,10 @@ static void recv_generator(char *fname,
}
if (fuzzy_basis)
need_fuzzy_dirlist = 1;
}
parent_dirname = dn;
-@@ -1153,7 +1203,7 @@ static void recv_generator(char *fname,
+@@ -1152,7 +1202,7 @@ static void recv_generator(char *fname,
need_fuzzy_dirlist = 0;
}
keep_dirlinks && S_ISDIR(file->mode));
stat_errno = errno;
}
-@@ -1171,8 +1221,9 @@ static void recv_generator(char *fname,
+@@ -1170,8 +1220,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)) {
-@@ -1181,8 +1232,8 @@ static void recv_generator(char *fname,
+@@ -1180,8 +1231,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;
}
-@@ -1191,14 +1242,14 @@ static void recv_generator(char *fname,
+@@ -1190,14 +1241,14 @@ static void recv_generator(char *fname,
dry_run++;
}
real_ret = statret;
itemizing, code);
if (j == -2) {
itemizing = 0;
-@@ -1207,7 +1258,11 @@ static void recv_generator(char *fname,
+@@ -1206,7 +1257,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) {
-@@ -1227,21 +1282,21 @@ static void recv_generator(char *fname,
+@@ -1226,21 +1281,21 @@ static void recv_generator(char *fname,
return;
}
}
}
#ifdef SUPPORT_HARD_LINKS
- if (preserve_hard_links && F_NOT_HLINK_FIRST(file)
+ if (preserve_hard_links && F_HLINK_NOT_FIRST(file)
- && hard_link_check(file, ndx, fname, statret, &st, itemizing, code))
- return;
+ && hard_link_check(file, ndx, fname, statret, &sx, itemizing, code))
#endif
if (preserve_links && S_ISLNK(file->mode)) {
-@@ -1261,17 +1316,17 @@ static void recv_generator(char *fname,
+@@ -1260,17 +1315,17 @@ static void recv_generator(char *fname,
char lnk[MAXPATHLEN];
int len;
#endif
if (remove_source_files == 1)
goto return_with_success;
-@@ -1279,10 +1334,10 @@ static void recv_generator(char *fname,
+@@ -1278,10 +1333,10 @@ static void recv_generator(char *fname,
}
/* Not the right symlink (or not a symlink), so
* delete it. */
itemizing, code);
if (j == -2) {
#ifndef CAN_HARDLINK_SYMLINK
-@@ -1307,7 +1362,7 @@ static void recv_generator(char *fname,
+@@ -1306,7 +1361,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)
-@@ -1333,33 +1388,38 @@ static void recv_generator(char *fname,
+@@ -1332,33 +1387,38 @@ static void recv_generator(char *fname,
if (statret == 0) {
char *t;
if (IS_DEVICE(file->mode)) {
t = "special file";
}
if (statret == 0
-- && (unsigned)(st.st_mode & ~CHMOD_BITS) == (file->mode & ~CHMOD_BITS)
+- && BITS_EQUAL(st.st_mode, file->mode, _S_IFMT)
- && st.st_rdev == rdev) {
-+ && (unsigned)(sx.st.st_mode & ~CHMOD_BITS) == (file->mode & ~CHMOD_BITS)
++ && BITS_EQUAL(sx.st.st_mode, file->mode, _S_IFMT)
+ && sx.st.st_rdev == rdev) {
/* The device or special file is identical. */
- if (itemizing)
itemizing, code);
if (j == -2) {
#ifndef CAN_HARDLINK_SPECIAL
-@@ -1389,7 +1449,11 @@ static void recv_generator(char *fname,
+@@ -1388,7 +1448,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)
-@@ -1401,7 +1465,7 @@ static void recv_generator(char *fname,
+@@ -1400,7 +1464,7 @@ static void recv_generator(char *fname,
if (remove_source_files == 1)
goto return_with_success;
}
}
if (!S_ISREG(file->mode)) {
-@@ -1435,7 +1499,7 @@ static void recv_generator(char *fname,
+@@ -1434,7 +1498,7 @@ static void recv_generator(char *fname,
}
if (update_only && statret == 0
if (verbose > 1)
rprintf(FINFO, "%s is newer\n", fname);
return;
-@@ -1444,20 +1508,20 @@ static void recv_generator(char *fname,
+@@ -1443,20 +1507,20 @@ static void recv_generator(char *fname,
fnamecmp = fname;
fnamecmp_type = FNAMECMP_FNAME;
}
if (j >= 0) {
fnamecmp = fnamecmpbuf;
-@@ -1467,7 +1531,7 @@ static void recv_generator(char *fname,
+@@ -1466,7 +1530,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
-@@ -1486,7 +1550,7 @@ static void recv_generator(char *fname,
+@@ -1485,7 +1549,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;
-@@ -1505,38 +1569,52 @@ static void recv_generator(char *fname,
+@@ -1504,36 +1568,41 @@ static void recv_generator(char *fname,
return;
}
do_unlink(partialptr);
handle_partial_dir(partialptr, PDIR_DELETE);
}
- if (itemizing) {
-- itemize(file, ndx, statret, &st,
+- if (itemizing)
+- itemize(file, ndx, statret, &st, 0, 0, NULL);
+- set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
++ if (itemizing) {
+#ifdef SUPPORT_ACLS
+ if (preserve_acls && statret == 0)
+ get_acl(fnamecmp, &sx);
+#endif
-+ itemize(file, ndx, statret, &sx,
- 0, 0, NULL);
-+#ifdef SUPPORT_ACLS
-+ //if (preserve_acls) {
-+ //if (fnamecmp_type == FNAMECMP_FNAME) {
-+ //sx.acc_acl = real_sx.acc_acl;
-+ //sx.def_acl = real_sx.def_acl;
-+ //} else
-+ //free_acl(&real_sx);
-+ //}
-+ assert(fnamecmp_type == FNAMECMP_FNAME);
-+#endif
- }
-- set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
++ itemize(file, ndx, statret, &sx, 0, 0, NULL);
++ }
+ set_file_attrs(fname, file, &sx, maybe_ATTRS_REPORT);
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && F_IS_HLINKED(file))
fnamecmp = partialptr;
fnamecmp_type = FNAMECMP_PARTIAL_DIR;
statret = 0;
-@@ -1561,16 +1639,20 @@ static void recv_generator(char *fname,
+@@ -1558,16 +1627,20 @@ static void recv_generator(char *fname,
/* pretend the file didn't exist */
#ifdef SUPPORT_HARD_LINKS
- if (preserve_hard_links && F_NOT_HLINK_LAST(file))
+ if (preserve_hard_links && F_HLINK_NOT_LAST(file))
- return;
+ goto cleanup;
#endif
}
if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) {
close(fd);
-@@ -1581,7 +1663,7 @@ static void recv_generator(char *fname,
+@@ -1578,7 +1651,7 @@ static void recv_generator(char *fname,
full_fname(backupptr));
unmake_file(back_file);
close(fd);
}
if ((f_copy = do_open(backupptr,
O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
-@@ -1589,14 +1671,14 @@ static void recv_generator(char *fname,
+@@ -1586,14 +1659,14 @@ static void recv_generator(char *fname,
full_fname(backupptr));
unmake_file(back_file);
close(fd);
}
if (verbose > 2)
-@@ -1618,26 +1700,34 @@ static void recv_generator(char *fname,
+@@ -1615,26 +1688,34 @@ static void recv_generator(char *fname,
iflags |= ITEM_BASIS_TYPE_FOLLOWS;
if (fnamecmp_type == FNAMECMP_FUZZY)
iflags |= ITEM_XNAME_FOLLOWS;
+ get_acl(fnamecmp, &real_sx);
+#endif
+ itemize(file, -1, real_ret, &real_sx, iflags, fnamecmp_type,
- fuzzy_file ? F_BASENAME(fuzzy_file) : NULL);
+ fuzzy_file ? fuzzy_file->basename : NULL);
+#ifdef SUPPORT_ACLS
+ if (preserve_acls)
+ free_acl(&real_sx);
if (f_copy >= 0) {
close(f_copy);
-@@ -1650,6 +1740,13 @@ static void recv_generator(char *fname,
+@@ -1647,6 +1728,13 @@ static void recv_generator(char *fname,
}
close(fd);
}
void generate_files(int f_out, struct file_list *flist, char *local_name)
-@@ -1716,6 +1813,8 @@ void generate_files(int f_out, struct fi
+@@ -1713,6 +1801,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;
extern int link_dest;
+extern int preserve_acls;
extern int make_backups;
+ extern int protocol_version;
extern int remove_source_files;
- extern int stdout_format_has_i;
-@@ -119,15 +120,19 @@ void match_hard_links(void)
+@@ -268,15 +269,19 @@ void match_hard_links(void)
}
static int maybe_hard_link(struct file_struct *file, int ndx,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
0, "");
}
-@@ -148,7 +153,11 @@ static int maybe_hard_link(struct file_s
+@@ -297,7 +302,11 @@ static int maybe_hard_link(struct file_s
if (hard_link_one(file, fname, oldname, 0)) {
if (itemizing) {
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
realname);
}
-@@ -162,7 +171,7 @@ static int maybe_hard_link(struct file_s
+@@ -311,7 +320,7 @@ static int maybe_hard_link(struct file_s
/* Only called if FLAG_HLINKED is set and FLAG_HLINK_FIRST is not. Returns:
* 0 = process the file, 1 = skip the file, -1 = error occurred. */
int hard_link_check(struct file_struct *file, int ndx, const char *fname,
enum logcode code)
{
STRUCT_STAT prev_st;
-@@ -213,18 +222,20 @@ int hard_link_check(struct file_struct *
+@@ -362,18 +371,20 @@ int hard_link_check(struct file_struct *
if (statret < 0 && basis_dir[0] != NULL) {
/* If we match an alt-dest item, we don't output this as a change. */
char cmpbuf[MAXPATHLEN];
if (verbose < 2 || !stdout_format_has_i) {
itemizing = 0;
code = FNONE;
-@@ -233,16 +244,36 @@ int hard_link_check(struct file_struct *
+@@ -382,16 +393,36 @@ int hard_link_check(struct file_struct *
}
break;
}
realname, itemizing, code) < 0)
return -1;
-@@ -277,7 +308,8 @@ void finish_hard_link(struct file_struct
+@@ -426,7 +457,8 @@ void finish_hard_link(struct file_struct
STRUCT_STAT *stp, int itemizing, enum logcode code,
int alt_dest)
{
char alt_name[MAXPATHLEN], *prev_name;
const char *our_name;
int prev_statret, ndx, prev_ndx = F_HL_PREV(file);
-@@ -301,14 +333,24 @@ void finish_hard_link(struct file_struct
+@@ -450,14 +482,24 @@ void finish_hard_link(struct file_struct
} else
our_name = fname;
int preserve_perms = 0;
int preserve_executability = 0;
int preserve_devices = 0;
-@@ -199,6 +200,7 @@ static void print_rsync_version(enum log
+@@ -198,6 +199,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;
-@@ -215,6 +217,10 @@ static void print_rsync_version(enum log
+@@ -214,6 +216,10 @@ static void print_rsync_version(enum log
hardlinks = "";
#endif
#ifdef SUPPORT_LINKS
links = "";
#endif
-@@ -233,8 +239,8 @@ static void print_rsync_version(enum log
+@@ -232,8 +238,8 @@ static void print_rsync_version(enum log
(int)(sizeof (int64) * 8));
rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
got_socketpair, hardlinks, links, ipv6, have_inplace);
#ifdef MAINTAINER_MODE
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
-@@ -280,7 +286,7 @@ void usage(enum logcode F)
+@@ -279,7 +285,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," --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");
-@@ -302,6 +308,9 @@ void usage(enum logcode F)
+@@ -301,6 +307,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");
rprintf(F," -o, --owner preserve owner (super-user only)\n");
rprintf(F," -g, --group preserve group\n");
rprintf(F," --devices preserve device files (super-user only)\n");
-@@ -422,6 +431,9 @@ static struct poptOption long_options[]
+@@ -421,6 +430,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 },
-@@ -1087,6 +1099,24 @@ int parse_arguments(int *argc, const cha
+@@ -1086,6 +1098,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. */
-@@ -1223,6 +1253,8 @@ int parse_arguments(int *argc, const cha
- preserve_uid = ++flist_extra_cnt;
- if (preserve_gid)
- preserve_gid = ++flist_extra_cnt;
-+ if (preserve_acls)
-+ preserve_acls = ++flist_extra_cnt;
-
- *argv = poptGetArgs(pc);
- *argc = count_args(*argv);
-@@ -1534,6 +1566,10 @@ void server_options(char **args,int *arg
+@@ -1528,6 +1558,10 @@ void server_options(char **args,int *arg
if (preserve_hard_links)
argstr[x++] = 'H';
+#endif
+
#ifdef HAVE_CHMOD
-- if ((st->st_mode & CHMOD_BITS) != (new_mode & CHMOD_BITS)) {
-+ if ((sxp->st.st_mode & CHMOD_BITS) != (new_mode & CHMOD_BITS)) {
+- if (!BITS_EQUAL(st->st_mode, new_mode, CHMOD_BITS)) {
++ if (!BITS_EQUAL(sxp->st.st_mode, new_mode, CHMOD_BITS)) {
int ret = do_chmod(fname, new_mode);
if (ret < 0) {
rsyserr(FERROR, errno,
--- old/rsync.h
+++ new/rsync.h
-@@ -500,6 +500,14 @@ struct idev {
+@@ -532,6 +532,14 @@ struct idev_node {
#define IN_LOOPBACKNET 127
#endif
+
#define GID_NONE ((gid_t)-1)
- struct file_struct {
-@@ -548,10 +556,12 @@ extern int preserve_gid;
+ union file_extras {
+@@ -551,6 +559,7 @@ struct file_struct {
+ extern int file_extra_cnt;
+ extern int preserve_uid;
+ extern int preserve_gid;
++extern int preserve_acls;
+
+ #define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
+ #define EXTRA_LEN (sizeof (union file_extras))
+@@ -583,10 +592,12 @@ extern int preserve_gid;
/* When the associated option is on, all entries will have these present: */
- #define F_UID(f) REQ_EXTRA(f, preserve_uid)->uid
- #define F_GID(f) REQ_EXTRA(f, preserve_gid)->gid
+ #define F_UID(f) REQ_EXTRA(f, preserve_uid)->unum
+ #define F_GID(f) REQ_EXTRA(f, preserve_gid)->unum
+#define F_ACL(f) REQ_EXTRA(f, preserve_acls)->unum
/* These items are per-entry optional and mutally exclusive: */
- #define F_HL_IDEV(f) OPT_EXTRA(f, LEN64_BUMP(f))->idev
+ #define F_HL_GNUM(f) OPT_EXTRA(f, LEN64_BUMP(f))->num
#define F_HL_PREV(f) OPT_EXTRA(f, LEN64_BUMP(f))->num
+#define F_DEF_ACL(f) OPT_EXTRA(f, LEN64_BUMP(f))->unum
/* This optional item might follow an F_HL_*() item.
* (Note: a device doesn't need to check LEN64_BUMP(f).) */
-@@ -687,6 +697,17 @@ struct stats {
+@@ -722,6 +733,17 @@ struct stats {
struct chmod_mode_struct;
#include "byteorder.h"
#include "lib/mdfour.h"
#include "lib/wildmatch.h"
-@@ -705,6 +726,16 @@ struct chmod_mode_struct;
+@@ -740,6 +762,16 @@ struct chmod_mode_struct;
#define NORETURN __attribute__((__noreturn__))
#endif
dit(bf(-E, --executability)) This option causes rsync to preserve the
executability (or non-executability) of regular files when bf(--perms) is
-@@ -805,6 +810,15 @@ quote(itemization(
+@@ -805,6 +810,14 @@ quote(itemization(
If bf(--perms) is enabled, this option is ignored.
+ACLs to be the same as the source ACLs. This nonstandard option only
+works if the remote rsync also supports it. bf(--acls) implies bf(--perms).
+
-+Note also that an optimization of the ACL-sending protocol used by this
-+version makes it incompatible with sending files to an older ACL-enabled
-+rsync unless you double the bf(--acls) option (e.g. bf(-AA)). This
-+doubling is not needed when pulling files from an older rsync.
++The ACL-sending protocol used by this version was first introduced in
++the patch that was shipped with 2.6.8. Sending ACLs to an older version
++of the ACL patch is not supported.
+
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
-@@ -1402,8 +1416,8 @@ if the receiving rsync is at least versi
+@@ -1402,8 +1415,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.
-@@ -1452,7 +1466,11 @@ quote(itemization(
+@@ -1452,7 +1465,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).