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.
30 static void show_malloc_stats(void);
32 /****************************************************************************
33 wait for a process to exit, calling io_flush while waiting
34 ****************************************************************************/
35 void wait_process(pid_t pid, int *status)
37 while (waitpid(pid, status, WNOHANG) == 0) {
42 /* TODO: If the child exited on a signal, then log an
43 * appropriate error message. Perhaps we should also accept a
44 * message describing the purpose of the child. Also indicate
45 * this to the caller so that thhey know something went
47 *status = WEXITSTATUS(*status);
50 static void report(int f)
52 time_t t = time(NULL);
57 extern int remote_version;
61 /* These come out from every process */
67 log_exit(0, __FILE__, __LINE__);
68 if (f == -1 || !am_sender) return;
71 send_stats = verbose || (remote_version >= 20);
73 if (am_sender && send_stats) {
75 /* store total_written in a temporary
76 because write_longint changes it */
77 w = stats.total_written;
78 write_longint(f,stats.total_read);
80 write_longint(f,stats.total_size);
85 /* this is the client */
87 if (!am_sender && send_stats) {
89 stats.total_written = read_longint(f);
90 /* store total_read in a temporary, read_longint changes it */
92 stats.total_size = read_longint(f);
97 if (!am_sender && !send_stats) {
98 /* missing the bytes written by the generator */
99 rprintf(FINFO, "\nCannot show stats as receiver because remote protocol version is less than 20\n");
100 rprintf(FINFO, "Use --stats -v to show stats\n");
103 rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
104 rprintf(FINFO,"Number of files transferred: %d\n",
105 stats.num_transferred_files);
106 rprintf(FINFO,"Total file size: %.0f bytes\n",
107 (double)stats.total_size);
108 rprintf(FINFO,"Total transferred file size: %.0f bytes\n",
109 (double)stats.total_transferred_size);
110 rprintf(FINFO,"Literal data: %.0f bytes\n",
111 (double)stats.literal_data);
112 rprintf(FINFO,"Matched data: %.0f bytes\n",
113 (double)stats.matched_data);
114 rprintf(FINFO,"File list size: %d\n", stats.flist_size);
115 rprintf(FINFO,"Total bytes written: %.0f\n",
116 (double)stats.total_written);
117 rprintf(FINFO,"Total bytes read: %.0f\n\n",
118 (double)stats.total_read);
121 if (verbose || do_stats) {
122 rprintf(FINFO,"wrote %.0f bytes read %.0f bytes %.2f bytes/sec\n",
123 (double)stats.total_written,
124 (double)stats.total_read,
125 (stats.total_written+stats.total_read)/(0.5 + (t-starttime)));
126 rprintf(FINFO,"total size is %.0f speedup is %.2f\n",
127 (double)stats.total_size,
128 (1.0*stats.total_size)/(stats.total_written+stats.total_read));
137 * If our C library can get malloc statistics, then show them to FINFO
139 static void show_malloc_stats(void)
143 extern int am_server;
144 extern int am_sender;
145 extern int am_daemon;
149 rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
151 am_server ? "server " : "",
152 am_daemon ? "daemon " : "",
153 am_sender ? "sender" : "receiver");
154 rprintf(FINFO, " arena: %10d (bytes from sbrk)\n", mi.arena);
155 rprintf(FINFO, " ordblks: %10d (chunks not in use)\n", mi.ordblks);
156 rprintf(FINFO, " smblks: %10d\n", mi.smblks);
157 rprintf(FINFO, " hblks: %10d (chunks from mmap)\n", mi.hblks);
158 rprintf(FINFO, " hblkhd: %10d (bytes from mmap)\n", mi.hblkhd);
159 rprintf(FINFO, " usmblks: %10d\n", mi.usmblks);
160 rprintf(FINFO, " fsmblks: %10d\n", mi.fsmblks);
161 rprintf(FINFO, " uordblks: %10d (bytes used)\n", mi.uordblks);
162 rprintf(FINFO, " fordblks: %10d (bytes free)\n", mi.fordblks);
163 rprintf(FINFO, " keepcost: %10d (bytes in releasable chunk)\n", mi.keepcost);
164 #endif /* HAVE_MALLINFO */
168 /* Start the remote shell. cmd may be NULL to use the default. */
169 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 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);
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 void child_main(int argc, char *argv[])
498 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 whole_file;
671 extern int write_batch;
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 if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) {
683 host = argv[0] + strlen(URL_PREFIX);
684 p = strchr(host,'/');
691 p = strchr(host,':');
693 rsync_port = atoi(p+1);
696 return start_socket_client(host, path, argc-1, argv+1);
700 p = find_colon(argv[0]);
703 if (p[1] == ':') { /* double colon */
705 return start_socket_client(argv[0], p+2, argc-1, argv+1);
710 exit_cleanup(RERR_SYNTAX);
715 shell_machine = argv[0];
722 p = find_colon(argv[argc-1]);
725 } else if (p[1] == ':') {
727 return start_socket_client(argv[argc-1], p+2, argc-1, argv);
732 exit_cleanup(RERR_SYNTAX);
736 shell_machine = NULL;
737 shell_path = argv[argc-1];
740 shell_machine = argv[argc-1];
748 shell_path = argv[argc-1];
752 p = strchr(shell_machine,'@');
755 shell_user = shell_machine;
761 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
762 shell_cmd?shell_cmd:"",
763 shell_machine?shell_machine:"",
764 shell_user?shell_user:"",
765 shell_path?shell_path:"");
768 if (!am_sender && argc > 1) {
770 exit_cleanup(RERR_SYNTAX);
773 if (argc == 0 && !am_sender) {
774 extern int list_only;
778 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out);
780 ret = client_run(f_in, f_out, pid, argc, argv);
789 static RETSIGTYPE sigusr1_handler(int UNUSED(val)) {
790 exit_cleanup(RERR_SIGNAL);
793 static RETSIGTYPE sigusr2_handler(int UNUSED(val)) {
794 extern int log_got_error;
795 if (log_got_error) _exit(RERR_PARTIAL);
799 static RETSIGTYPE sigchld_handler(int UNUSED(val)) {
801 while (waitpid(-1, NULL, WNOHANG) > 0) ;
807 * This routine catches signals and tries to send them to gdb.
809 * Because it's called from inside a signal handler it ought not to
810 * use too many library routines.
812 * @todo Perhaps use "screen -X" instead/as well, to help people
813 * debugging without easy access to X. Perhaps use an environment
814 * variable, or just call a script?
816 * @todo The /proc/ magic probably only works on Linux (and
817 * Solaris?) Can we be more portable?
819 #ifdef MAINTAINER_MODE
820 static RETSIGTYPE rsync_panic_handler(int UNUSED(whatsig))
825 "xterm -display :0 -T Panic -n Panic "
826 "-e gdb /proc/%d/exe %d",
829 /* Unless we failed to execute gdb, we allow the process to
830 * continue. I'm not sure if that's right. */
831 ret = system(cmd_buf);
838 int main(int argc,char *argv[])
841 extern int orig_umask;
843 extern int am_daemon;
844 extern int am_server;
846 extern int write_batch;
853 signal(SIGUSR1, sigusr1_handler);
854 signal(SIGUSR2, sigusr2_handler);
855 signal(SIGCHLD, sigchld_handler);
856 #ifdef MAINTAINER_MODE
857 signal(SIGSEGV, rsync_panic_handler);
858 signal(SIGFPE, rsync_panic_handler);
859 signal(SIGABRT, rsync_panic_handler);
860 signal(SIGBUS, rsync_panic_handler);
861 #endif /* def MAINTAINER_MODE */
863 starttime = time(NULL);
864 am_root = (getuid() == 0);
866 memset(&stats, 0, sizeof(stats));
870 exit_cleanup(RERR_SYNTAX);
873 /* we set a 0 umask so that correct file permissions can be
875 orig_umask = (int)umask(0);
877 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
878 /* FIXME: We ought to call the same error-handling
879 * code here, rather than relying on getopt. */
881 exit_cleanup(RERR_SYNTAX);
884 signal(SIGINT,SIGNAL_CAST sig_int);
885 signal(SIGHUP,SIGNAL_CAST sig_int);
886 signal(SIGTERM,SIGNAL_CAST sig_int);
888 /* Ignore SIGPIPE; we consistently check error codes and will
890 signal(SIGPIPE, SIG_IGN);
892 /* Initialize push_dir here because on some old systems getcwd
893 (implemented by forking "pwd" and reading its output) doesn't
894 work when there are other child processes. Also, on all systems
895 that implement getcwd that way "pwd" can't be found after chroot. */
898 if (write_batch && !am_server) {
899 write_batch_argvs_file(orig_argc, orig_argv);
903 return daemon_main();
908 exit_cleanup(RERR_SYNTAX);
912 verbose = MAX(verbose,1);
914 #ifndef SUPPORT_LINKS
915 if (!am_server && preserve_links) {
916 rprintf(FERROR,"ERROR: symbolic links not supported\n");
917 exit_cleanup(RERR_UNSUPPORTED);
922 set_nonblocking(STDIN_FILENO);
923 set_nonblocking(STDOUT_FILENO);
924 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
927 ret = start_client(argc, argv);
929 exit_cleanup(RERR_STARTCLIENT);