Tweaked some whitespace to match the latest version from autoconf.
[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 }
44c26bf2
WD
483 /* Caution: flist->count could be 0! */
484 if (flist->count == 1 && S_ISDIR(flist->files[0]->mode)) {
485 rprintf(FERROR,
486 "ERROR: cannot overwrite non-directory"
487 " with a directory\n");
488 exit_cleanup(RERR_FILESELECT);
489 }
cc8c5057
WD
490 } else if (errno != ENOENT) {
491 rsyserr(FERROR, errno, "cannot stat destination %s",
492 full_fname(dest_path));
493 exit_cleanup(RERR_FILESELECT);
1ff5450d
AT
494 }
495
eb598fac
WD
496 cp = strrchr(dest_path, '/');
497
498 /* If the destination path ends in a slash or we are transferring
499 * multiple files, create a directory at the destination path,
500 * enter the new directory, and use mode 1. */
501 if (flist->count > 1 || (cp && !cp[1])) {
502 /* Lop off the final slash (if any). */
503 if (cp && !cp[1])
504 *cp = '\0';
505
05278935 506 if (mkdir_defmode(dest_path) != 0) {
eb598fac
WD
507 rsyserr(FERROR, errno, "mkdir %s failed",
508 full_fname(dest_path));
509 exit_cleanup(RERR_FILEIO);
510 }
1ff5450d 511
eb598fac
WD
512 if (verbose)
513 rprintf(FINFO, "created directory %s\n", dest_path);
514
515 if (dry_run) {
516 /* Indicate that the destination directory doesn't
517 * really exist and return mode 1. */
518 dry_run++;
519 return NULL;
520 }
521
522 if (!push_dir(dest_path)) {
523 rsyserr(FERROR, errno, "push_dir#2 %s failed",
524 full_fname(dest_path));
525 exit_cleanup(RERR_FILESELECT);
526 }
e5a96f0f 527
e5a96f0f 528 return NULL;
1ff5450d
AT
529 }
530
eb598fac
WD
531 /* Otherwise, we are writing a single file, possibly on top of an
532 * existing non-directory. Change to the item's parent directory
533 * (if it has a path component), return the basename of the
534 * destination file as the local name, and use mode 2. */
535 if (!cp)
536 return dest_path;
537
538 if (cp == dest_path)
539 dest_path = "/";
540
541 *cp = '\0';
542 if (!push_dir(dest_path)) {
543 rsyserr(FERROR, errno, "push_dir#3 %s failed",
544 full_fname(dest_path));
65417579 545 exit_cleanup(RERR_FILESELECT);
1ff5450d 546 }
eb598fac 547 *cp = '/';
1ff5450d 548
eb598fac 549 return cp + 1;
c627d613
AT
550}
551
552
1a8e5c97 553/* This is only called by the sender. */
3485ae83 554static void read_final_goodbye(int f_in, int f_out)
4e0fcd85 555{
1a8e5c97
WD
556 int i;
557
558 if (protocol_version < 29)
559 i = read_int(f_in);
560 else {
3485ae83 561 while ((i = read_int(f_in)) == the_file_list->count
1a8e5c97
WD
562 && read_shortint(f_in) == ITEM_IS_NEW) {
563 /* Forward the keep-alive (no-op) to the receiver. */
3485ae83 564 write_int(f_out, the_file_list->count);
1a8e5c97
WD
565 write_shortint(f_out, ITEM_IS_NEW);
566 }
4e0fcd85
WD
567 }
568
1a8e5c97 569 if (i != -1) {
c7791b8c
WD
570 rprintf(FERROR, "Invalid packet at end of run (%d) [%s]\n",
571 i, who_am_i());
1a8e5c97 572 exit_cleanup(RERR_PROTOCOL);
4e0fcd85
WD
573 }
574}
575
576
eb598fac 577static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
c627d613 578{
7a6421fa
AT
579 struct file_list *flist;
580 char *dir = argv[0];
c627d613 581
45e08edb
WD
582 if (verbose > 2) {
583 rprintf(FINFO, "server_sender starting pid=%ld\n",
584 (long)getpid());
585 }
d9c7edf6 586
2adbcdc7 587 if (am_daemon && lp_write_only(module_id)) {
7a92ded3
WD
588 rprintf(FERROR, "ERROR: module is write only\n");
589 exit_cleanup(RERR_SYNTAX);
590 return;
591 }
bf26aa22
WD
592 if (am_daemon && lp_read_only(module_id) && remove_sent_files) {
593 rprintf(FERROR,
594 "ERROR: --remove-sent-files cannot be used with a read-only module\n");
595 exit_cleanup(RERR_SYNTAX);
596 return;
597 }
7a92ded3 598
59187666 599 if (!relative_paths && !push_dir(dir)) {
982e05bb
WD
600 rsyserr(FERROR, errno, "push_dir#3 %s failed",
601 full_fname(dir));
65417579 602 exit_cleanup(RERR_FILESELECT);
7a6421fa
AT
603 }
604 argc--;
605 argv++;
d9c7edf6 606
48a1ff0d 607 if (argc == 0 && (recurse || list_only)) {
e1f67417 608 argc = 1;
7a6421fa
AT
609 argv--;
610 argv[0] = ".";
611 }
d9c7edf6 612
7a6421fa 613 flist = send_file_list(f_out,argc,argv);
8d9dc9f9
AT
614 if (!flist || flist->count == 0) {
615 exit_cleanup(0);
616 }
a00628b3 617 the_file_list = flist;
8d9dc9f9 618
da3478b2
WD
619 io_start_buffering_in();
620 io_start_buffering_out();
621
7a6421fa 622 send_files(flist,f_out,f_in);
f1e3656e 623 io_flush(FULL_FLUSH);
33c4b445 624 handle_stats(f_out);
4e0fcd85 625 if (protocol_version >= 24)
3485ae83 626 read_final_goodbye(f_in, f_out);
f1e3656e 627 io_flush(FULL_FLUSH);
7a6421fa 628 exit_cleanup(0);
c627d613
AT
629}
630
631
dc5ddbcc
AT
632static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
633{
d186eb1a 634 int pid;
84e6d6fd 635 int exit_code = 0;
c70e07d9 636 int error_pipe[2];
dc5ddbcc 637
bb6721dc
WD
638 /* The receiving side mustn't obey this, or an existing symlink that
639 * points to an identical file won't be replaced by the referent. */
a695b379 640 copy_links = copy_dirlinks = 0;
bb6721dc 641
d186eb1a 642 if (preserve_hard_links)
3485ae83 643 init_hard_links();
dc5ddbcc 644
c70e07d9 645 if (fd_pair(error_pipe) < 0) {
ab759cd2 646 rsyserr(FERROR, errno, "pipe failed in do_recv");
c8f2f857 647 exit_cleanup(RERR_IPC);
554e0a8d 648 }
d9c7edf6 649
f1e3656e 650 io_flush(NORMAL_FLUSH);
c6e7fcb4 651
ba449e44 652 if ((pid = do_fork()) == -1) {
c8f2f857 653 rsyserr(FERROR, errno, "fork failed in do_recv");
ba449e44
WD
654 exit_cleanup(RERR_IPC);
655 }
656
657 if (pid == 0) {
554e0a8d 658 close(error_pipe[0]);
3a69fad0
WD
659 if (f_in != f_out)
660 close(f_out);
e08c9610 661
554e0a8d 662 /* we can't let two processes write to the socket at one time */
9eeb3b9c 663 close_multiplexing_out();
554e0a8d
AT
664
665 /* set place to send errors */
f1e3656e 666 set_msg_fd_out(error_pipe[1]);
554e0a8d 667
c70e07d9 668 recv_files(f_in, flist, local_name);
f1e3656e 669 io_flush(FULL_FLUSH);
33c4b445 670 handle_stats(f_in);
e08c9610 671
f1e3656e
WD
672 send_msg(MSG_DONE, "", 0);
673 io_flush(FULL_FLUSH);
4e0fcd85 674
40df65fd
WD
675 /* Handle any keep-alive packets from the post-processing work
676 * that the generator does. */
4e0fcd85 677 if (protocol_version >= 29) {
051182cb 678 kluge_around_eof = -1;
1a8e5c97
WD
679
680 /* This should only get stopped via a USR2 signal. */
681 while (read_int(f_in) == flist->count
682 && read_shortint(f_in) == ITEM_IS_NEW) {}
683
3485ae83
WD
684 rprintf(FERROR, "Invalid packet at end of run [%s]\n",
685 who_am_i());
1a8e5c97 686 exit_cleanup(RERR_PROTOCOL);
4e0fcd85
WD
687 }
688
9e0582f9
WD
689 /* Finally, we go to sleep until our parent kills us with a
690 * USR2 signal. We sleep for a short time, as on some OSes
691 * a signal won't interrupt a sleep! */
f1e3656e
WD
692 while (1)
693 msleep(20);
d186eb1a 694 }
dc5ddbcc 695
b695f242 696 am_generator = 1;
9eeb3b9c 697 close_multiplexing_in();
e8a96e27 698 if (write_batch && !am_server)
b9f592fb 699 stop_write_batch();
b695f242 700
554e0a8d 701 close(error_pipe[1]);
3a69fad0
WD
702 if (f_in != f_out)
703 close(f_in);
e1b3d5c4 704
da3478b2 705 io_start_buffering_out();
b3e10ed7 706
f1e3656e 707 set_msg_fd_in(error_pipe[0]);
554e0a8d 708
c70e07d9 709 generate_files(f_out, flist, local_name);
8d9dc9f9 710
33c4b445 711 handle_stats(-1);
f1e3656e 712 io_flush(FULL_FLUSH);
d04e9c51 713 if (protocol_version >= 24) {
8ada7518
AT
714 /* send a final goodbye message */
715 write_int(f_out, -1);
716 }
f1e3656e 717 io_flush(FULL_FLUSH);
8ada7518 718
f1e3656e 719 set_msg_fd_in(-1);
089a2435 720 kill(pid, SIGUSR2);
84e6d6fd
WD
721 wait_process_with_flush(pid, &exit_code);
722 return exit_code;
dc5ddbcc
AT
723}
724
c627d613 725
9486289c 726static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
c627d613 727{
84e6d6fd 728 int exit_code;
7a6421fa 729 struct file_list *flist;
6c2e5b56 730 char *local_name = NULL;
7a6421fa 731 char *dir = NULL;
07bff66f
WD
732 int save_verbose = verbose;
733
734 if (filesfrom_fd >= 0) {
735 /* We can't mix messages with files-from data on the socket,
736 * so temporarily turn off verbose messages. */
737 verbose = 0;
738 }
f0fca04e 739
45e08edb
WD
740 if (verbose > 2) {
741 rprintf(FINFO, "server_recv(%d) starting pid=%ld\n",
742 argc, (long)getpid());
743 }
09b7f5db 744
2adbcdc7 745 if (am_daemon && lp_read_only(module_id)) {
09b7f5db
AT
746 rprintf(FERROR,"ERROR: module is read only\n");
747 exit_cleanup(RERR_SYNTAX);
748 return;
749 }
750
7a6421fa
AT
751 if (argc > 0) {
752 dir = argv[0];
753 argc--;
754 argv++;
59187666 755 if (!am_daemon && !push_dir(dir)) {
982e05bb
WD
756 rsyserr(FERROR, errno, "push_dir#4 %s failed",
757 full_fname(dir));
65417579 758 exit_cleanup(RERR_FILESELECT);
d9c7edf6 759 }
7a6421fa 760 }
c627d613 761
da3478b2 762 io_start_buffering_in();
57dee64e 763 recv_filter_list(f_in);
c627d613 764
7c2a9e76 765 if (filesfrom_fd >= 0) {
07bff66f
WD
766 /* We need to send the files-from names to the sender at the
767 * same time that we receive the file-list from them, so we
768 * need the IO routines to automatically write out the names
769 * onto our f_out socket as we read the file-list. This
770 * avoids both deadlock and extra delays/buffers. */
7c2a9e76
WD
771 io_set_filesfrom_fds(filesfrom_fd, f_out);
772 filesfrom_fd = -1;
773 }
774
b9f592fb 775 flist = recv_file_list(f_in);
07bff66f 776 verbose = save_verbose;
4c36a13e
AT
777 if (!flist) {
778 rprintf(FERROR,"server_recv: recv_file_list error\n");
65417579 779 exit_cleanup(RERR_FILESELECT);
7a6421fa 780 }
a00628b3 781 the_file_list = flist;
d9c7edf6 782
29fad7a3 783 if (argc > 0)
7a6421fa 784 local_name = get_local_name(flist,argv[0]);
c627d613 785
84e6d6fd
WD
786 exit_code = do_recv(f_in,f_out,flist,local_name);
787 exit_cleanup(exit_code);
c627d613
AT
788}
789
790
734a94a2 791int child_main(int argc, char *argv[])
25d34a5c
MP
792{
793 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
734a94a2 794 return 0;
25d34a5c
MP
795}
796
797
9486289c 798void start_server(int f_in, int f_out, int argc, char *argv[])
366345fe 799{
f0359dd0
AT
800 set_nonblocking(f_in);
801 set_nonblocking(f_out);
802
da3478b2
WD
803 io_set_sock_fds(f_in, f_out);
804 setup_protocol(f_out, f_in);
595251de 805#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
9656de5d
WD
806 setup_iconv();
807#endif
da3478b2 808
d04e9c51 809 if (protocol_version >= 23)
da3478b2 810 io_start_multiplex_out();
7a6421fa 811
7a6421fa 812 if (am_sender) {
83926d3c 813 keep_dirlinks = 0; /* Must be disabled on the sender. */
bf26aa22
WD
814 if (need_messages_from_generator)
815 io_start_multiplex_in();
9b3318b0 816
7842418b 817 recv_filter_list(f_in);
7a6421fa
AT
818 do_server_sender(f_in, f_out, argc, argv);
819 } else {
820 do_server_recv(f_in, f_out, argc, argv);
821 }
822 exit_cleanup(0);
366345fe
AT
823}
824
0ba48136
MP
825
826/*
827 * This is called once the connection has been negotiated. It is used
828 * for rsyncd, remote-shell, and local connections.
829 */
19b27a48 830int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
9486289c 831{
088aac85 832 struct file_list *flist = NULL;
84e6d6fd 833 int exit_code = 0, exit_code2 = 0;
9486289c 834 char *local_name = NULL;
19b27a48
AT
835
836 cleanup_child_pid = pid;
67a28eb2 837 if (!read_batch) {
b9f592fb
WD
838 set_nonblocking(f_in);
839 set_nonblocking(f_out);
840 }
f0359dd0 841
da3478b2 842 io_set_sock_fds(f_in, f_out);
6d7b6081 843 setup_protocol(f_out,f_in);
595251de 844#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
9656de5d
WD
845 setup_iconv();
846#endif
6d7b6081 847
b9f592fb 848 if (protocol_version >= 23 && !read_batch)
da3478b2 849 io_start_multiplex_in();
d9c7edf6 850
18882701
WD
851 /* We set our stderr file handle to blocking because ssh might have
852 * set it to non-blocking. This can be particularly troublesome if
853 * stderr is a clone of stdout, because ssh would have set our stdout
854 * to non-blocking at the same time (which can easily cause us to lose
855 * output from our print statements). This kluge shouldn't cause ssh
856 * any problems for how we use it. Note also that we delayed setting
857 * this until after the above protocol setup so that we know for sure
858 * that ssh is done twiddling its file descriptors. */
859 set_blocking(STDERR_FILENO);
860
9486289c 861 if (am_sender) {
83926d3c 862 keep_dirlinks = 0; /* Must be disabled on the sender. */
da3478b2 863 io_start_buffering_out();
860236bf 864 if (!filesfrom_host)
a0a33ee5 865 set_msg_fd_in(f_in);
57dee64e 866 send_filter_list(f_out);
860236bf 867 if (filesfrom_host)
7c2a9e76 868 filesfrom_fd = f_in;
b9f592fb 869
e8a96e27 870 if (write_batch && !am_server)
b9f592fb 871 start_write_batch(f_out);
a00628b3 872 flist = send_file_list(f_out, argc, argv);
a0a33ee5 873 set_msg_fd_in(-1);
d9c7edf6 874 if (verbose > 3)
9486289c 875 rprintf(FINFO,"file list sent\n");
a00628b3 876 the_file_list = flist;
e1b3d5c4 877
f1e3656e 878 io_flush(NORMAL_FLUSH);
9486289c 879 send_files(flist,f_out,f_in);
f1e3656e 880 io_flush(FULL_FLUSH);
33c4b445 881 handle_stats(-1);
4e0fcd85 882 if (protocol_version >= 24)
3485ae83 883 read_final_goodbye(f_in, f_out);
9486289c
AT
884 if (pid != -1) {
885 if (verbose > 3)
08a740ff 886 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
f1e3656e 887 io_flush(FULL_FLUSH);
84e6d6fd 888 wait_process_with_flush(pid, &exit_code);
9486289c 889 }
33c4b445 890 output_summary();
c87ae64a 891 io_flush(FULL_FLUSH);
84e6d6fd 892 exit_cleanup(exit_code);
9486289c 893 }
f7632fc6 894
bf26aa22
WD
895 if (need_messages_from_generator && !read_batch)
896 io_start_multiplex_out();
897
48a1ff0d
WD
898 if (argc == 0)
899 list_only |= 1;
d9c7edf6 900
57dee64e 901 send_filter_list(read_batch ? -1 : f_out);
d9c7edf6 902
7c2a9e76
WD
903 if (filesfrom_fd >= 0) {
904 io_set_filesfrom_fds(filesfrom_fd, f_out);
905 filesfrom_fd = -1;
906 }
907
e8a96e27 908 if (write_batch && !am_server)
b9f592fb 909 start_write_batch(f_in);
9486289c 910 flist = recv_file_list(f_in);
a00628b3 911 the_file_list = flist;
d9c7edf6 912
9d19f8a5
WD
913 if (flist && flist->count > 0) {
914 local_name = get_local_name(flist, argv[0]);
d9c7edf6 915
84e6d6fd 916 exit_code2 = do_recv(f_in, f_out, flist, local_name);
9d19f8a5
WD
917 } else {
918 handle_stats(-1);
919 output_summary();
920 }
d9c7edf6 921
9486289c 922 if (pid != -1) {
8d9dc9f9 923 if (verbose > 3)
08a740ff 924 rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
f1e3656e 925 io_flush(FULL_FLUSH);
84e6d6fd 926 wait_process_with_flush(pid, &exit_code);
9486289c 927 }
d9c7edf6 928
84e6d6fd 929 return MAX(exit_code, exit_code2);
9486289c
AT
930}
931
7169bb4a
MP
932static int copy_argv (char *argv[])
933{
934 int i;
935
936 for (i = 0; argv[i]; i++) {
937 if (!(argv[i] = strdup(argv[i]))) {
938 rprintf (FERROR, "out of memory at %s(%d)\n",
939 __FILE__, __LINE__);
940 return RERR_MALLOC;
941 }
942 }
943
944 return 0;
945}
946
947
c1a04ecb 948/**
0ba48136
MP
949 * Start a client for either type of remote connection. Work out
950 * whether the arguments request a remote shell or rsyncd connection,
951 * and call the appropriate connection function, then run_client.
0b4af330
MP
952 *
953 * Calls either start_socket_client (for sockets) or do_cmd and
954 * client_run (for ssh).
c1a04ecb 955 **/
fc8a6b97 956static int start_client(int argc, char *argv[])
5d6bcd44
AT
957{
958 char *p;
959 char *shell_machine = NULL;
960 char *shell_path = NULL;
961 char *shell_user = NULL;
19b27a48
AT
962 int ret;
963 pid_t pid;
5d6bcd44 964 int f_in,f_out;
7169bb4a
MP
965 int rc;
966
967 /* Don't clobber argv[] so that ps(1) can still show the right
d9c7edf6 968 * command line. */
75aeac44 969 if ((rc = copy_argv(argv)))
7169bb4a 970 return rc;
5d6bcd44 971
d16c245f 972 if (!read_batch) { /* for read_batch, NO source is specified */
860236bf
WD
973 shell_path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
974 if (shell_path) { /* source is remote */
9425918d
WD
975 char *dummy1;
976 int dummy2;
ee8e2b15
WD
977 if (--argc
978 && check_for_hostspec(argv[argc], &dummy1, &dummy2)) {
9425918d
WD
979 rprintf(FERROR,
980 "The source and destination cannot both be remote.\n");
981 exit_cleanup(RERR_SYNTAX);
982 }
42ccb4c0 983 argv++;
860236bf
WD
984 if (filesfrom_host && *filesfrom_host
985 && strcmp(filesfrom_host, shell_machine) != 0) {
7c2a9e76 986 rprintf(FERROR,
50b31539 987 "--files-from hostname is not the same as the transfer hostname\n");
7c2a9e76
WD
988 exit_cleanup(RERR_SYNTAX);
989 }
860236bf 990 if (rsync_port) {
d9c7edf6 991 if (!shell_cmd) {
860236bf
WD
992 return start_socket_client(shell_machine,
993 shell_path,
42ccb4c0 994 argc, argv);
d9c7edf6 995 }
d9c7edf6 996 daemon_over_rsh = 1;
75aeac44 997 }
3591c066 998
42ccb4c0
WD
999 am_sender = 0;
1000 } else { /* source is local, check dest arg */
1001 am_sender = 1;
1002
ee8e2b15
WD
1003 if (argc > 1)
1004 p = argv[--argc];
1005 else {
1006 p = ".";
1007 list_only = 1;
d9c7edf6 1008 }
a125c82a 1009
ee8e2b15 1010 shell_path = check_for_hostspec(p, &shell_machine, &rsync_port);
860236bf
WD
1011 if (shell_path && filesfrom_host && *filesfrom_host
1012 && strcmp(filesfrom_host, shell_machine) != 0) {
7c2a9e76 1013 rprintf(FERROR,
50b31539 1014 "--files-from hostname is not the same as the transfer hostname\n");
7c2a9e76
WD
1015 exit_cleanup(RERR_SYNTAX);
1016 }
860236bf 1017 if (!shell_path) { /* no hostspec found, so src & dest are local */
d9c7edf6 1018 local_server = 1;
860236bf 1019 if (filesfrom_host) {
7c2a9e76 1020 rprintf(FERROR,
50b31539 1021 "--files-from cannot be remote when the transfer is local\n");
7c2a9e76
WD
1022 exit_cleanup(RERR_SYNTAX);
1023 }
860236bf 1024 shell_machine = NULL;
ee8e2b15 1025 shell_path = p;
860236bf 1026 } else if (rsync_port) {
d9c7edf6 1027 if (!shell_cmd) {
860236bf
WD
1028 return start_socket_client(shell_machine,
1029 shell_path,
42ccb4c0 1030 argc, argv);
d9c7edf6 1031 }
d9c7edf6 1032 daemon_over_rsh = 1;
a125c82a 1033 }
5d6bcd44 1034 }
d16c245f 1035 } else { /* read_batch */
d9c7edf6
WD
1036 local_server = 1;
1037 shell_path = argv[argc-1];
860236bf 1038 if (check_for_hostspec(shell_path, &shell_machine, &rsync_port)) {
b9f592fb
WD
1039 rprintf(FERROR, "remote destination is not allowed with --read-batch\n");
1040 exit_cleanup(RERR_SYNTAX);
1041 }
6902ed17
MP
1042 }
1043
5d6bcd44 1044 if (shell_machine) {
6fc048f4 1045 p = strrchr(shell_machine,'@');
5d6bcd44
AT
1046 if (p) {
1047 *p = 0;
1048 shell_user = shell_machine;
1049 shell_machine = p+1;
1050 }
1051 }
1052
1053 if (verbose > 3) {
9486289c 1054 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
45c49b52
WD
1055 shell_cmd ? shell_cmd : "",
1056 shell_machine ? shell_machine : "",
1057 shell_user ? shell_user : "",
1058 shell_path ? shell_path : "");
5d6bcd44 1059 }
d9c7edf6 1060
d16c245f 1061 /* for remote source, only single dest arg can remain ... */
f7632fc6 1062 if (!am_sender && argc > 1) {
5d6bcd44 1063 usage(FERROR);
65417579 1064 exit_cleanup(RERR_SYNTAX);
5d6bcd44 1065 }
27e3e9c9 1066
d16c245f 1067 /* ... or no dest at all */
48a1ff0d
WD
1068 if (!am_sender && argc == 0)
1069 list_only |= 1;
d9c7edf6 1070
75aeac44
WD
1071 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
1072 &f_in,&f_out);
1073
1074 /* if we're running an rsync server on the remote host over a
9af87151 1075 * remote shell command, we need to do the RSYNCD protocol first */
75aeac44
WD
1076 if (daemon_over_rsh) {
1077 int tmpret;
1078 tmpret = start_inband_exchange(shell_user, shell_path,
1079 f_in, f_out, argc);
1080 if (tmpret < 0)
1081 return tmpret;
1082 }
1083
fc8a6b97
AT
1084 ret = client_run(f_in, f_out, pid, argc, argv);
1085
1086 fflush(stdout);
1087 fflush(stderr);
1088
1089 return ret;
5d6bcd44
AT
1090}
1091
366345fe 1092
067669da
WD
1093static RETSIGTYPE sigusr1_handler(UNUSED(int val))
1094{
6bf32edb 1095 exit_cleanup(RERR_SIGNAL1);
82306bf6
AT
1096}
1097
067669da
WD
1098static RETSIGTYPE sigusr2_handler(UNUSED(int val))
1099{
33c4b445
WD
1100 if (!am_server)
1101 output_summary();
40df65fd 1102 close_all();
33c4b445
WD
1103 if (log_got_error)
1104 _exit(RERR_PARTIAL);
8b35435f
AT
1105 _exit(0);
1106}
1107
6d59ac19 1108RETSIGTYPE remember_children(UNUSED(int val))
067669da 1109{
029c1713 1110#ifdef WNOHANG
ee7118a8
DD
1111 int cnt, status;
1112 pid_t pid;
1113 /* An empty waitpid() loop was put here by Tridge and we could never
d9c7edf6 1114 * get him to explain why he put it in, so rather than taking it
ee7118a8
DD
1115 * out we're instead saving the child exit statuses for later use.
1116 * The waitpid() loop presumably eliminates all possibility of leaving
97d8e709 1117 * zombie children, maybe that's why he did it. */
ee7118a8 1118 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
9af87151
WD
1119 /* save the child's exit status */
1120 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
1121 if (pid_stat_table[cnt].pid == 0) {
1122 pid_stat_table[cnt].pid = pid;
1123 pid_stat_table[cnt].status = status;
1124 break;
1125 }
1126 }
ee7118a8 1127 }
029c1713 1128#endif
8261af74 1129#ifndef HAVE_SIGACTION
6d59ac19 1130 signal(SIGCHLD, remember_children);
60ee01f5 1131#endif
19b27a48
AT
1132}
1133
c0531332
MP
1134
1135/**
1136 * This routine catches signals and tries to send them to gdb.
1137 *
1138 * Because it's called from inside a signal handler it ought not to
1139 * use too many library routines.
1140 *
1141 * @todo Perhaps use "screen -X" instead/as well, to help people
1142 * debugging without easy access to X. Perhaps use an environment
1143 * variable, or just call a script?
1144 *
1145 * @todo The /proc/ magic probably only works on Linux (and
1146 * Solaris?) Can we be more portable?
1147 **/
1148#ifdef MAINTAINER_MODE
4fdc39dd
MP
1149const char *get_panic_action(void)
1150{
1151 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
1152
1153 if (cmd_fmt)
1154 return cmd_fmt;
1155 else
1156 return "xterm -display :0 -T Panic -n Panic "
1157 "-e gdb /proc/%d/exe %d";
1158}
1159
1160
9fb3f7a9
MP
1161/**
1162 * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
1163 *
1164 * This signal handler is only installed if we were configured with
1165 * --enable-maintainer-mode. Perhaps it should always be on and we
1166 * should just look at the environment variable, but I'm a bit leery
1167 * of a signal sending us into a busy loop.
1168 **/
067669da 1169static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
c0531332
MP
1170{
1171 char cmd_buf[300];
1172 int ret;
4fdc39dd
MP
1173
1174 sprintf(cmd_buf, get_panic_action(),
c0531332
MP
1175 getpid(), getpid());
1176
1177 /* Unless we failed to execute gdb, we allow the process to
1178 * continue. I'm not sure if that's right. */
1179 ret = system(cmd_buf);
1180 if (ret)
1181 _exit(ret);
1182}
1183#endif
1184
1185
5d6bcd44 1186int main(int argc,char *argv[])
d9c7edf6 1187{
ff81e809 1188 int ret;
66a9dc96
WD
1189 int orig_argc = argc;
1190 char **orig_argv = argv;
8261af74
WD
1191#ifdef HAVE_SIGACTION
1192# ifdef HAVE_SIGPROCMASK
60ee01f5 1193 sigset_t sigmask;
5d6bcd44 1194
60ee01f5 1195 sigemptyset(&sigmask);
8261af74 1196# endif
60ee01f5
WD
1197 sigact.sa_flags = SA_NOCLDSTOP;
1198#endif
1199 SIGACTMASK(SIGUSR1, sigusr1_handler);
1200 SIGACTMASK(SIGUSR2, sigusr2_handler);
6d59ac19 1201 SIGACTMASK(SIGCHLD, remember_children);
c0531332 1202#ifdef MAINTAINER_MODE
60ee01f5
WD
1203 SIGACTMASK(SIGSEGV, rsync_panic_handler);
1204 SIGACTMASK(SIGFPE, rsync_panic_handler);
1205 SIGACTMASK(SIGABRT, rsync_panic_handler);
1206 SIGACTMASK(SIGBUS, rsync_panic_handler);
1207#endif
5d6bcd44 1208
7a6421fa 1209 starttime = time(NULL);
6fe05820 1210 am_root = (MY_UID() == 0);
c627d613 1211
a800434a
AT
1212 memset(&stats, 0, sizeof(stats));
1213
df5e03da
AT
1214 if (argc < 2) {
1215 usage(FERROR);
65417579 1216 exit_cleanup(RERR_SYNTAX);
df5e03da
AT
1217 }
1218
7a6421fa 1219 /* we set a 0 umask so that correct file permissions can be
9af87151 1220 * carried across */
05278935 1221 orig_umask = umask(0);
5d6bcd44 1222
eb598fac
WD
1223#if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
1224 setlocale(LC_CTYPE, "");
1225#endif
1226
50135767 1227 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
d9c7edf6
WD
1228 /* FIXME: We ought to call the same error-handling
1229 * code here, rather than relying on getopt. */
50135767 1230 option_error();
65417579 1231 exit_cleanup(RERR_SYNTAX);
b11ed3b1 1232 }
5d6bcd44 1233
60ee01f5
WD
1234 SIGACTMASK(SIGINT, sig_int);
1235 SIGACTMASK(SIGHUP, sig_int);
1236 SIGACTMASK(SIGTERM, sig_int);
1237#if defined HAVE_SIGACTION && HAVE_SIGPROCMASK
1238 sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
1239#endif
6b83141d 1240
34758d5c
MP
1241 /* Ignore SIGPIPE; we consistently check error codes and will
1242 * see the EPIPE. */
60ee01f5 1243 SIGACTION(SIGPIPE, SIG_IGN);
55e54e46
WD
1244#ifdef SIGXFSZ
1245 SIGACTION(SIGXFSZ, SIG_IGN);
1246#endif
34758d5c 1247
c226b7c2 1248 /* Initialize push_dir here because on some old systems getcwd
9af87151
WD
1249 * (implemented by forking "pwd" and reading its output) doesn't
1250 * work when there are other child processes. Also, on all systems
1251 * that implement getcwd that way "pwd" can't be found after chroot. */
59187666 1252 push_dir(NULL);
c226b7c2 1253
44e9e221
WD
1254 init_flist();
1255
e8a96e27 1256 if ((write_batch || read_batch) && !am_server) {
b9f592fb 1257 if (write_batch)
66a9dc96 1258 write_batch_shell_file(orig_argc, orig_argv, argc);
b9f592fb 1259
dbbab0c4
WD
1260 if (read_batch && strcmp(batch_name, "-") == 0)
1261 batch_fd = STDIN_FILENO;
1262 else {
1263 batch_fd = do_open(batch_name,
b9f592fb
WD
1264 write_batch ? O_WRONLY | O_CREAT | O_TRUNC
1265 : O_RDONLY, S_IRUSR | S_IWUSR);
dbbab0c4 1266 }
b9f592fb
WD
1267 if (batch_fd < 0) {
1268 rsyserr(FERROR, errno, "Batch file %s open error",
71903f60 1269 full_fname(batch_name));
b9f592fb
WD
1270 exit_cleanup(RERR_FILEIO);
1271 }
9459290a
WD
1272 if (read_batch)
1273 read_stream_flags(batch_fd);
6902ed17 1274 }
e8a96e27
WD
1275 if (write_batch < 0)
1276 dry_run = 1;
6902ed17 1277
75aeac44 1278 if (am_daemon && !am_server)
7a6421fa 1279 return daemon_main();
f0fca04e 1280
08ac228f
AT
1281 if (argc < 1) {
1282 usage(FERROR);
65417579 1283 exit_cleanup(RERR_SYNTAX);
08ac228f
AT
1284 }
1285
7a6421fa 1286 if (am_server) {
f0359dd0
AT
1287 set_nonblocking(STDIN_FILENO);
1288 set_nonblocking(STDOUT_FILENO);
75aeac44
WD
1289 if (am_daemon)
1290 return start_daemon(STDIN_FILENO, STDOUT_FILENO);
7a6421fa
AT
1291 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
1292 }
c627d613 1293
ff81e809 1294 ret = start_client(argc, argv);
d9c7edf6 1295 if (ret == -1)
9098bbf3 1296 exit_cleanup(RERR_STARTCLIENT);
088aac85 1297 else
9098bbf3
MP
1298 exit_cleanup(ret);
1299
0f5a04e3 1300 return ret;
c627d613 1301}