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