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