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