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