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 csum_length
;
24 extern struct stats stats
;
33 * The sender gets checksums from the generator, calculates deltas,
34 * and transmits them to the receiver. The sender process runs on the
35 * machine holding the source files.
39 void read_sum_head(int f
, struct sum_struct
*sum
)
41 extern int protocol_version
;
43 sum
->count
= read_int(f
);
44 sum
->blength
= read_int(f
);
45 if (protocol_version
< 27) {
46 sum
->s2length
= csum_length
;
48 sum
->s2length
= read_int(f
);
49 if (sum
->s2length
> MD4_SUM_LENGTH
) {
50 rprintf(FERROR
, "Invalid checksum length %d\n",
52 exit_cleanup(RERR_PROTOCOL
);
55 sum
->remainder
= read_int(f
);
59 * Receive the checksums for a buffer
61 static struct sum_struct
*receive_sums(int f
)
67 s
= new(struct sum_struct
);
68 if (!s
) out_of_memory("receive_sums");
75 rprintf(FINFO
, "count=%ld n=%ld rem=%ld\n",
76 (long) s
->count
, (long) s
->blength
,
82 s
->sums
= new_array(struct sum_buf
, s
->count
);
83 if (!s
->sums
) out_of_memory("receive_sums");
85 for (i
= 0; i
< (int) s
->count
; i
++) {
86 s
->sums
[i
].sum1
= read_int(f
);
87 read_buf(f
, s
->sums
[i
].sum2
, s
->s2length
);
89 s
->sums
[i
].offset
= offset
;
92 if (i
== (int) s
->count
-1 && s
->remainder
!= 0) {
93 s
->sums
[i
].len
= s
->remainder
;
95 s
->sums
[i
].len
= s
->blength
;
97 offset
+= s
->sums
[i
].len
;
100 rprintf(FINFO
, "chunk[%d] len=%d offset=%.0f sum1=%08x\n",
101 i
, s
->sums
[i
].len
, (double)s
->sums
[i
].offset
, s
->sums
[i
].sum1
);
111 void send_files(struct file_list
*flist
, int f_out
, int f_in
)
114 struct sum_struct
*s
;
115 struct map_struct
*buf
= NULL
;
117 char fname
[MAXPATHLEN
];
119 struct file_struct
*file
;
121 extern struct stats stats
;
122 struct stats initial_stats
;
123 extern int write_batch
; /* dw */
124 extern int read_batch
; /* dw */
125 int checksums_match
; /* dw */
126 int buff_len
; /* dw */
127 char buff
[CHUNK_SIZE
]; /* dw */
132 rprintf(FINFO
, "send_files starting\n");
141 csum_length
= SUM_LENGTH
;
142 write_int(f_out
, -1);
144 rprintf(FINFO
, "send_files phase=%d\n", phase
);
150 if (i
< 0 || i
>= flist
->count
) {
151 rprintf(FERROR
, "Invalid file index %d (count=%d)\n",
153 exit_cleanup(RERR_PROTOCOL
);
156 file
= flist
->files
[i
];
158 stats
.num_transferred_files
++;
159 stats
.total_transferred_size
+= file
->length
;
163 strlcpy(fname
, file
->basedir
, MAXPATHLEN
);
164 if (strlen(fname
) == MAXPATHLEN
-1) {
166 rprintf(FERROR
, "send_files failed on long-named directory %s\n",
170 strlcat(fname
, "/", MAXPATHLEN
);
171 offset
= strlen(file
->basedir
)+1;
173 strlcat(fname
, f_name(file
), MAXPATHLEN
);
176 rprintf(FINFO
, "send_files(%d, %s)\n", i
, fname
);
179 if (!am_server
&& verbose
) { /* log transfer */
180 rprintf(FINFO
, "%s\n", fname
+offset
);
186 initial_stats
= stats
;
188 s
= receive_sums(f_in
);
191 rprintf(FERROR
, "receive_sums failed\n");
196 write_batch_csum_info(&i
, flist
->count
, s
);
199 fd
= do_open(fname
, O_RDONLY
, 0);
202 rprintf(FERROR
, "send_files failed to open %s: %s\n",
203 full_fname(fname
), strerror(errno
));
208 /* map the local file */
209 if (do_fstat(fd
, &st
) != 0) {
211 rprintf(FERROR
, "fstat failed: %s\n", strerror(errno
));
217 if (st
.st_size
> 0) {
218 buf
= map_file(fd
, st
.st_size
);
224 rprintf(FINFO
, "send_files mapped %s of size %.0f\n",
225 fname
, (double)st
.st_size
);
230 write_batch_delta_file((char *)&i
, sizeof(i
));
232 write_sum_head(f_out
, s
);
235 if (verbose
> 2 && !read_batch
)
236 rprintf(FINFO
, "calling match_sums %s\n", fname
);
238 if (!am_server
&& verbose
) { /* log transfer */
239 rprintf(FINFO
, "%s\n", fname
+offset
);
242 set_compression(fname
);
244 if (read_batch
) { /* dw */
245 /* read checksums originally computed on sender side */
246 read_batch_csum_info(i
, s
, &checksums_match
);
247 if (checksums_match
) {
248 read_batch_delta_file( (char *) &j
, sizeof(int) );
249 if (j
!= i
) { /* if flist index entries don't match*/
250 rprintf(FINFO
, "index mismatch in send_files\n");
251 rprintf(FINFO
, "read index = %d flist ndx = %d\n", j
, i
);
252 close_batch_delta_file();
253 close_batch_csums_file();
257 write_sum_head(f_out
, s
);
260 read_batch_delta_file( (char *) &buff_len
, sizeof(int) );
261 write_int(f_out
, buff_len
);
266 read_batch_delta_file(buff
, buff_len
);
267 write_buf(f_out
, buff
, buff_len
);
271 read_batch_delta_file( buff
, MD4_SUM_LENGTH
);
272 write_buf(f_out
, buff
, MD4_SUM_LENGTH
);
275 } else { /* not checksum match */
276 rprintf (FINFO
, "readbatch & checksums don't match\n");
277 rprintf (FINFO
, "filename=%s is being skipped\n", fname
);
281 match_sums(f_out
, s
, buf
, st
.st_size
);
282 log_send(file
, &initial_stats
);
285 if (!read_batch
) { /* dw */
291 "read errors mapping %s: (%d) %s\n",
303 rprintf(FINFO
, "sender finished %s\n", fname
);
307 rprintf(FINFO
, "send files finished\n");
311 write_int(f_out
, -1);
312 if (write_batch
|| read_batch
) { /* dw */
313 close_batch_csums_file();
314 close_batch_delta_file();