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. */
int len; /* Number of bytes read into `buf'. */
if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {
+ int save_errno = errno;
rsyserr(FERROR_XFER, errno, "open %s", full_fname(source));
+ errno = save_errno;
return -1;
}
if (ofd < 0) {
if (robust_unlink(dest) && errno != ENOENT) {
+ int save_errno = errno;
rsyserr(FERROR_XFER, errno, "unlink %s", full_fname(dest));
+ errno = save_errno;
return -1;
}
- if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0
- && (!create_bak_dir || errno != ENOENT || make_bak_dir(dest) < 0
- || (ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0)) {
- rsyserr(FERROR_XFER, errno, "open %s", full_fname(dest));
- close(ifd);
- return -1;
+ if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0) {
+ int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
+ if (create_bak_dir && errno == ENOENT && make_bak_dir(dest) == 0) {
+ if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0)
+ save_errno = errno ? errno : save_errno;
+ else
+ save_errno = 0;
+ }
+ if (save_errno) {
+ rsyserr(FERROR_XFER, save_errno, "open %s", full_fname(dest));
+ close(ifd);
+ errno = save_errno;
+ return -1;
+ }
}
}
while ((len = safe_read(ifd, buf, sizeof buf)) > 0) {
if (full_write(ofd, buf, len) < 0) {
+ int save_errno = errno;
rsyserr(FERROR_XFER, errno, "write %s", full_fname(dest));
close(ifd);
close(ofd);
+ errno = save_errno;
return -1;
}
}
if (len < 0) {
+ int save_errno = errno;
rsyserr(FERROR_XFER, errno, "read %s", full_fname(source));
close(ifd);
close(ofd);
+ errno = save_errno;
return -1;
}
}
if (close(ofd) < 0) {
+ int save_errno = errno;
rsyserr(FERROR_XFER, errno, "close failed on %s",
full_fname(dest));
+ errno = save_errno;
return -1;
}
+#ifdef SUPPORT_XATTRS
+ if (preserve_xattrs)
+ copy_xattrs(source, dest);
+#endif
+
return 0;
}
switch (errno) {
#ifdef ETXTBSY
case ETXTBSY:
- if (robust_unlink(to) != 0)
+ if (robust_unlink(to) != 0) {
+ errno = ETXTBSY;
return -1;
+ }
+ errno = ETXTBSY;
break;
#endif
case EXDEV:
if (partialptr) {
if (!handle_partial_dir(partialptr,PDIR_CREATE))
- return -1;
+ return -2;
to = partialptr;
}
if (copy_file(from, to, -1, mode, 0) != 0)
} else
use_buf = glob.arg_buf;
- if (from_glob || arg) {
+ if (from_glob || (arg && len)) {
STRUCT_STAT st;
int is_dir;
STRUCT_STAT st;
int statret = do_lstat(dir, &st);
if (statret == 0 && !S_ISDIR(st.st_mode)) {
- if (do_unlink(dir) < 0)
+ if (do_unlink(dir) < 0) {
+ *fn = '/';
return 0;
+ }
statret = -1;
}
- if (statret < 0 && do_mkdir(dir, 0700) < 0)
+ if (statret < 0 && do_mkdir(dir, 0700) < 0) {
+ *fn = '/';
return 0;
+ }
} else
do_rmdir(dir);
*fn = '/';