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