--help changes suggested by Francois
[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{
ddecf706
AT
359 int ret;
360
361 if (bsize != BLOCK_SIZE) return bsize;
362
363 ret = file->length / (10000); /* rough heuristic */
3ba62a83
AT
364 ret = ret & ~15; /* multiple of 16 */
365 if (ret < bsize) ret = bsize;
1aa71c8d 366 if (ret > CHUNK_SIZE/2) ret = CHUNK_SIZE/2;
3ba62a83
AT
367 return ret;
368}
369
c627d613
AT
370void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
371{
372 int fd;
bcacc18b 373 STRUCT_STAT st;
c6e7fcb4 374 struct map_struct *buf;
c627d613 375 struct sum_struct *s;
c627d613 376 int statret;
3ec4dd97 377 struct file_struct *file = flist->files[i];
c627d613
AT
378
379 if (verbose > 2)
9486289c 380 rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
c627d613 381
82306bf6 382 statret = link_stat(fname,&st);
c627d613 383
7b8356d0
AT
384 if (S_ISDIR(file->mode)) {
385 if (dry_run) return;
386 if (statret == 0 && !S_ISDIR(st.st_mode)) {
31e12522 387 if (do_unlink(fname) != 0) {
9486289c 388 rprintf(FERROR,"unlink %s : %s\n",fname,strerror(errno));
7b8356d0
AT
389 return;
390 }
391 statret = -1;
392 }
1b2d733a 393 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
6574b4f7
AT
394 if (!(relative_paths && errno==ENOENT &&
395 create_directory_path(fname)==0 &&
1b2d733a 396 do_mkdir(fname,file->mode)==0)) {
9486289c 397 rprintf(FERROR,"mkdir %s : %s (2)\n",
6574b4f7
AT
398 fname,strerror(errno));
399 }
400 }
7b8356d0 401 if (set_perms(fname,file,NULL,0) && verbose)
9486289c 402 rprintf(FINFO,"%s/\n",fname);
7b8356d0
AT
403 return;
404 }
405
dc5ddbcc 406 if (preserve_links && S_ISLNK(file->mode)) {
cbbe4892 407#if SUPPORT_LINKS
c627d613
AT
408 char lnk[MAXPATHLEN];
409 int l;
410 if (statret == 0) {
411 l = readlink(fname,lnk,MAXPATHLEN-1);
412 if (l > 0) {
413 lnk[l] = 0;
dc5ddbcc
AT
414 if (strcmp(lnk,file->link) == 0) {
415 set_perms(fname,file,&st,1);
c627d613
AT
416 return;
417 }
418 }
419 }
3cb6f5d6 420 delete_file(fname);
31e12522 421 if (do_symlink(file->link,fname) != 0) {
9486289c 422 rprintf(FERROR,"link %s -> %s : %s\n",
dc5ddbcc 423 fname,file->link,strerror(errno));
c627d613 424 } else {
dc5ddbcc 425 set_perms(fname,file,NULL,0);
c627d613 426 if (verbose)
9486289c 427 rprintf(FINFO,"%s -> %s\n",
dc5ddbcc 428 fname,file->link);
c627d613 429 }
cbbe4892 430#endif
c627d613
AT
431 return;
432 }
c627d613
AT
433
434#ifdef HAVE_MKNOD
7b8356d0 435 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
c627d613 436 if (statret != 0 ||
dc5ddbcc
AT
437 st.st_mode != file->mode ||
438 st.st_rdev != file->rdev) {
3cb6f5d6 439 delete_file(fname);
c627d613 440 if (verbose > 2)
9486289c 441 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
dc5ddbcc 442 fname,(int)file->mode,(int)file->rdev);
31e12522 443 if (do_mknod(fname,file->mode,file->rdev) != 0) {
9486289c 444 rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
c627d613 445 } else {
dc5ddbcc 446 set_perms(fname,file,NULL,0);
c627d613 447 if (verbose)
9486289c 448 rprintf(FINFO,"%s\n",fname);
c627d613
AT
449 }
450 } else {
dc5ddbcc 451 set_perms(fname,file,&st,1);
c627d613
AT
452 }
453 return;
454 }
455#endif
456
dc5ddbcc
AT
457 if (preserve_hard_links && check_hard_link(file)) {
458 if (verbose > 1)
9486289c 459 rprintf(FINFO,"%s is a hard link\n",f_name(file));
dc5ddbcc
AT
460 return;
461 }
462
463 if (!S_ISREG(file->mode)) {
9486289c 464 rprintf(FINFO,"skipping non-regular file %s\n",fname);
c627d613
AT
465 return;
466 }
467
468 if (statret == -1) {
469 if (errno == ENOENT) {
470 write_int(f_out,i);
471 if (!dry_run) send_sums(NULL,f_out);
472 } else {
473 if (verbose > 1)
9486289c 474 rprintf(FERROR,"recv_generator failed to open %s\n",fname);
c627d613
AT
475 }
476 return;
477 }
478
479 if (!S_ISREG(st.st_mode)) {
3cb6f5d6 480 if (delete_file(fname) != 0) {
7b8356d0
AT
481 return;
482 }
483
484 /* now pretend the file didn't exist */
485 write_int(f_out,i);
486 if (!dry_run) send_sums(NULL,f_out);
c627d613
AT
487 return;
488 }
489
6bbbc08b 490 if (update_only && st.st_mtime > file->modtime) {
c627d613 491 if (verbose > 1)
9486289c 492 rprintf(FINFO,"%s is newer\n",fname);
c627d613
AT
493 return;
494 }
495
964ca2ec 496 if (skip_file(fname, file, &st)) {
dc5ddbcc 497 set_perms(fname,file,&st,1);
c627d613
AT
498 return;
499 }
500
501 if (dry_run) {
502 write_int(f_out,i);
503 return;
504 }
505
82306bf6
AT
506 if (whole_file) {
507 write_int(f_out,i);
508 send_sums(NULL,f_out);
509 return;
510 }
511
c627d613
AT
512 /* open the file */
513 fd = open(fname,O_RDONLY);
514
515 if (fd == -1) {
9486289c
AT
516 rprintf(FERROR,"failed to open %s : %s\n",fname,strerror(errno));
517 rprintf(FERROR,"skipping %s\n",fname);
c627d613
AT
518 return;
519 }
520
521 if (st.st_size > 0) {
522 buf = map_file(fd,st.st_size);
c627d613
AT
523 } else {
524 buf = NULL;
525 }
526
527 if (verbose > 3)
9486289c 528 rprintf(FINFO,"gen mapped %s of size %d\n",fname,(int)st.st_size);
c627d613 529
3ba62a83 530 s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));
c627d613 531
9e31c482 532 if (verbose > 2)
9486289c 533 rprintf(FINFO,"sending sums for %d\n",i);
9e31c482 534
c627d613
AT
535 write_int(f_out,i);
536 send_sums(s,f_out);
c627d613
AT
537
538 close(fd);
1cdc8b50 539 if (buf) unmap_file(buf);
c627d613
AT
540
541 free_sums(s);
542}
543
544
545
9e31c482 546static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
c627d613
AT
547{
548 int i,n,remainder,len,count;
bcacc18b
AT
549 OFF_T offset = 0;
550 OFF_T offset2;
70d794dc 551 char *data;
ebb0a6f6
AT
552 static char file_sum1[MD4_SUM_LENGTH];
553 static char file_sum2[MD4_SUM_LENGTH];
9e31c482 554 char *map=NULL;
c627d613
AT
555
556 count = read_int(f_in);
557 n = read_int(f_in);
558 remainder = read_int(f_in);
559
9e31c482
AT
560 sum_init();
561
70d794dc 562 for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
c627d613
AT
563 if (i > 0) {
564 if (verbose > 3)
9486289c 565 rprintf(FINFO,"data recv %d at %d\n",i,(int)offset);
c627d613 566
a800434a 567 stats.literal_data += i;
9e31c482
AT
568 sum_update(data,i);
569
d867229b 570 if (fd != -1 && write_file(fd,data,i) != i) {
9486289c 571 rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
34ccb63e 572 exit_cleanup(1);
c627d613
AT
573 }
574 offset += i;
575 } else {
576 i = -(i+1);
577 offset2 = i*n;
578 len = n;
579 if (i == count-1 && remainder != 0)
580 len = remainder;
581
a800434a
AT
582 stats.matched_data += len;
583
c627d613 584 if (verbose > 3)
9486289c 585 rprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n",
c627d613
AT
586 i,len,(int)offset2,(int)offset);
587
9e31c482
AT
588 map = map_ptr(buf,offset2,len);
589
861c20b4 590 see_token(map, len);
9e31c482
AT
591 sum_update(map,len);
592
d867229b 593 if (fd != -1 && write_file(fd,map,len) != len) {
9486289c 594 rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
34ccb63e 595 exit_cleanup(1);
c627d613
AT
596 }
597 offset += len;
598 }
599 }
7bec6a5c 600
7b8356d0 601 if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
9486289c 602 rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
34ccb63e 603 exit_cleanup(1);
7bec6a5c 604 }
9e31c482
AT
605
606 sum_end(file_sum1);
607
608 if (remote_version >= 14) {
ebb0a6f6 609 read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
9e31c482 610 if (verbose > 2)
9486289c 611 rprintf(FINFO,"got file_sum\n");
7b8356d0 612 if (fd != -1 && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0)
9e31c482
AT
613 return 0;
614 }
615 return 1;
c627d613
AT
616}
617
618
619static void delete_one(struct file_struct *f)
620{
621 if (!S_ISDIR(f->mode)) {
31e12522 622 if (do_unlink(f_name(f)) != 0) {
9486289c 623 rprintf(FERROR,"unlink %s : %s\n",f_name(f),strerror(errno));
c627d613 624 } else if (verbose) {
9486289c 625 rprintf(FINFO,"deleting %s\n",f_name(f));
c627d613
AT
626 }
627 } else {
31e12522 628 if (do_rmdir(f_name(f)) != 0) {
98ae8c3e 629 if (errno != ENOTEMPTY && errno != EEXIST)
9486289c 630 rprintf(FERROR,"rmdir %s : %s\n",f_name(f),strerror(errno));
c627d613 631 } else if (verbose) {
9486289c 632 rprintf(FINFO,"deleting directory %s\n",f_name(f));
c627d613
AT
633 }
634 }
635}
636
637
3b3a2fbc 638
3333ffbd
AT
639static struct delete_list {
640 dev_t dev;
641 ino_t inode;
642} *delete_list;
643static int dlist_len, dlist_alloc_len;
3b3a2fbc 644
3333ffbd
AT
645static void add_delete_entry(struct file_struct *file)
646{
647 if (dlist_len == dlist_alloc_len) {
648 dlist_alloc_len += 1024;
fe8c0a98 649 delete_list = (struct delete_list *)Realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
3333ffbd 650 if (!delete_list) out_of_memory("add_delete_entry");
3b3a2fbc
AT
651 }
652
3333ffbd
AT
653 delete_list[dlist_len].dev = file->dev;
654 delete_list[dlist_len].inode = file->inode;
655 dlist_len++;
0a25de67 656
3333ffbd 657 if (verbose > 3)
9486289c 658 rprintf(FINFO,"added %s to delete list\n", f_name(file));
3333ffbd 659}
0a25de67 660
3333ffbd
AT
661/* yuck! This function wouldn't have been necessary if I had the sorting
662 algorithm right. Unfortunately fixing the sorting algorithm would introduce
663 a backward incompatibility as file list indexes are sent over the link.
664*/
665static int delete_already_done(struct file_list *flist,int j)
666{
667 int i;
bcacc18b 668 STRUCT_STAT st;
3b3a2fbc 669
3333ffbd 670 if (link_stat(f_name(flist->files[j]), &st)) return 1;
3b3a2fbc 671
3333ffbd
AT
672 for (i=0;i<dlist_len;i++) {
673 if (st.st_ino == delete_list[i].inode &&
674 st.st_dev == delete_list[i].dev)
675 return 1;
3b3a2fbc
AT
676 }
677
3b3a2fbc
AT
678 return 0;
679}
680
681
e92338c8
AT
682/* this deletes any files on the receiving side that are not present
683 on the sending side. For version 1.6.4 I have changed the behaviour
684 to match more closely what most people seem to expect of this option */
c627d613
AT
685static void delete_files(struct file_list *flist)
686{
3333ffbd
AT
687 struct file_list *local_file_list;
688 int i, j;
689 char *name;
4fe159a8 690
3333ffbd
AT
691 if (cvs_exclude)
692 add_cvs_excludes();
6ba9279f 693
3333ffbd 694 if (io_error) {
9486289c 695 rprintf(FINFO,"IO error encountered - skipping file deletion\n");
3333ffbd
AT
696 return;
697 }
3b3a2fbc 698
3333ffbd
AT
699 for (j=0;j<flist->count;j++) {
700 if (!S_ISDIR(flist->files[j]->mode) ||
701 !(flist->files[j]->flags & FLAG_DELETE)) continue;
3b3a2fbc 702
7b1ce0d7
AT
703 if (remote_version < 19 &&
704 delete_already_done(flist, j)) continue;
0a25de67 705
3333ffbd 706 name = strdup(f_name(flist->files[j]));
3b3a2fbc 707
3333ffbd
AT
708 if (!(local_file_list = send_file_list(-1,1,&name))) {
709 free(name);
710 continue;
711 }
3b3a2fbc 712
3333ffbd 713 if (verbose > 1)
9486289c 714 rprintf(FINFO,"deleting in %s\n", name);
e92338c8 715
3333ffbd
AT
716 for (i=local_file_list->count-1;i>=0;i--) {
717 if (!local_file_list->files[i]->basename) continue;
7b1ce0d7
AT
718 if (remote_version < 19 &&
719 S_ISDIR(local_file_list->files[i]->mode))
3333ffbd
AT
720 add_delete_entry(local_file_list->files[i]);
721 if (-1 == flist_find(flist,local_file_list->files[i])) {
722 delete_one(local_file_list->files[i]);
723 }
724 }
725 flist_free(local_file_list);
726 free(name);
727 }
c627d613
AT
728}
729
3a6a366f 730static char *cleanup_fname;
c627d613 731
34ccb63e 732void exit_cleanup(int code)
c627d613 733{
8d9dc9f9 734 io_flush();
82306bf6 735 if (cleanup_fname)
31e12522 736 do_unlink(cleanup_fname);
82306bf6
AT
737 signal(SIGUSR1, SIG_IGN);
738 if (code) {
3ba62a83 739 kill_all(SIGUSR1);
82306bf6
AT
740 }
741 exit(code);
34ccb63e
AT
742}
743
744void sig_int(void)
745{
746 exit_cleanup(1);
c627d613
AT
747}
748
749
c627d613 750
c627d613 751
a800434a
AT
752static int get_tmpname(char *fnametmp, char *fname)
753{
754 char *f;
755
756 /* open tmp file */
757 if (tmpdir) {
758 f = strrchr(fname,'/');
759 if (f == NULL)
760 f = fname;
761 else
762 f++;
763 if (strlen(tmpdir)+strlen(f)+10 > MAXPATHLEN) {
764 rprintf(FERROR,"filename too long\n");
765 return 0;
766 }
767 slprintf(fnametmp,MAXPATHLEN-1, "%s/.%s.XXXXXX",tmpdir,f);
768 return 1;
769 }
c627d613 770
a800434a
AT
771 f = strrchr(fname,'/');
772
773 if (strlen(fname)+9 > MAXPATHLEN) {
774 rprintf(FERROR,"filename too long\n");
775 return 0;
c6e7fcb4 776 }
c627d613 777
a800434a
AT
778 if (f) {
779 *f = 0;
780 slprintf(fnametmp,MAXPATHLEN-1,"%s/.%s.XXXXXX",
781 fname,f+1);
782 *f = '/';
783 } else {
784 slprintf(fnametmp,MAXPATHLEN-1,".%s.XXXXXX",fname);
785 }
c627d613 786
a800434a
AT
787 return 1;
788}
c627d613 789
a800434a
AT
790int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
791{
792 int fd1,fd2;
793 STRUCT_STAT st;
794 char *fname;
795 char fnametmp[MAXPATHLEN];
796 struct map_struct *buf;
797 int i;
798 struct file_struct *file;
799 int phase=0;
800 int recv_ok;
801
802 if (verbose > 2) {
803 rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
804 }
c627d613 805
a800434a
AT
806 if (recurse && delete_mode && !local_name && flist->count>0) {
807 delete_files(flist);
808 }
c627d613 809
a800434a
AT
810 while (1) {
811 i = read_int(f_in);
812 if (i == -1) {
813 if (phase==0 && remote_version >= 13) {
814 phase++;
815 csum_length = SUM_LENGTH;
816 if (verbose > 2)
817 rprintf(FINFO,"recv_files phase=%d\n",phase);
818 write_int(f_gen,-1);
819 continue;
820 }
821 break;
822 }
c627d613 823
a800434a
AT
824 if (i < 0 || i >= flist->count) {
825 rprintf(FERROR,"Invalid file index %d in recv_files (count=%d)\n",
826 i, flist->count);
827 exit_cleanup(1);
828 }
c627d613 829
a800434a
AT
830 file = flist->files[i];
831 fname = f_name(file);
c627d613 832
a800434a
AT
833 stats.num_transferred_files++;
834 stats.total_transferred_size += file->length;
c627d613 835
a800434a
AT
836 if (local_name)
837 fname = local_name;
c627d613 838
a800434a
AT
839 if (dry_run) {
840 if (!am_server && verbose)
841 printf("%s\n",fname);
842 continue;
843 }
c627d613 844
a800434a
AT
845 if (verbose > 2)
846 rprintf(FINFO,"recv_files(%s)\n",fname);
c627d613 847
a800434a
AT
848 /* open the file */
849 fd1 = open(fname,O_RDONLY);
c627d613 850
a800434a
AT
851 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
852 rprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
853 receive_data(f_in,NULL,-1,NULL);
854 close(fd1);
855 continue;
856 }
c627d613 857
a800434a
AT
858 if (fd1 != -1 && !S_ISREG(st.st_mode)) {
859 rprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
860 receive_data(f_in,NULL,-1,NULL);
861 close(fd1);
862 continue;
863 }
c627d613 864
a800434a
AT
865 if (fd1 != -1 && st.st_size > 0) {
866 buf = map_file(fd1,st.st_size);
867 if (verbose > 2)
868 rprintf(FINFO,"recv mapped %s of size %d\n",fname,(int)st.st_size);
869 } else {
870 buf = NULL;
871 }
c627d613 872
a800434a
AT
873 if (!get_tmpname(fnametmp,fname)) {
874 if (buf) unmap_file(buf);
875 close(fd1);
876 continue;
877 }
c627d613 878
a800434a
AT
879 if (NULL == do_mktemp(fnametmp)) {
880 rprintf(FERROR,"mktemp %s failed\n",fnametmp);
881 receive_data(f_in,buf,-1,NULL);
882 if (buf) unmap_file(buf);
883 close(fd1);
884 continue;
885 }
9e31c482 886
a800434a
AT
887 fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode);
888 if (fd2 == -1 && relative_paths && errno == ENOENT &&
889 create_directory_path(fnametmp) == 0) {
890 fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode);
891 }
892 if (fd2 == -1) {
893 rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
894 receive_data(f_in,buf,-1,NULL);
895 if (buf) unmap_file(buf);
896 close(fd1);
897 continue;
898 }
899
900 cleanup_fname = fnametmp;
901
902 if (!am_server && verbose)
903 printf("%s\n",fname);
904
905 /* recv file data */
906 recv_ok = receive_data(f_in,buf,fd2,fname);
907
908 if (buf) unmap_file(buf);
909 if (fd1 != -1) {
910 close(fd1);
911 }
912 close(fd2);
913
914 if (verbose > 2)
915 rprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
916
917 if (make_backups) {
918 char fnamebak[MAXPATHLEN];
919 if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
920 rprintf(FERROR,"backup filename too long\n");
921 continue;
922 }
923 slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
924 if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
925 rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
926 continue;
927 }
928 }
c627d613 929
a800434a
AT
930 /* move tmp file over real file */
931 if (do_rename(fnametmp,fname) != 0) {
932 if (errno == EXDEV) {
933 /* rename failed on cross-filesystem link.
934 Copy the file instead. */
935 if (copy_file(fnametmp,fname, file->mode)) {
936 rprintf(FERROR,"copy %s -> %s : %s\n",
937 fnametmp,fname,strerror(errno));
938 } else {
939 set_perms(fname,file,NULL,0);
940 }
941 do_unlink(fnametmp);
942 } else {
943 rprintf(FERROR,"rename %s -> %s : %s\n",
944 fnametmp,fname,strerror(errno));
945 do_unlink(fnametmp);
946 }
947 } else {
948 set_perms(fname,file,NULL,0);
949 }
7c596906 950
a800434a
AT
951 cleanup_fname = NULL;
952
953
954 if (!recv_ok) {
955 if (csum_length == SUM_LENGTH) {
956 rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
957 fname);
958 } else {
959 if (verbose > 1)
960 rprintf(FINFO,"redoing %s(%d)\n",fname,i);
961 write_int(f_gen,i);
962 }
963 }
964 }
7b8356d0 965
a800434a
AT
966 if (preserve_hard_links)
967 do_hard_links(flist);
968
969 /* now we need to fix any directory permissions that were
970 modified during the transfer */
971 for (i = 0; i < flist->count; i++) {
972 file = flist->files[i];
973 if (!file->basename || !S_ISDIR(file->mode)) continue;
974 recv_generator(f_name(file),flist,i,-1);
975 }
976
977 if (verbose > 2)
978 rprintf(FINFO,"recv_files finished\n");
979
980 return 0;
c627d613
AT
981}
982
983
984
71c46176 985void send_files(struct file_list *flist,int f_out,int f_in)
c627d613
AT
986{
987 int fd;
988 struct sum_struct *s;
c6e7fcb4 989 struct map_struct *buf;
bcacc18b 990 STRUCT_STAT st;
c627d613 991 char fname[MAXPATHLEN];
c627d613 992 int i;
dc5ddbcc 993 struct file_struct *file;
c6e7fcb4 994 int phase = 0;
c627d613
AT
995
996 if (verbose > 2)
9486289c 997 rprintf(FINFO,"send_files starting\n");
c627d613 998
4c36ddbe 999 setup_readbuffer(f_in);
720b47f2 1000
e7ebc36c 1001 while (1) {
1d3754ae
AT
1002 int offset=0;
1003
e7ebc36c
AT
1004 i = read_int(f_in);
1005 if (i == -1) {
1006 if (phase==0 && remote_version >= 13) {
1007 phase++;
1008 csum_length = SUM_LENGTH;
1009 write_int(f_out,-1);
e7ebc36c 1010 if (verbose > 2)
9486289c 1011 rprintf(FINFO,"send_files phase=%d\n",phase);
e7ebc36c
AT
1012 continue;
1013 }
1014 break;
1015 }
c627d613 1016
a800434a
AT
1017 if (i < 0 || i >= flist->count) {
1018 rprintf(FERROR,"Invalid file index %d (count=%d)\n",
1019 i, flist->count);
1020 exit_cleanup(1);
1021 }
1022
e7ebc36c
AT
1023 file = flist->files[i];
1024
a800434a
AT
1025 stats.num_transferred_files++;
1026 stats.total_transferred_size += file->length;
1027
e7ebc36c
AT
1028 fname[0] = 0;
1029 if (file->basedir) {
7a6421fa 1030 strlcpy(fname,file->basedir,MAXPATHLEN-1);
e7ebc36c 1031 if (strlen(fname) == MAXPATHLEN-1) {
6ba9279f 1032 io_error = 1;
9486289c 1033 rprintf(FERROR, "send_files failed on long-named directory %s\n",
e7ebc36c 1034 fname);
71c46176 1035 return;
e7ebc36c 1036 }
e42c9458 1037 strlcat(fname,"/",MAXPATHLEN-1);
7796395a 1038 offset = strlen(file->basedir)+1;
e7ebc36c 1039 }
e42c9458 1040 strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
e7ebc36c
AT
1041
1042 if (verbose > 2)
9486289c 1043 rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
e7ebc36c
AT
1044
1045 if (dry_run) {
1046 if (!am_server && verbose)
1047 printf("%s\n",fname);
1048 write_int(f_out,i);
1049 continue;
1050 }
c627d613 1051
e7ebc36c
AT
1052 s = receive_sums(f_in);
1053 if (!s) {
6ba9279f 1054 io_error = 1;
9486289c 1055 rprintf(FERROR,"receive_sums failed\n");
71c46176 1056 return;
e7ebc36c
AT
1057 }
1058
1059 fd = open(fname,O_RDONLY);
1060 if (fd == -1) {
6ba9279f 1061 io_error = 1;
9486289c 1062 rprintf(FERROR,"send_files failed to open %s: %s\n",
e7ebc36c 1063 fname,strerror(errno));
0b910560 1064 free_sums(s);
e7ebc36c
AT
1065 continue;
1066 }
1067
1068 /* map the local file */
bcacc18b 1069 if (do_fstat(fd,&st) != 0) {
6ba9279f 1070 io_error = 1;
9486289c 1071 rprintf(FERROR,"fstat failed : %s\n",strerror(errno));
0b910560 1072 free_sums(s);
e7ebc36c 1073 close(fd);
71c46176 1074 return;
e7ebc36c
AT
1075 }
1076
1077 if (st.st_size > 0) {
1078 buf = map_file(fd,st.st_size);
1079 } else {
1080 buf = NULL;
1081 }
1082
1083 if (verbose > 2)
9486289c 1084 rprintf(FINFO,"send_files mapped %s of size %d\n",
e7ebc36c
AT
1085 fname,(int)st.st_size);
1086
1087 write_int(f_out,i);
1088
1089 write_int(f_out,s->count);
1090 write_int(f_out,s->n);
1091 write_int(f_out,s->remainder);
1092
1093 if (verbose > 2)
9486289c 1094 rprintf(FINFO,"calling match_sums %s\n",fname);
e7ebc36c
AT
1095
1096 if (!am_server && verbose)
7796395a 1097 printf("%s\n",fname+offset);
e7ebc36c
AT
1098
1099 match_sums(f_out,s,buf,st.st_size);
e7ebc36c
AT
1100
1101 if (buf) unmap_file(buf);
1102 close(fd);
1103
1104 free_sums(s);
1105
1106 if (verbose > 2)
9486289c 1107 rprintf(FINFO,"sender finished %s\n",fname);
e7ebc36c 1108 }
c627d613 1109
dc5ddbcc 1110 if (verbose > 2)
9486289c 1111 rprintf(FINFO,"send files finished\n");
dc5ddbcc 1112
c627d613
AT
1113 match_report();
1114
1115 write_int(f_out,-1);
c627d613
AT
1116}
1117
1118
1119
c6e7fcb4 1120void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
c627d613
AT
1121{
1122 int i;
9e31c482 1123 int phase=0;
c627d613
AT
1124
1125 if (verbose > 2)
9486289c 1126 rprintf(FINFO,"generator starting pid=%d count=%d\n",
c627d613
AT
1127 (int)getpid(),flist->count);
1128
1129 for (i = 0; i < flist->count; i++) {
3ec4dd97 1130 struct file_struct *file = flist->files[i];
7b8356d0 1131 mode_t saved_mode = file->mode;
3ec4dd97 1132 if (!file->basename) continue;
7b8356d0
AT
1133
1134 /* we need to ensure that any directories we create have writeable
1135 permissions initially so that we can create the files within
1136 them. This is then fixed after the files are transferred */
1137 if (!am_root && S_ISDIR(file->mode)) {
1138 file->mode |= S_IWUSR; /* user write */
c627d613 1139 }
7b8356d0 1140
3ec4dd97 1141 recv_generator(local_name?local_name:f_name(file),
c627d613 1142 flist,i,f);
7b8356d0
AT
1143
1144 file->mode = saved_mode;
c627d613 1145 }
c6e7fcb4 1146
9e31c482
AT
1147 phase++;
1148 csum_length = SUM_LENGTH;
1149 ignore_times=1;
1150
1151 if (verbose > 2)
9486289c 1152 rprintf(FINFO,"generate_files phase=%d\n",phase);
9e31c482 1153
c627d613 1154 write_int(f,-1);
c6e7fcb4 1155
6ba9279f
AT
1156 /* we expect to just sit around now, so don't exit on a timeout. If we
1157 really get a timeout then the other process should exit */
1158 io_timeout = 0;
1159
c6e7fcb4 1160 if (remote_version >= 13) {
7b8356d0
AT
1161 /* in newer versions of the protocol the files can cycle through
1162 the system more than once to catch initial checksum errors */
c6e7fcb4 1163 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
3ec4dd97
AT
1164 struct file_struct *file = flist->files[i];
1165 recv_generator(local_name?local_name:f_name(file),
c6e7fcb4
AT
1166 flist,i,f);
1167 }
1168
9e31c482
AT
1169 phase++;
1170 if (verbose > 2)
9486289c 1171 rprintf(FINFO,"generate_files phase=%d\n",phase);
9e31c482 1172
c6e7fcb4 1173 write_int(f,-1);
c6e7fcb4 1174 }
c627d613 1175}
dc5ddbcc
AT
1176
1177