00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "rsync.h"
00023 #if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
00024 #include <locale.h>
00025 #endif
00026
00027 extern int verbose;
00028 extern int dry_run;
00029 extern int list_only;
00030 extern int am_root;
00031 extern int am_server;
00032 extern int am_sender;
00033 extern int am_generator;
00034 extern int am_daemon;
00035 extern int blocking_io;
00036 extern int remove_sent_files;
00037 extern int daemon_over_rsh;
00038 extern int need_messages_from_generator;
00039 extern int kluge_around_eof;
00040 extern int do_stats;
00041 extern int log_got_error;
00042 extern int module_id;
00043 extern int copy_links;
00044 extern int copy_dirlinks;
00045 extern int keep_dirlinks;
00046 extern int preserve_hard_links;
00047 extern int protocol_version;
00048 extern int recurse;
00049 extern int relative_paths;
00050 extern int rsync_port;
00051 extern int whole_file;
00052 extern int read_batch;
00053 extern int write_batch;
00054 extern int batch_fd;
00055 extern int batch_gen_fd;
00056 extern int filesfrom_fd;
00057 extern pid_t cleanup_child_pid;
00058 extern struct stats stats;
00059 extern char *filesfrom_host;
00060 extern char *rsync_path;
00061 extern char *shell_cmd;
00062 extern char *batch_name;
00063
00064 int local_server = 0;
00065 mode_t orig_umask = 0;
00066 struct file_list *the_file_list;
00067
00068
00069
00070 #define MAXCHILDPROCS 7
00071
00072 #ifdef HAVE_SIGACTION
00073 # ifdef HAVE_SIGPROCMASK
00074 # define SIGACTMASK(n,h) SIGACTION(n,h), sigaddset(&sigmask,(n))
00075 # else
00076 # define SIGACTMASK(n,h) SIGACTION(n,h)
00077 # endif
00078 static struct sigaction sigact;
00079 #endif
00080
00081 struct pid_status {
00082 pid_t pid;
00083 int status;
00084 } pid_stat_table[MAXCHILDPROCS];
00085
00086 static time_t starttime, endtime;
00087 static int64 total_read, total_written;
00088
00089 static void show_malloc_stats(void);
00090
00091
00092
00093 pid_t wait_process(pid_t pid, int *status_ptr, int flags)
00094 {
00095 pid_t waited_pid = waitpid(pid, status_ptr, flags);
00096
00097 if (waited_pid == -1 && errno == ECHILD) {
00098
00099
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 }
00112
00113
00114 static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
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
00125
00126
00127
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 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 static void handle_stats(int f)
00154 {
00155 endtime = time(NULL);
00156
00157
00158 total_read = stats.total_read;
00159 total_written = stats.total_written;
00160
00161 if (do_stats && verbose > 1) {
00162
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
00190
00191 if (f < 0 && !am_sender)
00192 ;
00193 else if (!am_sender) {
00194
00195
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
00205
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 }
00215
00216 static void output_summary(void)
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 }
00258
00259
00260
00261
00262
00263 static void show_malloc_stats(void)
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
00296 }
00297
00298
00299
00300 static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
00301 int *f_in, int *f_out)
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
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
00356
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
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;
00420 } else if (local_server) {
00421
00422
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;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 static char *get_local_name(struct file_list *flist, char *dest_path)
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
00465
00466
00467
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
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
00499
00500
00501 if (flist->count > 1 || (cp && !cp[1])) {
00502
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
00517
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
00532
00533
00534
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 }
00551
00552
00553
00554 static void read_final_goodbye(int f_in, int f_out)
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
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 }
00575
00576
00577 static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
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 }
00630
00631
00632 static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
00633 {
00634 int pid;
00635 int exit_code = 0;
00636 int error_pipe[2];
00637
00638
00639
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
00663 close_multiplexing_out();
00664
00665
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
00676
00677 if (protocol_version >= 29) {
00678 kluge_around_eof = -1;
00679
00680
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
00690
00691
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
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 }
00724
00725
00726 static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
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
00736
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
00767
00768
00769
00770
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 }
00789
00790
00791 int child_main(int argc, char *argv[])
00792 {
00793 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
00794 return 0;
00795 }
00796
00797
00798 void start_server(int f_in, int f_out, int argc, char *argv[])
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;
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 }
00824
00825
00826
00827
00828
00829
00830 int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
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
00852
00853
00854
00855
00856
00857
00858
00859 set_blocking(STDERR_FILENO);
00860
00861 if (am_sender) {
00862 keep_dirlinks = 0;
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 }
00931
00932 static int copy_argv (char *argv[])
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 }
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956 static int start_client(int argc, char *argv[])
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
00968
00969 if ((rc = copy_argv(argv)))
00970 return rc;
00971
00972 if (!read_batch) {
00973 shell_path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
00974 if (shell_path) {
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 {
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) {
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 {
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
01062 if (!am_sender && argc > 1) {
01063 usage(FERROR);
01064 exit_cleanup(RERR_SYNTAX);
01065 }
01066
01067
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
01075
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 }
01091
01092
01093 static RETSIGTYPE sigusr1_handler(UNUSED(int val))
01094 {
01095 exit_cleanup(RERR_SIGNAL1);
01096 }
01097
01098 static RETSIGTYPE sigusr2_handler(UNUSED(int val))
01099 {
01100 if (!am_server)
01101 output_summary();
01102 close_all();
01103 if (log_got_error)
01104 _exit(RERR_PARTIAL);
01105 _exit(0);
01106 }
01107
01108 RETSIGTYPE remember_children(UNUSED(int val))
01109 {
01110 #ifdef WNOHANG
01111 int cnt, status;
01112 pid_t pid;
01113
01114
01115
01116
01117
01118 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
01119
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 }
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 #ifdef MAINTAINER_MODE
01149 const char *get_panic_action(void)
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 }
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169 static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
01170 {
01171 char cmd_buf[300];
01172 int ret;
01173
01174 sprintf(cmd_buf, get_panic_action(),
01175 getpid(), getpid());
01176
01177
01178
01179 ret = system(cmd_buf);
01180 if (ret)
01181 _exit(ret);
01182 }
01183 #endif
01184
01185
01186 int main(int argc,char *argv[])
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
01220
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
01229
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
01242
01243 SIGACTION(SIGPIPE, SIG_IGN);
01244 #ifdef SIGXFSZ
01245 SIGACTION(SIGXFSZ, SIG_IGN);
01246 #endif
01247
01248
01249
01250
01251
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 }