1 /* -*- c-file-style: "linux" -*-
3 Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
4 Copyright (C) Paul Mackerras 1996
5 Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern struct stats stats;
29 static void show_malloc_stats(void);
31 /****************************************************************************
32 wait for a process to exit, calling io_flush while waiting
33 ****************************************************************************/
34 void wait_process(pid_t pid, int *status)
36 while (waitpid(pid, status, WNOHANG) == 0) {
41 /* TODO: If the child exited on a signal, then log an
42 * appropriate error message. Perhaps we should also accept a
43 * message describing the purpose of the child. Also indicate
44 * this to the caller so that thhey know something went
46 *status = WEXITSTATUS(*status);
49 static void report(int f)
51 time_t t = time(NULL);
56 extern int remote_version;
60 /* These come out from every process */
66 log_exit(0, __FILE__, __LINE__);
67 if (f == -1 || !am_sender) return;
70 send_stats = verbose || (remote_version >= 20);
72 if (am_sender && send_stats) {
74 /* store total_written in a temporary
75 because write_longint changes it */
76 w = stats.total_written;
77 write_longint(f,stats.total_read);
79 write_longint(f,stats.total_size);
84 /* this is the client */
86 if (!am_sender && send_stats) {
88 stats.total_written = read_longint(f);
89 /* store total_read in a temporary, read_longint changes it */
91 stats.total_size = read_longint(f);
96 if (!am_sender && !send_stats) {
97 /* missing the bytes written by the generator */
98 rprintf(FINFO, "\nCannot show stats as receiver because remote protocol version is less than 20\n");
99 rprintf(FINFO, "Use --stats -v to show stats\n");
102 rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
103 rprintf(FINFO,"Number of files transferred: %d\n",
104 stats.num_transferred_files);
105 rprintf(FINFO,"Total file size: %.0f bytes\n",
106 (double)stats.total_size);
107 rprintf(FINFO,"Total transferred file size: %.0f bytes\n",
108 (double)stats.total_transferred_size);
109 rprintf(FINFO,"Literal data: %.0f bytes\n",
110 (double)stats.literal_data);
111 rprintf(FINFO,"Matched data: %.0f bytes\n",
112 (double)stats.matched_data);
113 rprintf(FINFO,"File list size: %d\n", stats.flist_size);
114 rprintf(FINFO,"Total bytes written: %.0f\n",
115 (double)stats.total_written);
116 rprintf(FINFO,"Total bytes read: %.0f\n\n",
117 (double)stats.total_read);
120 if (verbose || do_stats) {
121 rprintf(FINFO,"wrote %.0f bytes read %.0f bytes %.2f bytes/sec\n",
122 (double)stats.total_written,
123 (double)stats.total_read,
124 (stats.total_written+stats.total_read)/(0.5 + (t-starttime)));
125 rprintf(FINFO,"total size is %.0f speedup is %.2f\n",
126 (double)stats.total_size,
127 (1.0*stats.total_size)/(stats.total_written+stats.total_read));
136 * If our C library can get malloc statistics, then show them to FINFO
138 static void show_malloc_stats(void)
142 extern int am_server;
143 extern int am_sender;
144 extern int am_daemon;
148 rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
150 am_server ? "server " : "",
151 am_daemon ? "daemon " : "",
152 am_sender ? "sender" : "receiver");
153 rprintf(FINFO, " arena: %10d (bytes from sbrk)\n", mi.arena);
154 rprintf(FINFO, " ordblks: %10d (chunks not in use)\n", mi.ordblks);
155 rprintf(FINFO, " smblks: %10d\n", mi.smblks);
156 rprintf(FINFO, " hblks: %10d (chunks from mmap)\n", mi.hblks);
157 rprintf(FINFO, " hblkhd: %10d (bytes from mmap)\n", mi.hblkhd);
158 rprintf(FINFO, " usmblks: %10d\n", mi.usmblks);
159 rprintf(FINFO, " fsmblks: %10d\n", mi.fsmblks);
160 rprintf(FINFO, " uordblks: %10d (bytes used)\n", mi.uordblks);
161 rprintf(FINFO, " fordblks: %10d (bytes free)\n", mi.fordblks);
162 rprintf(FINFO, " keepcost: %10d (bytes in releasable chunk)\n", mi.keepcost);
163 #endif /* HAVE_MALLINFO */
167 /* Start the remote shell. cmd may be NULL to use the default. */
168 static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
174 extern int local_server;
175 extern char *rsync_path;
176 extern int blocking_io;
177 extern int daemon_over_rsh;
178 extern int read_batch;
180 if (!read_batch && !local_server) {
182 cmd = getenv(RSYNC_RSH_ENV);
189 for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
194 /* remsh (on HPUX) takes the arguments the other way around */
195 args[argc++] = machine;
205 args[argc++] = machine;
208 args[argc++] = rsync_path;
210 if ((blocking_io == -1) && (strcmp(cmd, RSYNC_RSH) == 0))
213 server_options(args,&argc);
219 if (!daemon_over_rsh && path && *path)
225 rprintf(FINFO,"cmd=");
227 rprintf(FINFO,"%s ",args[i]);
233 create_flist_from_batch(); /* sets batch_flist */
234 ret = local_child(argc, args, f_in, f_out, child_main);
236 ret = piped_child(args,f_in,f_out);
244 out_of_memory("do_cmd");
245 return 0; /* not reached */
251 static char *get_local_name(struct file_list *flist,char *name)
254 extern int orig_umask;
257 rprintf(FINFO,"get_local_name count=%d %s\n",
258 flist->count, NS(name));
263 if (do_stat(name,&st) == 0) {
264 if (S_ISDIR(st.st_mode)) {
265 if (!push_dir(name, 0)) {
266 rprintf(FERROR,"push_dir %s : %s (1)\n",
267 name,strerror(errno));
268 exit_cleanup(RERR_FILESELECT);
272 if (flist->count > 1) {
273 rprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
274 exit_cleanup(RERR_FILESELECT);
279 if (flist->count <= 1)
282 if (do_mkdir(name,0777 & ~orig_umask) != 0) {
283 rprintf(FERROR, RSYNC_NAME ": mkdir %s: %s\n",
284 name, strerror(errno));
285 exit_cleanup(RERR_FILEIO);
288 rprintf(FINFO,"created directory %s\n",name);
291 if (!push_dir(name, 0)) {
292 rprintf(FERROR, RSYNC_NAME ": push_dir %s: %s\n",
293 name, strerror(errno));
294 exit_cleanup(RERR_FILESELECT);
303 static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
306 struct file_list *flist;
308 extern int relative_paths;
310 extern int remote_version;
313 rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
315 if (!relative_paths && !push_dir(dir, 0)) {
316 rprintf(FERROR,"push_dir %s: %s (3)\n",dir,strerror(errno));
317 exit_cleanup(RERR_FILESELECT);
322 if (strcmp(dir,".")) {
324 if (strcmp(dir,"/") == 0)
330 if (argc == 0 && recurse) {
336 flist = send_file_list(f_out,argc,argv);
337 if (!flist || flist->count == 0) {
341 send_files(flist,f_out,f_in);
344 if (remote_version >= 24) {
345 /* final goodbye message */
353 static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
359 extern int preserve_hard_links;
360 extern int delete_after;
362 extern int delete_mode;
363 extern int remote_version;
365 if (preserve_hard_links)
366 init_hard_links(flist);
369 /* I moved this here from recv_files() to prevent a race condition */
370 if (recurse && delete_mode && !local_name && flist->count>0) {
375 if (fd_pair(recv_pipe) < 0) {
376 rprintf(FERROR,"pipe failed in do_recv\n");
377 exit_cleanup(RERR_SOCKETIO);
380 if (fd_pair(error_pipe) < 0) {
381 rprintf(FERROR,"error pipe failed in do_recv\n");
382 exit_cleanup(RERR_SOCKETIO);
387 if ((pid=do_fork()) == 0) {
389 close(error_pipe[0]);
390 if (f_in != f_out) close(f_out);
392 /* we can't let two processes write to the socket at one time */
393 io_multiplexing_close();
395 /* set place to send errors */
396 set_error_fd(error_pipe[1]);
398 recv_files(f_in,flist,local_name,recv_pipe[1]);
402 write_int(recv_pipe[1],1);
405 /* finally we go to sleep until our parent kills us
406 with a USR2 signal. We sleep for a short time as on
407 some OSes a signal won't interrupt a sleep! */
413 close(error_pipe[1]);
414 if (f_in != f_out) close(f_in);
416 io_start_buffering(f_out);
418 io_set_error_fd(error_pipe[0]);
420 generate_files(f_out,flist,local_name,recv_pipe[0]);
422 read_int(recv_pipe[0]);
424 if (remote_version >= 24) {
425 /* send a final goodbye message */
426 write_int(f_out, -1);
431 wait_process(pid, &status);
436 static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
439 struct file_list *flist;
440 char *local_name=NULL;
442 extern int delete_mode;
443 extern int delete_excluded;
444 extern int am_daemon;
445 extern int module_id;
446 extern int am_sender;
447 extern int read_batch;
448 extern struct file_list *batch_flist;
451 rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
453 if (am_daemon && lp_read_only(module_id) && !am_sender) {
454 rprintf(FERROR,"ERROR: module is read only\n");
455 exit_cleanup(RERR_SYNTAX);
464 if (!am_daemon && !push_dir(dir, 0)) {
465 rprintf(FERROR,"push_dir %s : %s (4)\n",
466 dir,strerror(errno));
467 exit_cleanup(RERR_FILESELECT);
471 if (delete_mode && !delete_excluded)
472 recv_exclude_list(f_in);
477 flist = recv_file_list(f_in);
479 rprintf(FERROR,"server_recv: recv_file_list error\n");
480 exit_cleanup(RERR_FILESELECT);
484 if (strcmp(dir,".")) {
485 argv[0] += strlen(dir);
486 if (argv[0][0] == '/') argv[0]++;
488 local_name = get_local_name(flist,argv[0]);
491 status = do_recv(f_in,f_out,flist,local_name);
492 exit_cleanup(status);
496 int child_main(int argc, char *argv[])
498 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
503 void start_server(int f_in, int f_out, int argc, char *argv[])
505 extern int cvs_exclude;
506 extern int am_sender;
507 extern int remote_version;
508 extern int read_batch;
510 setup_protocol(f_out, f_in);
512 set_nonblocking(f_in);
513 set_nonblocking(f_out);
515 if (remote_version >= 23)
516 io_start_multiplex_out(f_out);
520 recv_exclude_list(f_in);
524 do_server_sender(f_in, f_out, argc, argv);
526 do_server_recv(f_in, f_out, argc, argv);
533 * This is called once the connection has been negotiated. It is used
534 * for rsyncd, remote-shell, and local connections.
536 int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
538 struct file_list *flist = NULL;
539 int status = 0, status2 = 0;
540 char *local_name = NULL;
541 extern int am_sender;
542 extern int remote_version;
543 extern pid_t cleanup_child_pid;
544 extern int write_batch;
545 extern int read_batch;
546 extern struct file_list *batch_flist;
548 cleanup_child_pid = pid;
552 set_nonblocking(f_in);
553 set_nonblocking(f_out);
555 setup_protocol(f_out,f_in);
557 if (remote_version >= 23)
558 io_start_multiplex_in(f_in);
561 extern int cvs_exclude;
562 extern int delete_mode;
563 extern int delete_excluded;
566 if (delete_mode && !delete_excluded)
567 send_exclude_list(f_out);
568 if (!read_batch) /* dw -- don't write to pipe */
569 flist = send_file_list(f_out,argc,argv);
571 rprintf(FINFO,"file list sent\n");
573 send_files(flist,f_out,f_in);
574 if (remote_version >= 24) {
575 /* final goodbye message */
580 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
582 wait_process(pid, &status);
585 exit_cleanup(status);
589 extern int list_only;
594 send_exclude_list(f_out);
596 flist = recv_file_list(f_in);
597 if (!flist || flist->count == 0) {
598 rprintf(FINFO, "client: nothing to do: "
599 "perhaps you need to specify some filenames or "
600 "the --recursive option?\n");
604 local_name = get_local_name(flist,argv[0]);
606 status2 = do_recv(f_in,f_out,flist,local_name);
610 rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
612 wait_process(pid, &status);
615 return MAX(status, status2);
618 static char *find_colon(char *s)
625 /* now check to see if there is a / in the string before the : - if there is then
626 discard the colon on the assumption that the : is part of a filename */
628 if (p2 && p2 < p) return NULL;
634 static int copy_argv (char *argv[])
638 for (i = 0; argv[i]; i++) {
639 if (!(argv[i] = strdup(argv[i]))) {
640 rprintf (FERROR, "out of memory at %s(%d)\n",
651 * Start a client for either type of remote connection. Work out
652 * whether the arguments request a remote shell or rsyncd connection,
653 * and call the appropriate connection function, then run_client.
655 * Calls either start_socket_client (for sockets) or do_cmd and
656 * client_run (for ssh).
658 static int start_client(int argc, char *argv[])
661 char *shell_machine = NULL;
662 char *shell_path = NULL;
663 char *shell_user = NULL;
667 extern int local_server;
668 extern int am_sender;
669 extern char *shell_cmd;
670 extern int rsync_port;
671 extern int daemon_over_rsh;
672 extern int read_batch;
675 /* Don't clobber argv[] so that ps(1) can still show the right
677 if ((rc = copy_argv(argv)))
680 /* rsync:// always uses rsync server over direct socket connection */
681 if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) {
684 host = argv[0] + strlen(URL_PREFIX);
685 p = strchr(host,'/');
692 p = strchr(host,':');
694 rsync_port = atoi(p+1);
697 return start_socket_client(host, path, argc-1, argv+1);
701 p = find_colon(argv[0]);
704 if (p[1] == ':') { /* double colon */
707 return start_socket_client(argv[0], p+2,
716 exit_cleanup(RERR_SYNTAX);
721 shell_machine = argv[0];
728 p = find_colon(argv[argc-1]);
731 } else if (p[1] == ':') { /* double colon */
734 return start_socket_client(argv[argc-1], p+2,
743 exit_cleanup(RERR_SYNTAX);
747 shell_machine = NULL;
748 shell_path = argv[argc-1];
751 shell_machine = argv[argc-1];
759 shell_path = argv[argc-1];
763 p = strchr(shell_machine,'@');
766 shell_user = shell_machine;
772 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
773 shell_cmd?shell_cmd:"",
774 shell_machine?shell_machine:"",
775 shell_user?shell_user:"",
776 shell_path?shell_path:"");
779 if (!am_sender && argc > 1) {
781 exit_cleanup(RERR_SYNTAX);
784 if (argc == 0 && !am_sender) {
785 extern int list_only;
789 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
792 /* if we're running an rsync server on the remote host over a
793 remote shell command, we need to do the RSYNCD protocol first */
794 if (daemon_over_rsh) {
796 tmpret = start_inband_exchange(shell_user, shell_path,
802 ret = client_run(f_in, f_out, pid, argc, argv);
811 static RETSIGTYPE sigusr1_handler(int UNUSED(val)) {
812 exit_cleanup(RERR_SIGNAL);
815 static RETSIGTYPE sigusr2_handler(int UNUSED(val)) {
816 extern int log_got_error;
817 if (log_got_error) _exit(RERR_PARTIAL);
821 static RETSIGTYPE sigchld_handler(int UNUSED(val)) {
823 while (waitpid(-1, NULL, WNOHANG) > 0) ;
829 * This routine catches signals and tries to send them to gdb.
831 * Because it's called from inside a signal handler it ought not to
832 * use too many library routines.
834 * @todo Perhaps use "screen -X" instead/as well, to help people
835 * debugging without easy access to X. Perhaps use an environment
836 * variable, or just call a script?
838 * @todo The /proc/ magic probably only works on Linux (and
839 * Solaris?) Can we be more portable?
841 #ifdef MAINTAINER_MODE
842 const char *get_panic_action(void)
844 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
849 return "xterm -display :0 -T Panic -n Panic "
850 "-e gdb /proc/%d/exe %d";
855 * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
857 * This signal handler is only installed if we were configured with
858 * --enable-maintainer-mode. Perhaps it should always be on and we
859 * should just look at the environment variable, but I'm a bit leery
860 * of a signal sending us into a busy loop.
862 static RETSIGTYPE rsync_panic_handler(int UNUSED(whatsig))
867 sprintf(cmd_buf, get_panic_action(),
870 /* Unless we failed to execute gdb, we allow the process to
871 * continue. I'm not sure if that's right. */
872 ret = system(cmd_buf);
879 int main(int argc,char *argv[])
882 extern int orig_umask;
884 extern int am_daemon;
885 extern int am_server;
887 extern int write_batch;
894 signal(SIGUSR1, sigusr1_handler);
895 signal(SIGUSR2, sigusr2_handler);
896 signal(SIGCHLD, sigchld_handler);
897 #ifdef MAINTAINER_MODE
898 signal(SIGSEGV, rsync_panic_handler);
899 signal(SIGFPE, rsync_panic_handler);
900 signal(SIGABRT, rsync_panic_handler);
901 signal(SIGBUS, rsync_panic_handler);
902 #endif /* def MAINTAINER_MODE */
904 starttime = time(NULL);
905 am_root = (getuid() == 0);
907 memset(&stats, 0, sizeof(stats));
911 exit_cleanup(RERR_SYNTAX);
914 /* we set a 0 umask so that correct file permissions can be
916 orig_umask = (int)umask(0);
918 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
919 /* FIXME: We ought to call the same error-handling
920 * code here, rather than relying on getopt. */
922 exit_cleanup(RERR_SYNTAX);
925 signal(SIGINT,SIGNAL_CAST sig_int);
926 signal(SIGHUP,SIGNAL_CAST sig_int);
927 signal(SIGTERM,SIGNAL_CAST sig_int);
929 /* Ignore SIGPIPE; we consistently check error codes and will
931 signal(SIGPIPE, SIG_IGN);
933 /* Initialize push_dir here because on some old systems getcwd
934 (implemented by forking "pwd" and reading its output) doesn't
935 work when there are other child processes. Also, on all systems
936 that implement getcwd that way "pwd" can't be found after chroot. */
939 if (write_batch && !am_server) {
940 write_batch_argvs_file(orig_argc, orig_argv);
943 if (am_daemon && !am_server)
944 return daemon_main();
948 exit_cleanup(RERR_SYNTAX);
952 verbose = MAX(verbose,1);
954 #ifndef SUPPORT_LINKS
955 if (!am_server && preserve_links) {
956 rprintf(FERROR,"ERROR: symbolic links not supported\n");
957 exit_cleanup(RERR_UNSUPPORTED);
962 set_nonblocking(STDIN_FILENO);
963 set_nonblocking(STDOUT_FILENO);
965 return start_daemon(STDIN_FILENO, STDOUT_FILENO);
966 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
969 ret = start_client(argc, argv);
971 exit_cleanup(RERR_STARTCLIENT);