stat_x sx;
struct file_struct *file;
char *buf;
+ int save_preserve_xattrs = preserve_xattrs;
int kept = 0;
int ret_code;
robust_unlink(fname); /* Just in case... */
}
}
+ preserve_xattrs = 0;
set_file_attrs(buf, file, NULL, fname, 0);
+ preserve_xattrs = save_preserve_xattrs;
unmake_file(file);
if (verbose > 1) {
cleanup:
if (back_file) {
+ int save_preserve_xattrs = preserve_xattrs;
if (f_copy >= 0)
close(f_copy);
+#ifdef SUPPORT_XATTRS
+ if (preserve_xattrs)
+ copy_xattrs(fname, backupptr);
+#endif
+ preserve_xattrs = 0;
set_file_attrs(backupptr, back_file, NULL, NULL, 0);
+ preserve_xattrs = save_preserve_xattrs;
if (verbose > 1) {
rprintf(FINFO, "backed up %s to %s\n",
fname, backupptr);
goto do_set_file_attrs;
}
- if (make_backups > 0 && overwriting_basis && !make_backup(fname))
- return 1;
+ if (make_backups > 0 && overwriting_basis) {
+ if (!make_backup(fname))
+ return 1;
+ fnamecmp = get_backup_name(fname);
+ }
/* Change permissions before putting the file into place. */
set_file_attrs(fnametmp, file, NULL, fnamecmp,
int relative_paths = 0;
int human_readable = 0;
int module_dirlen = 0;
+int preserve_xattrs = 0;
mode_t orig_umask = 002;
char *partial_dir;
char *module_dir;
return -1;
}
+ int copy_xattrs(UNUSED(const char *source), UNUSED(const char *dest))
+{
+ return -1;
+}
+
char *lp_name(UNUSED(int mod))
{
return NULL;
extern int modify_window;
extern int relative_paths;
extern int human_readable;
+extern int preserve_xattrs;
extern char *module_dir;
extern unsigned int module_dirlen;
extern mode_t orig_umask;
/* Copy a file. If ofd < 0, copy_file unlinks and opens the "dest" file.
* Otherwise, it just writes to and closes the provided file descriptor.
+ * In either case, if --xattrs are being preserved, the dest file will
+ * have its xattrs set from the source file.
*
* This is used in conjunction with the --temp-dir, --backup, and
* --copy-dest options. */
return -1;
}
+#ifdef SUPPORT_XATTRS
+ if (preserve_xattrs)
+ copy_xattrs(source, dest);
+#endif
+
return 0;
}
return 0;
}
+int copy_xattrs(const char *source, const char *dest)
+{
+ ssize_t list_len, name_len;
+ size_t datum_len;
+ char *name, *ptr;
+#ifdef HAVE_LINUX_XATTRS
+ int user_only = am_sender ? 0 : !am_root;
+#endif
+
+ /* This puts the name list into the "namebuf" buffer. */
+ if ((list_len = get_xattr_names(source)) < 0)
+ return -1;
+
+ for (name = namebuf; list_len > 0; name += name_len) {
+ name_len = strlen(name) + 1;
+ list_len -= name_len;
+
+#ifdef HAVE_LINUX_XATTRS
+ /* We always ignore the system namespace, and non-root
+ * ignores everything but the user namespace. */
+ if (user_only ? !HAS_PREFIX(name, USER_PREFIX)
+ : HAS_PREFIX(name, SYSTEM_PREFIX))
+ continue;
+#endif
+
+ datum_len = 0;
+ if (!(ptr = get_xattr_data(source, name, &datum_len, 0)))
+ return -1;
+ if (sys_lsetxattr(dest, name, ptr, datum_len) < 0) {
+ int save_errno = errno ? errno : EINVAL;
+ rsyserr(FERROR_XFER, errno,
+ "rsync_xal_set: lsetxattr(\"%s\",\"%s\") failed",
+ dest, name);
+ errno = save_errno;
+ return -1;
+ }
+ free(ptr);
+ }
+
+ return 0;
+}
+
static int find_matching_xattr(item_list *xalp)
{
size_t i, j;