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