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