Changed exclude/include matching so that normally wildcards will stop at
[rsync/rsync.git] / main.c
CommitLineData
c627d613
AT
1/*
2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#include "rsync.h"
21
f0fca04e 22time_t starttime = 0;
a800434a
AT
23
24struct stats stats;
5d6bcd44 25
34ccb63e 26extern int csum_length;
c627d613 27
7a6421fa 28extern int verbose;
c627d613
AT
29
30static void report(int f)
31{
7a6421fa
AT
32 time_t t = time(NULL);
33 extern int am_server;
34 extern int am_sender;
248fbb8c 35 extern int am_daemon;
a800434a 36 extern int do_stats;
7a6421fa 37
248fbb8c 38 if (am_daemon) {
a9766ef1 39 log_exit(0, __FILE__, __LINE__);
7b372642 40 if (f == -1 || !am_sender) return;
248fbb8c
AT
41 }
42
e19452a9
DD
43 if (am_server) {
44 if (verbose && am_sender) {
23c5aef1
DD
45 int64 w;
46 /* store total_written in a temporary
47 because write_longint changes it */
48 w = stats.total_written;
e19452a9 49 write_longint(f,stats.total_read);
23c5aef1 50 write_longint(f,w);
e19452a9
DD
51 write_longint(f,stats.total_size);
52 }
7a6421fa
AT
53 return;
54 }
e19452a9
DD
55
56 /* this is the client */
57
58 if (!am_sender && verbose) {
59 /* note that if (!verbose && do_stats) then these values will
60 be taken from the receiver side's copy. The total size
61 is identical but the bytes read and written are slightly
62 different. It's done this way to avoid modifying the
63 protocol to support --stats without -v. */
23c5aef1 64 int64 r;
a800434a 65 stats.total_written = read_longint(f);
23c5aef1
DD
66 /* store total_read in a temporary, read_longint changes it */
67 r = read_longint(f);
a800434a 68 stats.total_size = read_longint(f);
23c5aef1 69 stats.total_read = r;
a800434a
AT
70 }
71
72 if (do_stats) {
1f658d42
AT
73 rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
74 rprintf(FINFO,"Number of files transferred: %d\n",
a800434a 75 stats.num_transferred_files);
1f658d42 76 rprintf(FINFO,"Total file size: %.0f bytes\n",
a800434a 77 (double)stats.total_size);
1f658d42 78 rprintf(FINFO,"Total transferred file size: %.0f bytes\n",
a800434a 79 (double)stats.total_transferred_size);
1f658d42 80 rprintf(FINFO,"Literal data: %.0f bytes\n",
a800434a 81 (double)stats.literal_data);
1f658d42 82 rprintf(FINFO,"Matched data: %.0f bytes\n",
a800434a 83 (double)stats.matched_data);
1f658d42
AT
84 rprintf(FINFO,"File list size: %d\n", stats.flist_size);
85 rprintf(FINFO,"Total bytes written: %.0f\n",
a800434a 86 (double)stats.total_written);
1f658d42 87 rprintf(FINFO,"Total bytes read: %.0f\n\n",
a800434a 88 (double)stats.total_read);
7a6421fa
AT
89 }
90
e19452a9
DD
91 if (verbose || do_stats) {
92 rprintf(FINFO,"wrote %.0f bytes read %.0f bytes %.2f bytes/sec\n",
93 (double)stats.total_written,
94 (double)stats.total_read,
95 (stats.total_written+stats.total_read)/(0.5 + (t-starttime)));
96 rprintf(FINFO,"total size is %.0f speedup is %.2f\n",
97 (double)stats.total_size,
98 (1.0*stats.total_size)/(stats.total_written+stats.total_read));
99 }
fc8a6b97
AT
100
101 fflush(stdout);
102 fflush(stderr);
c627d613
AT
103}
104
105
e3cd198f 106static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
c627d613 107{
366345fe
AT
108 char *args[100];
109 int i,argc=0, ret;
110 char *tok,*dir=NULL;
7a6421fa
AT
111 extern int local_server;
112 extern char *rsync_path;
366345fe
AT
113
114 if (!local_server) {
115 if (!cmd)
116 cmd = getenv(RSYNC_RSH_ENV);
117 if (!cmd)
118 cmd = RSYNC_RSH;
119 cmd = strdup(cmd);
120 if (!cmd)
121 goto oom;
122
123 for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
124 args[argc++] = tok;
125 }
c627d613 126
7b8356d0 127#if HAVE_REMSH
366345fe
AT
128 /* remsh (on HPUX) takes the arguments the other way around */
129 args[argc++] = machine;
130 if (user) {
131 args[argc++] = "-l";
132 args[argc++] = user;
133 }
7b8356d0 134#else
366345fe
AT
135 if (user) {
136 args[argc++] = "-l";
137 args[argc++] = user;
138 }
139 args[argc++] = machine;
7b8356d0 140#endif
c627d613 141
366345fe 142 args[argc++] = rsync_path;
c627d613 143
366345fe
AT
144 server_options(args,&argc);
145 }
c627d613 146
366345fe 147 args[argc++] = ".";
76076c4b 148
366345fe
AT
149 if (path && *path)
150 args[argc++] = path;
c627d613 151
366345fe 152 args[argc] = NULL;
c627d613 153
366345fe 154 if (verbose > 3) {
9486289c 155 rprintf(FINFO,"cmd=");
366345fe 156 for (i=0;i<argc;i++)
9486289c
AT
157 rprintf(FINFO,"%s ",args[i]);
158 rprintf(FINFO,"\n");
366345fe
AT
159 }
160
161 if (local_server) {
162 ret = local_child(argc, args, f_in, f_out);
163 } else {
164 ret = piped_child(args,f_in,f_out);
165 }
c627d613 166
366345fe 167 if (dir) free(dir);
82306bf6 168
366345fe 169 return ret;
c627d613
AT
170
171oom:
366345fe
AT
172 out_of_memory("do_cmd");
173 return 0; /* not reached */
c627d613
AT
174}
175
176
177
178
179static char *get_local_name(struct file_list *flist,char *name)
180{
7a6421fa
AT
181 STRUCT_STAT st;
182 extern int orig_umask;
c627d613 183
c95da96a
AT
184 if (verbose > 2)
185 rprintf(FINFO,"get_local_name count=%d %s\n",
1f0610ef
DD
186 flist->count, NS(name));
187
188 if (!name)
189 return NULL;
c95da96a 190
1ff5450d
AT
191 if (do_stat(name,&st) == 0) {
192 if (S_ISDIR(st.st_mode)) {
5243c216
AT
193 if (!push_dir(name, 0)) {
194 rprintf(FERROR,"push_dir %s : %s (1)\n",
1ff5450d 195 name,strerror(errno));
65417579 196 exit_cleanup(RERR_FILESELECT);
1ff5450d
AT
197 }
198 return NULL;
199 }
200 if (flist->count > 1) {
201 rprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
65417579 202 exit_cleanup(RERR_FILESELECT);
1ff5450d
AT
203 }
204 return name;
205 }
206
207 if (flist->count == 1)
208 return name;
209
1ff5450d
AT
210 if (do_mkdir(name,0777 & ~orig_umask) != 0) {
211 rprintf(FERROR,"mkdir %s : %s (1)\n",name,strerror(errno));
65417579 212 exit_cleanup(RERR_FILEIO);
1ff5450d 213 } else {
b536f47e
AT
214 if (verbose > 0)
215 rprintf(FINFO,"created directory %s\n",name);
1ff5450d
AT
216 }
217
5243c216
AT
218 if (!push_dir(name, 0)) {
219 rprintf(FERROR,"push_dir %s : %s (2)\n",
220 name,strerror(errno));
65417579 221 exit_cleanup(RERR_FILESELECT);
1ff5450d
AT
222 }
223
224 return NULL;
c627d613
AT
225}
226
227
228
229
9486289c 230static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
c627d613 231{
7a6421fa
AT
232 int i;
233 struct file_list *flist;
234 char *dir = argv[0];
235 extern int relative_paths;
7a6421fa 236 extern int recurse;
c627d613 237
7a6421fa
AT
238 if (verbose > 2)
239 rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
c627d613 240
5243c216
AT
241 if (!relative_paths && !push_dir(dir, 0)) {
242 rprintf(FERROR,"push_dir %s: %s (3)\n",dir,strerror(errno));
65417579 243 exit_cleanup(RERR_FILESELECT);
7a6421fa
AT
244 }
245 argc--;
246 argv++;
c627d613 247
7a6421fa
AT
248 if (strcmp(dir,".")) {
249 int l = strlen(dir);
250 if (strcmp(dir,"/") == 0)
251 l = 0;
252 for (i=0;i<argc;i++)
253 argv[i] += l+1;
254 }
c627d613 255
7a6421fa
AT
256 if (argc == 0 && recurse) {
257 argc=1;
258 argv--;
259 argv[0] = ".";
260 }
261
3eb38818
AT
262 set_nonblocking(f_out);
263 if (f_in != f_out)
264 set_nonblocking(f_in);
265
7a6421fa 266 flist = send_file_list(f_out,argc,argv);
8d9dc9f9
AT
267 if (!flist || flist->count == 0) {
268 exit_cleanup(0);
269 }
270
7a6421fa
AT
271 send_files(flist,f_out,f_in);
272 report(f_out);
8d9dc9f9 273 io_flush();
7a6421fa 274 exit_cleanup(0);
c627d613
AT
275}
276
277
dc5ddbcc
AT
278static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
279{
d186eb1a
AT
280 int pid;
281 int status=0;
282 int recv_pipe[2];
283 extern int preserve_hard_links;
dc5ddbcc 284
d186eb1a
AT
285 if (preserve_hard_links)
286 init_hard_links(flist);
dc5ddbcc 287
d186eb1a
AT
288 if (pipe(recv_pipe) < 0) {
289 rprintf(FERROR,"pipe failed in do_recv\n");
65417579 290 exit_cleanup(RERR_SOCKETIO);
d186eb1a 291 }
c6e7fcb4 292
8d9dc9f9 293 io_flush();
c6e7fcb4 294
d186eb1a 295 if ((pid=do_fork()) == 0) {
e08c9610
AT
296 close(recv_pipe[0]);
297 if (f_in != f_out) close(f_out);
298
e1b3d5c4 299 set_nonblocking(f_in);
3eb38818 300 set_nonblocking(recv_pipe[1]);
e1b3d5c4 301
e08c9610 302 recv_files(f_in,flist,local_name,recv_pipe[1]);
ba5e128d 303 report(f_in);
e08c9610 304
8d9dc9f9
AT
305 io_flush();
306 _exit(0);
d186eb1a 307 }
dc5ddbcc 308
e08c9610
AT
309 close(recv_pipe[1]);
310 io_close_input(f_in);
311 if (f_in != f_out) close(f_in);
e1b3d5c4
AT
312
313 set_nonblocking(f_out);
3eb38818 314 set_nonblocking(recv_pipe[0]);
e1b3d5c4 315
b3e10ed7
AT
316 io_start_buffering(f_out);
317
e08c9610 318 generate_files(f_out,flist,local_name,recv_pipe[0]);
8d9dc9f9
AT
319
320 io_flush();
d186eb1a 321 waitpid(pid, &status, 0);
d186eb1a 322 return status;
dc5ddbcc
AT
323}
324
c627d613 325
9486289c 326static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
c627d613 327{
7a6421fa
AT
328 int status;
329 struct file_list *flist;
330 char *local_name=NULL;
331 char *dir = NULL;
332 extern int delete_mode;
333 extern int am_daemon;
f0fca04e 334
7a6421fa
AT
335 if (verbose > 2)
336 rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
337
7a6421fa
AT
338 if (argc > 0) {
339 dir = argv[0];
340 argc--;
341 argv++;
5243c216
AT
342 if (!am_daemon && !push_dir(dir, 0)) {
343 rprintf(FERROR,"push_dir %s : %s (4)\n",
7a6421fa 344 dir,strerror(errno));
65417579 345 exit_cleanup(RERR_FILESELECT);
7a6421fa
AT
346 }
347 }
c627d613 348
7a6421fa
AT
349 if (delete_mode)
350 recv_exclude_list(f_in);
c627d613 351
7a6421fa
AT
352 flist = recv_file_list(f_in);
353 if (!flist || flist->count == 0) {
8d9dc9f9 354 rprintf(FERROR,"server_recv: nothing to do\n");
65417579 355 exit_cleanup(RERR_FILESELECT);
7a6421fa
AT
356 }
357
358 if (argc > 0) {
359 if (strcmp(dir,".")) {
360 argv[0] += strlen(dir);
361 if (argv[0][0] == '/') argv[0]++;
362 }
363 local_name = get_local_name(flist,argv[0]);
364 }
c627d613 365
7a6421fa
AT
366 status = do_recv(f_in,f_out,flist,local_name);
367 exit_cleanup(status);
c627d613
AT
368}
369
370
9486289c 371void start_server(int f_in, int f_out, int argc, char *argv[])
366345fe 372{
7a6421fa
AT
373 extern int cvs_exclude;
374 extern int am_sender;
375
3eb38818
AT
376 set_nonblocking(f_out);
377 if (f_in != f_out)
378 set_nonblocking(f_in);
379
7a6421fa 380 setup_protocol(f_out, f_in);
3eb38818 381
7a6421fa
AT
382 if (am_sender) {
383 recv_exclude_list(f_in);
384 if (cvs_exclude)
385 add_cvs_excludes();
386 do_server_sender(f_in, f_out, argc, argv);
387 } else {
388 do_server_recv(f_in, f_out, argc, argv);
389 }
390 exit_cleanup(0);
366345fe
AT
391}
392
3591c066 393int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
9486289c
AT
394{
395 struct file_list *flist;
396 int status = 0, status2 = 0;
397 char *local_name = NULL;
7a6421fa 398 extern int am_sender;
f7632fc6 399 extern int list_only;
9486289c
AT
400
401 setup_protocol(f_out,f_in);
402
403 if (am_sender) {
7a6421fa
AT
404 extern int cvs_exclude;
405 extern int delete_mode;
9486289c
AT
406 if (cvs_exclude)
407 add_cvs_excludes();
408 if (delete_mode)
409 send_exclude_list(f_out);
410 flist = send_file_list(f_out,argc,argv);
411 if (verbose > 3)
412 rprintf(FINFO,"file list sent\n");
e1b3d5c4
AT
413
414 set_nonblocking(f_out);
415 if (f_in != f_out)
416 set_nonblocking(f_in);
417
9486289c
AT
418 send_files(flist,f_out,f_in);
419 if (pid != -1) {
420 if (verbose > 3)
8d9dc9f9
AT
421 rprintf(FINFO,"client_run waiting on %d\n",pid);
422 io_flush();
9486289c
AT
423 waitpid(pid, &status, 0);
424 }
425 report(-1);
426 exit_cleanup(status);
427 }
f7632fc6
AT
428
429 if (argc == 0) list_only = 1;
9486289c
AT
430
431 send_exclude_list(f_out);
432
433 flist = recv_file_list(f_in);
434 if (!flist || flist->count == 0) {
8d9dc9f9 435 rprintf(FINFO,"client: nothing to do\n");
9486289c
AT
436 exit_cleanup(0);
437 }
438
439 local_name = get_local_name(flist,argv[0]);
440
441 status2 = do_recv(f_in,f_out,flist,local_name);
442
9486289c 443 if (pid != -1) {
8d9dc9f9
AT
444 if (verbose > 3)
445 rprintf(FINFO,"client_run2 waiting on %d\n",pid);
446 io_flush();
9486289c
AT
447 waitpid(pid, &status, 0);
448 }
449
450 return status | status2;
451}
452
ca6c93f8
AT
453static char *find_colon(char *s)
454{
455 char *p, *p2;
456
457 p = strchr(s,':');
458 if (!p) return NULL;
459
460 /* now check to see if there is a / in the string before the : - if there is then
461 discard the colon on the assumption that the : is part of a filename */
462 p2 = strchr(s,'/');
463 if (p2 && p2 < p) return NULL;
464
465 return p;
466}
9486289c 467
fc8a6b97 468static int start_client(int argc, char *argv[])
5d6bcd44
AT
469{
470 char *p;
471 char *shell_machine = NULL;
472 char *shell_path = NULL;
473 char *shell_user = NULL;
fc8a6b97 474 int pid, ret;
5d6bcd44 475 int f_in,f_out;
7a6421fa
AT
476 extern int local_server;
477 extern int am_sender;
478 extern char *shell_cmd;
2acf81eb 479 extern int rsync_port;
5d6bcd44 480
f7632fc6
AT
481 if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) {
482 char *host, *path;
483
484 host = argv[0] + strlen(URL_PREFIX);
485 p = strchr(host,'/');
486 if (p) {
487 *p = 0;
488 path = p+1;
489 } else {
490 path="";
491 }
2acf81eb
DD
492 p = strchr(host,':');
493 if (p) {
494 rsync_port = atoi(p+1);
495 *p = 0;
496 }
f7632fc6
AT
497 return start_socket_client(host, path, argc-1, argv+1);
498 }
499
ca6c93f8 500 p = find_colon(argv[0]);
5d6bcd44
AT
501
502 if (p) {
9486289c
AT
503 if (p[1] == ':') {
504 *p = 0;
505 return start_socket_client(argv[0], p+2, argc-1, argv+1);
506 }
3591c066 507
f7632fc6 508 if (argc < 1) {
3591c066 509 usage(FERROR);
65417579 510 exit_cleanup(RERR_SYNTAX);
3591c066
AT
511 }
512
5d6bcd44
AT
513 am_sender = 0;
514 *p = 0;
515 shell_machine = argv[0];
516 shell_path = p+1;
517 argc--;
518 argv++;
519 } else {
520 am_sender = 1;
9486289c 521
ca6c93f8 522 p = find_colon(argv[argc-1]);
5d6bcd44
AT
523 if (!p) {
524 local_server = 1;
9486289c
AT
525 } else if (p[1] == ':') {
526 *p = 0;
527 return start_socket_client(argv[argc-1], p+2, argc-1, argv);
5d6bcd44 528 }
3591c066
AT
529
530 if (argc < 2) {
531 usage(FERROR);
65417579 532 exit_cleanup(RERR_SYNTAX);
3591c066 533 }
9486289c 534
5d6bcd44
AT
535 if (local_server) {
536 shell_machine = NULL;
537 shell_path = argv[argc-1];
538 } else {
539 *p = 0;
540 shell_machine = argv[argc-1];
541 shell_path = p+1;
542 }
543 argc--;
544 }
545
546 if (shell_machine) {
547 p = strchr(shell_machine,'@');
548 if (p) {
549 *p = 0;
550 shell_user = shell_machine;
551 shell_machine = p+1;
552 }
553 }
554
555 if (verbose > 3) {
9486289c 556 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
5d6bcd44
AT
557 shell_cmd?shell_cmd:"",
558 shell_machine?shell_machine:"",
559 shell_user?shell_user:"",
560 shell_path?shell_path:"");
561 }
562
f7632fc6 563 if (!am_sender && argc > 1) {
5d6bcd44 564 usage(FERROR);
65417579 565 exit_cleanup(RERR_SYNTAX);
5d6bcd44
AT
566 }
567
568 pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out);
569
fc8a6b97
AT
570 ret = client_run(f_in, f_out, pid, argc, argv);
571
572 fflush(stdout);
573 fflush(stderr);
574
575 return ret;
5d6bcd44
AT
576}
577
366345fe 578
6e4fb64e 579static RETSIGTYPE sigusr1_handler(int val) {
65417579 580 exit_cleanup(RERR_SIGNAL);
82306bf6
AT
581}
582
5d6bcd44 583int main(int argc,char *argv[])
7a6421fa
AT
584{
585 extern int am_root;
586 extern int orig_umask;
587 extern int dry_run;
588 extern int am_daemon;
589 extern int am_server;
5d6bcd44 590
7a6421fa 591 signal(SIGUSR1, sigusr1_handler);
5d6bcd44 592
7a6421fa
AT
593 starttime = time(NULL);
594 am_root = (getuid() == 0);
c627d613 595
a800434a
AT
596 memset(&stats, 0, sizeof(stats));
597
df5e03da
AT
598 if (argc < 2) {
599 usage(FERROR);
65417579 600 exit_cleanup(RERR_SYNTAX);
df5e03da
AT
601 }
602
7a6421fa
AT
603 /* we set a 0 umask so that correct file permissions can be
604 carried across */
605 orig_umask = (int)umask(0);
5d6bcd44 606
b86f0cef 607 if (!parse_arguments(argc, argv, 1)) {
65417579 608 exit_cleanup(RERR_SYNTAX);
b11ed3b1 609 }
5d6bcd44 610
7a6421fa
AT
611 argc -= optind;
612 argv += optind;
613 optind = 0;
c627d613 614
7a6421fa
AT
615 signal(SIGCHLD,SIG_IGN);
616 signal(SIGINT,SIGNAL_CAST sig_int);
617 signal(SIGPIPE,SIGNAL_CAST sig_int);
618 signal(SIGHUP,SIGNAL_CAST sig_int);
8638dd48 619 signal(SIGTERM,SIGNAL_CAST sig_int);
6b83141d 620
c226b7c2
DD
621 /* Initialize push_dir here because on some old systems getcwd
622 (implemented by forking "pwd" and reading its output) doesn't
623 work when there are other child processes. Also, on all systems
624 that implement getcwd that way "pwd" can't be found after chroot. */
625 push_dir(NULL,0);
626
7a6421fa
AT
627 if (am_daemon) {
628 return daemon_main();
629 }
f0fca04e 630
08ac228f
AT
631 if (argc < 1) {
632 usage(FERROR);
65417579 633 exit_cleanup(RERR_SYNTAX);
08ac228f
AT
634 }
635
7a6421fa
AT
636 if (dry_run)
637 verbose = MAX(verbose,1);
c627d613 638
cbbe4892 639#ifndef SUPPORT_LINKS
7a6421fa
AT
640 if (!am_server && preserve_links) {
641 rprintf(FERROR,"ERROR: symbolic links not supported\n");
65417579 642 exit_cleanup(RERR_UNSUPPORTED);
7a6421fa 643 }
cbbe4892
AT
644#endif
645
7a6421fa
AT
646 if (am_server) {
647 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
648 }
c627d613 649
7a6421fa 650 return start_client(argc, argv);
c627d613 651}
82306bf6 652