Blame SOURCES/rsync-3.1.3-xattr.patch

ecc3bb
diff --git a/xattrs.c b/xattrs.c
ecc3bb
index 508649c0..3c549192 100644
ecc3bb
--- a/xattrs.c
ecc3bb
+++ b/xattrs.c
ecc3bb
@@ -1055,7 +1055,7 @@ int set_xattr(const char *fname, const struct file_struct *file, const char *fna
ecc3bb
 {
ecc3bb
 	rsync_xa_list *glst = rsync_xal_l.items;
ecc3bb
 	item_list *lst;
ecc3bb
-	int ndx;
ecc3bb
+	int ndx, added_write_perm = 0;
ecc3bb
 
ecc3bb
 	if (dry_run)
ecc3bb
 		return 1; /* FIXME: --dry-run needs to compute this value */
ecc3bb
@@ -1084,10 +1084,23 @@ int set_xattr(const char *fname, const struct file_struct *file, const char *fna
ecc3bb
 	}
ecc3bb
 #endif
ecc3bb
 
ecc3bb
+	/* If the target file lacks write permission, we try to add it
ecc3bb
+	 * temporarily so we can change the extended attributes. */
ecc3bb
+	if (!am_root
ecc3bb
+#ifdef SUPPORT_LINKS
ecc3bb
+	 && !S_ISLNK(sxp->st.st_mode)
ecc3bb
+#endif
ecc3bb
+	 && access(fname, W_OK) < 0
ecc3bb
+	 && do_chmod(fname, (sxp->st.st_mode & CHMOD_BITS) | S_IWUSR) == 0)
ecc3bb
+		added_write_perm = 1;
ecc3bb
+
ecc3bb
 	ndx = F_XATTR(file);
ecc3bb
 	glst += ndx;
ecc3bb
 	lst = &glst->xa_items;
ecc3bb
-	return rsync_xal_set(fname, lst, fnamecmp, sxp);
ecc3bb
+	int return_value = rsync_xal_set(fname, lst, fnamecmp, sxp);
ecc3bb
+	if (added_write_perm) /* remove the temporary write permission */
ecc3bb
+		do_chmod(fname, sxp->st.st_mode);
ecc3bb
+	return return_value;
ecc3bb
 }
ecc3bb
 
ecc3bb
 #ifdef SUPPORT_ACLS