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