Update to use the new zlib-1.1.2 code.
[rsync/rsync.git] / token.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 #include "zlib/zlib.h"
22
23 extern int do_compression;
24
25
26 /* non-compressing recv token */
27 static int simple_recv_token(int f,char **data)
28 {
29         static int residue;
30         static char *buf;
31         int n;
32
33         if (!buf) {
34                 buf = (char *)malloc(CHUNK_SIZE);
35                 if (!buf) out_of_memory("simple_recv_token");
36         }
37
38         if (residue == 0) {
39                 int i = read_int(f);
40                 if (i <= 0) return i;
41                 residue = i;
42         }
43
44         *data = buf;
45         n = MIN(CHUNK_SIZE,residue);
46         residue -= n;
47         read_buf(f,buf,n);
48         return n;
49 }
50
51
52 /* non-compressing send token */
53 static void simple_send_token(int f,int token,
54                               struct map_struct *buf,OFF_T offset,int n)
55 {
56         if (n > 0) {
57                 int l = 0;
58                 while (l < n) {
59                         int n1 = MIN(CHUNK_SIZE,n-l);
60                         write_int(f,n1);
61                         write_buf(f,map_ptr(buf,offset+l,n1),n1);
62                         l += n1;
63                 }
64         }
65         /* a -2 token means to send data only and no token */
66         if (token != -2) {
67                 write_int(f,-(token+1));
68         }
69 }
70
71
72 /* Flag bytes in compressed stream are encoded as follows: */
73 #define END_FLAG        0       /* that's all folks */
74 #define TOKEN_LONG      0x20    /* followed by 32-bit token number */
75 #define TOKENRUN_LONG   0x21    /* ditto with 16-bit run count */
76 #define DEFLATED_DATA   0x40    /* + 6-bit high len, then low len byte */
77 #define TOKEN_REL       0x80    /* + 6-bit relative token number */
78 #define TOKENRUN_REL    0xc0    /* ditto with 16-bit run count */
79
80 #define MAX_DATA_COUNT  16383   /* fit 14 bit count into 2 bytes with flags */
81
82 /* For coding runs of tokens */
83 static int last_token = -1;
84 static int run_start;
85 static int last_run_end;
86
87 /* Deflation state */
88 static z_stream tx_strm;
89
90 /* Output buffer */
91 static char *obuf;
92
93 /* Send a deflated token */
94 static void
95 send_deflated_token(int f, int token,
96                     struct map_struct *buf, OFF_T offset, int nb, int toklen)
97 {
98         int n, r;
99         static int init_done, flush_pending;
100
101         if (last_token == -1) {
102                 /* initialization */
103                 if (!init_done) {
104                         tx_strm.next_in = NULL;
105                         tx_strm.zalloc = NULL;
106                         tx_strm.zfree = NULL;
107                         if (deflateInit2(&tx_strm, Z_DEFAULT_COMPRESSION,
108                                          Z_DEFLATED, -15, 8,
109                                          Z_DEFAULT_STRATEGY) != Z_OK) {
110                                 rprintf(FERROR, "compression init failed\n");
111                                 exit_cleanup(1);
112                         }
113                         if ((obuf = malloc(MAX_DATA_COUNT+2)) == NULL)
114                                 out_of_memory("send_deflated_token");
115                         init_done = 1;
116                 } else
117                         deflateReset(&tx_strm);
118                 last_run_end = 0;
119                 run_start = token;
120                 flush_pending = 0;
121
122         } else if (last_token == -2) {
123                 run_start = token;
124
125         } else if (nb != 0 || token != last_token + 1
126                    || token >= run_start + 65536) {
127                 /* output previous run */
128                 r = run_start - last_run_end;
129                 n = last_token - run_start;
130                 if (r >= 0 && r <= 63) {
131                         write_byte(f, (n==0? TOKEN_REL: TOKENRUN_REL) + r);
132                 } else {
133                         write_byte(f, (n==0? TOKEN_LONG: TOKENRUN_LONG));
134                         write_int(f, run_start);
135                 }
136                 if (n != 0) {
137                         write_byte(f, n);
138                         write_byte(f, n >> 8);
139                 }
140                 last_run_end = last_token;
141                 run_start = token;
142         }
143
144         last_token = token;
145
146         if (nb != 0 || flush_pending) {
147                 /* deflate the data starting at offset */
148                 int flush = Z_NO_FLUSH;
149                 tx_strm.avail_in = 0;
150                 tx_strm.avail_out = 0;
151                 do {
152                         if (tx_strm.avail_in == 0 && nb != 0) {
153                                 /* give it some more input */
154                                 n = MIN(nb, CHUNK_SIZE);
155                                 tx_strm.next_in = (Bytef *)
156                                         map_ptr(buf, offset, n);
157                                 tx_strm.avail_in = n;
158                                 nb -= n;
159                                 offset += n;
160                         }
161                         if (tx_strm.avail_out == 0) {
162                                 tx_strm.next_out = (Bytef *)(obuf + 2);
163                                 tx_strm.avail_out = MAX_DATA_COUNT;
164                                 if (flush != Z_NO_FLUSH) {
165                                         /*
166                                          * We left the last 4 bytes in the
167                                          * buffer, in case they are the
168                                          * last 4.  Move them to the front.
169                                          */
170                                         memcpy(tx_strm.next_out,
171                                                obuf+MAX_DATA_COUNT-2, 4);
172                                         tx_strm.next_out += 4;
173                                         tx_strm.avail_out -= 4;
174                                 }
175                         }
176                         if (nb == 0 && token != -2)
177                                 flush = Z_SYNC_FLUSH;
178                         r = deflate(&tx_strm, flush);
179                         if (r != Z_OK) {
180                                 rprintf(FERROR, "deflate returned %d\n", r);
181                                 exit_cleanup(1);
182                         }
183                         if (nb == 0 || tx_strm.avail_out == 0) {
184                                 n = MAX_DATA_COUNT - tx_strm.avail_out;
185                                 if (flush != Z_NO_FLUSH) {
186                                         /*
187                                          * We have to trim off the last 4
188                                          * bytes of output when flushing
189                                          * (they are just 0, 0, ff, ff).
190                                          */
191                                         n -= 4;
192                                 }
193                                 if (n > 0) {
194                                         obuf[0] = DEFLATED_DATA + (n >> 8);
195                                         obuf[1] = n;
196                                         write_buf(f, obuf, n+2);
197                                 }
198                         }
199                 } while (nb != 0 || tx_strm.avail_out == 0);
200                 flush_pending = token == -2;
201         }
202
203         if (token == -1) {
204                 /* end of file - clean up */
205                 write_byte(f, END_FLAG);
206
207         } else if (token != -2) {
208                 /* add the data in the current block to the compressor's
209                    history and hash table */
210                 tx_strm.next_in = (Bytef *) map_ptr(buf, offset, toklen);
211                 tx_strm.avail_in = toklen;
212                 tx_strm.next_out = (Bytef *) obuf;
213                 tx_strm.avail_out = MAX_DATA_COUNT;
214                 r = deflate(&tx_strm, Z_INSERT_ONLY);
215                 if (r != Z_OK || tx_strm.avail_in != 0) {
216                         rprintf(FERROR, "deflate on token returned %d (%d bytes left)\n",
217                                 r, tx_strm.avail_in);
218                         exit_cleanup(1);
219                 }
220         }
221 }
222
223
224 /* tells us what the receiver is in the middle of doing */
225 static enum { r_init, r_idle, r_running, r_inflating, r_inflated } recv_state;
226
227 /* for inflating stuff */
228 static z_stream rx_strm;
229 static char *cbuf;
230 static char *dbuf;
231
232 /* for decoding runs of tokens */
233 static int rx_token;
234 static int rx_run;
235
236 /* Receive a deflated token and inflate it */
237 static int
238 recv_deflated_token(int f, char **data)
239 {
240         int n, r, flag;
241         static int init_done;
242         static int saved_flag;
243
244         for (;;) {
245                 switch (recv_state) {
246                 case r_init:
247                         if (!init_done) {
248                                 rx_strm.next_out = NULL;
249                                 rx_strm.zalloc = NULL;
250                                 rx_strm.zfree = NULL;
251                                 if (inflateInit2(&rx_strm, -15) != Z_OK) {
252                                         rprintf(FERROR, "inflate init failed\n");
253                                         exit_cleanup(1);
254                                 }
255                                 if ((cbuf = malloc(MAX_DATA_COUNT)) == NULL
256                                     || (dbuf = malloc(CHUNK_SIZE)) == NULL)
257                                         out_of_memory("recv_deflated_token");
258                                 init_done = 1;
259                         } else {
260                                 inflateReset(&rx_strm);
261                         }
262                         recv_state = r_idle;
263                         rx_token = 0;
264                         break;
265
266                 case r_idle:
267                 case r_inflated:
268                         if (saved_flag) {
269                                 flag = saved_flag & 0xff;
270                                 saved_flag = 0;
271                         } else
272                                 flag = read_byte(f);
273                         if ((flag & 0xC0) == DEFLATED_DATA) {
274                                 n = ((flag & 0x3f) << 8) + read_byte(f);
275                                 read_buf(f, cbuf, n);
276                                 rx_strm.next_in = (Bytef *)cbuf;
277                                 rx_strm.avail_in = n;
278                                 recv_state = r_inflating;
279                                 break;
280                         }
281                         if (recv_state == r_inflated) {
282                                 /* check previous inflated stuff ended correctly */
283                                 rx_strm.avail_in = 0;
284                                 rx_strm.next_out = (Bytef *)dbuf;
285                                 rx_strm.avail_out = CHUNK_SIZE;
286                                 r = inflate(&rx_strm, Z_SYNC_FLUSH);
287                                 n = CHUNK_SIZE - rx_strm.avail_out;
288                                 /*
289                                  * Z_BUF_ERROR just means no progress was
290                                  * made, i.e. the decompressor didn't have
291                                  * any pending output for us.
292                                  */
293                                 if (r != Z_OK && r != Z_BUF_ERROR) {
294                                         rprintf(FERROR, "inflate flush returned %d (%d bytes)\n",
295                                                 r, n);
296                                         exit_cleanup(1);
297                                 }
298                                 if (n != 0 && r != Z_BUF_ERROR) {
299                                         /* have to return some more data and
300                                            save the flag for later. */
301                                         saved_flag = flag + 0x10000;
302                                         *data = dbuf;
303                                         return n;
304                                 }
305                                 /*
306                                  * At this point the decompressor should
307                                  * be expecting to see the 0, 0, ff, ff bytes.
308                                  */
309                                 if (!inflateSyncPoint(&rx_strm)) {
310                                         rprintf(FERROR, "decompressor lost sync!\n");
311                                         exit_cleanup(1);
312                                 }
313                                 rx_strm.avail_in = 4;
314                                 rx_strm.next_in = (Bytef *)cbuf;
315                                 cbuf[0] = cbuf[1] = 0;
316                                 cbuf[2] = cbuf[3] = 0xff;
317                                 inflate(&rx_strm, Z_SYNC_FLUSH);
318                                 recv_state = r_idle;
319                         }
320                         if (flag == END_FLAG) {
321                                 /* that's all folks */
322                                 recv_state = r_init;
323                                 return 0;
324                         }
325
326                         /* here we have a token of some kind */
327                         if (flag & TOKEN_REL) {
328                                 rx_token += flag & 0x3f;
329                                 flag >>= 6;
330                         } else
331                                 rx_token = read_int(f);
332                         if (flag & 1) {
333                                 rx_run = read_byte(f);
334                                 rx_run += read_byte(f) << 8;
335                                 recv_state = r_running;
336                         }
337                         return -1 - rx_token;
338
339                 case r_inflating:
340                         rx_strm.next_out = (Bytef *)dbuf;
341                         rx_strm.avail_out = CHUNK_SIZE;
342                         r = inflate(&rx_strm, Z_NO_FLUSH);
343                         n = CHUNK_SIZE - rx_strm.avail_out;
344                         if (r != Z_OK) {
345                                 rprintf(FERROR, "inflate returned %d (%d bytes)\n", r, n);
346                                 exit_cleanup(1);
347                         }
348                         if (rx_strm.avail_in == 0)
349                                 recv_state = r_inflated;
350                         if (n != 0) {
351                                 *data = dbuf;
352                                 return n;
353                         }
354                         break;
355
356                 case r_running:
357                         ++rx_token;
358                         if (--rx_run == 0)
359                                 recv_state = r_idle;
360                         return -1 - rx_token;
361                 }
362         }
363 }
364
365 /*
366  * put the data corresponding to a token that we've just returned
367  * from recv_deflated_token into the decompressor's history buffer.
368  */
369 void
370 see_deflate_token(char *buf, int len)
371 {
372         int r, blklen;
373         unsigned char hdr[5];
374
375         rx_strm.avail_in = 0;
376         blklen = 0;
377         hdr[0] = 0;
378         do {
379                 if (rx_strm.avail_in == 0 && len != 0) {
380                         if (blklen == 0) {
381                                 /* Give it a fake stored-block header. */
382                                 rx_strm.next_in = (Bytef *)hdr;
383                                 rx_strm.avail_in = 5;
384                                 blklen = len;
385                                 if (blklen > 0xffff)
386                                         blklen = 0xffff;
387                                 hdr[1] = blklen;
388                                 hdr[2] = blklen >> 8;
389                                 hdr[3] = ~hdr[1];
390                                 hdr[4] = ~hdr[2];
391                         } else {
392                                 rx_strm.next_in = (Bytef *)buf;
393                                 rx_strm.avail_in = blklen;
394                                 len -= blklen;
395                                 blklen = 0;
396                         }
397                 }
398                 rx_strm.next_out = (Bytef *)dbuf;
399                 rx_strm.avail_out = CHUNK_SIZE;
400                 r = inflate(&rx_strm, Z_SYNC_FLUSH);
401                 if (r != Z_OK) {
402                         rprintf(FERROR, "inflate (token) returned %d\n", r);
403                         exit_cleanup(1);
404                 }
405         } while (len || rx_strm.avail_out == 0);
406 }
407
408 /*
409  * transmit a verbatim buffer of length n followed by a token 
410  * If token == -1 then we have reached EOF 
411  * If n == 0 then don't send a buffer
412  */
413 void send_token(int f,int token,struct map_struct *buf,OFF_T offset,
414                 int n,int toklen)
415 {
416         if (!do_compression) {
417                 simple_send_token(f,token,buf,offset,n);
418         } else {
419                 send_deflated_token(f, token, buf, offset, n, toklen);
420         }
421 }
422
423
424 /*
425  * receive a token or buffer from the other end. If the reurn value is >0 then
426  * it is a data buffer of that length, and *data will point at the data.
427  * if the return value is -i then it represents token i-1
428  * if the return value is 0 then the end has been reached
429  */
430 int recv_token(int f,char **data)
431 {
432         int tok;
433
434         if (!do_compression) {
435                 tok = simple_recv_token(f,data);
436         } else {
437                 tok = recv_deflated_token(f, data);
438         }
439         return tok;
440 }
441
442 /*
443  * look at the data corresponding to a token, if necessary
444  */
445 void see_token(char *data, int toklen)
446 {
447         if (do_compression)
448                 see_deflate_token(data, toklen);
449 }