- Improved the way we generate the tar file.
[rsync/rsync.git] / main.c
CommitLineData
0ba48136 1/* -*- c-file-style: "linux" -*-
d9c7edf6 2
50135767 3 Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
c627d613 4 Copyright (C) Paul Mackerras 1996
e5a2b854 5 Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
d9c7edf6 6
c627d613
AT
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.
d9c7edf6 11
c627d613
AT
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.
d9c7edf6 16
c627d613
AT
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"
d9401514
WD
23#if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
24#include <locale.h>
25#endif
c627d613 26
50839b4b
WD
27extern int verbose;
28extern int dry_run;
29extern int list_only;
32eda096 30extern int am_root;
d9c7edf6
WD
31extern int am_server;
32extern int am_sender;
b695f242 33extern int am_generator;
d9c7edf6 34extern int am_daemon;
32eda096 35extern int blocking_io;
bf26aa22 36extern int remove_sent_files;
32eda096 37extern int daemon_over_rsh;
bf26aa22 38extern int need_messages_from_generator;
051182cb 39extern int kluge_around_eof;
32eda096 40extern int do_stats;
32eda096
WD
41extern int log_got_error;
42extern int module_id;
43extern int orig_umask;
bb6721dc 44extern int copy_links;
83926d3c 45extern int keep_dirlinks;
32eda096 46extern int preserve_hard_links;
d04e9c51 47extern int protocol_version;
32eda096
WD
48extern int recurse;
49extern int relative_paths;
50extern int rsync_port;
b1df18d7 51extern int whole_file;
32eda096
WD
52extern int read_batch;
53extern int write_batch;
b9f592fb 54extern int batch_fd;
c0d8e84c 55extern int batch_gen_fd;
32eda096
WD
56extern int filesfrom_fd;
57extern pid_t cleanup_child_pid;
50839b4b 58extern struct stats stats;
860236bf 59extern char *filesfrom_host;
32eda096
WD
60extern char *rsync_path;
61extern char *shell_cmd;
9b3318b0 62extern char *batch_name;
57dee64e
WD
63
64int local_server = 0;
a00628b3 65struct file_list *the_file_list;
c627d613 66
91c5833b
WD
67/* There's probably never more than at most 2 outstanding child processes,
68 * but set it higher, just in case. */
84e6d6fd 69#define MAXCHILDPROCS 7
ee7118a8 70
8261af74
WD
71#ifdef HAVE_SIGACTION
72# ifdef HAVE_SIGPROCMASK
73# define SIGACTMASK(n,h) SIGACTION(n,h), sigaddset(&sigmask,(n))
74# else
75# define SIGACTMASK(n,h) SIGACTION(n,h)
76# endif
60ee01f5
WD
77static struct sigaction sigact;
78#endif
79
ee7118a8
DD
80struct pid_status {
81 pid_t pid;
84e6d6fd 82 int status;
ee7118a8
DD
83} pid_stat_table[MAXCHILDPROCS];
84
33c4b445
WD
85static time_t starttime, endtime;
86static int64 total_read, total_written;
87
e5a2b854 88static void show_malloc_stats(void);
82980a23 89
97d8e709 90/* Works like waitpid(), but if we already harvested the child pid in our
6d59ac19 91 * remember_children(), we succeed instead of returning an error. */
97d8e709 92pid_t wait_process(pid_t pid, int *status_ptr, int flags)
82980a23 93{
97d8e709 94 pid_t waited_pid = waitpid(pid, status_ptr, flags);
d9c7edf6 95
6fb812f7 96 if (waited_pid == -1 && errno == ECHILD) {
97d8e709 97 /* Status of requested child no longer available: check to
6d59ac19 98 * see if it was processed by remember_children(). */
97d8e709 99 int cnt;
84e6d6fd 100 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
ee7118a8 101 if (pid == pid_stat_table[cnt].pid) {
97d8e709 102 *status_ptr = pid_stat_table[cnt].status;
ee7118a8 103 pid_stat_table[cnt].pid = 0;
97d8e709 104 return pid;
ee7118a8
DD
105 }
106 }
107 }
108
97d8e709
WD
109 return waited_pid;
110}
111
112/* Wait for a process to exit, calling io_flush while waiting. */
84e6d6fd 113static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
97d8e709
WD
114{
115 pid_t waited_pid;
116 int status;
117
118 while ((waited_pid = wait_process(pid, &status, WNOHANG)) == 0) {
119 msleep(20);
120 io_flush(FULL_FLUSH);
121 }
122
d9c7edf6
WD
123 /* TODO: If the child exited on a signal, then log an
124 * appropriate error message. Perhaps we should also accept a
125 * message describing the purpose of the child. Also indicate
dbefb6b4 126 * this to the caller so that they know something went wrong. */
84e6d6fd
WD
127 if (waited_pid < 0) {
128 rsyserr(FERROR, errno, "waitpid");
129 *exit_code_ptr = RERR_WAITCHILD;
130 } else if (!WIFEXITED(status)) {
40e6752f 131#ifdef WCOREDUMP
dbefb6b4 132 if (WCOREDUMP(status))
84e6d6fd 133 *exit_code_ptr = RERR_CRASHED;
40e6752f
WD
134 else
135#endif
136 if (WIFSIGNALED(status))
84e6d6fd 137 *exit_code_ptr = RERR_TERMINATED;
dbefb6b4 138 else
84e6d6fd 139 *exit_code_ptr = RERR_WAITCHILD;
dbefb6b4 140 } else
84e6d6fd 141 *exit_code_ptr = WEXITSTATUS(status);
82980a23
AT
142}
143
b9f592fb
WD
144/* This function gets called from all 3 processes. We want the client side
145 * to actually output the text, but the sender is the only process that has
146 * all the stats we need. So, if we're a client sender, we do the report.
147 * If we're a server sender, we write the stats on the supplied fd. If
148 * we're the client receiver we read the stats from the supplied fd and do
149 * the report. All processes might also generate a set of debug stats, if
150 * the verbose level is high enough (this is the only thing that the
151 * generator process and the server receiver ever do here). */
33c4b445 152static void handle_stats(int f)
c627d613 153{
33c4b445
WD
154 endtime = time(NULL);
155
b9f592fb 156 /* Cache two stats because the read/write code can change it. */
33c4b445
WD
157 total_read = stats.total_read;
158 total_written = stats.total_written;
7a6421fa 159
7bb7058e 160 if (do_stats && verbose > 1) {
5c15e29f 161 /* These come out from every process */
7bb7058e 162 show_malloc_stats();
86943126 163 show_flist_stats();
5c15e29f
MP
164 }
165
e5fbaa71
S
166 if (am_generator)
167 return;
168
248fbb8c 169 if (am_daemon) {
a9766ef1 170 log_exit(0, __FILE__, __LINE__);
83926d3c
WD
171 if (f == -1 || !am_sender)
172 return;
248fbb8c
AT
173 }
174
e19452a9 175 if (am_server) {
3e491682 176 if (am_sender) {
b9f592fb
WD
177 write_longint(f, total_read);
178 write_longint(f, total_written);
179 write_longint(f, stats.total_size);
f0f7e760
WD
180 if (protocol_version >= 29) {
181 write_longint(f, stats.flist_buildtime);
182 write_longint(f, stats.flist_xfertime);
183 }
e19452a9 184 }
7a6421fa
AT
185 return;
186 }
e19452a9
DD
187
188 /* this is the client */
d9c7edf6 189
9d19f8a5
WD
190 if (f < 0 && !am_sender) /* e.g. when we got an empty file list. */
191 ;
192 else if (!am_sender) {
58c5c245
WD
193 /* Read the first two in opposite order because the meaning of
194 * read/write swaps when switching from sender to receiver. */
b9f592fb
WD
195 total_written = read_longint(f);
196 total_read = read_longint(f);
a800434a 197 stats.total_size = read_longint(f);
f0f7e760
WD
198 if (protocol_version >= 29) {
199 stats.flist_buildtime = read_longint(f);
200 stats.flist_xfertime = read_longint(f);
201 }
e4676bb5 202 } else if (write_batch) {
b9f592fb
WD
203 /* The --read-batch process is going to be a client
204 * receiver, so we need to give it the stats. */
205 write_longint(batch_fd, total_read);
206 write_longint(batch_fd, total_written);
207 write_longint(batch_fd, stats.total_size);
f0f7e760
WD
208 if (protocol_version >= 29) {
209 write_longint(batch_fd, stats.flist_buildtime);
210 write_longint(batch_fd, stats.flist_xfertime);
211 }
a800434a 212 }
e4676bb5 213}
a800434a 214
e4676bb5
WD
215static void output_summary(void)
216{
a800434a 217 if (do_stats) {
1f658d42 218 rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
d9c7edf6
WD
219 rprintf(FINFO,"Number of files transferred: %d\n",
220 stats.num_transferred_files);
60613dc8
WD
221 rprintf(FINFO,"Total file size: %s bytes\n",
222 human_num(stats.total_size));
223 rprintf(FINFO,"Total transferred file size: %s bytes\n",
224 human_num(stats.total_transferred_size));
225 rprintf(FINFO,"Literal data: %s bytes\n",
226 human_num(stats.literal_data));
227 rprintf(FINFO,"Matched data: %s bytes\n",
228 human_num(stats.matched_data));
1f658d42 229 rprintf(FINFO,"File list size: %d\n", stats.flist_size);
f0f7e760
WD
230 if (stats.flist_buildtime) {
231 rprintf(FINFO,
232 "File list generation time: %.3f seconds\n",
233 (double)stats.flist_buildtime / 1000);
234 rprintf(FINFO,
235 "File list transfer time: %.3f seconds\n",
236 (double)stats.flist_xfertime / 1000);
237 }
60613dc8
WD
238 rprintf(FINFO,"Total bytes sent: %s\n",
239 human_num(total_written));
240 rprintf(FINFO,"Total bytes received: %s\n",
241 human_num(total_read));
7a6421fa 242 }
d9c7edf6 243
e19452a9 244 if (verbose || do_stats) {
b9f592fb 245 rprintf(FINFO,
60613dc8
WD
246 "\nsent %s bytes received %s bytes %s bytes/sec\n",
247 human_num(total_written), human_num(total_read),
248 human_dnum((total_written + total_read)/(0.5 + (endtime - starttime)), 2));
249 rprintf(FINFO, "total size is %s speedup is %.2f\n",
250 human_num(stats.total_size),
b9f592fb 251 (double)stats.total_size / (total_written+total_read));
e19452a9 252 }
fc8a6b97
AT
253
254 fflush(stdout);
255 fflush(stderr);
c627d613
AT
256}
257
258
e5a2b854
MP
259/**
260 * If our C library can get malloc statistics, then show them to FINFO
261 **/
262static void show_malloc_stats(void)
263{
4f5b0756 264#ifdef HAVE_MALLINFO
e5a2b854
MP
265 struct mallinfo mi;
266
267 mi = mallinfo();
268
ce672562 269 rprintf(FINFO, "\n" RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
f846a9bf
WD
270 getpid(), am_server ? "server " : "",
271 am_daemon ? "daemon " : "", who_am_i());
272 rprintf(FINFO, " arena: %10ld (bytes from sbrk)\n",
273 (long)mi.arena);
274 rprintf(FINFO, " ordblks: %10ld (chunks not in use)\n",
275 (long)mi.ordblks);
276 rprintf(FINFO, " smblks: %10ld\n",
277 (long)mi.smblks);
278 rprintf(FINFO, " hblks: %10ld (chunks from mmap)\n",
279 (long)mi.hblks);
280 rprintf(FINFO, " hblkhd: %10ld (bytes from mmap)\n",
281 (long)mi.hblkhd);
282 rprintf(FINFO, " allmem: %10ld (bytes from sbrk + mmap)\n",
283 (long)mi.arena + mi.hblkhd);
284 rprintf(FINFO, " usmblks: %10ld\n",
285 (long)mi.usmblks);
286 rprintf(FINFO, " fsmblks: %10ld\n",
287 (long)mi.fsmblks);
288 rprintf(FINFO, " uordblks: %10ld (bytes used)\n",
289 (long)mi.uordblks);
290 rprintf(FINFO, " fordblks: %10ld (bytes free)\n",
291 (long)mi.fordblks);
292 rprintf(FINFO, " keepcost: %10ld (bytes in releasable chunk)\n",
293 (long)mi.keepcost);
e5a2b854
MP
294#endif /* HAVE_MALLINFO */
295}
296
297
0882faa2 298/* Start the remote shell. cmd may be NULL to use the default. */
6c2e5b56
WD
299static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
300 int *f_in, int *f_out)
c627d613 301{
6c2e5b56 302 int i, argc = 0;
887e553f 303 char *args[MAX_ARGS];
19b27a48 304 pid_t ret;
82f0c63e 305 char *dir = NULL;
bb4aa89c 306 int dash_l_set = 0;
366345fe 307
088aac85 308 if (!read_batch && !local_server) {
82f0c63e 309 char *t, *f, in_quote = '\0';
9af87151 310 char *rsh_env = getenv(RSYNC_RSH_ENV);
366345fe 311 if (!cmd)
9af87151 312 cmd = rsh_env;
366345fe
AT
313 if (!cmd)
314 cmd = RSYNC_RSH;
315 cmd = strdup(cmd);
d9c7edf6 316 if (!cmd)
366345fe
AT
317 goto oom;
318
82f0c63e
WD
319 for (t = f = cmd; *f; f++) {
320 if (*f == ' ')
321 continue;
e7a392c7 322 /* Comparison leaves rooms for server_options(). */
d8c4d6de 323 if (argc >= MAX_ARGS - MAX_SERVER_ARGS) {
e7a392c7 324 rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
887e553f
WD
325 exit_cleanup(RERR_SYNTAX);
326 }
82f0c63e
WD
327 args[argc++] = t;
328 while (*f != ' ' || in_quote) {
329 if (!*f) {
330 if (in_quote) {
331 rprintf(FERROR,
332 "Missing trailing-%c in remote-shell command.\n",
333 in_quote);
334 exit_cleanup(RERR_SYNTAX);
335 }
336 f--;
337 break;
338 }
339 if (*f == '\'' || *f == '"') {
340 if (!in_quote) {
341 in_quote = *f++;
342 continue;
343 }
344 if (*f == in_quote && *++f != in_quote) {
345 in_quote = '\0';
346 continue;
347 }
348 }
349 *t++ = *f++;
350 }
351 *t++ = '\0';
887e553f 352 }
c627d613 353
d9c7edf6 354 /* check to see if we've already been given '-l user' in
9af87151 355 * the remote-shell command */
bb4aa89c
WD
356 for (i = 0; i < argc-1; i++) {
357 if (!strcmp(args[i], "-l") && args[i+1][0] != '-')
358 dash_l_set = 1;
359 }
360
4f5b0756 361#ifdef HAVE_REMSH
366345fe
AT
362 /* remsh (on HPUX) takes the arguments the other way around */
363 args[argc++] = machine;
bb4aa89c 364 if (user && !(daemon_over_rsh && dash_l_set)) {
366345fe
AT
365 args[argc++] = "-l";
366 args[argc++] = user;
367 }
7b8356d0 368#else
bb4aa89c 369 if (user && !(daemon_over_rsh && dash_l_set)) {
366345fe
AT
370 args[argc++] = "-l";
371 args[argc++] = user;
372 }
373 args[argc++] = machine;
7b8356d0 374#endif
c627d613 375
366345fe 376 args[argc++] = rsync_path;
c627d613 377
9af87151 378 if (blocking_io < 0) {
90e22f4b
WD
379 char *cp;
380 if ((cp = strrchr(cmd, '/')) != NULL)
381 cp++;
382 else
383 cp = cmd;
384 if (strcmp(cp, "rsh") == 0 || strcmp(cp, "remsh") == 0)
385 blocking_io = 1;
66b71163 386 }
e384bfbd 387
93689aa5 388 server_options(args,&argc);
e7a392c7
WD
389
390 if (argc >= MAX_ARGS - 2) {
391 rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
392 exit_cleanup(RERR_SYNTAX);
393 }
366345fe 394 }
c627d613 395
366345fe 396 args[argc++] = ".";
76076c4b 397
d9c7edf6 398 if (!daemon_over_rsh && path && *path)
366345fe 399 args[argc++] = path;
c627d613 400
366345fe 401 args[argc] = NULL;
c627d613 402
366345fe 403 if (verbose > 3) {
e7a392c7 404 for (i = 0; i < argc; i++)
45c49b52 405 rprintf(FINFO, "cmd[%d]=%s ", i, args[i]);
82f0c63e 406 rprintf(FINFO, "\n");
366345fe
AT
407 }
408
c0d8e84c
WD
409 if (read_batch) {
410 int from_gen_pipe[2];
411 if (fd_pair(from_gen_pipe) < 0) {
412 rsyserr(FERROR, errno, "pipe");
413 exit_cleanup(RERR_IPC);
414 }
415 batch_gen_fd = from_gen_pipe[0];
416 *f_out = from_gen_pipe[1];
417 *f_in = batch_fd;
418 ret = -1; /* no child pid */
419 } else if (local_server) {
b1df18d7
WD
420 /* If the user didn't request --[no-]whole-file, force
421 * it on, but only if we're not batch processing. */
c0d8e84c 422 if (whole_file < 0 && !write_batch)
b1df18d7 423 whole_file = 1;
25d34a5c 424 ret = local_child(argc, args, f_in, f_out, child_main);
c0d8e84c 425 } else
366345fe 426 ret = piped_child(args,f_in,f_out);
c627d613 427
3a69fad0
WD
428 if (dir)
429 free(dir);
82306bf6 430
366345fe 431 return ret;
c627d613 432
acee11fc 433 oom:
366345fe
AT
434 out_of_memory("do_cmd");
435 return 0; /* not reached */
c627d613
AT
436}
437
eb598fac
WD
438/* The receiving side operates in one of two modes:
439 *
440 * 1. it enters a directory and receives one or more files, placing them
441 * according to their names in the file-list.
442 *
443 * 2. it receives a single file and saves it using the name in the
444 * destination path instead of its file-list name. This requires a
445 * "local name" for writing out the destination file.
446 *
447 * So, our task is to figure out what mode/local-name we need and return
448 * either a NULL for mode 1, or the local-name for mode 2. We also
449 * change directory if there are any path components in dest_path. */
450static char *get_local_name(struct file_list *flist, char *dest_path)
c627d613 451{
7a6421fa 452 STRUCT_STAT st;
eb598fac 453 char *cp;
c627d613 454
eb598fac
WD
455 if (verbose > 2) {
456 rprintf(FINFO, "get_local_name count=%d %s\n",
457 flist->count, NS(dest_path));
458 }
1f0610ef 459
eb598fac 460 if (!dest_path)
1f0610ef 461 return NULL;
c95da96a 462
eb598fac
WD
463 /* If the destination path refers to an existing directory, enter
464 * it and use mode 1. If there is something other than a directory
465 * at the destination path, we must be transferring one file
466 * (anything at the destination will be overwritten). */
467 if (do_stat(dest_path, &st) == 0) {
1ff5450d 468 if (S_ISDIR(st.st_mode)) {
eb598fac 469 if (!push_dir(dest_path)) {
982e05bb 470 rsyserr(FERROR, errno, "push_dir#1 %s failed",
eb598fac 471 full_fname(dest_path));
65417579 472 exit_cleanup(RERR_FILESELECT);
1ff5450d
AT
473 }
474 return NULL;
475 }
476 if (flist->count > 1) {
eb598fac
WD
477 rprintf(FERROR,
478 "ERROR: destination must be a directory when"
479 " copying more than 1 file\n");
65417579 480 exit_cleanup(RERR_FILESELECT);
1ff5450d 481 }
1ff5450d
AT
482 }
483
eb598fac
WD
484 cp = strrchr(dest_path, '/');
485
486 /* If the destination path ends in a slash or we are transferring
487 * multiple files, create a directory at the destination path,
488 * enter the new directory, and use mode 1. */
489 if (flist->count > 1 || (cp && !cp[1])) {
490 /* Lop off the final slash (if any). */
491 if (cp && !cp[1])
492 *cp = '\0';
493
494 umask(orig_umask);
495 if (do_mkdir(dest_path, 0777) != 0) {
496 rsyserr(FERROR, errno, "mkdir %s failed",
497 full_fname(dest_path));
498 exit_cleanup(RERR_FILEIO);
499 }
500 umask(0);
1ff5450d 501
eb598fac
WD
502 if (verbose)
503 rprintf(FINFO, "created directory %s\n", dest_path);
504
505 if (dry_run) {
506 /* Indicate that the destination directory doesn't
507 * really exist and return mode 1. */
508 dry_run++;
509 return NULL;
510 }
511
512 if (!push_dir(dest_path)) {
513 rsyserr(FERROR, errno, "push_dir#2 %s failed",
514 full_fname(dest_path));
515 exit_cleanup(RERR_FILESELECT);
516 }
e5a96f0f 517
e5a96f0f 518 return NULL;
1ff5450d
AT
519 }
520
eb598fac
WD
521 /* Otherwise, we are writing a single file, possibly on top of an
522 * existing non-directory. Change to the item's parent directory
523 * (if it has a path component), return the basename of the
524 * destination file as the local name, and use mode 2. */
525 if (!cp)
526 return dest_path;
527
528 if (cp == dest_path)
529 dest_path = "/";
530
531 *cp = '\0';
532 if (!push_dir(dest_path)) {
533 rsyserr(FERROR, errno, "push_dir#3 %s failed",
534 full_fname(dest_path));
65417579 535 exit_cleanup(RERR_FILESELECT);
1ff5450d 536 }
eb598fac 537 *cp = '/';
1ff5450d 538
eb598fac 539 return cp + 1;
c627d613
AT
540}
541
542
1a8e5c97 543/* This is only called by the sender. */
3485ae83 544static void read_final_goodbye(int f_in, int f_out)
4e0fcd85 545{
1a8e5c97
WD
546 int i;
547
548 if (protocol_version < 29)
549 i = read_int(f_in);
550 else {
3485ae83 551 while ((i = read_int(f_in)) == the_file_list->count
1a8e5c97
WD
552 && read_shortint(f_in) == ITEM_IS_NEW) {
553 /* Forward the keep-alive (no-op) to the receiver. */
3485ae83 554 write_int(f_out, the_file_list->count);
1a8e5c97
WD
555 write_shortint(f_out, ITEM_IS_NEW);
556 }
4e0fcd85
WD
557 }
558
1a8e5c97 559 if (i != -1) {
c7791b8c
WD
560 rprintf(FERROR, "Invalid packet at end of run (%d) [%s]\n",
561 i, who_am_i());
1a8e5c97 562 exit_cleanup(RERR_PROTOCOL);
4e0fcd85
WD
563 }
564}
565
566
eb598fac 567static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
c627d613 568{
7a6421fa
AT
569 struct file_list *flist;
570 char *dir = argv[0];
c627d613 571
45e08edb
WD
572 if (verbose > 2) {
573 rprintf(FINFO, "server_sender starting pid=%ld\n",
574 (long)getpid());
575 }
d9c7edf6 576
2adbcdc7 577 if (am_daemon && lp_write_only(module_id)) {
7a92ded3
WD
578 rprintf(FERROR, "ERROR: module is write only\n");
579 exit_cleanup(RERR_SYNTAX);
580 return;
581 }
bf26aa22
WD
582 if (am_daemon && lp_read_only(module_id) && remove_sent_files) {
583 rprintf(FERROR,
584 "ERROR: --remove-sent-files cannot be used with a read-only module\n");
585 exit_cleanup(RERR_SYNTAX);
586 return;
587 }
7a92ded3 588
59187666 589 if (!relative_paths && !push_dir(dir)) {
982e05bb
WD
590 rsyserr(FERROR, errno, "push_dir#3 %s failed",
591 full_fname(dir));
65417579 592 exit_cleanup(RERR_FILESELECT);
7a6421fa
AT
593 }
594 argc--;
595 argv++;
d9c7edf6 596
48a1ff0d 597 if (argc == 0 && (recurse || list_only)) {
e1f67417 598 argc = 1;
7a6421fa
AT
599 argv--;
600 argv[0] = ".";
601 }
d9c7edf6 602
7a6421fa 603 flist = send_file_list(f_out,argc,argv);
8d9dc9f9
AT
604 if (!flist || flist->count == 0) {
605 exit_cleanup(0);
606 }
a00628b3 607 the_file_list = flist;
8d9dc9f9 608
da3478b2
WD
609 io_start_buffering_in();
610 io_start_buffering_out();
611
7a6421fa 612 send_files(flist,f_out,f_in);
f1e3656e 613 io_flush(FULL_FLUSH);
33c4b445 614 handle_stats(f_out);
4e0fcd85 615 if (protocol_version >= 24)
3485ae83 616 read_final_goodbye(f_in, f_out);
f1e3656e 617 io_flush(FULL_FLUSH);
7a6421fa 618 exit_cleanup(0);
c627d613
AT
619}
620
621
dc5ddbcc
AT
622static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
623{
d186eb1a 624 int pid;
84e6d6fd 625 int exit_code = 0;
c70e07d9 626 int error_pipe[2];
dc5ddbcc 627
bb6721dc
WD
628 /* The receiving side mustn't obey this, or an existing symlink that
629 * points to an identical file won't be replaced by the referent. */
630 copy_links = 0;
631
d186eb1a 632 if (preserve_hard_links)
3485ae83 633 init_hard_links();
dc5ddbcc 634
c70e07d9 635 if (fd_pair(error_pipe) < 0) {
ab759cd2 636 rsyserr(FERROR, errno, "pipe failed in do_recv");
c8f2f857 637 exit_cleanup(RERR_IPC);
554e0a8d 638 }
d9c7edf6 639
f1e3656e 640 io_flush(NORMAL_FLUSH);
c6e7fcb4 641
ba449e44 642 if ((pid = do_fork()) == -1) {
c8f2f857 643 rsyserr(FERROR, errno, "fork failed in do_recv");
ba449e44
WD
644 exit_cleanup(RERR_IPC);
645 }
646
647 if (pid == 0) {
554e0a8d 648 close(error_pipe[0]);
3a69fad0
WD
649 if (f_in != f_out)
650 close(f_out);
e08c9610 651
554e0a8d 652 /* we can't let two processes write to the socket at one time */
9eeb3b9c 653 close_multiplexing_out();
554e0a8d
AT
654
655 /* set place to send errors */
f1e3656e 656 set_msg_fd_out(error_pipe[1]);
554e0a8d 657
c70e07d9 658 recv_files(f_in, flist, local_name);
f1e3656e 659 io_flush(FULL_FLUSH);
33c4b445 660 handle_stats(f_in);
e08c9610 661
f1e3656e
WD
662 send_msg(MSG_DONE, "", 0);
663 io_flush(FULL_FLUSH);
4e0fcd85 664
40df65fd
WD
665 /* Handle any keep-alive packets from the post-processing work
666 * that the generator does. */
4e0fcd85 667 if (protocol_version >= 29) {
051182cb 668 kluge_around_eof = -1;
1a8e5c97
WD
669
670 /* This should only get stopped via a USR2 signal. */
671 while (read_int(f_in) == flist->count
672 && read_shortint(f_in) == ITEM_IS_NEW) {}
673
3485ae83
WD
674 rprintf(FERROR, "Invalid packet at end of run [%s]\n",
675 who_am_i());
1a8e5c97 676 exit_cleanup(RERR_PROTOCOL);
4e0fcd85
WD
677 }
678
9e0582f9
WD
679 /* Finally, we go to sleep until our parent kills us with a
680 * USR2 signal. We sleep for a short time, as on some OSes
681 * a signal won't interrupt a sleep! */
f1e3656e
WD
682 while (1)
683 msleep(20);
d186eb1a 684 }
dc5ddbcc 685
b695f242 686 am_generator = 1;
9eeb3b9c 687 close_multiplexing_in();
e8a96e27 688 if (write_batch && !am_server)
b9f592fb 689 stop_write_batch();
b695f242 690
554e0a8d 691 close(error_pipe[1]);
3a69fad0
WD
692 if (f_in != f_out)
693 close(f_in);
e1b3d5c4 694
da3478b2 695 io_start_buffering_out();
b3e10ed7 696
f1e3656e 697 set_msg_fd_in(error_pipe[0]);
554e0a8d 698
c70e07d9 699 generate_files(f_out, flist, local_name);
8d9dc9f9 700
33c4b445 701 handle_stats(-1);
f1e3656e 702 io_flush(FULL_FLUSH);
d04e9c51 703 if (protocol_version >= 24) {
8ada7518
AT
704 /* send a final goodbye message */
705 write_int(f_out, -1);
706 }
f1e3656e 707 io_flush(FULL_FLUSH);
8ada7518 708
f1e3656e 709 set_msg_fd_in(-1);
089a2435 710 kill(pid, SIGUSR2);
84e6d6fd
WD
711 wait_process_with_flush(pid, &exit_code);
712 return exit_code;
dc5ddbcc
AT
713}
714
c627d613 715
9486289c 716static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
c627d613 717{
84e6d6fd 718 int exit_code;
7a6421fa 719 struct file_list *flist;
6c2e5b56 720 char *local_name = NULL;
7a6421fa 721 char *dir = NULL;
07bff66f
WD
722 int save_verbose = verbose;
723
724 if (filesfrom_fd >= 0) {
725 /* We can't mix messages with files-from data on the socket,
726 * so temporarily turn off verbose messages. */
727 verbose = 0;
728 }
f0fca04e 729
45e08edb
WD
730 if (verbose > 2) {
731 rprintf(FINFO, "server_recv(%d) starting pid=%ld\n",
732 argc, (long)getpid());
733 }
09b7f5db 734
2adbcdc7 735 if (am_daemon && lp_read_only(module_id)) {
09b7f5db
AT
736 rprintf(FERROR,"ERROR: module is read only\n");
737 exit_cleanup(RERR_SYNTAX);
738 return;
739 }
740
7a6421fa
AT
741 if (argc > 0) {
742 dir = argv[0];
743 argc--;
744 argv++;
59187666 745 if (!am_daemon && !push_dir(dir)) {
982e05bb
WD
746 rsyserr(FERROR, errno, "push_dir#4 %s failed",
747 full_fname(dir));
65417579 748 exit_cleanup(RERR_FILESELECT);
d9c7edf6 749 }
7a6421fa 750 }
c627d613 751
da3478b2 752 io_start_buffering_in();
57dee64e 753 recv_filter_list(f_in);
c627d613 754
7c2a9e76 755 if (filesfrom_fd >= 0) {
07bff66f
WD
756 /* We need to send the files-from names to the sender at the
757 * same time that we receive the file-list from them, so we
758 * need the IO routines to automatically write out the names
759 * onto our f_out socket as we read the file-list. This
760 * avoids both deadlock and extra delays/buffers. */
7c2a9e76
WD
761 io_set_filesfrom_fds(filesfrom_fd, f_out);
762 filesfrom_fd = -1;
763 }
764
b9f592fb 765 flist = recv_file_list(f_in);
07bff66f 766 verbose = save_verbose;
4c36a13e
AT
767 if (!flist) {
768 rprintf(FERROR,"server_recv: recv_file_list error\n");
65417579 769 exit_cleanup(RERR_FILESELECT);
7a6421fa 770 }
a00628b3 771 the_file_list = flist;
d9c7edf6 772
29fad7a3 773 if (argc > 0)
7a6421fa 774 local_name = get_local_name(flist,argv[0]);
c627d613 775
84e6d6fd
WD
776 exit_code = do_recv(f_in,f_out,flist,local_name);
777 exit_cleanup(exit_code);
c627d613
AT
778}
779
780
734a94a2 781int child_main(int argc, char *argv[])
25d34a5c
MP
782{
783 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
734a94a2 784 return 0;
25d34a5c
MP
785}
786
787
9486289c 788void start_server(int f_in, int f_out, int argc, char *argv[])
366345fe 789{
f0359dd0
AT
790 set_nonblocking(f_in);
791 set_nonblocking(f_out);
792
da3478b2
WD
793 io_set_sock_fds(f_in, f_out);
794 setup_protocol(f_out, f_in);
595251de 795#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
9656de5d
WD
796 setup_iconv();
797#endif
da3478b2 798
d04e9c51 799 if (protocol_version >= 23)
da3478b2 800 io_start_multiplex_out();
7a6421fa 801
7a6421fa 802 if (am_sender) {
83926d3c 803 keep_dirlinks = 0; /* Must be disabled on the sender. */
bf26aa22
WD
804 if (need_messages_from_generator)
805 io_start_multiplex_in();
9b3318b0 806
7842418b 807 recv_filter_list(f_in);
7a6421fa
AT
808 do_server_sender(f_in, f_out, argc, argv);
809 } else {
810 do_server_recv(f_in, f_out, argc, argv);
811 }
812 exit_cleanup(0);
366345fe
AT
813}
814
0ba48136
MP
815
816/*
817 * This is called once the connection has been negotiated. It is used
818 * for rsyncd, remote-shell, and local connections.
819 */
19b27a48 820int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
9486289c 821{
088aac85 822 struct file_list *flist = NULL;
84e6d6fd 823 int exit_code = 0, exit_code2 = 0;
9486289c 824 char *local_name = NULL;
19b27a48
AT
825
826 cleanup_child_pid = pid;
67a28eb2 827 if (!read_batch) {
b9f592fb
WD
828 set_nonblocking(f_in);
829 set_nonblocking(f_out);
830 }
f0359dd0 831
da3478b2 832 io_set_sock_fds(f_in, f_out);
6d7b6081 833 setup_protocol(f_out,f_in);
595251de 834#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
9656de5d
WD
835 setup_iconv();
836#endif
6d7b6081 837
b9f592fb 838 if (protocol_version >= 23 && !read_batch)
da3478b2 839 io_start_multiplex_in();
d9c7edf6 840
18882701
WD
841 /* We set our stderr file handle to blocking because ssh might have
842 * set it to non-blocking. This can be particularly troublesome if
843 * stderr is a clone of stdout, because ssh would have set our stdout
844 * to non-blocking at the same time (which can easily cause us to lose
845 * output from our print statements). This kluge shouldn't cause ssh
846 * any problems for how we use it. Note also that we delayed setting
847 * this until after the above protocol setup so that we know for sure
848 * that ssh is done twiddling its file descriptors. */
849 set_blocking(STDERR_FILENO);
850
9486289c 851 if (am_sender) {
83926d3c 852 keep_dirlinks = 0; /* Must be disabled on the sender. */
da3478b2 853 io_start_buffering_out();
860236bf 854 if (!filesfrom_host)
a0a33ee5 855 set_msg_fd_in(f_in);
57dee64e 856 send_filter_list(f_out);
860236bf 857 if (filesfrom_host)
7c2a9e76 858 filesfrom_fd = f_in;
b9f592fb 859
e8a96e27 860 if (write_batch && !am_server)
b9f592fb 861 start_write_batch(f_out);
a00628b3 862 flist = send_file_list(f_out, argc, argv);
a0a33ee5 863 set_msg_fd_in(-1);
d9c7edf6 864 if (verbose > 3)
9486289c 865 rprintf(FINFO,"file list sent\n");
a00628b3 866 the_file_list = flist;
e1b3d5c4 867
f1e3656e 868 io_flush(NORMAL_FLUSH);
9486289c 869 send_files(flist,f_out,f_in);
f1e3656e 870 io_flush(FULL_FLUSH);
33c4b445 871 handle_stats(-1);
4e0fcd85 872 if (protocol_version >= 24)
3485ae83 873 read_final_goodbye(f_in, f_out);
9486289c
AT
874 if (pid != -1) {
875 if (verbose > 3)
08a740ff 876 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
f1e3656e 877 io_flush(FULL_FLUSH);
84e6d6fd 878 wait_process_with_flush(pid, &exit_code);
9486289c 879 }
33c4b445 880 output_summary();
c87ae64a 881 io_flush(FULL_FLUSH);
84e6d6fd 882 exit_cleanup(exit_code);
9486289c 883 }
f7632fc6 884
bf26aa22
WD
885 if (need_messages_from_generator && !read_batch)
886 io_start_multiplex_out();
887
48a1ff0d
WD
888 if (argc == 0)
889 list_only |= 1;
d9c7edf6 890
57dee64e 891 send_filter_list(read_batch ? -1 : f_out);
d9c7edf6 892
7c2a9e76
WD
893 if (filesfrom_fd >= 0) {
894 io_set_filesfrom_fds(filesfrom_fd, f_out);
895 filesfrom_fd = -1;
896 }
897
e8a96e27 898 if (write_batch && !am_server)
b9f592fb 899 start_write_batch(f_in);
9486289c 900 flist = recv_file_list(f_in);
a00628b3 901 the_file_list = flist;
d9c7edf6 902
9d19f8a5
WD
903 if (flist && flist->count > 0) {
904 local_name = get_local_name(flist, argv[0]);
d9c7edf6 905
84e6d6fd 906 exit_code2 = do_recv(f_in, f_out, flist, local_name);
9d19f8a5
WD
907 } else {
908 handle_stats(-1);
909 output_summary();
910 }
d9c7edf6 911
9486289c 912 if (pid != -1) {
8d9dc9f9 913 if (verbose > 3)
08a740ff 914 rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
f1e3656e 915 io_flush(FULL_FLUSH);
84e6d6fd 916 wait_process_with_flush(pid, &exit_code);
9486289c 917 }
d9c7edf6 918
84e6d6fd 919 return MAX(exit_code, exit_code2);
9486289c
AT
920}
921
7169bb4a
MP
922static int copy_argv (char *argv[])
923{
924 int i;
925
926 for (i = 0; argv[i]; i++) {
927 if (!(argv[i] = strdup(argv[i]))) {
928 rprintf (FERROR, "out of memory at %s(%d)\n",
929 __FILE__, __LINE__);
930 return RERR_MALLOC;
931 }
932 }
933
934 return 0;
935}
936
937
c1a04ecb 938/**
0ba48136
MP
939 * Start a client for either type of remote connection. Work out
940 * whether the arguments request a remote shell or rsyncd connection,
941 * and call the appropriate connection function, then run_client.
0b4af330
MP
942 *
943 * Calls either start_socket_client (for sockets) or do_cmd and
944 * client_run (for ssh).
c1a04ecb 945 **/
fc8a6b97 946static int start_client(int argc, char *argv[])
5d6bcd44
AT
947{
948 char *p;
949 char *shell_machine = NULL;
950 char *shell_path = NULL;
951 char *shell_user = NULL;
19b27a48
AT
952 int ret;
953 pid_t pid;
5d6bcd44 954 int f_in,f_out;
7169bb4a
MP
955 int rc;
956
957 /* Don't clobber argv[] so that ps(1) can still show the right
d9c7edf6 958 * command line. */
75aeac44 959 if ((rc = copy_argv(argv)))
7169bb4a 960 return rc;
5d6bcd44 961
d16c245f 962 if (!read_batch) { /* for read_batch, NO source is specified */
42ccb4c0 963 argc--;
860236bf
WD
964 shell_path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
965 if (shell_path) { /* source is remote */
9425918d
WD
966 char *dummy1;
967 int dummy2;
3f7bfac2 968 if (argc && check_for_hostspec(argv[argc], &dummy1, &dummy2)) {
9425918d
WD
969 rprintf(FERROR,
970 "The source and destination cannot both be remote.\n");
971 exit_cleanup(RERR_SYNTAX);
972 }
42ccb4c0 973 argv++;
860236bf
WD
974 if (filesfrom_host && *filesfrom_host
975 && strcmp(filesfrom_host, shell_machine) != 0) {
7c2a9e76 976 rprintf(FERROR,
50b31539 977 "--files-from hostname is not the same as the transfer hostname\n");
7c2a9e76
WD
978 exit_cleanup(RERR_SYNTAX);
979 }
860236bf 980 if (rsync_port) {
d9c7edf6 981 if (!shell_cmd) {
860236bf
WD
982 return start_socket_client(shell_machine,
983 shell_path,
42ccb4c0 984 argc, argv);
d9c7edf6 985 }
d9c7edf6 986 daemon_over_rsh = 1;
75aeac44 987 }
3591c066 988
42ccb4c0
WD
989 am_sender = 0;
990 } else { /* source is local, check dest arg */
991 am_sender = 1;
992
d16c245f 993 if (argc < 1) { /* destination required */
d9c7edf6
WD
994 usage(FERROR);
995 exit_cleanup(RERR_SYNTAX);
996 }
a125c82a 997
42ccb4c0 998 shell_path = check_for_hostspec(argv[argc], &shell_machine, &rsync_port);
860236bf
WD
999 if (shell_path && filesfrom_host && *filesfrom_host
1000 && strcmp(filesfrom_host, shell_machine) != 0) {
7c2a9e76 1001 rprintf(FERROR,
50b31539 1002 "--files-from hostname is not the same as the transfer hostname\n");
7c2a9e76
WD
1003 exit_cleanup(RERR_SYNTAX);
1004 }
860236bf 1005 if (!shell_path) { /* no hostspec found, so src & dest are local */
d9c7edf6 1006 local_server = 1;
860236bf 1007 if (filesfrom_host) {
7c2a9e76 1008 rprintf(FERROR,
50b31539 1009 "--files-from cannot be remote when the transfer is local\n");
7c2a9e76
WD
1010 exit_cleanup(RERR_SYNTAX);
1011 }
860236bf 1012 shell_machine = NULL;
42ccb4c0 1013 shell_path = argv[argc];
860236bf 1014 } else if (rsync_port) {
d9c7edf6 1015 if (!shell_cmd) {
860236bf
WD
1016 return start_socket_client(shell_machine,
1017 shell_path,
42ccb4c0 1018 argc, argv);
d9c7edf6 1019 }
d9c7edf6 1020 daemon_over_rsh = 1;
a125c82a 1021 }
5d6bcd44 1022 }
d16c245f 1023 } else { /* read_batch */
d9c7edf6
WD
1024 local_server = 1;
1025 shell_path = argv[argc-1];
860236bf 1026 if (check_for_hostspec(shell_path, &shell_machine, &rsync_port)) {
b9f592fb
WD
1027 rprintf(FERROR, "remote destination is not allowed with --read-batch\n");
1028 exit_cleanup(RERR_SYNTAX);
1029 }
6902ed17
MP
1030 }
1031
5d6bcd44 1032 if (shell_machine) {
6fc048f4 1033 p = strrchr(shell_machine,'@');
5d6bcd44
AT
1034 if (p) {
1035 *p = 0;
1036 shell_user = shell_machine;
1037 shell_machine = p+1;
1038 }
1039 }
1040
1041 if (verbose > 3) {
9486289c 1042 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
45c49b52
WD
1043 shell_cmd ? shell_cmd : "",
1044 shell_machine ? shell_machine : "",
1045 shell_user ? shell_user : "",
1046 shell_path ? shell_path : "");
5d6bcd44 1047 }
d9c7edf6 1048
d16c245f 1049 /* for remote source, only single dest arg can remain ... */
f7632fc6 1050 if (!am_sender && argc > 1) {
5d6bcd44 1051 usage(FERROR);
65417579 1052 exit_cleanup(RERR_SYNTAX);
5d6bcd44 1053 }
27e3e9c9 1054
d16c245f 1055 /* ... or no dest at all */
48a1ff0d
WD
1056 if (!am_sender && argc == 0)
1057 list_only |= 1;
d9c7edf6 1058
75aeac44
WD
1059 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
1060 &f_in,&f_out);
1061
1062 /* if we're running an rsync server on the remote host over a
9af87151 1063 * remote shell command, we need to do the RSYNCD protocol first */
75aeac44
WD
1064 if (daemon_over_rsh) {
1065 int tmpret;
1066 tmpret = start_inband_exchange(shell_user, shell_path,
1067 f_in, f_out, argc);
1068 if (tmpret < 0)
1069 return tmpret;
1070 }
1071
fc8a6b97
AT
1072 ret = client_run(f_in, f_out, pid, argc, argv);
1073
1074 fflush(stdout);
1075 fflush(stderr);
1076
1077 return ret;
5d6bcd44
AT
1078}
1079
366345fe 1080
067669da
WD
1081static RETSIGTYPE sigusr1_handler(UNUSED(int val))
1082{
6bf32edb 1083 exit_cleanup(RERR_SIGNAL1);
82306bf6
AT
1084}
1085
067669da
WD
1086static RETSIGTYPE sigusr2_handler(UNUSED(int val))
1087{
33c4b445
WD
1088 if (!am_server)
1089 output_summary();
40df65fd 1090 close_all();
33c4b445
WD
1091 if (log_got_error)
1092 _exit(RERR_PARTIAL);
8b35435f
AT
1093 _exit(0);
1094}
1095
6d59ac19 1096RETSIGTYPE remember_children(UNUSED(int val))
067669da 1097{
029c1713 1098#ifdef WNOHANG
ee7118a8
DD
1099 int cnt, status;
1100 pid_t pid;
1101 /* An empty waitpid() loop was put here by Tridge and we could never
d9c7edf6 1102 * get him to explain why he put it in, so rather than taking it
ee7118a8
DD
1103 * out we're instead saving the child exit statuses for later use.
1104 * The waitpid() loop presumably eliminates all possibility of leaving
97d8e709 1105 * zombie children, maybe that's why he did it. */
ee7118a8 1106 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
9af87151
WD
1107 /* save the child's exit status */
1108 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
1109 if (pid_stat_table[cnt].pid == 0) {
1110 pid_stat_table[cnt].pid = pid;
1111 pid_stat_table[cnt].status = status;
1112 break;
1113 }
1114 }
ee7118a8 1115 }
029c1713 1116#endif
8261af74 1117#ifndef HAVE_SIGACTION
6d59ac19 1118 signal(SIGCHLD, remember_children);
60ee01f5 1119#endif
19b27a48
AT
1120}
1121
c0531332
MP
1122
1123/**
1124 * This routine catches signals and tries to send them to gdb.
1125 *
1126 * Because it's called from inside a signal handler it ought not to
1127 * use too many library routines.
1128 *
1129 * @todo Perhaps use "screen -X" instead/as well, to help people
1130 * debugging without easy access to X. Perhaps use an environment
1131 * variable, or just call a script?
1132 *
1133 * @todo The /proc/ magic probably only works on Linux (and
1134 * Solaris?) Can we be more portable?
1135 **/
1136#ifdef MAINTAINER_MODE
4fdc39dd
MP
1137const char *get_panic_action(void)
1138{
1139 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
1140
1141 if (cmd_fmt)
1142 return cmd_fmt;
1143 else
1144 return "xterm -display :0 -T Panic -n Panic "
1145 "-e gdb /proc/%d/exe %d";
1146}
1147
1148
9fb3f7a9
MP
1149/**
1150 * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
1151 *
1152 * This signal handler is only installed if we were configured with
1153 * --enable-maintainer-mode. Perhaps it should always be on and we
1154 * should just look at the environment variable, but I'm a bit leery
1155 * of a signal sending us into a busy loop.
1156 **/
067669da 1157static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
c0531332
MP
1158{
1159 char cmd_buf[300];
1160 int ret;
4fdc39dd
MP
1161
1162 sprintf(cmd_buf, get_panic_action(),
c0531332
MP
1163 getpid(), getpid());
1164
1165 /* Unless we failed to execute gdb, we allow the process to
1166 * continue. I'm not sure if that's right. */
1167 ret = system(cmd_buf);
1168 if (ret)
1169 _exit(ret);
1170}
1171#endif
1172
1173
5d6bcd44 1174int main(int argc,char *argv[])
d9c7edf6 1175{
ff81e809 1176 int ret;
66a9dc96
WD
1177 int orig_argc = argc;
1178 char **orig_argv = argv;
8261af74
WD
1179#ifdef HAVE_SIGACTION
1180# ifdef HAVE_SIGPROCMASK
60ee01f5 1181 sigset_t sigmask;
5d6bcd44 1182
60ee01f5 1183 sigemptyset(&sigmask);
8261af74 1184# endif
60ee01f5
WD
1185 sigact.sa_flags = SA_NOCLDSTOP;
1186#endif
1187 SIGACTMASK(SIGUSR1, sigusr1_handler);
1188 SIGACTMASK(SIGUSR2, sigusr2_handler);
6d59ac19 1189 SIGACTMASK(SIGCHLD, remember_children);
c0531332 1190#ifdef MAINTAINER_MODE
60ee01f5
WD
1191 SIGACTMASK(SIGSEGV, rsync_panic_handler);
1192 SIGACTMASK(SIGFPE, rsync_panic_handler);
1193 SIGACTMASK(SIGABRT, rsync_panic_handler);
1194 SIGACTMASK(SIGBUS, rsync_panic_handler);
1195#endif
5d6bcd44 1196
7a6421fa 1197 starttime = time(NULL);
6fe05820 1198 am_root = (MY_UID() == 0);
c627d613 1199
a800434a
AT
1200 memset(&stats, 0, sizeof(stats));
1201
df5e03da
AT
1202 if (argc < 2) {
1203 usage(FERROR);
65417579 1204 exit_cleanup(RERR_SYNTAX);
df5e03da
AT
1205 }
1206
7a6421fa 1207 /* we set a 0 umask so that correct file permissions can be
9af87151 1208 * carried across */
7a6421fa 1209 orig_umask = (int)umask(0);
5d6bcd44 1210
eb598fac
WD
1211#if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
1212 setlocale(LC_CTYPE, "");
1213#endif
1214
50135767 1215 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
d9c7edf6
WD
1216 /* FIXME: We ought to call the same error-handling
1217 * code here, rather than relying on getopt. */
50135767 1218 option_error();
65417579 1219 exit_cleanup(RERR_SYNTAX);
b11ed3b1 1220 }
5d6bcd44 1221
60ee01f5
WD
1222 SIGACTMASK(SIGINT, sig_int);
1223 SIGACTMASK(SIGHUP, sig_int);
1224 SIGACTMASK(SIGTERM, sig_int);
1225#if defined HAVE_SIGACTION && HAVE_SIGPROCMASK
1226 sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
1227#endif
6b83141d 1228
34758d5c
MP
1229 /* Ignore SIGPIPE; we consistently check error codes and will
1230 * see the EPIPE. */
60ee01f5 1231 SIGACTION(SIGPIPE, SIG_IGN);
55e54e46
WD
1232#ifdef SIGXFSZ
1233 SIGACTION(SIGXFSZ, SIG_IGN);
1234#endif
34758d5c 1235
c226b7c2 1236 /* Initialize push_dir here because on some old systems getcwd
9af87151
WD
1237 * (implemented by forking "pwd" and reading its output) doesn't
1238 * work when there are other child processes. Also, on all systems
1239 * that implement getcwd that way "pwd" can't be found after chroot. */
59187666 1240 push_dir(NULL);
c226b7c2 1241
44e9e221
WD
1242 init_flist();
1243
e8a96e27 1244 if ((write_batch || read_batch) && !am_server) {
b9f592fb 1245 if (write_batch)
66a9dc96 1246 write_batch_shell_file(orig_argc, orig_argv, argc);
b9f592fb 1247
dbbab0c4
WD
1248 if (read_batch && strcmp(batch_name, "-") == 0)
1249 batch_fd = STDIN_FILENO;
1250 else {
1251 batch_fd = do_open(batch_name,
b9f592fb
WD
1252 write_batch ? O_WRONLY | O_CREAT | O_TRUNC
1253 : O_RDONLY, S_IRUSR | S_IWUSR);
dbbab0c4 1254 }
b9f592fb
WD
1255 if (batch_fd < 0) {
1256 rsyserr(FERROR, errno, "Batch file %s open error",
71903f60 1257 full_fname(batch_name));
b9f592fb
WD
1258 exit_cleanup(RERR_FILEIO);
1259 }
9459290a
WD
1260 if (read_batch)
1261 read_stream_flags(batch_fd);
6902ed17 1262 }
e8a96e27
WD
1263 if (write_batch < 0)
1264 dry_run = 1;
6902ed17 1265
75aeac44 1266 if (am_daemon && !am_server)
7a6421fa 1267 return daemon_main();
f0fca04e 1268
08ac228f
AT
1269 if (argc < 1) {
1270 usage(FERROR);
65417579 1271 exit_cleanup(RERR_SYNTAX);
08ac228f
AT
1272 }
1273
7a6421fa 1274 if (am_server) {
f0359dd0
AT
1275 set_nonblocking(STDIN_FILENO);
1276 set_nonblocking(STDOUT_FILENO);
75aeac44
WD
1277 if (am_daemon)
1278 return start_daemon(STDIN_FILENO, STDOUT_FILENO);
7a6421fa
AT
1279 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
1280 }
c627d613 1281
ff81e809 1282 ret = start_client(argc, argv);
d9c7edf6 1283 if (ret == -1)
9098bbf3 1284 exit_cleanup(RERR_STARTCLIENT);
088aac85 1285 else
9098bbf3
MP
1286 exit_cleanup(ret);
1287
0f5a04e3 1288 return ret;
c627d613 1289}