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