1/* 2 * Routines only used by the receiving process. 3 * 4 * Copyright (C) 1996-2000 Andrew Tridgell 5 * Copyright (C) 1996 Paul Mackerras 6 * Copyright (C) 2003, 2004, 2005, 2006 Wayne Davison 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 21 */ 22 23#include "rsync.h" 24 25#ifdef HAVE_COPYFILE 26#include <libgen.h> 27#include <copyfile.h> 28#endif 29 30extern int verbose; 31extern int do_xfers; 32extern int am_server; 33extern int do_progress; 34extern int log_before_transfer; 35extern int stdout_format_has_i; 36extern int logfile_format_has_i; 37extern int csum_length; 38extern int read_batch; 39extern int write_batch; 40extern int batch_gen_fd; 41extern int protocol_version; 42extern int relative_paths; 43extern int preserve_hard_links; 44extern int preserve_perms; 45extern int basis_dir_cnt; 46extern int make_backups; 47extern int cleanup_got_literal; 48extern int remove_source_files; 49extern int append_mode; 50extern int sparse_files; 51extern int keep_partial; 52extern int checksum_seed; 53extern int inplace; 54extern int no_cache; 55extern int delay_updates; 56extern int preserve_links; 57extern struct stats stats; 58extern char *stdout_format; 59extern char *tmpdir; 60extern char *partial_dir; 61extern char *basis_dir[]; 62extern struct file_list *the_file_list; 63extern struct filter_list_struct server_filter_list; 64#ifdef HAVE_COPYFILE 65extern int extended_attributes; 66#endif 67 68static struct bitbag *delayed_bits = NULL; 69static int phase = 0; 70/* We're either updating the basis file or an identical copy: */ 71static int updating_basis; 72 73 74/* 75 * get_tmpname() - create a tmp filename for a given filename 76 * 77 * If a tmpdir is defined, use that as the directory to 78 * put it in. Otherwise, the tmp filename is in the same 79 * directory as the given name. Note that there may be no 80 * directory at all in the given name! 81 * 82 * The tmp filename is basically the given filename with a 83 * dot prepended, and .XXXXXX appended (for mkstemp() to 84 * put its unique gunk in). Take care to not exceed 85 * either the MAXPATHLEN or NAME_MAX, esp. the last, as 86 * the basename basically becomes 8 chars longer. In that 87 * case, the original name is shortened sufficiently to 88 * make it all fit. 89 * 90 * Of course, there's no real reason for the tmp name to 91 * look like the original, except to satisfy us humans. 92 * As long as it's unique, rsync will work. 93 */ 94 95int get_tmpname(char *fnametmp, char *fname) 96{ 97 int maxname, added, length = 0; 98 char *f; 99 100 if (tmpdir) { 101 /* Note: this can't overflow, so the return value is safe */ 102 length = strlcpy(fnametmp, tmpdir, MAXPATHLEN - 2); 103 fnametmp[length++] = '/'; 104 } 105 106 if ((f = strrchr(fname, '/')) != NULL) { 107 ++f; 108 if (!tmpdir) { 109 length = f - fname; 110 /* copy up to and including the slash */ 111 strlcpy(fnametmp, fname, length + 1); 112 } 113 } else 114 f = fname; 115 fnametmp[length++] = '.'; 116 117 /* The maxname value is bufsize, and includes space for the '\0'. 118 * (Note that NAME_MAX get -8 for the leading '.' above.) */ 119 maxname = MIN(MAXPATHLEN - 7 - length, NAME_MAX - 8); 120 121 if (maxname < 1) { 122 rprintf(FERROR, "temporary filename too long: %s\n", fname); 123 fnametmp[0] = '\0'; 124 return 0; 125 } 126 127 added = strlcpy(fnametmp + length, f, maxname); 128 if (added >= maxname) 129 added = maxname - 1; 130 memcpy(fnametmp + length + added, ".XXXXXX", 8); 131 132 return 1; 133} 134 135 136static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r, 137 char *fname, int fd, OFF_T total_size) 138{ 139 static char file_sum1[MD4_SUM_LENGTH]; 140 static char file_sum2[MD4_SUM_LENGTH]; 141 struct map_struct *mapbuf; 142 struct sum_struct sum; 143 int32 len; 144 OFF_T offset = 0; 145 OFF_T offset2; 146 char *data; 147 int32 i; 148 char *map = NULL; 149 150 read_sum_head(f_in, &sum); 151 152 if (fd_r >= 0 && size_r > 0) { 153 int32 read_size = MAX(sum.blength * 2, 16*1024); 154 mapbuf = map_file(fd_r, size_r, read_size, sum.blength); 155 if (verbose > 2) { 156 rprintf(FINFO, "recv mapped %s of size %.0f\n", 157 fname_r, (double)size_r); 158 } 159 } else 160 mapbuf = NULL; 161 162 sum_init(checksum_seed); 163 164 if (append_mode) { 165 OFF_T j; 166 sum.flength = (OFF_T)sum.count * sum.blength; 167 if (sum.remainder) 168 sum.flength -= sum.blength - sum.remainder; 169 for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) { 170 if (do_progress) 171 show_progress(offset, total_size); 172 sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE), 173 CHUNK_SIZE); 174 offset = j; 175 } 176 if (offset < sum.flength) { 177 int32 len = sum.flength - offset; 178 if (do_progress) 179 show_progress(offset, total_size); 180 sum_update(map_ptr(mapbuf, offset, len), len); 181 offset = sum.flength; 182 } 183 if (fd != -1 && (j = do_lseek(fd, offset, SEEK_SET)) != offset) { 184 rsyserr(FERROR, errno, "lseek of %s returned %.0f, not %.0f", 185 full_fname(fname), (double)j, (double)offset); 186 exit_cleanup(RERR_FILEIO); 187 } 188 } 189 190 while ((i = recv_token(f_in, &data)) != 0) { 191 if (do_progress) 192 show_progress(offset, total_size); 193 194 if (i > 0) { 195 if (verbose > 3) { 196 rprintf(FINFO,"data recv %d at %.0f\n", 197 i,(double)offset); 198 } 199 200 stats.literal_data += i; 201 cleanup_got_literal = 1; 202 203 sum_update(data, i); 204 205 if (fd != -1 && write_file(fd,data,i) != i) 206 goto report_write_error; 207 offset += i; 208 continue; 209 } 210 211 i = -(i+1); 212 offset2 = i * (OFF_T)sum.blength; 213 len = sum.blength; 214 if (i == (int)sum.count-1 && sum.remainder != 0) 215 len = sum.remainder; 216 217 stats.matched_data += len; 218 219 if (verbose > 3) { 220 rprintf(FINFO, 221 "chunk[%d] of size %ld at %.0f offset=%.0f\n", 222 i, (long)len, (double)offset2, (double)offset); 223 } 224 225 if (mapbuf) { 226 map = map_ptr(mapbuf,offset2,len); 227 228 see_token(map, len); 229 sum_update(map, len); 230 } 231 232 if (updating_basis) { 233 if (offset == offset2 && fd != -1) { 234 OFF_T pos; 235 if (flush_write_file(fd) < 0) 236 goto report_write_error; 237 offset += len; 238 if ((pos = do_lseek(fd, len, SEEK_CUR)) != offset) { 239 rsyserr(FERROR, errno, 240 "lseek of %s returned %.0f, not %.0f", 241 full_fname(fname), 242 (double)pos, (double)offset); 243 exit_cleanup(RERR_FILEIO); 244 } 245 continue; 246 } 247 } 248 if (fd != -1 && map && write_file(fd, map, len) != (int)len) 249 goto report_write_error; 250 offset += len; 251 } 252 253 if (flush_write_file(fd) < 0) 254 goto report_write_error; 255 256#ifdef HAVE_FTRUNCATE 257 if (inplace && fd != -1) 258 ftruncate(fd, offset); 259#endif 260 261 if (do_progress) 262 end_progress(total_size); 263 264 if (fd != -1 && offset > 0 && sparse_end(fd) != 0) { 265 report_write_error: 266 rsyserr(FERROR, errno, "write failed on %s", 267 full_fname(fname)); 268 exit_cleanup(RERR_FILEIO); 269 } 270 271 sum_end(file_sum1); 272 273 if (mapbuf) 274 unmap_file(mapbuf); 275 276 read_buf(f_in,file_sum2,MD4_SUM_LENGTH); 277 if (verbose > 2) 278 rprintf(FINFO,"got file_sum\n"); 279 if (fd != -1 && memcmp(file_sum1, file_sum2, MD4_SUM_LENGTH) != 0) 280 return 0; 281 return 1; 282} 283 284 285static void discard_receive_data(int f_in, OFF_T length) 286{ 287 receive_data(f_in, NULL, -1, 0, NULL, -1, length); 288} 289 290static void handle_delayed_updates(struct file_list *flist, char *local_name) 291{ 292 char *fname, *partialptr, numbuf[4]; 293 int i; 294 295 for (i = -1; (i = bitbag_next_bit(delayed_bits, i)) >= 0; ) { 296 struct file_struct *file = flist->files[i]; 297 fname = local_name ? local_name : f_name(file, NULL); 298 if ((partialptr = partial_dir_fname(fname)) != NULL) { 299 if (make_backups && !make_backup(fname)) 300 continue; 301 if (verbose > 2) { 302 rprintf(FINFO, "renaming %s to %s\n", 303 partialptr, fname); 304 } 305 /* We don't use robust_rename() here because the 306 * partial-dir must be on the same drive. */ 307 if (do_rename(partialptr, fname) < 0) { 308 rsyserr(FERROR, errno, 309 "rename failed for %s (from %s)", 310 full_fname(fname), partialptr); 311 } else { 312 if (remove_source_files 313 || (preserve_hard_links 314 && file->link_u.links)) { 315 SIVAL(numbuf, 0, i); 316 send_msg(MSG_SUCCESS,numbuf,4); 317 } 318 handle_partial_dir(partialptr, PDIR_DELETE); 319 } 320 } 321 } 322} 323 324static int get_next_gen_i(int batch_gen_fd, int next_gen_i, int desired_i) 325{ 326 while (next_gen_i < desired_i) { 327 if (next_gen_i >= 0) { 328 rprintf(FINFO, 329 "(No batched update for%s \"%s\")\n", 330 phase ? " resend of" : "", 331 f_name(the_file_list->files[next_gen_i], NULL)); 332 } 333 next_gen_i = read_int(batch_gen_fd); 334 if (next_gen_i == -1) 335 next_gen_i = the_file_list->count; 336 } 337 return next_gen_i; 338} 339 340 341/** 342 * main routine for receiver process. 343 * 344 * Receiver process runs on the same host as the generator process. */ 345int recv_files(int f_in, struct file_list *flist, char *local_name) 346{ 347 int next_gen_i = -1; 348 int fd1,fd2; 349 STRUCT_STAT st; 350 int iflags, xlen; 351 char *fname, fbuf[MAXPATHLEN]; 352 char xname[MAXPATHLEN]; 353 char fnametmp[MAXPATHLEN]; 354 char *fnamecmp, *partialptr, numbuf[4]; 355 char fnamecmpbuf[MAXPATHLEN]; 356 uchar fnamecmp_type; 357 struct file_struct *file; 358 struct stats initial_stats; 359 int save_make_backups = make_backups; 360 int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i; 361 enum logcode log_code = log_before_transfer ? FLOG : FINFO; 362 int max_phase = protocol_version >= 29 ? 2 : 1; 363 int i, recv_ok; 364 365 if (verbose > 2) 366 rprintf(FINFO,"recv_files(%d) starting\n",flist->count); 367 368 if (flist->hlink_pool) { 369 pool_destroy(flist->hlink_pool); 370 flist->hlink_pool = NULL; 371 } 372 373 if (delay_updates) 374 delayed_bits = bitbag_create(flist->count); 375 376 updating_basis = inplace; 377 378 while (1) { 379 cleanup_disable(); 380 381 i = read_int(f_in); 382 if (i == -1) { 383 if (read_batch) { 384 get_next_gen_i(batch_gen_fd, next_gen_i, 385 flist->count); 386 next_gen_i = -1; 387 } 388 if (++phase > max_phase) 389 break; 390 csum_length = SUM_LENGTH; 391 if (verbose > 2) 392 rprintf(FINFO, "recv_files phase=%d\n", phase); 393 if (phase == 2 && delay_updates) 394 handle_delayed_updates(flist, local_name); 395 send_msg(MSG_DONE, "", 0); 396 if (keep_partial && !partial_dir) 397 make_backups = 0; /* prevents double backup */ 398 if (append_mode) { 399 append_mode = 0; 400 sparse_files = 0; 401 } 402 continue; 403 } 404 iflags = read_item_attrs(f_in, -1, i, &fnamecmp_type, 405 xname, &xlen); 406 if (iflags == ITEM_IS_NEW) /* no-op packet */ { 407 continue; 408 } 409 410 file = flist->files[i]; 411#ifdef HAVE_COPYFILE 412 if (local_name) { 413 if (extended_attributes 414 && !strncmp(file->basename, "._", 2)) { 415 if (dirname(local_name)) { 416 snprintf(fbuf, MAXPATHLEN, "%s/._%s", 417 dirname(local_name), basename(local_name)); 418 } else { 419 snprintf(fbuf, MAXPATHLEN, "._%s", local_name); 420 errno = 0; 421 } 422 fname = fbuf; 423 } else 424 fname = local_name; 425 } else 426#endif 427 fname = local_name ? local_name : f_name(file, fbuf); 428 429 if (verbose > 2) 430 rprintf(FINFO, "recv_files(%s)\n", fname); 431 432 if (!(iflags & ITEM_TRANSFER)) { 433 maybe_log_item(file, iflags, itemizing, xname); 434#ifdef HAVE_COPYFILE 435 if (do_xfers && extended_attributes && (file->flags & FLAG_CLEAR_METADATA)) { 436 if (0 == copyfile("/dev/null", fname, 0, 437 COPYFILE_XATTR | COPYFILE_ACL | (preserve_links ? COPYFILE_NOFOLLOW : 0))) { 438 file->flags &= ~FLAG_CLEAR_METADATA; 439 } else { 440 rprintf(FERROR, "copyfile(/dev/null, %s, COPYFILE_METADATA) failed:%d\n", fname, errno); 441 } 442 } 443#endif 444 continue; 445 } 446 if (phase == 2) { 447 rprintf(FERROR, 448 "got transfer request in phase 2 [%s]\n", 449 who_am_i()); 450 exit_cleanup(RERR_PROTOCOL); 451 } 452 453 stats.current_file_index = i; 454 stats.num_transferred_files++; 455 stats.total_transferred_size += file->length; 456 cleanup_got_literal = 0; 457 458 if (server_filter_list.head 459 && check_filter(&server_filter_list, fname, 0) < 0) { 460 rprintf(FERROR, "attempt to hack rsync failed.\n"); 461 exit_cleanup(RERR_PROTOCOL); 462 } 463 464 if (!do_xfers) { /* log the transfer */ 465 log_item(FCLIENT, file, &stats, iflags, NULL); 466 if (read_batch) 467 discard_receive_data(f_in, file->length); 468 continue; 469 } 470 if (write_batch < 0) { 471 log_item(FINFO, file, &stats, iflags, NULL); 472 if (!am_server) 473 discard_receive_data(f_in, file->length); 474 continue; 475 } 476 477 if (read_batch) { 478 next_gen_i = get_next_gen_i(batch_gen_fd, next_gen_i, i); 479 if (i < next_gen_i) { 480 rprintf(FINFO, 481 "(Skipping batched update for \"%s\")\n", 482 fname); 483 discard_receive_data(f_in, file->length); 484 continue; 485 } 486 next_gen_i = -1; 487 } 488 489 partialptr = partial_dir ? partial_dir_fname(fname) : fname; 490 491 if (protocol_version >= 29) { 492 switch (fnamecmp_type) { 493 case FNAMECMP_FNAME: 494 fnamecmp = fname; 495 break; 496 case FNAMECMP_PARTIAL_DIR: 497 fnamecmp = partialptr; 498 break; 499 case FNAMECMP_BACKUP: 500 fnamecmp = get_backup_name(fname); 501 break; 502 case FNAMECMP_FUZZY: 503 updating_basis = 0; 504 if (file->dirname) { 505 pathjoin(fnamecmpbuf, MAXPATHLEN, 506 file->dirname, xname); 507 fnamecmp = fnamecmpbuf; 508 } else 509 fnamecmp = xname; 510 break; 511 default: 512 updating_basis = 0; 513 if (fnamecmp_type >= basis_dir_cnt) { 514 rprintf(FERROR, 515 "invalid basis_dir index: %d.\n", 516 fnamecmp_type); 517 exit_cleanup(RERR_PROTOCOL); 518 } 519 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, 520 basis_dir[fnamecmp_type], fname); 521 fnamecmp = fnamecmpbuf; 522 break; 523 } 524 if (!fnamecmp || (server_filter_list.head 525 && check_filter(&server_filter_list, fname, 0) < 0)) 526 fnamecmp = fname; 527 } else { 528 /* Reminder: --inplace && --partial-dir are never 529 * enabled at the same time. */ 530 if (inplace && make_backups) { 531 if (!(fnamecmp = get_backup_name(fname))) 532 fnamecmp = fname; 533 } else if (partial_dir && partialptr) 534 fnamecmp = partialptr; 535 else 536 fnamecmp = fname; 537 } 538 539 initial_stats = stats; 540 541 /* open the file */ 542 fd1 = do_open(fnamecmp, O_RDONLY, 0); 543 544 if (fd1 == -1 && protocol_version < 29) { 545 if (fnamecmp != fname) { 546 fnamecmp = fname; 547 fd1 = do_open(fnamecmp, O_RDONLY, 0); 548 } 549 550 if (fd1 == -1 && basis_dir[0]) { 551 /* pre-29 allowed only one alternate basis */ 552 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, 553 basis_dir[0], fname); 554 fnamecmp = fnamecmpbuf; 555 fd1 = do_open(fnamecmp, O_RDONLY, 0); 556 } 557 } 558 559 if (fd1 == -1) { 560 st.st_mode = 0; 561 st.st_size = 0; 562 } else if (do_fstat(fd1,&st) != 0) { 563 rsyserr(FERROR, errno, "fstat %s failed", 564 full_fname(fnamecmp)); 565 discard_receive_data(f_in, file->length); 566 close(fd1); 567 continue; 568 } 569 570 if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) { 571 /* this special handling for directories 572 * wouldn't be necessary if robust_rename() 573 * and the underlying robust_unlink could cope 574 * with directories 575 */ 576 rprintf(FERROR,"recv_files: %s is a directory\n", 577 full_fname(fnamecmp)); 578 discard_receive_data(f_in, file->length); 579 close(fd1); 580 continue; 581 } 582 583 if (fd1 != -1 && !S_ISREG(st.st_mode)) { 584 close(fd1); 585 fd1 = -1; 586 } 587 588 /* If we're not preserving permissions, change the file-list's 589 * mode based on the local permissions and some heuristics. */ 590 if (!preserve_perms) { 591 int exists = fd1 != -1; 592 file->mode = dest_mode(file->mode, st.st_mode, exists); 593 } 594 595 /* We now check to see if we are writing the file "inplace" */ 596 if (inplace) { 597 fd2 = do_open(fname, O_WRONLY|O_CREAT, 0600); 598 if (fd2 == -1) { 599 rsyserr(FERROR, errno, "open %s failed", 600 full_fname(fname)); 601 discard_receive_data(f_in, file->length); 602 if (fd1 != -1) 603 close(fd1); 604 continue; 605 } 606 } else { 607 if (!get_tmpname(fnametmp,fname)) { 608 discard_receive_data(f_in, file->length); 609 if (fd1 != -1) 610 close(fd1); 611 continue; 612 } 613 614 /* we initially set the perms without the 615 * setuid/setgid bits to ensure that there is no race 616 * condition. They are then correctly updated after 617 * the lchown. Thanks to snabb@epipe.fi for pointing 618 * this out. We also set it initially without group 619 * access because of a similar race condition. */ 620 fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); 621 622 /* in most cases parent directories will already exist 623 * because their information should have been previously 624 * transferred, but that may not be the case with -R */ 625 if (fd2 == -1 && relative_paths && errno == ENOENT 626 && create_directory_path(fnametmp) == 0) { 627 /* Get back to name with XXXXXX in it. */ 628 get_tmpname(fnametmp, fname); 629 fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); 630 } 631 if (fd2 == -1) { 632 rsyserr(FERROR, errno, "mkstemp %s failed", 633 full_fname(fnametmp)); 634 discard_receive_data(f_in, file->length); 635 if (fd1 != -1) 636 close(fd1); 637 continue; 638 } 639 640 cleanup_set(fnametmp, partialptr, file, fd1, fd2); 641 } 642 643#ifdef F_NOCACHE 644 if (no_cache) { 645 fcntl(fd2, F_NOCACHE, 1); 646 } 647#endif /* F_NOCACHE */ 648#ifdef F_PREALLOCATE 649 { 650 fstore_t fstore; 651 bzero(&fstore, sizeof(fstore)); 652 fstore.fst_posmode = F_PEOFPOSMODE; 653 fstore.fst_length = file->length; 654 fcntl(fd2, F_PREALLOCATE, &fstore); 655 } 656#endif 657 /* log the transfer */ 658 if (log_before_transfer) 659 log_item(FCLIENT, file, &initial_stats, iflags, NULL); 660 else if (!am_server && verbose && do_progress) 661 rprintf(FINFO, "%s\n", fname); 662 663 /* recv file data */ 664 recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size, 665 fname, fd2, file->length); 666 667 log_item(log_code, file, &initial_stats, iflags, NULL); 668 669 if (fd1 != -1) 670 close(fd1); 671 if (close(fd2) < 0) { 672 rsyserr(FERROR, errno, "close failed on %s", 673 full_fname(fnametmp)); 674 exit_cleanup(RERR_FILEIO); 675 } 676 677 if ((recv_ok && (!delay_updates || !partialptr)) || inplace) { 678 char *temp_copy_name; 679 if (partialptr == fname) 680 partialptr = temp_copy_name = NULL; 681 else if (*partial_dir == '/') 682 temp_copy_name = NULL; 683 else 684 temp_copy_name = partialptr; 685 finish_transfer(fname, fnametmp, temp_copy_name, 686 file, recv_ok, 1); 687 if (fnamecmp == partialptr) { 688 do_unlink(partialptr); 689 handle_partial_dir(partialptr, PDIR_DELETE); 690 } 691 } else if (keep_partial && partialptr 692 && handle_partial_dir(partialptr, PDIR_CREATE)) { 693 finish_transfer(partialptr, fnametmp, NULL, 694 file, recv_ok, !partial_dir); 695 if (delay_updates && recv_ok) { 696 bitbag_set_bit(delayed_bits, i); 697 recv_ok = -1; 698 } 699 } else { 700 partialptr = NULL; 701 do_unlink(fnametmp); 702 } 703#ifdef HAVE_COPYFILE 704 if (extended_attributes && (file->flags & FLAG_CLEAR_METADATA)) { 705 if (0 == copyfile("/dev/null", fname, 0, 706 COPYFILE_XATTR | COPYFILE_ACL | (preserve_links ? COPYFILE_NOFOLLOW : 0))) { 707 file->flags &= ~FLAG_CLEAR_METADATA; 708 } else { 709 rprintf(FERROR, "copyfile(/dev/null, %s, COPYFILE_METADATA) failed:%d\n", fname, errno); 710 } 711 } 712#endif /* HAVE_COPYFILE */ 713 714 cleanup_disable(); 715 716 if (recv_ok > 0) { 717 if (remove_source_files 718 || (preserve_hard_links && file->link_u.links)) { 719 SIVAL(numbuf, 0, i); 720 send_msg(MSG_SUCCESS, numbuf, 4); 721 } 722 } else if (!recv_ok) { 723 int msgtype = phase || read_batch ? FERROR : FINFO; 724 if (msgtype == FERROR || verbose) { 725 char *errstr, *redostr, *keptstr; 726 if (!(keep_partial && partialptr) && !inplace) 727 keptstr = "discarded"; 728 else if (partial_dir) 729 keptstr = "put into partial-dir"; 730 else 731 keptstr = "retained"; 732 if (msgtype == FERROR) { 733 errstr = "ERROR"; 734 redostr = ""; 735 } else { 736 errstr = "WARNING"; 737 redostr = " (will try again)"; 738 } 739 rprintf(msgtype, 740 "%s: %s failed verification -- update %s%s.\n", 741 errstr, fname, keptstr, redostr); 742 } 743 if (!phase) { 744 SIVAL(numbuf, 0, i); 745 send_msg(MSG_REDO, numbuf, 4); 746 } 747 } 748 } 749 make_backups = save_make_backups; 750 751 if (phase == 2 && delay_updates) /* for protocol_version < 29 */ 752 handle_delayed_updates(flist, local_name); 753 754 if (verbose > 2) 755 rprintf(FINFO,"recv_files finished\n"); 756 757 return 0; 758} 759