関数 | |
static int | get_tmpname (char *fnametmp, char *fname) |
static int | receive_data (int f_in, char *fname_r, int fd_r, OFF_T size_r, char *fname, int fd, OFF_T total_size) |
static void | discard_receive_data (int f_in, OFF_T length) |
static void | handle_delayed_updates (struct file_list *flist, char *local_name) |
static int | get_next_gen_i (int batch_gen_fd, int next_gen_i, int desired_i) |
int | recv_files (int f_in, struct file_list *flist, char *local_name) |
main routine for receiver process. | |
変数 | |
int | verbose |
int | do_xfers |
int | am_daemon |
int | am_server |
int | do_progress |
int | log_before_transfer |
int | log_format_has_i |
int | daemon_log_format_has_i |
int | csum_length |
int | read_batch |
int | write_batch |
int | batch_gen_fd |
int | protocol_version |
int | relative_paths |
int | preserve_hard_links |
int | preserve_perms |
int | basis_dir_cnt |
int | make_backups |
int | cleanup_got_literal |
Set to True once literal data has been sent across the link for the current file. | |
int | remove_sent_files |
int | append_mode |
int | sparse_files |
int | keep_partial |
int | checksum_seed |
int | inplace |
int | delay_updates |
mode_t | orig_umask |
stats | stats |
char * | log_format |
char * | tmpdir |
char * | partial_dir |
char * | basis_dir [] |
file_list * | the_file_list |
filter_list_struct | server_filter_list |
static struct bitbag * | delayed_bits = NULL |
static int | phase = 0 |
static int get_tmpname | ( | char * | fnametmp, | |
char * | fname | |||
) | [static] |
receiver.c の 83 行で定義されています。
参照先 FERROR・rprintf()・strlcpy()・tmpdir.
参照元 recv_files().
00084 { 00085 char *f; 00086 int length = 0; 00087 int maxname; 00088 00089 if (tmpdir) { 00090 /* Note: this can't overflow, so the return value is safe */ 00091 length = strlcpy(fnametmp, tmpdir, MAXPATHLEN - 2); 00092 fnametmp[length++] = '/'; 00093 fnametmp[length] = '\0'; /* always NULL terminated */ 00094 } 00095 00096 if ((f = strrchr(fname, '/')) != NULL) { 00097 ++f; 00098 if (!tmpdir) { 00099 length = f - fname; 00100 /* copy up to and including the slash */ 00101 strlcpy(fnametmp, fname, length + 1); 00102 } 00103 } else 00104 f = fname; 00105 fnametmp[length++] = '.'; 00106 fnametmp[length] = '\0'; /* always NULL terminated */ 00107 00108 maxname = MIN(MAXPATHLEN - 7 - length, NAME_MAX - 8); 00109 00110 if (maxname < 1) { 00111 rprintf(FERROR, "temporary filename too long: %s\n", fname); 00112 fnametmp[0] = '\0'; 00113 return 0; 00114 } 00115 00116 strlcpy(fnametmp + length, f, maxname); 00117 strcat(fnametmp + length, ".XXXXXX"); 00118 00119 return 1; 00120 }
static int receive_data | ( | int | f_in, | |
char * | fname_r, | |||
int | fd_r, | |||
OFF_T | size_r, | |||
char * | fname, | |||
int | fd, | |||
OFF_T | total_size | |||
) | [static] |
receiver.c の 123 行で定義されています。
参照先 append_mode・sum_struct::blength・checksum_seed・cleanup_got_literal・sum_struct::count・do_lseek()・do_progress・end_progress()・errno・FERROR・FINFO・sum_struct::flength・flush_write_file()・full_fname()・inplace・stats::literal_data・map_file()・map_ptr()・stats::matched_data・read_buf()・read_sum_head()・recv_token()・sum_struct::remainder・rprintf()・rsyserr()・see_token()・show_progress()・sparse_end()・stats・sum_end()・sum_init()・sum_update()・unmap_file()・verbose・write_file().
参照元 discard_receive_data()・recv_files().
00125 { 00126 static char file_sum1[MD4_SUM_LENGTH]; 00127 static char file_sum2[MD4_SUM_LENGTH]; 00128 struct map_struct *mapbuf; 00129 struct sum_struct sum; 00130 int32 len; 00131 OFF_T offset = 0; 00132 OFF_T offset2; 00133 char *data; 00134 int32 i; 00135 char *map = NULL; 00136 00137 read_sum_head(f_in, &sum); 00138 00139 if (fd_r >= 0 && size_r > 0) { 00140 int32 read_size = MAX(sum.blength * 2, 16*1024); 00141 mapbuf = map_file(fd_r, size_r, read_size, sum.blength); 00142 if (verbose > 2) { 00143 rprintf(FINFO, "recv mapped %s of size %.0f\n", 00144 fname_r, (double)size_r); 00145 } 00146 } else 00147 mapbuf = NULL; 00148 00149 sum_init(checksum_seed); 00150 00151 if (append_mode) { 00152 OFF_T j; 00153 sum.flength = (OFF_T)sum.count * sum.blength; 00154 if (sum.remainder) 00155 sum.flength -= sum.blength - sum.remainder; 00156 for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) { 00157 if (do_progress) 00158 show_progress(offset, total_size); 00159 sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE), 00160 CHUNK_SIZE); 00161 offset = j; 00162 } 00163 if (offset < sum.flength) { 00164 int32 len = sum.flength - offset; 00165 if (do_progress) 00166 show_progress(offset, total_size); 00167 sum_update(map_ptr(mapbuf, offset, len), len); 00168 offset = sum.flength; 00169 } 00170 if (fd != -1 && do_lseek(fd, offset, SEEK_SET) != offset) { 00171 rsyserr(FERROR, errno, "lseek failed on %s", 00172 full_fname(fname)); 00173 exit_cleanup(RERR_FILEIO); 00174 } 00175 } 00176 00177 while ((i = recv_token(f_in, &data)) != 0) { 00178 if (do_progress) 00179 show_progress(offset, total_size); 00180 00181 if (i > 0) { 00182 if (verbose > 3) { 00183 rprintf(FINFO,"data recv %d at %.0f\n", 00184 i,(double)offset); 00185 } 00186 00187 stats.literal_data += i; 00188 cleanup_got_literal = 1; 00189 00190 sum_update(data, i); 00191 00192 if (fd != -1 && write_file(fd,data,i) != i) 00193 goto report_write_error; 00194 offset += i; 00195 continue; 00196 } 00197 00198 i = -(i+1); 00199 offset2 = i * (OFF_T)sum.blength; 00200 len = sum.blength; 00201 if (i == (int)sum.count-1 && sum.remainder != 0) 00202 len = sum.remainder; 00203 00204 stats.matched_data += len; 00205 00206 if (verbose > 3) { 00207 rprintf(FINFO, 00208 "chunk[%d] of size %ld at %.0f offset=%.0f\n", 00209 i, (long)len, (double)offset2, (double)offset); 00210 } 00211 00212 if (mapbuf) { 00213 map = map_ptr(mapbuf,offset2,len); 00214 00215 see_token(map, len); 00216 sum_update(map, len); 00217 } 00218 00219 if (inplace) { 00220 if (offset == offset2 && fd != -1) { 00221 if (flush_write_file(fd) < 0) 00222 goto report_write_error; 00223 offset += len; 00224 if (do_lseek(fd, len, SEEK_CUR) != offset) { 00225 rsyserr(FERROR, errno, 00226 "lseek failed on %s", 00227 full_fname(fname)); 00228 exit_cleanup(RERR_FILEIO); 00229 } 00230 continue; 00231 } 00232 } 00233 if (fd != -1 && map && write_file(fd, map, len) != (int)len) 00234 goto report_write_error; 00235 offset += len; 00236 } 00237 00238 if (flush_write_file(fd) < 0) 00239 goto report_write_error; 00240 00241 #ifdef HAVE_FTRUNCATE 00242 if (inplace && fd != -1) 00243 ftruncate(fd, offset); 00244 #endif 00245 00246 if (do_progress) 00247 end_progress(total_size); 00248 00249 if (fd != -1 && offset > 0 && sparse_end(fd) != 0) { 00250 report_write_error: 00251 rsyserr(FERROR, errno, "write failed on %s", 00252 full_fname(fname)); 00253 exit_cleanup(RERR_FILEIO); 00254 } 00255 00256 sum_end(file_sum1); 00257 00258 if (mapbuf) 00259 unmap_file(mapbuf); 00260 00261 read_buf(f_in,file_sum2,MD4_SUM_LENGTH); 00262 if (verbose > 2) 00263 rprintf(FINFO,"got file_sum\n"); 00264 if (fd != -1 && memcmp(file_sum1, file_sum2, MD4_SUM_LENGTH) != 0) 00265 return 0; 00266 return 1; 00267 }
static void discard_receive_data | ( | int | f_in, | |
OFF_T | length | |||
) | [static] |
receiver.c の 270 行で定義されています。
参照先 receive_data().
参照元 recv_files().
00271 { 00272 receive_data(f_in, NULL, -1, 0, NULL, -1, length); 00273 }
static void handle_delayed_updates | ( | struct file_list * | flist, | |
char * | local_name | |||
) | [static] |
receiver.c の 275 行で定義されています。
参照先 bitbag_next_bit()・delayed_bits・do_rename()・errno・f_name()・FERROR・file_list::files・FINFO・full_fname()・handle_partial_dir()・make_backup()・make_backups・MSG_SUCCESS・partial_dir_fname()・preserve_hard_links・remove_sent_files・rprintf()・rsyserr()・send_msg()・verbose.
参照元 recv_files().
00276 { 00277 char *fname, *partialptr, numbuf[4]; 00278 int i; 00279 00280 for (i = -1; (i = bitbag_next_bit(delayed_bits, i)) >= 0; ) { 00281 struct file_struct *file = flist->files[i]; 00282 fname = local_name ? local_name : f_name(file, NULL); 00283 if ((partialptr = partial_dir_fname(fname)) != NULL) { 00284 if (make_backups && !make_backup(fname)) 00285 continue; 00286 if (verbose > 2) { 00287 rprintf(FINFO, "renaming %s to %s\n", 00288 partialptr, fname); 00289 } 00290 /* We don't use robust_rename() here because the 00291 * partial-dir must be on the same drive. */ 00292 if (do_rename(partialptr, fname) < 0) { 00293 rsyserr(FERROR, errno, 00294 "rename failed for %s (from %s)", 00295 full_fname(fname), partialptr); 00296 } else { 00297 if (remove_sent_files 00298 || (preserve_hard_links 00299 && file->link_u.links)) { 00300 SIVAL(numbuf, 0, i); 00301 send_msg(MSG_SUCCESS,numbuf,4); 00302 } 00303 handle_partial_dir(partialptr, PDIR_DELETE); 00304 } 00305 } 00306 } 00307 }
static int get_next_gen_i | ( | int | batch_gen_fd, | |
int | next_gen_i, | |||
int | desired_i | |||
) | [static] |
receiver.c の 309 行で定義されています。
参照先 file_list::count・f_name()・file_list::files・FINFO・phase・read_int()・rprintf()・the_file_list.
参照元 recv_files().
00310 { 00311 while (next_gen_i < desired_i) { 00312 if (next_gen_i >= 0) { 00313 rprintf(FINFO, 00314 "(No batched update for%s \"%s\")\n", 00315 phase ? " resend of" : "", 00316 f_name(the_file_list->files[next_gen_i], NULL)); 00317 } 00318 next_gen_i = read_int(batch_gen_fd); 00319 if (next_gen_i == -1) 00320 next_gen_i = the_file_list->count; 00321 } 00322 return next_gen_i; 00323 }
int recv_files | ( | int | f_in, | |
struct file_list * | flist, | |||
char * | local_name | |||
) |
main routine for receiver process.
Receiver process runs on the same host as the generator process.
receiver.c の 330 行で定義されています。
参照先 am_daemon・am_server・append_mode・basis_dir・basis_dir_cnt・batch_gen_fd・bitbag_create()・bitbag_set_bit()・check_filter()・cleanup_disable()・cleanup_got_literal・cleanup_set()・file_list::count・create_directory_path()・csum_length・stats::current_file_index・daemon_log_format_has_i・default_perms_for_dir()・delay_updates・delayed_bits・dest_mode()・dflt_perms・file_struct::dirname・discard_receive_data()・do_fstat()・do_mkstemp()・do_open()・do_progress・do_unlink()・do_xfers・errno・f_name()・FERROR・file_list::files・FINFO・finish_transfer()・full_fname()・get_backup_name()・get_next_gen_i()・get_tmpname()・handle_delayed_updates()・handle_partial_dir()・filter_list_struct::head・file_list::hlink_pool・inplace・keep_partial・file_struct::length・log_before_transfer・log_format・log_format_has_i・log_item()・make_backups・maybe_log_item()・file_struct::mode・MSG_DONE・MSG_REDO・MSG_SUCCESS・stats::num_transferred_files・orig_umask・partial_dir・partial_dir_fname()・pathjoin()・phase・pool_destroy()・preserve_hard_links・preserve_perms・protocol_version・read_batch・read_int()・read_item_attrs()・receive_data()・relative_paths・remove_sent_files・rprintf()・rsyserr()・send_msg()・server_filter_list・sparse_files・stats・stats::total_transferred_size・verbose・who_am_i()・write_batch.
参照元 do_recv().
00331 { 00332 int next_gen_i = -1; 00333 int fd1,fd2; 00334 STRUCT_STAT st; 00335 int iflags, xlen; 00336 char *fname, fbuf[MAXPATHLEN]; 00337 char xname[MAXPATHLEN]; 00338 char fnametmp[MAXPATHLEN]; 00339 char *fnamecmp, *partialptr, numbuf[4]; 00340 char fnamecmpbuf[MAXPATHLEN]; 00341 uchar fnamecmp_type; 00342 struct file_struct *file; 00343 struct stats initial_stats; 00344 int save_make_backups = make_backups; 00345 int itemizing = am_daemon ? daemon_log_format_has_i 00346 : !am_server && log_format_has_i; 00347 int max_phase = protocol_version >= 29 ? 2 : 1; 00348 int dflt_perms = (ACCESSPERMS & ~orig_umask); 00349 #ifdef SUPPORT_ACLS 00350 char *parent_dirname = ""; 00351 #endif 00352 int i, recv_ok; 00353 00354 if (verbose > 2) 00355 rprintf(FINFO,"recv_files(%d) starting\n",flist->count); 00356 00357 if (flist->hlink_pool) { 00358 pool_destroy(flist->hlink_pool); 00359 flist->hlink_pool = NULL; 00360 } 00361 00362 if (delay_updates) 00363 delayed_bits = bitbag_create(flist->count); 00364 00365 while (1) { 00366 cleanup_disable(); 00367 00368 i = read_int(f_in); 00369 if (i == -1) { 00370 if (read_batch) { 00371 get_next_gen_i(batch_gen_fd, next_gen_i, 00372 flist->count); 00373 next_gen_i = -1; 00374 } 00375 if (++phase > max_phase) 00376 break; 00377 csum_length = SUM_LENGTH; 00378 if (verbose > 2) 00379 rprintf(FINFO, "recv_files phase=%d\n", phase); 00380 if (phase == 2 && delay_updates) 00381 handle_delayed_updates(flist, local_name); 00382 send_msg(MSG_DONE, "", 0); 00383 if (keep_partial && !partial_dir) 00384 make_backups = 0; /* prevents double backup */ 00385 if (append_mode) { 00386 append_mode = 0; 00387 sparse_files = 0; 00388 } 00389 continue; 00390 } 00391 00392 iflags = read_item_attrs(f_in, -1, i, &fnamecmp_type, 00393 xname, &xlen); 00394 if (iflags == ITEM_IS_NEW) /* no-op packet */ 00395 continue; 00396 00397 file = flist->files[i]; 00398 fname = local_name ? local_name : f_name(file, fbuf); 00399 00400 if (verbose > 2) 00401 rprintf(FINFO, "recv_files(%s)\n", fname); 00402 00403 if (!(iflags & ITEM_TRANSFER)) { 00404 maybe_log_item(file, iflags, itemizing, xname); 00405 continue; 00406 } 00407 if (phase == 2) { 00408 rprintf(FERROR, 00409 "got transfer request in phase 2 [%s]\n", 00410 who_am_i()); 00411 exit_cleanup(RERR_PROTOCOL); 00412 } 00413 00414 stats.current_file_index = i; 00415 stats.num_transferred_files++; 00416 stats.total_transferred_size += file->length; 00417 cleanup_got_literal = 0; 00418 00419 if (server_filter_list.head 00420 && check_filter(&server_filter_list, fname, 0) < 0) { 00421 rprintf(FERROR, "attempt to hack rsync failed.\n"); 00422 exit_cleanup(RERR_PROTOCOL); 00423 } 00424 00425 if (!do_xfers) { /* log the transfer */ 00426 if (!am_server && log_format) 00427 log_item(file, &stats, iflags, NULL); 00428 if (read_batch) 00429 discard_receive_data(f_in, file->length); 00430 continue; 00431 } 00432 if (write_batch < 0) { 00433 log_item(file, &stats, iflags, NULL); 00434 if (!am_server) 00435 discard_receive_data(f_in, file->length); 00436 continue; 00437 } 00438 00439 if (read_batch) { 00440 next_gen_i = get_next_gen_i(batch_gen_fd, next_gen_i, i); 00441 if (i < next_gen_i) { 00442 rprintf(FINFO, 00443 "(Skipping batched update for \"%s\")\n", 00444 fname); 00445 discard_receive_data(f_in, file->length); 00446 continue; 00447 } 00448 next_gen_i = -1; 00449 } 00450 00451 partialptr = partial_dir ? partial_dir_fname(fname) : fname; 00452 00453 if (protocol_version >= 29) { 00454 switch (fnamecmp_type) { 00455 case FNAMECMP_FNAME: 00456 fnamecmp = fname; 00457 break; 00458 case FNAMECMP_PARTIAL_DIR: 00459 fnamecmp = partialptr; 00460 break; 00461 case FNAMECMP_BACKUP: 00462 fnamecmp = get_backup_name(fname); 00463 break; 00464 case FNAMECMP_FUZZY: 00465 if (file->dirname) { 00466 pathjoin(fnamecmpbuf, MAXPATHLEN, 00467 file->dirname, xname); 00468 fnamecmp = fnamecmpbuf; 00469 } else 00470 fnamecmp = xname; 00471 break; 00472 default: 00473 if (fnamecmp_type >= basis_dir_cnt) { 00474 rprintf(FERROR, 00475 "invalid basis_dir index: %d.\n", 00476 fnamecmp_type); 00477 exit_cleanup(RERR_PROTOCOL); 00478 } 00479 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, 00480 basis_dir[fnamecmp_type], fname); 00481 fnamecmp = fnamecmpbuf; 00482 break; 00483 } 00484 if (!fnamecmp || (server_filter_list.head 00485 && check_filter(&server_filter_list, fname, 0) < 0)) 00486 fnamecmp = fname; 00487 } else { 00488 /* Reminder: --inplace && --partial-dir are never 00489 * enabled at the same time. */ 00490 if (inplace && make_backups) { 00491 if (!(fnamecmp = get_backup_name(fname))) 00492 fnamecmp = fname; 00493 } else if (partial_dir && partialptr) 00494 fnamecmp = partialptr; 00495 else 00496 fnamecmp = fname; 00497 } 00498 00499 initial_stats = stats; 00500 00501 /* open the file */ 00502 fd1 = do_open(fnamecmp, O_RDONLY, 0); 00503 00504 if (fd1 == -1 && protocol_version < 29) { 00505 if (fnamecmp != fname) { 00506 fnamecmp = fname; 00507 fd1 = do_open(fnamecmp, O_RDONLY, 0); 00508 } 00509 00510 if (fd1 == -1 && basis_dir[0]) { 00511 /* pre-29 allowed only one alternate basis */ 00512 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, 00513 basis_dir[0], fname); 00514 fnamecmp = fnamecmpbuf; 00515 fd1 = do_open(fnamecmp, O_RDONLY, 0); 00516 } 00517 } 00518 00519 if (fd1 != -1 && do_fstat(fd1,&st) != 0) { 00520 rsyserr(FERROR, errno, "fstat %s failed", 00521 full_fname(fnamecmp)); 00522 discard_receive_data(f_in, file->length); 00523 close(fd1); 00524 continue; 00525 } 00526 00527 if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) { 00528 /* this special handling for directories 00529 * wouldn't be necessary if robust_rename() 00530 * and the underlying robust_unlink could cope 00531 * with directories 00532 */ 00533 rprintf(FERROR,"recv_files: %s is a directory\n", 00534 full_fname(fnamecmp)); 00535 discard_receive_data(f_in, file->length); 00536 close(fd1); 00537 continue; 00538 } 00539 00540 if (fd1 != -1 && !S_ISREG(st.st_mode)) { 00541 close(fd1); 00542 fd1 = -1; 00543 } 00544 00545 /* If we're not preserving permissions, change the file-list's 00546 * mode based on the local permissions and some heuristics. */ 00547 if (!preserve_perms) { 00548 int exists = fd1 != -1; 00549 #ifdef SUPPORT_ACLS 00550 char *dn = file->dirname ? file->dirname : "."; 00551 if (parent_dirname != dn 00552 && strcmp(parent_dirname, dn) != 0) { 00553 dflt_perms = default_perms_for_dir(dn); 00554 parent_dirname = dn; 00555 } 00556 #endif 00557 file->mode = dest_mode(file->mode, st.st_mode, 00558 dflt_perms, exists); 00559 } 00560 00561 /* We now check to see if we are writing file "inplace" */ 00562 if (inplace) { 00563 fd2 = do_open(fname, O_WRONLY|O_CREAT, 0600); 00564 if (fd2 == -1) { 00565 rsyserr(FERROR, errno, "open %s failed", 00566 full_fname(fname)); 00567 discard_receive_data(f_in, file->length); 00568 if (fd1 != -1) 00569 close(fd1); 00570 continue; 00571 } 00572 } else { 00573 if (!get_tmpname(fnametmp,fname)) { 00574 discard_receive_data(f_in, file->length); 00575 if (fd1 != -1) 00576 close(fd1); 00577 continue; 00578 } 00579 00580 /* we initially set the perms without the 00581 * setuid/setgid bits to ensure that there is no race 00582 * condition. They are then correctly updated after 00583 * the lchown. Thanks to snabb@epipe.fi for pointing 00584 * this out. We also set it initially without group 00585 * access because of a similar race condition. */ 00586 fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); 00587 00588 /* in most cases parent directories will already exist 00589 * because their information should have been previously 00590 * transferred, but that may not be the case with -R */ 00591 if (fd2 == -1 && relative_paths && errno == ENOENT 00592 && create_directory_path(fnametmp) == 0) { 00593 /* Get back to name with XXXXXX in it. */ 00594 get_tmpname(fnametmp, fname); 00595 fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); 00596 } 00597 if (fd2 == -1) { 00598 rsyserr(FERROR, errno, "mkstemp %s failed", 00599 full_fname(fnametmp)); 00600 discard_receive_data(f_in, file->length); 00601 if (fd1 != -1) 00602 close(fd1); 00603 continue; 00604 } 00605 00606 if (keep_partial) 00607 cleanup_set(fnametmp, partialptr, file, fd1, fd2); 00608 } 00609 00610 /* log the transfer */ 00611 if (log_before_transfer) 00612 log_item(file, &initial_stats, iflags, NULL); 00613 else if (!am_server && verbose && do_progress) 00614 rprintf(FINFO, "%s\n", fname); 00615 00616 /* recv file data */ 00617 recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size, 00618 fname, fd2, file->length); 00619 00620 if (!log_before_transfer) 00621 log_item(file, &initial_stats, iflags, NULL); 00622 00623 if (fd1 != -1) 00624 close(fd1); 00625 if (close(fd2) < 0) { 00626 rsyserr(FERROR, errno, "close failed on %s", 00627 full_fname(fnametmp)); 00628 exit_cleanup(RERR_FILEIO); 00629 } 00630 00631 if ((recv_ok && (!delay_updates || !partialptr)) || inplace) { 00632 if (partialptr == fname || *partial_dir == '/') 00633 partialptr = NULL; 00634 finish_transfer(fname, fnametmp, partialptr, 00635 file, recv_ok, 1); 00636 if (fnamecmp == partialptr) { 00637 do_unlink(partialptr); 00638 handle_partial_dir(partialptr, PDIR_DELETE); 00639 } 00640 } else if (keep_partial && partialptr 00641 && handle_partial_dir(partialptr, PDIR_CREATE)) { 00642 finish_transfer(partialptr, fnametmp, NULL, 00643 file, recv_ok, !partial_dir); 00644 if (delay_updates && recv_ok) { 00645 bitbag_set_bit(delayed_bits, i); 00646 recv_ok = -1; 00647 } 00648 } else { 00649 partialptr = NULL; 00650 do_unlink(fnametmp); 00651 } 00652 00653 cleanup_disable(); 00654 00655 if (recv_ok > 0) { 00656 if (remove_sent_files 00657 || (preserve_hard_links && file->link_u.links)) { 00658 SIVAL(numbuf, 0, i); 00659 send_msg(MSG_SUCCESS, numbuf, 4); 00660 } 00661 } else if (!recv_ok) { 00662 int msgtype = phase || read_batch ? FERROR : FINFO; 00663 if (msgtype == FERROR || verbose) { 00664 char *errstr, *redostr, *keptstr; 00665 if (!(keep_partial && partialptr) && !inplace) 00666 keptstr = "discarded"; 00667 else if (partial_dir) 00668 keptstr = "put into partial-dir"; 00669 else 00670 keptstr = "retained"; 00671 if (msgtype == FERROR) { 00672 errstr = "ERROR"; 00673 redostr = ""; 00674 } else { 00675 errstr = "WARNING"; 00676 redostr = " (will try again)"; 00677 } 00678 rprintf(msgtype, 00679 "%s: %s failed verification -- update %s%s.\n", 00680 errstr, fname, keptstr, redostr); 00681 } 00682 if (!phase) { 00683 SIVAL(numbuf, 0, i); 00684 send_msg(MSG_REDO, numbuf, 4); 00685 } 00686 } 00687 } 00688 make_backups = save_make_backups; 00689 00690 if (phase == 2 && delay_updates) /* for protocol_version < 29 */ 00691 handle_delayed_updates(flist, local_name); 00692 00693 if (verbose > 2) 00694 rprintf(FINFO,"recv_files finished\n"); 00695 00696 return 0; 00697 }
int do_progress |
int log_format_has_i |
clientserver.c の 58 行で定義されています。
int csum_length |
checksum.c の 22 行で定義されています。
int read_batch |
int write_batch |
int batch_gen_fd |
int protocol_version |
int relative_paths |
int preserve_perms |
int basis_dir_cnt |
int make_backups |
Set to True once literal data has been sent across the link for the current file.
(????)
Handling the cleanup when a transfer is interrupted is tricky when --partial is selected. We need to ensure that the partial file is kept if any real data has been transferred.
参照元 _exit_cleanup()・cleanup_disable()・receive_data()・recv_files().
int append_mode |
int sparse_files |
int keep_partial |
int checksum_seed |
int delay_updates |
mode_t orig_umask |
char* log_format |
char* partial_dir |
struct file_list* the_file_list |
struct bitbag* delayed_bits = NULL [static] |
int phase = 0 [static] |
receiver.c の 59 行で定義されています。