When outputting the flist info (in a debug-level of verbosity) we
[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) {
778 *p = 0;
779 path = p+1;
780 } else {
a125c82a 781 path = "";
f7632fc6 782 }
2acf81eb
DD
783 p = strchr(host,':');
784 if (p) {
785 rsync_port = atoi(p+1);
786 *p = 0;
787 }
f7632fc6
AT
788 return start_socket_client(host, path, argc-1, argv+1);
789 }
790
d16c245f 791 if (!read_batch) { /* for read_batch, NO source is specified */
a125c82a 792 p = find_colon(argv[0]);
d16c245f 793 if (p) { /* source is remote */
7c2a9e76
WD
794 if (remote_filesfrom_file
795 && remote_filesfrom_file != files_from + 1
796 && strncmp(files_from, argv[0], p-argv[0]+1) != 0) {
797 rprintf(FERROR,
798 "--files-from hostname is not transfer hostname\n");
799 exit_cleanup(RERR_SYNTAX);
800 }
d9c7edf6
WD
801 if (p[1] == ':') { /* double colon */
802 *p = 0;
803 if (!shell_cmd) {
804 return start_socket_client(argv[0], p+2,
805 argc-1, argv+1);
806 }
807 p++;
808 daemon_over_rsh = 1;
75aeac44 809 }
3591c066 810
d16c245f 811 if (argc < 1) { /* destination required */
d9c7edf6
WD
812 usage(FERROR);
813 exit_cleanup(RERR_SYNTAX);
814 }
a125c82a 815
d9c7edf6
WD
816 am_sender = 0;
817 *p = 0;
818 shell_machine = argv[0];
819 shell_path = p+1;
d9c7edf6 820 argv++;
d16c245f 821 } else { /* source is local */
d9c7edf6
WD
822 am_sender = 1;
823
824 /* rsync:// destination uses rsync server over direct socket */
825 if (strncasecmp(URL_PREFIX, argv[argc-1], strlen(URL_PREFIX)) == 0) {
826 char *host, *path;
827
828 host = argv[argc-1] + strlen(URL_PREFIX);
829 p = strchr(host,'/');
830 if (p) {
831 *p = 0;
832 path = p+1;
833 } else {
834 path = "";
835 }
836 p = strchr(host,':');
837 if (p) {
838 rsync_port = atoi(p+1);
839 *p = 0;
840 }
841 return start_socket_client(host, path, argc-1, argv);
a125c82a 842 }
d9c7edf6 843
d16c245f 844 p = find_colon(argv[argc-1]); /* look in dest arg */
7c2a9e76
WD
845 if (p && remote_filesfrom_file
846 && remote_filesfrom_file != files_from + 1
847 && strncmp(files_from, argv[argc-1], p-argv[argc-1]+1) != 0) {
848 rprintf(FERROR,
849 "--files-from hostname is not transfer hostname\n");
850 exit_cleanup(RERR_SYNTAX);
851 }
d16c245f 852 if (!p) { /* no colon found, so src & dest are local */
d9c7edf6 853 local_server = 1;
7c2a9e76
WD
854 if (remote_filesfrom_file) {
855 rprintf(FERROR,
856 "--files-from is remote but transfer is local\n");
857 exit_cleanup(RERR_SYNTAX);
858 }
d9c7edf6 859 } else if (p[1] == ':') { /* double colon */
a125c82a 860 *p = 0;
d9c7edf6
WD
861 if (!shell_cmd) {
862 return start_socket_client(argv[argc-1], p+2,
863 argc-1, argv);
864 }
865 p++;
866 daemon_over_rsh = 1;
a125c82a 867 }
a125c82a 868
d9c7edf6
WD
869 if (argc < 2) {
870 usage(FERROR);
871 exit_cleanup(RERR_SYNTAX);
75aeac44 872 }
3591c066 873
d9c7edf6
WD
874 if (local_server) {
875 shell_machine = NULL;
876 shell_path = argv[argc-1];
877 } else {
878 *p = 0;
879 shell_machine = argv[argc-1];
880 shell_path = p+1;
881 }
5d6bcd44 882 }
d16c245f
WD
883 argc--;
884 } else { /* read_batch */
d9c7edf6
WD
885 local_server = 1;
886 shell_path = argv[argc-1];
b9f592fb
WD
887 if (find_colon(shell_path)) {
888 rprintf(FERROR, "remote destination is not allowed with --read-batch\n");
889 exit_cleanup(RERR_SYNTAX);
890 }
6902ed17
MP
891 }
892
5d6bcd44 893 if (shell_machine) {
6fc048f4 894 p = strrchr(shell_machine,'@');
5d6bcd44
AT
895 if (p) {
896 *p = 0;
897 shell_user = shell_machine;
898 shell_machine = p+1;
899 }
900 }
901
902 if (verbose > 3) {
9486289c 903 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
5d6bcd44
AT
904 shell_cmd?shell_cmd:"",
905 shell_machine?shell_machine:"",
906 shell_user?shell_user:"",
907 shell_path?shell_path:"");
908 }
d9c7edf6 909
d16c245f 910 /* for remote source, only single dest arg can remain ... */
f7632fc6 911 if (!am_sender && argc > 1) {
5d6bcd44 912 usage(FERROR);
65417579 913 exit_cleanup(RERR_SYNTAX);
5d6bcd44 914 }
27e3e9c9 915
d16c245f
WD
916 /* ... or no dest at all */
917 if (!am_sender && argc == 0) {
27e3e9c9
AT
918 list_only = 1;
919 }
d9c7edf6 920
75aeac44
WD
921 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
922 &f_in,&f_out);
923
924 /* if we're running an rsync server on the remote host over a
9af87151 925 * remote shell command, we need to do the RSYNCD protocol first */
75aeac44
WD
926 if (daemon_over_rsh) {
927 int tmpret;
928 tmpret = start_inband_exchange(shell_user, shell_path,
929 f_in, f_out, argc);
930 if (tmpret < 0)
931 return tmpret;
932 }
933
fc8a6b97
AT
934 ret = client_run(f_in, f_out, pid, argc, argv);
935
936 fflush(stdout);
937 fflush(stderr);
938
939 return ret;
5d6bcd44
AT
940}
941
366345fe 942
067669da
WD
943static RETSIGTYPE sigusr1_handler(UNUSED(int val))
944{
65417579 945 exit_cleanup(RERR_SIGNAL);
82306bf6
AT
946}
947
067669da
WD
948static RETSIGTYPE sigusr2_handler(UNUSED(int val))
949{
19b27a48 950 if (log_got_error) _exit(RERR_PARTIAL);
8b35435f
AT
951 _exit(0);
952}
953
067669da
WD
954static RETSIGTYPE sigchld_handler(UNUSED(int val))
955{
029c1713 956#ifdef WNOHANG
ee7118a8
DD
957 int cnt, status;
958 pid_t pid;
959 /* An empty waitpid() loop was put here by Tridge and we could never
d9c7edf6 960 * get him to explain why he put it in, so rather than taking it
ee7118a8
DD
961 * out we're instead saving the child exit statuses for later use.
962 * The waitpid() loop presumably eliminates all possibility of leaving
963 * zombie children, maybe that's why he did it.
964 */
965 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
9af87151
WD
966 /* save the child's exit status */
967 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
968 if (pid_stat_table[cnt].pid == 0) {
969 pid_stat_table[cnt].pid = pid;
970 pid_stat_table[cnt].status = status;
971 break;
972 }
973 }
ee7118a8 974 }
029c1713 975#endif
19b27a48
AT
976}
977
c0531332
MP
978
979/**
980 * This routine catches signals and tries to send them to gdb.
981 *
982 * Because it's called from inside a signal handler it ought not to
983 * use too many library routines.
984 *
985 * @todo Perhaps use "screen -X" instead/as well, to help people
986 * debugging without easy access to X. Perhaps use an environment
987 * variable, or just call a script?
988 *
989 * @todo The /proc/ magic probably only works on Linux (and
990 * Solaris?) Can we be more portable?
991 **/
992#ifdef MAINTAINER_MODE
4fdc39dd
MP
993const char *get_panic_action(void)
994{
995 const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
996
997 if (cmd_fmt)
998 return cmd_fmt;
999 else
1000 return "xterm -display :0 -T Panic -n Panic "
1001 "-e gdb /proc/%d/exe %d";
1002}
1003
1004
9fb3f7a9
MP
1005/**
1006 * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
1007 *
1008 * This signal handler is only installed if we were configured with
1009 * --enable-maintainer-mode. Perhaps it should always be on and we
1010 * should just look at the environment variable, but I'm a bit leery
1011 * of a signal sending us into a busy loop.
1012 **/
067669da 1013static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
c0531332
MP
1014{
1015 char cmd_buf[300];
1016 int ret;
4fdc39dd
MP
1017
1018 sprintf(cmd_buf, get_panic_action(),
c0531332
MP
1019 getpid(), getpid());
1020
1021 /* Unless we failed to execute gdb, we allow the process to
1022 * continue. I'm not sure if that's right. */
1023 ret = system(cmd_buf);
1024 if (ret)
1025 _exit(ret);
1026}
1027#endif
1028
1029
5d6bcd44 1030int main(int argc,char *argv[])
d9c7edf6 1031{
ff81e809 1032 int ret;
66a9dc96
WD
1033 int orig_argc = argc;
1034 char **orig_argv = argv;
5d6bcd44 1035
7a6421fa 1036 signal(SIGUSR1, sigusr1_handler);
8b35435f 1037 signal(SIGUSR2, sigusr2_handler);
19b27a48 1038 signal(SIGCHLD, sigchld_handler);
c0531332
MP
1039#ifdef MAINTAINER_MODE
1040 signal(SIGSEGV, rsync_panic_handler);
1041 signal(SIGFPE, rsync_panic_handler);
1042 signal(SIGABRT, rsync_panic_handler);
1043 signal(SIGBUS, rsync_panic_handler);
1044#endif /* def MAINTAINER_MODE */
5d6bcd44 1045
7a6421fa 1046 starttime = time(NULL);
6fe05820 1047 am_root = (MY_UID() == 0);
c627d613 1048
a800434a
AT
1049 memset(&stats, 0, sizeof(stats));
1050
df5e03da
AT
1051 if (argc < 2) {
1052 usage(FERROR);
65417579 1053 exit_cleanup(RERR_SYNTAX);
df5e03da
AT
1054 }
1055
7a6421fa 1056 /* we set a 0 umask so that correct file permissions can be
9af87151 1057 * carried across */
7a6421fa 1058 orig_umask = (int)umask(0);
5d6bcd44 1059
50135767 1060 if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
d9c7edf6
WD
1061 /* FIXME: We ought to call the same error-handling
1062 * code here, rather than relying on getopt. */
50135767 1063 option_error();
65417579 1064 exit_cleanup(RERR_SYNTAX);
b11ed3b1 1065 }
5d6bcd44 1066
7a6421fa 1067 signal(SIGINT,SIGNAL_CAST sig_int);
7a6421fa 1068 signal(SIGHUP,SIGNAL_CAST sig_int);
8638dd48 1069 signal(SIGTERM,SIGNAL_CAST sig_int);
6b83141d 1070
34758d5c
MP
1071 /* Ignore SIGPIPE; we consistently check error codes and will
1072 * see the EPIPE. */
1073 signal(SIGPIPE, SIG_IGN);
1074
c226b7c2 1075 /* Initialize push_dir here because on some old systems getcwd
9af87151
WD
1076 * (implemented by forking "pwd" and reading its output) doesn't
1077 * work when there are other child processes. Also, on all systems
1078 * that implement getcwd that way "pwd" can't be found after chroot. */
59187666 1079 push_dir(NULL);
c226b7c2 1080
44e9e221
WD
1081 init_flist();
1082
b9f592fb
WD
1083 if (write_batch || read_batch) {
1084 if (write_batch)
66a9dc96 1085 write_batch_shell_file(orig_argc, orig_argv, argc);
b9f592fb 1086
dbbab0c4
WD
1087 if (read_batch && strcmp(batch_name, "-") == 0)
1088 batch_fd = STDIN_FILENO;
1089 else {
1090 batch_fd = do_open(batch_name,
b9f592fb
WD
1091 write_batch ? O_WRONLY | O_CREAT | O_TRUNC
1092 : O_RDONLY, S_IRUSR | S_IWUSR);
dbbab0c4 1093 }
b9f592fb
WD
1094 if (batch_fd < 0) {
1095 rsyserr(FERROR, errno, "Batch file %s open error",
9b3318b0 1096 batch_name);
b9f592fb
WD
1097 exit_cleanup(RERR_FILEIO);
1098 }
9459290a
WD
1099 if (read_batch)
1100 read_stream_flags(batch_fd);
6902ed17
MP
1101 }
1102
75aeac44 1103 if (am_daemon && !am_server)
7a6421fa 1104 return daemon_main();
f0fca04e 1105
08ac228f
AT
1106 if (argc < 1) {
1107 usage(FERROR);
65417579 1108 exit_cleanup(RERR_SYNTAX);
08ac228f
AT
1109 }
1110
7a6421fa
AT
1111 if (dry_run)
1112 verbose = MAX(verbose,1);
c627d613 1113
7a6421fa 1114 if (am_server) {
f0359dd0
AT
1115 set_nonblocking(STDIN_FILENO);
1116 set_nonblocking(STDOUT_FILENO);
75aeac44
WD
1117 if (am_daemon)
1118 return start_daemon(STDIN_FILENO, STDOUT_FILENO);
7a6421fa
AT
1119 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
1120 }
c627d613 1121
ff81e809 1122 ret = start_client(argc, argv);
d9c7edf6 1123 if (ret == -1)
9098bbf3 1124 exit_cleanup(RERR_STARTCLIENT);
088aac85 1125 else
9098bbf3
MP
1126 exit_cleanup(ret);
1127
0f5a04e3 1128 return ret;
c627d613 1129}