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