Quiet a compiler warning.
[rsync/rsync.git] / sender.c
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
22 extern int verbose;
23 extern int csum_length;
24 extern struct stats stats;
25 extern int io_error;
26 extern int dry_run;
27 extern int am_server;
28
29
30 /**
31  * @file
32  *
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.
36  **/
37
38
39 void read_sum_head(int f, struct sum_struct *sum)
40 {
41         extern int protocol_version;
42
43         sum->count = read_int(f);
44         sum->blength = read_int(f);
45         if (protocol_version < 27) {
46                 sum->s2length = csum_length;
47         } else {
48                 sum->s2length = read_int(f);
49                 if (sum->s2length > MD4_SUM_LENGTH) {
50                         rprintf(FERROR, "Invalid checksum length %ld\n",
51                             (long)sum->s2length);
52                         exit_cleanup(RERR_PROTOCOL);
53                 }
54         }
55         sum->remainder = read_int(f);
56 }
57
58 /**
59  * Receive the checksums for a buffer
60  **/
61 static struct sum_struct *receive_sums(int f)
62 {
63         struct sum_struct *s;
64         int i;
65         OFF_T offset = 0;
66
67         s = new(struct sum_struct);
68         if (!s) out_of_memory("receive_sums");
69
70         read_sum_head(f, s);
71
72         s->sums = NULL;
73
74         if (verbose > 3)
75                 rprintf(FINFO, "count=%ld n=%ld rem=%ld\n",
76                         (long) s->count, (long) s->blength,
77                         (long) s->remainder);
78
79         if (s->count == 0)
80                 return(s);
81
82         s->sums = new_array(struct sum_buf, s->count);
83         if (!s->sums) out_of_memory("receive_sums");
84
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);
88
89                 s->sums[i].offset = offset;
90                 s->sums[i].i = i;
91
92                 if (i == (int) s->count-1 && s->remainder != 0) {
93                         s->sums[i].len = s->remainder;
94                 } else {
95                         s->sums[i].len = s->blength;
96                 }
97                 offset += s->sums[i].len;
98
99                 if (verbose > 3)
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);
102         }
103
104         s->flength = offset;
105
106         return s;
107 }
108
109
110
111 void send_files(struct file_list *flist, int f_out, int f_in)
112 {
113         int fd = -1;
114         struct sum_struct *s;
115         struct map_struct *buf = NULL;
116         STRUCT_STAT st;
117         char fname[MAXPATHLEN];
118         int i;
119         struct file_struct *file;
120         int phase = 0;
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 */
128         int j;   /* dw */
129         int done;   /* dw */
130
131         if (verbose > 2)
132                 rprintf(FINFO, "send_files starting\n");
133
134         while (1) {
135                 int offset = 0;
136
137                 i = read_int(f_in);
138                 if (i == -1) {
139                         if (phase == 0) {
140                                 phase++;
141                                 csum_length = SUM_LENGTH;
142                                 write_int(f_out, -1);
143                                 if (verbose > 2)
144                                         rprintf(FINFO, "send_files phase=%d\n", phase);
145                                 continue;
146                         }
147                         break;
148                 }
149
150                 if (i < 0 || i >= flist->count) {
151                         rprintf(FERROR, "Invalid file index %d (count=%d)\n",
152                                 i, flist->count);
153                         exit_cleanup(RERR_PROTOCOL);
154                 }
155
156                 file = flist->files[i];
157
158                 stats.num_transferred_files++;
159                 stats.total_transferred_size += file->length;
160
161                 fname[0] = 0;
162                 if (file->basedir) {
163                         strlcpy(fname, file->basedir, MAXPATHLEN);
164                         if (strlen(fname) == MAXPATHLEN-1) {
165                                 io_error |= IOERR_GENERAL;
166                                 rprintf(FERROR, "send_files failed on long-named directory %s\n",
167                                         full_fname(fname));
168                                 return;
169                         }
170                         strlcat(fname, "/", MAXPATHLEN);
171                         offset = strlen(file->basedir)+1;
172                 }
173                 strlcat(fname, f_name(file), MAXPATHLEN);
174
175                 if (verbose > 2)
176                         rprintf(FINFO, "send_files(%d, %s)\n", i, fname);
177
178                 if (dry_run) {
179                         if (!am_server && verbose) {    /* log transfer */
180                                 rprintf(FINFO, "%s\n", fname+offset);
181                         }
182                         write_int(f_out, i);
183                         continue;
184                 }
185
186                 initial_stats = stats;
187
188                 s = receive_sums(f_in);
189                 if (!s) {
190                         io_error |= IOERR_GENERAL;
191                         rprintf(FERROR, "receive_sums failed\n");
192                         return;
193                 }
194
195                 if (write_batch)
196                         write_batch_csum_info(&i, flist->count, s);
197
198                 if (!read_batch) {
199                         fd = do_open(fname, O_RDONLY, 0);
200                         if (fd == -1) {
201                                 if (errno == ENOENT) {
202                                         io_error |= IOERR_VANISHED;
203                                         rprintf(FINFO, "file has vanished: %s\n",
204                                                 full_fname(fname));
205                                 } else {
206                                         io_error |= IOERR_GENERAL;
207                                         rprintf(FERROR, "send_files failed to open %s: %s\n",
208                                                 full_fname(fname), strerror(errno));
209                                 }
210                                 free_sums(s);
211                                 continue;
212                         }
213
214                         /* map the local file */
215                         if (do_fstat(fd, &st) != 0) {
216                                 io_error |= IOERR_GENERAL;
217                                 rprintf(FERROR, "fstat failed: %s\n", strerror(errno));
218                                 free_sums(s);
219                                 close(fd);
220                                 return;
221                         }
222
223                         if (st.st_size > 0) {
224                                 buf = map_file(fd, st.st_size);
225                         } else {
226                                 buf = NULL;
227                         }
228
229                         if (verbose > 2)
230                                 rprintf(FINFO, "send_files mapped %s of size %.0f\n",
231                                         fname, (double)st.st_size);
232
233                         write_int(f_out, i);
234
235                         if (write_batch)
236                                 write_batch_delta_file((char *)&i, sizeof(i));
237
238                         write_sum_head(f_out, s);
239                 }
240
241                 if (verbose > 2 && !read_batch)
242                         rprintf(FINFO, "calling match_sums %s\n", fname);
243
244                 if (!am_server && verbose) {    /* log transfer */
245                         rprintf(FINFO, "%s\n", fname+offset);
246                 }
247
248                 set_compression(fname);
249
250                 if (read_batch) { /* dw */
251                         /* read checksums originally computed on sender side */
252                         read_batch_csum_info(i, s, &checksums_match);
253                         if (checksums_match) {
254                                 read_batch_delta_file( (char *) &j, sizeof(int) );
255                                 if (j != i) {    /* if flist index entries don't match*/
256                                         rprintf(FINFO, "index mismatch in send_files\n");
257                                         rprintf(FINFO, "read index = %d flist ndx = %d\n", j, i);
258                                         close_batch_delta_file();
259                                         close_batch_csums_file();
260                                         exit_cleanup(1);
261                                 } else {
262                                         write_int(f_out, j);
263                                         write_sum_head(f_out, s);
264                                         done = 0;
265                                         while (!done) {
266                                                 read_batch_delta_file( (char *) &buff_len, sizeof(int) );
267                                                 write_int(f_out, buff_len);
268                                                 if (buff_len == 0) {
269                                                         done = 1;
270                                                 } else {
271                                                         if (buff_len > 0) {
272                                                                 read_batch_delta_file(buff, buff_len);
273                                                                 write_buf(f_out, buff, buff_len);
274                                                         }
275                                                 }
276                                         }  /* end while  */
277                                         read_batch_delta_file( buff, MD4_SUM_LENGTH);
278                                         write_buf(f_out, buff, MD4_SUM_LENGTH);
279
280                                 }  /* j=i */
281                         } else {  /* not checksum match */
282                                 rprintf (FINFO, "readbatch & checksums don't match\n");
283                                 rprintf (FINFO, "filename=%s is being skipped\n", fname);
284                                 continue;
285                         }
286                 } else  {
287                         match_sums(f_out, s, buf, st.st_size);
288                         log_send(file, &initial_stats);
289                 }
290
291                 if (!read_batch) { /* dw */
292                         if (buf) {
293                                 j = unmap_file(buf);
294                                 if (j) {
295                                         io_error |= IOERR_GENERAL;
296                                         rprintf(FERROR,
297                                             "read errors mapping %s: (%d) %s\n",
298                                             full_fname(fname), j, strerror(j));
299                                 }
300                         }
301                         close(fd);
302                 }
303
304                 free_sums(s);
305
306                 if (verbose > 2)
307                         rprintf(FINFO, "sender finished %s\n", fname);
308         }
309
310         if (verbose > 2)
311                 rprintf(FINFO, "send files finished\n");
312
313         match_report();
314
315         write_int(f_out, -1);
316         if (write_batch || read_batch) { /* dw */
317                 close_batch_csums_file();
318                 close_batch_delta_file();
319         }
320
321 }
322
323
324
325
326