c_zlib.c 5.6 KB
Newer Older
1 2 3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
4 5
#include <openssl/objects.h>
#include <openssl/comp.h>
6 7 8

COMP_METHOD *COMP_zlib(void );

9
static COMP_METHOD zlib_method_nozlib={
10
	NID_undef,
11
	"(undef)",
12 13 14 15 16
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
17
	NULL,
18 19
	};

20 21 22
#ifndef ZLIB
#undef ZLIB_SHARED
#else
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

#include <zlib.h>

static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
	unsigned int olen, unsigned char *in, unsigned int ilen);
static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
	unsigned int olen, unsigned char *in, unsigned int ilen);

static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
	uLong sourceLen);

static COMP_METHOD zlib_method={
	NID_zlib_compression,
	LN_zlib_compression,
	NULL,
	NULL,
	zlib_compress_block,
	zlib_expand_block,
	NULL,
42
	NULL,
43 44
	};

45 46 47 48 49 50 51
/* 
 * When OpenSSL is built on Windows, we do not want to require that
 * the ZLIB.DLL be available in order for the OpenSSL DLLs to
 * work.  Therefore, all ZLIB routines are loaded at run time
 * and we do not link to a .LIB file.
 */
#if defined(WINDOWS) || defined(WIN32)
52 53
# include <windows.h>

R
Richard Levitte 已提交
54
# define Z_CALLCONV _stdcall
55 56 57 58 59 60 61
# define ZLIB_SHARED
#else
# define Z_CALLCONV
#endif /* !(WINDOWS || WIN32) */

#ifdef ZLIB_SHARED
#include <openssl/dso.h>
62 63

/* Prototypes for built in stubs */
64
static int stub_compress(Bytef *dest,uLongf *destLen,
65
	const Bytef *source, uLong sourceLen);
66 67 68 69
static int stub_inflateEnd(z_streamp strm);
static int stub_inflate(z_streamp strm, int flush);
static int stub_inflateInit_(z_streamp strm, const char * version,
	int stream_size);
70 71

/* Function pointers */
R
Richard Levitte 已提交
72
typedef int (Z_CALLCONV *compress_ft)(Bytef *dest,uLongf *destLen,
73
	const Bytef *source, uLong sourceLen);
R
Richard Levitte 已提交
74 75 76
typedef int (Z_CALLCONV *inflateEnd_ft)(z_streamp strm);
typedef int (Z_CALLCONV *inflate_ft)(z_streamp strm, int flush);
typedef int (Z_CALLCONV *inflateInit__ft)(z_streamp strm,
77 78 79 80 81
	const char * version, int stream_size);
static compress_ft	p_compress=NULL;
static inflateEnd_ft	p_inflateEnd=NULL;
static inflate_ft	p_inflate=NULL;
static inflateInit__ft	p_inflateInit_=NULL;
82 83

static int zlib_loaded = 0;     /* only attempt to init func pts once */
84
static DSO *zlib_dso = NULL;
85 86 87 88 89

#define compress                stub_compress
#define inflateEnd              stub_inflateEnd
#define inflate                 stub_inflate
#define inflateInit_            stub_inflateInit_
90
#endif /* ZLIB_SHARED */
91

U
Ulf Möller 已提交
92 93
static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
	     unsigned int olen, unsigned char *in, unsigned int ilen)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
	{
	unsigned long l;
	int i;
	int clear=1;

	if (ilen > 128)
		{
		out[0]=1;
		l=olen-1;
		i=compress(&(out[1]),&l,in,(unsigned long)ilen);
		if (i != Z_OK)
			return(-1);
		if (ilen > l)
			{
			clear=0;
			l++;
			}
		}
	if (clear)
		{
		out[0]=0;
		memcpy(&(out[1]),in,ilen);
		l=ilen+1;
		}
118 119 120 121
#ifdef DEBUG_ZLIB
	fprintf(stderr,"compress(%4d)->%4d %s\n",
		ilen,(int)l,(clear)?"clear":"zlib");
#endif
122 123 124
	return((int)l);
	}

U
Ulf Möller 已提交
125 126
static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
	     unsigned int olen, unsigned char *in, unsigned int ilen)
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
	{
	unsigned long l;
	int i;

	if (in[0])
		{
		l=olen;
		i=zz_uncompress(out,&l,&(in[1]),(unsigned long)ilen-1);
		if (i != Z_OK)
			return(-1);
		}
	else
		{
		memcpy(out,&(in[1]),ilen-1);
		l=ilen-1;
		}
143 144 145 146
#ifdef DEBUG_ZLIB
        fprintf(stderr,"expand  (%4d)->%4d %s\n",
		ilen,(int)l,in[0]?"zlib":"clear");
#endif
147 148 149
	return((int)l);
	}

U
Ulf Möller 已提交
150 151
static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source,
	     uLong sourceLen)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
{
    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);
        return err;
    }
    *destLen = stream.total_out;

    err = inflateEnd(&stream);
    return err;
}

#endif

U
Ulf Möller 已提交
184
COMP_METHOD *COMP_zlib(void)
185
	{
186 187
	COMP_METHOD *meth = &zlib_method_nozlib;

188 189
#ifdef ZLIB_SHARED
	if (!zlib_loaded)
190
		{
191
#if defined(WINDOWS) || defined(WIN32)
192
		zlib_dso = DSO_load(NULL, "ZLIB", NULL, 0);
193 194 195 196
#else
		zlib_dso = DSO_load(NULL, "z", NULL, 0);
#endif
		if (zlib_dso != NULL)
197
			{
198 199 200 201 202 203 204 205 206 207 208 209
			p_compress
				= (compress_ft) DSO_bind_func(zlib_dso,
					"compress");
			p_inflateEnd
				= (inflateEnd_ft) DSO_bind_func(zlib_dso,
					"inflateEnd");
			p_inflate
				= (inflate_ft) DSO_bind_func(zlib_dso,
					"inflate");
			p_inflateInit_
				= (inflateInit__ft) DSO_bind_func(zlib_dso,
					"inflateInit_");
210 211 212 213 214
			zlib_loaded++;
			meth = &zlib_method;
			}
		}

215
#elif defined(ZLIB)
216 217 218 219 220 221
	meth = &zlib_method;
#endif

	return(meth);
	}

222
#ifdef ZLIB_SHARED
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
/* Stubs for each function to be dynamicly loaded */
static int 
stub_compress(Bytef *dest,uLongf *destLen,const Bytef *source, uLong sourceLen)
	{
	if (p_compress)
		return(p_compress(dest,destLen,source,sourceLen));
	else
		return(Z_MEM_ERROR);
	}

static int
stub_inflateEnd(z_streamp strm)
	{
	if ( p_inflateEnd )
		return(p_inflateEnd(strm));
	else
		return(Z_MEM_ERROR);
	}

static int
stub_inflate(z_streamp strm, int flush)
	{
	if ( p_inflate )
		return(p_inflate(strm,flush));
	else
		return(Z_MEM_ERROR);
	}

static int
stub_inflateInit_(z_streamp strm, const char * version, int stream_size)
	{
	if ( p_inflateInit_ )
		return(p_inflateInit_(strm,version,stream_size));
	else
		return(Z_MEM_ERROR);
258 259
	}

260
#endif /* ZLIB_SHARED */