- Got rid of unused externs.
[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;
bb6721dc 43extern int copy_links;
83926d3c 44extern int keep_dirlinks;
32eda096 45extern int preserve_hard_links;
d04e9c51 46extern int protocol_version;
32eda096
WD
47extern int recurse;
48extern int relative_paths;
49extern int rsync_port;
b1df18d7 50extern int whole_file;
32eda096
WD
51extern int read_batch;
52extern int write_batch;
b9f592fb 53extern int batch_fd;
c0d8e84c 54extern int batch_gen_fd;
32eda096
WD
55extern int filesfrom_fd;
56extern pid_t cleanup_child_pid;
50839b4b 57extern struct stats stats;
860236bf 58extern char *filesfrom_host;
32eda096
WD
59extern char *rsync_path;
60extern char *shell_cmd;
9b3318b0 61extern char *batch_name;
57dee64e
WD
62
63int local_server = 0;
05278935 64mode_t orig_umask = 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
ee8e2b15 460 if (!dest_path || list_only)
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
05278935 494 if (mkdir_defmode(dest_path) != 0) {
eb598fac
WD
495 rsyserr(FERROR, errno, "mkdir %s failed",
496 full_fname(dest_path));
497 exit_cleanup(RERR_FILEIO);
498 }
1ff5450d 499
eb598fac
WD
500 if (verbose)
501 rprintf(FINFO, "created directory %s\n", dest_path);
502
503 if (dry_run) {
504 /* Indicate that the destination directory doesn't
505 * really exist and return mode 1. */
506 dry_run++;
507 return NULL;
508 }
509
510 if (!push_dir(dest_path)) {
511 rsyserr(FERROR, errno, "push_dir#2 %s failed",
512 full_fname(dest_path));
513 exit_cleanup(RERR_FILESELECT);
514 }
e5a96f0f 515
e5a96f0f 516 return NULL;
1ff5450d
AT
517 }
518
eb598fac
WD
519 /* Otherwise, we are writing a single file, possibly on top of an
520 * existing non-directory. Change to the item's parent directory
521 * (if it has a path component), return the basename of the
522 * destination file as the local name, and use mode 2. */
523 if (!cp)
524 return dest_path;
525
526 if (cp == dest_path)
527 dest_path = "/";
528
529 *cp = '\0';
530 if (!push_dir(dest_path)) {
531 rsyserr(FERROR, errno, "push_dir#3 %s failed",
532 full_fname(dest_path));
65417579 533 exit_cleanup(RERR_FILESELECT);
1ff5450d 534 }
eb598fac 535 *cp = '/';
1ff5450d 536
eb598fac 537 return cp + 1;
c627d613
AT
538}
539
540
1a8e5c97 541/* This is only called by the sender. */
3485ae83 542static void read_final_goodbye(int f_in, int f_out)
4e0fcd85 543{
1a8e5c97
WD
544 int i;
545
546 if (protocol_version < 29)
547 i = read_int(f_in);
548 else {
3485ae83 549 while ((i = read_int(f_in)) == the_file_list->count
1a8e5c97
WD
550 && read_shortint(f_in) == ITEM_IS_NEW) {
551 /* Forward the keep-alive (no-op) to the receiver. */
3485ae83 552 write_int(f_out, the_file_list->count);
1a8e5c97
WD
553 write_shortint(f_out, ITEM_IS_NEW);
554 }
4e0fcd85
WD
555 }
556
1a8e5c97 557 if (i != -1) {
c7791b8c
WD
558 rprintf(FERROR, "Invalid packet at end of run (%d) [%s]\n",
559 i, who_am_i());
1a8e5c97 560 exit_cleanup(RERR_PROTOCOL);
4e0fcd85
WD
561 }
562}
563
564
eb598fac 565static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
c627d613 566{
7a6421fa
AT
567 struct file_list *flist;
568 char *dir = argv[0];
c627d613 569
45e08edb
WD
570 if (verbose > 2) {
571 rprintf(FINFO, "server_sender starting pid=%ld\n",
572 (long)getpid());
573 }
d9c7edf6 574
2adbcdc7 575 if (am_daemon && lp_write_only(module_id)) {
7a92ded3
WD
576 rprintf(FERROR, "ERROR: module is write only\n");
577 exit_cleanup(RERR_SYNTAX);
578 return;
579 }
bf26aa22
WD
580 if (am_daemon && lp_read_only(module_id) && remove_sent_files) {
581 rprintf(FERROR,
582 "ERROR: --remove-sent-files cannot be used with a read-only module\n");
583 exit_cleanup(RERR_SYNTAX);
584 return;
585 }
7a92ded3 586
59187666 587 if (!relative_paths && !push_dir(dir)) {
982e05bb
WD
588 rsyserr(FERROR, errno, "push_dir#3 %s failed",
589 full_fname(dir));
65417579 590 exit_cleanup(RERR_FILESELECT);
7a6421fa
AT
591 }
592 argc--;
593 argv++;
d9c7edf6 594
48a1ff0d 595 if (argc == 0 && (recurse || list_only)) {
e1f67417 596 argc = 1;
7a6421fa
AT
597 argv--;
598 argv[0] = ".";
599 }
d9c7edf6 600
7a6421fa 601 flist = send_file_list(f_out,argc,argv);
8d9dc9f9
AT
602 if (!flist || flist->count == 0) {
603 exit_cleanup(0);
604 }
a00628b3 605 the_file_list = flist;
8d9dc9f9 606
da3478b2
WD
607 io_start_buffering_in();
608 io_start_buffering_out();
609
7a6421fa 610 send_files(flist,f_out,f_in);
f1e3656e 611 io_flush(FULL_FLUSH);
33c4b445 612 handle_stats(f_out);
4e0fcd85 613 if (protocol_version >= 24)
3485ae83 614 read_final_goodbye(f_in, f_out);
f1e3656e 615 io_flush(FULL_FLUSH);
7a6421fa 616 exit_cleanup(0);
c627d613
AT
617}
618
619
dc5ddbcc
AT
620static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
621{
d186eb1a 622 int pid;
84e6d6fd 623 int exit_code = 0;
c70e07d9 624 int error_pipe[2];
dc5ddbcc 625
bb6721dc
WD
626 /* The receiving side mustn't obey this, or an existing symlink that
627 * points to an identical file won't be replaced by the referent. */
628 copy_links = 0;
629
d186eb1a 630 if (preserve_hard_links)
3485ae83 631 init_hard_links();
dc5ddbcc 632
c70e07d9 633 if (fd_pair(error_pipe) < 0) {
ab759cd2 634 rsyserr(FERROR, errno, "pipe failed in do_recv");
c8f2f857 635 exit_cleanup(RERR_IPC);
554e0a8d 636 }
d9c7edf6 637
f1e3656e 638 io_flush(NORMAL_FLUSH);
c6e7fcb4 639
ba449e44 640 if ((pid = do_fork()) == -1) {
c8f2f857 641 rsyserr(FERROR, errno, "fork failed in do_recv");
ba449e44
WD
642 exit_cleanup(RERR_IPC);
643 }
644
645 if (pid == 0) {
554e0a8d 646 close(error_pipe[0]);
3a69fad0
WD
647 if (f_in != f_out)
648 close(f_out);
e08c9610 649
554e0a8d 650 /* we can't let two processes write to the socket at one time */
9eeb3b9c 651 close_multiplexing_out();
554e0a8d
AT
652
653 /* set place to send errors */
f1e3656e 654 set_msg_fd_out(error_pipe[1]);
554e0a8d 655
c70e07d9 656 recv_files(f_in, flist, local_name);
f1e3656e 657 io_flush(FULL_FLUSH);
33c4b445 658 handle_stats(f_in);
e08c9610 659
f1e3656e
WD
660 send_msg(MSG_DONE, "", 0);
661 io_flush(FULL_FLUSH);
4e0fcd85 662
40df65fd
WD
663 /* Handle any keep-alive packets from the post-processing work
664 * that the generator does. */
4e0fcd85 665 if (protocol_version >= 29) {
051182cb 666 kluge_around_eof = -1;
1a8e5c97
WD
667
668 /* This should only get stopped via a USR2 signal. */
669 while (read_int(f_in) == flist->count
670 && read_shortint(f_in) == ITEM_IS_NEW) {}
671
3485ae83
WD
672 rprintf(FERROR, "Invalid packet at end of run [%s]\n",
673 who_am_i());
1a8e5c97 674 exit_cleanup(RERR_PROTOCOL);
4e0fcd85
WD
675 }
676
9e0582f9
WD
677 /* Finally, we go to sleep until our parent kills us with a
678 * USR2 signal. We sleep for a short time, as on some OSes
679 * a signal won't interrupt a sleep! */
f1e3656e
WD
680 while (1)
681 msleep(20);
d186eb1a 682 }
dc5ddbcc 683
b695f242 684 am_generator = 1;
9eeb3b9c 685 close_multiplexing_in();
e8a96e27 686 if (write_batch && !am_server)
b9f592fb 687 stop_write_batch();
b695f242 688
554e0a8d 689 close(error_pipe[1]);
3a69fad0
WD
690 if (f_in != f_out)
691 close(f_in);
e1b3d5c4 692
da3478b2 693 io_start_buffering_out();
b3e10ed7 694
f1e3656e 695 set_msg_fd_in(error_pipe[0]);
554e0a8d 696
c70e07d9 697 generate_files(f_out, flist, local_name);
8d9dc9f9 698
33c4b445 699 handle_stats(-1);
f1e3656e 700 io_flush(FULL_FLUSH);
d04e9c51 701 if (protocol_version >= 24) {
8ada7518
AT
702 /* send a final goodbye message */
703 write_int(f_out, -1);
704 }
f1e3656e 705 io_flush(FULL_FLUSH);
8ada7518 706
f1e3656e 707 set_msg_fd_in(-1);
089a2435 708 kill(pid, SIGUSR2);
84e6d6fd
WD
709 wait_process_with_flush(pid, &exit_code);
710 return exit_code;
dc5ddbcc
AT
711}
712
c627d613 713
9486289c 714static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
c627d613 715{
84e6d6fd 716 int exit_code;
7a6421fa 717 struct file_list *flist;
6c2e5b56 718 char *local_name = NULL;
7a6421fa 719 char *dir = NULL;
07bff66f
WD
720 int save_verbose = verbose;
721
722 if (filesfrom_fd >= 0) {
723 /* We can't mix messages with files-from data on the socket,
724 * so temporarily turn off verbose messages. */
725 verbose = 0;
726 }
f0fca04e 727
45e08edb
WD
728 if (verbose > 2) {
729 rprintf(FINFO, "server_recv(%d) starting pid=%ld\n",
730 argc, (long)getpid());
731 }
09b7f5db 732
2adbcdc7 733 if (am_daemon && lp_read_only(module_id)) {
09b7f5db
AT
734 rprintf(FERROR,"ERROR: module is read only\n");
735 exit_cleanup(RERR_SYNTAX);
736 return;
737 }
738
7a6421fa
AT
739 if (argc > 0) {
740 dir = argv[0];
741 argc--;
742 argv++;
59187666 743 if (!am_daemon && !push_dir(dir)) {
982e05bb
WD
744 rsyserr(FERROR, errno, "push_dir#4 %s failed",
745 full_fname(dir));
65417579 746 exit_cleanup(RERR_FILESELECT);
d9c7edf6 747 }
7a6421fa 748 }
c627d613 749
da3478b2 750 io_start_buffering_in();
57dee64e 751 recv_filter_list(f_in);
c627d613 752
7c2a9e76 753 if (filesfrom_fd >= 0) {
07bff66f
WD
754 /* We need to send the files-from names to the sender at the
755 * same time that we receive the file-list from them, so we
756 * need the IO routines to automatically write out the names
757 * onto our f_out socket as we read the file-list. This
758 * avoids both deadlock and extra delays/buffers. */
7c2a9e76
WD
759 io_set_filesfrom_fds(filesfrom_fd, f_out);
760 filesfrom_fd = -1;
761 }
762
b9f592fb 763 flist = recv_file_list(f_in);
07bff66f 764 verbose = save_verbose;
4c36a13e
AT
765 if (!flist) {
766 rprintf(FERROR,"server_recv: recv_file_list error\n");
65417579 767 exit_cleanup(RERR_FILESELECT);
7a6421fa 768 }
a00628b3 769 the_file_list = flist;
d9c7edf6 770
29fad7a3 771 if (argc > 0)
7a6421fa 772 local_name = get_local_name(flist,argv[0]);
c627d613 773
84e6d6fd
WD
774 exit_code = do_recv(f_in,f_out,flist,local_name);
775 exit_cleanup(exit_code);
c627d613
AT
776}
777
778
734a94a2 779int child_main(int argc, char *argv[])
25d34a5c
MP
780{
781 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
734a94a2 782 return 0;
25d34a5c
MP
783}
784
785
9486289c 786void start_server(int f_in, int f_out, int argc, char *argv[])
366345fe 787{
f0359dd0
AT
788 set_nonblocking(f_in);
789 set_nonblocking(f_out);
790
da3478b2
WD
791 io_set_sock_fds(f_in, f_out);
792 setup_protocol(f_out, f_in);
595251de 793#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
9656de5d
WD
794 setup_iconv();
795#endif
da3478b2 796
d04e9c51 797 if (protocol_version >= 23)
da3478b2 798 io_start_multiplex_out();
7a6421fa 799
7a6421fa 800 if (am_sender) {
83926d3c 801 keep_dirlinks = 0; /* Must be disabled on the sender. */
bf26aa22
WD
802 if (need_messages_from_generator)
803 io_start_multiplex_in();
9b3318b0 804
7842418b 805 recv_filter_list(f_in);
7a6421fa
AT
806 do_server_sender(f_in, f_out, argc, argv);
807 } else {
808 do_server_recv(f_in, f_out, argc, argv);
809 }
810 exit_cleanup(0);
366345fe
AT
811}
812
0ba48136
MP
813
814/*
815 * This is called once the connection has been negotiated. It is used
816 * for rsyncd, remote-shell, and local connections.
817 */
19b27a48 818int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
9486289c 819{
088aac85 820 struct file_list *flist = NULL;
84e6d6fd 821 int exit_code = 0, exit_code2 = 0;
9486289c 822 char *local_name = NULL;
19b27a48
AT
823
824 cleanup_child_pid = pid;
67a28eb2 825 if (!read_batch) {
b9f592fb
WD
826 set_nonblocking(f_in);
827 set_nonblocking(f_out);
828 }
f0359dd0 829
da3478b2 830 io_set_sock_fds(f_in, f_out);
6d7b6081 831 setup_protocol(f_out,f_in);
595251de 832#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
9656de5d
WD
833 setup_iconv();
834#endif
6d7b6081 835
b9f592fb 836 if (protocol_version >= 23 && !read_batch)
da3478b2 837 io_start_multiplex_in();
d9c7edf6 838
18882701
WD
839 /* We set our stderr file handle to blocking because ssh might have
840 * set it to non-blocking. This can be particularly troublesome if
841 * stderr is a clone of stdout, because ssh would have set our stdout
842 * to non-blocking at the same time (which can easily cause us to lose
843 * output from our print statements). This kluge shouldn't cause ssh
844 * any problems for how we use it. Note also that we delayed setting
845 * this until after the above protocol setup so that we know for sure
846 * that ssh is done twiddling its file descriptors. */
847 set_blocking(STDERR_FILENO);
848
9486289c 849 if (am_sender) {
83926d3c 850 keep_dirlinks = 0; /* Must be disabled on the sender. */
da3478b2 851 io_start_buffering_out();
860236bf 852 if (!filesfrom_host)
a0a33ee5 853 set_msg_fd_in(f_in);
57dee64e 854 send_filter_list(f_out);
860236bf 855 if (filesfrom_host)
7c2a9e76 856 filesfrom_fd = f_in;
b9f592fb 857
e8a96e27 858 if (write_batch && !am_server)
b9f592fb 859 start_write_batch(f_out);
a00628b3 860 flist = send_file_list(f_out, argc, argv);
a0a33ee5 861 set_msg_fd_in(-1);
d9c7edf6 862 if (verbose > 3)
9486289c 863 rprintf(FINFO,"file list sent\n");
a00628b3 864 the_file_list = flist;
e1b3d5c4 865
f1e3656e 866 io_flush(NORMAL_FLUSH);
9486289c 867 send_files(flist,f_out,f_in);
f1e3656e 868 io_flush(FULL_FLUSH);
33c4b445 869 handle_stats(-1);
4e0fcd85 870 if (protocol_version >= 24)
3485ae83 871 read_final_goodbye(f_in, f_out);
9486289c
AT
872 if (pid != -1) {
873 if (verbose > 3)
08a740ff 874 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
f1e3656e 875 io_flush(FULL_FLUSH);
84e6d6fd 876 wait_process_with_flush(pid, &exit_code);
9486289c 877 }
33c4b445 878 output_summary();
c87ae64a 879 io_flush(FULL_FLUSH);
84e6d6fd 880 exit_cleanup(exit_code);
9486289c 881 }
f7632fc6 882
bf26aa22
WD
883 if (need_messages_from_generator && !read_batch)
884 io_start_multiplex_out();
885
48a1ff0d
WD
886 if (argc == 0)
887 list_only |= 1;
d9c7edf6 888
57dee64e 889 send_filter_list(read_batch ? -1 : f_out);
d9c7edf6 890
7c2a9e76
WD
891 if (filesfrom_fd >= 0) {
892 io_set_filesfrom_fds(filesfrom_fd, f_out);
893 filesfrom_fd = -1;
894 }
895
e8a96e27 896 if (write_batch && !am_server)
b9f592fb 897 start_write_batch(f_in);
9486289c 898 flist = recv_file_list(f_in);
a00628b3 899 the_file_list = flist;
d9c7edf6 900
9d19f8a5
WD
901 if (flist && flist->count > 0) {
902 local_name = get_local_name(flist, argv[0]);
d9c7edf6 903
84e6d6fd 904 exit_code2 = do_recv(f_in, f_out, flist, local_name);
9d19f8a5
WD
905 } else {
906 handle_stats(-1);
907 output_summary();
908 }
d9c7edf6 909
9486289c 910 if (pid != -1) {
8d9dc9f9 911 if (verbose > 3)
08a740ff 912 rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
f1e3656e 913 io_flush(FULL_FLUSH);
84e6d6fd 914 wait_process_with_flush(pid, &exit_code);
9486289c 915 }
d9c7edf6 916
84e6d6fd 917 return MAX(exit_code, exit_code2);
9486289c
AT
918}
919
7169bb4a
MP
920static int copy_argv (char *argv[])
921{
922 int i;
923
924 for (i = 0; argv[i]; i++) {
925 if (!(argv[i] = strdup(argv[i]))) {
926 rprintf (FERROR, "out of memory at %s(%d)\n",
927 __FILE__, __LINE__);
928 return RERR_MALLOC;
929 }
930 }
931
932 return 0;
933}
934
935
c1a04ecb 936/**
0ba48136
MP
937 * Start a client for either type of remote connection. Work out
938 * whether the arguments request a remote shell or rsyncd connection,
939 * and call the appropriate connection function, then run_client.
0b4af330
MP
940 *
941 * Calls either start_socket_client (for sockets) or do_cmd and
942 * client_run (for ssh).
c1a04ecb 943 **/
fc8a6b97 944static int start_client(int argc, char *argv[])
5d6bcd44
AT
945{
946 char *p;
947 char *shell_machine = NULL;
948 char *shell_path = NULL;
949 char *shell_user = NULL;
19b27a48
AT
950 int ret;
951 pid_t pid;
5d6bcd44 952 int f_in,f_out;
7169bb4a
MP
953 int rc;
954
955 /* Don't clobber argv[] so that ps(1) can still show the right
d9c7edf6 956 * command line. */
75aeac44 957 if ((rc = copy_argv(argv)))
7169bb4a 958 return rc;
5d6bcd44 959
d16c245f 960 if (!read_batch) { /* for read_batch, NO source is specified */
860236bf
WD
961 shell_path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
962 if (shell_path) { /* source is remote */
9425918d
WD
963 char *dummy1;
964 int dummy2;
ee8e2b15
WD
965 if (--argc
966 && check_for_hostspec(argv[argc], &dummy1, &dummy2)) {
9425918d
WD
967 rprintf(FERROR,
968 "The source and destination cannot both be remote.\n");
969 exit_cleanup(RERR_SYNTAX);
970 }
42ccb4c0 971 argv++;
860236bf
WD
972 if (filesfrom_host && *filesfrom_host
973 && strcmp(filesfrom_host, shell_machine) != 0) {
7c2a9e76 974 rprintf(FERROR,
50b31539 975 "--files-from hostname is not the same as the transfer hostname\n");
7c2a9e76
WD
976 exit_cleanup(RERR_SYNTAX);
977 }
860236bf 978 if (rsync_port) {
d9c7edf6 979 if (!shell_cmd) {
860236bf
WD
980 return start_socket_client(shell_machine,
981 shell_path,
42ccb4c0 982 argc, argv);
d9c7edf6 983 }
d9c7edf6 984 daemon_over_rsh = 1;
75aeac44 985 }
3591c066 986
42ccb4c0
WD
987 am_sender = 0;
988 } else { /* source is local, check dest arg */
989 am_sender = 1;
990
ee8e2b15
WD
991 if (argc > 1)
992 p = argv[--argc];
993 else {
994 p = ".";
995 list_only = 1;
d9c7edf6 996 }
a125c82a 997
ee8e2b15 998 shell_path = check_for_hostspec(p, &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;
ee8e2b15 1013 shell_path = p;
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 */
05278935 1209 orig_umask = 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}