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