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