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