Has same return codes as make_backup(). */
| 185 | |
| 186 | /* Has same return codes as make_backup(). */ |
| 187 | static inline int link_or_rename(const char *from, const char *to, |
| 188 | BOOL prefer_rename, STRUCT_STAT *stp) |
| 189 | { |
| 190 | #ifdef SUPPORT_HARD_LINKS |
| 191 | if (!prefer_rename) { |
| 192 | #ifndef CAN_HARDLINK_SYMLINK |
| 193 | if (S_ISLNK(stp->st_mode)) |
| 194 | return 0; /* Use copy code. */ |
| 195 | #endif |
| 196 | #ifndef CAN_HARDLINK_SPECIAL |
| 197 | if (IS_SPECIAL(stp->st_mode) || IS_DEVICE(stp->st_mode)) |
| 198 | return 0; /* Use copy code. */ |
| 199 | #endif |
| 200 | if (do_link_at(from, to) == 0) { |
| 201 | if (DEBUG_GTE(BACKUP, 1)) |
| 202 | rprintf(FINFO, "make_backup: HLINK %s successful.\n", from); |
| 203 | return 2; |
| 204 | } |
| 205 | /* We prefer to rename a regular file rather than copy it. */ |
| 206 | if (!S_ISREG(stp->st_mode) || errno == EEXIST || errno == EISDIR) |
| 207 | return 0; |
| 208 | } |
| 209 | #endif |
| 210 | if (do_rename_at(from, to) == 0) { |
| 211 | if (stp->st_nlink > 1 && !S_ISDIR(stp->st_mode)) { |
| 212 | /* If someone has hard-linked the file into the backup |
| 213 | * dir, rename() might return success but do nothing! */ |
| 214 | robust_unlink(from); /* Just in case... */ |
| 215 | } |
| 216 | if (DEBUG_GTE(BACKUP, 1)) |
| 217 | rprintf(FINFO, "make_backup: RENAME %s successful.\n", from); |
| 218 | return 1; |
| 219 | } |
| 220 | return 0; |
| 221 | } |
| 222 | |
| 223 | /* Hard-link, rename, or copy an item to the backup name. Returns 0 for |
| 224 | * failure, 1 if item was moved, 2 if item was duplicated or hard linked |
no test coverage detected