Call write_stream_flags() from start_write_batch().
[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);
d9c7edf6 180 rprintf(FINFO,"Total bytes written: %.0f\n",
b9f592fb 181 (double)total_written);
577ab12c 182 rprintf(FINFO,"Total bytes read: %.0f\n",
b9f592fb 183 (double)total_read);
7a6421fa 184 }
d9c7edf6 185
e19452a9 186 if (verbose || do_stats) {
b9f592fb
WD
187 rprintf(FINFO,
188 "\nwrote %.0f bytes read %.0f bytes %.2f bytes/sec\n",
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
AT
482 /* we can't let two processes write to the socket at one time */
483 io_multiplexing_close();
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;
b9f592fb
WD
502 if (write_batch)
503 stop_write_batch();
b695f242 504
554e0a8d 505 close(error_pipe[1]);
3a69fad0
WD
506 if (f_in != f_out)
507 close(f_in);
e1b3d5c4 508
da3478b2 509 io_start_buffering_out();
b3e10ed7 510
f1e3656e 511 set_msg_fd_in(error_pipe[0]);
554e0a8d 512
f1e3656e 513 generate_files(f_out, flist, local_name);
8d9dc9f9 514
40da9042 515 get_redo_num(); /* Read final MSG_DONE and any prior messages. */
e5fbaa71 516 report(-1);
f1e3656e 517 io_flush(FULL_FLUSH);
d04e9c51 518 if (protocol_version >= 24) {
8ada7518
AT
519 /* send a final goodbye message */
520 write_int(f_out, -1);
521 }
f1e3656e 522 io_flush(FULL_FLUSH);
8ada7518 523
f1e3656e 524 set_msg_fd_in(-1);
089a2435 525 kill(pid, SIGUSR2);
d79d1c69 526 wait_process(pid, &status);
d186eb1a 527 return status;
dc5ddbcc
AT
528}
529
c627d613 530
9486289c 531static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
c627d613 532{
7a6421fa
AT
533 int status;
534 struct file_list *flist;
6c2e5b56 535 char *local_name = NULL;
7a6421fa 536 char *dir = NULL;
f0fca04e 537
45e08edb
WD
538 if (verbose > 2) {
539 rprintf(FINFO, "server_recv(%d) starting pid=%ld\n",
540 argc, (long)getpid());
541 }
09b7f5db 542
2adbcdc7 543 if (am_daemon && lp_read_only(module_id)) {
09b7f5db
AT
544 rprintf(FERROR,"ERROR: module is read only\n");
545 exit_cleanup(RERR_SYNTAX);
546 return;
547 }
548
d9c7edf6 549
7a6421fa
AT
550 if (argc > 0) {
551 dir = argv[0];
552 argc--;
553 argv++;
59187666 554 if (!am_daemon && !push_dir(dir)) {
982e05bb
WD
555 rsyserr(FERROR, errno, "push_dir#4 %s failed",
556 full_fname(dir));
65417579 557 exit_cleanup(RERR_FILESELECT);
d9c7edf6 558 }
7a6421fa 559 }
c627d613 560
da3478b2 561 io_start_buffering_in();
b33b791e 562 if (delete_mode && !delete_excluded)
7a6421fa 563 recv_exclude_list(f_in);
c627d613 564
7c2a9e76
WD
565 if (filesfrom_fd >= 0) {
566 /* We're receiving the file info from the sender, so we need
567 * the IO routines to automatically write out the names onto
568 * our f_out socket as we read the list info from the sender.
569 * This avoids both deadlock and extra delays/buffers. */
570 io_set_filesfrom_fds(filesfrom_fd, f_out);
571 filesfrom_fd = -1;
572 }
573
b9f592fb 574 flist = recv_file_list(f_in);
4c36a13e
AT
575 if (!flist) {
576 rprintf(FERROR,"server_recv: recv_file_list error\n");
65417579 577 exit_cleanup(RERR_FILESELECT);
7a6421fa 578 }
d9c7edf6
WD
579
580 if (argc > 0) {
7a6421fa
AT
581 if (strcmp(dir,".")) {
582 argv[0] += strlen(dir);
3a69fad0
WD
583 if (argv[0][0] == '/')
584 argv[0]++;
7a6421fa
AT
585 }
586 local_name = get_local_name(flist,argv[0]);
587 }
c627d613 588
7a6421fa
AT
589 status = do_recv(f_in,f_out,flist,local_name);
590 exit_cleanup(status);
c627d613
AT
591}
592
593
734a94a2 594int child_main(int argc, char *argv[])
25d34a5c
MP
595{
596 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
734a94a2 597 return 0;
25d34a5c
MP
598}
599
600
9486289c 601void start_server(int f_in, int f_out, int argc, char *argv[])
366345fe 602{
f0359dd0
AT
603 set_nonblocking(f_in);
604 set_nonblocking(f_out);
605
da3478b2
WD
606 io_set_sock_fds(f_in, f_out);
607 setup_protocol(f_out, f_in);
608
d04e9c51 609 if (protocol_version >= 23)
da3478b2 610 io_start_multiplex_out();
7a6421fa 611
7a6421fa 612 if (am_sender) {
83926d3c 613 keep_dirlinks = 0; /* Must be disabled on the sender. */
9b3318b0 614
b9f592fb
WD
615 recv_exclude_list(f_in);
616 if (cvs_exclude)
617 add_cvs_excludes();
7a6421fa
AT
618 do_server_sender(f_in, f_out, argc, argv);
619 } else {
620 do_server_recv(f_in, f_out, argc, argv);
621 }
622 exit_cleanup(0);
366345fe
AT
623}
624
0ba48136
MP
625
626/*
627 * This is called once the connection has been negotiated. It is used
628 * for rsyncd, remote-shell, and local connections.
629 */
19b27a48 630int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
9486289c 631{
088aac85 632 struct file_list *flist = NULL;
9486289c
AT
633 int status = 0, status2 = 0;
634 char *local_name = NULL;
19b27a48
AT
635
636 cleanup_child_pid = pid;
b9f592fb 637 if (read_batch) {
b9f592fb
WD
638 assert(am_sender == 0);
639 } else {
640 set_nonblocking(f_in);
641 set_nonblocking(f_out);
642 }
f0359dd0 643
da3478b2 644 io_set_sock_fds(f_in, f_out);
6d7b6081
AT
645 setup_protocol(f_out,f_in);
646
b9f592fb 647 if (protocol_version >= 23 && !read_batch)
da3478b2 648 io_start_multiplex_in();
d9c7edf6 649
9486289c 650 if (am_sender) {
83926d3c 651 keep_dirlinks = 0; /* Must be disabled on the sender. */
da3478b2 652 io_start_buffering_out();
9486289c
AT
653 if (cvs_exclude)
654 add_cvs_excludes();
d9c7edf6 655 if (delete_mode && !delete_excluded)
9486289c 656 send_exclude_list(f_out);
7c2a9e76
WD
657 if (remote_filesfrom_file)
658 filesfrom_fd = f_in;
b9f592fb
WD
659
660 if (write_batch)
661 start_write_batch(f_out);
64c3523a 662 if (!read_batch) /* don't write to pipe */
d9c7edf6
WD
663 flist = send_file_list(f_out,argc,argv);
664 if (verbose > 3)
9486289c 665 rprintf(FINFO,"file list sent\n");
e1b3d5c4 666
f1e3656e 667 io_flush(NORMAL_FLUSH);
9486289c 668 send_files(flist,f_out,f_in);
f1e3656e 669 io_flush(FULL_FLUSH);
d04e9c51 670 if (protocol_version >= 24) {
d9c7edf6 671 /* final goodbye message */
6c65e146
AT
672 read_int(f_in);
673 }
9486289c
AT
674 if (pid != -1) {
675 if (verbose > 3)
08a740ff 676 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
f1e3656e 677 io_flush(FULL_FLUSH);
d79d1c69 678 wait_process(pid, &status);
9486289c 679 }
3d382777 680 report(-1);
f1e3656e 681 io_flush(FULL_FLUSH);
9486289c
AT
682 exit_cleanup(status);
683 }
f7632fc6 684
1082b52b 685 if (argc == 0)
27e3e9c9 686 list_only = 1;
d9c7edf6 687
1082b52b 688 if (!read_batch)
d9c7edf6
WD
689 send_exclude_list(f_out);
690
7c2a9e76
WD
691 if (filesfrom_fd >= 0) {
692 io_set_filesfrom_fds(filesfrom_fd, f_out);
693 filesfrom_fd = -1;
694 }
695
b9f592fb
WD
696 if (write_batch)
697 start_write_batch(f_in);
9486289c
AT
698 flist = recv_file_list(f_in);
699 if (!flist || flist->count == 0) {
796d484b 700 rprintf(FINFO, "client: nothing to do: "
d9c7edf6
WD
701 "perhaps you need to specify some filenames or "
702 "the --recursive option?\n");
9486289c
AT
703 exit_cleanup(0);
704 }
d9c7edf6 705
9486289c 706 local_name = get_local_name(flist,argv[0]);
d9c7edf6 707
9486289c 708 status2 = do_recv(f_in,f_out,flist,local_name);
d9c7edf6 709
9486289c 710 if (pid != -1) {
8d9dc9f9 711 if (verbose > 3)
08a740ff 712 rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
f1e3656e 713 io_flush(FULL_FLUSH);
d79d1c69 714 wait_process(pid, &status);
9486289c 715 }
d9c7edf6 716
ff81e809 717 return MAX(status, status2);
9486289c
AT
718}
719
7169bb4a
MP
720static int copy_argv (char *argv[])
721{
722 int i;
723
724 for (i = 0; argv[i]; i++) {
725 if (!(argv[i] = strdup(argv[i]))) {
726 rprintf (FERROR, "out of memory at %s(%d)\n",
727 __FILE__, __LINE__);
728 return RERR_MALLOC;
729 }
730 }
731
732 return 0;
733}
734
735
c1a04ecb 736/**
0ba48136
MP
737 * Start a client for either type of remote connection. Work out
738 * whether the arguments request a remote shell or rsyncd connection,
739 * and call the appropriate connection function, then run_client.
0b4af330
MP
740 *
741 * Calls either start_socket_client (for sockets) or do_cmd and
742 * client_run (for ssh).
c1a04ecb 743 **/
fc8a6b97 744static int start_client(int argc, char *argv[])
5d6bcd44
AT
745{
746 char *p;
747 char *shell_machine = NULL;
748 char *shell_path = NULL;
749 char *shell_user = NULL;
19b27a48
AT
750 int ret;
751 pid_t pid;
5d6bcd44 752 int f_in,f_out;
7169bb4a
MP
753 int rc;
754
755 /* Don't clobber argv[] so that ps(1) can still show the right
d9c7edf6 756 * command line. */
75aeac44 757 if ((rc = copy_argv(argv)))
7169bb4a 758 return rc;
5d6bcd44 759
75aeac44 760 /* rsync:// always uses rsync server over direct socket connection */
b9f592fb
WD
761 if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0
762 && !read_batch) {
f7632fc6
AT
763 char *host, *path;
764
7169bb4a 765 host = argv[0] + strlen(URL_PREFIX);
f7632fc6
AT
766 p = strchr(host,'/');
767 if (p) {
768 *p = 0;
769 path = p+1;
770 } else {
a125c82a 771 path = "";
f7632fc6 772 }
2acf81eb
DD
773 p = strchr(host,':');
774 if (p) {
775 rsync_port = atoi(p+1);
776 *p = 0;
777 }
f7632fc6
AT
778 return start_socket_client(host, path, argc-1, argv+1);
779 }
780
d16c245f 781 if (!read_batch) { /* for read_batch, NO source is specified */
a125c82a 782 p = find_colon(argv[0]);
d16c245f 783 if (p) { /* source is remote */
7c2a9e76
WD
784 if (remote_filesfrom_file
785 && remote_filesfrom_file != files_from + 1
786 && strncmp(files_from, argv[0], p-argv[0]+1) != 0) {
787 rprintf(FERROR,
788 "--files-from hostname is not transfer hostname\n");
789 exit_cleanup(RERR_SYNTAX);
790 }
d9c7edf6
WD
791 if (p[1] == ':') { /* double colon */
792 *p = 0;
793 if (!shell_cmd) {
794 return start_socket_client(argv[0], p+2,
795 argc-1, argv+1);
796 }
797 p++;
798 daemon_over_rsh = 1;
75aeac44 799 }
3591c066 800
d16c245f 801 if (argc < 1) { /* destination required */
d9c7edf6
WD
802 usage(FERROR);
803 exit_cleanup(RERR_SYNTAX);
804 }
a125c82a 805
d9c7edf6
WD
806 am_sender = 0;
807 *p = 0;
808 shell_machine = argv[0];
809 shell_path = p+1;
d9c7edf6 810 argv++;
d16c245f 811 } else { /* source is local */
d9c7edf6
WD
812 am_sender = 1;
813
814 /* rsync:// destination uses rsync server over direct socket */
815 if (strncasecmp(URL_PREFIX, argv[argc-1], strlen(URL_PREFIX)) == 0) {
816 char *host, *path;
817
818 host = argv[argc-1] + strlen(URL_PREFIX);
819 p = strchr(host,'/');
820 if (p) {
821 *p = 0;
822 path = p+1;
823 } else {
824 path = "";
825 }
826 p = strchr(host,':');
827 if (p) {
828 rsync_port = atoi(p+1);
829 *p = 0;
830 }
831 return start_socket_client(host, path, argc-1, argv);
a125c82a 832 }
d9c7edf6 833
d16c245f 834 p = find_colon(argv[argc-1]); /* look in dest arg */
7c2a9e76
WD
835 if (p && remote_filesfrom_file
836 && remote_filesfrom_file != files_from + 1
837 && strncmp(files_from, argv[argc-1], p-argv[argc-1]+1) != 0) {
838 rprintf(FERROR,
839 "--files-from hostname is not transfer hostname\n");
840 exit_cleanup(RERR_SYNTAX);
841 }
d16c245f 842 if (!p) { /* no colon found, so src & dest are local */
d9c7edf6 843 local_server = 1;
7c2a9e76
WD
844 if (remote_filesfrom_file) {
845 rprintf(FERROR,
846 "--files-from is remote but transfer is local\n");
847 exit_cleanup(RERR_SYNTAX);
848 }
d9c7edf6 849 } else if (p[1] == ':') { /* double colon */
a125c82a 850 *p = 0;
d9c7edf6
WD
851 if (!shell_cmd) {
852 return start_socket_client(argv[argc-1], p+2,
853 argc-1, argv);
854 }
855 p++;
856 daemon_over_rsh = 1;
a125c82a 857 }
a125c82a 858
d9c7edf6
WD
859 if (argc < 2) {
860 usage(FERROR);
861 exit_cleanup(RERR_SYNTAX);
75aeac44 862 }
3591c066 863
d9c7edf6
WD
864 if (local_server) {
865 shell_machine = NULL;
866 shell_path = argv[argc-1];
867 } else {
868 *p = 0;
869 shell_machine = argv[argc-1];
870 shell_path = p+1;
871 }
5d6bcd44 872 }
d16c245f
WD
873 argc--;
874 } else { /* read_batch */
d9c7edf6
WD
875 local_server = 1;
876 shell_path = argv[argc-1];
b9f592fb
WD
877 if (find_colon(shell_path)) {
878 rprintf(FERROR, "remote destination is not allowed with --read-batch\n");
879 exit_cleanup(RERR_SYNTAX);
880 }
6902ed17
MP
881 }
882
5d6bcd44 883 if (shell_machine) {
6fc048f4 884 p = strrchr(shell_machine,'@');
5d6bcd44
AT
885 if (p) {
886 *p = 0;
887 shell_user = shell_machine;
888 shell_machine = p+1;
889 }
890 }
891
892 if (verbose > 3) {
9486289c 893 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
5d6bcd44
AT
894 shell_cmd?shell_cmd:"",
895 shell_machine?shell_machine:"",
896 shell_user?shell_user:"",
897 shell_path?shell_path:"");
898 }
d9c7edf6 899
d16c245f 900 /* for remote source, only single dest arg can remain ... */
f7632fc6 901 if (!am_sender && argc > 1) {
5d6bcd44 902 usage(FERROR);
65417579 903 exit_cleanup(RERR_SYNTAX);
5d6bcd44 904 }
27e3e9c9 905
d16c245f
WD
906 /* ... or no dest at all */
907 if (!am_sender && argc == 0) {
27e3e9c9
AT
908 list_only = 1;
909 }
d9c7edf6 910
75aeac44
WD
911 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
912 &f_in,&f_out);
913
914 /* if we're running an rsync server on the remote host over a
9af87151 915 * remote shell command, we need to do the RSYNCD protocol first */
75aeac44
WD
916 if (daemon_over_rsh) {
917 int tmpret;
918 tmpret = start_inband_exchange(shell_user, shell_path,
919 f_in, f_out, argc);
920 if (tmpret < 0)
921 return tmpret;
922 }
923
fc8a6b97
AT
924 ret = client_run(f_in, f_out, pid, argc, argv);
925
926 fflush(stdout);
927 fflush(stderr);
928
929 return ret;
5d6bcd44
AT
930}
931
366345fe 932
067669da
WD
933static RETSIGTYPE sigusr1_handler(UNUSED(int val))
934{
65417579 935 exit_cleanup(RERR_SIGNAL);
82306bf6
AT
936}
937
067669da
WD
938static RETSIGTYPE sigusr2_handler(UNUSED(int val))
939{
19b27a48 940 if (log_got_error) _exit(RERR_PARTIAL);
8b35435f
AT
941 _exit(0);
942}
943
067669da
WD
944static RETSIGTYPE sigchld_handler(UNUSED(int val))
945{
029c1713 946#ifdef WNOHANG
ee7118a8
DD
947 int cnt, status;
948 pid_t pid;
949 /* An empty waitpid() loop was put here by Tridge and we could never
d9c7edf6 950 * get him to explain why he put it in, so rather than taking it
ee7118a8
DD
951 * out we're instead saving the child exit statuses for later use.
952 * The waitpid() loop presumably eliminates all possibility of leaving
953 * zombie children, maybe that's why he did it.
954 */
955 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
9af87151
WD
956 /* save the child's exit status */
957 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
958 if (pid_stat_table[cnt].pid == 0) {
959 pid_stat_table[cnt].pid = pid;
960 pid_stat_table[cnt].status = status;
961 break;
962 }
963 }
ee7118a8 964 }
029c1713 965#endif
19b27a48
AT
966}
967
c0531332
MP
968
969/**
970 * This routine catches signals and tries to send them to gdb.
971 *
972 * Because it's called from inside a signal handler it ought not to
973 * use too many library routines.
974 *
975 * @todo Perhaps use "screen -X" instead/as well, to help people
976 * debugging without easy access to X. Perhaps use an environment
977 * variable, or just call a script?
978 *
979 * @todo The /proc/ magic probably only works on Linux (and
980 * Solaris?) Can we be more portable?
981 **/
982#ifdef MAINTAINER_MODE
4fdc39dd
MP
983const char *get_panic_action(void)
984{
985 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
986
987 if (cmd_fmt)
988 return cmd_fmt;
989 else
990 return "xterm -display :0 -T Panic -n Panic "
991 "-e gdb /proc/%d/exe %d";
992}
993
994
9fb3f7a9
MP
995/**
996 * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
997 *
998 * This signal handler is only installed if we were configured with
999 * --enable-maintainer-mode. Perhaps it should always be on and we
1000 * should just look at the environment variable, but I'm a bit leery
1001 * of a signal sending us into a busy loop.
1002 **/
067669da 1003static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
c0531332
MP
1004{
1005 char cmd_buf[300];
1006 int ret;
4fdc39dd
MP
1007
1008 sprintf(cmd_buf, get_panic_action(),
c0531332
MP
1009 getpid(), getpid());
1010
1011 /* Unless we failed to execute gdb, we allow the process to
1012 * continue. I'm not sure if that's right. */
1013 ret = system(cmd_buf);
1014 if (ret)
1015 _exit(ret);
1016}
1017#endif
1018
1019
5d6bcd44 1020int main(int argc,char *argv[])
d9c7edf6 1021{
ff81e809 1022 int ret;
66a9dc96
WD
1023 int orig_argc = argc;
1024 char **orig_argv = argv;
5d6bcd44 1025
7a6421fa 1026 signal(SIGUSR1, sigusr1_handler);
8b35435f 1027 signal(SIGUSR2, sigusr2_handler);
19b27a48 1028 signal(SIGCHLD, sigchld_handler);
c0531332
MP
1029#ifdef MAINTAINER_MODE
1030 signal(SIGSEGV, rsync_panic_handler);
1031 signal(SIGFPE, rsync_panic_handler);
1032 signal(SIGABRT, rsync_panic_handler);
1033 signal(SIGBUS, rsync_panic_handler);
1034#endif /* def MAINTAINER_MODE */
5d6bcd44 1035
7a6421fa 1036 starttime = time(NULL);
6fe05820 1037 am_root = (MY_UID() == 0);
c627d613 1038
a800434a
AT
1039 memset(&stats, 0, sizeof(stats));
1040
df5e03da
AT
1041 if (argc < 2) {
1042 usage(FERROR);
65417579 1043 exit_cleanup(RERR_SYNTAX);
df5e03da
AT
1044 }
1045
7a6421fa 1046 /* we set a 0 umask so that correct file permissions can be
9af87151 1047 * carried across */
7a6421fa 1048 orig_umask = (int)umask(0);
5d6bcd44 1049
50135767 1050 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
d9c7edf6
WD
1051 /* FIXME: We ought to call the same error-handling
1052 * code here, rather than relying on getopt. */
50135767 1053 option_error();
65417579 1054 exit_cleanup(RERR_SYNTAX);
b11ed3b1 1055 }
5d6bcd44 1056
7a6421fa 1057 signal(SIGINT,SIGNAL_CAST sig_int);
7a6421fa 1058 signal(SIGHUP,SIGNAL_CAST sig_int);
8638dd48 1059 signal(SIGTERM,SIGNAL_CAST sig_int);
6b83141d 1060
34758d5c
MP
1061 /* Ignore SIGPIPE; we consistently check error codes and will
1062 * see the EPIPE. */
1063 signal(SIGPIPE, SIG_IGN);
1064
c226b7c2 1065 /* Initialize push_dir here because on some old systems getcwd
9af87151
WD
1066 * (implemented by forking "pwd" and reading its output) doesn't
1067 * work when there are other child processes. Also, on all systems
1068 * that implement getcwd that way "pwd" can't be found after chroot. */
59187666 1069 push_dir(NULL);
c226b7c2 1070
44e9e221
WD
1071 init_flist();
1072
b9f592fb
WD
1073 if (write_batch || read_batch) {
1074 if (write_batch)
66a9dc96 1075 write_batch_shell_file(orig_argc, orig_argv, argc);
b9f592fb 1076
dbbab0c4
WD
1077 if (read_batch && strcmp(batch_name, "-") == 0)
1078 batch_fd = STDIN_FILENO;
1079 else {
1080 batch_fd = do_open(batch_name,
b9f592fb
WD
1081 write_batch ? O_WRONLY | O_CREAT | O_TRUNC
1082 : O_RDONLY, S_IRUSR | S_IWUSR);
dbbab0c4 1083 }
b9f592fb
WD
1084 if (batch_fd < 0) {
1085 rsyserr(FERROR, errno, "Batch file %s open error",
9b3318b0 1086 batch_name);
b9f592fb
WD
1087 exit_cleanup(RERR_FILEIO);
1088 }
6902ed17
MP
1089 }
1090
75aeac44 1091 if (am_daemon && !am_server)
7a6421fa 1092 return daemon_main();
f0fca04e 1093
08ac228f
AT
1094 if (argc < 1) {
1095 usage(FERROR);
65417579 1096 exit_cleanup(RERR_SYNTAX);
08ac228f
AT
1097 }
1098
7a6421fa
AT
1099 if (dry_run)
1100 verbose = MAX(verbose,1);
c627d613 1101
7a6421fa 1102 if (am_server) {
f0359dd0
AT
1103 set_nonblocking(STDIN_FILENO);
1104 set_nonblocking(STDOUT_FILENO);
75aeac44
WD
1105 if (am_daemon)
1106 return start_daemon(STDIN_FILENO, STDOUT_FILENO);
7a6421fa
AT
1107 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
1108 }
c627d613 1109
ff81e809 1110 ret = start_client(argc, argv);
d9c7edf6 1111 if (ret == -1)
9098bbf3 1112 exit_cleanup(RERR_STARTCLIENT);
088aac85 1113 else
9098bbf3
MP
1114 exit_cleanup(ret);
1115
0f5a04e3 1116 return ret;
c627d613 1117}