2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
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.
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.
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.
23 extern int remote_version
;
24 extern int csum_length
;
25 extern struct stats stats
;
32 receive the checksums for a buffer
34 static struct sum_struct
*receive_sums(int f
)
40 s
= (struct sum_struct
*)malloc(sizeof(*s
));
41 if (!s
) out_of_memory("receive_sums");
43 s
->count
= read_int(f
);
45 s
->remainder
= read_int(f
);
49 rprintf(FINFO
,"count=%d n=%d rem=%d\n",
50 s
->count
,s
->n
,s
->remainder
);
55 s
->sums
= (struct sum_buf
*)malloc(sizeof(s
->sums
[0])*s
->count
);
56 if (!s
->sums
) out_of_memory("receive_sums");
58 for (i
=0;i
<s
->count
;i
++) {
59 s
->sums
[i
].sum1
= read_int(f
);
60 read_buf(f
,s
->sums
[i
].sum2
,csum_length
);
62 s
->sums
[i
].offset
= offset
;
65 if (i
== s
->count
-1 && s
->remainder
!= 0) {
66 s
->sums
[i
].len
= s
->remainder
;
68 s
->sums
[i
].len
= s
->n
;
70 offset
+= s
->sums
[i
].len
;
73 rprintf(FINFO
,"chunk[%d] len=%d offset=%.0f sum1=%08x\n",
74 i
,s
->sums
[i
].len
,(double)s
->sums
[i
].offset
,s
->sums
[i
].sum1
);
84 void send_files(struct file_list
*flist
,int f_out
,int f_in
)
88 struct map_struct
*buf
;
90 char fname
[MAXPATHLEN
];
92 struct file_struct
*file
;
94 extern struct stats stats
;
95 struct stats initial_stats
;
96 extern int write_batch
; /* dw */
97 extern int read_batch
; /* dw */
98 int checksums_match
; /* dw */
99 int buff_len
; /* dw */
100 char buff
[CHUNK_SIZE
]; /* dw */
105 rprintf(FINFO
,"send_files starting\n");
112 if (phase
==0 && remote_version
>= 13) {
114 csum_length
= SUM_LENGTH
;
117 rprintf(FINFO
,"send_files phase=%d\n",phase
);
123 if (i
< 0 || i
>= flist
->count
) {
124 rprintf(FERROR
,"Invalid file index %d (count=%d)\n",
126 exit_cleanup(RERR_PROTOCOL
);
129 file
= flist
->files
[i
];
131 stats
.num_transferred_files
++;
132 stats
.total_transferred_size
+= file
->length
;
136 strlcpy(fname
,file
->basedir
,MAXPATHLEN
);
137 if (strlen(fname
) == MAXPATHLEN
-1) {
139 rprintf(FERROR
, "send_files failed on long-named directory %s\n",
143 strlcat(fname
,"/",MAXPATHLEN
);
144 offset
= strlen(file
->basedir
)+1;
146 strlcat(fname
,f_name(file
),MAXPATHLEN
);
149 rprintf(FINFO
,"send_files(%d,%s)\n",i
,fname
);
153 log_transfer(file
, fname
+offset
);
159 initial_stats
= stats
;
161 s
= receive_sums(f_in
);
162 if (write_batch
) /* dw */
163 write_batch_csum_info(&i
,flist
->count
,s
);
166 rprintf(FERROR
,"receive_sums failed\n");
171 fd
= do_open(fname
, O_RDONLY
, 0);
174 rprintf(FERROR
,"send_files failed to open %s: %s\n",
175 fname
,strerror(errno
));
180 /* map the local file */
181 if (do_fstat(fd
,&st
) != 0) {
183 rprintf(FERROR
,"fstat failed : %s\n",strerror(errno
));
189 if (st
.st_size
> 0) {
190 buf
= map_file(fd
,st
.st_size
);
196 rprintf(FINFO
,"send_files mapped %s of size %.0f\n",
197 fname
,(double)st
.st_size
);
200 if (!read_batch
) { /* dw */
204 write_batch_delta_file((char *)&i
,sizeof(i
));
206 write_int(f_out
,s
->count
);
207 write_int(f_out
,s
->n
);
208 write_int(f_out
,s
->remainder
);
213 rprintf(FINFO
,"calling match_sums %s\n",fname
);
216 log_transfer(file
, fname
+offset
);
219 set_compression(fname
);
221 if (read_batch
) { /* dw */
222 /* read checksums originally computed on sender side */
223 read_batch_csum_info(i
, s
, &checksums_match
);
224 if (checksums_match
) {
225 read_batch_delta_file( (char *) &j
, sizeof(int) );
226 if (j
!= i
) { /* if flist index entries don't match*/
227 rprintf(FINFO
,"index mismatch in send_files\n");
228 rprintf(FINFO
,"read index = %d flist ndx = %d\n",j
,i
);
229 close_batch_delta_file();
230 close_batch_csums_file();
235 write_int(f_out
,s
->count
);
236 write_int(f_out
,s
->n
);
237 write_int(f_out
,s
->remainder
);
240 read_batch_delta_file( (char *) &buff_len
, sizeof(int) );
241 write_int(f_out
,buff_len
);
247 read_batch_delta_file(buff
, buff_len
);
248 write_buf(f_out
,buff
,buff_len
);
252 read_batch_delta_file( buff
, MD4_SUM_LENGTH
);
253 write_buf(f_out
, buff
, MD4_SUM_LENGTH
);
256 } else { /* not checksum match */
257 rprintf (FINFO
,"readbatch & checksums don't match\n");
258 rprintf (FINFO
,"filename=%s is being skipped\n",
263 match_sums(f_out
,s
,buf
,st
.st_size
);
264 log_send(file
, &initial_stats
);
267 if (!read_batch
) { /* dw */
268 if (buf
) unmap_file(buf
);
275 rprintf(FINFO
,"sender finished %s\n",fname
);
279 rprintf(FINFO
,"send files finished\n");
284 if (write_batch
|| read_batch
) { /* dw */
285 close_batch_csums_file();
286 close_batch_delta_file();