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