rsync to associate the wrong ACL/xattr information with received files.
static item_list access_acl_list = EMPTY_ITEM_LIST;
static item_list default_acl_list = EMPTY_ITEM_LIST;
+static size_t prior_access_count = (size_t)-1;
+static size_t prior_default_count = (size_t)-1;
+
/* === Calculations on ACL types === */
static const char *str_acl_type(SMB_ACL_TYPE_T type)
/* Turn the ACL data in stat_x into cached ACL data, setting the index
* values in the file struct. */
-void cache_acl(struct file_struct *file, stat_x *sxp)
+void cache_tmp_acl(struct file_struct *file, stat_x *sxp)
{
+ if (prior_access_count == (size_t)-1)
+ prior_access_count = access_acl_list.count;
+
F_ACL(file) = cache_rsync_acl(sxp->acc_acl,
SMB_ACL_TYPE_ACCESS, &access_acl_list);
if (S_ISDIR(sxp->st.st_mode)) {
+ if (prior_default_count == (size_t)-1)
+ prior_default_count = default_acl_list.count;
F_DIR_DEFACL(file) = cache_rsync_acl(sxp->def_acl,
SMB_ACL_TYPE_DEFAULT, &default_acl_list);
}
}
+static void uncache_duo_acls(item_list *duo_list, size_t start)
+{
+ acl_duo *duo_item = duo_list->items;
+ acl_duo *duo_start = duo_item + start;
+
+ duo_item += duo_list->count;
+ duo_list->count = start;
+
+ while (duo_item-- > duo_start) {
+ rsync_acl_free(&duo_item->racl);
+ if (duo_item->sacl)
+ sys_acl_free_acl(duo_item->sacl);
+ }
+}
+
+void uncache_tmp_acls(void)
+{
+ if (prior_access_count != (size_t)-1) {
+ uncache_duo_acls(&access_acl_list, prior_access_count);
+ prior_access_count = (size_t)-1;
+ }
+
+ if (prior_default_count != (size_t)-1) {
+ uncache_duo_acls(&default_acl_list, prior_default_count);
+ prior_default_count = (size_t)-1;
+ }
+}
+
#ifndef HAVE_OSX_ACLS
static mode_t change_sacl_perms(SMB_ACL_T sacl, rsync_acl *racl, mode_t old_mode, mode_t mode)
{
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
get_acl(rel, &sx);
- cache_acl(file, &sx);
+ cache_tmp_acl(file, &sx);
free_acl(&sx);
}
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
get_xattr(rel, &sx);
- cache_xattr(file, &sx);
+ cache_tmp_xattr(file, &sx);
free_xattr(&sx);
}
#endif
set_file_attrs(fbuf, file, NULL, NULL, 0);
unmake_file(file);
+#ifdef SUPPORT_ACLS
+ uncache_tmp_acls();
+#endif
+#ifdef SUPPORT_XATTRS
+ uncache_tmp_xattrs();
+#endif
}
}
*p = '/';
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
get_acl(fname, &sx);
- cache_acl(file, &sx);
+ cache_tmp_acl(file, &sx);
free_acl(&sx);
}
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
get_xattr(fname, &sx);
- cache_xattr(file, &sx);
+ cache_tmp_xattr(file, &sx);
free_xattr(&sx);
}
#endif
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
fname);
unmake_file(file);
+#ifdef SUPPORT_ACLS
+ uncache_tmp_acls();
+#endif
+#ifdef SUPPORT_XATTRS
+ uncache_tmp_xattrs();
+#endif
return 2;
}
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
full_fname(fname), buf);
unmake_file(file);
+#ifdef SUPPORT_ACLS
+ uncache_tmp_acls();
+#endif
+#ifdef SUPPORT_XATTRS
+ uncache_tmp_xattrs();
+#endif
return 0;
}
ret = 2;
preserve_xattrs = save_preserve_xattrs;
unmake_file(file);
+#ifdef SUPPORT_ACLS
+ uncache_tmp_acls();
+#endif
+#ifdef SUPPORT_XATTRS
+ uncache_tmp_xattrs();
+#endif
success:
if (INFO_GTE(BACKUP, 1)) {
static item_list empty_xattr = EMPTY_ITEM_LIST;
static item_list rsync_xal_l = EMPTY_ITEM_LIST;
+static size_t prior_xattr_count = (size_t)-1;
+
/* ------------------------------------------------------------------------- */
static void rsync_xal_free(item_list *xalp)
/* Turn the xattr data in stat_x into cached xattr data, setting the index
* values in the file struct. */
-void cache_xattr(struct file_struct *file, stat_x *sxp)
+void cache_tmp_xattr(struct file_struct *file, stat_x *sxp)
{
int ndx;
if (!sxp->xattr)
return;
+ if (prior_xattr_count == (size_t)-1)
+ prior_xattr_count = rsync_xal_l.count;
ndx = find_matching_xattr(sxp->xattr);
if (ndx < 0)
rsync_xal_store(sxp->xattr); /* adds item to rsync_xal_l */
F_XATTR(file) = ndx;
}
+void uncache_tmp_xattrs(void)
+{
+ if (prior_xattr_count != (size_t)-1) {
+ item_list *xattr_item = rsync_xal_l.items;
+ item_list *xattr_start = xattr_item + prior_xattr_count;
+ xattr_item += rsync_xal_l.count;
+ rsync_xal_l.count = prior_xattr_count;
+ while (xattr_item-- > xattr_start) {
+ rsync_xal_free(xattr_item);
+ free(xattr_item);
+ }
+ prior_xattr_count = (size_t)-1;
+ }
+}
+
static int rsync_xal_set(const char *fname, item_list *xalp,
const char *fnamecmp, stat_x *sxp)
{