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