Improved the default-blocking-I/O code to discern rsh from ssh
[rsync/rsync.git] / main.c
1 /* -*- c-file-style: "linux" -*-
2
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>
6
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.
11
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.
16
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.
20 */
21
22 #include "rsync.h"
23
24 time_t starttime = 0;
25
26 extern struct stats stats;
27 extern char *files_from;
28 extern int filesfrom_fd;
29 extern char *remote_filesfrom_file;
30 extern int am_server;
31 extern int am_sender;
32 extern int am_daemon;
33 extern int verbose;
34 extern int protocol_version;
35
36 /* there's probably never more than at most 2 outstanding child processes,
37  * but set it higher just in case.
38  */
39 #define MAXCHILDPROCS 5
40
41 struct pid_status {
42         pid_t pid;
43         int   status;
44 } pid_stat_table[MAXCHILDPROCS];
45
46 static void show_malloc_stats(void);
47
48 /****************************************************************************
49 wait for a process to exit, calling io_flush while waiting
50 ****************************************************************************/
51 void wait_process(pid_t pid, int *status)
52 {
53         pid_t waited_pid;
54         int cnt;
55
56         while ((waited_pid = waitpid(pid, status, WNOHANG)) == 0) {
57                 msleep(20);
58                 io_flush();
59         }
60
61         if ((waited_pid == -1) && (errno == ECHILD)) {
62                 /* status of requested child no longer available.
63                  * check to see if it was processed by the sigchld_handler.
64                  */
65                 for (cnt = 0;  cnt < MAXCHILDPROCS; cnt++) {
66                         if (pid == pid_stat_table[cnt].pid) {
67                                 *status = pid_stat_table[cnt].status;
68                                 pid_stat_table[cnt].pid = 0;
69                                 break;
70                         }
71                 }
72         }
73
74         /* TODO: If the child exited on a signal, then log an
75          * appropriate error message.  Perhaps we should also accept a
76          * message describing the purpose of the child.  Also indicate
77          * this to the caller so that thhey know something went
78          * wrong.  */
79         *status = WEXITSTATUS(*status);
80 }
81
82 static void report(int f)
83 {
84         time_t t = time(NULL);
85         extern int do_stats;
86         int send_stats;
87
88         if (do_stats && verbose > 1) {
89                 /* These come out from every process */
90                 show_malloc_stats();
91                 show_flist_stats();
92         }
93
94         if (am_daemon) {
95                 log_exit(0, __FILE__, __LINE__);
96                 if (f == -1 || !am_sender) return;
97         }
98
99         send_stats = verbose || protocol_version >= 20;
100         if (am_server) {
101                 if (am_sender && send_stats) {
102                         int64 w;
103                         /* store total_written in a temporary
104                          * because write_longint changes it */
105                         w = stats.total_written;
106                         write_longint(f,stats.total_read);
107                         write_longint(f,w);
108                         write_longint(f,stats.total_size);
109                 }
110                 return;
111         }
112
113         /* this is the client */
114
115         if (!am_sender && send_stats) {
116                 int64 r;
117                 stats.total_written = read_longint(f);
118                 /* store total_read in a temporary, read_longint changes it */
119                 r = read_longint(f);
120                 stats.total_size = read_longint(f);
121                 stats.total_read = r;
122         }
123
124         if (do_stats) {
125                 if (!am_sender && !send_stats) {
126                         /* missing the bytes written by the generator */
127                         rprintf(FINFO, "\nCannot show stats as receiver because remote protocol version is less than 20\n");
128                         rprintf(FINFO, "Use --stats -v to show stats\n");
129                         return;
130                 }
131                 rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
132                 rprintf(FINFO,"Number of files transferred: %d\n",
133                         stats.num_transferred_files);
134                 rprintf(FINFO,"Total file size: %.0f bytes\n",
135                         (double)stats.total_size);
136                 rprintf(FINFO,"Total transferred file size: %.0f bytes\n",
137                         (double)stats.total_transferred_size);
138                 rprintf(FINFO,"Literal data: %.0f bytes\n",
139                         (double)stats.literal_data);
140                 rprintf(FINFO,"Matched data: %.0f bytes\n",
141                         (double)stats.matched_data);
142                 rprintf(FINFO,"File list size: %d\n", stats.flist_size);
143                 rprintf(FINFO,"Total bytes written: %.0f\n",
144                         (double)stats.total_written);
145                 rprintf(FINFO,"Total bytes read: %.0f\n",
146                         (double)stats.total_read);
147         }
148
149         if (verbose || do_stats) {
150                 rprintf(FINFO,"\nwrote %.0f bytes  read %.0f bytes  %.2f bytes/sec\n",
151                         (double)stats.total_written,
152                         (double)stats.total_read,
153                         (stats.total_written+stats.total_read)/(0.5 + (t-starttime)));
154                 rprintf(FINFO,"total size is %.0f  speedup is %.2f\n",
155                         (double)stats.total_size,
156                         (1.0*stats.total_size)/(stats.total_written+stats.total_read));
157         }
158
159         fflush(stdout);
160         fflush(stderr);
161 }
162
163
164 /**
165  * If our C library can get malloc statistics, then show them to FINFO
166  **/
167 static void show_malloc_stats(void)
168 {
169 #ifdef HAVE_MALLINFO
170         struct mallinfo mi;
171
172         mi = mallinfo();
173
174         rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
175                 getpid(),
176                 am_server ? "server " : "",
177                 am_daemon ? "daemon " : "",
178                 am_sender ? "sender" : "receiver");
179         rprintf(FINFO, "  arena:     %10d   (bytes from sbrk)\n", mi.arena);
180         rprintf(FINFO, "  ordblks:   %10d   (chunks not in use)\n", mi.ordblks);
181         rprintf(FINFO, "  smblks:    %10d\n", mi.smblks);
182         rprintf(FINFO, "  hblks:     %10d   (chunks from mmap)\n", mi.hblks);
183         rprintf(FINFO, "  hblkhd:    %10d   (bytes from mmap)\n", mi.hblkhd);
184         rprintf(FINFO, "  usmblks:   %10d\n", mi.usmblks);
185         rprintf(FINFO, "  fsmblks:   %10d\n", mi.fsmblks);
186         rprintf(FINFO, "  uordblks:  %10d   (bytes used)\n", mi.uordblks);
187         rprintf(FINFO, "  fordblks:  %10d   (bytes free)\n", mi.fordblks);
188         rprintf(FINFO, "  keepcost:  %10d   (bytes in releasable chunk)\n", mi.keepcost);
189 #endif /* HAVE_MALLINFO */
190 }
191
192
193 /* Start the remote shell.   cmd may be NULL to use the default. */
194 static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
195 {
196         char *args[100];
197         int i,argc=0;
198         pid_t ret;
199         char *tok,*dir=NULL;
200         int dash_l_set = 0;
201         extern int local_server;
202         extern char *rsync_path;
203         extern int blocking_io;
204         extern int daemon_over_rsh;
205         extern int read_batch;
206
207         if (!read_batch && !local_server) {
208                 if (!cmd)
209                         cmd = getenv(RSYNC_RSH_ENV);
210                 if (!cmd)
211                         cmd = RSYNC_RSH;
212                 cmd = strdup(cmd);
213                 if (!cmd)
214                         goto oom;
215
216                 for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
217                         args[argc++] = tok;
218                 }
219
220                 /* check to see if we've already been given '-l user' in
221                    the remote-shell command */
222                 for (i = 0; i < argc-1; i++) {
223                         if (!strcmp(args[i], "-l") && args[i+1][0] != '-')
224                                 dash_l_set = 1;
225                 }
226
227 #if HAVE_REMSH
228                 /* remsh (on HPUX) takes the arguments the other way around */
229                 args[argc++] = machine;
230                 if (user && !(daemon_over_rsh && dash_l_set)) {
231                         args[argc++] = "-l";
232                         args[argc++] = user;
233                 }
234 #else
235                 if (user && !(daemon_over_rsh && dash_l_set)) {
236                         args[argc++] = "-l";
237                         args[argc++] = user;
238                 }
239                 args[argc++] = machine;
240 #endif
241
242                 args[argc++] = rsync_path;
243
244                 if (blocking_io == -1) {
245                         char *cp = strrchr(cmd, '/');
246                         if (cp)
247                                 cp++;
248                         else
249                                 cp = cmd;
250                         if (strcmp(cp, "rsh") == 0 || strcmp(cp, "remsh") == 0)
251                                 blocking_io = 1;
252                 }
253
254                 server_options(args,&argc);
255
256         }
257
258         args[argc++] = ".";
259
260         if (!daemon_over_rsh && path && *path)
261                 args[argc++] = path;
262
263         args[argc] = NULL;
264
265         if (verbose > 3) {
266                 rprintf(FINFO,"cmd=");
267                 for (i=0;i<argc;i++)
268                         rprintf(FINFO,"%s ",args[i]);
269                 rprintf(FINFO,"\n");
270         }
271
272         if (local_server) {
273                 if (read_batch)
274                         create_flist_from_batch(); /* sets batch_flist */
275                 ret = local_child(argc, args, f_in, f_out, child_main);
276         } else {
277                 ret = piped_child(args,f_in,f_out);
278         }
279
280         if (dir) free(dir);
281
282         return ret;
283
284 oom:
285         out_of_memory("do_cmd");
286         return 0; /* not reached */
287 }
288
289
290
291
292 static char *get_local_name(struct file_list *flist,char *name)
293 {
294         STRUCT_STAT st;
295         int e;
296         extern int orig_umask;
297
298         if (verbose > 2)
299                 rprintf(FINFO,"get_local_name count=%d %s\n",
300                         flist->count, NS(name));
301
302         if (!name)
303                 return NULL;
304
305         if (do_stat(name,&st) == 0) {
306                 if (S_ISDIR(st.st_mode)) {
307                         if (!push_dir(name, 0)) {
308                                 rprintf(FERROR, "push_dir %s failed: %s (1)\n",
309                                         full_fname(name), strerror(errno));
310                                 exit_cleanup(RERR_FILESELECT);
311                         }
312                         return NULL;
313                 }
314                 if (flist->count > 1) {
315                         rprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
316                         exit_cleanup(RERR_FILESELECT);
317                 }
318                 return name;
319         }
320
321         if (flist->count <= 1 && ((e = strlen(name)) <= 1 || name[e-1] != '/'))
322                 return name;
323
324         if (do_mkdir(name,0777 & ~orig_umask) != 0) {
325                 rprintf(FERROR, "mkdir %s failed: %s\n",
326                         full_fname(name), strerror(errno));
327                 exit_cleanup(RERR_FILEIO);
328         } else {
329                 if (verbose > 0)
330                         rprintf(FINFO,"created directory %s\n",name);
331         }
332
333         if (!push_dir(name, 0)) {
334                 rprintf(FERROR, "push_dir %s failed: %s (2)\n",
335                         full_fname(name), strerror(errno));
336                 exit_cleanup(RERR_FILESELECT);
337         }
338
339         return NULL;
340 }
341
342
343
344
345 static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
346 {
347         int i;
348         struct file_list *flist;
349         char *dir = argv[0];
350         extern int relative_paths;
351         extern int recurse;
352
353         if (verbose > 2)
354                 rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
355
356         if (!relative_paths && !push_dir(dir, 0)) {
357                 rprintf(FERROR, "push_dir %s failed: %s (3)\n",
358                         full_fname(dir), strerror(errno));
359                 exit_cleanup(RERR_FILESELECT);
360         }
361         argc--;
362         argv++;
363
364         if (strcmp(dir,".")) {
365                 int l = strlen(dir);
366                 if (strcmp(dir,"/") == 0)
367                         l = 0;
368                 for (i=0;i<argc;i++)
369                         argv[i] += l+1;
370         }
371
372         if (argc == 0 && recurse) {
373                 argc=1;
374                 argv--;
375                 argv[0] = ".";
376         }
377
378         flist = send_file_list(f_out,argc,argv);
379         if (!flist || flist->count == 0) {
380                 exit_cleanup(0);
381         }
382
383         send_files(flist,f_out,f_in);
384         io_flush();
385         report(f_out);
386         if (protocol_version >= 24) {
387                 /* final goodbye message */
388                 read_int(f_in);
389         }
390         io_flush();
391         exit_cleanup(0);
392 }
393
394
395 static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
396 {
397         int pid;
398         int status=0;
399         int recv_pipe[2];
400         int error_pipe[2];
401         extern int preserve_hard_links;
402         extern int delete_after;
403         extern int recurse;
404         extern int delete_mode;
405
406         if (preserve_hard_links)
407                 init_hard_links(flist);
408
409         if (!delete_after) {
410                 /* I moved this here from recv_files() to prevent a race condition */
411                 if (recurse && delete_mode && !local_name && flist->count>0) {
412                         delete_files(flist);
413                 }
414         }
415
416         if (fd_pair(recv_pipe) < 0) {
417                 rprintf(FERROR,"pipe failed in do_recv\n");
418                 exit_cleanup(RERR_SOCKETIO);
419         }
420
421         if (fd_pair(error_pipe) < 0) {
422                 rprintf(FERROR,"error pipe failed in do_recv\n");
423                 exit_cleanup(RERR_SOCKETIO);
424         }
425
426         io_flush();
427
428         if ((pid=do_fork()) == 0) {
429                 close(recv_pipe[0]);
430                 close(error_pipe[0]);
431                 if (f_in != f_out) close(f_out);
432
433                 /* we can't let two processes write to the socket at one time */
434                 io_multiplexing_close();
435
436                 /* set place to send errors */
437                 set_error_fd(error_pipe[1]);
438
439                 recv_files(f_in,flist,local_name,recv_pipe[1]);
440                 io_flush();
441                 report(f_in);
442
443                 write_int(recv_pipe[1],1);
444                 close(recv_pipe[1]);
445                 io_flush();
446                 /* finally we go to sleep until our parent kills us
447                    with a USR2 signal. We sleep for a short time as on
448                    some OSes a signal won't interrupt a sleep! */
449                 while (msleep(20))
450                         ;
451         }
452
453         close(recv_pipe[1]);
454         close(error_pipe[1]);
455         if (f_in != f_out) close(f_in);
456
457         io_start_buffering(f_out);
458
459         io_set_error_fd(error_pipe[0]);
460
461         generate_files(f_out,flist,local_name,recv_pipe[0]);
462
463         read_int(recv_pipe[0]);
464         close(recv_pipe[0]);
465         if (protocol_version >= 24) {
466                 /* send a final goodbye message */
467                 write_int(f_out, -1);
468         }
469         io_flush();
470
471         io_set_error_fd(-1);
472         kill(pid, SIGUSR2);
473         wait_process(pid, &status);
474         return status;
475 }
476
477
478 static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
479 {
480         int status;
481         struct file_list *flist;
482         char *local_name=NULL;
483         char *dir = NULL;
484         extern int delete_mode;
485         extern int delete_excluded;
486         extern int module_id;
487         extern int read_batch;
488         extern struct file_list *batch_flist;
489
490         if (verbose > 2)
491                 rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
492
493         if (am_daemon && lp_read_only(module_id) && !am_sender) {
494                 rprintf(FERROR,"ERROR: module is read only\n");
495                 exit_cleanup(RERR_SYNTAX);
496                 return;
497         }
498
499
500         if (argc > 0) {
501                 dir = argv[0];
502                 argc--;
503                 argv++;
504                 if (!am_daemon && !push_dir(dir, 0)) {
505                         rprintf(FERROR, "push_dir %s failed: %s (4)\n",
506                                 full_fname(dir), strerror(errno));
507                         exit_cleanup(RERR_FILESELECT);
508                 }
509         }
510
511         if (delete_mode && !delete_excluded)
512                 recv_exclude_list(f_in);
513
514         if (filesfrom_fd >= 0) {
515                 /* We're receiving the file info from the sender, so we need
516                  * the IO routines to automatically write out the names onto
517                  * our f_out socket as we read the list info from the sender.
518                  * This avoids both deadlock and extra delays/buffers. */
519                 io_set_filesfrom_fds(filesfrom_fd, f_out);
520                 filesfrom_fd = -1;
521         }
522
523         if (read_batch)
524                 flist = batch_flist;
525         else
526                 flist = recv_file_list(f_in);
527         if (!flist) {
528                 rprintf(FERROR,"server_recv: recv_file_list error\n");
529                 exit_cleanup(RERR_FILESELECT);
530         }
531
532         if (argc > 0) {
533                 if (strcmp(dir,".")) {
534                         argv[0] += strlen(dir);
535                         if (argv[0][0] == '/') argv[0]++;
536                 }
537                 local_name = get_local_name(flist,argv[0]);
538         }
539
540         status = do_recv(f_in,f_out,flist,local_name);
541         exit_cleanup(status);
542 }
543
544
545 int child_main(int argc, char *argv[])
546 {
547         start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
548         return 0;
549 }
550
551
552 void start_server(int f_in, int f_out, int argc, char *argv[])
553 {
554         extern int cvs_exclude;
555         extern int read_batch;
556
557         setup_protocol(f_out, f_in);
558
559         set_nonblocking(f_in);
560         set_nonblocking(f_out);
561
562         if (protocol_version >= 23)
563                 io_start_multiplex_out(f_out);
564
565         if (am_sender) {
566                 if (!read_batch) {
567                         recv_exclude_list(f_in);
568                         if (cvs_exclude)
569                                 add_cvs_excludes();
570                 }
571                 do_server_sender(f_in, f_out, argc, argv);
572         } else {
573                 do_server_recv(f_in, f_out, argc, argv);
574         }
575         exit_cleanup(0);
576 }
577
578
579 /*
580  * This is called once the connection has been negotiated.  It is used
581  * for rsyncd, remote-shell, and local connections.
582  */
583 int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
584 {
585         struct file_list *flist = NULL;
586         int status = 0, status2 = 0;
587         char *local_name = NULL;
588         extern pid_t cleanup_child_pid;
589         extern int write_batch;
590         extern int read_batch;
591         extern struct file_list *batch_flist;
592
593         cleanup_child_pid = pid;
594         if (read_batch)
595                 flist = batch_flist;
596
597         set_nonblocking(f_in);
598         set_nonblocking(f_out);
599
600         setup_protocol(f_out,f_in);
601
602         if (protocol_version >= 23)
603                 io_start_multiplex_in(f_in);
604
605         if (am_sender) {
606                 extern int cvs_exclude;
607                 extern int delete_mode;
608                 extern int delete_excluded;
609                 if (cvs_exclude)
610                         add_cvs_excludes();
611                 if (delete_mode && !delete_excluded)
612                         send_exclude_list(f_out);
613                 if (remote_filesfrom_file)
614                         filesfrom_fd = f_in;
615                 if (!read_batch) /*  dw -- don't write to pipe */
616                         flist = send_file_list(f_out,argc,argv);
617                 if (verbose > 3)
618                         rprintf(FINFO,"file list sent\n");
619
620                 send_files(flist,f_out,f_in);
621                 if (protocol_version >= 24) {
622                         /* final goodbye message */
623                         read_int(f_in);
624                 }
625                 if (pid != -1) {
626                         if (verbose > 3)
627                                 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
628                         io_flush();
629                         wait_process(pid, &status);
630                 }
631                 report(-1);
632                 exit_cleanup(status);
633         }
634
635         if (argc == 0) {
636                 extern int list_only;
637                 list_only = 1;
638         }
639
640         if (!write_batch)
641                 send_exclude_list(f_out);
642
643         if (filesfrom_fd >= 0) {
644                 io_set_filesfrom_fds(filesfrom_fd, f_out);
645                 filesfrom_fd = -1;
646         }
647
648         flist = recv_file_list(f_in);
649         if (!flist || flist->count == 0) {
650                 rprintf(FINFO, "client: nothing to do: "
651                         "perhaps you need to specify some filenames or "
652                         "the --recursive option?\n");
653                 exit_cleanup(0);
654         }
655
656         local_name = get_local_name(flist,argv[0]);
657
658         status2 = do_recv(f_in,f_out,flist,local_name);
659
660         if (pid != -1) {
661                 if (verbose > 3)
662                         rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
663                 io_flush();
664                 wait_process(pid, &status);
665         }
666
667         return MAX(status, status2);
668 }
669
670 static int copy_argv (char *argv[])
671 {
672         int i;
673
674         for (i = 0; argv[i]; i++) {
675                 if (!(argv[i] = strdup(argv[i]))) {
676                         rprintf (FERROR, "out of memory at %s(%d)\n",
677                                  __FILE__, __LINE__);
678                         return RERR_MALLOC;
679                 }
680         }
681
682         return 0;
683 }
684
685
686 /**
687  * Start a client for either type of remote connection.  Work out
688  * whether the arguments request a remote shell or rsyncd connection,
689  * and call the appropriate connection function, then run_client.
690  *
691  * Calls either start_socket_client (for sockets) or do_cmd and
692  * client_run (for ssh).
693  **/
694 static int start_client(int argc, char *argv[])
695 {
696         char *p;
697         char *shell_machine = NULL;
698         char *shell_path = NULL;
699         char *shell_user = NULL;
700         int ret;
701         pid_t pid;
702         int f_in,f_out;
703         extern int local_server;
704         extern char *shell_cmd;
705         extern int rsync_port;
706         extern int daemon_over_rsh;
707         extern int read_batch;
708         int rc;
709
710         /* Don't clobber argv[] so that ps(1) can still show the right
711          * command line. */
712         if ((rc = copy_argv(argv)))
713                 return rc;
714
715         /* rsync:// always uses rsync server over direct socket connection */
716         if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) {
717                 char *host, *path;
718
719                 host = argv[0] + strlen(URL_PREFIX);
720                 p = strchr(host,'/');
721                 if (p) {
722                         *p = 0;
723                         path = p+1;
724                 } else {
725                         path = "";
726                 }
727                 p = strchr(host,':');
728                 if (p) {
729                         rsync_port = atoi(p+1);
730                         *p = 0;
731                 }
732                 return start_socket_client(host, path, argc-1, argv+1);
733         }
734
735         if (!read_batch) {
736                 p = find_colon(argv[0]);
737                 if (p) {
738                         if (remote_filesfrom_file
739                          && remote_filesfrom_file != files_from + 1
740                          && strncmp(files_from, argv[0], p-argv[0]+1) != 0) {
741                                 rprintf(FERROR,
742                                         "--files-from hostname is not transfer hostname\n");
743                                 exit_cleanup(RERR_SYNTAX);
744                         }
745                         if (p[1] == ':') { /* double colon */
746                                 *p = 0;
747                                 if (!shell_cmd) {
748                                         return start_socket_client(argv[0], p+2,
749                                                                    argc-1, argv+1);
750                                 }
751                                 p++;
752                                 daemon_over_rsh = 1;
753                         }
754
755                         if (argc < 1) {
756                                 usage(FERROR);
757                                 exit_cleanup(RERR_SYNTAX);
758                         }
759
760                         am_sender = 0;
761                         *p = 0;
762                         shell_machine = argv[0];
763                         shell_path = p+1;
764                         argc--;
765                         argv++;
766                 } else {
767                         am_sender = 1;
768
769                         /* rsync:// destination uses rsync server over direct socket */
770                         if (strncasecmp(URL_PREFIX, argv[argc-1], strlen(URL_PREFIX)) == 0) {
771                                 char *host, *path;
772
773                                 host = argv[argc-1] + strlen(URL_PREFIX);
774                                 p = strchr(host,'/');
775                                 if (p) {
776                                         *p = 0;
777                                         path = p+1;
778                                 } else {
779                                         path = "";
780                                 }
781                                 p = strchr(host,':');
782                                 if (p) {
783                                         rsync_port = atoi(p+1);
784                                         *p = 0;
785                                 }
786                                 return start_socket_client(host, path, argc-1, argv);
787                         }
788
789                         p = find_colon(argv[argc-1]);
790                         if (p && remote_filesfrom_file
791                          && remote_filesfrom_file != files_from + 1
792                          && strncmp(files_from, argv[argc-1], p-argv[argc-1]+1) != 0) {
793                                 rprintf(FERROR,
794                                         "--files-from hostname is not transfer hostname\n");
795                                 exit_cleanup(RERR_SYNTAX);
796                         }
797                         if (!p) {
798                                 local_server = 1;
799                                 if (remote_filesfrom_file) {
800                                         rprintf(FERROR,
801                                                 "--files-from is remote but transfer is local\n");
802                                         exit_cleanup(RERR_SYNTAX);
803                                 }
804                         } else if (p[1] == ':') { /* double colon */
805                                 *p = 0;
806                                 if (!shell_cmd) {
807                                         return start_socket_client(argv[argc-1], p+2,
808                                                                    argc-1, argv);
809                                 }
810                                 p++;
811                                 daemon_over_rsh = 1;
812                         }
813
814                         if (argc < 2) {
815                                 usage(FERROR);
816                                 exit_cleanup(RERR_SYNTAX);
817                         }
818
819                         if (local_server) {
820                                 shell_machine = NULL;
821                                 shell_path = argv[argc-1];
822                         } else {
823                                 *p = 0;
824                                 shell_machine = argv[argc-1];
825                                 shell_path = p+1;
826                         }
827                         argc--;
828                 }
829         } else {
830                 am_sender = 1;
831                 local_server = 1;
832                 shell_path = argv[argc-1];
833         }
834
835         if (shell_machine) {
836                 p = strchr(shell_machine,'@');
837                 if (p) {
838                         *p = 0;
839                         shell_user = shell_machine;
840                         shell_machine = p+1;
841                 }
842         }
843
844         if (verbose > 3) {
845                 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
846                         shell_cmd?shell_cmd:"",
847                         shell_machine?shell_machine:"",
848                         shell_user?shell_user:"",
849                         shell_path?shell_path:"");
850         }
851
852         if (!am_sender && argc > 1) {
853                 usage(FERROR);
854                 exit_cleanup(RERR_SYNTAX);
855         }
856
857         if (argc == 0 && !am_sender) {
858                 extern int list_only;
859                 list_only = 1;
860         }
861
862         pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
863                      &f_in,&f_out);
864
865         /* if we're running an rsync server on the remote host over a
866            remote shell command, we need to do the RSYNCD protocol first */
867         if (daemon_over_rsh) {
868                 int tmpret;
869                 tmpret = start_inband_exchange(shell_user, shell_path,
870                                                f_in, f_out, argc);
871                 if (tmpret < 0)
872                         return tmpret;
873         }
874
875         ret = client_run(f_in, f_out, pid, argc, argv);
876
877         fflush(stdout);
878         fflush(stderr);
879
880         return ret;
881 }
882
883
884 static RETSIGTYPE sigusr1_handler(UNUSED(int val))
885 {
886         exit_cleanup(RERR_SIGNAL);
887 }
888
889 static RETSIGTYPE sigusr2_handler(UNUSED(int val))
890 {
891         extern int log_got_error;
892         if (log_got_error) _exit(RERR_PARTIAL);
893         _exit(0);
894 }
895
896 static RETSIGTYPE sigchld_handler(UNUSED(int val))
897 {
898 #ifdef WNOHANG
899         int cnt, status;
900         pid_t pid;
901         /* An empty waitpid() loop was put here by Tridge and we could never
902          * get him to explain why he put it in, so rather than taking it
903          * out we're instead saving the child exit statuses for later use.
904          * The waitpid() loop presumably eliminates all possibility of leaving
905          * zombie children, maybe that's why he did it.
906          */
907         while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
908                  /* save the child's exit status */
909                  for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
910                           if (pid_stat_table[cnt].pid == 0) {
911                                    pid_stat_table[cnt].pid = pid;
912                                    pid_stat_table[cnt].status = status;
913                                    break;
914                           }
915                  }
916         }
917 #endif
918 }
919
920
921 /**
922  * This routine catches signals and tries to send them to gdb.
923  *
924  * Because it's called from inside a signal handler it ought not to
925  * use too many library routines.
926  *
927  * @todo Perhaps use "screen -X" instead/as well, to help people
928  * debugging without easy access to X.  Perhaps use an environment
929  * variable, or just call a script?
930  *
931  * @todo The /proc/ magic probably only works on Linux (and
932  * Solaris?)  Can we be more portable?
933  **/
934 #ifdef MAINTAINER_MODE
935 const char *get_panic_action(void)
936 {
937         const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
938
939         if (cmd_fmt)
940                 return cmd_fmt;
941         else
942                 return "xterm -display :0 -T Panic -n Panic "
943                         "-e gdb /proc/%d/exe %d";
944 }
945
946
947 /**
948  * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
949  *
950  * This signal handler is only installed if we were configured with
951  * --enable-maintainer-mode.  Perhaps it should always be on and we
952  * should just look at the environment variable, but I'm a bit leery
953  * of a signal sending us into a busy loop.
954  **/
955 static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
956 {
957         char cmd_buf[300];
958         int ret;
959
960         sprintf(cmd_buf, get_panic_action(),
961                 getpid(), getpid());
962
963         /* Unless we failed to execute gdb, we allow the process to
964          * continue.  I'm not sure if that's right. */
965         ret = system(cmd_buf);
966         if (ret)
967                 _exit(ret);
968 }
969 #endif
970
971
972 int main(int argc,char *argv[])
973 {
974         extern int am_root;
975         extern int orig_umask;
976         extern int dry_run;
977         int ret;
978         extern int write_batch;
979         int orig_argc;
980         char **orig_argv;
981
982         orig_argc = argc;
983         orig_argv = argv;
984
985         signal(SIGUSR1, sigusr1_handler);
986         signal(SIGUSR2, sigusr2_handler);
987         signal(SIGCHLD, sigchld_handler);
988 #ifdef MAINTAINER_MODE
989         signal(SIGSEGV, rsync_panic_handler);
990         signal(SIGFPE, rsync_panic_handler);
991         signal(SIGABRT, rsync_panic_handler);
992         signal(SIGBUS, rsync_panic_handler);
993 #endif /* def MAINTAINER_MODE */
994
995         starttime = time(NULL);
996         am_root = (getuid() == 0);
997
998         memset(&stats, 0, sizeof(stats));
999
1000         if (argc < 2) {
1001                 usage(FERROR);
1002                 exit_cleanup(RERR_SYNTAX);
1003         }
1004
1005         /* we set a 0 umask so that correct file permissions can be
1006            carried across */
1007         orig_umask = (int)umask(0);
1008
1009         if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
1010                 /* FIXME: We ought to call the same error-handling
1011                  * code here, rather than relying on getopt. */
1012                 option_error();
1013                 exit_cleanup(RERR_SYNTAX);
1014         }
1015
1016         signal(SIGINT,SIGNAL_CAST sig_int);
1017         signal(SIGHUP,SIGNAL_CAST sig_int);
1018         signal(SIGTERM,SIGNAL_CAST sig_int);
1019
1020         /* Ignore SIGPIPE; we consistently check error codes and will
1021          * see the EPIPE. */
1022         signal(SIGPIPE, SIG_IGN);
1023
1024         /* Initialize push_dir here because on some old systems getcwd
1025            (implemented by forking "pwd" and reading its output) doesn't
1026            work when there are other child processes.  Also, on all systems
1027            that implement getcwd that way "pwd" can't be found after chroot. */
1028         push_dir(NULL,0);
1029
1030         if (write_batch && !am_server) {
1031                 write_batch_argvs_file(orig_argc, orig_argv);
1032         }
1033
1034         if (am_daemon && !am_server)
1035                 return daemon_main();
1036
1037         if (argc < 1) {
1038                 usage(FERROR);
1039                 exit_cleanup(RERR_SYNTAX);
1040         }
1041
1042         if (dry_run)
1043                 verbose = MAX(verbose,1);
1044
1045 #ifndef SUPPORT_LINKS
1046         if (!am_server && preserve_links) {
1047                 rprintf(FERROR,"ERROR: symbolic links not supported\n");
1048                 exit_cleanup(RERR_UNSUPPORTED);
1049         }
1050 #endif
1051
1052         if (am_server) {
1053                 set_nonblocking(STDIN_FILENO);
1054                 set_nonblocking(STDOUT_FILENO);
1055                 if (am_daemon)
1056                         return start_daemon(STDIN_FILENO, STDOUT_FILENO);
1057                 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
1058         }
1059
1060         ret = start_client(argc, argv);
1061         if (ret == -1)
1062                 exit_cleanup(RERR_STARTCLIENT);
1063         else
1064                 exit_cleanup(ret);
1065
1066         return ret;
1067 }