buffer overflow patches from mhpower@mit.edu (Matt Power)
[rsync/rsync.git] / rsync.c
... / ...
CommitLineData
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
22extern int csum_length;
23
24extern int verbose;
25extern int am_server;
26extern int always_checksum;
27extern time_t starttime;
28
29extern int remote_version;
30
31extern char *backup_suffix;
32
33extern int whole_file;
34extern int block_size;
35extern int update_only;
36extern int make_backups;
37extern int preserve_links;
38extern int preserve_hard_links;
39extern int preserve_perms;
40extern int preserve_devices;
41extern int preserve_uid;
42extern int preserve_gid;
43extern int preserve_times;
44extern int dry_run;
45extern int ignore_times;
46extern int recurse;
47extern int delete_mode;
48extern int cvs_exclude;
49extern int am_root;
50extern int relative_paths;
51
52/*
53 free a sums struct
54 */
55static void free_sums(struct sum_struct *s)
56{
57 if (s->sums) free(s->sums);
58 free(s);
59}
60
61
62
63/*
64 send a sums struct down a fd
65 */
66static void send_sums(struct sum_struct *s,int f_out)
67{
68 int i;
69
70 /* tell the other guy how many we are going to be doing and how many
71 bytes there are in the last chunk */
72 write_int(f_out,s?s->count:0);
73 write_int(f_out,s?s->n:block_size);
74 write_int(f_out,s?s->remainder:0);
75 if (s)
76 for (i=0;i<s->count;i++) {
77 write_int(f_out,s->sums[i].sum1);
78 write_buf(f_out,s->sums[i].sum2,csum_length);
79 }
80 write_flush(f_out);
81}
82
83
84/*
85 generate a stream of signatures/checksums that describe a buffer
86
87 generate approximately one checksum every n bytes
88 */
89static struct sum_struct *generate_sums(struct map_struct *buf,off_t len,int n)
90{
91 int i;
92 struct sum_struct *s;
93 int count;
94 int block_len = n;
95 int remainder = (len%block_len);
96 off_t offset = 0;
97
98 count = (len+(block_len-1))/block_len;
99
100 s = (struct sum_struct *)malloc(sizeof(*s));
101 if (!s) out_of_memory("generate_sums");
102
103 s->count = count;
104 s->remainder = remainder;
105 s->n = n;
106 s->flength = len;
107
108 if (count==0) {
109 s->sums = NULL;
110 return s;
111 }
112
113 if (verbose > 3)
114 fprintf(FERROR,"count=%d rem=%d n=%d flength=%d\n",
115 s->count,s->remainder,s->n,(int)s->flength);
116
117 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
118 if (!s->sums) out_of_memory("generate_sums");
119
120 for (i=0;i<count;i++) {
121 int n1 = MIN(len,n);
122 char *map = map_ptr(buf,offset,n1);
123
124 s->sums[i].sum1 = get_checksum1(map,n1);
125 get_checksum2(map,n1,s->sums[i].sum2);
126
127 s->sums[i].offset = offset;
128 s->sums[i].len = n1;
129 s->sums[i].i = i;
130
131 if (verbose > 3)
132 fprintf(FERROR,"chunk[%d] offset=%d len=%d sum1=%08x\n",
133 i,(int)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
134
135 len -= n1;
136 offset += n1;
137 }
138
139 return s;
140}
141
142
143/*
144 receive the checksums for a buffer
145 */
146static struct sum_struct *receive_sums(int f)
147{
148 struct sum_struct *s;
149 int i;
150 off_t offset = 0;
151
152 s = (struct sum_struct *)malloc(sizeof(*s));
153 if (!s) out_of_memory("receive_sums");
154
155 s->count = read_int(f);
156 s->n = read_int(f);
157 s->remainder = read_int(f);
158 s->sums = NULL;
159
160 if (verbose > 3)
161 fprintf(FERROR,"count=%d n=%d rem=%d\n",
162 s->count,s->n,s->remainder);
163
164 if (s->count == 0)
165 return(s);
166
167 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
168 if (!s->sums) out_of_memory("receive_sums");
169
170 for (i=0;i<s->count;i++) {
171 s->sums[i].sum1 = read_int(f);
172 read_buf(f,s->sums[i].sum2,csum_length);
173
174 s->sums[i].offset = offset;
175 s->sums[i].i = i;
176
177 if (i == s->count-1 && s->remainder != 0) {
178 s->sums[i].len = s->remainder;
179 } else {
180 s->sums[i].len = s->n;
181 }
182 offset += s->sums[i].len;
183
184 if (verbose > 3)
185 fprintf(FERROR,"chunk[%d] len=%d offset=%d sum1=%08x\n",
186 i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
187 }
188
189 s->flength = offset;
190
191 return s;
192}
193
194
195static int set_perms(char *fname,struct file_struct *file,struct stat *st,
196 int report)
197{
198 int updated = 0;
199 struct stat st2;
200
201 if (dry_run) return 0;
202
203 if (!st) {
204 if (link_stat(fname,&st2) != 0) {
205 fprintf(FERROR,"stat %s : %s\n",fname,strerror(errno));
206 return 0;
207 }
208 st = &st2;
209 }
210
211 if (preserve_times && !S_ISLNK(st->st_mode) &&
212 st->st_mtime != file->modtime) {
213 updated = 1;
214 if (set_modtime(fname,file->modtime) != 0) {
215 fprintf(FERROR,"failed to set times on %s : %s\n",
216 fname,strerror(errno));
217 return 0;
218 }
219 }
220
221#ifdef HAVE_CHMOD
222 if (preserve_perms && !S_ISLNK(st->st_mode) &&
223 st->st_mode != file->mode) {
224 updated = 1;
225 if (chmod(fname,file->mode) != 0) {
226 fprintf(FERROR,"failed to set permissions on %s : %s\n",
227 fname,strerror(errno));
228 return 0;
229 }
230 }
231#endif
232
233 if ((am_root && preserve_uid && st->st_uid != file->uid) ||
234 (preserve_gid && st->st_gid != file->gid)) {
235 updated = 1;
236 if (lchown(fname,
237 (am_root&&preserve_uid)?file->uid:-1,
238 preserve_gid?file->gid:-1) != 0) {
239 if (verbose>1 || preserve_uid)
240 fprintf(FERROR,"chown %s : %s\n",fname,strerror(errno));
241 return updated;
242 }
243 }
244
245 if (verbose > 1 && report) {
246 if (updated)
247 fprintf(FINFO,"%s\n",fname);
248 else
249 fprintf(FINFO,"%s is uptodate\n",fname);
250 }
251 return updated;
252}
253
254
255void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
256{
257 int fd;
258 struct stat st;
259 struct map_struct *buf;
260 struct sum_struct *s;
261 char sum[MD4_SUM_LENGTH];
262 int statret;
263 struct file_struct *file = &flist->files[i];
264
265 if (verbose > 2)
266 fprintf(FERROR,"recv_generator(%s,%d)\n",fname,i);
267
268 statret = link_stat(fname,&st);
269
270 if (S_ISDIR(file->mode)) {
271 if (dry_run) return;
272 if (statret == 0 && !S_ISDIR(st.st_mode)) {
273 if (unlink(fname) != 0) {
274 fprintf(FERROR,"unlink %s : %s\n",fname,strerror(errno));
275 return;
276 }
277 statret = -1;
278 }
279 if (statret != 0 && mkdir(fname,file->mode) != 0 && errno != EEXIST) {
280 if (!(relative_paths && errno==ENOENT &&
281 create_directory_path(fname)==0 &&
282 mkdir(fname,file->mode)==0)) {
283 fprintf(FERROR,"mkdir %s : %s (2)\n",
284 fname,strerror(errno));
285 }
286 }
287 if (set_perms(fname,file,NULL,0) && verbose)
288 fprintf(FINFO,"%s/\n",fname);
289 return;
290 }
291
292 if (preserve_links && S_ISLNK(file->mode)) {
293#if SUPPORT_LINKS
294 char lnk[MAXPATHLEN];
295 int l;
296 if (statret == 0) {
297 l = readlink(fname,lnk,MAXPATHLEN-1);
298 if (l > 0) {
299 lnk[l] = 0;
300 if (strcmp(lnk,file->link) == 0) {
301 set_perms(fname,file,&st,1);
302 return;
303 }
304 }
305 }
306 if (!dry_run) unlink(fname);
307 if (!dry_run && symlink(file->link,fname) != 0) {
308 fprintf(FERROR,"link %s -> %s : %s\n",
309 fname,file->link,strerror(errno));
310 } else {
311 set_perms(fname,file,NULL,0);
312 if (verbose)
313 fprintf(FINFO,"%s -> %s\n",
314 fname,file->link);
315 }
316#endif
317 return;
318 }
319
320#ifdef HAVE_MKNOD
321 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
322 if (statret != 0 ||
323 st.st_mode != file->mode ||
324 st.st_rdev != file->rdev) {
325 if (!dry_run) unlink(fname);
326 if (verbose > 2)
327 fprintf(FERROR,"mknod(%s,0%o,0x%x)\n",
328 fname,(int)file->mode,(int)file->rdev);
329 if (!dry_run &&
330 mknod(fname,file->mode,file->rdev) != 0) {
331 fprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
332 } else {
333 set_perms(fname,file,NULL,0);
334 if (verbose)
335 fprintf(FINFO,"%s\n",fname);
336 }
337 } else {
338 set_perms(fname,file,&st,1);
339 }
340 return;
341 }
342#endif
343
344 if (preserve_hard_links && check_hard_link(file)) {
345 if (verbose > 1)
346 fprintf(FINFO,"%s is a hard link\n",file->name);
347 return;
348 }
349
350 if (!S_ISREG(file->mode)) {
351 fprintf(FERROR,"skipping non-regular file %s\n",fname);
352 return;
353 }
354
355 if (statret == -1) {
356 if (errno == ENOENT) {
357 write_int(f_out,i);
358 if (!dry_run) send_sums(NULL,f_out);
359 } else {
360 if (verbose > 1)
361 fprintf(FERROR,"recv_generator failed to open %s\n",fname);
362 }
363 return;
364 }
365
366 if (!S_ISREG(st.st_mode)) {
367 /* its not a regular file on the receiving end, but it is on the
368 sending end. If its a directory then skip it (too dangerous to
369 do a recursive deletion??) otherwise try to unlink it */
370 if (S_ISDIR(st.st_mode)) {
371 fprintf(FERROR,"ERROR: %s is a directory\n",fname);
372 return;
373 }
374 if (unlink(fname) != 0) {
375 fprintf(FERROR,"%s : not a regular file (generator)\n",fname);
376 return;
377 }
378
379 /* now pretend the file didn't exist */
380 write_int(f_out,i);
381 if (!dry_run) send_sums(NULL,f_out);
382 return;
383 }
384
385 if (update_only && st.st_mtime >= file->modtime) {
386 if (verbose > 1)
387 fprintf(FERROR,"%s is newer\n",fname);
388 return;
389 }
390
391 if (always_checksum && S_ISREG(st.st_mode)) {
392 file_checksum(fname,sum,st.st_size);
393 }
394
395 if (st.st_size == file->length &&
396 ((!ignore_times && st.st_mtime == file->modtime) ||
397 (always_checksum && S_ISREG(st.st_mode) &&
398 memcmp(sum,file->sum,csum_length) == 0))) {
399 set_perms(fname,file,&st,1);
400 return;
401 }
402
403 if (dry_run) {
404 write_int(f_out,i);
405 return;
406 }
407
408 if (whole_file) {
409 write_int(f_out,i);
410 send_sums(NULL,f_out);
411 return;
412 }
413
414 /* open the file */
415 fd = open(fname,O_RDONLY);
416
417 if (fd == -1) {
418 fprintf(FERROR,"failed to open %s : %s\n",fname,strerror(errno));
419 fprintf(FERROR,"skipping %s\n",fname);
420 return;
421 }
422
423 if (st.st_size > 0) {
424 buf = map_file(fd,st.st_size);
425 } else {
426 buf = NULL;
427 }
428
429 if (verbose > 3)
430 fprintf(FERROR,"gen mapped %s of size %d\n",fname,(int)st.st_size);
431
432 s = generate_sums(buf,st.st_size,block_size);
433
434 if (verbose > 2)
435 fprintf(FERROR,"sending sums for %d\n",i);
436
437 write_int(f_out,i);
438 send_sums(s,f_out);
439 write_flush(f_out);
440
441 close(fd);
442 if (buf) unmap_file(buf);
443
444 free_sums(s);
445}
446
447
448
449static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
450{
451 int i,n,remainder,len,count;
452 off_t offset = 0;
453 off_t offset2;
454 char *data;
455 static char file_sum1[MD4_SUM_LENGTH];
456 static char file_sum2[MD4_SUM_LENGTH];
457 char *map=NULL;
458
459 count = read_int(f_in);
460 n = read_int(f_in);
461 remainder = read_int(f_in);
462
463 sum_init();
464
465 for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
466 if (i > 0) {
467 if (verbose > 3)
468 fprintf(FERROR,"data recv %d at %d\n",i,(int)offset);
469
470 sum_update(data,i);
471
472 if (fd != -1 && write_sparse(fd,data,i) != i) {
473 fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
474 exit_cleanup(1);
475 }
476 offset += i;
477 } else {
478 i = -(i+1);
479 offset2 = i*n;
480 len = n;
481 if (i == count-1 && remainder != 0)
482 len = remainder;
483
484 if (verbose > 3)
485 fprintf(FERROR,"chunk[%d] of size %d at %d offset=%d\n",
486 i,len,(int)offset2,(int)offset);
487
488 map = map_ptr(buf,offset2,len);
489
490 see_token(map, len);
491 sum_update(map,len);
492
493 if (fd != -1 && write_sparse(fd,map,len) != len) {
494 fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
495 exit_cleanup(1);
496 }
497 offset += len;
498 }
499 }
500
501 if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
502 fprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
503 exit_cleanup(1);
504 }
505
506 sum_end(file_sum1);
507
508 if (remote_version >= 14) {
509 read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
510 if (verbose > 2)
511 fprintf(FERROR,"got file_sum\n");
512 if (fd != -1 && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0)
513 return 0;
514 }
515 return 1;
516}
517
518
519static void delete_one(struct file_struct *f)
520{
521 if (!S_ISDIR(f->mode)) {
522 if (!dry_run && unlink(f->name) != 0) {
523 fprintf(FERROR,"unlink %s : %s\n",f->name,strerror(errno));
524 } else if (verbose) {
525 fprintf(FERROR,"deleting %s\n",f->name);
526 }
527 } else {
528 if (!dry_run && rmdir(f->name) != 0) {
529 if (errno != ENOTEMPTY)
530 fprintf(FERROR,"rmdir %s : %s\n",f->name,strerror(errno));
531 } else if (verbose) {
532 fprintf(FERROR,"deleting directory %s\n",f->name);
533 }
534 }
535}
536
537
538/* this deletes any files on the receiving side that are not present
539 on the sending side. For version 1.6.4 I have changed the behaviour
540 to match more closely what most people seem to expect of this option */
541static void delete_files(struct file_list *flist)
542{
543 struct file_list *local_file_list;
544 int i, j;
545 char *last_name=NULL;
546
547 if (cvs_exclude)
548 add_cvs_excludes();
549
550 for (j=0;j<flist->count;j++) {
551 if (!S_ISDIR(flist->files[j].mode)) continue;
552 if (strcmp(flist->files[j].name,".")==0) continue;
553 if (last_name &&
554 flist->files[j].name[strlen(last_name)] == '/' &&
555 strncmp(flist->files[j].name,last_name, strlen(last_name))==0)
556 continue;
557 last_name = flist->files[j].name;
558 if (!(local_file_list = send_file_list(-1,1,&last_name)))
559 continue;
560 if (verbose > 1)
561 fprintf(FINFO,"deleting in %s\n", last_name);
562
563 for (i=local_file_list->count-1;i>=0;i--) {
564 if (!local_file_list->files[i].name) continue;
565 if (-1 == flist_find(flist,&local_file_list->files[i])) {
566 delete_one(&local_file_list->files[i]);
567 }
568 }
569 }
570}
571
572static char *cleanup_fname = NULL;
573
574void exit_cleanup(int code)
575{
576 if (cleanup_fname)
577 unlink(cleanup_fname);
578 signal(SIGUSR1, SIG_IGN);
579 if (code) {
580#ifdef GETPGRP_VOID
581 kill(-getpgrp(), SIGUSR1);
582#else
583 kill(-getpgrp(getpid()), SIGUSR1);
584#endif
585 }
586 exit(code);
587}
588
589void sig_int(void)
590{
591 exit_cleanup(1);
592}
593
594
595int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
596{
597 int fd1,fd2;
598 struct stat st;
599 char *fname;
600 char fnametmp[MAXPATHLEN];
601 struct map_struct *buf;
602 int i;
603 struct file_struct *file;
604 int phase=0;
605 int recv_ok;
606
607 if (verbose > 2) {
608 fprintf(FERROR,"recv_files(%d) starting\n",flist->count);
609 }
610
611 if (recurse && delete_mode && !local_name && flist->count>0) {
612 delete_files(flist);
613 }
614
615 while (1)
616 {
617 i = read_int(f_in);
618 if (i == -1) {
619 if (phase==0 && remote_version >= 13) {
620 phase++;
621 csum_length = SUM_LENGTH;
622 if (verbose > 2)
623 fprintf(FERROR,"recv_files phase=%d\n",phase);
624 write_int(f_gen,-1);
625 write_flush(f_gen);
626 continue;
627 }
628 break;
629 }
630
631 file = &flist->files[i];
632 fname = file->name;
633
634 if (local_name)
635 fname = local_name;
636
637 if (dry_run) {
638 if (!am_server && verbose)
639 printf("%s\n",fname);
640 continue;
641 }
642
643 if (verbose > 2)
644 fprintf(FERROR,"recv_files(%s)\n",fname);
645
646 /* open the file */
647 fd1 = open(fname,O_RDONLY);
648
649 if (fd1 != -1 && fstat(fd1,&st) != 0) {
650 fprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
651 receive_data(f_in,NULL,-1,NULL);
652 close(fd1);
653 continue;
654 }
655
656 if (fd1 != -1 && !S_ISREG(st.st_mode)) {
657 fprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
658 receive_data(f_in,NULL,-1,NULL);
659 close(fd1);
660 continue;
661 }
662
663 if (fd1 != -1 && st.st_size > 0) {
664 buf = map_file(fd1,st.st_size);
665 if (verbose > 2)
666 fprintf(FERROR,"recv mapped %s of size %d\n",fname,(int)st.st_size);
667 } else {
668 buf = NULL;
669 }
670
671 /* open tmp file */
672 if (strlen(fname) > (MAXPATHLEN-8)) {
673 fprintf(FERROR,"filename too long\n");
674 close(fd1);
675 continue;
676 }
677 sprintf(fnametmp,"%s.XXXXXX",fname);
678 if (NULL == mktemp(fnametmp)) {
679 fprintf(FERROR,"mktemp %s failed\n",fnametmp);
680 receive_data(f_in,buf,-1,NULL);
681 if (buf) unmap_file(buf);
682 close(fd1);
683 continue;
684 }
685 fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode);
686 if (fd2 == -1 && relative_paths && errno == ENOENT &&
687 create_directory_path(fnametmp) == 0) {
688 fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode);
689 }
690 if (fd2 == -1) {
691 fprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
692 receive_data(f_in,buf,-1,NULL);
693 if (buf) unmap_file(buf);
694 close(fd1);
695 continue;
696 }
697
698 cleanup_fname = fnametmp;
699
700 if (!am_server && verbose)
701 printf("%s\n",fname);
702
703 /* recv file data */
704 recv_ok = receive_data(f_in,buf,fd2,fname);
705
706 if (fd1 != -1) {
707 if (buf) unmap_file(buf);
708 close(fd1);
709 }
710 close(fd2);
711
712 if (verbose > 2)
713 fprintf(FERROR,"renaming %s to %s\n",fnametmp,fname);
714
715 if (make_backups) {
716 char fnamebak[MAXPATHLEN];
717 if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
718 fprintf(FERROR,"backup filename too long\n");
719 continue;
720 }
721 sprintf(fnamebak,"%s%s",fname,backup_suffix);
722 if (rename(fname,fnamebak) != 0 && errno != ENOENT) {
723 fprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
724 continue;
725 }
726 }
727
728 /* move tmp file over real file */
729 if (rename(fnametmp,fname) != 0) {
730 fprintf(FERROR,"rename %s -> %s : %s\n",
731 fnametmp,fname,strerror(errno));
732 unlink(fnametmp);
733 }
734
735 cleanup_fname = NULL;
736
737 set_perms(fname,file,NULL,0);
738
739 if (!recv_ok) {
740 if (verbose > 1)
741 fprintf(FERROR,"redoing %s(%d)\n",fname,i);
742 if (csum_length == SUM_LENGTH)
743 fprintf(FERROR,"ERROR: file corruption in %s\n",fname);
744 write_int(f_gen,i);
745 }
746 }
747
748 if (preserve_hard_links)
749 do_hard_links(flist);
750
751 /* now we need to fix any directory permissions that were
752 modified during the transfer */
753 for (i = 0; i < flist->count; i++) {
754 struct file_struct *file = &flist->files[i];
755 if (!file->name || !S_ISDIR(file->mode)) continue;
756 recv_generator(file->name,flist,i,-1);
757 }
758
759 if (verbose > 2)
760 fprintf(FERROR,"recv_files finished\n");
761
762 return 0;
763}
764
765
766
767off_t send_files(struct file_list *flist,int f_out,int f_in)
768{
769 int fd;
770 struct sum_struct *s;
771 struct map_struct *buf;
772 struct stat st;
773 char fname[MAXPATHLEN];
774 off_t total=0;
775 int i;
776 struct file_struct *file;
777 int phase = 0;
778
779 if (verbose > 2)
780 fprintf(FERROR,"send_files starting\n");
781
782 setup_nonblocking(f_in,f_out);
783
784 while (1)
785 {
786 i = read_int(f_in);
787 if (i == -1) {
788 if (phase==0 && remote_version >= 13) {
789 phase++;
790 csum_length = SUM_LENGTH;
791 write_int(f_out,-1);
792 write_flush(f_out);
793 if (verbose > 2)
794 fprintf(FERROR,"send_files phase=%d\n",phase);
795 continue;
796 }
797 break;
798 }
799
800 file = &flist->files[i];
801
802 fname[0] = 0;
803 if (file->dir) {
804 strncpy(fname,file->dir,MAXPATHLEN-1);
805 fname[MAXPATHLEN-1] = 0;
806 if (strlen(fname) == MAXPATHLEN-1) {
807 fprintf(FERROR, "send_files failed on long-named directory %s\n",
808 fname);
809 return -1;
810 }
811 strcat(fname,"/");
812 }
813 strncat(fname,file->name,MAXPATHLEN-strlen(fname));
814
815 if (verbose > 2)
816 fprintf(FERROR,"send_files(%d,%s)\n",i,fname);
817
818 if (dry_run) {
819 if (!am_server && verbose)
820 printf("%s\n",fname);
821 write_int(f_out,i);
822 continue;
823 }
824
825 s = receive_sums(f_in);
826 if (!s) {
827 fprintf(FERROR,"receive_sums failed\n");
828 return -1;
829 }
830
831 fd = open(fname,O_RDONLY);
832 if (fd == -1) {
833 fprintf(FERROR,"send_files failed to open %s: %s\n",
834 fname,strerror(errno));
835 continue;
836 }
837
838 /* map the local file */
839 if (fstat(fd,&st) != 0) {
840 fprintf(FERROR,"fstat failed : %s\n",strerror(errno));
841 close(fd);
842 return -1;
843 }
844
845 if (st.st_size > 0) {
846 buf = map_file(fd,st.st_size);
847 } else {
848 buf = NULL;
849 }
850
851 if (verbose > 2)
852 fprintf(FERROR,"send_files mapped %s of size %d\n",
853 fname,(int)st.st_size);
854
855 write_int(f_out,i);
856
857 write_int(f_out,s->count);
858 write_int(f_out,s->n);
859 write_int(f_out,s->remainder);
860
861 if (verbose > 2)
862 fprintf(FERROR,"calling match_sums %s\n",fname);
863
864 if (!am_server && verbose)
865 printf("%s\n",fname);
866
867 match_sums(f_out,s,buf,st.st_size);
868 write_flush(f_out);
869
870 if (buf) unmap_file(buf);
871 close(fd);
872
873 free_sums(s);
874
875 if (verbose > 2)
876 fprintf(FERROR,"sender finished %s\n",fname);
877
878 total += st.st_size;
879 }
880
881 if (verbose > 2)
882 fprintf(FERROR,"send files finished\n");
883
884 match_report();
885
886 write_int(f_out,-1);
887 write_flush(f_out);
888
889 return total;
890}
891
892
893
894void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
895{
896 int i;
897 int phase=0;
898
899 if (verbose > 2)
900 fprintf(FERROR,"generator starting pid=%d count=%d\n",
901 (int)getpid(),flist->count);
902
903 for (i = 0; i < flist->count; i++) {
904 struct file_struct *file = &flist->files[i];
905 mode_t saved_mode = file->mode;
906 if (!file->name) continue;
907
908 /* we need to ensure that any directories we create have writeable
909 permissions initially so that we can create the files within
910 them. This is then fixed after the files are transferred */
911 if (!am_root && S_ISDIR(file->mode)) {
912 file->mode |= S_IWUSR; /* user write */
913 }
914
915 recv_generator(local_name?local_name:file->name,
916 flist,i,f);
917
918 file->mode = saved_mode;
919 }
920
921 phase++;
922 csum_length = SUM_LENGTH;
923 ignore_times=1;
924
925 if (verbose > 2)
926 fprintf(FERROR,"generate_files phase=%d\n",phase);
927
928 write_int(f,-1);
929 write_flush(f);
930
931 if (remote_version >= 13) {
932 /* in newer versions of the protocol the files can cycle through
933 the system more than once to catch initial checksum errors */
934 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
935 struct file_struct *file = &flist->files[i];
936 recv_generator(local_name?local_name:file->name,
937 flist,i,f);
938 }
939
940 phase++;
941 if (verbose > 2)
942 fprintf(FERROR,"generate_files phase=%d\n",phase);
943
944 write_int(f,-1);
945 write_flush(f);
946 }
947
948
949 if (verbose > 2)
950 fprintf(FERROR,"generator wrote %d\n",write_total());
951}
952
953