00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "rsync.h"
00021 #include "zlib/zlib.h"
00022
00023 extern int do_compression;
00024 extern int module_id;
00025 extern int def_compress_level;
00026
00027 static int compression_level, per_file_default_level;
00028
00029
00030 void set_compression(char *fname)
00031 {
00032 static char *match_list;
00033 char *s;
00034
00035 if (!do_compression)
00036 return;
00037
00038 if (!match_list) {
00039 char *t, *f = lp_dont_compress(module_id);
00040 int len = strlen(f);
00041 if (!(match_list = t = new_array(char, len + 2)))
00042 out_of_memory("set_compression");
00043 while (*f) {
00044 if (*f == ' ') {
00045 f++;
00046 continue;
00047 }
00048 do {
00049 if (isupper(*(unsigned char *)f))
00050 *t++ = tolower(*(unsigned char *)f);
00051 else
00052 *t++ = *f;
00053 } while (*++f != ' ' && *f);
00054 *t++ = '\0';
00055 }
00056
00057 if (t - match_list == 2 && match_list[0] == '*') {
00058 t = match_list;
00059 per_file_default_level = 0;
00060 } else
00061 per_file_default_level = def_compress_level;
00062 *t++ = '\0';
00063 }
00064
00065 compression_level = per_file_default_level;
00066
00067 if (!*match_list)
00068 return;
00069
00070 if ((s = strrchr(fname, '/')) != NULL)
00071 fname = s + 1;
00072
00073 for (s = match_list; *s; s += strlen(s) + 1) {
00074 if (iwildmatch(s, fname)) {
00075 compression_level = 0;
00076 break;
00077 }
00078 }
00079 }
00080
00081
00082 static int32 simple_recv_token(int f, char **data)
00083 {
00084 static int32 residue;
00085 static char *buf;
00086 int32 n;
00087
00088 if (!buf) {
00089 buf = new_array(char, CHUNK_SIZE);
00090 if (!buf)
00091 out_of_memory("simple_recv_token");
00092 }
00093
00094 if (residue == 0) {
00095 int32 i = read_int(f);
00096 if (i <= 0)
00097 return i;
00098 residue = i;
00099 }
00100
00101 *data = buf;
00102 n = MIN(CHUNK_SIZE,residue);
00103 residue -= n;
00104 read_buf(f,buf,n);
00105 return n;
00106 }
00107
00108
00109
00110 static void simple_send_token(int f, int32 token, struct map_struct *buf,
00111 OFF_T offset, int32 n)
00112 {
00113 if (n > 0) {
00114 int32 len = 0;
00115 while (len < n) {
00116 int32 n1 = MIN(CHUNK_SIZE, n-len);
00117 write_int(f, n1);
00118 write_buf(f, map_ptr(buf, offset+len, n1), n1);
00119 len += n1;
00120 }
00121 }
00122
00123 if (token != -2)
00124 write_int(f, -(token+1));
00125 }
00126
00127
00128
00129 #define END_FLAG 0
00130 #define TOKEN_LONG 0x20
00131 #define TOKENRUN_LONG 0x21
00132 #define DEFLATED_DATA 0x40
00133 #define TOKEN_REL 0x80
00134 #define TOKENRUN_REL 0xc0
00135
00136 #define MAX_DATA_COUNT 16383
00137
00138
00139
00140
00141
00142 #define AVAIL_OUT_SIZE(avail_in_size) ((avail_in_size)*1001/1000+16)
00143
00144
00145 static int32 last_token = -1;
00146 static int32 run_start;
00147 static int32 last_run_end;
00148
00149
00150 static z_stream tx_strm;
00151
00152
00153 static char *obuf;
00154
00155
00156
00157 #if MAX_DATA_COUNT+2 > AVAIL_OUT_SIZE(CHUNK_SIZE)
00158 #define OBUF_SIZE (MAX_DATA_COUNT+2)
00159 #else
00160 #define OBUF_SIZE AVAIL_OUT_SIZE(CHUNK_SIZE)
00161 #endif
00162
00163
00164 static void
00165 send_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
00166 int32 nb, int32 toklen)
00167 {
00168 int32 n, r;
00169 static int init_done, flush_pending;
00170
00171 if (last_token == -1) {
00172
00173 if (!init_done) {
00174 tx_strm.next_in = NULL;
00175 tx_strm.zalloc = NULL;
00176 tx_strm.zfree = NULL;
00177 if (deflateInit2(&tx_strm, compression_level,
00178 Z_DEFLATED, -15, 8,
00179 Z_DEFAULT_STRATEGY) != Z_OK) {
00180 rprintf(FERROR, "compression init failed\n");
00181 exit_cleanup(RERR_STREAMIO);
00182 }
00183 if ((obuf = new_array(char, OBUF_SIZE)) == NULL)
00184 out_of_memory("send_deflated_token");
00185 init_done = 1;
00186 } else
00187 deflateReset(&tx_strm);
00188 last_run_end = 0;
00189 run_start = token;
00190 flush_pending = 0;
00191
00192 } else if (last_token == -2) {
00193 run_start = token;
00194
00195 } else if (nb != 0 || token != last_token + 1
00196 || token >= run_start + 65536) {
00197
00198 r = run_start - last_run_end;
00199 n = last_token - run_start;
00200 if (r >= 0 && r <= 63) {
00201 write_byte(f, (n==0? TOKEN_REL: TOKENRUN_REL) + r);
00202 } else {
00203 write_byte(f, (n==0? TOKEN_LONG: TOKENRUN_LONG));
00204 write_int(f, run_start);
00205 }
00206 if (n != 0) {
00207 write_byte(f, n);
00208 write_byte(f, n >> 8);
00209 }
00210 last_run_end = last_token;
00211 run_start = token;
00212 }
00213
00214 last_token = token;
00215
00216 if (nb != 0 || flush_pending) {
00217
00218 int flush = Z_NO_FLUSH;
00219 tx_strm.avail_in = 0;
00220 tx_strm.avail_out = 0;
00221 do {
00222 if (tx_strm.avail_in == 0 && nb != 0) {
00223
00224 n = MIN(nb, CHUNK_SIZE);
00225 tx_strm.next_in = (Bytef *)
00226 map_ptr(buf, offset, n);
00227 tx_strm.avail_in = n;
00228 nb -= n;
00229 offset += n;
00230 }
00231 if (tx_strm.avail_out == 0) {
00232 tx_strm.next_out = (Bytef *)(obuf + 2);
00233 tx_strm.avail_out = MAX_DATA_COUNT;
00234 if (flush != Z_NO_FLUSH) {
00235
00236
00237
00238
00239
00240 memcpy(tx_strm.next_out,
00241 obuf+MAX_DATA_COUNT-2, 4);
00242 tx_strm.next_out += 4;
00243 tx_strm.avail_out -= 4;
00244 }
00245 }
00246 if (nb == 0 && token != -2)
00247 flush = Z_SYNC_FLUSH;
00248 r = deflate(&tx_strm, flush);
00249 if (r != Z_OK) {
00250 rprintf(FERROR, "deflate returned %d\n", r);
00251 exit_cleanup(RERR_STREAMIO);
00252 }
00253 if (nb == 0 || tx_strm.avail_out == 0) {
00254 n = MAX_DATA_COUNT - tx_strm.avail_out;
00255 if (flush != Z_NO_FLUSH) {
00256
00257
00258
00259
00260
00261 n -= 4;
00262 }
00263 if (n > 0) {
00264 obuf[0] = DEFLATED_DATA + (n >> 8);
00265 obuf[1] = n;
00266 write_buf(f, obuf, n+2);
00267 }
00268 }
00269 } while (nb != 0 || tx_strm.avail_out == 0);
00270 flush_pending = token == -2;
00271 }
00272
00273 if (token == -1) {
00274
00275 write_byte(f, END_FLAG);
00276 } else if (token != -2) {
00277
00278
00279 do {
00280
00281
00282 int32 n1 = toklen > 0xffff ? 0xffff : toklen;
00283 toklen -= n1;
00284 tx_strm.next_in = (Bytef *)map_ptr(buf, offset, n1);
00285 tx_strm.avail_in = n1;
00286 tx_strm.next_out = (Bytef *) obuf;
00287 tx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
00288 r = deflate(&tx_strm, Z_INSERT_ONLY);
00289 if (r != Z_OK || tx_strm.avail_in != 0) {
00290 rprintf(FERROR, "deflate on token returned %d (%d bytes left)\n",
00291 r, tx_strm.avail_in);
00292 exit_cleanup(RERR_STREAMIO);
00293 }
00294 } while (toklen > 0);
00295 }
00296 }
00297
00298
00299
00300 static enum { r_init, r_idle, r_running, r_inflating, r_inflated } recv_state;
00301
00302
00303 static z_stream rx_strm;
00304 static char *cbuf;
00305 static char *dbuf;
00306
00307
00308 static int32 rx_token;
00309 static int32 rx_run;
00310
00311
00312 static int32 recv_deflated_token(int f, char **data)
00313 {
00314 static int init_done;
00315 static int32 saved_flag;
00316 int32 n, flag;
00317 int r;
00318
00319 for (;;) {
00320 switch (recv_state) {
00321 case r_init:
00322 if (!init_done) {
00323 rx_strm.next_out = NULL;
00324 rx_strm.zalloc = NULL;
00325 rx_strm.zfree = NULL;
00326 if (inflateInit2(&rx_strm, -15) != Z_OK) {
00327 rprintf(FERROR, "inflate init failed\n");
00328 exit_cleanup(RERR_STREAMIO);
00329 }
00330 if (!(cbuf = new_array(char, MAX_DATA_COUNT))
00331 || !(dbuf = new_array(char, AVAIL_OUT_SIZE(CHUNK_SIZE))))
00332 out_of_memory("recv_deflated_token");
00333 init_done = 1;
00334 } else {
00335 inflateReset(&rx_strm);
00336 }
00337 recv_state = r_idle;
00338 rx_token = 0;
00339 break;
00340
00341 case r_idle:
00342 case r_inflated:
00343 if (saved_flag) {
00344 flag = saved_flag & 0xff;
00345 saved_flag = 0;
00346 } else
00347 flag = read_byte(f);
00348 if ((flag & 0xC0) == DEFLATED_DATA) {
00349 n = ((flag & 0x3f) << 8) + read_byte(f);
00350 read_buf(f, cbuf, n);
00351 rx_strm.next_in = (Bytef *)cbuf;
00352 rx_strm.avail_in = n;
00353 recv_state = r_inflating;
00354 break;
00355 }
00356 if (recv_state == r_inflated) {
00357
00358 rx_strm.avail_in = 0;
00359 rx_strm.next_out = (Bytef *)dbuf;
00360 rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
00361 r = inflate(&rx_strm, Z_SYNC_FLUSH);
00362 n = AVAIL_OUT_SIZE(CHUNK_SIZE) - rx_strm.avail_out;
00363
00364
00365
00366
00367
00368 if (r != Z_OK && r != Z_BUF_ERROR) {
00369 rprintf(FERROR, "inflate flush returned %d (%d bytes)\n",
00370 r, n);
00371 exit_cleanup(RERR_STREAMIO);
00372 }
00373 if (n != 0 && r != Z_BUF_ERROR) {
00374
00375
00376 saved_flag = flag + 0x10000;
00377 *data = dbuf;
00378 return n;
00379 }
00380
00381
00382
00383
00384 if (!inflateSyncPoint(&rx_strm)) {
00385 rprintf(FERROR, "decompressor lost sync!\n");
00386 exit_cleanup(RERR_STREAMIO);
00387 }
00388 rx_strm.avail_in = 4;
00389 rx_strm.next_in = (Bytef *)cbuf;
00390 cbuf[0] = cbuf[1] = 0;
00391 cbuf[2] = cbuf[3] = 0xff;
00392 inflate(&rx_strm, Z_SYNC_FLUSH);
00393 recv_state = r_idle;
00394 }
00395 if (flag == END_FLAG) {
00396
00397 recv_state = r_init;
00398 return 0;
00399 }
00400
00401
00402 if (flag & TOKEN_REL) {
00403 rx_token += flag & 0x3f;
00404 flag >>= 6;
00405 } else
00406 rx_token = read_int(f);
00407 if (flag & 1) {
00408 rx_run = read_byte(f);
00409 rx_run += read_byte(f) << 8;
00410 recv_state = r_running;
00411 }
00412 return -1 - rx_token;
00413
00414 case r_inflating:
00415 rx_strm.next_out = (Bytef *)dbuf;
00416 rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
00417 r = inflate(&rx_strm, Z_NO_FLUSH);
00418 n = AVAIL_OUT_SIZE(CHUNK_SIZE) - rx_strm.avail_out;
00419 if (r != Z_OK) {
00420 rprintf(FERROR, "inflate returned %d (%d bytes)\n", r, n);
00421 exit_cleanup(RERR_STREAMIO);
00422 }
00423 if (rx_strm.avail_in == 0)
00424 recv_state = r_inflated;
00425 if (n != 0) {
00426 *data = dbuf;
00427 return n;
00428 }
00429 break;
00430
00431 case r_running:
00432 ++rx_token;
00433 if (--rx_run == 0)
00434 recv_state = r_idle;
00435 return -1 - rx_token;
00436 }
00437 }
00438 }
00439
00440
00441
00442
00443
00444 static void see_deflate_token(char *buf, int32 len)
00445 {
00446 int r;
00447 int32 blklen;
00448 unsigned char hdr[5];
00449
00450 rx_strm.avail_in = 0;
00451 blklen = 0;
00452 hdr[0] = 0;
00453 do {
00454 if (rx_strm.avail_in == 0 && len != 0) {
00455 if (blklen == 0) {
00456
00457 rx_strm.next_in = (Bytef *)hdr;
00458 rx_strm.avail_in = 5;
00459 blklen = len;
00460 if (blklen > 0xffff)
00461 blklen = 0xffff;
00462 hdr[1] = blklen;
00463 hdr[2] = blklen >> 8;
00464 hdr[3] = ~hdr[1];
00465 hdr[4] = ~hdr[2];
00466 } else {
00467 rx_strm.next_in = (Bytef *)buf;
00468 rx_strm.avail_in = blklen;
00469 len -= blklen;
00470 blklen = 0;
00471 }
00472 }
00473 rx_strm.next_out = (Bytef *)dbuf;
00474 rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
00475 r = inflate(&rx_strm, Z_SYNC_FLUSH);
00476 if (r != Z_OK) {
00477 rprintf(FERROR, "inflate (token) returned %d\n", r);
00478 exit_cleanup(RERR_STREAMIO);
00479 }
00480 } while (len || rx_strm.avail_out == 0);
00481 }
00482
00483
00484
00485
00486
00487
00488 void send_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
00489 int32 n, int32 toklen)
00490 {
00491 if (!do_compression)
00492 simple_send_token(f, token, buf, offset, n);
00493 else
00494 send_deflated_token(f, token, buf, offset, n, toklen);
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504 int32 recv_token(int f, char **data)
00505 {
00506 int tok;
00507
00508 if (!do_compression) {
00509 tok = simple_recv_token(f,data);
00510 } else {
00511 tok = recv_deflated_token(f, data);
00512 }
00513 return tok;
00514 }
00515
00516
00517
00518
00519 void see_token(char *data, int32 toklen)
00520 {
00521 if (do_compression)
00522 see_deflate_token(data, toklen);
00523 }