This is only called for regular files. We return -2 if we've finished * handling the file, -1 if no dest-linking occurred, or a non-negative * value if we found an alternate basis file. If we're called with the * find_exact_for_existing flag, the destination file already exists, so * we only try to find an exact alt-dest match. In this case, the returns * are only -2 & -1 (both as above).
| 952 | * we only try to find an exact alt-dest match. In this case, the returns |
| 953 | * are only -2 & -1 (both as above). */ |
| 954 | static int try_dests_reg(struct file_struct *file, char *fname, int ndx, |
| 955 | char *cmpbuf, stat_x *sxp, int find_exact_for_existing, |
| 956 | int itemizing, enum logcode code) |
| 957 | { |
| 958 | STRUCT_STAT real_st = sxp->st; |
| 959 | int best_match = -1; |
| 960 | int match_level = 0; |
| 961 | int j = 0; |
| 962 | |
| 963 | do { |
| 964 | pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname); |
| 965 | if (link_stat(cmpbuf, &sxp->st, 0) < 0 || !S_ISREG(sxp->st.st_mode)) |
| 966 | continue; |
| 967 | if (match_level == 0) { |
| 968 | best_match = j; |
| 969 | match_level = 1; |
| 970 | } |
| 971 | if (!quick_check_ok(FT_REG, cmpbuf, file, &sxp->st)) |
| 972 | continue; |
| 973 | if (match_level == 1) { |
| 974 | best_match = j; |
| 975 | match_level = 2; |
| 976 | } |
| 977 | if (unchanged_attrs(cmpbuf, file, sxp)) { |
| 978 | best_match = j; |
| 979 | match_level = 3; |
| 980 | break; |
| 981 | } |
| 982 | free_stat_x(sxp); |
| 983 | } while (basis_dir[++j] != NULL); |
| 984 | |
| 985 | if (!match_level) |
| 986 | goto got_nothing_for_ya; |
| 987 | |
| 988 | if (j != best_match) { |
| 989 | j = best_match; |
| 990 | pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname); |
| 991 | if (link_stat(cmpbuf, &sxp->st, 0) < 0) |
| 992 | goto got_nothing_for_ya; |
| 993 | } |
| 994 | |
| 995 | if (match_level == 3 && alt_dest_type != COPY_DEST) { |
| 996 | if (find_exact_for_existing) { |
| 997 | if (alt_dest_type == LINK_DEST && real_st.st_dev == sxp->st.st_dev && real_st.st_ino == sxp->st.st_ino) |
| 998 | return -1; |
| 999 | if (do_unlink_at(fname) < 0 && errno != ENOENT) |
| 1000 | goto got_nothing_for_ya; |
| 1001 | } |
| 1002 | #ifdef SUPPORT_HARD_LINKS |
| 1003 | if (alt_dest_type == LINK_DEST) { |
| 1004 | if (!hard_link_one(file, fname, cmpbuf, 1)) |
| 1005 | goto try_a_copy; |
| 1006 | if (atimes_ndx) |
| 1007 | set_file_attrs(fname, file, sxp, NULL, 0); |
| 1008 | if (preserve_hard_links && F_IS_HLINKED(file)) |
| 1009 | finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j); |
| 1010 | if (!maybe_ATTRS_REPORT && (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) { |
| 1011 | itemize(cmpbuf, file, ndx, 1, sxp, |
no test coverage detected