+ int i = 0;
+
+ do {
+ pathjoin(fnamebuf, MAXPATHLEN, basis_dir[i], fname);
+ if (link_stat(fnamebuf, &st, 0) < 0 || S_ISDIR(st.st_mode)
+ || !unchanged_attrs(file, &st))
+ continue;
+ if (IS_DEVICE(file->mode)) {
+ if (!IS_DEVICE(st.st_mode) || st.st_rdev != file->u.rdev)
+ continue;
+ } else if (IS_SPECIAL(file->mode)) {
+ if (!IS_SPECIAL(st.st_mode) || st.st_rdev != file->u.rdev)
+ continue;
+#ifdef CAN_HARDLINK_SYMLINK
+ } else if (S_ISLNK(file->mode)) {
+#ifdef SUPPORT_LINKS
+ char lnk[MAXPATHLEN];
+ int len;
+ if ((len = readlink(fnamebuf, lnk, MAXPATHLEN-1)) <= 0)
+ continue;
+ lnk[len] = '\0';
+ if (strcmp(lnk, file->u.link) != 0)
+#endif
+ continue;
+#endif
+ } else {
+ rprintf(FERROR,
+ "internal: try_dests_non() called with invalid mode (%o)\n",
+ file->mode);
+ exit_cleanup(RERR_UNSUPPORTED);
+ }
+ if (link_dest) {
+ if (do_link(fnamebuf, fname) < 0) {
+ rsyserr(FERROR, errno,
+ "failed to hard-link %s with %s",
+ fnamebuf, fname);
+ break;
+ }
+ if (preserve_hard_links && file->link_u.links)
+ hard_link_cluster(file, ndx, itemizing, code);
+ }
+ if (itemizing && log_format_has_i && verbose > 1) {
+ int changes = compare_dest ? 0 : ITEM_LOCAL_CHANGE
+ + (link_dest ? ITEM_XNAME_FOLLOWS : 0);
+ char *lp = link_dest ? "" : NULL;
+ itemize(file, ndx, 0, &st, changes, 0, lp);
+ }
+ if (verbose > 1 && maybe_ATTRS_REPORT) {
+ code = daemon_log_format_has_i || dry_run
+ ? FCLIENT : FINFO;
+ rprintf(code, "%s is uptodate\n", fname);
+ }
+ return -2;
+ } while (basis_dir[++i] != NULL);
+
+ return -1;
+}
+
+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 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;