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 /* rsync:// destination uses rsync server over direct socket */
729 if (strncasecmp(URL_PREFIX, argv[argc-1], strlen(URL_PREFIX)) == 0) {
732 host = argv[argc-1] + strlen(URL_PREFIX);
733 p = strchr(host,'/');
740 p = strchr(host,':');
742 rsync_port = atoi(p+1);
745 return start_socket_client(host, path, argc-1, argv);
748 p = find_colon(argv[argc-1]);
751 } else if (p[1] == ':') { /* double colon */
754 return start_socket_client(argv[argc-1], p+2,
763 exit_cleanup(RERR_SYNTAX);
767 shell_machine = NULL;
768 shell_path = argv[argc-1];
771 shell_machine = argv[argc-1];
779 shell_path = argv[argc-1];
783 p = strchr(shell_machine,'@');
786 shell_user = shell_machine;
792 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
793 shell_cmd?shell_cmd:"",
794 shell_machine?shell_machine:"",
795 shell_user?shell_user:"",
796 shell_path?shell_path:"");
799 if (!am_sender && argc > 1) {
801 exit_cleanup(RERR_SYNTAX);
804 if (argc == 0 && !am_sender) {
805 extern int list_only;
809 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
812 /* if we're running an rsync server on the remote host over a
813 remote shell command, we need to do the RSYNCD protocol first */
814 if (daemon_over_rsh) {
816 tmpret = start_inband_exchange(shell_user, shell_path,
822 ret = client_run(f_in, f_out, pid, argc, argv);
831 static RETSIGTYPE sigusr1_handler(int UNUSED(val)) {
832 exit_cleanup(RERR_SIGNAL);
835 static RETSIGTYPE sigusr2_handler(int UNUSED(val)) {
836 extern int log_got_error;
837 if (log_got_error) _exit(RERR_PARTIAL);
841 static RETSIGTYPE sigchld_handler(int UNUSED(val)) {
843 while (waitpid(-1, NULL, WNOHANG) > 0) ;
849 * This routine catches signals and tries to send them to gdb.
851 * Because it's called from inside a signal handler it ought not to
852 * use too many library routines.
854 * @todo Perhaps use "screen -X" instead/as well, to help people
855 * debugging without easy access to X. Perhaps use an environment
856 * variable, or just call a script?
858 * @todo The /proc/ magic probably only works on Linux (and
859 * Solaris?) Can we be more portable?
861 #ifdef MAINTAINER_MODE
862 const char *get_panic_action(void)
864 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
869 return "xterm -display :0 -T Panic -n Panic "
870 "-e gdb /proc/%d/exe %d";
875 * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
877 * This signal handler is only installed if we were configured with
878 * --enable-maintainer-mode. Perhaps it should always be on and we
879 * should just look at the environment variable, but I'm a bit leery
880 * of a signal sending us into a busy loop.
882 static RETSIGTYPE rsync_panic_handler(int UNUSED(whatsig))
887 sprintf(cmd_buf, get_panic_action(),
890 /* Unless we failed to execute gdb, we allow the process to
891 * continue. I'm not sure if that's right. */
892 ret = system(cmd_buf);
899 int main(int argc,char *argv[])
902 extern int orig_umask;
904 extern int am_daemon;
905 extern int am_server;
907 extern int write_batch;
914 signal(SIGUSR1, sigusr1_handler);
915 signal(SIGUSR2, sigusr2_handler);
916 signal(SIGCHLD, sigchld_handler);
917 #ifdef MAINTAINER_MODE
918 signal(SIGSEGV, rsync_panic_handler);
919 signal(SIGFPE, rsync_panic_handler);
920 signal(SIGABRT, rsync_panic_handler);
921 signal(SIGBUS, rsync_panic_handler);
922 #endif /* def MAINTAINER_MODE */
924 starttime = time(NULL);
925 am_root = (getuid() == 0);
927 memset(&stats, 0, sizeof(stats));
931 exit_cleanup(RERR_SYNTAX);
934 /* we set a 0 umask so that correct file permissions can be
936 orig_umask = (int)umask(0);
938 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
939 /* FIXME: We ought to call the same error-handling
940 * code here, rather than relying on getopt. */
942 exit_cleanup(RERR_SYNTAX);
945 signal(SIGINT,SIGNAL_CAST sig_int);
946 signal(SIGHUP,SIGNAL_CAST sig_int);
947 signal(SIGTERM,SIGNAL_CAST sig_int);
949 /* Ignore SIGPIPE; we consistently check error codes and will
951 signal(SIGPIPE, SIG_IGN);
953 /* Initialize push_dir here because on some old systems getcwd
954 (implemented by forking "pwd" and reading its output) doesn't
955 work when there are other child processes. Also, on all systems
956 that implement getcwd that way "pwd" can't be found after chroot. */
959 if (write_batch && !am_server) {
960 write_batch_argvs_file(orig_argc, orig_argv);
963 if (am_daemon && !am_server)
964 return daemon_main();
968 exit_cleanup(RERR_SYNTAX);
972 verbose = MAX(verbose,1);
974 #ifndef SUPPORT_LINKS
975 if (!am_server && preserve_links) {
976 rprintf(FERROR,"ERROR: symbolic links not supported\n");
977 exit_cleanup(RERR_UNSUPPORTED);
982 set_nonblocking(STDIN_FILENO);
983 set_nonblocking(STDOUT_FILENO);
985 return start_daemon(STDIN_FILENO, STDOUT_FILENO);
986 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
989 ret = start_client(argc, argv);
991 exit_cleanup(RERR_STARTCLIENT);