+ if (!match_level)
+ return -1;
+
+ if (j != best_match) {
+ j = best_match;
+ pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
+ if (link_stat(cmpbuf, stp, 0) < 0)
+ return -1;
+ }
+
+ if (match_level == 3) {
+#ifdef SUPPORT_HARD_LINKS
+ if (link_dest
+#ifndef CAN_HARDLINK_SYMLINK
+ && !S_ISLNK(file->mode)
+#endif
+#ifndef CAN_HARDLINK_SPECIAL
+ && !IS_SPECIAL(file->mode) && !IS_DEVICE(file->mode)
+#endif
+ && !S_ISDIR(file->mode)) {
+ if (do_link(cmpbuf, fname) < 0) {
+ rsyserr(FERROR, errno,
+ "failed to hard-link %s with %s",
+ cmpbuf, fname);
+ return j;
+ }
+ if (preserve_hard_links && IS_HLINKED(file))
+ hard_link_cluster(file, ndx, itemizing, code, -1);
+ } else
+#endif
+ match_level = 2;
+ if (itemizing && stdout_format_has_i
+ && (verbose > 1 || stdout_format_has_i > 1)) {
+ int chg = compare_dest && type != TYPE_DIR ? 0
+ : ITEM_LOCAL_CHANGE
+ + (match_level == 3 ? ITEM_XNAME_FOLLOWS : 0);
+ char *lp = match_level == 3 ? "" : NULL;
+ itemize(file, ndx, 0, stp, chg + ITEM_MATCHED, 0, lp);
+ }
+ if (verbose > 1 && maybe_ATTRS_REPORT) {
+ rprintf(FCLIENT, "%s%s is uptodate\n",
+ fname, type == TYPE_DIR ? "/" : "");
+ }
+ return -2;
+ }
+
+ return j;
+}
+
+static int phase = 0;
+
+/* Acts on the_file_list->file's ndx'th item, whose name is fname. If a dir,
+ * make sure it exists, and has the right permissions/timestamp info. For
+ * all other non-regular files (symlinks, etc.) we create them here. For
+ * regular files that have changed, we try to find a basis file and then
+ * start sending checksums.
+ *
+ * When fname is non-null, it must point to a MAXPATHLEN buffer!
+ *
+ * Note that f_out is set to -1 when doing final directory-permission and
+ * modification-time repair. */
+static void recv_generator(char *fname, struct file_struct *file, int ndx,
+ int itemizing, int maybe_ATTRS_REPORT,
+ enum logcode code, int f_out)
+{
+ static int missing_below = -1, excluded_below = -1;
+ static const char *parent_dirname = "";
+ static struct file_list *fuzzy_dirlist = NULL;
+ static int need_fuzzy_dirlist = 0;
+ struct file_struct *fuzzy_file = NULL;
+ int fd = -1, f_copy = -1;
+ STRUCT_STAT st, real_st, partial_st;
+ struct file_struct *back_file = NULL;
+ int statret, real_ret, stat_errno;
+ char *fnamecmp, *partialptr, *backupptr = NULL;