データ構造 | |
struct | pid_status |
関数 | |
static void | show_malloc_stats (void) |
If our C library can get malloc statistics, then show them to FINFO | |
pid_t | wait_process (pid_t pid, int *status_ptr, int flags) |
static void | wait_process_with_flush (pid_t pid, int *exit_code_ptr) |
static void | handle_stats (int f) |
static void | output_summary (void) |
static pid_t | do_cmd (char *cmd, char *machine, char *user, char *path, int *f_in, int *f_out) |
static char * | get_local_name (struct file_list *flist, char *dest_path) |
static void | read_final_goodbye (int f_in, int f_out) |
static void | do_server_sender (int f_in, int f_out, int argc, char *argv[]) |
static int | do_recv (int f_in, int f_out, struct file_list *flist, char *local_name) |
static void | do_server_recv (int f_in, int f_out, int argc, char *argv[]) |
int | child_main (int argc, char *argv[]) |
void | start_server (int f_in, int f_out, int argc, char *argv[]) |
int | client_run (int f_in, int f_out, pid_t pid, int argc, char *argv[]) |
static int | copy_argv (char *argv[]) |
static int | start_client (int argc, char *argv[]) |
Start a client for either type of remote connection. | |
static RETSIGTYPE | sigusr1_handler (UNUSED(int val)) |
static RETSIGTYPE | sigusr2_handler (UNUSED(int val)) |
RETSIGTYPE | remember_children (UNUSED(int val)) |
const char * | get_panic_action (void) |
This routine catches signals and tries to send them to gdb. | |
static RETSIGTYPE | rsync_panic_handler (UNUSED(int whatsig)) |
Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION. | |
int | main (int argc, char *argv[]) |
変数 | |
int | verbose |
int | dry_run |
int | list_only |
int | am_root |
int | am_server |
int | am_sender |
int | am_generator |
int | am_daemon |
int | blocking_io |
int | remove_sent_files |
int | daemon_over_rsh |
int | need_messages_from_generator |
int | kluge_around_eof |
int | do_stats |
int | log_got_error |
int | module_id |
int | copy_links |
int | copy_dirlinks |
int | keep_dirlinks |
int | preserve_hard_links |
int | protocol_version |
int | recurse |
int | relative_paths |
int | rsync_port |
int | whole_file |
If 1, send the whole file as literal data rather than trying to create an incremental diff. | |
int | read_batch |
int | write_batch |
int | batch_fd |
int | batch_gen_fd |
int | filesfrom_fd |
pid_t | cleanup_child_pid |
stats | stats |
char * | filesfrom_host |
char * | rsync_path |
char * | shell_cmd |
char * | batch_name |
int | local_server = 0 |
mode_t | orig_umask = 0 |
file_list * | the_file_list |
static struct sigaction | sigact |
pid_status | pid_stat_table [MAXCHILDPROCS] |
static time_t | starttime |
static time_t | endtime |
static int64 | total_read |
static int64 | total_written |
static void show_malloc_stats | ( | void | ) | [static] |
If our C library can get malloc statistics, then show them to FINFO
参照先 am_daemon・am_server・FINFO・rprintf()・who_am_i().
参照元 handle_stats().
00264 { 00265 #ifdef HAVE_MALLINFO 00266 struct mallinfo mi; 00267 00268 mi = mallinfo(); 00269 00270 rprintf(FINFO, "\n" RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n", 00271 getpid(), am_server ? "server " : "", 00272 am_daemon ? "daemon " : "", who_am_i()); 00273 rprintf(FINFO, " arena: %10ld (bytes from sbrk)\n", 00274 (long)mi.arena); 00275 rprintf(FINFO, " ordblks: %10ld (chunks not in use)\n", 00276 (long)mi.ordblks); 00277 rprintf(FINFO, " smblks: %10ld\n", 00278 (long)mi.smblks); 00279 rprintf(FINFO, " hblks: %10ld (chunks from mmap)\n", 00280 (long)mi.hblks); 00281 rprintf(FINFO, " hblkhd: %10ld (bytes from mmap)\n", 00282 (long)mi.hblkhd); 00283 rprintf(FINFO, " allmem: %10ld (bytes from sbrk + mmap)\n", 00284 (long)mi.arena + mi.hblkhd); 00285 rprintf(FINFO, " usmblks: %10ld\n", 00286 (long)mi.usmblks); 00287 rprintf(FINFO, " fsmblks: %10ld\n", 00288 (long)mi.fsmblks); 00289 rprintf(FINFO, " uordblks: %10ld (bytes used)\n", 00290 (long)mi.uordblks); 00291 rprintf(FINFO, " fordblks: %10ld (bytes free)\n", 00292 (long)mi.fordblks); 00293 rprintf(FINFO, " keepcost: %10ld (bytes in releasable chunk)\n", 00294 (long)mi.keepcost); 00295 #endif /* HAVE_MALLINFO */ 00296 }
pid_t wait_process | ( | pid_t | pid, | |
int * | status_ptr, | |||
int | flags | |||
) |
参照先 errno・pid_status::pid・pid_stat_table・waitpid().
参照元 _exit_cleanup()・finish_pre_exec()・rsync_module()・wait_process_with_flush().
00094 { 00095 pid_t waited_pid = waitpid(pid, status_ptr, flags); 00096 00097 if (waited_pid == -1 && errno == ECHILD) { 00098 /* Status of requested child no longer available: check to 00099 * see if it was processed by remember_children(). */ 00100 int cnt; 00101 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) { 00102 if (pid == pid_stat_table[cnt].pid) { 00103 *status_ptr = pid_stat_table[cnt].status; 00104 pid_stat_table[cnt].pid = 0; 00105 return pid; 00106 } 00107 } 00108 } 00109 00110 return waited_pid; 00111 }
static void wait_process_with_flush | ( | pid_t | pid, | |
int * | exit_code_ptr | |||
) | [static] |
参照先 errno・FERROR・io_flush()・msleep()・rsyserr()・wait_process().
参照元 client_run()・do_recv().
00115 { 00116 pid_t waited_pid; 00117 int status; 00118 00119 while ((waited_pid = wait_process(pid, &status, WNOHANG)) == 0) { 00120 msleep(20); 00121 io_flush(FULL_FLUSH); 00122 } 00123 00124 /* TODO: If the child exited on a signal, then log an 00125 * appropriate error message. Perhaps we should also accept a 00126 * message describing the purpose of the child. Also indicate 00127 * this to the caller so that they know something went wrong. */ 00128 if (waited_pid < 0) { 00129 rsyserr(FERROR, errno, "waitpid"); 00130 *exit_code_ptr = RERR_WAITCHILD; 00131 } else if (!WIFEXITED(status)) { 00132 #ifdef WCOREDUMP 00133 if (WCOREDUMP(status)) 00134 *exit_code_ptr = RERR_CRASHED; 00135 else 00136 #endif 00137 if (WIFSIGNALED(status)) 00138 *exit_code_ptr = RERR_TERMINATED; 00139 else 00140 *exit_code_ptr = RERR_WAITCHILD; 00141 } else 00142 *exit_code_ptr = WEXITSTATUS(status); 00143 }
static void handle_stats | ( | int | f | ) | [static] |
参照先 am_daemon・am_generator・am_sender・am_server・batch_fd・do_stats・endtime・stats::flist_buildtime・stats::flist_xfertime・log_exit()・protocol_version・read_longint()・show_flist_stats()・show_malloc_stats()・stats・stats::total_read・total_read・stats::total_size・stats::total_written・total_written・verbose・write_batch・write_longint().
参照元 client_run()・do_recv()・do_server_sender().
00154 { 00155 endtime = time(NULL); 00156 00157 /* Cache two stats because the read/write code can change it. */ 00158 total_read = stats.total_read; 00159 total_written = stats.total_written; 00160 00161 if (do_stats && verbose > 1) { 00162 /* These come out from every process */ 00163 show_malloc_stats(); 00164 show_flist_stats(); 00165 } 00166 00167 if (am_generator) 00168 return; 00169 00170 if (am_daemon) { 00171 log_exit(0, __FILE__, __LINE__); 00172 if (f == -1 || !am_sender) 00173 return; 00174 } 00175 00176 if (am_server) { 00177 if (am_sender) { 00178 write_longint(f, total_read); 00179 write_longint(f, total_written); 00180 write_longint(f, stats.total_size); 00181 if (protocol_version >= 29) { 00182 write_longint(f, stats.flist_buildtime); 00183 write_longint(f, stats.flist_xfertime); 00184 } 00185 } 00186 return; 00187 } 00188 00189 /* this is the client */ 00190 00191 if (f < 0 && !am_sender) /* e.g. when we got an empty file list. */ 00192 ; 00193 else if (!am_sender) { 00194 /* Read the first two in opposite order because the meaning of 00195 * read/write swaps when switching from sender to receiver. */ 00196 total_written = read_longint(f); 00197 total_read = read_longint(f); 00198 stats.total_size = read_longint(f); 00199 if (protocol_version >= 29) { 00200 stats.flist_buildtime = read_longint(f); 00201 stats.flist_xfertime = read_longint(f); 00202 } 00203 } else if (write_batch) { 00204 /* The --read-batch process is going to be a client 00205 * receiver, so we need to give it the stats. */ 00206 write_longint(batch_fd, total_read); 00207 write_longint(batch_fd, total_written); 00208 write_longint(batch_fd, stats.total_size); 00209 if (protocol_version >= 29) { 00210 write_longint(batch_fd, stats.flist_buildtime); 00211 write_longint(batch_fd, stats.flist_xfertime); 00212 } 00213 } 00214 }
static void output_summary | ( | void | ) | [static] |
参照先 do_stats・endtime・FINFO・stats::flist_buildtime・stats::flist_size・stats::flist_xfertime・human_dnum()・human_num()・stats::literal_data・stats::matched_data・stats::num_files・stats::num_transferred_files・rprintf()・starttime・stats・total_read・stats::total_size・stats::total_transferred_size・total_written・verbose.
参照元 client_run()・sigusr2_handler().
00217 { 00218 if (do_stats) { 00219 rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files); 00220 rprintf(FINFO,"Number of files transferred: %d\n", 00221 stats.num_transferred_files); 00222 rprintf(FINFO,"Total file size: %s bytes\n", 00223 human_num(stats.total_size)); 00224 rprintf(FINFO,"Total transferred file size: %s bytes\n", 00225 human_num(stats.total_transferred_size)); 00226 rprintf(FINFO,"Literal data: %s bytes\n", 00227 human_num(stats.literal_data)); 00228 rprintf(FINFO,"Matched data: %s bytes\n", 00229 human_num(stats.matched_data)); 00230 rprintf(FINFO,"File list size: %d\n", stats.flist_size); 00231 if (stats.flist_buildtime) { 00232 rprintf(FINFO, 00233 "File list generation time: %.3f seconds\n", 00234 (double)stats.flist_buildtime / 1000); 00235 rprintf(FINFO, 00236 "File list transfer time: %.3f seconds\n", 00237 (double)stats.flist_xfertime / 1000); 00238 } 00239 rprintf(FINFO,"Total bytes sent: %s\n", 00240 human_num(total_written)); 00241 rprintf(FINFO,"Total bytes received: %s\n", 00242 human_num(total_read)); 00243 } 00244 00245 if (verbose || do_stats) { 00246 rprintf(FINFO, 00247 "\nsent %s bytes received %s bytes %s bytes/sec\n", 00248 human_num(total_written), human_num(total_read), 00249 human_dnum((total_written + total_read)/(0.5 + (endtime - starttime)), 2)); 00250 rprintf(FINFO, "total size is %s speedup is %.2f\n", 00251 human_num(stats.total_size), 00252 (double)stats.total_size / (total_written+total_read)); 00253 } 00254 00255 fflush(stdout); 00256 fflush(stderr); 00257 }
static pid_t do_cmd | ( | char * | cmd, | |
char * | machine, | |||
char * | user, | |||
char * | path, | |||
int * | f_in, | |||
int * | f_out | |||
) | [static] |
参照先 batch_fd・batch_gen_fd・blocking_io・child_main()・daemon_over_rsh・errno・fd_pair()・FERROR・FINFO・local_child()・local_server・out_of_memory()・piped_child()・read_batch・rprintf()・rsync_path・rsyserr()・server_options()・strdup()・verbose・whole_file・write_batch.
参照元 start_client().
00302 { 00303 int i, argc = 0; 00304 char *args[MAX_ARGS]; 00305 pid_t ret; 00306 char *dir = NULL; 00307 int dash_l_set = 0; 00308 00309 if (!read_batch && !local_server) { 00310 char *t, *f, in_quote = '\0'; 00311 char *rsh_env = getenv(RSYNC_RSH_ENV); 00312 if (!cmd) 00313 cmd = rsh_env; 00314 if (!cmd) 00315 cmd = RSYNC_RSH; 00316 cmd = strdup(cmd); 00317 if (!cmd) 00318 goto oom; 00319 00320 for (t = f = cmd; *f; f++) { 00321 if (*f == ' ') 00322 continue; 00323 /* Comparison leaves rooms for server_options(). */ 00324 if (argc >= MAX_ARGS - MAX_SERVER_ARGS) { 00325 rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n"); 00326 exit_cleanup(RERR_SYNTAX); 00327 } 00328 args[argc++] = t; 00329 while (*f != ' ' || in_quote) { 00330 if (!*f) { 00331 if (in_quote) { 00332 rprintf(FERROR, 00333 "Missing trailing-%c in remote-shell command.\n", 00334 in_quote); 00335 exit_cleanup(RERR_SYNTAX); 00336 } 00337 f--; 00338 break; 00339 } 00340 if (*f == '\'' || *f == '"') { 00341 if (!in_quote) { 00342 in_quote = *f++; 00343 continue; 00344 } 00345 if (*f == in_quote && *++f != in_quote) { 00346 in_quote = '\0'; 00347 continue; 00348 } 00349 } 00350 *t++ = *f++; 00351 } 00352 *t++ = '\0'; 00353 } 00354 00355 /* check to see if we've already been given '-l user' in 00356 * the remote-shell command */ 00357 for (i = 0; i < argc-1; i++) { 00358 if (!strcmp(args[i], "-l") && args[i+1][0] != '-') 00359 dash_l_set = 1; 00360 } 00361 00362 #ifdef HAVE_REMSH 00363 /* remsh (on HPUX) takes the arguments the other way around */ 00364 args[argc++] = machine; 00365 if (user && !(daemon_over_rsh && dash_l_set)) { 00366 args[argc++] = "-l"; 00367 args[argc++] = user; 00368 } 00369 #else 00370 if (user && !(daemon_over_rsh && dash_l_set)) { 00371 args[argc++] = "-l"; 00372 args[argc++] = user; 00373 } 00374 args[argc++] = machine; 00375 #endif 00376 00377 args[argc++] = rsync_path; 00378 00379 if (blocking_io < 0) { 00380 char *cp; 00381 if ((cp = strrchr(cmd, '/')) != NULL) 00382 cp++; 00383 else 00384 cp = cmd; 00385 if (strcmp(cp, "rsh") == 0 || strcmp(cp, "remsh") == 0) 00386 blocking_io = 1; 00387 } 00388 00389 server_options(args,&argc); 00390 00391 if (argc >= MAX_ARGS - 2) { 00392 rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n"); 00393 exit_cleanup(RERR_SYNTAX); 00394 } 00395 } 00396 00397 args[argc++] = "."; 00398 00399 if (!daemon_over_rsh && path && *path) 00400 args[argc++] = path; 00401 00402 args[argc] = NULL; 00403 00404 if (verbose > 3) { 00405 for (i = 0; i < argc; i++) 00406 rprintf(FINFO, "cmd[%d]=%s ", i, args[i]); 00407 rprintf(FINFO, "\n"); 00408 } 00409 00410 if (read_batch) { 00411 int from_gen_pipe[2]; 00412 if (fd_pair(from_gen_pipe) < 0) { 00413 rsyserr(FERROR, errno, "pipe"); 00414 exit_cleanup(RERR_IPC); 00415 } 00416 batch_gen_fd = from_gen_pipe[0]; 00417 *f_out = from_gen_pipe[1]; 00418 *f_in = batch_fd; 00419 ret = -1; /* no child pid */ 00420 } else if (local_server) { 00421 /* If the user didn't request --[no-]whole-file, force 00422 * it on, but only if we're not batch processing. */ 00423 if (whole_file < 0 && !write_batch) 00424 whole_file = 1; 00425 ret = local_child(argc, args, f_in, f_out, child_main); 00426 } else 00427 ret = piped_child(args,f_in,f_out); 00428 00429 if (dir) 00430 free(dir); 00431 00432 return ret; 00433 00434 oom: 00435 out_of_memory("do_cmd"); 00436 return 0; /* not reached */ 00437 }
static char* get_local_name | ( | struct file_list * | flist, | |
char * | dest_path | |||
) | [static] |
参照先 file_list::count・do_stat()・dry_run・errno・FERROR・file_list::files・FINFO・full_fname()・list_only・mkdir_defmode()・file_struct::mode・push_dir()・rprintf()・rsyserr()・verbose.
参照元 client_run()・do_server_recv().
00452 { 00453 STRUCT_STAT st; 00454 char *cp; 00455 00456 if (verbose > 2) { 00457 rprintf(FINFO, "get_local_name count=%d %s\n", 00458 flist->count, NS(dest_path)); 00459 } 00460 00461 if (!dest_path || list_only) 00462 return NULL; 00463 00464 /* If the destination path refers to an existing directory, enter 00465 * it and use mode 1. If there is something other than a directory 00466 * at the destination path, we must be transferring one file 00467 * (anything at the destination will be overwritten). */ 00468 if (do_stat(dest_path, &st) == 0) { 00469 if (S_ISDIR(st.st_mode)) { 00470 if (!push_dir(dest_path)) { 00471 rsyserr(FERROR, errno, "push_dir#1 %s failed", 00472 full_fname(dest_path)); 00473 exit_cleanup(RERR_FILESELECT); 00474 } 00475 return NULL; 00476 } 00477 if (flist->count > 1) { 00478 rprintf(FERROR, 00479 "ERROR: destination must be a directory when" 00480 " copying more than 1 file\n"); 00481 exit_cleanup(RERR_FILESELECT); 00482 } 00483 /* Caution: flist->count could be 0! */ 00484 if (flist->count == 1 && S_ISDIR(flist->files[0]->mode)) { 00485 rprintf(FERROR, 00486 "ERROR: cannot overwrite non-directory" 00487 " with a directory\n"); 00488 exit_cleanup(RERR_FILESELECT); 00489 } 00490 } else if (errno != ENOENT) { 00491 rsyserr(FERROR, errno, "cannot stat destination %s", 00492 full_fname(dest_path)); 00493 exit_cleanup(RERR_FILESELECT); 00494 } 00495 00496 cp = strrchr(dest_path, '/'); 00497 00498 /* If the destination path ends in a slash or we are transferring 00499 * multiple files, create a directory at the destination path, 00500 * enter the new directory, and use mode 1. */ 00501 if (flist->count > 1 || (cp && !cp[1])) { 00502 /* Lop off the final slash (if any). */ 00503 if (cp && !cp[1]) 00504 *cp = '\0'; 00505 00506 if (mkdir_defmode(dest_path) != 0) { 00507 rsyserr(FERROR, errno, "mkdir %s failed", 00508 full_fname(dest_path)); 00509 exit_cleanup(RERR_FILEIO); 00510 } 00511 00512 if (verbose) 00513 rprintf(FINFO, "created directory %s\n", dest_path); 00514 00515 if (dry_run) { 00516 /* Indicate that the destination directory doesn't 00517 * really exist and return mode 1. */ 00518 dry_run++; 00519 return NULL; 00520 } 00521 00522 if (!push_dir(dest_path)) { 00523 rsyserr(FERROR, errno, "push_dir#2 %s failed", 00524 full_fname(dest_path)); 00525 exit_cleanup(RERR_FILESELECT); 00526 } 00527 00528 return NULL; 00529 } 00530 00531 /* Otherwise, we are writing a single file, possibly on top of an 00532 * existing non-directory. Change to the item's parent directory 00533 * (if it has a path component), return the basename of the 00534 * destination file as the local name, and use mode 2. */ 00535 if (!cp) 00536 return dest_path; 00537 00538 if (cp == dest_path) 00539 dest_path = "/"; 00540 00541 *cp = '\0'; 00542 if (!push_dir(dest_path)) { 00543 rsyserr(FERROR, errno, "push_dir#3 %s failed", 00544 full_fname(dest_path)); 00545 exit_cleanup(RERR_FILESELECT); 00546 } 00547 *cp = '/'; 00548 00549 return cp + 1; 00550 }
static void read_final_goodbye | ( | int | f_in, | |
int | f_out | |||
) | [static] |
参照先 file_list::count・FERROR・protocol_version・read_int()・read_shortint()・rprintf()・the_file_list・who_am_i()・write_int()・write_shortint().
参照元 client_run()・do_server_sender().
00555 { 00556 int i; 00557 00558 if (protocol_version < 29) 00559 i = read_int(f_in); 00560 else { 00561 while ((i = read_int(f_in)) == the_file_list->count 00562 && read_shortint(f_in) == ITEM_IS_NEW) { 00563 /* Forward the keep-alive (no-op) to the receiver. */ 00564 write_int(f_out, the_file_list->count); 00565 write_shortint(f_out, ITEM_IS_NEW); 00566 } 00567 } 00568 00569 if (i != -1) { 00570 rprintf(FERROR, "Invalid packet at end of run (%d) [%s]\n", 00571 i, who_am_i()); 00572 exit_cleanup(RERR_PROTOCOL); 00573 } 00574 }
static void do_server_sender | ( | int | f_in, | |
int | f_out, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
参照先 am_daemon・file_list::count・errno・FERROR・FINFO・full_fname()・handle_stats()・io_flush()・io_start_buffering_in()・io_start_buffering_out()・list_only・module_id・protocol_version・push_dir()・read_final_goodbye()・recurse・relative_paths・remove_sent_files・rprintf()・rsyserr()・send_file_list()・send_files()・the_file_list・verbose.
参照元 start_server().
00578 { 00579 struct file_list *flist; 00580 char *dir = argv[0]; 00581 00582 if (verbose > 2) { 00583 rprintf(FINFO, "server_sender starting pid=%ld\n", 00584 (long)getpid()); 00585 } 00586 00587 if (am_daemon && lp_write_only(module_id)) { 00588 rprintf(FERROR, "ERROR: module is write only\n"); 00589 exit_cleanup(RERR_SYNTAX); 00590 return; 00591 } 00592 if (am_daemon && lp_read_only(module_id) && remove_sent_files) { 00593 rprintf(FERROR, 00594 "ERROR: --remove-sent-files cannot be used with a read-only module\n"); 00595 exit_cleanup(RERR_SYNTAX); 00596 return; 00597 } 00598 00599 if (!relative_paths && !push_dir(dir)) { 00600 rsyserr(FERROR, errno, "push_dir#3 %s failed", 00601 full_fname(dir)); 00602 exit_cleanup(RERR_FILESELECT); 00603 } 00604 argc--; 00605 argv++; 00606 00607 if (argc == 0 && (recurse || list_only)) { 00608 argc = 1; 00609 argv--; 00610 argv[0] = "."; 00611 } 00612 00613 flist = send_file_list(f_out,argc,argv); 00614 if (!flist || flist->count == 0) { 00615 exit_cleanup(0); 00616 } 00617 the_file_list = flist; 00618 00619 io_start_buffering_in(); 00620 io_start_buffering_out(); 00621 00622 send_files(flist,f_out,f_in); 00623 io_flush(FULL_FLUSH); 00624 handle_stats(f_out); 00625 if (protocol_version >= 24) 00626 read_final_goodbye(f_in, f_out); 00627 io_flush(FULL_FLUSH); 00628 exit_cleanup(0); 00629 }
static int do_recv | ( | int | f_in, | |
int | f_out, | |||
struct file_list * | flist, | |||
char * | local_name | |||
) | [static] |
参照先 am_generator・am_server・close_multiplexing_in()・close_multiplexing_out()・copy_dirlinks・copy_links・file_list::count・do_fork()・errno・fd_pair()・FERROR・generate_files()・handle_stats()・init_hard_links()・io_flush()・io_start_buffering_out()・kluge_around_eof・MSG_DONE・msleep()・preserve_hard_links・protocol_version・read_int()・read_shortint()・recv_files()・rprintf()・rsyserr()・send_msg()・set_msg_fd_in()・set_msg_fd_out()・stop_write_batch()・wait_process_with_flush()・who_am_i()・write_batch・write_int().
参照元 client_run()・do_server_recv().
00633 { 00634 int pid; 00635 int exit_code = 0; 00636 int error_pipe[2]; 00637 00638 /* The receiving side mustn't obey this, or an existing symlink that 00639 * points to an identical file won't be replaced by the referent. */ 00640 copy_links = copy_dirlinks = 0; 00641 00642 if (preserve_hard_links) 00643 init_hard_links(); 00644 00645 if (fd_pair(error_pipe) < 0) { 00646 rsyserr(FERROR, errno, "pipe failed in do_recv"); 00647 exit_cleanup(RERR_IPC); 00648 } 00649 00650 io_flush(NORMAL_FLUSH); 00651 00652 if ((pid = do_fork()) == -1) { 00653 rsyserr(FERROR, errno, "fork failed in do_recv"); 00654 exit_cleanup(RERR_IPC); 00655 } 00656 00657 if (pid == 0) { 00658 close(error_pipe[0]); 00659 if (f_in != f_out) 00660 close(f_out); 00661 00662 /* we can't let two processes write to the socket at one time */ 00663 close_multiplexing_out(); 00664 00665 /* set place to send errors */ 00666 set_msg_fd_out(error_pipe[1]); 00667 00668 recv_files(f_in, flist, local_name); 00669 io_flush(FULL_FLUSH); 00670 handle_stats(f_in); 00671 00672 send_msg(MSG_DONE, "", 0); 00673 io_flush(FULL_FLUSH); 00674 00675 /* Handle any keep-alive packets from the post-processing work 00676 * that the generator does. */ 00677 if (protocol_version >= 29) { 00678 kluge_around_eof = -1; 00679 00680 /* This should only get stopped via a USR2 signal. */ 00681 while (read_int(f_in) == flist->count 00682 && read_shortint(f_in) == ITEM_IS_NEW) {} 00683 00684 rprintf(FERROR, "Invalid packet at end of run [%s]\n", 00685 who_am_i()); 00686 exit_cleanup(RERR_PROTOCOL); 00687 } 00688 00689 /* Finally, we go to sleep until our parent kills us with a 00690 * USR2 signal. We sleep for a short time, as on some OSes 00691 * a signal won't interrupt a sleep! */ 00692 while (1) 00693 msleep(20); 00694 } 00695 00696 am_generator = 1; 00697 close_multiplexing_in(); 00698 if (write_batch && !am_server) 00699 stop_write_batch(); 00700 00701 close(error_pipe[1]); 00702 if (f_in != f_out) 00703 close(f_in); 00704 00705 io_start_buffering_out(); 00706 00707 set_msg_fd_in(error_pipe[0]); 00708 00709 generate_files(f_out, flist, local_name); 00710 00711 handle_stats(-1); 00712 io_flush(FULL_FLUSH); 00713 if (protocol_version >= 24) { 00714 /* send a final goodbye message */ 00715 write_int(f_out, -1); 00716 } 00717 io_flush(FULL_FLUSH); 00718 00719 set_msg_fd_in(-1); 00720 kill(pid, SIGUSR2); 00721 wait_process_with_flush(pid, &exit_code); 00722 return exit_code; 00723 }
static void do_server_recv | ( | int | f_in, | |
int | f_out, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
参照先 am_daemon・do_recv()・errno・FERROR・filesfrom_fd・FINFO・full_fname()・get_local_name()・io_set_filesfrom_fds()・io_start_buffering_in()・module_id・push_dir()・recv_file_list()・recv_filter_list()・rprintf()・rsyserr()・the_file_list・verbose.
参照元 start_server().
00727 { 00728 int exit_code; 00729 struct file_list *flist; 00730 char *local_name = NULL; 00731 char *dir = NULL; 00732 int save_verbose = verbose; 00733 00734 if (filesfrom_fd >= 0) { 00735 /* We can't mix messages with files-from data on the socket, 00736 * so temporarily turn off verbose messages. */ 00737 verbose = 0; 00738 } 00739 00740 if (verbose > 2) { 00741 rprintf(FINFO, "server_recv(%d) starting pid=%ld\n", 00742 argc, (long)getpid()); 00743 } 00744 00745 if (am_daemon && lp_read_only(module_id)) { 00746 rprintf(FERROR,"ERROR: module is read only\n"); 00747 exit_cleanup(RERR_SYNTAX); 00748 return; 00749 } 00750 00751 if (argc > 0) { 00752 dir = argv[0]; 00753 argc--; 00754 argv++; 00755 if (!am_daemon && !push_dir(dir)) { 00756 rsyserr(FERROR, errno, "push_dir#4 %s failed", 00757 full_fname(dir)); 00758 exit_cleanup(RERR_FILESELECT); 00759 } 00760 } 00761 00762 io_start_buffering_in(); 00763 recv_filter_list(f_in); 00764 00765 if (filesfrom_fd >= 0) { 00766 /* We need to send the files-from names to the sender at the 00767 * same time that we receive the file-list from them, so we 00768 * need the IO routines to automatically write out the names 00769 * onto our f_out socket as we read the file-list. This 00770 * avoids both deadlock and extra delays/buffers. */ 00771 io_set_filesfrom_fds(filesfrom_fd, f_out); 00772 filesfrom_fd = -1; 00773 } 00774 00775 flist = recv_file_list(f_in); 00776 verbose = save_verbose; 00777 if (!flist) { 00778 rprintf(FERROR,"server_recv: recv_file_list error\n"); 00779 exit_cleanup(RERR_FILESELECT); 00780 } 00781 the_file_list = flist; 00782 00783 if (argc > 0) 00784 local_name = get_local_name(flist,argv[0]); 00785 00786 exit_code = do_recv(f_in,f_out,flist,local_name); 00787 exit_cleanup(exit_code); 00788 }
int child_main | ( | int | argc, | |
char * | argv[] | |||
) |
参照先 start_server().
参照元 do_cmd()・local_child().
00792 { 00793 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv); 00794 return 0; 00795 }
void start_server | ( | int | f_in, | |
int | f_out, | |||
int | argc, | |||
char * | argv[] | |||
) |
参照先 am_sender・do_server_recv()・do_server_sender()・io_set_sock_fds()・io_start_multiplex_in()・io_start_multiplex_out()・keep_dirlinks・need_messages_from_generator・protocol_version・recv_filter_list()・set_nonblocking()・setup_iconv()・setup_protocol().
参照元 child_main()・main()・rsync_module().
00799 { 00800 set_nonblocking(f_in); 00801 set_nonblocking(f_out); 00802 00803 io_set_sock_fds(f_in, f_out); 00804 setup_protocol(f_out, f_in); 00805 #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H 00806 setup_iconv(); 00807 #endif 00808 00809 if (protocol_version >= 23) 00810 io_start_multiplex_out(); 00811 00812 if (am_sender) { 00813 keep_dirlinks = 0; /* Must be disabled on the sender. */ 00814 if (need_messages_from_generator) 00815 io_start_multiplex_in(); 00816 00817 recv_filter_list(f_in); 00818 do_server_sender(f_in, f_out, argc, argv); 00819 } else { 00820 do_server_recv(f_in, f_out, argc, argv); 00821 } 00822 exit_cleanup(0); 00823 }
int client_run | ( | int | f_in, | |
int | f_out, | |||
pid_t | pid, | |||
int | argc, | |||
char * | argv[] | |||
) |
参照先 am_sender・am_server・cleanup_child_pid・file_list::count・do_recv()・filesfrom_fd・filesfrom_host・FINFO・get_local_name()・handle_stats()・io_flush()・io_set_filesfrom_fds()・io_set_sock_fds()・io_start_buffering_out()・io_start_multiplex_in()・io_start_multiplex_out()・keep_dirlinks・list_only・need_messages_from_generator・output_summary()・protocol_version・read_batch・read_final_goodbye()・recv_file_list()・rprintf()・send_file_list()・send_files()・send_filter_list()・set_blocking()・set_msg_fd_in()・set_nonblocking()・setup_iconv()・setup_protocol()・start_write_batch()・the_file_list・verbose・wait_process_with_flush()・write_batch.
参照元 start_client()・start_socket_client().
00831 { 00832 struct file_list *flist = NULL; 00833 int exit_code = 0, exit_code2 = 0; 00834 char *local_name = NULL; 00835 00836 cleanup_child_pid = pid; 00837 if (!read_batch) { 00838 set_nonblocking(f_in); 00839 set_nonblocking(f_out); 00840 } 00841 00842 io_set_sock_fds(f_in, f_out); 00843 setup_protocol(f_out,f_in); 00844 #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H 00845 setup_iconv(); 00846 #endif 00847 00848 if (protocol_version >= 23 && !read_batch) 00849 io_start_multiplex_in(); 00850 00851 /* We set our stderr file handle to blocking because ssh might have 00852 * set it to non-blocking. This can be particularly troublesome if 00853 * stderr is a clone of stdout, because ssh would have set our stdout 00854 * to non-blocking at the same time (which can easily cause us to lose 00855 * output from our print statements). This kluge shouldn't cause ssh 00856 * any problems for how we use it. Note also that we delayed setting 00857 * this until after the above protocol setup so that we know for sure 00858 * that ssh is done twiddling its file descriptors. */ 00859 set_blocking(STDERR_FILENO); 00860 00861 if (am_sender) { 00862 keep_dirlinks = 0; /* Must be disabled on the sender. */ 00863 io_start_buffering_out(); 00864 if (!filesfrom_host) 00865 set_msg_fd_in(f_in); 00866 send_filter_list(f_out); 00867 if (filesfrom_host) 00868 filesfrom_fd = f_in; 00869 00870 if (write_batch && !am_server) 00871 start_write_batch(f_out); 00872 flist = send_file_list(f_out, argc, argv); 00873 set_msg_fd_in(-1); 00874 if (verbose > 3) 00875 rprintf(FINFO,"file list sent\n"); 00876 the_file_list = flist; 00877 00878 io_flush(NORMAL_FLUSH); 00879 send_files(flist,f_out,f_in); 00880 io_flush(FULL_FLUSH); 00881 handle_stats(-1); 00882 if (protocol_version >= 24) 00883 read_final_goodbye(f_in, f_out); 00884 if (pid != -1) { 00885 if (verbose > 3) 00886 rprintf(FINFO,"client_run waiting on %d\n", (int) pid); 00887 io_flush(FULL_FLUSH); 00888 wait_process_with_flush(pid, &exit_code); 00889 } 00890 output_summary(); 00891 io_flush(FULL_FLUSH); 00892 exit_cleanup(exit_code); 00893 } 00894 00895 if (need_messages_from_generator && !read_batch) 00896 io_start_multiplex_out(); 00897 00898 if (argc == 0) 00899 list_only |= 1; 00900 00901 send_filter_list(read_batch ? -1 : f_out); 00902 00903 if (filesfrom_fd >= 0) { 00904 io_set_filesfrom_fds(filesfrom_fd, f_out); 00905 filesfrom_fd = -1; 00906 } 00907 00908 if (write_batch && !am_server) 00909 start_write_batch(f_in); 00910 flist = recv_file_list(f_in); 00911 the_file_list = flist; 00912 00913 if (flist && flist->count > 0) { 00914 local_name = get_local_name(flist, argv[0]); 00915 00916 exit_code2 = do_recv(f_in, f_out, flist, local_name); 00917 } else { 00918 handle_stats(-1); 00919 output_summary(); 00920 } 00921 00922 if (pid != -1) { 00923 if (verbose > 3) 00924 rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid); 00925 io_flush(FULL_FLUSH); 00926 wait_process_with_flush(pid, &exit_code); 00927 } 00928 00929 return MAX(exit_code, exit_code2); 00930 }
static int copy_argv | ( | char * | argv[] | ) | [static] |
参照先 FERROR・rprintf()・strdup().
参照元 start_client().
00933 { 00934 int i; 00935 00936 for (i = 0; argv[i]; i++) { 00937 if (!(argv[i] = strdup(argv[i]))) { 00938 rprintf (FERROR, "out of memory at %s(%d)\n", 00939 __FILE__, __LINE__); 00940 return RERR_MALLOC; 00941 } 00942 } 00943 00944 return 0; 00945 }
static int start_client | ( | int | argc, | |
char * | argv[] | |||
) | [static] |
Start a client for either type of remote connection.
Work out whether the arguments request a remote shell or rsyncd connection, and call the appropriate connection function, then run_client.
Calls either start_socket_client (for sockets) or do_cmd and client_run (for ssh).
参照先 am_sender・check_for_hostspec()・client_run()・copy_argv()・daemon_over_rsh・do_cmd()・FERROR・filesfrom_host・FINFO・list_only・local_server・read_batch・rprintf()・rsync_port・shell_cmd・start_inband_exchange()・start_socket_client()・usage()・verbose.
参照元 main().
00957 { 00958 char *p; 00959 char *shell_machine = NULL; 00960 char *shell_path = NULL; 00961 char *shell_user = NULL; 00962 int ret; 00963 pid_t pid; 00964 int f_in,f_out; 00965 int rc; 00966 00967 /* Don't clobber argv[] so that ps(1) can still show the right 00968 * command line. */ 00969 if ((rc = copy_argv(argv))) 00970 return rc; 00971 00972 if (!read_batch) { /* for read_batch, NO source is specified */ 00973 shell_path = check_for_hostspec(argv[0], &shell_machine, &rsync_port); 00974 if (shell_path) { /* source is remote */ 00975 char *dummy1; 00976 int dummy2; 00977 if (--argc 00978 && check_for_hostspec(argv[argc], &dummy1, &dummy2)) { 00979 rprintf(FERROR, 00980 "The source and destination cannot both be remote.\n"); 00981 exit_cleanup(RERR_SYNTAX); 00982 } 00983 argv++; 00984 if (filesfrom_host && *filesfrom_host 00985 && strcmp(filesfrom_host, shell_machine) != 0) { 00986 rprintf(FERROR, 00987 "--files-from hostname is not the same as the transfer hostname\n"); 00988 exit_cleanup(RERR_SYNTAX); 00989 } 00990 if (rsync_port) { 00991 if (!shell_cmd) { 00992 return start_socket_client(shell_machine, 00993 shell_path, 00994 argc, argv); 00995 } 00996 daemon_over_rsh = 1; 00997 } 00998 00999 am_sender = 0; 01000 } else { /* source is local, check dest arg */ 01001 am_sender = 1; 01002 01003 if (argc > 1) 01004 p = argv[--argc]; 01005 else { 01006 p = "."; 01007 list_only = 1; 01008 } 01009 01010 shell_path = check_for_hostspec(p, &shell_machine, &rsync_port); 01011 if (shell_path && filesfrom_host && *filesfrom_host 01012 && strcmp(filesfrom_host, shell_machine) != 0) { 01013 rprintf(FERROR, 01014 "--files-from hostname is not the same as the transfer hostname\n"); 01015 exit_cleanup(RERR_SYNTAX); 01016 } 01017 if (!shell_path) { /* no hostspec found, so src & dest are local */ 01018 local_server = 1; 01019 if (filesfrom_host) { 01020 rprintf(FERROR, 01021 "--files-from cannot be remote when the transfer is local\n"); 01022 exit_cleanup(RERR_SYNTAX); 01023 } 01024 shell_machine = NULL; 01025 shell_path = p; 01026 } else if (rsync_port) { 01027 if (!shell_cmd) { 01028 return start_socket_client(shell_machine, 01029 shell_path, 01030 argc, argv); 01031 } 01032 daemon_over_rsh = 1; 01033 } 01034 } 01035 } else { /* read_batch */ 01036 local_server = 1; 01037 shell_path = argv[argc-1]; 01038 if (check_for_hostspec(shell_path, &shell_machine, &rsync_port)) { 01039 rprintf(FERROR, "remote destination is not allowed with --read-batch\n"); 01040 exit_cleanup(RERR_SYNTAX); 01041 } 01042 } 01043 01044 if (shell_machine) { 01045 p = strrchr(shell_machine,'@'); 01046 if (p) { 01047 *p = 0; 01048 shell_user = shell_machine; 01049 shell_machine = p+1; 01050 } 01051 } 01052 01053 if (verbose > 3) { 01054 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n", 01055 shell_cmd ? shell_cmd : "", 01056 shell_machine ? shell_machine : "", 01057 shell_user ? shell_user : "", 01058 shell_path ? shell_path : ""); 01059 } 01060 01061 /* for remote source, only single dest arg can remain ... */ 01062 if (!am_sender && argc > 1) { 01063 usage(FERROR); 01064 exit_cleanup(RERR_SYNTAX); 01065 } 01066 01067 /* ... or no dest at all */ 01068 if (!am_sender && argc == 0) 01069 list_only |= 1; 01070 01071 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path, 01072 &f_in,&f_out); 01073 01074 /* if we're running an rsync server on the remote host over a 01075 * remote shell command, we need to do the RSYNCD protocol first */ 01076 if (daemon_over_rsh) { 01077 int tmpret; 01078 tmpret = start_inband_exchange(shell_user, shell_path, 01079 f_in, f_out, argc); 01080 if (tmpret < 0) 01081 return tmpret; 01082 } 01083 01084 ret = client_run(f_in, f_out, pid, argc, argv); 01085 01086 fflush(stdout); 01087 fflush(stderr); 01088 01089 return ret; 01090 }
static RETSIGTYPE sigusr1_handler | ( | UNUSED(int val) | ) | [static] |
static RETSIGTYPE sigusr2_handler | ( | UNUSED(int val) | ) | [static] |
参照先 am_server・close_all()・log_got_error・output_summary().
参照元 main().
01099 { 01100 if (!am_server) 01101 output_summary(); 01102 close_all(); 01103 if (log_got_error) 01104 _exit(RERR_PARTIAL); 01105 _exit(0); 01106 }
RETSIGTYPE remember_children | ( | UNUSED(int val) | ) |
参照先 pid_stat_table・pid_status::status・waitpid().
参照元 main()・start_daemon().
01109 { 01110 #ifdef WNOHANG 01111 int cnt, status; 01112 pid_t pid; 01113 /* An empty waitpid() loop was put here by Tridge and we could never 01114 * get him to explain why he put it in, so rather than taking it 01115 * out we're instead saving the child exit statuses for later use. 01116 * The waitpid() loop presumably eliminates all possibility of leaving 01117 * zombie children, maybe that's why he did it. */ 01118 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 01119 /* save the child's exit status */ 01120 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) { 01121 if (pid_stat_table[cnt].pid == 0) { 01122 pid_stat_table[cnt].pid = pid; 01123 pid_stat_table[cnt].status = status; 01124 break; 01125 } 01126 } 01127 } 01128 #endif 01129 #ifndef HAVE_SIGACTION 01130 signal(SIGCHLD, remember_children); 01131 #endif 01132 }
const char* get_panic_action | ( | void | ) |
This routine catches signals and tries to send them to gdb.
Because it's called from inside a signal handler it ought not to use too many library routines.
参照元 print_rsync_version()・rsync_panic_handler().
01150 { 01151 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION"); 01152 01153 if (cmd_fmt) 01154 return cmd_fmt; 01155 else 01156 return "xterm -display :0 -T Panic -n Panic " 01157 "-e gdb /proc/%d/exe %d"; 01158 }
static RETSIGTYPE rsync_panic_handler | ( | UNUSED(int whatsig) | ) | [static] |
Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
This signal handler is only installed if we were configured with --enable-maintainer-mode. Perhaps it should always be on and we should just look at the environment variable, but I'm a bit leery of a signal sending us into a busy loop.
参照先 get_panic_action()・sprintf().
参照元 main().
01170 { 01171 char cmd_buf[300]; 01172 int ret; 01173 01174 sprintf(cmd_buf, get_panic_action(), 01175 getpid(), getpid()); 01176 01177 /* Unless we failed to execute gdb, we allow the process to 01178 * continue. I'm not sure if that's right. */ 01179 ret = system(cmd_buf); 01180 if (ret) 01181 _exit(ret); 01182 }
int main | ( | int | argc, | |
char * | argv[] | |||
) |
参照先 am_daemon・am_root・am_server・batch_fd・batch_name・daemon_main()・do_open()・dry_run・errno・FERROR・full_fname()・init_flist()・option_error()・orig_umask・parse_arguments()・push_dir()・read_batch・read_stream_flags()・remember_children()・rsync_panic_handler()・rsyserr()・set_nonblocking()・sig_int()・sigact・sigusr1_handler()・sigusr2_handler()・start_client()・start_daemon()・start_server()・starttime・stats・usage()・write_batch・write_batch_shell_file().
01187 { 01188 int ret; 01189 int orig_argc = argc; 01190 char **orig_argv = argv; 01191 #ifdef HAVE_SIGACTION 01192 # ifdef HAVE_SIGPROCMASK 01193 sigset_t sigmask; 01194 01195 sigemptyset(&sigmask); 01196 # endif 01197 sigact.sa_flags = SA_NOCLDSTOP; 01198 #endif 01199 SIGACTMASK(SIGUSR1, sigusr1_handler); 01200 SIGACTMASK(SIGUSR2, sigusr2_handler); 01201 SIGACTMASK(SIGCHLD, remember_children); 01202 #ifdef MAINTAINER_MODE 01203 SIGACTMASK(SIGSEGV, rsync_panic_handler); 01204 SIGACTMASK(SIGFPE, rsync_panic_handler); 01205 SIGACTMASK(SIGABRT, rsync_panic_handler); 01206 SIGACTMASK(SIGBUS, rsync_panic_handler); 01207 #endif 01208 01209 starttime = time(NULL); 01210 am_root = (MY_UID() == 0); 01211 01212 memset(&stats, 0, sizeof(stats)); 01213 01214 if (argc < 2) { 01215 usage(FERROR); 01216 exit_cleanup(RERR_SYNTAX); 01217 } 01218 01219 /* we set a 0 umask so that correct file permissions can be 01220 * carried across */ 01221 orig_umask = umask(0); 01222 01223 #if defined CONFIG_LOCALE && defined HAVE_SETLOCALE 01224 setlocale(LC_CTYPE, ""); 01225 #endif 01226 01227 if (!parse_arguments(&argc, (const char ***) &argv, 1)) { 01228 /* FIXME: We ought to call the same error-handling 01229 * code here, rather than relying on getopt. */ 01230 option_error(); 01231 exit_cleanup(RERR_SYNTAX); 01232 } 01233 01234 SIGACTMASK(SIGINT, sig_int); 01235 SIGACTMASK(SIGHUP, sig_int); 01236 SIGACTMASK(SIGTERM, sig_int); 01237 #if defined HAVE_SIGACTION && HAVE_SIGPROCMASK 01238 sigprocmask(SIG_UNBLOCK, &sigmask, NULL); 01239 #endif 01240 01241 /* Ignore SIGPIPE; we consistently check error codes and will 01242 * see the EPIPE. */ 01243 SIGACTION(SIGPIPE, SIG_IGN); 01244 #ifdef SIGXFSZ 01245 SIGACTION(SIGXFSZ, SIG_IGN); 01246 #endif 01247 01248 /* Initialize push_dir here because on some old systems getcwd 01249 * (implemented by forking "pwd" and reading its output) doesn't 01250 * work when there are other child processes. Also, on all systems 01251 * that implement getcwd that way "pwd" can't be found after chroot. */ 01252 push_dir(NULL); 01253 01254 init_flist(); 01255 01256 if ((write_batch || read_batch) && !am_server) { 01257 if (write_batch) 01258 write_batch_shell_file(orig_argc, orig_argv, argc); 01259 01260 if (read_batch && strcmp(batch_name, "-") == 0) 01261 batch_fd = STDIN_FILENO; 01262 else { 01263 batch_fd = do_open(batch_name, 01264 write_batch ? O_WRONLY | O_CREAT | O_TRUNC 01265 : O_RDONLY, S_IRUSR | S_IWUSR); 01266 } 01267 if (batch_fd < 0) { 01268 rsyserr(FERROR, errno, "Batch file %s open error", 01269 full_fname(batch_name)); 01270 exit_cleanup(RERR_FILEIO); 01271 } 01272 if (read_batch) 01273 read_stream_flags(batch_fd); 01274 } 01275 if (write_batch < 0) 01276 dry_run = 1; 01277 01278 if (am_daemon && !am_server) 01279 return daemon_main(); 01280 01281 if (argc < 1) { 01282 usage(FERROR); 01283 exit_cleanup(RERR_SYNTAX); 01284 } 01285 01286 if (am_server) { 01287 set_nonblocking(STDIN_FILENO); 01288 set_nonblocking(STDOUT_FILENO); 01289 if (am_daemon) 01290 return start_daemon(STDIN_FILENO, STDOUT_FILENO); 01291 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv); 01292 } 01293 01294 ret = start_client(argc, argv); 01295 if (ret == -1) 01296 exit_cleanup(RERR_STARTCLIENT); 01297 else 01298 exit_cleanup(ret); 01299 01300 return ret; 01301 }
int am_generator |
int blocking_io |
int daemon_over_rsh |
int kluge_around_eof |
int do_stats |
int log_got_error |
int module_id |
clientserver.c の 60 行で定義されています。
int copy_links |
int copy_dirlinks |
int keep_dirlinks |
int protocol_version |
int relative_paths |
int rsync_port |
int whole_file |
int read_batch |
int write_batch |
int batch_gen_fd |
int filesfrom_fd |
pid_t cleanup_child_pid |
char* filesfrom_host |
char* rsync_path |
char* shell_cmd |
char* batch_name |
int local_server = 0 |
mode_t orig_umask = 0 |
struct file_list* the_file_list |
struct pid_status pid_stat_table[MAXCHILDPROCS] |
time_t starttime [static] |
time_t endtime [static] |
int64 total_read [static] |
int64 total_written [static] |