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