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