File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / rsync / token.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Nov 1 09:54:32 2016 UTC (7 years, 7 months ago) by misho
Branches: rsync, MAIN
CVS tags: v3_1_2p5, HEAD
rsync 3.1.2

    1: /*
    2:  * Routines used by the file-transfer code.
    3:  *
    4:  * Copyright (C) 1996 Andrew Tridgell
    5:  * Copyright (C) 1996 Paul Mackerras
    6:  * Copyright (C) 2003-2015 Wayne Davison
    7:  *
    8:  * This program is free software; you can redistribute it and/or modify
    9:  * it under the terms of the GNU General Public License as published by
   10:  * the Free Software Foundation; either version 3 of the License, or
   11:  * (at your option) any later version.
   12:  *
   13:  * This program is distributed in the hope that it will be useful,
   14:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16:  * GNU General Public License for more details.
   17:  *
   18:  * You should have received a copy of the GNU General Public License along
   19:  * with this program; if not, visit the http://fsf.org website.
   20:  */
   21: 
   22: #include "rsync.h"
   23: #include "itypes.h"
   24: #include <zlib.h>
   25: 
   26: extern int do_compression;
   27: extern int protocol_version;
   28: extern int module_id;
   29: extern int def_compress_level;
   30: extern char *skip_compress;
   31: 
   32: static int compression_level, per_file_default_level;
   33: 
   34: struct suffix_tree {
   35: 	struct suffix_tree *sibling;
   36: 	struct suffix_tree *child;
   37: 	char letter, word_end;
   38: };
   39: 
   40: static char *match_list;
   41: static struct suffix_tree *suftree;
   42: 
   43: static void add_suffix(struct suffix_tree **prior, char ltr, const char *str)
   44: {
   45: 	struct suffix_tree *node, *newnode;
   46: 
   47: 	if (ltr == '[') {
   48: 		const char *after = strchr(str, ']');
   49: 		/* Treat "[foo" and "[]" as having a literal '['. */
   50: 		if (after && after++ != str+1) {
   51: 			while ((ltr = *str++) != ']')
   52: 				add_suffix(prior, ltr, after);
   53: 			return;
   54: 		}
   55: 	}
   56: 
   57: 	for (node = *prior; node; prior = &node->sibling, node = node->sibling) {
   58: 		if (node->letter == ltr) {
   59: 			if (*str)
   60: 				add_suffix(&node->child, *str, str+1);
   61: 			else
   62: 				node->word_end = 1;
   63: 			return;
   64: 		}
   65: 		if (node->letter > ltr)
   66: 			break;
   67: 	}
   68: 	if (!(newnode = new(struct suffix_tree)))
   69: 		out_of_memory("add_suffix");
   70: 	newnode->sibling = node;
   71: 	newnode->child = NULL;
   72: 	newnode->letter = ltr;
   73: 	*prior = newnode;
   74: 	if (*str) {
   75: 		add_suffix(&newnode->child, *str, str+1);
   76: 		newnode->word_end = 0;
   77: 	} else
   78: 		newnode->word_end = 1;
   79: }
   80: 
   81: static void add_nocompress_suffixes(const char *str)
   82: {
   83: 	char *buf, *t;
   84: 	const char *f = str;
   85: 
   86: 	if (!(buf = new_array(char, strlen(f) + 1)))
   87: 		out_of_memory("add_nocompress_suffixes");
   88: 
   89: 	while (*f) {
   90: 		if (*f == '/') {
   91: 			f++;
   92: 			continue;
   93: 		}
   94: 
   95: 		t = buf;
   96: 		do {
   97: 			if (isUpper(f))
   98: 				*t++ = toLower(f);
   99: 			else
  100: 				*t++ = *f;
  101: 		} while (*++f != '/' && *f);
  102: 		*t++ = '\0';
  103: 
  104: 		add_suffix(&suftree, *buf, buf+1);
  105: 	}
  106: 
  107: 	free(buf);
  108: }
  109: 
  110: static void init_set_compression(void)
  111: {
  112: 	const char *f;
  113: 	char *t, *start;
  114: 
  115: 	if (skip_compress)
  116: 		add_nocompress_suffixes(skip_compress);
  117: 
  118: 	/* A non-daemon transfer skips the default suffix list if the
  119: 	 * user specified --skip-compress. */
  120: 	if (skip_compress && module_id < 0)
  121: 		f = "";
  122: 	else
  123: 		f = lp_dont_compress(module_id);
  124: 
  125: 	if (!(match_list = t = new_array(char, strlen(f) + 2)))
  126: 		out_of_memory("set_compression");
  127: 
  128: 	per_file_default_level = def_compress_level;
  129: 
  130: 	while (*f) {
  131: 		if (*f == ' ') {
  132: 			f++;
  133: 			continue;
  134: 		}
  135: 
  136: 		start = t;
  137: 		do {
  138: 			if (isUpper(f))
  139: 				*t++ = toLower(f);
  140: 			else
  141: 				*t++ = *f;
  142: 		} while (*++f != ' ' && *f);
  143: 		*t++ = '\0';
  144: 
  145: 		if (t - start == 1+1 && *start == '*') {
  146: 			/* Optimize a match-string of "*". */
  147: 			*match_list = '\0';
  148: 			suftree = NULL;
  149: 			per_file_default_level = 0;
  150: 			break;
  151: 		}
  152: 
  153: 		/* Move *.foo items into the stuffix tree. */
  154: 		if (*start == '*' && start[1] == '.' && start[2]
  155: 		 && !strpbrk(start+2, ".?*")) {
  156: 			add_suffix(&suftree, start[2], start+3);
  157: 			t = start;
  158: 		}
  159: 	}
  160: 	*t++ = '\0';
  161: }
  162: 
  163: /* determine the compression level based on a wildcard filename list */
  164: void set_compression(const char *fname)
  165: {
  166: 	const struct suffix_tree *node;
  167: 	const char *s;
  168: 	char ltr;
  169: 
  170: 	if (!do_compression)
  171: 		return;
  172: 
  173: 	if (!match_list)
  174: 		init_set_compression();
  175: 
  176: 	compression_level = per_file_default_level;
  177: 
  178: 	if (!*match_list && !suftree)
  179: 		return;
  180: 
  181: 	if ((s = strrchr(fname, '/')) != NULL)
  182: 		fname = s + 1;
  183: 
  184: 	for (s = match_list; *s; s += strlen(s) + 1) {
  185: 		if (iwildmatch(s, fname)) {
  186: 			compression_level = 0;
  187: 			return;
  188: 		}
  189: 	}
  190: 
  191: 	if (!(node = suftree) || !(s = strrchr(fname, '.'))
  192: 	 || s == fname || !(ltr = *++s))
  193: 		return;
  194: 
  195: 	while (1) {
  196: 		if (isUpper(&ltr))
  197: 			ltr = toLower(&ltr);
  198: 		while (node->letter != ltr) {
  199: 			if (node->letter > ltr)
  200: 				return;
  201: 			if (!(node = node->sibling))
  202: 				return;
  203: 		}
  204: 		if ((ltr = *++s) == '\0') {
  205: 			if (node->word_end)
  206: 				compression_level = 0;
  207: 			return;
  208: 		}
  209: 		if (!(node = node->child))
  210: 			return;
  211: 	}
  212: }
  213: 
  214: /* non-compressing recv token */
  215: static int32 simple_recv_token(int f, char **data)
  216: {
  217: 	static int32 residue;
  218: 	static char *buf;
  219: 	int32 n;
  220: 
  221: 	if (!buf) {
  222: 		buf = new_array(char, CHUNK_SIZE);
  223: 		if (!buf)
  224: 			out_of_memory("simple_recv_token");
  225: 	}
  226: 
  227: 	if (residue == 0) {
  228: 		int32 i = read_int(f);
  229: 		if (i <= 0)
  230: 			return i;
  231: 		residue = i;
  232: 	}
  233: 
  234: 	*data = buf;
  235: 	n = MIN(CHUNK_SIZE,residue);
  236: 	residue -= n;
  237: 	read_buf(f,buf,n);
  238: 	return n;
  239: }
  240: 
  241: /* non-compressing send token */
  242: static void simple_send_token(int f, int32 token, struct map_struct *buf,
  243: 			      OFF_T offset, int32 n)
  244: {
  245: 	if (n > 0) {
  246: 		int32 len = 0;
  247: 		while (len < n) {
  248: 			int32 n1 = MIN(CHUNK_SIZE, n-len);
  249: 			write_int(f, n1);
  250: 			write_buf(f, map_ptr(buf, offset+len, n1), n1);
  251: 			len += n1;
  252: 		}
  253: 	}
  254: 	/* a -2 token means to send data only and no token */
  255: 	if (token != -2)
  256: 		write_int(f, -(token+1));
  257: }
  258: 
  259: /* Flag bytes in compressed stream are encoded as follows: */
  260: #define END_FLAG	0	/* that's all folks */
  261: #define TOKEN_LONG	0x20	/* followed by 32-bit token number */
  262: #define TOKENRUN_LONG	0x21	/* ditto with 16-bit run count */
  263: #define DEFLATED_DATA	0x40	/* + 6-bit high len, then low len byte */
  264: #define TOKEN_REL	0x80	/* + 6-bit relative token number */
  265: #define TOKENRUN_REL	0xc0	/* ditto with 16-bit run count */
  266: 
  267: #define MAX_DATA_COUNT	16383	/* fit 14 bit count into 2 bytes with flags */
  268: 
  269: /* zlib.h says that if we want to be able to compress something in a single
  270:  * call, avail_out must be at least 0.1% larger than avail_in plus 12 bytes.
  271:  * We'll add in 0.1%+16, just to be safe (and we'll avoid floating point,
  272:  * to ensure that this is a compile-time value). */
  273: #define AVAIL_OUT_SIZE(avail_in_size) ((avail_in_size)*1001/1000+16)
  274: 
  275: /* For coding runs of tokens */
  276: static int32 last_token = -1;
  277: static int32 run_start;
  278: static int32 last_run_end;
  279: 
  280: /* Deflation state */
  281: static z_stream tx_strm;
  282: 
  283: /* Output buffer */
  284: static char *obuf;
  285: 
  286: /* We want obuf to be able to hold both MAX_DATA_COUNT+2 bytes as well as
  287:  * AVAIL_OUT_SIZE(CHUNK_SIZE) bytes, so make sure that it's large enough. */
  288: #if MAX_DATA_COUNT+2 > AVAIL_OUT_SIZE(CHUNK_SIZE)
  289: #define OBUF_SIZE	(MAX_DATA_COUNT+2)
  290: #else
  291: #define OBUF_SIZE	AVAIL_OUT_SIZE(CHUNK_SIZE)
  292: #endif
  293: 
  294: /* Send a deflated token */
  295: static void
  296: send_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
  297: 		    int32 nb, int32 toklen)
  298: {
  299: 	int32 n, r;
  300: 	static int init_done, flush_pending;
  301: 
  302: 	if (last_token == -1) {
  303: 		/* initialization */
  304: 		if (!init_done) {
  305: 			tx_strm.next_in = NULL;
  306: 			tx_strm.zalloc = NULL;
  307: 			tx_strm.zfree = NULL;
  308: 			if (deflateInit2(&tx_strm, compression_level,
  309: 					 Z_DEFLATED, -15, 8,
  310: 					 Z_DEFAULT_STRATEGY) != Z_OK) {
  311: 				rprintf(FERROR, "compression init failed\n");
  312: 				exit_cleanup(RERR_PROTOCOL);
  313: 			}
  314: 			if ((obuf = new_array(char, OBUF_SIZE)) == NULL)
  315: 				out_of_memory("send_deflated_token");
  316: 			init_done = 1;
  317: 		} else
  318: 			deflateReset(&tx_strm);
  319: 		last_run_end = 0;
  320: 		run_start = token;
  321: 		flush_pending = 0;
  322: 	} else if (last_token == -2) {
  323: 		run_start = token;
  324: 	} else if (nb != 0 || token != last_token + 1
  325: 		   || token >= run_start + 65536) {
  326: 		/* output previous run */
  327: 		r = run_start - last_run_end;
  328: 		n = last_token - run_start;
  329: 		if (r >= 0 && r <= 63) {
  330: 			write_byte(f, (n==0? TOKEN_REL: TOKENRUN_REL) + r);
  331: 		} else {
  332: 			write_byte(f, (n==0? TOKEN_LONG: TOKENRUN_LONG));
  333: 			write_int(f, run_start);
  334: 		}
  335: 		if (n != 0) {
  336: 			write_byte(f, n);
  337: 			write_byte(f, n >> 8);
  338: 		}
  339: 		last_run_end = last_token;
  340: 		run_start = token;
  341: 	}
  342: 
  343: 	last_token = token;
  344: 
  345: 	if (nb != 0 || flush_pending) {
  346: 		/* deflate the data starting at offset */
  347: 		int flush = Z_NO_FLUSH;
  348: 		tx_strm.avail_in = 0;
  349: 		tx_strm.avail_out = 0;
  350: 		do {
  351: 			if (tx_strm.avail_in == 0 && nb != 0) {
  352: 				/* give it some more input */
  353: 				n = MIN(nb, CHUNK_SIZE);
  354: 				tx_strm.next_in = (Bytef *)
  355: 					map_ptr(buf, offset, n);
  356: 				tx_strm.avail_in = n;
  357: 				nb -= n;
  358: 				offset += n;
  359: 			}
  360: 			if (tx_strm.avail_out == 0) {
  361: 				tx_strm.next_out = (Bytef *)(obuf + 2);
  362: 				tx_strm.avail_out = MAX_DATA_COUNT;
  363: 				if (flush != Z_NO_FLUSH) {
  364: 					/*
  365: 					 * We left the last 4 bytes in the
  366: 					 * buffer, in case they are the
  367: 					 * last 4.  Move them to the front.
  368: 					 */
  369: 					memcpy(tx_strm.next_out,
  370: 					       obuf+MAX_DATA_COUNT-2, 4);
  371: 					tx_strm.next_out += 4;
  372: 					tx_strm.avail_out -= 4;
  373: 				}
  374: 			}
  375: 			if (nb == 0 && token != -2)
  376: 				flush = Z_SYNC_FLUSH;
  377: 			r = deflate(&tx_strm, flush);
  378: 			if (r != Z_OK) {
  379: 				rprintf(FERROR, "deflate returned %d\n", r);
  380: 				exit_cleanup(RERR_STREAMIO);
  381: 			}
  382: 			if (nb == 0 || tx_strm.avail_out == 0) {
  383: 				n = MAX_DATA_COUNT - tx_strm.avail_out;
  384: 				if (flush != Z_NO_FLUSH) {
  385: 					/*
  386: 					 * We have to trim off the last 4
  387: 					 * bytes of output when flushing
  388: 					 * (they are just 0, 0, ff, ff).
  389: 					 */
  390: 					n -= 4;
  391: 				}
  392: 				if (n > 0) {
  393: 					obuf[0] = DEFLATED_DATA + (n >> 8);
  394: 					obuf[1] = n;
  395: 					write_buf(f, obuf, n+2);
  396: 				}
  397: 			}
  398: 		} while (nb != 0 || tx_strm.avail_out == 0);
  399: 		flush_pending = token == -2;
  400: 	}
  401: 
  402: 	if (token == -1) {
  403: 		/* end of file - clean up */
  404: 		write_byte(f, END_FLAG);
  405: 	} else if (token != -2 && do_compression == 1) {
  406: 		/* Add the data in the current block to the compressor's
  407: 		 * history and hash table. */
  408: #ifndef EXTERNAL_ZLIB
  409: 		do {
  410: 			/* Break up long sections in the same way that
  411: 			 * see_deflate_token() does. */
  412: 			int32 n1 = toklen > 0xffff ? 0xffff : toklen;
  413: 			toklen -= n1;
  414: 			tx_strm.next_in = (Bytef *)map_ptr(buf, offset, n1);
  415: 			tx_strm.avail_in = n1;
  416: 			if (protocol_version >= 31) /* Newer protocols avoid a data-duplicating bug */
  417: 				offset += n1;
  418: 			tx_strm.next_out = (Bytef *) obuf;
  419: 			tx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
  420: 			r = deflate(&tx_strm, Z_INSERT_ONLY);
  421: 			if (r != Z_OK || tx_strm.avail_in != 0) {
  422: 				rprintf(FERROR, "deflate on token returned %d (%d bytes left)\n",
  423: 					r, tx_strm.avail_in);
  424: 				exit_cleanup(RERR_STREAMIO);
  425: 			}
  426: 		} while (toklen > 0);
  427: #else
  428: 		toklen++;
  429: 		rprintf(FERROR, "Impossible error in external-zlib code (1).\n");
  430: 		exit_cleanup(RERR_STREAMIO);
  431: #endif
  432: 	}
  433: }
  434: 
  435: /* tells us what the receiver is in the middle of doing */
  436: static enum { r_init, r_idle, r_running, r_inflating, r_inflated } recv_state;
  437: 
  438: /* for inflating stuff */
  439: static z_stream rx_strm;
  440: static char *cbuf;
  441: static char *dbuf;
  442: 
  443: /* for decoding runs of tokens */
  444: static int32 rx_token;
  445: static int32 rx_run;
  446: 
  447: /* Receive a deflated token and inflate it */
  448: static int32 recv_deflated_token(int f, char **data)
  449: {
  450: 	static int init_done;
  451: 	static int32 saved_flag;
  452: 	int32 n, flag;
  453: 	int r;
  454: 
  455: 	for (;;) {
  456: 		switch (recv_state) {
  457: 		case r_init:
  458: 			if (!init_done) {
  459: 				rx_strm.next_out = NULL;
  460: 				rx_strm.zalloc = NULL;
  461: 				rx_strm.zfree = NULL;
  462: 				if (inflateInit2(&rx_strm, -15) != Z_OK) {
  463: 					rprintf(FERROR, "inflate init failed\n");
  464: 					exit_cleanup(RERR_PROTOCOL);
  465: 				}
  466: 				if (!(cbuf = new_array(char, MAX_DATA_COUNT))
  467: 				    || !(dbuf = new_array(char, AVAIL_OUT_SIZE(CHUNK_SIZE))))
  468: 					out_of_memory("recv_deflated_token");
  469: 				init_done = 1;
  470: 			} else {
  471: 				inflateReset(&rx_strm);
  472: 			}
  473: 			recv_state = r_idle;
  474: 			rx_token = 0;
  475: 			break;
  476: 
  477: 		case r_idle:
  478: 		case r_inflated:
  479: 			if (saved_flag) {
  480: 				flag = saved_flag & 0xff;
  481: 				saved_flag = 0;
  482: 			} else
  483: 				flag = read_byte(f);
  484: 			if ((flag & 0xC0) == DEFLATED_DATA) {
  485: 				n = ((flag & 0x3f) << 8) + read_byte(f);
  486: 				read_buf(f, cbuf, n);
  487: 				rx_strm.next_in = (Bytef *)cbuf;
  488: 				rx_strm.avail_in = n;
  489: 				recv_state = r_inflating;
  490: 				break;
  491: 			}
  492: 			if (recv_state == r_inflated) {
  493: 				/* check previous inflated stuff ended correctly */
  494: 				rx_strm.avail_in = 0;
  495: 				rx_strm.next_out = (Bytef *)dbuf;
  496: 				rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
  497: 				r = inflate(&rx_strm, Z_SYNC_FLUSH);
  498: 				n = AVAIL_OUT_SIZE(CHUNK_SIZE) - rx_strm.avail_out;
  499: 				/*
  500: 				 * Z_BUF_ERROR just means no progress was
  501: 				 * made, i.e. the decompressor didn't have
  502: 				 * any pending output for us.
  503: 				 */
  504: 				if (r != Z_OK && r != Z_BUF_ERROR) {
  505: 					rprintf(FERROR, "inflate flush returned %d (%d bytes)\n",
  506: 						r, n);
  507: 					exit_cleanup(RERR_STREAMIO);
  508: 				}
  509: 				if (n != 0 && r != Z_BUF_ERROR) {
  510: 					/* have to return some more data and
  511: 					   save the flag for later. */
  512: 					saved_flag = flag + 0x10000;
  513: 					*data = dbuf;
  514: 					return n;
  515: 				}
  516: 				/*
  517: 				 * At this point the decompressor should
  518: 				 * be expecting to see the 0, 0, ff, ff bytes.
  519: 				 */
  520: 				if (!inflateSyncPoint(&rx_strm)) {
  521: 					rprintf(FERROR, "decompressor lost sync!\n");
  522: 					exit_cleanup(RERR_STREAMIO);
  523: 				}
  524: 				rx_strm.avail_in = 4;
  525: 				rx_strm.next_in = (Bytef *)cbuf;
  526: 				cbuf[0] = cbuf[1] = 0;
  527: 				cbuf[2] = cbuf[3] = 0xff;
  528: 				inflate(&rx_strm, Z_SYNC_FLUSH);
  529: 				recv_state = r_idle;
  530: 			}
  531: 			if (flag == END_FLAG) {
  532: 				/* that's all folks */
  533: 				recv_state = r_init;
  534: 				return 0;
  535: 			}
  536: 
  537: 			/* here we have a token of some kind */
  538: 			if (flag & TOKEN_REL) {
  539: 				rx_token += flag & 0x3f;
  540: 				flag >>= 6;
  541: 			} else
  542: 				rx_token = read_int(f);
  543: 			if (flag & 1) {
  544: 				rx_run = read_byte(f);
  545: 				rx_run += read_byte(f) << 8;
  546: 				recv_state = r_running;
  547: 			}
  548: 			return -1 - rx_token;
  549: 
  550: 		case r_inflating:
  551: 			rx_strm.next_out = (Bytef *)dbuf;
  552: 			rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
  553: 			r = inflate(&rx_strm, Z_NO_FLUSH);
  554: 			n = AVAIL_OUT_SIZE(CHUNK_SIZE) - rx_strm.avail_out;
  555: 			if (r != Z_OK) {
  556: 				rprintf(FERROR, "inflate returned %d (%d bytes)\n", r, n);
  557: 				exit_cleanup(RERR_STREAMIO);
  558: 			}
  559: 			if (rx_strm.avail_in == 0)
  560: 				recv_state = r_inflated;
  561: 			if (n != 0) {
  562: 				*data = dbuf;
  563: 				return n;
  564: 			}
  565: 			break;
  566: 
  567: 		case r_running:
  568: 			++rx_token;
  569: 			if (--rx_run == 0)
  570: 				recv_state = r_idle;
  571: 			return -1 - rx_token;
  572: 		}
  573: 	}
  574: }
  575: 
  576: /*
  577:  * put the data corresponding to a token that we've just returned
  578:  * from recv_deflated_token into the decompressor's history buffer.
  579:  */
  580: static void see_deflate_token(char *buf, int32 len)
  581: {
  582: #ifndef EXTERNAL_ZLIB
  583: 	int r;
  584: 	int32 blklen;
  585: 	unsigned char hdr[5];
  586: 
  587: 	rx_strm.avail_in = 0;
  588: 	blklen = 0;
  589: 	hdr[0] = 0;
  590: 	do {
  591: 		if (rx_strm.avail_in == 0 && len != 0) {
  592: 			if (blklen == 0) {
  593: 				/* Give it a fake stored-block header. */
  594: 				rx_strm.next_in = (Bytef *)hdr;
  595: 				rx_strm.avail_in = 5;
  596: 				blklen = len;
  597: 				if (blklen > 0xffff)
  598: 					blklen = 0xffff;
  599: 				hdr[1] = blklen;
  600: 				hdr[2] = blklen >> 8;
  601: 				hdr[3] = ~hdr[1];
  602: 				hdr[4] = ~hdr[2];
  603: 			} else {
  604: 				rx_strm.next_in = (Bytef *)buf;
  605: 				rx_strm.avail_in = blklen;
  606: 				if (protocol_version >= 31) /* Newer protocols avoid a data-duplicating bug */
  607: 					buf += blklen;
  608: 				len -= blklen;
  609: 				blklen = 0;
  610: 			}
  611: 		}
  612: 		rx_strm.next_out = (Bytef *)dbuf;
  613: 		rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
  614: 		r = inflate(&rx_strm, Z_SYNC_FLUSH);
  615: 		if (r != Z_OK && r != Z_BUF_ERROR) {
  616: 			rprintf(FERROR, "inflate (token) returned %d\n", r);
  617: 			exit_cleanup(RERR_STREAMIO);
  618: 		}
  619: 	} while (len || rx_strm.avail_out == 0);
  620: #else
  621: 	buf++; len++;
  622: 	rprintf(FERROR, "Impossible error in external-zlib code (2).\n");
  623: 	exit_cleanup(RERR_STREAMIO);
  624: #endif
  625: }
  626: 
  627: /**
  628:  * Transmit a verbatim buffer of length @p n followed by a token.
  629:  * If token == -1 then we have reached EOF
  630:  * If n == 0 then don't send a buffer
  631:  */
  632: void send_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
  633: 		int32 n, int32 toklen)
  634: {
  635: 	if (!do_compression)
  636: 		simple_send_token(f, token, buf, offset, n);
  637: 	else
  638: 		send_deflated_token(f, token, buf, offset, n, toklen);
  639: }
  640: 
  641: /*
  642:  * receive a token or buffer from the other end. If the reurn value is >0 then
  643:  * it is a data buffer of that length, and *data will point at the data.
  644:  * if the return value is -i then it represents token i-1
  645:  * if the return value is 0 then the end has been reached
  646:  */
  647: int32 recv_token(int f, char **data)
  648: {
  649: 	int tok;
  650: 
  651: 	if (!do_compression) {
  652: 		tok = simple_recv_token(f,data);
  653: 	} else {
  654: 		tok = recv_deflated_token(f, data);
  655: 	}
  656: 	return tok;
  657: }
  658: 
  659: /*
  660:  * look at the data corresponding to a token, if necessary
  661:  */
  662: void see_token(char *data, int32 toklen)
  663: {
  664: 	if (do_compression == 1)
  665: 		see_deflate_token(data, toklen);
  666: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>