os/ossrv/ssl/libcrypto/src/crypto/comp/c_zlib.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
     3 
     4 Redistribution and use in source and binary forms, with or without 
     5 modification, are permitted provided that the following conditions are met:
     6 
     7 * Redistributions of source code must retain the above copyright notice, this 
     8   list of conditions and the following disclaimer.
     9 * Redistributions in binary form must reproduce the above copyright notice, 
    10   this list of conditions and the following disclaimer in the documentation 
    11   and/or other materials provided with the distribution.
    12 * Neither the name of Nokia Corporation nor the names of its contributors 
    13   may be used to endorse or promote products derived from this software 
    14   without specific prior written permission.
    15 
    16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
    17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
    18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
    19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
    20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
    21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
    22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
    23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
    24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    26 
    27 Description:
    28 */
    29 
    30 #include <stdio.h>
    31 #include <stdlib.h>
    32 #include <string.h>
    33 #include <openssl/objects.h>
    34 #include <openssl/comp.h>
    35 #include <openssl/err.h>
    36 #if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
    37 #include "libcrypto_wsd_macros.h"
    38 #include "libcrypto_wsd.h"
    39 #endif
    40 
    41 
    42 COMP_METHOD *COMP_zlib(void );
    43 #ifndef EMULATOR
    44 static COMP_METHOD zlib_method_nozlib={
    45 	NID_undef,
    46 	"(undef)",
    47 	NULL,
    48 	NULL,
    49 	NULL,
    50 	NULL,
    51 	NULL,
    52 	NULL,
    53 	};
    54 #else//EMULATOR
    55   GET_STATIC_VAR_FROM_TLS(zlib_method_nozlib,c_zlib,COMP_METHOD)
    56   #define zlib_method_nozlib (*GET_WSD_VAR_NAME(zlib_method_nozlib,c_zlib, s)())
    57   const COMP_METHOD temp_s_zlib_method_nozlib={
    58 	NID_undef,
    59 	"(undef)",
    60 	NULL,
    61 	NULL,
    62 	NULL,
    63 	NULL,
    64 	NULL,
    65 	NULL,
    66 	};
    67 #endif//EMULATOR
    68 
    69 #ifndef ZLIB
    70 #undef ZLIB_SHARED
    71 #else
    72 
    73 #include <zlib.h>
    74 
    75 static int zlib_stateful_init(COMP_CTX *ctx);
    76 static void zlib_stateful_finish(COMP_CTX *ctx);
    77 static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
    78 	unsigned int olen, unsigned char *in, unsigned int ilen);
    79 static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
    80 	unsigned int olen, unsigned char *in, unsigned int ilen);
    81 
    82 #if 0
    83 static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
    84 	unsigned int olen, unsigned char *in, unsigned int ilen);
    85 static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
    86 	unsigned int olen, unsigned char *in, unsigned int ilen);
    87 
    88 static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
    89 	uLong sourceLen);
    90 
    91 static COMP_METHOD zlib_stateless_method={
    92 	NID_zlib_compression,
    93 	LN_zlib_compression,
    94 	NULL,
    95 	NULL,
    96 	zlib_compress_block,
    97 	zlib_expand_block,
    98 	NULL,
    99 	NULL,
   100 	};
   101 #endif
   102 #ifndef EMULATOR
   103 static COMP_METHOD zlib_stateful_method={
   104 	NID_zlib_compression,
   105 	LN_zlib_compression,
   106 	zlib_stateful_init,
   107 	zlib_stateful_finish,
   108 	zlib_stateful_compress_block,
   109 	zlib_stateful_expand_block,
   110 	NULL,
   111 	NULL,
   112 	};
   113 #else//EMULATOR
   114   GET_STATIC_VAR_FROM_TLS(zlib_stateful_method,c_zlib,COMP_METHOD)
   115   #define zlib_stateful_method (*GET_WSD_VAR_NAME(zlib_stateful_method,c_zlib, s)())
   116   const COMP_METHOD temp_s_zlib_stateful_method={
   117 	NID_zlib_compression,
   118 	LN_zlib_compression,
   119 	zlib_stateful_init,
   120 	zlib_stateful_finish,
   121 	zlib_stateful_compress_block,
   122 	zlib_stateful_expand_block,
   123 	NULL,
   124 	NULL,
   125 	};
   126 #endif//EMULATOR
   127 
   128 /* 
   129  * When OpenSSL is built on Windows, we do not want to require that
   130  * the ZLIB.DLL be available in order for the OpenSSL DLLs to
   131  * work.  Therefore, all ZLIB routines are loaded at run time
   132  * and we do not link to a .LIB file.
   133  */
   134 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
   135 # include <windows.h>
   136 
   137 # define Z_CALLCONV _stdcall
   138 # ifndef ZLIB_SHARED
   139 #  define ZLIB_SHARED
   140 # endif
   141 #else
   142 # define Z_CALLCONV
   143 #endif /* !(OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32) */
   144 
   145 #ifdef ZLIB_SHARED
   146 #include <openssl/dso.h>
   147 
   148 /* Prototypes for built in stubs */
   149 #if 0
   150 static int stub_compress(Bytef *dest,uLongf *destLen,
   151 	const Bytef *source, uLong sourceLen);
   152 #endif
   153 static int stub_inflateEnd(z_streamp strm);
   154 static int stub_inflate(z_streamp strm, int flush);
   155 static int stub_inflateInit_(z_streamp strm, const char * version,
   156 	int stream_size);
   157 static int stub_deflateEnd(z_streamp strm);
   158 static int stub_deflate(z_streamp strm, int flush);
   159 static int stub_deflateInit_(z_streamp strm, int level,
   160 	const char * version, int stream_size);
   161 
   162 #ifndef EMULATOR
   163 /* Function pointers */
   164 typedef int (Z_CALLCONV *compress_ft)(Bytef *dest,uLongf *destLen,
   165 	const Bytef *source, uLong sourceLen);
   166 typedef int (Z_CALLCONV *inflateEnd_ft)(z_streamp strm);
   167 typedef int (Z_CALLCONV *inflate_ft)(z_streamp strm, int flush);
   168 typedef int (Z_CALLCONV *inflateInit__ft)(z_streamp strm,
   169 	const char * version, int stream_size);
   170 typedef int (Z_CALLCONV *deflateEnd_ft)(z_streamp strm);
   171 typedef int (Z_CALLCONV *deflate_ft)(z_streamp strm, int flush);
   172 typedef int (Z_CALLCONV *deflateInit__ft)(z_streamp strm, int level,
   173 	const char * version, int stream_size);
   174 #endif	
   175 	
   176 #ifndef EMULATOR	
   177 static compress_ft	p_compress=NULL;
   178 static inflateEnd_ft	p_inflateEnd=NULL;
   179 static inflate_ft	p_inflate=NULL;
   180 static inflateInit__ft	p_inflateInit_=NULL;
   181 
   182 static deflateEnd_ft	p_deflateEnd=NULL;
   183 static deflate_ft	p_deflate=NULL;
   184 static deflateInit__ft	p_deflateInit_=NULL;
   185 static int zlib_loaded = 0;     /* only attempt to init func pts once */
   186 static DSO *zlib_dso = NULL;
   187 #else
   188 GET_STATIC_VAR_FROM_TLS(p_compress,c_zlib,compress_ft)
   189 #define p_compress (*GET_WSD_VAR_NAME(p_compress,c_zlib, s)())
   190 
   191 GET_STATIC_VAR_FROM_TLS(p_inflateEnd,c_zlib,inflateEnd_ft)
   192 #define p_inflateEnd (*GET_WSD_VAR_NAME(p_inflateEnd,c_zlib, s)())
   193 
   194 
   195 GET_STATIC_VAR_FROM_TLS(p_inflate,c_zlib,inflate_ft)
   196 #define p_inflate (*GET_WSD_VAR_NAME(p_inflate,c_zlib, s)())
   197 
   198 GET_STATIC_VAR_FROM_TLS(p_inflateInit_,c_zlib,inflateInit__ft)
   199 #define p_inflateInit_ (*GET_WSD_VAR_NAME(p_inflateInit_,c_zlib, s)())
   200 
   201 GET_STATIC_VAR_FROM_TLS(p_deflateEnd,c_zlib,deflateEnd_ft)
   202 #define p_deflateEnd (*GET_WSD_VAR_NAME(p_deflateEnd,c_zlib, s)())
   203 
   204 GET_STATIC_VAR_FROM_TLS(p_deflate,c_zlib,deflate_ft)
   205 #define p_deflate (*GET_WSD_VAR_NAME(p_deflate,c_zlib, s)())
   206 
   207 GET_STATIC_VAR_FROM_TLS(p_deflateInit_,c_zlib,deflateInit__ft)
   208 #define p_deflateInit_ (*GET_WSD_VAR_NAME(p_deflateInit_,c_zlib, s)())
   209 
   210 
   211 GET_STATIC_VAR_FROM_TLS(zlib_loaded ,c_zlib,int)
   212 #define zlib_loaded  (*GET_WSD_VAR_NAME(zlib_loaded ,c_zlib, s)())
   213 
   214 GET_STATIC_VAR_FROM_TLS(zlib_dso ,c_zlib,DSO *)
   215 #define zlib_dso  (*GET_WSD_VAR_NAME(zlib_dso ,c_zlib, s)())
   216 
   217 #endif
   218 
   219 #define compress                stub_compress
   220 #define inflateEnd              stub_inflateEnd
   221 #define inflate                 stub_inflate
   222 #define inflateInit_            stub_inflateInit_
   223 #define deflateEnd              stub_deflateEnd
   224 #define deflate                 stub_deflate
   225 #define deflateInit_            stub_deflateInit_
   226 #endif /* ZLIB_SHARED */
   227 
   228 struct zlib_state
   229 	{
   230 	z_stream istream;
   231 	z_stream ostream;
   232 	};
   233 
   234 #ifndef EMULATOR
   235 static int zlib_stateful_ex_idx = -1;
   236 #else
   237 GET_STATIC_VAR_FROM_TLS(zlib_stateful_ex_idx,c_zlib,int)
   238 #define zlib_stateful_ex_idx (*GET_WSD_VAR_NAME(zlib_stateful_ex_idx,c_zlib, s)())
   239 #endif
   240 
   241 static void zlib_stateful_free_ex_data(void *obj, void *item,
   242 	CRYPTO_EX_DATA *ad, int ind,long argl, void *argp)
   243 	{
   244 	struct zlib_state *state = (struct zlib_state *)item;
   245 	inflateEnd(&state->istream);
   246 	deflateEnd(&state->ostream);
   247 	OPENSSL_free(state);
   248 	}
   249 
   250 static int zlib_stateful_init(COMP_CTX *ctx)
   251 	{
   252 	int err;
   253 	struct zlib_state *state =
   254 		(struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state));
   255 
   256 	if (state == NULL)
   257 		goto err;
   258 
   259 	state->istream.zalloc = Z_NULL;
   260 	state->istream.zfree = Z_NULL;
   261 	state->istream.opaque = Z_NULL;
   262 	state->istream.next_in = Z_NULL;
   263 	state->istream.next_out = Z_NULL;
   264 	state->istream.avail_in = 0;
   265 	state->istream.avail_out = 0;
   266 	err = inflateInit_(&state->istream,
   267 		ZLIB_VERSION, sizeof(z_stream));
   268 	if (err != Z_OK)
   269 		goto err;
   270 
   271 	state->ostream.zalloc = Z_NULL;
   272 	state->ostream.zfree = Z_NULL;
   273 	state->ostream.opaque = Z_NULL;
   274 	state->ostream.next_in = Z_NULL;
   275 	state->ostream.next_out = Z_NULL;
   276 	state->ostream.avail_in = 0;
   277 	state->ostream.avail_out = 0;
   278 	err = deflateInit_(&state->ostream,Z_DEFAULT_COMPRESSION,
   279 		ZLIB_VERSION, sizeof(z_stream));
   280 	if (err != Z_OK)
   281 		goto err;
   282 
   283 	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
   284 	if (zlib_stateful_ex_idx == -1)
   285 		{
   286 		CRYPTO_w_lock(CRYPTO_LOCK_COMP);
   287 		if (zlib_stateful_ex_idx == -1)
   288 			zlib_stateful_ex_idx =
   289 				CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
   290 					0,NULL,NULL,NULL,zlib_stateful_free_ex_data);
   291 		CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
   292 		if (zlib_stateful_ex_idx == -1)
   293 			goto err;
   294 		}
   295 	CRYPTO_set_ex_data(&ctx->ex_data,zlib_stateful_ex_idx,state);
   296 	return 1;
   297  err:
   298 	if (state) OPENSSL_free(state);
   299 	return 0;
   300 	}
   301 
   302 static void zlib_stateful_finish(COMP_CTX *ctx)
   303 	{
   304 	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
   305 	}
   306 
   307 static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
   308 	unsigned int olen, unsigned char *in, unsigned int ilen)
   309 	{
   310 	int err = Z_OK;
   311 	struct zlib_state *state =
   312 		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
   313 			zlib_stateful_ex_idx);
   314 
   315 	if (state == NULL)
   316 		return -1;
   317 
   318 	state->ostream.next_in = in;
   319 	state->ostream.avail_in = ilen;
   320 	state->ostream.next_out = out;
   321 	state->ostream.avail_out = olen;
   322 	if (ilen > 0)
   323 		err = deflate(&state->ostream, Z_SYNC_FLUSH);
   324 	if (err != Z_OK)
   325 		return -1;
   326 #ifdef DEBUG_ZLIB
   327 	fprintf(stderr,"compress(%4d)->%4d %s\n",
   328 		ilen,olen - state->ostream.avail_out,
   329 		(ilen != olen - state->ostream.avail_out)?"zlib":"clear");
   330 #endif
   331 	return olen - state->ostream.avail_out;
   332 	}
   333 
   334 static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
   335 	unsigned int olen, unsigned char *in, unsigned int ilen)
   336 	{
   337 	int err = Z_OK;
   338 
   339 	struct zlib_state *state =
   340 		(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
   341 			zlib_stateful_ex_idx);
   342 
   343 	if (state == NULL)
   344 		return 0;
   345 
   346 	state->istream.next_in = in;
   347 	state->istream.avail_in = ilen;
   348 	state->istream.next_out = out;
   349 	state->istream.avail_out = olen;
   350 	if (ilen > 0)
   351 		err = inflate(&state->istream, Z_SYNC_FLUSH);
   352 	if (err != Z_OK)
   353 		return -1;
   354 #ifdef DEBUG_ZLIB
   355 	fprintf(stderr,"expand(%4d)->%4d %s\n",
   356 		ilen,olen - state->istream.avail_out,
   357 		(ilen != olen - state->istream.avail_out)?"zlib":"clear");
   358 #endif
   359 	return olen - state->istream.avail_out;
   360 	}
   361 
   362 #if 0
   363 static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
   364 	unsigned int olen, unsigned char *in, unsigned int ilen)
   365 	{
   366 	unsigned long l;
   367 	int i;
   368 	int clear=1;
   369 
   370 	if (ilen > 128)
   371 		{
   372 		out[0]=1;
   373 		l=olen-1;
   374 		i=compress(&(out[1]),&l,in,(unsigned long)ilen);
   375 		if (i != Z_OK)
   376 			return(-1);
   377 		if (ilen > l)
   378 			{
   379 			clear=0;
   380 			l++;
   381 			}
   382 		}
   383 	if (clear)
   384 		{
   385 		out[0]=0;
   386 		memcpy(&(out[1]),in,ilen);
   387 		l=ilen+1;
   388 		}
   389 #ifdef DEBUG_ZLIB
   390 	fprintf(stderr,"compress(%4d)->%4d %s\n",
   391 		ilen,(int)l,(clear)?"clear":"zlib");
   392 #endif
   393 	return((int)l);
   394 	}
   395 
   396 static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
   397 	unsigned int olen, unsigned char *in, unsigned int ilen)
   398 	{
   399 	unsigned long l;
   400 	int i;
   401 
   402 	if (in[0])
   403 		{
   404 		l=olen;
   405 		i=zz_uncompress(out,&l,&(in[1]),(unsigned long)ilen-1);
   406 		if (i != Z_OK)
   407 			return(-1);
   408 		}
   409 	else
   410 		{
   411 		memcpy(out,&(in[1]),ilen-1);
   412 		l=ilen-1;
   413 		}
   414 #ifdef DEBUG_ZLIB
   415         fprintf(stderr,"expand  (%4d)->%4d %s\n",
   416 		ilen,(int)l,in[0]?"zlib":"clear");
   417 #endif
   418 	return((int)l);
   419 	}
   420 
   421 static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source,
   422 	     uLong sourceLen)
   423 {
   424     z_stream stream;
   425     int err;
   426 
   427     stream.next_in = (Bytef*)source;
   428     stream.avail_in = (uInt)sourceLen;
   429     /* Check for source > 64K on 16-bit machine: */
   430     if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
   431 
   432     stream.next_out = dest;
   433     stream.avail_out = (uInt)*destLen;
   434     if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
   435 
   436     stream.zalloc = (alloc_func)0;
   437     stream.zfree = (free_func)0;
   438 
   439     err = inflateInit_(&stream,
   440 	    ZLIB_VERSION, sizeof(z_stream));
   441     if (err != Z_OK) return err;
   442 
   443     err = inflate(&stream, Z_FINISH);
   444     if (err != Z_STREAM_END) {
   445         inflateEnd(&stream);
   446         return err;
   447     }
   448     *destLen = stream.total_out;
   449 
   450     err = inflateEnd(&stream);
   451     return err;
   452 }
   453 #endif
   454 
   455 #endif
   456 
   457 EXPORT_C COMP_METHOD *COMP_zlib(void)
   458 	{
   459 	COMP_METHOD *meth = &zlib_method_nozlib;
   460 
   461 #ifdef ZLIB_SHARED
   462 	if (!zlib_loaded)
   463 		{
   464 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
   465 		zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0);
   466 		if (!zlib_dso)
   467 			{
   468 			zlib_dso = DSO_load(NULL, "ZLIB", NULL, 0);
   469 			if (zlib_dso)
   470 				{
   471 				/* Clear the errors from the first failed
   472 				   DSO_load() */
   473 				ERR_clear_error();
   474 				}
   475 			}
   476 #else
   477 		zlib_dso = DSO_load(NULL, "z", NULL, 0);
   478 #endif
   479 #ifndef SYMBIAN
   480 		if (zlib_dso != NULL)
   481 			{
   482 			p_compress
   483 				= (compress_ft) DSO_bind_func(zlib_dso,
   484 					"compress");
   485 			p_inflateEnd
   486 				= (inflateEnd_ft) DSO_bind_func(zlib_dso,
   487 					"inflateEnd");
   488 			p_inflate
   489 				= (inflate_ft) DSO_bind_func(zlib_dso,
   490 					"inflate");
   491 			p_inflateInit_
   492 				= (inflateInit__ft) DSO_bind_func(zlib_dso,
   493 					"inflateInit_");
   494 			p_deflateEnd
   495 				= (deflateEnd_ft) DSO_bind_func(zlib_dso,
   496 					"deflateEnd");
   497 			p_deflate
   498 				= (deflate_ft) DSO_bind_func(zlib_dso,
   499 					"deflate");
   500 			p_deflateInit_
   501 				= (deflateInit__ft) DSO_bind_func(zlib_dso,
   502 					"deflateInit_");
   503 			zlib_loaded++;
   504 			}
   505 #else
   506 #ifdef LIBDL_ONLY_ORDINALS
   507 #define zlib_compress "2"
   508 #define zlib_inflateEnd "34"
   509 #define zlib_inflate "33"
   510 #define zlib_inflateInit_ "36"
   511 #define zlib_deflateEnd "9"
   512 #define zlib_deflate "6"
   513 #define zlib_deflateInit_ "11"
   514 #else
   515 #define zlib_compress compress
   516 #define zlib_inflateEnd inflateEnd
   517 #define zlib_inflate inflate
   518 #define zlib_inflateInit_ inflateInit_
   519 #define zlib_deflateEnd deflateEnd
   520 #define zlib_deflate deflate
   521 #define zlib_deflateInit_ deflateInit_
   522 #endif
   523 	    if (zlib_dso != NULL)
   524 			{
   525 			p_compress
   526 				= (compress_ft) DSO_bind_func(zlib_dso,
   527 					(const char*)zlib_compress);
   528 			p_inflateEnd
   529 				= (inflateEnd_ft) DSO_bind_func(zlib_dso,
   530 					(const char*)zlib_inflateEnd);
   531 			p_inflate
   532 				= (inflate_ft) DSO_bind_func(zlib_dso,
   533 					(const char*)zlib_inflate);
   534 			p_inflateInit_
   535 				= (inflateInit__ft) DSO_bind_func(zlib_dso,
   536 					(const char*)zlib_inflateInit_);
   537 			p_deflateEnd
   538 				= (deflateEnd_ft) DSO_bind_func(zlib_dso,
   539 					(const char*)zlib_deflateEnd);
   540 			p_deflate
   541 				= (deflate_ft) DSO_bind_func(zlib_dso,
   542 					(const char*)zlib_deflate);
   543 			p_deflateInit_
   544 				= (deflateInit__ft) DSO_bind_func(zlib_dso,
   545 					(const char*)zlib_deflateInit_);
   546 			zlib_loaded++;
   547 			}
   548 
   549 #endif			
   550 		}
   551 
   552 #endif
   553 #if defined(ZLIB) || defined(ZLIB_SHARED)
   554 			{
   555 		/* init zlib_stateful_ex_idx here so that in a multi-process
   556 		 * application it's enough to intialize openssl before forking
   557 		 * (idx will be inherited in all the children) */
   558 		if (zlib_stateful_ex_idx == -1)
   559 			{
   560 			CRYPTO_w_lock(CRYPTO_LOCK_COMP);
   561 			if (zlib_stateful_ex_idx == -1)
   562 				zlib_stateful_ex_idx =
   563 					CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
   564 						0,NULL,NULL,NULL,zlib_stateful_free_ex_data);
   565 			CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
   566 			if (zlib_stateful_ex_idx == -1)
   567 				goto err;
   568 			}
   569 		
   570 		meth = &zlib_stateful_method;
   571 		}
   572 err:	
   573 #endif
   574 
   575 	return(meth);
   576 	}
   577 
   578 #ifdef ZLIB_SHARED
   579 #if 0
   580 /* Stubs for each function to be dynamicly loaded */
   581 static int 
   582 stub_compress(Bytef *dest,uLongf *destLen,const Bytef *source, uLong sourceLen)
   583 	{
   584 	if (p_compress)
   585 		return(p_compress(dest,destLen,source,sourceLen));
   586 	else
   587 		return(Z_MEM_ERROR);
   588 	}
   589 #endif
   590 
   591 static int
   592 stub_inflateEnd(z_streamp strm)
   593 	{
   594 	if ( p_inflateEnd )
   595 		return(p_inflateEnd(strm));
   596 	else
   597 		return(Z_MEM_ERROR);
   598 	}
   599 
   600 static int
   601 stub_inflate(z_streamp strm, int flush)
   602 	{
   603 	if ( p_inflate )
   604 		return(p_inflate(strm,flush));
   605 	else
   606 		return(Z_MEM_ERROR);
   607 	}
   608 
   609 static int
   610 stub_inflateInit_(z_streamp strm, const char * version, int stream_size)
   611 	{
   612 	if ( p_inflateInit_ )
   613 		return(p_inflateInit_(strm,version,stream_size));
   614 	else
   615 		return(Z_MEM_ERROR);
   616 	}
   617 
   618 static int
   619 stub_deflateEnd(z_streamp strm)
   620 	{
   621 	if ( p_deflateEnd )
   622 		return(p_deflateEnd(strm));
   623 	else
   624 		return(Z_MEM_ERROR);
   625 	}
   626 
   627 static int
   628 stub_deflate(z_streamp strm, int flush)
   629 	{
   630 	if ( p_deflate )
   631 		return(p_deflate(strm,flush));
   632 	else
   633 		return(Z_MEM_ERROR);
   634 	}
   635 
   636 static int
   637 stub_deflateInit_(z_streamp strm, int level,
   638 	const char * version, int stream_size)
   639 	{
   640 	if ( p_deflateInit_ )
   641 		return(p_deflateInit_(strm,level,version,stream_size));
   642 	else
   643 		return(Z_MEM_ERROR);
   644 	}
   645 
   646 #endif /* ZLIB_SHARED */