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