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;
32 /* there's probably never more than at most 2 outstanding child processes,
33 * but set it higher just in case.
35 #define MAXCHILDPROCS 5
40 } pid_stat_table[MAXCHILDPROCS];
42 static void show_malloc_stats(void);
44 /****************************************************************************
45 wait for a process to exit, calling io_flush while waiting
46 ****************************************************************************/
47 void wait_process(pid_t pid, int *status)
52 while ((waited_pid = waitpid(pid, status, WNOHANG)) == 0) {
57 if ((waited_pid == -1) && (errno == ECHILD)) {
58 /* status of requested child no longer available.
59 * check to see if it was processed by the sigchld_handler.
61 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
62 if (pid == pid_stat_table[cnt].pid) {
63 *status = pid_stat_table[cnt].status;
64 pid_stat_table[cnt].pid = 0;
70 /* TODO: If the child exited on a signal, then log an
71 * appropriate error message. Perhaps we should also accept a
72 * message describing the purpose of the child. Also indicate
73 * this to the caller so that thhey know something went
75 *status = WEXITSTATUS(*status);
78 static void report(int f)
80 time_t t = time(NULL);
82 extern int remote_version;
86 /* These come out from every process */
92 log_exit(0, __FILE__, __LINE__);
93 if (f == -1 || !am_sender) return;
96 send_stats = verbose || (remote_version >= 20);
98 if (am_sender && send_stats) {
100 /* store total_written in a temporary
101 * because write_longint changes it */
102 w = stats.total_written;
103 write_longint(f,stats.total_read);
105 write_longint(f,stats.total_size);
110 /* this is the client */
112 if (!am_sender && send_stats) {
114 stats.total_written = read_longint(f);
115 /* store total_read in a temporary, read_longint changes it */
117 stats.total_size = read_longint(f);
118 stats.total_read = r;
122 if (!am_sender && !send_stats) {
123 /* missing the bytes written by the generator */
124 rprintf(FINFO, "\nCannot show stats as receiver because remote protocol version is less than 20\n");
125 rprintf(FINFO, "Use --stats -v to show stats\n");
128 rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
129 rprintf(FINFO,"Number of files transferred: %d\n",
130 stats.num_transferred_files);
131 rprintf(FINFO,"Total file size: %.0f bytes\n",
132 (double)stats.total_size);
133 rprintf(FINFO,"Total transferred file size: %.0f bytes\n",
134 (double)stats.total_transferred_size);
135 rprintf(FINFO,"Literal data: %.0f bytes\n",
136 (double)stats.literal_data);
137 rprintf(FINFO,"Matched data: %.0f bytes\n",
138 (double)stats.matched_data);
139 rprintf(FINFO,"File list size: %d\n", stats.flist_size);
140 rprintf(FINFO,"Total bytes written: %.0f\n",
141 (double)stats.total_written);
142 rprintf(FINFO,"Total bytes read: %.0f\n\n",
143 (double)stats.total_read);
146 if (verbose || do_stats) {
147 rprintf(FINFO,"wrote %.0f bytes read %.0f bytes %.2f bytes/sec\n",
148 (double)stats.total_written,
149 (double)stats.total_read,
150 (stats.total_written+stats.total_read)/(0.5 + (t-starttime)));
151 rprintf(FINFO,"total size is %.0f speedup is %.2f\n",
152 (double)stats.total_size,
153 (1.0*stats.total_size)/(stats.total_written+stats.total_read));
162 * If our C library can get malloc statistics, then show them to FINFO
164 static void show_malloc_stats(void)
171 rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
173 am_server ? "server " : "",
174 am_daemon ? "daemon " : "",
175 am_sender ? "sender" : "receiver");
176 rprintf(FINFO, " arena: %10d (bytes from sbrk)\n", mi.arena);
177 rprintf(FINFO, " ordblks: %10d (chunks not in use)\n", mi.ordblks);
178 rprintf(FINFO, " smblks: %10d\n", mi.smblks);
179 rprintf(FINFO, " hblks: %10d (chunks from mmap)\n", mi.hblks);
180 rprintf(FINFO, " hblkhd: %10d (bytes from mmap)\n", mi.hblkhd);
181 rprintf(FINFO, " usmblks: %10d\n", mi.usmblks);
182 rprintf(FINFO, " fsmblks: %10d\n", mi.fsmblks);
183 rprintf(FINFO, " uordblks: %10d (bytes used)\n", mi.uordblks);
184 rprintf(FINFO, " fordblks: %10d (bytes free)\n", mi.fordblks);
185 rprintf(FINFO, " keepcost: %10d (bytes in releasable chunk)\n", mi.keepcost);
186 #endif /* HAVE_MALLINFO */
190 /* Start the remote shell. cmd may be NULL to use the default. */
191 static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
198 extern int local_server;
199 extern char *rsync_path;
200 extern int blocking_io;
201 extern int daemon_over_rsh;
202 extern int read_batch;
204 if (!read_batch && !local_server) {
206 cmd = getenv(RSYNC_RSH_ENV);
213 for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
217 /* check to see if we've already been given '-l user' in
218 the remote-shell command */
219 for (i = 0; i < argc-1; i++) {
220 if (!strcmp(args[i], "-l") && args[i+1][0] != '-')
225 /* remsh (on HPUX) takes the arguments the other way around */
226 args[argc++] = machine;
227 if (user && !(daemon_over_rsh && dash_l_set)) {
232 if (user && !(daemon_over_rsh && dash_l_set)) {
236 args[argc++] = machine;
239 args[argc++] = rsync_path;
241 if ((blocking_io == -1) && (strcmp(cmd, RSYNC_RSH) == 0))
244 server_options(args,&argc);
250 if (!daemon_over_rsh && path && *path)
256 rprintf(FINFO,"cmd=");
258 rprintf(FINFO,"%s ",args[i]);
264 create_flist_from_batch(); /* sets batch_flist */
265 ret = local_child(argc, args, f_in, f_out, child_main);
267 ret = piped_child(args,f_in,f_out);
275 out_of_memory("do_cmd");
276 return 0; /* not reached */
282 static char *get_local_name(struct file_list *flist,char *name)
285 extern int orig_umask;
288 rprintf(FINFO,"get_local_name count=%d %s\n",
289 flist->count, NS(name));
294 if (do_stat(name,&st) == 0) {
295 if (S_ISDIR(st.st_mode)) {
296 if (!push_dir(name, 0)) {
297 rprintf(FERROR,"push_dir %s : %s (1)\n",
298 name,strerror(errno));
299 exit_cleanup(RERR_FILESELECT);
303 if (flist->count > 1) {
304 rprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
305 exit_cleanup(RERR_FILESELECT);
310 if (flist->count <= 1)
313 if (do_mkdir(name,0777 & ~orig_umask) != 0) {
314 rprintf(FERROR, RSYNC_NAME ": mkdir %s: %s\n",
315 name, strerror(errno));
316 exit_cleanup(RERR_FILEIO);
319 rprintf(FINFO,"created directory %s\n",name);
322 if (!push_dir(name, 0)) {
323 rprintf(FERROR, RSYNC_NAME ": push_dir %s: %s\n",
324 name, strerror(errno));
325 exit_cleanup(RERR_FILESELECT);
334 static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
337 struct file_list *flist;
339 extern int relative_paths;
341 extern int remote_version;
344 rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
346 if (!relative_paths && !push_dir(dir, 0)) {
347 rprintf(FERROR,"push_dir %s: %s (3)\n",dir,strerror(errno));
348 exit_cleanup(RERR_FILESELECT);
353 if (strcmp(dir,".")) {
355 if (strcmp(dir,"/") == 0)
361 if (argc == 0 && recurse) {
367 flist = send_file_list(f_out,argc,argv);
368 if (!flist || flist->count == 0) {
372 send_files(flist,f_out,f_in);
375 if (remote_version >= 24) {
376 /* final goodbye message */
384 static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
390 extern int preserve_hard_links;
391 extern int delete_after;
393 extern int delete_mode;
394 extern int remote_version;
396 if (preserve_hard_links)
397 init_hard_links(flist);
400 /* I moved this here from recv_files() to prevent a race condition */
401 if (recurse && delete_mode && !local_name && flist->count>0) {
406 if (fd_pair(recv_pipe) < 0) {
407 rprintf(FERROR,"pipe failed in do_recv\n");
408 exit_cleanup(RERR_SOCKETIO);
411 if (fd_pair(error_pipe) < 0) {
412 rprintf(FERROR,"error pipe failed in do_recv\n");
413 exit_cleanup(RERR_SOCKETIO);
418 if ((pid=do_fork()) == 0) {
420 close(error_pipe[0]);
421 if (f_in != f_out) close(f_out);
423 /* we can't let two processes write to the socket at one time */
424 io_multiplexing_close();
426 /* set place to send errors */
427 set_error_fd(error_pipe[1]);
429 recv_files(f_in,flist,local_name,recv_pipe[1]);
433 write_int(recv_pipe[1],1);
436 /* finally we go to sleep until our parent kills us
437 with a USR2 signal. We sleep for a short time as on
438 some OSes a signal won't interrupt a sleep! */
444 close(error_pipe[1]);
445 if (f_in != f_out) close(f_in);
447 io_start_buffering(f_out);
449 io_set_error_fd(error_pipe[0]);
451 generate_files(f_out,flist,local_name,recv_pipe[0]);
453 read_int(recv_pipe[0]);
455 if (remote_version >= 24) {
456 /* send a final goodbye message */
457 write_int(f_out, -1);
463 wait_process(pid, &status);
468 static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
471 struct file_list *flist;
472 char *local_name=NULL;
474 extern int delete_mode;
475 extern int delete_excluded;
476 extern int module_id;
477 extern int read_batch;
478 extern struct file_list *batch_flist;
481 rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
483 if (am_daemon && lp_read_only(module_id) && !am_sender) {
484 rprintf(FERROR,"ERROR: module is read only\n");
485 exit_cleanup(RERR_SYNTAX);
494 if (!am_daemon && !push_dir(dir, 0)) {
495 rprintf(FERROR,"push_dir %s : %s (4)\n",
496 dir,strerror(errno));
497 exit_cleanup(RERR_FILESELECT);
501 if (delete_mode && !delete_excluded)
502 recv_exclude_list(f_in);
507 flist = recv_file_list(f_in);
509 rprintf(FERROR,"server_recv: recv_file_list error\n");
510 exit_cleanup(RERR_FILESELECT);
514 if (strcmp(dir,".")) {
515 argv[0] += strlen(dir);
516 if (argv[0][0] == '/') argv[0]++;
518 local_name = get_local_name(flist,argv[0]);
521 status = do_recv(f_in,f_out,flist,local_name);
522 exit_cleanup(status);
526 int child_main(int argc, char *argv[])
528 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
533 void start_server(int f_in, int f_out, int argc, char *argv[])
535 extern int cvs_exclude;
536 extern int remote_version;
537 extern int read_batch;
539 setup_protocol(f_out, f_in);
541 set_nonblocking(f_in);
542 set_nonblocking(f_out);
544 if (remote_version >= 23)
545 io_start_multiplex_out(f_out);
549 recv_exclude_list(f_in);
553 do_server_sender(f_in, f_out, argc, argv);
555 do_server_recv(f_in, f_out, argc, argv);
562 * This is called once the connection has been negotiated. It is used
563 * for rsyncd, remote-shell, and local connections.
565 int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
567 struct file_list *flist = NULL;
568 int status = 0, status2 = 0;
569 char *local_name = NULL;
570 extern int remote_version;
571 extern pid_t cleanup_child_pid;
572 extern int write_batch;
573 extern int read_batch;
574 extern struct file_list *batch_flist;
576 cleanup_child_pid = pid;
580 set_nonblocking(f_in);
581 set_nonblocking(f_out);
583 setup_protocol(f_out,f_in);
585 if (remote_version >= 23)
586 io_start_multiplex_in(f_in);
589 extern int cvs_exclude;
590 extern int delete_mode;
591 extern int delete_excluded;
594 if (delete_mode && !delete_excluded)
595 send_exclude_list(f_out);
596 if (!read_batch) /* dw -- don't write to pipe */
597 flist = send_file_list(f_out,argc,argv);
599 rprintf(FINFO,"file list sent\n");
601 send_files(flist,f_out,f_in);
602 if (remote_version >= 24) {
603 /* final goodbye message */
608 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
610 wait_process(pid, &status);
613 exit_cleanup(status);
617 extern int list_only;
622 send_exclude_list(f_out);
624 flist = recv_file_list(f_in);
625 if (!flist || flist->count == 0) {
626 rprintf(FINFO, "client: nothing to do: "
627 "perhaps you need to specify some filenames or "
628 "the --recursive option?\n");
632 local_name = get_local_name(flist,argv[0]);
634 status2 = do_recv(f_in,f_out,flist,local_name);
638 rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
640 wait_process(pid, &status);
643 return MAX(status, status2);
646 static char *find_colon(char *s)
653 /* now check to see if there is a / in the string before the : - if there is then
654 discard the colon on the assumption that the : is part of a filename */
656 if (p2 && p2 < p) return NULL;
662 static int copy_argv (char *argv[])
666 for (i = 0; argv[i]; i++) {
667 if (!(argv[i] = strdup(argv[i]))) {
668 rprintf (FERROR, "out of memory at %s(%d)\n",
679 * Start a client for either type of remote connection. Work out
680 * whether the arguments request a remote shell or rsyncd connection,
681 * and call the appropriate connection function, then run_client.
683 * Calls either start_socket_client (for sockets) or do_cmd and
684 * client_run (for ssh).
686 static int start_client(int argc, char *argv[])
689 char *shell_machine = NULL;
690 char *shell_path = NULL;
691 char *shell_user = NULL;
695 extern int local_server;
696 extern char *shell_cmd;
697 extern int rsync_port;
698 extern int daemon_over_rsh;
699 extern int read_batch;
702 /* Don't clobber argv[] so that ps(1) can still show the right
704 if ((rc = copy_argv(argv)))
707 /* rsync:// always uses rsync server over direct socket connection */
708 if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) {
711 host = argv[0] + strlen(URL_PREFIX);
712 p = strchr(host,'/');
719 p = strchr(host,':');
721 rsync_port = atoi(p+1);
724 return start_socket_client(host, path, argc-1, argv+1);
728 p = find_colon(argv[0]);
730 if (p[1] == ':') { /* double colon */
733 return start_socket_client(argv[0], p+2,
742 exit_cleanup(RERR_SYNTAX);
747 shell_machine = argv[0];
754 /* rsync:// destination uses rsync server over direct socket */
755 if (strncasecmp(URL_PREFIX, argv[argc-1], strlen(URL_PREFIX)) == 0) {
758 host = argv[argc-1] + strlen(URL_PREFIX);
759 p = strchr(host,'/');
766 p = strchr(host,':');
768 rsync_port = atoi(p+1);
771 return start_socket_client(host, path, argc-1, argv);
774 p = find_colon(argv[argc-1]);
777 } else if (p[1] == ':') { /* double colon */
780 return start_socket_client(argv[argc-1], p+2,
789 exit_cleanup(RERR_SYNTAX);
793 shell_machine = NULL;
794 shell_path = argv[argc-1];
797 shell_machine = argv[argc-1];
805 shell_path = argv[argc-1];
809 p = strchr(shell_machine,'@');
812 shell_user = shell_machine;
818 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
819 shell_cmd?shell_cmd:"",
820 shell_machine?shell_machine:"",
821 shell_user?shell_user:"",
822 shell_path?shell_path:"");
825 if (!am_sender && argc > 1) {
827 exit_cleanup(RERR_SYNTAX);
830 if (argc == 0 && !am_sender) {
831 extern int list_only;
835 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
838 /* if we're running an rsync server on the remote host over a
839 remote shell command, we need to do the RSYNCD protocol first */
840 if (daemon_over_rsh) {
842 tmpret = start_inband_exchange(shell_user, shell_path,
848 ret = client_run(f_in, f_out, pid, argc, argv);
857 static RETSIGTYPE sigusr1_handler(int UNUSED(val)) {
858 exit_cleanup(RERR_SIGNAL);
861 static RETSIGTYPE sigusr2_handler(int UNUSED(val)) {
862 extern int log_got_error;
863 if (log_got_error) _exit(RERR_PARTIAL);
867 static RETSIGTYPE sigchld_handler(int UNUSED(val)) {
871 /* An empty waitpid() loop was put here by Tridge and we could never
872 * get him to explain why he put it in, so rather than taking it
873 * out we're instead saving the child exit statuses for later use.
874 * The waitpid() loop presumably eliminates all possibility of leaving
875 * zombie children, maybe that's why he did it.
877 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
878 /* save the child's exit status */
879 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
880 if (pid_stat_table[cnt].pid == 0) {
881 pid_stat_table[cnt].pid = pid;
882 pid_stat_table[cnt].status = status;
892 * This routine catches signals and tries to send them to gdb.
894 * Because it's called from inside a signal handler it ought not to
895 * use too many library routines.
897 * @todo Perhaps use "screen -X" instead/as well, to help people
898 * debugging without easy access to X. Perhaps use an environment
899 * variable, or just call a script?
901 * @todo The /proc/ magic probably only works on Linux (and
902 * Solaris?) Can we be more portable?
904 #ifdef MAINTAINER_MODE
905 const char *get_panic_action(void)
907 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
912 return "xterm -display :0 -T Panic -n Panic "
913 "-e gdb /proc/%d/exe %d";
918 * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
920 * This signal handler is only installed if we were configured with
921 * --enable-maintainer-mode. Perhaps it should always be on and we
922 * should just look at the environment variable, but I'm a bit leery
923 * of a signal sending us into a busy loop.
925 static RETSIGTYPE rsync_panic_handler(int UNUSED(whatsig))
930 sprintf(cmd_buf, get_panic_action(),
933 /* Unless we failed to execute gdb, we allow the process to
934 * continue. I'm not sure if that's right. */
935 ret = system(cmd_buf);
942 int main(int argc,char *argv[])
945 extern int orig_umask;
948 extern int write_batch;
955 signal(SIGUSR1, sigusr1_handler);
956 signal(SIGUSR2, sigusr2_handler);
957 signal(SIGCHLD, sigchld_handler);
958 #ifdef MAINTAINER_MODE
959 signal(SIGSEGV, rsync_panic_handler);
960 signal(SIGFPE, rsync_panic_handler);
961 signal(SIGABRT, rsync_panic_handler);
962 signal(SIGBUS, rsync_panic_handler);
963 #endif /* def MAINTAINER_MODE */
965 starttime = time(NULL);
966 am_root = (getuid() == 0);
968 memset(&stats, 0, sizeof(stats));
972 exit_cleanup(RERR_SYNTAX);
975 /* we set a 0 umask so that correct file permissions can be
977 orig_umask = (int)umask(0);
979 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
980 /* FIXME: We ought to call the same error-handling
981 * code here, rather than relying on getopt. */
983 exit_cleanup(RERR_SYNTAX);
986 signal(SIGINT,SIGNAL_CAST sig_int);
987 signal(SIGHUP,SIGNAL_CAST sig_int);
988 signal(SIGTERM,SIGNAL_CAST sig_int);
990 /* Ignore SIGPIPE; we consistently check error codes and will
992 signal(SIGPIPE, SIG_IGN);
994 /* Initialize push_dir here because on some old systems getcwd
995 (implemented by forking "pwd" and reading its output) doesn't
996 work when there are other child processes. Also, on all systems
997 that implement getcwd that way "pwd" can't be found after chroot. */
1000 if (write_batch && !am_server) {
1001 write_batch_argvs_file(orig_argc, orig_argv);
1004 if (am_daemon && !am_server)
1005 return daemon_main();
1009 exit_cleanup(RERR_SYNTAX);
1013 verbose = MAX(verbose,1);
1015 #ifndef SUPPORT_LINKS
1016 if (!am_server && preserve_links) {
1017 rprintf(FERROR,"ERROR: symbolic links not supported\n");
1018 exit_cleanup(RERR_UNSUPPORTED);
1023 set_nonblocking(STDIN_FILENO);
1024 set_nonblocking(STDOUT_FILENO);
1026 return start_daemon(STDIN_FILENO, STDOUT_FILENO);
1027 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
1030 ret = start_client(argc, argv);
1032 exit_cleanup(RERR_STARTCLIENT);