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