added note to docs saying that --stats doesn't work unless -v is used
[rsync/rsync.git] / rsync.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
43a481dc
AT
22extern int csum_length;
23
c627d613
AT
24extern int verbose;
25extern int am_server;
26extern int always_checksum;
27extern time_t starttime;
28
c6e7fcb4
AT
29extern int remote_version;
30
c627d613 31extern char *backup_suffix;
950ab32d 32extern char *tmpdir;
c627d613 33
82306bf6 34extern int whole_file;
c627d613
AT
35extern int block_size;
36extern int update_only;
37extern int make_backups;
38extern int preserve_links;
dc5ddbcc 39extern int preserve_hard_links;
c627d613
AT
40extern int preserve_perms;
41extern int preserve_devices;
42extern int preserve_uid;
43extern int preserve_gid;
44extern int preserve_times;
45extern int dry_run;
46extern int ignore_times;
47extern int recurse;
48extern int delete_mode;
49extern int cvs_exclude;
7b8356d0 50extern int am_root;
6574b4f7 51extern int relative_paths;
6ba9279f
AT
52extern int io_timeout;
53extern int io_error;
a800434a 54extern struct stats stats;
c627d613
AT
55
56/*
57 free a sums struct
58 */
59static void free_sums(struct sum_struct *s)
60{
61 if (s->sums) free(s->sums);
62 free(s);
63}
64
65
3cb6f5d6
AT
66/*
67 * delete a file or directory. If force_delet is set then delete
68 * recursively
69 */
70static int delete_file(char *fname)
71{
72 DIR *d;
73 struct dirent *di;
74 char buf[MAXPATHLEN];
75 extern int force_delete;
bcacc18b 76 STRUCT_STAT st;
3cb6f5d6 77 int ret;
05848a2c 78 extern int recurse;
3cb6f5d6
AT
79
80 if (do_unlink(fname) == 0 || errno == ENOENT) return 0;
81
82#if SUPPORT_LINKS
bcacc18b 83 ret = do_lstat(fname, &st);
3cb6f5d6 84#else
bcacc18b 85 ret = do_stat(fname, &st);
3cb6f5d6
AT
86#endif
87 if (ret) {
9486289c 88 rprintf(FERROR,"stat(%s) : %s\n", fname, strerror(errno));
3cb6f5d6
AT
89 return -1;
90 }
91
92 if (!S_ISDIR(st.st_mode)) {
9486289c 93 rprintf(FERROR,"unlink(%s) : %s\n", fname, strerror(errno));
3cb6f5d6
AT
94 return -1;
95 }
96
97 if (do_rmdir(fname) == 0 || errno == ENOENT) return 0;
05848a2c
AT
98 if (!force_delete || !recurse ||
99 (errno != ENOTEMPTY && errno != EEXIST)) {
9486289c 100 rprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno));
3cb6f5d6
AT
101 return -1;
102 }
103
104 /* now we do a recsursive delete on the directory ... */
105 d = opendir(fname);
106 if (!d) {
9486289c 107 rprintf(FERROR,"opendir(%s): %s\n",
3cb6f5d6
AT
108 fname,strerror(errno));
109 return -1;
110 }
111
112 for (di=readdir(d); di; di=readdir(d)) {
d6e6ecbd
AT
113 char *dname = d_name(di);
114 if (strcmp(dname,".")==0 ||
115 strcmp(dname,"..")==0)
3cb6f5d6 116 continue;
e42c9458 117 slprintf(buf, sizeof(buf)-1, "%s/%s", fname, dname);
3cb6f5d6 118 if (verbose > 0)
9486289c 119 rprintf(FINFO,"deleting %s\n", buf);
3cb6f5d6
AT
120 if (delete_file(buf) != 0) {
121 closedir(d);
122 return -1;
123 }
124 }
125
126 closedir(d);
127
128 if (do_rmdir(fname) != 0) {
9486289c 129 rprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno));
3cb6f5d6
AT
130 return -1;
131 }
132
133 return 0;
134}
c627d613
AT
135
136/*
137 send a sums struct down a fd
138 */
139static void send_sums(struct sum_struct *s,int f_out)
140{
141 int i;
142
143 /* tell the other guy how many we are going to be doing and how many
144 bytes there are in the last chunk */
145 write_int(f_out,s?s->count:0);
146 write_int(f_out,s?s->n:block_size);
147 write_int(f_out,s?s->remainder:0);
148 if (s)
149 for (i=0;i<s->count;i++) {
150 write_int(f_out,s->sums[i].sum1);
43a481dc 151 write_buf(f_out,s->sums[i].sum2,csum_length);
c627d613 152 }
c627d613
AT
153}
154
155
156/*
157 generate a stream of signatures/checksums that describe a buffer
158
159 generate approximately one checksum every n bytes
160 */
bcacc18b 161static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
c627d613
AT
162{
163 int i;
164 struct sum_struct *s;
165 int count;
166 int block_len = n;
167 int remainder = (len%block_len);
bcacc18b 168 OFF_T offset = 0;
c627d613
AT
169
170 count = (len+(block_len-1))/block_len;
171
172 s = (struct sum_struct *)malloc(sizeof(*s));
173 if (!s) out_of_memory("generate_sums");
174
175 s->count = count;
176 s->remainder = remainder;
177 s->n = n;
178 s->flength = len;
179
180 if (count==0) {
181 s->sums = NULL;
182 return s;
183 }
184
185 if (verbose > 3)
9486289c 186 rprintf(FINFO,"count=%d rem=%d n=%d flength=%d\n",
c627d613
AT
187 s->count,s->remainder,s->n,(int)s->flength);
188
189 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
190 if (!s->sums) out_of_memory("generate_sums");
191
192 for (i=0;i<count;i++) {
193 int n1 = MIN(len,n);
d9bea2dd 194 char *map = map_ptr(buf,offset,n1);
c627d613 195
d9bea2dd
AT
196 s->sums[i].sum1 = get_checksum1(map,n1);
197 get_checksum2(map,n1,s->sums[i].sum2);
c627d613
AT
198
199 s->sums[i].offset = offset;
200 s->sums[i].len = n1;
201 s->sums[i].i = i;
202
203 if (verbose > 3)
9486289c 204 rprintf(FINFO,"chunk[%d] offset=%d len=%d sum1=%08x\n",
c627d613
AT
205 i,(int)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
206
207 len -= n1;
c627d613
AT
208 offset += n1;
209 }
210
211 return s;
212}
213
214
215/*
216 receive the checksums for a buffer
217 */
218static struct sum_struct *receive_sums(int f)
219{
220 struct sum_struct *s;
221 int i;
bcacc18b 222 OFF_T offset = 0;
c627d613
AT
223
224 s = (struct sum_struct *)malloc(sizeof(*s));
225 if (!s) out_of_memory("receive_sums");
226
227 s->count = read_int(f);
228 s->n = read_int(f);
229 s->remainder = read_int(f);
230 s->sums = NULL;
231
232 if (verbose > 3)
9486289c 233 rprintf(FINFO,"count=%d n=%d rem=%d\n",
c627d613
AT
234 s->count,s->n,s->remainder);
235
c627d613
AT
236 if (s->count == 0)
237 return(s);
238
239 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
240 if (!s->sums) out_of_memory("receive_sums");
241
242 for (i=0;i<s->count;i++) {
243 s->sums[i].sum1 = read_int(f);
43a481dc 244 read_buf(f,s->sums[i].sum2,csum_length);
c627d613
AT
245
246 s->sums[i].offset = offset;
247 s->sums[i].i = i;
248
249 if (i == s->count-1 && s->remainder != 0) {
250 s->sums[i].len = s->remainder;
251 } else {
252 s->sums[i].len = s->n;
253 }
254 offset += s->sums[i].len;
255
256 if (verbose > 3)
9486289c 257 rprintf(FINFO,"chunk[%d] len=%d offset=%d sum1=%08x\n",
c627d613
AT
258 i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
259 }
260
261 s->flength = offset;
262
263 return s;
264}
265
266
bcacc18b 267static int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
7b8356d0 268 int report)
c627d613
AT
269{
270 int updated = 0;
bcacc18b 271 STRUCT_STAT st2;
943882a2 272 extern int am_daemon;
c627d613 273
7b8356d0 274 if (dry_run) return 0;
c627d613
AT
275
276 if (!st) {
82306bf6 277 if (link_stat(fname,&st2) != 0) {
9486289c 278 rprintf(FERROR,"stat %s : %s\n",fname,strerror(errno));
7b8356d0 279 return 0;
c627d613
AT
280 }
281 st = &st2;
282 }
283
7bec6a5c
AT
284 if (preserve_times && !S_ISLNK(st->st_mode) &&
285 st->st_mtime != file->modtime) {
c627d613
AT
286 updated = 1;
287 if (set_modtime(fname,file->modtime) != 0) {
9486289c 288 rprintf(FERROR,"failed to set times on %s : %s\n",
c627d613 289 fname,strerror(errno));
7b8356d0 290 return 0;
c627d613
AT
291 }
292 }
293
294#ifdef HAVE_CHMOD
7bec6a5c
AT
295 if (preserve_perms && !S_ISLNK(st->st_mode) &&
296 st->st_mode != file->mode) {
c627d613 297 updated = 1;
7308bd66 298 if (do_chmod(fname,file->mode) != 0) {
9486289c 299 rprintf(FERROR,"failed to set permissions on %s : %s\n",
c627d613 300 fname,strerror(errno));
7b8356d0 301 return 0;
c627d613
AT
302 }
303 }
304#endif
305
943882a2
AT
306 if ((am_root || !am_daemon) &&
307 ((am_root && preserve_uid && st->st_uid != file->uid) ||
308 (preserve_gid && st->st_gid != file->gid))) {
5fb543d5
AT
309 if (do_lchown(fname,
310 (am_root&&preserve_uid)?file->uid:-1,
311 preserve_gid?file->gid:-1) != 0) {
312 if (preserve_uid && st->st_uid != file->uid)
313 updated = 1;
314 if (verbose>1 || preserve_uid)
9486289c 315 rprintf(FERROR,"chown %s : %s\n",
5fb543d5
AT
316 fname,strerror(errno));
317 return updated;
318 }
319 updated = 1;
c627d613
AT
320 }
321
322 if (verbose > 1 && report) {
5fb543d5 323 if (updated)
9486289c 324 rprintf(FINFO,"%s\n",fname);
5fb543d5 325 else
9486289c 326 rprintf(FINFO,"%s is uptodate\n",fname);
c627d613 327 }
7b8356d0 328 return updated;
c627d613
AT
329}
330
331
964ca2ec
AT
332/* choose whether to skip a particular file */
333static int skip_file(char *fname,
bcacc18b 334 struct file_struct *file, STRUCT_STAT *st)
964ca2ec
AT
335{
336 if (st->st_size != file->length) {
337 return 0;
338 }
339
340 /* if always checksum is set then we use the checksum instead
341 of the file time to determine whether to sync */
342 if (always_checksum && S_ISREG(st->st_mode)) {
343 char sum[MD4_SUM_LENGTH];
344 file_checksum(fname,sum,st->st_size);
345 return (memcmp(sum,file->sum,csum_length) == 0);
346 }
347
348 if (ignore_times) {
349 return 0;
350 }
351
352 return (st->st_mtime == file->modtime);
353}
354
355
3ba62a83
AT
356/* use a larger block size for really big files */
357int adapt_block_size(struct file_struct *file, int bsize)
358{
359 int ret = file->length / (10000); /* rough heuristic */
360 ret = ret & ~15; /* multiple of 16 */
361 if (ret < bsize) ret = bsize;
1aa71c8d 362 if (ret > CHUNK_SIZE/2) ret = CHUNK_SIZE/2;
3ba62a83
AT
363 return ret;
364}
365
c627d613
AT
366void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
367{
368 int fd;
bcacc18b 369 STRUCT_STAT st;
c6e7fcb4 370 struct map_struct *buf;
c627d613 371 struct sum_struct *s;
c627d613 372 int statret;
3ec4dd97 373 struct file_struct *file = flist->files[i];
c627d613
AT
374
375 if (verbose > 2)
9486289c 376 rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
c627d613 377
82306bf6 378 statret = link_stat(fname,&st);
c627d613 379
7b8356d0
AT
380 if (S_ISDIR(file->mode)) {
381 if (dry_run) return;
382 if (statret == 0 && !S_ISDIR(st.st_mode)) {
31e12522 383 if (do_unlink(fname) != 0) {
9486289c 384 rprintf(FERROR,"unlink %s : %s\n",fname,strerror(errno));
7b8356d0
AT
385 return;
386 }
387 statret = -1;
388 }
1b2d733a 389 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
6574b4f7
AT
390 if (!(relative_paths && errno==ENOENT &&
391 create_directory_path(fname)==0 &&
1b2d733a 392 do_mkdir(fname,file->mode)==0)) {
9486289c 393 rprintf(FERROR,"mkdir %s : %s (2)\n",
6574b4f7
AT
394 fname,strerror(errno));
395 }
396 }
7b8356d0 397 if (set_perms(fname,file,NULL,0) && verbose)
9486289c 398 rprintf(FINFO,"%s/\n",fname);
7b8356d0
AT
399 return;
400 }
401
dc5ddbcc 402 if (preserve_links && S_ISLNK(file->mode)) {
cbbe4892 403#if SUPPORT_LINKS
c627d613
AT
404 char lnk[MAXPATHLEN];
405 int l;
406 if (statret == 0) {
407 l = readlink(fname,lnk,MAXPATHLEN-1);
408 if (l > 0) {
409 lnk[l] = 0;
dc5ddbcc
AT
410 if (strcmp(lnk,file->link) == 0) {
411 set_perms(fname,file,&st,1);
c627d613
AT
412 return;
413 }
414 }
415 }
3cb6f5d6 416 delete_file(fname);
31e12522 417 if (do_symlink(file->link,fname) != 0) {
9486289c 418 rprintf(FERROR,"link %s -> %s : %s\n",
dc5ddbcc 419 fname,file->link,strerror(errno));
c627d613 420 } else {
dc5ddbcc 421 set_perms(fname,file,NULL,0);
c627d613 422 if (verbose)
9486289c 423 rprintf(FINFO,"%s -> %s\n",
dc5ddbcc 424 fname,file->link);
c627d613 425 }
cbbe4892 426#endif
c627d613
AT
427 return;
428 }
c627d613
AT
429
430#ifdef HAVE_MKNOD
7b8356d0 431 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
c627d613 432 if (statret != 0 ||
dc5ddbcc
AT
433 st.st_mode != file->mode ||
434 st.st_rdev != file->rdev) {
3cb6f5d6 435 delete_file(fname);
c627d613 436 if (verbose > 2)
9486289c 437 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
dc5ddbcc 438 fname,(int)file->mode,(int)file->rdev);
31e12522 439 if (do_mknod(fname,file->mode,file->rdev) != 0) {
9486289c 440 rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
c627d613 441 } else {
dc5ddbcc 442 set_perms(fname,file,NULL,0);
c627d613 443 if (verbose)
9486289c 444 rprintf(FINFO,"%s\n",fname);
c627d613
AT
445 }
446 } else {
dc5ddbcc 447 set_perms(fname,file,&st,1);
c627d613
AT
448 }
449 return;
450 }
451#endif
452
dc5ddbcc
AT
453 if (preserve_hard_links && check_hard_link(file)) {
454 if (verbose > 1)
9486289c 455 rprintf(FINFO,"%s is a hard link\n",f_name(file));
dc5ddbcc
AT
456 return;
457 }
458
459 if (!S_ISREG(file->mode)) {
9486289c 460 rprintf(FINFO,"skipping non-regular file %s\n",fname);
c627d613
AT
461 return;
462 }
463
464 if (statret == -1) {
465 if (errno == ENOENT) {
466 write_int(f_out,i);
467 if (!dry_run) send_sums(NULL,f_out);
468 } else {
469 if (verbose > 1)
9486289c 470 rprintf(FERROR,"recv_generator failed to open %s\n",fname);
c627d613
AT
471 }
472 return;
473 }
474
475 if (!S_ISREG(st.st_mode)) {
3cb6f5d6 476 if (delete_file(fname) != 0) {
7b8356d0
AT
477 return;
478 }
479
480 /* now pretend the file didn't exist */
481 write_int(f_out,i);
482 if (!dry_run) send_sums(NULL,f_out);
c627d613
AT
483 return;
484 }
485
6bbbc08b 486 if (update_only && st.st_mtime > file->modtime) {
c627d613 487 if (verbose > 1)
9486289c 488 rprintf(FINFO,"%s is newer\n",fname);
c627d613
AT
489 return;
490 }
491
964ca2ec 492 if (skip_file(fname, file, &st)) {
dc5ddbcc 493 set_perms(fname,file,&st,1);
c627d613
AT
494 return;
495 }
496
497 if (dry_run) {
498 write_int(f_out,i);
499 return;
500 }
501
82306bf6
AT
502 if (whole_file) {
503 write_int(f_out,i);
504 send_sums(NULL,f_out);
505 return;
506 }
507
c627d613
AT
508 /* open the file */
509 fd = open(fname,O_RDONLY);
510
511 if (fd == -1) {
9486289c
AT
512 rprintf(FERROR,"failed to open %s : %s\n",fname,strerror(errno));
513 rprintf(FERROR,"skipping %s\n",fname);
c627d613
AT
514 return;
515 }
516
517 if (st.st_size > 0) {
518 buf = map_file(fd,st.st_size);
c627d613
AT
519 } else {
520 buf = NULL;
521 }
522
523 if (verbose > 3)
9486289c 524 rprintf(FINFO,"gen mapped %s of size %d\n",fname,(int)st.st_size);
c627d613 525
3ba62a83 526 s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));
c627d613 527
9e31c482 528 if (verbose > 2)
9486289c 529 rprintf(FINFO,"sending sums for %d\n",i);
9e31c482 530
c627d613
AT
531 write_int(f_out,i);
532 send_sums(s,f_out);
c627d613
AT
533
534 close(fd);
1cdc8b50 535 if (buf) unmap_file(buf);
c627d613
AT
536
537 free_sums(s);
538}
539
540
541
9e31c482 542static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
c627d613
AT
543{
544 int i,n,remainder,len,count;
bcacc18b
AT
545 OFF_T offset = 0;
546 OFF_T offset2;
70d794dc 547 char *data;
ebb0a6f6
AT
548 static char file_sum1[MD4_SUM_LENGTH];
549 static char file_sum2[MD4_SUM_LENGTH];
9e31c482 550 char *map=NULL;
c627d613
AT
551
552 count = read_int(f_in);
553 n = read_int(f_in);
554 remainder = read_int(f_in);
555
9e31c482
AT
556 sum_init();
557
70d794dc 558 for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
c627d613
AT
559 if (i > 0) {
560 if (verbose > 3)
9486289c 561 rprintf(FINFO,"data recv %d at %d\n",i,(int)offset);
c627d613 562
a800434a 563 stats.literal_data += i;
9e31c482
AT
564 sum_update(data,i);
565
d867229b 566 if (fd != -1 && write_file(fd,data,i) != i) {
9486289c 567 rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
34ccb63e 568 exit_cleanup(1);
c627d613
AT
569 }
570 offset += i;
571 } else {
572 i = -(i+1);
573 offset2 = i*n;
574 len = n;
575 if (i == count-1 && remainder != 0)
576 len = remainder;
577
a800434a
AT
578 stats.matched_data += len;
579
c627d613 580 if (verbose > 3)
9486289c 581 rprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n",
c627d613
AT
582 i,len,(int)offset2,(int)offset);
583
9e31c482
AT
584 map = map_ptr(buf,offset2,len);
585
861c20b4 586 see_token(map, len);
9e31c482
AT
587 sum_update(map,len);
588
d867229b 589 if (fd != -1 && write_file(fd,map,len) != len) {
9486289c 590 rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
34ccb63e 591 exit_cleanup(1);
c627d613
AT
592 }
593 offset += len;
594 }
595 }
7bec6a5c 596
7b8356d0 597 if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
9486289c 598 rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
34ccb63e 599 exit_cleanup(1);
7bec6a5c 600 }
9e31c482
AT
601
602 sum_end(file_sum1);
603
604 if (remote_version >= 14) {
ebb0a6f6 605 read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
9e31c482 606 if (verbose > 2)
9486289c 607 rprintf(FINFO,"got file_sum\n");
7b8356d0 608 if (fd != -1 && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0)
9e31c482
AT
609 return 0;
610 }
611 return 1;
c627d613
AT
612}
613
614
615static void delete_one(struct file_struct *f)
616{
617 if (!S_ISDIR(f->mode)) {
31e12522 618 if (do_unlink(f_name(f)) != 0) {
9486289c 619 rprintf(FERROR,"unlink %s : %s\n",f_name(f),strerror(errno));
c627d613 620 } else if (verbose) {
9486289c 621 rprintf(FINFO,"deleting %s\n",f_name(f));
c627d613
AT
622 }
623 } else {
31e12522 624 if (do_rmdir(f_name(f)) != 0) {
98ae8c3e 625 if (errno != ENOTEMPTY && errno != EEXIST)
9486289c 626 rprintf(FERROR,"rmdir %s : %s\n",f_name(f),strerror(errno));
c627d613 627 } else if (verbose) {
9486289c 628 rprintf(FINFO,"deleting directory %s\n",f_name(f));
c627d613
AT
629 }
630 }
631}
632
633
3b3a2fbc 634
3333ffbd
AT
635static struct delete_list {
636 dev_t dev;
637 ino_t inode;
638} *delete_list;
639static int dlist_len, dlist_alloc_len;
3b3a2fbc 640
3333ffbd
AT
641static void add_delete_entry(struct file_struct *file)
642{
643 if (dlist_len == dlist_alloc_len) {
644 dlist_alloc_len += 1024;
fe8c0a98 645 delete_list = (struct delete_list *)Realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
3333ffbd 646 if (!delete_list) out_of_memory("add_delete_entry");
3b3a2fbc
AT
647 }
648
3333ffbd
AT
649 delete_list[dlist_len].dev = file->dev;
650 delete_list[dlist_len].inode = file->inode;
651 dlist_len++;
0a25de67 652
3333ffbd 653 if (verbose > 3)
9486289c 654 rprintf(FINFO,"added %s to delete list\n", f_name(file));
3333ffbd 655}
0a25de67 656
3333ffbd
AT
657/* yuck! This function wouldn't have been necessary if I had the sorting
658 algorithm right. Unfortunately fixing the sorting algorithm would introduce
659 a backward incompatibility as file list indexes are sent over the link.
660*/
661static int delete_already_done(struct file_list *flist,int j)
662{
663 int i;
bcacc18b 664 STRUCT_STAT st;
3b3a2fbc 665
3333ffbd 666 if (link_stat(f_name(flist->files[j]), &st)) return 1;
3b3a2fbc 667
3333ffbd
AT
668 for (i=0;i<dlist_len;i++) {
669 if (st.st_ino == delete_list[i].inode &&
670 st.st_dev == delete_list[i].dev)
671 return 1;
3b3a2fbc
AT
672 }
673
3b3a2fbc
AT
674 return 0;
675}
676
677
e92338c8
AT
678/* this deletes any files on the receiving side that are not present
679 on the sending side. For version 1.6.4 I have changed the behaviour
680 to match more closely what most people seem to expect of this option */
c627d613
AT
681static void delete_files(struct file_list *flist)
682{
3333ffbd
AT
683 struct file_list *local_file_list;
684 int i, j;
685 char *name;
4fe159a8 686
3333ffbd
AT
687 if (cvs_exclude)
688 add_cvs_excludes();
6ba9279f 689
3333ffbd 690 if (io_error) {
9486289c 691 rprintf(FINFO,"IO error encountered - skipping file deletion\n");
3333ffbd
AT
692 return;
693 }
3b3a2fbc 694
3333ffbd
AT
695 for (j=0;j<flist->count;j++) {
696 if (!S_ISDIR(flist->files[j]->mode) ||
697 !(flist->files[j]->flags & FLAG_DELETE)) continue;
3b3a2fbc 698
7b1ce0d7
AT
699 if (remote_version < 19 &&
700 delete_already_done(flist, j)) continue;
0a25de67 701
3333ffbd 702 name = strdup(f_name(flist->files[j]));
3b3a2fbc 703
3333ffbd
AT
704 if (!(local_file_list = send_file_list(-1,1,&name))) {
705 free(name);
706 continue;
707 }
3b3a2fbc 708
3333ffbd 709 if (verbose > 1)
9486289c 710 rprintf(FINFO,"deleting in %s\n", name);
e92338c8 711
3333ffbd
AT
712 for (i=local_file_list->count-1;i>=0;i--) {
713 if (!local_file_list->files[i]->basename) continue;
7b1ce0d7
AT
714 if (remote_version < 19 &&
715 S_ISDIR(local_file_list->files[i]->mode))
3333ffbd
AT
716 add_delete_entry(local_file_list->files[i]);
717 if (-1 == flist_find(flist,local_file_list->files[i])) {
718 delete_one(local_file_list->files[i]);
719 }
720 }
721 flist_free(local_file_list);
722 free(name);
723 }
c627d613
AT
724}
725
3a6a366f 726static char *cleanup_fname;
c627d613 727
34ccb63e 728void exit_cleanup(int code)
c627d613 729{
8d9dc9f9 730 io_flush();
82306bf6 731 if (cleanup_fname)
31e12522 732 do_unlink(cleanup_fname);
82306bf6
AT
733 signal(SIGUSR1, SIG_IGN);
734 if (code) {
3ba62a83 735 kill_all(SIGUSR1);
82306bf6
AT
736 }
737 exit(code);
34ccb63e
AT
738}
739
740void sig_int(void)
741{
742 exit_cleanup(1);
c627d613
AT
743}
744
745
c627d613 746
c627d613 747
a800434a
AT
748static int get_tmpname(char *fnametmp, char *fname)
749{
750 char *f;
751
752 /* open tmp file */
753 if (tmpdir) {
754 f = strrchr(fname,'/');
755 if (f == NULL)
756 f = fname;
757 else
758 f++;
759 if (strlen(tmpdir)+strlen(f)+10 > MAXPATHLEN) {
760 rprintf(FERROR,"filename too long\n");
761 return 0;
762 }
763 slprintf(fnametmp,MAXPATHLEN-1, "%s/.%s.XXXXXX",tmpdir,f);
764 return 1;
765 }
c627d613 766
a800434a
AT
767 f = strrchr(fname,'/');
768
769 if (strlen(fname)+9 > MAXPATHLEN) {
770 rprintf(FERROR,"filename too long\n");
771 return 0;
c6e7fcb4 772 }
c627d613 773
a800434a
AT
774 if (f) {
775 *f = 0;
776 slprintf(fnametmp,MAXPATHLEN-1,"%s/.%s.XXXXXX",
777 fname,f+1);
778 *f = '/';
779 } else {
780 slprintf(fnametmp,MAXPATHLEN-1,".%s.XXXXXX",fname);
781 }
c627d613 782
a800434a
AT
783 return 1;
784}
c627d613 785
a800434a
AT
786int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
787{
788 int fd1,fd2;
789 STRUCT_STAT st;
790 char *fname;
791 char fnametmp[MAXPATHLEN];
792 struct map_struct *buf;
793 int i;
794 struct file_struct *file;
795 int phase=0;
796 int recv_ok;
797
798 if (verbose > 2) {
799 rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
800 }
c627d613 801
a800434a
AT
802 if (recurse && delete_mode && !local_name && flist->count>0) {
803 delete_files(flist);
804 }
c627d613 805
a800434a
AT
806 while (1) {
807 i = read_int(f_in);
808 if (i == -1) {
809 if (phase==0 && remote_version >= 13) {
810 phase++;
811 csum_length = SUM_LENGTH;
812 if (verbose > 2)
813 rprintf(FINFO,"recv_files phase=%d\n",phase);
814 write_int(f_gen,-1);
815 continue;
816 }
817 break;
818 }
c627d613 819
a800434a
AT
820 if (i < 0 || i >= flist->count) {
821 rprintf(FERROR,"Invalid file index %d in recv_files (count=%d)\n",
822 i, flist->count);
823 exit_cleanup(1);
824 }
c627d613 825
a800434a
AT
826 file = flist->files[i];
827 fname = f_name(file);
c627d613 828
a800434a
AT
829 stats.num_transferred_files++;
830 stats.total_transferred_size += file->length;
c627d613 831
a800434a
AT
832 if (local_name)
833 fname = local_name;
c627d613 834
a800434a
AT
835 if (dry_run) {
836 if (!am_server && verbose)
837 printf("%s\n",fname);
838 continue;
839 }
c627d613 840
a800434a
AT
841 if (verbose > 2)
842 rprintf(FINFO,"recv_files(%s)\n",fname);
c627d613 843
a800434a
AT
844 /* open the file */
845 fd1 = open(fname,O_RDONLY);
c627d613 846
a800434a
AT
847 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
848 rprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
849 receive_data(f_in,NULL,-1,NULL);
850 close(fd1);
851 continue;
852 }
c627d613 853
a800434a
AT
854 if (fd1 != -1 && !S_ISREG(st.st_mode)) {
855 rprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
856 receive_data(f_in,NULL,-1,NULL);
857 close(fd1);
858 continue;
859 }
c627d613 860
a800434a
AT
861 if (fd1 != -1 && st.st_size > 0) {
862 buf = map_file(fd1,st.st_size);
863 if (verbose > 2)
864 rprintf(FINFO,"recv mapped %s of size %d\n",fname,(int)st.st_size);
865 } else {
866 buf = NULL;
867 }
c627d613 868
a800434a
AT
869 if (!get_tmpname(fnametmp,fname)) {
870 if (buf) unmap_file(buf);
871 close(fd1);
872 continue;
873 }
c627d613 874
a800434a
AT
875 if (NULL == do_mktemp(fnametmp)) {
876 rprintf(FERROR,"mktemp %s failed\n",fnametmp);
877 receive_data(f_in,buf,-1,NULL);
878 if (buf) unmap_file(buf);
879 close(fd1);
880 continue;
881 }
9e31c482 882
a800434a
AT
883 fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode);
884 if (fd2 == -1 && relative_paths && errno == ENOENT &&
885 create_directory_path(fnametmp) == 0) {
886 fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode);
887 }
888 if (fd2 == -1) {
889 rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
890 receive_data(f_in,buf,-1,NULL);
891 if (buf) unmap_file(buf);
892 close(fd1);
893 continue;
894 }
895
896 cleanup_fname = fnametmp;
897
898 if (!am_server && verbose)
899 printf("%s\n",fname);
900
901 /* recv file data */
902 recv_ok = receive_data(f_in,buf,fd2,fname);
903
904 if (buf) unmap_file(buf);
905 if (fd1 != -1) {
906 close(fd1);
907 }
908 close(fd2);
909
910 if (verbose > 2)
911 rprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
912
913 if (make_backups) {
914 char fnamebak[MAXPATHLEN];
915 if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
916 rprintf(FERROR,"backup filename too long\n");
917 continue;
918 }
919 slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
920 if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
921 rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
922 continue;
923 }
924 }
c627d613 925
a800434a
AT
926 /* move tmp file over real file */
927 if (do_rename(fnametmp,fname) != 0) {
928 if (errno == EXDEV) {
929 /* rename failed on cross-filesystem link.
930 Copy the file instead. */
931 if (copy_file(fnametmp,fname, file->mode)) {
932 rprintf(FERROR,"copy %s -> %s : %s\n",
933 fnametmp,fname,strerror(errno));
934 } else {
935 set_perms(fname,file,NULL,0);
936 }
937 do_unlink(fnametmp);
938 } else {
939 rprintf(FERROR,"rename %s -> %s : %s\n",
940 fnametmp,fname,strerror(errno));
941 do_unlink(fnametmp);
942 }
943 } else {
944 set_perms(fname,file,NULL,0);
945 }
7c596906 946
a800434a
AT
947 cleanup_fname = NULL;
948
949
950 if (!recv_ok) {
951 if (csum_length == SUM_LENGTH) {
952 rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
953 fname);
954 } else {
955 if (verbose > 1)
956 rprintf(FINFO,"redoing %s(%d)\n",fname,i);
957 write_int(f_gen,i);
958 }
959 }
960 }
7b8356d0 961
a800434a
AT
962 if (preserve_hard_links)
963 do_hard_links(flist);
964
965 /* now we need to fix any directory permissions that were
966 modified during the transfer */
967 for (i = 0; i < flist->count; i++) {
968 file = flist->files[i];
969 if (!file->basename || !S_ISDIR(file->mode)) continue;
970 recv_generator(f_name(file),flist,i,-1);
971 }
972
973 if (verbose > 2)
974 rprintf(FINFO,"recv_files finished\n");
975
976 return 0;
c627d613
AT
977}
978
979
980
71c46176 981void send_files(struct file_list *flist,int f_out,int f_in)
c627d613
AT
982{
983 int fd;
984 struct sum_struct *s;
c6e7fcb4 985 struct map_struct *buf;
bcacc18b 986 STRUCT_STAT st;
c627d613 987 char fname[MAXPATHLEN];
c627d613 988 int i;
dc5ddbcc 989 struct file_struct *file;
c6e7fcb4 990 int phase = 0;
c627d613
AT
991
992 if (verbose > 2)
9486289c 993 rprintf(FINFO,"send_files starting\n");
c627d613 994
4c36ddbe 995 setup_readbuffer(f_in);
720b47f2 996
e7ebc36c 997 while (1) {
1d3754ae
AT
998 int offset=0;
999
e7ebc36c
AT
1000 i = read_int(f_in);
1001 if (i == -1) {
1002 if (phase==0 && remote_version >= 13) {
1003 phase++;
1004 csum_length = SUM_LENGTH;
1005 write_int(f_out,-1);
e7ebc36c 1006 if (verbose > 2)
9486289c 1007 rprintf(FINFO,"send_files phase=%d\n",phase);
e7ebc36c
AT
1008 continue;
1009 }
1010 break;
1011 }
c627d613 1012
a800434a
AT
1013 if (i < 0 || i >= flist->count) {
1014 rprintf(FERROR,"Invalid file index %d (count=%d)\n",
1015 i, flist->count);
1016 exit_cleanup(1);
1017 }
1018
e7ebc36c
AT
1019 file = flist->files[i];
1020
a800434a
AT
1021 stats.num_transferred_files++;
1022 stats.total_transferred_size += file->length;
1023
e7ebc36c
AT
1024 fname[0] = 0;
1025 if (file->basedir) {
7a6421fa 1026 strlcpy(fname,file->basedir,MAXPATHLEN-1);
e7ebc36c 1027 if (strlen(fname) == MAXPATHLEN-1) {
6ba9279f 1028 io_error = 1;
9486289c 1029 rprintf(FERROR, "send_files failed on long-named directory %s\n",
e7ebc36c 1030 fname);
71c46176 1031 return;
e7ebc36c 1032 }
e42c9458 1033 strlcat(fname,"/",MAXPATHLEN-1);
7796395a 1034 offset = strlen(file->basedir)+1;
e7ebc36c 1035 }
e42c9458 1036 strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
e7ebc36c
AT
1037
1038 if (verbose > 2)
9486289c 1039 rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
e7ebc36c
AT
1040
1041 if (dry_run) {
1042 if (!am_server && verbose)
1043 printf("%s\n",fname);
1044 write_int(f_out,i);
1045 continue;
1046 }
c627d613 1047
e7ebc36c
AT
1048 s = receive_sums(f_in);
1049 if (!s) {
6ba9279f 1050 io_error = 1;
9486289c 1051 rprintf(FERROR,"receive_sums failed\n");
71c46176 1052 return;
e7ebc36c
AT
1053 }
1054
1055 fd = open(fname,O_RDONLY);
1056 if (fd == -1) {
6ba9279f 1057 io_error = 1;
9486289c 1058 rprintf(FERROR,"send_files failed to open %s: %s\n",
e7ebc36c 1059 fname,strerror(errno));
0b910560 1060 free_sums(s);
e7ebc36c
AT
1061 continue;
1062 }
1063
1064 /* map the local file */
bcacc18b 1065 if (do_fstat(fd,&st) != 0) {
6ba9279f 1066 io_error = 1;
9486289c 1067 rprintf(FERROR,"fstat failed : %s\n",strerror(errno));
0b910560 1068 free_sums(s);
e7ebc36c 1069 close(fd);
71c46176 1070 return;
e7ebc36c
AT
1071 }
1072
1073 if (st.st_size > 0) {
1074 buf = map_file(fd,st.st_size);
1075 } else {
1076 buf = NULL;
1077 }
1078
1079 if (verbose > 2)
9486289c 1080 rprintf(FINFO,"send_files mapped %s of size %d\n",
e7ebc36c
AT
1081 fname,(int)st.st_size);
1082
1083 write_int(f_out,i);
1084
1085 write_int(f_out,s->count);
1086 write_int(f_out,s->n);
1087 write_int(f_out,s->remainder);
1088
1089 if (verbose > 2)
9486289c 1090 rprintf(FINFO,"calling match_sums %s\n",fname);
e7ebc36c
AT
1091
1092 if (!am_server && verbose)
7796395a 1093 printf("%s\n",fname+offset);
e7ebc36c
AT
1094
1095 match_sums(f_out,s,buf,st.st_size);
e7ebc36c
AT
1096
1097 if (buf) unmap_file(buf);
1098 close(fd);
1099
1100 free_sums(s);
1101
1102 if (verbose > 2)
9486289c 1103 rprintf(FINFO,"sender finished %s\n",fname);
e7ebc36c 1104 }
c627d613 1105
dc5ddbcc 1106 if (verbose > 2)
9486289c 1107 rprintf(FINFO,"send files finished\n");
dc5ddbcc 1108
c627d613
AT
1109 match_report();
1110
1111 write_int(f_out,-1);
c627d613
AT
1112}
1113
1114
1115
c6e7fcb4 1116void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
c627d613
AT
1117{
1118 int i;
9e31c482 1119 int phase=0;
c627d613
AT
1120
1121 if (verbose > 2)
9486289c 1122 rprintf(FINFO,"generator starting pid=%d count=%d\n",
c627d613
AT
1123 (int)getpid(),flist->count);
1124
1125 for (i = 0; i < flist->count; i++) {
3ec4dd97 1126 struct file_struct *file = flist->files[i];
7b8356d0 1127 mode_t saved_mode = file->mode;
3ec4dd97 1128 if (!file->basename) continue;
7b8356d0
AT
1129
1130 /* we need to ensure that any directories we create have writeable
1131 permissions initially so that we can create the files within
1132 them. This is then fixed after the files are transferred */
1133 if (!am_root && S_ISDIR(file->mode)) {
1134 file->mode |= S_IWUSR; /* user write */
c627d613 1135 }
7b8356d0 1136
3ec4dd97 1137 recv_generator(local_name?local_name:f_name(file),
c627d613 1138 flist,i,f);
7b8356d0
AT
1139
1140 file->mode = saved_mode;
c627d613 1141 }
c6e7fcb4 1142
9e31c482
AT
1143 phase++;
1144 csum_length = SUM_LENGTH;
1145 ignore_times=1;
1146
1147 if (verbose > 2)
9486289c 1148 rprintf(FINFO,"generate_files phase=%d\n",phase);
9e31c482 1149
c627d613 1150 write_int(f,-1);
c6e7fcb4 1151
6ba9279f
AT
1152 /* we expect to just sit around now, so don't exit on a timeout. If we
1153 really get a timeout then the other process should exit */
1154 io_timeout = 0;
1155
c6e7fcb4 1156 if (remote_version >= 13) {
7b8356d0
AT
1157 /* in newer versions of the protocol the files can cycle through
1158 the system more than once to catch initial checksum errors */
c6e7fcb4 1159 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
3ec4dd97
AT
1160 struct file_struct *file = flist->files[i];
1161 recv_generator(local_name?local_name:f_name(file),
c6e7fcb4
AT
1162 flist,i,f);
1163 }
1164
9e31c482
AT
1165 phase++;
1166 if (verbose > 2)
9486289c 1167 rprintf(FINFO,"generate_files phase=%d\n",phase);
9e31c482 1168
c6e7fcb4 1169 write_int(f,-1);
c6e7fcb4 1170 }
c627d613 1171}
dc5ddbcc
AT
1172
1173