extern int read_batch;
extern int safe_symlinks;
extern long block_size; /* "long" because popt can't set an int32. */
+extern int unsort_ndx;
extern int max_delete;
extern int force_delete;
extern int one_file_system;
extern int backup_suffix_len;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
extern struct filter_list_struct server_filter_list;
-#ifdef ICONV_OPTION
-extern int ic_ndx;
-#endif
int ignore_perishable = 0;
int non_perishable_cnt = 0;
check_ret:
if (replace && ret != DR_SUCCESS) {
- rprintf(FERROR, "could not make way for new %s: %s\n",
+ rprintf(FERROR_XFER, "could not make way for new %s: %s\n",
replace, fbuf);
}
return ret;
static int remember_delete(struct file_struct *file, const char *fname)
{
int len;
-
+
while (1) {
len = snprintf(deldelay_buf + deldelay_cnt,
deldelay_size - deldelay_cnt,
for (j = 0; j < cur_flist->used; j++) {
struct file_struct *file = cur_flist->sorted[j];
- if (!(file->flags & FLAG_XFER_DIR))
+ if (!(file->flags & FLAG_CONTENT_DIR))
continue;
f_name(file, fbuf);
rprintf(FINFO, " \r");
}
-int unchanged_attrs(const char *fname, struct file_struct *file, statx *sxp)
+int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
{
+#ifndef HAVE_LUTIMES
+ if (S_ISLNK(file->mode)) {
+ ;
+ } else
+#endif
+ if (preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0)
+ return 0;
+
if (preserve_perms && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
return 0;
}
void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statret,
- statx *sxp, int32 iflags, uchar fnamecmp_type,
+ stat_x *sxp, int32 iflags, uchar fnamecmp_type,
const char *xname)
{
if (statret >= 0) { /* A from-dest-dir statret can == 1! */
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
|| (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0))
iflags |= ITEM_REPORT_TIME;
+#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
+ if (S_ISLNK(file->mode)) {
+ ;
+ } else
+#endif
if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
iflags |= ITEM_REPORT_PERMS;
if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid)
return lowest_j;
}
+/* Copy a file found in our --copy-dest handling. */
+static int copy_altdest_file(const char *src, const char *dest, struct file_struct *file)
+{
+ char buf[MAXPATHLEN];
+ const char *copy_to, *partialptr;
+ int ok, fd_w;
+
+ if (inplace) {
+ /* Let copy_file open the destination in place. */
+ fd_w = -1;
+ copy_to = dest;
+ } else {
+ fd_w = open_tmpfile(buf, dest, file);
+ if (fd_w < 0)
+ return -1;
+ copy_to = buf;
+ }
+ cleanup_set(copy_to, NULL, NULL, -1, -1);
+ if (copy_file(src, copy_to, fd_w, file->mode, 0) < 0) {
+ if (verbose) {
+ rsyserr(FINFO, errno, "copy_file %s => %s",
+ full_fname(src), copy_to);
+ }
+ /* Try to clean up. */
+ unlink(copy_to);
+ cleanup_disable();
+ return -1;
+ }
+ partialptr = partial_dir ? partial_dir_fname(dest) : NULL;
+ ok = finish_transfer(dest, copy_to, src, partialptr, file, 1, 0);
+ cleanup_disable();
+ return ok ? 0 : -1;
+}
+
/* This is only called for regular files. We return -2 if we've finished
* handling the file, -1 if no dest-linking occurred, or a non-negative
* value if we found an alternate basis file. */
static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
- char *cmpbuf, statx *sxp, int itemizing,
+ char *cmpbuf, stat_x *sxp, int itemizing,
enum logcode code)
{
int best_match = -1;
case 2:
if (!unchanged_attrs(cmpbuf, file, sxp))
continue;
- if (always_checksum > 0 && preserve_times
- && cmp_time(sxp->st.st_mtime, file->modtime))
- continue;
best_match = j;
match_level = 3;
break;
#ifdef SUPPORT_HARD_LINKS
try_a_copy: /* Copy the file locally. */
#endif
- if (copy_file(cmpbuf, fname, file->mode, 0) < 0) {
- if (verbose) {
- rsyserr(FINFO, errno, "copy_file %s => %s",
- full_fname(cmpbuf), fname);
- }
+ if (!dry_run && copy_altdest_file(cmpbuf, fname, file) < 0)
return -1;
- }
- set_file_attrs(fname, file, NULL, cmpbuf, 0);
if (itemizing)
itemize(cmpbuf, file, ndx, 0, sxp, ITEM_LOCAL_CHANGE, 0, NULL);
#ifdef SUPPORT_XATTRS
* handling the file, or -1 if no dest-linking occurred, or a non-negative
* value if we found an alternate basis file. */
static int try_dests_non(struct file_struct *file, char *fname, int ndx,
- char *cmpbuf, statx *sxp, int itemizing,
+ char *cmpbuf, stat_x *sxp, int itemizing,
enum logcode code)
{
char lnk[MAXPATHLEN];
#endif
&& !S_ISDIR(file->mode)) {
if (do_link(cmpbuf, fname) < 0) {
- rsyserr(FERROR, errno,
+ rsyserr(FERROR_XFER, errno,
"failed to hard-link %s with %s",
cmpbuf, fname);
return j;
static int need_fuzzy_dirlist = 0;
struct file_struct *fuzzy_file = NULL;
int fd = -1, f_copy = -1;
- statx sx, real_sx;
+ stat_x sx, real_sx;
STRUCT_STAT partial_st;
struct file_struct *back_file = NULL;
int statret, real_ret, stat_errno;
char *fnamecmp, *partialptr, *backupptr = NULL;
char fnamecmpbuf[MAXPATHLEN];
uchar fnamecmp_type;
- int implied_dirs_are_missing = relative_paths && !implied_dirs && !inc_recurse;
+ int implied_dirs_are_missing = relative_paths && !implied_dirs && protocol_version < 30;
int del_opts = delete_mode || force_delete ? DEL_RECURSE : 0;
if (verbose > 2)
if (list_only) {
if (S_ISDIR(file->mode)
- && ((!implied_dirs && !(file->flags & FLAG_XFER_DIR))
+ && ((!implied_dirs && file->flags & FLAG_IMPLIED_DIR)
|| (inc_recurse && ndx != cur_flist->ndx_start - 1)))
return;
list_file_entry(file);
if (relative_paths && !implied_dirs
&& do_stat(dn, &sx.st) < 0
&& create_directory_path(fname) < 0) {
- rsyserr(FERROR, errno,
+ rsyserr(FERROR_XFER, errno,
"recv_generator: mkdir %s failed",
full_fname(dn));
}
}
if (S_ISDIR(file->mode)) {
- if (!implied_dirs && !(file->flags & FLAG_XFER_DIR))
+ if (!implied_dirs && file->flags & FLAG_IMPLIED_DIR)
goto cleanup;
if (inc_recurse && ndx != cur_flist->ndx_start - 1) {
- /* In inc_recurse mode we want ot make sure any missing
+ /* In inc_recurse mode we want to make sure any missing
* directories get created while we're still processing
* the parent dir (which allows us to touch the parent
* dir's mtime right away). We will handle the dir in
if (!relative_paths || errno != ENOENT
|| create_directory_path(fname) < 0
|| (do_mkdir(fname, file->mode) < 0 && errno != EEXIST)) {
- rsyserr(FERROR, errno,
+ rsyserr(FERROR_XFER, errno,
"recv_generator: mkdir %s failed",
full_fname(fname));
skipping_dir_contents:
if (!am_root && !(file->mode & S_IWUSR) && dir_tweaking) {
mode_t mode = file->mode | S_IWUSR;
if (do_chmod(fname, mode) < 0) {
- rsyserr(FERROR, errno,
+ rsyserr(FERROR_XFER, errno,
"failed to modify permissions on %s",
full_fname(fname));
}
}
}
else if (delete_during && f_out != -1 && !phase && dry_run < 2
- && (file->flags & FLAG_XFER_DIR))
+ && (file->flags & FLAG_CONTENT_DIR))
delete_in_dir(fname, file, &real_sx.st.st_dev);
goto cleanup;
}
set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
if (itemizing)
itemize(fname, file, ndx, 0, &sx, 0, 0, NULL);
-#ifdef SUPPORT_HARD_LINKS
+#if defined SUPPORT_HARD_LINKS && defined CAN_HARDLINK_SYMLINK
if (preserve_hard_links && F_IS_HLINKED(file))
finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1);
#endif
}
#endif
if (do_symlink(sl, fname) != 0) {
- rsyserr(FERROR, errno, "symlink %s -> \"%s\" failed",
+ rsyserr(FERROR_XFER, errno, "symlink %s -> \"%s\" failed",
full_fname(fname), sl);
} else {
set_file_attrs(fname, file, NULL, NULL, 0);
(long)major(rdev), (long)minor(rdev));
}
if (do_mknod(fname, file->mode, rdev) < 0) {
- rsyserr(FERROR, errno, "mknod %s failed",
+ rsyserr(FERROR_XFER, errno, "mknod %s failed",
full_fname(fname));
} else {
set_file_attrs(fname, file, NULL, NULL, 0);
#endif
if (stat_errno == ENOENT)
goto notify_others;
- rsyserr(FERROR, stat_errno, "recv_generator: failed to stat %s",
+ rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s",
full_fname(fname));
goto cleanup;
}
goto cleanup;
if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
goto pretend_missing;
- if (copy_file(fname, backupptr, back_file->mode, 1) < 0) {
+ if (copy_file(fname, backupptr, -1, back_file->mode, 1) < 0) {
unmake_file(back_file);
back_file = NULL;
goto cleanup;
goto pretend_missing;
}
if (robust_unlink(backupptr) && errno != ENOENT) {
- rsyserr(FERROR, errno, "unlink %s",
+ rsyserr(FERROR_XFER, errno, "unlink %s",
full_fname(backupptr));
unmake_file(back_file);
back_file = NULL;
if ((f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0
&& (errno != ENOENT || make_bak_dir(backupptr) < 0
|| (f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0)) {
- rsyserr(FERROR, errno, "open %s",
+ rsyserr(FERROR_XFER, errno, "open %s",
full_fname(backupptr));
unmake_file(back_file);
back_file = NULL;
for (i = start; i <= end; i++, counter++) {
file = flist->files[i];
if (!S_ISDIR(file->mode)
- || (relative_paths && !implied_dirs && !(file->flags & FLAG_XFER_DIR)))
+ || (!implied_dirs && file->flags & FLAG_IMPLIED_DIR))
continue;
if (verbose > 3) {
fname = f_name(file, NULL);
char fbuf[MAXPATHLEN];
int ndx;
+ while (1) {
#ifdef SUPPORT_HARD_LINKS
- while (preserve_hard_links && (ndx = get_hlink_num()) != -1) {
- flist = flist_for_ndx(ndx);
- assert(flist != NULL);
- file = flist->files[ndx - flist->ndx_start];
- assert(file->flags & FLAG_HLINKED);
- finish_hard_link(file, f_name(file, fbuf), ndx, NULL, itemizing, code, -1);
- }
+ if (preserve_hard_links && (ndx = get_hlink_num()) != -1) {
+ flist = flist_for_ndx(ndx);
+ assert(flist != NULL);
+ file = flist->files[ndx - flist->ndx_start];
+ assert(file->flags & FLAG_HLINKED);
+ finish_hard_link(file, f_name(file, fbuf), ndx, NULL, itemizing, code, -1);
+ flist->in_progress--;
+ continue;
+ }
#endif
- while (check_redo && (ndx = get_redo_num()) != -1) {
- csum_length = SUM_LENGTH;
- max_size = -max_size;
- min_size = -min_size;
- ignore_existing = -ignore_existing;
- ignore_non_existing = -ignore_non_existing;
- update_only = -update_only;
- always_checksum = -always_checksum;
- size_only = -size_only;
- append_mode = -append_mode;
- make_backups = -make_backups; /* avoid dup backup w/inplace */
- ignore_times++;
-
- flist = cur_flist;
- cur_flist = flist_for_ndx(ndx);
-
- file = cur_flist->files[ndx - cur_flist->ndx_start];
- if (solo_file)
- strlcpy(fbuf, solo_file, sizeof fbuf);
- else
- f_name(file, fbuf);
- recv_generator(fbuf, file, ndx, itemizing, code, sock_f_out);
- cur_flist->to_redo--;
-
- cur_flist = flist;
-
- csum_length = SHORT_SUM_LENGTH;
- max_size = -max_size;
- min_size = -min_size;
- ignore_existing = -ignore_existing;
- ignore_non_existing = -ignore_non_existing;
- update_only = -update_only;
- always_checksum = -always_checksum;
- size_only = -size_only;
- append_mode = -append_mode;
- make_backups = -make_backups;
- ignore_times--;
- }
-
- while (cur_flist != first_flist) { /* only possible with inc_recurse */
+ if (check_redo && (ndx = get_redo_num()) != -1) {
+ csum_length = SUM_LENGTH;
+ max_size = -max_size;
+ min_size = -min_size;
+ ignore_existing = -ignore_existing;
+ ignore_non_existing = -ignore_non_existing;
+ update_only = -update_only;
+ always_checksum = -always_checksum;
+ size_only = -size_only;
+ append_mode = -append_mode;
+ make_backups = -make_backups; /* avoid dup backup w/inplace */
+ ignore_times++;
+
+ flist = cur_flist;
+ cur_flist = flist_for_ndx(ndx);
+
+ file = cur_flist->files[ndx - cur_flist->ndx_start];
+ if (solo_file)
+ strlcpy(fbuf, solo_file, sizeof fbuf);
+ else
+ f_name(file, fbuf);
+ recv_generator(fbuf, file, ndx, itemizing, code, sock_f_out);
+ cur_flist->to_redo--;
+
+ cur_flist = flist;
+
+ csum_length = SHORT_SUM_LENGTH;
+ max_size = -max_size;
+ min_size = -min_size;
+ ignore_existing = -ignore_existing;
+ ignore_non_existing = -ignore_non_existing;
+ update_only = -update_only;
+ always_checksum = -always_checksum;
+ size_only = -size_only;
+ append_mode = -append_mode;
+ make_backups = -make_backups;
+ ignore_times--;
+ continue;
+ }
+
+ if (cur_flist == first_flist)
+ break;
+
+ /* We only get here if inc_recurse is enabled. */
if (first_flist->in_progress || first_flist->to_redo)
break;
if (delete_during == 2 || !dir_tweaking) {
/* Skip directory touch-up. */
- } else if (first_flist->ndx_start != 0)
+ } else if (first_flist->parent_ndx >= 0)
touch_up_dirs(dir_flist, first_flist->parent_ndx);
flist_free(first_flist); /* updates first_flist */
}
#endif
- if (inc_recurse && cur_flist->ndx_start) {
+ if (inc_recurse && cur_flist->parent_ndx >= 0) {
struct file_struct *fp = dir_flist->files[cur_flist->parent_ndx];
f_name(fp, fbuf);
ndx = cur_flist->ndx_start - 1;
recv_generator(fbuf, fp, ndx, itemizing, code, f_out);
- if (delete_during && dry_run < 2) {
- if (BITS_SETnUNSET(fp->flags, FLAG_XFER_DIR, FLAG_MISSING_DIR)) {
+ if (delete_during && dry_run < 2 && !list_only) {
+ if (BITS_SETnUNSET(fp->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR)) {
dev_t dirdev;
if (one_file_system) {
uint32 *devp = F_DIR_DEV_P(fp);
if (!F_IS_ACTIVE(file))
continue;
-#ifdef ICONV_OPTION
- if (ic_ndx)
+ if (unsort_ndx)
ndx = F_NDX(file);
else
-#endif
ndx = i + cur_flist->ndx_start;
if (solo_file)