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