You need to sign in or sign up before continuing.
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 17 18
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	};

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

#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,
	};

43 44 45 46 47 48 49
/* 
 * 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)
50 51 52 53 54 55 56 57 58 59
# include <windows.h>

# define Z_CALLCONV _stcall
# define ZLIB_SHARED
#else
# define Z_CALLCONV
#endif /* !(WINDOWS || WIN32) */

#ifdef ZLIB_SHARED
#include <openssl/dso.h>
60 61

/* Prototypes for built in stubs */
62
static int stub_compress(Bytef *dest,uLongf *destLen,
63
	const Bytef *source, uLong sourceLen);
64 65 66 67
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);
68 69

/* Function pointers */
70
typedef int Z_CALLCONV (*compress_ft)(Bytef *dest,uLongf *destLen,
71
	const Bytef *source, uLong sourceLen);
72 73 74 75 76 77 78 79
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,
	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;
80 81

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

#define compress                stub_compress
#define inflateEnd              stub_inflateEnd
#define inflate                 stub_inflate
#define inflateInit_            stub_inflateInit_
88
#endif /* ZLIB_SHARED */
89

U
Ulf Möller 已提交
90 91
static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
	     unsigned int olen, unsigned char *in, unsigned int ilen)
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
	{
	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;
		}
116 117 118 119
#ifdef DEBUG_ZLIB
	fprintf(stderr,"compress(%4d)->%4d %s\n",
		ilen,(int)l,(clear)?"clear":"zlib");
#endif
120 121 122
	return((int)l);
	}

U
Ulf Möller 已提交
123 124
static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
	     unsigned int olen, unsigned char *in, unsigned int ilen)
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
	{
	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;
		}
141 142 143 144
#ifdef DEBUG_ZLIB
        fprintf(stderr,"expand  (%4d)->%4d %s\n",
		ilen,(int)l,in[0]?"zlib":"clear");
#endif
145 146 147
	return((int)l);
	}

U
Ulf Möller 已提交
148 149
static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source,
	     uLong sourceLen)
150 151 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
{
    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 已提交
182
COMP_METHOD *COMP_zlib(void)
183
	{
184 185
	COMP_METHOD *meth = &zlib_method_nozlib;

186 187
#ifdef ZLIB_SHARED
	if (!zlib_loaded)
188
		{
189
#if defined(WINDOWS) || defined(WIN32)
190
		zlib_dso = DSO_load(NULL, "ZLIB", NULL, 0);
191 192 193 194
#else
		zlib_dso = DSO_load(NULL, "z", NULL, 0);
#endif
		if (zlib_dso != NULL)
195
			{
196 197 198 199 200 201 202 203 204 205 206 207
			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_");
208 209 210 211 212
			zlib_loaded++;
			meth = &zlib_method;
			}
		}

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

	return(meth);
	}

220
#ifdef ZLIB_SHARED
221 222 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
/* 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);
256 257
	}

258
#endif /* ZLIB_SHARED */