| 129 | } |
| 130 | |
| 131 | void successful_send(int ndx) |
| 132 | { |
| 133 | char fname[MAXPATHLEN]; |
| 134 | char *failed_op; |
| 135 | struct file_struct *file; |
| 136 | struct file_list *flist; |
| 137 | STRUCT_STAT st; |
| 138 | |
| 139 | if (!remove_source_files) |
| 140 | return; |
| 141 | |
| 142 | flist = flist_for_ndx(ndx, "successful_send"); |
| 143 | if (ndx < flist->ndx_start) |
| 144 | exit_cleanup(RERR_PROTOCOL); |
| 145 | file = flist->files[ndx - flist->ndx_start]; |
| 146 | if (!change_pathname(file, NULL, 0)) |
| 147 | return; |
| 148 | f_name(file, fname); |
| 149 | |
| 150 | if ((copy_links ? do_stat(fname, &st) : do_lstat(fname, &st)) < 0) { |
| 151 | failed_op = "re-lstat"; |
| 152 | goto failed; |
| 153 | } |
| 154 | |
| 155 | if (local_server |
| 156 | && (int64)st.st_dev == IVAL64(num_dev_ino_buf, 4) |
| 157 | && (int64)st.st_ino == IVAL64(num_dev_ino_buf, 4 + 8)) { |
| 158 | rprintf(FERROR_XFER, "ERROR: Skipping sender remove of destination file: %s\n", fname); |
| 159 | return; |
| 160 | } |
| 161 | |
| 162 | if (st.st_size != F_LENGTH(file) || st.st_mtime != file->modtime |
| 163 | #ifdef ST_MTIME_NSEC |
| 164 | || (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file)) |
| 165 | #endif |
| 166 | ) { |
| 167 | rprintf(FERROR_XFER, "ERROR: Skipping sender remove for changed file: %s\n", fname); |
| 168 | return; |
| 169 | } |
| 170 | |
| 171 | if (do_unlink(fname) < 0) { |
| 172 | failed_op = "remove"; |
| 173 | failed: |
| 174 | if (errno == ENOENT) |
| 175 | rprintf(FINFO, "sender file already removed: %s\n", fname); |
| 176 | else |
| 177 | rsyserr(FERROR_XFER, errno, "sender failed to %s %s", failed_op, fname); |
| 178 | } else { |
| 179 | if (INFO_GTE(REMOVE, 1)) |
| 180 | rprintf(FINFO, "sender removed %s\n", fname); |
| 181 | } |
| 182 | } |
| 183 | |
| 184 | static void write_ndx_and_attrs(int f_out, int ndx, int iflags, |
| 185 | const char *fname, struct file_struct *file, |
no test coverage detected