diff options
Diffstat (limited to 'lib')
68 files changed, 24810 insertions, 0 deletions
diff --git a/lib/libc/crypt/arc4random.c b/lib/libc/crypt/arc4random.c new file mode 100644 index 0000000..1a16bd3 --- /dev/null +++ b/lib/libc/crypt/arc4random.c @@ -0,0 +1,198 @@ +/*	$OpenBSD: arc4random.c,v 1.55 2019/03/24 17:56:54 deraadt Exp $	*/ + +/* + * Copyright (c) 1996, David Mazieres <dm@uun.org> + * Copyright (c) 2008, Damien Miller <djm@openbsd.org> + * Copyright (c) 2013, Markus Friedl <markus@openbsd.org> + * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * ChaCha based random number generator for OpenBSD. + */ + +#include <fcntl.h> +#include <limits.h> +#include <signal.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/time.h> + +#define KEYSTREAM_ONLY +#include "chacha_private.h" + +#define minimum(a, b) ((a) < (b) ? (a) : (b)) + +#if defined(__GNUC__) || defined(_MSC_VER) +#define inline __inline +#else				/* __GNUC__ || _MSC_VER */ +#define inline +#endif				/* !__GNUC__ && !_MSC_VER */ + +#define KEYSZ	32 +#define IVSZ	8 +#define BLOCKSZ	64 +#define RSBUFSZ	(16*BLOCKSZ) + +/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */ +static struct _rs { +	size_t		rs_have;	/* valid bytes at end of rs_buf */ +	size_t		rs_count;	/* bytes till reseed */ +} *rs; + +/* Maybe be preserved in fork children, if _rs_allocate() decides. */ +static struct _rsx { +	chacha_ctx	rs_chacha;	/* chacha context for random keystream */ +	u_char		rs_buf[RSBUFSZ];	/* keystream blocks */ +} *rsx; + +static inline int _rs_allocate(struct _rs **, struct _rsx **); +static inline void _rs_forkdetect(void); +#include "arc4random.h" + +static inline void _rs_rekey(u_char *dat, size_t datlen); + +static inline void +_rs_init(u_char *buf, size_t n) +{ +	if (n < KEYSZ + IVSZ) +		return; + +	if (rs == NULL) { +		if (_rs_allocate(&rs, &rsx) == -1) +			_exit(1); +	} + +	chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0); +	chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ); +} + +static void +_rs_stir(void) +{ +	u_char rnd[KEYSZ + IVSZ]; + +	if (getentropy(rnd, sizeof rnd) == -1) +		_getentropy_fail(); + +	if (!rs) +		_rs_init(rnd, sizeof(rnd)); +	else +		_rs_rekey(rnd, sizeof(rnd)); +	explicit_bzero(rnd, sizeof(rnd));	/* discard source seed */ + +	/* invalidate rs_buf */ +	rs->rs_have = 0; +	memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); + +	rs->rs_count = 1600000; +} + +static inline void +_rs_stir_if_needed(size_t len) +{ +	_rs_forkdetect(); +	if (!rs || rs->rs_count <= len) +		_rs_stir(); +	if (rs->rs_count <= len) +		rs->rs_count = 0; +	else +		rs->rs_count -= len; +} + +static inline void +_rs_rekey(u_char *dat, size_t datlen) +{ +#ifndef KEYSTREAM_ONLY +	memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); +#endif +	/* fill rs_buf with the keystream */ +	chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf, +	    rsx->rs_buf, sizeof(rsx->rs_buf)); +	/* mix in optional user provided data */ +	if (dat) { +		size_t i, m; + +		m = minimum(datlen, KEYSZ + IVSZ); +		for (i = 0; i < m; i++) +			rsx->rs_buf[i] ^= dat[i]; +	} +	/* immediately reinit for backtracking resistance */ +	_rs_init(rsx->rs_buf, KEYSZ + IVSZ); +	memset(rsx->rs_buf, 0, KEYSZ + IVSZ); +	rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ; +} + +static inline void +_rs_random_buf(void *_buf, size_t n) +{ +	u_char *buf = (u_char *)_buf; +	u_char *keystream; +	size_t m; + +	_rs_stir_if_needed(n); +	while (n > 0) { +		if (rs->rs_have > 0) { +			m = minimum(n, rs->rs_have); +			keystream = rsx->rs_buf + sizeof(rsx->rs_buf) +			    - rs->rs_have; +			memcpy(buf, keystream, m); +			memset(keystream, 0, m); +			buf += m; +			n -= m; +			rs->rs_have -= m; +		} +		if (rs->rs_have == 0) +			_rs_rekey(NULL, 0); +	} +} + +static inline void +_rs_random_u32(uint32_t *val) +{ +	u_char *keystream; + +	_rs_stir_if_needed(sizeof(*val)); +	if (rs->rs_have < sizeof(*val)) +		_rs_rekey(NULL, 0); +	keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have; +	memcpy(val, keystream, sizeof(*val)); +	memset(keystream, 0, sizeof(*val)); +	rs->rs_have -= sizeof(*val); +} + +uint32_t +arc4random(void) +{ +	uint32_t val; + +	_ARC4_LOCK(); +	_rs_random_u32(&val); +	_ARC4_UNLOCK(); +	return val; +} +DEF_WEAK(arc4random); + +void +arc4random_buf(void *buf, size_t n) +{ +	_ARC4_LOCK(); +	_rs_random_buf(buf, n); +	_ARC4_UNLOCK(); +} +DEF_WEAK(arc4random_buf); diff --git a/lib/libc/crypt/arc4random_uniform.c b/lib/libc/crypt/arc4random_uniform.c new file mode 100644 index 0000000..a18b5b1 --- /dev/null +++ b/lib/libc/crypt/arc4random_uniform.c @@ -0,0 +1,57 @@ +/*	$OpenBSD: arc4random_uniform.c,v 1.3 2019/01/20 02:59:07 bcook Exp $	*/ + +/* + * Copyright (c) 2008, Damien Miller <djm@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdint.h> +#include <stdlib.h> + +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound).  This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +uint32_t +arc4random_uniform(uint32_t upper_bound) +{ +	uint32_t r, min; + +	if (upper_bound < 2) +		return 0; + +	/* 2**32 % x == (2**32 - x) % x */ +	min = -upper_bound % upper_bound; + +	/* +	 * This could theoretically loop forever but each retry has +	 * p > 0.5 (worst case, usually far better) of selecting a +	 * number inside the range we need, so it should rarely need +	 * to re-roll. +	 */ +	for (;;) { +		r = arc4random(); +		if (r >= min) +			break; +	} + +	return r % upper_bound; +} +DEF_WEAK(arc4random_uniform); diff --git a/lib/libc/crypt/blowfish.c b/lib/libc/crypt/blowfish.c new file mode 100644 index 0000000..a658e60 --- /dev/null +++ b/lib/libc/crypt/blowfish.c @@ -0,0 +1,698 @@ +/* $OpenBSD: blowfish.c,v 1.19 2015/09/11 09:18:27 guenther Exp $ */ +/* + * Blowfish block cipher for OpenBSD + * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * All rights reserved. + * + * Implementation advice by David Mazieres <dm@lcs.mit.edu>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + *    must display the following acknowledgement: + *      This product includes software developed by Niels Provos. + * 4. The name of the author may not be used to endorse or promote products + *    derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This code is derived from section 14.3 and the given source + * in section V of Applied Cryptography, second edition. + * Blowfish is an unpatented fast block cipher designed by + * Bruce Schneier. + */ + +#if 0 +#include <stdio.h>		/* used for debugging */ +#include <string.h> +#endif + +#include <sys/types.h> +#include <blf.h> + +#undef inline +#ifdef __GNUC__ +#define inline __inline +#else				/* !__GNUC__ */ +#define inline +#endif				/* !__GNUC__ */ + +/* Function for Feistel Networks */ + +#define F(s, x) ((((s)[        (((x)>>24)&0xFF)]  \ +		 + (s)[0x100 + (((x)>>16)&0xFF)]) \ +		 ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \ +		 + (s)[0x300 + ( (x)     &0xFF)]) + +#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n]) + +void +Blowfish_encipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr) +{ +	u_int32_t Xl; +	u_int32_t Xr; +	u_int32_t *s = c->S[0]; +	u_int32_t *p = c->P; + +	Xl = *xl; +	Xr = *xr; + +	Xl ^= p[0]; +	BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2); +	BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4); +	BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6); +	BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8); +	BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10); +	BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12); +	BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14); +	BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16); + +	*xl = Xr ^ p[17]; +	*xr = Xl; +} +DEF_WEAK(Blowfish_encipher); + +void +Blowfish_decipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr) +{ +	u_int32_t Xl; +	u_int32_t Xr; +	u_int32_t *s = c->S[0]; +	u_int32_t *p = c->P; + +	Xl = *xl; +	Xr = *xr; + +	Xl ^= p[17]; +	BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15); +	BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13); +	BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11); +	BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9); +	BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7); +	BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5); +	BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3); +	BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1); + +	*xl = Xr ^ p[0]; +	*xr = Xl; +} +DEF_WEAK(Blowfish_decipher); + +void +Blowfish_initstate(blf_ctx *c) +{ +	/* P-box and S-box tables initialized with digits of Pi */ + +	static const blf_ctx initstate = +	{ { +		{ +			0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, +			0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, +			0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, +			0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, +			0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, +			0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, +			0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, +			0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, +			0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, +			0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, +			0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, +			0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, +			0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, +			0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, +			0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, +			0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, +			0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, +			0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, +			0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, +			0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, +			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, +			0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, +			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, +			0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, +			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, +			0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, +			0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, +			0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, +			0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, +			0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, +			0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, +			0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, +			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, +			0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, +			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, +			0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, +			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, +			0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, +			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, +			0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, +			0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, +			0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, +			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, +			0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, +			0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, +			0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, +			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, +			0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, +			0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, +			0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, +			0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, +			0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, +			0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, +			0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, +			0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, +			0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, +			0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, +			0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, +			0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, +			0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, +			0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, +			0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, +			0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, +		0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a}, +		{ +			0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, +			0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, +			0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, +			0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, +			0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, +			0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, +			0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, +			0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, +			0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, +			0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, +			0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, +			0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, +			0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, +			0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, +			0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, +			0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, +			0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, +			0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, +			0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, +			0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, +			0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, +			0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, +			0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, +			0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, +			0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, +			0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, +			0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, +			0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, +			0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, +			0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, +			0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, +			0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, +			0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, +			0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, +			0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, +			0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, +			0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, +			0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, +			0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, +			0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, +			0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, +			0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, +			0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, +			0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, +			0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, +			0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, +			0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, +			0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, +			0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, +			0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, +			0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, +			0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, +			0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, +			0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, +			0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, +			0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, +			0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, +			0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, +			0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, +			0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, +			0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, +			0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, +			0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, +		0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7}, +		{ +			0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, +			0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, +			0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, +			0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, +			0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, +			0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, +			0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, +			0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, +			0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, +			0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, +			0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, +			0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, +			0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, +			0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, +			0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, +			0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, +			0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, +			0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, +			0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, +			0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, +			0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, +			0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, +			0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, +			0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, +			0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, +			0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, +			0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, +			0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, +			0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, +			0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, +			0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, +			0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, +			0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, +			0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, +			0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, +			0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, +			0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, +			0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, +			0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, +			0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, +			0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, +			0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, +			0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, +			0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, +			0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, +			0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, +			0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, +			0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, +			0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, +			0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, +			0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, +			0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, +			0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, +			0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, +			0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, +			0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, +			0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, +			0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, +			0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, +			0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, +			0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, +			0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, +			0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, +		0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0}, +		{ +			0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, +			0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, +			0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, +			0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, +			0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, +			0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, +			0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, +			0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, +			0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, +			0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, +			0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, +			0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, +			0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, +			0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, +			0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, +			0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, +			0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, +			0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, +			0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, +			0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, +			0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, +			0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, +			0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, +			0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, +			0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, +			0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, +			0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, +			0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, +			0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, +			0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, +			0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, +			0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, +			0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, +			0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, +			0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, +			0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, +			0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, +			0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, +			0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, +			0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, +			0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, +			0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, +			0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, +			0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, +			0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, +			0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, +			0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, +			0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, +			0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, +			0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, +			0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, +			0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, +			0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, +			0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, +			0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, +			0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, +			0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, +			0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, +			0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, +			0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, +			0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, +			0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, +			0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, +		0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6} +	}, +	{ +		0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, +		0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, +		0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, +		0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, +		0x9216d5d9, 0x8979fb1b +	} }; + +	*c = initstate; +} +DEF_WEAK(Blowfish_initstate); + +u_int32_t +Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, +    u_int16_t *current) +{ +	u_int8_t i; +	u_int16_t j; +	u_int32_t temp; + +	temp = 0x00000000; +	j = *current; + +	for (i = 0; i < 4; i++, j++) { +		if (j >= databytes) +			j = 0; +		temp = (temp << 8) | data[j]; +	} + +	*current = j; +	return temp; +} +DEF_WEAK(Blowfish_stream2word); + +void +Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes) +{ +	u_int16_t i; +	u_int16_t j; +	u_int16_t k; +	u_int32_t temp; +	u_int32_t datal; +	u_int32_t datar; + +	j = 0; +	for (i = 0; i < BLF_N + 2; i++) { +		/* Extract 4 int8 to 1 int32 from keystream */ +		temp = Blowfish_stream2word(key, keybytes, &j); +		c->P[i] = c->P[i] ^ temp; +	} + +	j = 0; +	datal = 0x00000000; +	datar = 0x00000000; +	for (i = 0; i < BLF_N + 2; i += 2) { +		Blowfish_encipher(c, &datal, &datar); + +		c->P[i] = datal; +		c->P[i + 1] = datar; +	} + +	for (i = 0; i < 4; i++) { +		for (k = 0; k < 256; k += 2) { +			Blowfish_encipher(c, &datal, &datar); + +			c->S[i][k] = datal; +			c->S[i][k + 1] = datar; +		} +	} +} +DEF_WEAK(Blowfish_expand0state); + + +void +Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes, +    const u_int8_t *key, u_int16_t keybytes) +{ +	u_int16_t i; +	u_int16_t j; +	u_int16_t k; +	u_int32_t temp; +	u_int32_t datal; +	u_int32_t datar; + +	j = 0; +	for (i = 0; i < BLF_N + 2; i++) { +		/* Extract 4 int8 to 1 int32 from keystream */ +		temp = Blowfish_stream2word(key, keybytes, &j); +		c->P[i] = c->P[i] ^ temp; +	} + +	j = 0; +	datal = 0x00000000; +	datar = 0x00000000; +	for (i = 0; i < BLF_N + 2; i += 2) { +		datal ^= Blowfish_stream2word(data, databytes, &j); +		datar ^= Blowfish_stream2word(data, databytes, &j); +		Blowfish_encipher(c, &datal, &datar); + +		c->P[i] = datal; +		c->P[i + 1] = datar; +	} + +	for (i = 0; i < 4; i++) { +		for (k = 0; k < 256; k += 2) { +			datal ^= Blowfish_stream2word(data, databytes, &j); +			datar ^= Blowfish_stream2word(data, databytes, &j); +			Blowfish_encipher(c, &datal, &datar); + +			c->S[i][k] = datal; +			c->S[i][k + 1] = datar; +		} +	} + +} +DEF_WEAK(Blowfish_expandstate); + +void +blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len) +{ +	/* Initialize S-boxes and subkeys with Pi */ +	Blowfish_initstate(c); + +	/* Transform S-boxes and subkeys with key */ +	Blowfish_expand0state(c, k, len); +} +DEF_WEAK(blf_key); + +void +blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks) +{ +	u_int32_t *d; +	u_int16_t i; + +	d = data; +	for (i = 0; i < blocks; i++) { +		Blowfish_encipher(c, d, d + 1); +		d += 2; +	} +} +DEF_WEAK(blf_enc); + +void +blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks) +{ +	u_int32_t *d; +	u_int16_t i; + +	d = data; +	for (i = 0; i < blocks; i++) { +		Blowfish_decipher(c, d, d + 1); +		d += 2; +	} +} +DEF_WEAK(blf_dec); + +void +blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) +{ +	u_int32_t l, r; +	u_int32_t i; + +	for (i = 0; i < len; i += 8) { +		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; +		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; +		Blowfish_encipher(c, &l, &r); +		data[0] = l >> 24 & 0xff; +		data[1] = l >> 16 & 0xff; +		data[2] = l >> 8 & 0xff; +		data[3] = l & 0xff; +		data[4] = r >> 24 & 0xff; +		data[5] = r >> 16 & 0xff; +		data[6] = r >> 8 & 0xff; +		data[7] = r & 0xff; +		data += 8; +	} +} +DEF_WEAK(blf_ecb_encrypt); + +void +blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) +{ +	u_int32_t l, r; +	u_int32_t i; + +	for (i = 0; i < len; i += 8) { +		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; +		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; +		Blowfish_decipher(c, &l, &r); +		data[0] = l >> 24 & 0xff; +		data[1] = l >> 16 & 0xff; +		data[2] = l >> 8 & 0xff; +		data[3] = l & 0xff; +		data[4] = r >> 24 & 0xff; +		data[5] = r >> 16 & 0xff; +		data[6] = r >> 8 & 0xff; +		data[7] = r & 0xff; +		data += 8; +	} +} +DEF_WEAK(blf_ecb_decrypt); + +void +blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len) +{ +	u_int32_t l, r; +	u_int32_t i, j; + +	for (i = 0; i < len; i += 8) { +		for (j = 0; j < 8; j++) +			data[j] ^= iv[j]; +		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; +		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; +		Blowfish_encipher(c, &l, &r); +		data[0] = l >> 24 & 0xff; +		data[1] = l >> 16 & 0xff; +		data[2] = l >> 8 & 0xff; +		data[3] = l & 0xff; +		data[4] = r >> 24 & 0xff; +		data[5] = r >> 16 & 0xff; +		data[6] = r >> 8 & 0xff; +		data[7] = r & 0xff; +		iv = data; +		data += 8; +	} +} +DEF_WEAK(blf_cbc_encrypt); + +void +blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len) +{ +	u_int32_t l, r; +	u_int8_t *iv; +	u_int32_t i, j; + +	iv = data + len - 16; +	data = data + len - 8; +	for (i = len - 8; i >= 8; i -= 8) { +		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; +		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; +		Blowfish_decipher(c, &l, &r); +		data[0] = l >> 24 & 0xff; +		data[1] = l >> 16 & 0xff; +		data[2] = l >> 8 & 0xff; +		data[3] = l & 0xff; +		data[4] = r >> 24 & 0xff; +		data[5] = r >> 16 & 0xff; +		data[6] = r >> 8 & 0xff; +		data[7] = r & 0xff; +		for (j = 0; j < 8; j++) +			data[j] ^= iv[j]; +		iv -= 8; +		data -= 8; +	} +	l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; +	r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; +	Blowfish_decipher(c, &l, &r); +	data[0] = l >> 24 & 0xff; +	data[1] = l >> 16 & 0xff; +	data[2] = l >> 8 & 0xff; +	data[3] = l & 0xff; +	data[4] = r >> 24 & 0xff; +	data[5] = r >> 16 & 0xff; +	data[6] = r >> 8 & 0xff; +	data[7] = r & 0xff; +	for (j = 0; j < 8; j++) +		data[j] ^= iva[j]; +} +DEF_WEAK(blf_cbc_decrypt); + +#if 0 +void +report(u_int32_t data[], u_int16_t len) +{ +	u_int16_t i; +	for (i = 0; i < len; i += 2) +		printf("Block %0hd: %08lx %08lx.\n", +		    i / 2, data[i], data[i + 1]); +} +void +main(void) +{ + +	blf_ctx c; +	char    key[] = "AAAAA"; +	char    key2[] = "abcdefghijklmnopqrstuvwxyz"; + +	u_int32_t data[10]; +	u_int32_t data2[] = +	{0x424c4f57l, 0x46495348l}; + +	u_int16_t i; + +	/* First test */ +	for (i = 0; i < 10; i++) +		data[i] = i; + +	blf_key(&c, (u_int8_t *) key, 5); +	blf_enc(&c, data, 5); +	blf_dec(&c, data, 1); +	blf_dec(&c, data + 2, 4); +	printf("Should read as 0 - 9.\n"); +	report(data, 10); + +	/* Second test */ +	blf_key(&c, (u_int8_t *) key2, strlen(key2)); +	blf_enc(&c, data2, 1); +	printf("\nShould read as: 0x324ed0fe 0xf413a203.\n"); +	report(data2, 2); +	blf_dec(&c, data2, 1); +	report(data2, 2); +} +#endif diff --git a/lib/libc/crypt/chacha_private.h b/lib/libc/crypt/chacha_private.h new file mode 100644 index 0000000..7c3680f --- /dev/null +++ b/lib/libc/crypt/chacha_private.h @@ -0,0 +1,222 @@ +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */ + +typedef unsigned char u8; +typedef unsigned int u32; + +typedef struct +{ +  u32 input[16]; /* could be compressed */ +} chacha_ctx; + +#define U8C(v) (v##U) +#define U32C(v) (v##U) + +#define U8V(v) ((u8)(v) & U8C(0xFF)) +#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) + +#define ROTL32(v, n) \ +  (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define U8TO32_LITTLE(p) \ +  (((u32)((p)[0])      ) | \ +   ((u32)((p)[1]) <<  8) | \ +   ((u32)((p)[2]) << 16) | \ +   ((u32)((p)[3]) << 24)) + +#define U32TO8_LITTLE(p, v) \ +  do { \ +    (p)[0] = U8V((v)      ); \ +    (p)[1] = U8V((v) >>  8); \ +    (p)[2] = U8V((v) >> 16); \ +    (p)[3] = U8V((v) >> 24); \ +  } while (0) + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +#define QUARTERROUND(a,b,c,d) \ +  a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ +  c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ +  a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ +  c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); + +static const char sigma[16] = "expand 32-byte k"; +static const char tau[16] = "expand 16-byte k"; + +static void +chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits) +{ +  const char *constants; + +  x->input[4] = U8TO32_LITTLE(k + 0); +  x->input[5] = U8TO32_LITTLE(k + 4); +  x->input[6] = U8TO32_LITTLE(k + 8); +  x->input[7] = U8TO32_LITTLE(k + 12); +  if (kbits == 256) { /* recommended */ +    k += 16; +    constants = sigma; +  } else { /* kbits == 128 */ +    constants = tau; +  } +  x->input[8] = U8TO32_LITTLE(k + 0); +  x->input[9] = U8TO32_LITTLE(k + 4); +  x->input[10] = U8TO32_LITTLE(k + 8); +  x->input[11] = U8TO32_LITTLE(k + 12); +  x->input[0] = U8TO32_LITTLE(constants + 0); +  x->input[1] = U8TO32_LITTLE(constants + 4); +  x->input[2] = U8TO32_LITTLE(constants + 8); +  x->input[3] = U8TO32_LITTLE(constants + 12); +} + +static void +chacha_ivsetup(chacha_ctx *x,const u8 *iv) +{ +  x->input[12] = 0; +  x->input[13] = 0; +  x->input[14] = U8TO32_LITTLE(iv + 0); +  x->input[15] = U8TO32_LITTLE(iv + 4); +} + +static void +chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) +{ +  u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; +  u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; +  u8 *ctarget = NULL; +  u8 tmp[64]; +  u_int i; + +  if (!bytes) return; + +  j0 = x->input[0]; +  j1 = x->input[1]; +  j2 = x->input[2]; +  j3 = x->input[3]; +  j4 = x->input[4]; +  j5 = x->input[5]; +  j6 = x->input[6]; +  j7 = x->input[7]; +  j8 = x->input[8]; +  j9 = x->input[9]; +  j10 = x->input[10]; +  j11 = x->input[11]; +  j12 = x->input[12]; +  j13 = x->input[13]; +  j14 = x->input[14]; +  j15 = x->input[15]; + +  for (;;) { +    if (bytes < 64) { +      for (i = 0;i < bytes;++i) tmp[i] = m[i]; +      m = tmp; +      ctarget = c; +      c = tmp; +    } +    x0 = j0; +    x1 = j1; +    x2 = j2; +    x3 = j3; +    x4 = j4; +    x5 = j5; +    x6 = j6; +    x7 = j7; +    x8 = j8; +    x9 = j9; +    x10 = j10; +    x11 = j11; +    x12 = j12; +    x13 = j13; +    x14 = j14; +    x15 = j15; +    for (i = 20;i > 0;i -= 2) { +      QUARTERROUND( x0, x4, x8,x12) +      QUARTERROUND( x1, x5, x9,x13) +      QUARTERROUND( x2, x6,x10,x14) +      QUARTERROUND( x3, x7,x11,x15) +      QUARTERROUND( x0, x5,x10,x15) +      QUARTERROUND( x1, x6,x11,x12) +      QUARTERROUND( x2, x7, x8,x13) +      QUARTERROUND( x3, x4, x9,x14) +    } +    x0 = PLUS(x0,j0); +    x1 = PLUS(x1,j1); +    x2 = PLUS(x2,j2); +    x3 = PLUS(x3,j3); +    x4 = PLUS(x4,j4); +    x5 = PLUS(x5,j5); +    x6 = PLUS(x6,j6); +    x7 = PLUS(x7,j7); +    x8 = PLUS(x8,j8); +    x9 = PLUS(x9,j9); +    x10 = PLUS(x10,j10); +    x11 = PLUS(x11,j11); +    x12 = PLUS(x12,j12); +    x13 = PLUS(x13,j13); +    x14 = PLUS(x14,j14); +    x15 = PLUS(x15,j15); + +#ifndef KEYSTREAM_ONLY +    x0 = XOR(x0,U8TO32_LITTLE(m + 0)); +    x1 = XOR(x1,U8TO32_LITTLE(m + 4)); +    x2 = XOR(x2,U8TO32_LITTLE(m + 8)); +    x3 = XOR(x3,U8TO32_LITTLE(m + 12)); +    x4 = XOR(x4,U8TO32_LITTLE(m + 16)); +    x5 = XOR(x5,U8TO32_LITTLE(m + 20)); +    x6 = XOR(x6,U8TO32_LITTLE(m + 24)); +    x7 = XOR(x7,U8TO32_LITTLE(m + 28)); +    x8 = XOR(x8,U8TO32_LITTLE(m + 32)); +    x9 = XOR(x9,U8TO32_LITTLE(m + 36)); +    x10 = XOR(x10,U8TO32_LITTLE(m + 40)); +    x11 = XOR(x11,U8TO32_LITTLE(m + 44)); +    x12 = XOR(x12,U8TO32_LITTLE(m + 48)); +    x13 = XOR(x13,U8TO32_LITTLE(m + 52)); +    x14 = XOR(x14,U8TO32_LITTLE(m + 56)); +    x15 = XOR(x15,U8TO32_LITTLE(m + 60)); +#endif + +    j12 = PLUSONE(j12); +    if (!j12) { +      j13 = PLUSONE(j13); +      /* stopping at 2^70 bytes per nonce is user's responsibility */ +    } + +    U32TO8_LITTLE(c + 0,x0); +    U32TO8_LITTLE(c + 4,x1); +    U32TO8_LITTLE(c + 8,x2); +    U32TO8_LITTLE(c + 12,x3); +    U32TO8_LITTLE(c + 16,x4); +    U32TO8_LITTLE(c + 20,x5); +    U32TO8_LITTLE(c + 24,x6); +    U32TO8_LITTLE(c + 28,x7); +    U32TO8_LITTLE(c + 32,x8); +    U32TO8_LITTLE(c + 36,x9); +    U32TO8_LITTLE(c + 40,x10); +    U32TO8_LITTLE(c + 44,x11); +    U32TO8_LITTLE(c + 48,x12); +    U32TO8_LITTLE(c + 52,x13); +    U32TO8_LITTLE(c + 56,x14); +    U32TO8_LITTLE(c + 60,x15); + +    if (bytes <= 64) { +      if (bytes < 64) { +        for (i = 0;i < bytes;++i) ctarget[i] = c[i]; +      } +      x->input[12] = j12; +      x->input[13] = j13; +      return; +    } +    bytes -= 64; +    c += 64; +#ifndef KEYSTREAM_ONLY +    m += 64; +#endif +  } +} diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c new file mode 100644 index 0000000..982dd87 --- /dev/null +++ b/lib/libc/gen/fts.c @@ -0,0 +1,1053 @@ +/*	$OpenBSD: fts.c,v 1.59 2019/06/28 13:32:41 deraadt Exp $	*/ + +/*- + * Copyright (c) 1990, 1993, 1994 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h>	/* ALIGN */ +#include <sys/stat.h> +#include <sys/types.h> + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <fts.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b)) + +static FTSENT	*fts_alloc(FTS *, char *, size_t); +static FTSENT	*fts_build(FTS *, int); +static void	 fts_lfree(FTSENT *); +static void	 fts_load(FTS *, FTSENT *); +static size_t	 fts_maxarglen(char * const *); +static void	 fts_padjust(FTS *, FTSENT *); +static int	 fts_palloc(FTS *, size_t); +static FTSENT	*fts_sort(FTS *, FTSENT *, int); +static u_short	 fts_stat(FTS *, FTSENT *, int, int); +static int	 fts_safe_changedir(FTS *, FTSENT *, int, char *); + +#define	ISDOT(a)	(a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) + +#define	CLR(opt)	(sp->fts_options &= ~(opt)) +#define	ISSET(opt)	(sp->fts_options & (opt)) +#define	SET(opt)	(sp->fts_options |= (opt)) + +#define	FCHDIR(sp, fd)	(!ISSET(FTS_NOCHDIR) && fchdir(fd)) + +/* fts_build flags */ +#define	BCHILD		1		/* fts_children */ +#define	BNAMES		2		/* fts_children, names only */ +#define	BREAD		3		/* fts_read */ + +FTS * +fts_open(char * const *argv, int options, +    int (*compar)(const FTSENT **, const FTSENT **)) +{ +	FTS *sp; +	FTSENT *p, *root; +	int nitems; +	FTSENT *parent, *prev; + +	/* Options check. */ +	if (options & ~FTS_OPTIONMASK) { +		errno = EINVAL; +		return (NULL); +	} + +	/* At least one path must be specified. */ +	if (*argv == NULL) { +		errno = EINVAL; +		return (NULL); +	} + +	/* Allocate/initialize the stream */ +	if ((sp = calloc(1, sizeof(FTS))) == NULL) +		return (NULL); +	sp->fts_compar = compar; +	sp->fts_options = options; + +	/* Logical walks turn on NOCHDIR; symbolic links are too hard. */ +	if (ISSET(FTS_LOGICAL)) +		SET(FTS_NOCHDIR); + +	/* +	 * Start out with 1K of path space, and enough, in any case, +	 * to hold the user's paths. +	 */ +	if (fts_palloc(sp, MAXIMUM(fts_maxarglen(argv), PATH_MAX))) +		goto mem1; + +	/* Allocate/initialize root's parent. */ +	if ((parent = fts_alloc(sp, "", 0)) == NULL) +		goto mem2; +	parent->fts_level = FTS_ROOTPARENTLEVEL; + +	/* Allocate/initialize root(s). */ +	for (root = prev = NULL, nitems = 0; *argv; ++argv, ++nitems) { +		if ((p = fts_alloc(sp, *argv, strlen(*argv))) == NULL) +			goto mem3; +		p->fts_level = FTS_ROOTLEVEL; +		p->fts_parent = parent; +		p->fts_accpath = p->fts_name; +		p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW), -1); + +		/* Command-line "." and ".." are real directories. */ +		if (p->fts_info == FTS_DOT) +			p->fts_info = FTS_D; + +		/* +		 * If comparison routine supplied, traverse in sorted +		 * order; otherwise traverse in the order specified. +		 */ +		if (compar) { +			p->fts_link = root; +			root = p; +		} else { +			p->fts_link = NULL; +			if (root == NULL) +				root = p; +			else +				prev->fts_link = p; +			prev = p; +		} +	} +	if (compar && nitems > 1) +		root = fts_sort(sp, root, nitems); + +	/* +	 * Allocate a dummy pointer and make fts_read think that we've just +	 * finished the node before the root(s); set p->fts_info to FTS_INIT +	 * so that everything about the "current" node is ignored. +	 */ +	if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) +		goto mem3; +	sp->fts_cur->fts_link = root; +	sp->fts_cur->fts_info = FTS_INIT; + +	/* +	 * If using chdir(2), grab a file descriptor pointing to dot to ensure +	 * that we can get back here; this could be avoided for some paths, +	 * but almost certainly not worth the effort.  Slashes, symbolic links, +	 * and ".." are all fairly nasty problems.  Note, if we can't get the +	 * descriptor we run anyway, just more slowly. +	 */ +	if (!ISSET(FTS_NOCHDIR) && +	    (sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC)) == -1) +		SET(FTS_NOCHDIR); + +	if (nitems == 0) +		free(parent); + +	return (sp); + +mem3:	fts_lfree(root); +	free(parent); +mem2:	free(sp->fts_path); +mem1:	free(sp); +	return (NULL); +} +DEF_WEAK(fts_open); + +static void +fts_load(FTS *sp, FTSENT *p) +{ +	size_t len; +	char *cp; + +	/* +	 * Load the stream structure for the next traversal.  Since we don't +	 * actually enter the directory until after the preorder visit, set +	 * the fts_accpath field specially so the chdir gets done to the right +	 * place and the user can access the first node.  From fts_open it's +	 * known that the path will fit. +	 */ +	len = p->fts_pathlen = p->fts_namelen; +	memmove(sp->fts_path, p->fts_name, len + 1); +	if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) { +		len = strlen(++cp); +		memmove(p->fts_name, cp, len + 1); +		p->fts_namelen = len; +	} +	p->fts_accpath = p->fts_path = sp->fts_path; +	sp->fts_dev = p->fts_dev; +} + +int +fts_close(FTS *sp) +{ +	FTSENT *freep, *p; +	int rfd, error = 0; + +	/* +	 * This still works if we haven't read anything -- the dummy structure +	 * points to the root list, so we step through to the end of the root +	 * list which has a valid parent pointer. +	 */ +	if (sp->fts_cur) { +		for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { +			freep = p; +			p = p->fts_link ? p->fts_link : p->fts_parent; +			free(freep); +		} +		free(p); +	} + +	/* Stash the original directory fd if needed. */ +	rfd = ISSET(FTS_NOCHDIR) ? -1 : sp->fts_rfd; + +	/* Free up child linked list, sort array, path buffer, stream ptr.*/ +	if (sp->fts_child) +		fts_lfree(sp->fts_child); +	free(sp->fts_array); +	free(sp->fts_path); +	free(sp); + +	/* Return to original directory, checking for error. */ +	if (rfd != -1) { +		int saved_errno; +		error = fchdir(rfd); +		saved_errno = errno; +		(void)close(rfd); +		errno = saved_errno; +	} + +	return (error); +} +DEF_WEAK(fts_close); + +/* + * Special case of "/" at the end of the path so that slashes aren't + * appended which would cause paths to be written as "....//foo". + */ +#define	NAPPEND(p)							\ +	(p->fts_path[p->fts_pathlen - 1] == '/'				\ +	    ? p->fts_pathlen - 1 : p->fts_pathlen) + +FTSENT * +fts_read(FTS *sp) +{ +	FTSENT *p, *tmp; +	int instr; +	char *t; +	int saved_errno; + +	/* If finished or unrecoverable error, return NULL. */ +	if (sp->fts_cur == NULL || ISSET(FTS_STOP)) +		return (NULL); + +	/* Set current node pointer. */ +	p = sp->fts_cur; + +	/* Save and zero out user instructions. */ +	instr = p->fts_instr; +	p->fts_instr = FTS_NOINSTR; + +	/* Any type of file may be re-visited; re-stat and re-turn. */ +	if (instr == FTS_AGAIN) { +		p->fts_info = fts_stat(sp, p, 0, -1); +		return (p); +	} + +	/* +	 * Following a symlink -- SLNONE test allows application to see +	 * SLNONE and recover.  If indirecting through a symlink, have +	 * keep a pointer to current location.  If unable to get that +	 * pointer, follow fails. +	 */ +	if (instr == FTS_FOLLOW && +	    (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { +		p->fts_info = fts_stat(sp, p, 1, -1); +		if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { +			if ((p->fts_symfd = +			    open(".", O_RDONLY | O_CLOEXEC)) == -1) { +				p->fts_errno = errno; +				p->fts_info = FTS_ERR; +			} else +				p->fts_flags |= FTS_SYMFOLLOW; +		} +		return (p); +	} + +	/* Directory in pre-order. */ +	if (p->fts_info == FTS_D) { +		/* If skipped or crossed mount point, do post-order visit. */ +		if (instr == FTS_SKIP || +		    (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) { +			if (p->fts_flags & FTS_SYMFOLLOW) +				(void)close(p->fts_symfd); +			if (sp->fts_child) { +				fts_lfree(sp->fts_child); +				sp->fts_child = NULL; +			} +			p->fts_info = FTS_DP; +			return (p); +		} + +		/* Rebuild if only read the names and now traversing. */ +		if (sp->fts_child && ISSET(FTS_NAMEONLY)) { +			CLR(FTS_NAMEONLY); +			fts_lfree(sp->fts_child); +			sp->fts_child = NULL; +		} + +		/* +		 * Cd to the subdirectory. +		 * +		 * If have already read and now fail to chdir, whack the list +		 * to make the names come out right, and set the parent errno +		 * so the application will eventually get an error condition. +		 * Set the FTS_DONTCHDIR flag so that when we logically change +		 * directories back to the parent we don't do a chdir. +		 * +		 * If haven't read do so.  If the read fails, fts_build sets +		 * FTS_STOP or the fts_info field of the node. +		 */ +		if (sp->fts_child) { +			if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) { +				p->fts_errno = errno; +				p->fts_flags |= FTS_DONTCHDIR; +				for (p = sp->fts_child; p; p = p->fts_link) +					p->fts_accpath = +					    p->fts_parent->fts_accpath; +			} +		} else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { +			if (ISSET(FTS_STOP)) +				return (NULL); +			return (p); +		} +		p = sp->fts_child; +		sp->fts_child = NULL; +		goto name; +	} + +	/* Move to the next node on this level. */ +next:	tmp = p; +	if ((p = p->fts_link)) { +		free(tmp); + +		/* +		 * If reached the top, return to the original directory (or +		 * the root of the tree), and load the paths for the next root. +		 */ +		if (p->fts_level == FTS_ROOTLEVEL) { +			if (FCHDIR(sp, sp->fts_rfd)) { +				SET(FTS_STOP); +				return (NULL); +			} +			fts_load(sp, p); +			return (sp->fts_cur = p); +		} + +		/* +		 * User may have called fts_set on the node.  If skipped, +		 * ignore.  If followed, get a file descriptor so we can +		 * get back if necessary. +		 */ +		if (p->fts_instr == FTS_SKIP) +			goto next; +		if (p->fts_instr == FTS_FOLLOW) { +			p->fts_info = fts_stat(sp, p, 1, -1); +			if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { +				if ((p->fts_symfd = +				    open(".", O_RDONLY | O_CLOEXEC)) == -1) { +					p->fts_errno = errno; +					p->fts_info = FTS_ERR; +				} else +					p->fts_flags |= FTS_SYMFOLLOW; +			} +			p->fts_instr = FTS_NOINSTR; +		} + +name:		t = sp->fts_path + NAPPEND(p->fts_parent); +		*t++ = '/'; +		memmove(t, p->fts_name, p->fts_namelen + 1); +		return (sp->fts_cur = p); +	} + +	/* Move up to the parent node. */ +	p = tmp->fts_parent; +	free(tmp); + +	if (p->fts_level == FTS_ROOTPARENTLEVEL) { +		/* +		 * Done; free everything up and set errno to 0 so the user +		 * can distinguish between error and EOF. +		 */ +		free(p); +		errno = 0; +		return (sp->fts_cur = NULL); +	} + +	/* NUL terminate the pathname. */ +	sp->fts_path[p->fts_pathlen] = '\0'; + +	/* +	 * Return to the parent directory.  If at a root node or came through +	 * a symlink, go back through the file descriptor.  Otherwise, cd up +	 * one directory. +	 */ +	if (p->fts_level == FTS_ROOTLEVEL) { +		if (FCHDIR(sp, sp->fts_rfd)) { +			SET(FTS_STOP); +			sp->fts_cur = p; +			return (NULL); +		} +	} else if (p->fts_flags & FTS_SYMFOLLOW) { +		if (FCHDIR(sp, p->fts_symfd)) { +			saved_errno = errno; +			(void)close(p->fts_symfd); +			errno = saved_errno; +			SET(FTS_STOP); +			sp->fts_cur = p; +			return (NULL); +		} +		(void)close(p->fts_symfd); +	} else if (!(p->fts_flags & FTS_DONTCHDIR) && +	    fts_safe_changedir(sp, p->fts_parent, -1, "..")) { +		SET(FTS_STOP); +		sp->fts_cur = p; +		return (NULL); +	} +	p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; +	return (sp->fts_cur = p); +} +DEF_WEAK(fts_read); + +/* + * Fts_set takes the stream as an argument although it's not used in this + * implementation; it would be necessary if anyone wanted to add global + * semantics to fts using fts_set.  An error return is allowed for similar + * reasons. + */ +int +fts_set(FTS *sp, FTSENT *p, int instr) +{ +	if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW && +	    instr != FTS_NOINSTR && instr != FTS_SKIP) { +		errno = EINVAL; +		return (1); +	} +	p->fts_instr = instr; +	return (0); +} +DEF_WEAK(fts_set); + +FTSENT * +fts_children(FTS *sp, int instr) +{ +	FTSENT *p; +	int fd; + +	if (instr && instr != FTS_NAMEONLY) { +		errno = EINVAL; +		return (NULL); +	} + +	/* Set current node pointer. */ +	p = sp->fts_cur; + +	/* +	 * Errno set to 0 so user can distinguish empty directory from +	 * an error. +	 */ +	errno = 0; + +	/* Fatal errors stop here. */ +	if (ISSET(FTS_STOP)) +		return (NULL); + +	/* Return logical hierarchy of user's arguments. */ +	if (p->fts_info == FTS_INIT) +		return (p->fts_link); + +	/* +	 * If not a directory being visited in pre-order, stop here.  Could +	 * allow FTS_DNR, assuming the user has fixed the problem, but the +	 * same effect is available with FTS_AGAIN. +	 */ +	if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) +		return (NULL); + +	/* Free up any previous child list. */ +	if (sp->fts_child) +		fts_lfree(sp->fts_child); + +	if (instr == FTS_NAMEONLY) { +		SET(FTS_NAMEONLY); +		instr = BNAMES; +	} else +		instr = BCHILD; + +	/* +	 * If using chdir on a relative path and called BEFORE fts_read does +	 * its chdir to the root of a traversal, we can lose -- we need to +	 * chdir into the subdirectory, and we don't know where the current +	 * directory is, so we can't get back so that the upcoming chdir by +	 * fts_read will work. +	 */ +	if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' || +	    ISSET(FTS_NOCHDIR)) +		return (sp->fts_child = fts_build(sp, instr)); + +	if ((fd = open(".", O_RDONLY | O_CLOEXEC)) == -1) +		return (NULL); +	sp->fts_child = fts_build(sp, instr); +	if (fchdir(fd)) { +		(void)close(fd); +		return (NULL); +	} +	(void)close(fd); +	return (sp->fts_child); +} +DEF_WEAK(fts_children); + +/* + * This is the tricky part -- do not casually change *anything* in here.  The + * idea is to build the linked list of entries that are used by fts_children + * and fts_read.  There are lots of special cases. + * + * The real slowdown in walking the tree is the stat calls.  If FTS_NOSTAT is + * set and it's a physical walk (so that symbolic links can't be directories), + * we can do things quickly.  First, if it's a 4.4BSD file system, the type + * of the file is in the directory entry.  Otherwise, we assume that the number + * of subdirectories in a node is equal to the number of links to the parent. + * The former skips all stat calls.  The latter skips stat calls in any leaf + * directories and for any files after the subdirectories in the directory have + * been found, cutting the stat calls by about 2/3. + */ +static FTSENT * +fts_build(FTS *sp, int type) +{ +	struct dirent *dp; +	FTSENT *p, *head; +	FTSENT *cur, *tail; +	DIR *dirp; +	void *oldaddr; +	size_t len, maxlen; +	int nitems, cderrno, descend, level, nlinks, nostat, doadjust; +	int saved_errno; +	char *cp; +	size_t namlen; + +	/* Set current node pointer. */ +	cur = sp->fts_cur; + +	/* +	 * Open the directory for reading.  If this fails, we're done. +	 * If being called from fts_read, set the fts_info field. +	 */ +	if ((dirp = opendir(cur->fts_accpath)) == NULL) { +		if (type == BREAD) { +			cur->fts_info = FTS_DNR; +			cur->fts_errno = errno; +		} +		return (NULL); +	} + +	/* +	 * Nlinks is the number of possible entries of type directory in the +	 * directory if we're cheating on stat calls, 0 if we're not doing +	 * any stat calls at all, -1 if we're doing stats on everything. +	 */ +	if (type == BNAMES) +		nlinks = 0; +	else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) { +		nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2); +		nostat = 1; +	} else { +		nlinks = -1; +		nostat = 0; +	} + +#ifdef notdef +	(void)printf("nlinks == %d (cur: %u)\n", nlinks, cur->fts_nlink); +	(void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n", +	    ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT)); +#endif +	/* +	 * If we're going to need to stat anything or we want to descend +	 * and stay in the directory, chdir.  If this fails we keep going, +	 * but set a flag so we don't chdir after the post-order visit. +	 * We won't be able to stat anything, but we can still return the +	 * names themselves.  Note, that since fts_read won't be able to +	 * chdir into the directory, it will have to return different path +	 * names than before, i.e. "a/b" instead of "b".  Since the node +	 * has already been visited in pre-order, have to wait until the +	 * post-order visit to return the error.  There is a special case +	 * here, if there was nothing to stat then it's not an error to +	 * not be able to stat.  This is all fairly nasty.  If a program +	 * needed sorted entries or stat information, they had better be +	 * checking FTS_NS on the returned nodes. +	 */ +	cderrno = 0; +	if (nlinks || type == BREAD) { +		if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) { +			if (nlinks && type == BREAD) +				cur->fts_errno = errno; +			cur->fts_flags |= FTS_DONTCHDIR; +			descend = 0; +			cderrno = errno; +			(void)closedir(dirp); +			dirp = NULL; +		} else +			descend = 1; +	} else +		descend = 0; + +	/* +	 * Figure out the max file name length that can be stored in the +	 * current path -- the inner loop allocates more path as necessary. +	 * We really wouldn't have to do the maxlen calculations here, we +	 * could do them in fts_read before returning the path, but it's a +	 * lot easier here since the length is part of the dirent structure. +	 * +	 * If not changing directories set a pointer so that can just append +	 * each new name into the path. +	 */ +	len = NAPPEND(cur); +	if (ISSET(FTS_NOCHDIR)) { +		cp = sp->fts_path + len; +		*cp++ = '/'; +	} +	len++; +	maxlen = sp->fts_pathlen - len; + +	/* +	 * fts_level is signed so we must prevent it from wrapping +	 * around to FTS_ROOTLEVEL and FTS_ROOTPARENTLEVEL. +	 */ +	level = cur->fts_level; +	if (level < FTS_MAXLEVEL) +	    level++; + +	/* Read the directory, attaching each entry to the `link' pointer. */ +	doadjust = 0; +	for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) { +		if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) +			continue; + +		namlen = strlen(dp->d_name); +		if (!(p = fts_alloc(sp, dp->d_name, namlen))) +			goto mem1; +		if (namlen >= maxlen) {	/* include space for NUL */ +			oldaddr = sp->fts_path; +			if (fts_palloc(sp, namlen +len + 1)) { +				/* +				 * No more memory for path or structures.  Save +				 * errno, free up the current structure and the +				 * structures already allocated. +				 */ +mem1:				saved_errno = errno; +				free(p); +				fts_lfree(head); +				(void)closedir(dirp); +				cur->fts_info = FTS_ERR; +				SET(FTS_STOP); +				errno = saved_errno; +				return (NULL); +			} +			/* Did realloc() change the pointer? */ +			if (oldaddr != sp->fts_path) { +				doadjust = 1; +				if (ISSET(FTS_NOCHDIR)) +					cp = sp->fts_path + len; +			} +			maxlen = sp->fts_pathlen - len; +		} + +		p->fts_level = level; +		p->fts_parent = sp->fts_cur; +		p->fts_pathlen = len + namlen; +		if (p->fts_pathlen < len) { +			/* +			 * If we wrap, free up the current structure and +			 * the structures already allocated, then error +			 * out with ENAMETOOLONG. +			 */ +			free(p); +			fts_lfree(head); +			(void)closedir(dirp); +			cur->fts_info = FTS_ERR; +			SET(FTS_STOP); +			errno = ENAMETOOLONG; +			return (NULL); +		} + +		if (cderrno) { +			if (nlinks) { +				p->fts_info = FTS_NS; +				p->fts_errno = cderrno; +			} else +				p->fts_info = FTS_NSOK; +			p->fts_accpath = cur->fts_accpath; +		} else if (nlinks == 0 +#ifdef DT_DIR +		    || (nostat && +		    dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN) +#endif +		    ) { +			p->fts_accpath = +			    ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; +			p->fts_info = FTS_NSOK; +		} else { +			/* Build a file name for fts_stat to stat. */ +			if (ISSET(FTS_NOCHDIR)) { +				p->fts_accpath = p->fts_path; +				memmove(cp, p->fts_name, p->fts_namelen + 1); +				p->fts_info = fts_stat(sp, p, 0, dirfd(dirp)); +			} else { +				p->fts_accpath = p->fts_name; +				p->fts_info = fts_stat(sp, p, 0, -1); +			} + +			/* Decrement link count if applicable. */ +			if (nlinks > 0 && (p->fts_info == FTS_D || +			    p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) +				--nlinks; +		} + +		/* We walk in directory order so "ls -f" doesn't get upset. */ +		p->fts_link = NULL; +		if (head == NULL) +			head = tail = p; +		else { +			tail->fts_link = p; +			tail = p; +		} +		++nitems; +	} +	if (dirp) +		(void)closedir(dirp); + +	/* +	 * If realloc() changed the address of the path, adjust the +	 * addresses for the rest of the tree and the dir list. +	 */ +	if (doadjust) +		fts_padjust(sp, head); + +	/* +	 * If not changing directories, reset the path back to original +	 * state. +	 */ +	if (ISSET(FTS_NOCHDIR)) { +		if (len == sp->fts_pathlen || nitems == 0) +			--cp; +		*cp = '\0'; +	} + +	/* +	 * If descended after called from fts_children or after called from +	 * fts_read and nothing found, get back.  At the root level we use +	 * the saved fd; if one of fts_open()'s arguments is a relative path +	 * to an empty directory, we wind up here with no other way back.  If +	 * can't get back, we're done. +	 */ +	if (descend && (type == BCHILD || !nitems) && +	    (cur->fts_level == FTS_ROOTLEVEL ? FCHDIR(sp, sp->fts_rfd) : +	    fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) { +		cur->fts_info = FTS_ERR; +		SET(FTS_STOP); +		return (NULL); +	} + +	/* If didn't find anything, return NULL. */ +	if (!nitems) { +		if (type == BREAD) +			cur->fts_info = FTS_DP; +		return (NULL); +	} + +	/* Sort the entries. */ +	if (sp->fts_compar && nitems > 1) +		head = fts_sort(sp, head, nitems); +	return (head); +} + +static u_short +fts_stat(FTS *sp, FTSENT *p, int follow, int dfd) +{ +	FTSENT *t; +	dev_t dev; +	ino_t ino; +	struct stat *sbp, sb; +	int saved_errno; +	const char *path; + +	if (dfd == -1) { +		path = p->fts_accpath; +		dfd = AT_FDCWD; +	} else +		path = p->fts_name; + +	/* If user needs stat info, stat buffer already allocated. */ +	sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; + +	/* +	 * If doing a logical walk, or application requested FTS_FOLLOW, do +	 * a stat(2).  If that fails, check for a non-existent symlink.  If +	 * fail, set the errno from the stat call. +	 */ +	if (ISSET(FTS_LOGICAL) || follow) { +		if (fstatat(dfd, path, sbp, 0)) { +			saved_errno = errno; +			if (!fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { +				errno = 0; +				return (FTS_SLNONE); +			} +			p->fts_errno = saved_errno; +			goto err; +		} +	} else if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { +		p->fts_errno = errno; +err:		memset(sbp, 0, sizeof(struct stat)); +		return (FTS_NS); +	} + +	if (S_ISDIR(sbp->st_mode)) { +		/* +		 * Set the device/inode.  Used to find cycles and check for +		 * crossing mount points.  Also remember the link count, used +		 * in fts_build to limit the number of stat calls.  It is +		 * understood that these fields are only referenced if fts_info +		 * is set to FTS_D. +		 */ +		dev = p->fts_dev = sbp->st_dev; +		ino = p->fts_ino = sbp->st_ino; +		p->fts_nlink = sbp->st_nlink; + +		if (ISDOT(p->fts_name)) +			return (FTS_DOT); + +		/* +		 * Cycle detection is done by brute force when the directory +		 * is first encountered.  If the tree gets deep enough or the +		 * number of symbolic links to directories is high enough, +		 * something faster might be worthwhile. +		 */ +		for (t = p->fts_parent; +		    t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) +			if (ino == t->fts_ino && dev == t->fts_dev) { +				p->fts_cycle = t; +				return (FTS_DC); +			} +		return (FTS_D); +	} +	if (S_ISLNK(sbp->st_mode)) +		return (FTS_SL); +	if (S_ISREG(sbp->st_mode)) +		return (FTS_F); +	return (FTS_DEFAULT); +} + +static FTSENT * +fts_sort(FTS *sp, FTSENT *head, int nitems) +{ +	FTSENT **ap, *p; + +	/* +	 * Construct an array of pointers to the structures and call qsort(3). +	 * Reassemble the array in the order returned by qsort.  If unable to +	 * sort for memory reasons, return the directory entries in their +	 * current order.  Allocate enough space for the current needs plus +	 * 40 so don't realloc one entry at a time. +	 */ +	if (nitems > sp->fts_nitems) { +		struct _ftsent **a; + +		if ((a = reallocarray(sp->fts_array, +		    nitems + 40, sizeof(FTSENT *))) == NULL) { +			free(sp->fts_array); +			sp->fts_array = NULL; +			sp->fts_nitems = 0; +			return (head); +		} +		sp->fts_nitems = nitems + 40; +		sp->fts_array = a; +	} +	for (ap = sp->fts_array, p = head; p; p = p->fts_link) +		*ap++ = p; +	qsort(sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar); +	for (head = *(ap = sp->fts_array); --nitems; ++ap) +		ap[0]->fts_link = ap[1]; +	ap[0]->fts_link = NULL; +	return (head); +} + +static FTSENT * +fts_alloc(FTS *sp, char *name, size_t namelen) +{ +	FTSENT *p; +	size_t len; + +	/* +	 * The file name is a variable length array and no stat structure is +	 * necessary if the user has set the nostat bit.  Allocate the FTSENT +	 * structure, the file name and the stat structure in one chunk, but +	 * be careful that the stat structure is reasonably aligned.  Since the +	 * fts_name field is declared to be of size 1, the fts_name pointer is +	 * namelen + 2 before the first possible address of the stat structure. +	 */ +	len = sizeof(FTSENT) + namelen; +	if (!ISSET(FTS_NOSTAT)) +		len += sizeof(struct stat) + ALIGNBYTES; +	if ((p = calloc(1, len)) == NULL) +		return (NULL); + +	p->fts_path = sp->fts_path; +	p->fts_namelen = namelen; +	p->fts_instr = FTS_NOINSTR; +	if (!ISSET(FTS_NOSTAT)) +		p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2); +	memcpy(p->fts_name, name, namelen); + +	return (p); +} + +static void +fts_lfree(FTSENT *head) +{ +	FTSENT *p; + +	/* Free a linked list of structures. */ +	while ((p = head)) { +		head = head->fts_link; +		free(p); +	} +} + +/* + * Allow essentially unlimited paths; find, rm, ls should all work on any tree. + * Most systems will allow creation of paths much longer than PATH_MAX, even + * though the kernel won't resolve them.  Add the size (not just what's needed) + * plus 256 bytes so don't realloc the path 2 bytes at a time. + */ +static int +fts_palloc(FTS *sp, size_t more) +{ +	char *p; + +	/* +	 * Check for possible wraparound. +	 */ +	more += 256; +	if (sp->fts_pathlen + more < sp->fts_pathlen) { +		free(sp->fts_path); +		sp->fts_path = NULL; +		errno = ENAMETOOLONG; +		return (1); +	} +	p = recallocarray(sp->fts_path, sp->fts_pathlen, +	    sp->fts_pathlen + more, 1); +	if (p == NULL) { +		free(sp->fts_path); +		sp->fts_path = NULL; +		return (1); +	} +	sp->fts_pathlen += more; +	sp->fts_path = p; +	return (0); +} + +/* + * When the path is realloc'd, have to fix all of the pointers in structures + * already returned. + */ +static void +fts_padjust(FTS *sp, FTSENT *head) +{ +	FTSENT *p; +	char *addr = sp->fts_path; + +#define	ADJUST(p) {							\ +	if ((p)->fts_accpath != (p)->fts_name) {			\ +		(p)->fts_accpath =					\ +		    (char *)addr + ((p)->fts_accpath - (p)->fts_path);	\ +	}								\ +	(p)->fts_path = addr;						\ +} +	/* Adjust the current set of children. */ +	for (p = sp->fts_child; p; p = p->fts_link) +		ADJUST(p); + +	/* Adjust the rest of the tree, including the current level. */ +	for (p = head; p->fts_level >= FTS_ROOTLEVEL;) { +		ADJUST(p); +		p = p->fts_link ? p->fts_link : p->fts_parent; +	} +} + +static size_t +fts_maxarglen(char * const *argv) +{ +	size_t len, max; + +	for (max = 0; *argv; ++argv) +		if ((len = strlen(*argv)) > max) +			max = len; +	return (max + 1); +} + +/* + * Change to dir specified by fd or p->fts_accpath without getting + * tricked by someone changing the world out from underneath us. + * Assumes p->fts_dev and p->fts_ino are filled in. + */ +static int +fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path) +{ +	int ret, oerrno, newfd; +	struct stat sb; + +	newfd = fd; +	if (ISSET(FTS_NOCHDIR)) +		return (0); +	if (fd == -1 && (newfd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) == -1) +		return (-1); +	if (fstat(newfd, &sb) == -1) { +		ret = -1; +		goto bail; +	} +	if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) { +		errno = ENOENT;		/* disinformation */ +		ret = -1; +		goto bail; +	} +	ret = fchdir(newfd); +bail: +	oerrno = errno; +	if (fd == -1) +		(void)close(newfd); +	errno = oerrno; +	return (ret); +} diff --git a/lib/libc/gen/getprogname.c b/lib/libc/gen/getprogname.c new file mode 100644 index 0000000..a020830 --- /dev/null +++ b/lib/libc/gen/getprogname.c @@ -0,0 +1,24 @@ +/* $OpenBSD: getprogname.c,v 1.4 2016/03/13 18:34:20 guenther Exp $ */ +/* + * Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> + +const char * +getprogname(void) +{ +	return (__progname); +} diff --git a/lib/libc/gen/pwcache.c b/lib/libc/gen/pwcache.c new file mode 100644 index 0000000..2f30f4b --- /dev/null +++ b/lib/libc/gen/pwcache.c @@ -0,0 +1,433 @@ +/*	$OpenBSD: pwcache.c,v 1.15 2018/09/22 02:47:23 millert Exp $	*/ + +/*- + * Copyright (c) 1992 Keith Muller. + * Copyright (c) 1992, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Keith Muller of the University of California, San Diego. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> + +#include <assert.h> +#include <grp.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +/* + * Constants and data structures used to implement group and password file + * caches.  Name lengths have been chosen to be as large as those supported + * by the passwd and group files as well as the standard archive formats. + * CACHE SIZES MUST BE PRIME + */ +#define UNMLEN		32	/* >= user name found in any protocol */ +#define GNMLEN		32	/* >= group name found in any protocol */ +#define UID_SZ		317	/* size of uid to user_name cache */ +#define UNM_SZ		317	/* size of user_name to uid cache */ +#define GID_SZ		251	/* size of gid to group_name cache */ +#define GNM_SZ		251	/* size of group_name to gid cache */ +#define VALID		1	/* entry and name are valid */ +#define INVALID		2	/* entry valid, name NOT valid */ + +/* + * Node structures used in the user, group, uid, and gid caches. + */ + +typedef struct uidc { +	int valid;		/* is this a valid or a miss entry */ +	char name[UNMLEN];	/* uid name */ +	uid_t uid;		/* cached uid */ +} UIDC; + +typedef struct gidc { +	int valid;		/* is this a valid or a miss entry */ +	char name[GNMLEN];	/* gid name */ +	gid_t gid;		/* cached gid */ +} GIDC; + +/* + * Routines that control user, group, uid and gid caches. + * Traditional passwd/group cache routines perform quite poorly with + * archives. The chances of hitting a valid lookup with an archive is quite a + * bit worse than with files already resident on the file system. These misses + * create a MAJOR performance cost. To adress this problem, these routines + * cache both hits and misses. + */ + +static UIDC **uidtb;	/* uid to name cache */ +static GIDC **gidtb;	/* gid to name cache */ +static UIDC **usrtb;	/* user name to uid cache */ +static GIDC **grptb;	/* group name to gid cache */ + +static u_int +st_hash(const char *name, size_t len, int tabsz) +{ +	u_int key = 0; + +	assert(name != NULL); + +	while (len--) { +		key += *name++; +		key = (key << 8) | (key >> 24); +	} + +	return key % tabsz; +} + +/* + * uidtb_start + *	creates an an empty uidtb + * Return: + *	0 if ok, -1 otherwise + */ +static int +uidtb_start(void) +{ +	static int fail = 0; + +	if (uidtb != NULL) +		return 0; +	if (fail) +		return -1; +	if ((uidtb = calloc(UID_SZ, sizeof(UIDC *))) == NULL) { +		++fail; +		return -1; +	} +	return 0; +} + +/* + * gidtb_start + *	creates an an empty gidtb + * Return: + *	0 if ok, -1 otherwise + */ +static int +gidtb_start(void) +{ +	static int fail = 0; + +	if (gidtb != NULL) +		return 0; +	if (fail) +		return -1; +	if ((gidtb = calloc(GID_SZ, sizeof(GIDC *))) == NULL) { +		++fail; +		return -1; +	} +	return 0; +} + +/* + * usrtb_start + *	creates an an empty usrtb + * Return: + *	0 if ok, -1 otherwise + */ +static int +usrtb_start(void) +{ +	static int fail = 0; + +	if (usrtb != NULL) +		return 0; +	if (fail) +		return -1; +	if ((usrtb = calloc(UNM_SZ, sizeof(UIDC *))) == NULL) { +		++fail; +		return -1; +	} +	return 0; +} + +/* + * grptb_start + *	creates an an empty grptb + * Return: + *	0 if ok, -1 otherwise + */ +static int +grptb_start(void) +{ +	static int fail = 0; + +	if (grptb != NULL) +		return 0; +	if (fail) +		return -1; +	if ((grptb = calloc(GNM_SZ, sizeof(GIDC *))) == NULL) { +		++fail; +		return -1; +	} +	return 0; +} + +/* + * user_from_uid() + *	caches the name (if any) for the uid. If noname clear, we always + *	return the stored name (if valid or invalid match). + *	We use a simple hash table. + * Return: + *	Pointer to stored name (or a empty string) + */ +const char * +user_from_uid(uid_t uid, int noname) +{ +	struct passwd *pw; +	UIDC **pptr, *ptr = NULL; + +	if ((uidtb != NULL) || (uidtb_start() == 0)) { +		/* +		 * see if we have this uid cached +		 */ +		pptr = uidtb + (uid % UID_SZ); +		ptr = *pptr; + +		if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) { +			/* +			 * have an entry for this uid +			 */ +			if (!noname || (ptr->valid == VALID)) +				return ptr->name; +			return NULL; +		} + +		if (ptr == NULL) +			*pptr = ptr = malloc(sizeof(UIDC)); +	} + +	pw = getpwuid(uid); +	if (pw == NULL) { +		/* +		 * no match for this uid in the local password file +		 * a string that is the uid in numeric format +		 */ +		if (ptr == NULL) +			return NULL; +		ptr->uid = uid; +		(void)snprintf(ptr->name, UNMLEN, "%u", uid); +		ptr->valid = INVALID; +		if (noname) +			return NULL; +	} else { +		/* +		 * there is an entry for this uid in the password file +		 */ +		if (ptr == NULL) +			return pw->pw_name; +		ptr->uid = uid; +		(void)strlcpy(ptr->name, pw->pw_name, sizeof(ptr->name)); +		ptr->valid = VALID; +	} +	return ptr->name; +} + +/* + * group_from_gid() + *	caches the name (if any) for the gid. If noname clear, we always + *	return the stored name (if valid or invalid match). + *	We use a simple hash table. + * Return: + *	Pointer to stored name (or a empty string) + */ +const char * +group_from_gid(gid_t gid, int noname) +{ +	struct group *gr; +	GIDC **pptr, *ptr = NULL; + +	if ((gidtb != NULL) || (gidtb_start() == 0)) { +		/* +		 * see if we have this gid cached +		 */ +		pptr = gidtb + (gid % GID_SZ); +		ptr = *pptr; + +		if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) { +			/* +			 * have an entry for this gid +			 */ +			if (!noname || (ptr->valid == VALID)) +				return ptr->name; +			return NULL; +		} + +		if (ptr == NULL) +			*pptr = ptr = malloc(sizeof(GIDC)); +	} + +	gr = getgrgid(gid); +	if (gr == NULL) { +		/* +		 * no match for this gid in the local group file, put in +		 * a string that is the gid in numeric format +		 */ +		if (ptr == NULL) +			return NULL; +		ptr->gid = gid; +		(void)snprintf(ptr->name, GNMLEN, "%u", gid); +		ptr->valid = INVALID; +		if (noname) +			return NULL; +	} else { +		/* +		 * there is an entry for this group in the group file +		 */ +		if (ptr == NULL) +			return gr->gr_name; +		ptr->gid = gid; +		(void)strlcpy(ptr->name, gr->gr_name, sizeof(ptr->name)); +		ptr->valid = VALID; +	} +	return ptr->name; +} + +/* + * uid_from_user() + *	caches the uid for a given user name. We use a simple hash table. + * Return: + *	0 if the user name is found (filling in uid), -1 otherwise + */ +int +uid_from_user(const char *name, uid_t *uid) +{ +	struct passwd *pw; +	UIDC **pptr, *ptr = NULL; +	size_t namelen; + +	/* +	 * return -1 for mangled names +	 */ +	if (name == NULL || ((namelen = strlen(name)) == 0)) +		return -1; + +	if ((usrtb != NULL) || (usrtb_start() == 0)) { +		/* +		 * look up in hash table, if found and valid return the uid, +		 * if found and invalid, return a -1 +		 */ +		pptr = usrtb + st_hash(name, namelen, UNM_SZ); +		ptr = *pptr; + +		if ((ptr != NULL) && (ptr->valid > 0) && +		    strcmp(name, ptr->name) == 0) { +			if (ptr->valid == INVALID) +				return -1; +			*uid = ptr->uid; +			return 0; +		} + +		if (ptr == NULL) +			*pptr = ptr = malloc(sizeof(UIDC)); +	} + +	/* +	 * no match, look it up, if no match store it as an invalid entry, +	 * or store the matching uid +	 */ +	pw = getpwnam(name); +	if (ptr == NULL) { +		if (pw == NULL) +			return -1; +		*uid = pw->pw_uid; +		return 0; +	} +	(void)strlcpy(ptr->name, name, sizeof(ptr->name)); +	if (pw == NULL) { +		ptr->valid = INVALID; +		return -1; +	} +	ptr->valid = VALID; +	*uid = ptr->uid = pw->pw_uid; +	return 0; +} + +/* + * gid_from_group() + *	caches the gid for a given group name. We use a simple hash table. + * Return: + *	0 if the group name is found (filling in gid), -1 otherwise + */ +int +gid_from_group(const char *name, gid_t *gid) +{ +	struct group *gr; +	GIDC **pptr, *ptr = NULL; +	size_t namelen; + +	/* +	 * return -1 for mangled names +	 */ +	if (name == NULL || ((namelen = strlen(name)) == 0)) +		return -1; + +	if ((grptb != NULL) || (grptb_start() == 0)) { +		/* +		 * look up in hash table, if found and valid return the uid, +		 * if found and invalid, return a -1 +		 */ +		pptr = grptb + st_hash(name, namelen, GID_SZ); +		ptr = *pptr; + +		if ((ptr != NULL) && (ptr->valid > 0) && +		    strcmp(name, ptr->name) == 0) { +			if (ptr->valid == INVALID) +				return -1; +			*gid = ptr->gid; +			return 0; +		} + +		if (ptr == NULL) +			*pptr = ptr = malloc(sizeof(GIDC)); +	} + +	/* +	 * no match, look it up, if no match store it as an invalid entry, +	 * or store the matching gid +	 */ +	gr = getgrnam(name); +	if (ptr == NULL) { +		if (gr == NULL) +			return -1; +		*gid = gr->gr_gid; +		return 0; +	} + +	(void)strlcpy(ptr->name, name, sizeof(ptr->name)); +	if (gr == NULL) { +		ptr->valid = INVALID; +		return -1; +	} +	ptr->valid = VALID; +	*gid = ptr->gid = gr->gr_gid; +	return 0; +} diff --git a/lib/libc/gen/readpassphrase.c b/lib/libc/gen/readpassphrase.c new file mode 100644 index 0000000..e2a6121 --- /dev/null +++ b/lib/libc/gen/readpassphrase.c @@ -0,0 +1,190 @@ +/*	$OpenBSD: readpassphrase.c,v 1.27 2019/01/25 00:19:25 millert Exp $	*/ + +/* + * Copyright (c) 2000-2002, 2007, 2010 + *	Todd C. Miller <millert@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <pwd.h> +#include <signal.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> +#include <readpassphrase.h> + +#ifndef TCSASOFT +#define TCSASOFT 0 +#endif + +static volatile sig_atomic_t signo[_NSIG]; + +static void handler(int); + +char * +readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) +{ +	ssize_t nr; +	int input, output, save_errno, i, need_restart; +	char ch, *p, *end; +	struct termios term, oterm; +	struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; +	struct sigaction savetstp, savettin, savettou, savepipe; + +	/* I suppose we could alloc on demand in this case (XXX). */ +	if (bufsiz == 0) { +		errno = EINVAL; +		return(NULL); +	} + +restart: +	for (i = 0; i < _NSIG; i++) +		signo[i] = 0; +	nr = -1; +	save_errno = 0; +	need_restart = 0; +	/* +	 * Read and write to /dev/tty if available.  If not, read from +	 * stdin and write to stderr unless a tty is required. +	 */ +	if ((flags & RPP_STDIN) || +	    (input = output = open(_PATH_TTY, O_RDWR)) == -1) { +		if (flags & RPP_REQUIRE_TTY) { +			errno = ENOTTY; +			return(NULL); +		} +		input = STDIN_FILENO; +		output = STDERR_FILENO; +	} + +	/* +	 * Turn off echo if possible. +	 * If we are using a tty but are not the foreground pgrp this will +	 * generate SIGTTOU, so do it *before* installing the signal handlers. +	 */ +	if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { +		memcpy(&term, &oterm, sizeof(term)); +		if (!(flags & RPP_ECHO_ON)) +			term.c_lflag &= ~(ECHO | ECHONL); +#ifdef VSTATUS +		if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) +			term.c_cc[VSTATUS] = _POSIX_VDISABLE; +#endif +		(void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); +	} else { +		memset(&term, 0, sizeof(term)); +		term.c_lflag |= ECHO; +		memset(&oterm, 0, sizeof(oterm)); +		oterm.c_lflag |= ECHO; +	} + +	/* +	 * Catch signals that would otherwise cause the user to end +	 * up with echo turned off in the shell.  Don't worry about +	 * things like SIGXCPU and SIGVTALRM for now. +	 */ +	sigemptyset(&sa.sa_mask); +	sa.sa_flags = 0;		/* don't restart system calls */ +	sa.sa_handler = handler; +	(void)sigaction(SIGALRM, &sa, &savealrm); +	(void)sigaction(SIGHUP, &sa, &savehup); +	(void)sigaction(SIGINT, &sa, &saveint); +	(void)sigaction(SIGPIPE, &sa, &savepipe); +	(void)sigaction(SIGQUIT, &sa, &savequit); +	(void)sigaction(SIGTERM, &sa, &saveterm); +	(void)sigaction(SIGTSTP, &sa, &savetstp); +	(void)sigaction(SIGTTIN, &sa, &savettin); +	(void)sigaction(SIGTTOU, &sa, &savettou); + +	if (!(flags & RPP_STDIN)) +		(void)write(output, prompt, strlen(prompt)); +	end = buf + bufsiz - 1; +	p = buf; +	while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { +		if (p < end) { +			if ((flags & RPP_SEVENBIT)) +				ch &= 0x7f; +			if (isalpha((unsigned char)ch)) { +				if ((flags & RPP_FORCELOWER)) +					ch = (char)tolower((unsigned char)ch); +				if ((flags & RPP_FORCEUPPER)) +					ch = (char)toupper((unsigned char)ch); +			} +			*p++ = ch; +		} +	} +	*p = '\0'; +	save_errno = errno; +	if (!(term.c_lflag & ECHO)) +		(void)write(output, "\n", 1); + +	/* Restore old terminal settings and signals. */ +	if (memcmp(&term, &oterm, sizeof(term)) != 0) { +		const int sigttou = signo[SIGTTOU]; + +		/* Ignore SIGTTOU generated when we are not the fg pgrp. */ +		while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 && +		    errno == EINTR && !signo[SIGTTOU]) +			continue; +		signo[SIGTTOU] = sigttou; +	} +	(void)sigaction(SIGALRM, &savealrm, NULL); +	(void)sigaction(SIGHUP, &savehup, NULL); +	(void)sigaction(SIGINT, &saveint, NULL); +	(void)sigaction(SIGQUIT, &savequit, NULL); +	(void)sigaction(SIGPIPE, &savepipe, NULL); +	(void)sigaction(SIGTERM, &saveterm, NULL); +	(void)sigaction(SIGTSTP, &savetstp, NULL); +	(void)sigaction(SIGTTIN, &savettin, NULL); +	(void)sigaction(SIGTTOU, &savettou, NULL); +	if (input != STDIN_FILENO) +		(void)close(input); + +	/* +	 * If we were interrupted by a signal, resend it to ourselves +	 * now that we have restored the signal handlers. +	 */ +	for (i = 0; i < _NSIG; i++) { +		if (signo[i]) { +			kill(getpid(), i); +			switch (i) { +			case SIGTSTP: +			case SIGTTIN: +			case SIGTTOU: +				need_restart = 1; +			} +		} +	} +	if (need_restart) +		goto restart; + +	if (save_errno) +		errno = save_errno; +	return(nr == -1 ? NULL : buf); +} +DEF_WEAK(readpassphrase); + +static void +handler(int s) +{ +	signo[s] = 1; +} diff --git a/lib/libc/gen/setprogname.c b/lib/libc/gen/setprogname.c new file mode 100644 index 0000000..0c1573c --- /dev/null +++ b/lib/libc/gen/setprogname.c @@ -0,0 +1,31 @@ +/* $OpenBSD: setprogname.c,v 1.6 2017/09/17 06:38:03 otto Exp $ */ +/* + * Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <string.h> +#include <stdlib.h> + +void +setprogname(const char *progname) +{ +	char *tmpn; + +	tmpn = strrchr(progname, '/'); +	if (tmpn == NULL) +		__progname = (char *)progname; +	else +		__progname = (char *)tmpn + 1; +} diff --git a/lib/libc/gen/unvis.c b/lib/libc/gen/unvis.c new file mode 100644 index 0000000..05749aa --- /dev/null +++ b/lib/libc/gen/unvis.c @@ -0,0 +1,286 @@ +/*	$OpenBSD: unvis.c,v 1.17 2015/09/13 11:32:51 guenther Exp $ */ +/*- + * Copyright (c) 1989, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <ctype.h> +#include <vis.h> + +/* + * decode driven by state machine + */ +#define	S_GROUND	0	/* haven't seen escape char */ +#define	S_START		1	/* start decoding special sequence */ +#define	S_META		2	/* metachar started (M) */ +#define	S_META1		3	/* metachar more, regular char (-) */ +#define	S_CTRL		4	/* control char started (^) */ +#define	S_OCTAL2	5	/* octal digit 2 */ +#define	S_OCTAL3	6	/* octal digit 3 */ + +#define	isoctal(c)	(((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') + +/* + * unvis - decode characters previously encoded by vis + */ +int +unvis(char *cp, char c, int *astate, int flag) +{ + +	if (flag & UNVIS_END) { +		if (*astate == S_OCTAL2 || *astate == S_OCTAL3) { +			*astate = S_GROUND; +			return (UNVIS_VALID); +		}  +		return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); +	} + +	switch (*astate) { + +	case S_GROUND: +		*cp = 0; +		if (c == '\\') { +			*astate = S_START; +			return (0); +		}  +		*cp = c; +		return (UNVIS_VALID); + +	case S_START: +		switch(c) { +		case '-': +			*cp = 0; +			*astate = S_GROUND; +			return (0); +		case '\\': +		case '"': +			*cp = c; +			*astate = S_GROUND; +			return (UNVIS_VALID); +		case '0': case '1': case '2': case '3': +		case '4': case '5': case '6': case '7': +			*cp = (c - '0'); +			*astate = S_OCTAL2; +			return (0); +		case 'M': +			*cp = (char) 0200; +			*astate = S_META; +			return (0); +		case '^': +			*astate = S_CTRL; +			return (0); +		case 'n': +			*cp = '\n'; +			*astate = S_GROUND; +			return (UNVIS_VALID); +		case 'r': +			*cp = '\r'; +			*astate = S_GROUND; +			return (UNVIS_VALID); +		case 'b': +			*cp = '\b'; +			*astate = S_GROUND; +			return (UNVIS_VALID); +		case 'a': +			*cp = '\007'; +			*astate = S_GROUND; +			return (UNVIS_VALID); +		case 'v': +			*cp = '\v'; +			*astate = S_GROUND; +			return (UNVIS_VALID); +		case 't': +			*cp = '\t'; +			*astate = S_GROUND; +			return (UNVIS_VALID); +		case 'f': +			*cp = '\f'; +			*astate = S_GROUND; +			return (UNVIS_VALID); +		case 's': +			*cp = ' '; +			*astate = S_GROUND; +			return (UNVIS_VALID); +		case 'E': +			*cp = '\033'; +			*astate = S_GROUND; +			return (UNVIS_VALID); +		case '\n': +			/* +			 * hidden newline +			 */ +			*astate = S_GROUND; +			return (UNVIS_NOCHAR); +		case '$': +			/* +			 * hidden marker +			 */ +			*astate = S_GROUND; +			return (UNVIS_NOCHAR); +		} +		*astate = S_GROUND; +		return (UNVIS_SYNBAD); +		  +	case S_META: +		if (c == '-') +			*astate = S_META1; +		else if (c == '^') +			*astate = S_CTRL; +		else { +			*astate = S_GROUND; +			return (UNVIS_SYNBAD); +		} +		return (0); +		  +	case S_META1: +		*astate = S_GROUND; +		*cp |= c; +		return (UNVIS_VALID); +		  +	case S_CTRL: +		if (c == '?') +			*cp |= 0177; +		else +			*cp |= c & 037; +		*astate = S_GROUND; +		return (UNVIS_VALID); + +	case S_OCTAL2:	/* second possible octal digit */ +		if (isoctal(c)) { +			/*  +			 * yes - and maybe a third  +			 */ +			*cp = (*cp << 3) + (c - '0'); +			*astate = S_OCTAL3;	 +			return (0); +		}  +		/*  +		 * no - done with current sequence, push back passed char  +		 */ +		*astate = S_GROUND; +		return (UNVIS_VALIDPUSH); + +	case S_OCTAL3:	/* third possible octal digit */ +		*astate = S_GROUND; +		if (isoctal(c)) { +			*cp = (*cp << 3) + (c - '0'); +			return (UNVIS_VALID); +		} +		/* +		 * we were done, push back passed char +		 */ +		return (UNVIS_VALIDPUSH); + +	default:	 +		/*  +		 * decoder in unknown state - (probably uninitialized)  +		 */ +		*astate = S_GROUND; +		return (UNVIS_SYNBAD); +	} +} +DEF_WEAK(unvis); + +/* + * strunvis - decode src into dst  + * + *	Number of chars decoded into dst is returned, -1 on error. + *	Dst is null terminated. + */ + +int +strunvis(char *dst, const char *src) +{ +	char c; +	char *start = dst; +	int state = 0; + +	while ((c = *src++)) { +	again: +		switch (unvis(dst, c, &state, 0)) { +		case UNVIS_VALID: +			dst++; +			break; +		case UNVIS_VALIDPUSH: +			dst++; +			goto again; +		case 0: +		case UNVIS_NOCHAR: +			break; +		default: +			*dst = '\0'; +			return (-1); +		} +	} +	if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) +		dst++; +	*dst = '\0'; +	return (dst - start); +} + +ssize_t +strnunvis(char *dst, const char *src, size_t sz) +{ +	char c, p; +	char *start = dst, *end = dst + sz - 1; +	int state = 0; + +	if (sz > 0) +		*end = '\0'; +	while ((c = *src++)) { +	again: +		switch (unvis(&p, c, &state, 0)) { +		case UNVIS_VALID: +			if (dst < end) +				*dst = p; +			dst++; +			break; +		case UNVIS_VALIDPUSH: +			if (dst < end) +				*dst = p; +			dst++; +			goto again; +		case 0: +		case UNVIS_NOCHAR: +			break; +		default: +			if (dst <= end) +				*dst = '\0'; +			return (-1); +		} +	} +	if (unvis(&p, c, &state, UNVIS_END) == UNVIS_VALID) { +		if (dst < end) +			*dst = p; +		dst++; +	} +	if (dst <= end) +		*dst = '\0'; +	return (dst - start); +} + diff --git a/lib/libc/gen/vis.c b/lib/libc/gen/vis.c new file mode 100644 index 0000000..4400c7b --- /dev/null +++ b/lib/libc/gen/vis.c @@ -0,0 +1,243 @@ +/*	$OpenBSD: vis.c,v 1.25 2015/09/13 11:32:51 guenther Exp $ */ +/*- + * Copyright (c) 1989, 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <errno.h> +#include <ctype.h> +#include <limits.h> +#include <string.h> +#include <stdlib.h> +#include <vis.h> + +#define	isoctal(c)	(((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +#define	isvisible(c,flag)						\ +	(((c) == '\\' || (flag & VIS_ALL) == 0) &&			\ +	(((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) &&		\ +	(((c) != '*' && (c) != '?' && (c) != '[' && (c) != '#') ||	\ +		(flag & VIS_GLOB) == 0) && isgraph((u_char)(c))) ||	\ +	((flag & VIS_SP) == 0 && (c) == ' ') ||				\ +	((flag & VIS_TAB) == 0 && (c) == '\t') ||			\ +	((flag & VIS_NL) == 0 && (c) == '\n') ||			\ +	((flag & VIS_SAFE) && ((c) == '\b' ||				\ +		(c) == '\007' || (c) == '\r' ||				\ +		isgraph((u_char)(c)))))) + +/* + * vis - visually encode characters + */ +char * +vis(char *dst, int c, int flag, int nextc) +{ +	if (isvisible(c, flag)) { +		if ((c == '"' && (flag & VIS_DQ) != 0) || +		    (c == '\\' && (flag & VIS_NOSLASH) == 0)) +			*dst++ = '\\'; +		*dst++ = c; +		*dst = '\0'; +		return (dst); +	} + +	if (flag & VIS_CSTYLE) { +		switch(c) { +		case '\n': +			*dst++ = '\\'; +			*dst++ = 'n'; +			goto done; +		case '\r': +			*dst++ = '\\'; +			*dst++ = 'r'; +			goto done; +		case '\b': +			*dst++ = '\\'; +			*dst++ = 'b'; +			goto done; +		case '\a': +			*dst++ = '\\'; +			*dst++ = 'a'; +			goto done; +		case '\v': +			*dst++ = '\\'; +			*dst++ = 'v'; +			goto done; +		case '\t': +			*dst++ = '\\'; +			*dst++ = 't'; +			goto done; +		case '\f': +			*dst++ = '\\'; +			*dst++ = 'f'; +			goto done; +		case ' ': +			*dst++ = '\\'; +			*dst++ = 's'; +			goto done; +		case '\0': +			*dst++ = '\\'; +			*dst++ = '0'; +			if (isoctal(nextc)) { +				*dst++ = '0'; +				*dst++ = '0'; +			} +			goto done; +		} +	} +	if (((c & 0177) == ' ') || (flag & VIS_OCTAL) || +	    ((flag & VIS_GLOB) && (c == '*' || c == '?' || c == '[' || c == '#'))) { +		*dst++ = '\\'; +		*dst++ = ((u_char)c >> 6 & 07) + '0'; +		*dst++ = ((u_char)c >> 3 & 07) + '0'; +		*dst++ = ((u_char)c & 07) + '0'; +		goto done; +	} +	if ((flag & VIS_NOSLASH) == 0) +		*dst++ = '\\'; +	if (c & 0200) { +		c &= 0177; +		*dst++ = 'M'; +	} +	if (iscntrl((u_char)c)) { +		*dst++ = '^'; +		if (c == 0177) +			*dst++ = '?'; +		else +			*dst++ = c + '@'; +	} else { +		*dst++ = '-'; +		*dst++ = c; +	} +done: +	*dst = '\0'; +	return (dst); +} +DEF_WEAK(vis); + +/* + * strvis, strnvis, strvisx - visually encode characters from src into dst + *	 + *	Dst must be 4 times the size of src to account for possible + *	expansion.  The length of dst, not including the trailing NULL, + *	is returned.  + * + *	Strnvis will write no more than siz-1 bytes (and will NULL terminate). + *	The number of bytes needed to fully encode the string is returned. + * + *	Strvisx encodes exactly len bytes from src into dst. + *	This is useful for encoding a block of data. + */ +int +strvis(char *dst, const char *src, int flag) +{ +	char c; +	char *start; + +	for (start = dst; (c = *src);) +		dst = vis(dst, c, flag, *++src); +	*dst = '\0'; +	return (dst - start); +} +DEF_WEAK(strvis); + +int +strnvis(char *dst, const char *src, size_t siz, int flag) +{ +	char *start, *end; +	char tbuf[5]; +	int c, i; + +	i = 0; +	for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) { +		if (isvisible(c, flag)) { +			if ((c == '"' && (flag & VIS_DQ) != 0) || +			    (c == '\\' && (flag & VIS_NOSLASH) == 0)) { +				/* need space for the extra '\\' */ +				if (dst + 1 >= end) { +					i = 2; +					break; +				} +				*dst++ = '\\'; +			} +			i = 1; +			*dst++ = c; +			src++; +		} else { +			i = vis(tbuf, c, flag, *++src) - tbuf; +			if (dst + i <= end) { +				memcpy(dst, tbuf, i); +				dst += i; +			} else { +				src--; +				break; +			} +		} +	} +	if (siz > 0) +		*dst = '\0'; +	if (dst + i > end) { +		/* adjust return value for truncation */ +		while ((c = *src)) +			dst += vis(tbuf, c, flag, *++src) - tbuf; +	} +	return (dst - start); +} + +int +stravis(char **outp, const char *src, int flag) +{ +	char *buf; +	int len, serrno; + +	buf = reallocarray(NULL, 4, strlen(src) + 1); +	if (buf == NULL) +		return -1; +	len = strvis(buf, src, flag); +	serrno = errno; +	*outp = realloc(buf, len + 1); +	if (*outp == NULL) { +		*outp = buf; +		errno = serrno; +	} +	return (len); +} + +int +strvisx(char *dst, const char *src, size_t len, int flag) +{ +	char c; +	char *start; + +	for (start = dst; len > 1; len--) { +		c = *src; +		dst = vis(dst, c, flag, *++src); +	} +	if (len) +		dst = vis(dst, *src, flag, '\0'); +	*dst = '\0'; +	return (dst - start); +} diff --git a/lib/libc/gen/vwarnc.c b/lib/libc/gen/vwarnc.c new file mode 100644 index 0000000..e528de3 --- /dev/null +++ b/lib/libc/gen/vwarnc.c @@ -0,0 +1,47 @@ +/*	$OpenBSD: vwarnc.c,v 1.3 2016/03/13 18:34:20 guenther Exp $ */ +/*- + * Copyright (c) 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +void +vwarnc(int code, const char *fmt, va_list ap) +{ +	(void)fprintf(stderr, "%s: ", __progname); +	if (fmt != NULL) { +		(void)vfprintf(stderr, fmt, ap); +		(void)fprintf(stderr, ": "); +	} +	(void)fprintf(stderr, "%s\n", strerror(code)); +} +DEF_WEAK(vwarnc); diff --git a/lib/libc/gen/warnc.c b/lib/libc/gen/warnc.c new file mode 100644 index 0000000..bbda54b --- /dev/null +++ b/lib/libc/gen/warnc.c @@ -0,0 +1,43 @@ +/*	$OpenBSD: warnc.c,v 1.2 2015/08/31 02:53:57 guenther Exp $ */ +/*- + * Copyright (c) 1993 + *	The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <err.h> +#include <stdarg.h> + +void +warnc(int code, const char *fmt, ...) +{ +	va_list ap; + +	va_start(ap, fmt); +	vwarnc(code, fmt, ap); +	va_end(ap); +} +DEF_WEAK(warnc); diff --git a/lib/libc/hash/helper.c b/lib/libc/hash/helper.c new file mode 100644 index 0000000..06e8060 --- /dev/null +++ b/lib/libc/hash/helper.c @@ -0,0 +1,118 @@ +/*	$OpenBSD: helper.c,v 1.18 2019/06/28 13:32:41 deraadt Exp $ */ + +/* + * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * If we meet some day, and you think this stuff is worth it, you + * can buy me a beer in return. Poul-Henning Kamp + */ + +#include <sys/types.h> +#include <sys/cdefs.h> +#include <sys/stat.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <hashinc> + +#define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b)) + +char * +HASHEnd(HASH_CTX *ctx, char *buf) +{ +	int i; +	u_int8_t digest[HASH_DIGEST_LENGTH]; +	static const char hex[] = "0123456789abcdef"; + +	if (buf == NULL && (buf = malloc(HASH_DIGEST_STRING_LENGTH)) == NULL) +		return (NULL); + +	HASHFinal(digest, ctx); +	for (i = 0; i < HASH_DIGEST_LENGTH; i++) { +		buf[i + i] = hex[digest[i] >> 4]; +		buf[i + i + 1] = hex[digest[i] & 0x0f]; +	} +	buf[i + i] = '\0'; +	explicit_bzero(digest, sizeof(digest)); +	return (buf); +} +DEF_WEAK(HASHEnd); + +char * +HASHFileChunk(const char *filename, char *buf, off_t off, off_t len) +{ +	struct stat sb; +	u_char buffer[BUFSIZ]; +	HASH_CTX ctx; +	int fd, save_errno; +	ssize_t nr; + +	HASHInit(&ctx); + +	if ((fd = open(filename, O_RDONLY)) == -1) +		return (NULL); +	if (len == 0) { +		if (fstat(fd, &sb) == -1) { +			save_errno = errno; +			close(fd); +			errno = save_errno; +			return (NULL); +		} +		len = sb.st_size; +	} +	if (off > 0 && lseek(fd, off, SEEK_SET) == -1) { +		save_errno = errno; +		close(fd); +		errno = save_errno; +		return (NULL); +	} + +	while ((nr = read(fd, buffer, MINIMUM(sizeof(buffer), len))) > 0) { +		HASHUpdate(&ctx, buffer, nr); +		if (len > 0 && (len -= nr) == 0) +			break; +	} + +	save_errno = errno; +	close(fd); +	errno = save_errno; +	return (nr == -1 ? NULL : HASHEnd(&ctx, buf)); +} +DEF_WEAK(HASHFileChunk); + +char * +HASHFile(const char *filename, char *buf) +{ +	return (HASHFileChunk(filename, buf, 0, 0)); +} +DEF_WEAK(HASHFile); + +char * +HASHData(const u_char *data, size_t len, char *buf) +{ +	HASH_CTX ctx; + +	HASHInit(&ctx); +	HASHUpdate(&ctx, data, len); +	return (HASHEnd(&ctx, buf)); +} +DEF_WEAK(HASHData); diff --git a/lib/libc/hash/md5.c b/lib/libc/hash/md5.c new file mode 100644 index 0000000..97a444d --- /dev/null +++ b/lib/libc/hash/md5.c @@ -0,0 +1,252 @@ +/*	$OpenBSD: md5.c,v 1.11 2015/09/11 09:18:27 guenther Exp $	*/ + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest.	This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +#include <sys/cdefs.h> +#include <sys/types.h> +#include <string.h> +#include <md5.h> + +#define PUT_64BIT_LE(cp, value) do {					\ +	(cp)[7] = (value) >> 56;					\ +	(cp)[6] = (value) >> 48;					\ +	(cp)[5] = (value) >> 40;					\ +	(cp)[4] = (value) >> 32;					\ +	(cp)[3] = (value) >> 24;					\ +	(cp)[2] = (value) >> 16;					\ +	(cp)[1] = (value) >> 8;						\ +	(cp)[0] = (value); } while (0) + +#define PUT_32BIT_LE(cp, value) do {					\ +	(cp)[3] = (value) >> 24;					\ +	(cp)[2] = (value) >> 16;					\ +	(cp)[1] = (value) >> 8;						\ +	(cp)[0] = (value); } while (0) + +static u_int8_t PADDING[MD5_BLOCK_LENGTH] = { +	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void +MD5Init(MD5_CTX *ctx) +{ +	ctx->count = 0; +	ctx->state[0] = 0x67452301; +	ctx->state[1] = 0xefcdab89; +	ctx->state[2] = 0x98badcfe; +	ctx->state[3] = 0x10325476; +} +DEF_WEAK(MD5Init); + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void +MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len) +{ +	size_t have, need; + +	/* Check how many bytes we already have and how many more we need. */ +	have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); +	need = MD5_BLOCK_LENGTH - have; + +	/* Update bitcount */ +	ctx->count += (u_int64_t)len << 3; + +	if (len >= need) { +		if (have != 0) { +			memcpy(ctx->buffer + have, input, need); +			MD5Transform(ctx->state, ctx->buffer); +			input += need; +			len -= need; +			have = 0; +		} + +		/* Process data in MD5_BLOCK_LENGTH-byte chunks. */ +		while (len >= MD5_BLOCK_LENGTH) { +			MD5Transform(ctx->state, input); +			input += MD5_BLOCK_LENGTH; +			len -= MD5_BLOCK_LENGTH; +		} +	} + +	/* Handle any remaining bytes of data. */ +	if (len != 0) +		memcpy(ctx->buffer + have, input, len); +} +DEF_WEAK(MD5Update); + +/* + * Pad pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void +MD5Pad(MD5_CTX *ctx) +{ +	u_int8_t count[8]; +	size_t padlen; + +	/* Convert count to 8 bytes in little endian order. */ +	PUT_64BIT_LE(count, ctx->count); + +	/* Pad out to 56 mod 64. */ +	padlen = MD5_BLOCK_LENGTH - +	    ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); +	if (padlen < 1 + 8) +		padlen += MD5_BLOCK_LENGTH; +	MD5Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */ +	MD5Update(ctx, count, 8); +} +DEF_WEAK(MD5Pad); + +/* + * Final wrapup--call MD5Pad, fill in digest and zero out ctx. + */ +void +MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx) +{ +	int i; + +	MD5Pad(ctx); +	for (i = 0; i < 4; i++) +		PUT_32BIT_LE(digest + i * 4, ctx->state[i]); +	explicit_bzero(ctx, sizeof(*ctx)); +} +DEF_WEAK(MD5Final); + + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ +	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data.  MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void +MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH]) +{ +	u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4]; + +#if BYTE_ORDER == LITTLE_ENDIAN +	memcpy(in, block, sizeof(in)); +#else +	for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) { +		in[a] = (u_int32_t)( +		    (u_int32_t)(block[a * 4 + 0]) | +		    (u_int32_t)(block[a * 4 + 1]) <<  8 | +		    (u_int32_t)(block[a * 4 + 2]) << 16 | +		    (u_int32_t)(block[a * 4 + 3]) << 24); +	} +#endif + +	a = state[0]; +	b = state[1]; +	c = state[2]; +	d = state[3]; + +	MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7); +	MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); +	MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); +	MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); +	MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7); +	MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); +	MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); +	MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); +	MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7); +	MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); +	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); +	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); +	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7); +	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); +	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); +	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + +	MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5); +	MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9); +	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); +	MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); +	MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5); +	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9); +	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); +	MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); +	MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5); +	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9); +	MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); +	MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); +	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5); +	MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9); +	MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); +	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + +	MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4); +	MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); +	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); +	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); +	MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4); +	MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); +	MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); +	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); +	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4); +	MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); +	MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); +	MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); +	MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4); +	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); +	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); +	MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23); + +	MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6); +	MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10); +	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); +	MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21); +	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6); +	MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10); +	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); +	MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21); +	MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f,  6); +	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); +	MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15); +	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); +	MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82,  6); +	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); +	MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15); +	MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21); + +	state[0] += a; +	state[1] += b; +	state[2] += c; +	state[3] += d; +} +DEF_WEAK(MD5Transform); diff --git a/lib/libc/hash/rmd160.c b/lib/libc/hash/rmd160.c new file mode 100644 index 0000000..c2e368f --- /dev/null +++ b/lib/libc/hash/rmd160.c @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2001 Markus Friedl.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160", + * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997, + * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf + */ +#include <sys/cdefs.h> +#include <sys/types.h> +#include <endian.h> +#include <string.h> +#include <rmd160.h> + +#define PUT_64BIT_LE(cp, value) do {                                    \ +	(cp)[7] = (value) >> 56;                                        \ +	(cp)[6] = (value) >> 48;                                        \ +	(cp)[5] = (value) >> 40;                                        \ +	(cp)[4] = (value) >> 32;                                        \ +	(cp)[3] = (value) >> 24;                                        \ +	(cp)[2] = (value) >> 16;                                        \ +	(cp)[1] = (value) >> 8;                                         \ +	(cp)[0] = (value); } while (0) + +#define PUT_32BIT_LE(cp, value) do {                                    \ +	(cp)[3] = (value) >> 24;                                        \ +	(cp)[2] = (value) >> 16;                                        \ +	(cp)[1] = (value) >> 8;                                         \ +	(cp)[0] = (value); } while (0) + +#define	H0	0x67452301U +#define	H1	0xEFCDAB89U +#define	H2	0x98BADCFEU +#define	H3	0x10325476U +#define	H4	0xC3D2E1F0U + +#define	K0	0x00000000U +#define	K1	0x5A827999U +#define	K2	0x6ED9EBA1U +#define	K3	0x8F1BBCDCU +#define	K4	0xA953FD4EU + +#define	KK0	0x50A28BE6U +#define	KK1	0x5C4DD124U +#define	KK2	0x6D703EF3U +#define	KK3	0x7A6D76E9U +#define	KK4	0x00000000U + +/* rotate x left n bits.  */ +#define ROL(n, x) (((x) << (n)) | ((x) >> (32-(n)))) + +#define F0(x, y, z) ((x) ^ (y) ^ (z)) +#define F1(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define F2(x, y, z) (((x) | (~y)) ^ (z)) +#define F3(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define F4(x, y, z) ((x) ^ ((y) | (~z))) + +#define R(a, b, c, d, e, Fj, Kj, sj, rj)                                \ +	do {                                                            \ +		a = ROL(sj, a + Fj(b,c,d) + X(rj) + Kj) + e;            \ +		c = ROL(10, c);                                         \ +	} while(0) + +#define X(i)	x[i] + +static u_int8_t PADDING[RMD160_BLOCK_LENGTH] = { +	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void +RMD160Init(RMD160_CTX *ctx) +{ +	ctx->count = 0; +	ctx->state[0] = H0; +	ctx->state[1] = H1; +	ctx->state[2] = H2; +	ctx->state[3] = H3; +	ctx->state[4] = H4; +} +DEF_WEAK(RMD160Init); + +void +RMD160Update(RMD160_CTX *ctx, const u_int8_t *input, size_t len) +{ +	size_t have, off, need; + +	have = (ctx->count / 8) % RMD160_BLOCK_LENGTH; +	need = RMD160_BLOCK_LENGTH - have; +	ctx->count += 8 * len; +	off = 0; + +	if (len >= need) { +		if (have) { +			memcpy(ctx->buffer + have, input, need); +			RMD160Transform(ctx->state, ctx->buffer); +			off = need; +			have = 0; +		} +		/* now the buffer is empty */ +		while (off + RMD160_BLOCK_LENGTH <= len) { +			RMD160Transform(ctx->state, input+off); +			off += RMD160_BLOCK_LENGTH; +		} +	} +	if (off < len) +		memcpy(ctx->buffer + have, input+off, len-off); +} +DEF_WEAK(RMD160Update); + +void +RMD160Pad(RMD160_CTX *ctx) +{ +	u_int8_t size[8]; +	size_t padlen; + +	PUT_64BIT_LE(size, ctx->count); + +	/* +	 * pad to RMD160_BLOCK_LENGTH byte blocks, at least one byte from +	 * PADDING plus 8 bytes for the size +	 */ +	padlen = RMD160_BLOCK_LENGTH - ((ctx->count / 8) % RMD160_BLOCK_LENGTH); +	if (padlen < 1 + 8) +		padlen += RMD160_BLOCK_LENGTH; +	RMD160Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */ +	RMD160Update(ctx, size, 8); +} +DEF_WEAK(RMD160Pad); + +void +RMD160Final(u_int8_t digest[RMD160_DIGEST_LENGTH], RMD160_CTX *ctx) +{ +	int i; + +	RMD160Pad(ctx); +	for (i = 0; i < 5; i++) +		PUT_32BIT_LE(digest + i*4, ctx->state[i]); +	explicit_bzero(ctx, sizeof (*ctx)); +} +DEF_WEAK(RMD160Final); + +void +RMD160Transform(u_int32_t state[5], const u_int8_t block[RMD160_BLOCK_LENGTH]) +{ +	u_int32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16]; + +#if BYTE_ORDER == LITTLE_ENDIAN +	memcpy(x, block, RMD160_BLOCK_LENGTH); +#else +	int i; + +	for (i = 0; i < 16; i++) +		x[i] = (u_int32_t)( +		    (u_int32_t)(block[i*4 + 0]) | +		    (u_int32_t)(block[i*4 + 1]) <<  8 | +		    (u_int32_t)(block[i*4 + 2]) << 16 | +		    (u_int32_t)(block[i*4 + 3]) << 24); +#endif + +	a = state[0]; +	b = state[1]; +	c = state[2]; +	d = state[3]; +	e = state[4]; + +	/* Round 1 */ +	R(a, b, c, d, e, F0, K0, 11,  0); +	R(e, a, b, c, d, F0, K0, 14,  1); +	R(d, e, a, b, c, F0, K0, 15,  2); +	R(c, d, e, a, b, F0, K0, 12,  3); +	R(b, c, d, e, a, F0, K0,  5,  4); +	R(a, b, c, d, e, F0, K0,  8,  5); +	R(e, a, b, c, d, F0, K0,  7,  6); +	R(d, e, a, b, c, F0, K0,  9,  7); +	R(c, d, e, a, b, F0, K0, 11,  8); +	R(b, c, d, e, a, F0, K0, 13,  9); +	R(a, b, c, d, e, F0, K0, 14, 10); +	R(e, a, b, c, d, F0, K0, 15, 11); +	R(d, e, a, b, c, F0, K0,  6, 12); +	R(c, d, e, a, b, F0, K0,  7, 13); +	R(b, c, d, e, a, F0, K0,  9, 14); +	R(a, b, c, d, e, F0, K0,  8, 15); /* #15 */ +	/* Round 2 */ +	R(e, a, b, c, d, F1, K1,  7,  7); +	R(d, e, a, b, c, F1, K1,  6,  4); +	R(c, d, e, a, b, F1, K1,  8, 13); +	R(b, c, d, e, a, F1, K1, 13,  1); +	R(a, b, c, d, e, F1, K1, 11, 10); +	R(e, a, b, c, d, F1, K1,  9,  6); +	R(d, e, a, b, c, F1, K1,  7, 15); +	R(c, d, e, a, b, F1, K1, 15,  3); +	R(b, c, d, e, a, F1, K1,  7, 12); +	R(a, b, c, d, e, F1, K1, 12,  0); +	R(e, a, b, c, d, F1, K1, 15,  9); +	R(d, e, a, b, c, F1, K1,  9,  5); +	R(c, d, e, a, b, F1, K1, 11,  2); +	R(b, c, d, e, a, F1, K1,  7, 14); +	R(a, b, c, d, e, F1, K1, 13, 11); +	R(e, a, b, c, d, F1, K1, 12,  8); /* #31 */ +	/* Round 3 */ +	R(d, e, a, b, c, F2, K2, 11,  3); +	R(c, d, e, a, b, F2, K2, 13, 10); +	R(b, c, d, e, a, F2, K2,  6, 14); +	R(a, b, c, d, e, F2, K2,  7,  4); +	R(e, a, b, c, d, F2, K2, 14,  9); +	R(d, e, a, b, c, F2, K2,  9, 15); +	R(c, d, e, a, b, F2, K2, 13,  8); +	R(b, c, d, e, a, F2, K2, 15,  1); +	R(a, b, c, d, e, F2, K2, 14,  2); +	R(e, a, b, c, d, F2, K2,  8,  7); +	R(d, e, a, b, c, F2, K2, 13,  0); +	R(c, d, e, a, b, F2, K2,  6,  6); +	R(b, c, d, e, a, F2, K2,  5, 13); +	R(a, b, c, d, e, F2, K2, 12, 11); +	R(e, a, b, c, d, F2, K2,  7,  5); +	R(d, e, a, b, c, F2, K2,  5, 12); /* #47 */ +	/* Round 4 */ +	R(c, d, e, a, b, F3, K3, 11,  1); +	R(b, c, d, e, a, F3, K3, 12,  9); +	R(a, b, c, d, e, F3, K3, 14, 11); +	R(e, a, b, c, d, F3, K3, 15, 10); +	R(d, e, a, b, c, F3, K3, 14,  0); +	R(c, d, e, a, b, F3, K3, 15,  8); +	R(b, c, d, e, a, F3, K3,  9, 12); +	R(a, b, c, d, e, F3, K3,  8,  4); +	R(e, a, b, c, d, F3, K3,  9, 13); +	R(d, e, a, b, c, F3, K3, 14,  3); +	R(c, d, e, a, b, F3, K3,  5,  7); +	R(b, c, d, e, a, F3, K3,  6, 15); +	R(a, b, c, d, e, F3, K3,  8, 14); +	R(e, a, b, c, d, F3, K3,  6,  5); +	R(d, e, a, b, c, F3, K3,  5,  6); +	R(c, d, e, a, b, F3, K3, 12,  2); /* #63 */ +	/* Round 5 */ +	R(b, c, d, e, a, F4, K4,  9,  4); +	R(a, b, c, d, e, F4, K4, 15,  0); +	R(e, a, b, c, d, F4, K4,  5,  5); +	R(d, e, a, b, c, F4, K4, 11,  9); +	R(c, d, e, a, b, F4, K4,  6,  7); +	R(b, c, d, e, a, F4, K4,  8, 12); +	R(a, b, c, d, e, F4, K4, 13,  2); +	R(e, a, b, c, d, F4, K4, 12, 10); +	R(d, e, a, b, c, F4, K4,  5, 14); +	R(c, d, e, a, b, F4, K4, 12,  1); +	R(b, c, d, e, a, F4, K4, 13,  3); +	R(a, b, c, d, e, F4, K4, 14,  8); +	R(e, a, b, c, d, F4, K4, 11, 11); +	R(d, e, a, b, c, F4, K4,  8,  6); +	R(c, d, e, a, b, F4, K4,  5, 15); +	R(b, c, d, e, a, F4, K4,  6, 13); /* #79 */ + +	aa = a ; bb = b; cc = c; dd = d; ee = e; + +	a = state[0]; +	b = state[1]; +	c = state[2]; +	d = state[3]; +	e = state[4]; + +	/* Parallel round 1 */ +	R(a, b, c, d, e, F4, KK0,  8,  5); +	R(e, a, b, c, d, F4, KK0,  9, 14); +	R(d, e, a, b, c, F4, KK0,  9,  7); +	R(c, d, e, a, b, F4, KK0, 11,  0); +	R(b, c, d, e, a, F4, KK0, 13,  9); +	R(a, b, c, d, e, F4, KK0, 15,  2); +	R(e, a, b, c, d, F4, KK0, 15, 11); +	R(d, e, a, b, c, F4, KK0,  5,  4); +	R(c, d, e, a, b, F4, KK0,  7, 13); +	R(b, c, d, e, a, F4, KK0,  7,  6); +	R(a, b, c, d, e, F4, KK0,  8, 15); +	R(e, a, b, c, d, F4, KK0, 11,  8); +	R(d, e, a, b, c, F4, KK0, 14,  1); +	R(c, d, e, a, b, F4, KK0, 14, 10); +	R(b, c, d, e, a, F4, KK0, 12,  3); +	R(a, b, c, d, e, F4, KK0,  6, 12); /* #15 */ +	/* Parallel round 2 */ +	R(e, a, b, c, d, F3, KK1,  9,  6); +	R(d, e, a, b, c, F3, KK1, 13, 11); +	R(c, d, e, a, b, F3, KK1, 15,  3); +	R(b, c, d, e, a, F3, KK1,  7,  7); +	R(a, b, c, d, e, F3, KK1, 12,  0); +	R(e, a, b, c, d, F3, KK1,  8, 13); +	R(d, e, a, b, c, F3, KK1,  9,  5); +	R(c, d, e, a, b, F3, KK1, 11, 10); +	R(b, c, d, e, a, F3, KK1,  7, 14); +	R(a, b, c, d, e, F3, KK1,  7, 15); +	R(e, a, b, c, d, F3, KK1, 12,  8); +	R(d, e, a, b, c, F3, KK1,  7, 12); +	R(c, d, e, a, b, F3, KK1,  6,  4); +	R(b, c, d, e, a, F3, KK1, 15,  9); +	R(a, b, c, d, e, F3, KK1, 13,  1); +	R(e, a, b, c, d, F3, KK1, 11,  2); /* #31 */ +	/* Parallel round 3 */ +	R(d, e, a, b, c, F2, KK2,  9, 15); +	R(c, d, e, a, b, F2, KK2,  7,  5); +	R(b, c, d, e, a, F2, KK2, 15,  1); +	R(a, b, c, d, e, F2, KK2, 11,  3); +	R(e, a, b, c, d, F2, KK2,  8,  7); +	R(d, e, a, b, c, F2, KK2,  6, 14); +	R(c, d, e, a, b, F2, KK2,  6,  6); +	R(b, c, d, e, a, F2, KK2, 14,  9); +	R(a, b, c, d, e, F2, KK2, 12, 11); +	R(e, a, b, c, d, F2, KK2, 13,  8); +	R(d, e, a, b, c, F2, KK2,  5, 12); +	R(c, d, e, a, b, F2, KK2, 14,  2); +	R(b, c, d, e, a, F2, KK2, 13, 10); +	R(a, b, c, d, e, F2, KK2, 13,  0); +	R(e, a, b, c, d, F2, KK2,  7,  4); +	R(d, e, a, b, c, F2, KK2,  5, 13); /* #47 */ +	/* Parallel round 4 */ +	R(c, d, e, a, b, F1, KK3, 15,  8); +	R(b, c, d, e, a, F1, KK3,  5,  6); +	R(a, b, c, d, e, F1, KK3,  8,  4); +	R(e, a, b, c, d, F1, KK3, 11,  1); +	R(d, e, a, b, c, F1, KK3, 14,  3); +	R(c, d, e, a, b, F1, KK3, 14, 11); +	R(b, c, d, e, a, F1, KK3,  6, 15); +	R(a, b, c, d, e, F1, KK3, 14,  0); +	R(e, a, b, c, d, F1, KK3,  6,  5); +	R(d, e, a, b, c, F1, KK3,  9, 12); +	R(c, d, e, a, b, F1, KK3, 12,  2); +	R(b, c, d, e, a, F1, KK3,  9, 13); +	R(a, b, c, d, e, F1, KK3, 12,  9); +	R(e, a, b, c, d, F1, KK3,  5,  7); +	R(d, e, a, b, c, F1, KK3, 15, 10); +	R(c, d, e, a, b, F1, KK3,  8, 14); /* #63 */ +	/* Parallel round 5 */ +	R(b, c, d, e, a, F0, KK4,  8, 12); +	R(a, b, c, d, e, F0, KK4,  5, 15); +	R(e, a, b, c, d, F0, KK4, 12, 10); +	R(d, e, a, b, c, F0, KK4,  9,  4); +	R(c, d, e, a, b, F0, KK4, 12,  1); +	R(b, c, d, e, a, F0, KK4,  5,  5); +	R(a, b, c, d, e, F0, KK4, 14,  8); +	R(e, a, b, c, d, F0, KK4,  6,  7); +	R(d, e, a, b, c, F0, KK4,  8,  6); +	R(c, d, e, a, b, F0, KK4, 13,  2); +	R(b, c, d, e, a, F0, KK4,  6, 13); +	R(a, b, c, d, e, F0, KK4,  5, 14); +	R(e, a, b, c, d, F0, KK4, 15,  0); +	R(d, e, a, b, c, F0, KK4, 13,  3); +	R(c, d, e, a, b, F0, KK4, 11,  9); +	R(b, c, d, e, a, F0, KK4, 11, 11); /* #79 */ + +	t =        state[1] + cc + d; +	state[1] = state[2] + dd + e; +	state[2] = state[3] + ee + a; +	state[3] = state[4] + aa + b; +	state[4] = state[0] + bb + c; +	state[0] = t; +} +DEF_WEAK(RMD160Transform); diff --git a/lib/libc/hash/sha1.c b/lib/libc/hash/sha1.c new file mode 100644 index 0000000..ef6e2c2 --- /dev/null +++ b/lib/libc/hash/sha1.c @@ -0,0 +1,179 @@ +/*	$OpenBSD: sha1.c,v 1.27 2019/06/07 22:56:36 dtucker Exp $	*/ + +/* + * SHA-1 in C + * By Steve Reid <steve@edmweb.com> + * 100% Public Domain + * + * Test Vectors (from FIPS PUB 180-1) + * "abc" + *   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D + * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + *   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 + * A million repetitions of "a" + *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F + */ + +#include <sys/cdefs.h> +#include <sys/types.h> +#include <string.h> +#include <sha1.h> + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* + * blk0() and blk() perform the initial expand. + * I got the idea of expanding during the round function from SSLeay + */ +#if BYTE_ORDER == LITTLE_ENDIAN +# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ +    |(rol(block->l[i],8)&0x00FF00FF)) +#else +# define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ +    ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + +typedef union { +	u_int8_t c[64]; +	u_int32_t l[16]; +} CHAR64LONG16; + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +void +SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH]) +{ +	u_int32_t a, b, c, d, e; +	u_int8_t workspace[SHA1_BLOCK_LENGTH]; +	CHAR64LONG16 *block = (CHAR64LONG16 *)workspace; + +	(void)memcpy(block, buffer, SHA1_BLOCK_LENGTH); + +	/* Copy context->state[] to working vars */ +	a = state[0]; +	b = state[1]; +	c = state[2]; +	d = state[3]; +	e = state[4]; + +	/* 4 rounds of 20 operations each. Loop unrolled. */ +	R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); +	R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); +	R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); +	R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); +	R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); +	R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); +	R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); +	R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); +	R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); +	R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); +	R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); +	R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); +	R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); +	R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); +	R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); +	R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); +	R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); +	R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); +	R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); +	R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + +	/* Add the working vars back into context.state[] */ +	state[0] += a; +	state[1] += b; +	state[2] += c; +	state[3] += d; +	state[4] += e; + +	/* Wipe variables */ +	a = b = c = d = e = 0; +} +DEF_WEAK(SHA1Transform); + + +/* + * SHA1Init - Initialize new context + */ +void +SHA1Init(SHA1_CTX *context) +{ + +	/* SHA1 initialization constants */ +	context->count = 0; +	context->state[0] = 0x67452301; +	context->state[1] = 0xEFCDAB89; +	context->state[2] = 0x98BADCFE; +	context->state[3] = 0x10325476; +	context->state[4] = 0xC3D2E1F0; +} +DEF_WEAK(SHA1Init); + + +/* + * Run your data through this. + */ +void +SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len) +{ +	size_t i, j; + +	j = (size_t)((context->count >> 3) & 63); +	context->count += ((u_int64_t)len << 3); +	if ((j + len) > 63) { +		(void)memcpy(&context->buffer[j], data, (i = 64-j)); +		SHA1Transform(context->state, context->buffer); +		for ( ; i + 63 < len; i += 64) +			SHA1Transform(context->state, (u_int8_t *)&data[i]); +		j = 0; +	} else { +		i = 0; +	} +	(void)memcpy(&context->buffer[j], &data[i], len - i); +} +DEF_WEAK(SHA1Update); + + +/* + * Add padding and return the message digest. + */ +void +SHA1Pad(SHA1_CTX *context) +{ +	u_int8_t finalcount[8]; +	u_int i; + +	for (i = 0; i < 8; i++) { +		finalcount[i] = (u_int8_t)((context->count >> +		    ((7 - (i & 7)) * 8)) & 255);	/* Endian independent */ +	} +	SHA1Update(context, (u_int8_t *)"\200", 1); +	while ((context->count & 504) != 448) +		SHA1Update(context, (u_int8_t *)"\0", 1); +	SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ +} +DEF_WEAK(SHA1Pad); + +void +SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) +{ +	u_int i; + +	SHA1Pad(context); +	for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { +		digest[i] = (u_int8_t) +		   ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); +	} +	explicit_bzero(context, sizeof(*context)); +} +DEF_WEAK(SHA1Final); diff --git a/lib/libc/hash/sha2.c b/lib/libc/hash/sha2.c new file mode 100644 index 0000000..3374197 --- /dev/null +++ b/lib/libc/hash/sha2.c @@ -0,0 +1,977 @@ +/*	$OpenBSD: sha2.c,v 1.28 2019/07/23 12:35:22 dtucker Exp $	*/ + +/* + * FILE:	sha2.c + * AUTHOR:	Aaron D. Gifford <me@aarongifford.com> + *  + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + *  + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ + */ + +#include <sys/types.h> +#include <sys/cdefs.h> +#include <sys/compat.h> + +#include <string.h> +#include <sha2.h> + +/* + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file).  Either define on the command line, for example: + * + *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + *   #define SHA2_UNROLL_TRANSFORM + * + */ +#ifndef SHA2_SMALL +#if defined(__amd64__) || defined(__i386__) +#define SHA2_UNROLL_TRANSFORM +#endif +#endif + +/*** SHA-224/256/384/512 Machine Architecture Definitions *****************/ +/* + * BYTE_ORDER NOTE: + * + * Please make sure that your system defines BYTE_ORDER.  If your + * architecture is little-endian, make sure it also defines + * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are + * equivalent. + * + * If your system does not define the above, then you can do so by + * hand like this: + * + *   #define LITTLE_ENDIAN 1234 + *   #define BIG_ENDIAN    4321 + * + * And for little-endian machines, add: + * + *   #define BYTE_ORDER LITTLE_ENDIAN  + * + * Or for big-endian machines: + * + *   #define BYTE_ORDER BIG_ENDIAN + * + * The FreeBSD machine this was written on defines BYTE_ORDER + * appropriately by including <sys/types.h> (which in turn includes + * <machine/endian.h> where the appropriate definitions are actually + * made). + */ +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +#endif + + +/*** SHA-224/256/384/512 Various Length Definitions ***********************/ +/* NOTE: Most of these are in sha2.h */ +#define SHA224_SHORT_BLOCK_LENGTH	(SHA224_BLOCK_LENGTH - 8) +#define SHA256_SHORT_BLOCK_LENGTH	(SHA256_BLOCK_LENGTH - 8) +#define SHA384_SHORT_BLOCK_LENGTH	(SHA384_BLOCK_LENGTH - 16) +#define SHA512_SHORT_BLOCK_LENGTH	(SHA512_BLOCK_LENGTH - 16) + +/*** ENDIAN SPECIFIC COPY MACROS **************************************/ +#define BE_8_TO_32(dst, cp) do {					\ +	(dst) = (u_int32_t)(cp)[3] | ((u_int32_t)(cp)[2] << 8) |	\ +	    ((u_int32_t)(cp)[1] << 16) | ((u_int32_t)(cp)[0] << 24);	\ +} while(0) + +#define BE_8_TO_64(dst, cp) do {					\ +	(dst) = (u_int64_t)(cp)[7] | ((u_int64_t)(cp)[6] << 8) |	\ +	    ((u_int64_t)(cp)[5] << 16) | ((u_int64_t)(cp)[4] << 24) |	\ +	    ((u_int64_t)(cp)[3] << 32) | ((u_int64_t)(cp)[2] << 40) |	\ +	    ((u_int64_t)(cp)[1] << 48) | ((u_int64_t)(cp)[0] << 56);	\ +} while (0) + +#define BE_64_TO_8(cp, src) do {					\ +	(cp)[0] = (src) >> 56;						\ +        (cp)[1] = (src) >> 48;						\ +	(cp)[2] = (src) >> 40;						\ +	(cp)[3] = (src) >> 32;						\ +	(cp)[4] = (src) >> 24;						\ +	(cp)[5] = (src) >> 16;						\ +	(cp)[6] = (src) >> 8;						\ +	(cp)[7] = (src);						\ +} while (0) + +#define BE_32_TO_8(cp, src) do {					\ +	(cp)[0] = (src) >> 24;						\ +	(cp)[1] = (src) >> 16;						\ +	(cp)[2] = (src) >> 8;						\ +	(cp)[3] = (src);						\ +} while (0) + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) do {						\ +	(w)[0] += (u_int64_t)(n);					\ +	if ((w)[0] < (n)) {						\ +		(w)[1]++;						\ +	}								\ +} while (0) + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and + *   S is a ROTATION) because the SHA-224/256/384/512 description document + *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this + *   same "backwards" definition. + */ +/* Shift-right (used in SHA-224, SHA-256, SHA-384, and SHA-512): */ +#define R(b,x) 		((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-224 and SHA-256): */ +#define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b)))) + +/* Two of six logical functions used in SHA-224, SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Four of six logical functions used in SHA-224 and SHA-256: */ +#define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x))) +#define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x))) +#define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x))) +#define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) +#define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) +#define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x))) +#define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x))) + + +/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ +/* Hash constant words K for SHA-224 and SHA-256: */ +static const u_int32_t K256[64] = { +	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, +	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, +	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, +	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, +	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, +	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, +	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, +	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, +	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, +	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, +	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, +	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, +	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, +	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, +	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, +	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Initial hash value H for SHA-256: */ +static const u_int32_t sha256_initial_hash_value[8] = { +	0x6a09e667UL, +	0xbb67ae85UL, +	0x3c6ef372UL, +	0xa54ff53aUL, +	0x510e527fUL, +	0x9b05688cUL, +	0x1f83d9abUL, +	0x5be0cd19UL +}; + +/* Hash constant words K for SHA-384 and SHA-512: */ +static const u_int64_t K512[80] = { +	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, +	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, +	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, +	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, +	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, +	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, +	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, +	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, +	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, +	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, +	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, +	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, +	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, +	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, +	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, +	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, +	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, +	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, +	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, +	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, +	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, +	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, +	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, +	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, +	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, +	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, +	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, +	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, +	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, +	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, +	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, +	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, +	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, +	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, +	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, +	0x113f9804bef90daeULL, 0x1b710b35131c471bULL, +	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, +	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, +	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, +	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +/* Initial hash value H for SHA-512 */ +static const u_int64_t sha512_initial_hash_value[8] = { +	0x6a09e667f3bcc908ULL, +	0xbb67ae8584caa73bULL, +	0x3c6ef372fe94f82bULL, +	0xa54ff53a5f1d36f1ULL, +	0x510e527fade682d1ULL, +	0x9b05688c2b3e6c1fULL, +	0x1f83d9abfb41bd6bULL, +	0x5be0cd19137e2179ULL +}; + +#if !defined(SHA2_SMALL) +/* Initial hash value H for SHA-224: */ +static const u_int32_t sha224_initial_hash_value[8] = { +	0xc1059ed8UL, +	0x367cd507UL, +	0x3070dd17UL, +	0xf70e5939UL, +	0xffc00b31UL, +	0x68581511UL, +	0x64f98fa7UL, +	0xbefa4fa4UL +}; + +/* Initial hash value H for SHA-384 */ +static const u_int64_t sha384_initial_hash_value[8] = { +	0xcbbb9d5dc1059ed8ULL, +	0x629a292a367cd507ULL, +	0x9159015a3070dd17ULL, +	0x152fecd8f70e5939ULL, +	0x67332667ffc00b31ULL, +	0x8eb44a8768581511ULL, +	0xdb0c2e0d64f98fa7ULL, +	0x47b5481dbefa4fa4ULL +}; + +/* Initial hash value H for SHA-512-256 */ +static const u_int64_t sha512_256_initial_hash_value[8] = { +	0x22312194fc2bf72cULL, +	0x9f555fa3c84c64c2ULL, +	0x2393b86b6f53b151ULL, +	0x963877195940eabdULL, +	0x96283ee2a88effe3ULL, +	0xbe5e1e2553863992ULL, +	0x2b0199fc2c85b8aaULL, +	0x0eb72ddc81c52ca2ULL +}; + +/*** SHA-224: *********************************************************/ +void +SHA224Init(SHA2_CTX *context) +{ +	memcpy(context->state.st32, sha224_initial_hash_value, +	    sizeof(sha224_initial_hash_value)); +	memset(context->buffer, 0, sizeof(context->buffer)); +	context->bitcount[0] = 0; +} +DEF_WEAK(SHA224Init); + +MAKE_CLONE(SHA224Transform, SHA256Transform); +MAKE_CLONE(SHA224Update, SHA256Update); +MAKE_CLONE(SHA224Pad, SHA256Pad); +DEF_WEAK(SHA224Transform); +DEF_WEAK(SHA224Update); +DEF_WEAK(SHA224Pad); + +void +SHA224Final(u_int8_t digest[SHA224_DIGEST_LENGTH], SHA2_CTX *context) +{ +	SHA224Pad(context); + +#if BYTE_ORDER == LITTLE_ENDIAN +	int	i; + +	/* Convert TO host byte order */ +	for (i = 0; i < 7; i++) +		BE_32_TO_8(digest + i * 4, context->state.st32[i]); +#else +	memcpy(digest, context->state.st32, SHA224_DIGEST_LENGTH); +#endif +	explicit_bzero(context, sizeof(*context)); +} +DEF_WEAK(SHA224Final); +#endif /* !defined(SHA2_SMALL) */ + +/*** SHA-256: *********************************************************/ +void +SHA256Init(SHA2_CTX *context) +{ +	memcpy(context->state.st32, sha256_initial_hash_value, +	    sizeof(sha256_initial_hash_value)); +	memset(context->buffer, 0, sizeof(context->buffer)); +	context->bitcount[0] = 0; +} +DEF_WEAK(SHA256Init); + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-256 round macros: */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do {				    \ +	BE_8_TO_32(W256[j], data);					    \ +	data += 4;							    \ +	T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \ +	(d) += T1;							    \ +	(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c));		    \ +	j++;								    \ +} while(0) + +#define ROUND256(a,b,c,d,e,f,g,h) do {					    \ +	s0 = W256[(j+1)&0x0f];						    \ +	s0 = sigma0_256(s0);						    \ +	s1 = W256[(j+14)&0x0f];						    \ +	s1 = sigma1_256(s1);						    \ +	T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] +	    \ +	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);		    \ +	(d) += T1;							    \ +	(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c));		    \ +	j++;								    \ +} while(0) + +void +SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) +{ +	u_int32_t	a, b, c, d, e, f, g, h, s0, s1; +	u_int32_t	T1, W256[16]; +	int		j; + +	/* Initialize registers with the prev. intermediate value */ +	a = state[0]; +	b = state[1]; +	c = state[2]; +	d = state[3]; +	e = state[4]; +	f = state[5]; +	g = state[6]; +	h = state[7]; + +	j = 0; +	do { +		/* Rounds 0 to 15 (unrolled): */ +		ROUND256_0_TO_15(a,b,c,d,e,f,g,h); +		ROUND256_0_TO_15(h,a,b,c,d,e,f,g); +		ROUND256_0_TO_15(g,h,a,b,c,d,e,f); +		ROUND256_0_TO_15(f,g,h,a,b,c,d,e); +		ROUND256_0_TO_15(e,f,g,h,a,b,c,d); +		ROUND256_0_TO_15(d,e,f,g,h,a,b,c); +		ROUND256_0_TO_15(c,d,e,f,g,h,a,b); +		ROUND256_0_TO_15(b,c,d,e,f,g,h,a); +	} while (j < 16); + +	/* Now for the remaining rounds up to 63: */ +	do { +		ROUND256(a,b,c,d,e,f,g,h); +		ROUND256(h,a,b,c,d,e,f,g); +		ROUND256(g,h,a,b,c,d,e,f); +		ROUND256(f,g,h,a,b,c,d,e); +		ROUND256(e,f,g,h,a,b,c,d); +		ROUND256(d,e,f,g,h,a,b,c); +		ROUND256(c,d,e,f,g,h,a,b); +		ROUND256(b,c,d,e,f,g,h,a); +	} while (j < 64); + +	/* Compute the current intermediate hash value */ +	state[0] += a; +	state[1] += b; +	state[2] += c; +	state[3] += d; +	state[4] += e; +	state[5] += f; +	state[6] += g; +	state[7] += h; + +	/* Clean up */ +	a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void +SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) +{ +	u_int32_t	a, b, c, d, e, f, g, h, s0, s1; +	u_int32_t	T1, T2, W256[16]; +	int		j; + +	/* Initialize registers with the prev. intermediate value */ +	a = state[0]; +	b = state[1]; +	c = state[2]; +	d = state[3]; +	e = state[4]; +	f = state[5]; +	g = state[6]; +	h = state[7]; + +	j = 0; +	do { +		BE_8_TO_32(W256[j], data); +		data += 4; +		/* Apply the SHA-256 compression function to update a..h */ +		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; +		T2 = Sigma0_256(a) + Maj(a, b, c); +		h = g; +		g = f; +		f = e; +		e = d + T1; +		d = c; +		c = b; +		b = a; +		a = T1 + T2; + +		j++; +	} while (j < 16); + +	do { +		/* Part of the message block expansion: */ +		s0 = W256[(j+1)&0x0f]; +		s0 = sigma0_256(s0); +		s1 = W256[(j+14)&0x0f];	 +		s1 = sigma1_256(s1); + +		/* Apply the SHA-256 compression function to update a..h */ +		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +  +		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); +		T2 = Sigma0_256(a) + Maj(a, b, c); +		h = g; +		g = f; +		f = e; +		e = d + T1; +		d = c; +		c = b; +		b = a; +		a = T1 + T2; + +		j++; +	} while (j < 64); + +	/* Compute the current intermediate hash value */ +	state[0] += a; +	state[1] += b; +	state[2] += c; +	state[3] += d; +	state[4] += e; +	state[5] += f; +	state[6] += g; +	state[7] += h; + +	/* Clean up */ +	a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ +DEF_WEAK(SHA256Transform); + +void +SHA256Update(SHA2_CTX *context, const u_int8_t *data, size_t len) +{ +	u_int64_t	freespace, usedspace; + +	/* Calling with no data is valid (we do nothing) */ +	if (len == 0) +		return; + +	usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH; +	if (usedspace > 0) { +		/* Calculate how much free space is available in the buffer */ +		freespace = SHA256_BLOCK_LENGTH - usedspace; + +		if (len >= freespace) { +			/* Fill the buffer completely and process it */ +			memcpy(&context->buffer[usedspace], data, freespace); +			context->bitcount[0] += freespace << 3; +			len -= freespace; +			data += freespace; +			SHA256Transform(context->state.st32, context->buffer); +		} else { +			/* The buffer is not yet full */ +			memcpy(&context->buffer[usedspace], data, len); +			context->bitcount[0] += (u_int64_t)len << 3; +			/* Clean up: */ +			usedspace = freespace = 0; +			return; +		} +	} +	while (len >= SHA256_BLOCK_LENGTH) { +		/* Process as many complete blocks as we can */ +		SHA256Transform(context->state.st32, data); +		context->bitcount[0] += SHA256_BLOCK_LENGTH << 3; +		len -= SHA256_BLOCK_LENGTH; +		data += SHA256_BLOCK_LENGTH; +	} +	if (len > 0) { +		/* There's left-overs, so save 'em */ +		memcpy(context->buffer, data, len); +		context->bitcount[0] += len << 3; +	} +	/* Clean up: */ +	usedspace = freespace = 0; +} +DEF_WEAK(SHA256Update); + +void +SHA256Pad(SHA2_CTX *context) +{ +	unsigned int	usedspace; + +	usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH; +	if (usedspace > 0) { +		/* Begin padding with a 1 bit: */ +		context->buffer[usedspace++] = 0x80; + +		if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { +			/* Set-up for the last transform: */ +			memset(&context->buffer[usedspace], 0, +			    SHA256_SHORT_BLOCK_LENGTH - usedspace); +		} else { +			if (usedspace < SHA256_BLOCK_LENGTH) { +				memset(&context->buffer[usedspace], 0, +				    SHA256_BLOCK_LENGTH - usedspace); +			} +			/* Do second-to-last transform: */ +			SHA256Transform(context->state.st32, context->buffer); + +			/* Prepare for last transform: */ +			memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); +		} +	} else { +		/* Set-up for the last transform: */ +		memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); + +		/* Begin padding with a 1 bit: */ +		*context->buffer = 0x80; +	} +	/* Store the length of input data (in bits) in big endian format: */ +	BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], +	    context->bitcount[0]); + +	/* Final transform: */ +	SHA256Transform(context->state.st32, context->buffer); + +	/* Clean up: */ +	usedspace = 0; +} +DEF_WEAK(SHA256Pad); + +void +SHA256Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *context) +{ +	SHA256Pad(context); + +#if BYTE_ORDER == LITTLE_ENDIAN +	int	i; + +	/* Convert TO host byte order */ +	for (i = 0; i < 8; i++) +		BE_32_TO_8(digest + i * 4, context->state.st32[i]); +#else +	memcpy(digest, context->state.st32, SHA256_DIGEST_LENGTH); +#endif +	explicit_bzero(context, sizeof(*context)); +} +DEF_WEAK(SHA256Final); + + +/*** SHA-512: *********************************************************/ +void +SHA512Init(SHA2_CTX *context) +{ +	memcpy(context->state.st64, sha512_initial_hash_value, +	    sizeof(sha512_initial_hash_value)); +	memset(context->buffer, 0, sizeof(context->buffer)); +	context->bitcount[0] = context->bitcount[1] =  0; +} +DEF_WEAK(SHA512Init); + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-512 round macros: */ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do {				    \ +	BE_8_TO_64(W512[j], data);					    \ +	data += 8;							    \ +	T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \ +	(d) += T1;							    \ +	(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c));		    \ +	j++;								    \ +} while(0) + + +#define ROUND512(a,b,c,d,e,f,g,h) do {					    \ +	s0 = W512[(j+1)&0x0f];						    \ +	s0 = sigma0_512(s0);						    \ +	s1 = W512[(j+14)&0x0f];						    \ +	s1 = sigma1_512(s1);						    \ +	T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] +	    \ +             (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);		    \ +	(d) += T1;							    \ +	(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c));		    \ +	j++;								    \ +} while(0) + +void +SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) +{ +	u_int64_t	a, b, c, d, e, f, g, h, s0, s1; +	u_int64_t	T1, W512[16]; +	int		j; + +	/* Initialize registers with the prev. intermediate value */ +	a = state[0]; +	b = state[1]; +	c = state[2]; +	d = state[3]; +	e = state[4]; +	f = state[5]; +	g = state[6]; +	h = state[7]; + +	j = 0; +	do { +		/* Rounds 0 to 15 (unrolled): */ +		ROUND512_0_TO_15(a,b,c,d,e,f,g,h); +		ROUND512_0_TO_15(h,a,b,c,d,e,f,g); +		ROUND512_0_TO_15(g,h,a,b,c,d,e,f); +		ROUND512_0_TO_15(f,g,h,a,b,c,d,e); +		ROUND512_0_TO_15(e,f,g,h,a,b,c,d); +		ROUND512_0_TO_15(d,e,f,g,h,a,b,c); +		ROUND512_0_TO_15(c,d,e,f,g,h,a,b); +		ROUND512_0_TO_15(b,c,d,e,f,g,h,a); +	} while (j < 16); + +	/* Now for the remaining rounds up to 79: */ +	do { +		ROUND512(a,b,c,d,e,f,g,h); +		ROUND512(h,a,b,c,d,e,f,g); +		ROUND512(g,h,a,b,c,d,e,f); +		ROUND512(f,g,h,a,b,c,d,e); +		ROUND512(e,f,g,h,a,b,c,d); +		ROUND512(d,e,f,g,h,a,b,c); +		ROUND512(c,d,e,f,g,h,a,b); +		ROUND512(b,c,d,e,f,g,h,a); +	} while (j < 80); + +	/* Compute the current intermediate hash value */ +	state[0] += a; +	state[1] += b; +	state[2] += c; +	state[3] += d; +	state[4] += e; +	state[5] += f; +	state[6] += g; +	state[7] += h; + +	/* Clean up */ +	a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void +SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) +{ +	u_int64_t	a, b, c, d, e, f, g, h, s0, s1; +	u_int64_t	T1, T2, W512[16]; +	int		j; + +	/* Initialize registers with the prev. intermediate value */ +	a = state[0]; +	b = state[1]; +	c = state[2]; +	d = state[3]; +	e = state[4]; +	f = state[5]; +	g = state[6]; +	h = state[7]; + +	j = 0; +	do { +		BE_8_TO_64(W512[j], data); +		data += 8; +		/* Apply the SHA-512 compression function to update a..h */ +		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; +		T2 = Sigma0_512(a) + Maj(a, b, c); +		h = g; +		g = f; +		f = e; +		e = d + T1; +		d = c; +		c = b; +		b = a; +		a = T1 + T2; + +		j++; +	} while (j < 16); + +	do { +		/* Part of the message block expansion: */ +		s0 = W512[(j+1)&0x0f]; +		s0 = sigma0_512(s0); +		s1 = W512[(j+14)&0x0f]; +		s1 =  sigma1_512(s1); + +		/* Apply the SHA-512 compression function to update a..h */ +		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + +		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); +		T2 = Sigma0_512(a) + Maj(a, b, c); +		h = g; +		g = f; +		f = e; +		e = d + T1; +		d = c; +		c = b; +		b = a; +		a = T1 + T2; + +		j++; +	} while (j < 80); + +	/* Compute the current intermediate hash value */ +	state[0] += a; +	state[1] += b; +	state[2] += c; +	state[3] += d; +	state[4] += e; +	state[5] += f; +	state[6] += g; +	state[7] += h; + +	/* Clean up */ +	a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ +DEF_WEAK(SHA512Transform); + +void +SHA512Update(SHA2_CTX *context, const u_int8_t *data, size_t len) +{ +	size_t	freespace, usedspace; + +	/* Calling with no data is valid (we do nothing) */ +	if (len == 0) +		return; + +	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; +	if (usedspace > 0) { +		/* Calculate how much free space is available in the buffer */ +		freespace = SHA512_BLOCK_LENGTH - usedspace; + +		if (len >= freespace) { +			/* Fill the buffer completely and process it */ +			memcpy(&context->buffer[usedspace], data, freespace); +			ADDINC128(context->bitcount, freespace << 3); +			len -= freespace; +			data += freespace; +			SHA512Transform(context->state.st64, context->buffer); +		} else { +			/* The buffer is not yet full */ +			memcpy(&context->buffer[usedspace], data, len); +			ADDINC128(context->bitcount, len << 3); +			/* Clean up: */ +			usedspace = freespace = 0; +			return; +		} +	} +	while (len >= SHA512_BLOCK_LENGTH) { +		/* Process as many complete blocks as we can */ +		SHA512Transform(context->state.st64, data); +		ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); +		len -= SHA512_BLOCK_LENGTH; +		data += SHA512_BLOCK_LENGTH; +	} +	if (len > 0) { +		/* There's left-overs, so save 'em */ +		memcpy(context->buffer, data, len); +		ADDINC128(context->bitcount, len << 3); +	} +	/* Clean up: */ +	usedspace = freespace = 0; +} +DEF_WEAK(SHA512Update); + +void +SHA512Pad(SHA2_CTX *context) +{ +	unsigned int	usedspace; + +	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; +	if (usedspace > 0) { +		/* Begin padding with a 1 bit: */ +		context->buffer[usedspace++] = 0x80; + +		if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { +			/* Set-up for the last transform: */ +			memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace); +		} else { +			if (usedspace < SHA512_BLOCK_LENGTH) { +				memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace); +			} +			/* Do second-to-last transform: */ +			SHA512Transform(context->state.st64, context->buffer); + +			/* And set-up for the last transform: */ +			memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2); +		} +	} else { +		/* Prepare for final transform: */ +		memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH); + +		/* Begin padding with a 1 bit: */ +		*context->buffer = 0x80; +	} +	/* Store the length of input data (in bits) in big endian format: */ +	BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], +	    context->bitcount[1]); +	BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8], +	    context->bitcount[0]); + +	/* Final transform: */ +	SHA512Transform(context->state.st64, context->buffer); + +	/* Clean up: */ +	usedspace = 0; +} +DEF_WEAK(SHA512Pad); + +void +SHA512Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *context) +{ +	SHA512Pad(context); + +#if BYTE_ORDER == LITTLE_ENDIAN +	int	i; + +	/* Convert TO host byte order */ +	for (i = 0; i < 8; i++) +		BE_64_TO_8(digest + i * 8, context->state.st64[i]); +#else +	memcpy(digest, context->state.st64, SHA512_DIGEST_LENGTH); +#endif +	explicit_bzero(context, sizeof(*context)); +} +DEF_WEAK(SHA512Final); + +#if !defined(SHA2_SMALL) + +/*** SHA-384: *********************************************************/ +void +SHA384Init(SHA2_CTX *context) +{ +	memcpy(context->state.st64, sha384_initial_hash_value, +	    sizeof(sha384_initial_hash_value)); +	memset(context->buffer, 0, sizeof(context->buffer)); +	context->bitcount[0] = context->bitcount[1] = 0; +} +DEF_WEAK(SHA384Init); + +MAKE_CLONE(SHA384Transform, SHA512Transform); +MAKE_CLONE(SHA384Update, SHA512Update); +MAKE_CLONE(SHA384Pad, SHA512Pad); +DEF_WEAK(SHA384Transform); +DEF_WEAK(SHA384Update); +DEF_WEAK(SHA384Pad); + +void +SHA384Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *context) +{ +	SHA384Pad(context); + +#if BYTE_ORDER == LITTLE_ENDIAN +	int	i; + +	/* Convert TO host byte order */ +	for (i = 0; i < 6; i++) +		BE_64_TO_8(digest + i * 8, context->state.st64[i]); +#else +	memcpy(digest, context->state.st64, SHA384_DIGEST_LENGTH); +#endif +	/* Zero out state data */ +	explicit_bzero(context, sizeof(*context)); +} +DEF_WEAK(SHA384Final); + +/*** SHA-512/256: *********************************************************/ +void +SHA512_256Init(SHA2_CTX *context) +{ +	memcpy(context->state.st64, sha512_256_initial_hash_value, +	    sizeof(sha512_256_initial_hash_value)); +	memset(context->buffer, 0, sizeof(context->buffer)); +	context->bitcount[0] = context->bitcount[1] = 0; +} +DEF_WEAK(SHA512_256Init); + +MAKE_CLONE(SHA512_256Transform, SHA512Transform); +MAKE_CLONE(SHA512_256Update, SHA512Update); +MAKE_CLONE(SHA512_256Pad, SHA512Pad); +DEF_WEAK(SHA512_256Transform); +DEF_WEAK(SHA512_256Update); +DEF_WEAK(SHA512_256Pad); + +void +SHA512_256Final(u_int8_t digest[SHA512_256_DIGEST_LENGTH], SHA2_CTX *context) +{ +	SHA512_256Pad(context); + +#if BYTE_ORDER == LITTLE_ENDIAN +	int	i; + +	/* Convert TO host byte order */ +	for (i = 0; i < 4; i++) +		BE_64_TO_8(digest + i * 8, context->state.st64[i]); +#else +	memcpy(digest, context->state.st64, SHA512_256_DIGEST_LENGTH); +#endif +	/* Zero out state data */ +	explicit_bzero(context, sizeof(*context)); +} +DEF_WEAK(SHA512_256Final); +#endif /* !defined(SHA2_SMALL) */ diff --git a/lib/libc/net/base64.c b/lib/libc/net/base64.c new file mode 100644 index 0000000..e90696d --- /dev/null +++ b/lib/libc/net/base64.c @@ -0,0 +1,315 @@ +/*	$OpenBSD: base64.c,v 1.8 2015/01/16 16:48:51 deraadt Exp $	*/ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software.  No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> + +#include <ctype.h> +#include <resolv.h> +#include <stdio.h> + +#include <stdlib.h> +#include <string.h> + +static const char Base64[] = +	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) +   The following encoding technique is taken from RFC 1521 by Borenstein +   and Freed.  It is reproduced here in a slightly edited form for +   convenience. + +   A 65-character subset of US-ASCII is used, enabling 6 bits to be +   represented per printable character. (The extra 65th character, "=", +   is used to signify a special processing function.) + +   The encoding process represents 24-bit groups of input bits as output +   strings of 4 encoded characters. Proceeding from left to right, a +   24-bit input group is formed by concatenating 3 8-bit input groups. +   These 24 bits are then treated as 4 concatenated 6-bit groups, each +   of which is translated into a single digit in the base64 alphabet. + +   Each 6-bit group is used as an index into an array of 64 printable +   characters. The character referenced by the index is placed in the +   output string. + +                         Table 1: The Base64 Alphabet + +      Value Encoding  Value Encoding  Value Encoding  Value Encoding +          0 A            17 R            34 i            51 z +          1 B            18 S            35 j            52 0 +          2 C            19 T            36 k            53 1 +          3 D            20 U            37 l            54 2 +          4 E            21 V            38 m            55 3 +          5 F            22 W            39 n            56 4 +          6 G            23 X            40 o            57 5 +          7 H            24 Y            41 p            58 6 +          8 I            25 Z            42 q            59 7 +          9 J            26 a            43 r            60 8 +         10 K            27 b            44 s            61 9 +         11 L            28 c            45 t            62 + +         12 M            29 d            46 u            63 / +         13 N            30 e            47 v +         14 O            31 f            48 w         (pad) = +         15 P            32 g            49 x +         16 Q            33 h            50 y + +   Special processing is performed if fewer than 24 bits are available +   at the end of the data being encoded.  A full encoding quantum is +   always completed at the end of a quantity.  When fewer than 24 input +   bits are available in an input group, zero bits are added (on the +   right) to form an integral number of 6-bit groups.  Padding at the +   end of the data is performed using the '=' character. + +   Since all base64 input is an integral number of octets, only the +         -------------------------------------------------                        +   following cases can arise: +    +       (1) the final quantum of encoding input is an integral +           multiple of 24 bits; here, the final unit of encoded +	   output will be an integral multiple of 4 characters +	   with no "=" padding, +       (2) the final quantum of encoding input is exactly 8 bits; +           here, the final unit of encoded output will be two +	   characters followed by two "=" padding characters, or +       (3) the final quantum of encoding input is exactly 16 bits; +           here, the final unit of encoded output will be three +	   characters followed by one "=" padding character. +   */ + +int +b64_ntop(src, srclength, target, targsize) +	u_char const *src; +	size_t srclength; +	char *target; +	size_t targsize; +{ +	size_t datalength = 0; +	u_char input[3]; +	u_char output[4]; +	int i; + +	while (2 < srclength) { +		input[0] = *src++; +		input[1] = *src++; +		input[2] = *src++; +		srclength -= 3; + +		output[0] = input[0] >> 2; +		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); +		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); +		output[3] = input[2] & 0x3f; + +		if (datalength + 4 > targsize) +			return (-1); +		target[datalength++] = Base64[output[0]]; +		target[datalength++] = Base64[output[1]]; +		target[datalength++] = Base64[output[2]]; +		target[datalength++] = Base64[output[3]]; +	} +     +	/* Now we worry about padding. */ +	if (0 != srclength) { +		/* Get what's left. */ +		input[0] = input[1] = input[2] = '\0'; +		for (i = 0; i < srclength; i++) +			input[i] = *src++; +	 +		output[0] = input[0] >> 2; +		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); +		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + +		if (datalength + 4 > targsize) +			return (-1); +		target[datalength++] = Base64[output[0]]; +		target[datalength++] = Base64[output[1]]; +		if (srclength == 1) +			target[datalength++] = Pad64; +		else +			target[datalength++] = Base64[output[2]]; +		target[datalength++] = Pad64; +	} +	if (datalength >= targsize) +		return (-1); +	target[datalength] = '\0';	/* Returned value doesn't count \0. */ +	return (datalength); +} + +/* skips all whitespace anywhere. +   converts characters, four at a time, starting at (or after) +   src from base - 64 numbers into three 8 bit bytes in the target area. +   it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(src, target, targsize) +	char const *src; +	u_char *target; +	size_t targsize; +{ +	int tarindex, state, ch; +	u_char nextbyte; +	char *pos; + +	state = 0; +	tarindex = 0; + +	while ((ch = (unsigned char)*src++) != '\0') { +		if (isspace(ch))	/* Skip whitespace anywhere. */ +			continue; + +		if (ch == Pad64) +			break; + +		pos = strchr(Base64, ch); +		if (pos == 0) 		/* A non-base64 character. */ +			return (-1); + +		switch (state) { +		case 0: +			if (target) { +				if (tarindex >= targsize) +					return (-1); +				target[tarindex] = (pos - Base64) << 2; +			} +			state = 1; +			break; +		case 1: +			if (target) { +				if (tarindex >= targsize) +					return (-1); +				target[tarindex]   |=  (pos - Base64) >> 4; +				nextbyte = ((pos - Base64) & 0x0f) << 4; +				if (tarindex + 1 < targsize) +					target[tarindex+1] = nextbyte; +				else if (nextbyte) +					return (-1); +			} +			tarindex++; +			state = 2; +			break; +		case 2: +			if (target) { +				if (tarindex >= targsize) +					return (-1); +				target[tarindex]   |=  (pos - Base64) >> 2; +				nextbyte = ((pos - Base64) & 0x03) << 6; +				if (tarindex + 1 < targsize) +					target[tarindex+1] = nextbyte; +				else if (nextbyte) +					return (-1); +			} +			tarindex++; +			state = 3; +			break; +		case 3: +			if (target) { +				if (tarindex >= targsize) +					return (-1); +				target[tarindex] |= (pos - Base64); +			} +			tarindex++; +			state = 0; +			break; +		} +	} + +	/* +	 * We are done decoding Base-64 chars.  Let's see if we ended +	 * on a byte boundary, and/or with erroneous trailing characters. +	 */ + +	if (ch == Pad64) {			/* We got a pad char. */ +		ch = (unsigned char)*src++;	/* Skip it, get next. */ +		switch (state) { +		case 0:		/* Invalid = in first position */ +		case 1:		/* Invalid = in second position */ +			return (-1); + +		case 2:		/* Valid, means one byte of info */ +			/* Skip any number of spaces. */ +			for (; ch != '\0'; ch = (unsigned char)*src++) +				if (!isspace(ch)) +					break; +			/* Make sure there is another trailing = sign. */ +			if (ch != Pad64) +				return (-1); +			ch = (unsigned char)*src++;		/* Skip the = */ +			/* Fall through to "single trailing =" case. */ +			/* FALLTHROUGH */ + +		case 3:		/* Valid, means two bytes of info */ +			/* +			 * We know this char is an =.  Is there anything but +			 * whitespace after it? +			 */ +			for (; ch != '\0'; ch = (unsigned char)*src++) +				if (!isspace(ch)) +					return (-1); + +			/* +			 * Now make sure for cases 2 and 3 that the "extra" +			 * bits that slopped past the last full byte were +			 * zeros.  If we don't check them, they become a +			 * subliminal channel. +			 */ +			if (target && tarindex < targsize && +			    target[tarindex] != 0) +				return (-1); +		} +	} else { +		/* +		 * We ended by seeing the end of the string.  Make sure we +		 * have no partial bytes lying around. +		 */ +		if (state != 0) +			return (-1); +	} + +	return (tarindex); +} diff --git a/lib/libc/stdlib/freezero.c b/lib/libc/stdlib/freezero.c new file mode 100644 index 0000000..31face3 --- /dev/null +++ b/lib/libc/stdlib/freezero.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> + * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> + * Copyright (c) 2008 Damien Miller <djm@openbsd.org> + * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <string.h> +#include <stdlib.h> + +void +freezero(void *ptr, size_t sz) +{ +	/* This is legal. */ +	if (ptr == NULL) +		return; + +	explicit_bzero(ptr, sz); +	free(ptr); +} diff --git a/lib/libc/stdlib/reallocarray.c b/lib/libc/stdlib/reallocarray.c new file mode 100644 index 0000000..baea252 --- /dev/null +++ b/lib/libc/stdlib/reallocarray.c @@ -0,0 +1,39 @@ +/*	$OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $	*/ +/* + * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4)) + +void * +reallocarray(void *optr, size_t nmemb, size_t size) +{ +	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && +	    nmemb > 0 && SIZE_MAX / nmemb < size) { +		errno = ENOMEM; +		return NULL; +	} +	return realloc(optr, size * nmemb); +} +DEF_WEAK(reallocarray); diff --git a/lib/libc/stdlib/recallocarray.c b/lib/libc/stdlib/recallocarray.c new file mode 100644 index 0000000..a2f37fe --- /dev/null +++ b/lib/libc/stdlib/recallocarray.c @@ -0,0 +1,81 @@ +/*	$OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $	*/ +/* + * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <errno.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) +{ +	size_t oldsize, newsize; +	void *newptr; + +	if (ptr == NULL) +		return calloc(newnmemb, size); + +	if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && +	    newnmemb > 0 && SIZE_MAX / newnmemb < size) { +		errno = ENOMEM; +		return NULL; +	} +	newsize = newnmemb * size; + +	if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && +	    oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { +		errno = EINVAL; +		return NULL; +	} +	oldsize = oldnmemb * size; +	 +	/* +	 * Don't bother too much if we're shrinking just a bit, +	 * we do not shrink for series of small steps, oh well. +	 */ +	if (newsize <= oldsize) { +		size_t d = oldsize - newsize; + +		if (d < oldsize / 2 && d < getpagesize()) { +			memset((char *)ptr + newsize, 0, d); +			return ptr; +		} +	} + +	newptr = malloc(newsize); +	if (newptr == NULL) +		return NULL; + +	if (newsize > oldsize) { +		memcpy(newptr, ptr, oldsize); +		memset((char *)newptr + oldsize, 0, newsize - oldsize); +	} else +		memcpy(newptr, ptr, newsize); + +	explicit_bzero(ptr, oldsize); +	free(ptr); + +	return newptr; +} +DEF_WEAK(recallocarray); diff --git a/lib/libc/stdlib/strtonum.c b/lib/libc/stdlib/strtonum.c new file mode 100644 index 0000000..ad22d1c --- /dev/null +++ b/lib/libc/stdlib/strtonum.c @@ -0,0 +1,66 @@ +/*	$OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $	*/ + +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <errno.h> +#include <limits.h> +#include <stdlib.h> + +#define	INVALID		1 +#define	TOOSMALL	2 +#define	TOOLARGE	3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, +    const char **errstrp) +{ +	long long ll = 0; +	int error = 0; +	char *ep; +	struct errval { +		const char *errstr; +		int err; +	} ev[4] = { +		{ NULL,		0 }, +		{ "invalid",	EINVAL }, +		{ "too small",	ERANGE }, +		{ "too large",	ERANGE }, +	}; + +	ev[0].err = errno; +	errno = 0; +	if (minval > maxval) { +		error = INVALID; +	} else { +		ll = strtoll(numstr, &ep, 10); +		if (numstr == ep || *ep != '\0') +			error = INVALID; +		else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) +			error = TOOSMALL; +		else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) +			error = TOOLARGE; +	} +	if (errstrp != NULL) +		*errstrp = ev[error].errstr; +	errno = ev[error].err; +	if (error) +		ll = 0; + +	return (ll); +} +DEF_WEAK(strtonum); diff --git a/lib/libc/string/strmode.c b/lib/libc/string/strmode.c new file mode 100644 index 0000000..609b893 --- /dev/null +++ b/lib/libc/string/strmode.c @@ -0,0 +1,141 @@ +/*	$OpenBSD: strmode.c,v 1.8 2015/08/31 02:53:57 guenther Exp $ */ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> + +/* XXX mode should be mode_t */ + +void +strmode(int mode, char *p) +{ +	 /* print type */ +	switch (mode & S_IFMT) { +	case S_IFDIR:			/* directory */ +		*p++ = 'd'; +		break; +	case S_IFCHR:			/* character special */ +		*p++ = 'c'; +		break; +	case S_IFBLK:			/* block special */ +		*p++ = 'b'; +		break; +	case S_IFREG:			/* regular */ +		*p++ = '-'; +		break; +	case S_IFLNK:			/* symbolic link */ +		*p++ = 'l'; +		break; +	case S_IFSOCK:			/* socket */ +		*p++ = 's'; +		break; +#ifdef S_IFIFO +	case S_IFIFO:			/* fifo */ +		*p++ = 'p'; +		break; +#endif +	default:			/* unknown */ +		*p++ = '?'; +		break; +	} +	/* usr */ +	if (mode & S_IRUSR) +		*p++ = 'r'; +	else +		*p++ = '-'; +	if (mode & S_IWUSR) +		*p++ = 'w'; +	else +		*p++ = '-'; +	switch (mode & (S_IXUSR | S_ISUID)) { +	case 0: +		*p++ = '-'; +		break; +	case S_IXUSR: +		*p++ = 'x'; +		break; +	case S_ISUID: +		*p++ = 'S'; +		break; +	case S_IXUSR | S_ISUID: +		*p++ = 's'; +		break; +	} +	/* group */ +	if (mode & S_IRGRP) +		*p++ = 'r'; +	else +		*p++ = '-'; +	if (mode & S_IWGRP) +		*p++ = 'w'; +	else +		*p++ = '-'; +	switch (mode & (S_IXGRP | S_ISGID)) { +	case 0: +		*p++ = '-'; +		break; +	case S_IXGRP: +		*p++ = 'x'; +		break; +	case S_ISGID: +		*p++ = 'S'; +		break; +	case S_IXGRP | S_ISGID: +		*p++ = 's'; +		break; +	} +	/* other */ +	if (mode & S_IROTH) +		*p++ = 'r'; +	else +		*p++ = '-'; +	if (mode & S_IWOTH) +		*p++ = 'w'; +	else +		*p++ = '-'; +	switch (mode & (S_IXOTH | S_ISVTX)) { +	case 0: +		*p++ = '-'; +		break; +	case S_IXOTH: +		*p++ = 'x'; +		break; +	case S_ISVTX: +		*p++ = 'T'; +		break; +	case S_IXOTH | S_ISVTX: +		*p++ = 't'; +		break; +	} +	*p++ = ' ';		/* will be a '+' if ACL's implemented */ +	*p = '\0'; +} +DEF_WEAK(strmode); diff --git a/lib/libc/string/timingsafe_bcmp.c b/lib/libc/string/timingsafe_bcmp.c new file mode 100644 index 0000000..0409ec3 --- /dev/null +++ b/lib/libc/string/timingsafe_bcmp.c @@ -0,0 +1,30 @@ +/*	$OpenBSD: timingsafe_bcmp.c,v 1.3 2015/08/31 02:53:57 guenther Exp $	*/ +/* + * Copyright (c) 2010 Damien Miller.  All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <string.h> + +int +timingsafe_bcmp(const void *b1, const void *b2, size_t n) +{ +	const unsigned char *p1 = b1, *p2 = b2; +	int ret = 0; + +	for (; n > 0; n--) +		ret |= *p1++ ^ *p2++; +	return (ret != 0); +} +DEF_WEAK(timingsafe_bcmp); diff --git a/lib/libc/string/timingsafe_memcmp.c b/lib/libc/string/timingsafe_memcmp.c new file mode 100644 index 0000000..373f8cb --- /dev/null +++ b/lib/libc/string/timingsafe_memcmp.c @@ -0,0 +1,47 @@ +/*	$OpenBSD: timingsafe_memcmp.c,v 1.2 2015/08/31 02:53:57 guenther Exp $	*/ +/* + * Copyright (c) 2014 Google Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <limits.h> +#include <string.h> + +int +timingsafe_memcmp(const void *b1, const void *b2, size_t len) +{ +        const unsigned char *p1 = b1, *p2 = b2; +        size_t i; +        int res = 0, done = 0; + +        for (i = 0; i < len; i++) { +                /* lt is -1 if p1[i] < p2[i]; else 0. */ +                int lt = (p1[i] - p2[i]) >> CHAR_BIT; + +                /* gt is -1 if p1[i] > p2[i]; else 0. */ +                int gt = (p2[i] - p1[i]) >> CHAR_BIT; + +                /* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */ +                int cmp = lt - gt; + +                /* set res = cmp if !done. */ +                res |= cmp & ~done; + +                /* set done if p1[i] != p2[i]. */ +                done |= lt | gt; +        } + +        return (res); +} +DEF_WEAK(timingsafe_memcmp); diff --git a/lib/libcrypto/arc4random/arc4random_linux.h b/lib/libcrypto/arc4random/arc4random_linux.h new file mode 100644 index 0000000..5e1cf34 --- /dev/null +++ b/lib/libcrypto/arc4random/arc4random_linux.h @@ -0,0 +1,88 @@ +/*	$OpenBSD: arc4random_linux.h,v 1.12 2019/07/11 10:37:28 inoguchi Exp $	*/ + +/* + * Copyright (c) 1996, David Mazieres <dm@uun.org> + * Copyright (c) 2008, Damien Miller <djm@openbsd.org> + * Copyright (c) 2013, Markus Friedl <markus@openbsd.org> + * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Stub functions for portability. + */ + +#include <sys/mman.h> + +#include <pthread.h> +#include <signal.h> + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx) +#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx) + +#if defined(__GLIBC__) && !(defined(__UCLIBC__) && !defined(__ARCH_USE_MMU__)) +extern void *__dso_handle; +extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *); +#define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle) +#else +#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f)) +#endif + +static inline void +_getentropy_fail(void) +{ +	raise(SIGKILL); +} + +static volatile sig_atomic_t _rs_forked; + +static inline void +_rs_forkhandler(void) +{ +	_rs_forked = 1; +} + +static inline void +_rs_forkdetect(void) +{ +	static pid_t _rs_pid = 0; +	pid_t pid = getpid(); + +        /* XXX unusual calls to clone() can bypass checks */ +	if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) { +		_rs_pid = pid; +		_rs_forked = 0; +		if (rs) +			memset(rs, 0, sizeof(*rs)); +	} +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ +	if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, +	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) +		return (-1); + +	if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, +	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { +		munmap(*rsp, sizeof(**rsp)); +		*rsp = NULL; +		return (-1); +	} + +	_ARC4_ATFORK(_rs_forkhandler); +	return (0); +} diff --git a/lib/libcrypto/md32_common.h b/lib/libcrypto/md32_common.h new file mode 100644 index 0000000..0dca617 --- /dev/null +++ b/lib/libcrypto/md32_common.h @@ -0,0 +1,345 @@ +/* $OpenBSD: md32_common.h,v 1.22 2016/11/04 13:56:04 miod Exp $ */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in + *    the documentation and/or other materials provided with the + *    distribution. + * + * 3. All advertising materials mentioning features or use of this + *    software must display the following acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + *    endorse or promote products derived from this software without + *    prior written permission. For written permission, please contact + *    licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + *    nor may "OpenSSL" appear in their names without prior written + *    permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + *    acknowledgment: + *    "This product includes software developed by the OpenSSL Project + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +/* + * This is a generic 32 bit "collector" for message digest algorithms. + * Whenever needed it collects input character stream into chunks of + * 32 bit values and invokes a block function that performs actual hash + * calculations. + * + * Porting guide. + * + * Obligatory macros: + * + * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN + *	this macro defines byte order of input stream. + * HASH_CBLOCK + *	size of a unit chunk HASH_BLOCK operates on. + * HASH_LONG + *	has to be at least 32 bit wide. + * HASH_CTX + *	context structure that at least contains following + *	members: + *		typedef struct { + *			... + *			HASH_LONG	Nl,Nh; + *			either { + *			HASH_LONG	data[HASH_LBLOCK]; + *			unsigned char	data[HASH_CBLOCK]; + *			}; + *			unsigned int	num; + *			... + *			} HASH_CTX; + *	data[] vector is expected to be zeroed upon first call to + *	HASH_UPDATE. + * HASH_UPDATE + *	name of "Update" function, implemented here. + * HASH_TRANSFORM + *	name of "Transform" function, implemented here. + * HASH_FINAL + *	name of "Final" function, implemented here. + * HASH_BLOCK_DATA_ORDER + *	name of "block" function capable of treating *unaligned* input + *	message in original (data) byte order, implemented externally. + * HASH_MAKE_STRING + *	macro convering context variables to an ASCII hash string. + * + * MD5 example: + * + *	#define DATA_ORDER_IS_LITTLE_ENDIAN + * + *	#define HASH_LONG		MD5_LONG + *	#define HASH_CTX		MD5_CTX + *	#define HASH_CBLOCK		MD5_CBLOCK + *	#define HASH_UPDATE		MD5_Update + *	#define HASH_TRANSFORM		MD5_Transform + *	#define HASH_FINAL		MD5_Final + *	#define HASH_BLOCK_DATA_ORDER	md5_block_data_order + * + *					<appro@fy.chalmers.se> + */ + +#include <stdint.h> + +#include <openssl/opensslconf.h> + +#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) +#error "DATA_ORDER must be defined!" +#endif + +#ifndef HASH_CBLOCK +#error "HASH_CBLOCK must be defined!" +#endif +#ifndef HASH_LONG +#error "HASH_LONG must be defined!" +#endif +#ifndef HASH_CTX +#error "HASH_CTX must be defined!" +#endif + +#ifndef HASH_UPDATE +#error "HASH_UPDATE must be defined!" +#endif +#ifndef HASH_TRANSFORM +#error "HASH_TRANSFORM must be defined!" +#endif +#if !defined(HASH_FINAL) && !defined(HASH_NO_FINAL) +#error "HASH_FINAL or HASH_NO_FINAL must be defined!" +#endif + +#ifndef HASH_BLOCK_DATA_ORDER +#error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif + +/* + * This common idiom is recognized by the compiler and turned into a + * CPU-specific intrinsic as appropriate.  + * e.g. GCC optimizes to roll on amd64 at -O0 + */ +static inline uint32_t ROTATE(uint32_t a, uint32_t n) +{ +	return (a<<n)|(a>>(32-n)); +} + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +#if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if (defined(__i386) || defined(__i386__) || \ +      defined(__x86_64) || defined(__x86_64__)) +    /* +     * This gives ~30-40% performance improvement in SHA-256 compiled +     * with gcc [on P4]. Well, first macro to be frank. We can pull +     * this trick on x86* platforms only, because these CPUs can fetch +     * unaligned data without raising an exception. +     */ +#  define HOST_c2l(c,l)	({ unsigned int r=*((const unsigned int *)(c));	\ +				   asm ("bswapl %0":"=r"(r):"0"(r));	\ +				   (c)+=4; (l)=r;			}) +#  define HOST_l2c(l,c)	({ unsigned int r=(l);			\ +				   asm ("bswapl %0":"=r"(r):"0"(r));	\ +				   *((unsigned int *)(c))=r; (c)+=4;	}) +# endif +#endif + +#ifndef HOST_c2l +#define HOST_c2l(c,l) do {l =(((unsigned long)(*((c)++)))<<24);	\ +			  l|=(((unsigned long)(*((c)++)))<<16);	\ +			  l|=(((unsigned long)(*((c)++)))<< 8);	\ +			  l|=(((unsigned long)(*((c)++)))    );	\ +		      } while (0) +#endif +#ifndef HOST_l2c +#define HOST_l2c(l,c) do {*((c)++)=(unsigned char)(((l)>>24)&0xff);	\ +			  *((c)++)=(unsigned char)(((l)>>16)&0xff);	\ +			  *((c)++)=(unsigned char)(((l)>> 8)&0xff);	\ +			  *((c)++)=(unsigned char)(((l)    )&0xff);	\ +		      } while (0) +#endif + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +#  define HOST_c2l(c,l)	((l)=*((const unsigned int *)(c)), (c)+=4) +#  define HOST_l2c(l,c)	(*((unsigned int *)(c))=(l), (c)+=4) +#endif + +#ifndef HOST_c2l +#define HOST_c2l(c,l) do {l =(((unsigned long)(*((c)++)))    );	\ +			  l|=(((unsigned long)(*((c)++)))<< 8);	\ +			  l|=(((unsigned long)(*((c)++)))<<16);	\ +			  l|=(((unsigned long)(*((c)++)))<<24);	\ +		      } while (0) +#endif +#ifndef HOST_l2c +#define HOST_l2c(l,c) do {*((c)++)=(unsigned char)(((l)    )&0xff);	\ +			  *((c)++)=(unsigned char)(((l)>> 8)&0xff);	\ +			  *((c)++)=(unsigned char)(((l)>>16)&0xff);	\ +			  *((c)++)=(unsigned char)(((l)>>24)&0xff);	\ +		      } while (0) +#endif + +#endif + +/* + * Time for some action:-) + */ + +int +HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) +{ +	const unsigned char *data = data_; +	unsigned char *p; +	HASH_LONG l; +	size_t n; + +	if (len == 0) +		return 1; + +	l = (c->Nl + (((HASH_LONG)len) << 3))&0xffffffffUL; +	/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to +	 * Wei Dai <weidai@eskimo.com> for pointing it out. */ +	if (l < c->Nl) /* overflow */ +		c->Nh++; +	c->Nh+=(HASH_LONG)(len>>29);	/* might cause compiler warning on 16-bit */ +	c->Nl = l; + +	n = c->num; +	if (n != 0) { +		p = (unsigned char *)c->data; + +		if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { +			memcpy (p + n, data, HASH_CBLOCK - n); +			HASH_BLOCK_DATA_ORDER (c, p, 1); +			n = HASH_CBLOCK - n; +			data += n; +			len -= n; +			c->num = 0; +			memset (p,0,HASH_CBLOCK);	/* keep it zeroed */ +		} else { +			memcpy (p + n, data, len); +			c->num += (unsigned int)len; +			return 1; +		} +	} + +	n = len/HASH_CBLOCK; +	if (n > 0) { +		HASH_BLOCK_DATA_ORDER (c, data, n); +		n    *= HASH_CBLOCK; +		data += n; +		len -= n; +	} + +	if (len != 0) { +		p = (unsigned char *)c->data; +		c->num = (unsigned int)len; +		memcpy (p, data, len); +	} +	return 1; +} + + +void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data) +{ +	HASH_BLOCK_DATA_ORDER (c, data, 1); +} + + +#ifndef HASH_NO_FINAL +int HASH_FINAL (unsigned char *md, HASH_CTX *c) +{ +	unsigned char *p = (unsigned char *)c->data; +	size_t n = c->num; + +	p[n] = 0x80; /* there is always room for one */ +	n++; + +	if (n > (HASH_CBLOCK - 8)) { +		memset (p + n, 0, HASH_CBLOCK - n); +		n = 0; +		HASH_BLOCK_DATA_ORDER (c, p, 1); +	} +	memset (p + n, 0, HASH_CBLOCK - 8 - n); + +	p += HASH_CBLOCK - 8; +#if   defined(DATA_ORDER_IS_BIG_ENDIAN) +	HOST_l2c(c->Nh, p); +	HOST_l2c(c->Nl, p); +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) +	HOST_l2c(c->Nl, p); +	HOST_l2c(c->Nh, p); +#endif +	p -= HASH_CBLOCK; +	HASH_BLOCK_DATA_ORDER (c, p, 1); +	c->num = 0; +	memset (p, 0, HASH_CBLOCK); + +#ifndef HASH_MAKE_STRING +#error "HASH_MAKE_STRING must be defined!" +#else +	HASH_MAKE_STRING(c, md); +#endif + +	return 1; +} +#endif + +#ifndef MD32_REG_T +#if defined(__alpha) || defined(__sparcv9) || defined(__mips) +#define MD32_REG_T long +/* + * This comment was originaly written for MD5, which is why it + * discusses A-D. But it basically applies to all 32-bit digests, + * which is why it was moved to common header file. + * + * In case you wonder why A-D are declared as long and not + * as MD5_LONG. Doing so results in slight performance + * boost on LP64 architectures. The catch is we don't + * really care if 32 MSBs of a 64-bit register get polluted + * with eventual overflows as we *save* only 32 LSBs in + * *either* case. Now declaring 'em long excuses the compiler + * from keeping 32 MSBs zeroed resulting in 13% performance + * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. + * Well, to be honest it should say that this *prevents* + * performance degradation. + *				<appro@fy.chalmers.se> + */ +#else +/* + * Above is not absolute and there are LP64 compilers that + * generate better code if MD32_REG_T is defined int. The above + * pre-processor condition reflects the circumstances under which + * the conclusion was made and is subject to further extension. + *				<appro@fy.chalmers.se> + */ +#define MD32_REG_T int +#endif +#endif diff --git a/lib/libcrypto/sha/sha256.c b/lib/libcrypto/sha/sha256.c new file mode 100644 index 0000000..9c05d3b --- /dev/null +++ b/lib/libcrypto/sha/sha256.c @@ -0,0 +1,284 @@ +/* $OpenBSD: sha256.c,v 1.10 2019/01/21 23:20:31 jsg Exp $ */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project.  All rights reserved + * according to the OpenSSL license [found in ../../LICENSE]. + * ==================================================================== + */ + +#include <openssl/opensslconf.h> + +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) + +#include <machine/endian.h> + +#include <stdlib.h> +#include <string.h> + +#include <openssl/crypto.h> +#include <openssl/sha.h> +#include <openssl/opensslv.h> + +int SHA224_Init(SHA256_CTX *c) +	{ +	memset (c,0,sizeof(*c)); +	c->h[0]=0xc1059ed8UL;	c->h[1]=0x367cd507UL; +	c->h[2]=0x3070dd17UL;	c->h[3]=0xf70e5939UL; +	c->h[4]=0xffc00b31UL;	c->h[5]=0x68581511UL; +	c->h[6]=0x64f98fa7UL;	c->h[7]=0xbefa4fa4UL; +	c->md_len=SHA224_DIGEST_LENGTH; +	return 1; +	} + +int SHA256_Init(SHA256_CTX *c) +	{ +	memset (c,0,sizeof(*c)); +	c->h[0]=0x6a09e667UL;	c->h[1]=0xbb67ae85UL; +	c->h[2]=0x3c6ef372UL;	c->h[3]=0xa54ff53aUL; +	c->h[4]=0x510e527fUL;	c->h[5]=0x9b05688cUL; +	c->h[6]=0x1f83d9abUL;	c->h[7]=0x5be0cd19UL; +	c->md_len=SHA256_DIGEST_LENGTH; +	return 1; +	} + +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) +	{ +	SHA256_CTX c; +	static unsigned char m[SHA224_DIGEST_LENGTH]; + +	if (md == NULL) md=m; +	SHA224_Init(&c); +	SHA256_Update(&c,d,n); +	SHA256_Final(md,&c); +	explicit_bzero(&c,sizeof(c)); +	return(md); +	} + +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) +	{ +	SHA256_CTX c; +	static unsigned char m[SHA256_DIGEST_LENGTH]; + +	if (md == NULL) md=m; +	SHA256_Init(&c); +	SHA256_Update(&c,d,n); +	SHA256_Final(md,&c); +	explicit_bzero(&c,sizeof(c)); +	return(md); +	} + +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) +{   return SHA256_Update (c,data,len);   } +int SHA224_Final (unsigned char *md, SHA256_CTX *c) +{   return SHA256_Final (md,c);   } + +#define	DATA_ORDER_IS_BIG_ENDIAN + +#define	HASH_LONG		SHA_LONG +#define	HASH_CTX		SHA256_CTX +#define	HASH_CBLOCK		SHA_CBLOCK +/* + * Note that FIPS180-2 discusses "Truncation of the Hash Function Output." + * default: case below covers for it. It's not clear however if it's + * permitted to truncate to amount of bytes not divisible by 4. I bet not, + * but if it is, then default: case shall be extended. For reference. + * Idea behind separate cases for pre-defined lengths is to let the + * compiler decide if it's appropriate to unroll small loops. + */ +#define	HASH_MAKE_STRING(c,s)	do {	\ +	unsigned long ll;		\ +	unsigned int  nn;		\ +	switch ((c)->md_len)		\ +	{   case SHA224_DIGEST_LENGTH:	\ +		for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++)	\ +		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\ +		break;			\ +	    case SHA256_DIGEST_LENGTH:	\ +		for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++)	\ +		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\ +		break;			\ +	    default:			\ +		if ((c)->md_len > SHA256_DIGEST_LENGTH)	\ +		    return 0;				\ +		for (nn=0;nn<(c)->md_len/4;nn++)		\ +		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\ +		break;			\ +	}				\ +	} while (0) + +#define	HASH_UPDATE		SHA256_Update +#define	HASH_TRANSFORM		SHA256_Transform +#define	HASH_FINAL		SHA256_Final +#define	HASH_BLOCK_DATA_ORDER	sha256_block_data_order +#ifndef SHA256_ASM +static +#endif +void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num); + +#include "md32_common.h" + +#ifndef SHA256_ASM +static const SHA_LONG K256[64] = { +	0x428a2f98UL,0x71374491UL,0xb5c0fbcfUL,0xe9b5dba5UL, +	0x3956c25bUL,0x59f111f1UL,0x923f82a4UL,0xab1c5ed5UL, +	0xd807aa98UL,0x12835b01UL,0x243185beUL,0x550c7dc3UL, +	0x72be5d74UL,0x80deb1feUL,0x9bdc06a7UL,0xc19bf174UL, +	0xe49b69c1UL,0xefbe4786UL,0x0fc19dc6UL,0x240ca1ccUL, +	0x2de92c6fUL,0x4a7484aaUL,0x5cb0a9dcUL,0x76f988daUL, +	0x983e5152UL,0xa831c66dUL,0xb00327c8UL,0xbf597fc7UL, +	0xc6e00bf3UL,0xd5a79147UL,0x06ca6351UL,0x14292967UL, +	0x27b70a85UL,0x2e1b2138UL,0x4d2c6dfcUL,0x53380d13UL, +	0x650a7354UL,0x766a0abbUL,0x81c2c92eUL,0x92722c85UL, +	0xa2bfe8a1UL,0xa81a664bUL,0xc24b8b70UL,0xc76c51a3UL, +	0xd192e819UL,0xd6990624UL,0xf40e3585UL,0x106aa070UL, +	0x19a4c116UL,0x1e376c08UL,0x2748774cUL,0x34b0bcb5UL, +	0x391c0cb3UL,0x4ed8aa4aUL,0x5b9cca4fUL,0x682e6ff3UL, +	0x748f82eeUL,0x78a5636fUL,0x84c87814UL,0x8cc70208UL, +	0x90befffaUL,0xa4506cebUL,0xbef9a3f7UL,0xc67178f2UL }; + +/* + * FIPS specification refers to right rotations, while our ROTATE macro + * is left one. This is why you might notice that rotation coefficients + * differ from those observed in FIPS document by 32-N... + */ +#define Sigma0(x)	(ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10)) +#define Sigma1(x)	(ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7)) +#define sigma0(x)	(ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3)) +#define sigma1(x)	(ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10)) + +#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#ifdef OPENSSL_SMALL_FOOTPRINT + +static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num) +	{ +	unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1,T2; +	SHA_LONG	X[16],l; +	int i; +	const unsigned char *data=in; + +			while (num--) { + +	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3]; +	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7]; + +	for (i=0;i<16;i++) +		{ +		HOST_c2l(data,l); T1 = X[i] = l; +		T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; +		T2 = Sigma0(a) + Maj(a,b,c); +		h = g;	g = f;	f = e;	e = d + T1; +		d = c;	c = b;	b = a;	a = T1 + T2; +		} + +	for (;i<64;i++) +		{ +		s0 = X[(i+1)&0x0f];	s0 = sigma0(s0); +		s1 = X[(i+14)&0x0f];	s1 = sigma1(s1); + +		T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf]; +		T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; +		T2 = Sigma0(a) + Maj(a,b,c); +		h = g;	g = f;	f = e;	e = d + T1; +		d = c;	c = b;	b = a;	a = T1 + T2; +		} + +	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d; +	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h; + +			} +} + +#else + +#define	ROUND_00_15(i,a,b,c,d,e,f,g,h)		do {	\ +	T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];	\ +	h = Sigma0(a) + Maj(a,b,c);			\ +	d += T1;	h += T1;		} while (0) + +#define	ROUND_16_63(i,a,b,c,d,e,f,g,h,X)	do {	\ +	s0 = X[(i+1)&0x0f];	s0 = sigma0(s0);	\ +	s1 = X[(i+14)&0x0f];	s1 = sigma1(s1);	\ +	T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f];	\ +	ROUND_00_15(i,a,b,c,d,e,f,g,h);		} while (0) + +static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num) +	{ +	unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1; +	SHA_LONG	X[16]; +	int i; +	const unsigned char *data=in; + +			while (num--) { + +	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3]; +	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7]; + +	if (BYTE_ORDER != LITTLE_ENDIAN && +	    sizeof(SHA_LONG)==4 && ((size_t)in%4)==0) +		{ +		const SHA_LONG *W=(const SHA_LONG *)data; + +		T1 = X[0] = W[0];	ROUND_00_15(0,a,b,c,d,e,f,g,h); +		T1 = X[1] = W[1];	ROUND_00_15(1,h,a,b,c,d,e,f,g); +		T1 = X[2] = W[2];	ROUND_00_15(2,g,h,a,b,c,d,e,f); +		T1 = X[3] = W[3];	ROUND_00_15(3,f,g,h,a,b,c,d,e); +		T1 = X[4] = W[4];	ROUND_00_15(4,e,f,g,h,a,b,c,d); +		T1 = X[5] = W[5];	ROUND_00_15(5,d,e,f,g,h,a,b,c); +		T1 = X[6] = W[6];	ROUND_00_15(6,c,d,e,f,g,h,a,b); +		T1 = X[7] = W[7];	ROUND_00_15(7,b,c,d,e,f,g,h,a); +		T1 = X[8] = W[8];	ROUND_00_15(8,a,b,c,d,e,f,g,h); +		T1 = X[9] = W[9];	ROUND_00_15(9,h,a,b,c,d,e,f,g); +		T1 = X[10] = W[10];	ROUND_00_15(10,g,h,a,b,c,d,e,f); +		T1 = X[11] = W[11];	ROUND_00_15(11,f,g,h,a,b,c,d,e); +		T1 = X[12] = W[12];	ROUND_00_15(12,e,f,g,h,a,b,c,d); +		T1 = X[13] = W[13];	ROUND_00_15(13,d,e,f,g,h,a,b,c); +		T1 = X[14] = W[14];	ROUND_00_15(14,c,d,e,f,g,h,a,b); +		T1 = X[15] = W[15];	ROUND_00_15(15,b,c,d,e,f,g,h,a); + +		data += SHA256_CBLOCK; +		} +	else +		{ +		SHA_LONG l; + +		HOST_c2l(data,l); T1 = X[0] = l;  ROUND_00_15(0,a,b,c,d,e,f,g,h); +		HOST_c2l(data,l); T1 = X[1] = l;  ROUND_00_15(1,h,a,b,c,d,e,f,g); +		HOST_c2l(data,l); T1 = X[2] = l;  ROUND_00_15(2,g,h,a,b,c,d,e,f); +		HOST_c2l(data,l); T1 = X[3] = l;  ROUND_00_15(3,f,g,h,a,b,c,d,e); +		HOST_c2l(data,l); T1 = X[4] = l;  ROUND_00_15(4,e,f,g,h,a,b,c,d); +		HOST_c2l(data,l); T1 = X[5] = l;  ROUND_00_15(5,d,e,f,g,h,a,b,c); +		HOST_c2l(data,l); T1 = X[6] = l;  ROUND_00_15(6,c,d,e,f,g,h,a,b); +		HOST_c2l(data,l); T1 = X[7] = l;  ROUND_00_15(7,b,c,d,e,f,g,h,a); +		HOST_c2l(data,l); T1 = X[8] = l;  ROUND_00_15(8,a,b,c,d,e,f,g,h); +		HOST_c2l(data,l); T1 = X[9] = l;  ROUND_00_15(9,h,a,b,c,d,e,f,g); +		HOST_c2l(data,l); T1 = X[10] = l; ROUND_00_15(10,g,h,a,b,c,d,e,f); +		HOST_c2l(data,l); T1 = X[11] = l; ROUND_00_15(11,f,g,h,a,b,c,d,e); +		HOST_c2l(data,l); T1 = X[12] = l; ROUND_00_15(12,e,f,g,h,a,b,c,d); +		HOST_c2l(data,l); T1 = X[13] = l; ROUND_00_15(13,d,e,f,g,h,a,b,c); +		HOST_c2l(data,l); T1 = X[14] = l; ROUND_00_15(14,c,d,e,f,g,h,a,b); +		HOST_c2l(data,l); T1 = X[15] = l; ROUND_00_15(15,b,c,d,e,f,g,h,a); +		} + +	for (i=16;i<64;i+=8) +		{ +		ROUND_16_63(i+0,a,b,c,d,e,f,g,h,X); +		ROUND_16_63(i+1,h,a,b,c,d,e,f,g,X); +		ROUND_16_63(i+2,g,h,a,b,c,d,e,f,X); +		ROUND_16_63(i+3,f,g,h,a,b,c,d,e,X); +		ROUND_16_63(i+4,e,f,g,h,a,b,c,d,X); +		ROUND_16_63(i+5,d,e,f,g,h,a,b,c,X); +		ROUND_16_63(i+6,c,d,e,f,g,h,a,b,X); +		ROUND_16_63(i+7,b,c,d,e,f,g,h,a,X); +		} + +	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d; +	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h; + +			} +	} + +#endif +#endif /* SHA256_ASM */ + +#endif /* OPENSSL_NO_SHA256 */ diff --git a/lib/libcrypto/sha/sha512.c b/lib/libcrypto/sha/sha512.c new file mode 100644 index 0000000..6b95cfa --- /dev/null +++ b/lib/libcrypto/sha/sha512.c @@ -0,0 +1,547 @@ +/* $OpenBSD: sha512.c,v 1.15 2016/11/04 13:56:05 miod Exp $ */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project.  All rights reserved + * according to the OpenSSL license [found in ../../LICENSE]. + * ==================================================================== + */ + +#include <machine/endian.h> + +#include <stdlib.h> +#include <string.h> + +#include <openssl/opensslconf.h> + +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) +/* + * IMPLEMENTATION NOTES. + * + * As you might have noticed 32-bit hash algorithms: + * + * - permit SHA_LONG to be wider than 32-bit (case on CRAY); + * - optimized versions implement two transform functions: one operating + *   on [aligned] data in host byte order and one - on data in input + *   stream byte order; + * - share common byte-order neutral collector and padding function + *   implementations, ../md32_common.h; + * + * Neither of the above applies to this SHA-512 implementations. Reasons + * [in reverse order] are: + * + * - it's the only 64-bit hash algorithm for the moment of this writing, + *   there is no need for common collector/padding implementation [yet]; + * - by supporting only one transform function [which operates on + *   *aligned* data in input stream byte order, big-endian in this case] + *   we minimize burden of maintenance in two ways: a) collector/padding + *   function is simpler; b) only one transform function to stare at; + * - SHA_LONG64 is required to be exactly 64-bit in order to be able to + *   apply a number of optimizations to mitigate potential performance + *   penalties caused by previous design decision; + * + * Caveat lector. + * + * Implementation relies on the fact that "long long" is 64-bit on + * both 32- and 64-bit platforms. If some compiler vendor comes up + * with 128-bit long long, adjustment to sha.h would be required. + * As this implementation relies on 64-bit integer type, it's totally + * inappropriate for platforms which don't support it, most notably + * 16-bit platforms. + *					<appro@fy.chalmers.se> + */ + +#include <openssl/crypto.h> +#include <openssl/opensslv.h> +#include <openssl/sha.h> + +#if !defined(__STRICT_ALIGNMENT) || defined(SHA512_ASM) +#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA +#endif + +int SHA384_Init(SHA512_CTX *c) +	{ +	c->h[0]=U64(0xcbbb9d5dc1059ed8); +	c->h[1]=U64(0x629a292a367cd507); +	c->h[2]=U64(0x9159015a3070dd17); +	c->h[3]=U64(0x152fecd8f70e5939); +	c->h[4]=U64(0x67332667ffc00b31); +	c->h[5]=U64(0x8eb44a8768581511); +	c->h[6]=U64(0xdb0c2e0d64f98fa7); +	c->h[7]=U64(0x47b5481dbefa4fa4); + +        c->Nl=0;        c->Nh=0; +        c->num=0;       c->md_len=SHA384_DIGEST_LENGTH; +        return 1; +	} + +int SHA512_Init(SHA512_CTX *c) +	{ +	c->h[0]=U64(0x6a09e667f3bcc908); +	c->h[1]=U64(0xbb67ae8584caa73b); +	c->h[2]=U64(0x3c6ef372fe94f82b); +	c->h[3]=U64(0xa54ff53a5f1d36f1); +	c->h[4]=U64(0x510e527fade682d1); +	c->h[5]=U64(0x9b05688c2b3e6c1f); +	c->h[6]=U64(0x1f83d9abfb41bd6b); +	c->h[7]=U64(0x5be0cd19137e2179); + +        c->Nl=0;        c->Nh=0; +        c->num=0;       c->md_len=SHA512_DIGEST_LENGTH; +        return 1; +	} + +#ifndef SHA512_ASM +static +#endif +void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num); + +int SHA512_Final (unsigned char *md, SHA512_CTX *c) +	{ +	unsigned char *p=(unsigned char *)c->u.p; +	size_t n=c->num; + +	p[n]=0x80;	/* There always is a room for one */ +	n++; +	if (n > (sizeof(c->u)-16)) +		memset (p+n,0,sizeof(c->u)-n), n=0, +		sha512_block_data_order (c,p,1); + +	memset (p+n,0,sizeof(c->u)-16-n); +#if BYTE_ORDER == BIG_ENDIAN +	c->u.d[SHA_LBLOCK-2] = c->Nh; +	c->u.d[SHA_LBLOCK-1] = c->Nl; +#else +	p[sizeof(c->u)-1]  = (unsigned char)(c->Nl); +	p[sizeof(c->u)-2]  = (unsigned char)(c->Nl>>8); +	p[sizeof(c->u)-3]  = (unsigned char)(c->Nl>>16); +	p[sizeof(c->u)-4]  = (unsigned char)(c->Nl>>24); +	p[sizeof(c->u)-5]  = (unsigned char)(c->Nl>>32); +	p[sizeof(c->u)-6]  = (unsigned char)(c->Nl>>40); +	p[sizeof(c->u)-7]  = (unsigned char)(c->Nl>>48); +	p[sizeof(c->u)-8]  = (unsigned char)(c->Nl>>56); +	p[sizeof(c->u)-9]  = (unsigned char)(c->Nh); +	p[sizeof(c->u)-10] = (unsigned char)(c->Nh>>8); +	p[sizeof(c->u)-11] = (unsigned char)(c->Nh>>16); +	p[sizeof(c->u)-12] = (unsigned char)(c->Nh>>24); +	p[sizeof(c->u)-13] = (unsigned char)(c->Nh>>32); +	p[sizeof(c->u)-14] = (unsigned char)(c->Nh>>40); +	p[sizeof(c->u)-15] = (unsigned char)(c->Nh>>48); +	p[sizeof(c->u)-16] = (unsigned char)(c->Nh>>56); +#endif + +	sha512_block_data_order (c,p,1); + +	if (md==0) return 0; + +	switch (c->md_len) +		{ +		/* Let compiler decide if it's appropriate to unroll... */ +		case SHA384_DIGEST_LENGTH: +			for (n=0;n<SHA384_DIGEST_LENGTH/8;n++) +				{ +				SHA_LONG64 t = c->h[n]; + +				*(md++)	= (unsigned char)(t>>56); +				*(md++)	= (unsigned char)(t>>48); +				*(md++)	= (unsigned char)(t>>40); +				*(md++)	= (unsigned char)(t>>32); +				*(md++)	= (unsigned char)(t>>24); +				*(md++)	= (unsigned char)(t>>16); +				*(md++)	= (unsigned char)(t>>8); +				*(md++)	= (unsigned char)(t); +				} +			break; +		case SHA512_DIGEST_LENGTH: +			for (n=0;n<SHA512_DIGEST_LENGTH/8;n++) +				{ +				SHA_LONG64 t = c->h[n]; + +				*(md++)	= (unsigned char)(t>>56); +				*(md++)	= (unsigned char)(t>>48); +				*(md++)	= (unsigned char)(t>>40); +				*(md++)	= (unsigned char)(t>>32); +				*(md++)	= (unsigned char)(t>>24); +				*(md++)	= (unsigned char)(t>>16); +				*(md++)	= (unsigned char)(t>>8); +				*(md++)	= (unsigned char)(t); +				} +			break; +		/* ... as well as make sure md_len is not abused. */ +		default:	return 0; +		} + +	return 1; +	} + +int SHA384_Final (unsigned char *md,SHA512_CTX *c) +{   return SHA512_Final (md,c);   } + +int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len) +	{ +	SHA_LONG64	l; +	unsigned char  *p=c->u.p; +	const unsigned char *data=(const unsigned char *)_data; + +	if (len==0) return  1; + +	l = (c->Nl+(((SHA_LONG64)len)<<3))&U64(0xffffffffffffffff); +	if (l < c->Nl)		c->Nh++; +	if (sizeof(len)>=8)	c->Nh+=(((SHA_LONG64)len)>>61); +	c->Nl=l; + +	if (c->num != 0) +		{ +		size_t n = sizeof(c->u) - c->num; + +		if (len < n) +			{ +			memcpy (p+c->num,data,len), c->num += (unsigned int)len; +			return 1; +			} +		else	{ +			memcpy (p+c->num,data,n), c->num = 0; +			len-=n, data+=n; +			sha512_block_data_order (c,p,1); +			} +		} + +	if (len >= sizeof(c->u)) +		{ +#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA +		if ((size_t)data%sizeof(c->u.d[0]) != 0) +			while (len >= sizeof(c->u)) +				memcpy (p,data,sizeof(c->u)), +				sha512_block_data_order (c,p,1), +				len  -= sizeof(c->u), +				data += sizeof(c->u); +		else +#endif +			sha512_block_data_order (c,data,len/sizeof(c->u)), +			data += len, +			len  %= sizeof(c->u), +			data -= len; +		} + +	if (len != 0)	memcpy (p,data,len), c->num = (int)len; + +	return 1; +	} + +int SHA384_Update (SHA512_CTX *c, const void *data, size_t len) +{   return SHA512_Update (c,data,len);   } + +void SHA512_Transform (SHA512_CTX *c, const unsigned char *data) +	{ +#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA +	if ((size_t)data%sizeof(c->u.d[0]) != 0) +		memcpy(c->u.p,data,sizeof(c->u.p)), +		data = c->u.p; +#endif +	sha512_block_data_order (c,data,1); +	} + +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md) +	{ +	SHA512_CTX c; +	static unsigned char m[SHA384_DIGEST_LENGTH]; + +	if (md == NULL) md=m; +	SHA384_Init(&c); +	SHA512_Update(&c,d,n); +	SHA512_Final(md,&c); +	explicit_bzero(&c,sizeof(c)); +	return(md); +	} + +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md) +	{ +	SHA512_CTX c; +	static unsigned char m[SHA512_DIGEST_LENGTH]; + +	if (md == NULL) md=m; +	SHA512_Init(&c); +	SHA512_Update(&c,d,n); +	SHA512_Final(md,&c); +	explicit_bzero(&c,sizeof(c)); +	return(md); +	} + +#ifndef SHA512_ASM +static const SHA_LONG64 K512[80] = { +        U64(0x428a2f98d728ae22),U64(0x7137449123ef65cd), +        U64(0xb5c0fbcfec4d3b2f),U64(0xe9b5dba58189dbbc), +        U64(0x3956c25bf348b538),U64(0x59f111f1b605d019), +        U64(0x923f82a4af194f9b),U64(0xab1c5ed5da6d8118), +        U64(0xd807aa98a3030242),U64(0x12835b0145706fbe), +        U64(0x243185be4ee4b28c),U64(0x550c7dc3d5ffb4e2), +        U64(0x72be5d74f27b896f),U64(0x80deb1fe3b1696b1), +        U64(0x9bdc06a725c71235),U64(0xc19bf174cf692694), +        U64(0xe49b69c19ef14ad2),U64(0xefbe4786384f25e3), +        U64(0x0fc19dc68b8cd5b5),U64(0x240ca1cc77ac9c65), +        U64(0x2de92c6f592b0275),U64(0x4a7484aa6ea6e483), +        U64(0x5cb0a9dcbd41fbd4),U64(0x76f988da831153b5), +        U64(0x983e5152ee66dfab),U64(0xa831c66d2db43210), +        U64(0xb00327c898fb213f),U64(0xbf597fc7beef0ee4), +        U64(0xc6e00bf33da88fc2),U64(0xd5a79147930aa725), +        U64(0x06ca6351e003826f),U64(0x142929670a0e6e70), +        U64(0x27b70a8546d22ffc),U64(0x2e1b21385c26c926), +        U64(0x4d2c6dfc5ac42aed),U64(0x53380d139d95b3df), +        U64(0x650a73548baf63de),U64(0x766a0abb3c77b2a8), +        U64(0x81c2c92e47edaee6),U64(0x92722c851482353b), +        U64(0xa2bfe8a14cf10364),U64(0xa81a664bbc423001), +        U64(0xc24b8b70d0f89791),U64(0xc76c51a30654be30), +        U64(0xd192e819d6ef5218),U64(0xd69906245565a910), +        U64(0xf40e35855771202a),U64(0x106aa07032bbd1b8), +        U64(0x19a4c116b8d2d0c8),U64(0x1e376c085141ab53), +        U64(0x2748774cdf8eeb99),U64(0x34b0bcb5e19b48a8), +        U64(0x391c0cb3c5c95a63),U64(0x4ed8aa4ae3418acb), +        U64(0x5b9cca4f7763e373),U64(0x682e6ff3d6b2b8a3), +        U64(0x748f82ee5defb2fc),U64(0x78a5636f43172f60), +        U64(0x84c87814a1f0ab72),U64(0x8cc702081a6439ec), +        U64(0x90befffa23631e28),U64(0xa4506cebde82bde9), +        U64(0xbef9a3f7b2c67915),U64(0xc67178f2e372532b), +        U64(0xca273eceea26619c),U64(0xd186b8c721c0c207), +        U64(0xeada7dd6cde0eb1e),U64(0xf57d4f7fee6ed178), +        U64(0x06f067aa72176fba),U64(0x0a637dc5a2c898a6), +        U64(0x113f9804bef90dae),U64(0x1b710b35131c471b), +        U64(0x28db77f523047d84),U64(0x32caab7b40c72493), +        U64(0x3c9ebe0a15c9bebc),U64(0x431d67c49c100d4c), +        U64(0x4cc5d4becb3e42b6),U64(0x597f299cfc657e2a), +        U64(0x5fcb6fab3ad6faec),U64(0x6c44198c4a475817) }; + +#if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__x86_64) || defined(__x86_64__) +#  define ROTR(a,n)	({ SHA_LONG64 ret;		\ +				asm ("rorq %1,%0"	\ +				: "=r"(ret)		\ +				: "J"(n),"0"(a)		\ +				: "cc"); ret;		}) +#   define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x)));	\ +				asm ("bswapq	%0"		\ +				: "=r"(ret)			\ +				: "0"(ret)); ret;		}) +# elif (defined(__i386) || defined(__i386__)) +#   define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ +			 unsigned int hi=p[0],lo=p[1];		\ +				asm ("bswapl %0; bswapl %1;"	\ +				: "=r"(lo),"=r"(hi)		\ +				: "0"(lo),"1"(hi));		\ +				((SHA_LONG64)hi)<<32|lo;	}) +# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) +#  define ROTR(a,n)	({ SHA_LONG64 ret;		\ +				asm ("rotrdi %0,%1,%2"	\ +				: "=r"(ret)		\ +				: "r"(a),"K"(n)); ret;	}) +# endif +#endif + +#ifndef PULL64 +#define B(x,j)    (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8)) +#define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7)) +#endif + +#ifndef ROTR +#define ROTR(x,s)	(((x)>>s) | (x)<<(64-s)) +#endif + +#define Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) +#define Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) +#define sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7)) +#define sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) + +#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) +/* + * This code should give better results on 32-bit CPU with less than + * ~24 registers, both size and performance wise... + */ +static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) +	{ +	const SHA_LONG64 *W=in; +	SHA_LONG64	A,E,T; +	SHA_LONG64	X[9+80],*F; +	int i; + +			while (num--) { + +	F    = X+80; +	A    = ctx->h[0];	F[1] = ctx->h[1]; +	F[2] = ctx->h[2];	F[3] = ctx->h[3]; +	E    = ctx->h[4];	F[5] = ctx->h[5]; +	F[6] = ctx->h[6];	F[7] = ctx->h[7]; + +	for (i=0;i<16;i++,F--) +		{ +		T = PULL64(W[i]); +		F[0] = A; +		F[4] = E; +		F[8] = T; +		T   += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i]; +		E    = F[3] + T; +		A    = T + Sigma0(A) + Maj(A,F[1],F[2]); +		} + +	for (;i<80;i++,F--) +		{ +		T    = sigma0(F[8+16-1]); +		T   += sigma1(F[8+16-14]); +		T   += F[8+16] + F[8+16-9]; + +		F[0] = A; +		F[4] = E; +		F[8] = T; +		T   += F[7] + Sigma1(E) + Ch(E,F[5],F[6]) + K512[i]; +		E    = F[3] + T; +		A    = T + Sigma0(A) + Maj(A,F[1],F[2]); +		} + +	ctx->h[0] += A;		ctx->h[1] += F[1]; +	ctx->h[2] += F[2];	ctx->h[3] += F[3]; +	ctx->h[4] += E;		ctx->h[5] += F[5]; +	ctx->h[6] += F[6];	ctx->h[7] += F[7]; + +			W+=SHA_LBLOCK; +			} +	} + +#elif defined(OPENSSL_SMALL_FOOTPRINT) + +static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) +	{ +	const SHA_LONG64 *W=in; +	SHA_LONG64	a,b,c,d,e,f,g,h,s0,s1,T1,T2; +	SHA_LONG64	X[16]; +	int i; + +			while (num--) { + +	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3]; +	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7]; + +	for (i=0;i<16;i++) +		{ +#if BYTE_ORDER == BIG_ENDIAN +		T1 = X[i] = W[i]; +#else +		T1 = X[i] = PULL64(W[i]); +#endif +		T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; +		T2 = Sigma0(a) + Maj(a,b,c); +		h = g;	g = f;	f = e;	e = d + T1; +		d = c;	c = b;	b = a;	a = T1 + T2; +		} + +	for (;i<80;i++) +		{ +		s0 = X[(i+1)&0x0f];	s0 = sigma0(s0); +		s1 = X[(i+14)&0x0f];	s1 = sigma1(s1); + +		T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf]; +		T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; +		T2 = Sigma0(a) + Maj(a,b,c); +		h = g;	g = f;	f = e;	e = d + T1; +		d = c;	c = b;	b = a;	a = T1 + T2; +		} + +	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d; +	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h; + +			W+=SHA_LBLOCK; +			} +	} + +#else + +#define	ROUND_00_15(i,a,b,c,d,e,f,g,h)		do {	\ +	T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];	\ +	h = Sigma0(a) + Maj(a,b,c);			\ +	d += T1;	h += T1;		} while (0) + +#define	ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X)	do {	\ +	s0 = X[(j+1)&0x0f];	s0 = sigma0(s0);	\ +	s1 = X[(j+14)&0x0f];	s1 = sigma1(s1);	\ +	T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f];	\ +	ROUND_00_15(i+j,a,b,c,d,e,f,g,h);		} while (0) + +static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) +	{ +	const SHA_LONG64 *W=in; +	SHA_LONG64	a,b,c,d,e,f,g,h,s0,s1,T1; +	SHA_LONG64	X[16]; +	int i; + +			while (num--) { + +	a = ctx->h[0];	b = ctx->h[1];	c = ctx->h[2];	d = ctx->h[3]; +	e = ctx->h[4];	f = ctx->h[5];	g = ctx->h[6];	h = ctx->h[7]; + +#if BYTE_ORDER == BIG_ENDIAN +	T1 = X[0] = W[0];	ROUND_00_15(0,a,b,c,d,e,f,g,h); +	T1 = X[1] = W[1];	ROUND_00_15(1,h,a,b,c,d,e,f,g); +	T1 = X[2] = W[2];	ROUND_00_15(2,g,h,a,b,c,d,e,f); +	T1 = X[3] = W[3];	ROUND_00_15(3,f,g,h,a,b,c,d,e); +	T1 = X[4] = W[4];	ROUND_00_15(4,e,f,g,h,a,b,c,d); +	T1 = X[5] = W[5];	ROUND_00_15(5,d,e,f,g,h,a,b,c); +	T1 = X[6] = W[6];	ROUND_00_15(6,c,d,e,f,g,h,a,b); +	T1 = X[7] = W[7];	ROUND_00_15(7,b,c,d,e,f,g,h,a); +	T1 = X[8] = W[8];	ROUND_00_15(8,a,b,c,d,e,f,g,h); +	T1 = X[9] = W[9];	ROUND_00_15(9,h,a,b,c,d,e,f,g); +	T1 = X[10] = W[10];	ROUND_00_15(10,g,h,a,b,c,d,e,f); +	T1 = X[11] = W[11];	ROUND_00_15(11,f,g,h,a,b,c,d,e); +	T1 = X[12] = W[12];	ROUND_00_15(12,e,f,g,h,a,b,c,d); +	T1 = X[13] = W[13];	ROUND_00_15(13,d,e,f,g,h,a,b,c); +	T1 = X[14] = W[14];	ROUND_00_15(14,c,d,e,f,g,h,a,b); +	T1 = X[15] = W[15];	ROUND_00_15(15,b,c,d,e,f,g,h,a); +#else +	T1 = X[0]  = PULL64(W[0]);	ROUND_00_15(0,a,b,c,d,e,f,g,h); +	T1 = X[1]  = PULL64(W[1]);	ROUND_00_15(1,h,a,b,c,d,e,f,g); +	T1 = X[2]  = PULL64(W[2]);	ROUND_00_15(2,g,h,a,b,c,d,e,f); +	T1 = X[3]  = PULL64(W[3]);	ROUND_00_15(3,f,g,h,a,b,c,d,e); +	T1 = X[4]  = PULL64(W[4]);	ROUND_00_15(4,e,f,g,h,a,b,c,d); +	T1 = X[5]  = PULL64(W[5]);	ROUND_00_15(5,d,e,f,g,h,a,b,c); +	T1 = X[6]  = PULL64(W[6]);	ROUND_00_15(6,c,d,e,f,g,h,a,b); +	T1 = X[7]  = PULL64(W[7]);	ROUND_00_15(7,b,c,d,e,f,g,h,a); +	T1 = X[8]  = PULL64(W[8]);	ROUND_00_15(8,a,b,c,d,e,f,g,h); +	T1 = X[9]  = PULL64(W[9]);	ROUND_00_15(9,h,a,b,c,d,e,f,g); +	T1 = X[10] = PULL64(W[10]);	ROUND_00_15(10,g,h,a,b,c,d,e,f); +	T1 = X[11] = PULL64(W[11]);	ROUND_00_15(11,f,g,h,a,b,c,d,e); +	T1 = X[12] = PULL64(W[12]);	ROUND_00_15(12,e,f,g,h,a,b,c,d); +	T1 = X[13] = PULL64(W[13]);	ROUND_00_15(13,d,e,f,g,h,a,b,c); +	T1 = X[14] = PULL64(W[14]);	ROUND_00_15(14,c,d,e,f,g,h,a,b); +	T1 = X[15] = PULL64(W[15]);	ROUND_00_15(15,b,c,d,e,f,g,h,a); +#endif + +	for (i=16;i<80;i+=16) +		{ +		ROUND_16_80(i, 0,a,b,c,d,e,f,g,h,X); +		ROUND_16_80(i, 1,h,a,b,c,d,e,f,g,X); +		ROUND_16_80(i, 2,g,h,a,b,c,d,e,f,X); +		ROUND_16_80(i, 3,f,g,h,a,b,c,d,e,X); +		ROUND_16_80(i, 4,e,f,g,h,a,b,c,d,X); +		ROUND_16_80(i, 5,d,e,f,g,h,a,b,c,X); +		ROUND_16_80(i, 6,c,d,e,f,g,h,a,b,X); +		ROUND_16_80(i, 7,b,c,d,e,f,g,h,a,X); +		ROUND_16_80(i, 8,a,b,c,d,e,f,g,h,X); +		ROUND_16_80(i, 9,h,a,b,c,d,e,f,g,X); +		ROUND_16_80(i,10,g,h,a,b,c,d,e,f,X); +		ROUND_16_80(i,11,f,g,h,a,b,c,d,e,X); +		ROUND_16_80(i,12,e,f,g,h,a,b,c,d,X); +		ROUND_16_80(i,13,d,e,f,g,h,a,b,c,X); +		ROUND_16_80(i,14,c,d,e,f,g,h,a,b,X); +		ROUND_16_80(i,15,b,c,d,e,f,g,h,a,X); +		} + +	ctx->h[0] += a;	ctx->h[1] += b;	ctx->h[2] += c;	ctx->h[3] += d; +	ctx->h[4] += e;	ctx->h[5] += f;	ctx->h[6] += g;	ctx->h[7] += h; + +			W+=SHA_LBLOCK; +			} +	} + +#endif + +#endif /* SHA512_ASM */ + +#endif /* !OPENSSL_NO_SHA512 */ diff --git a/lib/libutil/bcrypt_pbkdf.c b/lib/libutil/bcrypt_pbkdf.c new file mode 100644 index 0000000..e937194 --- /dev/null +++ b/lib/libutil/bcrypt_pbkdf.c @@ -0,0 +1,176 @@ +/* $OpenBSD: bcrypt_pbkdf.c,v 1.15 2019/11/21 16:13:39 tedu Exp $ */ +/* + * Copyright (c) 2013 Ted Unangst <tedu@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/cdefs.h> + +#include <stdint.h> +#include <stdlib.h> +#include <blf.h> +#include <sha2.h> +#include <string.h> +#include <util.h> + +#define	MINIMUM(a,b) (((a) < (b)) ? (a) : (b)) + +/* + * pkcs #5 pbkdf2 implementation using the "bcrypt" hash + * + * The bcrypt hash function is derived from the bcrypt password hashing + * function with the following modifications: + * 1. The input password and salt are preprocessed with SHA512. + * 2. The output length is expanded to 256 bits. + * 3. Subsequently the magic string to be encrypted is lengthened and modifed + *    to "OxychromaticBlowfishSwatDynamite" + * 4. The hash function is defined to perform 64 rounds of initial state + *    expansion. (More rounds are performed by iterating the hash.) + * + * Note that this implementation pulls the SHA512 operations into the caller + * as a performance optimization. + * + * One modification from official pbkdf2. Instead of outputting key material + * linearly, we mix it. pbkdf2 has a known weakness where if one uses it to + * generate (e.g.) 512 bits of key material for use as two 256 bit keys, an + * attacker can merely run once through the outer loop, but the user + * always runs it twice. Shuffling output bytes requires computing the + * entirety of the key material to assemble any subkey. This is something a + * wise caller could do; we just do it for you. + */ + +#define BCRYPT_WORDS 8 +#define BCRYPT_HASHSIZE (BCRYPT_WORDS * 4) + +static void +bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out) +{ +	blf_ctx state; +	uint8_t ciphertext[BCRYPT_HASHSIZE] = +	    "OxychromaticBlowfishSwatDynamite"; +	uint32_t cdata[BCRYPT_WORDS]; +	int i; +	uint16_t j; +	size_t shalen = SHA512_DIGEST_LENGTH; + +	/* key expansion */ +	Blowfish_initstate(&state); +	Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen); +	for (i = 0; i < 64; i++) { +		Blowfish_expand0state(&state, sha2salt, shalen); +		Blowfish_expand0state(&state, sha2pass, shalen); +	} + +	/* encryption */ +	j = 0; +	for (i = 0; i < BCRYPT_WORDS; i++) +		cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext), +		    &j); +	for (i = 0; i < 64; i++) +		blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t)); + +	/* copy out */ +	for (i = 0; i < BCRYPT_WORDS; i++) { +		out[4 * i + 3] = (cdata[i] >> 24) & 0xff; +		out[4 * i + 2] = (cdata[i] >> 16) & 0xff; +		out[4 * i + 1] = (cdata[i] >> 8) & 0xff; +		out[4 * i + 0] = cdata[i] & 0xff; +	} + +	/* zap */ +	explicit_bzero(ciphertext, sizeof(ciphertext)); +	explicit_bzero(cdata, sizeof(cdata)); +	explicit_bzero(&state, sizeof(state)); +} + +int +bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, +    uint8_t *key, size_t keylen, unsigned int rounds) +{ +	SHA2_CTX ctx; +	uint8_t sha2pass[SHA512_DIGEST_LENGTH]; +	uint8_t sha2salt[SHA512_DIGEST_LENGTH]; +	uint8_t out[BCRYPT_HASHSIZE]; +	uint8_t tmpout[BCRYPT_HASHSIZE]; +	uint8_t countsalt[4]; +	size_t i, j, amt, stride; +	uint32_t count; +	size_t origkeylen = keylen; + +	/* nothing crazy */ +	if (rounds < 1) +		goto bad; +	if (passlen == 0 || saltlen == 0 || keylen == 0 || +	    keylen > sizeof(out) * sizeof(out)) +		goto bad; +	stride = (keylen + sizeof(out) - 1) / sizeof(out); +	amt = (keylen + stride - 1) / stride; + +	/* collapse password */ +	SHA512Init(&ctx); +	SHA512Update(&ctx, pass, passlen); +	SHA512Final(sha2pass, &ctx); + + +	/* generate key, sizeof(out) at a time */ +	for (count = 1; keylen > 0; count++) { +		countsalt[0] = (count >> 24) & 0xff; +		countsalt[1] = (count >> 16) & 0xff; +		countsalt[2] = (count >> 8) & 0xff; +		countsalt[3] = count & 0xff; + +		/* first round, salt is salt */ +		SHA512Init(&ctx); +		SHA512Update(&ctx, salt, saltlen); +		SHA512Update(&ctx, countsalt, sizeof(countsalt)); +		SHA512Final(sha2salt, &ctx); +		bcrypt_hash(sha2pass, sha2salt, tmpout); +		memcpy(out, tmpout, sizeof(out)); + +		for (i = 1; i < rounds; i++) { +			/* subsequent rounds, salt is previous output */ +			SHA512Init(&ctx); +			SHA512Update(&ctx, tmpout, sizeof(tmpout)); +			SHA512Final(sha2salt, &ctx); +			bcrypt_hash(sha2pass, sha2salt, tmpout); +			for (j = 0; j < sizeof(out); j++) +				out[j] ^= tmpout[j]; +		} + +		/* +		 * pbkdf2 deviation: output the key material non-linearly. +		 */ +		amt = MINIMUM(amt, keylen); +		for (i = 0; i < amt; i++) { +			size_t dest = i * stride + (count - 1); +			if (dest >= origkeylen) +				break; +			key[dest] = out[i]; +		} +		keylen -= i; +	} + +	/* zap */ +	explicit_bzero(&ctx, sizeof(ctx)); +	explicit_bzero(out, sizeof(out)); +	explicit_bzero(tmpout, sizeof(tmpout)); + +	return 0; + +bad: +	/* overwrite with random in case caller doesn't check return code */ +	arc4random_buf(key, keylen); +	return -1; +} diff --git a/lib/libutil/ohash.c b/lib/libutil/ohash.c new file mode 100644 index 0000000..9537c60 --- /dev/null +++ b/lib/libutil/ohash.c @@ -0,0 +1,328 @@ +/* $OpenBSD: ohash.c,v 1.1 2014/06/02 18:52:03 deraadt Exp $ */ + +/* Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/cdefs.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include "ohash.h" + +struct _ohash_record { +	uint32_t	hv; +	const char	*p; +}; + +#define DELETED		((const char *)h) +#define NONE		(h->size) + +/* Don't bother changing the hash table if the change is small enough.  */ +#define MINSIZE		(1UL << 4) +#define MINDELETED	4 + +static void ohash_resize(struct ohash *); + + +/* This handles the common case of variable length keys, where the + * key is stored at the end of the record. + */ +void * +ohash_create_entry(struct ohash_info *i, const char *start, const char **end) +{ +	char *p; + +	if (!*end) +		*end = start + strlen(start); +	p = (i->alloc)(i->key_offset + (*end - start) + 1, i->data); +	if (p) { +		memcpy(p+i->key_offset, start, *end-start); +		p[i->key_offset + (*end - start)] = '\0'; +	} +	return (void *)p; +} + +/* hash_delete only frees the hash structure. Use hash_first/hash_next + * to free entries as well.  */ +void +ohash_delete(struct ohash *h) +{ +	(h->info.free)(h->t, h->info.data); +#ifndef NDEBUG +	h->t = NULL; +#endif +} + +static void +ohash_resize(struct ohash *h) +{ +	struct _ohash_record *n; +	size_t ns; +	unsigned int	j; +	unsigned int	i, incr; + +	if (4 * h->deleted < h->total) { +		if (h->size >= (UINT_MAX >> 1U)) +			ns = UINT_MAX; +		else +			ns = h->size << 1U; +	} else if (3 * h->deleted > 2 * h->total) +		ns = h->size >> 1U; +	else +		ns = h->size; +	if (ns < MINSIZE) +		ns = MINSIZE; +#ifdef STATS_HASH +	STAT_HASH_EXPAND++; +	STAT_HASH_SIZE += ns - h->size; +#endif + +	n = (h->info.calloc)(ns, sizeof(struct _ohash_record), h->info.data); +	if (!n) +		return; + +	for (j = 0; j < h->size; j++) { +		if (h->t[j].p != NULL && h->t[j].p != DELETED) { +			i = h->t[j].hv % ns; +			incr = ((h->t[j].hv % (ns - 2)) & ~1) + 1; +			while (n[i].p != NULL) { +				i += incr; +				if (i >= ns) +					i -= ns; +			} +			n[i].hv = h->t[j].hv; +			n[i].p = h->t[j].p; +		} +	} +	(h->info.free)(h->t, h->info.data); +	h->t = n; +	h->size = ns; +	h->total -= h->deleted; +	h->deleted = 0; +} + +void * +ohash_remove(struct ohash *h, unsigned int i) +{ +	void		*result = (void *)h->t[i].p; + +	if (result == NULL || result == DELETED) +		return NULL; + +#ifdef STATS_HASH +	STAT_HASH_ENTRIES--; +#endif +	h->t[i].p = DELETED; +	h->deleted++; +	if (h->deleted >= MINDELETED && 4 * h->deleted > h->total) +		ohash_resize(h); +	return result; +} + +void * +ohash_find(struct ohash *h, unsigned int i) +{ +	if (h->t[i].p == DELETED) +		return NULL; +	else +		return (void *)h->t[i].p; +} + +void * +ohash_insert(struct ohash *h, unsigned int i, void *p) +{ +#ifdef STATS_HASH +	STAT_HASH_ENTRIES++; +#endif +	if (h->t[i].p == DELETED) { +		h->deleted--; +		h->t[i].p = p; +	} else { +		h->t[i].p = p; +		/* Arbitrary resize boundary.  Tweak if not efficient enough.  */ +		if (++h->total * 4 > h->size * 3) +			ohash_resize(h); +	} +	return p; +} + +unsigned int +ohash_entries(struct ohash *h) +{ +	return h->total - h->deleted; +} + +void * +ohash_first(struct ohash *h, unsigned int *pos) +{ +	*pos = 0; +	return ohash_next(h, pos); +} + +void * +ohash_next(struct ohash *h, unsigned int *pos) +{ +	for (; *pos < h->size; (*pos)++) +		if (h->t[*pos].p != DELETED && h->t[*pos].p != NULL) +			return (void *)h->t[(*pos)++].p; +	return NULL; +} + +void +ohash_init(struct ohash *h, unsigned int size, struct ohash_info *info) +{ +	h->size = 1UL << size; +	if (h->size < MINSIZE) +		h->size = MINSIZE; +#ifdef STATS_HASH +	STAT_HASH_CREATION++; +	STAT_HASH_SIZE += h->size; +#endif +	/* Copy info so that caller may free it.  */ +	h->info.key_offset = info->key_offset; +	h->info.calloc = info->calloc; +	h->info.free = info->free; +	h->info.alloc = info->alloc; +	h->info.data = info->data; +	h->t = (h->info.calloc)(h->size, sizeof(struct _ohash_record), +		    h->info.data); +	h->total = h->deleted = 0; +} + +uint32_t +ohash_interval(const char *s, const char **e) +{ +	uint32_t k; + +	if (!*e) +		*e = s + strlen(s); +	if (s == *e) +		k = 0; +	else +		k = *s++; +	while (s != *e) +		k =  ((k << 2) | (k >> 30)) ^ *s++; +	return k; +} + +unsigned int +ohash_lookup_interval(struct ohash *h, const char *start, const char *end, +    uint32_t hv) +{ +	unsigned int	i, incr; +	unsigned int	empty; + +#ifdef STATS_HASH +	STAT_HASH_LOOKUP++; +#endif +	empty = NONE; +	i = hv % h->size; +	incr = ((hv % (h->size-2)) & ~1) + 1; +	while (h->t[i].p != NULL) { +#ifdef STATS_HASH +		STAT_HASH_LENGTH++; +#endif +		if (h->t[i].p == DELETED) { +			if (empty == NONE) +				empty = i; +		} else if (h->t[i].hv == hv && +		    strncmp(h->t[i].p+h->info.key_offset, start, +			end - start) == 0 && +		    (h->t[i].p+h->info.key_offset)[end-start] == '\0') { +			if (empty != NONE) { +				h->t[empty].hv = hv; +				h->t[empty].p = h->t[i].p; +				h->t[i].p = DELETED; +				return empty; +			} else { +#ifdef STATS_HASH +				STAT_HASH_POSITIVE++; +#endif +				return i; +			} +		} +		i += incr; +		if (i >= h->size) +			i -= h->size; +	} + +	/* Found an empty position.  */ +	if (empty != NONE) +		i = empty; +	h->t[i].hv = hv; +	return i; +} + +unsigned int +ohash_lookup_memory(struct ohash *h, const char *k, size_t size, uint32_t hv) +{ +	unsigned int	i, incr; +	unsigned int	empty; + +#ifdef STATS_HASH +	STAT_HASH_LOOKUP++; +#endif +	empty = NONE; +	i = hv % h->size; +	incr = ((hv % (h->size-2)) & ~1) + 1; +	while (h->t[i].p != NULL) { +#ifdef STATS_HASH +		STAT_HASH_LENGTH++; +#endif +		if (h->t[i].p == DELETED) { +			if (empty == NONE) +				empty = i; +		} else if (h->t[i].hv == hv && +		    memcmp(h->t[i].p+h->info.key_offset, k, size) == 0) { +			if (empty != NONE) { +				h->t[empty].hv = hv; +				h->t[empty].p = h->t[i].p; +				h->t[i].p = DELETED; +				return empty; +			} else { +#ifdef STATS_HASH +				STAT_HASH_POSITIVE++; +#endif +			}	return i; +		} +		i += incr; +		if (i >= h->size) +			i -= h->size; +	} + +	/* Found an empty position.  */ +	if (empty != NONE) +		i = empty; +	h->t[i].hv = hv; +	return i; +} + +unsigned int +ohash_qlookup(struct ohash *h, const char *s) +{ +	const char *e = NULL; +	return ohash_qlookupi(h, s, &e); +} + +unsigned int +ohash_qlookupi(struct ohash *h, const char *s, const char **e) +{ +	uint32_t hv; + +	hv = ohash_interval(s, e); +	return ohash_lookup_interval(h, s, *e, hv); +} diff --git a/lib/libutil/ohash.h b/lib/libutil/ohash.h new file mode 100644 index 0000000..c5f81ec --- /dev/null +++ b/lib/libutil/ohash.h @@ -0,0 +1,74 @@ +/* $OpenBSD: ohash.h,v 1.2 2014/06/02 18:52:03 deraadt Exp $ */ + +/* Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef OHASH_H +#define OHASH_H + +/* Open hashing support.  + * Open hashing was chosen because it is much lighter than other hash + * techniques, and more efficient in most cases. + */ + +/* user-visible data structure */ +struct ohash_info { +	ptrdiff_t key_offset; +	void *data;	/* user data */ +	void *(*calloc)(size_t, size_t, void *); +	void (*free)(void *, void *); +	void *(*alloc)(size_t, void *); +}; + +struct _ohash_record; + +/* private structure. It's there just so you can do a sizeof */ +struct ohash { +	struct _ohash_record 	*t; +	struct ohash_info 	info; +	unsigned int 		size; +	unsigned int 		total; +	unsigned int 		deleted; +}; + +/* For this to be tweakable, we use small primitives, and leave part of the + * logic to the client application.  e.g., hashing is left to the client + * application.  We also provide a simple table entry lookup that yields + * a hashing table index (opaque) to be used in find/insert/remove. + * The keys are stored at a known position in the client data. + */ +__BEGIN_DECLS +void ohash_init(struct ohash *, unsigned, struct ohash_info *); +void ohash_delete(struct ohash *); + +unsigned int ohash_lookup_interval(struct ohash *, const char *, +	    const char *, uint32_t); +unsigned int ohash_lookup_memory(struct ohash *, const char *, +	    size_t, uint32_t) +		__attribute__ ((__bounded__(__string__,2,3))); +void *ohash_find(struct ohash *, unsigned int); +void *ohash_remove(struct ohash *, unsigned int); +void *ohash_insert(struct ohash *, unsigned int, void *); +void *ohash_first(struct ohash *, unsigned int *); +void *ohash_next(struct ohash *, unsigned int *); +unsigned int ohash_entries(struct ohash *); + +void *ohash_create_entry(struct ohash_info *, const char *, const char **); +uint32_t ohash_interval(const char *, const char **); + +unsigned int ohash_qlookupi(struct ohash *, const char *, const char **); +unsigned int ohash_qlookup(struct ohash *, const char *); +__END_DECLS +#endif diff --git a/lib/libutil/pidfile.c b/lib/libutil/pidfile.c new file mode 100644 index 0000000..7c07a20 --- /dev/null +++ b/lib/libutil/pidfile.c @@ -0,0 +1,106 @@ +/*	$OpenBSD: pidfile.c,v 1.14 2019/06/28 14:20:40 schwarze Exp $	*/ +/*	$NetBSD: pidfile.c,v 1.4 2001/02/19 22:43:42 cgd Exp $	*/ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +#include <sys/types.h> +#include <errno.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <util.h> + +static char *pidfile_path; +static pid_t pidfile_pid; + +static void pidfile_cleanup(void); + +extern char *__progname; + +int +pidfile(const char *basename) +{ +	int save_errno; +	pid_t pid; +	FILE *f; + +	if (basename == NULL) +		basename = __progname; + +	free(pidfile_path); +	pidfile_path = NULL; + +	/* _PATH_VARRUN includes trailing / */ +	if (asprintf(&pidfile_path, "%s%s.pid", _PATH_VARRUN, basename) == -1) +		return (-1); + +	if ((f = fopen(pidfile_path, "w")) == NULL) { +		save_errno = errno; +		free(pidfile_path); +		pidfile_path = NULL; +		errno = save_errno; +		return (-1); +	} + +	pid = getpid(); +	if (fprintf(f, "%ld\n", (long)pid) <= 0 || fflush(f) != 0) { +		save_errno = errno; +		(void) fclose(f); +		(void) unlink(pidfile_path); +		free(pidfile_path); +		pidfile_path = NULL; +		errno = save_errno; +		return (-1); +	} +	(void) fclose(f); + +	pidfile_pid = pid; +	if (atexit(pidfile_cleanup) != 0) { +		save_errno = errno; +		(void) unlink(pidfile_path); +		free(pidfile_path); +		pidfile_path = NULL; +		pidfile_pid = 0; +		errno = save_errno; +		return (-1); +	} + +	return (0); +} + +static void +pidfile_cleanup(void) +{ + +	if (pidfile_path != NULL && pidfile_pid == getpid()) +		(void) unlink(pidfile_path); +} diff --git a/lib/libutil/util.h b/lib/libutil/util.h new file mode 100644 index 0000000..d7aa8fa --- /dev/null +++ b/lib/libutil/util.h @@ -0,0 +1,127 @@ +/*	$OpenBSD: util.h,v 1.36 2019/08/30 03:57:56 deraadt Exp $	*/ +/*	$NetBSD: util.h,v 1.2 1996/05/16 07:00:22 thorpej Exp $	*/ + +/*- + * Copyright (c) 1995 + *	The Regents of the University of California.  All rights reserved. + * Portions Copyright (c) 1996, Jason Downs.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#include <sys/types.h> + +/* + * fparseln() specific operation flags. + */ +#define FPARSELN_UNESCESC	0x01 +#define FPARSELN_UNESCCONT	0x02 +#define FPARSELN_UNESCCOMM	0x04 +#define FPARSELN_UNESCREST	0x08 +#define FPARSELN_UNESCALL	0x0f + +/* + * opendev() specific operation flags. + */ +#define OPENDEV_PART	0x01		/* Try to open the raw partition. */ +#define OPENDEV_BLCK	0x04		/* Open block, not character device. */ + +/* + * uu_lock(3) specific flags. + */ +#define UU_LOCK_INUSE (1) +#define UU_LOCK_OK (0) +#define UU_LOCK_OPEN_ERR (-1) +#define UU_LOCK_READ_ERR (-2) +#define UU_LOCK_CREAT_ERR (-3) +#define UU_LOCK_WRITE_ERR (-4) +#define UU_LOCK_LINK_ERR (-5) +#define UU_LOCK_TRY_ERR (-6) +#define UU_LOCK_OWNER_ERR (-7) + +/* + * fmt_scaled(3) specific flags. + */ +#define	FMT_SCALED_STRSIZE	7	/* minus sign, 4 digits, suffix, null byte */ + +/* + * stub struct definitions. + */ +struct __sFILE; +struct login_cap; +struct passwd; +struct termios; +struct utmp; +struct winsize; + +__BEGIN_DECLS +char   *fparseln(struct __sFILE *, size_t *, size_t *, const char[3], int); +void	login(struct utmp *); +int	login_tty(int); +int	logout(const char *); +void	logwtmp(const char *, const char *, const char *); +int	opendev(const char *, int, int, char **); +int	pidfile(const char *); +void	pw_setdir(const char *); +char   *pw_file(const char *); +int	pw_lock(int); +int	pw_mkdb(char *, int); +int	pw_abort(void); +void	pw_init(void); +void	pw_edit(int, const char *); +void	pw_prompt(void); +void	pw_copy(int, int, const struct passwd *, const struct passwd *); +int	pw_scan(char *, struct passwd *, int *); +void	pw_error(const char *, int, int); +int	getptmfd(void); +int	openpty(int *, int *, char *, struct termios *, struct winsize *); +int	fdopenpty(int, int *, int *, char *, struct termios *, +	    struct winsize *); +int	opendisk(const char *, int, char *, size_t, int); +pid_t	forkpty(int *, char *, struct termios *, struct winsize *); +pid_t	fdforkpty(int, int *, char *, struct termios *, struct winsize *); +int	getmaxpartitions(void); +int	getrawpartition(void); +void	login_fbtab(const char *, uid_t, gid_t); +int	login_check_expire(struct __sFILE *, struct passwd *, char *, int); +char   *readlabelfs(char *, int); +const char *uu_lockerr(int); +int     uu_lock(const char *); +int	uu_lock_txfr(const char *, pid_t); +int     uu_unlock(const char *); +int	fmt_scaled(long long, char *); +int	scan_scaled(char *, long long *); +int	isduid(const char *, int); +int	pkcs5_pbkdf2(const char *, size_t, const uint8_t *, size_t, +    uint8_t *, size_t, unsigned int); +int	bcrypt_pbkdf(const char *, size_t, const uint8_t *, size_t, +    uint8_t *, size_t, unsigned int); + +__END_DECLS + +#endif /* !_UTIL_H_ */ diff --git a/lib/libz/CVS/Entries b/lib/libz/CVS/Entries new file mode 100644 index 0000000..baf70f2 --- /dev/null +++ b/lib/libz/CVS/Entries @@ -0,0 +1,30 @@ +/ChangeLog/1.4/Wed Jul 20 15:56:40 2005// +/Makefile/1.20/Wed Sep 14 06:26:03 2016// +/README/1.7/Wed Jul 20 15:56:40 2005// +/adler32.c/1.6/Wed Jul 20 15:56:40 2005// +/algorithm.doc/1.3/Tue Dec 16 22:33:02 2003// +/compress.3/1.19/Fri Mar 16 16:58:26 2018// +/compress.c/1.6/Wed Jul 20 15:56:41 2005// +/crc32.c/1.8/Wed Jul 20 15:56:41 2005// +/crc32.h/1.1/Tue Dec 16 22:33:02 2003// +/deflate.c/1.11/Tue Oct 27 23:59:31 2009// +/deflate.h/1.8/Mon Nov 26 09:28:33 2007// +/generate_pkgconfig.sh/1.2/Thu May  5 20:58:15 2011// +/gzio.c/1.15/Sat Apr 18 17:11:37 2020// +/infback.c/1.6/Sat Jun  1 11:39:57 2019// +/inffast.c/1.8/Sat Jun  1 11:39:57 2019// +/inffast.h/1.4/Tue Dec 16 22:33:02 2003// +/inffixed.h/1.3/Tue Dec 16 22:33:02 2003// +/inflate.c/1.10/Sat Jun  1 11:39:57 2019// +/inflate.h/1.2/Wed Jul 20 15:56:41 2005// +/inftrees.c/1.9/Tue Oct 27 23:59:31 2009// +/inftrees.h/1.5/Wed Jul 20 15:56:41 2005// +/shlib_version/1.10/Tue Aug 13 05:52:17 2013// +/trees.c/1.8/Wed Jul 20 15:56:41 2005// +/trees.h/1.2/Tue Mar 12 00:25:57 2002// +/uncompr.c/1.5/Tue Dec 16 22:33:02 2003// +/zconf.h/1.8/Sun May 12 15:56:56 2019// +/zlib.h/1.11/Sun May 12 15:56:56 2019// +/zutil.c/1.9/Fri Aug 21 23:30:59 2015// +/zutil.h/1.9/Wed Jul 20 15:56:42 2005// +D diff --git a/lib/libz/CVS/Repository b/lib/libz/CVS/Repository new file mode 100644 index 0000000..f89f39e --- /dev/null +++ b/lib/libz/CVS/Repository @@ -0,0 +1 @@ +src/lib/libz diff --git a/lib/libz/CVS/Root b/lib/libz/CVS/Root new file mode 100644 index 0000000..3811072 --- /dev/null +++ b/lib/libz/CVS/Root @@ -0,0 +1 @@ +/cvs diff --git a/lib/libz/ChangeLog b/lib/libz/ChangeLog new file mode 100644 index 0000000..c1b187d --- /dev/null +++ b/lib/libz/ChangeLog @@ -0,0 +1,855 @@ + +                ChangeLog file for zlib + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit +  compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Added zran.c example of compressed data random access to examples +  directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase +  ENOUGH and MAXD -- this repairs a possible security vulnerability for +  invalid inflate input.  Thanks to Tavis Ormandy and Markus Oberhumer for +  discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to +  avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, +  fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h +  and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and +  contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid +  dynamic blocks with only literals and no distance codes -- +  Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c +    - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate +    - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using +  the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm +  [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream, +  and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip +  [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines +  [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in +  INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings +  [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation +  of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a +  parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type +  to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between +  16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for +  Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in +  zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid +  library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by +  special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags +    - Report 0 for huffman and rle strategies and for level == 0 or 1 +    - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] +    - When Z_RLE requested, restrict matches to distance one +    - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] +    - Refine detection of Turbo C need for dummy returns +    - Refine ZLIB_DLL compilation +    - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to +  write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code +    - About 20% faster +    - Does not allocate 32K window unless and until needed +    - Automatically detects and decompresses gzip streams +    - Raw inflate no longer needs an extra dummy byte at end +    - Added inflateBack functions using a callback interface--even faster +      than inflate, useful for file utilities (gzip, zip) +    - Added inflateCopy() function to record state for random access on +      externally generated deflate streams (e.g. in gzip files) +    - More readable code (I hope) +- New and improved crc32() +    - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer +  and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their +  return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that +  is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): +    - Document raw deflate and inflate +    - Update RFCs URL +    - Point out that zlib and gzip formats are different +    - Note that Z_BUF_ERROR is not fatal +    - Document string limit for gzprintf() and possible buffer overflow +    - Note requirement on avail_out when flushing +    - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. +  This creates a security problem described in +  http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window +  less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size +  of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent +  occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file +  (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) +  See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz  (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean"  (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: +  . zutil.c, zutil.h: added "const" for zmem* +  . Make_vms.com: fixed some typos +  . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists +  . msdos/Makefile.msc: remove "default rtl link library" info from obj files +  . msdos/Makefile.*: use model-dependent name for the built zlib library +  . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: +     new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) +  See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code +  completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode  (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib +  (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the +  compression ratio on some files. This also allows inlining _tr_tally for +  matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain +  on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with +  the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing +  them at run time (thanks to Ken Raeburn for this suggestion). To create +  trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and +  gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to +  Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface +  (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface +  (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or +  inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: +   contrib/asm386/ by Gilles Vollant <info@winimage.com> +        386 asm code replacing longest_match(). +   contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu> +        A C++ I/O streams interface to the zlib gz* functions +   contrib/iostream2/  by Tyge Løvset <Tyge.Lovset@cmr.no> +        Another C++ I/O streams interface +   contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag@tid.es> +        A very simple tar.gz file extractor using zlib +   contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl> +        How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression +  level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string +  (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF +  bit, so the decompressor could decompress all the correct data but went +  on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS +  small and medium models; this makes the library incompatible with previous +  versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with +  avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), +  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level +  and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith +  -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: +     warning C4746: 'inflate_mask' : unsized array treated as  '__far' +     (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but +  not completely flushed in rare occasions). +- default window size is same for compression and decompression +  (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other +  typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug +  was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized +  pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this +  is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) +  (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with +  TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning +  (one's complement) is now done inside crc32(). WARNING: this is +  incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but +  not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. +  Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush +  if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting +  user-provided history buffer. This is supported only in deflateInit2 +  and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/lib/libz/Makefile b/lib/libz/Makefile new file mode 100644 index 0000000..cba7339 --- /dev/null +++ b/lib/libz/Makefile @@ -0,0 +1,30 @@ +#	$OpenBSD: Makefile,v 1.20 2016/09/14 06:26:03 natano Exp $ + +LIB=	z +HDRS=	zconf.h zlib.h +SRCS=	adler32.c compress.c crc32.c deflate.c gzio.c infback.c \ +	inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c +MAN=	compress.3 +CFLAGS+=-DHAVE_STRERROR -DHAVE_MEMCPY -DHAS_vsnprintf -DHAS_snprintf + +PC_FILES=zlib.pc +CLEANFILES+=${PC_FILES} + +includes: +	@cd ${.CURDIR}; for i in $(HDRS); do \ +		j="cmp -s $$i ${DESTDIR}/usr/include/$$i || \ +		    ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m 444 \ +		    $$i ${DESTDIR}/usr/include"; \ +		echo $$j; \ +		eval "$$j"; \ +	done + +all: ${PC_FILES} +${PC_FILES}: zlib.h +	/bin/sh ${.CURDIR}/generate_pkgconfig.sh -c ${.CURDIR} -o ${.OBJDIR} + +beforeinstall: +	${INSTALL} ${INSTALL_COPY} -o root -g ${SHAREGRP} \ +	    -m ${SHAREMODE} ${.OBJDIR}/${PC_FILES} ${DESTDIR}/usr/lib/pkgconfig/ + +.include <bsd.lib.mk> diff --git a/lib/libz/README b/lib/libz/README new file mode 100644 index 0000000..758cc50 --- /dev/null +++ b/lib/libz/README @@ -0,0 +1,125 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.3 is a general purpose data compression library.  All the code is +thread safe.  The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) +and rfc1952.txt (gzip format). These documents are also available in other +formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file example.c which also tests that the library +is working correctly. Another example is given in the file minigzip.c. The +compression library itself is composed of all source files except example.c and +minigzip.c. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile. In short "make test; make install" should work for most +machines. For Unix: "./configure; make test; make install". For MSDOS, use one +of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. + +Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant +<info@winimage.com> for the Windows DLL version. The zlib home page is +http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, +please check this site to verify that you have the latest version of zlib; +otherwise get the latest version and check whether the problem still exists or +not. + +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking +for help. + +Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997 +issue of  Dr. Dobb's Journal; a copy of the article is available in +http://dogma.net/markn/articles/zlibtool/zlibtool.htm + +The changes made in version 1.2.3 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory "contrib". + +A Java implementation of zlib is available in the Java Development Kit +http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html +See the zlib home page http://www.zlib.org for details. + +A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the +CPAN (Comprehensive Perl Archive Network) sites +http://www.cpan.org/modules/by-module/Compress/ + +A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is +available in Python 1.5 and later versions, see +http://www.python.org/doc/lib/module-zlib.html + +A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is +availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant <info@winimage.com>, is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With +  -O, one libpng test fails. The test works in 32 bit mode (with the -n32 +  compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works +  when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is +  necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with +  other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + +- When building a shared, i.e. dynamic library on Mac OS X, the library must be +  installed before testing (do "make install" before "make test"), since the +  library location is specified in the library. + + +Acknowledgments: + +  The deflate format used by zlib was defined by Phil Katz. The deflate +  and zlib specifications were written by L. Peter Deutsch. Thanks to all the +  people who reported problems and suggested various improvements in zlib; +  they are too numerous to cite here. + +Copyright notice: + + (C) 1995-2004 Jean-loup Gailly and Mark Adler + +  This software is provided 'as-is', without any express or implied +  warranty.  In no event will the authors be held liable for any damages +  arising from the use of this software. + +  Permission is granted to anyone to use this software for any purpose, +  including commercial applications, and to alter it and redistribute it +  freely, subject to the following restrictions: + +  1. The origin of this software must not be misrepresented; you must not +     claim that you wrote the original software. If you use this software +     in a product, an acknowledgment in the product documentation would be +     appreciated but is not required. +  2. Altered source versions must be plainly marked as such, and must not be +     misrepresented as being the original software. +  3. This notice may not be removed or altered from any source distribution. + +  Jean-loup Gailly        Mark Adler +  jloup@gzip.org          madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind.  The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. Please +read the FAQ for more information on the distribution of modified source +versions. diff --git a/lib/libz/adler32.c b/lib/libz/adler32.c new file mode 100644 index 0000000..932094f --- /dev/null +++ b/lib/libz/adler32.c @@ -0,0 +1,148 @@ +/*	$OpenBSD: adler32.c,v 1.6 2005/07/20 15:56:40 millert Exp $	*/ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +#define BASE 65521UL    /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4); +#define DO16(buf)   DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +#  define MOD(a) \ +    do { \ +        if (a >= (BASE << 16)) a -= (BASE << 16); \ +        if (a >= (BASE << 15)) a -= (BASE << 15); \ +        if (a >= (BASE << 14)) a -= (BASE << 14); \ +        if (a >= (BASE << 13)) a -= (BASE << 13); \ +        if (a >= (BASE << 12)) a -= (BASE << 12); \ +        if (a >= (BASE << 11)) a -= (BASE << 11); \ +        if (a >= (BASE << 10)) a -= (BASE << 10); \ +        if (a >= (BASE << 9)) a -= (BASE << 9); \ +        if (a >= (BASE << 8)) a -= (BASE << 8); \ +        if (a >= (BASE << 7)) a -= (BASE << 7); \ +        if (a >= (BASE << 6)) a -= (BASE << 6); \ +        if (a >= (BASE << 5)) a -= (BASE << 5); \ +        if (a >= (BASE << 4)) a -= (BASE << 4); \ +        if (a >= (BASE << 3)) a -= (BASE << 3); \ +        if (a >= (BASE << 2)) a -= (BASE << 2); \ +        if (a >= (BASE << 1)) a -= (BASE << 1); \ +        if (a >= BASE) a -= BASE; \ +    } while (0) +#  define MOD4(a) \ +    do { \ +        if (a >= (BASE << 4)) a -= (BASE << 4); \ +        if (a >= (BASE << 3)) a -= (BASE << 3); \ +        if (a >= (BASE << 2)) a -= (BASE << 2); \ +        if (a >= (BASE << 1)) a -= (BASE << 1); \ +        if (a >= BASE) a -= BASE; \ +    } while (0) +#else +#  define MOD(a) a %= BASE +#  define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) +    uLong adler; +    const Bytef *buf; +    uInt len; +{ +    unsigned long sum2; +    unsigned n; + +    /* split Adler-32 into component sums */ +    sum2 = (adler >> 16) & 0xffff; +    adler &= 0xffff; + +    /* in case user likes doing a byte at a time, keep it fast */ +    if (len == 1) { +        adler += buf[0]; +        if (adler >= BASE) +            adler -= BASE; +        sum2 += adler; +        if (sum2 >= BASE) +            sum2 -= BASE; +        return adler | (sum2 << 16); +    } + +    /* initial Adler-32 value (deferred check for len == 1 speed) */ +    if (buf == Z_NULL) +        return 1L; + +    /* in case short lengths are provided, keep it somewhat fast */ +    if (len < 16) { +        while (len--) { +            adler += *buf++; +            sum2 += adler; +        } +        if (adler >= BASE) +            adler -= BASE; +        MOD4(sum2);             /* only added so many BASE's */ +        return adler | (sum2 << 16); +    } + +    /* do length NMAX blocks -- requires just one modulo operation */ +    while (len >= NMAX) { +        len -= NMAX; +        n = NMAX / 16;          /* NMAX is divisible by 16 */ +        do { +            DO16(buf);          /* 16 sums unrolled */ +            buf += 16; +        } while (--n); +        MOD(adler); +        MOD(sum2); +    } + +    /* do remaining bytes (less than NMAX, still just one modulo) */ +    if (len) {                  /* avoid modulos if none remaining */ +        while (len >= 16) { +            len -= 16; +            DO16(buf); +            buf += 16; +        } +        while (len--) { +            adler += *buf++; +            sum2 += adler; +        } +        MOD(adler); +        MOD(sum2); +    } + +    /* return recombined sums */ +    return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) +    uLong adler1; +    uLong adler2; +    z_off_t len2; +{ +    unsigned long sum1; +    unsigned long sum2; +    unsigned rem; + +    /* the derivation of this formula is left as an exercise for the reader */ +    rem = (unsigned)(len2 % BASE); +    sum1 = adler1 & 0xffff; +    sum2 = rem * sum1; +    MOD(sum2); +    sum1 += (adler2 & 0xffff) + BASE - 1; +    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; +    if (sum1 > BASE) sum1 -= BASE; +    if (sum1 > BASE) sum1 -= BASE; +    if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); +    if (sum2 > BASE) sum2 -= BASE; +    return sum1 | (sum2 << 16); +} diff --git a/lib/libz/algorithm.doc b/lib/libz/algorithm.doc new file mode 100644 index 0000000..b022dde --- /dev/null +++ b/lib/libz/algorithm.doc @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data.  The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length).  Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes.  (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast.  The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code.  It gets that many bits from the +stream, and looks it up in the table.  The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table.  If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code.  However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table.  What inflate() does is +simply to make the number of bits in the first table a variable, and  then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits.  Also the distance trees have 30 possible +values, and the size of the first table is six bits.  Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like.  You are correct that it's not a Huffman tree.  It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol.  The +symbol could be as short as one bit or as long as 15 bits.  If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits.  For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits.  Again, there are duplicated +entries as needed.  The idea is that most of the time the symbol will be short +and there will only be one table look up.  (That's whole idea behind data +compression in the first place.)  For the less frequent long symbols, there +will be two lookups.  If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient.  For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble.  Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is?  The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols.  At the +other extreme, you could make a new table for every bit in the code.  In fact, +that's essentially a Huffman tree.  But then you spend two much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble.  Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed.  That's compared to 64 entries for a single table.  Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table).  Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol.  That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on.  For inflate, the +meaning of a particular symbol is often more than just a letter.  It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value.  Or it might be the special end-of-block code.  The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly        Mark Adler +jloup@gzip.org          madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +http://www.ietf.org/rfc/rfc1951.txt diff --git a/lib/libz/compress.3 b/lib/libz/compress.3 new file mode 100644 index 0000000..cfac921 --- /dev/null +++ b/lib/libz/compress.3 @@ -0,0 +1,2810 @@ +.\"	$OpenBSD: compress.3,v 1.19 2018/03/16 16:58:26 schwarze Exp $ +.\" +.\"  Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler +.\" +.\"  This software is provided 'as-is', without any express or implied +.\"  warranty.  In no event will the authors be held liable for any damages +.\"  arising from the use of this software. +.\" +.\"  Permission is granted to anyone to use this software for any purpose, +.\"  including commercial applications, and to alter it and redistribute it +.\"  freely, subject to the following restrictions: +.\" +.\"  The origin of this software must not be misrepresented; you must not +.\"  claim that you wrote the original software. If you use this software +.\"  in a product, an acknowledgment in the product documentation would be +.\"  appreciated but is not required. +.\"  Altered source versions must be plainly marked as such, and must not be +.\"  misrepresented as being the original software. +.\"  This notice may not be removed or altered from any source distribution. +.\" +.\" Converted to mdoc format for the OpenBSD project +.\" by Jason McIntyre <jmc@openbsd.org> +.\" +.\" This page corresponds to zlib version 1.2.3 +.\" +.Dd $Mdocdate: March 16 2018 $ +.Dt COMPRESS 3 +.Os +.Sh NAME +.Nm compress , +.Nm zlibVersion , +.Nm deflateInit , +.Nm deflate , +.Nm deflateEnd , +.Nm inflateInit , +.Nm inflate , +.Nm inflateEnd , +.Nm deflateInit2 , +.Nm deflateSetDictionary , +.Nm deflateCopy , +.Nm deflateReset , +.Nm deflateParams , +.Nm deflateTune , +.Nm deflateBound , +.Nm deflatePrime , +.Nm deflateSetHeader , +.Nm inflateInit2 , +.Nm inflateSetDictionary , +.Nm inflateSync , +.Nm inflateCopy , +.Nm inflateReset , +.Nm inflatePrime , +.Nm inflateGetHeader , +.Nm inflateBackInit , +.Nm inflateBack , +.Nm inflateBackEnd , +.Nm zlibCompileFlags , +.Nm compress2 , +.Nm compressBound , +.Nm uncompress , +.Nm gzopen , +.Nm gzdopen , +.Nm gzsetparams , +.Nm gzread , +.Nm gzwrite , +.Nm gzprintf , +.Nm gzputs , +.Nm gzgets , +.Nm gzputc , +.Nm gzgetc , +.Nm gzungetc , +.Nm gzflush , +.Nm gzseek , +.Nm gzrewind , +.Nm gztell , +.Nm gzeof , +.Nm gzdirect , +.Nm gzclose , +.Nm gzerror , +.Nm gzclearerr , +.Nm adler32 , +.Nm adler32_combine , +.Nm crc32 , +.Nm crc32_combine +.Nd zlib general purpose compression library +.Sh SYNOPSIS +.In zlib.h +.Pp +Basic functions +.Pp +.Ft const char * +.Fn zlibVersion "void" +.Ft int +.Fn deflateInit "z_streamp strm" "int level" +.Ft int +.Fn deflate "z_streamp strm" "int flush" +.Ft int +.Fn deflateEnd "z_streamp strm" +.Ft int +.Fn inflateInit "z_streamp strm" +.Ft int +.Fn inflate "z_streamp strm" "int flush" +.Ft int +.Fn inflateEnd "z_streamp strm" +.Pp +Advanced functions +.Pp +.Ft int +.Fn deflateInit2 "z_streamp strm" "int level" "int method" "int windowBits" "int memLevel" "int strategy" +.Ft int +.Fn deflateSetDictionary "z_streamp strm" "const Bytef *dictionary" "uInt dictLength" +.Ft int +.Fn deflateCopy "z_streamp dest" "z_streamp source" +.Ft int +.Fn deflateReset "z_streamp strm" +.Ft int +.Fn deflateParams "z_streamp strm" "int level" "int strategy" +.Ft int +.Fn deflateTune "z_streamp strm" "int good_length" "int max_lazy" "int nice_length" "int max_chain" +.Ft uLong +.Fn deflateBound "z_streamp strm" "uLong sourceLen" +.Ft int +.Fn deflatePrime "z_streamp strm" "int bits" "int value" +.Ft int +.Fn deflateSetHeader "z_streamp strm" "gz_headerp head" +.Ft int +.Fn inflateInit2 "z_streamp strm" "int windowBits" +.Ft int +.Fn inflateSetDictionary "z_streamp strm" "const Bytef *dictionary" "uInt dictLength" +.Ft int +.Fn inflateSync "z_streamp strm" +.Ft int +.Fn inflateCopy "z_streamp dst" "z_streamp source" +.Ft int +.Fn inflateReset "z_streamp strm" +.Ft int +.Fn inflatePrime "z_streamp strm" "int bits" "int value" +.Ft int +.Fn inflateGetHeader "z_streamp strm" "gz_headerp head" +.Ft int +.Fn inflateBackInit "z_stream *strm" "int windowBits" "unsigned char FAR *window" +.Ft int +.Fn inflateBack "z_stream *strm" "in_func in" "void FAR *in_desc" "out_func out" "void FAR *out_desc" +.Ft int +.Fn inflateBackEnd "z_stream *strm" +.Ft uLong +.Fn zlibCompileFlags "void" +.Pp +Utility functions +.Pp +.Fd typedef voidp gzFile; +.Pp +.Ft int +.Fn compress "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" +.Ft int +.Fn compress2 "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" "int level" +.Ft uLong +.Fn compressBound "uLong sourceLen" +.Ft int +.Fn uncompress "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" +.Ft gzFile +.Fn gzopen "const char *path" "const char *mode" +.Ft gzFile +.Fn gzdopen "int fd" "const char *mode" +.Ft int +.Fn gzsetparams "gzFile file" "int level" "int strategy" +.Ft int +.Fn gzread "gzFile file" "voidp buf" "unsigned len" +.Ft int +.Fn gzwrite "gzFile file" "voidpc buf" "unsigned len" +.Ft int +.Fn gzprintf "gzFile file" "const char *format" "..." +.Ft int +.Fn gzputs "gzFile file" "const char *s" +.Ft char * +.Fn gzgets "gzFile file" "char *buf" "int len" +.Ft int +.Fn gzputc "gzFile file" "int c" +.Ft int +.Fn gzgetc "gzFile file" +.Ft int +.Fn gzungetc "int c" "gzFile file" +.Ft int +.Fn gzflush "gzFile file" "int flush" +.Ft z_off_t +.Fn gzseek "gzFile file" "z_off_t offset" "int whence" +.Ft int +.Fn gzrewind "gzFile file" +.Ft z_off_t +.Fn gztell "gzFile file" +.Ft int +.Fn gzeof "gzFile file" +.Ft int +.Fn gzdirect "gzFile file" +.Ft int +.Fn gzclose "gzFile file" +.Ft const char * +.Fn gzerror "gzFile file" "int *errnum" +.Ft void +.Fn gzclearerr "gzFile file" +.Pp +Checksum functions +.Pp +.Ft uLong +.Fn adler32 "uLong adler" "const Bytef *buf" "uInt len" +.Ft uLong +.Fn adler32_combine "uLong adler1" "uLong adler2" "z_off_t len2" +.Ft uLong +.Fn crc32 "uLong crc" "const Bytef *buf" "uInt len" +.Ft uLong +.Fn crc32_combine "uLong crc1" "uLong crc2" "z_off_t len2" +.Sh DESCRIPTION +This manual page describes the +.Nm zlib +general purpose compression library, version 1.2.3. +.Pp +The +.Nm zlib +compression library provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method +.Pq deflation +but other algorithms will be added later and will have the same +stream interface. +.Pp +Compression can be done in a single step if the buffers are large enough +.Pq for example if an input file is mmap'ed , +or can be done by repeated calls of the compression function. +In the latter case, the application must provide more input +and/or consume the output +.Pq providing more output space +before each call. +.Pp +The compressed data format used by default by the in-memory functions is the +.Nm zlib +format, which is a zlib wrapper documented in RFC 1950, +wrapped around a deflate stream, which is itself documented in RFC 1951. +.Pp +The library also supports reading and writing files in +.Xr gzip 1 +.Pq .gz +format with an interface similar to that of +.Xr stdio 3 +using the functions that start with +.Qq gz . +The gzip format is different from the zlib format. +gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. +This library can optionally read and write gzip streams in memory as well. +.Pp +The zlib format was designed to be compact and fast for use in memory +and on communications channels. +The gzip format was designed for single-file compression on file systems, +has a larger header than zlib to maintain directory information, +and uses a different, slower, check method than zlib. +.Pp +The library does not install any signal handler. +The decoder checks the consistency of the compressed data, +so the library should never crash even in case of corrupted input. +.Pp +The functions within the library are divided into the following sections: +.Pp +.Bl -dash -offset indent -compact +.It +Basic functions +.It +Advanced functions +.It +Utility functions +.It +Checksum functions +.El +.Sh BASIC FUNCTIONS +.Bl -tag -width Ds +.It Xo +.Fa const char * +.Fn zlibVersion "void" ; +.Xc +.Pp +The application can compare +.Fn zlibVersion +and +.Dv ZLIB_VERSION +for consistency. +If the first character differs, the library code actually used is +not compatible with the +.In zlib.h +header file used by the application. +This check is automatically made by +.Fn deflateInit +and +.Fn inflateInit . +.It Xo +.Fa int +.Fn deflateInit "z_streamp strm" "int level" ; +.Xc +.Pp +The +.Fn deflateInit +function initializes the internal stream state for compression. +The fields +.Fa zalloc , +.Fa zfree , +and +.Fa opaque +must be initialized before by the caller. +If +.Fa zalloc +and +.Fa zfree +are set to +.Dv Z_NULL , +.Fn deflateInit +updates them to use default allocation functions. +.Pp +The compression level must be +.Dv Z_DEFAULT_COMPRESSION , +or between 0 and 9: +1 gives best speed, 9 gives best compression, 0 gives no compression at all +(the input data is simply copied a block at a time). +.Pp +.Dv Z_DEFAULT_COMPRESSION +requests a default compromise between speed and compression +.Pq currently equivalent to level 6 . +.Pp +.Fn deflateInit +returns +.Dv Z_OK +if successful, +.Dv Z_MEM_ERROR +if there was not enough memory, +.Dv Z_STREAM_ERROR +if level is not a valid compression level, +.Dv Z_VERSION_ERROR +if the +.Nm zlib +library version +.Pq zlib_version +is incompatible with the version assumed by the caller +.Pq ZLIB_VERSION . +.Fa msg +is set to null if there is no error message. +.Fn deflateInit +does not perform any compression: this will be done by +.Fn deflate . +.It Xo +.Fa int +.Fn deflate "z_streamp strm" "int flush" ; +.Xc +.Pp +.Fn deflate +compresses as much data as possible, and stops when the input +buffer becomes empty or the output buffer becomes full. +It may introduce some output latency +.Pq reading input without producing any output +except when forced to flush. +.Pp +The detailed semantics are as follows. +.Fn deflate +performs one or both of the following actions: +.Pp +Compress more input starting at +.Fa next_in +and update +.Fa next_in +and +.Fa avail_in +accordingly. +If not all input can be processed +(because there is not enough room in the output buffer), +.Fa next_in +and +.Fa avail_in +are updated and processing will resume at this point for the next call to +.Fn deflate . +.Pp +Provide more output starting at +.Fa next_out +and update +.Fa next_out +and +.Fa avail_out +accordingly. +This action is forced if the parameter +.Fa flush +is non-zero. +Forcing +.Fa flush +frequently degrades the compression ratio, +so this parameter should be set only when necessary +.Pq in interactive applications . +Some output may be provided even if +.Fa flush +is not set. +.Pp +Before the call to +.Fn deflate , +the application should ensure that at least +one of the actions is possible, by providing more input and/or consuming +more output, and updating +.Fa avail_in +or +.Fa avail_out +accordingly; +.Fa avail_out +should never be zero before the call. +The application can consume the compressed output when it wants, +for example when the output buffer is full +.Pq avail_out == 0 , +or after each call to +.Fn deflate . +If +.Fn deflate +returns +.Dv Z_OK +and with zero +.Fa avail_out , +it must be called again after making room in the +output buffer because there might be more output pending. +.Pp +Normally the parameter +.Fa flush +is set to +.Dv Z_NO_FLUSH , +which allows +.Fn deflate +to decide how much data to accumulate before producing output, +in order to maximise compression. +.Pp +If the parameter +.Fa flush +is set to +.Dv Z_SYNC_FLUSH , +all pending output is flushed to the output buffer and the output +is aligned on a byte boundary, so that the decompressor can get all +input data available so far. +(In particular, +.Fa avail_in +is zero after the call if enough output space +has been provided before the call.) +Flushing may degrade compression for some compression algorithms +and so it should be used only when necessary. +.Pp +If +.Fa flush +is set to +.Dv Z_FULL_FLUSH , +all output is flushed as with +.Dv Z_SYNC_FLUSH , +and the compression state is reset so that decompression can restart from this +point if previous compressed data has been damaged or if random access +is desired. +Using +.Dv Z_FULL_FLUSH +too often can seriously degrade compression. +.Pp +If +.Fn deflate +returns with avail_out == 0, this function must be called again +with the same value of the flush parameter and more output space +(updated +.Fa avail_out ) , +until the flush is complete +.Pf ( Fn deflate +returns with non-zero +.Fa avail_out ) . +In the case of a +.Dv Z_FULL_FLUSH +or a +.Dv Z_SYNC_FLUSH , +make sure that +.Fa avail_out +is greater than six to avoid repeated flush markers due to avail_out == 0 +on return. +.Pp +If the parameter +.Fa flush +is set to +.Dv Z_FINISH , +pending input is processed, pending output is flushed and +.Fn deflate +returns with +.Dv Z_STREAM_END +if there was enough output space; if +.Fn deflate +returns with +.Dv Z_OK , +this function must be called again with +.Dv Z_FINISH +and more output space +(updated +.Fa avail_out +but no more input data, until it returns with +.Dv Z_STREAM_END +or an error. +After +.Fn deflate +has returned +.Dv Z_STREAM_END , +the only possible operations on the stream are +.Fn deflateReset +or +.Fn deflateEnd . +.Pp +.Dv Z_FINISH +can be used immediately after +.Fn deflateInit +if all the compression is to be done in a single step. +In this case, +.Fa avail_out +must be at least the value returned by +.Fn deflateBound +.Pq see below . +If +.Fn deflate +does not return +.Dv Z_STREAM_END , +then it must be called again as described above. +.Pp +.Fn deflate +sets strm->adler to the Adler-32 checksum of all input read so far +(that is, +.Fa total_in +bytes). +.Pp +.Fn deflate +may update strm->data_type +if it can make a good guess about the input data type +.Pq Z_BINARY or Z_TEXT . +If in doubt, the data is considered binary. +This field is only for information purposes and does not affect +the compression algorithm in any manner. +.Pp +.Fn deflate +returns +.Dv Z_OK +if some progress has been made +.Pq more input processed or more output produced , +.Dv Z_STREAM_END +if all input has been consumed and all output has been produced +(only when +.Fa flush +is set to +.Dv Z_FINISH ) , +.Dv Z_STREAM_ERROR +if the stream state was inconsistent +(for example, if +.Fa next_in +or +.Fa next_out +was +.Dv NULL ) , +.Dv Z_BUF_ERROR +if no progress is possible +(for example, +.Fa avail_in +or +.Fa avail_out +was zero). +Note that +.Dv Z_BUF_ERROR +is not fatal, and +.Fn deflate +can be called again with more input and more output space +to continue processing. +.It Xo +.Fa int +.Fn deflateEnd "z_streamp strm" ; +.Xc +.Pp +All dynamically allocated data structures for this stream are freed. +This function discards any unprocessed input and does not flush any +pending output. +.Pp +.Fn deflateEnd +returns +.Dv Z_OK +if successful, +.Dv Z_STREAM_ERROR +if the stream state was inconsistent, +.Dv Z_DATA_ERROR +if the stream was freed prematurely +.Pq some input or output was discarded . +In the error case, +.Fa msg +may be set but then points to a static string +.Pq which must not be deallocated . +.It Xo +.Fa int +.Fn inflateInit "z_streamp strm" ; +.Xc +The +.Fn inflateInit +function initializes the internal stream state for decompression. +The fields +.Fa next_in , +.Fa avail_in , +.Fa zalloc , +.Fa zfree , +and +.Fa opaque +must be initialized before by the caller. +If +.Fa next_in +is not +.Dv Z_NULL +and +.Fa avail_in +is large enough +.Pq the exact value depends on the compression method , +.Fn inflateInit +determines the compression method from the +.Nm zlib +header and allocates all data structures accordingly; +otherwise the allocation will be deferred to the first call to +.Fn inflate . +If +.Fa zalloc +and +.Fa zfree +are set to +.Dv Z_NULL , +.Fn inflateInit +updates them to use default allocation functions. +.Pp +.Fn inflateInit +returns +.Dv Z_OK +if successful, +.Dv Z_MEM_ERROR +if there was not enough memory, +.Dv Z_VERSION_ERROR +if the +.Nm zlib +library version is incompatible with the version assumed by the caller. +.Fa msg +is set to null if there is no error message. +.Fn inflateInit +does not perform any decompression apart from reading the +.Nm zlib +header if present: this will be done by +.Fn inflate . +(So +.Fa next_in +and +.Fa avail_in +may be modified, +but +.Fa next_out +and +.Fa avail_out +are unchanged.) +.It Xo +.Fa int +.Fn inflate "z_streamp strm" "int flush" ; +.Xc +.Fn inflate +decompresses as much data as possible, and stops when the input +buffer becomes empty or the output buffer becomes full. +It may introduce some output latency +.Pq reading input without producing any output +except when forced to flush. +.Pp +The detailed semantics are as follows. +.Fn inflate +performs one or both of the following actions: +.Pp +Decompress more input starting at +.Fa next_in +and update +.Fa next_in +and +.Fa avail_in +accordingly. +If not all input can be processed +(because there is not enough room in the output buffer), +.Fa next_in +is updated and processing will resume at this point for the next call to +.Fn inflate . +.Pp +Provide more output starting at +.Fa next_out +and update +.Fa next_out +and +.Fa avail_out +accordingly. +.Fn inflate +provides as much output as possible, +until there is no more input data or no more space in the output buffer +.Pq see below about the flush parameter . +.Pp +Before the call to +.Fn inflate , +the application should ensure that at least one of the actions is possible, +by providing more input and/or consuming more output, +and updating the next_* and avail_* values accordingly. +The application can consume the uncompressed output when it wants, +for example when the output buffer is full (avail_out == 0), +or after each call to +.Fn inflate . +If +.Fn inflate +returns +.Dv Z_OK +and with zero +.Fa avail_out , +it must be called again after making room +in the output buffer because there might be more output pending. +.Pp +The +.Fa flush +parameter of +.Fn inflate +can be +.Dv Z_NO_FLUSH , Z_SYNC_FLUSH , Z_FINISH , +or +.Dv Z_BLOCK . +.Dv Z_SYNC_FLUSH +requests that +.Fn inflate +flush as much output as possible to the output buffer. +.Dv Z_BLOCK +requests that +.Fn inflate +stop if and when it gets to the next deflate block boundary. +When decoding the zlib or gzip format, this will cause +.Fn inflate +to return immediately after the header and before the first block. +When doing a raw inflate, +.Fn inflate +will go ahead and process the first block, +and will return when it gets to the end of that block, +or when it runs out of data. +.Pp +The +.Dv Z_BLOCK +option assists in appending to or combining deflate streams. +Also to assist in this, on return +.Fn inflate +will set strm->data_type to the number of unused bits in the last byte +taken from strm->next_in, plus 64 if +.Fn inflate +is currently decoding the last block in the deflate stream, plus 128 if +.Fn inflate +returned immediately after decoding an end-of-block code or decoding +the complete header up to just before the first byte of the deflate stream. +The end-of-block will not be indicated until all of the uncompressed data +from that block has been written to strm->next_out. +The number of unused bits may in general be greater than seven, +except when bit 7 of data_type is set, +in which case the number of unused bits will be less than eight. +.Pp +.Fn inflate +should normally be called until it returns +.Dv Z_STREAM_END +or an error. +However if all decompression is to be performed in a single step +.Pq a single call to inflate , +the parameter +.Fa flush +should be set to +.Dv Z_FINISH . +In this case all pending input is processed and all pending output is flushed; +.Fa avail_out +must be large enough to hold all the uncompressed data. +(The size of the uncompressed data may have been saved +by the compressor for this purpose.) +The next operation on this stream must be +.Fn inflateEnd +to deallocate the decompression state. +The use of +.Dv Z_FINISH +is never required, but can be used to inform +.Fn inflate +that a faster approach may be used for the single +.Fn inflate +call. +.Pp +In this implementation, +.Fn inflate +always flushes as much output as possible to the output buffer, +and always uses the faster approach on the first call. +So the only effect of the +.Fa flush +parameter in this implementation is on the return value of +.Fn inflate , +as noted below, or when it returns early because +.Dv Z_BLOCK +is used. +.Pp +If a preset dictionary is needed after this call (see +.Fn inflateSetDictionary +below), +.Fn inflate +sets strm->adler to the Adler-32 checksum of the dictionary +chosen by the compressor and returns Z_NEED_DICT; otherwise it sets +strm->adler to the Adler-32 checksum of all output produced so far +(that is, +.Fa total_out +bytes) and returns +.Dv Z_OK , Z_STREAM_END +or an error code as described below. +At the end of the stream, +.Fn inflate +checks that its computed Adler-32 checksum is equal to that saved by +the compressor and returns +.Dv Z_STREAM_END +only if the checksum is correct. +.Pp +.Fn inflate +will decompress and check either zlib-wrapped or gzip-wrapped deflate data. +The header type is detected automatically. +Any information contained in the gzip header is not retained, +so applications that need that information should instead use raw inflate; see +.Fn inflateInit2 +below, or +.Fn inflateBack +and perform their own processing of the gzip header and trailer. +.Pp +.Fn inflate +returns +.Dv Z_OK +if some progress has been made +.Pq more input processed or more output produced , +.Dv Z_STREAM_END +if the end of the compressed data has been reached and all uncompressed output +has been produced, +.Dv Z_NEED_DICT +if a preset dictionary is needed at this point, +.Dv Z_DATA_ERROR +if the input data was corrupted (input stream not conforming to the +.Nm zlib +format or incorrect check value), +.Dv Z_STREAM_ERROR +if the stream structure was inconsistent +(for example, if +.Fa next_in +or +.Fa next_out +was +.Dv NULL ) , +.Dv Z_MEM_ERROR +if there was not enough memory, +.Dv Z_BUF_ERROR +if no progress is possible or if there was not enough room in the output buffer +when +.Dv Z_FINISH +is used. +Note that +.Dv Z_BUF_ERROR +is not fatal, and +.Fn inflate +can be called again with more input and more output space +to continue compressing. +If +.Dv Z_DATA_ERROR +is returned, the application may then call +.Fn inflateSync +to look for a good compression block if a partial recovery +of the data is desired. +.It Xo +.Fa int +.Fn inflateEnd "z_streamp strm" ; +.Xc +All dynamically allocated data structures for this stream are freed. +This function discards any unprocessed input and does not flush any +pending output. +.Pp +.Fn inflateEnd +returns +.Dv Z_OK +if successful, or +.Dv Z_STREAM_ERROR +if the stream state was inconsistent. +In the error case, +.Fa msg +may be set but then points to a static string +.Pq which must not be deallocated . +.El +.Sh ADVANCED FUNCTIONS +The following functions are needed only in some special applications. +.Bl -tag -width Ds +.It Xo +.Fa int +.Fn deflateInit2 "z_streamp strm" "int level" "int method" "int windowBits" "int memLevel" "int strategy" ; +.Xc +.Pp +This is another version of +.Fn deflateInit +with more compression options. +The fields +.Fa next_in , +.Fa zalloc , +.Fa zfree , +and +.Fa opaque +must be initialized before by the caller. +.Pp +The +.Fa method +parameter is the compression method. +It must be +.Dv Z_DEFLATED +in this version of the library. +.Pp +The +.Fa windowBits +parameter is the base two logarithm of the window size +.Pq the size of the history buffer . +It should be in the range 8..15 for this version of the library. +Larger values of this parameter result in better compression +at the expense of memory usage. +The default value is 15 if +.Fn deflateInit +is used instead. +.Pp +.Fa windowBits +can also be -8..-15 for raw deflate. +In this case, -windowBits determines the window size. +.Fn deflate +will then generate raw deflate data with no zlib header or trailer, +and will not compute an Adler-32 check value. +.Pp +.Fa windowBits +can also be greater than 15 for optional gzip encoding. +Add 16 to +.Fa windowBits +to write a simple gzip header and trailer around the +compressed data instead of a zlib wrapper. +The gzip header will have no file name, no extra data, no comment, +no modification time +.Pq set to zero , +no header crc, and the operating system will be set to 255 +.Pq unknown . +If a gzip stream is being written, +strm->adler is a crc32 instead of an adler32. +.Pp +The +.Fa memLevel +parameter specifies how much memory should be allocated +for the internal compression state. +memLevel=1 uses minimum memory but is slow and reduces compression ratio; +memLevel=9 uses maximum memory for optimal speed. +The default value is 8. +See +.In zconf.h +for total memory usage as a function of +.Fa windowBits +and +.Fa memLevel . +.Pp +The +.Fa strategy +parameter is used to tune the compression algorithm. +Use the value +.Dv Z_DEFAULT_STRATEGY +for normal data; +.Dv Z_FILTERED +for data produced by a filter +.Pq or predictor ; +.Dv Z_HUFFMAN_ONLY +to force Huffman encoding only +.Pq no string match , +or +.Dv Z_RLE +to limit match distances to one +.Pq run-length encoding . +Filtered data consists mostly of small values with a +somewhat random distribution. +In this case, the compression algorithm is tuned to compress them better. +The effect of +.Dv Z_FILTERED +is to force more Huffman coding and less string matching; +it is somewhat intermediate between +.Dv Z_DEFAULT +and +.Dv Z_HUFFMAN_ONLY . +.Dv Z_RLE +is designed to be almost as fast as +.Dv Z_HUFFMAN_ONLY , +but gives better compression for PNG image data. +The +.Fa strategy +parameter only affects the compression ratio but not the correctness of the +compressed output, even if it is not set appropriately. +.Dv Z_FIXED +prevents the use of dynamic Huffman codes, +allowing for a simpler decoder for special applications. +.Pp +.Fn deflateInit2 +returns +.Dv Z_OK +if successful, +.Dv Z_MEM_ERROR +if there was not enough memory, +.Dv Z_STREAM_ERROR +if a parameter is invalid +.Pq such as an invalid method . +.Fa msg +is set to null if there is no error message. +.Fn deflateInit2 +does not perform any compression: this will be done by +.Fn deflate . +.It Xo +.Fa int +.Fn deflateSetDictionary "z_streamp strm" "const Bytef *dictionary" "uInt dictLength" ; +.Xc +.Pp +Initializes the compression dictionary from the given byte sequence +without producing any compressed output. +This function must be called immediately after +.Fn deflateInit , +.Fn deflateInit2 , +or +.Fn deflateReset , +before any call to +.Fn deflate . +The compressor and decompressor must use exactly the same dictionary +(see +.Fn inflateSetDictionary ) . +.Pp +The dictionary should consist of strings +.Pq byte sequences +that are likely to be encountered later in the data to be compressed, +with the most commonly used strings preferably put towards +the end of the dictionary. +Using a dictionary is most useful when the data to be compressed is short +and can be predicted with good accuracy; +the data can then be compressed better than with the default empty dictionary. +.Pp +Depending on the size of the compression data structures selected by +.Fn deflateInit +or +.Fn deflateInit2 , +a part of the dictionary may in effect be discarded, +for example if the dictionary is larger than the window size in +.Fn deflate +or +.Fn deflate2 . +Thus the strings most likely to be useful should be +put at the end of the dictionary, not at the front. +In addition, the current implementation of +.Fn deflate +will use at most the window size minus 262 bytes of the provided dictionary. +.Pp +Upon return of this function, strm->adler is set to the Adler-32 value +of the dictionary; the decompressor may later use this value to determine +which dictionary has been used by the compressor. +(The Adler-32 value applies to the whole dictionary even if only a subset +of the dictionary is actually used by the compressor.) +If a raw deflate was requested, then the Adler-32 value is not computed +and strm->adler is not set. +.Pp +.Fn deflateSetDictionary +returns +.Dv Z_OK +if successful, +or +.Dv Z_STREAM_ERROR +if a parameter is invalid +.Pq such as NULL dictionary +or the stream state is inconsistent +(for example if +.Fn deflate +has already been called for this stream or if the compression method is bsort). +.Fn deflateSetDictionary +does not perform any compression: this will be done by +.Fn deflate . +.It Xo +.Fa int +.Fn deflateCopy "z_streamp dest" "z_streamp source" ; +.Xc +.Pp +The +.Fn deflateCopy +function sets the destination stream as a complete copy of the source stream. +.Pp +This function can be useful when several compression strategies will be +tried, for example when there are several ways of pre-processing the input +data with a filter. +The streams that will be discarded should then be freed by calling +.Fn deflateEnd . +Note that +.Fn deflateCopy +duplicates the internal compression state which can be quite large, +so this strategy is slow and can consume lots of memory. +.Pp +.Fn deflateCopy +returns +.Dv Z_OK +if successful, +.Dv Z_MEM_ERROR +if there was not enough memory, +.Dv Z_STREAM_ERROR +if the source stream state was inconsistent +(such as +.Fa zalloc +being NULL). +.Fa msg +is left unchanged in both source and destination. +.It Xo +.Fa int +.Fn deflateReset "z_streamp strm" ; +.Xc +.Pp +This function is equivalent to +.Fn deflateEnd +followed by +.Fn deflateInit , +but does not free and reallocate all the internal compression state. +The stream will keep the same compression level and any other attributes +that may have been set by +.Fn deflateInit2 . +.Pp +.Fn deflateReset +returns +.Dv Z_OK +if successful, or +.Dv Z_STREAM_ERROR +if the source stream state was inconsistent +(such as +.Fa zalloc +or +.Fa state +being NULL). +.It Xo +.Fa int +.Fn deflateParams "z_streamp strm" "int level" "int strategy" ; +.Xc +.Pp +The +.Fn deflateParams +function dynamically updates the compression level and compression strategy. +The interpretation of level and strategy is as in +.Fn deflateInit2 . +This can be used to switch between compression and straight copy +of the input data, or to switch to a different kind of input data +requiring a different strategy. +If the compression level is changed, the input available so far +is compressed with the old level +.Pq and may be flushed ; +the new level will take effect only at the next call to +.Fn deflate . +.Pp +Before the call to +.Fn deflateParams , +the stream state must be set as for a call to +.Fn deflate , +since the currently available input may have to be compressed and flushed. +In particular, strm->avail_out must be non-zero. +.Pp +.Fn deflateParams +returns +.Dv Z_OK +if successful, +.Dv Z_STREAM_ERROR +if the source stream state was inconsistent or if a parameter was invalid, or +.Dv Z_BUF_ERROR +if strm->avail_out was zero. +.It Xo +.Fa int +.Fn deflateTune "z_streamp strm" "int good_length" "int max_lazy" "int nice_length" "int max_chain" +.Xc +.Pp +Fine tune +.Fn deflate Ns 's +internal compression parameters. +This should only be used by someone who understands the algorithm +used by zlib's deflate for searching for the best matching string, +and even then only by the most fanatic optimizer +trying to squeeze out the last compressed bit for their specific input data. +Read the +.Pa deflate.c +source code for the meaning of the +.Fa max_lazy , good_length , nice_length , +and +.Fa max_chain +parameters. +.Pp +.Fn deflateTune +can be called after +.Fn deflateInit +or +.Fn deflateInit2 , +and returns +.Dv Z_OK +on success, or +.Dv Z_STREAM_ERROR +for an invalid deflate stream. +.It Xo +.Fa uLong +.Fn deflateBound "z_streamp strm" "uLong sourceLen" +.Xc +.Pp +.Fn deflateBound +returns an upper bound on the compressed size after deflation of +.Fa sourceLen +bytes. +It must be called after +.Fn deflateInit +or +.Fn deflateInit2 . +This would be used to allocate an output buffer for deflation in a single pass, +and so would be called before +.Fn deflate . +.It Xo +.Fa int +.Fn deflatePrime "z_streamp strm" "int bits" "int value" +.Xc +.Pp +.Fn deflatePrime +inserts +.Fa bits +in the deflate output stream. +The intent is that this function is used to start off the deflate output +with the bits leftover from a previous deflate stream when appending to it. +As such, this function can only be used for raw deflate, +and must be used before the first +.Fn deflate +call after a +.Fn deflateInit2 +or +.Fn deflateReset . +.Fa bits +must be less than or equal to 16, +and that many of the least significant bits of +.Fa value +will be inserted in the output. +.Pp +.Fn deflatePrime +returns +.Dv Z_OK +if successful, or +.Dv Z_STREAM_ERROR +if the source stream state was inconsistent. +.It Xo +.Fa int +.Fn deflateSetHeader "z_streamp strm" "gz_headerp head" +.Xc +.Pp +.Fn deflateSetHeader +provides gzip header information for when a gzip +stream is requested by +.Fn deflateInit2 . +.Fn deflateSetHeader +may be called after +.Fn deflateInit2 +or +.Fn deflateReset +and before the first call of +.Fn deflate . +The text, time, os, extra field, name, and comment information +in the provided gz_header structure are written to the gzip header +(xflag is ignored \- the extra flags are set +according to the compression level). +The caller must assure that, if not +.Dv Z_NULL , +.Fa name +and +.Fa comment +are terminated with a zero byte, +and that if +.Fa extra +is not +.Dv Z_NULL , +that +.Fa extra_len +bytes are available there. +If hcrc is true, a gzip header CRC is included. +Note that the current versions of the command-line version of +.Xr gzip 1 +do not support header CRCs, and will report that it is a +.Dq multi-part gzip file +and give up. +.Pp +If +.Fn deflateSetHeader +is not used, the default gzip header has text false, +the time set to zero, and os set to 255, with no extra, name, or comment +fields. +The gzip header is returned to the default state by +.Fn deflateReset . +.Pp +.Fn deflateSetHeader +returns +.Dv Z_OK +if successful, or +.Dv Z_STREAM_ERROR +if the source stream state was inconsistent. +.It Xo +.Fa int +.Fn inflateInit2 "z_streamp strm" "int windowBits" ; +.Xc +.Pp +This is another version of +.Fn inflateInit +with an extra parameter. +The fields +.Fa next_in , +.Fa avail_in , +.Fa zalloc , +.Fa zfree , +and +.Fa opaque +must be initialized before by the caller. +.Pp +The +.Fa windowBits +parameter is the base two logarithm of the maximum window size +.Pq the size of the history buffer . +It should be in the range 8..15 for this version of the library. +The default value is 15 if +.Fn inflateInit +is used instead. +.Fa windowBits +must be greater than or equal to the +.Fa windowBits +value provided to +.Fn deflateInit2 +while compressing, or it must be equal to 15 if +.Fn deflateInit2 +was not used. +If a compressed stream with a larger window size is given as input, +.Fn inflate +will return with the error code +.Dv Z_DATA_ERROR +instead of trying to allocate a larger window. +.Pp +.Fa windowBits +can also be -8..-15 for raw inflate. +In this case, -windowBits determines the window size. +.Fn inflate +will then process raw deflate data, not looking for a zlib or gzip header, +not generating a check value, and not looking for any check values +for comparison at the end of the stream. +This is for use with other formats that use the deflate compressed data format +such as zip. +Those formats provide their own check values. +If a custom format is developed using the raw deflate format +for compressed data, it is recommended that a check value such as an Adler-32 +or a crc32 be applied to the uncompressed data as is done in the zlib, gzip, +and zip formats. +For most applications, the zlib format should be used as is. +Note that comments above on the use in +.Fn deflateInit2 +applies to the magnitude of +.Fa windowBits . +.Pp +.Fa windowBits +can also be greater than 15 for optional gzip decoding. +Add 32 to windowBits to enable zlib and gzip decoding with automatic header +detection, or add 16 to decode only the gzip format +(the zlib format will return a +.Dv Z_DATA_ERROR ) . +If a gzip stream is being decoded, +strm->adler is a crc32 instead of an adler32. +.Pp +.Fn inflateInit2 +returns +.Dv Z_OK +if successful, +.Dv Z_MEM_ERROR +if there was not enough memory, +.Dv Z_STREAM_ERROR +if a parameter is invalid +(such as a null strm). +.Fa msg +is set to null if there is no error message. +.Fn inflateInit2 +does not perform any decompression apart from reading the +.Nm zlib +header if present: this will be done by +.Fn inflate . +(So +.Fa next_in +and +.Fa avail_in +may be modified, but +.Fa next_out +and +.Fa avail_out +are unchanged.) +.It Xo +.Fa int +.Fn inflateSetDictionary "z_streamp strm" "const Bytef *dictionary" "uInt dictLength" ; +.Xc +.Pp +Initializes the decompression dictionary from the given uncompressed byte +sequence. +This function must be called immediately after a call to +.Fn inflate +if that call returned +.Dv Z_NEED_DICT . +The dictionary chosen by the compressor can be determined from the +Adler-32 value returned by that call to +.Fn inflate . +The compressor and decompressor must use exactly the same dictionary +(see +.Fn deflateSetDictionary ) . +For raw inflate, this function can be called immediately after +.Fn inflateInit2 +or +.Fn inflateReset +and before any call to +.Fn inflate +to set the dictionary. +The application must ensure that the dictionary +that was used for compression is provided. +.Pp +.Fn inflateSetDictionary +returns +.Dv Z_OK +if successful, +.Dv Z_STREAM_ERROR +if a parameter is invalid +.Pq such as NULL dictionary +or the stream state is inconsistent, +.Dv Z_DATA_ERROR +if the given dictionary doesn't match the expected one +.Pq incorrect Adler-32 value . +.Fn inflateSetDictionary +does not perform any decompression: this will be done by subsequent calls of +.Fn inflate . +.It Xo +.Fa int +.Fn inflateSync "z_streamp strm" ; +.Xc +.Pp +Skips invalid compressed data until a full flush point +(see above the description of +.Fn deflate +with +.Dv Z_FULL_FLUSH ) +can be found, or until all available input is skipped. +No output is provided. +.Pp +.Fn inflateSync +returns +.Dv Z_OK +if a full flush point has been found, +.Dv Z_BUF_ERROR +if no more input was provided, +.Dv Z_DATA_ERROR +if no flush point has been found, or +.Dv Z_STREAM_ERROR +if the stream structure was inconsistent. +In the success case, the application may save the current value of +.Fa total_in +which indicates where valid compressed data was found. +In the error case, the application may repeatedly call +.Fn inflateSync , +providing more input each time, until success or end of the input data. +.It Xo +.Fa int +.Fn inflateCopy "z_streamp dest" "z_streamp source" +.Xc +.Pp +Sets the destination stream as a complete copy of the source stream. +.Pp +This function can be useful when randomly accessing a large stream. +The first pass through the stream can periodically record the inflate state, +allowing restarting inflate at those points when randomly accessing the stream. +.Pp +.Fn inflateCopy +returns +.Dv Z_OK +if success, +.Dv Z_MEM_ERROR +if there was not enough memory, +.Dv Z_STREAM_ERROR +if the source stream state was inconsistent +(such as +.Fa zalloc +being NULL). +.Fa msg +is left unchanged in both +.Fa source +and +.Fa dest . +.It Xo +.Fa int +.Fn inflateReset "z_streamp strm" ; +.Xc +.Pp +This function is equivalent to +.Fn inflateEnd +followed by +.Fn inflateInit , +but does not free and reallocate all the internal decompression state. +The stream will keep attributes that may have been set by +.Fn inflateInit2 . +.Pp +.Fn inflateReset +returns +.Dv Z_OK +if successful, or +.Dv Z_STREAM_ERROR +if the source stream state was inconsistent +(such as +.Fa zalloc +or +.Fa state +being NULL). +.It Xo +.Fa int +.Fn inflatePrime "z_stream strm" "int bits" "int value" +.Xc +.Pp +This function inserts bits in the inflate input stream. +The intent is that this function is used +to start inflating at a bit position in the middle of a byte. +The provided bits will be used before any bytes are used from +.Fa next_in . +This function should only be used with raw inflate, +and should be used before the first +.Fn inflate +call after +.Fn inflateInit2 +or +.Fn inflateReset . +.Fa bits +must be less than or equal to 16, +and that many of the least significant bits of value +will be inserted in the input. +.Pp +.Fn inflatePrime +returns +.Dv Z_OK +if successful, or +.Dv Z_STREAM_ERROR +if the source stream state was inconsistent. +.It Xo +.Fa int +.Fn inflateGetHeader "z_streamp strm" "gz_headerp head" +.Xc +.Pp +.Fn inflateGetHeader +requests that gzip header information be stored in the +provided gz_header structure. +.Fn inflateGetHeader +may be called after +.Fn inflateInit2 +or +.Fn inflateReset , +and before the first call of +.Fn inflate . +As +.Fn inflate +processes the gzip stream, head->done is zero until the header +is completed, at which time head->done is set to one. +If a zlib stream is being decoded, +then head->done is set to \-1 to indicate that there will be +no gzip header information forthcoming. +Note that +.Dv Z_BLOCK +can be used to force +.Fn inflate +to return immediately after header processing is complete +and before any actual data is decompressed. +.Pp +The text, time, xflags, and os fields are filled in with the gzip header +contents. +hcrc is set to true if there is a header CRC. +(The header CRC was valid if done is set to one.) +If extra is not +.Dv Z_NULL , +then +.Fa extra_max +contains the maximum number of bytes to write to +.Fa extra . +Once done is true, +.Fa extra_len +contains the actual extra field length, and +.Fa extra +contains the extra field, or that field truncated if +.Fa extra_max +is less than +.Fa extra_len . +If name is not +.Dv Z_NULL , +then up to +.Fa name_max +characters are written there, +terminated with a zero unless the length is greater than +.Fa name_max . +If comment is not +.Dv Z_NULL , +then up to +.Fa comm_max +characters are written there, +terminated with a zero unless the length is greater than +.Fa comm_max . +When any of extra, name, or comment are not +.Dv Z_NULL +and the respective field is not present in the header, +then that field is set to +.Dv Z_NULL +to signal its absence. +This allows the use of +.Fn deflateSetHeader +with the returned structure to duplicate the header. +However if those fields are set to allocated memory, +then the application will need to save those pointers +elsewhere so that they can be eventually freed. +.Pp +If +.Fn inflateGetHeader +is not used, then the header information is simply discarded. +The header is always checked for validity, +including the header CRC if present. +.Fn inflateReset +will reset the process to discard the header information. +The application would need to call +.Fn inflateGetHeader +again to retrieve the header from the next gzip stream. +.Pp +.Fn inflateGetHeader +returns +.Dv Z_OK +if successful, +or +.Dv Z_STREAM_ERROR +if the source stream state was inconsistent. +.It Xo +.Fa int +.Fn inflateBackInit "z_stream *strm" "int windowBits" "unsigned char FAR *window" +.Xc +.Pp +Initialize the internal stream state for decompression using +.Fn inflateBack +calls. +The fields +.Fa zalloc , zfree +and +.Fa opaque +in +.Fa strm +must be initialized before the call. +If +.Fa zalloc +and +.Fa zfree +are +.Dv Z_NULL , +then the default library-derived memory allocation routines are used. +.Fa windowBits +is the base two logarithm of the window size, in the range 8..15. +.Fa window +is a caller supplied buffer of that size. +Except for special applications where it is assured that +.Fn deflate +was used with small window sizes, +.Fa windowBits +must be 15 and a 32K byte window must be supplied to be able to decompress +general deflate streams. +.Pp +See +.Fn inflateBack +for the usage of these routines. +.Pp +.Fn inflateBackInit +will return +.Dv Z_OK +on success, +.Dv Z_STREAM_ERROR +if any of the parameters are invalid, +.Dv Z_MEM_ERROR +if the internal state could not be allocated, or +.Dv Z_VERSION_ERROR +if the version of the library does not match the version of the header file. +.It Xo +.Fa int +.Fn inflateBack "z_stream *strm" "in_func in" "void FAR *in_desc" "out_func out" "void FAR *out_desc" +.Xc +.Pp +.Fn inflateBack +does a raw inflate with a single call using a call-back +interface for input and output. +This is more efficient than +.Fn inflate +for file I/O applications in that it avoids copying between the output and the +sliding window by simply making the window itself the output buffer. +This function trusts the application to not change the output buffer passed by +the output function, at least until +.Fn inflateBack +returns. +.Pp +.Fn inflateBackInit +must be called first to allocate the internal state +and to initialize the state with the user-provided window buffer. +.Fn inflateBack +may then be used multiple times to inflate a complete, raw +deflate stream with each call. +.Fn inflateBackEnd +is then called to free the allocated state. +.Pp +A raw deflate stream is one with no zlib or gzip header or trailer. +This routine would normally be used in a utility that reads zip or gzip +files and writes out uncompressed files. +The utility would decode the header and process the trailer on its own, +hence this routine expects only the raw deflate stream to decompress. +This is different from the normal behavior of +.Fn inflate , +which expects either a zlib or gzip header and +trailer around the deflate stream. +.Pp +.Fn inflateBack +uses two subroutines supplied by the caller that are then called by +.Fn inflateBack +for input and output. +.Fn inflateBack +calls those routines until it reads a complete deflate stream and writes out +all of the uncompressed data, or until it encounters an error. +The function's parameters and return types are defined above in the +in_func and out_func typedefs. +.Fn inflateBack +will call in(in_desc, &buf) which should return the +number of bytes of provided input, and a pointer to that input in +.Fa buf . +If there is no input available, +.Fn in +must return zero +\(em buf is ignored in that case \(em +and +.Fn inflateBack +will return a buffer error. +.Fn inflateBack +will call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. +.Fn out +should return zero on success, or non-zero on failure. +If +.Fn out +returns non-zero, +.Fn inflateBack +will return with an error. +Neither +.Fn in +nor +.Fn out +are permitted to change the contents of the window provided to +.Fn inflateBackInit , +which is also the buffer that +.Fn out +uses to write from. +The length written by +.Fn out +will be at most the window size. +Any non-zero amount of input may be provided by +.Fn in . +.Pp +For convenience, +.Fn inflateBack +can be provided input on the first call by setting strm->next_in +and strm->avail_in. +If that input is exhausted, then +.Fn in +will be called. +Therefore strm->next_in must be initialized before calling +.Fn inflateBack . +If strm->next_in is +.Dv Z_NULL , +then +.Fn in +will be called immediately for input. +If strm->next_in is not +.Dv Z_NULL , +then strm->avail_in must also be initialized, +and then if strm->avail_in is not zero, +input will initially be taken from +strm->next_in[0 .. strm->avail_in \- 1]. +.Pp +The +.Fa in_desc +and +.Fa out_desc +parameters of +.Fn inflateBack +are passed as the first parameter of +.Fn in +and +.Fn out +respectively when they are called. +These descriptors can be optionally used to pass any information that the +caller-supplied +.Fn in +and +.Fn out +functions need to do their job. +.Pp +On return, +.Fn inflateBack +will set strm->next_in and strm->avail_in to pass back any unused input +that was provided by the last +.Fn in +call. +The return values of +.Fn inflateBack +can be +.Dv Z_STREAM_END +on success, +.Dv Z_BUF_ERROR +if +.Fn in +or +.Fn out +returned an error, +.Dv Z_DATA_ERROR +if there was a format error in the deflate stream +(in which case strm->msg is set to indicate the nature of the error), +or +.Dv Z_STREAM_ERROR +if the stream was not properly initialized. +In the case of +.Dv Z_BUF_ERROR , +an input or output error can be distinguished using strm->next_in which +will be +.Dv Z_NULL +only if +.Fn in +returned an error. +If strm->next is not +.Dv Z_NULL , +then the +.Dv Z_BUF_ERROR +was due to +.Fn out +returning non-zero. +.Po +.Fn in +will always be called before +.Fn out , +so strm->next_in is assured to be defined if +.Fn out +returns non-zero. +.Pc +Note that +.Fn inflateBack +cannot return +.Dv Z_OK . +.It Xo +.Fa int +.Fn inflateBackEnd "z_stream *strm" +.Xc +.Pp +All memory allocated by +.Fn inflateBackInit +is freed. +.Pp +.Fn inflateBackEnd +returns +.Dv Z_OK +on success, or +.Dv Z_STREAM_ERROR +if the stream state was inconsistent. +.It Xo +.Fa uLong +.Fn zlibCompileFlags "void" +.Xc +.Pp +This function returns flags indicating compile-time options. +.Pp +Type sizes, two bits each: +.Pp +.Bl -tag -width Ds -offset indent -compact +.It 00 +16 bits +.It 01 +32 bits +.It 10 +64 bits +.It 11 +other: +.Pp +.Bl -tag -width Ds -offset indent -compact +.It 1.0 +size of uInt +.It 3.2 +size of uLong +.It 5.4 +size of voidpf +.Pq pointer +.It 7.6 +size of z_off_t +.El +.El +.Pp +Compiler, assembler, and debug options: +.Pp +.Bl -tag -width Ds -offset indent -compact +.It 8 +DEBUG +.It 9 +ASMV or ASMINF \(em use ASM code +.It 10 +ZLIB_WINAPI \(em exported functions use the WINAPI calling convention +.It 11 +0 +.Pq reserved +.El +.Pp +One-time table building +.Pq smaller code, but not thread-safe if true : +.Pp +.Bl -tag -width Ds -offset indent -compact +.It 12 +BUILDFIXED \(em build static block decoding tables when needed +.It 13 +DYNAMIC_CRC_TABLE \(em build CRC calculation tables when needed +.It 14,15 +0 +.Pq reserved +.El +.Pp +Library content (indicates missing functionality): +.Pp +.Bl -tag -width Ds -offset indent -compact +.It 16 +NO_GZCOMPRESS \(em gz* functions cannot compress +.Pq to avoid linking deflate code when not needed +.It 17 +NO_GZIP \(em deflate can't write gzip streams, and inflate can't detect +and decode gzip streams +.Pq to avoid linking CRC code +.It 18-19 +0 +.Pq reserved +.El +.Pp +Operation variations (changes in library functionality): +.Pp +.Bl -tag -width Ds -offset indent -compact +.It 20 +PKZIP_BUG_WORKAROUND \(em slightly more permissive inflate +.It 21 +FASTEST \(em deflate algorithm with only one, lowest compression level +.It 22,23 +0 +.Pq reserved +.El +.Pp +The sprintf variant used by gzprintf +.Pq zero is best : +.Pp +.Bl -tag -width Ds -offset indent -compact +.It 24 +0 = vs*, 1 = s* \(em 1 means limited to 20 arguments after the format +.It 25 +0 = *nprintf, 1 = *printf \(em 1 means +.Fn gzprintf +not secure! +.It 26 +0 = returns value, 1 = void \(em 1 means inferred string length returned +.El +.Pp +Remainder: +.Pp +.Bl -tag -width Ds -offset indent -compact +.It 27-31 +0 +.Pq reserved +.El +.El +.Sh UTILITY FUNCTIONS +The following utility functions are implemented on top of the +basic stream-oriented functions. +To simplify the interface, +some default options are assumed (compression level and memory usage, +standard memory allocation functions). +The source code of these utility functions can easily be modified +if you need special options. +.Bl -tag -width Ds +.It Xo +.Fa int +.Fn compress "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" ; +.Xc +.Pp +The +.Fn compress +function compresses the source buffer into the destination buffer. +.Fa sourceLen +is the byte length of the source buffer. +Upon entry, +.Fa destLen +is the total size of the destination buffer, +which must be at least the value returned by +.Fn compressBound sourcelen . +Upon exit, +.Fa destLen +is the actual size of the compressed buffer. +This function can be used to compress a whole file at once if the +input file is mmap'ed. +.Pp +.Fn compress +returns +.Dv Z_OK +if successful, +.Dv Z_MEM_ERROR +if there was not enough memory, or +.Dv Z_BUF_ERROR +if there was not enough room in the output buffer. +.It Xo +.Fa int +.Fn compress2 "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" "int level" ; +.Xc +.Pp +The +.Fn compress2 +function compresses the source buffer into the destination buffer. +The +.Fa level +parameter has the same meaning as in +.Fn deflateInit . +.Fa sourceLen +is the byte length of the source buffer. +Upon entry, +.Fa destLen +is the total size of the destination buffer, +which must be at least the value returned by +.Fn compressBound sourceLen . +Upon exit, +.Fa destLen +is the actual size of the compressed buffer. +.Pp +.Fn compress2 +returns +.Dv Z_OK +if successful, +.Dv Z_MEM_ERROR +if there was not enough memory, +.Dv Z_BUF_ERROR +if there was not enough room in the output buffer, or +.Dv Z_STREAM_ERROR +if the level parameter is invalid. +.It Xo +.Fa int +.Fn compressBound "uLong sourceLen" +.Xc +.Pp +.Fn compressBound +returns an upper bound on the compressed size after +.Fn compress +or +.Fn compress2 +on +.Fa sourceLen +bytes. +It would be used before a +.Fn compress +or +.Fn compress2 +call to allocate the destination buffer. +.It Xo +.Fa int +.Fn uncompress "Bytef *dest" "uLongf *destLen" "const Bytef *source" "uLong sourceLen" ; +.Xc +.Pp +The +.Fn uncompress +function decompresses the source buffer into the destination buffer. +.Fa sourceLen +is the byte length of the source buffer. +Upon entry, +.Fa destLen +is the total size of the destination buffer, +which must be large enough to hold the entire uncompressed data. +(The size of the uncompressed data must have been saved previously +by the compressor and transmitted to the decompressor +by some mechanism outside the scope of this compression library.) +Upon exit, +.Fa destLen +is the actual size of the compressed buffer. +This function can be used to decompress a whole file at once if the +input file is mmap'ed. +.Pp +.Fn uncompress +returns +.Dv Z_OK +if successful, +.Dv Z_MEM_ERROR +if there was not enough memory, +.Dv Z_BUF_ERROR +if there was not enough room in the output buffer, or +.Dv Z_DATA_ERROR +if the input data was corrupted or incomplete. +.It Xo +.Fa gzFile +.Fn gzopen "const char *path" "const char *mode" ; +.Xc +.Pp +The +.Fn gzopen +function opens a gzip +.Pq .gz +file for reading or writing. +The mode parameter is as in +.Xr fopen 3 +.Po +.Qq rb +or +.Qq wb +.Pc +but can also include a compression level +.Pq "wb9" +or a strategy: +.Sq f +for filtered data, as in +.Qq wb6f ; +.Sq h +for Huffman only compression, as in +.Qq wb1h , +or +.Sq R +for run-length encoding as in +.Qq wb1R . +(See the description of +.Fn deflateInit2 +for more information about the strategy parameter.) +.Pp +.Fn gzopen +can be used to read a file which is not in gzip format; +in this case +.Fn gzread +will directly read from the file without decompression. +.Pp +.Fn gzopen +returns +.Dv NULL +if the file could not be opened or if there was +insufficient memory to allocate the (de)compression state; +errno can be checked to distinguish the two cases (if errno is zero, the +.Nm zlib +error is +.Dv Z_MEM_ERROR ) . +.It Xo +.Fa gzFile +.Fn gzdopen "int fd" "const char *mode" ; +.Xc +.Pp +The +.Fn gzdopen +function associates a gzFile with the file descriptor +.Fa fd . +File descriptors are obtained from calls like +.Xr open 2 , +.Xr dup 2 , +.Xr creat 3 , +.Xr pipe 2 , +or +.Xr fileno 3 +(if the file has been previously opened with +.Xr fopen 3 ) . +The +.Fa mode +parameter is as in +.Fn gzopen . +.Pp +The next call to +.Fn gzclose +on the returned gzFile will also close the file descriptor fd, +just like fclose(fdopen(fd), mode) closes the file descriptor fd. +If you want to keep fd open, use gzdopen(dup(fd), mode). +.Pp +.Fn gzdopen +returns +.Dv NULL +if there was insufficient memory to allocate the (de)compression state. +.It Xo +.Fa int +.Fn gzsetparams "gzFile file" "int level" "int strategy" ; +.Xc +.Pp +The +.Fn gzsetparams +function dynamically updates the compression level or strategy. +See the description of +.Fn deflateInit2 +for the meaning of these parameters. +.Pp +.Fn gzsetparams +returns +.Dv Z_OK +if successful, or +.Dv Z_STREAM_ERROR +if the file was not opened for writing. +.It Xo +.Fa int +.Fn gzread "gzFile file" "voidp buf" "unsigned len" ; +.Xc +.Pp +The +.Fn gzread +function reads the given number of uncompressed bytes from the compressed file. +If the input file was not in gzip format, +.Fn gzread +copies the given number of bytes into the buffer. +.Pp +.Fn gzread +returns the number of uncompressed bytes actually read +(0 for end of file, \-1 for error). +.It Xo +.Fa int +.Fn gzwrite "gzFile file" "voidpc buf" "unsigned len" ; +.Xc +.Pp +The +.Fn gzwrite +function writes the given number of uncompressed bytes into the compressed file. +.Fn gzwrite +returns the number of uncompressed bytes actually written +.Pq 0 in case of error . +.It Xo +.Fa int +.Fn gzprintf "gzFile file" "const char *format" "..." ; +.Xc +.Pp +The +.Fn gzprintf +function converts, formats, and writes the args to the compressed file +under control of the format string, as in +.Xr fprintf 3 . +.Fn gzprintf +returns the number of uncompressed bytes actually written +.Pq 0 in case of error . +The number of uncompressed bytes written is limited to 4095. +The caller should make sure that this limit is not exceeded. +If it is exceeded, then +.Fn gzprintf +will return an error +.Pq 0 +with nothing written. +In this case, there may also be a buffer overflow +with unpredictable consequences, which is possible only if +.Nm zlib +was compiled with the insecure functions +.Fn sprintf +or +.Fn vsprintf +because the secure +.Fn snprintf +or +.Fn vsnprintf +functions were not available. +.It Xo +.Fa int +.Fn gzputs "gzFile file" "const char *s" ; +.Xc +.Pp +The +.Fn gzputs +function writes the given null-terminated string to the compressed file, +excluding the terminating null character. +.Pp +.Fn gzputs +returns the number of characters written, or \-1 in case of error. +.It Xo +.Fa char * +.Fn gzgets "gzFile file" "char *buf" "int len" ; +.Xc +.Pp +The +.Fn gzgets +function reads bytes from the compressed file until len\-1 characters are read, +or a newline character is read and transferred to +.Fa buf , +or an end-of-file condition is encountered. +The string is then terminated with a null character. +.Pp +.Fn gzgets +returns +.Fa buf , +or +.Dv Z_NULL +in case of error. +.It Xo +.Fa int +.Fn gzputc "gzFile file" "int c" ; +.Xc +.Pp +The +.Fn gzputc +function writes +.Fa c , +converted to an unsigned char, into the compressed file. +.Fn gzputc +returns the value that was written, or \-1 in case of error. +.It Xo +.Fa int +.Fn gzgetc "gzFile file" ; +.Xc +.Pp +The +.Fn gzgetc +function reads one byte from the compressed file. +.Fn gzgetc +returns this byte or \-1 in case of end of file or error. +.It Xo +.Fa int +.Fn gzungetc "int c" "gzFile file" +.Xc +.Pp +Push one character back onto the stream to be read again later. +Only one character of push-back is allowed. +.Fn gzungetc +returns the character pushed, or \-1 on failure. +.Fn gzungetc +will fail if a character has been pushed but not read yet, or if +.Fa c +is \-1. +The pushed character will be discarded if the stream is repositioned with +.Fn gzseek +or +.Fn gzrewind . +.It Xo +.Fa int +.Fn gzflush "gzFile file" "int flush" ; +.Xc +.Pp +The +.Fn gzflush +function flushes all pending output into the compressed file. +The parameter +.Fa flush +is as in the +.Fn deflate +function. +The return value is the +.Nm zlib +error number (see function +.Fn gzerror +below). +.Fn gzflush +returns +.Dv Z_OK +if the flush parameter is +.Dv Z_FINISH +and all output could be flushed. +.Pp +.Fn gzflush +should be called only when strictly necessary because it can +degrade compression. +.It Xo +.Fa z_off_t +.Fn gzseek "gzFile file" "z_off_t offset" "int whence" ; +.Xc +.Pp +Sets the starting position for the next +.Fn gzread +or +.Fn gzwrite +on the given compressed file. +The offset represents a number of bytes in the uncompressed data stream. +The whence parameter is defined as in +.Xr lseek 2 ; +the value +.Dv SEEK_END +is not supported. +.Pp +If the file is opened for reading, this function is emulated but can be +extremely slow. +If the file is opened for writing, only forward seeks are supported; +.Fn gzseek +then compresses a sequence of zeroes up to the new starting position. +.Pp +.Fn gzseek +returns the resulting offset location as measured in bytes from +the beginning of the uncompressed stream, or \-1 in case of error, +in particular if the file is opened for writing and the new starting position +would be before the current position. +.It Xo +.Fa int +.Fn gzrewind "gzFile file" ; +.Xc +.Pp +The +.Fn gzrewind +function rewinds the given +.Fa file . +This function is supported only for reading. +.Pp +gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +.It Xo +.Fa z_off_t +.Fn gztell "gzFile file" ; +.Xc +.Pp +The +.Fn gztell +function returns the starting position for the next +.Fn gzread +or +.Fn gzwrite +on the given compressed file. +This position represents a number of bytes in the uncompressed data stream. +.Pp +gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR). +.It Xo +.Fa int +.Fn gzeof "gzFile file" ; +.Xc +.Pp +The +.Fn gzeof +function returns 1 when +.Dv EOF +has previously been detected reading the given input stream, otherwise zero. +.It Xo +.Fa int +.Fn gzdirect "gzFile file" ; +.Xc +.Pp +The +.Fn gzdirect +function returns 1 if the file is being read directly +without compression; +otherwise it returns 0. +.It Xo +.Fa int +.Fn gzclose "gzFile file" ; +.Xc +.Pp +The +.Fn gzclose +function flushes all pending output if necessary, closes the compressed file +and deallocates all the (de)compression state. +The return value is the +.Nm zlib +error number (see function +.Fn gzerror +below). +.It Xo +.Fa const char * +.Fn gzerror "gzFile file" "int *errnum" ; +.Xc +.Pp +The +.Fn gzerror +function returns the error message for the last error which occurred on the +given compressed +.Fa file . +.Fa errnum +is set to the +.Nm zlib +error number. +If an error occurred in the file system and not in the compression library, +.Fa errnum +is set to +.Dv Z_ERRNO +and the application may consult errno to get the exact error code. +.It Xo +.Fa void +.Fn gzclearerr "gzFile file" +.Xc +Clears the error and end-of-file flags for +.Fa file . +This is analogous to the +.Fn clearerr +function in stdio. +This is useful for continuing to read a gzip file +that is being written concurrently. +.El +.Sh CHECKSUM FUNCTIONS +These functions are not related to compression but are exported +anyway because they might be useful in applications using the +compression library. +.Bl -tag -width Ds +.It Xo +.Fa uLong +.Fn adler32 "uLong adler" "const Bytef *buf" "uInt len" ; +.Xc +The +.Fn adler32 +function updates a running Adler-32 checksum with the bytes buf[0..len-1] +and returns the updated checksum. +If +.Fa buf +is +.Dv NULL , +this function returns the required initial value for the checksum. +.Pp +An Adler-32 checksum is almost as reliable as a CRC32 but can be computed +much faster. +Usage example: +.Bd -unfilled -offset indent +uLong adler = adler32(0L, Z_NULL, 0); + +while (read_buffer(buffer, length) != EOF) { +adler = adler32(adler, buffer, length); +} +if (adler != original_adler) error(); +.Ed +.It Xo +.Fa uLong +.Fn adler32_combine "uLong adler1" "uLong adler2" "z_off_t len2" +.Xc +.Pp +The +.Fn adler32_combine +function combines two Adler-32 checksums into one. +For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, +Adler-32 checksums are calculated for each, adler1 and adler2. +.Fn adler32_combine +returns the Adler-32 checksum of seq1 and seq2 concatenated, +requiring only adler1, adler2, and len2. +.It Xo +.Fa uLong +.Fn crc32 "uLong crc" "const Bytef *buf" "uInt len" ; +.Xc +.Pp +The +.Fn crc32 +function updates a running CRC-32 with the bytes buf[0..len-1] +and returns the updated CRC-32. +If +.Fa buf +is +.Dv NULL , +this function returns the required initial value for the CRC. +Pre- and post-conditioning +.Pq one's complement +is performed within this function so it shouldn't be done by the application. +Usage example: +.Bd -unfilled -offset indent +uLong crc = crc32(0L, Z_NULL, 0); + +while (read_buffer(buffer, length) != EOF) { +crc = crc32(crc, buffer, length); +} +if (crc != original_crc) error(); +.Ed +.It Xo +.Fa uLong +.Fn crc32_combine "uLong crc1" "uLong crc2" "z_off_t len2" +.Xc +.Pp +The +.Fn crc32_combine +function combines two CRC-32 check values into one. +For two sequences of bytes, +seq1 and seq2 with lengths len1 and len2, +CRC-32 check values are calculated for each, crc1 and crc2. +.Fn crc32_combine +returns the CRC-32 check value of seq1 and seq2 concatenated, +requiring only crc1, crc2, and len2. +.El +.Sh STRUCTURES +.Bd -unfilled +struct internal_state; + +typedef struct z_stream_s { +    Bytef    *next_in;  /* next input byte */ +    uInt     avail_in;  /* number of bytes available at next_in */ +    off_t    total_in;  /* total nb of input bytes read so far */ + +    Bytef    *next_out; /* next output byte should be put there */ +    uInt     avail_out; /* remaining free space at next_out */ +    off_t    total_out; /* total nb of bytes output so far */ + +    char     *msg;      /* last error message, NULL if no error */ +    struct internal_state FAR *state; /* not visible by applications */ + +    alloc_func zalloc;  /* used to allocate the internal state */ +    free_func  zfree;   /* used to free the internal state */ +    voidpf     opaque;  /* private data object passed to zalloc and zfree*/ + +    int     data_type;  /* best guess about the data type: binary or text*/ +    uLong   adler;      /* adler32 value of the uncompressed data */ +    uLong   reserved;   /* reserved for future use */ +} z_stream; + +typedef z_stream FAR * z_streamp; +.Ed +.Bd -unfilled +/* +     gzip header information passed to and from zlib routines. +  See RFC 1952 for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { +    int     text;       /* true if compressed data believed to be text */ +    uLong   time;       /* modification time */ +    int     xflags;     /*extra flags (not used when writing a gzip file)*/ +    int     os;         /* operating system */ +    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */ +    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */ +    uInt    extra_max;  /* space at extra (only when reading header) */ +    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL*/ +    uInt    name_max;   /* space at name (only when reading header) */ +    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */ +    uInt    comm_max;   /* space at comment (only when reading header) */ +    int     hcrc;       /* true if there was or will be a header crc */ +    int     done;       /* true when done reading gzip header (not used +                           when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; +.Ed +.Pp +The application must update +.Fa next_in +and +.Fa avail_in +when +.Fa avail_in +has dropped to zero. +It must update +.Fa next_out +and +.Fa avail_out +when +.Fa avail_out +has dropped to zero. +The application must initialize +.Fa zalloc , +.Fa zfree , +and +.Fa opaque +before calling the init function. +All other fields are set by the compression library +and must not be updated by the application. +.Pp +The +.Fa opaque +value provided by the application will be passed as the first +parameter for calls to +.Fn zalloc +and +.Fn zfree . +This can be useful for custom memory management. +The compression library attaches no meaning to the +.Fa opaque +value. +.Pp +.Fa zalloc +must return +.Dv Z_NULL +if there is not enough memory for the object. +If +.Nm zlib +is used in a multi-threaded application, +.Fa zalloc +and +.Fa zfree +must be thread safe. +.Pp +On 16-bit systems, the functions +.Fa zalloc +and +.Fa zfree +must be able to allocate exactly 65536 bytes, +but will not be required to allocate more than this if the symbol MAXSEG_64K +is defined (see +.In zconf.h ) . +.Pp +WARNING: On MSDOS, pointers returned by +.Fa zalloc +for objects of exactly 65536 bytes *must* have their offset normalized to zero. +The default allocation function provided by this library ensures this (see +.Pa zutil.c ) . +To reduce memory requirements and avoid any allocation of 64K objects, +at the expense of compression ratio, +compile the library with -DMAX_WBITS=14 (see +.In zconf.h ) . +.Pp +The fields +.Fa total_in +and +.Fa total_out +can be used for statistics or progress reports. +After compression, +.Fa total_in +holds the total size of the uncompressed data and may be saved for use +in the decompressor +(particularly if the decompressor wants to decompress everything +in a single step). +.Sh CONSTANTS +.Bd -unfilled +#define Z_NO_FLUSH      0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH    2 +#define Z_FULL_FLUSH    3 +#define Z_FINISH        4 +#define Z_BLOCK		5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK            0 +#define Z_STREAM_END    1 +#define Z_NEED_DICT     2 +#define Z_ERRNO        (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR   (-3) +#define Z_MEM_ERROR    (-4) +#define Z_BUF_ERROR    (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. + * Negative values are errors, + * positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION         0 +#define Z_BEST_SPEED             1 +#define Z_BEST_COMPRESSION       9 +#define Z_DEFAULT_COMPRESSION  (-1) +/* compression levels */ + +#define Z_FILTERED            1 +#define Z_HUFFMAN_ONLY        2 +#define Z_RLE                 3 +#define Z_FIXED               4 +#define Z_DEFAULT_STRATEGY    0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY   0 +#define Z_TEXT     1 +#define Z_ASCII    Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN  2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED   8 +/* The deflate compression method + * (the only one supported in this version) +*/ + +#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ +.Ed +.Sh VARIOUS HACKS +deflateInit and inflateInit are macros to allow checking the +.Nm zlib +version and the compiler's view of +.Fa z_stream . +.Bl -tag -width Ds +.It Xo +.Fa int +.Fn deflateInit_ "z_stream strm" "int level" "const char *version" "int stream_size" ; +.Xc +.It Xo +.Fa int +.Fn inflateInit_ "z_stream strm" "const char *version" "int stream_size" ; +.Xc +.It Xo +.Fa int +.Fo deflateInit2_ +.Fa "z_stream strm" +.Fa "int level" +.Fa "int method" +.Fa "int windowBits" +.Fa "int memLevel" +.Fa "int strategy" +.Fa "const char *version" +.Fa "int stream_size" +.Fc +.Xc +.It Xo +.Fa int +.Fn inflateInit2_ "z_stream strm" "int windowBits" "const char *version" "int stream_size" ; +.Xc +.It Xo +.Fa int +.Fn inflateBackInit_ "z_stream *strm" "int windowBits" "unsigned char FAR *window" "const char *version" "int stream_size" +.Xc +.It Xo +.Fa const char * +.Fn zError "int err" ; +.Xc +.It Xo +.Fa int +.Fn inflateSyncPoint "z_streamp z" ; +.Xc +.It Xo +.Fa const uLongf * +.Fn "get_crc_table" "void" ; +.Xc +.El +.Sh SEE ALSO +.Xr compress 1 , +.Xr gzip 1 +.Sh STANDARDS +.Rs +.%A P. Deutsch +.%A J-L. Gailly +.%D May 1996 +.%R RFC 1950 +.%T ZLIB Compressed Data Format Specification version 3.3 +.Re +.Pp +.Rs +.%A P. Deutsch +.%D May 1996 +.%R RFC 1951 +.%T DEFLATE Compressed Data Format Specification version 1.3 +.Re +.Pp +.Rs +.%A P. Deutsch +.%D May 1996 +.%R RFC 1952 +.%T GZIP file format specification version 4.3 +.Re +.Sh HISTORY +This manual page is based on an HTML version of +.In zlib.h +converted by +.An piaip Aq Mt piaip@csie.ntu.edu.tw +and was converted to mdoc format by the +.Ox +project. +.Sh AUTHORS +.An Jean-loup Gailly Aq Mt jloup@gzip.org +.An Mark Adler Aq Mt madler@alumni.caltech.edu diff --git a/lib/libz/compress.c b/lib/libz/compress.c new file mode 100644 index 0000000..f501874 --- /dev/null +++ b/lib/libz/compress.c @@ -0,0 +1,79 @@ +/*	$OpenBSD: compress.c,v 1.6 2005/07/20 15:56:41 millert Exp $	*/ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== +     Compresses the source buffer into the destination buffer. The level +   parameter has the same meaning as in deflateInit.  sourceLen is the byte +   length of the source buffer. Upon entry, destLen is the total size of the +   destination buffer, which must be at least 0.1% larger than sourceLen plus +   12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + +     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough +   memory, Z_BUF_ERROR if there was not enough room in the output buffer, +   Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) +    Bytef *dest; +    uLongf *destLen; +    const Bytef *source; +    uLong sourceLen; +    int level; +{ +    z_stream stream; +    int err; + +    stream.next_in = (Bytef*)source; +    stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K +    /* Check for source > 64K on 16-bit machine: */ +    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif +    stream.next_out = dest; +    stream.avail_out = (uInt)*destLen; +    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + +    stream.zalloc = (alloc_func)0; +    stream.zfree = (free_func)0; +    stream.opaque = (voidpf)0; + +    err = deflateInit(&stream, level); +    if (err != Z_OK) return err; + +    err = deflate(&stream, Z_FINISH); +    if (err != Z_STREAM_END) { +        deflateEnd(&stream); +        return err == Z_OK ? Z_BUF_ERROR : err; +    } +    *destLen = stream.total_out; + +    err = deflateEnd(&stream); +    return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) +    Bytef *dest; +    uLongf *destLen; +    const Bytef *source; +    uLong sourceLen; +{ +    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== +     If the default memLevel or windowBits for deflateInit() is changed, then +   this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) +    uLong sourceLen; +{ +    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; +} diff --git a/lib/libz/compress.cat3 b/lib/libz/compress.cat3 new file mode 100644 index 0000000..bcd9add --- /dev/null +++ b/lib/libz/compress.cat3 @@ -0,0 +1,1556 @@ +COMPRESS(3)              BSD Library Functions Manual              COMPRESS(3) + +[1mNAME[0m +     [1mcompress[22m, [1mzlibVersion[22m, [1mdeflateInit[22m, [1mdeflate[22m, [1mdeflateEnd[22m, [1minflateInit[22m, +     [1minflate[22m, [1minflateEnd[22m, [1mdeflateInit2[22m, [1mdeflateSetDictionary[22m, [1mdeflateCopy[22m, +     [1mdeflateReset[22m, [1mdeflateParams[22m, [1mdeflateTune[22m, [1mdeflateBound[22m, [1mdeflatePrime[22m, +     [1mdeflateSetHeader[22m, [1minflateInit2[22m, [1minflateSetDictionary[22m, [1minflateSync[22m, +     [1minflateCopy[22m, [1minflateReset[22m, [1minflatePrime[22m, [1minflateGetHeader[22m, +     [1minflateBackInit[22m, [1minflateBack[22m, [1minflateBackEnd[22m, [1mzlibCompileFlags[22m, +     [1mcompress2[22m, [1mcompressBound[22m, [1muncompress[22m, [1mgzopen[22m, [1mgzdopen[22m, [1mgzsetparams[22m, +     [1mgzread[22m, [1mgzwrite[22m, [1mgzprintf[22m, [1mgzputs[22m, [1mgzgets[22m, [1mgzputc[22m, [1mgzgetc[22m, [1mgzungetc[22m, +     [1mgzflush[22m, [1mgzseek[22m, [1mgzrewind[22m, [1mgztell[22m, [1mgzeof[22m, [1mgzdirect[22m, [1mgzclose[22m, [1mgzerror[22m, +     [1mgzclearerr[22m, [1madler32[22m, [1madler32_combine[22m, [1mcrc32[22m, [1mcrc32_combine [22m-- zlib gen- +     eral purpose compression library + +[1mSYNOPSIS[0m +     [1m#include <zlib.h>[0m + +     Basic functions + +     [4mconst[24m [4mchar[24m [4m*[0m +     [1mzlibVersion[22m([4mvoid[24m); + +     [4mint[0m +     [1mdeflateInit[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mlevel[24m); + +     [4mint[0m +     [1mdeflate[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mflush[24m); + +     [4mint[0m +     [1mdeflateEnd[22m([4mz_streamp[24m [4mstrm[24m); + +     [4mint[0m +     [1minflateInit[22m([4mz_streamp[24m [4mstrm[24m); + +     [4mint[0m +     [1minflate[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mflush[24m); + +     [4mint[0m +     [1minflateEnd[22m([4mz_streamp[24m [4mstrm[24m); + +     Advanced functions + +     [4mint[0m +     [1mdeflateInit2[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mlevel[24m, [4mint[24m [4mmethod[24m, [4mint[24m [4mwindowBits[24m, +         [4mint[24m [4mmemLevel[24m, [4mint[24m [4mstrategy[24m); + +     [4mint[0m +     [1mdeflateSetDictionary[22m([4mz_streamp[24m [4mstrm[24m, [4mconst[24m [4mBytef[24m [4m*dictionary[24m, +         [4muInt[24m [4mdictLength[24m); + +     [4mint[0m +     [1mdeflateCopy[22m([4mz_streamp[24m [4mdest[24m, [4mz_streamp[24m [4msource[24m); + +     [4mint[0m +     [1mdeflateReset[22m([4mz_streamp[24m [4mstrm[24m); + +     [4mint[0m +     [1mdeflateParams[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mlevel[24m, [4mint[24m [4mstrategy[24m); + +     [4mint[0m +     [1mdeflateTune[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mgood_length[24m, [4mint[24m [4mmax_lazy[24m, +         [4mint[24m [4mnice_length[24m, [4mint[24m [4mmax_chain[24m); + +     [4muLong[0m +     [1mdeflateBound[22m([4mz_streamp[24m [4mstrm[24m, [4muLong[24m [4msourceLen[24m); + +     [4mint[0m +     [1mdeflatePrime[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mbits[24m, [4mint[24m [4mvalue[24m); + +     [4mint[0m +     [1mdeflateSetHeader[22m([4mz_streamp[24m [4mstrm[24m, [4mgz_headerp[24m [4mhead[24m); + +     [4mint[0m +     [1minflateInit2[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mwindowBits[24m); + +     [4mint[0m +     [1minflateSetDictionary[22m([4mz_streamp[24m [4mstrm[24m, [4mconst[24m [4mBytef[24m [4m*dictionary[24m, +         [4muInt[24m [4mdictLength[24m); + +     [4mint[0m +     [1minflateSync[22m([4mz_streamp[24m [4mstrm[24m); + +     [4mint[0m +     [1minflateCopy[22m([4mz_streamp[24m [4mdst[24m, [4mz_streamp[24m [4msource[24m); + +     [4mint[0m +     [1minflateReset[22m([4mz_streamp[24m [4mstrm[24m); + +     [4mint[0m +     [1minflatePrime[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mbits[24m, [4mint[24m [4mvalue[24m); + +     [4mint[0m +     [1minflateGetHeader[22m([4mz_streamp[24m [4mstrm[24m, [4mgz_headerp[24m [4mhead[24m); + +     [4mint[0m +     [1minflateBackInit[22m([4mz_stream[24m [4m*strm[24m, [4mint[24m [4mwindowBits[24m, +         [4munsigned[24m [4mchar[24m [4mFAR[24m [4m*window[24m); + +     [4mint[0m +     [1minflateBack[22m([4mz_stream[24m [4m*strm[24m, [4min_func[24m [4min[24m, [4mvoid[24m [4mFAR[24m [4m*in_desc[24m, [4mout_func[24m [4mout[24m, +         [4mvoid[24m [4mFAR[24m [4m*out_desc[24m); + +     [4mint[0m +     [1minflateBackEnd[22m([4mz_stream[24m [4m*strm[24m); + +     [4muLong[0m +     [1mzlibCompileFlags[22m([4mvoid[24m); + +     Utility functions + +     [1mtypedef voidp gzFile;[0m + +     [4mint[0m +     [1mcompress[22m([4mBytef[24m [4m*dest[24m, [4muLongf[24m [4m*destLen[24m, [4mconst[24m [4mBytef[24m [4m*source[24m, +         [4muLong[24m [4msourceLen[24m); + +     [4mint[0m +     [1mcompress2[22m([4mBytef[24m [4m*dest[24m, [4muLongf[24m [4m*destLen[24m, [4mconst[24m [4mBytef[24m [4m*source[24m, +         [4muLong[24m [4msourceLen[24m, [4mint[24m [4mlevel[24m); + +     [4muLong[0m +     [1mcompressBound[22m([4muLong[24m [4msourceLen[24m); + +     [4mint[0m +     [1muncompress[22m([4mBytef[24m [4m*dest[24m, [4muLongf[24m [4m*destLen[24m, [4mconst[24m [4mBytef[24m [4m*source[24m, +         [4muLong[24m [4msourceLen[24m); + +     [4mgzFile[0m +     [1mgzopen[22m([4mconst[24m [4mchar[24m [4m*path[24m, [4mconst[24m [4mchar[24m [4m*mode[24m); + +     [4mgzFile[0m +     [1mgzdopen[22m([4mint[24m [4mfd[24m, [4mconst[24m [4mchar[24m [4m*mode[24m); + +     [4mint[0m +     [1mgzsetparams[22m([4mgzFile[24m [4mfile[24m, [4mint[24m [4mlevel[24m, [4mint[24m [4mstrategy[24m); + +     [4mint[0m +     [1mgzread[22m([4mgzFile[24m [4mfile[24m, [4mvoidp[24m [4mbuf[24m, [4munsigned[24m [4mlen[24m); + +     [4mint[0m +     [1mgzwrite[22m([4mgzFile[24m [4mfile[24m, [4mvoidpc[24m [4mbuf[24m, [4munsigned[24m [4mlen[24m); + +     [4mint[0m +     [1mgzprintf[22m([4mgzFile[24m [4mfile[24m, [4mconst[24m [4mchar[24m [4m*format[24m, [4m...[24m); + +     [4mint[0m +     [1mgzputs[22m([4mgzFile[24m [4mfile[24m, [4mconst[24m [4mchar[24m [4m*s[24m); + +     [4mchar[24m [4m*[0m +     [1mgzgets[22m([4mgzFile[24m [4mfile[24m, [4mchar[24m [4m*buf[24m, [4mint[24m [4mlen[24m); + +     [4mint[0m +     [1mgzputc[22m([4mgzFile[24m [4mfile[24m, [4mint[24m [4mc[24m); + +     [4mint[0m +     [1mgzgetc[22m([4mgzFile[24m [4mfile[24m); + +     [4mint[0m +     [1mgzungetc[22m([4mint[24m [4mc[24m, [4mgzFile[24m [4mfile[24m); + +     [4mint[0m +     [1mgzflush[22m([4mgzFile[24m [4mfile[24m, [4mint[24m [4mflush[24m); + +     [4mz_off_t[0m +     [1mgzseek[22m([4mgzFile[24m [4mfile[24m, [4mz_off_t[24m [4moffset[24m, [4mint[24m [4mwhence[24m); + +     [4mint[0m +     [1mgzrewind[22m([4mgzFile[24m [4mfile[24m); + +     [4mz_off_t[0m +     [1mgztell[22m([4mgzFile[24m [4mfile[24m); + +     [4mint[0m +     [1mgzeof[22m([4mgzFile[24m [4mfile[24m); + +     [4mint[0m +     [1mgzdirect[22m([4mgzFile[24m [4mfile[24m); + +     [4mint[0m +     [1mgzclose[22m([4mgzFile[24m [4mfile[24m); + +     [4mconst[24m [4mchar[24m [4m*[0m +     [1mgzerror[22m([4mgzFile[24m [4mfile[24m, [4mint[24m [4m*errnum[24m); + +     [4mvoid[0m +     [1mgzclearerr[22m([4mgzFile[24m [4mfile[24m); + +     Checksum functions + +     [4muLong[0m +     [1madler32[22m([4muLong[24m [4madler[24m, [4mconst[24m [4mBytef[24m [4m*buf[24m, [4muInt[24m [4mlen[24m); + +     [4muLong[0m +     [1madler32_combine[22m([4muLong[24m [4madler1[24m, [4muLong[24m [4madler2[24m, [4mz_off_t[24m [4mlen2[24m); + +     [4muLong[0m +     [1mcrc32[22m([4muLong[24m [4mcrc[24m, [4mconst[24m [4mBytef[24m [4m*buf[24m, [4muInt[24m [4mlen[24m); + +     [4muLong[0m +     [1mcrc32_combine[22m([4muLong[24m [4mcrc1[24m, [4muLong[24m [4mcrc2[24m, [4mz_off_t[24m [4mlen2[24m); + +[1mDESCRIPTION[0m +     This manual page describes the [1mzlib [22mgeneral purpose compression library, +     version 1.2.3. + +     The [1mzlib [22mcompression library provides in-memory compression and decom- +     pression functions, including integrity checks of the uncompressed data. +     This version of the library supports only one compression method +     (deflation) but other algorithms will be added later and will have the +     same stream interface. + +     Compression can be done in a single step if the buffers are large enough +     (for example if an input file is mmap'ed), or can be done by repeated +     calls of the compression function.  In the latter case, the application +     must provide more input and/or consume the output (providing more output +     space) before each call. + +     The compressed data format used by default by the in-memory functions is +     the [1mzlib [22mformat, which is a zlib wrapper documented in RFC 1950, wrapped +     around a deflate stream, which is itself documented in RFC 1951. + +     The library also supports reading and writing files in gzip(1) (.gz) for- +     mat with an interface similar to that of stdio(3) using the functions +     that start with "gz".  The gzip format is different from the zlib format. +     gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate +     stream.  This library can optionally read and write gzip streams in mem- +     ory as well. + +     The zlib format was designed to be compact and fast for use in memory and +     on communications channels.  The gzip format was designed for single-file +     compression on file systems, has a larger header than zlib to maintain +     directory information, and uses a different, slower, check method than +     zlib. + +     The library does not install any signal handler.  The decoder checks the +     consistency of the compressed data, so the library should never crash +     even in case of corrupted input. + +     The functions within the library are divided into the following sections: + +           [1m-   [22mBasic functions +           [1m-   [22mAdvanced functions +           [1m-   [22mUtility functions +           [1m-   [22mChecksum functions + +[1mBASIC FUNCTIONS[0m +     [4mconst[24m [4mchar[24m [4m*[24m [1mzlibVersion[22m([4mvoid[24m); + +             The application can compare [1mzlibVersion[22m() and ZLIB_VERSION for +             consistency.  If the first character differs, the library code +             actually used is not compatible with the <[4mzlib.h[24m> header file +             used by the application.  This check is automatically made by +             [1mdeflateInit[22m() and [1minflateInit[22m(). + +     [4mint[24m [1mdeflateInit[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mlevel[24m); + +             The [1mdeflateInit[22m() function initializes the internal stream state +             for compression.  The fields [4mzalloc[24m, [4mzfree[24m, and [4mopaque[24m must be +             initialized before by the caller.  If [4mzalloc[24m and [4mzfree[24m are set to +             Z_NULL, [1mdeflateInit[22m() updates them to use default allocation +             functions. + +             The compression level must be Z_DEFAULT_COMPRESSION, or between 0 +             and 9: 1 gives best speed, 9 gives best compression, 0 gives no +             compression at all (the input data is simply copied a block at a +             time). + +             Z_DEFAULT_COMPRESSION requests a default compromise between speed +             and compression (currently equivalent to level 6). + +             [1mdeflateInit[22m() returns Z_OK if successful, Z_MEM_ERROR if there +             was not enough memory, Z_STREAM_ERROR if level is not a valid +             compression level, Z_VERSION_ERROR if the [1mzlib [22mlibrary version +             (zlib_version) is incompatible with the version assumed by the +             caller (ZLIB_VERSION).  [4mmsg[24m is set to null if there is no error +             message.  [1mdeflateInit[22m() does not perform any compression: this +             will be done by [1mdeflate[22m(). + +     [4mint[24m [1mdeflate[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mflush[24m); + +             [1mdeflate[22m() compresses as much data as possible, and stops when the +             input buffer becomes empty or the output buffer becomes full.  It +             may introduce some output latency (reading input without +             producing any output) except when forced to flush. + +             The detailed semantics are as follows.  [1mdeflate[22m() performs one or +             both of the following actions: + +             Compress more input starting at [4mnext_in[24m and update [4mnext_in[24m and +             [4mavail_in[24m accordingly.  If not all input can be processed (because +             there is not enough room in the output buffer), [4mnext_in[24m and +             [4mavail_in[24m are updated and processing will resume at this point for +             the next call to [1mdeflate[22m(). + +             Provide more output starting at [4mnext_out[24m and update [4mnext_out[24m and +             [4mavail_out[24m accordingly.  This action is forced if the parameter +             [4mflush[24m is non-zero.  Forcing [4mflush[24m frequently degrades the com- +             pression ratio, so this parameter should be set only when neces- +             sary (in interactive applications).  Some output may be provided +             even if [4mflush[24m is not set. + +             Before the call to [1mdeflate[22m(), the application should ensure that +             at least one of the actions is possible, by providing more input +             and/or consuming more output, and updating [4mavail_in[24m or [4mavail_out[0m +             accordingly; [4mavail_out[24m should never be zero before the call.  The +             application can consume the compressed output when it wants, for +             example when the output buffer is full (avail_out == 0), or after +             each call to [1mdeflate[22m().  If [1mdeflate[22m() returns Z_OK and with zero +             [4mavail_out[24m, it must be called again after making room in the out- +             put buffer because there might be more output pending. + +             Normally the parameter [4mflush[24m is set to Z_NO_FLUSH, which allows +             [1mdeflate[22m() to decide how much data to accumulate before producing +             output, in order to maximise compression. + +             If the parameter [4mflush[24m is set to Z_SYNC_FLUSH, all pending output +             is flushed to the output buffer and the output is aligned on a +             byte boundary, so that the decompressor can get all input data +             available so far.  (In particular, [4mavail_in[24m is zero after the +             call if enough output space has been provided before the call.) +             Flushing may degrade compression for some compression algorithms +             and so it should be used only when necessary. + +             If [4mflush[24m is set to Z_FULL_FLUSH, all output is flushed as with +             Z_SYNC_FLUSH, and the compression state is reset so that decom- +             pression can restart from this point if previous compressed data +             has been damaged or if random access is desired.  Using +             Z_FULL_FLUSH too often can seriously degrade compression. + +             If [1mdeflate[22m() returns with avail_out == 0, this function must be +             called again with the same value of the flush parameter and more +             output space (updated [4mavail_out[24m), until the flush is complete +             ([1mdeflate[22m() returns with non-zero [4mavail_out[24m).  In the case of a +             Z_FULL_FLUSH or a Z_SYNC_FLUSH, make sure that [4mavail_out[24m is +             greater than six to avoid repeated flush markers due to avail_out +             == 0 on return. + +             If the parameter [4mflush[24m is set to Z_FINISH, pending input is pro- +             cessed, pending output is flushed and [1mdeflate[22m() returns with +             Z_STREAM_END if there was enough output space; if [1mdeflate[22m() re- +             turns with Z_OK, this function must be called again with Z_FINISH +             and more output space (updated [4mavail_out[24m but no more input data, +             until it returns with Z_STREAM_END or an error.  After [1mdeflate[22m() +             has returned Z_STREAM_END, the only possible operations on the +             stream are [1mdeflateReset[22m() or [1mdeflateEnd[22m(). + +             Z_FINISH can be used immediately after [1mdeflateInit[22m() if all the +             compression is to be done in a single step.  In this case, +             [4mavail_out[24m must be at least the value returned by [1mdeflateBound[22m() +             (see below).  If [1mdeflate[22m() does not return Z_STREAM_END, then it +             must be called again as described above. + +             [1mdeflate[22m() sets strm->adler to the Adler-32 checksum of all input +             read so far (that is, [4mtotal_in[24m bytes). + +             [1mdeflate[22m() may update strm->data_type if it can make a good guess +             about the input data type (Z_BINARY or Z_TEXT).  If in doubt, the +             data is considered binary.  This field is only for information +             purposes and does not affect the compression algorithm in any +             manner. + +             [1mdeflate[22m() returns Z_OK if some progress has been made (more input +             processed or more output produced), Z_STREAM_END if all input has +             been consumed and all output has been produced (only when [4mflush[0m +             is set to Z_FINISH), Z_STREAM_ERROR if the stream state was in- +             consistent (for example, if [4mnext_in[24m or [4mnext_out[24m was NULL), +             Z_BUF_ERROR if no progress is possible (for example, [4mavail_in[24m or +             [4mavail_out[24m was zero).  Note that Z_BUF_ERROR is not fatal, and +             [1mdeflate[22m() can be called again with more input and more output +             space to continue processing. + +     [4mint[24m [1mdeflateEnd[22m([4mz_streamp[24m [4mstrm[24m); + +             All dynamically allocated data structures for this stream are +             freed.  This function discards any unprocessed input and does not +             flush any pending output. + +             [1mdeflateEnd[22m() returns Z_OK if successful, Z_STREAM_ERROR if the +             stream state was inconsistent, Z_DATA_ERROR if the stream was +             freed prematurely (some input or output was discarded).  In the +             error case, [4mmsg[24m may be set but then points to a static string +             (which must not be deallocated). + +     [4mint[24m [1minflateInit[22m([4mz_streamp[24m [4mstrm[24m); +             The [1minflateInit[22m() function initializes the internal stream state +             for decompression.  The fields [4mnext_in[24m, [4mavail_in[24m, [4mzalloc[24m, [4mzfree[24m, +             and [4mopaque[24m must be initialized before by the caller.  If [4mnext_in[0m +             is not Z_NULL and [4mavail_in[24m is large enough (the exact value +             depends on the compression method), [1minflateInit[22m() determines the +             compression method from the [1mzlib [22mheader and allocates all data +             structures accordingly; otherwise the allocation will be deferred +             to the first call to [1minflate[22m().  If [4mzalloc[24m and [4mzfree[24m are set to +             Z_NULL, [1minflateInit[22m() updates them to use default allocation +             functions. + +             [1minflateInit[22m() returns Z_OK if successful, Z_MEM_ERROR if there +             was not enough memory, Z_VERSION_ERROR if the [1mzlib [22mlibrary ver- +             sion is incompatible with the version assumed by the caller.  [4mmsg[0m +             is set to null if there is no error message.  [1minflateInit[22m() does +             not perform any decompression apart from reading the [1mzlib [22mheader +             if present: this will be done by [1minflate[22m().  (So [4mnext_in[24m and +             [4mavail_in[24m may be modified, but [4mnext_out[24m and [4mavail_out[24m are un- +             changed.) + +     [4mint[24m [1minflate[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mflush[24m); +             [1minflate[22m() decompresses as much data as possible, and stops when +             the input buffer becomes empty or the output buffer becomes full. +             It may introduce some output latency (reading input without +             producing any output) except when forced to flush. + +             The detailed semantics are as follows.  [1minflate[22m() performs one or +             both of the following actions: + +             Decompress more input starting at [4mnext_in[24m and update [4mnext_in[24m and +             [4mavail_in[24m accordingly.  If not all input can be processed (because +             there is not enough room in the output buffer), [4mnext_in[24m is up- +             dated and processing will resume at this point for the next call +             to [1minflate[22m(). + +             Provide more output starting at [4mnext_out[24m and update [4mnext_out[24m and +             [4mavail_out[24m accordingly.  [1minflate[22m() provides as much output as pos- +             sible, until there is no more input data or no more space in the +             output buffer (see below about the flush parameter). + +             Before the call to [1minflate[22m(), the application should ensure that +             at least one of the actions is possible, by providing more input +             and/or consuming more output, and updating the next_* and avail_* +             values accordingly.  The application can consume the uncompressed +             output when it wants, for example when the output buffer is full +             (avail_out == 0), or after each call to [1minflate[22m().  If [1minflate[22m() +             returns Z_OK and with zero [4mavail_out[24m, it must be called again af- +             ter making room in the output buffer because there might be more +             output pending. + +             The [4mflush[24m parameter of [1minflate[22m() can be Z_NO_FLUSH, Z_SYNC_FLUSH, +             Z_FINISH, or Z_BLOCK.  Z_SYNC_FLUSH requests that [1minflate[22m() flush +             as much output as possible to the output buffer.  Z_BLOCK re- +             quests that [1minflate[22m() stop if and when it gets to the next de- +             flate block boundary.  When decoding the zlib or gzip format, +             this will cause [1minflate[22m() to return immediately after the header +             and before the first block.  When doing a raw inflate, [1minflate[22m() +             will go ahead and process the first block, and will return when +             it gets to the end of that block, or when it runs out of data. + +             The Z_BLOCK option assists in appending to or combining deflate +             streams.  Also to assist in this, on return [1minflate[22m() will set +             strm->data_type to the number of unused bits in the last byte +             taken from strm->next_in, plus 64 if [1minflate[22m() is currently de- +             coding the last block in the deflate stream, plus 128 if +             [1minflate[22m() returned immediately after decoding an end-of-block +             code or decoding the complete header up to just before the first +             byte of the deflate stream.  The end-of-block will not be indi- +             cated until all of the uncompressed data from that block has been +             written to strm->next_out.  The number of unused bits may in gen- +             eral be greater than seven, except when bit 7 of data_type is +             set, in which case the number of unused bits will be less than +             eight. + +             [1minflate[22m() should normally be called until it returns Z_STREAM_END +             or an error.  However if all decompression is to be performed in +             a single step (a single call to inflate), the parameter [4mflush[0m +             should be set to Z_FINISH.  In this case all pending input is +             processed and all pending output is flushed; [4mavail_out[24m must be +             large enough to hold all the uncompressed data.  (The size of the +             uncompressed data may have been saved by the compressor for this +             purpose.)  The next operation on this stream must be [1minflateEnd[22m() +             to deallocate the decompression state.  The use of Z_FINISH is +             never required, but can be used to inform [1minflate[22m() that a faster +             approach may be used for the single [1minflate[22m() call. + +             In this implementation, [1minflate[22m() always flushes as much output +             as possible to the output buffer, and always uses the faster ap- +             proach on the first call.  So the only effect of the [4mflush[24m param- +             eter in this implementation is on the return value of [1minflate[22m(), +             as noted below, or when it returns early because Z_BLOCK is used. + +             If a preset dictionary is needed after this call (see +             [1minflateSetDictionary[22m() below), [1minflate[22m() sets strm->adler to the +             Adler-32 checksum of the dictionary chosen by the compressor and +             returns Z_NEED_DICT; otherwise it sets strm->adler to the +             Adler-32 checksum of all output produced so far (that is, +             [4mtotal_out[24m bytes) and returns Z_OK, Z_STREAM_END or an error code +             as described below.  At the end of the stream, [1minflate[22m() checks +             that its computed Adler-32 checksum is equal to that saved by the +             compressor and returns Z_STREAM_END only if the checksum is cor- +             rect. + +             [1minflate[22m() will decompress and check either zlib-wrapped or gzip- +             wrapped deflate data.  The header type is detected automatically. +             Any information contained in the gzip header is not retained, so +             applications that need that information should instead use raw +             inflate; see [1minflateInit2[22m() below, or [1minflateBack[22m() and perform +             their own processing of the gzip header and trailer. + +             [1minflate[22m() returns Z_OK if some progress has been made (more input +             processed or more output produced), Z_STREAM_END if the end of +             the compressed data has been reached and all uncompressed output +             has been produced, Z_NEED_DICT if a preset dictionary is needed +             at this point, Z_DATA_ERROR if the input data was corrupted (in- +             put stream not conforming to the [1mzlib [22mformat or incorrect check +             value), Z_STREAM_ERROR if the stream structure was inconsistent +             (for example, if [4mnext_in[24m or [4mnext_out[24m was NULL), Z_MEM_ERROR if +             there was not enough memory, Z_BUF_ERROR if no progress is possi- +             ble or if there was not enough room in the output buffer when +             Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and +             [1minflate[22m() can be called again with more input and more output +             space to continue compressing.  If Z_DATA_ERROR is returned, the +             application may then call [1minflateSync[22m() to look for a good com- +             pression block if a partial recovery of the data is desired. + +     [4mint[24m [1minflateEnd[22m([4mz_streamp[24m [4mstrm[24m); +             All dynamically allocated data structures for this stream are +             freed.  This function discards any unprocessed input and does not +             flush any pending output. + +             [1minflateEnd[22m() returns Z_OK if successful, or Z_STREAM_ERROR if the +             stream state was inconsistent.  In the error case, [4mmsg[24m may be set +             but then points to a static string (which must not be +             deallocated). + +[1mADVANCED FUNCTIONS[0m +     The following functions are needed only in some special applications. + +     [4mint[24m [1mdeflateInit2[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mlevel[24m, [4mint[24m [4mmethod[24m, [4mint[24m [4mwindowBits[24m, +             [4mint[24m [4mmemLevel[24m, [4mint[24m [4mstrategy[24m); + +             This is another version of [1mdeflateInit[22m() with more compression +             options.  The fields [4mnext_in[24m, [4mzalloc[24m, [4mzfree[24m, and [4mopaque[24m must be +             initialized before by the caller. + +             The [4mmethod[24m parameter is the compression method.  It must be +             Z_DEFLATED in this version of the library. + +             The [4mwindowBits[24m parameter is the base two logarithm of the window +             size (the size of the history buffer).  It should be in the range +             8..15 for this version of the library.  Larger values of this pa- +             rameter result in better compression at the expense of memory us- +             age.  The default value is 15 if [1mdeflateInit[22m() is used instead. + +             [4mwindowBits[24m can also be -8..-15 for raw deflate.  In this case, +             -windowBits determines the window size.  [1mdeflate[22m() will then gen- +             erate raw deflate data with no zlib header or trailer, and will +             not compute an Adler-32 check value. + +             [4mwindowBits[24m can also be greater than 15 for optional gzip encod- +             ing.  Add 16 to [4mwindowBits[24m to write a simple gzip header and +             trailer around the compressed data instead of a zlib wrapper. +             The gzip header will have no file name, no extra data, no com- +             ment, no modification time (set to zero), no header crc, and the +             operating system will be set to 255 (unknown).  If a gzip stream +             is being written, strm->adler is a crc32 instead of an adler32. + +             The [4mmemLevel[24m parameter specifies how much memory should be allo- +             cated for the internal compression state.  memLevel=1 uses mini- +             mum memory but is slow and reduces compression ratio; memLevel=9 +             uses maximum memory for optimal speed.  The default value is 8. +             See <[4mzconf.h[24m> for total memory usage as a function of [4mwindowBits[0m +             and [4mmemLevel[24m. + +             The [4mstrategy[24m parameter is used to tune the compression algorithm. +             Use the value Z_DEFAULT_STRATEGY for normal data; Z_FILTERED for +             data produced by a filter (or predictor); Z_HUFFMAN_ONLY to force +             Huffman encoding only (no string match), or Z_RLE to limit match +             distances to one (run-length encoding).  Filtered data consists +             mostly of small values with a somewhat random distribution.  In +             this case, the compression algorithm is tuned to compress them +             better.  The effect of Z_FILTERED is to force more Huffman coding +             and less string matching; it is somewhat intermediate between +             Z_DEFAULT and Z_HUFFMAN_ONLY.  Z_RLE is designed to be almost as +             fast as Z_HUFFMAN_ONLY, but gives better compression for PNG im- +             age data.  The [4mstrategy[24m parameter only affects the compression +             ratio but not the correctness of the compressed output, even if +             it is not set appropriately.  Z_FIXED prevents the use of dynamic +             Huffman codes, allowing for a simpler decoder for special appli- +             cations. + +             [1mdeflateInit2[22m() returns Z_OK if successful, Z_MEM_ERROR if there +             was not enough memory, Z_STREAM_ERROR if a parameter is invalid +             (such as an invalid method).  [4mmsg[24m is set to null if there is no +             error message.  [1mdeflateInit2[22m() does not perform any compression: +             this will be done by [1mdeflate[22m(). + +     [4mint[24m [1mdeflateSetDictionary[22m([4mz_streamp[24m [4mstrm[24m, [4mconst[24m [4mBytef[24m [4m*dictionary[24m, [4muInt[0m +             [4mdictLength[24m); + +             Initializes the compression dictionary from the given byte se- +             quence without producing any compressed output.  This function +             must be called immediately after [1mdeflateInit[22m(), [1mdeflateInit2[22m(), +             or [1mdeflateReset[22m(), before any call to [1mdeflate[22m().  The compressor +             and decompressor must use exactly the same dictionary (see +             [1minflateSetDictionary[22m()). + +             The dictionary should consist of strings (byte sequences) that +             are likely to be encountered later in the data to be compressed, +             with the most commonly used strings preferably put towards the +             end of the dictionary.  Using a dictionary is most useful when +             the data to be compressed is short and can be predicted with good +             accuracy; the data can then be compressed better than with the +             default empty dictionary. + +             Depending on the size of the compression data structures selected +             by [1mdeflateInit[22m() or [1mdeflateInit2[22m(), a part of the dictionary may +             in effect be discarded, for example if the dictionary is larger +             than the window size in [1mdeflate[22m() or [1mdeflate2[22m().  Thus the +             strings most likely to be useful should be put at the end of the +             dictionary, not at the front.  In addition, the current implemen- +             tation of [1mdeflate[22m() will use at most the window size minus 262 +             bytes of the provided dictionary. + +             Upon return of this function, strm->adler is set to the Adler-32 +             value of the dictionary; the decompressor may later use this +             value to determine which dictionary has been used by the compres- +             sor.  (The Adler-32 value applies to the whole dictionary even if +             only a subset of the dictionary is actually used by the compres- +             sor.)  If a raw deflate was requested, then the Adler-32 value is +             not computed and strm->adler is not set. + +             [1mdeflateSetDictionary[22m() returns Z_OK if successful, or +             Z_STREAM_ERROR if a parameter is invalid (such as NULL +             dictionary) or the stream state is inconsistent (for example if +             [1mdeflate[22m() has already been called for this stream or if the com- +             pression method is bsort).  [1mdeflateSetDictionary[22m() does not per- +             form any compression: this will be done by [1mdeflate[22m(). + +     [4mint[24m [1mdeflateCopy[22m([4mz_streamp[24m [4mdest[24m, [4mz_streamp[24m [4msource[24m); + +             The [1mdeflateCopy[22m() function sets the destination stream as a com- +             plete copy of the source stream. + +             This function can be useful when several compression strategies +             will be tried, for example when there are several ways of pre- +             processing the input data with a filter.  The streams that will +             be discarded should then be freed by calling [1mdeflateEnd[22m().  Note +             that [1mdeflateCopy[22m() duplicates the internal compression state +             which can be quite large, so this strategy is slow and can con- +             sume lots of memory. + +             [1mdeflateCopy[22m() returns Z_OK if successful, Z_MEM_ERROR if there +             was not enough memory, Z_STREAM_ERROR if the source stream state +             was inconsistent (such as [4mzalloc[24m being NULL).  [4mmsg[24m is left un- +             changed in both source and destination. + +     [4mint[24m [1mdeflateReset[22m([4mz_streamp[24m [4mstrm[24m); + +             This function is equivalent to [1mdeflateEnd[22m() followed by +             [1mdeflateInit[22m(), but does not free and reallocate all the internal +             compression state.  The stream will keep the same compression +             level and any other attributes that may have been set by +             [1mdeflateInit2[22m(). + +             [1mdeflateReset[22m() returns Z_OK if successful, or Z_STREAM_ERROR if +             the source stream state was inconsistent (such as [4mzalloc[24m or [4mstate[0m +             being NULL). + +     [4mint[24m [1mdeflateParams[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mlevel[24m, [4mint[24m [4mstrategy[24m); + +             The [1mdeflateParams[22m() function dynamically updates the compression +             level and compression strategy.  The interpretation of level and +             strategy is as in [1mdeflateInit2[22m().  This can be used to switch be- +             tween compression and straight copy of the input data, or to +             switch to a different kind of input data requiring a different +             strategy.  If the compression level is changed, the input avail- +             able so far is compressed with the old level (and may be +             flushed); the new level will take effect only at the next call to +             [1mdeflate[22m(). + +             Before the call to [1mdeflateParams[22m(), the stream state must be set +             as for a call to [1mdeflate[22m(), since the currently available input +             may have to be compressed and flushed.  In particular, +             strm->avail_out must be non-zero. + +             [1mdeflateParams[22m() returns Z_OK if successful, Z_STREAM_ERROR if the +             source stream state was inconsistent or if a parameter was in- +             valid, or Z_BUF_ERROR if strm->avail_out was zero. + +     [4mint[24m [1mdeflateTune[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mgood_length[24m, [4mint[24m [4mmax_lazy[24m, [4mint[0m +             [4mnice_length[24m, [4mint[24m [4mmax_chain[24m) + +             Fine tune [1mdeflate[22m()'s internal compression parameters.  This +             should only be used by someone who understands the algorithm used +             by zlib's deflate for searching for the best matching string, and +             even then only by the most fanatic optimizer trying to squeeze +             out the last compressed bit for their specific input data.  Read +             the [4mdeflate.c[24m source code for the meaning of the [4mmax_lazy[24m, +             [4mgood_length[24m, [4mnice_length[24m, and [4mmax_chain[24m parameters. + +             [1mdeflateTune[22m() can be called after [1mdeflateInit[22m() or +             [1mdeflateInit2[22m(), and returns Z_OK on success, or Z_STREAM_ERROR +             for an invalid deflate stream. + +     [4muLong[24m [1mdeflateBound[22m([4mz_streamp[24m [4mstrm[24m, [4muLong[24m [4msourceLen[24m) + +             [1mdeflateBound[22m() returns an upper bound on the compressed size af- +             ter deflation of [4msourceLen[24m bytes.  It must be called after +             [1mdeflateInit[22m() or [1mdeflateInit2[22m().  This would be used to allocate +             an output buffer for deflation in a single pass, and so would be +             called before [1mdeflate[22m(). + +     [4mint[24m [1mdeflatePrime[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mbits[24m, [4mint[24m [4mvalue[24m) + +             [1mdeflatePrime[22m() inserts [4mbits[24m in the deflate output stream.  The +             intent is that this function is used to start off the deflate +             output with the bits leftover from a previous deflate stream when +             appending to it.  As such, this function can only be used for raw +             deflate, and must be used before the first [1mdeflate[22m() call after a +             [1mdeflateInit2[22m() or [1mdeflateReset[22m().  [4mbits[24m must be less than or +             equal to 16, and that many of the least significant bits of [4mvalue[0m +             will be inserted in the output. + +             [1mdeflatePrime[22m() returns Z_OK if successful, or Z_STREAM_ERROR if +             the source stream state was inconsistent. + +     [4mint[24m [1mdeflateSetHeader[22m([4mz_streamp[24m [4mstrm[24m, [4mgz_headerp[24m [4mhead[24m) + +             [1mdeflateSetHeader[22m() provides gzip header information for when a +             gzip stream is requested by [1mdeflateInit2[22m().  [1mdeflateSetHeader[22m() +             may be called after [1mdeflateInit2[22m() or [1mdeflateReset[22m() and before +             the first call of [1mdeflate[22m().  The text, time, os, extra field, +             name, and comment information in the provided gz_header structure +             are written to the gzip header (xflag is ignored - the extra +             flags are set according to the compression level).  The caller +             must assure that, if not Z_NULL, [4mname[24m and [4mcomment[24m are terminated +             with a zero byte, and that if [4mextra[24m is not Z_NULL, that [4mextra_len[0m +             bytes are available there.  If hcrc is true, a gzip header CRC is +             included.  Note that the current versions of the command-line +             version of gzip(1) do not support header CRCs, and will report +             that it is a "multi-part gzip file" and give up. + +             If [1mdeflateSetHeader[22m() is not used, the default gzip header has +             text false, the time set to zero, and os set to 255, with no ex- +             tra, name, or comment fields.  The gzip header is returned to the +             default state by [1mdeflateReset[22m(). + +             [1mdeflateSetHeader[22m() returns Z_OK if successful, or Z_STREAM_ERROR +             if the source stream state was inconsistent. + +     [4mint[24m [1minflateInit2[22m([4mz_streamp[24m [4mstrm[24m, [4mint[24m [4mwindowBits[24m); + +             This is another version of [1minflateInit[22m() with an extra parameter. +             The fields [4mnext_in[24m, [4mavail_in[24m, [4mzalloc[24m, [4mzfree[24m, and [4mopaque[24m must be +             initialized before by the caller. + +             The [4mwindowBits[24m parameter is the base two logarithm of the maximum +             window size (the size of the history buffer).  It should be in +             the range 8..15 for this version of the library.  The default +             value is 15 if [1minflateInit[22m() is used instead.  [4mwindowBits[24m must be +             greater than or equal to the [4mwindowBits[24m value provided to +             [1mdeflateInit2[22m() while compressing, or it must be equal to 15 if +             [1mdeflateInit2[22m() was not used.  If a compressed stream with a +             larger window size is given as input, [1minflate[22m() will return with +             the error code Z_DATA_ERROR instead of trying to allocate a +             larger window. + +             [4mwindowBits[24m can also be -8..-15 for raw inflate.  In this case, +             -windowBits determines the window size.  [1minflate[22m() will then +             process raw deflate data, not looking for a zlib or gzip header, +             not generating a check value, and not looking for any check val- +             ues for comparison at the end of the stream.  This is for use +             with other formats that use the deflate compressed data format +             such as zip.  Those formats provide their own check values.  If a +             custom format is developed using the raw deflate format for com- +             pressed data, it is recommended that a check value such as an +             Adler-32 or a crc32 be applied to the uncompressed data as is +             done in the zlib, gzip, and zip formats.  For most applications, +             the zlib format should be used as is.  Note that comments above +             on the use in [1mdeflateInit2[22m() applies to the magnitude of +             [4mwindowBits[24m. + +             [4mwindowBits[24m can also be greater than 15 for optional gzip decod- +             ing.  Add 32 to windowBits to enable zlib and gzip decoding with +             automatic header detection, or add 16 to decode only the gzip +             format (the zlib format will return a Z_DATA_ERROR).  If a gzip +             stream is being decoded, strm->adler is a crc32 instead of an +             adler32. + +             [1minflateInit2[22m() returns Z_OK if successful, Z_MEM_ERROR if there +             was not enough memory, Z_STREAM_ERROR if a parameter is invalid +             (such as a null strm).  [4mmsg[24m is set to null if there is no error +             message.  [1minflateInit2[22m() does not perform any decompression apart +             from reading the [1mzlib [22mheader if present: this will be done by +             [1minflate[22m().  (So [4mnext_in[24m and [4mavail_in[24m may be modified, but +             [4mnext_out[24m and [4mavail_out[24m are unchanged.) + +     [4mint[24m [1minflateSetDictionary[22m([4mz_streamp[24m [4mstrm[24m, [4mconst[24m [4mBytef[24m [4m*dictionary[24m, [4muInt[0m +             [4mdictLength[24m); + +             Initializes the decompression dictionary from the given uncom- +             pressed byte sequence.  This function must be called immediately +             after a call to [1minflate[22m() if that call returned Z_NEED_DICT.  The +             dictionary chosen by the compressor can be determined from the +             Adler-32 value returned by that call to [1minflate[22m().  The compres- +             sor and decompressor must use exactly the same dictionary (see +             [1mdeflateSetDictionary[22m()).  For raw inflate, this function can be +             called immediately after [1minflateInit2[22m() or [1minflateReset[22m() and be- +             fore any call to [1minflate[22m() to set the dictionary.  The applica- +             tion must ensure that the dictionary that was used for compres- +             sion is provided. + +             [1minflateSetDictionary[22m() returns Z_OK if successful, Z_STREAM_ERROR +             if a parameter is invalid (such as NULL dictionary) or the stream +             state is inconsistent, Z_DATA_ERROR if the given dictionary +             doesn't match the expected one (incorrect Adler-32 value). +             [1minflateSetDictionary[22m() does not perform any decompression: this +             will be done by subsequent calls of [1minflate[22m(). + +     [4mint[24m [1minflateSync[22m([4mz_streamp[24m [4mstrm[24m); + +             Skips invalid compressed data until a full flush point (see above +             the description of [1mdeflate[22m() with Z_FULL_FLUSH) can be found, or +             until all available input is skipped.  No output is provided. + +             [1minflateSync[22m() returns Z_OK if a full flush point has been found, +             Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no +             flush point has been found, or Z_STREAM_ERROR if the stream +             structure was inconsistent.  In the success case, the application +             may save the current value of [4mtotal_in[24m which indicates where +             valid compressed data was found.  In the error case, the applica- +             tion may repeatedly call [1minflateSync[22m(), providing more input each +             time, until success or end of the input data. + +     [4mint[24m [1minflateCopy[22m([4mz_streamp[24m [4mdest[24m, [4mz_streamp[24m [4msource[24m) + +             Sets the destination stream as a complete copy of the source +             stream. + +             This function can be useful when randomly accessing a large +             stream.  The first pass through the stream can periodically +             record the inflate state, allowing restarting inflate at those +             points when randomly accessing the stream. + +             [1minflateCopy[22m() returns Z_OK if success, Z_MEM_ERROR if there was +             not enough memory, Z_STREAM_ERROR if the source stream state was +             inconsistent (such as [4mzalloc[24m being NULL).  [4mmsg[24m is left unchanged +             in both [4msource[24m and [4mdest[24m. + +     [4mint[24m [1minflateReset[22m([4mz_streamp[24m [4mstrm[24m); + +             This function is equivalent to [1minflateEnd[22m() followed by +             [1minflateInit[22m(), but does not free and reallocate all the internal +             decompression state.  The stream will keep attributes that may +             have been set by [1minflateInit2[22m(). + +             [1minflateReset[22m() returns Z_OK if successful, or Z_STREAM_ERROR if +             the source stream state was inconsistent (such as [4mzalloc[24m or [4mstate[0m +             being NULL). + +     [4mint[24m [1minflatePrime[22m([4mz_stream[24m [4mstrm[24m, [4mint[24m [4mbits[24m, [4mint[24m [4mvalue[24m) + +             This function inserts bits in the inflate input stream.  The in- +             tent is that this function is used to start inflating at a bit +             position in the middle of a byte.  The provided bits will be used +             before any bytes are used from [4mnext_in[24m.  This function should +             only be used with raw inflate, and should be used before the +             first [1minflate[22m() call after [1minflateInit2[22m() or [1minflateReset[22m(). +             [4mbits[24m must be less than or equal to 16, and that many of the least +             significant bits of value will be inserted in the input. + +             [1minflatePrime[22m() returns Z_OK if successful, or Z_STREAM_ERROR if +             the source stream state was inconsistent. + +     [4mint[24m [1minflateGetHeader[22m([4mz_streamp[24m [4mstrm[24m, [4mgz_headerp[24m [4mhead[24m) + +             [1minflateGetHeader[22m() requests that gzip header information be +             stored in the provided gz_header structure.  [1minflateGetHeader[22m() +             may be called after [1minflateInit2[22m() or [1minflateReset[22m(), and before +             the first call of [1minflate[22m().  As [1minflate[22m() processes the gzip +             stream, head->done is zero until the header is completed, at +             which time head->done is set to one.  If a zlib stream is being +             decoded, then head->done is set to -1 to indicate that there will +             be no gzip header information forthcoming.  Note that Z_BLOCK can +             be used to force [1minflate[22m() to return immediately after header +             processing is complete and before any actual data is decom- +             pressed. + +             The text, time, xflags, and os fields are filled in with the gzip +             header contents.  hcrc is set to true if there is a header CRC. +             (The header CRC was valid if done is set to one.)  If extra is +             not Z_NULL, then [4mextra_max[24m contains the maximum number of bytes +             to write to [4mextra[24m.  Once done is true, [4mextra_len[24m contains the ac- +             tual extra field length, and [4mextra[24m contains the extra field, or +             that field truncated if [4mextra_max[24m is less than [4mextra_len[24m.  If +             name is not Z_NULL, then up to [4mname_max[24m characters are written +             there, terminated with a zero unless the length is greater than +             [4mname_max[24m.  If comment is not Z_NULL, then up to [4mcomm_max[24m charac- +             ters are written there, terminated with a zero unless the length +             is greater than [4mcomm_max[24m.  When any of extra, name, or comment +             are not Z_NULL and the respective field is not present in the +             header, then that field is set to Z_NULL to signal its absence. +             This allows the use of [1mdeflateSetHeader[22m() with the returned +             structure to duplicate the header.  However if those fields are +             set to allocated memory, then the application will need to save +             those pointers elsewhere so that they can be eventually freed. + +             If [1minflateGetHeader[22m() is not used, then the header information is +             simply discarded.  The header is always checked for validity, in- +             cluding the header CRC if present.  [1minflateReset[22m() will reset the +             process to discard the header information.  The application would +             need to call [1minflateGetHeader[22m() again to retrieve the header from +             the next gzip stream. + +             [1minflateGetHeader[22m() returns Z_OK if successful, or Z_STREAM_ERROR +             if the source stream state was inconsistent. + +     [4mint[24m [1minflateBackInit[22m([4mz_stream[24m [4m*strm[24m, [4mint[24m [4mwindowBits[24m, [4munsigned[24m [4mchar[24m [4mFAR[0m +             [4m*window[24m) + +             Initialize the internal stream state for decompression using +             [1minflateBack[22m() calls.  The fields [4mzalloc[24m, [4mzfree[24m and [4mopaque[24m in [4mstrm[0m +             must be initialized before the call.  If [4mzalloc[24m and [4mzfree[24m are +             Z_NULL, then the default library-derived memory allocation rou- +             tines are used.  [4mwindowBits[24m is the base two logarithm of the win- +             dow size, in the range 8..15.  [4mwindow[24m is a caller supplied buffer +             of that size.  Except for special applications where it is as- +             sured that [1mdeflate[22m() was used with small window sizes, [4mwindowBits[0m +             must be 15 and a 32K byte window must be supplied to be able to +             decompress general deflate streams. + +             See [1minflateBack[22m() for the usage of these routines. + +             [1minflateBackInit[22m() will return Z_OK on success, Z_STREAM_ERROR if +             any of the parameters are invalid, Z_MEM_ERROR if the internal +             state could not be allocated, or Z_VERSION_ERROR if the version +             of the library does not match the version of the header file. + +     [4mint[24m [1minflateBack[22m([4mz_stream[24m [4m*strm[24m, [4min_func[24m [4min[24m, [4mvoid[24m [4mFAR[24m [4m*in_desc[24m, [4mout_func[0m +             [4mout[24m, [4mvoid[24m [4mFAR[24m [4m*out_desc[24m) + +             [1minflateBack[22m() does a raw inflate with a single call using a call- +             back interface for input and output.  This is more efficient than +             [1minflate[22m() for file I/O applications in that it avoids copying be- +             tween the output and the sliding window by simply making the win- +             dow itself the output buffer.  This function trusts the applica- +             tion to not change the output buffer passed by the output func- +             tion, at least until [1minflateBack[22m() returns. + +             [1minflateBackInit[22m() must be called first to allocate the internal +             state and to initialize the state with the user-provided window +             buffer.  [1minflateBack[22m() may then be used multiple times to inflate +             a complete, raw deflate stream with each call.  [1minflateBackEnd[22m() +             is then called to free the allocated state. + +             A raw deflate stream is one with no zlib or gzip header or +             trailer.  This routine would normally be used in a utility that +             reads zip or gzip files and writes out uncompressed files.  The +             utility would decode the header and process the trailer on its +             own, hence this routine expects only the raw deflate stream to +             decompress.  This is different from the normal behavior of +             [1minflate[22m(), which expects either a zlib or gzip header and trailer +             around the deflate stream. + +             [1minflateBack[22m() uses two subroutines supplied by the caller that +             are then called by [1minflateBack[22m() for input and output. +             [1minflateBack[22m() calls those routines until it reads a complete de- +             flate stream and writes out all of the uncompressed data, or un- +             til it encounters an error.  The function's parameters and return +             types are defined above in the in_func and out_func typedefs. +             [1minflateBack[22m() will call in(in_desc, &buf) which should return the +             number of bytes of provided input, and a pointer to that input in +             [4mbuf[24m.  If there is no input available, [1min[22m() must return zero -- +             buf is ignored in that case -- and [1minflateBack[22m() will return a +             buffer error.  [1minflateBack[22m() will call out(out_desc, buf, len) to +             write the uncompressed data buf[0..len-1].  [1mout[22m() should return +             zero on success, or non-zero on failure.  If [1mout[22m() returns non- +             zero, [1minflateBack[22m() will return with an error.  Neither [1min[22m() nor +             [1mout[22m() are permitted to change the contents of the window provided +             to [1minflateBackInit[22m(), which is also the buffer that [1mout[22m() uses to +             write from.  The length written by [1mout[22m() will be at most the win- +             dow size.  Any non-zero amount of input may be provided by [1min[22m(). + +             For convenience, [1minflateBack[22m() can be provided input on the first +             call by setting strm->next_in and strm->avail_in.  If that input +             is exhausted, then [1min[22m() will be called.  Therefore strm->next_in +             must be initialized before calling [1minflateBack[22m().  If +             strm->next_in is Z_NULL, then [1min[22m() will be called immediately for +             input.  If strm->next_in is not Z_NULL, then strm->avail_in must +             also be initialized, and then if strm->avail_in is not zero, in- +             put will initially be taken from strm->next_in[0 .. +             strm->avail_in - 1]. + +             The [4min_desc[24m and [4mout_desc[24m parameters of [1minflateBack[22m() are passed +             as the first parameter of [1min[22m() and [1mout[22m() respectively when they +             are called.  These descriptors can be optionally used to pass any +             information that the caller-supplied [1min[22m() and [1mout[22m() functions +             need to do their job. + +             On return, [1minflateBack[22m() will set strm->next_in and +             strm->avail_in to pass back any unused input that was provided by +             the last [1min[22m() call.  The return values of [1minflateBack[22m() can be +             Z_STREAM_END on success, Z_BUF_ERROR if [1min[22m() or [1mout[22m() returned an +             error, Z_DATA_ERROR if there was a format error in the deflate +             stream (in which case strm->msg is set to indicate the nature of +             the error), or Z_STREAM_ERROR if the stream was not properly ini- +             tialized.  In the case of Z_BUF_ERROR, an input or output error +             can be distinguished using strm->next_in which will be Z_NULL +             only if [1min[22m() returned an error.  If strm->next is not Z_NULL, +             then the Z_BUF_ERROR was due to [1mout[22m() returning non-zero.  ([1min[22m() +             will always be called before [1mout[22m(), so strm->next_in is assured +             to be defined if [1mout[22m() returns non-zero.)  Note that +             [1minflateBack[22m() cannot return Z_OK. + +     [4mint[24m [1minflateBackEnd[22m([4mz_stream[24m [4m*strm[24m) + +             All memory allocated by [1minflateBackInit[22m() is freed. + +             [1minflateBackEnd[22m() returns Z_OK on success, or Z_STREAM_ERROR if +             the stream state was inconsistent. + +     [4muLong[24m [1mzlibCompileFlags[22m([4mvoid[24m) + +             This function returns flags indicating compile-time options. + +             Type sizes, two bits each: + +                   00      16 bits +                   01      32 bits +                   10      64 bits +                   11      other: + +                                 1.0     size of uInt +                                 3.2     size of uLong +                                 5.4     size of voidpf (pointer) +                                 7.6     size of z_off_t + +             Compiler, assembler, and debug options: + +                   8       DEBUG +                   9       ASMV or ASMINF -- use ASM code +                   10      ZLIB_WINAPI -- exported functions use the WINAPI +                           calling convention +                   11      0 (reserved) + +             One-time table building (smaller code, but not thread-safe if +             true): + +                   12      BUILDFIXED -- build static block decoding tables +                           when needed +                   13      DYNAMIC_CRC_TABLE -- build CRC calculation tables +                           when needed +                   14,15   0 (reserved) + +             Library content (indicates missing functionality): + +                   16      NO_GZCOMPRESS -- gz* functions cannot compress (to +                           avoid linking deflate code when not needed) +                   17      NO_GZIP -- deflate can't write gzip streams, and +                           inflate can't detect and decode gzip streams (to +                           avoid linking CRC code) +                   18-19   0 (reserved) + +             Operation variations (changes in library functionality): + +                   20      PKZIP_BUG_WORKAROUND -- slightly more permissive +                           inflate +                   21      FASTEST -- deflate algorithm with only one, lowest +                           compression level +                   22,23   0 (reserved) + +             The sprintf variant used by gzprintf (zero is best): + +                   24      0 = vs*, 1 = s* -- 1 means limited to 20 arguments +                           after the format +                   25      0 = *nprintf, 1 = *printf -- 1 means [1mgzprintf[22m() not +                           secure! +                   26      0 = returns value, 1 = void -- 1 means inferred +                           string length returned + +             Remainder: + +                   27-31   0 (reserved) + +[1mUTILITY FUNCTIONS[0m +     The following utility functions are implemented on top of the basic +     stream-oriented functions.  To simplify the interface, some default op- +     tions are assumed (compression level and memory usage, standard memory +     allocation functions).  The source code of these utility functions can +     easily be modified if you need special options. + +     [4mint[24m [1mcompress[22m([4mBytef[24m [4m*dest[24m, [4muLongf[24m [4m*destLen[24m, [4mconst[24m [4mBytef[24m [4m*source[24m, [4muLong[0m +             [4msourceLen[24m); + +             The [1mcompress[22m() function compresses the source buffer into the +             destination buffer.  [4msourceLen[24m is the byte length of the source +             buffer.  Upon entry, [4mdestLen[24m is the total size of the destination +             buffer, which must be at least the value returned by +             [1mcompressBound[22m([4msourcelen[24m).  Upon exit, [4mdestLen[24m is the actual size +             of the compressed buffer.  This function can be used to compress +             a whole file at once if the input file is mmap'ed. + +             [1mcompress[22m() returns Z_OK if successful, Z_MEM_ERROR if there was +             not enough memory, or Z_BUF_ERROR if there was not enough room in +             the output buffer. + +     [4mint[24m [1mcompress2[22m([4mBytef[24m [4m*dest[24m, [4muLongf[24m [4m*destLen[24m, [4mconst[24m [4mBytef[24m [4m*source[24m, [4muLong[0m +             [4msourceLen[24m, [4mint[24m [4mlevel[24m); + +             The [1mcompress2[22m() function compresses the source buffer into the +             destination buffer.  The [4mlevel[24m parameter has the same meaning as +             in [1mdeflateInit[22m().  [4msourceLen[24m is the byte length of the source +             buffer.  Upon entry, [4mdestLen[24m is the total size of the destination +             buffer, which must be at least the value returned by +             [1mcompressBound[22m([4msourceLen[24m).  Upon exit, [4mdestLen[24m is the actual size +             of the compressed buffer. + +             [1mcompress2[22m() returns Z_OK if successful, Z_MEM_ERROR if there was +             not enough memory, Z_BUF_ERROR if there was not enough room in +             the output buffer, or Z_STREAM_ERROR if the level parameter is +             invalid. + +     [4mint[24m [1mcompressBound[22m([4muLong[24m [4msourceLen[24m) + +             [1mcompressBound[22m() returns an upper bound on the compressed size af- +             ter [1mcompress[22m() or [1mcompress2[22m() on [4msourceLen[24m bytes.  It would be +             used before a [1mcompress[22m() or [1mcompress2[22m() call to allocate the des- +             tination buffer. + +     [4mint[24m [1muncompress[22m([4mBytef[24m [4m*dest[24m, [4muLongf[24m [4m*destLen[24m, [4mconst[24m [4mBytef[24m [4m*source[24m, [4muLong[0m +             [4msourceLen[24m); + +             The [1muncompress[22m() function decompresses the source buffer into the +             destination buffer.  [4msourceLen[24m is the byte length of the source +             buffer.  Upon entry, [4mdestLen[24m is the total size of the destination +             buffer, which must be large enough to hold the entire uncom- +             pressed data.  (The size of the uncompressed data must have been +             saved previously by the compressor and transmitted to the decom- +             pressor by some mechanism outside the scope of this compression +             library.)  Upon exit, [4mdestLen[24m is the actual size of the com- +             pressed buffer.  This function can be used to decompress a whole +             file at once if the input file is mmap'ed. + +             [1muncompress[22m() returns Z_OK if successful, Z_MEM_ERROR if there was +             not enough memory, Z_BUF_ERROR if there was not enough room in +             the output buffer, or Z_DATA_ERROR if the input data was cor- +             rupted or incomplete. + +     [4mgzFile[24m [1mgzopen[22m([4mconst[24m [4mchar[24m [4m*path[24m, [4mconst[24m [4mchar[24m [4m*mode[24m); + +             The [1mgzopen[22m() function opens a gzip (.gz) file for reading or +             writing.  The mode parameter is as in fopen(3) ("rb" or "wb") but +             can also include a compression level (wb9) or a strategy: `f' for +             filtered data, as in "wb6f"; `h' for Huffman only compression, as +             in "wb1h", or `R' for run-length encoding as in "wb1R".  (See the +             description of [1mdeflateInit2[22m() for more information about the +             strategy parameter.) + +             [1mgzopen[22m() can be used to read a file which is not in gzip format; +             in this case [1mgzread[22m() will directly read from the file without +             decompression. + +             [1mgzopen[22m() returns NULL if the file could not be opened or if there +             was insufficient memory to allocate the (de)compression state; +             errno can be checked to distinguish the two cases (if errno is +             zero, the [1mzlib [22merror is Z_MEM_ERROR). + +     [4mgzFile[24m [1mgzdopen[22m([4mint[24m [4mfd[24m, [4mconst[24m [4mchar[24m [4m*mode[24m); + +             The [1mgzdopen[22m() function associates a gzFile with the file descrip- +             tor [4mfd[24m.  File descriptors are obtained from calls like open(2), +             dup(2), creat(3), pipe(2), or fileno(3) (if the file has been +             previously opened with fopen(3)).  The [4mmode[24m parameter is as in +             [1mgzopen[22m(). + +             The next call to [1mgzclose[22m() on the returned gzFile will also close +             the file descriptor fd, just like fclose(fdopen(fd), mode) closes +             the file descriptor fd.  If you want to keep fd open, use gz- +             dopen(dup(fd), mode). + +             [1mgzdopen[22m() returns NULL if there was insufficient memory to allo- +             cate the (de)compression state. + +     [4mint[24m [1mgzsetparams[22m([4mgzFile[24m [4mfile[24m, [4mint[24m [4mlevel[24m, [4mint[24m [4mstrategy[24m); + +             The [1mgzsetparams[22m() function dynamically updates the compression +             level or strategy.  See the description of [1mdeflateInit2[22m() for the +             meaning of these parameters. + +             [1mgzsetparams[22m() returns Z_OK if successful, or Z_STREAM_ERROR if +             the file was not opened for writing. + +     [4mint[24m [1mgzread[22m([4mgzFile[24m [4mfile[24m, [4mvoidp[24m [4mbuf[24m, [4munsigned[24m [4mlen[24m); + +             The [1mgzread[22m() function reads the given number of uncompressed +             bytes from the compressed file.  If the input file was not in +             gzip format, [1mgzread[22m() copies the given number of bytes into the +             buffer. + +             [1mgzread[22m() returns the number of uncompressed bytes actually read +             (0 for end of file, -1 for error). + +     [4mint[24m [1mgzwrite[22m([4mgzFile[24m [4mfile[24m, [4mvoidpc[24m [4mbuf[24m, [4munsigned[24m [4mlen[24m); + +             The [1mgzwrite[22m() function writes the given number of uncompressed +             bytes into the compressed file.  [1mgzwrite[22m() returns the number of +             uncompressed bytes actually written (0 in case of error). + +     [4mint[24m [1mgzprintf[22m([4mgzFile[24m [4mfile[24m, [4mconst[24m [4mchar[24m [4m*format[24m, [4m...[24m); + +             The [1mgzprintf[22m() function converts, formats, and writes the args to +             the compressed file under control of the format string, as in +             fprintf(3).  [1mgzprintf[22m() returns the number of uncompressed bytes +             actually written (0 in case of error).  The number of uncom- +             pressed bytes written is limited to 4095.  The caller should make +             sure that this limit is not exceeded.  If it is exceeded, then +             [1mgzprintf[22m() will return an error (0) with nothing written.  In +             this case, there may also be a buffer overflow with unpredictable +             consequences, which is possible only if [1mzlib [22mwas compiled with +             the insecure functions [1msprintf[22m() or [1mvsprintf[22m() because the secure +             [1msnprintf[22m() or [1mvsnprintf[22m() functions were not available. + +     [4mint[24m [1mgzputs[22m([4mgzFile[24m [4mfile[24m, [4mconst[24m [4mchar[24m [4m*s[24m); + +             The [1mgzputs[22m() function writes the given null-terminated string to +             the compressed file, excluding the terminating null character. + +             [1mgzputs[22m() returns the number of characters written, or -1 in case +             of error. + +     [4mchar[24m [4m*[24m [1mgzgets[22m([4mgzFile[24m [4mfile[24m, [4mchar[24m [4m*buf[24m, [4mint[24m [4mlen[24m); + +             The [1mgzgets[22m() function reads bytes from the compressed file until +             len-1 characters are read, or a newline character is read and +             transferred to [4mbuf[24m, or an end-of-file condition is encountered. +             The string is then terminated with a null character. + +             [1mgzgets[22m() returns [4mbuf[24m, or Z_NULL in case of error. + +     [4mint[24m [1mgzputc[22m([4mgzFile[24m [4mfile[24m, [4mint[24m [4mc[24m); + +             The [1mgzputc[22m() function writes [4mc[24m, converted to an unsigned char, +             into the compressed file.  [1mgzputc[22m() returns the value that was +             written, or -1 in case of error. + +     [4mint[24m [1mgzgetc[22m([4mgzFile[24m [4mfile[24m); + +             The [1mgzgetc[22m() function reads one byte from the compressed file. +             [1mgzgetc[22m() returns this byte or -1 in case of end of file or error. + +     [4mint[24m [1mgzungetc[22m([4mint[24m [4mc[24m, [4mgzFile[24m [4mfile[24m) + +             Push one character back onto the stream to be read again later. +             Only one character of push-back is allowed.  [1mgzungetc[22m() returns +             the character pushed, or -1 on failure.  [1mgzungetc[22m() will fail if +             a character has been pushed but not read yet, or if [4mc[24m is -1.  The +             pushed character will be discarded if the stream is repositioned +             with [1mgzseek[22m() or [1mgzrewind[22m(). + +     [4mint[24m [1mgzflush[22m([4mgzFile[24m [4mfile[24m, [4mint[24m [4mflush[24m); + +             The [1mgzflush[22m() function flushes all pending output into the com- +             pressed file.  The parameter [4mflush[24m is as in the [1mdeflate[22m() func- +             tion.  The return value is the [1mzlib [22merror number (see function +             [1mgzerror[22m() below).  [1mgzflush[22m() returns Z_OK if the flush parameter +             is Z_FINISH and all output could be flushed. + +             [1mgzflush[22m() should be called only when strictly necessary because +             it can degrade compression. + +     [4mz_off_t[24m [1mgzseek[22m([4mgzFile[24m [4mfile[24m, [4mz_off_t[24m [4moffset[24m, [4mint[24m [4mwhence[24m); + +             Sets the starting position for the next [1mgzread[22m() or [1mgzwrite[22m() on +             the given compressed file.  The offset represents a number of +             bytes in the uncompressed data stream.  The whence parameter is +             defined as in lseek(2); the value SEEK_END is not supported. + +             If the file is opened for reading, this function is emulated but +             can be extremely slow.  If the file is opened for writing, only +             forward seeks are supported; [1mgzseek[22m() then compresses a sequence +             of zeroes up to the new starting position. + +             [1mgzseek[22m() returns the resulting offset location as measured in +             bytes from the beginning of the uncompressed stream, or -1 in +             case of error, in particular if the file is opened for writing +             and the new starting position would be before the current posi- +             tion. + +     [4mint[24m [1mgzrewind[22m([4mgzFile[24m [4mfile[24m); + +             The [1mgzrewind[22m() function rewinds the given [4mfile[24m.  This function is +             supported only for reading. + +             gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). + +     [4mz_off_t[24m [1mgztell[22m([4mgzFile[24m [4mfile[24m); + +             The [1mgztell[22m() function returns the starting position for the next +             [1mgzread[22m() or [1mgzwrite[22m() on the given compressed file.  This posi- +             tion represents a number of bytes in the uncompressed data +             stream. + +             gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR). + +     [4mint[24m [1mgzeof[22m([4mgzFile[24m [4mfile[24m); + +             The [1mgzeof[22m() function returns 1 when EOF has previously been de- +             tected reading the given input stream, otherwise zero. + +     [4mint[24m [1mgzdirect[22m([4mgzFile[24m [4mfile[24m); + +             The [1mgzdirect[22m() function returns 1 if the file is being read di- +             rectly without compression; otherwise it returns 0. + +     [4mint[24m [1mgzclose[22m([4mgzFile[24m [4mfile[24m); + +             The [1mgzclose[22m() function flushes all pending output if necessary, +             closes the compressed file and deallocates all the (de)compres- +             sion state.  The return value is the [1mzlib [22merror number (see func- +             tion [1mgzerror[22m() below). + +     [4mconst[24m [4mchar[24m [4m*[24m [1mgzerror[22m([4mgzFile[24m [4mfile[24m, [4mint[24m [4m*errnum[24m); + +             The [1mgzerror[22m() function returns the error message for the last er- +             ror which occurred on the given compressed [4mfile[24m.  [4merrnum[24m is set +             to the [1mzlib [22merror number.  If an error occurred in the file sys- +             tem and not in the compression library, [4merrnum[24m is set to Z_ERRNO +             and the application may consult errno to get the exact error +             code. + +     [4mvoid[24m [1mgzclearerr[22m([4mgzFile[24m [4mfile[24m) +             Clears the error and end-of-file flags for [4mfile[24m.  This is analo- +             gous to the [1mclearerr[22m() function in stdio.  This is useful for +             continuing to read a gzip file that is being written concur- +             rently. + +[1mCHECKSUM FUNCTIONS[0m +     These functions are not related to compression but are exported anyway +     because they might be useful in applications using the compression li- +     brary. + +     [4muLong[24m [1madler32[22m([4muLong[24m [4madler[24m, [4mconst[24m [4mBytef[24m [4m*buf[24m, [4muInt[24m [4mlen[24m); +             The [1madler32[22m() function updates a running Adler-32 checksum with +             the bytes buf[0..len-1] and returns the updated checksum.  If [4mbuf[0m +             is NULL, this function returns the required initial value for the +             checksum. + +             An Adler-32 checksum is almost as reliable as a CRC32 but can be +             computed much faster.  Usage example: + +                   uLong adler = adler32(0L, Z_NULL, 0); + +                   while (read_buffer(buffer, length) != EOF) { +                   adler = adler32(adler, buffer, length); +                   } +                   if (adler != original_adler) error(); + +     [4muLong[24m [1madler32_combine[22m([4muLong[24m [4madler1[24m, [4muLong[24m [4madler2[24m, [4mz_off_t[24m [4mlen2[24m) + +             The [1madler32_combine[22m() function combines two Adler-32 checksums +             into one.  For two sequences of bytes, seq1 and seq2 with lengths +             len1 and len2, Adler-32 checksums are calculated for each, adler1 +             and adler2.  [1madler32_combine[22m() returns the Adler-32 checksum of +             seq1 and seq2 concatenated, requiring only adler1, adler2, and +             len2. + +     [4muLong[24m [1mcrc32[22m([4muLong[24m [4mcrc[24m, [4mconst[24m [4mBytef[24m [4m*buf[24m, [4muInt[24m [4mlen[24m); + +             The [1mcrc32[22m() function updates a running CRC-32 with the bytes +             buf[0..len-1] and returns the updated CRC-32.  If [4mbuf[24m is NULL, +             this function returns the required initial value for the CRC. +             Pre- and post-conditioning (one's complement) is performed within +             this function so it shouldn't be done by the application.  Usage +             example: + +                   uLong crc = crc32(0L, Z_NULL, 0); + +                   while (read_buffer(buffer, length) != EOF) { +                   crc = crc32(crc, buffer, length); +                   } +                   if (crc != original_crc) error(); + +     [4muLong[24m [1mcrc32_combine[22m([4muLong[24m [4mcrc1[24m, [4muLong[24m [4mcrc2[24m, [4mz_off_t[24m [4mlen2[24m) + +             The [1mcrc32_combine[22m() function combines two CRC-32 check values +             into one.  For two sequences of bytes, seq1 and seq2 with lengths +             len1 and len2, CRC-32 check values are calculated for each, crc1 +             and crc2.  [1mcrc32_combine[22m() returns the CRC-32 check value of seq1 +             and seq2 concatenated, requiring only crc1, crc2, and len2. + +[1mSTRUCTURES[0m +     struct internal_state; + +     typedef struct z_stream_s { +         Bytef    *next_in;  /* next input byte */ +         uInt     avail_in;  /* number of bytes available at next_in */ +         off_t    total_in;  /* total nb of input bytes read so far */ + +         Bytef    *next_out; /* next output byte should be put there */ +         uInt     avail_out; /* remaining free space at next_out */ +         off_t    total_out; /* total nb of bytes output so far */ + +         char     *msg;      /* last error message, NULL if no error */ +         struct internal_state FAR *state; /* not visible by applications */ + +         alloc_func zalloc;  /* used to allocate the internal state */ +         free_func  zfree;   /* used to free the internal state */ +         voidpf     opaque;  /* private data object passed to zalloc and zfree*/ + +         int     data_type;  /* best guess about the data type: binary or text*/ +         uLong   adler;      /* adler32 value of the uncompressed data */ +         uLong   reserved;   /* reserved for future use */ +     } z_stream; + +     typedef z_stream FAR * z_streamp; + +     /* +          gzip header information passed to and from zlib routines. +       See RFC 1952 for more details on the meanings of these fields. +     */ +     typedef struct gz_header_s { +         int     text;       /* true if compressed data believed to be text */ +         uLong   time;       /* modification time */ +         int     xflags;     /*extra flags (not used when writing a gzip file)*/ +         int     os;         /* operating system */ +         Bytef   *extra;     /* pointer to extra field or Z_NULL if none */ +         uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */ +         uInt    extra_max;  /* space at extra (only when reading header) */ +         Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL*/ +         uInt    name_max;   /* space at name (only when reading header) */ +         Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */ +         uInt    comm_max;   /* space at comment (only when reading header) */ +         int     hcrc;       /* true if there was or will be a header crc */ +         int     done;       /* true when done reading gzip header (not used +                                when writing a gzip file) */ +     } gz_header; + +     typedef gz_header FAR *gz_headerp; + +     The application must update [4mnext_in[24m and [4mavail_in[24m when [4mavail_in[24m has +     dropped to zero.  It must update [4mnext_out[24m and [4mavail_out[24m when [4mavail_out[0m +     has dropped to zero.  The application must initialize [4mzalloc[24m, [4mzfree[24m, and +     [4mopaque[24m before calling the init function.  All other fields are set by the +     compression library and must not be updated by the application. + +     The [4mopaque[24m value provided by the application will be passed as the first +     parameter for calls to [1mzalloc[22m() and [1mzfree[22m().  This can be useful for cus- +     tom memory management.  The compression library attaches no meaning to +     the [4mopaque[24m value. + +     [4mzalloc[24m must return Z_NULL if there is not enough memory for the object. +     If [1mzlib [22mis used in a multi-threaded application, [4mzalloc[24m and [4mzfree[24m must be +     thread safe. + +     On 16-bit systems, the functions [4mzalloc[24m and [4mzfree[24m must be able to allo- +     cate exactly 65536 bytes, but will not be required to allocate more than +     this if the symbol MAXSEG_64K is defined (see <[4mzconf.h[24m>). + +     WARNING: On MSDOS, pointers returned by [4mzalloc[24m for objects of exactly +     65536 bytes *must* have their offset normalized to zero.  The default al- +     location function provided by this library ensures this (see [4mzutil.c[24m). +     To reduce memory requirements and avoid any allocation of 64K objects, at +     the expense of compression ratio, compile the library with -DMAX_WBITS=14 +     (see <[4mzconf.h[24m>). + +     The fields [4mtotal_in[24m and [4mtotal_out[24m can be used for statistics or progress +     reports.  After compression, [4mtotal_in[24m holds the total size of the uncom- +     pressed data and may be saved for use in the decompressor (particularly +     if the decompressor wants to decompress everything in a single step). + +[1mCONSTANTS[0m +     #define Z_NO_FLUSH      0 +     #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +     #define Z_SYNC_FLUSH    2 +     #define Z_FULL_FLUSH    3 +     #define Z_FINISH        4 +     #define Z_BLOCK          5 +     /* Allowed flush values; see deflate() and inflate() below for details */ + +     #define Z_OK            0 +     #define Z_STREAM_END    1 +     #define Z_NEED_DICT     2 +     #define Z_ERRNO        (-1) +     #define Z_STREAM_ERROR (-2) +     #define Z_DATA_ERROR   (-3) +     #define Z_MEM_ERROR    (-4) +     #define Z_BUF_ERROR    (-5) +     #define Z_VERSION_ERROR (-6) +     /* Return codes for the compression/decompression functions. +      * Negative values are errors, +      * positive values are used for special but normal events. +      */ + +     #define Z_NO_COMPRESSION         0 +     #define Z_BEST_SPEED             1 +     #define Z_BEST_COMPRESSION       9 +     #define Z_DEFAULT_COMPRESSION  (-1) +     /* compression levels */ + +     #define Z_FILTERED            1 +     #define Z_HUFFMAN_ONLY        2 +     #define Z_RLE                 3 +     #define Z_FIXED               4 +     #define Z_DEFAULT_STRATEGY    0 +     /* compression strategy; see deflateInit2() below for details */ + +     #define Z_BINARY   0 +     #define Z_TEXT     1 +     #define Z_ASCII    Z_TEXT /* for compatibility with 1.2.2 and earlier */ +     #define Z_UNKNOWN  2 +     /* Possible values of the data_type field (though see inflate()) */ + +     #define Z_DEFLATED   8 +     /* The deflate compression method +      * (the only one supported in this version) +     */ + +     #define Z_NULL  0  /* for initializing zalloc, zfree, opaque */ + +     #define zlib_version zlibVersion() +     /* for compatibility with versions < 1.0.2 */ + +[1mVARIOUS HACKS[0m +     deflateInit and inflateInit are macros to allow checking the [1mzlib [22mversion +     and the compiler's view of [4mz_stream[24m. + +     [4mint[24m [1mdeflateInit_[22m([4mz_stream[24m [4mstrm[24m, [4mint[24m [4mlevel[24m, [4mconst[24m [4mchar[24m [4m*version[24m, [4mint[0m +             [4mstream_size[24m); + +     [4mint[24m [1minflateInit_[22m([4mz_stream[24m [4mstrm[24m, [4mconst[24m [4mchar[24m [4m*version[24m, [4mint[24m [4mstream_size[24m); + +     [4mint[24m [1mdeflateInit2_[22m([4mz_stream[24m [4mstrm[24m, [4mint[24m [4mlevel[24m, [4mint[24m [4mmethod[24m, [4mint[24m [4mwindowBits[24m, +             [4mint[24m [4mmemLevel[24m, [4mint[24m [4mstrategy[24m, [4mconst[24m [4mchar[24m [4m*version[24m, [4mint[24m [4mstream_size[24m) + +     [4mint[24m [1minflateInit2_[22m([4mz_stream[24m [4mstrm[24m, [4mint[24m [4mwindowBits[24m, [4mconst[24m [4mchar[24m [4m*version[24m, [4mint[0m +             [4mstream_size[24m); + +     [4mint[24m [1minflateBackInit_[22m([4mz_stream[24m [4m*strm[24m, [4mint[24m [4mwindowBits[24m, [4munsigned[24m [4mchar[24m [4mFAR[0m +             [4m*window[24m, [4mconst[24m [4mchar[24m [4m*version[24m, [4mint[24m [4mstream_size[24m) + +     [4mconst[24m [4mchar[24m [4m*[24m [1mzError[22m([4mint[24m [4merr[24m); + +     [4mint[24m [1minflateSyncPoint[22m([4mz_streamp[24m [4mz[24m); + +     [4mconst[24m [4muLongf[24m [4m*[24m [1mget_crc_table[22m([4mvoid[24m); + +[1mSEE ALSO[0m +     compress(1), gzip(1) + +[1mSTANDARDS[0m +     P. Deutsch and J-L. Gailly, [4mZLIB[24m [4mCompressed[24m [4mData[24m [4mFormat[24m [4mSpecification[0m +     [4mversion[24m [4m3.3[24m, RFC 1950, May 1996. + +     P. Deutsch, [4mDEFLATE[24m [4mCompressed[24m [4mData[24m [4mFormat[24m [4mSpecification[24m [4mversion[24m [4m1.3[24m, RFC +     1951, May 1996. + +     P. Deutsch, [4mGZIP[24m [4mfile[24m [4mformat[24m [4mspecification[24m [4mversion[24m [4m4.3[24m, RFC 1952, May +     1996. + +[1mHISTORY[0m +     This manual page is based on an HTML version of <[4mzlib.h[24m> converted by +     piaip <[4mpiaip@csie.ntu.edu.tw[24m> and was converted to mdoc format by the +     OpenBSD project. + +[1mAUTHORS[0m +     Jean-loup Gailly <[4mjloup@gzip.org[24m> +     Mark Adler <[4mmadler@alumni.caltech.edu[24m> + +BSD                             March 16, 2018                             BSD diff --git a/lib/libz/crc32.c b/lib/libz/crc32.c new file mode 100644 index 0000000..fe88dba --- /dev/null +++ b/lib/libz/crc32.c @@ -0,0 +1,422 @@ +/*	$OpenBSD: crc32.c,v 1.8 2005/07/20 15:56:41 millert Exp $	*/ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors.  This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* +  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore +  protection on the static variables used to control the first-use generation +  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should +  first call get_crc_table() to initialize the tables before allowing more than +  one thread to use crc32(). + */ + +#ifdef MAKECRCH +#  include <stdio.h> +#  ifndef DYNAMIC_CRC_TABLE +#    define DYNAMIC_CRC_TABLE +#  endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ +   +#include "zutil.h"      /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +#  ifdef STDC           /* need ANSI C limits.h to determine sizes */ +#    include <limits.h> +#    define BYFOUR +#    if (UINT_MAX == 0xffffffffUL) +       typedef unsigned int u4; +#    else +#      if (ULONG_MAX == 0xffffffffUL) +         typedef unsigned long u4; +#      else +#        if (USHRT_MAX == 0xffffffffUL) +           typedef unsigned short u4; +#        else +#          undef BYFOUR     /* can't find a four-byte integer type! */ +#        endif +#      endif +#    endif +#  endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +#  define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ +                (((w)&0xff00)<<8)+(((w)&0xff)<<24)) +   local unsigned long crc32_little OF((unsigned long, +                        const unsigned char FAR *, unsigned)); +   local unsigned long crc32_big OF((unsigned long, +                        const unsigned char FAR *, unsigned)); +#  define TBLS 8 +#else +#  define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, +                                         unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH +   local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* +  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: +  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + +  Polynomials over GF(2) are represented in binary, one bit per coefficient, +  with the lowest powers in the most significant bit.  Then adding polynomials +  is just exclusive-or, and multiplying a polynomial by x is a right shift by +  one.  If we call the above polynomial p, and represent a byte as the +  polynomial q, also with the lowest power in the most significant bit (so the +  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, +  where a mod b means the remainder after dividing a by b. + +  This calculation is done using the shift-register method of multiplying and +  taking the remainder.  The register is initialized to zero, and for each +  incoming bit, x^32 is added mod p to the register if the bit is a one (where +  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by +  x (which is shifting right by one and adding x^32 mod p if the bit shifted +  out is a one).  We start with the highest power (least significant bit) of +  q and repeat for all eight bits of q. + +  The first table is simply the CRC of all possible eight bit values.  This is +  all the information needed to generate CRCs on data a byte at a time for all +  combinations of CRC register values and incoming bytes.  The remaining tables +  allow for word-at-a-time CRC calculation for both big-endian and little- +  endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ +    unsigned long c; +    int n, k; +    unsigned long poly;                 /* polynomial exclusive-or pattern */ +    /* terms of polynomial defining this crc (except x^32): */ +    static volatile int first = 1;      /* flag to limit concurrent making */ +    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + +    /* See if another task is already doing this (not thread-safe, but better +       than nothing -- significantly reduces duration of vulnerability in +       case the advice about DYNAMIC_CRC_TABLE is ignored) */ +    if (first) { +        first = 0; + +        /* make exclusive-or pattern from polynomial (0xedb88320UL) */ +        poly = 0UL; +        for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) +            poly |= 1UL << (31 - p[n]); + +        /* generate a crc for every 8-bit value */ +        for (n = 0; n < 256; n++) { +            c = (unsigned long)n; +            for (k = 0; k < 8; k++) +                c = c & 1 ? poly ^ (c >> 1) : c >> 1; +            crc_table[0][n] = c; +        } + +#ifdef BYFOUR +        /* generate crc for each value followed by one, two, and three zeros, +           and then the byte reversal of those as well as the first table */ +        for (n = 0; n < 256; n++) { +            c = crc_table[0][n]; +            crc_table[4][n] = REV(c); +            for (k = 1; k < 4; k++) { +                c = crc_table[0][c & 0xff] ^ (c >> 8); +                crc_table[k][n] = c; +                crc_table[k + 4][n] = REV(c); +            } +        } +#endif /* BYFOUR */ + +        crc_table_empty = 0; +    } +    else {      /* not first */ +        /* wait for the other guy to finish (not efficient, but rare) */ +        while (crc_table_empty) +            ; +    } + +#ifdef MAKECRCH +    /* write out CRC tables to crc32.h */ +    { +        FILE *out; + +        out = fopen("crc32.h", "w"); +        if (out == NULL) return; +        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); +        fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); +        fprintf(out, "local const unsigned long FAR "); +        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n"); +        write_table(out, crc_table[0]); +#  ifdef BYFOUR +        fprintf(out, "#ifdef BYFOUR\n"); +        for (k = 1; k < 8; k++) { +            fprintf(out, "  },\n  {\n"); +            write_table(out, crc_table[k]); +        } +        fprintf(out, "#endif\n"); +#  endif /* BYFOUR */ +        fprintf(out, "  }\n};\n"); +        fclose(out); +    } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) +    FILE *out; +    const unsigned long FAR *table; +{ +    int n; + +    for (n = 0; n < 256; n++) +        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ", table[n], +                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE +    if (crc_table_empty) +        make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ +    return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) +    unsigned long crc; +    const unsigned char FAR *buf; +    unsigned len; +{ +    if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE +    if (crc_table_empty) +        make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR +    if (sizeof(void *) == sizeof(ptrdiff_t)) { +        u4 endian; + +        endian = 1; +        if (*((unsigned char *)(&endian))) +            return crc32_little(crc, buf, len); +        else +            return crc32_big(crc, buf, len); +    } +#endif /* BYFOUR */ +    crc = crc ^ 0xffffffffUL; +    while (len >= 8) { +        DO8; +        len -= 8; +    } +    if (len) do { +        DO1; +    } while (--len); +    return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ +        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ +            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) +    unsigned long crc; +    const unsigned char FAR *buf; +    unsigned len; +{ +    register u4 c; +    register const u4 FAR *buf4; + +    c = (u4)crc; +    c = ~c; +    while (len && ((ptrdiff_t)buf & 3)) { +        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); +        len--; +    } + +    buf4 = (const u4 FAR *)(const void FAR *)buf; +    while (len >= 32) { +        DOLIT32; +        len -= 32; +    } +    while (len >= 4) { +        DOLIT4; +        len -= 4; +    } +    buf = (const unsigned char FAR *)buf4; + +    if (len) do { +        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); +    } while (--len); +    c = ~c; +    return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ +        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ +            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) +    unsigned long crc; +    const unsigned char FAR *buf; +    unsigned len; +{ +    register u4 c; +    register const u4 FAR *buf4; + +    c = REV((u4)crc); +    c = ~c; +    while (len && ((ptrdiff_t)buf & 3)) { +        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); +        len--; +    } + +    buf4 = (const u4 FAR *)(const void FAR *)buf; +    buf4--; +    while (len >= 32) { +        DOBIG32; +        len -= 32; +    } +    while (len >= 4) { +        DOBIG4; +        len -= 4; +    } +    buf4++; +    buf = (const unsigned char FAR *)buf4; + +    if (len) do { +        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); +    } while (--len); +    c = ~c; +    return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) +    unsigned long *mat; +    unsigned long vec; +{ +    unsigned long sum; + +    sum = 0; +    while (vec) { +        if (vec & 1) +            sum ^= *mat; +        vec >>= 1; +        mat++; +    } +    return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) +    unsigned long *square; +    unsigned long *mat; +{ +    int n; + +    for (n = 0; n < GF2_DIM; n++) +        square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) +    uLong crc1; +    uLong crc2; +    z_off_t len2; +{ +    int n; +    unsigned long row; +    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */ +    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */ + +    /* degenerate case */ +    if (len2 == 0) +        return crc1; + +    /* put operator for one zero bit in odd */ +    odd[0] = 0xedb88320L;           /* CRC-32 polynomial */ +    row = 1; +    for (n = 1; n < GF2_DIM; n++) { +        odd[n] = row; +        row <<= 1; +    } + +    /* put operator for two zero bits in even */ +    gf2_matrix_square(even, odd); + +    /* put operator for four zero bits in odd */ +    gf2_matrix_square(odd, even); + +    /* apply len2 zeros to crc1 (first square will put the operator for one +       zero byte, eight zero bits, in even) */ +    do { +        /* apply zeros operator for this bit of len2 */ +        gf2_matrix_square(even, odd); +        if (len2 & 1) +            crc1 = gf2_matrix_times(even, crc1); +        len2 >>= 1; + +        /* if no more bits set, then done */ +        if (len2 == 0) +            break; + +        /* another iteration of the loop with odd and even swapped */ +        gf2_matrix_square(odd, even); +        if (len2 & 1) +            crc1 = gf2_matrix_times(odd, crc1); +        len2 >>= 1; + +        /* if no more bits set, then done */ +    } while (len2 != 0); + +    /* return combined crc */ +    crc1 ^= crc2; +    return crc1; +} diff --git a/lib/libz/crc32.h b/lib/libz/crc32.h new file mode 100644 index 0000000..8053b61 --- /dev/null +++ b/lib/libz/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ +  { +    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, +    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, +    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, +    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, +    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, +    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, +    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, +    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, +    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, +    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, +    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, +    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, +    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, +    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, +    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, +    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, +    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, +    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, +    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, +    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, +    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, +    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, +    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, +    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, +    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, +    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, +    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, +    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, +    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, +    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, +    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, +    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, +    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, +    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, +    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, +    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, +    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, +    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, +    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, +    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, +    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, +    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, +    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, +    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, +    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, +    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, +    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, +    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, +    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, +    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, +    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, +    0x2d02ef8dUL +#ifdef BYFOUR +  }, +  { +    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, +    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, +    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, +    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, +    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, +    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, +    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, +    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, +    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, +    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, +    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, +    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, +    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, +    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, +    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, +    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, +    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, +    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, +    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, +    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, +    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, +    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, +    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, +    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, +    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, +    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, +    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, +    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, +    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, +    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, +    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, +    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, +    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, +    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, +    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, +    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, +    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, +    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, +    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, +    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, +    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, +    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, +    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, +    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, +    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, +    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, +    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, +    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, +    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, +    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, +    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, +    0x9324fd72UL +  }, +  { +    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, +    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, +    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, +    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, +    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, +    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, +    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, +    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, +    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, +    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, +    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, +    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, +    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, +    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, +    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, +    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, +    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, +    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, +    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, +    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, +    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, +    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, +    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, +    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, +    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, +    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, +    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, +    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, +    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, +    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, +    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, +    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, +    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, +    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, +    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, +    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, +    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, +    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, +    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, +    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, +    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, +    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, +    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, +    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, +    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, +    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, +    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, +    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, +    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, +    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, +    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, +    0xbe9834edUL +  }, +  { +    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, +    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, +    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, +    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, +    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, +    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, +    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, +    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, +    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, +    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, +    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, +    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, +    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, +    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, +    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, +    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, +    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, +    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, +    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, +    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, +    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, +    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, +    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, +    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, +    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, +    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, +    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, +    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, +    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, +    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, +    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, +    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, +    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, +    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, +    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, +    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, +    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, +    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, +    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, +    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, +    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, +    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, +    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, +    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, +    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, +    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, +    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, +    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, +    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, +    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, +    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, +    0xde0506f1UL +  }, +  { +    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, +    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, +    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, +    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, +    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, +    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, +    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, +    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, +    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, +    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, +    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, +    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, +    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, +    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, +    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, +    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, +    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, +    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, +    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, +    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, +    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, +    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, +    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, +    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, +    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, +    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, +    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, +    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, +    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, +    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, +    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, +    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, +    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, +    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, +    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, +    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, +    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, +    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, +    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, +    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, +    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, +    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, +    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, +    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, +    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, +    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, +    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, +    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, +    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, +    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, +    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, +    0x8def022dUL +  }, +  { +    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, +    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, +    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, +    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, +    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, +    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, +    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, +    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, +    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, +    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, +    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, +    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, +    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, +    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, +    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, +    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, +    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, +    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, +    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, +    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, +    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, +    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, +    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, +    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, +    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, +    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, +    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, +    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, +    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, +    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, +    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, +    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, +    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, +    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, +    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, +    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, +    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, +    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, +    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, +    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, +    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, +    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, +    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, +    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, +    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, +    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, +    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, +    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, +    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, +    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, +    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, +    0x72fd2493UL +  }, +  { +    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, +    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, +    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, +    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, +    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, +    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, +    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, +    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, +    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, +    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, +    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, +    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, +    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, +    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, +    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, +    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, +    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, +    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, +    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, +    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, +    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, +    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, +    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, +    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, +    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, +    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, +    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, +    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, +    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, +    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, +    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, +    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, +    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, +    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, +    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, +    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, +    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, +    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, +    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, +    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, +    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, +    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, +    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, +    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, +    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, +    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, +    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, +    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, +    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, +    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, +    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, +    0xed3498beUL +  }, +  { +    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, +    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, +    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, +    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, +    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, +    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, +    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, +    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, +    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, +    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, +    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, +    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, +    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, +    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, +    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, +    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, +    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, +    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, +    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, +    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, +    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, +    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, +    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, +    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, +    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, +    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, +    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, +    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, +    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, +    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, +    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, +    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, +    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, +    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, +    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, +    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, +    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, +    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, +    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, +    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, +    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, +    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, +    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, +    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, +    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, +    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, +    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, +    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, +    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, +    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, +    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, +    0xf10605deUL +#endif +  } +}; diff --git a/lib/libz/deflate.c b/lib/libz/deflate.c new file mode 100644 index 0000000..5cc3f7a --- /dev/null +++ b/lib/libz/deflate.c @@ -0,0 +1,1734 @@ +/*	$OpenBSD: deflate.c,v 1.11 2009/10/27 23:59:31 deraadt Exp $	*/ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + *  ALGORITHM + * + *      The "deflation" process depends on being able to identify portions + *      of the input text which are identical to earlier input (within a + *      sliding window trailing behind the input currently being processed). + * + *      The most straightforward technique turns out to be the fastest for + *      most input files: try all possible matches and select the longest. + *      The key feature of this algorithm is that insertions into the string + *      dictionary are very simple and thus fast, and deletions are avoided + *      completely. Insertions are performed at each input character, whereas + *      string matches are performed only when the previous match ends. So it + *      is preferable to spend more time in matches to allow very fast string + *      insertions and avoid deletions. The matching algorithm for small + *      strings is inspired from that of Rabin & Karp. A brute force approach + *      is used to find longer strings when a small match has been found. + *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + *      (by Leonid Broukhis). + *         A previous version of this file used a more sophisticated algorithm + *      (by Fiala and Greene) which is guaranteed to run in linear amortized + *      time, but has a larger average cost, uses more memory and is patented. + *      However the F&G algorithm may be faster for some highly redundant + *      files if the parameter max_chain_length (described below) is too large. + * + *  ACKNOWLEDGEMENTS + * + *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + *      I found it in 'freeze' written by Leonid Broukhis. + *      Thanks to many people for bug reports and testing. + * + *  REFERENCES + * + *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + *      Available in http://www.ietf.org/rfc/rfc1951.txt + * + *      A description of the Rabin and Karp algorithm is given in the book + *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + *      Fiala,E.R., and Greene,D.H. + *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + + +#include "deflate.h" + +/* +  If you use the zlib library in a product, an acknowledgment is welcome +  in the documentation of your product. If for some reason you cannot +  include such an acknowledgment, I would appreciate that you keep this +  copyright string in the executable of your product. + */ + +/* =========================================================================== + *  Function prototypes. + */ +typedef enum { +    need_more,      /* block not completed, need more input or more output */ +    block_done,     /* block flush performed */ +    finish_started, /* finish started, need only more output at next deflate */ +    finish_done     /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window    OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast   OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow   OF((deflate_state *s, int flush)); +#endif +local void lm_init        OF((deflate_state *s)); +local void putShortMSB    OF((deflate_state *s, uInt b)); +local void flush_pending  OF((z_streamp strm)); +local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifndef FASTEST +#ifdef ASMV +      void match_init OF((void)); /* asm code initialization */ +      uInt longest_match  OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match  OF((deflate_state *s, IPos cur_match)); +#endif +#endif +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG +local  void check_match OF((deflate_state *s, IPos start, IPos match, +                            int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +#  define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { +   ush good_length; /* reduce lazy search above this match length */ +   ush max_lazy;    /* do not perform lazy search above this match length */ +   ush nice_length; /* quit search above this match length */ +   ush max_chain; +   compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/*      good lazy nice chain */ +/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */ +/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/*      good lazy nice chain */ +/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */ +/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4,    5, 16,    8, deflate_fast}, +/* 3 */ {4,    6, 32,   32, deflate_fast}, + +/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */ +/* 5 */ {8,   16, 32,   32, deflate_slow}, +/* 6 */ {8,   16, 128, 128, deflate_slow}, +/* 7 */ {8,   32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN  assertion: all calls to UPDATE_HASH are made with consecutive + *    input characters, so that a running hash key can be computed from the + *    previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN  assertion: all calls to INSERT_STRING are made with consecutive + *    input characters and the first MIN_MATCH bytes of str are valid + *    (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ +   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ +    match_head = s->head[s->ins_h], \ +    s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ +   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ +    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ +    s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ +    s->head[s->hash_size-1] = NIL; \ +    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) +    z_streamp strm; +    int level; +    const char *version; +    int stream_size; +{ +    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, +                         Z_DEFAULT_STRATEGY, version, stream_size); +    /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, +                  version, stream_size) +    z_streamp strm; +    int  level; +    int  method; +    int  windowBits; +    int  memLevel; +    int  strategy; +    const char *version; +    int stream_size; +{ +    deflate_state *s; +    int wrap = 1; +    static const char my_version[] = ZLIB_VERSION; + +    ushf *overlay; +    /* We overlay pending_buf and d_buf+l_buf. This works since the average +     * output size for (length,distance) codes is <= 24 bits. +     */ + +    if (version == Z_NULL || version[0] != my_version[0] || +        stream_size != sizeof(z_stream)) { +        return Z_VERSION_ERROR; +    } +    if (strm == Z_NULL) return Z_STREAM_ERROR; + +    strm->msg = Z_NULL; +    if (strm->zalloc == (alloc_func)0) { +        strm->zalloc = zcalloc; +        strm->opaque = (voidpf)0; +    } +    if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST +    if (level != 0) level = 1; +#else +    if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + +    if (windowBits < 0) { /* suppress zlib wrapper */ +        wrap = 0; +        windowBits = -windowBits; +    } +#ifdef GZIP +    else if (windowBits > 15) { +        wrap = 2;       /* write gzip wrapper instead */ +        windowBits -= 16; +    } +#endif +    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || +        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || +        strategy < 0 || strategy > Z_FIXED) { +        return Z_STREAM_ERROR; +    } +    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */ +    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); +    if (s == Z_NULL) return Z_MEM_ERROR; +    strm->state = (struct internal_state FAR *)s; +    s->strm = strm; + +    s->wrap = wrap; +    s->gzhead = Z_NULL; +    s->w_bits = windowBits; +    s->w_size = 1 << s->w_bits; +    s->w_mask = s->w_size - 1; + +    s->hash_bits = memLevel + 7; +    s->hash_size = 1 << s->hash_bits; +    s->hash_mask = s->hash_size - 1; +    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + +    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); +    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos)); +    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos)); + +    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + +    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); +    s->pending_buf = (uchf *) overlay; +    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + +    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || +        s->pending_buf == Z_NULL) { +        s->status = FINISH_STATE; +        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); +        deflateEnd (strm); +        return Z_MEM_ERROR; +    } +    s->d_buf = overlay + s->lit_bufsize/sizeof(ush); +    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + +    s->level = level; +    s->strategy = strategy; +    s->method = (Byte)method; + +    return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) +    z_streamp strm; +    const Bytef *dictionary; +    uInt  dictLength; +{ +    deflate_state *s; +    uInt length = dictLength; +    uInt n; +    IPos hash_head = 0; + +    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || +        strm->state->wrap == 2 || +        (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) +        return Z_STREAM_ERROR; + +    s = strm->state; +    if (s->wrap) +        strm->adler = adler32(strm->adler, dictionary, dictLength); + +    if (length < MIN_MATCH) return Z_OK; +    if (length > MAX_DIST(s)) { +        length = MAX_DIST(s); +        dictionary += dictLength - length; /* use the tail of the dictionary */ +    } +    zmemcpy(s->window, dictionary, length); +    s->strstart = length; +    s->block_start = (long)length; + +    /* Insert all strings in the hash table (except for the last two bytes). +     * s->lookahead stays null, so s->ins_h will be recomputed at the next +     * call of fill_window. +     */ +    s->ins_h = s->window[0]; +    UPDATE_HASH(s, s->ins_h, s->window[1]); +    for (n = 0; n <= length - MIN_MATCH; n++) { +        INSERT_STRING(s, n, hash_head); +    } +    if (hash_head) hash_head = 0;  /* to make compiler happy */ +    return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) +    z_streamp strm; +{ +    deflate_state *s; + +    if (strm == Z_NULL || strm->state == Z_NULL || +        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { +        return Z_STREAM_ERROR; +    } + +    strm->total_in = strm->total_out = 0; +    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ +    strm->data_type = Z_UNKNOWN; + +    s = (deflate_state *)strm->state; +    s->pending = 0; +    s->pending_out = s->pending_buf; + +    if (s->wrap < 0) { +        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ +    } +    s->status = s->wrap ? INIT_STATE : BUSY_STATE; +    strm->adler = +#ifdef GZIP +        s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif +        adler32(0L, Z_NULL, 0); +    s->last_flush = Z_NO_FLUSH; + +    _tr_init(s); +    lm_init(s); + +    return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) +    z_streamp strm; +    gz_headerp head; +{ +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; +    if (strm->state->wrap != 2) return Z_STREAM_ERROR; +    strm->state->gzhead = head; +    return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) +    z_streamp strm; +    int bits; +    int value; +{ +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; +    strm->state->bi_valid = bits; +    strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); +    return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) +    z_streamp strm; +    int level; +    int strategy; +{ +    deflate_state *s; +    compress_func func; +    int err = Z_OK; + +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; +    s = strm->state; + +#ifdef FASTEST +    if (level != 0) level = 1; +#else +    if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif +    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { +        return Z_STREAM_ERROR; +    } +    func = configuration_table[s->level].func; + +    if (func != configuration_table[level].func && strm->total_in != 0) { +        /* Flush the last buffer: */ +        err = deflate(strm, Z_PARTIAL_FLUSH); +    } +    if (s->level != level) { +        s->level = level; +        s->max_lazy_match   = configuration_table[level].max_lazy; +        s->good_match       = configuration_table[level].good_length; +        s->nice_match       = configuration_table[level].nice_length; +        s->max_chain_length = configuration_table[level].max_chain; +    } +    s->strategy = strategy; +    return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) +    z_streamp strm; +    int good_length; +    int max_lazy; +    int nice_length; +    int max_chain; +{ +    deflate_state *s; + +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; +    s = strm->state; +    s->good_match = good_length; +    s->max_lazy_match = max_lazy; +    s->nice_match = nice_length; +    s->max_chain_length = max_chain; +    return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well.  The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds + * for every combination of windowBits and memLevel, as well as wrap. + * But even the conservative upper bound of about 14% expansion does not + * seem onerous for output buffer allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) +    z_streamp strm; +    uLong sourceLen; +{ +    deflate_state *s; +    uLong destLen; + +    /* conservative upper bound */ +    destLen = sourceLen + +              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + +    /* if can't get parameters, return conservative bound */ +    if (strm == Z_NULL || strm->state == Z_NULL) +        return destLen; + +    /* if not default parameters, return conservative bound */ +    s = strm->state; +    if (s->w_bits != 15 || s->hash_bits != 8 + 7) +        return destLen; + +    /* default settings: return tight bound for that case */ +    return compressBound(sourceLen); +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) +    deflate_state *s; +    uInt b; +{ +    put_byte(s, (Byte)(b >> 8)); +    put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) +    z_streamp strm; +{ +    unsigned len = strm->state->pending; + +    if (len > strm->avail_out) len = strm->avail_out; +    if (len == 0) return; + +    zmemcpy(strm->next_out, strm->state->pending_out, len); +    strm->next_out  += len; +    strm->state->pending_out  += len; +    strm->total_out += len; +    strm->avail_out  -= len; +    strm->state->pending -= len; +    if (strm->state->pending == 0) { +        strm->state->pending_out = strm->state->pending_buf; +    } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) +    z_streamp strm; +    int flush; +{ +    int old_flush; /* value of flush param for previous deflate call */ +    deflate_state *s; + +    if (strm == Z_NULL || strm->state == Z_NULL || +        flush > Z_FINISH || flush < 0) { +        return Z_STREAM_ERROR; +    } +    s = strm->state; + +    if (strm->next_out == Z_NULL || +        (strm->next_in == Z_NULL && strm->avail_in != 0) || +        (s->status == FINISH_STATE && flush != Z_FINISH)) { +        ERR_RETURN(strm, Z_STREAM_ERROR); +    } +    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + +    s->strm = strm; /* just in case */ +    old_flush = s->last_flush; +    s->last_flush = flush; + +    /* Write the header */ +    if (s->status == INIT_STATE) { +#ifdef GZIP +        if (s->wrap == 2) { +            strm->adler = crc32(0L, Z_NULL, 0); +            put_byte(s, 31); +            put_byte(s, 139); +            put_byte(s, 8); +            if (s->gzhead == NULL) { +                put_byte(s, 0); +                put_byte(s, 0); +                put_byte(s, 0); +                put_byte(s, 0); +                put_byte(s, 0); +                put_byte(s, s->level == 9 ? 2 : +                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? +                             4 : 0)); +                put_byte(s, OS_CODE); +                s->status = BUSY_STATE; +            } +            else { +                put_byte(s, (s->gzhead->text ? 1 : 0) + +                            (s->gzhead->hcrc ? 2 : 0) + +                            (s->gzhead->extra == Z_NULL ? 0 : 4) + +                            (s->gzhead->name == Z_NULL ? 0 : 8) + +                            (s->gzhead->comment == Z_NULL ? 0 : 16) +                        ); +                put_byte(s, (Byte)(s->gzhead->time & 0xff)); +                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); +                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); +                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); +                put_byte(s, s->level == 9 ? 2 : +                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? +                             4 : 0)); +                put_byte(s, s->gzhead->os & 0xff); +                if (s->gzhead->extra != NULL) { +                    put_byte(s, s->gzhead->extra_len & 0xff); +                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); +                } +                if (s->gzhead->hcrc) +                    strm->adler = crc32(strm->adler, s->pending_buf, +                                        s->pending); +                s->gzindex = 0; +                s->status = EXTRA_STATE; +            } +        } +        else +#endif +        { +            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; +            uInt level_flags; + +            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) +                level_flags = 0; +            else if (s->level < 6) +                level_flags = 1; +            else if (s->level == 6) +                level_flags = 2; +            else +                level_flags = 3; +            header |= (level_flags << 6); +            if (s->strstart != 0) header |= PRESET_DICT; +            header += 31 - (header % 31); + +            s->status = BUSY_STATE; +            putShortMSB(s, header); + +            /* Save the adler32 of the preset dictionary: */ +            if (s->strstart != 0) { +                putShortMSB(s, (uInt)(strm->adler >> 16)); +                putShortMSB(s, (uInt)(strm->adler & 0xffff)); +            } +            strm->adler = adler32(0L, Z_NULL, 0); +        } +    } +#ifdef GZIP +    if (s->status == EXTRA_STATE) { +        if (s->gzhead->extra != NULL) { +            uInt beg = s->pending;  /* start of bytes to update crc */ + +            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { +                if (s->pending == s->pending_buf_size) { +                    if (s->gzhead->hcrc && s->pending > beg) +                        strm->adler = crc32(strm->adler, s->pending_buf + beg, +                                            s->pending - beg); +                    flush_pending(strm); +                    beg = s->pending; +                    if (s->pending == s->pending_buf_size) +                        break; +                } +                put_byte(s, s->gzhead->extra[s->gzindex]); +                s->gzindex++; +            } +            if (s->gzhead->hcrc && s->pending > beg) +                strm->adler = crc32(strm->adler, s->pending_buf + beg, +                                    s->pending - beg); +            if (s->gzindex == s->gzhead->extra_len) { +                s->gzindex = 0; +                s->status = NAME_STATE; +            } +        } +        else +            s->status = NAME_STATE; +    } +    if (s->status == NAME_STATE) { +        if (s->gzhead->name != NULL) { +            uInt beg = s->pending;  /* start of bytes to update crc */ +            int val; + +            do { +                if (s->pending == s->pending_buf_size) { +                    if (s->gzhead->hcrc && s->pending > beg) +                        strm->adler = crc32(strm->adler, s->pending_buf + beg, +                                            s->pending - beg); +                    flush_pending(strm); +                    beg = s->pending; +                    if (s->pending == s->pending_buf_size) { +                        val = 1; +                        break; +                    } +                } +                val = s->gzhead->name[s->gzindex++]; +                put_byte(s, val); +            } while (val != 0); +            if (s->gzhead->hcrc && s->pending > beg) +                strm->adler = crc32(strm->adler, s->pending_buf + beg, +                                    s->pending - beg); +            if (val == 0) { +                s->gzindex = 0; +                s->status = COMMENT_STATE; +            } +        } +        else +            s->status = COMMENT_STATE; +    } +    if (s->status == COMMENT_STATE) { +        if (s->gzhead->comment != NULL) { +            uInt beg = s->pending;  /* start of bytes to update crc */ +            int val; + +            do { +                if (s->pending == s->pending_buf_size) { +                    if (s->gzhead->hcrc && s->pending > beg) +                        strm->adler = crc32(strm->adler, s->pending_buf + beg, +                                            s->pending - beg); +                    flush_pending(strm); +                    beg = s->pending; +                    if (s->pending == s->pending_buf_size) { +                        val = 1; +                        break; +                    } +                } +                val = s->gzhead->comment[s->gzindex++]; +                put_byte(s, val); +            } while (val != 0); +            if (s->gzhead->hcrc && s->pending > beg) +                strm->adler = crc32(strm->adler, s->pending_buf + beg, +                                    s->pending - beg); +            if (val == 0) +                s->status = HCRC_STATE; +        } +        else +            s->status = HCRC_STATE; +    } +    if (s->status == HCRC_STATE) { +        if (s->gzhead->hcrc) { +            if (s->pending + 2 > s->pending_buf_size) +                flush_pending(strm); +            if (s->pending + 2 <= s->pending_buf_size) { +                put_byte(s, (Byte)(strm->adler & 0xff)); +                put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); +                strm->adler = crc32(0L, Z_NULL, 0); +                s->status = BUSY_STATE; +            } +        } +        else +            s->status = BUSY_STATE; +    } +#endif + +    /* Flush as much pending output as possible */ +    if (s->pending != 0) { +        flush_pending(strm); +        if (strm->avail_out == 0) { +            /* Since avail_out is 0, deflate will be called again with +             * more output space, but possibly with both pending and +             * avail_in equal to zero. There won't be anything to do, +             * but this is not an error situation so make sure we +             * return OK instead of BUF_ERROR at next call of deflate: +             */ +            s->last_flush = -1; +            return Z_OK; +        } + +    /* Make sure there is something to do and avoid duplicate consecutive +     * flushes. For repeated and useless calls with Z_FINISH, we keep +     * returning Z_STREAM_END instead of Z_BUF_ERROR. +     */ +    } else if (strm->avail_in == 0 && flush <= old_flush && +               flush != Z_FINISH) { +        ERR_RETURN(strm, Z_BUF_ERROR); +    } + +    /* User must not provide more input after the first FINISH: */ +    if (s->status == FINISH_STATE && strm->avail_in != 0) { +        ERR_RETURN(strm, Z_BUF_ERROR); +    } + +    /* Start a new block or continue the current one. +     */ +    if (strm->avail_in != 0 || s->lookahead != 0 || +        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { +        block_state bstate; + +        bstate = (*(configuration_table[s->level].func))(s, flush); + +        if (bstate == finish_started || bstate == finish_done) { +            s->status = FINISH_STATE; +        } +        if (bstate == need_more || bstate == finish_started) { +            if (strm->avail_out == 0) { +                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ +            } +            return Z_OK; +            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call +             * of deflate should use the same flush parameter to make sure +             * that the flush is complete. So we don't have to output an +             * empty block here, this will be done at next call. This also +             * ensures that for a very small output buffer, we emit at most +             * one empty block. +             */ +        } +        if (bstate == block_done) { +            if (flush == Z_PARTIAL_FLUSH) { +                _tr_align(s); +            } else { /* FULL_FLUSH or SYNC_FLUSH */ +                _tr_stored_block(s, (char*)0, 0L, 0); +                /* For a full flush, this empty block will be recognized +                 * as a special marker by inflate_sync(). +                 */ +                if (flush == Z_FULL_FLUSH) { +                    CLEAR_HASH(s);             /* forget history */ +                } +            } +            flush_pending(strm); +            if (strm->avail_out == 0) { +              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ +              return Z_OK; +            } +        } +    } +    Assert(strm->avail_out > 0, "bug2"); + +    if (flush != Z_FINISH) return Z_OK; +    if (s->wrap <= 0) return Z_STREAM_END; + +    /* Write the trailer */ +#ifdef GZIP +    if (s->wrap == 2) { +        put_byte(s, (Byte)(strm->adler & 0xff)); +        put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); +        put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); +        put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); +        put_byte(s, (Byte)(strm->total_in & 0xff)); +        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); +        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); +        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); +    } +    else +#endif +    { +        putShortMSB(s, (uInt)(strm->adler >> 16)); +        putShortMSB(s, (uInt)(strm->adler & 0xffff)); +    } +    flush_pending(strm); +    /* If avail_out is zero, the application will call deflate again +     * to flush the rest. +     */ +    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ +    return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) +    z_streamp strm; +{ +    int status; + +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + +    status = strm->state->status; +    if (status != INIT_STATE && +        status != EXTRA_STATE && +        status != NAME_STATE && +        status != COMMENT_STATE && +        status != HCRC_STATE && +        status != BUSY_STATE && +        status != FINISH_STATE) { +      return Z_STREAM_ERROR; +    } + +    /* Deallocate in reverse order of allocations: */ +    TRY_FREE(strm, strm->state->pending_buf); +    TRY_FREE(strm, strm->state->head); +    TRY_FREE(strm, strm->state->prev); +    TRY_FREE(strm, strm->state->window); + +    ZFREE(strm, strm->state); +    strm->state = Z_NULL; + +    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) +    z_streamp dest; +    z_streamp source; +{ +#ifdef MAXSEG_64K +    return Z_STREAM_ERROR; +#else +    deflate_state *ds; +    deflate_state *ss; +    ushf *overlay; + + +    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { +        return Z_STREAM_ERROR; +    } + +    ss = source->state; + +    zmemcpy(dest, source, sizeof(z_stream)); + +    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); +    if (ds == Z_NULL) return Z_MEM_ERROR; +    dest->state = (struct internal_state FAR *) ds; +    zmemcpy(ds, ss, sizeof(deflate_state)); +    ds->strm = dest; + +    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); +    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos)); +    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos)); +    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); +    ds->pending_buf = (uchf *) overlay; + +    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || +        ds->pending_buf == Z_NULL) { +        deflateEnd (dest); +        return Z_MEM_ERROR; +    } +    /* following zmemcpy do not work for 16-bit MSDOS */ +    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); +    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); +    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); +    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + +    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); +    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + +    ds->l_desc.dyn_tree = ds->dyn_ltree; +    ds->d_desc.dyn_tree = ds->dyn_dtree; +    ds->bl_desc.dyn_tree = ds->bl_tree; + +    return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read.  All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) +    z_streamp strm; +    Bytef *buf; +    unsigned size; +{ +    unsigned len = strm->avail_in; + +    if (len > size) len = size; +    if (len == 0) return 0; + +    strm->avail_in  -= len; + +    if (strm->state->wrap == 1) { +        strm->adler = adler32(strm->adler, strm->next_in, len); +    } +#ifdef GZIP +    else if (strm->state->wrap == 2) { +        strm->adler = crc32(strm->adler, strm->next_in, len); +    } +#endif +    zmemcpy(buf, strm->next_in, len); +    strm->next_in  += len; +    strm->total_in += len; + +    return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) +    deflate_state *s; +{ +    s->window_size = (ulg)2L*s->w_size; + +    CLEAR_HASH(s); + +    /* Set the default configuration parameters: +     */ +    s->max_lazy_match   = configuration_table[s->level].max_lazy; +    s->good_match       = configuration_table[s->level].good_length; +    s->nice_match       = configuration_table[s->level].nice_length; +    s->max_chain_length = configuration_table[s->level].max_chain; + +    s->strstart = 0; +    s->block_start = 0L; +    s->lookahead = 0; +    s->match_length = s->prev_length = MIN_MATCH-1; +    s->match_available = 0; +    s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV +    match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) +    deflate_state *s; +    IPos cur_match;                             /* current match */ +{ +    unsigned chain_length = s->max_chain_length;/* max hash chain length */ +    register Bytef *scan = s->window + s->strstart; /* current string */ +    register Bytef *match;                       /* matched string */ +    register int len;                           /* length of current match */ +    int best_len = s->prev_length;              /* best match length so far */ +    int nice_match = s->nice_match;             /* stop if match long enough */ +    IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +        s->strstart - (IPos)MAX_DIST(s) : NIL; +    /* Stop when cur_match becomes <= limit. To simplify the code, +     * we prevent matches with the string of window index 0. +     */ +    Posf *prev = s->prev; +    uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK +    /* Compare two bytes at a time. Note: this is not always beneficial. +     * Try with and without -DUNALIGNED_OK to check. +     */ +    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; +    register ush scan_start = *(ushf*)scan; +    register ush scan_end   = *(ushf*)(scan+best_len-1); +#else +    register Bytef *strend = s->window + s->strstart + MAX_MATCH; +    register Byte scan_end1  = scan[best_len-1]; +    register Byte scan_end   = scan[best_len]; +#endif + +    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. +     * It is easy to get rid of this optimization if necessary. +     */ +    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + +    /* Do not waste too much time if we already have a good match: */ +    if (s->prev_length >= s->good_match) { +        chain_length >>= 2; +    } +    /* Do not look for matches beyond the end of the input. This is necessary +     * to make deflate deterministic. +     */ +    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + +    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + +    do { +        Assert(cur_match < s->strstart, "no future"); +        match = s->window + cur_match; + +        /* Skip to next match if the match length cannot increase +         * or if the match length is less than 2.  Note that the checks below +         * for insufficient lookahead only occur occasionally for performance +         * reasons.  Therefore uninitialized memory will be accessed, and +         * conditional jumps will be made that depend on those values. +         * However the length of the match is limited to the lookahead, so +         * the output of deflate is not affected by the uninitialized values. +         */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) +        /* This code assumes sizeof(unsigned short) == 2. Do not use +         * UNALIGNED_OK if your compiler uses a different size. +         */ +        if (*(ushf*)(match+best_len-1) != scan_end || +            *(ushf*)match != scan_start) continue; + +        /* It is not necessary to compare scan[2] and match[2] since they are +         * always equal when the other bytes match, given that the hash keys +         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at +         * strstart+3, +5, ... up to strstart+257. We check for insufficient +         * lookahead only every 4th comparison; the 128th check will be made +         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is +         * necessary to put more guard bytes at the end of the window, or +         * to check more often for insufficient lookahead. +         */ +        Assert(scan[2] == match[2], "scan[2]?"); +        scan++, match++; +        do { +        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && +                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) && +                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) && +                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) && +                 scan < strend); +        /* The funny "do {}" generates better code on most compilers */ + +        /* Here, scan <= window+strstart+257 */ +        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); +        if (*scan == *match) scan++; + +        len = (MAX_MATCH - 1) - (int)(strend-scan); +        scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + +        if (match[best_len]   != scan_end  || +            match[best_len-1] != scan_end1 || +            *match            != *scan     || +            *++match          != scan[1])      continue; + +        /* The check at best_len-1 can be removed because it will be made +         * again later. (This heuristic is not always a win.) +         * It is not necessary to compare scan[2] and match[2] since they +         * are always equal when the other bytes match, given that +         * the hash keys are equal and that HASH_BITS >= 8. +         */ +        scan += 2, match++; +        Assert(*scan == *match, "match[2]?"); + +        /* We check for insufficient lookahead only every 8th comparison; +         * the 256th check will be made at strstart+258. +         */ +        do { +        } while (*++scan == *++match && *++scan == *++match && +                 *++scan == *++match && *++scan == *++match && +                 *++scan == *++match && *++scan == *++match && +                 *++scan == *++match && *++scan == *++match && +                 scan < strend); + +        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + +        len = MAX_MATCH - (int)(strend - scan); +        scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + +        if (len > best_len) { +            s->match_start = cur_match; +            best_len = len; +            if (len >= nice_match) break; +#ifdef UNALIGNED_OK +            scan_end = *(ushf*)(scan+best_len-1); +#else +            scan_end1  = scan[best_len-1]; +            scan_end   = scan[best_len]; +#endif +        } +    } while ((cur_match = prev[cur_match & wmask]) > limit +             && --chain_length != 0); + +    if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +    return s->lookahead; +} +#endif /* ASMV */ +#endif /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 or strategy == Z_RLE only + */ +local uInt longest_match_fast(s, cur_match) +    deflate_state *s; +    IPos cur_match;                             /* current match */ +{ +    register Bytef *scan = s->window + s->strstart; /* current string */ +    register Bytef *match;                       /* matched string */ +    register int len;                           /* length of current match */ +    register Bytef *strend = s->window + s->strstart + MAX_MATCH; + +    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. +     * It is easy to get rid of this optimization if necessary. +     */ +    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + +    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + +    Assert(cur_match < s->strstart, "no future"); + +    match = s->window + cur_match; + +    /* Return failure if the match length is less than 2: +     */ +    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + +    /* The check at best_len-1 can be removed because it will be made +     * again later. (This heuristic is not always a win.) +     * It is not necessary to compare scan[2] and match[2] since they +     * are always equal when the other bytes match, given that +     * the hash keys are equal and that HASH_BITS >= 8. +     */ +    scan += 2, match += 2; +    Assert(*scan == *match, "match[2]?"); + +    /* We check for insufficient lookahead only every 8th comparison; +     * the 256th check will be made at strstart+258. +     */ +    do { +    } while (*++scan == *++match && *++scan == *++match && +             *++scan == *++match && *++scan == *++match && +             *++scan == *++match && *++scan == *++match && +             *++scan == *++match && *++scan == *++match && +             scan < strend); + +    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + +    len = MAX_MATCH - (int)(strend - scan); + +    if (len < MIN_MATCH) return MIN_MATCH - 1; + +    s->match_start = cur_match; +    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) +    deflate_state *s; +    IPos start, match; +    int length; +{ +    /* check that the match is indeed a match */ +    if (zmemcmp(s->window + match, +                s->window + start, length) != EQUAL) { +        fprintf(stderr, " start %u, match %u, length %d\n", +                start, match, length); +        do { +            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); +        } while (--length != 0); +        z_error("invalid match"); +    } +    if (z_verbose > 1) { +        fprintf(stderr,"\\[%d,%d]", start-match, length); +        do { putc(s->window[start++], stderr); } while (--length != 0); +    } +} +#else +#  define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + *    At least one byte has been read, or avail_in == 0; reads are + *    performed for at least two bytes (required for the zip translate_eol + *    option -- not supported here). + */ +local void fill_window(s) +    deflate_state *s; +{ +    register unsigned n, m; +    register Posf *p; +    unsigned more;    /* Amount of free space at the end of the window. */ +    uInt wsize = s->w_size; + +    do { +        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + +        /* Deal with !@#$% 64K limit: */ +        if (sizeof(int) <= 2) { +            if (more == 0 && s->strstart == 0 && s->lookahead == 0) { +                more = wsize; + +            } else if (more == (unsigned)(-1)) { +                /* Very unlikely, but possible on 16 bit machine if +                 * strstart == 0 && lookahead == 1 (input done a byte at time) +                 */ +                more--; +            } +        } + +        /* If the window is almost full and there is insufficient lookahead, +         * move the upper half to the lower one to make room in the upper half. +         */ +        if (s->strstart >= wsize+MAX_DIST(s)) { + +            zmemcpy(s->window, s->window+wsize, (unsigned)wsize); +            s->match_start -= wsize; +            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */ +            s->block_start -= (long) wsize; + +            /* Slide the hash table (could be avoided with 32 bit values +               at the expense of memory usage). We slide even when level == 0 +               to keep the hash table consistent if we switch back to level > 0 +               later. (Using level 0 permanently is not an optimal usage of +               zlib, so we don't care about this pathological case.) +             */ +            /* %%% avoid this when Z_RLE */ +            n = s->hash_size; +            p = &s->head[n]; +            do { +                m = *--p; +                *p = (Pos)(m >= wsize ? m-wsize : NIL); +            } while (--n); + +            n = wsize; +#ifndef FASTEST +            p = &s->prev[n]; +            do { +                m = *--p; +                *p = (Pos)(m >= wsize ? m-wsize : NIL); +                /* If n is not on any hash chain, prev[n] is garbage but +                 * its value will never be used. +                 */ +            } while (--n); +#endif +            more += wsize; +        } +        if (s->strm->avail_in == 0) return; + +        /* If there was no sliding: +         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && +         *    more == window_size - lookahead - strstart +         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) +         * => more >= window_size - 2*WSIZE + 2 +         * In the BIG_MEM or MMAP case (not yet supported), +         *   window_size == input_size + MIN_LOOKAHEAD  && +         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. +         * Otherwise, window_size == 2*WSIZE so more >= 2. +         * If there was sliding, more >= WSIZE. So in all cases, more >= 2. +         */ +        Assert(more >= 2, "more < 2"); + +        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); +        s->lookahead += n; + +        /* Initialize the hash value now that we have some input: */ +        if (s->lookahead >= MIN_MATCH) { +            s->ins_h = s->window[s->strstart]; +            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 +            Call UPDATE_HASH() MIN_MATCH-3 more times +#endif +        } +        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, +         * but this is not important since only literal bytes will be emitted. +         */ + +    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ +   _tr_flush_block(s, (s->block_start >= 0L ? \ +                   (charf *)&s->window[(unsigned)s->block_start] : \ +                   (charf *)Z_NULL), \ +                (ulg)((long)s->strstart - s->block_start), \ +                (eof)); \ +   s->block_start = s->strstart; \ +   flush_pending(s->strm); \ +   Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ +   FLUSH_BLOCK_ONLY(s, eof); \ +   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) +    deflate_state *s; +    int flush; +{ +    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited +     * to pending_buf_size, and each stored block has a 5 byte header: +     */ +    ulg max_block_size = 0xffff; +    ulg max_start; + +    if (max_block_size > s->pending_buf_size - 5) { +        max_block_size = s->pending_buf_size - 5; +    } + +    /* Copy as much as possible from input to output: */ +    for (;;) { +        /* Fill the window as much as possible: */ +        if (s->lookahead <= 1) { + +            Assert(s->strstart < s->w_size+MAX_DIST(s) || +                   s->block_start >= (long)s->w_size, "slide too late"); + +            fill_window(s); +            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + +            if (s->lookahead == 0) break; /* flush the current block */ +        } +        Assert(s->block_start >= 0L, "block gone"); + +        s->strstart += s->lookahead; +        s->lookahead = 0; + +        /* Emit a stored block if pending_buf will be full: */ +        max_start = s->block_start + max_block_size; +        if (s->strstart == 0 || (ulg)s->strstart >= max_start) { +            /* strstart == 0 is possible when wraparound on 16-bit machine */ +            s->lookahead = (uInt)(s->strstart - max_start); +            s->strstart = (uInt)max_start; +            FLUSH_BLOCK(s, 0); +        } +        /* Flush if we may have to slide, otherwise block_start may become +         * negative and the data will be gone: +         */ +        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { +            FLUSH_BLOCK(s, 0); +        } +    } +    FLUSH_BLOCK(s, flush == Z_FINISH); +    return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) +    deflate_state *s; +    int flush; +{ +    IPos hash_head = NIL; /* head of the hash chain */ +    int bflush;           /* set if current block must be flushed */ + +    for (;;) { +        /* Make sure that we always have enough lookahead, except +         * at the end of the input file. We need MAX_MATCH bytes +         * for the next match, plus MIN_MATCH bytes to insert the +         * string following the next match. +         */ +        if (s->lookahead < MIN_LOOKAHEAD) { +            fill_window(s); +            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { +                return need_more; +            } +            if (s->lookahead == 0) break; /* flush the current block */ +        } + +        /* Insert the string window[strstart .. strstart+2] in the +         * dictionary, and set hash_head to the head of the hash chain: +         */ +        if (s->lookahead >= MIN_MATCH) { +            INSERT_STRING(s, s->strstart, hash_head); +        } + +        /* Find the longest match, discarding those <= prev_length. +         * At this point we have always match_length < MIN_MATCH +         */ +        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { +            /* To simplify the code, we prevent matches with the string +             * of window index 0 (in particular we have to avoid a match +             * of the string with itself at the start of the input file). +             */ +#ifdef FASTEST +            if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || +                (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { +                s->match_length = longest_match_fast (s, hash_head); +            } +#else +            if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { +                s->match_length = longest_match (s, hash_head); +            } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { +                s->match_length = longest_match_fast (s, hash_head); +            } +#endif +            /* longest_match() or longest_match_fast() sets match_start */ +        } +        if (s->match_length >= MIN_MATCH) { +            check_match(s, s->strstart, s->match_start, s->match_length); + +            _tr_tally_dist(s, s->strstart - s->match_start, +                           s->match_length - MIN_MATCH, bflush); + +            s->lookahead -= s->match_length; + +            /* Insert new strings in the hash table only if the match length +             * is not too large. This saves time but degrades compression. +             */ +#ifndef FASTEST +            if (s->match_length <= s->max_insert_length && +                s->lookahead >= MIN_MATCH) { +                s->match_length--; /* string at strstart already in table */ +                do { +                    s->strstart++; +                    INSERT_STRING(s, s->strstart, hash_head); +                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are +                     * always MIN_MATCH bytes ahead. +                     */ +                } while (--s->match_length != 0); +                s->strstart++; +            } else +#endif +            { +                s->strstart += s->match_length; +                s->match_length = 0; +                s->ins_h = s->window[s->strstart]; +                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 +                Call UPDATE_HASH() MIN_MATCH-3 more times +#endif +                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not +                 * matter since it will be recomputed at next deflate call. +                 */ +            } +        } else { +            /* No match, output a literal byte */ +            Tracevv((stderr,"%c", s->window[s->strstart])); +            _tr_tally_lit (s, s->window[s->strstart], bflush); +            s->lookahead--; +            s->strstart++; +        } +        if (bflush) FLUSH_BLOCK(s, 0); +    } +    FLUSH_BLOCK(s, flush == Z_FINISH); +    return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) +    deflate_state *s; +    int flush; +{ +    IPos hash_head = NIL;    /* head of hash chain */ +    int bflush;              /* set if current block must be flushed */ + +    /* Process the input block. */ +    for (;;) { +        /* Make sure that we always have enough lookahead, except +         * at the end of the input file. We need MAX_MATCH bytes +         * for the next match, plus MIN_MATCH bytes to insert the +         * string following the next match. +         */ +        if (s->lookahead < MIN_LOOKAHEAD) { +            fill_window(s); +            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { +                return need_more; +            } +            if (s->lookahead == 0) break; /* flush the current block */ +        } + +        /* Insert the string window[strstart .. strstart+2] in the +         * dictionary, and set hash_head to the head of the hash chain: +         */ +        if (s->lookahead >= MIN_MATCH) { +            INSERT_STRING(s, s->strstart, hash_head); +        } + +        /* Find the longest match, discarding those <= prev_length. +         */ +        s->prev_length = s->match_length, s->prev_match = s->match_start; +        s->match_length = MIN_MATCH-1; + +        if (hash_head != NIL && s->prev_length < s->max_lazy_match && +            s->strstart - hash_head <= MAX_DIST(s)) { +            /* To simplify the code, we prevent matches with the string +             * of window index 0 (in particular we have to avoid a match +             * of the string with itself at the start of the input file). +             */ +            if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { +                s->match_length = longest_match (s, hash_head); +            } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { +                s->match_length = longest_match_fast (s, hash_head); +            } +            /* longest_match() or longest_match_fast() sets match_start */ + +            if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 +                || (s->match_length == MIN_MATCH && +                    s->strstart - s->match_start > TOO_FAR) +#endif +                )) { + +                /* If prev_match is also MIN_MATCH, match_start is garbage +                 * but we will ignore the current match anyway. +                 */ +                s->match_length = MIN_MATCH-1; +            } +        } +        /* If there was a match at the previous step and the current +         * match is not better, output the previous match: +         */ +        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { +            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; +            /* Do not insert strings in hash table beyond this. */ + +            check_match(s, s->strstart-1, s->prev_match, s->prev_length); + +            _tr_tally_dist(s, s->strstart -1 - s->prev_match, +                           s->prev_length - MIN_MATCH, bflush); + +            /* Insert in hash table all strings up to the end of the match. +             * strstart-1 and strstart are already inserted. If there is not +             * enough lookahead, the last two strings are not inserted in +             * the hash table. +             */ +            s->lookahead -= s->prev_length-1; +            s->prev_length -= 2; +            do { +                if (++s->strstart <= max_insert) { +                    INSERT_STRING(s, s->strstart, hash_head); +                } +            } while (--s->prev_length != 0); +            s->match_available = 0; +            s->match_length = MIN_MATCH-1; +            s->strstart++; + +            if (bflush) FLUSH_BLOCK(s, 0); + +        } else if (s->match_available) { +            /* If there was no match at the previous position, output a +             * single literal. If there was a match but the current match +             * is longer, truncate the previous match to a single literal. +             */ +            Tracevv((stderr,"%c", s->window[s->strstart-1])); +            _tr_tally_lit(s, s->window[s->strstart-1], bflush); +            if (bflush) { +                FLUSH_BLOCK_ONLY(s, 0); +            } +            s->strstart++; +            s->lookahead--; +            if (s->strm->avail_out == 0) return need_more; +        } else { +            /* There is no previous match to compare with, wait for +             * the next step to decide. +             */ +            s->match_available = 1; +            s->strstart++; +            s->lookahead--; +        } +    } +    Assert (flush != Z_NO_FLUSH, "no flush?"); +    if (s->match_available) { +        Tracevv((stderr,"%c", s->window[s->strstart-1])); +        _tr_tally_lit(s, s->window[s->strstart-1], bflush); +        s->match_available = 0; +    } +    FLUSH_BLOCK(s, flush == Z_FINISH); +    return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +#if 0 +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one.  Do not maintain a hash table.  (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) +    deflate_state *s; +    int flush; +{ +    int bflush;         /* set if current block must be flushed */ +    uInt run;           /* length of run */ +    uInt max;           /* maximum length of run */ +    uInt prev;          /* byte at distance one to match */ +    Bytef *scan;        /* scan for end of run */ + +    for (;;) { +        /* Make sure that we always have enough lookahead, except +         * at the end of the input file. We need MAX_MATCH bytes +         * for the longest encodable run. +         */ +        if (s->lookahead < MAX_MATCH) { +            fill_window(s); +            if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { +                return need_more; +            } +            if (s->lookahead == 0) break; /* flush the current block */ +        } + +        /* See how many times the previous byte repeats */ +        run = 0; +        if (s->strstart > 0) {      /* if there is a previous byte, that is */ +            max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; +            scan = s->window + s->strstart - 1; +            prev = *scan++; +            do { +                if (*scan++ != prev) +                    break; +            } while (++run < max); +        } + +        /* Emit match if have run of MIN_MATCH or longer, else emit literal */ +        if (run >= MIN_MATCH) { +            check_match(s, s->strstart, s->strstart - 1, run); +            _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); +            s->lookahead -= run; +            s->strstart += run; +        } else { +            /* No match, output a literal byte */ +            Tracevv((stderr,"%c", s->window[s->strstart])); +            _tr_tally_lit (s, s->window[s->strstart], bflush); +            s->lookahead--; +            s->strstart++; +        } +        if (bflush) FLUSH_BLOCK(s, 0); +    } +    FLUSH_BLOCK(s, flush == Z_FINISH); +    return flush == Z_FINISH ? finish_done : block_done; +} +#endif diff --git a/lib/libz/deflate.h b/lib/libz/deflate.h new file mode 100644 index 0000000..8d2a878 --- /dev/null +++ b/lib/libz/deflate.h @@ -0,0 +1,331 @@ +/*	$OpenBSD: deflate.h,v 1.8 2007/11/26 09:28:33 martynas Exp $	*/ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2004 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and +   trailer creation by deflate().  NO_GZIP would be used to avoid linking in +   the crc code when it is not needed.  For shared libraries, gzip encoding +   should be left enabled. */ +#ifndef NO_GZIP +#  define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS  256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES   30 +/* number of distance codes */ + +#define BL_CODES  19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE    42 +#define EXTRA_STATE   69 +#define NAME_STATE    73 +#define COMMENT_STATE 91 +#define HCRC_STATE   103 +#define BUSY_STATE   113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { +    union { +        ush  freq;       /* frequency count */ +        ush  code;       /* bit string */ +    } fc; +    union { +        ush  dad;        /* father node in Huffman tree */ +        ush  len;        /* length of bit string */ +    } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad  dl.dad +#define Len  dl.len + +typedef struct static_tree_desc_s  static_tree_desc; + +typedef struct tree_desc_s { +    ct_data *dyn_tree;           /* the dynamic tree */ +    int     max_code;            /* largest code with non zero frequency */ +    static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { +    z_streamp strm;      /* pointer back to this zlib stream */ +    int   status;        /* as the name implies */ +    Bytef *pending_buf;  /* output still pending */ +    ulg   pending_buf_size; /* size of pending_buf */ +    Bytef *pending_out;  /* next pending byte to output to the stream */ +    uInt   pending;      /* nb of bytes in the pending buffer */ +    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */ +    gz_headerp  gzhead;  /* gzip header information to write */ +    uInt   gzindex;      /* where in extra, name, or comment */ +    Byte  method;        /* STORED (for zip only) or DEFLATED */ +    int   last_flush;    /* value of flush param for previous deflate call */ + +                /* used by deflate.c: */ + +    uInt  w_size;        /* LZ77 window size (32K by default) */ +    uInt  w_bits;        /* log2(w_size)  (8..16) */ +    uInt  w_mask;        /* w_size - 1 */ + +    Bytef *window; +    /* Sliding window. Input bytes are read into the second half of the window, +     * and move to the first half later to keep a dictionary of at least wSize +     * bytes. With this organization, matches are limited to a distance of +     * wSize-MAX_MATCH bytes, but this ensures that IO is always +     * performed with a length multiple of the block size. Also, it limits +     * the window size to 64K, which is quite useful on MSDOS. +     * To do: use the user input buffer as sliding window. +     */ + +    ulg window_size; +    /* Actual size of window: 2*wSize, except when the user input buffer +     * is directly used as sliding window. +     */ + +    Posf *prev; +    /* Link to older string with same hash index. To limit the size of this +     * array to 64K, this link is maintained only for the last 32K strings. +     * An index in this array is thus a window index modulo 32K. +     */ + +    Posf *head; /* Heads of the hash chains or NIL. */ + +    uInt  ins_h;          /* hash index of string to be inserted */ +    uInt  hash_size;      /* number of elements in hash table */ +    uInt  hash_bits;      /* log2(hash_size) */ +    uInt  hash_mask;      /* hash_size-1 */ + +    uInt  hash_shift; +    /* Number of bits by which ins_h must be shifted at each input +     * step. It must be such that after MIN_MATCH steps, the oldest +     * byte no longer takes part in the hash key, that is: +     *   hash_shift * MIN_MATCH >= hash_bits +     */ + +    long block_start; +    /* Window position at the beginning of the current output block. Gets +     * negative when the window is moved backwards. +     */ + +    uInt match_length;           /* length of best match */ +    IPos prev_match;             /* previous match */ +    int match_available;         /* set if previous match exists */ +    uInt strstart;               /* start of string to insert */ +    uInt match_start;            /* start of matching string */ +    uInt lookahead;              /* number of valid bytes ahead in window */ + +    uInt prev_length; +    /* Length of the best match at previous step. Matches not greater than this +     * are discarded. This is used in the lazy match evaluation. +     */ + +    uInt max_chain_length; +    /* To speed up deflation, hash chains are never searched beyond this +     * length.  A higher limit improves compression ratio but degrades the +     * speed. +     */ + +    uInt max_lazy_match; +    /* Attempt to find a better match only when the current match is strictly +     * smaller than this value. This mechanism is used only for compression +     * levels >= 4. +     */ +#   define max_insert_length  max_lazy_match +    /* Insert new strings in the hash table only if the match length is not +     * greater than this length. This saves time but degrades compression. +     * max_insert_length is used only for compression levels <= 3. +     */ + +    int level;    /* compression level (1..9) */ +    int strategy; /* favor or force Huffman coding*/ + +    uInt good_match; +    /* Use a faster search when the previous match is longer than this */ + +    int nice_match; /* Stop searching when current match exceeds this */ + +                /* used by trees.c: */ +    /* Didn't use ct_data typedef below to suppress compiler warning */ +    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */ +    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ +    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */ + +    struct tree_desc_s l_desc;               /* desc. for literal tree */ +    struct tree_desc_s d_desc;               /* desc. for distance tree */ +    struct tree_desc_s bl_desc;              /* desc. for bit length tree */ + +    ush bl_count[MAX_BITS+1]; +    /* number of codes at each bit length for an optimal tree */ + +    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */ +    int heap_len;               /* number of elements in the heap */ +    int heap_max;               /* element of largest frequency */ +    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. +     * The same heap array is used to build all trees. +     */ + +    uch depth[2*L_CODES+1]; +    /* Depth of each subtree used as tie breaker for trees of equal frequency +     */ + +    uchf *l_buf;          /* buffer for literals or lengths */ + +    uInt  lit_bufsize; +    /* Size of match buffer for literals/lengths.  There are 4 reasons for +     * limiting lit_bufsize to 64K: +     *   - frequencies can be kept in 16 bit counters +     *   - if compression is not successful for the first block, all input +     *     data is still in the window so we can still emit a stored block even +     *     when input comes from standard input.  (This can also be done for +     *     all blocks if lit_bufsize is not greater than 32K.) +     *   - if compression is not successful for a file smaller than 64K, we can +     *     even emit a stored file instead of a stored block (saving 5 bytes). +     *     This is applicable only for zip (not gzip or zlib). +     *   - creating new Huffman trees less frequently may not provide fast +     *     adaptation to changes in the input data statistics. (Take for +     *     example a binary file with poorly compressible code followed by +     *     a highly compressible string table.) Smaller buffer sizes give +     *     fast adaptation but have of course the overhead of transmitting +     *     trees more frequently. +     *   - I can't count above 4 +     */ + +    uInt last_lit;      /* running index in l_buf */ + +    ushf *d_buf; +    /* Buffer for distances. To simplify the code, d_buf and l_buf have +     * the same number of elements. To use different lengths, an extra flag +     * array would be necessary. +     */ + +    ulg opt_len;        /* bit length of current block with optimal trees */ +    ulg static_len;     /* bit length of current block with static trees */ +    uInt matches;       /* number of string matches in current block */ +    int last_eob_len;   /* bit length of EOB code for last block */ + +#ifdef DEBUG +    ulg compressed_len; /* total bit length of compressed file mod 2^32 */ +    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */ +#endif + +    ush bi_buf; +    /* Output buffer. bits are inserted starting at the bottom (least +     * significant bits). +     */ +    int bi_valid; +    /* Number of valid bits in bi_buf.  All bits above the last valid bit +     * are always zero. +     */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +        /* in trees.c */ +void _tr_init         OF((deflate_state *s)); +int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len, +                          int eof)); +void _tr_align        OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, +                          int eof)); + +#define d_code(dist) \ +   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) +  extern uch _length_code[]; +  extern uch _dist_code[]; +#else +  extern const uch _length_code[]; +  extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ +  { uch cc = (c); \ +    s->d_buf[s->last_lit] = 0; \ +    s->l_buf[s->last_lit++] = cc; \ +    s->dyn_ltree[cc].Freq++; \ +    flush = (s->last_lit == s->lit_bufsize-1); \ +   } +# define _tr_tally_dist(s, distance, length, flush) \ +  { uch len = (length); \ +    ush dist = (distance); \ +    s->d_buf[s->last_lit] = dist; \ +    s->l_buf[s->last_lit++] = len; \ +    dist--; \ +    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ +    s->dyn_dtree[d_code(dist)].Freq++; \ +    flush = (s->last_lit == s->lit_bufsize-1); \ +  } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ +              flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/lib/libz/generate_pkgconfig.sh b/lib/libz/generate_pkgconfig.sh new file mode 100644 index 0000000..5d75d1c --- /dev/null +++ b/lib/libz/generate_pkgconfig.sh @@ -0,0 +1,70 @@ +#!/bin/sh +# +# $OpenBSD: generate_pkgconfig.sh,v 1.2 2011/05/05 20:58:15 jasper Exp $ +# +# Copyright (c) 2010,2011 Jasper Lievisse Adriaanse <jasper@openbsd.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# Generate pkg-config file for zlib. + +usage() { +	echo "usage: ${0##*/} -c current_directory -o obj_directory" +	exit 1 +} + +curdir= +objdir= +while getopts "c:o:" flag; do +	case "$flag" in +		c) +			curdir=$OPTARG +			;; +		o) +			objdir=$OPTARG +			;; +		*) +			usage +			;; +	esac +done + +[ -n "${curdir}" ] || usage +if [ ! -d "${curdir}" ]; then +	echo "${0##*/}: ${curdir}: not found" +	exit 1 +fi +[ -n "${objdir}" ] || usage +if [ ! -w "${objdir}" ]; then +	echo "${0##*/}: ${objdir}: not found or not writable" +	exit 1 +fi + +version_re="s/^#define[[:blank:]]+ZLIB_VERSION[[:blank:]]+\"(.*)\".*/\1/p" +version_file=${curdir}/zlib.h +lib_version=$(sed -nE ${version_re} ${version_file}) + +pc_file="${objdir}/zlib.pc" +cat > ${pc_file} << __EOF__ +prefix=/usr +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: zlib +Description: zlib compression library +Version: ${lib_version} +Requires:  +Libs: -L\${libdir} -lz +Cflags: -I\${includedir} +__EOF__ diff --git a/lib/libz/gzio.c b/lib/libz/gzio.c new file mode 100644 index 0000000..ab77ad9 --- /dev/null +++ b/lib/libz/gzio.c @@ -0,0 +1,1003 @@ +/*	$OpenBSD: gzio.c,v 1.15 2020/04/18 17:11:37 schwarze Exp $	*/ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. + */ + + +#include <stdio.h> + +#include "zutil.h" + +#ifdef NO_DEFLATE       /* for compatibility with old definition */ +#  define NO_GZCOMPRESS +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +#ifndef Z_BUFSIZE +#  ifdef MAXSEG_64K +#    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +#  else +#    define Z_BUFSIZE 16384 +#  endif +#endif +#ifndef Z_PRINTF_BUFSIZE +#  define Z_PRINTF_BUFSIZE 4096 +#endif + +#ifdef __MVS__ +#  pragma map (fdopen , "\174\174FDOPEN") +   FILE *fdopen(int, const char *); +#endif + +#ifndef STDC +extern voidp  malloc OF((uInt size)); +extern void   free   OF((voidpf ptr)); +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME    0x08 /* bit 3 set: original file name present */ +#define COMMENT      0x10 /* bit 4 set: file comment present */ +#define RESERVED     0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { +    z_stream stream; +    int      z_err;   /* error code for last stream operation */ +    int      z_eof;   /* set if end of input file */ +    FILE     *file;   /* .gz file */ +    Byte     *inbuf;  /* input buffer */ +    Byte     *outbuf; /* output buffer */ +    uLong    crc;     /* crc32 of uncompressed data */ +    char     *msg;    /* error message */ +    char     *path;   /* path name for debugging only */ +    int      transparent; /* 1 if input file is not a .gz file */ +    char     mode;    /* 'w' or 'r' */ +    z_off_t  start;   /* start of compressed data in file (header skipped) */ +    z_off_t  in;      /* bytes into deflate or inflate */ +    z_off_t  out;     /* bytes out of deflate or inflate */ +    int      back;    /* one character push-back */ +    int      last;    /* true if push-back is last character */ +} gz_stream; + + +local gzFile gz_open      OF((const char *path, const char *mode, int  fd)); +local int do_flush        OF((gzFile file, int flush)); +local int    get_byte     OF((gz_stream *s)); +local void   check_header OF((gz_stream *s)); +local int    destroy      OF((gz_stream *s)); +local void   putLong      OF((FILE *file, uLong x)); +local uLong  getLong      OF((gz_stream *s)); + +/* =========================================================================== +     Opens a gzip (.gz) file for reading or writing. The mode parameter +   is as in fopen ("rb" or "wb"). The file is given either by file descriptor +   or path name (if fd == -1). +     gz_open returns NULL if the file could not be opened or if there was +   insufficient memory to allocate the (de)compression state; errno +   can be checked to distinguish the two cases (if errno is zero, the +   zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) +    const char *path; +    const char *mode; +    int  fd; +{ +    int err; +    int level = Z_DEFAULT_COMPRESSION; /* compression level */ +    int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ +    char *p = (char*)mode; +    gz_stream *s; +    char fmode[80]; /* copy of mode, without the compression level */ +    char *m = fmode; +    size_t len; + +    if (!path || !mode) return Z_NULL; + +    s = (gz_stream *)ALLOC(sizeof(gz_stream)); +    if (!s) return Z_NULL; + +    s->stream.zalloc = (alloc_func)0; +    s->stream.zfree = (free_func)0; +    s->stream.opaque = (voidpf)0; +    s->stream.next_in = s->inbuf = Z_NULL; +    s->stream.next_out = s->outbuf = Z_NULL; +    s->stream.avail_in = s->stream.avail_out = 0; +    s->file = NULL; +    s->z_err = Z_OK; +    s->z_eof = 0; +    s->in = 0; +    s->out = 0; +    s->back = EOF; +    s->crc = crc32(0L, Z_NULL, 0); +    s->msg = NULL; +    s->transparent = 0; + +    len = strlen(path)+1; +    s->path = (char*)ALLOC(len); +    if (s->path == NULL) { +        return destroy(s), (gzFile)Z_NULL; +    } +    strlcpy(s->path, path, len); /* do this early for debugging */ + +    s->mode = '\0'; +    do { +        if (*p == 'r') s->mode = 'r'; +        if (*p == 'w' || *p == 'a') s->mode = 'w'; +        if (*p >= '0' && *p <= '9') { +            level = *p - '0'; +        } else if (*p == 'f') { +          strategy = Z_FILTERED; +        } else if (*p == 'h') { +          strategy = Z_HUFFMAN_ONLY; +        } else if (*p == 'R') { +          strategy = Z_RLE; +        } else { +            *m++ = *p; /* copy the mode */ +        } +    } while (*p++ && m != fmode + sizeof(fmode)); +    if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + +    if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS +        err = Z_STREAM_ERROR; +#else +        err = deflateInit2(&(s->stream), level, +                           Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); +        /* windowBits is passed < 0 to suppress zlib header */ + +        s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif +        if (err != Z_OK || s->outbuf == Z_NULL) { +            return destroy(s), (gzFile)Z_NULL; +        } +    } else { +        s->stream.next_in  = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + +        err = inflateInit2(&(s->stream), -MAX_WBITS); +        /* windowBits is passed < 0 to tell that there is no zlib header. +         * Note that in this case inflate *requires* an extra "dummy" byte +         * after the compressed stream in order to complete decompression and +         * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are +         * present after the compressed stream. +         */ +        if (err != Z_OK || s->inbuf == Z_NULL) { +            return destroy(s), (gzFile)Z_NULL; +        } +    } +    s->stream.avail_out = Z_BUFSIZE; + +    errno = 0; +    s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + +    if (s->file == NULL) { +        return destroy(s), (gzFile)Z_NULL; +    } +    if (s->mode == 'w') { +        /* Write a very simple .gz header: +         */ +        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], +             Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); +        s->start = 10L; +        /* We use 10L instead of ftell(s->file) to because ftell causes an +         * fflush on some systems. This version of the library doesn't use +         * start anyway in write mode, so this initialization is not +         * necessary. +         */ +    } else { +        check_header(s); /* skip the .gz header */ +        s->start = ftell(s->file) - s->stream.avail_in; +    } + +    return (gzFile)s; +} + +/* =========================================================================== +     Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) +    const char *path; +    const char *mode; +{ +    return gz_open (path, mode, -1); +} + +/* =========================================================================== +     Associate a gzFile with the file descriptor fd. fd is not dup'ed here +   to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) +    int fd; +    const char *mode; +{ +    char name[46];      /* allow for up to 128-bit integers */ + +    if (fd < 0) return (gzFile)Z_NULL; +    snprintf(name, sizeof name, "<fd:%d>", fd); /* for debugging */ + +    return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) +    gzFile file; +    int level; +    int strategy; +{ +    gz_stream *s = (gz_stream*)file; + +    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + +    /* Make room to allow flushing */ +    if (s->stream.avail_out == 0) { + +        s->stream.next_out = s->outbuf; +        if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { +            s->z_err = Z_ERRNO; +        } +        s->stream.avail_out = Z_BUFSIZE; +    } + +    return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== +     Read a byte from a gz_stream; update next_in and avail_in. Return EOF +   for end of file. +   IN assertion: the stream s has been successfully opened for reading. +*/ +local int get_byte(s) +    gz_stream *s; +{ +    if (s->z_eof) return EOF; +    if (s->stream.avail_in == 0) { +        errno = 0; +        s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); +        if (s->stream.avail_in == 0) { +            s->z_eof = 1; +            if (ferror(s->file)) s->z_err = Z_ERRNO; +            return EOF; +        } +        s->stream.next_in = s->inbuf; +    } +    s->stream.avail_in--; +    return *(s->stream.next_in)++; +} + +/* =========================================================================== +      Check the gzip header of a gz_stream opened for reading. Set the stream +    mode to transparent if the gzip magic header is not present; set s->err +    to Z_DATA_ERROR if the magic header is present but the rest of the header +    is incorrect. +    IN assertion: the stream s has already been created successfully; +       s->stream.avail_in is zero for the first time, but may be non-zero +       for concatenated .gz files. +*/ +local void check_header(s) +    gz_stream *s; +{ +    int method; /* method byte */ +    int flags;  /* flags byte */ +    uInt len; +    int c; + +    /* Assure two bytes in the buffer so we can peek ahead -- handle case +       where first byte of header is at the end of the buffer after the last +       gzip segment */ +    len = s->stream.avail_in; +    if (len < 2) { +        if (len) s->inbuf[0] = s->stream.next_in[0]; +        errno = 0; +        len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); +        if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; +        s->stream.avail_in += len; +        s->stream.next_in = s->inbuf; +        if (s->stream.avail_in < 2) { +            s->transparent = 1; +            return; +        } +    } + +    /* Peek ahead to check the gzip magic header */ +    if (s->stream.next_in[0] != gz_magic[0] || +        s->stream.next_in[1] != gz_magic[1]) { +        s->transparent = 1; +        return; +    } +    s->stream.avail_in -= 2; +    s->stream.next_in += 2; + +    /* Check the rest of the gzip header */ +    method = get_byte(s); +    flags = get_byte(s); +    if (method != Z_DEFLATED || (flags & RESERVED) != 0) { +        s->z_err = Z_DATA_ERROR; +        return; +    } + +    /* Discard time, xflags and OS code: */ +    for (len = 0; len < 6; len++) (void)get_byte(s); + +    if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ +        len  =  (uInt)get_byte(s); +        len += ((uInt)get_byte(s))<<8; +        /* len is garbage if EOF but the loop below will quit anyway */ +        while (len-- != 0 && get_byte(s) != EOF) ; +    } +    if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ +        while ((c = get_byte(s)) != 0 && c != EOF) ; +    } +    if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */ +        while ((c = get_byte(s)) != 0 && c != EOF) ; +    } +    if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */ +        for (len = 0; len < 2; len++) (void)get_byte(s); +    } +    s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. +   Try freeing in the reverse order of allocations. + */ +local int destroy (s) +    gz_stream *s; +{ +    int err = Z_OK; + +    if (!s) return Z_STREAM_ERROR; + +    TRYFREE(s->msg); + +    if (s->stream.state != NULL) { +        if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS +            err = Z_STREAM_ERROR; +#else +            err = deflateEnd(&(s->stream)); +#endif +        } else if (s->mode == 'r') { +            err = inflateEnd(&(s->stream)); +        } +    } +    if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE +        if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif +            err = Z_ERRNO; +    } +    if (s->z_err < 0) err = s->z_err; + +    TRYFREE(s->inbuf); +    TRYFREE(s->outbuf); +    TRYFREE(s->path); +    TRYFREE(s); +    return err; +} + +/* =========================================================================== +     Reads the given number of uncompressed bytes from the compressed file. +   gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) +    gzFile file; +    voidp buf; +    unsigned len; +{ +    gz_stream *s = (gz_stream*)file; +    Bytef *start = (Bytef*)buf; /* starting point for crc computation */ +    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + +    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + +    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; +    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */ + +    next_out = (Byte*)buf; +    s->stream.next_out = (Bytef*)buf; +    s->stream.avail_out = len; + +    if (s->stream.avail_out && s->back != EOF) { +        *next_out++ = s->back; +        s->stream.next_out++; +        s->stream.avail_out--; +        s->back = EOF; +        s->out++; +        start++; +        if (s->last) { +            s->z_err = Z_STREAM_END; +            return 1; +        } +    } + +    while (s->stream.avail_out != 0) { + +        if (s->transparent) { +            /* Copy first the lookahead bytes: */ +            uInt n = s->stream.avail_in; +            if (n > s->stream.avail_out) n = s->stream.avail_out; +            if (n > 0) { +                zmemcpy(s->stream.next_out, s->stream.next_in, n); +                next_out += n; +                s->stream.next_out = next_out; +                s->stream.next_in   += n; +                s->stream.avail_out -= n; +                s->stream.avail_in  -= n; +            } +            if (s->stream.avail_out > 0) { +                s->stream.avail_out -= +                    (uInt)fread(next_out, 1, s->stream.avail_out, s->file); +            } +            len -= s->stream.avail_out; +            s->in  += len; +            s->out += len; +            if (len == 0) s->z_eof = 1; +            return (int)len; +        } +        if (s->stream.avail_in == 0 && !s->z_eof) { + +            errno = 0; +            s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); +            if (s->stream.avail_in == 0) { +                s->z_eof = 1; +                if (ferror(s->file)) { +                    s->z_err = Z_ERRNO; +                    break; +                } +            } +            s->stream.next_in = s->inbuf; +        } +        s->in += s->stream.avail_in; +        s->out += s->stream.avail_out; +        s->z_err = inflate(&(s->stream), Z_NO_FLUSH); +        s->in -= s->stream.avail_in; +        s->out -= s->stream.avail_out; + +        if (s->z_err == Z_STREAM_END) { +            /* Check CRC and original size */ +            s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); +            start = s->stream.next_out; + +            if (getLong(s) != s->crc) { +                s->z_err = Z_DATA_ERROR; +            } else { +                (void)getLong(s); +                /* The uncompressed length returned by above getlong() may be +                 * different from s->out in case of concatenated .gz files. +                 * Check for such files: +                 */ +                check_header(s); +                if (s->z_err == Z_OK) { +                    inflateReset(&(s->stream)); +                    s->crc = crc32(0L, Z_NULL, 0); +                } +            } +        } +        if (s->z_err != Z_OK || s->z_eof) break; +    } +    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + +    if (len == s->stream.avail_out && +        (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) +        return -1; +    return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== +      Reads one byte from the compressed file. gzgetc returns this byte +   or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) +    gzFile file; +{ +    unsigned char c; + +    return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== +      Push one byte back onto the stream. +*/ +int ZEXPORT gzungetc(c, file) +    int c; +    gzFile file; +{ +    gz_stream *s = (gz_stream*)file; + +    if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; +    s->back = c; +    s->out--; +    s->last = (s->z_err == Z_STREAM_END); +    if (s->last) s->z_err = Z_OK; +    s->z_eof = 0; +    return c; +} + + +/* =========================================================================== +      Reads bytes from the compressed file until len-1 characters are +   read, or a newline character is read and transferred to buf, or an +   end-of-file condition is encountered.  The string is then terminated +   with a null character. +      gzgets returns buf, or Z_NULL in case of error. + +      The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) +    gzFile file; +    char *buf; +    int len; +{ +    char *b = buf; +    if (buf == Z_NULL || len <= 0) return Z_NULL; + +    while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; +    *buf = '\0'; +    return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_GZCOMPRESS +/* =========================================================================== +     Writes the given number of uncompressed bytes into the compressed file. +   gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) +    gzFile file; +    voidpc buf; +    unsigned len; +{ +    gz_stream *s = (gz_stream*)file; + +    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + +    s->stream.next_in = (Bytef*)buf; +    s->stream.avail_in = len; + +    while (s->stream.avail_in != 0) { + +        if (s->stream.avail_out == 0) { + +            s->stream.next_out = s->outbuf; +            if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { +                s->z_err = Z_ERRNO; +                break; +            } +            s->stream.avail_out = Z_BUFSIZE; +        } +        s->in += s->stream.avail_in; +        s->out += s->stream.avail_out; +        s->z_err = deflate(&(s->stream), Z_NO_FLUSH); +        s->in -= s->stream.avail_in; +        s->out -= s->stream.avail_out; +        if (s->z_err != Z_OK) break; +    } +    s->crc = crc32(s->crc, (const Bytef *)buf, len); + +    return (int)(len - s->stream.avail_in); +} + + +/* =========================================================================== +     Converts, formats, and writes the args to the compressed file under +   control of the format string, as in fprintf. gzprintf returns the number of +   uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include <stdarg.h> + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ +    char buf[Z_PRINTF_BUFSIZE]; +    va_list va; +    int len; + +    va_start(va, format); +#ifdef HAS_vsnprintf +    len = vsnprintf(buf, sizeof(buf), format, va); +#else +    (void)vsprintf(buf, format, va); +    len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ +#endif +    va_end(va); +    if (len <= 0 || len >= sizeof(buf)) return 0; + +    return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, +	               a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) +    gzFile file; +    const char *format; +    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, +	a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ +    char buf[Z_PRINTF_BUFSIZE]; +    int len; + +#ifdef HAS_snprintf +    len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, +	     a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +#else +    sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, +	    a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +    len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ +#endif +    if (len <= 0 || len >= sizeof(buf)) return 0; + +    return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== +      Writes c, converted to an unsigned char, into the compressed file. +   gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) +    gzFile file; +    int c; +{ +    unsigned char cc = (unsigned char) c; /* required for big endian systems */ + +    return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== +      Writes the given null-terminated string to the compressed file, excluding +   the terminating null character. +      gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) +    gzFile file; +    const char *s; +{ +    return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== +     Flushes all pending output into the compressed file. The parameter +   flush is as in the deflate() function. +*/ +local int do_flush (file, flush) +    gzFile file; +    int flush; +{ +    uInt len; +    int done = 0; +    gz_stream *s = (gz_stream*)file; + +    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + +    s->stream.avail_in = 0; /* should be zero already anyway */ + +    for (;;) { +        len = Z_BUFSIZE - s->stream.avail_out; + +        if (len != 0) { +            if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { +                s->z_err = Z_ERRNO; +                return Z_ERRNO; +            } +            s->stream.next_out = s->outbuf; +            s->stream.avail_out = Z_BUFSIZE; +        } +        if (done) break; +        s->out += s->stream.avail_out; +        s->z_err = deflate(&(s->stream), flush); +        s->out -= s->stream.avail_out; + +        /* Ignore the second of two consecutive flushes: */ +        if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + +        /* deflate has finished flushing only when it hasn't used up +         * all the available space in the output buffer: +         */ +        done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + +        if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; +    } +    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) +     gzFile file; +     int flush; +{ +    gz_stream *s = (gz_stream*)file; +    int err = do_flush (file, flush); + +    if (err) return err; +    fflush(s->file); +    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_GZCOMPRESS */ + +/* =========================================================================== +      Sets the starting position for the next gzread or gzwrite on the given +   compressed file. The offset represents a number of bytes in the +      gzseek returns the resulting offset location as measured in bytes from +   the beginning of the uncompressed stream, or -1 in case of error. +      SEEK_END is not implemented, returns error. +      In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) +    gzFile file; +    z_off_t offset; +    int whence; +{ +    gz_stream *s = (gz_stream*)file; + +    if (s == NULL || whence == SEEK_END || +	s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { +	return -1L; +    } +     +    if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS +	return -1L; +#else +	if (whence == SEEK_SET) { +	    offset -= s->in; +	} +	if (offset < 0) return -1L; + +	/* At this point, offset is the number of zero bytes to write. */ +	if (s->inbuf == Z_NULL) { +	    s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ +	    if (s->inbuf == Z_NULL) return -1L; +	    zmemzero(s->inbuf, Z_BUFSIZE); +	} +	while (offset > 0)  { +	    uInt size = Z_BUFSIZE; +	    if (offset < Z_BUFSIZE) size = (uInt)offset; + +	    size = gzwrite(file, s->inbuf, size); +	    if (size == 0) return -1L; + +	    offset -= size; +	} +	return s->in; +#endif +    } +    /* Rest of function is for reading only */ + +    /* compute absolute position */ +    if (whence == SEEK_CUR) { +	offset += s->out; +    } +    if (offset < 0) return -1L; + +    if (s->transparent) { +	/* map to fseek */ +	s->back = EOF; +	s->stream.avail_in = 0; +	s->stream.next_in = s->inbuf; +        if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + +	s->in = s->out = offset; +	return offset; +    } + +    /* For a negative seek, rewind and use positive seek */ +    if (offset >= s->out) { +	offset -= s->out; +    } else if (gzrewind(file) < 0) { +	return -1L; +    } +    /* offset is now the number of bytes to skip. */ + +    if (offset != 0 && s->outbuf == Z_NULL) { +	s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +	if (s->outbuf == Z_NULL) return -1L; +    } +    if (offset && s->back != EOF) { +        s->back = EOF; +        s->out++; +        offset--; +        if (s->last) s->z_err = Z_STREAM_END; +    } +    while (offset > 0)  { +	int size = Z_BUFSIZE; +	if (offset < Z_BUFSIZE) size = (int)offset; + +	size = gzread(file, s->outbuf, (uInt)size); +	if (size <= 0) return -1L; +	offset -= size; +    } +    return s->out; +} + +/* =========================================================================== +     Rewinds input file.  +*/ +int ZEXPORT gzrewind (file) +    gzFile file; +{ +    gz_stream *s = (gz_stream*)file; + +    if (s == NULL || s->mode != 'r') return -1; + +    s->z_err = Z_OK; +    s->z_eof = 0; +    s->back = EOF; +    s->stream.avail_in = 0; +    s->stream.next_in = s->inbuf; +    s->crc = crc32(0L, Z_NULL, 0); +    if (!s->transparent) (void)inflateReset(&s->stream); +    s->in = 0; +    s->out = 0; +    return fseek(s->file, s->start, SEEK_SET); +} + +/* =========================================================================== +     Returns the starting position for the next gzread or gzwrite on the +   given compressed file. This position represents a number of bytes in the +   uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) +    gzFile file; +{ +    return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== +     Returns 1 when EOF has previously been detected reading the given +   input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) +    gzFile file; +{ +    gz_stream *s = (gz_stream*)file; + +    /* With concatenated compressed files that can have embedded +     * crc trailers, z_eof is no longer the only/best indicator of EOF +     * on a gz_stream. Handle end-of-stream error explicitly here. +     */ +    if (s == NULL || s->mode != 'r') return 0; +    if (s->z_eof) return 1; +    return s->z_err == Z_STREAM_END; +} + +/* =========================================================================== +     Returns 1 if reading and doing so transparently, otherwise zero. +*/ +int ZEXPORT gzdirect (file) +    gzFile file; +{ +    gz_stream *s = (gz_stream*)file; + +    if (s == NULL || s->mode != 'r') return 0; +    return s->transparent; +} + +/* =========================================================================== +   Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) +    FILE *file; +    uLong x; +{ +    int n; +    for (n = 0; n < 4; n++) { +        fputc((int)(x & 0xff), file); +        x >>= 8; +    } +} + +/* =========================================================================== +   Reads a long in LSB order from the given gz_stream. Sets z_err in case +   of error. +*/ +local uLong getLong (s) +    gz_stream *s; +{ +    uLong x = (uLong)get_byte(s); +    int c; + +    x += ((uLong)get_byte(s))<<8; +    x += ((uLong)get_byte(s))<<16; +    c = get_byte(s); +    if (c == EOF) s->z_err = Z_DATA_ERROR; +    x += ((uLong)c)<<24; +    return x; +} + +/* =========================================================================== +     Flushes all pending output if necessary, closes the compressed file +   and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) +    gzFile file; +{ +    gz_stream *s = (gz_stream*)file; + +    if (s == NULL) return Z_STREAM_ERROR; + +    if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS +        return Z_STREAM_ERROR; +#else +        if (do_flush (file, Z_FINISH) != Z_OK) +            return destroy((gz_stream*)file); + +        putLong (s->file, s->crc); +        putLong (s->file, (uLong)(s->in & 0xffffffff)); +#endif +    } +    return destroy((gz_stream*)file); +} + +#ifdef STDC +#  define zstrerror(errnum) strerror(errnum) +#else +#  define zstrerror(errnum) "" +#endif + +/* =========================================================================== +     Returns the error message for the last error which occurred on the +   given compressed file. errnum is set to zlib error number. If an +   error occurred in the file system and not in the compression library, +   errnum is set to Z_ERRNO and the application may consult errno +   to get the exact error code. +*/ +const char * ZEXPORT gzerror (file, errnum) +    gzFile file; +    int *errnum; +{ +    char *m; +    gz_stream *s = (gz_stream*)file; +    size_t len; + +    if (s == NULL) { +        *errnum = Z_STREAM_ERROR; +        return (const char*)ERR_MSG(Z_STREAM_ERROR); +    } +    *errnum = s->z_err; +    if (*errnum == Z_OK) return (const char*)""; + +    m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + +    if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + +    TRYFREE(s->msg); +    len = strlen(s->path) + strlen(m) + 3; +    s->msg = (char*)ALLOC(len); +    if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); +    strlcpy(s->msg, s->path, len); +    strlcat(s->msg, ": ", len); +    strlcat(s->msg, m, len); +    return (const char*)s->msg; +} + +/* =========================================================================== +     Clear the error and end-of-file flags, and do the same for the real file. +*/ +void ZEXPORT gzclearerr (file) +    gzFile file; +{ +    gz_stream *s = (gz_stream*)file; + +    if (s == NULL) return; +    if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; +    s->z_eof = 0; +    clearerr(s->file); +} diff --git a/lib/libz/infback.c b/lib/libz/infback.c new file mode 100644 index 0000000..e980358 --- /dev/null +++ b/lib/libz/infback.c @@ -0,0 +1,637 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* +   This code is largely copied from inflate.c.  Normally either infback.o or +   inflate.o would be linked into an application--not both.  The interface +   with inffast.c is retained so that optimized assembler-coded versions of +   inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* +   strm provides memory allocation functions in zalloc and zfree, or +   Z_NULL to use the library memory allocation functions. + +   windowBits is in the range 8..15, and window is a user-supplied +   window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ +    struct inflate_state FAR *state; + +    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || +        stream_size != (int)(sizeof(z_stream))) +        return Z_VERSION_ERROR; +    if (strm == Z_NULL || window == Z_NULL || +        windowBits < 8 || windowBits > 15) +        return Z_STREAM_ERROR; +    strm->msg = Z_NULL;                 /* in case we return an error */ +    if (strm->zalloc == (alloc_func)0) { +        strm->zalloc = zcalloc; +        strm->opaque = (voidpf)0; +    } +    if (strm->zfree == (free_func)0) strm->zfree = zcfree; +    state = (struct inflate_state FAR *)ZALLOC(strm, 1, +                                               sizeof(struct inflate_state)); +    if (state == Z_NULL) return Z_MEM_ERROR; +    Tracev((stderr, "inflate: allocated\n")); +    strm->state = (struct internal_state FAR *)state; +    state->dmax = 32768U; +    state->wbits = windowBits; +    state->wsize = 1U << windowBits; +    state->window = window; +    state->write = 0; +    state->whave = 0; +    return Z_OK; +} + +/* +   Return state with length and distance decoding tables and index sizes set to +   fixed code decoding.  Normally this returns fixed tables from inffixed.h. +   If BUILDFIXED is defined, then instead this routine builds the tables the +   first time it's called, and returns those tables the first time and +   thereafter.  This reduces the size of the code by about 2K bytes, in +   exchange for a little execution time.  However, BUILDFIXED should not be +   used for threaded applications, since the rewriting of the tables and virgin +   may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED +    static int virgin = 1; +    static code *lenfix, *distfix; +    static code fixed[544]; + +    /* build fixed huffman tables if first call (may not be thread safe) */ +    if (virgin) { +        unsigned sym, bits; +        static code *next; + +        /* literal/length table */ +        sym = 0; +        while (sym < 144) state->lens[sym++] = 8; +        while (sym < 256) state->lens[sym++] = 9; +        while (sym < 280) state->lens[sym++] = 7; +        while (sym < 288) state->lens[sym++] = 8; +        next = fixed; +        lenfix = next; +        bits = 9; +        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + +        /* distance table */ +        sym = 0; +        while (sym < 32) state->lens[sym++] = 5; +        distfix = next; +        bits = 5; +        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + +        /* do this just once */ +        virgin = 0; +    } +#else /* !BUILDFIXED */ +#   include "inffixed.h" +#endif /* BUILDFIXED */ +    state->lencode = lenfix; +    state->lenbits = 9; +    state->distcode = distfix; +    state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ +    do { \ +        put = strm->next_out; \ +        left = strm->avail_out; \ +        next = strm->next_in; \ +        have = strm->avail_in; \ +        hold = state->hold; \ +        bits = state->bits; \ +    } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ +    do { \ +        strm->next_out = put; \ +        strm->avail_out = left; \ +        strm->next_in = next; \ +        strm->avail_in = have; \ +        state->hold = hold; \ +        state->bits = bits; \ +    } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ +    do { \ +        hold = 0; \ +        bits = 0; \ +    } while (0) + +/* Assure that some input is available.  If input is requested, but denied, +   then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ +    do { \ +        if (have == 0) { \ +            have = in(in_desc, &next); \ +            if (have == 0) { \ +                next = Z_NULL; \ +                ret = Z_BUF_ERROR; \ +                goto inf_leave; \ +            } \ +        } \ +    } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() +   with an error if there is no input available. */ +#define PULLBYTE() \ +    do { \ +        PULL(); \ +        have--; \ +        hold += (unsigned long)(*next++) << bits; \ +        bits += 8; \ +    } while (0) + +/* Assure that there are at least n bits in the bit accumulator.  If there is +   not enough available input to do that, then return from inflateBack() with +   an error. */ +#define NEEDBITS(n) \ +    do { \ +        while (bits < (unsigned)(n)) \ +            PULLBYTE(); \ +    } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ +    ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ +    do { \ +        hold >>= (n); \ +        bits -= (unsigned)(n); \ +    } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ +    do { \ +        hold >>= bits & 7; \ +        bits -= bits & 7; \ +    } while (0) + +/* Assure that some output space is available, by writing out the window +   if it's full.  If the write fails, return from inflateBack() with a +   Z_BUF_ERROR. */ +#define ROOM() \ +    do { \ +        if (left == 0) { \ +            put = state->window; \ +            left = state->wsize; \ +            state->whave = left; \ +            if (out(out_desc, put, left)) { \ +                ret = Z_BUF_ERROR; \ +                goto inf_leave; \ +            } \ +        } \ +    } while (0) + +/* +   strm provides the memory allocation functions and window buffer on input, +   and provides information on the unused input on return.  For Z_DATA_ERROR +   returns, strm will also provide an error message. + +   in() and out() are the call-back input and output functions.  When +   inflateBack() needs more input, it calls in().  When inflateBack() has +   filled the window with output, or when it completes with data in the +   window, it calls out() to write out the data.  The application must not +   change the provided input until in() is called again or inflateBack() +   returns.  The application must not change the window/output buffer until +   inflateBack() returns. + +   in() and out() are called with a descriptor parameter provided in the +   inflateBack() call.  This parameter can be a structure that provides the +   information required to do the read or write, as well as accumulated +   information on the input and output such as totals and check values. + +   in() should return zero on failure.  out() should return non-zero on +   failure.  If either in() or out() fails, than inflateBack() returns a +   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it +   was in() or out() that caused in the error.  Otherwise,  inflateBack() +   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format +   error, or Z_MEM_ERROR if it could not allocate memory for the state. +   inflateBack() can also return Z_STREAM_ERROR if the input parameters +   are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ +    struct inflate_state FAR *state; +    z_const unsigned char FAR *next;    /* next input */ +    unsigned char FAR *put;     /* next output */ +    unsigned have, left;        /* available input and output */ +    unsigned long hold;         /* bit buffer */ +    unsigned bits;              /* bits in bit buffer */ +    unsigned copy;              /* number of stored or match bytes to copy */ +    unsigned char FAR *from;    /* where to copy match bytes from */ +    code this;                  /* current decoding table entry */ +    code last;                  /* parent table entry */ +    unsigned len;               /* length to copy for repeats, bits to drop */ +    int ret;                    /* return code */ +    static const unsigned short order[19] = /* permutation of code lengths */ +        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +    /* Check that the strm exists and that the state was initialized */ +    if (strm == Z_NULL || strm->state == Z_NULL) +        return Z_STREAM_ERROR; +    state = (struct inflate_state FAR *)strm->state; + +    /* Reset the state */ +    strm->msg = Z_NULL; +    state->mode = TYPE; +    state->last = 0; +    state->whave = 0; +    next = strm->next_in; +    have = next != Z_NULL ? strm->avail_in : 0; +    hold = 0; +    bits = 0; +    put = state->window; +    left = state->wsize; + +    /* Inflate until end of block marked as last */ +    for (;;) +        switch (state->mode) { +        case TYPE: +            /* determine and dispatch block type */ +            if (state->last) { +                BYTEBITS(); +                state->mode = DONE; +                break; +            } +            NEEDBITS(3); +            state->last = BITS(1); +            DROPBITS(1); +            switch (BITS(2)) { +            case 0:                             /* stored block */ +                Tracev((stderr, "inflate:     stored block%s\n", +                        state->last ? " (last)" : "")); +                state->mode = STORED; +                break; +            case 1:                             /* fixed block */ +                fixedtables(state); +                Tracev((stderr, "inflate:     fixed codes block%s\n", +                        state->last ? " (last)" : "")); +                state->mode = LEN;              /* decode codes */ +                break; +            case 2:                             /* dynamic block */ +                Tracev((stderr, "inflate:     dynamic codes block%s\n", +                        state->last ? " (last)" : "")); +                state->mode = TABLE; +                break; +            case 3: +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid block type"; +#endif +                state->mode = BAD; +            } +            DROPBITS(2); +            break; + +        case STORED: +            /* get and verify stored block length */ +            BYTEBITS();                         /* go to byte boundary */ +            NEEDBITS(32); +            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid stored block lengths"; +#endif +                state->mode = BAD; +                break; +            } +            state->length = (unsigned)hold & 0xffff; +            Tracev((stderr, "inflate:       stored length %u\n", +                    state->length)); +            INITBITS(); + +            /* copy stored block from input to output */ +            while (state->length != 0) { +                copy = state->length; +                PULL(); +                ROOM(); +                if (copy > have) copy = have; +                if (copy > left) copy = left; +                zmemcpy(put, next, copy); +                have -= copy; +                next += copy; +                left -= copy; +                put += copy; +                state->length -= copy; +            } +            Tracev((stderr, "inflate:       stored end\n")); +            state->mode = TYPE; +            break; + +        case TABLE: +            /* get dynamic table entries descriptor */ +            NEEDBITS(14); +            state->nlen = BITS(5) + 257; +            DROPBITS(5); +            state->ndist = BITS(5) + 1; +            DROPBITS(5); +            state->ncode = BITS(4) + 4; +            DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND +            if (state->nlen > 286 || state->ndist > 30) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"too many length or distance symbols"; +#endif +                state->mode = BAD; +                break; +            } +#endif +            Tracev((stderr, "inflate:       table sizes ok\n")); + +            /* get code length code lengths (not a typo) */ +            state->have = 0; +            while (state->have < state->ncode) { +                NEEDBITS(3); +                state->lens[order[state->have++]] = (unsigned short)BITS(3); +                DROPBITS(3); +            } +            while (state->have < 19) +                state->lens[order[state->have++]] = 0; +            state->next = state->codes; +            state->lencode = (code const FAR *)(state->next); +            state->lenbits = 7; +            ret = inflate_table(CODES, state->lens, 19, &(state->next), +                                &(state->lenbits), state->work); +            if (ret) { +                strm->msg = (char *)"invalid code lengths set"; +                state->mode = BAD; +                break; +            } +            Tracev((stderr, "inflate:       code lengths ok\n")); + +            /* get length and distance code code lengths */ +            state->have = 0; +            while (state->have < state->nlen + state->ndist) { +                for (;;) { +                    this = state->lencode[BITS(state->lenbits)]; +                    if ((unsigned)(this.bits) <= bits) break; +                    PULLBYTE(); +                } +                if (this.val < 16) { +                    NEEDBITS(this.bits); +                    DROPBITS(this.bits); +                    state->lens[state->have++] = this.val; +                } +                else { +                    if (this.val == 16) { +                        NEEDBITS(this.bits + 2); +                        DROPBITS(this.bits); +                        if (state->have == 0) { +                            strm->msg = (char *)"invalid bit length repeat"; +                            state->mode = BAD; +                            break; +                        } +                        len = (unsigned)(state->lens[state->have - 1]); +                        copy = 3 + BITS(2); +                        DROPBITS(2); +                    } +                    else if (this.val == 17) { +                        NEEDBITS(this.bits + 3); +                        DROPBITS(this.bits); +                        len = 0; +                        copy = 3 + BITS(3); +                        DROPBITS(3); +                    } +                    else { +                        NEEDBITS(this.bits + 7); +                        DROPBITS(this.bits); +                        len = 0; +                        copy = 11 + BITS(7); +                        DROPBITS(7); +                    } +                    if (state->have + copy > state->nlen + state->ndist) { +                        strm->msg = (char *)"invalid bit length repeat"; +                        state->mode = BAD; +                        break; +                    } +                    while (copy--) +                        state->lens[state->have++] = (unsigned short)len; +                } +            } + +            /* handle error breaks in while */ +            if (state->mode == BAD) break; + +            /* build code tables */ +            state->next = state->codes; +            state->lencode = (code const FAR *)(state->next); +            state->lenbits = 9; +            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), +                                &(state->lenbits), state->work); +            if (ret) { +                strm->msg = (char *)"invalid literal/lengths set"; +                state->mode = BAD; +                break; +            } +            state->distcode = (code const FAR *)(state->next); +            state->distbits = 6; +            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, +                            &(state->next), &(state->distbits), state->work); +            if (ret) { +                strm->msg = (char *)"invalid distances set"; +                state->mode = BAD; +                break; +            } +            Tracev((stderr, "inflate:       codes ok\n")); +            state->mode = LEN; + +        case LEN: +#ifndef SLOW +            /* use inflate_fast() if we have enough input and output */ +            if (have >= 6 && left >= 258) { +                RESTORE(); +                if (state->whave < state->wsize) +                    state->whave = state->wsize - left; +                inflate_fast(strm, state->wsize); +                LOAD(); +                break; +            } +#endif + +            /* get a literal, length, or end-of-block code */ +            for (;;) { +                this = state->lencode[BITS(state->lenbits)]; +                if ((unsigned)(this.bits) <= bits) break; +                PULLBYTE(); +            } +            if (this.op && (this.op & 0xf0) == 0) { +                last = this; +                for (;;) { +                    this = state->lencode[last.val + +                            (BITS(last.bits + last.op) >> last.bits)]; +                    if ((unsigned)(last.bits + this.bits) <= bits) break; +                    PULLBYTE(); +                } +                DROPBITS(last.bits); +            } +            DROPBITS(this.bits); +            state->length = (unsigned)this.val; + +            /* process literal */ +            if (this.op == 0) { +                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? +                        "inflate:         literal '%c'\n" : +                        "inflate:         literal 0x%02x\n", this.val)); +                ROOM(); +                *put++ = (unsigned char)(state->length); +                left--; +                state->mode = LEN; +                break; +            } + +            /* process end of block */ +            if (this.op & 32) { +                Tracevv((stderr, "inflate:         end of block\n")); +                state->mode = TYPE; +                break; +            } + +            /* invalid code */ +            if (this.op & 64) { +                strm->msg = (char *)"invalid literal/length code"; +                state->mode = BAD; +                break; +            } + +            /* length code -- get extra bits, if any */ +            state->extra = (unsigned)(this.op) & 15; +            if (state->extra != 0) { +                NEEDBITS(state->extra); +                state->length += BITS(state->extra); +                DROPBITS(state->extra); +            } +            Tracevv((stderr, "inflate:         length %u\n", state->length)); + +            /* get distance code */ +            for (;;) { +                this = state->distcode[BITS(state->distbits)]; +                if ((unsigned)(this.bits) <= bits) break; +                PULLBYTE(); +            } +            if ((this.op & 0xf0) == 0) { +                last = this; +                for (;;) { +                    this = state->distcode[last.val + +                            (BITS(last.bits + last.op) >> last.bits)]; +                    if ((unsigned)(last.bits + this.bits) <= bits) break; +                    PULLBYTE(); +                } +                DROPBITS(last.bits); +            } +            DROPBITS(this.bits); +            if (this.op & 64) { +                strm->msg = (char *)"invalid distance code"; +                state->mode = BAD; +                break; +            } +            state->offset = (unsigned)this.val; + +            /* get distance extra bits, if any */ +            state->extra = (unsigned)(this.op) & 15; +            if (state->extra != 0) { +                NEEDBITS(state->extra); +                state->offset += BITS(state->extra); +                DROPBITS(state->extra); +            } +            if (state->offset > state->wsize - (state->whave < state->wsize ? +                                                left : 0)) { +                strm->msg = (char *)"invalid distance too far back"; +                state->mode = BAD; +                break; +            } +            Tracevv((stderr, "inflate:         distance %u\n", state->offset)); + +            /* copy match from window to output */ +            do { +                ROOM(); +                copy = state->wsize - state->offset; +                if (copy < left) { +                    from = put + copy; +                    copy = left - copy; +                } +                else { +                    from = put - state->offset; +                    copy = left; +                } +                if (copy > state->length) copy = state->length; +                state->length -= copy; +                left -= copy; +                do { +                    *put++ = *from++; +                } while (--copy); +            } while (state->length != 0); +            break; + +        case DONE: +            /* inflate stream terminated properly -- write leftover output */ +            ret = Z_STREAM_END; +            if (left < state->wsize) { +                if (out(out_desc, state->window, state->wsize - left)) +                    ret = Z_BUF_ERROR; +            } +            goto inf_leave; + +        case BAD: +            ret = Z_DATA_ERROR; +            goto inf_leave; + +        default:                /* can't happen, but makes compilers happy */ +            ret = Z_STREAM_ERROR; +            goto inf_leave; +        } + +    /* Return unused input */ +  inf_leave: +    strm->next_in = next; +    strm->avail_in = have; +    return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ +    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) +        return Z_STREAM_ERROR; +    ZFREE(strm, strm->state); +    strm->state = Z_NULL; +    Tracev((stderr, "inflate: end\n")); +    return Z_OK; +} diff --git a/lib/libz/inffast.c b/lib/libz/inffast.c new file mode 100644 index 0000000..988806c --- /dev/null +++ b/lib/libz/inffast.c @@ -0,0 +1,331 @@ +/*	$OpenBSD: inffast.c,v 1.8 2019/06/01 11:39:57 jca Exp $	*/ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. +   Based on testing to date, +   Pre-increment preferred for: +   - PowerPC G3 (Adler) +   - MIPS R5000 (Randers-Pehrson) +   Post-increment preferred for: +   - none +   No measurable difference: +   - Pentium III (Anderson) +   - M68060 (Nikl) + */ +#ifdef POSTINC +#  define OFF 0 +#  define PUP(a) *(a)++ +#else +#  define OFF 1 +#  define PUP(a) *++(a) +#endif + +/* +   Decode literal, length, and distance codes and write out the resulting +   literal and match bytes until either not enough input or output is +   available, an end-of-block is encountered, or a data error is encountered. +   When large enough input and output buffers are supplied to inflate(), for +   example, a 16K input buffer and a 64K output buffer, more than 95% of the +   inflate execution time is spent in this routine. + +   Entry assumptions: + +        state->mode == LEN +        strm->avail_in >= 6 +        strm->avail_out >= 258 +        start >= strm->avail_out +        state->bits < 8 + +   On return, state->mode is one of: + +        LEN -- ran out of enough output space or enough available input +        TYPE -- reached end of block code, inflate() to interpret next block +        BAD -- error in block data + +   Notes: + +    - The maximum input bits used by a length/distance pair is 15 bits for the +      length code, 5 bits for the length extra, 15 bits for the distance code, +      and 13 bits for the distance extra.  This totals 48 bits, or six bytes. +      Therefore if strm->avail_in >= 6, then there is enough input to avoid +      checking for available input while decoding. + +    - The maximum bytes that a single length/distance pair can output is 258 +      bytes, which is the maximum length that can be coded.  inflate_fast() +      requires strm->avail_out >= 258 for each loop to avoid checking for +      output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start;         /* inflate()'s starting value for strm->avail_out */ +{ +    struct inflate_state FAR *state; +    z_const unsigned char FAR *in;      /* local strm->next_in */ +    z_const unsigned char FAR *last;    /* while in < last, enough input available */ +    unsigned char FAR *out;     /* local strm->next_out */ +    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */ +    unsigned char FAR *end;     /* while out < end, enough space available */ +#ifdef INFLATE_STRICT +    unsigned dmax;              /* maximum distance from zlib header */ +#endif +    unsigned wsize;             /* window size or zero if not using window */ +    unsigned whave;             /* valid bytes in the window */ +    unsigned write;             /* window write index */ +    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */ +    unsigned long hold;         /* local strm->hold */ +    unsigned bits;              /* local strm->bits */ +    code const FAR *lcode;      /* local strm->lencode */ +    code const FAR *dcode;      /* local strm->distcode */ +    unsigned lmask;             /* mask for first level of length codes */ +    unsigned dmask;             /* mask for first level of distance codes */ +    code this;                  /* retrieved table entry */ +    unsigned op;                /* code bits, operation, extra bits, or */ +                                /*  window position, window bytes to copy */ +    unsigned len;               /* match length, unused bytes */ +    unsigned dist;              /* match distance */ +    unsigned char FAR *from;    /* where to copy match from */ + +    /* copy state to local variables */ +    state = (struct inflate_state FAR *)strm->state; +    in = strm->next_in - OFF; +    last = in + (strm->avail_in - 5); +    out = strm->next_out - OFF; +    beg = out - (start - strm->avail_out); +    end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT +    dmax = state->dmax; +#endif +    wsize = state->wsize; +    whave = state->whave; +    write = state->write; +    window = state->window; +    hold = state->hold; +    bits = state->bits; +    lcode = state->lencode; +    dcode = state->distcode; +    lmask = (1U << state->lenbits) - 1; +    dmask = (1U << state->distbits) - 1; + +    /* decode literals and length/distances until end-of-block or not enough +       input data or output space */ +    do { +        if (bits < 15) { +            hold += (unsigned long)(PUP(in)) << bits; +            bits += 8; +            hold += (unsigned long)(PUP(in)) << bits; +            bits += 8; +        } +        this = lcode[hold & lmask]; +      dolen: +        op = (unsigned)(this.bits); +        hold >>= op; +        bits -= op; +        op = (unsigned)(this.op); +        if (op == 0) {                          /* literal */ +            Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? +                    "inflate:         literal '%c'\n" : +                    "inflate:         literal 0x%02x\n", this.val)); +            PUP(out) = (unsigned char)(this.val); +        } +        else if (op & 16) {                     /* length base */ +            len = (unsigned)(this.val); +            op &= 15;                           /* number of extra bits */ +            if (op) { +                if (bits < op) { +                    hold += (unsigned long)(PUP(in)) << bits; +                    bits += 8; +                } +                len += (unsigned)hold & ((1U << op) - 1); +                hold >>= op; +                bits -= op; +            } +            Tracevv((stderr, "inflate:         length %u\n", len)); +            if (bits < 15) { +                hold += (unsigned long)(PUP(in)) << bits; +                bits += 8; +                hold += (unsigned long)(PUP(in)) << bits; +                bits += 8; +            } +            this = dcode[hold & dmask]; +          dodist: +            op = (unsigned)(this.bits); +            hold >>= op; +            bits -= op; +            op = (unsigned)(this.op); +            if (op & 16) {                      /* distance base */ +                dist = (unsigned)(this.val); +                op &= 15;                       /* number of extra bits */ +                if (bits < op) { +                    hold += (unsigned long)(PUP(in)) << bits; +                    bits += 8; +                    if (bits < op) { +                        hold += (unsigned long)(PUP(in)) << bits; +                        bits += 8; +                    } +                } +                dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT +                if (dist > dmax) { +                    strm->msg = (char *)"invalid distance too far back"; +                    state->mode = BAD; +                    break; +                } +#endif +                hold >>= op; +                bits -= op; +                Tracevv((stderr, "inflate:         distance %u\n", dist)); +                op = (unsigned)(out - beg);     /* max distance in output */ +                if (dist > op) {                /* see if copy from window */ +                    op = dist - op;             /* distance back in window */ +                    if (op > whave) { +#ifdef SMALL   +			strm->msg = "error"; +#else +                        strm->msg = (char *)"invalid distance too far back"; +#endif +                        state->mode = BAD; +                        break; +                    } +                    from = window - OFF; +                    if (write == 0) {           /* very common case */ +                        from += wsize - op; +                        if (op < len) {         /* some from window */ +                            len -= op; +                            do { +                                PUP(out) = PUP(from); +                            } while (--op); +                            from = out - dist;  /* rest from output */ +                        } +                    } +                    else if (write < op) {      /* wrap around window */ +                        from += wsize + write - op; +                        op -= write; +                        if (op < len) {         /* some from end of window */ +                            len -= op; +                            do { +                                PUP(out) = PUP(from); +                            } while (--op); +                            from = window - OFF; +                            if (write < len) {  /* some from start of window */ +                                op = write; +                                len -= op; +                                do { +                                    PUP(out) = PUP(from); +                                } while (--op); +                                from = out - dist;      /* rest from output */ +                            } +                        } +                    } +                    else {                      /* contiguous in window */ +                        from += write - op; +                        if (op < len) {         /* some from window */ +                            len -= op; +                            do { +                                PUP(out) = PUP(from); +                            } while (--op); +                            from = out - dist;  /* rest from output */ +                        } +                    } +                    while (len > 2) { +                        PUP(out) = PUP(from); +                        PUP(out) = PUP(from); +                        PUP(out) = PUP(from); +                        len -= 3; +                    } +                    if (len) { +                        PUP(out) = PUP(from); +                        if (len > 1) +                            PUP(out) = PUP(from); +                    } +                } +                else { +                    from = out - dist;          /* copy direct from output */ +                    do {                        /* minimum length is three */ +                        PUP(out) = PUP(from); +                        PUP(out) = PUP(from); +                        PUP(out) = PUP(from); +                        len -= 3; +                    } while (len > 2); +                    if (len) { +                        PUP(out) = PUP(from); +                        if (len > 1) +                            PUP(out) = PUP(from); +                    } +                } +            } +            else if ((op & 64) == 0) {          /* 2nd level distance code */ +                this = dcode[this.val + (hold & ((1U << op) - 1))]; +                goto dodist; +            } +            else { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid distance code"; +#endif +                state->mode = BAD; +                break; +            } +        } +        else if ((op & 64) == 0) {              /* 2nd level length code */ +            this = lcode[this.val + (hold & ((1U << op) - 1))]; +            goto dolen; +        } +        else if (op & 32) {                     /* end-of-block */ +            Tracevv((stderr, "inflate:         end of block\n")); +            state->mode = TYPE; +            break; +        } +        else { +#ifdef SMALL   +	    strm->msg = "error"; +#else +            strm->msg = (char *)"invalid literal/length code"; +#endif +            state->mode = BAD; +            break; +        } +    } while (in < last && out < end); + +    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ +    len = bits >> 3; +    in -= len; +    bits -= len << 3; +    hold &= (1U << bits) - 1; + +    /* update state and return */ +    strm->next_in = in + OFF; +    strm->next_out = out + OFF; +    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); +    strm->avail_out = (unsigned)(out < end ? +                                 257 + (end - out) : 257 - (out - end)); +    state->hold = hold; +    state->bits = bits; +    return; +} + +/* +   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): +   - Using bit fields for code structure +   - Different op definition to avoid & for extra bits (do & for table bits) +   - Three separate decoding do-loops for direct, window, and write == 0 +   - Special case for distance > 1 copies to do overlapped load and store copy +   - Explicit branch predictions (based on measured branch probabilities) +   - Deferring match copy and interspersed it with decoding subsequent codes +   - Swapping literal/length else +   - Swapping window/direct else +   - Larger unrolled copy loops (three is about right) +   - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/lib/libz/inffast.h b/lib/libz/inffast.h new file mode 100644 index 0000000..0283eea --- /dev/null +++ b/lib/libz/inffast.h @@ -0,0 +1,12 @@ +/*	$OpenBSD: inffast.h,v 1.4 2003/12/16 22:33:02 henning Exp $	*/ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + +void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/lib/libz/inffixed.h b/lib/libz/inffixed.h new file mode 100644 index 0000000..be9fb24 --- /dev/null +++ b/lib/libz/inffixed.h @@ -0,0 +1,95 @@ +/*	$OpenBSD: inffixed.h,v 1.3 2003/12/16 22:33:02 henning Exp $	*/ +    /* inffixed.h -- table for decoding fixed codes +     * Generated automatically by makefixed(). +     */ + +    /* WARNING: this file should *not* be used by applications. It +       is part of the implementation of the compression library and +       is subject to change. Applications should only use zlib.h. +     */ + +    static const code lenfix[512] = { +        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, +        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, +        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, +        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, +        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, +        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, +        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, +        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, +        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, +        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, +        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, +        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, +        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, +        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, +        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, +        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, +        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, +        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, +        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, +        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, +        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, +        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, +        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, +        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, +        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, +        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, +        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, +        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, +        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, +        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, +        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, +        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, +        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, +        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, +        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, +        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, +        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, +        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, +        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, +        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, +        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, +        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, +        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, +        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, +        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, +        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, +        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, +        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, +        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, +        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, +        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, +        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, +        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, +        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, +        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, +        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, +        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, +        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, +        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, +        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, +        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, +        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, +        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, +        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, +        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, +        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, +        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, +        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, +        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, +        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, +        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, +        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, +        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, +        {0,9,255} +    }; + +    static const code distfix[32] = { +        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, +        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, +        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, +        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, +        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, +        {22,5,193},{64,5,0} +    }; diff --git a/lib/libz/inflate.c b/lib/libz/inflate.c new file mode 100644 index 0000000..37930a9 --- /dev/null +++ b/lib/libz/inflate.c @@ -0,0 +1,1447 @@ +/*	$OpenBSD: inflate.c,v 1.10 2019/06/01 11:39:57 jca Exp $	*/ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0    24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + *   creation of window when not needed, minimize use of window when it is + *   needed, make inffast.c even faster, implement gzip decoding, and to + *   improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1    25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2    4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + *   to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3    22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + *   buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4    1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common write == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + *   source file infback.c to provide a call-back interface to inflate for + *   programs like gzip and unzip -- uses window as output buffer to avoid + *   window copying + * + * 1.2.beta5    1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + *   input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6    4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + *   make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7    27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0        9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + *   for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + *   and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +#  ifndef BUILDFIXED +#    define BUILDFIXED +#  endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED +   void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, z_const unsigned char FAR *buf, +                              unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ +    struct inflate_state FAR *state; + +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; +    state = (struct inflate_state FAR *)strm->state; +    strm->total_in = strm->total_out = state->total = 0; +    strm->msg = Z_NULL; +    strm->adler = 1;        /* to support ill-conceived Java test suite */ +    state->mode = HEAD; +    state->last = 0; +    state->havedict = 0; +    state->dmax = 32768U; +    state->head = Z_NULL; +    state->wsize = 0; +    state->whave = 0; +    state->write = 0; +    state->hold = 0; +    state->bits = 0; +    state->lencode = state->distcode = state->next = state->codes; +    Tracev((stderr, "inflate: reset\n")); +    return Z_OK; +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ +    struct inflate_state FAR *state; + +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; +    state = (struct inflate_state FAR *)strm->state; +    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; +    value &= (1L << bits) - 1; +    state->hold += value << state->bits; +    state->bits += bits; +    return Z_OK; +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ +    struct inflate_state FAR *state; + +    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || +        stream_size != (int)(sizeof(z_stream))) +        return Z_VERSION_ERROR; +    if (strm == Z_NULL) return Z_STREAM_ERROR; +    strm->msg = Z_NULL;                 /* in case we return an error */ +    if (strm->zalloc == (alloc_func)0) { +        strm->zalloc = zcalloc; +        strm->opaque = (voidpf)0; +    } +    if (strm->zfree == (free_func)0) strm->zfree = zcfree; +    state = (struct inflate_state FAR *) +            ZALLOC(strm, 1, sizeof(struct inflate_state)); +    if (state == Z_NULL) return Z_MEM_ERROR; +    Tracev((stderr, "inflate: allocated\n")); +    strm->state = (struct internal_state FAR *)state; +    if (windowBits < 0) { +        state->wrap = 0; +        windowBits = -windowBits; +    } +    else { +        state->wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP +        if (windowBits < 48) windowBits &= 15; +#endif +    } +    if (windowBits < 8 || windowBits > 15) { +        ZFREE(strm, state); +        strm->state = Z_NULL; +        return Z_STREAM_ERROR; +    } +    state->wbits = (unsigned)windowBits; +    state->window = Z_NULL; +    return inflateReset(strm); +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ +    return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +/* +   Return state with length and distance decoding tables and index sizes set to +   fixed code decoding.  Normally this returns fixed tables from inffixed.h. +   If BUILDFIXED is defined, then instead this routine builds the tables the +   first time it's called, and returns those tables the first time and +   thereafter.  This reduces the size of the code by about 2K bytes, in +   exchange for a little execution time.  However, BUILDFIXED should not be +   used for threaded applications, since the rewriting of the tables and virgin +   may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED +    static int virgin = 1; +    static code *lenfix, *distfix; +    static code fixed[544]; + +    /* build fixed huffman tables if first call (may not be thread safe) */ +    if (virgin) { +        unsigned sym, bits; +        static code *next; + +        /* literal/length table */ +        sym = 0; +        while (sym < 144) state->lens[sym++] = 8; +        while (sym < 256) state->lens[sym++] = 9; +        while (sym < 280) state->lens[sym++] = 7; +        while (sym < 288) state->lens[sym++] = 8; +        next = fixed; +        lenfix = next; +        bits = 9; +        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + +        /* distance table */ +        sym = 0; +        while (sym < 32) state->lens[sym++] = 5; +        distfix = next; +        bits = 5; +        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + +        /* do this just once */ +        virgin = 0; +    } +#else /* !BUILDFIXED */ +#   include "inffixed.h" +#endif /* BUILDFIXED */ +    state->lencode = lenfix; +    state->lenbits = 9; +    state->distcode = distfix; +    state->distbits = 5; +} + +#ifdef MAKEFIXED +#include <stdio.h> + +/* +   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also +   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes +   those tables to stdout, which would be piped to inffixed.h.  A small program +   can simply call makefixed to do this: + +    void makefixed(void); + +    int main(void) +    { +        makefixed(); +        return 0; +    } + +   Then that can be linked with zlib built with MAKEFIXED defined and run: + +    a.out > inffixed.h + */ +void makefixed() +{ +    unsigned low, size; +    struct inflate_state state; + +    fixedtables(&state); +    puts("    /* inffixed.h -- table for decoding fixed codes"); +    puts("     * Generated automatically by makefixed()."); +    puts("     */"); +    puts(""); +    puts("    /* WARNING: this file should *not* be used by applications."); +    puts("       It is part of the implementation of this library and is"); +    puts("       subject to change. Applications should only use zlib.h."); +    puts("     */"); +    puts(""); +    size = 1U << 9; +    printf("    static const code lenfix[%u] = {", size); +    low = 0; +    for (;;) { +        if ((low % 7) == 0) printf("\n        "); +        printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, +               state.lencode[low].val); +        if (++low == size) break; +        putchar(','); +    } +    puts("\n    };"); +    size = 1U << 5; +    printf("\n    static const code distfix[%u] = {", size); +    low = 0; +    for (;;) { +        if ((low % 6) == 0) printf("\n        "); +        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, +               state.distcode[low].val); +        if (++low == size) break; +        putchar(','); +    } +    puts("\n    };"); +} +#endif /* MAKEFIXED */ + +/* +   Update the window with the last wsize (normally 32K) bytes written before +   returning.  If window does not exist yet, create it.  This is only called +   when a window is already in use, or when output has been written during this +   inflate call, but the end of the deflate stream has not been reached yet. +   It is also called to create a window for dictionary data when a dictionary +   is loaded. + +   Providing output buffers larger than 32K to inflate() should provide a speed +   advantage, since only the last 32K of output is copied to the sliding window +   upon return from inflate(), and since all distances after the first 32K of +   output will fall in the output data, making match copies simpler and faster. +   The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ +    struct inflate_state FAR *state; +    unsigned copy, dist; + +    state = (struct inflate_state FAR *)strm->state; + +    /* if it hasn't been done already, allocate space for the window */ +    if (state->window == Z_NULL) { +        state->window = (unsigned char FAR *) +                        ZALLOC(strm, 1U << state->wbits, +                               sizeof(unsigned char)); +        if (state->window == Z_NULL) return 1; +    } + +    /* if window not in use yet, initialize */ +    if (state->wsize == 0) { +        state->wsize = 1U << state->wbits; +        state->write = 0; +        state->whave = 0; +    } + +    /* copy state->wsize or less output bytes into the circular window */ +    copy = out - strm->avail_out; +    if (copy >= state->wsize) { +        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); +        state->write = 0; +        state->whave = state->wsize; +    } +    else { +        dist = state->wsize - state->write; +        if (dist > copy) dist = copy; +        zmemcpy(state->window + state->write, strm->next_out - copy, dist); +        copy -= dist; +        if (copy) { +            zmemcpy(state->window, strm->next_out - copy, copy); +            state->write = copy; +            state->whave = state->wsize; +        } +        else { +            state->write += dist; +            if (state->write == state->wsize) state->write = 0; +            if (state->whave < state->wsize) state->whave += dist; +        } +    } +    return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +#  define UPDATE(check, buf, len) \ +    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +#  define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +#  define CRC2(check, word) \ +    do { \ +        hbuf[0] = (unsigned char)(word); \ +        hbuf[1] = (unsigned char)((word) >> 8); \ +        check = crc32(check, hbuf, 2); \ +    } while (0) + +#  define CRC4(check, word) \ +    do { \ +        hbuf[0] = (unsigned char)(word); \ +        hbuf[1] = (unsigned char)((word) >> 8); \ +        hbuf[2] = (unsigned char)((word) >> 16); \ +        hbuf[3] = (unsigned char)((word) >> 24); \ +        check = crc32(check, hbuf, 4); \ +    } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ +    do { \ +        put = strm->next_out; \ +        left = strm->avail_out; \ +        next = strm->next_in; \ +        have = strm->avail_in; \ +        hold = state->hold; \ +        bits = state->bits; \ +    } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ +    do { \ +        strm->next_out = put; \ +        strm->avail_out = left; \ +        strm->next_in = next; \ +        strm->avail_in = have; \ +        state->hold = hold; \ +        state->bits = bits; \ +    } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ +    do { \ +        hold = 0; \ +        bits = 0; \ +    } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() +   if there is no input available. */ +#define PULLBYTE() \ +    do { \ +        if (have == 0) goto inf_leave; \ +        have--; \ +        hold += (unsigned long)(*next++) << bits; \ +        bits += 8; \ +    } while (0) + +/* Assure that there are at least n bits in the bit accumulator.  If there is +   not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ +    do { \ +        while (bits < (unsigned)(n)) \ +            PULLBYTE(); \ +    } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ +    ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ +    do { \ +        hold >>= (n); \ +        bits -= (unsigned)(n); \ +    } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ +    do { \ +        hold >>= bits & 7; \ +        bits -= bits & 7; \ +    } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ +    ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ +     (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* +   inflate() uses a state machine to process as much input data and generate as +   much output data as possible before returning.  The state machine is +   structured roughly as follows: + +    for (;;) switch (state) { +    ... +    case STATEn: +        if (not enough input data or output space to make progress) +            return; +        ... make progress ... +        state = STATEm; +        break; +    ... +    } + +   so when inflate() is called again, the same case is attempted again, and +   if the appropriate resources are provided, the machine proceeds to the +   next state.  The NEEDBITS() macro is usually the way the state evaluates +   whether it can proceed or should return.  NEEDBITS() does the return if +   the requested bits are not available.  The typical use of the BITS macros +   is: + +        NEEDBITS(n); +        ... do something with BITS(n) ... +        DROPBITS(n); + +   where NEEDBITS(n) either returns from inflate() if there isn't enough +   input left to load n bits into the accumulator, or it continues.  BITS(n) +   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops +   the low n bits off the accumulator.  INITBITS() clears the accumulator +   and sets the number of available bits to zero.  BYTEBITS() discards just +   enough bits to put the accumulator on a byte boundary.  After BYTEBITS() +   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + +   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return +   if there is no input available.  The decoding of variable length codes uses +   PULLBYTE() directly in order to pull just enough bytes to decode the next +   code, and no more. + +   Some states loop until they get enough input, making sure that enough +   state information is maintained to continue the loop where it left off +   if NEEDBITS() returns in the loop.  For example, want, need, and keep +   would all have to actually be part of the saved state in case NEEDBITS() +   returns: + +    case STATEw: +        while (want < need) { +            NEEDBITS(n); +            keep[want++] = BITS(n); +            DROPBITS(n); +        } +        state = STATEx; +    case STATEx: + +   As shown above, if the next state is also the next case, then the break +   is omitted. + +   A state may also return if there is not enough output space available to +   complete that state.  Those states are copying stored data, writing a +   literal byte, and copying a matching string. + +   When returning, a "goto inf_leave" is used to update the total counters, +   update the check value, and determine whether any progress has been made +   during that inflate() call in order to return the proper return code. +   Progress is defined as a change in either strm->avail_in or strm->avail_out. +   When there is a window, goto inf_leave will update the window with the last +   output written.  If a goto inf_leave occurs in the middle of decompression +   and there is no window currently, goto inf_leave will create one and copy +   output to the window for the next call of inflate(). + +   In this implementation, the flush parameter of inflate() only affects the +   return code (per zlib.h).  inflate() always writes as much as possible to +   strm->next_out, given the space available and the provided input--the effect +   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers +   the allocation of and copying into a sliding window until necessary, which +   provides the effect documented in zlib.h for Z_FINISH when the entire input +   stream available.  So the only thing the flush parameter actually does is: +   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it +   will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ +    struct inflate_state FAR *state; +    z_const unsigned char FAR *next;    /* next input */ +    unsigned char FAR *put;     /* next output */ +    unsigned have, left;        /* available input and output */ +    unsigned long hold;         /* bit buffer */ +    unsigned bits;              /* bits in bit buffer */ +    unsigned in, out;           /* save starting available input and output */ +    unsigned copy;              /* number of stored or match bytes to copy */ +    unsigned char FAR *from;    /* where to copy match bytes from */ +    code this;                  /* current decoding table entry */ +    code last;                  /* parent table entry */ +    unsigned len;               /* length to copy for repeats, bits to drop */ +    int ret;                    /* return code */ +#ifdef GUNZIP +    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */ +#endif +    static const unsigned short order[19] = /* permutation of code lengths */ +        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || +        (strm->next_in == Z_NULL && strm->avail_in != 0)) +        return Z_STREAM_ERROR; + +    state = (struct inflate_state FAR *)strm->state; +    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */ +    LOAD(); +    in = have; +    out = left; +    ret = Z_OK; +    for (;;) +        switch (state->mode) { +        case HEAD: +            if (state->wrap == 0) { +                state->mode = TYPEDO; +                break; +            } +            NEEDBITS(16); +#ifdef GUNZIP +            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */ +                state->check = crc32(0L, Z_NULL, 0); +                CRC2(state->check, hold); +                INITBITS(); +                state->mode = FLAGS; +                break; +            } +            state->flags = 0;           /* expect zlib header */ +            if (state->head != Z_NULL) +                state->head->done = -1; +            if (!(state->wrap & 1) ||   /* check if zlib header allowed */ +#else +            if ( +#endif +                ((BITS(8) << 8) + (hold >> 8)) % 31) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"incorrect header check"; +#endif +                state->mode = BAD; +                break; +            } +            if (BITS(4) != Z_DEFLATED) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"unknown compression method"; +#endif +                state->mode = BAD; +                break; +            } +            DROPBITS(4); +	    len = BITS(4) + 8; +	    if (len > state->wbits) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid window size"; +#endif +                state->mode = BAD; +                break; +            } +	    state->dmax = 1U << len; +            Tracev((stderr, "inflate:   zlib header ok\n")); +            strm->adler = state->check = adler32(0L, Z_NULL, 0); +            state->mode = hold & 0x200 ? DICTID : TYPE; +            INITBITS(); +            break; +#ifdef GUNZIP +        case FLAGS: +            NEEDBITS(16); +            state->flags = (int)(hold); +            if ((state->flags & 0xff) != Z_DEFLATED) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"unknown compression method"; +#endif +                state->mode = BAD; +                break; +            } +            if (state->flags & 0xe000) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"unknown header flags set"; +#endif +                state->mode = BAD; +                break; +            } +            if (state->head != Z_NULL) +                state->head->text = (int)((hold >> 8) & 1); +            if (state->flags & 0x0200) CRC2(state->check, hold); +            INITBITS(); +            state->mode = TIME; +        case TIME: +            NEEDBITS(32); +            if (state->head != Z_NULL) +                state->head->time = hold; +            if (state->flags & 0x0200) CRC4(state->check, hold); +            INITBITS(); +            state->mode = OS; +        case OS: +            NEEDBITS(16); +            if (state->head != Z_NULL) { +                state->head->xflags = (int)(hold & 0xff); +                state->head->os = (int)(hold >> 8); +            } +            if (state->flags & 0x0200) CRC2(state->check, hold); +            INITBITS(); +            state->mode = EXLEN; +        case EXLEN: +            if (state->flags & 0x0400) { +                NEEDBITS(16); +                state->length = (unsigned)(hold); +                if (state->head != Z_NULL) +                    state->head->extra_len = (unsigned)hold; +                if (state->flags & 0x0200) CRC2(state->check, hold); +                INITBITS(); +            } +            else if (state->head != Z_NULL) +                state->head->extra = Z_NULL; +            state->mode = EXTRA; +        case EXTRA: +            if (state->flags & 0x0400) { +                copy = state->length; +                if (copy > have) copy = have; +                if (copy) { +                    if (state->head != Z_NULL && +                        state->head->extra != Z_NULL) { +                        len = state->head->extra_len - state->length; +                        zmemcpy(state->head->extra + len, next, +                                len + copy > state->head->extra_max ? +                                state->head->extra_max - len : copy); +                    } +                    if (state->flags & 0x0200) +                        state->check = crc32(state->check, next, copy); +                    have -= copy; +                    next += copy; +                    state->length -= copy; +                } +                if (state->length) goto inf_leave; +            } +            state->length = 0; +            state->mode = NAME; +        case NAME: +            if (state->flags & 0x0800) { +                if (have == 0) goto inf_leave; +                copy = 0; +                do { +                    len = (unsigned)(next[copy++]); +                    if (state->head != Z_NULL && +                            state->head->name != Z_NULL && +                            state->length < state->head->name_max) +                        state->head->name[state->length++] = len; +                } while (len && copy < have); +                if (state->flags & 0x0200) +                    state->check = crc32(state->check, next, copy); +                have -= copy; +                next += copy; +                if (len) goto inf_leave; +            } +            else if (state->head != Z_NULL) +                state->head->name = Z_NULL; +            state->length = 0; +            state->mode = COMMENT; +        case COMMENT: +            if (state->flags & 0x1000) { +                if (have == 0) goto inf_leave; +                copy = 0; +                do { +                    len = (unsigned)(next[copy++]); +                    if (state->head != Z_NULL && +                            state->head->comment != Z_NULL && +                            state->length < state->head->comm_max) +                        state->head->comment[state->length++] = len; +                } while (len && copy < have); +                if (state->flags & 0x0200) +                    state->check = crc32(state->check, next, copy); +                have -= copy; +                next += copy; +                if (len) goto inf_leave; +            } +            else if (state->head != Z_NULL) +                state->head->comment = Z_NULL; +            state->mode = HCRC; +        case HCRC: +            if (state->flags & 0x0200) { +                NEEDBITS(16); +                if (hold != (state->check & 0xffff)) { +#ifdef SMALL   +		    strm->msg = "error"; +#else +                    strm->msg = (char *)"header crc mismatch"; +#endif +                    state->mode = BAD; +                    break; +                } +                INITBITS(); +            } +            if (state->head != Z_NULL) { +                state->head->hcrc = (int)((state->flags >> 9) & 1); +                state->head->done = 1; +            } +            strm->adler = state->check = crc32(0L, Z_NULL, 0); +            state->mode = TYPE; +            break; +#endif +        case DICTID: +            NEEDBITS(32); +            strm->adler = state->check = REVERSE(hold); +            INITBITS(); +            state->mode = DICT; +        case DICT: +            if (state->havedict == 0) { +                RESTORE(); +                return Z_NEED_DICT; +            } +            strm->adler = state->check = adler32(0L, Z_NULL, 0); +            state->mode = TYPE; +        case TYPE: +            if (flush == Z_BLOCK) goto inf_leave; +        case TYPEDO: +            if (state->last) { +                BYTEBITS(); +                state->mode = CHECK; +                break; +            } +            NEEDBITS(3); +            state->last = BITS(1); +            DROPBITS(1); +            switch (BITS(2)) { +            case 0:                             /* stored block */ +                Tracev((stderr, "inflate:     stored block%s\n", +                        state->last ? " (last)" : "")); +                state->mode = STORED; +                break; +            case 1:                             /* fixed block */ +                fixedtables(state); +                Tracev((stderr, "inflate:     fixed codes block%s\n", +                        state->last ? " (last)" : "")); +                state->mode = LEN;              /* decode codes */ +                break; +            case 2:                             /* dynamic block */ +                Tracev((stderr, "inflate:     dynamic codes block%s\n", +                        state->last ? " (last)" : "")); +                state->mode = TABLE; +                break; +            case 3: +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid block type"; +#endif +                state->mode = BAD; +            } +            DROPBITS(2); +            break; +        case STORED: +            BYTEBITS();                         /* go to byte boundary */ +            NEEDBITS(32); +            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid stored block lengths"; +#endif +                state->mode = BAD; +                break; +            } +            state->length = (unsigned)hold & 0xffff; +            Tracev((stderr, "inflate:       stored length %u\n", +                    state->length)); +            INITBITS(); +            state->mode = COPY; +        case COPY: +            copy = state->length; +            if (copy) { +                if (copy > have) copy = have; +                if (copy > left) copy = left; +                if (copy == 0) goto inf_leave; +                zmemcpy(put, next, copy); +                have -= copy; +                next += copy; +                left -= copy; +                put += copy; +                state->length -= copy; +                break; +            } +            Tracev((stderr, "inflate:       stored end\n")); +            state->mode = TYPE; +            break; +        case TABLE: +            NEEDBITS(14); +            state->nlen = BITS(5) + 257; +            DROPBITS(5); +            state->ndist = BITS(5) + 1; +            DROPBITS(5); +            state->ncode = BITS(4) + 4; +            DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND +            if (state->nlen > 286 || state->ndist > 30) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"too many length or distance symbols"; +#endif +                state->mode = BAD; +                break; +            } +#endif +            Tracev((stderr, "inflate:       table sizes ok\n")); +            state->have = 0; +            state->mode = LENLENS; +        case LENLENS: +            while (state->have < state->ncode) { +                NEEDBITS(3); +                state->lens[order[state->have++]] = (unsigned short)BITS(3); +                DROPBITS(3); +            } +            while (state->have < 19) +                state->lens[order[state->have++]] = 0; +            state->next = state->codes; +            state->lencode = (code const FAR *)(state->next); +            state->lenbits = 7; +            ret = inflate_table(CODES, state->lens, 19, &(state->next), +                                &(state->lenbits), state->work); +            if (ret) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid code lengths set"; +#endif +                state->mode = BAD; +                break; +            } +            Tracev((stderr, "inflate:       code lengths ok\n")); +            state->have = 0; +            state->mode = CODELENS; +        case CODELENS: +            while (state->have < state->nlen + state->ndist) { +                for (;;) { +                    this = state->lencode[BITS(state->lenbits)]; +                    if ((unsigned)(this.bits) <= bits) break; +                    PULLBYTE(); +                } +                if (this.val < 16) { +                    NEEDBITS(this.bits); +                    DROPBITS(this.bits); +                    state->lens[state->have++] = this.val; +                } +                else { +                    if (this.val == 16) { +                        NEEDBITS(this.bits + 2); +                        DROPBITS(this.bits); +                        if (state->have == 0) { +#ifdef SMALL   +			    strm->msg = "error"; +#else +                            strm->msg = (char *)"invalid bit length repeat"; +#endif +                            state->mode = BAD; +                            break; +                        } +                        len = state->lens[state->have - 1]; +                        copy = 3 + BITS(2); +                        DROPBITS(2); +                    } +                    else if (this.val == 17) { +                        NEEDBITS(this.bits + 3); +                        DROPBITS(this.bits); +                        len = 0; +                        copy = 3 + BITS(3); +                        DROPBITS(3); +                    } +                    else { +                        NEEDBITS(this.bits + 7); +                        DROPBITS(this.bits); +                        len = 0; +                        copy = 11 + BITS(7); +                        DROPBITS(7); +                    } +                    if (state->have + copy > state->nlen + state->ndist) { +#ifdef SMALL   +			strm->msg = "error"; +#else +                        strm->msg = (char *)"invalid bit length repeat"; +#endif +                        state->mode = BAD; +                        break; +                    } +                    while (copy--) +                        state->lens[state->have++] = (unsigned short)len; +                } +            } + +            /* handle error breaks in while */ +            if (state->mode == BAD) break; + +            /* build code tables */ +            state->next = state->codes; +            state->lencode = (code const FAR *)(state->next); +            state->lenbits = 9; +            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), +                                &(state->lenbits), state->work); +            if (ret) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid literal/lengths set"; +#endif +                state->mode = BAD; +                break; +            } +            state->distcode = (code const FAR *)(state->next); +            state->distbits = 6; +            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, +                            &(state->next), &(state->distbits), state->work); +            if (ret) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid distances set"; +#endif +                state->mode = BAD; +                break; +            } +            Tracev((stderr, "inflate:       codes ok\n")); +            state->mode = LEN; +        case LEN: +#ifndef SLOW +            if (have >= 6 && left >= 258) { +                RESTORE(); +                inflate_fast(strm, out); +                LOAD(); +                break; +            } +#endif +            for (;;) { +                this = state->lencode[BITS(state->lenbits)]; +                if ((unsigned)(this.bits) <= bits) break; +                PULLBYTE(); +            } +            if (this.op && (this.op & 0xf0) == 0) { +                last = this; +                for (;;) { +                    this = state->lencode[last.val + +                            (BITS(last.bits + last.op) >> last.bits)]; +                    if ((unsigned)(last.bits + this.bits) <= bits) break; +                    PULLBYTE(); +                } +                DROPBITS(last.bits); +            } +            DROPBITS(this.bits); +            state->length = (unsigned)this.val; +            if ((int)(this.op) == 0) { +                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? +                        "inflate:         literal '%c'\n" : +                        "inflate:         literal 0x%02x\n", this.val)); +                state->mode = LIT; +                break; +            } +            if (this.op & 32) { +                Tracevv((stderr, "inflate:         end of block\n")); +                state->mode = TYPE; +                break; +            } +            if (this.op & 64) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid literal/length code"; +#endif +                state->mode = BAD; +                break; +            } +            state->extra = (unsigned)(this.op) & 15; +            state->mode = LENEXT; +        case LENEXT: +            if (state->extra) { +                NEEDBITS(state->extra); +                state->length += BITS(state->extra); +                DROPBITS(state->extra); +            } +            Tracevv((stderr, "inflate:         length %u\n", state->length)); +            state->mode = DIST; +        case DIST: +            for (;;) { +                this = state->distcode[BITS(state->distbits)]; +                if ((unsigned)(this.bits) <= bits) break; +                PULLBYTE(); +            } +            if ((this.op & 0xf0) == 0) { +                last = this; +                for (;;) { +                    this = state->distcode[last.val + +                            (BITS(last.bits + last.op) >> last.bits)]; +                    if ((unsigned)(last.bits + this.bits) <= bits) break; +                    PULLBYTE(); +                } +                DROPBITS(last.bits); +            } +            DROPBITS(this.bits); +            if (this.op & 64) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid distance code"; +#endif +                state->mode = BAD; +                break; +            } +            state->offset = (unsigned)this.val; +            state->extra = (unsigned)(this.op) & 15; +            state->mode = DISTEXT; +        case DISTEXT: +            if (state->extra) { +                NEEDBITS(state->extra); +                state->offset += BITS(state->extra); +                DROPBITS(state->extra); +            } +#ifdef INFLATE_STRICT +            if (state->offset > state->dmax) { +                strm->msg = (char *)"invalid distance too far back"; +                state->mode = BAD; +                break; +            } +#endif +            if (state->offset > state->whave + out - left) { +#ifdef SMALL   +		strm->msg = "error"; +#else +                strm->msg = (char *)"invalid distance too far back"; +#endif +                state->mode = BAD; +                break; +            } +            Tracevv((stderr, "inflate:         distance %u\n", state->offset)); +            state->mode = MATCH; +        case MATCH: +            if (left == 0) goto inf_leave; +            copy = out - left; +            if (state->offset > copy) {         /* copy from window */ +                copy = state->offset - copy; +                if (copy > state->write) { +                    copy -= state->write; +                    from = state->window + (state->wsize - copy); +                } +                else +                    from = state->window + (state->write - copy); +                if (copy > state->length) copy = state->length; +            } +            else {                              /* copy from output */ +                from = put - state->offset; +                copy = state->length; +            } +            if (copy > left) copy = left; +            left -= copy; +            state->length -= copy; +            do { +                *put++ = *from++; +            } while (--copy); +            if (state->length == 0) state->mode = LEN; +            break; +        case LIT: +            if (left == 0) goto inf_leave; +            *put++ = (unsigned char)(state->length); +            left--; +            state->mode = LEN; +            break; +        case CHECK: +            if (state->wrap) { +                NEEDBITS(32); +                out -= left; +                strm->total_out += out; +                state->total += out; +                if (out) +                    strm->adler = state->check = +                        UPDATE(state->check, put - out, out); +                out = left; +                if (( +#ifdef GUNZIP +                     state->flags ? hold : +#endif +                     REVERSE(hold)) != state->check) { +#ifdef SMALL   +		    strm->msg = "error"; +#else +                    strm->msg = (char *)"incorrect data check"; +#endif +                    state->mode = BAD; +                    break; +                } +                INITBITS(); +                Tracev((stderr, "inflate:   check matches trailer\n")); +            } +#ifdef GUNZIP +            state->mode = LENGTH; +        case LENGTH: +            if (state->wrap && state->flags) { +                NEEDBITS(32); +                if (hold != (state->total & 0xffffffffUL)) { +#ifdef SMALL   +		    strm->msg = "error"; +#else +                    strm->msg = (char *)"incorrect length check"; +#endif +                    state->mode = BAD; +                    break; +                } +                INITBITS(); +                Tracev((stderr, "inflate:   length matches trailer\n")); +            } +#endif +            state->mode = DONE; +        case DONE: +            ret = Z_STREAM_END; +            goto inf_leave; +        case BAD: +            ret = Z_DATA_ERROR; +            goto inf_leave; +        case MEM: +            return Z_MEM_ERROR; +        case SYNC: +        default: +            return Z_STREAM_ERROR; +        } + +    /* +       Return from inflate(), updating the total counts and the check value. +       If there was no progress during the inflate() call, return a buffer +       error.  Call updatewindow() to create and/or update the window state. +       Note: a memory error from inflate() is non-recoverable. +     */ +  inf_leave: +    RESTORE(); +    if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) +        if (updatewindow(strm, out)) { +            state->mode = MEM; +            return Z_MEM_ERROR; +        } +    in -= strm->avail_in; +    out -= strm->avail_out; +    strm->total_in += in; +    strm->total_out += out; +    state->total += out; +    if (state->wrap && out) +        strm->adler = state->check = +            UPDATE(state->check, strm->next_out - out, out); +    strm->data_type = state->bits + (state->last ? 64 : 0) + +                      (state->mode == TYPE ? 128 : 0); +    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) +        ret = Z_BUF_ERROR; +    return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ +    struct inflate_state FAR *state; +    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) +        return Z_STREAM_ERROR; +    state = (struct inflate_state FAR *)strm->state; +    if (state->window != Z_NULL) ZFREE(strm, state->window); +    ZFREE(strm, strm->state); +    strm->state = Z_NULL; +    Tracev((stderr, "inflate: end\n")); +    return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ +    struct inflate_state FAR *state; +    unsigned long id; + +    /* check state */ +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; +    state = (struct inflate_state FAR *)strm->state; +    if (state->wrap != 0 && state->mode != DICT) +        return Z_STREAM_ERROR; + +    /* check for correct dictionary id */ +    if (state->mode == DICT) { +        id = adler32(0L, Z_NULL, 0); +        id = adler32(id, dictionary, dictLength); +        if (id != state->check) +            return Z_DATA_ERROR; +    } + +    /* copy dictionary to window */ +    if (updatewindow(strm, strm->avail_out)) { +        state->mode = MEM; +        return Z_MEM_ERROR; +    } +    if (dictLength > state->wsize) { +        zmemcpy(state->window, dictionary + dictLength - state->wsize, +                state->wsize); +        state->whave = state->wsize; +    } +    else { +        zmemcpy(state->window + state->wsize - dictLength, dictionary, +                dictLength); +        state->whave = dictLength; +    } +    state->havedict = 1; +    Tracev((stderr, "inflate:   dictionary set\n")); +    return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ +    struct inflate_state FAR *state; + +    /* check state */ +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; +    state = (struct inflate_state FAR *)strm->state; +    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + +    /* save header structure */ +    state->head = head; +    head->done = 0; +    return Z_OK; +} + +/* +   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found +   or when out of input.  When called, *have is the number of pattern bytes +   found in order so far, in 0..3.  On return *have is updated to the new +   state.  If on return *have equals four, then the pattern was found and the +   return value is how many bytes were read including the last byte of the +   pattern.  If *have is less than four, then the pattern has not been found +   yet and the return value is len.  In the latter case, syncsearch() can be +   called again with more data and the *have state.  *have is initialized to +   zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +z_const unsigned char FAR *buf; +unsigned len; +{ +    unsigned got; +    unsigned next; + +    got = *have; +    next = 0; +    while (next < len && got < 4) { +        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) +            got++; +        else if (buf[next]) +            got = 0; +        else +            got = 4 - got; +        next++; +    } +    *have = got; +    return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ +    unsigned len;               /* number of bytes to look at or looked at */ +    unsigned long in, out;      /* temporary to save total_in and total_out */ +    unsigned char buf[4];       /* to restore bit buffer to byte string */ +    struct inflate_state FAR *state; + +    /* check parameters */ +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; +    state = (struct inflate_state FAR *)strm->state; +    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + +    /* if first time, start search in bit buffer */ +    if (state->mode != SYNC) { +        state->mode = SYNC; +        state->hold <<= state->bits & 7; +        state->bits -= state->bits & 7; +        len = 0; +        while (state->bits >= 8) { +            buf[len++] = (unsigned char)(state->hold); +            state->hold >>= 8; +            state->bits -= 8; +        } +        state->have = 0; +        syncsearch(&(state->have), buf, len); +    } + +    /* search available input */ +    len = syncsearch(&(state->have), strm->next_in, strm->avail_in); +    strm->avail_in -= len; +    strm->next_in += len; +    strm->total_in += len; + +    /* return no joy or set up to restart inflate() on a new block */ +    if (state->have != 4) return Z_DATA_ERROR; +    in = strm->total_in;  out = strm->total_out; +    inflateReset(strm); +    strm->total_in = in;  strm->total_out = out; +    state->mode = TYPE; +    return Z_OK; +} + +/* +   Returns true if inflate is currently at the end of a block generated by +   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP +   implementation to provide an additional safety check. PPP uses +   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored +   block. When decompressing, PPP checks that at the end of input packet, +   inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ +    struct inflate_state FAR *state; + +    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; +    state = (struct inflate_state FAR *)strm->state; +    return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ +    struct inflate_state FAR *state; +    struct inflate_state FAR *copy; +    unsigned char FAR *window; +    unsigned wsize; + +    /* check input */ +    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || +        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) +        return Z_STREAM_ERROR; +    state = (struct inflate_state FAR *)source->state; + +    /* allocate space */ +    copy = (struct inflate_state FAR *) +           ZALLOC(source, 1, sizeof(struct inflate_state)); +    if (copy == Z_NULL) return Z_MEM_ERROR; +    window = Z_NULL; +    if (state->window != Z_NULL) { +        window = (unsigned char FAR *) +                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); +        if (window == Z_NULL) { +            ZFREE(source, copy); +            return Z_MEM_ERROR; +        } +    } + +    /* copy state */ +    zmemcpy(dest, source, sizeof(z_stream)); +    zmemcpy(copy, state, sizeof(struct inflate_state)); +    if (state->lencode >= state->codes && +        state->lencode <= state->codes + ENOUGH - 1) { +        copy->lencode = copy->codes + (state->lencode - state->codes); +        copy->distcode = copy->codes + (state->distcode - state->codes); +    } +    copy->next = copy->codes + (state->next - state->codes); +    if (window != Z_NULL) { +        wsize = 1U << state->wbits; +        zmemcpy(window, state->window, wsize); +    } +    copy->window = window; +    dest->state = (struct internal_state FAR *)copy; +    return Z_OK; +} diff --git a/lib/libz/inflate.h b/lib/libz/inflate.h new file mode 100644 index 0000000..07bd3e7 --- /dev/null +++ b/lib/libz/inflate.h @@ -0,0 +1,115 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and +   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in +   the crc code when it is not needed.  For shared libraries, gzip decoding +   should be left enabled. */ +#ifndef NO_GZIP +#  define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { +    HEAD,       /* i: waiting for magic header */ +    FLAGS,      /* i: waiting for method and flags (gzip) */ +    TIME,       /* i: waiting for modification time (gzip) */ +    OS,         /* i: waiting for extra flags and operating system (gzip) */ +    EXLEN,      /* i: waiting for extra length (gzip) */ +    EXTRA,      /* i: waiting for extra bytes (gzip) */ +    NAME,       /* i: waiting for end of file name (gzip) */ +    COMMENT,    /* i: waiting for end of comment (gzip) */ +    HCRC,       /* i: waiting for header crc (gzip) */ +    DICTID,     /* i: waiting for dictionary check value */ +    DICT,       /* waiting for inflateSetDictionary() call */ +        TYPE,       /* i: waiting for type bits, including last-flag bit */ +        TYPEDO,     /* i: same, but skip check to exit inflate on new block */ +        STORED,     /* i: waiting for stored size (length and complement) */ +        COPY,       /* i/o: waiting for input or output to copy stored block */ +        TABLE,      /* i: waiting for dynamic block table lengths */ +        LENLENS,    /* i: waiting for code length code lengths */ +        CODELENS,   /* i: waiting for length/lit and distance code lengths */ +            LEN,        /* i: waiting for length/lit code */ +            LENEXT,     /* i: waiting for length extra bits */ +            DIST,       /* i: waiting for distance code */ +            DISTEXT,    /* i: waiting for distance extra bits */ +            MATCH,      /* o: waiting for output space to copy string */ +            LIT,        /* o: waiting for output space to write literal */ +    CHECK,      /* i: waiting for 32-bit check value */ +    LENGTH,     /* i: waiting for 32-bit length (gzip) */ +    DONE,       /* finished check, done -- remain here until reset */ +    BAD,        /* got a data error -- remain here until reset */ +    MEM,        /* got an inflate() memory error -- remain here until reset */ +    SYNC        /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* +    State transitions between above modes - + +    (most modes can go to the BAD or MEM mode -- not shown for clarity) + +    Process header: +        HEAD -> (gzip) or (zlib) +        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME +        NAME -> COMMENT -> HCRC -> TYPE +        (zlib) -> DICTID or TYPE +        DICTID -> DICT -> TYPE +    Read deflate blocks: +            TYPE -> STORED or TABLE or LEN or CHECK +            STORED -> COPY -> TYPE +            TABLE -> LENLENS -> CODELENS -> LEN +    Read deflate codes: +                LEN -> LENEXT or LIT or TYPE +                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN +                LIT -> LEN +    Process trailer: +        CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls.  Approximately 7K bytes. */ +struct inflate_state { +    inflate_mode mode;          /* current inflate mode */ +    int last;                   /* true if processing last block */ +    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */ +    int havedict;               /* true if dictionary provided */ +    int flags;                  /* gzip header method and flags (0 if zlib) */ +    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */ +    unsigned long check;        /* protected copy of check value */ +    unsigned long total;        /* protected copy of output count */ +    gz_headerp head;            /* where to save gzip header information */ +        /* sliding window */ +    unsigned wbits;             /* log base 2 of requested window size */ +    unsigned wsize;             /* window size or zero if not using window */ +    unsigned whave;             /* valid bytes in the window */ +    unsigned write;             /* window write index */ +    unsigned char FAR *window;  /* allocated sliding window, if needed */ +        /* bit accumulator */ +    unsigned long hold;         /* input bit accumulator */ +    unsigned bits;              /* number of bits in "in" */ +        /* for string and stored block copying */ +    unsigned length;            /* literal or length of data to copy */ +    unsigned offset;            /* distance back to copy string from */ +        /* for table and code decoding */ +    unsigned extra;             /* extra bits needed */ +        /* fixed and dynamic code tables */ +    code const FAR *lencode;    /* starting table for length/literal codes */ +    code const FAR *distcode;   /* starting table for distance codes */ +    unsigned lenbits;           /* index bits for lencode */ +    unsigned distbits;          /* index bits for distcode */ +        /* dynamic table building */ +    unsigned ncode;             /* number of code length code lengths */ +    unsigned nlen;              /* number of length code lengths */ +    unsigned ndist;             /* number of distance code lengths */ +    unsigned have;              /* number of code lengths in lens[] */ +    code FAR *next;             /* next available space in codes[] */ +    unsigned short lens[320];   /* temporary storage for code lengths */ +    unsigned short work[288];   /* work area for code table building */ +    code codes[ENOUGH];         /* space for code tables */ +}; diff --git a/lib/libz/inftrees.c b/lib/libz/inftrees.c new file mode 100644 index 0000000..0b879cd --- /dev/null +++ b/lib/libz/inftrees.c @@ -0,0 +1,328 @@ +/*	$OpenBSD: inftrees.c,v 1.9 2009/10/27 23:59:31 deraadt Exp $	*/ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +/* +  If you use the zlib library in a product, an acknowledgment is welcome +  in the documentation of your product. If for some reason you cannot +  include such an acknowledgment, I would appreciate that you keep this +  copyright string in the executable of your product. + */ + +/* +   Build a set of tables to decode the provided canonical Huffman code. +   The code lengths are lens[0..codes-1].  The result starts at *table, +   whose indices are 0..2^bits-1.  work is a writable array of at least +   lens shorts, which is used as a work area.  type is the type of code +   to be generated, CODES, LENS, or DISTS.  On return, zero is success, +   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table +   on return points to the next available entry's address.  bits is the +   requested root table index bits, and on return it is the actual root +   table index bits.  It will differ if the request is greater than the +   longest code or if it is less than the shortest code. + */ +int inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ +    unsigned len;               /* a code's length in bits */ +    unsigned sym;               /* index of code symbols */ +    unsigned min, max;          /* minimum and maximum code lengths */ +    unsigned root;              /* number of index bits for root table */ +    unsigned curr;              /* number of index bits for current table */ +    unsigned drop;              /* code bits to drop for sub-table */ +    int left;                   /* number of prefix codes available */ +    unsigned used;              /* code entries in table used */ +    unsigned huff;              /* Huffman code */ +    unsigned incr;              /* for incrementing code, index */ +    unsigned fill;              /* index for replicating entries */ +    unsigned low;               /* low bits for current root entry */ +    unsigned mask;              /* mask for low root bits */ +    code this;                  /* table entry for duplication */ +    code FAR *next;             /* next available space in table */ +    const unsigned short FAR *base;     /* base value table to use */ +    const unsigned short FAR *extra;    /* extra bits table to use */ +    int end;                    /* use base and extra for symbol > end */ +    unsigned short count[MAXBITS+1];    /* number of codes of each length */ +    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */ +    static const unsigned short lbase[31] = { /* Length codes 257..285 base */ +        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, +        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; +    static const unsigned short lext[31] = { /* Length codes 257..285 extra */ +        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, +        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; +    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ +        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, +        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, +        8193, 12289, 16385, 24577, 0, 0}; +    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ +        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, +        23, 23, 24, 24, 25, 25, 26, 26, 27, 27, +        28, 28, 29, 29, 64, 64}; + +    /* +       Process a set of code lengths to create a canonical Huffman code.  The +       code lengths are lens[0..codes-1].  Each length corresponds to the +       symbols 0..codes-1.  The Huffman code is generated by first sorting the +       symbols by length from short to long, and retaining the symbol order +       for codes with equal lengths.  Then the code starts with all zero bits +       for the first code of the shortest length, and the codes are integer +       increments for the same length, and zeros are appended as the length +       increases.  For the deflate format, these bits are stored backwards +       from their more natural integer increment ordering, and so when the +       decoding tables are built in the large loop below, the integer codes +       are incremented backwards. + +       This routine assumes, but does not check, that all of the entries in +       lens[] are in the range 0..MAXBITS.  The caller must assure this. +       1..MAXBITS is interpreted as that code length.  zero means that that +       symbol does not occur in this code. + +       The codes are sorted by computing a count of codes for each length, +       creating from that a table of starting indices for each length in the +       sorted table, and then entering the symbols in order in the sorted +       table.  The sorted table is work[], with that space being provided by +       the caller. + +       The length counts are used for other purposes as well, i.e. finding +       the minimum and maximum length codes, determining if there are any +       codes at all, checking for a valid set of lengths, and looking ahead +       at length counts to determine sub-table sizes when building the +       decoding tables. +     */ + +    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ +    for (len = 0; len <= MAXBITS; len++) +        count[len] = 0; +    for (sym = 0; sym < codes; sym++) +        count[lens[sym]]++; + +    /* bound code lengths, force root to be within code lengths */ +    root = *bits; +    for (max = MAXBITS; max >= 1; max--) +        if (count[max] != 0) break; +    if (root > max) root = max; +    if (max == 0) {                     /* no symbols to code at all */ +        this.op = (unsigned char)64;    /* invalid code marker */ +        this.bits = (unsigned char)1; +        this.val = (unsigned short)0; +        *(*table)++ = this;             /* make a table to force an error */ +        *(*table)++ = this; +        *bits = 1; +        return 0;     /* no symbols, but wait for decoding to report error */ +    } +    for (min = 1; min <= MAXBITS; min++) +        if (count[min] != 0) break; +    if (root < min) root = min; + +    /* check for an over-subscribed or incomplete set of lengths */ +    left = 1; +    for (len = 1; len <= MAXBITS; len++) { +        left <<= 1; +        left -= count[len]; +        if (left < 0) return -1;        /* over-subscribed */ +    } +    if (left > 0 && (type == CODES || max != 1)) +        return -1;                      /* incomplete set */ + +    /* generate offsets into symbol table for each length for sorting */ +    offs[1] = 0; +    for (len = 1; len < MAXBITS; len++) +        offs[len + 1] = offs[len] + count[len]; + +    /* sort symbols by length, by symbol order within each length */ +    for (sym = 0; sym < codes; sym++) +        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + +    /* +       Create and fill in decoding tables.  In this loop, the table being +       filled is at next and has curr index bits.  The code being used is huff +       with length len.  That code is converted to an index by dropping drop +       bits off of the bottom.  For codes where len is less than drop + curr, +       those top drop + curr - len bits are incremented through all values to +       fill the table with replicated entries. + +       root is the number of index bits for the root table.  When len exceeds +       root, sub-tables are created pointed to by the root entry with an index +       of the low root bits of huff.  This is saved in low to check for when a +       new sub-table should be started.  drop is zero when the root table is +       being filled, and drop is root when sub-tables are being filled. + +       When a new sub-table is needed, it is necessary to look ahead in the +       code lengths to determine what size sub-table is needed.  The length +       counts are used for this, and so count[] is decremented as codes are +       entered in the tables. + +       used keeps track of how many table entries have been allocated from the +       provided *table space.  It is checked when a LENS table is being made +       against the space in *table, ENOUGH, minus the maximum space needed by +       the worst case distance code, MAXD.  This should never happen, but the +       sufficiency of ENOUGH has not been proven exhaustively, hence the check. +       This assumes that when type == LENS, bits == 9. + +       sym increments through all symbols, and the loop terminates when +       all codes of length max, i.e. all codes, have been processed.  This +       routine permits incomplete codes, so another loop after this one fills +       in the rest of the decoding tables with invalid code markers. +     */ + +    /* set up for code type */ +    switch (type) { +    case CODES: +        base = extra = work;    /* dummy value--not used */ +        end = 19; +        break; +    case LENS: +        base = lbase; +        base -= 257; +        extra = lext; +        extra -= 257; +        end = 256; +        break; +    default:            /* DISTS */ +        base = dbase; +        extra = dext; +        end = -1; +    } + +    /* initialize state for loop */ +    huff = 0;                   /* starting code */ +    sym = 0;                    /* starting code symbol */ +    len = min;                  /* starting code length */ +    next = *table;              /* current table to fill in */ +    curr = root;                /* current table index bits */ +    drop = 0;                   /* current bits to drop from code for index */ +    low = (unsigned)(-1);       /* trigger new sub-table when len > root */ +    used = 1U << root;          /* use root table entries */ +    mask = used - 1;            /* mask for comparing low */ + +    /* check available table space */ +    if (type == LENS && used >= ENOUGH - MAXD) +        return 1; + +    /* process all codes and make table entries */ +    for (;;) { +        /* create table entry */ +        this.bits = (unsigned char)(len - drop); +        if ((int)(work[sym]) < end) { +            this.op = (unsigned char)0; +            this.val = work[sym]; +        } +        else if ((int)(work[sym]) > end) { +            this.op = (unsigned char)(extra[work[sym]]); +            this.val = base[work[sym]]; +        } +        else { +            this.op = (unsigned char)(32 + 64);         /* end of block */ +            this.val = 0; +        } + +        /* replicate for those indices with low len bits equal to huff */ +        incr = 1U << (len - drop); +        fill = 1U << curr; +        min = fill;                 /* save offset to next table */ +        do { +            fill -= incr; +            next[(huff >> drop) + fill] = this; +        } while (fill != 0); + +        /* backwards increment the len-bit code huff */ +        incr = 1U << (len - 1); +        while (huff & incr) +            incr >>= 1; +        if (incr != 0) { +            huff &= incr - 1; +            huff += incr; +        } +        else +            huff = 0; + +        /* go to next symbol, update count, len */ +        sym++; +        if (--(count[len]) == 0) { +            if (len == max) break; +            len = lens[work[sym]]; +        } + +        /* create new sub-table if needed */ +        if (len > root && (huff & mask) != low) { +            /* if first time, transition to sub-tables */ +            if (drop == 0) +                drop = root; + +            /* increment past last table */ +            next += min;            /* here min is 1 << curr */ + +            /* determine length of next table */ +            curr = len - drop; +            left = (int)(1 << curr); +            while (curr + drop < max) { +                left -= count[curr + drop]; +                if (left <= 0) break; +                curr++; +                left <<= 1; +            } + +            /* check for enough space */ +            used += 1U << curr; +            if (type == LENS && used >= ENOUGH - MAXD) +                return 1; + +            /* point entry in root table to sub-table */ +            low = huff & mask; +            (*table)[low].op = (unsigned char)curr; +            (*table)[low].bits = (unsigned char)root; +            (*table)[low].val = (unsigned short)(next - *table); +        } +    } + +    /* +       Fill in rest of table for incomplete codes.  This loop is similar to the +       loop above in incrementing huff for table indices.  It is assumed that +       len is equal to curr + drop, so there is no loop needed to increment +       through high index bits.  When the current sub-table is filled, the loop +       drops back to the root table to fill in any remaining entries there. +     */ +    this.op = (unsigned char)64;                /* invalid code marker */ +    this.bits = (unsigned char)(len - drop); +    this.val = (unsigned short)0; +    while (huff != 0) { +        /* when done with sub-table, drop back to root table */ +        if (drop != 0 && (huff & mask) != low) { +            drop = 0; +            len = root; +            next = *table; +            this.bits = (unsigned char)len; +        } + +        /* put invalid code marker in table */ +        next[huff >> drop] = this; + +        /* backwards increment the len-bit code huff */ +        incr = 1U << (len - 1); +        while (huff & incr) +            incr >>= 1; +        if (incr != 0) { +            huff &= incr - 1; +            huff += incr; +        } +        else +            huff = 0; +    } + +    /* set return parameters */ +    *table += used; +    *bits = root; +    return 0; +} diff --git a/lib/libz/inftrees.h b/lib/libz/inftrees.h new file mode 100644 index 0000000..e032c6b --- /dev/null +++ b/lib/libz/inftrees.h @@ -0,0 +1,56 @@ +/*	$OpenBSD: inftrees.h,v 1.5 2005/07/20 15:56:41 millert Exp $	*/ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables.  Each entry provides either the +   information needed to do the operation requested by the code that +   indexed that table entry, or it provides a pointer to another +   table that indexes more bits of the code.  op indicates whether +   the entry is a pointer to another table, a literal, a length or +   distance, an end-of-block, or an invalid code.  For a table +   pointer, the low four bits of op is the number of index bits of +   that table.  For a length or distance, the low four bits of op +   is the number of extra bits to get after the code.  bits is +   the number of bits in this code or part of the code to drop off +   of the bit buffer.  val is the actual byte to output in the case +   of a literal, the base length or distance, or the offset from +   the current table to the next table.  Each entry is four bytes. */ +typedef struct { +    unsigned char op;           /* operation, extra bits, table bits */ +    unsigned char bits;         /* bits in this part of the code */ +    unsigned short val;         /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): +    00000000 - literal +    0000tttt - table link, tttt != 0 is the number of table index bits +    0001eeee - length or distance, eeee is the number of extra bits +    01100000 - end of block +    01000000 - invalid code + */ + +/* Maximum size of dynamic tree.  The maximum found in a long but non- +   exhaustive search was 1444 code structures (852 for length/literals +   and 592 for distances, the latter actually the result of an +   exhaustive search).  The true maximum is not known, but the value +   below is more than safe. */ +#define ENOUGH 2048 +#define MAXD 592 + +/* Type of code to build for inftable() */ +typedef enum { +    CODES, +    LENS, +    DISTS +} codetype; + +extern int inflate_table OF((codetype type, unsigned short FAR *lens, +                             unsigned codes, code FAR * FAR *table, +                             unsigned FAR *bits, unsigned short FAR *work)); diff --git a/lib/libz/shlib_version b/lib/libz/shlib_version new file mode 100644 index 0000000..3066b97 --- /dev/null +++ b/lib/libz/shlib_version @@ -0,0 +1,2 @@ +major=5 +minor=0 diff --git a/lib/libz/trees.c b/lib/libz/trees.c new file mode 100644 index 0000000..c163626 --- /dev/null +++ b/lib/libz/trees.c @@ -0,0 +1,1219 @@ +/*	$OpenBSD: trees.c,v 1.8 2005/07/20 15:56:41 millert Exp $	*/ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2005 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + *  ALGORITHM + * + *      The "deflation" process uses several Huffman trees. The more + *      common source values are represented by shorter bit sequences. + * + *      Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values).  The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + *  REFERENCES + * + *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + *      Storer, James A. + *          Data Compression:  Methods and Theory, pp. 49-50. + *          Computer Science Press, 1988.  ISBN 0-7167-8156-5. + * + *      Sedgewick, R. + *          Algorithms, p290. + *          Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +#  include <ctype.h> +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6      16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10    17 +/* repeat a zero length 3-10 times  (3 bits of repeat count) */ + +#define REPZ_11_138  18 +/* repeat a zero length 11-138 times  (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ +   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ +   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ +   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] +   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN  512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +#  include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { +    const ct_data *static_tree;  /* static tree or NULL */ +    const intf *extra_bits;      /* extra bits for each code or NULL */ +    int     extra_base;          /* base index for extra_bits */ +    int     elems;               /* max number of elements in the tree */ +    int     max_length;          /* max bit length for the codes */ +}; + +local static_tree_desc  static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc  static_d_desc = +{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS}; + +local static_tree_desc  static_bl_desc = +{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block     OF((deflate_state *s)); +local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen     OF((deflate_state *s, tree_desc *desc)); +local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree     OF((deflate_state *s, tree_desc *desc)); +local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code)); +local int  build_bl_tree  OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, +                              int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, +                              ct_data *dtree)); +local void set_data_type  OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup      OF((deflate_state *s)); +local void bi_flush       OF((deflate_state *s)); +local void copy_block     OF((deflate_state *s, charf *buf, unsigned len, +                              int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) +   /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +#  define send_code(s, c, tree) \ +     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ +       send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ +    put_byte(s, (uch)((w) & 0xff)); \ +    put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits      OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) +    deflate_state *s; +    int value;  /* value to send */ +    int length; /* number of bits */ +{ +    Tracevv((stderr," l %2d v %4x ", length, value)); +    Assert(length > 0 && length <= 15, "invalid length"); +    s->bits_sent += (ulg)length; + +    /* If not enough room in bi_buf, use (valid) bits from bi_buf and +     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) +     * unused bits in value. +     */ +    if (s->bi_valid > (int)Buf_size - length) { +        s->bi_buf |= (value << s->bi_valid); +        put_short(s, s->bi_buf); +        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); +        s->bi_valid += length - Buf_size; +    } else { +        s->bi_buf |= value << s->bi_valid; +        s->bi_valid += length; +    } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ +  if (s->bi_valid > (int)Buf_size - len) {\ +    int val = value;\ +    s->bi_buf |= (val << s->bi_valid);\ +    put_short(s, s->bi_buf);\ +    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ +    s->bi_valid += len - Buf_size;\ +  } else {\ +    s->bi_buf |= (value) << s->bi_valid;\ +    s->bi_valid += len;\ +  }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) +    static int static_init_done = 0; +    int n;        /* iterates over tree elements */ +    int bits;     /* bit counter */ +    int length;   /* length value */ +    int code;     /* code value */ +    int dist;     /* distance index */ +    ush bl_count[MAX_BITS+1]; +    /* number of codes at each bit length for an optimal tree */ + +    if (static_init_done) return; + +    /* For some embedded targets, global variables are not initialized: */ +    static_l_desc.static_tree = static_ltree; +    static_l_desc.extra_bits = extra_lbits; +    static_d_desc.static_tree = static_dtree; +    static_d_desc.extra_bits = extra_dbits; +    static_bl_desc.extra_bits = extra_blbits; + +    /* Initialize the mapping length (0..255) -> length code (0..28) */ +    length = 0; +    for (code = 0; code < LENGTH_CODES-1; code++) { +        base_length[code] = length; +        for (n = 0; n < (1<<extra_lbits[code]); n++) { +            _length_code[length++] = (uch)code; +        } +    } +    Assert (length == 256, "tr_static_init: length != 256"); +    /* Note that the length 255 (match length 258) can be represented +     * in two different ways: code 284 + 5 bits or code 285, so we +     * overwrite length_code[255] to use the best encoding: +     */ +    _length_code[length-1] = (uch)code; + +    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ +    dist = 0; +    for (code = 0 ; code < 16; code++) { +        base_dist[code] = dist; +        for (n = 0; n < (1<<extra_dbits[code]); n++) { +            _dist_code[dist++] = (uch)code; +        } +    } +    Assert (dist == 256, "tr_static_init: dist != 256"); +    dist >>= 7; /* from now on, all distances are divided by 128 */ +    for ( ; code < D_CODES; code++) { +        base_dist[code] = dist << 7; +        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { +            _dist_code[256 + dist++] = (uch)code; +        } +    } +    Assert (dist == 256, "tr_static_init: 256+dist != 512"); + +    /* Construct the codes of the static literal tree */ +    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; +    n = 0; +    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; +    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; +    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; +    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; +    /* Codes 286 and 287 do not exist, but we must include them in the +     * tree construction to get a canonical Huffman tree (longest code +     * all ones) +     */ +    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + +    /* The static distance tree is trivial: */ +    for (n = 0; n < D_CODES; n++) { +        static_dtree[n].Len = 5; +        static_dtree[n].Code = bi_reverse((unsigned)n, 5); +    } +    static_init_done = 1; + +#  ifdef GEN_TREES_H +    gen_trees_header(); +#  endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +#  ifndef DEBUG +#    include <stdio.h> +#  endif + +#  define SEPARATOR(i, last, width) \ +      ((i) == (last)? "\n};\n\n" :    \ +       ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ +    FILE *header = fopen("trees.h", "w"); +    int i; + +    Assert (header != NULL, "Can't open trees.h"); +    fprintf(header, +            "/* header created automatically with -DGEN_TREES_H */\n\n"); + +    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); +    for (i = 0; i < L_CODES+2; i++) { +        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, +                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); +    } + +    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); +    for (i = 0; i < D_CODES; i++) { +        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, +                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); +    } + +    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); +    for (i = 0; i < DIST_CODE_LEN; i++) { +        fprintf(header, "%2u%s", _dist_code[i], +                SEPARATOR(i, DIST_CODE_LEN-1, 20)); +    } + +    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); +    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { +        fprintf(header, "%2u%s", _length_code[i], +                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); +    } + +    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); +    for (i = 0; i < LENGTH_CODES; i++) { +        fprintf(header, "%1u%s", base_length[i], +                SEPARATOR(i, LENGTH_CODES-1, 20)); +    } + +    fprintf(header, "local const int base_dist[D_CODES] = {\n"); +    for (i = 0; i < D_CODES; i++) { +        fprintf(header, "%5u%s", base_dist[i], +                SEPARATOR(i, D_CODES-1, 10)); +    } + +    fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) +    deflate_state *s; +{ +    tr_static_init(); + +    s->l_desc.dyn_tree = s->dyn_ltree; +    s->l_desc.stat_desc = &static_l_desc; + +    s->d_desc.dyn_tree = s->dyn_dtree; +    s->d_desc.stat_desc = &static_d_desc; + +    s->bl_desc.dyn_tree = s->bl_tree; +    s->bl_desc.stat_desc = &static_bl_desc; + +    s->bi_buf = 0; +    s->bi_valid = 0; +    s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG +    s->compressed_len = 0L; +    s->bits_sent = 0L; +#endif + +    /* Initialize the first block of the first file: */ +    init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) +    deflate_state *s; +{ +    int n; /* iterates over tree elements */ + +    /* Initialize the trees. */ +    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0; +    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0; +    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + +    s->dyn_ltree[END_BLOCK].Freq = 1; +    s->opt_len = s->static_len = 0L; +    s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ +    top = s->heap[SMALLEST]; \ +    s->heap[SMALLEST] = s->heap[s->heap_len--]; \ +    pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ +   (tree[n].Freq < tree[m].Freq || \ +   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) +    deflate_state *s; +    ct_data *tree;  /* the tree to restore */ +    int k;               /* node to move down */ +{ +    int v = s->heap[k]; +    int j = k << 1;  /* left son of k */ +    while (j <= s->heap_len) { +        /* Set j to the smallest of the two sons: */ +        if (j < s->heap_len && +            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { +            j++; +        } +        /* Exit if v is smaller than both sons */ +        if (smaller(tree, v, s->heap[j], s->depth)) break; + +        /* Exchange v with the smallest son */ +        s->heap[k] = s->heap[j];  k = j; + +        /* And continue down the tree, setting j to the left son of k */ +        j <<= 1; +    } +    s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + *    above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + *     array bl_count contains the frequencies for each bit length. + *     The length opt_len is updated; static_len is also updated if stree is + *     not null. + */ +local void gen_bitlen(s, desc) +    deflate_state *s; +    tree_desc *desc;    /* the tree descriptor */ +{ +    ct_data *tree        = desc->dyn_tree; +    int max_code         = desc->max_code; +    const ct_data *stree = desc->stat_desc->static_tree; +    const intf *extra    = desc->stat_desc->extra_bits; +    int base             = desc->stat_desc->extra_base; +    int max_length       = desc->stat_desc->max_length; +    int h;              /* heap index */ +    int n, m;           /* iterate over the tree elements */ +    int bits;           /* bit length */ +    int xbits;          /* extra bits */ +    ush f;              /* frequency */ +    int overflow = 0;   /* number of elements with bit length too large */ + +    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + +    /* In a first pass, compute the optimal bit lengths (which may +     * overflow in the case of the bit length tree). +     */ +    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + +    for (h = s->heap_max+1; h < HEAP_SIZE; h++) { +        n = s->heap[h]; +        bits = tree[tree[n].Dad].Len + 1; +        if (bits > max_length) bits = max_length, overflow++; +        tree[n].Len = (ush)bits; +        /* We overwrite tree[n].Dad which is no longer needed */ + +        if (n > max_code) continue; /* not a leaf node */ + +        s->bl_count[bits]++; +        xbits = 0; +        if (n >= base) xbits = extra[n-base]; +        f = tree[n].Freq; +        s->opt_len += (ulg)f * (bits + xbits); +        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); +    } +    if (overflow == 0) return; + +    Trace((stderr,"\nbit length overflow\n")); +    /* This happens for example on obj2 and pic of the Calgary corpus */ + +    /* Find the first bit length which could increase: */ +    do { +        bits = max_length-1; +        while (s->bl_count[bits] == 0) bits--; +        s->bl_count[bits]--;      /* move one leaf down the tree */ +        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ +        s->bl_count[max_length]--; +        /* The brother of the overflow item also moves one step up, +         * but this does not affect bl_count[max_length] +         */ +        overflow -= 2; +    } while (overflow > 0); + +    /* Now recompute all bit lengths, scanning in increasing frequency. +     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all +     * lengths instead of fixing only the wrong ones. This idea is taken +     * from 'ar' written by Haruhiko Okumura.) +     */ +    for (bits = max_length; bits != 0; bits--) { +        n = s->bl_count[bits]; +        while (n != 0) { +            m = s->heap[--h]; +            if (m > max_code) continue; +            if ((unsigned) tree[m].Len != (unsigned) bits) { +                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); +                s->opt_len += ((long)bits - (long)tree[m].Len) +                              *(long)tree[m].Freq; +                tree[m].Len = (ush)bits; +            } +            n--; +        } +    } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + *     zero code length. + */ +local void gen_codes (tree, max_code, bl_count) +    ct_data *tree;             /* the tree to decorate */ +    int max_code;              /* largest code with non zero frequency */ +    ushf *bl_count;            /* number of codes at each bit length */ +{ +    ush next_code[MAX_BITS+1]; /* next code value for each bit length */ +    ush code = 0;              /* running code value */ +    int bits;                  /* bit index */ +    int n;                     /* code index */ + +    /* The distribution counts are first used to generate the code values +     * without bit reversal. +     */ +    for (bits = 1; bits <= MAX_BITS; bits++) { +        next_code[bits] = code = (code + bl_count[bits-1]) << 1; +    } +    /* Check that the bit counts in bl_count are consistent. The last code +     * must be all ones. +     */ +    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, +            "inconsistent bit counts"); +    Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + +    for (n = 0;  n <= max_code; n++) { +        int len = tree[n].Len; +        if (len == 0) continue; +        /* Now reverse the bits */ +        tree[n].Code = bi_reverse(next_code[len]++, len); + +        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", +             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); +    } +} + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + *     and corresponding code. The length opt_len is updated; static_len is + *     also updated if stree is not null. The field max_code is set. + */ +local void build_tree(s, desc) +    deflate_state *s; +    tree_desc *desc; /* the tree descriptor */ +{ +    ct_data *tree         = desc->dyn_tree; +    const ct_data *stree  = desc->stat_desc->static_tree; +    int elems             = desc->stat_desc->elems; +    int n, m;          /* iterate over heap elements */ +    int max_code = -1; /* largest code with non zero frequency */ +    int node;          /* new node being created */ + +    /* Construct the initial heap, with least frequent element in +     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. +     * heap[0] is not used. +     */ +    s->heap_len = 0, s->heap_max = HEAP_SIZE; + +    for (n = 0; n < elems; n++) { +        if (tree[n].Freq != 0) { +            s->heap[++(s->heap_len)] = max_code = n; +            s->depth[n] = 0; +        } else { +            tree[n].Len = 0; +        } +    } + +    /* The pkzip format requires that at least one distance code exists, +     * and that at least one bit should be sent even if there is only one +     * possible code. So to avoid special checks later on we force at least +     * two codes of non zero frequency. +     */ +    while (s->heap_len < 2) { +        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); +        tree[node].Freq = 1; +        s->depth[node] = 0; +        s->opt_len--; if (stree) s->static_len -= stree[node].Len; +        /* node is 0 or 1 so it does not have extra bits */ +    } +    desc->max_code = max_code; + +    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, +     * establish sub-heaps of increasing lengths: +     */ +    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + +    /* Construct the Huffman tree by repeatedly combining the least two +     * frequent nodes. +     */ +    node = elems;              /* next internal node of the tree */ +    do { +        pqremove(s, tree, n);  /* n = node of least frequency */ +        m = s->heap[SMALLEST]; /* m = node of next least frequency */ + +        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ +        s->heap[--(s->heap_max)] = m; + +        /* Create a new node father of n and m */ +        tree[node].Freq = tree[n].Freq + tree[m].Freq; +        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? +                                s->depth[n] : s->depth[m]) + 1); +        tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE +        if (tree == s->bl_tree) { +            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", +                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); +        } +#endif +        /* and insert the new node in the heap */ +        s->heap[SMALLEST] = node++; +        pqdownheap(s, tree, SMALLEST); + +    } while (s->heap_len >= 2); + +    s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + +    /* At this point, the fields freq and dad are set. We can now +     * generate the bit lengths. +     */ +    gen_bitlen(s, (tree_desc *)desc); + +    /* The field len is now set, we can generate the bit codes */ +    gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) +    deflate_state *s; +    ct_data *tree;   /* the tree to be scanned */ +    int max_code;    /* and its largest code of non zero frequency */ +{ +    int n;                     /* iterates over all tree elements */ +    int prevlen = -1;          /* last emitted length */ +    int curlen;                /* length of current code */ +    int nextlen = tree[0].Len; /* length of next code */ +    int count = 0;             /* repeat count of the current code */ +    int max_count = 7;         /* max repeat count */ +    int min_count = 4;         /* min repeat count */ + +    if (nextlen == 0) max_count = 138, min_count = 3; +    tree[max_code+1].Len = (ush)0xffff; /* guard */ + +    for (n = 0; n <= max_code; n++) { +        curlen = nextlen; nextlen = tree[n+1].Len; +        if (++count < max_count && curlen == nextlen) { +            continue; +        } else if (count < min_count) { +            s->bl_tree[curlen].Freq += count; +        } else if (curlen != 0) { +            if (curlen != prevlen) s->bl_tree[curlen].Freq++; +            s->bl_tree[REP_3_6].Freq++; +        } else if (count <= 10) { +            s->bl_tree[REPZ_3_10].Freq++; +        } else { +            s->bl_tree[REPZ_11_138].Freq++; +        } +        count = 0; prevlen = curlen; +        if (nextlen == 0) { +            max_count = 138, min_count = 3; +        } else if (curlen == nextlen) { +            max_count = 6, min_count = 3; +        } else { +            max_count = 7, min_count = 4; +        } +    } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) +    deflate_state *s; +    ct_data *tree; /* the tree to be scanned */ +    int max_code;       /* and its largest code of non zero frequency */ +{ +    int n;                     /* iterates over all tree elements */ +    int prevlen = -1;          /* last emitted length */ +    int curlen;                /* length of current code */ +    int nextlen = tree[0].Len; /* length of next code */ +    int count = 0;             /* repeat count of the current code */ +    int max_count = 7;         /* max repeat count */ +    int min_count = 4;         /* min repeat count */ + +    /* tree[max_code+1].Len = -1; */  /* guard already set */ +    if (nextlen == 0) max_count = 138, min_count = 3; + +    for (n = 0; n <= max_code; n++) { +        curlen = nextlen; nextlen = tree[n+1].Len; +        if (++count < max_count && curlen == nextlen) { +            continue; +        } else if (count < min_count) { +            do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + +        } else if (curlen != 0) { +            if (curlen != prevlen) { +                send_code(s, curlen, s->bl_tree); count--; +            } +            Assert(count >= 3 && count <= 6, " 3_6?"); +            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + +        } else if (count <= 10) { +            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + +        } else { +            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); +        } +        count = 0; prevlen = curlen; +        if (nextlen == 0) { +            max_count = 138, min_count = 3; +        } else if (curlen == nextlen) { +            max_count = 6, min_count = 3; +        } else { +            max_count = 7, min_count = 4; +        } +    } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) +    deflate_state *s; +{ +    int max_blindex;  /* index of last bit length code of non zero freq */ + +    /* Determine the bit length frequencies for literal and distance trees */ +    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); +    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + +    /* Build the bit length tree: */ +    build_tree(s, (tree_desc *)(&(s->bl_desc))); +    /* opt_len now includes the length of the tree representations, except +     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. +     */ + +    /* Determine the number of bit length codes to send. The pkzip format +     * requires that at least 4 bit length codes be sent. (appnote.txt says +     * 3 but the actual value used is 4.) +     */ +    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { +        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; +    } +    /* Update opt_len to include the bit length tree and counts */ +    s->opt_len += 3*(max_blindex+1) + 5+5+4; +    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", +            s->opt_len, s->static_len)); + +    return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) +    deflate_state *s; +    int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ +    int rank;                    /* index in bl_order */ + +    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); +    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, +            "too many codes"); +    Tracev((stderr, "\nbl counts: ")); +    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ +    send_bits(s, dcodes-1,   5); +    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */ +    for (rank = 0; rank < blcodes; rank++) { +        Tracev((stderr, "\nbl code %2d ", bl_order[rank])); +        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); +    } +    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + +    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ +    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + +    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ +    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) +    deflate_state *s; +    charf *buf;       /* input block */ +    ulg stored_len;   /* length of input block */ +    int eof;          /* true if this is the last block for a file */ +{ +    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */ +#ifdef DEBUG +    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; +    s->compressed_len += (stored_len + 4) << 3; +#endif +    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) +    deflate_state *s; +{ +    send_bits(s, STATIC_TREES<<1, 3); +    send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG +    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif +    bi_flush(s); +    /* Of the 10 bits for the empty block, we have already sent +     * (10 - bi_valid) bits. The lookahead for the last real code (before +     * the EOB of the previous block) was thus at least one plus the length +     * of the EOB plus what we have just sent of the empty static block. +     */ +    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { +        send_bits(s, STATIC_TREES<<1, 3); +        send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG +        s->compressed_len += 10L; +#endif +        bi_flush(s); +    } +    s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) +    deflate_state *s; +    charf *buf;       /* input block, or NULL if too old */ +    ulg stored_len;   /* length of input block */ +    int eof;          /* true if this is the last block for a file */ +{ +    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ +    int max_blindex = 0;  /* index of last bit length code of non zero freq */ + +    /* Build the Huffman trees unless a stored block is forced */ +    if (s->level > 0) { + +        /* Check if the file is binary or text */ +        if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) +            set_data_type(s); + +        /* Construct the literal and distance trees */ +        build_tree(s, (tree_desc *)(&(s->l_desc))); +        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, +                s->static_len)); + +        build_tree(s, (tree_desc *)(&(s->d_desc))); +        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, +                s->static_len)); +        /* At this point, opt_len and static_len are the total bit lengths of +         * the compressed block data, excluding the tree representations. +         */ + +        /* Build the bit length tree for the above two trees, and get the index +         * in bl_order of the last bit length code to send. +         */ +        max_blindex = build_bl_tree(s); + +        /* Determine the best encoding. Compute the block lengths in bytes. */ +        opt_lenb = (s->opt_len+3+7)>>3; +        static_lenb = (s->static_len+3+7)>>3; + +        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", +                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, +                s->last_lit)); + +        if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + +    } else { +        Assert(buf != (char*)0, "lost buf"); +        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ +    } + +#ifdef FORCE_STORED +    if (buf != (char*)0) { /* force stored block */ +#else +    if (stored_len+4 <= opt_lenb && buf != (char*)0) { +                       /* 4: two words for the lengths */ +#endif +        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. +         * Otherwise we can't have processed more than WSIZE input bytes since +         * the last block flush, because compression would have been +         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to +         * transform a block into a stored block. +         */ +        _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC +    } else if (static_lenb >= 0) { /* force static trees */ +#else +    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif +        send_bits(s, (STATIC_TREES<<1)+eof, 3); +        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG +        s->compressed_len += 3 + s->static_len; +#endif +    } else { +        send_bits(s, (DYN_TREES<<1)+eof, 3); +        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, +                       max_blindex+1); +        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG +        s->compressed_len += 3 + s->opt_len; +#endif +    } +    Assert (s->compressed_len == s->bits_sent, "bad compressed size"); +    /* The above check is made mod 2^32, for files larger than 512 MB +     * and uLong implemented on 32 bits. +     */ +    init_block(s); + +    if (eof) { +        bi_windup(s); +#ifdef DEBUG +        s->compressed_len += 7;  /* align on byte boundary */ +#endif +    } +    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, +           s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) +    deflate_state *s; +    unsigned dist;  /* distance of matched string */ +    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ +    s->d_buf[s->last_lit] = (ush)dist; +    s->l_buf[s->last_lit++] = (uch)lc; +    if (dist == 0) { +        /* lc is the unmatched char */ +        s->dyn_ltree[lc].Freq++; +    } else { +        s->matches++; +        /* Here, lc is the match length - MIN_MATCH */ +        dist--;             /* dist = match distance - 1 */ +        Assert((ush)dist < (ush)MAX_DIST(s) && +               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && +               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match"); + +        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; +        s->dyn_dtree[d_code(dist)].Freq++; +    } + +#ifdef TRUNCATE_BLOCK +    /* Try to guess if it is profitable to stop the current block here */ +    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { +        /* Compute an upper bound for the compressed length */ +        ulg out_length = (ulg)s->last_lit*8L; +        ulg in_length = (ulg)((long)s->strstart - s->block_start); +        int dcode; +        for (dcode = 0; dcode < D_CODES; dcode++) { +            out_length += (ulg)s->dyn_dtree[dcode].Freq * +                (5L+extra_dbits[dcode]); +        } +        out_length >>= 3; +        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", +               s->last_lit, in_length, out_length, +               100L - out_length*100L/in_length)); +        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; +    } +#endif +    return (s->last_lit == s->lit_bufsize-1); +    /* We avoid equality with lit_bufsize because of wraparound at 64K +     * on 16 bit machines and because stored blocks are restricted to +     * 64K-1 bytes. +     */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) +    deflate_state *s; +    ct_data *ltree; /* literal tree */ +    ct_data *dtree; /* distance tree */ +{ +    unsigned dist;      /* distance of matched string */ +    int lc;             /* match length or unmatched char (if dist == 0) */ +    unsigned lx = 0;    /* running index in l_buf */ +    unsigned code;      /* the code to send */ +    int extra;          /* number of extra bits to send */ + +    if (s->last_lit != 0) do { +        dist = s->d_buf[lx]; +        lc = s->l_buf[lx++]; +        if (dist == 0) { +            send_code(s, lc, ltree); /* send a literal byte */ +            Tracecv(isgraph(lc), (stderr," '%c' ", lc)); +        } else { +            /* Here, lc is the match length - MIN_MATCH */ +            code = _length_code[lc]; +            send_code(s, code+LITERALS+1, ltree); /* send the length code */ +            extra = extra_lbits[code]; +            if (extra != 0) { +                lc -= base_length[code]; +                send_bits(s, lc, extra);       /* send the extra length bits */ +            } +            dist--; /* dist is now the match distance - 1 */ +            code = d_code(dist); +            Assert (code < D_CODES, "bad d_code"); + +            send_code(s, code, dtree);       /* send the distance code */ +            extra = extra_dbits[code]; +            if (extra != 0) { +                dist -= base_dist[code]; +                send_bits(s, dist, extra);   /* send the extra distance bits */ +            } +        } /* literal or match pair ? */ + +        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ +        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, +               "pendingBuf overflow"); + +    } while (lx < s->last_lit); + +    send_code(s, END_BLOCK, ltree); +    s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to BINARY or TEXT, using a crude approximation: + * set it to Z_TEXT if all symbols are either printable characters (33 to 255) + * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local void set_data_type(s) +    deflate_state *s; +{ +    int n; + +    for (n = 0; n < 9; n++) +        if (s->dyn_ltree[n].Freq != 0) +            break; +    if (n == 9) +        for (n = 14; n < 32; n++) +            if (s->dyn_ltree[n].Freq != 0) +                break; +    s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) +    unsigned code; /* the value to invert */ +    int len;       /* its bit length */ +{ +    register unsigned res = 0; +    do { +        res |= code & 1; +        code >>= 1, res <<= 1; +    } while (--len > 0); +    return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) +    deflate_state *s; +{ +    if (s->bi_valid == 16) { +        put_short(s, s->bi_buf); +        s->bi_buf = 0; +        s->bi_valid = 0; +    } else if (s->bi_valid >= 8) { +        put_byte(s, (Byte)s->bi_buf); +        s->bi_buf >>= 8; +        s->bi_valid -= 8; +    } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) +    deflate_state *s; +{ +    if (s->bi_valid > 8) { +        put_short(s, s->bi_buf); +    } else if (s->bi_valid > 0) { +        put_byte(s, (Byte)s->bi_buf); +    } +    s->bi_buf = 0; +    s->bi_valid = 0; +#ifdef DEBUG +    s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) +    deflate_state *s; +    charf    *buf;    /* the input data */ +    unsigned len;     /* its length */ +    int      header;  /* true if block header must be written */ +{ +    bi_windup(s);        /* align on byte boundary */ +    s->last_eob_len = 8; /* enough lookahead for inflate */ + +    if (header) { +        put_short(s, (ush)len); +        put_short(s, (ush)~len); +#ifdef DEBUG +        s->bits_sent += 2*16; +#endif +    } +#ifdef DEBUG +    s->bits_sent += (ulg)len<<3; +#endif +    while (len--) { +        put_byte(s, *buf++); +    } +} diff --git a/lib/libz/trees.h b/lib/libz/trees.h new file mode 100644 index 0000000..ca79189 --- /dev/null +++ b/lib/libz/trees.h @@ -0,0 +1,129 @@ +/*	$OpenBSD: trees.h,v 1.2 2002/03/12 00:25:57 millert Exp $	*/ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}}, +{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}}, +{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}}, +{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}}, +{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}}, +{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}}, +{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}}, +{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}}, +{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}}, +{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}}, +{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}}, +{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}}, +{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}}, +{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}}, +{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}}, +{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}}, +{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}}, +{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}}, +{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}}, +{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}}, +{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}}, +{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}}, +{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}}, +{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}}, +{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}}, +{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}}, +{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}}, +{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}}, +{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}}, +{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}}, +{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}}, +{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}}, +{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}}, +{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}}, +{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}}, +{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}}, +{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}}, +{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}}, +{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}}, +{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}}, +{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}}, +{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}}, +{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}}, +{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}}, +{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}}, +{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}}, +{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}}, +{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}}, +{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}}, +{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}}, +{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}}, +{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}}, +{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}}, +{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}}, +{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}}, +{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}}, +{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}}, +{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8, + 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { +    0,     1,     2,     3,     4,     6,     8,    12,    16,    24, +   32,    48,    64,    96,   128,   192,   256,   384,   512,   768, + 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576 +}; + diff --git a/lib/libz/uncompr.c b/lib/libz/uncompr.c new file mode 100644 index 0000000..2b50fa3 --- /dev/null +++ b/lib/libz/uncompr.c @@ -0,0 +1,61 @@ +/*	$OpenBSD: uncompr.c,v 1.5 2003/12/16 22:33:02 henning Exp $	*/ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== +     Decompresses the source buffer into the destination buffer.  sourceLen is +   the byte length of the source buffer. Upon entry, destLen is the total +   size of the destination buffer, which must be large enough to hold the +   entire uncompressed data. (The size of the uncompressed data must have +   been saved previously by the compressor and transmitted to the decompressor +   by some mechanism outside the scope of this compression library.) +   Upon exit, destLen is the actual size of the compressed buffer. +     This function can be used to decompress a whole file at once if the +   input file is mmap'ed. + +     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not +   enough memory, Z_BUF_ERROR if there was not enough room in the output +   buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) +    Bytef *dest; +    uLongf *destLen; +    const Bytef *source; +    uLong sourceLen; +{ +    z_stream stream; +    int err; + +    stream.next_in = (Bytef*)source; +    stream.avail_in = (uInt)sourceLen; +    /* Check for source > 64K on 16-bit machine: */ +    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + +    stream.next_out = dest; +    stream.avail_out = (uInt)*destLen; +    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + +    stream.zalloc = (alloc_func)0; +    stream.zfree = (free_func)0; + +    err = inflateInit(&stream); +    if (err != Z_OK) return err; + +    err = inflate(&stream, Z_FINISH); +    if (err != Z_STREAM_END) { +        inflateEnd(&stream); +        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) +            return Z_DATA_ERROR; +        return err; +    } +    *destLen = stream.total_out; + +    err = inflateEnd(&stream); +    return err; +} diff --git a/lib/libz/zconf.h b/lib/libz/zconf.h new file mode 100644 index 0000000..7ac5b7b --- /dev/null +++ b/lib/libz/zconf.h @@ -0,0 +1,330 @@ +/*	$OpenBSD: zconf.h,v 1.8 2019/05/12 15:56:56 jca Exp $	*/ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +#  define deflateInit_          z_deflateInit_ +#  define deflate               z_deflate +#  define deflateEnd            z_deflateEnd +#  define inflateInit_          z_inflateInit_ +#  define inflate               z_inflate +#  define inflateEnd            z_inflateEnd +#  define deflateInit2_         z_deflateInit2_ +#  define deflateSetDictionary  z_deflateSetDictionary +#  define deflateCopy           z_deflateCopy +#  define deflateReset          z_deflateReset +#  define deflateParams         z_deflateParams +#  define deflateBound          z_deflateBound +#  define deflatePrime          z_deflatePrime +#  define inflateInit2_         z_inflateInit2_ +#  define inflateSetDictionary  z_inflateSetDictionary +#  define inflateSync           z_inflateSync +#  define inflateSyncPoint      z_inflateSyncPoint +#  define inflateCopy           z_inflateCopy +#  define inflateReset          z_inflateReset +#  define inflateBack           z_inflateBack +#  define inflateBackEnd        z_inflateBackEnd +#  define compress              z_compress +#  define compress2             z_compress2 +#  define compressBound         z_compressBound +#  define uncompress            z_uncompress +#  define adler32               z_adler32 +#  define crc32                 z_crc32 +#  define get_crc_table         z_get_crc_table +#  define zError                z_zError + +#  define alloc_func            z_alloc_func +#  define free_func             z_free_func +#  define in_func               z_in_func +#  define out_func              z_out_func +#  define Byte                  z_Byte +#  define uInt                  z_uInt +#  define uLong                 z_uLong +#  define Bytef                 z_Bytef +#  define charf                 z_charf +#  define intf                  z_intf +#  define uIntf                 z_uIntf +#  define uLongf                z_uLongf +#  define voidpf                z_voidpf +#  define voidp                 z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +#  define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +#  define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +#  define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +#  ifndef WIN32 +#    define WIN32 +#  endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +#    ifndef SYS16BIT +#      define SYS16BIT +#    endif +#  endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +#  define MAXSEG_64K +#endif +#ifdef MSDOS +#  define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +#  ifndef STDC +#    define STDC +#  endif +#  if __STDC_VERSION__ >= 199901L +#    ifndef STDC99 +#      define STDC99 +#    endif +#  endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +#  define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +#  define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +#  define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +#  define STDC +#endif + +#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */ +#  define STDC +#endif + +#ifndef STDC +#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +#    define const       /* note: need a more gentle solution here */ +#  endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +#  define z_const const +#else +#  define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +#  define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +#  ifdef MAXSEG_64K +#    define MAX_MEM_LEVEL 8 +#  else +#    define MAX_MEM_LEVEL 9 +#  endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +#  define MAX_WBITS   15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): +            (1 << (windowBits+2)) +  (1 << (memLevel+9)) + that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with +     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + +   The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + +                        /* Type declarations */ + +#ifndef OF /* function prototypes */ +#  ifdef STDC +#    define OF(args)  args +#  else +#    define OF(args)  () +#  endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +#  if defined(M_I86SM) || defined(M_I86MM) +     /* MSC small or medium model */ +#    define SMALL_MEDIUM +#    ifdef _MSC_VER +#      define FAR _far +#    else +#      define FAR far +#    endif +#  endif +#  if (defined(__SMALL__) || defined(__MEDIUM__)) +     /* Turbo C small or medium model */ +#    define SMALL_MEDIUM +#    ifdef __BORLANDC__ +#      define FAR _far +#    else +#      define FAR far +#    endif +#  endif +#endif + +#if defined(WINDOWS) || defined(WIN32) +   /* If building or using zlib as a DLL, define ZLIB_DLL. +    * This is not mandatory, but it offers a little performance increase. +    */ +#  ifdef ZLIB_DLL +#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +#      ifdef ZLIB_INTERNAL +#        define ZEXTERN extern __declspec(dllexport) +#      else +#        define ZEXTERN extern __declspec(dllimport) +#      endif +#    endif +#  endif  /* ZLIB_DLL */ +   /* If building or using zlib with the WINAPI/WINAPIV calling convention, +    * define ZLIB_WINAPI. +    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. +    */ +#  ifdef ZLIB_WINAPI +#    ifdef FAR +#      undef FAR +#    endif +#    include <windows.h> +     /* No need for _export, use ZLIB.DEF instead. */ +     /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +#    define ZEXPORT WINAPI +#    ifdef WIN32 +#      define ZEXPORTVA WINAPIV +#    else +#      define ZEXPORTVA FAR CDECL +#    endif +#  endif +#endif + +#if defined (__BEOS__) +#  ifdef ZLIB_DLL +#    ifdef ZLIB_INTERNAL +#      define ZEXPORT   __declspec(dllexport) +#      define ZEXPORTVA __declspec(dllexport) +#    else +#      define ZEXPORT   __declspec(dllimport) +#      define ZEXPORTVA __declspec(dllimport) +#    endif +#  endif +#endif + +#ifndef ZEXTERN +#  define ZEXTERN extern +#endif +#ifndef ZEXPORT +#  define ZEXPORT +#endif +#ifndef ZEXPORTVA +#  define ZEXPORTVA +#endif + +#ifndef FAR +#  define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char  Byte;  /* 8 bits */ +#endif +typedef unsigned int   uInt;  /* 16 bits or more */ +typedef unsigned long  uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM +   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +#  define Bytef Byte FAR +#else +   typedef Byte  FAR Bytef; +#endif +typedef char  FAR charf; +typedef int   FAR intf; +typedef uInt  FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC +   typedef void const *voidpc; +   typedef void FAR   *voidpf; +   typedef void       *voidp; +#else +   typedef Byte const *voidpc; +   typedef Byte FAR   *voidpf; +   typedef Byte       *voidp; +#endif + +#include <sys/types.h> /* for off_t */ +#include <unistd.h>    /* for SEEK_* and off_t */ +#define z_off_t  off_t +#ifndef SEEK_SET +#  define SEEK_SET        0       /* Seek from beginning of file.  */ +#  define SEEK_CUR        1       /* Seek from current position.  */ +#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */ +#endif + +#if defined(__OS400__) +#define NO_vsnprintf +#endif + +#if defined(__MVS__) +#  define NO_vsnprintf +#  ifdef FAR +#    undef FAR +#  endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +#   pragma map(deflateInit_,"DEIN") +#   pragma map(deflateInit2_,"DEIN2") +#   pragma map(deflateEnd,"DEEND") +#   pragma map(deflateBound,"DEBND") +#   pragma map(inflateInit_,"ININ") +#   pragma map(inflateInit2_,"ININ2") +#   pragma map(inflateEnd,"INEND") +#   pragma map(inflateSync,"INSY") +#   pragma map(inflateSetDictionary,"INSEDI") +#   pragma map(compressBound,"CMBND") +#   pragma map(inflate_table,"INTABL") +#   pragma map(inflate_fast,"INFA") +#   pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/lib/libz/zlib.h b/lib/libz/zlib.h new file mode 100644 index 0000000..a2c23f0 --- /dev/null +++ b/lib/libz/zlib.h @@ -0,0 +1,1359 @@ +/*	$OpenBSD: zlib.h,v 1.11 2019/05/12 15:56:56 jca Exp $	*/ +/* zlib.h -- interface of the 'zlib' general purpose compression library +  version 1.2.3, July 18th, 2005 + +  Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + +  This software is provided 'as-is', without any express or implied +  warranty.  In no event will the authors be held liable for any damages +  arising from the use of this software. + +  Permission is granted to anyone to use this software for any purpose, +  including commercial applications, and to alter it and redistribute it +  freely, subject to the following restrictions: + +  1. The origin of this software must not be misrepresented; you must not +     claim that you wrote the original software. If you use this software +     in a product, an acknowledgment in the product documentation would be +     appreciated but is not required. +  2. Altered source versions must be plainly marked as such, and must not be +     misrepresented as being the original software. +  3. This notice may not be removed or altered from any source distribution. + +  Jean-loup Gailly        Mark Adler +  jloup@gzip.org          madler@alumni.caltech.edu + + +  The data format used by the zlib library is described by RFCs (Request for +  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt +  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* +     The 'zlib' compression library provides in-memory compression and +  decompression functions, including integrity checks of the uncompressed +  data.  This version of the library supports only one compression method +  (deflation) but other algorithms will be added later and will have the same +  stream interface. + +     Compression can be done in a single step if the buffers are large +  enough (for example if an input file is mmap'ed), or can be done by +  repeated calls of the compression function.  In the latter case, the +  application must provide more input and/or consume the output +  (providing more output space) before each call. + +     The compressed data format used by default by the in-memory functions is +  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped +  around a deflate stream, which is itself documented in RFC 1951. + +     The library also supports reading and writing files in gzip (.gz) format +  with an interface similar to that of stdio using the functions that start +  with "gz".  The gzip format is different from the zlib format.  gzip is a +  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + +     This library can optionally read and write gzip streams in memory as well. + +     The zlib format was designed to be compact and fast for use in memory +  and on communications channels.  The gzip format was designed for single- +  file compression on file systems, has a larger header than zlib to maintain +  directory information, and uses a different, slower check method than zlib. + +     The library does not install any signal handler. The decoder checks +  the consistency of the compressed data, so the library should never +  crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void   (*free_func)  OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { +    z_const Bytef *next_in;     /* next input byte */ +    uInt     avail_in;  /* number of bytes available at next_in */ +    z_off_t  total_in;  /* total nb of input bytes read so far */ + +    Bytef    *next_out; /* next output byte should be put there */ +    uInt     avail_out; /* remaining free space at next_out */ +    z_off_t  total_out; /* total nb of bytes output so far */ + +    z_const char *msg;  /* last error message, NULL if no error */ +    struct internal_state FAR *state; /* not visible by applications */ + +    alloc_func zalloc;  /* used to allocate the internal state */ +    free_func  zfree;   /* used to free the internal state */ +    voidpf     opaque;  /* private data object passed to zalloc and zfree */ + +    int     data_type;  /* best guess about the data type: binary or text */ +    uLong   adler;      /* adler32 value of the uncompressed data */ +    uLong   reserved;   /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* +     gzip header information passed to and from zlib routines.  See RFC 1952 +  for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { +    int     text;       /* true if compressed data believed to be text */ +    uLong   time;       /* modification time */ +    int     xflags;     /* extra flags (not used when writing a gzip file) */ +    int     os;         /* operating system */ +    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */ +    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */ +    uInt    extra_max;  /* space at extra (only when reading header) */ +    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */ +    uInt    name_max;   /* space at name (only when reading header) */ +    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */ +    uInt    comm_max;   /* space at comment (only when reading header) */ +    int     hcrc;       /* true if there was or will be a header crc */ +    int     done;       /* true when done reading gzip header (not used +                           when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* +   The application must update next_in and avail_in when avail_in has +   dropped to zero. It must update next_out and avail_out when avail_out +   has dropped to zero. The application must initialize zalloc, zfree and +   opaque before calling the init function. All other fields are set by the +   compression library and must not be updated by the application. + +   The opaque value provided by the application will be passed as the first +   parameter for calls of zalloc and zfree. This can be useful for custom +   memory management. The compression library attaches no meaning to the +   opaque value. + +   zalloc must return Z_NULL if there is not enough memory for the object. +   If zlib is used in a multi-threaded application, zalloc and zfree must be +   thread safe. + +   On 16-bit systems, the functions zalloc and zfree must be able to allocate +   exactly 65536 bytes, but will not be required to allocate more than this +   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, +   pointers returned by zalloc for objects of exactly 65536 bytes *must* +   have their offset normalized to zero. The default allocation function +   provided by this library ensures this (see zutil.c). To reduce memory +   requirements and avoid any allocation of 64K objects, at the expense of +   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + +   The fields total_in and total_out can be used for statistics or +   progress reports. After compression, total_in holds the total size of +   the uncompressed data and may be saved for use in the decompressor +   (particularly if the decompressor wants to decompress everything in +   a single step). +*/ + +                        /* constants */ + +#define Z_NO_FLUSH      0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH    2 +#define Z_FULL_FLUSH    3 +#define Z_FINISH        4 +#define Z_BLOCK         5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK            0 +#define Z_STREAM_END    1 +#define Z_NEED_DICT     2 +#define Z_ERRNO        (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR   (-3) +#define Z_MEM_ERROR    (-4) +#define Z_BUF_ERROR    (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION         0 +#define Z_BEST_SPEED             1 +#define Z_BEST_COMPRESSION       9 +#define Z_DEFAULT_COMPRESSION  (-1) +/* compression levels */ + +#define Z_FILTERED            1 +#define Z_HUFFMAN_ONLY        2 +#define Z_RLE                 3 +#define Z_FIXED               4 +#define Z_DEFAULT_STRATEGY    0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY   0 +#define Z_TEXT     1 +#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN  2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED   8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + +                        /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. +   If the first character differs, the library code actually used is +   not compatible with the zlib.h header file used by the application. +   This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + +     Initializes the internal stream state for compression. The fields +   zalloc, zfree and opaque must be initialized before by the caller. +   If zalloc and zfree are set to Z_NULL, deflateInit updates them to +   use default allocation functions. + +     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: +   1 gives best speed, 9 gives best compression, 0 gives no compression at +   all (the input data is simply copied a block at a time). +   Z_DEFAULT_COMPRESSION requests a default compromise between speed and +   compression (currently equivalent to level 6). + +     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not +   enough memory, Z_STREAM_ERROR if level is not a valid compression level, +   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible +   with the version assumed by the caller (ZLIB_VERSION). +   msg is set to null if there is no error message.  deflateInit does not +   perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* +    deflate compresses as much data as possible, and stops when the input +  buffer becomes empty or the output buffer becomes full. It may introduce some +  output latency (reading input without producing any output) except when +  forced to flush. + +    The detailed semantics are as follows. deflate performs one or both of the +  following actions: + +  - Compress more input starting at next_in and update next_in and avail_in +    accordingly. If not all input can be processed (because there is not +    enough room in the output buffer), next_in and avail_in are updated and +    processing will resume at this point for the next call of deflate(). + +  - Provide more output starting at next_out and update next_out and avail_out +    accordingly. This action is forced if the parameter flush is non zero. +    Forcing flush frequently degrades the compression ratio, so this parameter +    should be set only when necessary (in interactive applications). +    Some output may be provided even if flush is not set. + +  Before the call of deflate(), the application should ensure that at least +  one of the actions is possible, by providing more input and/or consuming +  more output, and updating avail_in or avail_out accordingly; avail_out +  should never be zero before the call. The application can consume the +  compressed output when it wants, for example when the output buffer is full +  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK +  and with zero avail_out, it must be called again after making room in the +  output buffer because there might be more output pending. + +    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to +  decide how much data to accumulate before producing output, in order to +  maximize compression. + +    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is +  flushed to the output buffer and the output is aligned on a byte boundary, so +  that the decompressor can get all input data available so far. (In particular +  avail_in is zero after the call if enough output space has been provided +  before the call.)  Flushing may degrade compression for some compression +  algorithms and so it should be used only when necessary. + +    If flush is set to Z_FULL_FLUSH, all output is flushed as with +  Z_SYNC_FLUSH, and the compression state is reset so that decompression can +  restart from this point if previous compressed data has been damaged or if +  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade +  compression. + +    If deflate returns with avail_out == 0, this function must be called again +  with the same value of the flush parameter and more output space (updated +  avail_out), until the flush is complete (deflate returns with non-zero +  avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that +  avail_out is greater than six to avoid repeated flush markers due to +  avail_out == 0 on return. + +    If the parameter flush is set to Z_FINISH, pending input is processed, +  pending output is flushed and deflate returns with Z_STREAM_END if there +  was enough output space; if deflate returns with Z_OK, this function must be +  called again with Z_FINISH and more output space (updated avail_out) but no +  more input data, until it returns with Z_STREAM_END or an error. After +  deflate has returned Z_STREAM_END, the only possible operations on the +  stream are deflateReset or deflateEnd. + +    Z_FINISH can be used immediately after deflateInit if all the compression +  is to be done in a single step. In this case, avail_out must be at least +  the value returned by deflateBound (see below). If deflate does not return +  Z_STREAM_END, then it must be called again as described above. + +    deflate() sets strm->adler to the adler32 checksum of all input read +  so far (that is, total_in bytes). + +    deflate() may update strm->data_type if it can make a good guess about +  the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered +  binary. This field is only for information purposes and does not affect +  the compression algorithm in any manner. + +    deflate() returns Z_OK if some progress has been made (more input +  processed or more output produced), Z_STREAM_END if all input has been +  consumed and all output has been produced (only when flush is set to +  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example +  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible +  (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not +  fatal, and deflate() can be called again with more input and more output +  space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* +     All dynamically allocated data structures for this stream are freed. +   This function discards any unprocessed input and does not flush any +   pending output. + +     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the +   stream state was inconsistent, Z_DATA_ERROR if the stream was freed +   prematurely (some input or output was discarded). In the error case, +   msg may be set but then points to a static string (which must not be +   deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + +     Initializes the internal stream state for decompression. The fields +   next_in, avail_in, zalloc, zfree and opaque must be initialized before by +   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact +   value depends on the compression method), inflateInit determines the +   compression method from the zlib header and allocates all data structures +   accordingly; otherwise the allocation will be deferred to the first call of +   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to +   use default allocation functions. + +     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough +   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the +   version assumed by the caller.  msg is set to null if there is no error +   message. inflateInit does not perform any decompression apart from reading +   the zlib header if present: this will be done by inflate().  (So next_in and +   avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* +    inflate decompresses as much data as possible, and stops when the input +  buffer becomes empty or the output buffer becomes full. It may introduce +  some output latency (reading input without producing any output) except when +  forced to flush. + +  The detailed semantics are as follows. inflate performs one or both of the +  following actions: + +  - Decompress more input starting at next_in and update next_in and avail_in +    accordingly. If not all input can be processed (because there is not +    enough room in the output buffer), next_in is updated and processing +    will resume at this point for the next call of inflate(). + +  - Provide more output starting at next_out and update next_out and avail_out +    accordingly.  inflate() provides as much output as possible, until there +    is no more input data or no more space in the output buffer (see below +    about the flush parameter). + +  Before the call of inflate(), the application should ensure that at least +  one of the actions is possible, by providing more input and/or consuming +  more output, and updating the next_* and avail_* values accordingly. +  The application can consume the uncompressed output when it wants, for +  example when the output buffer is full (avail_out == 0), or after each +  call of inflate(). If inflate returns Z_OK and with zero avail_out, it +  must be called again after making room in the output buffer because there +  might be more output pending. + +    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, +  Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much +  output as possible to the output buffer. Z_BLOCK requests that inflate() stop +  if and when it gets to the next deflate block boundary. When decoding the +  zlib or gzip format, this will cause inflate() to return immediately after +  the header and before the first block. When doing a raw inflate, inflate() +  will go ahead and process the first block, and will return when it gets to +  the end of that block, or when it runs out of data. + +    The Z_BLOCK option assists in appending to or combining deflate streams. +  Also to assist in this, on return inflate() will set strm->data_type to the +  number of unused bits in the last byte taken from strm->next_in, plus 64 +  if inflate() is currently decoding the last block in the deflate stream, +  plus 128 if inflate() returned immediately after decoding an end-of-block +  code or decoding the complete header up to just before the first byte of the +  deflate stream. The end-of-block will not be indicated until all of the +  uncompressed data from that block has been written to strm->next_out.  The +  number of unused bits may in general be greater than seven, except when +  bit 7 of data_type is set, in which case the number of unused bits will be +  less than eight. + +    inflate() should normally be called until it returns Z_STREAM_END or an +  error. However if all decompression is to be performed in a single step +  (a single call of inflate), the parameter flush should be set to +  Z_FINISH. In this case all pending input is processed and all pending +  output is flushed; avail_out must be large enough to hold all the +  uncompressed data. (The size of the uncompressed data may have been saved +  by the compressor for this purpose.) The next operation on this stream must +  be inflateEnd to deallocate the decompression state. The use of Z_FINISH +  is never required, but can be used to inform inflate that a faster approach +  may be used for the single inflate() call. + +     In this implementation, inflate() always flushes as much output as +  possible to the output buffer, and always uses the faster approach on the +  first call. So the only effect of the flush parameter in this implementation +  is on the return value of inflate(), as noted below, or when it returns early +  because Z_BLOCK is used. + +     If a preset dictionary is needed after this call (see inflateSetDictionary +  below), inflate sets strm->adler to the adler32 checksum of the dictionary +  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets +  strm->adler to the adler32 checksum of all output produced so far (that is, +  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described +  below. At the end of the stream, inflate() checks that its computed adler32 +  checksum is equal to that saved by the compressor and returns Z_STREAM_END +  only if the checksum is correct. + +    inflate() will decompress and check either zlib-wrapped or gzip-wrapped +  deflate data.  The header type is detected automatically.  Any information +  contained in the gzip header is not retained, so applications that need that +  information should instead use raw inflate, see inflateInit2() below, or +  inflateBack() and perform their own processing of the gzip header and +  trailer. + +    inflate() returns Z_OK if some progress has been made (more input processed +  or more output produced), Z_STREAM_END if the end of the compressed data has +  been reached and all uncompressed output has been produced, Z_NEED_DICT if a +  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was +  corrupted (input stream not conforming to the zlib format or incorrect check +  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example +  if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, +  Z_BUF_ERROR if no progress is possible or if there was not enough room in the +  output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and +  inflate() can be called again with more input and more output space to +  continue decompressing. If Z_DATA_ERROR is returned, the application may then +  call inflateSync() to look for a good compression block if a partial recovery +  of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* +     All dynamically allocated data structures for this stream are freed. +   This function discards any unprocessed input and does not flush any +   pending output. + +     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state +   was inconsistent. In the error case, msg may be set but then points to a +   static string (which must not be deallocated). +*/ + +                        /* Advanced functions */ + +/* +    The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, +                                     int  level, +                                     int  method, +                                     int  windowBits, +                                     int  memLevel, +                                     int  strategy)); + +     This is another version of deflateInit with more compression options. The +   fields next_in, zalloc, zfree and opaque must be initialized before by +   the caller. + +     The method parameter is the compression method. It must be Z_DEFLATED in +   this version of the library. + +     The windowBits parameter is the base two logarithm of the window size +   (the size of the history buffer). It should be in the range 8..15 for this +   version of the library. Larger values of this parameter result in better +   compression at the expense of memory usage. The default value is 15 if +   deflateInit is used instead. + +     windowBits can also be -8..-15 for raw deflate. In this case, -windowBits +   determines the window size. deflate() will then generate raw deflate data +   with no zlib header or trailer, and will not compute an adler32 check value. + +     windowBits can also be greater than 15 for optional gzip encoding. Add +   16 to windowBits to write a simple gzip header and trailer around the +   compressed data instead of a zlib wrapper. The gzip header will have no +   file name, no extra data, no comment, no modification time (set to zero), +   no header crc, and the operating system will be set to 255 (unknown).  If a +   gzip stream is being written, strm->adler is a crc32 instead of an adler32. + +     The memLevel parameter specifies how much memory should be allocated +   for the internal compression state. memLevel=1 uses minimum memory but +   is slow and reduces compression ratio; memLevel=9 uses maximum memory +   for optimal speed. The default value is 8. See zconf.h for total memory +   usage as a function of windowBits and memLevel. + +     The strategy parameter is used to tune the compression algorithm. Use the +   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a +   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no +   string match), or Z_RLE to limit match distances to one (run-length +   encoding). Filtered data consists mostly of small values with a somewhat +   random distribution. In this case, the compression algorithm is tuned to +   compress them better. The effect of Z_FILTERED is to force more Huffman +   coding and less string matching; it is somewhat intermediate between +   Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as +   Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy +   parameter only affects the compression ratio but not the correctness of the +   compressed output even if it is not set appropriately.  Z_FIXED prevents the +   use of dynamic Huffman codes, allowing for a simpler decoder for special +   applications. + +      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough +   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid +   method). msg is set to null if there is no error message.  deflateInit2 does +   not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, +                                             const Bytef *dictionary, +                                             uInt  dictLength)); +/* +     Initializes the compression dictionary from the given byte sequence +   without producing any compressed output. This function must be called +   immediately after deflateInit, deflateInit2 or deflateReset, before any +   call of deflate. The compressor and decompressor must use exactly the same +   dictionary (see inflateSetDictionary). + +     The dictionary should consist of strings (byte sequences) that are likely +   to be encountered later in the data to be compressed, with the most commonly +   used strings preferably put towards the end of the dictionary. Using a +   dictionary is most useful when the data to be compressed is short and can be +   predicted with good accuracy; the data can then be compressed better than +   with the default empty dictionary. + +     Depending on the size of the compression data structures selected by +   deflateInit or deflateInit2, a part of the dictionary may in effect be +   discarded, for example if the dictionary is larger than the window size in +   deflate or deflate2. Thus the strings most likely to be useful should be +   put at the end of the dictionary, not at the front. In addition, the +   current implementation of deflate will use at most the window size minus +   262 bytes of the provided dictionary. + +     Upon return of this function, strm->adler is set to the adler32 value +   of the dictionary; the decompressor may later use this value to determine +   which dictionary has been used by the compressor. (The adler32 value +   applies to the whole dictionary even if only a subset of the dictionary is +   actually used by the compressor.) If a raw deflate was requested, then the +   adler32 value is not computed and strm->adler is not set. + +     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a +   parameter is invalid (such as NULL dictionary) or the stream state is +   inconsistent (for example if deflate has already been called for this stream +   or if the compression method is bsort). deflateSetDictionary does not +   perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, +                                    z_streamp source)); +/* +     Sets the destination stream as a complete copy of the source stream. + +     This function can be useful when several compression strategies will be +   tried, for example when there are several ways of pre-processing the input +   data with a filter. The streams that will be discarded should then be freed +   by calling deflateEnd.  Note that deflateCopy duplicates the internal +   compression state which can be quite large, so this strategy is slow and +   can consume lots of memory. + +     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not +   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent +   (such as zalloc being NULL). msg is left unchanged in both source and +   destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* +     This function is equivalent to deflateEnd followed by deflateInit, +   but does not free and reallocate all the internal compression state. +   The stream will keep the same compression level and any other attributes +   that may have been set by deflateInit2. + +      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source +   stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, +                                      int level, +                                      int strategy)); +/* +     Dynamically update the compression level and compression strategy.  The +   interpretation of level and strategy is as in deflateInit2.  This can be +   used to switch between compression and straight copy of the input data, or +   to switch to a different kind of input data requiring a different +   strategy. If the compression level is changed, the input available so far +   is compressed with the old level (and may be flushed); the new level will +   take effect only at the next call of deflate(). + +     Before the call of deflateParams, the stream state must be set as for +   a call of deflate(), since the currently available input may have to +   be compressed and flushed. In particular, strm->avail_out must be non-zero. + +     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source +   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR +   if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, +                                    int good_length, +                                    int max_lazy, +                                    int nice_length, +                                    int max_chain)); +/* +     Fine tune deflate's internal compression parameters.  This should only be +   used by someone who understands the algorithm used by zlib's deflate for +   searching for the best matching string, and even then only by the most +   fanatic optimizer trying to squeeze out the last compressed bit for their +   specific input data.  Read the deflate.c source code for the meaning of the +   max_lazy, good_length, nice_length, and max_chain parameters. + +     deflateTune() can be called after deflateInit() or deflateInit2(), and +   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, +                                       uLong sourceLen)); +/* +     deflateBound() returns an upper bound on the compressed size after +   deflation of sourceLen bytes.  It must be called after deflateInit() +   or deflateInit2().  This would be used to allocate an output buffer +   for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, +                                     int bits, +                                     int value)); +/* +     deflatePrime() inserts bits in the deflate output stream.  The intent +  is that this function is used to start off the deflate output with the +  bits leftover from a previous deflate stream when appending to it.  As such, +  this function can only be used for raw deflate, and must be used before the +  first deflate() call after a deflateInit2() or deflateReset().  bits must be +  less than or equal to 16, and that many of the least significant bits of +  value will be inserted in the output. + +      deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source +   stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, +                                         gz_headerp head)); +/* +      deflateSetHeader() provides gzip header information for when a gzip +   stream is requested by deflateInit2().  deflateSetHeader() may be called +   after deflateInit2() or deflateReset() and before the first call of +   deflate().  The text, time, os, extra field, name, and comment information +   in the provided gz_header structure are written to the gzip header (xflag is +   ignored -- the extra flags are set according to the compression level).  The +   caller must assure that, if not Z_NULL, name and comment are terminated with +   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are +   available there.  If hcrc is true, a gzip header crc is included.  Note that +   the current versions of the command-line version of gzip (up through version +   1.3.x) do not support header crc's, and will report that it is a "multi-part +   gzip file" and give up. + +      If deflateSetHeader is not used, the default gzip header has text false, +   the time set to zero, and os set to 255, with no extra, name, or comment +   fields.  The gzip header is returned to the default state by deflateReset(). + +      deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source +   stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, +                                     int  windowBits)); + +     This is another version of inflateInit with an extra parameter. The +   fields next_in, avail_in, zalloc, zfree and opaque must be initialized +   before by the caller. + +     The windowBits parameter is the base two logarithm of the maximum window +   size (the size of the history buffer).  It should be in the range 8..15 for +   this version of the library. The default value is 15 if inflateInit is used +   instead. windowBits must be greater than or equal to the windowBits value +   provided to deflateInit2() while compressing, or it must be equal to 15 if +   deflateInit2() was not used. If a compressed stream with a larger window +   size is given as input, inflate() will return with the error code +   Z_DATA_ERROR instead of trying to allocate a larger window. + +     windowBits can also be -8..-15 for raw inflate. In this case, -windowBits +   determines the window size. inflate() will then process raw deflate data, +   not looking for a zlib or gzip header, not generating a check value, and not +   looking for any check values for comparison at the end of the stream. This +   is for use with other formats that use the deflate compressed data format +   such as zip.  Those formats provide their own check values. If a custom +   format is developed using the raw deflate format for compressed data, it is +   recommended that a check value such as an adler32 or a crc32 be applied to +   the uncompressed data as is done in the zlib, gzip, and zip formats.  For +   most applications, the zlib format should be used as is. Note that comments +   above on the use in deflateInit2() applies to the magnitude of windowBits. + +     windowBits can also be greater than 15 for optional gzip decoding. Add +   32 to windowBits to enable zlib and gzip decoding with automatic header +   detection, or add 16 to decode only the gzip format (the zlib format will +   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is +   a crc32 instead of an adler32. + +     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough +   memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg +   is set to null if there is no error message.  inflateInit2 does not perform +   any decompression apart from reading the zlib header if present: this will +   be done by inflate(). (So next_in and avail_in may be modified, but next_out +   and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, +                                             const Bytef *dictionary, +                                             uInt  dictLength)); +/* +     Initializes the decompression dictionary from the given uncompressed byte +   sequence. This function must be called immediately after a call of inflate, +   if that call returned Z_NEED_DICT. The dictionary chosen by the compressor +   can be determined from the adler32 value returned by that call of inflate. +   The compressor and decompressor must use exactly the same dictionary (see +   deflateSetDictionary).  For raw inflate, this function can be called +   immediately after inflateInit2() or inflateReset() and before any call of +   inflate() to set the dictionary.  The application must insure that the +   dictionary that was used for compression is provided. + +     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a +   parameter is invalid (such as NULL dictionary) or the stream state is +   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the +   expected one (incorrect adler32 value). inflateSetDictionary does not +   perform any decompression: this will be done by subsequent calls of +   inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* +    Skips invalid compressed data until a full flush point (see above the +  description of deflate with Z_FULL_FLUSH) can be found, or until all +  available input is skipped. No output is provided. + +    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR +  if no more input was provided, Z_DATA_ERROR if no flush point has been found, +  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success +  case, the application may save the current current value of total_in which +  indicates where valid compressed data was found. In the error case, the +  application may repeatedly call inflateSync, providing more input each time, +  until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, +                                    z_streamp source)); +/* +     Sets the destination stream as a complete copy of the source stream. + +     This function can be useful when randomly accessing a large stream.  The +   first pass through the stream can periodically record the inflate state, +   allowing restarting inflate at those points when randomly accessing the +   stream. + +     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not +   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent +   (such as zalloc being NULL). msg is left unchanged in both source and +   destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* +     This function is equivalent to inflateEnd followed by inflateInit, +   but does not free and reallocate all the internal decompression state. +   The stream will keep attributes that may have been set by inflateInit2. + +      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source +   stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, +                                     int bits, +                                     int value)); +/* +     This function inserts bits in the inflate input stream.  The intent is +  that this function is used to start inflating at a bit position in the +  middle of a byte.  The provided bits will be used before any bytes are used +  from next_in.  This function should only be used with raw inflate, and +  should be used before the first inflate() call after inflateInit2() or +  inflateReset().  bits must be less than or equal to 16, and that many of the +  least significant bits of value will be inserted in the input. + +      inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source +   stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, +                                         gz_headerp head)); +/* +      inflateGetHeader() requests that gzip header information be stored in the +   provided gz_header structure.  inflateGetHeader() may be called after +   inflateInit2() or inflateReset(), and before the first call of inflate(). +   As inflate() processes the gzip stream, head->done is zero until the header +   is completed, at which time head->done is set to one.  If a zlib stream is +   being decoded, then head->done is set to -1 to indicate that there will be +   no gzip header information forthcoming.  Note that Z_BLOCK can be used to +   force inflate() to return immediately after header processing is complete +   and before any actual data is decompressed. + +      The text, time, xflags, and os fields are filled in with the gzip header +   contents.  hcrc is set to true if there is a header CRC.  (The header CRC +   was valid if done is set to one.)  If extra is not Z_NULL, then extra_max +   contains the maximum number of bytes to write to extra.  Once done is true, +   extra_len contains the actual extra field length, and extra contains the +   extra field, or that field truncated if extra_max is less than extra_len. +   If name is not Z_NULL, then up to name_max characters are written there, +   terminated with a zero unless the length is greater than name_max.  If +   comment is not Z_NULL, then up to comm_max characters are written there, +   terminated with a zero unless the length is greater than comm_max.  When +   any of extra, name, or comment are not Z_NULL and the respective field is +   not present in the header, then that field is set to Z_NULL to signal its +   absence.  This allows the use of deflateSetHeader() with the returned +   structure to duplicate the header.  However if those fields are set to +   allocated memory, then the application will need to save those pointers +   elsewhere so that they can be eventually freed. + +      If inflateGetHeader is not used, then the header information is simply +   discarded.  The header is always checked for validity, including the header +   CRC if present.  inflateReset() will reset the process to discard the header +   information.  The application would need to call inflateGetHeader() again to +   retrieve the header from the next gzip stream. + +      inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source +   stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, +                                        unsigned char FAR *window)); + +     Initialize the internal stream state for decompression using inflateBack() +   calls.  The fields zalloc, zfree and opaque in strm must be initialized +   before the call.  If zalloc and zfree are Z_NULL, then the default library- +   derived memory allocation routines are used.  windowBits is the base two +   logarithm of the window size, in the range 8..15.  window is a caller +   supplied buffer of that size.  Except for special applications where it is +   assured that deflate was used with small window sizes, windowBits must be 15 +   and a 32K byte window must be supplied to be able to decompress general +   deflate streams. + +     See inflateBack() for the usage of these routines. + +     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of +   the parameters are invalid, Z_MEM_ERROR if the internal state could not +   be allocated, or Z_VERSION_ERROR if the version of the library does not +   match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, +                                z_const unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, +                                    in_func in, void FAR *in_desc, +                                    out_func out, void FAR *out_desc)); +/* +     inflateBack() does a raw inflate with a single call using a call-back +   interface for input and output.  This is more efficient than inflate() for +   file i/o applications in that it avoids copying between the output and the +   sliding window by simply making the window itself the output buffer.  This +   function trusts the application to not change the output buffer passed by +   the output function, at least until inflateBack() returns. + +     inflateBackInit() must be called first to allocate the internal state +   and to initialize the state with the user-provided window buffer. +   inflateBack() may then be used multiple times to inflate a complete, raw +   deflate stream with each call.  inflateBackEnd() is then called to free +   the allocated state. + +     A raw deflate stream is one with no zlib or gzip header or trailer. +   This routine would normally be used in a utility that reads zip or gzip +   files and writes out uncompressed files.  The utility would decode the +   header and process the trailer on its own, hence this routine expects +   only the raw deflate stream to decompress.  This is different from the +   normal behavior of inflate(), which expects either a zlib or gzip header and +   trailer around the deflate stream. + +     inflateBack() uses two subroutines supplied by the caller that are then +   called by inflateBack() for input and output.  inflateBack() calls those +   routines until it reads a complete deflate stream and writes out all of the +   uncompressed data, or until it encounters an error.  The function's +   parameters and return types are defined above in the in_func and out_func +   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the +   number of bytes of provided input, and a pointer to that input in buf.  If +   there is no input available, in() must return zero--buf is ignored in that +   case--and inflateBack() will return a buffer error.  inflateBack() will call +   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out() +   should return zero on success, or non-zero on failure.  If out() returns +   non-zero, inflateBack() will return with an error.  Neither in() nor out() +   are permitted to change the contents of the window provided to +   inflateBackInit(), which is also the buffer that out() uses to write from. +   The length written by out() will be at most the window size.  Any non-zero +   amount of input may be provided by in(). + +     For convenience, inflateBack() can be provided input on the first call by +   setting strm->next_in and strm->avail_in.  If that input is exhausted, then +   in() will be called.  Therefore strm->next_in must be initialized before +   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called +   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in +   must also be initialized, and then if strm->avail_in is not zero, input will +   initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + +     The in_desc and out_desc parameters of inflateBack() is passed as the +   first parameter of in() and out() respectively when they are called.  These +   descriptors can be optionally used to pass any information that the caller- +   supplied in() and out() functions need to do their job. + +     On return, inflateBack() will set strm->next_in and strm->avail_in to +   pass back any unused input that was provided by the last in() call.  The +   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR +   if in() or out() returned an error, Z_DATA_ERROR if there was a format +   error in the deflate stream (in which case strm->msg is set to indicate the +   nature of the error), or Z_STREAM_ERROR if the stream was not properly +   initialized.  In the case of Z_BUF_ERROR, an input or output error can be +   distinguished using strm->next_in which will be Z_NULL only if in() returned +   an error.  If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to +   out() returning non-zero.  (in() will always be called before out(), so +   strm->next_in is assured to be defined if out() returns non-zero.)  Note +   that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* +     All memory allocated by inflateBackInit() is freed. + +     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream +   state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + +    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: +     1.0: size of uInt +     3.2: size of uLong +     5.4: size of voidpf (pointer) +     7.6: size of z_off_t + +    Compiler, assembler, and debug options: +     8: DEBUG +     9: ASMV or ASMINF -- use ASM code +     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention +     11: 0 (reserved) + +    One-time table building (smaller code, but not thread-safe if true): +     12: BUILDFIXED -- build static block decoding tables when needed +     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed +     14,15: 0 (reserved) + +    Library content (indicates missing functionality): +     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking +                          deflate code when not needed) +     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect +                    and decode gzip streams (to avoid linking crc code) +     18-19: 0 (reserved) + +    Operation variations (changes in library functionality): +     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate +     21: FASTEST -- deflate algorithm with only one, lowest compression level +     22,23: 0 (reserved) + +    The sprintf variant used by gzprintf (zero is best): +     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format +     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! +     26: 0 = returns value, 1 = void -- 1 means inferred string length returned + +    Remainder: +     27-31: 0 (reserved) + */ + + +                        /* utility functions */ + +/* +     The following utility functions are implemented on top of the +   basic stream-oriented functions. To simplify the interface, some +   default options are assumed (compression level and memory usage, +   standard memory allocation functions). The source code of these +   utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen, +                                 const Bytef *source, uLong sourceLen)); +/* +     Compresses the source buffer into the destination buffer.  sourceLen is +   the byte length of the source buffer. Upon entry, destLen is the total +   size of the destination buffer, which must be at least the value returned +   by compressBound(sourceLen). Upon exit, destLen is the actual size of the +   compressed buffer. +     This function can be used to compress a whole file at once if the +   input file is mmap'ed. +     compress returns Z_OK if success, Z_MEM_ERROR if there was not +   enough memory, Z_BUF_ERROR if there was not enough room in the output +   buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen, +                                  const Bytef *source, uLong sourceLen, +                                  int level)); +/* +     Compresses the source buffer into the destination buffer. The level +   parameter has the same meaning as in deflateInit.  sourceLen is the byte +   length of the source buffer. Upon entry, destLen is the total size of the +   destination buffer, which must be at least the value returned by +   compressBound(sourceLen). Upon exit, destLen is the actual size of the +   compressed buffer. + +     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough +   memory, Z_BUF_ERROR if there was not enough room in the output buffer, +   Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* +     compressBound() returns an upper bound on the compressed size after +   compress() or compress2() on sourceLen bytes.  It would be used before +   a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen, +                                   const Bytef *source, uLong sourceLen)); +/* +     Decompresses the source buffer into the destination buffer.  sourceLen is +   the byte length of the source buffer. Upon entry, destLen is the total +   size of the destination buffer, which must be large enough to hold the +   entire uncompressed data. (The size of the uncompressed data must have +   been saved previously by the compressor and transmitted to the decompressor +   by some mechanism outside the scope of this compression library.) +   Upon exit, destLen is the actual size of the compressed buffer. +     This function can be used to decompress a whole file at once if the +   input file is mmap'ed. + +     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not +   enough memory, Z_BUF_ERROR if there was not enough room in the output +   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode)); +/* +     Opens a gzip (.gz) file for reading or writing. The mode parameter +   is as in fopen ("rb" or "wb") but can also include a compression level +   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for +   Huffman only compression as in "wb1h", or 'R' for run-length encoding +   as in "wb1R". (See the description of deflateInit2 for more information +   about the strategy parameter.) + +     gzopen can be used to read a file which is not in gzip format; in this +   case gzread will directly read from the file without decompression. + +     gzopen returns NULL if the file could not be opened or if there was +   insufficient memory to allocate the (de)compression state; errno +   can be checked to distinguish the two cases (if errno is zero, the +   zlib error is Z_MEM_ERROR).  */ + +ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode)); +/* +     gzdopen() associates a gzFile with the file descriptor fd.  File +   descriptors are obtained from calls like open, dup, creat, pipe or +   fileno (in the file has been previously opened with fopen). +   The mode parameter is as in gzopen. +     The next call of gzclose on the returned gzFile will also close the +   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file +   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). +     gzdopen returns NULL if there was insufficient memory to allocate +   the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* +     Dynamically update the compression level or strategy. See the description +   of deflateInit2 for the meaning of these parameters. +     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not +   opened for writing. +*/ + +ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len)); +/* +     Reads the given number of uncompressed bytes from the compressed file. +   If the input file was not in gzip format, gzread copies the given number +   of bytes into the buffer. +     gzread returns the number of uncompressed bytes actually read (0 for +   end of file, -1 for error). */ + +ZEXTERN int ZEXPORT    gzwrite OF((gzFile file, +                                   voidpc buf, unsigned len)); +/* +     Writes the given number of uncompressed bytes into the compressed file. +   gzwrite returns the number of uncompressed bytes actually written +   (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...)); +/* +     Converts, formats, and writes the args to the compressed file under +   control of the format string, as in fprintf. gzprintf returns the number of +   uncompressed bytes actually written (0 in case of error).  The number of +   uncompressed bytes written is limited to 4095. The caller should assure that +   this limit is not exceeded. If it is exceeded, then gzprintf() will return +   return an error (0) with nothing written. In this case, there may also be a +   buffer overflow with unpredictable consequences, which is possible only if +   zlib was compiled with the insecure functions sprintf() or vsprintf() +   because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* +      Writes the given null-terminated string to the compressed file, excluding +   the terminating null character. +      gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* +      Reads bytes from the compressed file until len-1 characters are read, or +   a newline character is read and transferred to buf, or an end-of-file +   condition is encountered.  The string is then terminated with a null +   character. +      gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c)); +/* +      Writes c, converted to an unsigned char, into the compressed file. +   gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT    gzgetc OF((gzFile file)); +/* +      Reads one byte from the compressed file. gzgetc returns this byte +   or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT    gzungetc OF((int c, gzFile file)); +/* +      Push one character back onto the stream to be read again later. +   Only one character of push-back is allowed.  gzungetc() returns the +   character pushed, or -1 on failure.  gzungetc() will fail if a +   character has been pushed but not read yet, or if c is -1. The pushed +   character will be discarded if the stream is repositioned with gzseek() +   or gzrewind(). +*/ + +ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush)); +/* +     Flushes all pending output into the compressed file. The parameter +   flush is as in the deflate() function. The return value is the zlib +   error number (see function gzerror below). gzflush returns Z_OK if +   the flush parameter is Z_FINISH and all output could be flushed. +     gzflush should be called only when strictly necessary because it can +   degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file, +                                      z_off_t offset, int whence)); +/* +      Sets the starting position for the next gzread or gzwrite on the +   given compressed file. The offset represents a number of bytes in the +   uncompressed data stream. The whence parameter is defined as in lseek(2); +   the value SEEK_END is not supported. +     If the file is opened for reading, this function is emulated but can be +   extremely slow. If the file is opened for writing, only forward seeks are +   supported; gzseek then compresses a sequence of zeroes up to the new +   starting position. + +      gzseek returns the resulting offset location as measured in bytes from +   the beginning of the uncompressed stream, or -1 in case of error, in +   particular if the file is opened for writing and the new starting position +   would be before the current position. +*/ + +ZEXTERN int ZEXPORT    gzrewind OF((gzFile file)); +/* +     Rewinds the given file. This function is supported only for reading. + +   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file)); +/* +     Returns the starting position for the next gzread or gzwrite on the +   given compressed file. This position represents a number of bytes in the +   uncompressed data stream. + +   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* +     Returns 1 when EOF has previously been detected reading the given +   input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* +     Returns 1 if file is being read directly without decompression, otherwise +   zero. +*/ + +ZEXTERN int ZEXPORT    gzclose OF((gzFile file)); +/* +     Flushes all pending output if necessary, closes the compressed file +   and deallocates all the (de)compression state. The return value is the zlib +   error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* +     Returns the error message for the last error which occurred on the +   given compressed file. errnum is set to zlib error number. If an +   error occurred in the file system and not in the compression library, +   errnum is set to Z_ERRNO and the application may consult errno +   to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* +     Clears the error and end-of-file flags for file. This is analogous to the +   clearerr() function in stdio. This is useful for continuing to read a gzip +   file that is being written concurrently. +*/ + +                        /* checksum functions */ + +/* +     These functions are not related to compression but are exported +   anyway because they might be useful in applications using the +   compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* +     Update a running Adler-32 checksum with the bytes buf[0..len-1] and +   return the updated checksum. If buf is NULL, this function returns +   the required initial value for the checksum. +   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed +   much faster. Usage example: + +     uLong adler = adler32(0L, Z_NULL, 0); + +     while (read_buffer(buffer, length) != EOF) { +       adler = adler32(adler, buffer, length); +     } +     if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, +                                          z_off_t len2)); +/* +     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1 +   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for +   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of +   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len)); +/* +     Update a running CRC-32 with the bytes buf[0..len-1] and return the +   updated CRC-32. If buf is NULL, this function returns the required initial +   value for the for the crc. Pre- and post-conditioning (one's complement) is +   performed within this function so it shouldn't be done by the application. +   Usage example: + +     uLong crc = crc32(0L, Z_NULL, 0); + +     while (read_buffer(buffer, length) != EOF) { +       crc = crc32(crc, buffer, length); +     } +     if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* +     Combine two CRC-32 check values into one.  For two sequences of bytes, +   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were +   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32 +   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and +   len2. +*/ + + +                        /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, +                                     const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, +                                     const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method, +                                      int windowBits, int memLevel, +                                      int strategy, const char *version, +                                      int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits, +                                      const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, +                                         unsigned char FAR *window, +                                         const char *version, +                                         int stream_size)); +#define deflateInit(strm, level) \ +        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ +        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ +        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ +                      (strategy),           ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ +        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ +        inflateBackInit_((strm), (windowBits), (window), \ +        ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) +    struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char   * ZEXPORT zError           OF((int)); +ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/lib/libz/zutil.c b/lib/libz/zutil.c new file mode 100644 index 0000000..42813db --- /dev/null +++ b/lib/libz/zutil.c @@ -0,0 +1,319 @@ +/*	$OpenBSD: zutil.c,v 1.9 2015/08/21 23:30:59 deraadt Exp $	*/ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state      {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary",     /* Z_NEED_DICT       2  */ +"stream end",          /* Z_STREAM_END      1  */ +"",                    /* Z_OK              0  */ +"file error",          /* Z_ERRNO         (-1) */ +"stream error",        /* Z_STREAM_ERROR  (-2) */ +"data error",          /* Z_DATA_ERROR    (-3) */ +"insufficient memory", /* Z_MEM_ERROR     (-4) */ +"buffer error",        /* Z_BUF_ERROR     (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ +    return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ +    uLong flags; + +    flags = 0; +    switch (sizeof(uInt)) { +    case 2:     break; +    case 4:     flags += 1;     break; +    case 8:     flags += 2;     break; +    default:    flags += 3; +    } +    switch (sizeof(uLong)) { +    case 2:     break; +    case 4:     flags += 1 << 2;        break; +    case 8:     flags += 2 << 2;        break; +    default:    flags += 3 << 2; +    } +    switch (sizeof(voidpf)) { +    case 2:     break; +    case 4:     flags += 1 << 4;        break; +    case 8:     flags += 2 << 4;        break; +    default:    flags += 3 << 4; +    } +    switch (sizeof(z_off_t)) { +    case 2:     break; +    case 4:     flags += 1 << 6;        break; +    case 8:     flags += 2 << 6;        break; +    default:    flags += 3 << 6; +    } +#ifdef DEBUG +    flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) +    flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI +    flags += 1 << 10; +#endif +#ifdef BUILDFIXED +    flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE +    flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS +    flags += 1L << 16; +#endif +#ifdef NO_GZIP +    flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND +    flags += 1L << 20; +#endif +#ifdef FASTEST +    flags += 1L << 21; +#endif +#ifdef STDC +#  ifdef NO_vsnprintf +        flags += 1L << 25; +#    ifdef HAS_vsprintf_void +        flags += 1L << 26; +#    endif +#  else +#    ifdef HAS_vsnprintf_void +        flags += 1L << 26; +#    endif +#  endif +#else +        flags += 1L << 24; +#  ifdef NO_snprintf +        flags += 1L << 25; +#    ifdef HAS_sprintf_void +        flags += 1L << 26; +#    endif +#  else +#    ifdef HAS_snprintf_void +        flags += 1L << 26; +#    endif +#  endif +#endif +    return flags; +} + +#ifdef DEBUG + +#  ifndef verbose +#    define verbose 0 +#  endif +int z_verbose = verbose; + +void z_error (m) +    char *m; +{ +    fprintf(stderr, "%s\n", m); +    exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) +    int err; +{ +    return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) +    /* The Microsoft C Run-Time Library for Windows CE doesn't have +     * errno.  We define it as a global variable to simplify porting. +     * Its value is always 0 and should not be used. +     */ +    int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) +    Bytef* dest; +    const Bytef* source; +    uInt  len; +{ +    if (len == 0) return; +    do { +        *dest++ = *source++; /* ??? to be unrolled */ +    } while (--len != 0); +} + +int zmemcmp(s1, s2, len) +    const Bytef* s1; +    const Bytef* s2; +    uInt  len; +{ +    uInt j; + +    for (j = 0; j < len; j++) { +        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; +    } +    return 0; +} + +void zmemzero(dest, len) +    Bytef* dest; +    uInt  len; +{ +    if (len == 0) return; +    do { +        *dest++ = 0;  /* ??? to be unrolled */ +    } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +#  define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { +    voidpf org_ptr; +    voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ +    voidpf buf = opaque; /* just to make some compilers happy */ +    ulg bsize = (ulg)items*size; + +    /* If we allocate less than 65520 bytes, we assume that farmalloc +     * will return a usable pointer which doesn't have to be normalized. +     */ +    if (bsize < 65520L) { +        buf = farmalloc(bsize); +        if (*(ush*)&buf != 0) return buf; +    } else { +        buf = farmalloc(bsize + 16L); +    } +    if (buf == NULL || next_ptr >= MAX_PTR) return NULL; +    table[next_ptr].org_ptr = buf; + +    /* Normalize the pointer to seg:0 */ +    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; +    *(ush*)&buf = 0; +    table[next_ptr++].new_ptr = buf; +    return buf; +} + +void  zcfree (voidpf opaque, voidpf ptr) +{ +    int n; +    if (*(ush*)&ptr != 0) { /* object < 64K */ +        farfree(ptr); +        return; +    } +    /* Find the original pointer */ +    for (n = 0; n < next_ptr; n++) { +        if (ptr != table[n].new_ptr) continue; + +        farfree(table[n].org_ptr); +        while (++n < next_ptr) { +            table[n-1] = table[n]; +        } +        next_ptr--; +        return; +    } +    ptr = opaque; /* just to make some compilers happy */ +    Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +#  define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +#  define _halloc  halloc +#  define _hfree   hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ +    if (opaque) opaque = 0; /* to make compiler happy */ +    return _halloc((long)items, size); +} + +void  zcfree (voidpf opaque, voidpf ptr) +{ +    if (opaque) opaque = 0; /* to make compiler happy */ +    _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp  malloc OF((uInt size)); +extern voidp  calloc OF((uInt items, uInt size)); +extern void   free   OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) +    voidpf opaque; +    unsigned items; +    unsigned size; +{ +    if (opaque) items += size - size; /* make compiler happy */ +    if (items == 0 || size == 0) +        return (NULL); +    return reallocarray(NULL, items, size); +} + +void  zcfree (opaque, ptr) +    voidpf opaque; +    voidpf ptr; +{ +    free(ptr); +    if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/lib/libz/zutil.h b/lib/libz/zutil.h new file mode 100644 index 0000000..5726e18 --- /dev/null +++ b/lib/libz/zutil.h @@ -0,0 +1,273 @@ +/*	$OpenBSD: zutil.h,v 1.9 2005/07/20 15:56:42 millert Exp $	*/ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is +   part of the implementation of the compression library and is +   subject to change. Applications should only use zlib.h. + */ + + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef _STANDALONE +#include <stand.h> +#else +#ifdef STDC +#  ifndef _WIN32_WCE +#    include <stddef.h> +#  endif +#  include <string.h> +#  include <stdlib.h> +#endif +#ifdef NO_ERRNO_H +#   ifdef _WIN32_WCE +      /* The Microsoft C Run-Time Library for Windows CE doesn't have +       * errno.  We define it as a global variable to simplify porting. +       * Its value is always 0 and should not be used.  We rename it to +       * avoid conflict with other libraries that use the same workaround. +       */ +#     define errno z_errno +#   endif +    extern int errno; +#else +#  ifndef _WIN32_WCE +#    include <errno.h> +#  endif +#endif +#endif + +#ifndef local +#  define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char  uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long  ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ +  return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + +        /* common constants */ + +#ifndef DEF_WBITS +#  define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +#  define DEF_MEM_LEVEL 8 +#else +#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES    2 +/* The three kinds of block type */ + +#define MIN_MATCH  3 +#define MAX_MATCH  258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + +        /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +#  define OS_CODE  0x00 +#  if defined(__TURBOC__) || defined(__BORLANDC__) +#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) +       /* Allow compilation with ANSI keywords only enabled */ +       void _Cdecl farfree( void *block ); +       void *_Cdecl farmalloc( unsigned long nbytes ); +#    else +#      include <alloc.h> +#    endif +#  else /* MSC or DJGPP */ +#    include <malloc.h> +#  endif +#endif + +#ifdef AMIGA +#  define OS_CODE  0x01 +#endif + +#if defined(VAXC) || defined(VMS) +#  define OS_CODE  0x02 +#  define F_OPEN(name, mode) \ +     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +#  define OS_CODE  0x05 +#endif + +#ifdef OS2 +#  define OS_CODE  0x06 +#  ifdef M_I86 +     #include <malloc.h> +#  endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +#  define OS_CODE  0x07 +#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +#    include <unix.h> /* for fdopen */ +#  else +#    ifndef fdopen +#      define fdopen(fd,mode) NULL /* No fdopen() */ +#    endif +#  endif +#endif + +#ifdef TOPS20 +#  define OS_CODE  0x0a +#endif + +#ifdef WIN32 +#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */ +#    define OS_CODE  0x0b +#  endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +#  define OS_CODE  0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +#  define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +#  if defined(_WIN32_WCE) +#    define fdopen(fd,mode) NULL /* No fdopen() */ +#    ifndef _PTRDIFF_T_DEFINED +       typedef int ptrdiff_t; +#      define _PTRDIFF_T_DEFINED +#    endif +#  else +#    define fdopen(fd,type)  _fdopen(fd,type) +#  endif +#endif + +        /* common defaults */ + +#ifndef OS_CODE +#  define OS_CODE  0x03  /* assume Unix */ +#endif + +#ifndef F_OPEN +#  define F_OPEN(name, mode) fopen((name), (mode)) +#endif + +         /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +#  ifndef HAVE_VSNPRINTF +#    define HAVE_VSNPRINTF +#  endif +#endif +#if defined(__CYGWIN__) +#  ifndef HAVE_VSNPRINTF +#    define HAVE_VSNPRINTF +#  endif +#endif +#ifndef HAVE_VSNPRINTF +#  ifdef MSDOS +     /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), +        but for now we just assume it doesn't. */ +#    define NO_vsnprintf +#  endif +#  ifdef __TURBOC__ +#    define NO_vsnprintf +#  endif +#  ifdef WIN32 +     /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +#    if !defined(vsnprintf) && !defined(NO_vsnprintf) +#      define vsnprintf _vsnprintf +#    endif +#  endif +#  ifdef __SASC +#    define NO_vsnprintf +#  endif +#endif +#ifdef VMS +#  define NO_vsnprintf +#endif + +#if defined(pyr) +#  define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. +  * You may have to use the same strategy for Borland C (untested). +  * The __SC__ check is for Symantec. +  */ +#  define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +#  define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +#    define zmemcpy _fmemcpy +#    define zmemcmp _fmemcmp +#    define zmemzero(dest, len) _fmemset(dest, 0, len) +#  else +#    define zmemcpy memcpy +#    define zmemcmp memcmp +#    define zmemzero(dest, len) memset(dest, 0, len) +#  endif +#else +   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len)); +   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len)); +   extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +#  include <stdio.h> +   extern int z_verbose; +   extern void z_error    OF((char *m)); +#  define Assert(cond,msg) {if(!(cond)) z_error(msg);} +#  define Trace(x) {if (z_verbose>=0) fprintf x ;} +#  define Tracev(x) {if (z_verbose>0) fprintf x ;} +#  define Tracevv(x) {if (z_verbose>1) fprintf x ;} +#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +#  define Assert(cond,msg) +#  define Trace(x) +#  define Tracev(x) +#  define Tracevv(x) +#  define Tracec(c,x) +#  define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void   zcfree  OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ +           (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */  | 
