+ if (!skip_atomic) {
+ if (do_rename(tmpname, fname) < 0) {
+ rsyserr(FERROR_XFER, errno, "rename %s -> \"%s\" failed",
+ full_fname(tmpname), full_fname(fname));
+ do_unlink(tmpname);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+#ifdef SUPPORT_HARD_LINKS
+static void handle_skipped_hlink(struct file_struct *file, int itemizing,
+ enum logcode code, int f_out)
+{
+ char fbuf[MAXPATHLEN];
+ int new_last_ndx;
+ struct file_list *save_flist = cur_flist;
+
+ /* If we skip the last item in a chain of links and there was a
+ * prior non-skipped hard-link waiting to finish, finish it now. */
+ if ((new_last_ndx = skip_hard_link(file, &cur_flist)) < 0)
+ return;
+
+ file = cur_flist->files[new_last_ndx - cur_flist->ndx_start];
+ cur_flist->in_progress--; /* undo prior increment */
+ f_name(file, fbuf);
+ recv_generator(fbuf, file, new_last_ndx, itemizing, code, f_out);
+
+ cur_flist = save_flist;
+}
+#endif
+
+static void touch_up_dirs(struct file_list *flist, int ndx)
+{
+ static int counter = 0;
+ struct file_struct *file;
+ char *fname;
+ BOOL fix_dir_perms;
+ int i, start, end;
+
+ if (ndx < 0) {
+ start = 0;
+ end = flist->used - 1;
+ } else
+ start = end = ndx;
+
+ /* Fix any directory permissions that were modified during the
+ * transfer and/or re-set any tweaked modified-time values. */
+ for (i = start; i <= end; i++, counter++) {
+ file = flist->files[i];
+ if (!S_ISDIR(file->mode)
+ || (!implied_dirs && file->flags & FLAG_IMPLIED_DIR))
+ continue;
+ if (DEBUG_GTE(TIME, 2)) {
+ fname = f_name(file, NULL);
+ rprintf(FINFO, "touch_up_dirs: %s (%d)\n",
+ NS(fname), i);
+ }
+ /* Be sure not to retouch permissions with --fake-super. */
+ fix_dir_perms = !am_root && !(file->mode & S_IWUSR);
+ if (!F_IS_ACTIVE(file) || file->flags & FLAG_MISSING_DIR
+ || !(need_retouch_dir_times || fix_dir_perms))
+ continue;
+ fname = f_name(file, NULL);
+ if (fix_dir_perms)
+ do_chmod(fname, file->mode);
+ if (need_retouch_dir_times) {
+ STRUCT_STAT st;
+ if (link_stat(fname, &st, 0) == 0
+ && cmp_time(st.st_mtime, file->modtime) != 0)
+ set_modtime(fname, file->modtime, F_MOD_NSEC(file), file->mode);
+ }
+ if (counter >= loopchk_limit) {
+ if (allowed_lull)
+ maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH);
+ else
+ maybe_flush_socket(0);
+ counter = 0;
+ }
+ }