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