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