if we get EWOULDBLOCK on a write then reduce the amount of data we are
[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;
c627d613 734
34ccb63e 735void exit_cleanup(int code)
c627d613 736{
8d9dc9f9 737 io_flush();
82306bf6 738 if (cleanup_fname)
31e12522 739 do_unlink(cleanup_fname);
82306bf6
AT
740 signal(SIGUSR1, SIG_IGN);
741 if (code) {
3ba62a83 742 kill_all(SIGUSR1);
82306bf6
AT
743 }
744 exit(code);
34ccb63e
AT
745}
746
747void sig_int(void)
748{
749 exit_cleanup(1);
c627d613
AT
750}
751
752
c627d613 753
c627d613 754
a800434a
AT
755static int get_tmpname(char *fnametmp, char *fname)
756{
757 char *f;
758
759 /* open tmp file */
760 if (tmpdir) {
761 f = strrchr(fname,'/');
762 if (f == NULL)
763 f = fname;
764 else
765 f++;
766 if (strlen(tmpdir)+strlen(f)+10 > MAXPATHLEN) {
767 rprintf(FERROR,"filename too long\n");
768 return 0;
769 }
770 slprintf(fnametmp,MAXPATHLEN-1, "%s/.%s.XXXXXX",tmpdir,f);
771 return 1;
772 }
c627d613 773
a800434a
AT
774 f = strrchr(fname,'/');
775
776 if (strlen(fname)+9 > MAXPATHLEN) {
777 rprintf(FERROR,"filename too long\n");
778 return 0;
c6e7fcb4 779 }
c627d613 780
a800434a
AT
781 if (f) {
782 *f = 0;
783 slprintf(fnametmp,MAXPATHLEN-1,"%s/.%s.XXXXXX",
784 fname,f+1);
785 *f = '/';
786 } else {
787 slprintf(fnametmp,MAXPATHLEN-1,".%s.XXXXXX",fname);
788 }
c627d613 789
a800434a
AT
790 return 1;
791}
c627d613 792
a800434a
AT
793int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
794{
795 int fd1,fd2;
796 STRUCT_STAT st;
797 char *fname;
798 char fnametmp[MAXPATHLEN];
799 struct map_struct *buf;
800 int i;
801 struct file_struct *file;
802 int phase=0;
803 int recv_ok;
804
805 if (verbose > 2) {
806 rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
807 }
c627d613 808
a800434a
AT
809 if (recurse && delete_mode && !local_name && flist->count>0) {
810 delete_files(flist);
811 }
c627d613 812
a800434a
AT
813 while (1) {
814 i = read_int(f_in);
815 if (i == -1) {
816 if (phase==0 && remote_version >= 13) {
817 phase++;
818 csum_length = SUM_LENGTH;
819 if (verbose > 2)
820 rprintf(FINFO,"recv_files phase=%d\n",phase);
821 write_int(f_gen,-1);
822 continue;
823 }
824 break;
825 }
c627d613 826
a800434a
AT
827 if (i < 0 || i >= flist->count) {
828 rprintf(FERROR,"Invalid file index %d in recv_files (count=%d)\n",
829 i, flist->count);
830 exit_cleanup(1);
831 }
c627d613 832
a800434a
AT
833 file = flist->files[i];
834 fname = f_name(file);
c627d613 835
a800434a
AT
836 stats.num_transferred_files++;
837 stats.total_transferred_size += file->length;
c627d613 838
a800434a
AT
839 if (local_name)
840 fname = local_name;
c627d613 841
a800434a
AT
842 if (dry_run) {
843 if (!am_server && verbose)
844 printf("%s\n",fname);
845 continue;
846 }
c627d613 847
a800434a
AT
848 if (verbose > 2)
849 rprintf(FINFO,"recv_files(%s)\n",fname);
c627d613 850
a800434a
AT
851 /* open the file */
852 fd1 = open(fname,O_RDONLY);
c627d613 853
a800434a
AT
854 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
855 rprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
856 receive_data(f_in,NULL,-1,NULL);
857 close(fd1);
858 continue;
859 }
c627d613 860
a800434a
AT
861 if (fd1 != -1 && !S_ISREG(st.st_mode)) {
862 rprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
863 receive_data(f_in,NULL,-1,NULL);
864 close(fd1);
865 continue;
866 }
c627d613 867
a800434a
AT
868 if (fd1 != -1 && st.st_size > 0) {
869 buf = map_file(fd1,st.st_size);
870 if (verbose > 2)
871 rprintf(FINFO,"recv mapped %s of size %d\n",fname,(int)st.st_size);
872 } else {
873 buf = NULL;
874 }
c627d613 875
a800434a
AT
876 if (!get_tmpname(fnametmp,fname)) {
877 if (buf) unmap_file(buf);
878 close(fd1);
879 continue;
880 }
c627d613 881
a800434a
AT
882 if (NULL == do_mktemp(fnametmp)) {
883 rprintf(FERROR,"mktemp %s failed\n",fnametmp);
884 receive_data(f_in,buf,-1,NULL);
885 if (buf) unmap_file(buf);
886 close(fd1);
887 continue;
888 }
9e31c482 889
22b19332
AT
890 /* we initially set the perms without the
891 setuid/setgid bits to ensure that there is no race
892 condition. They are then correctly updated after
893 the lchown. Thanks to snabb@epipe.fi for pointing
894 this out */
895 fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
896 file->mode & ACCESSPERMS);
897
a800434a
AT
898 if (fd2 == -1 && relative_paths && errno == ENOENT &&
899 create_directory_path(fnametmp) == 0) {
22b19332
AT
900 fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
901 file->mode & ACCESSPERMS);
a800434a
AT
902 }
903 if (fd2 == -1) {
904 rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
905 receive_data(f_in,buf,-1,NULL);
906 if (buf) unmap_file(buf);
907 close(fd1);
908 continue;
909 }
910
911 cleanup_fname = fnametmp;
912
913 if (!am_server && verbose)
914 printf("%s\n",fname);
915
916 /* recv file data */
917 recv_ok = receive_data(f_in,buf,fd2,fname);
918
919 if (buf) unmap_file(buf);
920 if (fd1 != -1) {
921 close(fd1);
922 }
923 close(fd2);
924
925 if (verbose > 2)
926 rprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
927
928 if (make_backups) {
929 char fnamebak[MAXPATHLEN];
930 if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
931 rprintf(FERROR,"backup filename too long\n");
932 continue;
933 }
934 slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
935 if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
936 rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
937 continue;
938 }
939 }
c627d613 940
a800434a
AT
941 /* move tmp file over real file */
942 if (do_rename(fnametmp,fname) != 0) {
943 if (errno == EXDEV) {
944 /* rename failed on cross-filesystem link.
945 Copy the file instead. */
946 if (copy_file(fnametmp,fname, file->mode)) {
947 rprintf(FERROR,"copy %s -> %s : %s\n",
948 fnametmp,fname,strerror(errno));
949 } else {
950 set_perms(fname,file,NULL,0);
951 }
952 do_unlink(fnametmp);
953 } else {
954 rprintf(FERROR,"rename %s -> %s : %s\n",
955 fnametmp,fname,strerror(errno));
956 do_unlink(fnametmp);
957 }
958 } else {
959 set_perms(fname,file,NULL,0);
960 }
7c596906 961
a800434a
AT
962 cleanup_fname = NULL;
963
964
965 if (!recv_ok) {
966 if (csum_length == SUM_LENGTH) {
967 rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
968 fname);
969 } else {
970 if (verbose > 1)
971 rprintf(FINFO,"redoing %s(%d)\n",fname,i);
972 write_int(f_gen,i);
973 }
974 }
975 }
7b8356d0 976
a800434a
AT
977 if (preserve_hard_links)
978 do_hard_links(flist);
979
980 /* now we need to fix any directory permissions that were
981 modified during the transfer */
982 for (i = 0; i < flist->count; i++) {
983 file = flist->files[i];
984 if (!file->basename || !S_ISDIR(file->mode)) continue;
985 recv_generator(f_name(file),flist,i,-1);
986 }
987
988 if (verbose > 2)
989 rprintf(FINFO,"recv_files finished\n");
990
991 return 0;
c627d613
AT
992}
993
994
995
71c46176 996void send_files(struct file_list *flist,int f_out,int f_in)
c627d613
AT
997{
998 int fd;
999 struct sum_struct *s;
c6e7fcb4 1000 struct map_struct *buf;
bcacc18b 1001 STRUCT_STAT st;
c627d613 1002 char fname[MAXPATHLEN];
c627d613 1003 int i;
dc5ddbcc 1004 struct file_struct *file;
c6e7fcb4 1005 int phase = 0;
c627d613
AT
1006
1007 if (verbose > 2)
9486289c 1008 rprintf(FINFO,"send_files starting\n");
c627d613 1009
4c36ddbe 1010 setup_readbuffer(f_in);
720b47f2 1011
e7ebc36c 1012 while (1) {
1d3754ae
AT
1013 int offset=0;
1014
e7ebc36c
AT
1015 i = read_int(f_in);
1016 if (i == -1) {
1017 if (phase==0 && remote_version >= 13) {
1018 phase++;
1019 csum_length = SUM_LENGTH;
1020 write_int(f_out,-1);
e7ebc36c 1021 if (verbose > 2)
9486289c 1022 rprintf(FINFO,"send_files phase=%d\n",phase);
e7ebc36c
AT
1023 continue;
1024 }
1025 break;
1026 }
c627d613 1027
a800434a
AT
1028 if (i < 0 || i >= flist->count) {
1029 rprintf(FERROR,"Invalid file index %d (count=%d)\n",
1030 i, flist->count);
1031 exit_cleanup(1);
1032 }
1033
e7ebc36c
AT
1034 file = flist->files[i];
1035
a800434a
AT
1036 stats.num_transferred_files++;
1037 stats.total_transferred_size += file->length;
1038
e7ebc36c
AT
1039 fname[0] = 0;
1040 if (file->basedir) {
7a6421fa 1041 strlcpy(fname,file->basedir,MAXPATHLEN-1);
e7ebc36c 1042 if (strlen(fname) == MAXPATHLEN-1) {
6ba9279f 1043 io_error = 1;
9486289c 1044 rprintf(FERROR, "send_files failed on long-named directory %s\n",
e7ebc36c 1045 fname);
71c46176 1046 return;
e7ebc36c 1047 }
e42c9458 1048 strlcat(fname,"/",MAXPATHLEN-1);
7796395a 1049 offset = strlen(file->basedir)+1;
e7ebc36c 1050 }
e42c9458 1051 strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
e7ebc36c
AT
1052
1053 if (verbose > 2)
9486289c 1054 rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
e7ebc36c
AT
1055
1056 if (dry_run) {
1057 if (!am_server && verbose)
1058 printf("%s\n",fname);
1059 write_int(f_out,i);
1060 continue;
1061 }
c627d613 1062
e7ebc36c
AT
1063 s = receive_sums(f_in);
1064 if (!s) {
6ba9279f 1065 io_error = 1;
9486289c 1066 rprintf(FERROR,"receive_sums failed\n");
71c46176 1067 return;
e7ebc36c
AT
1068 }
1069
1070 fd = open(fname,O_RDONLY);
1071 if (fd == -1) {
6ba9279f 1072 io_error = 1;
9486289c 1073 rprintf(FERROR,"send_files failed to open %s: %s\n",
e7ebc36c 1074 fname,strerror(errno));
0b910560 1075 free_sums(s);
e7ebc36c
AT
1076 continue;
1077 }
1078
1079 /* map the local file */
bcacc18b 1080 if (do_fstat(fd,&st) != 0) {
6ba9279f 1081 io_error = 1;
9486289c 1082 rprintf(FERROR,"fstat failed : %s\n",strerror(errno));
0b910560 1083 free_sums(s);
e7ebc36c 1084 close(fd);
71c46176 1085 return;
e7ebc36c
AT
1086 }
1087
1088 if (st.st_size > 0) {
1089 buf = map_file(fd,st.st_size);
1090 } else {
1091 buf = NULL;
1092 }
1093
1094 if (verbose > 2)
9486289c 1095 rprintf(FINFO,"send_files mapped %s of size %d\n",
e7ebc36c
AT
1096 fname,(int)st.st_size);
1097
1098 write_int(f_out,i);
1099
1100 write_int(f_out,s->count);
1101 write_int(f_out,s->n);
1102 write_int(f_out,s->remainder);
1103
1104 if (verbose > 2)
9486289c 1105 rprintf(FINFO,"calling match_sums %s\n",fname);
e7ebc36c
AT
1106
1107 if (!am_server && verbose)
7796395a 1108 printf("%s\n",fname+offset);
e7ebc36c
AT
1109
1110 match_sums(f_out,s,buf,st.st_size);
e7ebc36c
AT
1111
1112 if (buf) unmap_file(buf);
1113 close(fd);
1114
1115 free_sums(s);
1116
1117 if (verbose > 2)
9486289c 1118 rprintf(FINFO,"sender finished %s\n",fname);
e7ebc36c 1119 }
c627d613 1120
dc5ddbcc 1121 if (verbose > 2)
9486289c 1122 rprintf(FINFO,"send files finished\n");
dc5ddbcc 1123
c627d613
AT
1124 match_report();
1125
1126 write_int(f_out,-1);
c627d613
AT
1127}
1128
1129
1130
c6e7fcb4 1131void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
c627d613
AT
1132{
1133 int i;
9e31c482 1134 int phase=0;
c627d613
AT
1135
1136 if (verbose > 2)
9486289c 1137 rprintf(FINFO,"generator starting pid=%d count=%d\n",
c627d613
AT
1138 (int)getpid(),flist->count);
1139
1140 for (i = 0; i < flist->count; i++) {
3ec4dd97 1141 struct file_struct *file = flist->files[i];
7b8356d0 1142 mode_t saved_mode = file->mode;
3ec4dd97 1143 if (!file->basename) continue;
7b8356d0
AT
1144
1145 /* we need to ensure that any directories we create have writeable
1146 permissions initially so that we can create the files within
1147 them. This is then fixed after the files are transferred */
1148 if (!am_root && S_ISDIR(file->mode)) {
1149 file->mode |= S_IWUSR; /* user write */
c627d613 1150 }
7b8356d0 1151
3ec4dd97 1152 recv_generator(local_name?local_name:f_name(file),
c627d613 1153 flist,i,f);
7b8356d0
AT
1154
1155 file->mode = saved_mode;
c627d613 1156 }
c6e7fcb4 1157
9e31c482
AT
1158 phase++;
1159 csum_length = SUM_LENGTH;
1160 ignore_times=1;
1161
1162 if (verbose > 2)
9486289c 1163 rprintf(FINFO,"generate_files phase=%d\n",phase);
9e31c482 1164
c627d613 1165 write_int(f,-1);
c6e7fcb4 1166
6ba9279f
AT
1167 /* we expect to just sit around now, so don't exit on a timeout. If we
1168 really get a timeout then the other process should exit */
1169 io_timeout = 0;
1170
c6e7fcb4 1171 if (remote_version >= 13) {
7b8356d0
AT
1172 /* in newer versions of the protocol the files can cycle through
1173 the system more than once to catch initial checksum errors */
c6e7fcb4 1174 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
3ec4dd97
AT
1175 struct file_struct *file = flist->files[i];
1176 recv_generator(local_name?local_name:f_name(file),
c6e7fcb4
AT
1177 flist,i,f);
1178 }
1179
9e31c482
AT
1180 phase++;
1181 if (verbose > 2)
9486289c 1182 rprintf(FINFO,"generate_files phase=%d\n",phase);
9e31c482 1183
c6e7fcb4 1184 write_int(f,-1);
c6e7fcb4 1185 }
c627d613 1186}
dc5ddbcc
AT
1187
1188