-
- if ((statret == -1) && (compare_dest != NULL)) {
- /* try the file at compare_dest instead */
- int saveerrno = errno;
- snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
- statret = link_stat(fnamecmpbuf,&st);
- if (!S_ISREG(st.st_mode))
- statret = -1;
- if (statret == -1)
- errno = saveerrno;
- else
- fnamecmp = fnamecmpbuf;
+ fnamecmp_type = FNAMECMP_FNAME;
+
+ if (statret == -1 && basis_dir[0] != NULL) {
+ int fallback_match = -1;
+ int match_level = 0;
+ int i = 0;
+ do {
+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
+ basis_dir[i], fname);
+ if (link_stat(fnamecmpbuf, &st, 0) == 0
+ && S_ISREG(st.st_mode)) {
+ statret = 0;
+ if (link_dest) {
+ if (!match_level) {
+ fallback_match = i;
+ match_level = 1;
+ } else if (match_level == 2
+ && !unchanged_attrs(file, &st))
+ continue;
+ if (!unchanged_file(fnamecmpbuf, file, &st))
+ continue;
+ fallback_match = i;
+ match_level = 2;
+ if (!unchanged_attrs(file, &st))
+ continue;
+ }
+ match_level = 3;
+ break;
+ }
+ } while (basis_dir[++i] != NULL);
+ if (statret == 0) {
+ if (match_level < 3) {
+ i = fallback_match;
+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
+ basis_dir[i], fname);
+ }
+#if HAVE_LINK
+ if (link_dest && match_level == 3 && !dry_run) {
+ if (do_link(fnamecmpbuf, fname) < 0) {
+ if (verbose) {
+ rsyserr(FINFO, errno,
+ "link %s => %s",
+ full_fname(fnamecmpbuf),
+ safe_fname(fname));
+ }
+ fnamecmp = fnamecmpbuf;
+ fnamecmp_type = i;
+ }
+ } else
+#endif
+ {
+ fnamecmp = fnamecmpbuf;
+ fnamecmp_type = i;
+ }
+ }