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)
175 extern int local_server;
176 extern char *rsync_path;
177 extern int blocking_io;
178 extern int daemon_over_rsh;
179 extern int read_batch;
181 if (!read_batch && !local_server) {
183 cmd = getenv(RSYNC_RSH_ENV);
190 for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
194 /* check to see if we've already been given '-l user' in
195 the remote-shell command */
196 for (i = 0; i < argc-1; i++) {
197 if (!strcmp(args[i], "-l") && args[i+1][0] != '-')
202 /* remsh (on HPUX) takes the arguments the other way around */
203 args[argc++] = machine;
204 if (user && !(daemon_over_rsh && dash_l_set)) {
209 if (user && !(daemon_over_rsh && dash_l_set)) {
213 args[argc++] = machine;
216 args[argc++] = rsync_path;
218 if ((blocking_io == -1) && (strcmp(cmd, RSYNC_RSH) == 0))
221 server_options(args,&argc);
227 if (!daemon_over_rsh && path && *path)
233 rprintf(FINFO,"cmd=");
235 rprintf(FINFO,"%s ",args[i]);
241 create_flist_from_batch(); /* sets batch_flist */
242 ret = local_child(argc, args, f_in, f_out, child_main);
244 ret = piped_child(args,f_in,f_out);
252 out_of_memory("do_cmd");
253 return 0; /* not reached */
259 static char *get_local_name(struct file_list *flist,char *name)
262 extern int orig_umask;
265 rprintf(FINFO,"get_local_name count=%d %s\n",
266 flist->count, NS(name));
271 if (do_stat(name,&st) == 0) {
272 if (S_ISDIR(st.st_mode)) {
273 if (!push_dir(name, 0)) {
274 rprintf(FERROR,"push_dir %s : %s (1)\n",
275 name,strerror(errno));
276 exit_cleanup(RERR_FILESELECT);
280 if (flist->count > 1) {
281 rprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
282 exit_cleanup(RERR_FILESELECT);
287 if (flist->count <= 1)
290 if (do_mkdir(name,0777 & ~orig_umask) != 0) {
291 rprintf(FERROR, RSYNC_NAME ": mkdir %s: %s\n",
292 name, strerror(errno));
293 exit_cleanup(RERR_FILEIO);
296 rprintf(FINFO,"created directory %s\n",name);
299 if (!push_dir(name, 0)) {
300 rprintf(FERROR, RSYNC_NAME ": push_dir %s: %s\n",
301 name, strerror(errno));
302 exit_cleanup(RERR_FILESELECT);
311 static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
314 struct file_list *flist;
316 extern int relative_paths;
318 extern int remote_version;
321 rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
323 if (!relative_paths && !push_dir(dir, 0)) {
324 rprintf(FERROR,"push_dir %s: %s (3)\n",dir,strerror(errno));
325 exit_cleanup(RERR_FILESELECT);
330 if (strcmp(dir,".")) {
332 if (strcmp(dir,"/") == 0)
338 if (argc == 0 && recurse) {
344 flist = send_file_list(f_out,argc,argv);
345 if (!flist || flist->count == 0) {
349 send_files(flist,f_out,f_in);
352 if (remote_version >= 24) {
353 /* final goodbye message */
361 static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
367 extern int preserve_hard_links;
368 extern int delete_after;
370 extern int delete_mode;
371 extern int remote_version;
373 if (preserve_hard_links)
374 init_hard_links(flist);
377 /* I moved this here from recv_files() to prevent a race condition */
378 if (recurse && delete_mode && !local_name && flist->count>0) {
383 if (fd_pair(recv_pipe) < 0) {
384 rprintf(FERROR,"pipe failed in do_recv\n");
385 exit_cleanup(RERR_SOCKETIO);
388 if (fd_pair(error_pipe) < 0) {
389 rprintf(FERROR,"error pipe failed in do_recv\n");
390 exit_cleanup(RERR_SOCKETIO);
395 if ((pid=do_fork()) == 0) {
397 close(error_pipe[0]);
398 if (f_in != f_out) close(f_out);
400 /* we can't let two processes write to the socket at one time */
401 io_multiplexing_close();
403 /* set place to send errors */
404 set_error_fd(error_pipe[1]);
406 recv_files(f_in,flist,local_name,recv_pipe[1]);
410 write_int(recv_pipe[1],1);
413 /* finally we go to sleep until our parent kills us
414 with a USR2 signal. We sleep for a short time as on
415 some OSes a signal won't interrupt a sleep! */
421 close(error_pipe[1]);
422 if (f_in != f_out) close(f_in);
424 io_start_buffering(f_out);
426 io_set_error_fd(error_pipe[0]);
428 generate_files(f_out,flist,local_name,recv_pipe[0]);
430 read_int(recv_pipe[0]);
432 if (remote_version >= 24) {
433 /* send a final goodbye message */
434 write_int(f_out, -1);
439 wait_process(pid, &status);
444 static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
447 struct file_list *flist;
448 char *local_name=NULL;
450 extern int delete_mode;
451 extern int delete_excluded;
452 extern int am_daemon;
453 extern int module_id;
454 extern int am_sender;
455 extern int read_batch;
456 extern struct file_list *batch_flist;
459 rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
461 if (am_daemon && lp_read_only(module_id) && !am_sender) {
462 rprintf(FERROR,"ERROR: module is read only\n");
463 exit_cleanup(RERR_SYNTAX);
472 if (!am_daemon && !push_dir(dir, 0)) {
473 rprintf(FERROR,"push_dir %s : %s (4)\n",
474 dir,strerror(errno));
475 exit_cleanup(RERR_FILESELECT);
479 if (delete_mode && !delete_excluded)
480 recv_exclude_list(f_in);
485 flist = recv_file_list(f_in);
487 rprintf(FERROR,"server_recv: recv_file_list error\n");
488 exit_cleanup(RERR_FILESELECT);
492 if (strcmp(dir,".")) {
493 argv[0] += strlen(dir);
494 if (argv[0][0] == '/') argv[0]++;
496 local_name = get_local_name(flist,argv[0]);
499 status = do_recv(f_in,f_out,flist,local_name);
500 exit_cleanup(status);
504 int child_main(int argc, char *argv[])
506 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
511 void start_server(int f_in, int f_out, int argc, char *argv[])
513 extern int cvs_exclude;
514 extern int am_sender;
515 extern int remote_version;
516 extern int read_batch;
518 setup_protocol(f_out, f_in);
520 set_nonblocking(f_in);
521 set_nonblocking(f_out);
523 if (remote_version >= 23)
524 io_start_multiplex_out(f_out);
528 recv_exclude_list(f_in);
532 do_server_sender(f_in, f_out, argc, argv);
534 do_server_recv(f_in, f_out, argc, argv);
541 * This is called once the connection has been negotiated. It is used
542 * for rsyncd, remote-shell, and local connections.
544 int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
546 struct file_list *flist = NULL;
547 int status = 0, status2 = 0;
548 char *local_name = NULL;
549 extern int am_sender;
550 extern int remote_version;
551 extern pid_t cleanup_child_pid;
552 extern int write_batch;
553 extern int read_batch;
554 extern struct file_list *batch_flist;
556 cleanup_child_pid = pid;
560 set_nonblocking(f_in);
561 set_nonblocking(f_out);
563 setup_protocol(f_out,f_in);
565 if (remote_version >= 23)
566 io_start_multiplex_in(f_in);
569 extern int cvs_exclude;
570 extern int delete_mode;
571 extern int delete_excluded;
574 if (delete_mode && !delete_excluded)
575 send_exclude_list(f_out);
576 if (!read_batch) /* dw -- don't write to pipe */
577 flist = send_file_list(f_out,argc,argv);
579 rprintf(FINFO,"file list sent\n");
581 send_files(flist,f_out,f_in);
582 if (remote_version >= 24) {
583 /* final goodbye message */
588 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
590 wait_process(pid, &status);
593 exit_cleanup(status);
597 extern int list_only;
602 send_exclude_list(f_out);
604 flist = recv_file_list(f_in);
605 if (!flist || flist->count == 0) {
606 rprintf(FINFO, "client: nothing to do: "
607 "perhaps you need to specify some filenames or "
608 "the --recursive option?\n");
612 local_name = get_local_name(flist,argv[0]);
614 status2 = do_recv(f_in,f_out,flist,local_name);
618 rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
620 wait_process(pid, &status);
623 return MAX(status, status2);
626 static char *find_colon(char *s)
633 /* now check to see if there is a / in the string before the : - if there is then
634 discard the colon on the assumption that the : is part of a filename */
636 if (p2 && p2 < p) return NULL;
642 static int copy_argv (char *argv[])
646 for (i = 0; argv[i]; i++) {
647 if (!(argv[i] = strdup(argv[i]))) {
648 rprintf (FERROR, "out of memory at %s(%d)\n",
659 * Start a client for either type of remote connection. Work out
660 * whether the arguments request a remote shell or rsyncd connection,
661 * and call the appropriate connection function, then run_client.
663 * Calls either start_socket_client (for sockets) or do_cmd and
664 * client_run (for ssh).
666 static int start_client(int argc, char *argv[])
669 char *shell_machine = NULL;
670 char *shell_path = NULL;
671 char *shell_user = NULL;
675 extern int local_server;
676 extern int am_sender;
677 extern char *shell_cmd;
678 extern int rsync_port;
679 extern int daemon_over_rsh;
680 extern int read_batch;
683 /* Don't clobber argv[] so that ps(1) can still show the right
685 if ((rc = copy_argv(argv)))
688 /* rsync:// always uses rsync server over direct socket connection */
689 if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) {
692 host = argv[0] + strlen(URL_PREFIX);
693 p = strchr(host,'/');
700 p = strchr(host,':');
702 rsync_port = atoi(p+1);
705 return start_socket_client(host, path, argc-1, argv+1);
709 p = find_colon(argv[0]);
712 if (p[1] == ':') { /* double colon */
715 return start_socket_client(argv[0], p+2,
724 exit_cleanup(RERR_SYNTAX);
729 shell_machine = argv[0];
736 /* rsync:// destination uses rsync server over direct socket */
737 if (strncasecmp(URL_PREFIX, argv[argc-1], strlen(URL_PREFIX)) == 0) {
740 host = argv[argc-1] + strlen(URL_PREFIX);
741 p = strchr(host,'/');
748 p = strchr(host,':');
750 rsync_port = atoi(p+1);
753 return start_socket_client(host, path, argc-1, argv);
756 p = find_colon(argv[argc-1]);
759 } else if (p[1] == ':') { /* double colon */
762 return start_socket_client(argv[argc-1], p+2,
771 exit_cleanup(RERR_SYNTAX);
775 shell_machine = NULL;
776 shell_path = argv[argc-1];
779 shell_machine = argv[argc-1];
787 shell_path = argv[argc-1];
791 p = strchr(shell_machine,'@');
794 shell_user = shell_machine;
800 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
801 shell_cmd?shell_cmd:"",
802 shell_machine?shell_machine:"",
803 shell_user?shell_user:"",
804 shell_path?shell_path:"");
807 if (!am_sender && argc > 1) {
809 exit_cleanup(RERR_SYNTAX);
812 if (argc == 0 && !am_sender) {
813 extern int list_only;
817 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
820 /* if we're running an rsync server on the remote host over a
821 remote shell command, we need to do the RSYNCD protocol first */
822 if (daemon_over_rsh) {
824 tmpret = start_inband_exchange(shell_user, shell_path,
830 ret = client_run(f_in, f_out, pid, argc, argv);
839 static RETSIGTYPE sigusr1_handler(int UNUSED(val)) {
840 exit_cleanup(RERR_SIGNAL);
843 static RETSIGTYPE sigusr2_handler(int UNUSED(val)) {
844 extern int log_got_error;
845 if (log_got_error) _exit(RERR_PARTIAL);
849 static RETSIGTYPE sigchld_handler(int UNUSED(val)) {
851 while (waitpid(-1, NULL, WNOHANG) > 0) ;
857 * This routine catches signals and tries to send them to gdb.
859 * Because it's called from inside a signal handler it ought not to
860 * use too many library routines.
862 * @todo Perhaps use "screen -X" instead/as well, to help people
863 * debugging without easy access to X. Perhaps use an environment
864 * variable, or just call a script?
866 * @todo The /proc/ magic probably only works on Linux (and
867 * Solaris?) Can we be more portable?
869 #ifdef MAINTAINER_MODE
870 const char *get_panic_action(void)
872 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
877 return "xterm -display :0 -T Panic -n Panic "
878 "-e gdb /proc/%d/exe %d";
883 * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
885 * This signal handler is only installed if we were configured with
886 * --enable-maintainer-mode. Perhaps it should always be on and we
887 * should just look at the environment variable, but I'm a bit leery
888 * of a signal sending us into a busy loop.
890 static RETSIGTYPE rsync_panic_handler(int UNUSED(whatsig))
895 sprintf(cmd_buf, get_panic_action(),
898 /* Unless we failed to execute gdb, we allow the process to
899 * continue. I'm not sure if that's right. */
900 ret = system(cmd_buf);
907 int main(int argc,char *argv[])
910 extern int orig_umask;
912 extern int am_daemon;
913 extern int am_server;
915 extern int write_batch;
922 signal(SIGUSR1, sigusr1_handler);
923 signal(SIGUSR2, sigusr2_handler);
924 signal(SIGCHLD, sigchld_handler);
925 #ifdef MAINTAINER_MODE
926 signal(SIGSEGV, rsync_panic_handler);
927 signal(SIGFPE, rsync_panic_handler);
928 signal(SIGABRT, rsync_panic_handler);
929 signal(SIGBUS, rsync_panic_handler);
930 #endif /* def MAINTAINER_MODE */
932 starttime = time(NULL);
933 am_root = (getuid() == 0);
935 memset(&stats, 0, sizeof(stats));
939 exit_cleanup(RERR_SYNTAX);
942 /* we set a 0 umask so that correct file permissions can be
944 orig_umask = (int)umask(0);
946 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
947 /* FIXME: We ought to call the same error-handling
948 * code here, rather than relying on getopt. */
950 exit_cleanup(RERR_SYNTAX);
953 signal(SIGINT,SIGNAL_CAST sig_int);
954 signal(SIGHUP,SIGNAL_CAST sig_int);
955 signal(SIGTERM,SIGNAL_CAST sig_int);
957 /* Ignore SIGPIPE; we consistently check error codes and will
959 signal(SIGPIPE, SIG_IGN);
961 /* Initialize push_dir here because on some old systems getcwd
962 (implemented by forking "pwd" and reading its output) doesn't
963 work when there are other child processes. Also, on all systems
964 that implement getcwd that way "pwd" can't be found after chroot. */
967 if (write_batch && !am_server) {
968 write_batch_argvs_file(orig_argc, orig_argv);
971 if (am_daemon && !am_server)
972 return daemon_main();
976 exit_cleanup(RERR_SYNTAX);
980 verbose = MAX(verbose,1);
982 #ifndef SUPPORT_LINKS
983 if (!am_server && preserve_links) {
984 rprintf(FERROR,"ERROR: symbolic links not supported\n");
985 exit_cleanup(RERR_UNSUPPORTED);
990 set_nonblocking(STDIN_FILENO);
991 set_nonblocking(STDOUT_FILENO);
993 return start_daemon(STDIN_FILENO, STDOUT_FILENO);
994 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
997 ret = start_client(argc, argv);
999 exit_cleanup(RERR_STARTCLIENT);