Added new function discard_receive_data().
[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;
32eda096
WD
56extern int filesfrom_fd;
57extern pid_t cleanup_child_pid;
58extern char *files_from;
59extern char *remote_filesfrom_file;
60extern char *rsync_path;
61extern char *shell_cmd;
9b3318b0 62extern char *batch_name;
c627d613 63
b695f242 64
ee7118a8
DD
65/* there's probably never more than at most 2 outstanding child processes,
66 * but set it higher just in case.
67 */
68#define MAXCHILDPROCS 5
69
70struct pid_status {
71 pid_t pid;
72 int status;
73} pid_stat_table[MAXCHILDPROCS];
74
e5a2b854 75static void show_malloc_stats(void);
82980a23
AT
76
77/****************************************************************************
78wait for a process to exit, calling io_flush while waiting
79****************************************************************************/
80void wait_process(pid_t pid, int *status)
81{
ee7118a8
DD
82 pid_t waited_pid;
83 int cnt;
84
85 while ((waited_pid = waitpid(pid, status, WNOHANG)) == 0) {
a24c6870 86 msleep(20);
f1e3656e 87 io_flush(FULL_FLUSH);
82980a23 88 }
d9c7edf6 89
6fb812f7 90 if (waited_pid == -1 && errno == ECHILD) {
ee7118a8
DD
91 /* status of requested child no longer available.
92 * check to see if it was processed by the sigchld_handler.
93 */
94 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
95 if (pid == pid_stat_table[cnt].pid) {
96 *status = pid_stat_table[cnt].status;
97 pid_stat_table[cnt].pid = 0;
98 break;
99 }
100 }
101 }
102
d9c7edf6
WD
103 /* TODO: If the child exited on a signal, then log an
104 * appropriate error message. Perhaps we should also accept a
105 * message describing the purpose of the child. Also indicate
106 * this to the caller so that thhey know something went
107 * wrong. */
82980a23
AT
108 *status = WEXITSTATUS(*status);
109}
110
b9f592fb
WD
111/* This function gets called from all 3 processes. We want the client side
112 * to actually output the text, but the sender is the only process that has
113 * all the stats we need. So, if we're a client sender, we do the report.
114 * If we're a server sender, we write the stats on the supplied fd. If
115 * we're the client receiver we read the stats from the supplied fd and do
116 * the report. All processes might also generate a set of debug stats, if
117 * the verbose level is high enough (this is the only thing that the
118 * generator process and the server receiver ever do here). */
c627d613
AT
119static void report(int f)
120{
b9f592fb
WD
121 /* Cache two stats because the read/write code can change it. */
122 int64 total_read = stats.total_read;
123 int64 total_written = stats.total_written;
7a6421fa 124 time_t t = time(NULL);
7a6421fa 125
7bb7058e 126 if (do_stats && verbose > 1) {
5c15e29f 127 /* These come out from every process */
7bb7058e 128 show_malloc_stats();
86943126 129 show_flist_stats();
5c15e29f
MP
130 }
131
e5fbaa71
S
132 if (am_generator)
133 return;
134
248fbb8c 135 if (am_daemon) {
a9766ef1 136 log_exit(0, __FILE__, __LINE__);
83926d3c
WD
137 if (f == -1 || !am_sender)
138 return;
248fbb8c
AT
139 }
140
e19452a9 141 if (am_server) {
3e491682 142 if (am_sender) {
b9f592fb
WD
143 write_longint(f, total_read);
144 write_longint(f, total_written);
145 write_longint(f, stats.total_size);
e19452a9 146 }
7a6421fa
AT
147 return;
148 }
e19452a9
DD
149
150 /* this is the client */
d9c7edf6 151
3e491682 152 if (!am_sender) {
b9f592fb
WD
153 total_written = read_longint(f);
154 total_read = read_longint(f);
a800434a 155 stats.total_size = read_longint(f);
b9f592fb
WD
156 } else if (write_batch) {
157 /* The --read-batch process is going to be a client
158 * receiver, so we need to give it the stats. */
159 write_longint(batch_fd, total_read);
160 write_longint(batch_fd, total_written);
161 write_longint(batch_fd, stats.total_size);
a800434a
AT
162 }
163
164 if (do_stats) {
1f658d42 165 rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
d9c7edf6
WD
166 rprintf(FINFO,"Number of files transferred: %d\n",
167 stats.num_transferred_files);
168 rprintf(FINFO,"Total file size: %.0f bytes\n",
169 (double)stats.total_size);
170 rprintf(FINFO,"Total transferred file size: %.0f bytes\n",
171 (double)stats.total_transferred_size);
172 rprintf(FINFO,"Literal data: %.0f bytes\n",
173 (double)stats.literal_data);
174 rprintf(FINFO,"Matched data: %.0f bytes\n",
175 (double)stats.matched_data);
1f658d42 176 rprintf(FINFO,"File list size: %d\n", stats.flist_size);
d9c7edf6 177 rprintf(FINFO,"Total bytes written: %.0f\n",
b9f592fb 178 (double)total_written);
577ab12c 179 rprintf(FINFO,"Total bytes read: %.0f\n",
b9f592fb 180 (double)total_read);
7a6421fa 181 }
d9c7edf6 182
e19452a9 183 if (verbose || do_stats) {
b9f592fb
WD
184 rprintf(FINFO,
185 "\nwrote %.0f bytes read %.0f bytes %.2f bytes/sec\n",
186 (double)total_written, (double)total_read,
187 (total_written + total_read)/(0.5 + (t - starttime)));
188 rprintf(FINFO, "total size is %.0f speedup is %.2f\n",
d9c7edf6 189 (double)stats.total_size,
b9f592fb 190 (double)stats.total_size / (total_written+total_read));
e19452a9 191 }
fc8a6b97
AT
192
193 fflush(stdout);
194 fflush(stderr);
c627d613
AT
195}
196
197
e5a2b854
MP
198/**
199 * If our C library can get malloc statistics, then show them to FINFO
200 **/
201static void show_malloc_stats(void)
202{
203#ifdef HAVE_MALLINFO
204 struct mallinfo mi;
205
206 mi = mallinfo();
207
ce672562 208 rprintf(FINFO, "\n" RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
5c15e29f
MP
209 getpid(),
210 am_server ? "server " : "",
211 am_daemon ? "daemon " : "",
b695f242 212 who_am_i());
e5a2b854
MP
213 rprintf(FINFO, " arena: %10d (bytes from sbrk)\n", mi.arena);
214 rprintf(FINFO, " ordblks: %10d (chunks not in use)\n", mi.ordblks);
215 rprintf(FINFO, " smblks: %10d\n", mi.smblks);
216 rprintf(FINFO, " hblks: %10d (chunks from mmap)\n", mi.hblks);
217 rprintf(FINFO, " hblkhd: %10d (bytes from mmap)\n", mi.hblkhd);
7b74bba1
S
218 rprintf(FINFO, " allmem: %10d (bytes from sbrk + mmap)\n",
219 mi.arena + mi.hblkhd);
e5a2b854
MP
220 rprintf(FINFO, " usmblks: %10d\n", mi.usmblks);
221 rprintf(FINFO, " fsmblks: %10d\n", mi.fsmblks);
222 rprintf(FINFO, " uordblks: %10d (bytes used)\n", mi.uordblks);
223 rprintf(FINFO, " fordblks: %10d (bytes free)\n", mi.fordblks);
224 rprintf(FINFO, " keepcost: %10d (bytes in releasable chunk)\n", mi.keepcost);
225#endif /* HAVE_MALLINFO */
226}
227
228
0882faa2 229/* Start the remote shell. cmd may be NULL to use the default. */
6c2e5b56
WD
230static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
231 int *f_in, int *f_out)
c627d613 232{
6c2e5b56 233 int i, argc = 0;
887e553f 234 char *args[MAX_ARGS];
19b27a48 235 pid_t ret;
6c2e5b56 236 char *tok, *dir = NULL;
bb4aa89c 237 int dash_l_set = 0;
366345fe 238
088aac85 239 if (!read_batch && !local_server) {
9af87151 240 char *rsh_env = getenv(RSYNC_RSH_ENV);
366345fe 241 if (!cmd)
9af87151 242 cmd = rsh_env;
366345fe
AT
243 if (!cmd)
244 cmd = RSYNC_RSH;
245 cmd = strdup(cmd);
d9c7edf6 246 if (!cmd)
366345fe
AT
247 goto oom;
248
887e553f 249 for (tok = strtok(cmd, " "); tok; tok = strtok(NULL, " ")) {
e7a392c7
WD
250 /* Comparison leaves rooms for server_options(). */
251 if (argc >= MAX_ARGS - 100) {
252 rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
887e553f
WD
253 exit_cleanup(RERR_SYNTAX);
254 }
366345fe 255 args[argc++] = tok;
887e553f 256 }
c627d613 257
d9c7edf6 258 /* check to see if we've already been given '-l user' in
9af87151 259 * the remote-shell command */
bb4aa89c
WD
260 for (i = 0; i < argc-1; i++) {
261 if (!strcmp(args[i], "-l") && args[i+1][0] != '-')
262 dash_l_set = 1;
263 }
264
7b8356d0 265#if HAVE_REMSH
366345fe
AT
266 /* remsh (on HPUX) takes the arguments the other way around */
267 args[argc++] = machine;
bb4aa89c 268 if (user && !(daemon_over_rsh && dash_l_set)) {
366345fe
AT
269 args[argc++] = "-l";
270 args[argc++] = user;
271 }
7b8356d0 272#else
bb4aa89c 273 if (user && !(daemon_over_rsh && dash_l_set)) {
366345fe
AT
274 args[argc++] = "-l";
275 args[argc++] = user;
276 }
277 args[argc++] = machine;
7b8356d0 278#endif
c627d613 279
366345fe 280 args[argc++] = rsync_path;
c627d613 281
9af87151 282 if (blocking_io < 0) {
90e22f4b
WD
283 char *cp;
284 if ((cp = strrchr(cmd, '/')) != NULL)
285 cp++;
286 else
287 cp = cmd;
288 if (strcmp(cp, "rsh") == 0 || strcmp(cp, "remsh") == 0)
289 blocking_io = 1;
66b71163 290 }
e384bfbd 291
93689aa5 292 server_options(args,&argc);
e7a392c7
WD
293
294 if (argc >= MAX_ARGS - 2) {
295 rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
296 exit_cleanup(RERR_SYNTAX);
297 }
366345fe 298 }
c627d613 299
366345fe 300 args[argc++] = ".";
76076c4b 301
d9c7edf6 302 if (!daemon_over_rsh && path && *path)
366345fe 303 args[argc++] = path;
c627d613 304
366345fe 305 args[argc] = NULL;
c627d613 306
366345fe 307 if (verbose > 3) {
9486289c 308 rprintf(FINFO,"cmd=");
e7a392c7 309 for (i = 0; i < argc; i++)
9486289c
AT
310 rprintf(FINFO,"%s ",args[i]);
311 rprintf(FINFO,"\n");
366345fe
AT
312 }
313
314 if (local_server) {
b1df18d7
WD
315 /* If the user didn't request --[no-]whole-file, force
316 * it on, but only if we're not batch processing. */
317 if (whole_file < 0 && !read_batch && !write_batch)
318 whole_file = 1;
25d34a5c 319 ret = local_child(argc, args, f_in, f_out, child_main);
366345fe
AT
320 } else {
321 ret = piped_child(args,f_in,f_out);
322 }
c627d613 323
3a69fad0
WD
324 if (dir)
325 free(dir);
82306bf6 326
366345fe 327 return ret;
c627d613
AT
328
329oom:
366345fe
AT
330 out_of_memory("do_cmd");
331 return 0; /* not reached */
c627d613
AT
332}
333
334
c627d613
AT
335static char *get_local_name(struct file_list *flist,char *name)
336{
7a6421fa 337 STRUCT_STAT st;
87cc45e1 338 int e;
c627d613 339
c95da96a 340 if (verbose > 2)
d9c7edf6 341 rprintf(FINFO,"get_local_name count=%d %s\n",
1f0610ef
DD
342 flist->count, NS(name));
343
d9c7edf6 344 if (!name)
1f0610ef 345 return NULL;
c95da96a 346
1ff5450d
AT
347 if (do_stat(name,&st) == 0) {
348 if (S_ISDIR(st.st_mode)) {
59187666 349 if (!push_dir(name)) {
982e05bb
WD
350 rsyserr(FERROR, errno, "push_dir#1 %s failed",
351 full_fname(name));
65417579 352 exit_cleanup(RERR_FILESELECT);
1ff5450d
AT
353 }
354 return NULL;
355 }
356 if (flist->count > 1) {
357 rprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
65417579 358 exit_cleanup(RERR_FILESELECT);
1ff5450d
AT
359 }
360 return name;
361 }
362
87cc45e1 363 if (flist->count <= 1 && ((e = strlen(name)) <= 1 || name[e-1] != '/'))
1ff5450d
AT
364 return name;
365
1ff5450d 366 if (do_mkdir(name,0777 & ~orig_umask) != 0) {
982e05bb 367 rsyserr(FERROR, errno, "mkdir %s failed", full_fname(name));
65417579 368 exit_cleanup(RERR_FILEIO);
1ff5450d 369 } else {
b536f47e
AT
370 if (verbose > 0)
371 rprintf(FINFO,"created directory %s\n",name);
1ff5450d
AT
372 }
373
59187666 374 if (!push_dir(name)) {
982e05bb
WD
375 rsyserr(FERROR, errno, "push_dir#2 %s failed",
376 full_fname(name));
65417579 377 exit_cleanup(RERR_FILESELECT);
1ff5450d
AT
378 }
379
380 return NULL;
c627d613
AT
381}
382
383
9486289c 384static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
c627d613 385{
7a6421fa
AT
386 int i;
387 struct file_list *flist;
388 char *dir = argv[0];
c627d613 389
45e08edb
WD
390 if (verbose > 2) {
391 rprintf(FINFO, "server_sender starting pid=%ld\n",
392 (long)getpid());
393 }
d9c7edf6 394
7a92ded3
WD
395 if (am_daemon && lp_write_only(module_id) && am_sender) {
396 rprintf(FERROR, "ERROR: module is write only\n");
397 exit_cleanup(RERR_SYNTAX);
398 return;
399 }
400
59187666 401 if (!relative_paths && !push_dir(dir)) {
982e05bb
WD
402 rsyserr(FERROR, errno, "push_dir#3 %s failed",
403 full_fname(dir));
65417579 404 exit_cleanup(RERR_FILESELECT);
7a6421fa
AT
405 }
406 argc--;
407 argv++;
d9c7edf6 408
7a6421fa
AT
409 if (strcmp(dir,".")) {
410 int l = strlen(dir);
d9c7edf6 411 if (strcmp(dir,"/") == 0)
7a6421fa 412 l = 0;
e7a392c7 413 for (i = 0; i < argc; i++)
7a6421fa
AT
414 argv[i] += l+1;
415 }
c627d613 416
7a6421fa 417 if (argc == 0 && recurse) {
e1f67417 418 argc = 1;
7a6421fa
AT
419 argv--;
420 argv[0] = ".";
421 }
d9c7edf6 422
7a6421fa 423 flist = send_file_list(f_out,argc,argv);
8d9dc9f9
AT
424 if (!flist || flist->count == 0) {
425 exit_cleanup(0);
426 }
427
da3478b2
WD
428 io_start_buffering_in();
429 io_start_buffering_out();
430
7a6421fa 431 send_files(flist,f_out,f_in);
f1e3656e 432 io_flush(FULL_FLUSH);
7a6421fa 433 report(f_out);
d04e9c51 434 if (protocol_version >= 24) {
d9c7edf6 435 /* final goodbye message */
64c3523a
WD
436 read_int(f_in);
437 }
f1e3656e 438 io_flush(FULL_FLUSH);
7a6421fa 439 exit_cleanup(0);
c627d613
AT
440}
441
442
dc5ddbcc
AT
443static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
444{
d186eb1a 445 int pid;
e1f67417 446 int status = 0;
554e0a8d 447 int error_pipe[2];
dc5ddbcc 448
d186eb1a
AT
449 if (preserve_hard_links)
450 init_hard_links(flist);
dc5ddbcc 451
6957ae33
AT
452 if (!delete_after) {
453 /* I moved this here from recv_files() to prevent a race condition */
454 if (recurse && delete_mode && !local_name && flist->count>0) {
455 delete_files(flist);
456 }
457 }
458
08f15335 459 if (fd_pair(error_pipe) < 0) {
554e0a8d
AT
460 rprintf(FERROR,"error pipe failed in do_recv\n");
461 exit_cleanup(RERR_SOCKETIO);
462 }
d9c7edf6 463
f1e3656e 464 io_flush(NORMAL_FLUSH);
c6e7fcb4 465
e1f67417 466 if ((pid = do_fork()) == 0) {
554e0a8d 467 close(error_pipe[0]);
3a69fad0
WD
468 if (f_in != f_out)
469 close(f_out);
e08c9610 470
554e0a8d
AT
471 /* we can't let two processes write to the socket at one time */
472 io_multiplexing_close();
473
474 /* set place to send errors */
f1e3656e 475 set_msg_fd_out(error_pipe[1]);
554e0a8d 476
f1e3656e
WD
477 recv_files(f_in,flist,local_name);
478 io_flush(FULL_FLUSH);
ba5e128d 479 report(f_in);
e08c9610 480
f1e3656e
WD
481 send_msg(MSG_DONE, "", 0);
482 io_flush(FULL_FLUSH);
4a748188 483 /* finally we go to sleep until our parent kills us
9af87151
WD
484 * with a USR2 signal. We sleep for a short time as on
485 * some OSes a signal won't interrupt a sleep! */
f1e3656e
WD
486 while (1)
487 msleep(20);
d186eb1a 488 }
dc5ddbcc 489
b695f242 490 am_generator = 1;
b9f592fb
WD
491 if (write_batch)
492 stop_write_batch();
b695f242 493
554e0a8d 494 close(error_pipe[1]);
3a69fad0
WD
495 if (f_in != f_out)
496 close(f_in);
e1b3d5c4 497
da3478b2 498 io_start_buffering_out();
b3e10ed7 499
f1e3656e 500 set_msg_fd_in(error_pipe[0]);
554e0a8d 501
f1e3656e 502 generate_files(f_out, flist, local_name);
8d9dc9f9 503
40da9042 504 get_redo_num(); /* Read final MSG_DONE and any prior messages. */
e5fbaa71 505 report(-1);
f1e3656e 506 io_flush(FULL_FLUSH);
d04e9c51 507 if (protocol_version >= 24) {
8ada7518
AT
508 /* send a final goodbye message */
509 write_int(f_out, -1);
510 }
f1e3656e 511 io_flush(FULL_FLUSH);
8ada7518 512
f1e3656e 513 set_msg_fd_in(-1);
089a2435 514 kill(pid, SIGUSR2);
d79d1c69 515 wait_process(pid, &status);
d186eb1a 516 return status;
dc5ddbcc
AT
517}
518
c627d613 519
9486289c 520static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
c627d613 521{
7a6421fa
AT
522 int status;
523 struct file_list *flist;
6c2e5b56 524 char *local_name = NULL;
7a6421fa 525 char *dir = NULL;
f0fca04e 526
45e08edb
WD
527 if (verbose > 2) {
528 rprintf(FINFO, "server_recv(%d) starting pid=%ld\n",
529 argc, (long)getpid());
530 }
09b7f5db
AT
531
532 if (am_daemon && lp_read_only(module_id) && !am_sender) {
533 rprintf(FERROR,"ERROR: module is read only\n");
534 exit_cleanup(RERR_SYNTAX);
535 return;
536 }
537
d9c7edf6 538
7a6421fa
AT
539 if (argc > 0) {
540 dir = argv[0];
541 argc--;
542 argv++;
59187666 543 if (!am_daemon && !push_dir(dir)) {
982e05bb
WD
544 rsyserr(FERROR, errno, "push_dir#4 %s failed",
545 full_fname(dir));
65417579 546 exit_cleanup(RERR_FILESELECT);
d9c7edf6 547 }
7a6421fa 548 }
c627d613 549
da3478b2 550 io_start_buffering_in();
b33b791e 551 if (delete_mode && !delete_excluded)
7a6421fa 552 recv_exclude_list(f_in);
c627d613 553
7c2a9e76
WD
554 if (filesfrom_fd >= 0) {
555 /* We're receiving the file info from the sender, so we need
556 * the IO routines to automatically write out the names onto
557 * our f_out socket as we read the list info from the sender.
558 * This avoids both deadlock and extra delays/buffers. */
559 io_set_filesfrom_fds(filesfrom_fd, f_out);
560 filesfrom_fd = -1;
561 }
562
b9f592fb 563 flist = recv_file_list(f_in);
4c36a13e
AT
564 if (!flist) {
565 rprintf(FERROR,"server_recv: recv_file_list error\n");
65417579 566 exit_cleanup(RERR_FILESELECT);
7a6421fa 567 }
d9c7edf6
WD
568
569 if (argc > 0) {
7a6421fa
AT
570 if (strcmp(dir,".")) {
571 argv[0] += strlen(dir);
3a69fad0
WD
572 if (argv[0][0] == '/')
573 argv[0]++;
7a6421fa
AT
574 }
575 local_name = get_local_name(flist,argv[0]);
576 }
c627d613 577
7a6421fa
AT
578 status = do_recv(f_in,f_out,flist,local_name);
579 exit_cleanup(status);
c627d613
AT
580}
581
582
734a94a2 583int child_main(int argc, char *argv[])
25d34a5c
MP
584{
585 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
734a94a2 586 return 0;
25d34a5c
MP
587}
588
589
9486289c 590void start_server(int f_in, int f_out, int argc, char *argv[])
366345fe 591{
f0359dd0
AT
592 set_nonblocking(f_in);
593 set_nonblocking(f_out);
594
da3478b2
WD
595 io_set_sock_fds(f_in, f_out);
596 setup_protocol(f_out, f_in);
597
d04e9c51 598 if (protocol_version >= 23)
da3478b2 599 io_start_multiplex_out();
7a6421fa 600
7a6421fa 601 if (am_sender) {
83926d3c 602 keep_dirlinks = 0; /* Must be disabled on the sender. */
9b3318b0 603
b9f592fb
WD
604 recv_exclude_list(f_in);
605 if (cvs_exclude)
606 add_cvs_excludes();
7a6421fa
AT
607 do_server_sender(f_in, f_out, argc, argv);
608 } else {
609 do_server_recv(f_in, f_out, argc, argv);
610 }
611 exit_cleanup(0);
366345fe
AT
612}
613
0ba48136
MP
614
615/*
616 * This is called once the connection has been negotiated. It is used
617 * for rsyncd, remote-shell, and local connections.
618 */
19b27a48 619int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
9486289c 620{
088aac85 621 struct file_list *flist = NULL;
9486289c
AT
622 int status = 0, status2 = 0;
623 char *local_name = NULL;
19b27a48
AT
624
625 cleanup_child_pid = pid;
b9f592fb
WD
626 if (read_batch) {
627 /* This is the heart of the read_batch approach:
628 * Switcher-roo the file descriptors, and
629 * nobody's the wiser. */
630 close(f_in);
631 close(f_out);
632 f_in = batch_fd;
633 f_out = do_open("/dev/null", O_WRONLY, 0);
634 assert(am_sender == 0);
635 } else {
636 set_nonblocking(f_in);
637 set_nonblocking(f_out);
638 }
f0359dd0 639
da3478b2 640 io_set_sock_fds(f_in, f_out);
6d7b6081
AT
641 setup_protocol(f_out,f_in);
642
b9f592fb 643 if (protocol_version >= 23 && !read_batch)
da3478b2 644 io_start_multiplex_in();
d9c7edf6 645
9486289c 646 if (am_sender) {
83926d3c 647 keep_dirlinks = 0; /* Must be disabled on the sender. */
da3478b2 648 io_start_buffering_out();
9486289c
AT
649 if (cvs_exclude)
650 add_cvs_excludes();
d9c7edf6 651 if (delete_mode && !delete_excluded)
9486289c 652 send_exclude_list(f_out);
7c2a9e76
WD
653 if (remote_filesfrom_file)
654 filesfrom_fd = f_in;
b9f592fb
WD
655
656 if (write_batch)
657 start_write_batch(f_out);
658 /* Can be unconditional, but this is theoretically
659 * more efficent for read_batch case. */
64c3523a 660 if (!read_batch) /* don't write to pipe */
d9c7edf6
WD
661 flist = send_file_list(f_out,argc,argv);
662 if (verbose > 3)
9486289c 663 rprintf(FINFO,"file list sent\n");
e1b3d5c4 664
f1e3656e 665 io_flush(NORMAL_FLUSH);
9486289c 666 send_files(flist,f_out,f_in);
f1e3656e 667 io_flush(FULL_FLUSH);
d04e9c51 668 if (protocol_version >= 24) {
d9c7edf6 669 /* final goodbye message */
6c65e146
AT
670 read_int(f_in);
671 }
9486289c
AT
672 if (pid != -1) {
673 if (verbose > 3)
08a740ff 674 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
f1e3656e 675 io_flush(FULL_FLUSH);
d79d1c69 676 wait_process(pid, &status);
9486289c 677 }
3d382777 678 report(-1);
f1e3656e 679 io_flush(FULL_FLUSH);
9486289c
AT
680 exit_cleanup(status);
681 }
f7632fc6 682
1082b52b 683 if (argc == 0)
27e3e9c9 684 list_only = 1;
d9c7edf6 685
b9f592fb
WD
686 /* Can be unconditional, but this is theoretically more
687 * efficient for the read_batch case. */
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;
088aac85 1023 int orig_argc;
76f79ba7 1024 char **orig_argv;
6902ed17 1025
088aac85 1026 orig_argc = argc;
76f79ba7 1027 orig_argv = argv;
5d6bcd44 1028
7a6421fa 1029 signal(SIGUSR1, sigusr1_handler);
8b35435f 1030 signal(SIGUSR2, sigusr2_handler);
19b27a48 1031 signal(SIGCHLD, sigchld_handler);
c0531332
MP
1032#ifdef MAINTAINER_MODE
1033 signal(SIGSEGV, rsync_panic_handler);
1034 signal(SIGFPE, rsync_panic_handler);
1035 signal(SIGABRT, rsync_panic_handler);
1036 signal(SIGBUS, rsync_panic_handler);
1037#endif /* def MAINTAINER_MODE */
5d6bcd44 1038
7a6421fa 1039 starttime = time(NULL);
6fe05820 1040 am_root = (MY_UID() == 0);
c627d613 1041
a800434a
AT
1042 memset(&stats, 0, sizeof(stats));
1043
df5e03da
AT
1044 if (argc < 2) {
1045 usage(FERROR);
65417579 1046 exit_cleanup(RERR_SYNTAX);
df5e03da
AT
1047 }
1048
7a6421fa 1049 /* we set a 0 umask so that correct file permissions can be
9af87151 1050 * carried across */
7a6421fa 1051 orig_umask = (int)umask(0);
5d6bcd44 1052
50135767 1053 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
d9c7edf6
WD
1054 /* FIXME: We ought to call the same error-handling
1055 * code here, rather than relying on getopt. */
50135767 1056 option_error();
65417579 1057 exit_cleanup(RERR_SYNTAX);
b11ed3b1 1058 }
5d6bcd44 1059
7a6421fa 1060 signal(SIGINT,SIGNAL_CAST sig_int);
7a6421fa 1061 signal(SIGHUP,SIGNAL_CAST sig_int);
8638dd48 1062 signal(SIGTERM,SIGNAL_CAST sig_int);
6b83141d 1063
34758d5c
MP
1064 /* Ignore SIGPIPE; we consistently check error codes and will
1065 * see the EPIPE. */
1066 signal(SIGPIPE, SIG_IGN);
1067
c226b7c2 1068 /* Initialize push_dir here because on some old systems getcwd
9af87151
WD
1069 * (implemented by forking "pwd" and reading its output) doesn't
1070 * work when there are other child processes. Also, on all systems
1071 * that implement getcwd that way "pwd" can't be found after chroot. */
59187666 1072 push_dir(NULL);
c226b7c2 1073
44e9e221
WD
1074 init_flist();
1075
b9f592fb
WD
1076 if (write_batch || read_batch) {
1077 if (write_batch)
1078 write_batch_argvs_file(orig_argc, orig_argv);
1079
dbbab0c4
WD
1080 if (read_batch && strcmp(batch_name, "-") == 0)
1081 batch_fd = STDIN_FILENO;
1082 else {
1083 batch_fd = do_open(batch_name,
b9f592fb
WD
1084 write_batch ? O_WRONLY | O_CREAT | O_TRUNC
1085 : O_RDONLY, S_IRUSR | S_IWUSR);
dbbab0c4 1086 }
b9f592fb
WD
1087 if (batch_fd < 0) {
1088 rsyserr(FERROR, errno, "Batch file %s open error",
9b3318b0 1089 batch_name);
b9f592fb
WD
1090 exit_cleanup(RERR_FILEIO);
1091 }
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}