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