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