popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
--- old/acls.c
+++ new/acls.c
-@@ -0,0 +1,1098 @@
+@@ -0,0 +1,1096 @@
+/*
+ * Handle passing Access Control Lists between systems.
+ *
+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 === */
+ free_acl(sxp);
+ return -1;
+ }
-+ } else if (errno == ENOTSUP) {
++ } else if (errno == ENOTSUP || errno == ENOSYS) {
+ /* ACLs are not supported, so pretend we have a basic ACL. */
+ if (type == SMB_ACL_TYPE_ACCESS)
+ rsync_acl_fake_perms(racl, sxp->st.st_mode);
+ sxp->def_acl = racl;
+ }
+
-+ /* Avoid sending values that can be inferred from other data,
-+ * but only when preserve_acls == 1 (it is 2 when we must be
-+ * backward compatible with older acls.diff versions). */
-+ if (type == SMB_ACL_TYPE_ACCESS && preserve_acls == 1)
++ /* Avoid sending values that can be inferred from other data. */
++ if (type == SMB_ACL_TYPE_ACCESS)
+ rsync_acl_strip_perms(racl);
+ if ((ndx = find_matching_rsync_acl(type, racl_list, racl)) != -1) {
+ write_byte(f, type == SMB_ACL_TYPE_ACCESS ? 'a' : 'd');
+{
+ SMB_ACL_TYPE_T type;
+ item_list *racl_list;
-+ char *ndx_ptr;
+
+ if (S_ISLNK(file->mode))
+ return;
+
+ type = SMB_ACL_TYPE_ACCESS;
+ racl_list = &access_acl_list;
-+ ndx_ptr = (char*)file + file_struct_len;
+ do {
+ char tag = read_byte(f);
+ int ndx;
+ exit_cleanup(RERR_STREAMIO);
+ }
+ }
-+ SIVAL(ndx_ptr, 0, ndx);
++ if (type == SMB_ACL_TYPE_ACCESS)
++ F_ACL(file) = ndx;
++ else
++ F_DEFACL(file) = ndx;
+ racl_list = &default_acl_list;
-+ ndx_ptr += 4;
+ } while (BUMP_TYPE(type) && S_ISDIR(file->mode));
+}
+
+ SMB_ACL_TYPE_T type;
+ rsync_acl *racl;
+ item_list *racl_list;
-+ char *ndx_ptr;
+ int ndx;
+
+ if (S_ISLNK(file->mode))
+ type = SMB_ACL_TYPE_ACCESS;
+ racl = sxp->acc_acl;
+ racl_list = &access_acl_list;
-+ ndx_ptr = (char*)file + file_struct_len;
+ do {
+ if (!racl)
+ ndx = -1;
+ new_duo->sacl = NULL;
+ *racl = empty_rsync_acl;
+ }
-+ SIVAL(ndx_ptr, 0, ndx);
++ if (type == SMB_ACL_TYPE_ACCESS)
++ F_ACL(file) = ndx;
++ else
++ F_DEFACL(file) = ndx;
+ racl = sxp->def_acl;
+ racl_list = &default_acl_list;
-+ ndx_ptr += 4;
+ } while (BUMP_TYPE(type) && S_ISDIR(sxp->st.st_mode));
+
+ free_acl(sxp);
+{
+ int unchanged = 1;
+ SMB_ACL_TYPE_T type;
-+ char *ndx_ptr;
+
+ if (!dry_run && (read_only || list_only)) {
+ errno = EROFS;
+ return 1;
+
+ type = SMB_ACL_TYPE_ACCESS;
-+ ndx_ptr = (char*)file + file_struct_len;
+ do {
+ acl_duo *duo_item;
++ int32 ndx;
+ BOOL eq;
-+ int32 ndx = IVAL(ndx_ptr, 0);
-+
-+ ndx_ptr += 4;
+
+ if (type == SMB_ACL_TYPE_ACCESS) {
++ ndx = F_ACL(file);
+ if (ndx < 0 || (size_t)ndx >= access_acl_list.count)
+ continue;
+ duo_item = access_acl_list.items;
+ eq = sxp->acc_acl
+ && rsync_acl_equal_enough(sxp->acc_acl, &duo_item->racl, file->mode);
+ } else {
++ ndx = F_DEFACL(file);
+ if (ndx < 0 || (size_t)ndx >= default_acl_list.count)
+ continue;
+ duo_item = default_acl_list.items;
+ /* Couldn't get an ACL. Darn. */
+ switch (errno) {
+ case ENOTSUP:
-+ /* ACLs are disabled. We could yell at the user to turn them on, but... */
++ case ENOSYS:
++ /* No ACLs are available. */
+ break;
+ case ENOENT:
+ if (dry_run) {
+#endif /* SUPPORT_ACLS */
--- old/backup.c
+++ new/backup.c
-@@ -29,6 +29,7 @@ extern char *backup_suffix;
- extern char *backup_dir;
+@@ -23,6 +23,7 @@
+ extern int verbose;
extern int am_root;
+extern int preserve_acls;
extern int preserve_devices;
extern int preserve_specials;
extern int preserve_links;
-@@ -94,7 +95,8 @@ path
+@@ -95,7 +96,8 @@ path
****************************************************************************/
static int make_bak_dir(char *fullpath)
{
char *rel = fullpath + backup_dir_len;
char *end = rel + strlen(rel);
char *p = end;
-@@ -126,15 +128,24 @@ static int make_bak_dir(char *fullpath)
+@@ -127,15 +129,24 @@ static int make_bak_dir(char *fullpath)
if (p >= rel) {
/* Try to transfer the directory settings of the
* actual dir that the files are coming from. */
}
}
*p = '/';
-@@ -172,15 +183,18 @@ static int robust_move(const char *src,
+@@ -173,15 +184,18 @@ static int robust_move(const char *src,
* We will move the file to be deleted into a parallel directory tree. */
static int keep_backup(const char *fname)
{
if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
return 1; /* the file could have disappeared */
-@@ -188,6 +202,13 @@ static int keep_backup(const char *fname
- if (!(buf = get_backup_name(fname)))
+@@ -191,6 +205,13 @@ static int keep_backup(const char *fname
return 0;
+ }
+#ifdef SUPPORT_ACLS
+ if (preserve_acls) {
/* Check to see if this is a device file, or link */
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|| (preserve_specials && IS_SPECIAL(file->mode))) {
-@@ -256,7 +277,7 @@ static int keep_backup(const char *fname
+@@ -261,7 +282,7 @@ static int keep_backup(const char *fname
if (robust_move(fname, buf) != 0) {
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
full_fname(fname), buf);
extern int preserve_links;
extern int preserve_hard_links;
extern int preserve_devices;
-@@ -135,6 +136,8 @@ static void list_file_entry(struct file_
+@@ -143,6 +144,8 @@ static void list_file_entry(struct file_
permstring(permbuf, f->mode);
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
-@@ -496,6 +499,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;
-+#ifdef SUPPORT_ACLS
-+ int xtra_len;
-+#endif
- OFF_T file_length;
- char *basename, *dirname, *bp;
- struct file_struct *file;
-@@ -599,13 +605,27 @@ static struct file_struct *receive_file_
-
- sum_len = always_checksum && S_ISREG(mode) ? MD4_SUM_LENGTH : 0;
+@@ -621,6 +624,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)
-+ xtra_len = (S_ISDIR(mode) ? 2 : 1) * 4;
-+ else
-+ xtra_len = 0;
++ extra_len += (S_ISDIR(mode) ? 2 : 1) * sizeof (union flist_extras);
+#endif
+
- alloc_len = file_struct_len + dirname_len + basename_len
-+#ifdef SUPPORT_ACLS
-+ + xtra_len
-+#endif
- + linkname_len + sum_len;
- bp = pool_alloc(flist->file_pool, alloc_len, "receive_file_entry");
-
- file = (struct file_struct *)bp;
- memset(bp, 0, file_struct_len);
- bp += file_struct_len;
-+#ifdef SUPPORT_ACLS
-+ bp += xtra_len;
-+#endif
+ sum_len = always_checksum && S_ISREG(mode) ? MD4_SUM_LENGTH : 0;
- file->modtime = modtime;
- file->length = file_length;
-@@ -700,6 +720,11 @@ static struct file_struct *receive_file_
- read_buf(f, sum, checksum_len);
+ alloc_len = file_struct_len + dirname_len + basename_len
+@@ -725,6 +734,11 @@ static struct file_struct *recv_file_ent
+ read_buf(f, bp, checksum_len);
}
+#ifdef SUPPORT_ACLS
return file;
}
-@@ -957,6 +982,9 @@ static struct file_struct *send_file_nam
+@@ -977,6 +991,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);
-@@ -966,6 +994,15 @@ static struct file_struct *send_file_nam
+@@ -986,11 +1003,24 @@ 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);
-@@ -973,6 +1010,15 @@ static struct file_struct *send_file_nam
- if (file->basename[0]) {
- flist->files[flist->count++] = file;
- send_file_entry(file, f);
-+#ifdef SUPPORT_ACLS
-+ if (preserve_acls && f >= 0)
-+ send_acl(&sx, f);
-+#endif
-+ } else {
+ flist->files[flist->count++] = file;
+ send_file_entry(file, f);
+#ifdef SUPPORT_ACLS
-+ if (preserve_acls && f >= 0)
-+ free_acl(&sx);
++ if (preserve_acls && f >= 0)
++ send_acl(&sx, f);
+#endif
- }
return file;
}
+
--- old/generator.c
+++ new/generator.c
@@ -35,6 +35,7 @@ extern int do_progress;
extern int preserve_links;
extern int preserve_devices;
extern int preserve_specials;
-@@ -85,6 +86,7 @@ extern long block_size; /* "long" becaus
- extern int max_delete;
- extern int force_delete;
- extern int one_file_system;
-+extern mode_t orig_umask;
+@@ -89,6 +90,7 @@ extern int one_file_system;
+ extern int file_struct_len;
extern struct stats stats;
extern dev_t filesystem_dev;
++extern mode_t orig_umask;
extern char *backup_dir;
-@@ -445,22 +447,27 @@ static void do_delete_pass(struct file_l
+ extern char *backup_suffix;
+ extern int backup_suffix_len;
+@@ -447,22 +449,27 @@ static void do_delete_pass(struct file_l
rprintf(FINFO, " \r");
}
+ && (sxp->st.st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
return 0;
-- if (am_root && preserve_uid && st->st_uid != file->uid)
-+ if (am_root && preserve_uid && sxp->st.st_uid != file->uid)
+- if (am_root && preserve_uid && st->st_uid != F_UID(file))
++ if (am_root && preserve_uid && sxp->st.st_uid != F_UID(file))
return 0;
-- 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)
+- if (preserve_gid && F_GID(file) != GID_NONE && st->st_gid != F_GID(file))
++ if (preserve_gid && F_GID(file) != GID_NONE && sxp->st.st_gid != F_GID(file))
return 0;
+#ifdef SUPPORT_ACLS
int32 iflags, uchar fnamecmp_type, const char *xname)
{
if (statret >= 0) { /* A from-dest-dir statret can == 1! */
-@@ -468,20 +475,24 @@ void itemize(struct file_struct *file, i
+@@ -470,20 +477,24 @@ void itemize(struct file_struct *file, i
: S_ISDIR(file->mode) ? !omit_dir_times
: !S_ISLNK(file->mode);
- if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
+ if ((file->mode & CHMOD_BITS) != (sxp->st.st_mode & CHMOD_BITS))
iflags |= ITEM_REPORT_PERMS;
-- if (preserve_uid && am_root && file->uid != st->st_uid)
-+ if (preserve_uid && am_root && file->uid != sxp->st.st_uid)
+- if (preserve_uid && am_root && F_UID(file) != st->st_uid)
++ if (preserve_uid && am_root && F_UID(file) != sxp->st.st_uid)
iflags |= ITEM_REPORT_OWNER;
- if (preserve_gid && file->gid != GID_NONE
-- && st->st_gid != file->gid)
-+ && sxp->st.st_gid != file->gid)
+ if (preserve_gid && F_GID(file) != GID_NONE
+- && st->st_gid != F_GID(file))
++ && sxp->st.st_gid != F_GID(file))
iflags |= ITEM_REPORT_GROUP;
+#ifdef SUPPORT_ACLS
+ if (preserve_acls && set_acl(NULL, file, sxp) == 0)
} else
iflags |= ITEM_IS_NEW;
-@@ -734,7 +745,7 @@ void check_for_finished_hlinks(int itemi
+@@ -735,7 +746,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;
-@@ -743,7 +754,7 @@ static int try_dests_reg(struct file_str
+@@ -744,7 +755,7 @@ static int try_dests_reg(struct file_str
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
continue;
switch (match_level) {
case 0:
-@@ -751,16 +762,20 @@ static int try_dests_reg(struct file_str
+@@ -752,16 +763,20 @@ static int try_dests_reg(struct file_str
match_level = 1;
/* FALL THROUGH */
case 1:
continue;
best_match = j;
match_level = 3;
-@@ -775,7 +790,7 @@ static int try_dests_reg(struct file_str
+@@ -776,7 +791,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;
}
-@@ -783,7 +798,7 @@ static int try_dests_reg(struct file_str
+@@ -784,15 +799,20 @@ 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);
+ if (hard_link_one(file, ndx, fname, 0, sxp,
cmpbuf, 1, i, code) < 0)
goto try_a_copy;
- if (preserve_hard_links && file->link_u.links) {
-@@ -793,8 +808,13 @@ static int try_dests_reg(struct file_str
- }
+ if (preserve_hard_links && IS_HLINKED(file))
+ hard_link_cluster(file, ndx, itemizing, code, j);
} else
#endif
- if (itemizing)
if (verbose > 1 && maybe_ATTRS_REPORT) {
rprintf(FCLIENT, "%s is uptodate\n", fname);
}
-@@ -810,8 +830,13 @@ static int try_dests_reg(struct file_str
+@@ -808,8 +828,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)
-@@ -832,7 +857,7 @@ static int try_dests_reg(struct file_str
+@@ -830,7 +855,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];
-@@ -864,24 +889,24 @@ static int try_dests_non(struct file_str
+@@ -862,24 +887,24 @@ static int try_dests_non(struct file_str
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
continue;
break;
#endif
-@@ -895,7 +920,7 @@ static int try_dests_non(struct file_str
+@@ -893,7 +918,7 @@ static int try_dests_non(struct file_str
break;
case TYPE_SPECIAL:
case TYPE_DEVICE:
-- if (stp->st_rdev != file->u.rdev)
-+ if (sxp->st.st_rdev != file->u.rdev)
+- if (stp->st_rdev != MAKEDEV(F_DMAJOR(file), F_DMINOR(file)))
++ if (sxp->st.st_rdev != MAKEDEV(F_DMAJOR(file), F_DMINOR(file)))
continue;
break;
#ifdef SUPPORT_LINKS
-@@ -912,7 +937,11 @@ static int try_dests_non(struct file_str
+@@ -910,7 +935,11 @@ static int try_dests_non(struct file_str
match_level = 2;
best_match = j;
}
match_level = 3;
best_match = j;
break;
-@@ -925,7 +954,7 @@ static int try_dests_non(struct file_str
+@@ -923,7 +952,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;
}
-@@ -956,7 +985,15 @@ static int try_dests_non(struct file_str
+@@ -954,7 +983,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",
-@@ -969,6 +1006,7 @@ static int try_dests_non(struct file_str
+@@ -967,6 +1004,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
-@@ -990,7 +1028,8 @@ static void recv_generator(char *fname,
+@@ -988,7 +1026,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;
-@@ -1046,6 +1085,9 @@ static void recv_generator(char *fname,
+@@ -1044,6 +1083,9 @@ static void recv_generator(char *fname,
} else if (!dry_run)
return;
}
if (dry_run > 1) {
statret = -1;
stat_errno = ENOENT;
-@@ -1053,7 +1095,7 @@ static void recv_generator(char *fname,
+@@ -1051,7 +1093,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",
-@@ -1065,6 +1107,10 @@ static void recv_generator(char *fname,
+@@ -1063,6 +1105,10 @@ static void recv_generator(char *fname,
}
if (fuzzy_basis)
need_fuzzy_dirlist = 1;
}
parent_dirname = dn;
-@@ -1074,7 +1120,7 @@ static void recv_generator(char *fname,
+@@ -1072,7 +1118,7 @@ static void recv_generator(char *fname,
need_fuzzy_dirlist = 0;
}
keep_dirlinks && S_ISDIR(file->mode));
stat_errno = errno;
}
-@@ -1092,8 +1138,9 @@ static void recv_generator(char *fname,
+@@ -1090,8 +1136,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)) {
-@@ -1102,8 +1149,8 @@ static void recv_generator(char *fname,
+@@ -1100,8 +1147,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;
}
-@@ -1112,14 +1159,14 @@ static void recv_generator(char *fname,
+@@ -1110,14 +1157,14 @@ static void recv_generator(char *fname,
dry_run++;
}
real_ret = statret;
itemizing, maybe_ATTRS_REPORT, code);
if (j == -2) {
itemizing = 0;
-@@ -1128,7 +1175,11 @@ static void recv_generator(char *fname,
+@@ -1126,7 +1173,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) {
-@@ -1148,21 +1199,21 @@ static void recv_generator(char *fname,
+@@ -1146,21 +1197,21 @@ static void recv_generator(char *fname,
return;
}
}
- real_st.st_dev = filesystem_dev;
+ real_sx.st.st_dev = filesystem_dev;
if (delete_during && f_out != -1 && !phase && dry_run < 2
- && (file->flags & FLAG_DEL_HERE))
+ && (file->flags & FLAG_XFER_DIR))
- delete_in_dir(the_file_list, fname, file, &real_st);
- return;
+ delete_in_dir(the_file_list, fname, file, &real_sx.st);
+ goto cleanup;
}
- if (preserve_hard_links && file->link_u.links
+ if (preserve_hard_links && IS_HLINKED(file)
- && hard_link_check(file, ndx, fname, statret, &st,
+ && hard_link_check(file, ndx, fname, statret, &sx,
itemizing, code, HL_CHECK_MASTER))
if (preserve_links && S_ISLNK(file->mode)) {
#ifdef SUPPORT_LINKS
-@@ -1180,15 +1231,15 @@ static void recv_generator(char *fname,
+@@ -1179,14 +1230,14 @@ static void recv_generator(char *fname,
char lnk[MAXPATHLEN];
int len;
+ if (!S_ISLNK(sx.st.st_mode))
statret = -1;
else if ((len = readlink(fname, lnk, MAXPATHLEN-1)) > 0
- && strncmp(lnk, file->u.link, len) == 0
- && file->u.link[len] == '\0') {
+ && strncmp(lnk, sl, len) == 0 && sl[len] == '\0') {
/* The link is pointing to the right place. */
if (itemizing)
- itemize(file, ndx, 0, &st, 0, 0, NULL);
- set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
+ itemize(file, ndx, 0, &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 (preserve_hard_links && IS_HLINKED(file))
+ hard_link_cluster(file, ndx, itemizing, code, -1);
if (remove_source_files == 1)
-@@ -1197,10 +1248,10 @@ static void recv_generator(char *fname,
+@@ -1195,10 +1246,10 @@ static void recv_generator(char *fname,
}
/* Not the right symlink (or not a symlink), so
* delete it. */
itemizing, maybe_ATTRS_REPORT, code);
if (j == -2) {
#ifndef CAN_HARDLINK_SYMLINK
-@@ -1216,7 +1267,7 @@ static void recv_generator(char *fname,
+@@ -1214,7 +1265,7 @@ static void recv_generator(char *fname,
statret = 1;
}
- if (preserve_hard_links && file->link_u.links
+ if (preserve_hard_links && IS_HLINKED(file)
- && hard_link_check(file, ndx, fname, -1, &st,
+ && hard_link_check(file, ndx, fname, -1, &sx,
itemizing, code, HL_SKIP))
return;
- if (do_symlink(file->u.link, fname) != 0) {
-@@ -1225,7 +1276,7 @@ static void recv_generator(char *fname,
+ if (do_symlink(sl, fname) != 0) {
+@@ -1223,7 +1274,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)
-@@ -1247,31 +1298,36 @@ static void recv_generator(char *fname,
+@@ -1246,31 +1297,36 @@ static void recv_generator(char *fname,
if (statret == 0) {
char *t;
if (IS_DEVICE(file->mode)) {
}
if (statret == 0
- && (st.st_mode & ~CHMOD_BITS) == (file->mode & ~CHMOD_BITS)
-- && st.st_rdev == file->u.rdev) {
+- && st.st_rdev == rdev) {
+ && (sx.st.st_mode & ~CHMOD_BITS) == (file->mode & ~CHMOD_BITS)
-+ && sx.st.st_rdev == file->u.rdev) {
++ && sx.st.st_rdev == rdev) {
/* The device or special file is identical. */
- if (itemizing)
- itemize(file, ndx, 0, &st, 0, 0, NULL);
+ itemize(file, ndx, 0, &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 (preserve_hard_links && IS_HLINKED(file))
+ hard_link_cluster(file, ndx, itemizing, code, -1);
if (remove_source_files == 1)
goto return_with_success;
- return;
itemizing, maybe_ATTRS_REPORT, code);
if (j == -2) {
#ifndef CAN_HARDLINK_SPECIAL
-@@ -1287,7 +1343,7 @@ static void recv_generator(char *fname,
+@@ -1286,7 +1342,7 @@ static void recv_generator(char *fname,
statret = 1;
}
- if (preserve_hard_links && file->link_u.links
+ if (preserve_hard_links && IS_HLINKED(file)
- && hard_link_check(file, ndx, fname, -1, &st,
+ && hard_link_check(file, ndx, fname, -1, &sx,
itemizing, code, HL_SKIP))
return;
if (verbose > 2) {
-@@ -1300,7 +1356,11 @@ static void recv_generator(char *fname,
+@@ -1299,7 +1355,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)
-@@ -1310,7 +1370,7 @@ static void recv_generator(char *fname,
+@@ -1309,7 +1369,7 @@ static void recv_generator(char *fname,
if (remove_source_files == 1)
goto return_with_success;
}
}
if (!S_ISREG(file->mode)) {
-@@ -1344,7 +1404,7 @@ static void recv_generator(char *fname,
+@@ -1343,7 +1403,7 @@ static void recv_generator(char *fname,
}
if (update_only && statret == 0
if (verbose > 1)
rprintf(FINFO, "%s is newer\n", fname);
return;
-@@ -1353,20 +1413,20 @@ static void recv_generator(char *fname,
+@@ -1352,20 +1412,20 @@ static void recv_generator(char *fname,
fnamecmp = fname;
fnamecmp_type = FNAMECMP_FNAME;
}
if (j >= 0) {
fnamecmp = fnamecmpbuf;
-@@ -1376,7 +1436,7 @@ static void recv_generator(char *fname,
+@@ -1375,7 +1435,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
-@@ -1395,7 +1455,7 @@ static void recv_generator(char *fname,
+@@ -1394,7 +1454,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;
-@@ -1404,7 +1464,7 @@ static void recv_generator(char *fname,
+@@ -1403,7 +1463,7 @@ static void recv_generator(char *fname,
if (statret != 0) {
- if (preserve_hard_links && file->link_u.links
+ if (preserve_hard_links && IS_HLINKED(file)
- && hard_link_check(file, ndx, fname, statret, &st,
+ && hard_link_check(file, ndx, fname, statret, &sx,
itemizing, code, HL_SKIP))
return;
if (stat_errno == ENOENT)
-@@ -1414,39 +1474,52 @@ static void recv_generator(char *fname,
+@@ -1413,39 +1473,52 @@ static void recv_generator(char *fname,
return;
}
}
- set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
+ 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 (preserve_hard_links && IS_HLINKED(file))
+ hard_link_cluster(file, ndx, itemizing, code, -1);
if (remove_source_files != 1)
- return;
+ goto cleanup;
fnamecmp = partialptr;
fnamecmp_type = FNAMECMP_PARTIAL_DIR;
statret = 0;
-@@ -1470,17 +1543,21 @@ static void recv_generator(char *fname,
+@@ -1469,17 +1542,21 @@ static void recv_generator(char *fname,
pretend_missing:
/* pretend the file didn't exist */
- if (preserve_hard_links && file->link_u.links
+ if (preserve_hard_links && IS_HLINKED(file)
- && hard_link_check(file, ndx, fname, statret, &st,
+ && hard_link_check(file, ndx, fname, statret, &sx,
itemizing, code, HL_SKIP))
}
if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) {
close(fd);
-@@ -1491,7 +1568,7 @@ static void recv_generator(char *fname,
+@@ -1490,7 +1567,7 @@ static void recv_generator(char *fname,
full_fname(backupptr));
- free(back_file);
+ unmake_file(back_file);
close(fd);
- return;
+ goto cleanup;
}
if ((f_copy = do_open(backupptr,
O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
-@@ -1499,14 +1576,14 @@ static void recv_generator(char *fname,
+@@ -1498,14 +1575,14 @@ static void recv_generator(char *fname,
full_fname(backupptr));
- free(back_file);
+ unmake_file(back_file);
close(fd);
- return;
+ goto cleanup;
}
if (verbose > 2)
-@@ -1524,24 +1601,32 @@ static void recv_generator(char *fname,
+@@ -1523,24 +1600,32 @@ static void recv_generator(char *fname,
iflags |= ITEM_BASIS_TYPE_FOLLOWS;
if (fnamecmp_type == FNAMECMP_FUZZY)
iflags |= ITEM_XNAME_FOLLOWS;
}
if (!do_xfers) {
- if (preserve_hard_links && file->link_u.links)
- hard_link_cluster(file, ndx, itemizing, code);
+ if (preserve_hard_links && IS_HLINKED(file))
+ hard_link_cluster(file, ndx, itemizing, code, -1);
- return;
+ goto cleanup;
}
if (f_copy >= 0) {
close(f_copy);
-@@ -1554,6 +1639,13 @@ static void recv_generator(char *fname,
+@@ -1553,6 +1638,13 @@ static void recv_generator(char *fname,
}
close(fd);
}
void generate_files(int f_out, struct file_list *flist, char *local_name)
-@@ -1615,6 +1707,8 @@ void generate_files(int f_out, struct fi
+@@ -1614,6 +1706,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
-@@ -26,6 +26,7 @@
- extern int verbose;
+@@ -27,6 +27,7 @@ extern int verbose;
+ extern int dry_run;
extern int do_xfers;
extern int link_dest;
+extern int preserve_acls;
extern int make_backups;
+ extern int flist_extra_ndx;
extern int remove_source_files;
- extern int stdout_format_has_i;
-@@ -146,15 +147,19 @@ void init_hard_links(void)
+@@ -155,15 +156,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, "");
}
-@@ -169,13 +174,13 @@ static int maybe_hard_link(struct file_s
+@@ -178,13 +183,13 @@ static int maybe_hard_link(struct file_s
return -1;
}
}
enum logcode code, int skip)
{
#ifdef SUPPORT_HARD_LINKS
-@@ -216,7 +221,7 @@ int hard_link_check(struct file_struct *
+@@ -228,7 +233,7 @@ int hard_link_check(struct file_struct *
|| st2.st_ino != st3.st_ino)
continue;
statret = 1;
if (verbose < 2 || !stdout_format_has_i) {
itemizing = 0;
code = FNONE;
-@@ -226,12 +231,16 @@ int hard_link_check(struct file_struct *
+@@ -238,12 +243,16 @@ int hard_link_check(struct file_struct *
if (!unchanged_file(cmpbuf, file, &st3))
continue;
statret = 1;
toname, &st2, itemizing, code);
if (remove_source_files == 1 && do_xfers) {
char numbuf[4];
-@@ -249,7 +258,7 @@ int hard_link_check(struct file_struct *
+@@ -261,7 +270,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)) {
-@@ -265,7 +274,11 @@ int hard_link_one(struct file_struct *fi
+@@ -277,7 +286,11 @@ int hard_link_one(struct file_struct *fi
}
if (itemizing) {
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
terse ? "" : toname);
}
-@@ -282,11 +295,12 @@ void hard_link_cluster(struct file_struc
+@@ -294,14 +307,15 @@ void hard_link_cluster(struct file_struc
#ifdef SUPPORT_HARD_LINKS
char hlink1[MAXPATHLEN];
char *hlink2;
+ statx sx;
+ STRUCT_STAT st;
int statret, ndx = master;
+ struct hlist *hl = F_HLIST(file);
- file->F_HLINDEX = FINISHED_LINK;
+ hl->hlindex = FINISHED_LINK;
+ if (dry_run)
+ hl->dest_used = dest_used + 1;
- if (link_stat(f_name(file, hlink1), &st1, 0) < 0)
+ if (link_stat(f_name(file, hlink1), &st, 0) < 0)
return;
- if (!(file->flags & FLAG_HLINK_TOL)) {
- while (!(file->flags & FLAG_HLINK_EOL)) {
-@@ -300,9 +314,13 @@ void hard_link_cluster(struct file_struc
- if (file->F_HLINDEX != SKIPPED_LINK)
+ if (!(file->flags & FLAG_HLINK_FIRST)) {
+ while (!(file->flags & FLAG_HLINK_LAST)) {
+@@ -317,9 +331,13 @@ void hard_link_cluster(struct file_struc
+ if (hl->hlindex != SKIPPED_LINK)
continue;
hlink2 = f_name(file, NULL);
- statret = link_stat(hlink2, &st2, 0);
+#endif /* SUPPORT_ACLS */
--- old/log.c
+++ new/log.c
-@@ -614,8 +614,10 @@ static void log_formatted(enum logcode c
+@@ -618,8 +618,10 @@ static void log_formatted(enum logcode c
c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
+ case 'A':
+#ifdef SUPPORT_ACLS
-+ preserve_acls++;
++ preserve_acls = 1;
+ preserve_perms = 1;
+ break;
+#else
default:
/* A large opt value means that set_refuse_options()
* turned this option off. */
-@@ -1529,6 +1559,10 @@ void server_options(char **args,int *arg
+@@ -1223,6 +1253,8 @@ int parse_arguments(int *argc, const cha
+ preserve_uid = flist_extra_ndx++;
+ if (preserve_gid)
+ preserve_gid = flist_extra_ndx++;
++ if (preserve_acls)
++ preserve_acls = flist_extra_ndx++;
+
+ *argv = poptGetArgs(pc);
+ *argc = count_args(*argv);
+@@ -1534,6 +1566,10 @@ void server_options(char **args,int *arg
if (preserve_hard_links)
argstr[x++] = 'H';
if (preserve_gid)
--- old/receiver.c
+++ new/receiver.c
-@@ -47,6 +47,7 @@ extern int keep_partial;
+@@ -48,6 +48,7 @@ extern int keep_partial;
extern int checksum_seed;
extern int inplace;
extern int delay_updates;
extern int preserve_perms;
extern int preserve_executability;
extern int preserve_times;
-@@ -47,7 +48,6 @@ extern int preserve_gid;
+@@ -48,7 +49,6 @@ extern int preserve_gid;
extern int inplace;
extern int keep_dirlinks;
extern int make_backups;
-extern mode_t orig_umask;
extern struct stats stats;
+ extern struct file_list *the_file_list;
extern struct chmod_mode_struct *daemon_chmod_modes;
-
-@@ -100,7 +100,8 @@ void free_sums(struct sum_struct *s)
+@@ -153,7 +153,8 @@ void free_sums(struct sum_struct *s)
/* 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. */
{
int new_mode;
/* If the file already exists, we'll return the local permissions,
-@@ -117,56 +118,65 @@ mode_t dest_mode(mode_t flist_mode, mode
+@@ -170,56 +171,65 @@ mode_t dest_mode(mode_t flist_mode, mode
new_mode |= (new_mode & 0444) >> 2;
}
} else {
updated = 1;
}
-- change_uid = am_root && preserve_uid && st->st_uid != file->uid;
-+ change_uid = am_root && preserve_uid && sxp->st.st_uid != file->uid;
- change_gid = preserve_gid && file->gid != GID_NONE
-- && st->st_gid != file->gid;
-+ && sxp->st.st_gid != file->gid;
+- change_uid = am_root && preserve_uid && st->st_uid != F_UID(file);
++ change_uid = am_root && preserve_uid && sxp->st.st_uid != F_UID(file);
+ change_gid = preserve_gid && F_GID(file) != GID_NONE
+- && st->st_gid != F_GID(file);
++ && sxp->st.st_gid != F_GID(file);
#if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK
- if (S_ISLNK(st->st_mode))
+ if (S_ISLNK(sxp->st.st_mode))
;
else
#endif
-@@ -176,45 +186,57 @@ int set_file_attrs(char *fname, struct f
+@@ -229,45 +239,57 @@ int set_file_attrs(char *fname, struct f
rprintf(FINFO,
"set uid of %s from %ld to %ld\n",
fname,
-- (long)st->st_uid, (long)file->uid);
-+ (long)sxp->st.st_uid, (long)file->uid);
+- (long)st->st_uid, (long)F_UID(file));
++ (long)sxp->st.st_uid, (long)F_UID(file));
}
if (change_gid) {
rprintf(FINFO,
"set gid of %s from %ld to %ld\n",
fname,
-- (long)st->st_gid, (long)file->gid);
-+ (long)sxp->st.st_gid, (long)file->gid);
+- (long)st->st_gid, (long)F_GID(file));
++ (long)sxp->st.st_gid, (long)F_GID(file));
}
}
if (do_lchown(fname,
-- change_uid ? file->uid : st->st_uid,
-- change_gid ? file->gid : st->st_gid) != 0) {
-+ change_uid ? file->uid : sxp->st.st_uid,
-+ change_gid ? file->gid : sxp->st.st_gid) != 0) {
+- change_uid ? F_UID(file) : st->st_uid,
+- change_gid ? F_GID(file) : st->st_gid) != 0) {
++ change_uid ? F_UID(file) : sxp->st.st_uid,
++ change_gid ? F_GID(file) : sxp->st.st_gid) != 0) {
/* shouldn't have attempted to change uid or gid
* unless have the privilege */
rsyserr(FERROR, errno, "%s %s failed",
}
if (ret == 0) /* ret == 1 if symlink could not be set */
updated = 1;
-@@ -227,6 +249,11 @@ int set_file_attrs(char *fname, struct f
+@@ -280,6 +302,11 @@ int set_file_attrs(char *fname, struct f
else
rprintf(FCLIENT, "%s is uptodate\n", fname);
}
--- old/rsync.h
+++ new/rsync.h
-@@ -493,6 +493,14 @@ struct idev {
+@@ -495,6 +495,14 @@ struct idev {
#define IN_LOOPBACKNET 127
#endif
#define GID_NONE ((gid_t)-1)
#define HL_CHECK_MASTER 0
-@@ -656,6 +664,17 @@ struct stats {
+@@ -540,10 +548,12 @@ union flist_extras {
+ /* When enabled, all entries have these: */
+ #define F_UID(f) FLIST_EXTRA(f, preserve_uid).uid
+ #define F_GID(f) FLIST_EXTRA(f, preserve_gid).gid
++#define F_ACL(f) FLIST_EXTRA(f, preserve_acls).num
+
+ /* These are per-entry optional and mutally exclusive: */
+ #define F_IDEV(f) FLIST_EXTRA(f, flist_extra_ndx).idev
+ #define F_HLIST(f) FLIST_EXTRA(f, flist_extra_ndx).hlist
++#define F_DEFACL(f) FLIST_EXTRA(f, flist_extra_ndx).num
+
+ /* These are per-entry optional, but always both or neither: */
+ #define F_DMAJOR(f) FLIST_EXTRA(f, flist_extra_ndx + (IS_HLINKED(f)? 1 : 0)).num
+@@ -667,6 +677,17 @@ struct stats {
struct chmod_mode_struct;
#include "byteorder.h"
#include "lib/mdfour.h"
#include "lib/wildmatch.h"
-@@ -674,6 +693,16 @@ struct chmod_mode_struct;
+@@ -685,6 +706,16 @@ struct chmod_mode_struct;
#define NORETURN __attribute__((__noreturn__))
#endif
extern int numeric_ids;
extern int am_root;
-@@ -273,7 +274,7 @@ void send_uid_list(int f)
- if (numeric_ids)
- return;
+@@ -270,7 +271,7 @@ void send_uid_list(int f)
+ {
+ struct idlist *list;
- if (preserve_uid) {
+ if (preserve_uid || preserve_acls) {
int len;
/* we send sequences of uid/byte-length/name */
for (list = uidlist; list; list = list->next) {
-@@ -290,7 +291,7 @@ void send_uid_list(int f)
+@@ -287,7 +288,7 @@ void send_uid_list(int f)
write_int(f, 0);
}
int len;
for (list = gidlist; list; list = list->next) {
if (!list->name)
-@@ -311,7 +312,7 @@ void recv_uid_list(int f, struct file_li
+@@ -308,7 +309,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);
-@@ -323,7 +324,7 @@ void recv_uid_list(int f, struct file_li
+@@ -320,7 +321,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);
-@@ -335,6 +336,16 @@ void recv_uid_list(int f, struct file_li
+@@ -332,6 +333,16 @@ void recv_uid_list(int f, struct file_li
}
}