- Added a new public function, iwildmatch(), which will treat all
[rsync/rsync.git] / token.c
CommitLineData
d67c8bdf 1/*
70d794dc
AT
2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
d67c8bdf 4
70d794dc
AT
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.
d67c8bdf 9
70d794dc
AT
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.
d67c8bdf 14
70d794dc
AT
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"
5914bf15 21#include "zlib/zlib.h"
70d794dc
AT
22
23extern int do_compression;
d67c8bdf 24extern int module_id;
e8a8167a 25extern int def_compress_level;
d67c8bdf 26
e8a8167a 27static int compression_level;
70d794dc 28
83fff1aa
AT
29/* determine the compression level based on a wildcard filename list */
30void set_compression(char *fname)
31{
83fff1aa
AT
32 char *dont;
33 char *tok;
34
d67c8bdf
WD
35 if (!do_compression)
36 return;
83fff1aa 37
e8a8167a 38 compression_level = def_compress_level;
83fff1aa
AT
39 dont = lp_dont_compress(module_id);
40
d67c8bdf
WD
41 if (!dont || !*dont)
42 return;
83fff1aa 43
d67c8bdf 44 if (dont[0] == '*' && !dont[1]) {
63f0774f
DD
45 /* an optimization to skip the rest of this routine */
46 compression_level = 0;
47 return;
48 }
49
0fe987e2
WD
50 if ((tok = strrchr(fname, '/')) != NULL)
51 fname = tok + 1;
52
83fff1aa
AT
53 dont = strdup(dont);
54 fname = strdup(fname);
d67c8bdf
WD
55 if (!dont || !fname)
56 return;
83fff1aa
AT
57
58 strlower(dont);
59 strlower(fname);
60
d67c8bdf 61 for (tok = strtok(dont, " "); tok; tok = strtok(NULL, " ")) {
fe332038 62 if (wildmatch(tok, fname)) {
83fff1aa
AT
63 compression_level = 0;
64 break;
65 }
66 }
67 free(dont);
68 free(fname);
69}
70d794dc
AT
70
71/* non-compressing recv token */
7fcbf9e4 72static int32 simple_recv_token(int f, char **data)
70d794dc 73{
acc461c7 74 static int32 residue;
c5eb3650 75 static char *buf;
7fcbf9e4 76 int32 n;
70d794dc 77
c5eb3650 78 if (!buf) {
58cadc86 79 buf = new_array(char, CHUNK_SIZE);
d67c8bdf
WD
80 if (!buf)
81 out_of_memory("simple_recv_token");
c5eb3650 82 }
70d794dc 83
c5eb3650 84 if (residue == 0) {
7fcbf9e4 85 int32 i = read_int(f);
d67c8bdf
WD
86 if (i <= 0)
87 return i;
c5eb3650
AT
88 residue = i;
89 }
70d794dc 90
c5eb3650
AT
91 *data = buf;
92 n = MIN(CHUNK_SIZE,residue);
93 residue -= n;
94 read_buf(f,buf,n);
95 return n;
70d794dc
AT
96}
97
98
99/* non-compressing send token */
acc461c7 100static void simple_send_token(int f, int32 token, struct map_struct *buf,
7fcbf9e4 101 OFF_T offset, int32 n)
70d794dc 102{
c5eb3650 103 if (n > 0) {
7fcbf9e4
WD
104 int32 len = 0;
105 while (len < n) {
106 int32 n1 = MIN(CHUNK_SIZE, n-len);
107 write_int(f, n1);
108 write_buf(f, map_ptr(buf, offset+len, n1), n1);
109 len += n1;
c5eb3650
AT
110 }
111 }
45f133b9 112 /* a -2 token means to send data only and no token */
7fcbf9e4
WD
113 if (token != -2)
114 write_int(f, -(token+1));
70d794dc
AT
115}
116
117
861c20b4
PM
118/* Flag bytes in compressed stream are encoded as follows: */
119#define END_FLAG 0 /* that's all folks */
120#define TOKEN_LONG 0x20 /* followed by 32-bit token number */
121#define TOKENRUN_LONG 0x21 /* ditto with 16-bit run count */
122#define DEFLATED_DATA 0x40 /* + 6-bit high len, then low len byte */
123#define TOKEN_REL 0x80 /* + 6-bit relative token number */
124#define TOKENRUN_REL 0xc0 /* ditto with 16-bit run count */
125
126#define MAX_DATA_COUNT 16383 /* fit 14 bit count into 2 bytes with flags */
127
24733919
WD
128/* zlib.h says that if we want to be able to compress something in a single
129 * call, avail_out must be at least 0.1% larger than avail_in plus 12 bytes.
130 * We'll add in 0.1%+16, just to be safe (and we'll avoid floating point,
131 * to ensure that this is a compile-time value). */
132#define AVAIL_OUT_SIZE(avail_in_size) ((avail_in_size)*1001/1000+16)
133
861c20b4 134/* For coding runs of tokens */
acc461c7
WD
135static int32 last_token = -1;
136static int32 run_start;
137static int32 last_run_end;
861c20b4
PM
138
139/* Deflation state */
140static z_stream tx_strm;
141
142/* Output buffer */
3a6a366f 143static char *obuf;
24733919
WD
144
145/* We want obuf to be able to hold both MAX_DATA_COUNT+2 bytes as well as
146 * AVAIL_OUT_SIZE(CHUNK_SIZE) bytes, so make sure that it's large enough. */
147#if MAX_DATA_COUNT+2 > AVAIL_OUT_SIZE(CHUNK_SIZE)
148#define OBUF_SIZE (MAX_DATA_COUNT+2)
149#else
150#define OBUF_SIZE AVAIL_OUT_SIZE(CHUNK_SIZE)
151#endif
861c20b4
PM
152
153/* Send a deflated token */
154static void
acc461c7 155send_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
7fcbf9e4 156 int32 nb, int32 toklen)
861c20b4 157{
7fcbf9e4 158 int32 n, r;
5914bf15
PM
159 static int init_done, flush_pending;
160
161 if (last_token == -1) {
162 /* initialization */
163 if (!init_done) {
164 tx_strm.next_in = NULL;
165 tx_strm.zalloc = NULL;
166 tx_strm.zfree = NULL;
83fff1aa 167 if (deflateInit2(&tx_strm, compression_level,
5914bf15
PM
168 Z_DEFLATED, -15, 8,
169 Z_DEFAULT_STRATEGY) != Z_OK) {
170 rprintf(FERROR, "compression init failed\n");
65417579 171 exit_cleanup(RERR_STREAMIO);
5914bf15 172 }
58cadc86 173 if ((obuf = new_array(char, OBUF_SIZE)) == NULL)
5914bf15
PM
174 out_of_memory("send_deflated_token");
175 init_done = 1;
176 } else
177 deflateReset(&tx_strm);
178 last_run_end = 0;
179 run_start = token;
180 flush_pending = 0;
181
182 } else if (last_token == -2) {
183 run_start = token;
184
185 } else if (nb != 0 || token != last_token + 1
186 || token >= run_start + 65536) {
187 /* output previous run */
188 r = run_start - last_run_end;
189 n = last_token - run_start;
190 if (r >= 0 && r <= 63) {
191 write_byte(f, (n==0? TOKEN_REL: TOKENRUN_REL) + r);
192 } else {
193 write_byte(f, (n==0? TOKEN_LONG: TOKENRUN_LONG));
194 write_int(f, run_start);
195 }
196 if (n != 0) {
197 write_byte(f, n);
198 write_byte(f, n >> 8);
199 }
200 last_run_end = last_token;
201 run_start = token;
861c20b4 202 }
5914bf15
PM
203
204 last_token = token;
205
206 if (nb != 0 || flush_pending) {
207 /* deflate the data starting at offset */
208 int flush = Z_NO_FLUSH;
209 tx_strm.avail_in = 0;
210 tx_strm.avail_out = 0;
211 do {
212 if (tx_strm.avail_in == 0 && nb != 0) {
213 /* give it some more input */
214 n = MIN(nb, CHUNK_SIZE);
215 tx_strm.next_in = (Bytef *)
216 map_ptr(buf, offset, n);
217 tx_strm.avail_in = n;
218 nb -= n;
219 offset += n;
220 }
221 if (tx_strm.avail_out == 0) {
222 tx_strm.next_out = (Bytef *)(obuf + 2);
223 tx_strm.avail_out = MAX_DATA_COUNT;
224 if (flush != Z_NO_FLUSH) {
225 /*
226 * We left the last 4 bytes in the
227 * buffer, in case they are the
228 * last 4. Move them to the front.
229 */
230 memcpy(tx_strm.next_out,
231 obuf+MAX_DATA_COUNT-2, 4);
232 tx_strm.next_out += 4;
233 tx_strm.avail_out -= 4;
234 }
235 }
236 if (nb == 0 && token != -2)
237 flush = Z_SYNC_FLUSH;
238 r = deflate(&tx_strm, flush);
239 if (r != Z_OK) {
240 rprintf(FERROR, "deflate returned %d\n", r);
65417579 241 exit_cleanup(RERR_STREAMIO);
5914bf15
PM
242 }
243 if (nb == 0 || tx_strm.avail_out == 0) {
244 n = MAX_DATA_COUNT - tx_strm.avail_out;
245 if (flush != Z_NO_FLUSH) {
246 /*
247 * We have to trim off the last 4
248 * bytes of output when flushing
249 * (they are just 0, 0, ff, ff).
250 */
251 n -= 4;
252 }
253 if (n > 0) {
254 obuf[0] = DEFLATED_DATA + (n >> 8);
255 obuf[1] = n;
256 write_buf(f, obuf, n+2);
257 }
258 }
259 } while (nb != 0 || tx_strm.avail_out == 0);
260 flush_pending = token == -2;
861c20b4 261 }
861c20b4 262
5914bf15
PM
263 if (token == -1) {
264 /* end of file - clean up */
265 write_byte(f, END_FLAG);
5914bf15 266 } else if (token != -2) {
acc461c7
WD
267 /* Add the data in the current block to the compressor's
268 * history and hash table. */
01f439ec
WD
269 do {
270 /* Break up long sections in the same way that
271 * see_deflate_token() does. */
272 int32 n1 = toklen > 0xffff ? 0xffff : toklen;
273 toklen -= n1;
274 tx_strm.next_in = (Bytef *)map_ptr(buf, offset, n1);
275 tx_strm.avail_in = n1;
276 tx_strm.next_out = (Bytef *) obuf;
277 tx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
278 r = deflate(&tx_strm, Z_INSERT_ONLY);
279 if (r != Z_OK || tx_strm.avail_in != 0) {
280 rprintf(FERROR, "deflate on token returned %d (%d bytes left)\n",
281 r, tx_strm.avail_in);
282 exit_cleanup(RERR_STREAMIO);
283 }
284 } while (toklen > 0);
861c20b4 285 }
861c20b4
PM
286}
287
288
289/* tells us what the receiver is in the middle of doing */
290static enum { r_init, r_idle, r_running, r_inflating, r_inflated } recv_state;
70d794dc 291
861c20b4
PM
292/* for inflating stuff */
293static z_stream rx_strm;
294static char *cbuf;
295static char *dbuf;
296
297/* for decoding runs of tokens */
7fcbf9e4
WD
298static int32 rx_token;
299static int32 rx_run;
861c20b4
PM
300
301/* Receive a deflated token and inflate it */
7fcbf9e4 302static int32 recv_deflated_token(int f, char **data)
861c20b4 303{
5914bf15 304 static int init_done;
acc461c7
WD
305 static int32 saved_flag;
306 int32 n, flag;
307 int r;
5914bf15
PM
308
309 for (;;) {
310 switch (recv_state) {
311 case r_init:
312 if (!init_done) {
313 rx_strm.next_out = NULL;
314 rx_strm.zalloc = NULL;
315 rx_strm.zfree = NULL;
316 if (inflateInit2(&rx_strm, -15) != Z_OK) {
317 rprintf(FERROR, "inflate init failed\n");
65417579 318 exit_cleanup(RERR_STREAMIO);
5914bf15 319 }
58cadc86
WD
320 if (!(cbuf = new_array(char, MAX_DATA_COUNT))
321 || !(dbuf = new_array(char, AVAIL_OUT_SIZE(CHUNK_SIZE))))
5914bf15
PM
322 out_of_memory("recv_deflated_token");
323 init_done = 1;
324 } else {
325 inflateReset(&rx_strm);
326 }
b8d4524b 327 recv_state = r_idle;
5914bf15
PM
328 rx_token = 0;
329 break;
330
331 case r_idle:
332 case r_inflated:
333 if (saved_flag) {
334 flag = saved_flag & 0xff;
335 saved_flag = 0;
336 } else
337 flag = read_byte(f);
338 if ((flag & 0xC0) == DEFLATED_DATA) {
339 n = ((flag & 0x3f) << 8) + read_byte(f);
340 read_buf(f, cbuf, n);
341 rx_strm.next_in = (Bytef *)cbuf;
342 rx_strm.avail_in = n;
343 recv_state = r_inflating;
344 break;
345 }
346 if (recv_state == r_inflated) {
347 /* check previous inflated stuff ended correctly */
348 rx_strm.avail_in = 0;
349 rx_strm.next_out = (Bytef *)dbuf;
1dbb94ca 350 rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
5914bf15 351 r = inflate(&rx_strm, Z_SYNC_FLUSH);
1dbb94ca 352 n = AVAIL_OUT_SIZE(CHUNK_SIZE) - rx_strm.avail_out;
5914bf15
PM
353 /*
354 * Z_BUF_ERROR just means no progress was
355 * made, i.e. the decompressor didn't have
356 * any pending output for us.
357 */
358 if (r != Z_OK && r != Z_BUF_ERROR) {
359 rprintf(FERROR, "inflate flush returned %d (%d bytes)\n",
360 r, n);
65417579 361 exit_cleanup(RERR_STREAMIO);
5914bf15
PM
362 }
363 if (n != 0 && r != Z_BUF_ERROR) {
364 /* have to return some more data and
365 save the flag for later. */
366 saved_flag = flag + 0x10000;
367 *data = dbuf;
368 return n;
369 }
370 /*
371 * At this point the decompressor should
372 * be expecting to see the 0, 0, ff, ff bytes.
373 */
374 if (!inflateSyncPoint(&rx_strm)) {
375 rprintf(FERROR, "decompressor lost sync!\n");
65417579 376 exit_cleanup(RERR_STREAMIO);
5914bf15
PM
377 }
378 rx_strm.avail_in = 4;
379 rx_strm.next_in = (Bytef *)cbuf;
380 cbuf[0] = cbuf[1] = 0;
381 cbuf[2] = cbuf[3] = 0xff;
382 inflate(&rx_strm, Z_SYNC_FLUSH);
383 recv_state = r_idle;
384 }
385 if (flag == END_FLAG) {
386 /* that's all folks */
387 recv_state = r_init;
388 return 0;
389 }
390
391 /* here we have a token of some kind */
392 if (flag & TOKEN_REL) {
393 rx_token += flag & 0x3f;
394 flag >>= 6;
395 } else
396 rx_token = read_int(f);
397 if (flag & 1) {
398 rx_run = read_byte(f);
399 rx_run += read_byte(f) << 8;
400 recv_state = r_running;
401 }
402 return -1 - rx_token;
403
404 case r_inflating:
405 rx_strm.next_out = (Bytef *)dbuf;
1dbb94ca 406 rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
5914bf15 407 r = inflate(&rx_strm, Z_NO_FLUSH);
1dbb94ca 408 n = AVAIL_OUT_SIZE(CHUNK_SIZE) - rx_strm.avail_out;
5914bf15
PM
409 if (r != Z_OK) {
410 rprintf(FERROR, "inflate returned %d (%d bytes)\n", r, n);
65417579 411 exit_cleanup(RERR_STREAMIO);
5914bf15
PM
412 }
413 if (rx_strm.avail_in == 0)
414 recv_state = r_inflated;
415 if (n != 0) {
416 *data = dbuf;
417 return n;
418 }
419 break;
420
421 case r_running:
422 ++rx_token;
423 if (--rx_run == 0)
424 recv_state = r_idle;
425 return -1 - rx_token;
b8d4524b 426 }
861c20b4 427 }
861c20b4
PM
428}
429
430/*
431 * put the data corresponding to a token that we've just returned
432 * from recv_deflated_token into the decompressor's history buffer.
433 */
7fcbf9e4 434static void see_deflate_token(char *buf, int32 len)
861c20b4 435{
acc461c7
WD
436 int r;
437 int32 blklen;
5914bf15
PM
438 unsigned char hdr[5];
439
440 rx_strm.avail_in = 0;
441 blklen = 0;
442 hdr[0] = 0;
443 do {
444 if (rx_strm.avail_in == 0 && len != 0) {
445 if (blklen == 0) {
446 /* Give it a fake stored-block header. */
447 rx_strm.next_in = (Bytef *)hdr;
448 rx_strm.avail_in = 5;
449 blklen = len;
450 if (blklen > 0xffff)
451 blklen = 0xffff;
452 hdr[1] = blklen;
453 hdr[2] = blklen >> 8;
454 hdr[3] = ~hdr[1];
455 hdr[4] = ~hdr[2];
456 } else {
457 rx_strm.next_in = (Bytef *)buf;
458 rx_strm.avail_in = blklen;
459 len -= blklen;
460 blklen = 0;
461 }
462 }
463 rx_strm.next_out = (Bytef *)dbuf;
1dbb94ca 464 rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
5914bf15
PM
465 r = inflate(&rx_strm, Z_SYNC_FLUSH);
466 if (r != Z_OK) {
467 rprintf(FERROR, "inflate (token) returned %d\n", r);
65417579 468 exit_cleanup(RERR_STREAMIO);
5914bf15
PM
469 }
470 } while (len || rx_strm.avail_out == 0);
861c20b4 471}
70d794dc 472
79f671cc
MP
473/**
474 * Transmit a verbatim buffer of length @p n followed by a token.
d67c8bdf 475 * If token == -1 then we have reached EOF
70d794dc 476 * If n == 0 then don't send a buffer
70d794dc 477 */
acc461c7 478void send_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
7fcbf9e4 479 int32 n, int32 toklen)
70d794dc 480{
7fcbf9e4
WD
481 if (!do_compression)
482 simple_send_token(f, token, buf, offset, n);
483 else
5914bf15 484 send_deflated_token(f, token, buf, offset, n, toklen);
70d794dc
AT
485}
486
487
488/*
489 * receive a token or buffer from the other end. If the reurn value is >0 then
490 * it is a data buffer of that length, and *data will point at the data.
491 * if the return value is -i then it represents token i-1
492 * if the return value is 0 then the end has been reached
493 */
7fcbf9e4 494int32 recv_token(int f, char **data)
70d794dc 495{
5914bf15
PM
496 int tok;
497
498 if (!do_compression) {
499 tok = simple_recv_token(f,data);
500 } else {
501 tok = recv_deflated_token(f, data);
502 }
503 return tok;
861c20b4
PM
504}
505
506/*
507 * look at the data corresponding to a token, if necessary
508 */
7fcbf9e4 509void see_token(char *data, int32 toklen)
861c20b4 510{
5914bf15
PM
511 if (do_compression)
512 see_deflate_token(data, toklen);
70d794dc 513}