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