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