+ flist = flist_for_ndx(ndx, "successful_send");
+ file = flist->files[ndx - flist->ndx_start];
+ if (!change_pathname(file, NULL, 0))
+ return;
+ f_name(file, fname);
+
+ 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);
+ }
+}
+
+static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
+ const char *fname, struct file_struct *file,
+ uchar fnamecmp_type, char *buf, int len)
+{
+ write_ndx(f_out, ndx);
+ if (protocol_version < 29)
+ return;
+ write_shortint(f_out, iflags);
+ if (iflags & ITEM_BASIS_TYPE_FOLLOWS)
+ write_byte(f_out, fnamecmp_type);
+ if (iflags & ITEM_XNAME_FOLLOWS)
+ write_vstring(f_out, buf, len);
+#ifdef SUPPORT_XATTRS
+ 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
+}
+
+void send_files(int f_in, int f_out)
+{