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