X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/05c36015f79d0d2975f15b08e31ea72825700f11..bd685982389b78a158921b7839bdeca501338d19:/sender.c diff --git a/sender.c b/sender.c index 600ad847..ebc8839f 100644 --- a/sender.c +++ b/sender.c @@ -123,8 +123,10 @@ static struct sum_struct *receive_sums(int f) void successful_send(int ndx) { char fname[MAXPATHLEN]; + char *failed_op; struct file_struct *file; struct file_list *flist; + STRUCT_STAT st; if (!remove_source_files) return; @@ -135,11 +137,31 @@ void successful_send(int ndx) return; f_name(file, fname); - if (do_unlink(fname) == 0) { + if (do_lstat(fname, &st) < 0) { + failed_op = "re-lstat"; + goto failed; + } + + if (st.st_size != F_LENGTH(file) || st.st_mtime != file->modtime +#ifdef ST_MTIME_NSEC + || (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file)) +#endif + ) { + rprintf(FERROR, "ERROR: Skipping sender remove for changed file: %s\n", fname); + return; + } + + if (do_unlink(fname) < 0) { + failed_op = "remove"; + failed: + if (errno == ENOENT) + rprintf(FINFO, "sender file already removed: %s\n", fname); + else + rsyserr(FERROR, errno, "sender failed to %s %s", failed_op, fname); + } else { if (INFO_GTE(REMOVE, 1)) rprintf(FINFO, "sender removed %s\n", fname); - } else - rsyserr(FERROR, errno, "sender failed to remove %s", fname); + } } static void write_ndx_and_attrs(int f_out, int ndx, int iflags, @@ -155,7 +177,8 @@ static void write_ndx_and_attrs(int f_out, int ndx, int iflags, if (iflags & ITEM_XNAME_FOLLOWS) write_vstring(f_out, buf, len); #ifdef SUPPORT_XATTRS - if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers) + if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers + && (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))) send_xattr_request(fname, file, f_out); #endif } @@ -236,7 +259,8 @@ void send_files(int f_in, int f_out) rprintf(FINFO, "send_files(%d, %s%s%s)\n", ndx, path,slash,fname); #ifdef SUPPORT_XATTRS - if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers) + if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers + && (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))) recv_xattr_request(file, f_in); #endif