Go to the source code of this file.
Functions | |
void | show_malloc_stats (void) |
If our C library can get malloc statistics, then show them to FINFO. More... | |
void | wait_process (pid_t pid, int *status) |
void | report (int f) |
pid_t | do_cmd (char *cmd, char *machine, char *user, char *path, int *f_in, int *f_out) |
char * | get_local_name (struct file_list *flist, char *name) |
void | do_server_sender (int f_in, int f_out, int argc, char *argv[]) |
int | do_recv (int f_in, int f_out, struct file_list *flist, char *local_name) |
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[]) |
char * | find_colon (char *s) |
int | copy_argv (char *argv[]) |
int | start_client (int argc, char *argv[]) |
Start a client for either type of remote connection. More... | |
RETSIGTYPE | sigusr1_handler (int UNUSED(val)) |
RETSIGTYPE | sigusr2_handler (int UNUSED(val)) |
RETSIGTYPE | sigchld_handler (int UNUSED(val)) |
const char * | get_panic_action (void) |
This routine catches signals and tries to send them to gdb. More... | |
RETSIGTYPE | rsync_panic_handler (int UNUSED(whatsig)) |
Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION. More... | |
int | main (int argc, char *argv[]) |
Variables | |
time_t | starttime = 0 |
stats | stats |
int | verbose |
|
If our C library can get malloc statistics, then show them to FINFO.
Definition at line 138 of file main.c. References am_daemon, am_sender, FINFO, and rprintf(). Referenced by report().
00139 { 00140 #ifdef HAVE_MALLINFO 00141 struct mallinfo mi; 00142 extern int am_server; 00143 extern int am_sender; 00144 extern int am_daemon; 00145 00146 mi = mallinfo(); 00147 00148 rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n", 00149 getpid(), 00150 am_server ? "server " : "", 00151 am_daemon ? "daemon " : "", 00152 am_sender ? "sender" : "receiver"); 00153 rprintf(FINFO, " arena: %10d (bytes from sbrk)\n", mi.arena); 00154 rprintf(FINFO, " ordblks: %10d (chunks not in use)\n", mi.ordblks); 00155 rprintf(FINFO, " smblks: %10d\n", mi.smblks); 00156 rprintf(FINFO, " hblks: %10d (chunks from mmap)\n", mi.hblks); 00157 rprintf(FINFO, " hblkhd: %10d (bytes from mmap)\n", mi.hblkhd); 00158 rprintf(FINFO, " usmblks: %10d\n", mi.usmblks); 00159 rprintf(FINFO, " fsmblks: %10d\n", mi.fsmblks); 00160 rprintf(FINFO, " uordblks: %10d (bytes used)\n", mi.uordblks); 00161 rprintf(FINFO, " fordblks: %10d (bytes free)\n", mi.fordblks); 00162 rprintf(FINFO, " keepcost: %10d (bytes in releasable chunk)\n", mi.keepcost); 00163 #endif /* HAVE_MALLINFO */ 00164 } |
|
Definition at line 34 of file main.c. References io_flush(), msleep(), and waitpid(). Referenced by client_run(), and do_recv().
00035 { 00036 while (waitpid(pid, status, WNOHANG) == 0) { 00037 msleep(20); 00038 io_flush(); 00039 } 00040 00041 /* TODO: If the child exited on a signal, then log an 00042 * appropriate error message. Perhaps we should also accept a 00043 * message describing the purpose of the child. Also indicate 00044 * this to the caller so that thhey know something went 00045 * wrong. */ 00046 *status = WEXITSTATUS(*status); 00047 } |
|
Definition at line 49 of file main.c. References am_daemon, am_sender, do_stats, FINFO, stats::flist_size, stats::literal_data, log_exit(), stats::matched_data, stats::num_files, stats::num_transferred_files, read_longint(), rprintf(), show_flist_stats(), show_malloc_stats(), starttime, stats::total_read, stats::total_size, stats::total_transferred_size, stats::total_written, verbose, and write_longint(). Referenced by client_run(), do_recv(), and do_server_sender().
00050 { 00051 time_t t = time(NULL); 00052 extern int am_server; 00053 extern int am_sender; 00054 extern int am_daemon; 00055 extern int do_stats; 00056 extern int remote_version; 00057 int send_stats; 00058 00059 if (do_stats) { 00060 /* These come out from every process */ 00061 show_malloc_stats(); 00062 show_flist_stats(); 00063 } 00064 00065 if (am_daemon) { 00066 log_exit(0, __FILE__, __LINE__); 00067 if (f == -1 || !am_sender) return; 00068 } 00069 00070 send_stats = verbose || (remote_version >= 20); 00071 if (am_server) { 00072 if (am_sender && send_stats) { 00073 int64 w; 00074 /* store total_written in a temporary 00075 because write_longint changes it */ 00076 w = stats.total_written; 00077 write_longint(f,stats.total_read); 00078 write_longint(f,w); 00079 write_longint(f,stats.total_size); 00080 } 00081 return; 00082 } 00083 00084 /* this is the client */ 00085 00086 if (!am_sender && send_stats) { 00087 int64 r; 00088 stats.total_written = read_longint(f); 00089 /* store total_read in a temporary, read_longint changes it */ 00090 r = read_longint(f); 00091 stats.total_size = read_longint(f); 00092 stats.total_read = r; 00093 } 00094 00095 if (do_stats) { 00096 if (!am_sender && !send_stats) { 00097 /* missing the bytes written by the generator */ 00098 rprintf(FINFO, "\nCannot show stats as receiver because remote protocol version is less than 20\n"); 00099 rprintf(FINFO, "Use --stats -v to show stats\n"); 00100 return; 00101 } 00102 rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files); 00103 rprintf(FINFO,"Number of files transferred: %d\n", 00104 stats.num_transferred_files); 00105 rprintf(FINFO,"Total file size: %.0f bytes\n", 00106 (double)stats.total_size); 00107 rprintf(FINFO,"Total transferred file size: %.0f bytes\n", 00108 (double)stats.total_transferred_size); 00109 rprintf(FINFO,"Literal data: %.0f bytes\n", 00110 (double)stats.literal_data); 00111 rprintf(FINFO,"Matched data: %.0f bytes\n", 00112 (double)stats.matched_data); 00113 rprintf(FINFO,"File list size: %d\n", stats.flist_size); 00114 rprintf(FINFO,"Total bytes written: %.0f\n", 00115 (double)stats.total_written); 00116 rprintf(FINFO,"Total bytes read: %.0f\n\n", 00117 (double)stats.total_read); 00118 } 00119 00120 if (verbose || do_stats) { 00121 rprintf(FINFO,"wrote %.0f bytes read %.0f bytes %.2f bytes/sec\n", 00122 (double)stats.total_written, 00123 (double)stats.total_read, 00124 (stats.total_written+stats.total_read)/(0.5 + (t-starttime))); 00125 rprintf(FINFO,"total size is %.0f speedup is %.2f\n", 00126 (double)stats.total_size, 00127 (1.0*stats.total_size)/(stats.total_written+stats.total_read)); 00128 } 00129 00130 fflush(stdout); 00131 fflush(stderr); 00132 } |
|
Definition at line 168 of file main.c. References blocking_io, child_main(), create_flist_from_batch(), FINFO, getenv(), local_child(), local_server, out_of_memory(), piped_child(), rprintf(), rsync_path, server_options(), strdup(), and verbose. Referenced by start_client().
00169 { 00170 char *args[100]; 00171 int i,argc=0; 00172 pid_t ret; 00173 char *tok,*dir=NULL; 00174 extern int local_server; 00175 extern char *rsync_path; 00176 extern int blocking_io; 00177 extern int read_batch; 00178 00179 if (!read_batch && !local_server) { 00180 if (!cmd) 00181 cmd = getenv(RSYNC_RSH_ENV); 00182 if (!cmd) 00183 cmd = RSYNC_RSH; 00184 cmd = strdup(cmd); 00185 if (!cmd) 00186 goto oom; 00187 00188 for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) { 00189 args[argc++] = tok; 00190 } 00191 00192 #if HAVE_REMSH 00193 /* remsh (on HPUX) takes the arguments the other way around */ 00194 args[argc++] = machine; 00195 if (user) { 00196 args[argc++] = "-l"; 00197 args[argc++] = user; 00198 } 00199 #else 00200 if (user) { 00201 args[argc++] = "-l"; 00202 args[argc++] = user; 00203 } 00204 args[argc++] = machine; 00205 #endif 00206 00207 args[argc++] = rsync_path; 00208 00209 if ((blocking_io == -1) && (strcmp(cmd, RSYNC_RSH) == 0)) 00210 blocking_io = 1; 00211 00212 server_options(args,&argc); 00213 00214 } 00215 00216 args[argc++] = "."; 00217 00218 if (path && *path) 00219 args[argc++] = path; 00220 00221 args[argc] = NULL; 00222 00223 if (verbose > 3) { 00224 rprintf(FINFO,"cmd="); 00225 for (i=0;i<argc;i++) 00226 rprintf(FINFO,"%s ",args[i]); 00227 rprintf(FINFO,"\n"); 00228 } 00229 00230 if (local_server) { 00231 if (read_batch) 00232 create_flist_from_batch(); /* sets batch_flist */ 00233 ret = local_child(argc, args, f_in, f_out, child_main); 00234 } else { 00235 ret = piped_child(args,f_in,f_out); 00236 } 00237 00238 if (dir) free(dir); 00239 00240 return ret; 00241 00242 oom: 00243 out_of_memory("do_cmd"); 00244 return 0; /* not reached */ 00245 } |
|
Definition at line 250 of file main.c. References file_list::count, do_mkdir(), do_stat(), FERROR, FINFO, orig_umask, push_dir(), rprintf(), and verbose. Referenced by client_run(), and do_server_recv().
00251 { 00252 STRUCT_STAT st; 00253 extern int orig_umask; 00254 00255 if (verbose > 2) 00256 rprintf(FINFO,"get_local_name count=%d %s\n", 00257 flist->count, NS(name)); 00258 00259 if (!name) 00260 return NULL; 00261 00262 if (do_stat(name,&st) == 0) { 00263 if (S_ISDIR(st.st_mode)) { 00264 if (!push_dir(name, 0)) { 00265 rprintf(FERROR,"push_dir %s : %s (1)\n", 00266 name,strerror(errno)); 00267 exit_cleanup(RERR_FILESELECT); 00268 } 00269 return NULL; 00270 } 00271 if (flist->count > 1) { 00272 rprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n"); 00273 exit_cleanup(RERR_FILESELECT); 00274 } 00275 return name; 00276 } 00277 00278 if (flist->count <= 1) 00279 return name; 00280 00281 if (do_mkdir(name,0777 & ~orig_umask) != 0) { 00282 rprintf(FERROR, RSYNC_NAME ": mkdir %s: %s\n", 00283 name, strerror(errno)); 00284 exit_cleanup(RERR_FILEIO); 00285 } else { 00286 if (verbose > 0) 00287 rprintf(FINFO,"created directory %s\n",name); 00288 } 00289 00290 if (!push_dir(name, 0)) { 00291 rprintf(FERROR, RSYNC_NAME ": push_dir %s: %s\n", 00292 name, strerror(errno)); 00293 exit_cleanup(RERR_FILESELECT); 00294 } 00295 00296 return NULL; 00297 } |
|
Definition at line 302 of file main.c. References file_list::count, FERROR, FINFO, io_flush(), push_dir(), read_int(), report(), rprintf(), send_file_list(), send_files(), and verbose. Referenced by start_server().
00303 { 00304 int i; 00305 struct file_list *flist; 00306 char *dir = argv[0]; 00307 extern int relative_paths; 00308 extern int recurse; 00309 extern int remote_version; 00310 00311 if (verbose > 2) 00312 rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid()); 00313 00314 if (!relative_paths && !push_dir(dir, 0)) { 00315 rprintf(FERROR,"push_dir %s: %s (3)\n",dir,strerror(errno)); 00316 exit_cleanup(RERR_FILESELECT); 00317 } 00318 argc--; 00319 argv++; 00320 00321 if (strcmp(dir,".")) { 00322 int l = strlen(dir); 00323 if (strcmp(dir,"/") == 0) 00324 l = 0; 00325 for (i=0;i<argc;i++) 00326 argv[i] += l+1; 00327 } 00328 00329 if (argc == 0 && recurse) { 00330 argc=1; 00331 argv--; 00332 argv[0] = "."; 00333 } 00334 00335 flist = send_file_list(f_out,argc,argv); 00336 if (!flist || flist->count == 0) { 00337 exit_cleanup(0); 00338 } 00339 00340 send_files(flist,f_out,f_in); 00341 io_flush(); 00342 report(f_out); 00343 if (remote_version >= 24) { 00344 /* final goodbye message */ 00345 read_int(f_in); 00346 } 00347 io_flush(); 00348 exit_cleanup(0); 00349 } |
|
Definition at line 352 of file main.c. References file_list::count, delete_after, delete_files(), do_fork(), fd_pair(), FERROR, generate_files(), init_hard_links(), io_flush(), io_multiplexing_close(), io_set_error_fd(), io_start_buffering(), msleep(), read_int(), recv_files(), report(), rprintf(), set_error_fd(), wait_process(), and write_int(). Referenced by client_run(), and do_server_recv().
00353 { 00354 int pid; 00355 int status=0; 00356 int recv_pipe[2]; 00357 int error_pipe[2]; 00358 extern int preserve_hard_links; 00359 extern int delete_after; 00360 extern int recurse; 00361 extern int delete_mode; 00362 extern int remote_version; 00363 00364 if (preserve_hard_links) 00365 init_hard_links(flist); 00366 00367 if (!delete_after) { 00368 /* I moved this here from recv_files() to prevent a race condition */ 00369 if (recurse && delete_mode && !local_name && flist->count>0) { 00370 delete_files(flist); 00371 } 00372 } 00373 00374 if (fd_pair(recv_pipe) < 0) { 00375 rprintf(FERROR,"pipe failed in do_recv\n"); 00376 exit_cleanup(RERR_SOCKETIO); 00377 } 00378 00379 if (fd_pair(error_pipe) < 0) { 00380 rprintf(FERROR,"error pipe failed in do_recv\n"); 00381 exit_cleanup(RERR_SOCKETIO); 00382 } 00383 00384 io_flush(); 00385 00386 if ((pid=do_fork()) == 0) { 00387 close(recv_pipe[0]); 00388 close(error_pipe[0]); 00389 if (f_in != f_out) close(f_out); 00390 00391 /* we can't let two processes write to the socket at one time */ 00392 io_multiplexing_close(); 00393 00394 /* set place to send errors */ 00395 set_error_fd(error_pipe[1]); 00396 00397 recv_files(f_in,flist,local_name,recv_pipe[1]); 00398 io_flush(); 00399 report(f_in); 00400 00401 write_int(recv_pipe[1],1); 00402 close(recv_pipe[1]); 00403 io_flush(); 00404 /* finally we go to sleep until our parent kills us 00405 with a USR2 signal. We sleep for a short time as on 00406 some OSes a signal won't interrupt a sleep! */ 00407 while (msleep(20)) 00408 ; 00409 } 00410 00411 close(recv_pipe[1]); 00412 close(error_pipe[1]); 00413 if (f_in != f_out) close(f_in); 00414 00415 io_start_buffering(f_out); 00416 00417 io_set_error_fd(error_pipe[0]); 00418 00419 generate_files(f_out,flist,local_name,recv_pipe[0]); 00420 00421 read_int(recv_pipe[0]); 00422 close(recv_pipe[0]); 00423 if (remote_version >= 24) { 00424 /* send a final goodbye message */ 00425 write_int(f_out, -1); 00426 } 00427 io_flush(); 00428 00429 kill(pid, SIGUSR2); 00430 wait_process(pid, &status); 00431 return status; 00432 } |
|
Definition at line 435 of file main.c. References am_daemon, am_sender, delete_excluded, do_recv(), FERROR, FINFO, get_local_name(), push_dir(), recv_exclude_list(), recv_file_list(), rprintf(), and verbose. Referenced by start_server().
00436 { 00437 int status; 00438 struct file_list *flist; 00439 char *local_name=NULL; 00440 char *dir = NULL; 00441 extern int delete_mode; 00442 extern int delete_excluded; 00443 extern int am_daemon; 00444 extern int module_id; 00445 extern int am_sender; 00446 extern int read_batch; 00447 extern struct file_list *batch_flist; 00448 00449 if (verbose > 2) 00450 rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid()); 00451 00452 if (am_daemon && lp_read_only(module_id) && !am_sender) { 00453 rprintf(FERROR,"ERROR: module is read only\n"); 00454 exit_cleanup(RERR_SYNTAX); 00455 return; 00456 } 00457 00458 00459 if (argc > 0) { 00460 dir = argv[0]; 00461 argc--; 00462 argv++; 00463 if (!am_daemon && !push_dir(dir, 0)) { 00464 rprintf(FERROR,"push_dir %s : %s (4)\n", 00465 dir,strerror(errno)); 00466 exit_cleanup(RERR_FILESELECT); 00467 } 00468 } 00469 00470 if (delete_mode && !delete_excluded) 00471 recv_exclude_list(f_in); 00472 00473 if (read_batch) 00474 flist = batch_flist; 00475 else 00476 flist = recv_file_list(f_in); 00477 if (!flist) { 00478 rprintf(FERROR,"server_recv: recv_file_list error\n"); 00479 exit_cleanup(RERR_FILESELECT); 00480 } 00481 00482 if (argc > 0) { 00483 if (strcmp(dir,".")) { 00484 argv[0] += strlen(dir); 00485 if (argv[0][0] == '/') argv[0]++; 00486 } 00487 local_name = get_local_name(flist,argv[0]); 00488 } 00489 00490 status = do_recv(f_in,f_out,flist,local_name); 00491 exit_cleanup(status); 00492 } |
|
Definition at line 495 of file main.c. References start_server(). Referenced by do_cmd(), and local_child().
00496 { 00497 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv); 00498 return 0; 00499 } |
|
Definition at line 502 of file main.c. References add_cvs_excludes(), am_sender, do_server_recv(), do_server_sender(), io_start_multiplex_out(), recv_exclude_list(), set_nonblocking(), and setup_protocol(). Referenced by child_main(), main(), and rsync_module().
00503 { 00504 extern int cvs_exclude; 00505 extern int am_sender; 00506 extern int remote_version; 00507 extern int read_batch; 00508 00509 setup_protocol(f_out, f_in); 00510 00511 set_nonblocking(f_in); 00512 set_nonblocking(f_out); 00513 00514 if (remote_version >= 23) 00515 io_start_multiplex_out(f_out); 00516 00517 if (am_sender) { 00518 if (!read_batch) { 00519 recv_exclude_list(f_in); 00520 if (cvs_exclude) 00521 add_cvs_excludes(); 00522 } 00523 do_server_sender(f_in, f_out, argc, argv); 00524 } else { 00525 do_server_recv(f_in, f_out, argc, argv); 00526 } 00527 exit_cleanup(0); 00528 } |
|
Definition at line 535 of file main.c. References add_cvs_excludes(), am_sender, cleanup_child_pid, file_list::count, delete_excluded, do_recv(), FINFO, get_local_name(), io_flush(), io_start_multiplex_in(), read_int(), recv_file_list(), report(), rprintf(), send_exclude_list(), send_file_list(), send_files(), set_nonblocking(), setup_protocol(), verbose, and wait_process(). Referenced by start_client(), and start_socket_client().
00536 { 00537 struct file_list *flist = NULL; 00538 int status = 0, status2 = 0; 00539 char *local_name = NULL; 00540 extern int am_sender; 00541 extern int remote_version; 00542 extern pid_t cleanup_child_pid; 00543 extern int write_batch; 00544 extern int read_batch; 00545 extern struct file_list *batch_flist; 00546 00547 cleanup_child_pid = pid; 00548 if (read_batch) 00549 flist = batch_flist; 00550 00551 set_nonblocking(f_in); 00552 set_nonblocking(f_out); 00553 00554 setup_protocol(f_out,f_in); 00555 00556 if (remote_version >= 23) 00557 io_start_multiplex_in(f_in); 00558 00559 if (am_sender) { 00560 extern int cvs_exclude; 00561 extern int delete_mode; 00562 extern int delete_excluded; 00563 if (cvs_exclude) 00564 add_cvs_excludes(); 00565 if (delete_mode && !delete_excluded) 00566 send_exclude_list(f_out); 00567 if (!read_batch) /* dw -- don't write to pipe */ 00568 flist = send_file_list(f_out,argc,argv); 00569 if (verbose > 3) 00570 rprintf(FINFO,"file list sent\n"); 00571 00572 send_files(flist,f_out,f_in); 00573 if (remote_version >= 24) { 00574 /* final goodbye message */ 00575 read_int(f_in); 00576 } 00577 if (pid != -1) { 00578 if (verbose > 3) 00579 rprintf(FINFO,"client_run waiting on %d\n", (int) pid); 00580 io_flush(); 00581 wait_process(pid, &status); 00582 } 00583 report(-1); 00584 exit_cleanup(status); 00585 } 00586 00587 if (argc == 0) { 00588 extern int list_only; 00589 list_only = 1; 00590 } 00591 00592 if (!write_batch) 00593 send_exclude_list(f_out); 00594 00595 flist = recv_file_list(f_in); 00596 if (!flist || flist->count == 0) { 00597 rprintf(FINFO, "client: nothing to do: " 00598 "perhaps you need to specify some filenames or " 00599 "the --recursive option?\n"); 00600 exit_cleanup(0); 00601 } 00602 00603 local_name = get_local_name(flist,argv[0]); 00604 00605 status2 = do_recv(f_in,f_out,flist,local_name); 00606 00607 if (pid != -1) { 00608 if (verbose > 3) 00609 rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid); 00610 io_flush(); 00611 wait_process(pid, &status); 00612 } 00613 00614 return MAX(status, status2); 00615 } |
|
Definition at line 617 of file main.c. Referenced by start_client().
00618 { 00619 char *p, *p2; 00620 00621 p = strchr(s,':'); 00622 if (!p) return NULL; 00623 00624 /* now check to see if there is a / in the string before the : - if there is then 00625 discard the colon on the assumption that the : is part of a filename */ 00626 p2 = strchr(s,'/'); 00627 if (p2 && p2 < p) return NULL; 00628 00629 return p; 00630 } |
|
Definition at line 633 of file main.c. References FERROR, rprintf(), and strdup(). Referenced by start_client().
|
|
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). Definition at line 657 of file main.c. References am_sender, client_run(), copy_argv(), do_cmd(), FERROR, find_colon(), FINFO, host, local_server, rprintf(), shell_cmd, start_socket_client(), usage(), and verbose. Referenced by main().
00658 { 00659 char *p; 00660 char *shell_machine = NULL; 00661 char *shell_path = NULL; 00662 char *shell_user = NULL; 00663 int ret; 00664 pid_t pid; 00665 int f_in,f_out; 00666 extern int local_server; 00667 extern int am_sender; 00668 extern char *shell_cmd; 00669 extern int rsync_port; 00670 extern int read_batch; 00671 int rc; 00672 00673 /* Don't clobber argv[] so that ps(1) can still show the right 00674 command line. */ 00675 if ((rc = copy_argv (argv))) 00676 return rc; 00677 00678 if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) { 00679 char *host, *path; 00680 00681 host = argv[0] + strlen(URL_PREFIX); 00682 p = strchr(host,'/'); 00683 if (p) { 00684 *p = 0; 00685 path = p+1; 00686 } else { 00687 path=""; 00688 } 00689 p = strchr(host,':'); 00690 if (p) { 00691 rsync_port = atoi(p+1); 00692 *p = 0; 00693 } 00694 return start_socket_client(host, path, argc-1, argv+1); 00695 } 00696 00697 if (!read_batch) { 00698 p = find_colon(argv[0]); 00699 00700 if (p) { 00701 if (p[1] == ':') { /* double colon */ 00702 *p = 0; 00703 return start_socket_client(argv[0], p+2, argc-1, argv+1); 00704 } 00705 00706 if (argc < 1) { 00707 usage(FERROR); 00708 exit_cleanup(RERR_SYNTAX); 00709 } 00710 00711 am_sender = 0; 00712 *p = 0; 00713 shell_machine = argv[0]; 00714 shell_path = p+1; 00715 argc--; 00716 argv++; 00717 } else { 00718 am_sender = 1; 00719 00720 p = find_colon(argv[argc-1]); 00721 if (!p) { 00722 local_server = 1; 00723 } else if (p[1] == ':') { 00724 *p = 0; 00725 return start_socket_client(argv[argc-1], p+2, argc-1, argv); 00726 } 00727 00728 if (argc < 2) { 00729 usage(FERROR); 00730 exit_cleanup(RERR_SYNTAX); 00731 } 00732 00733 if (local_server) { 00734 shell_machine = NULL; 00735 shell_path = argv[argc-1]; 00736 } else { 00737 *p = 0; 00738 shell_machine = argv[argc-1]; 00739 shell_path = p+1; 00740 } 00741 argc--; 00742 } 00743 } else { 00744 am_sender = 1; 00745 local_server = 1; 00746 shell_path = argv[argc-1]; 00747 } 00748 00749 if (shell_machine) { 00750 p = strchr(shell_machine,'@'); 00751 if (p) { 00752 *p = 0; 00753 shell_user = shell_machine; 00754 shell_machine = p+1; 00755 } 00756 } 00757 00758 if (verbose > 3) { 00759 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n", 00760 shell_cmd?shell_cmd:"", 00761 shell_machine?shell_machine:"", 00762 shell_user?shell_user:"", 00763 shell_path?shell_path:""); 00764 } 00765 00766 if (!am_sender && argc > 1) { 00767 usage(FERROR); 00768 exit_cleanup(RERR_SYNTAX); 00769 } 00770 00771 if (argc == 0 && !am_sender) { 00772 extern int list_only; 00773 list_only = 1; 00774 } 00775 00776 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out); 00777 00778 ret = client_run(f_in, f_out, pid, argc, argv); 00779 00780 fflush(stdout); 00781 fflush(stderr); 00782 00783 return ret; 00784 } |
|
Definition at line 787 of file main.c. Referenced by main().
00787 { 00788 exit_cleanup(RERR_SIGNAL); 00789 } |
|
Definition at line 791 of file main.c. References log_got_error. Referenced by main().
00791 { 00792 extern int log_got_error; 00793 if (log_got_error) _exit(RERR_PARTIAL); 00794 _exit(0); 00795 } |
|
Definition at line 797 of file main.c. References waitpid(). Referenced by main().
00797 { 00798 #ifdef WNOHANG 00799 while (waitpid(-1, NULL, WNOHANG) > 0) ; 00800 #endif 00801 } |
|
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.
Definition at line 818 of file main.c. References getenv(). Referenced by print_rsync_version(), and rsync_panic_handler().
00819 { 00820 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION"); 00821 00822 if (cmd_fmt) 00823 return cmd_fmt; 00824 else 00825 return "xterm -display :0 -T Panic -n Panic " 00826 "-e gdb /proc/%d/exe %d"; 00827 } |
|
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. Definition at line 838 of file main.c. References get_panic_action(), and sprintf(). Referenced by main().
00839 { 00840 char cmd_buf[300]; 00841 int ret; 00842 00843 sprintf(cmd_buf, get_panic_action(), 00844 getpid(), getpid()); 00845 00846 /* Unless we failed to execute gdb, we allow the process to 00847 * continue. I'm not sure if that's right. */ 00848 ret = system(cmd_buf); 00849 if (ret) 00850 _exit(ret); 00851 } |
|
Definition at line 855 of file main.c. References am_daemon, daemon_main(), FERROR, option_error(), orig_umask, parse_arguments(), push_dir(), rprintf(), rsync_panic_handler(), set_nonblocking(), sig_int(), sigchld_handler(), sigusr1_handler(), sigusr2_handler(), start_client(), start_server(), starttime, usage(), verbose, and write_batch_argvs_file().
00856 { 00857 extern int am_root; 00858 extern int orig_umask; 00859 extern int dry_run; 00860 extern int am_daemon; 00861 extern int am_server; 00862 int ret; 00863 extern int write_batch; 00864 int orig_argc; 00865 char **orig_argv; 00866 00867 orig_argc = argc; 00868 orig_argv = argv; 00869 00870 signal(SIGUSR1, sigusr1_handler); 00871 signal(SIGUSR2, sigusr2_handler); 00872 signal(SIGCHLD, sigchld_handler); 00873 #ifdef MAINTAINER_MODE 00874 signal(SIGSEGV, rsync_panic_handler); 00875 signal(SIGFPE, rsync_panic_handler); 00876 signal(SIGABRT, rsync_panic_handler); 00877 signal(SIGBUS, rsync_panic_handler); 00878 #endif /* def MAINTAINER_MODE */ 00879 00880 starttime = time(NULL); 00881 am_root = (getuid() == 0); 00882 00883 memset(&stats, 0, sizeof(stats)); 00884 00885 if (argc < 2) { 00886 usage(FERROR); 00887 exit_cleanup(RERR_SYNTAX); 00888 } 00889 00890 /* we set a 0 umask so that correct file permissions can be 00891 carried across */ 00892 orig_umask = (int)umask(0); 00893 00894 if (!parse_arguments(&argc, (const char ***) &argv, 1)) { 00895 /* FIXME: We ought to call the same error-handling 00896 * code here, rather than relying on getopt. */ 00897 option_error(); 00898 exit_cleanup(RERR_SYNTAX); 00899 } 00900 00901 signal(SIGINT,SIGNAL_CAST sig_int); 00902 signal(SIGHUP,SIGNAL_CAST sig_int); 00903 signal(SIGTERM,SIGNAL_CAST sig_int); 00904 00905 /* Ignore SIGPIPE; we consistently check error codes and will 00906 * see the EPIPE. */ 00907 signal(SIGPIPE, SIG_IGN); 00908 00909 /* Initialize push_dir here because on some old systems getcwd 00910 (implemented by forking "pwd" and reading its output) doesn't 00911 work when there are other child processes. Also, on all systems 00912 that implement getcwd that way "pwd" can't be found after chroot. */ 00913 push_dir(NULL,0); 00914 00915 if (write_batch && !am_server) { 00916 write_batch_argvs_file(orig_argc, orig_argv); 00917 } 00918 00919 if (am_daemon) { 00920 return daemon_main(); 00921 } 00922 00923 if (argc < 1) { 00924 usage(FERROR); 00925 exit_cleanup(RERR_SYNTAX); 00926 } 00927 00928 if (dry_run) 00929 verbose = MAX(verbose,1); 00930 00931 #ifndef SUPPORT_LINKS 00932 if (!am_server && preserve_links) { 00933 rprintf(FERROR,"ERROR: symbolic links not supported\n"); 00934 exit_cleanup(RERR_UNSUPPORTED); 00935 } 00936 #endif 00937 00938 if (am_server) { 00939 set_nonblocking(STDIN_FILENO); 00940 set_nonblocking(STDOUT_FILENO); 00941 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv); 00942 } 00943 00944 ret = start_client(argc, argv); 00945 if (ret == -1) 00946 exit_cleanup(RERR_STARTCLIENT); 00947 else 00948 exit_cleanup(ret); 00949 00950 exit(ret); 00951 /* NOTREACHED */ 00952 } |
|
|
|
|
|
Definition at line 27 of file main.c. Referenced by client_run(), do_cmd(), do_server_recv(), do_server_sender(), get_local_name(), main(), report(), and start_client(). |