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 read_batch;
179 if (!read_batch && !local_server) {
181 cmd = getenv(RSYNC_RSH_ENV);
188 for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
193 /* remsh (on HPUX) takes the arguments the other way around */
194 args[argc++] = machine;
204 args[argc++] = machine;
207 args[argc++] = rsync_path;
209 if ((blocking_io == -1) && (strcmp(cmd, RSYNC_RSH) == 0))
212 server_options(args,&argc);
224 rprintf(FINFO,"cmd=");
226 rprintf(FINFO,"%s ",args[i]);
232 create_flist_from_batch(); /* sets batch_flist */
233 ret = local_child(argc, args, f_in, f_out, child_main);
235 ret = piped_child(args,f_in,f_out);
243 out_of_memory("do_cmd");
244 return 0; /* not reached */
250 static char *get_local_name(struct file_list *flist,char *name)
253 extern int orig_umask;
256 rprintf(FINFO,"get_local_name count=%d %s\n",
257 flist->count, NS(name));
262 if (do_stat(name,&st) == 0) {
263 if (S_ISDIR(st.st_mode)) {
264 if (!push_dir(name, 0)) {
265 rprintf(FERROR,"push_dir %s : %s (1)\n",
266 name,strerror(errno));
267 exit_cleanup(RERR_FILESELECT);
271 if (flist->count > 1) {
272 rprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
273 exit_cleanup(RERR_FILESELECT);
278 if (flist->count <= 1)
281 if (do_mkdir(name,0777 & ~orig_umask) != 0) {
282 rprintf(FERROR, RSYNC_NAME ": mkdir %s: %s\n",
283 name, strerror(errno));
284 exit_cleanup(RERR_FILEIO);
287 rprintf(FINFO,"created directory %s\n",name);
290 if (!push_dir(name, 0)) {
291 rprintf(FERROR, RSYNC_NAME ": push_dir %s: %s\n",
292 name, strerror(errno));
293 exit_cleanup(RERR_FILESELECT);
302 static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
305 struct file_list *flist;
307 extern int relative_paths;
309 extern int remote_version;
312 rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
314 if (!relative_paths && !push_dir(dir, 0)) {
315 rprintf(FERROR,"push_dir %s: %s (3)\n",dir,strerror(errno));
316 exit_cleanup(RERR_FILESELECT);
321 if (strcmp(dir,".")) {
323 if (strcmp(dir,"/") == 0)
329 if (argc == 0 && recurse) {
335 flist = send_file_list(f_out,argc,argv);
336 if (!flist || flist->count == 0) {
340 send_files(flist,f_out,f_in);
343 if (remote_version >= 24) {
344 /* final goodbye message */
352 static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
358 extern int preserve_hard_links;
359 extern int delete_after;
361 extern int delete_mode;
362 extern int remote_version;
364 if (preserve_hard_links)
365 init_hard_links(flist);
368 /* I moved this here from recv_files() to prevent a race condition */
369 if (recurse && delete_mode && !local_name && flist->count>0) {
374 if (fd_pair(recv_pipe) < 0) {
375 rprintf(FERROR,"pipe failed in do_recv\n");
376 exit_cleanup(RERR_SOCKETIO);
379 if (fd_pair(error_pipe) < 0) {
380 rprintf(FERROR,"error pipe failed in do_recv\n");
381 exit_cleanup(RERR_SOCKETIO);
386 if ((pid=do_fork()) == 0) {
388 close(error_pipe[0]);
389 if (f_in != f_out) close(f_out);
391 /* we can't let two processes write to the socket at one time */
392 io_multiplexing_close();
394 /* set place to send errors */
395 set_error_fd(error_pipe[1]);
397 recv_files(f_in,flist,local_name,recv_pipe[1]);
401 write_int(recv_pipe[1],1);
404 /* finally we go to sleep until our parent kills us
405 with a USR2 signal. We sleep for a short time as on
406 some OSes a signal won't interrupt a sleep! */
412 close(error_pipe[1]);
413 if (f_in != f_out) close(f_in);
415 io_start_buffering(f_out);
417 io_set_error_fd(error_pipe[0]);
419 generate_files(f_out,flist,local_name,recv_pipe[0]);
421 read_int(recv_pipe[0]);
423 if (remote_version >= 24) {
424 /* send a final goodbye message */
425 write_int(f_out, -1);
430 wait_process(pid, &status);
435 static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
438 struct file_list *flist;
439 char *local_name=NULL;
441 extern int delete_mode;
442 extern int delete_excluded;
443 extern int am_daemon;
444 extern int module_id;
445 extern int am_sender;
446 extern int read_batch;
447 extern struct file_list *batch_flist;
450 rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
452 if (am_daemon && lp_read_only(module_id) && !am_sender) {
453 rprintf(FERROR,"ERROR: module is read only\n");
454 exit_cleanup(RERR_SYNTAX);
463 if (!am_daemon && !push_dir(dir, 0)) {
464 rprintf(FERROR,"push_dir %s : %s (4)\n",
465 dir,strerror(errno));
466 exit_cleanup(RERR_FILESELECT);
470 if (delete_mode && !delete_excluded)
471 recv_exclude_list(f_in);
476 flist = recv_file_list(f_in);
478 rprintf(FERROR,"server_recv: recv_file_list error\n");
479 exit_cleanup(RERR_FILESELECT);
483 if (strcmp(dir,".")) {
484 argv[0] += strlen(dir);
485 if (argv[0][0] == '/') argv[0]++;
487 local_name = get_local_name(flist,argv[0]);
490 status = do_recv(f_in,f_out,flist,local_name);
491 exit_cleanup(status);
495 int child_main(int argc, char *argv[])
497 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
502 void start_server(int f_in, int f_out, int argc, char *argv[])
504 extern int cvs_exclude;
505 extern int am_sender;
506 extern int remote_version;
507 extern int read_batch;
509 setup_protocol(f_out, f_in);
511 set_nonblocking(f_in);
512 set_nonblocking(f_out);
514 if (remote_version >= 23)
515 io_start_multiplex_out(f_out);
519 recv_exclude_list(f_in);
523 do_server_sender(f_in, f_out, argc, argv);
525 do_server_recv(f_in, f_out, argc, argv);
532 * This is called once the connection has been negotiated. It is used
533 * for rsyncd, remote-shell, and local connections.
535 int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
537 struct file_list *flist = NULL;
538 int status = 0, status2 = 0;
539 char *local_name = NULL;
540 extern int am_sender;
541 extern int remote_version;
542 extern pid_t cleanup_child_pid;
543 extern int write_batch;
544 extern int read_batch;
545 extern struct file_list *batch_flist;
547 cleanup_child_pid = pid;
551 set_nonblocking(f_in);
552 set_nonblocking(f_out);
554 setup_protocol(f_out,f_in);
556 if (remote_version >= 23)
557 io_start_multiplex_in(f_in);
560 extern int cvs_exclude;
561 extern int delete_mode;
562 extern int delete_excluded;
565 if (delete_mode && !delete_excluded)
566 send_exclude_list(f_out);
567 if (!read_batch) /* dw -- don't write to pipe */
568 flist = send_file_list(f_out,argc,argv);
570 rprintf(FINFO,"file list sent\n");
572 send_files(flist,f_out,f_in);
573 if (remote_version >= 24) {
574 /* final goodbye message */
579 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
581 wait_process(pid, &status);
584 exit_cleanup(status);
588 extern int list_only;
593 send_exclude_list(f_out);
595 flist = recv_file_list(f_in);
596 if (!flist || flist->count == 0) {
597 rprintf(FINFO, "client: nothing to do: "
598 "perhaps you need to specify some filenames or "
599 "the --recursive option?\n");
603 local_name = get_local_name(flist,argv[0]);
605 status2 = do_recv(f_in,f_out,flist,local_name);
609 rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
611 wait_process(pid, &status);
614 return MAX(status, status2);
617 static char *find_colon(char *s)
624 /* now check to see if there is a / in the string before the : - if there is then
625 discard the colon on the assumption that the : is part of a filename */
627 if (p2 && p2 < p) return NULL;
633 static int copy_argv (char *argv[])
637 for (i = 0; argv[i]; i++) {
638 if (!(argv[i] = strdup(argv[i]))) {
639 rprintf (FERROR, "out of memory at %s(%d)\n",
650 * Start a client for either type of remote connection. Work out
651 * whether the arguments request a remote shell or rsyncd connection,
652 * and call the appropriate connection function, then run_client.
654 * Calls either start_socket_client (for sockets) or do_cmd and
655 * client_run (for ssh).
657 static int start_client(int argc, char *argv[])
660 char *shell_machine = NULL;
661 char *shell_path = NULL;
662 char *shell_user = NULL;
666 extern int local_server;
667 extern int am_sender;
668 extern char *shell_cmd;
669 extern int rsync_port;
670 extern int read_batch;
673 /* Don't clobber argv[] so that ps(1) can still show the right
675 if ((rc = copy_argv (argv)))
678 if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) {
681 host = argv[0] + strlen(URL_PREFIX);
682 p = strchr(host,'/');
689 p = strchr(host,':');
691 rsync_port = atoi(p+1);
694 return start_socket_client(host, path, argc-1, argv+1);
698 p = find_colon(argv[0]);
701 if (p[1] == ':') { /* double colon */
703 return start_socket_client(argv[0], p+2, argc-1, argv+1);
708 exit_cleanup(RERR_SYNTAX);
713 shell_machine = argv[0];
720 p = find_colon(argv[argc-1]);
723 } else if (p[1] == ':') {
725 return start_socket_client(argv[argc-1], p+2, argc-1, argv);
730 exit_cleanup(RERR_SYNTAX);
734 shell_machine = NULL;
735 shell_path = argv[argc-1];
738 shell_machine = argv[argc-1];
746 shell_path = argv[argc-1];
750 p = strchr(shell_machine,'@');
753 shell_user = shell_machine;
759 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
760 shell_cmd?shell_cmd:"",
761 shell_machine?shell_machine:"",
762 shell_user?shell_user:"",
763 shell_path?shell_path:"");
766 if (!am_sender && argc > 1) {
768 exit_cleanup(RERR_SYNTAX);
771 if (argc == 0 && !am_sender) {
772 extern int list_only;
776 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out);
778 ret = client_run(f_in, f_out, pid, argc, argv);
787 static RETSIGTYPE sigusr1_handler(int UNUSED(val)) {
788 exit_cleanup(RERR_SIGNAL);
791 static RETSIGTYPE sigusr2_handler(int UNUSED(val)) {
792 extern int log_got_error;
793 if (log_got_error) _exit(RERR_PARTIAL);
797 static RETSIGTYPE sigchld_handler(int UNUSED(val)) {
799 while (waitpid(-1, NULL, WNOHANG) > 0) ;
805 * This routine catches signals and tries to send them to gdb.
807 * Because it's called from inside a signal handler it ought not to
808 * use too many library routines.
810 * @todo Perhaps use "screen -X" instead/as well, to help people
811 * debugging without easy access to X. Perhaps use an environment
812 * variable, or just call a script?
814 * @todo The /proc/ magic probably only works on Linux (and
815 * Solaris?) Can we be more portable?
817 #ifdef MAINTAINER_MODE
818 const char *get_panic_action(void)
820 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
825 return "xterm -display :0 -T Panic -n Panic "
826 "-e gdb /proc/%d/exe %d";
831 * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
833 * This signal handler is only installed if we were configured with
834 * --enable-maintainer-mode. Perhaps it should always be on and we
835 * should just look at the environment variable, but I'm a bit leery
836 * of a signal sending us into a busy loop.
838 static RETSIGTYPE rsync_panic_handler(int UNUSED(whatsig))
843 sprintf(cmd_buf, get_panic_action(),
846 /* Unless we failed to execute gdb, we allow the process to
847 * continue. I'm not sure if that's right. */
848 ret = system(cmd_buf);
855 int main(int argc,char *argv[])
858 extern int orig_umask;
860 extern int am_daemon;
861 extern int am_server;
863 extern int write_batch;
870 signal(SIGUSR1, sigusr1_handler);
871 signal(SIGUSR2, sigusr2_handler);
872 signal(SIGCHLD, sigchld_handler);
873 #ifdef MAINTAINER_MODE
874 signal(SIGSEGV, rsync_panic_handler);
875 signal(SIGFPE, rsync_panic_handler);
876 signal(SIGABRT, rsync_panic_handler);
877 signal(SIGBUS, rsync_panic_handler);
878 #endif /* def MAINTAINER_MODE */
880 starttime = time(NULL);
881 am_root = (getuid() == 0);
883 memset(&stats, 0, sizeof(stats));
887 exit_cleanup(RERR_SYNTAX);
890 /* we set a 0 umask so that correct file permissions can be
892 orig_umask = (int)umask(0);
894 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
895 /* FIXME: We ought to call the same error-handling
896 * code here, rather than relying on getopt. */
898 exit_cleanup(RERR_SYNTAX);
901 signal(SIGINT,SIGNAL_CAST sig_int);
902 signal(SIGHUP,SIGNAL_CAST sig_int);
903 signal(SIGTERM,SIGNAL_CAST sig_int);
905 /* Ignore SIGPIPE; we consistently check error codes and will
907 signal(SIGPIPE, SIG_IGN);
909 /* Initialize push_dir here because on some old systems getcwd
910 (implemented by forking "pwd" and reading its output) doesn't
911 work when there are other child processes. Also, on all systems
912 that implement getcwd that way "pwd" can't be found after chroot. */
915 if (write_batch && !am_server) {
916 write_batch_argvs_file(orig_argc, orig_argv);
920 return daemon_main();
925 exit_cleanup(RERR_SYNTAX);
929 verbose = MAX(verbose,1);
931 #ifndef SUPPORT_LINKS
932 if (!am_server && preserve_links) {
933 rprintf(FERROR,"ERROR: symbolic links not supported\n");
934 exit_cleanup(RERR_UNSUPPORTED);
939 set_nonblocking(STDIN_FILENO);
940 set_nonblocking(STDOUT_FILENO);
941 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
944 ret = start_client(argc, argv);
946 exit_cleanup(RERR_STARTCLIENT);