Finish off a file transfer: renaming the file and setting the file's * attributes (e.g. permissions, ownership, etc.). If the robust_rename() * call is forced to copy the temp file and partialptr is both non-NULL and * not an absolute path, we stage the file into the partial-dir and then * rename it into place. This returns 1 on success or 0 on failure. */
| 722 | * not an absolute path, we stage the file into the partial-dir and then |
| 723 | * rename it into place. This returns 1 on success or 0 on failure. */ |
| 724 | int finish_transfer(const char *fname, const char *fnametmp, |
| 725 | const char *fnamecmp, const char *partialptr, |
| 726 | struct file_struct *file, int ok_to_set_time, |
| 727 | int overwriting_basis) |
| 728 | { |
| 729 | int ret; |
| 730 | const char *temp_copy_name = partialptr && *partialptr != '/' ? partialptr : NULL; |
| 731 | |
| 732 | if (inplace) { |
| 733 | if (DEBUG_GTE(RECV, 1)) |
| 734 | rprintf(FINFO, "finishing %s\n", fname); |
| 735 | fnametmp = fname; |
| 736 | goto do_set_file_attrs; |
| 737 | } |
| 738 | |
| 739 | if (make_backups > 0 && overwriting_basis) { |
| 740 | int ok = make_backup(fname, False); |
| 741 | if (!ok) |
| 742 | exit_cleanup(RERR_FILEIO); |
| 743 | if (ok == 1 && fnamecmp == fname) |
| 744 | fnamecmp = get_backup_name(fname); |
| 745 | } |
| 746 | |
| 747 | /* Change permissions before putting the file into place. */ |
| 748 | set_file_attrs(fnametmp, file, NULL, fnamecmp, |
| 749 | ok_to_set_time ? ATTRS_ACCURATE_TIME : ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME | ATTRS_SKIP_CRTIME); |
| 750 | |
| 751 | /* move tmp file over real file */ |
| 752 | if (DEBUG_GTE(RECV, 1)) |
| 753 | rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname); |
| 754 | ret = robust_rename(fnametmp, fname, temp_copy_name, file->mode); |
| 755 | if (ret < 0) { |
| 756 | rsyserr(FERROR_XFER, errno, "%s %s -> \"%s\"", |
| 757 | ret == -2 ? "copy" : "rename", |
| 758 | full_fname(fnametmp), fname); |
| 759 | if (!partialptr || (ret == -2 && temp_copy_name) |
| 760 | || robust_rename(fnametmp, partialptr, NULL, file->mode) < 0) |
| 761 | do_unlink_at(fnametmp); |
| 762 | return 0; |
| 763 | } |
| 764 | if (ret == 0) { |
| 765 | /* The file was moved into place (not copied), so it's done. */ |
| 766 | return 1; |
| 767 | } |
| 768 | /* The file was copied, so tweak the perms of the copied file. If it |
| 769 | * was copied to partialptr, move it into its final destination. */ |
| 770 | fnametmp = temp_copy_name ? temp_copy_name : fname; |
| 771 | |
| 772 | do_set_file_attrs: |
| 773 | set_file_attrs(fnametmp, file, NULL, fnamecmp, |
| 774 | ok_to_set_time ? ATTRS_ACCURATE_TIME : ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME | ATTRS_SKIP_CRTIME); |
| 775 | |
| 776 | if (temp_copy_name) { |
| 777 | if (do_rename_at(fnametmp, fname) < 0) { |
| 778 | rsyserr(FERROR_XFER, errno, "rename %s -> \"%s\"", |
| 779 | full_fname(fnametmp), fname); |
| 780 | return 0; |
| 781 | } |
no test coverage detected