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