]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/comp/c_zlib.c
free null cleanup finale
[thirdparty/openssl.git] / crypto / comp / c_zlib.c
CommitLineData
dfeab068
RE
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
ec577822
BM
4#include <openssl/objects.h>
5#include <openssl/comp.h>
bdbc9b4d 6#include <openssl/err.h>
dfeab068 7
0f113f3e
MC
8COMP_METHOD *COMP_zlib(void);
9
10static COMP_METHOD zlib_method_nozlib = {
11 NID_undef,
12 "(undef)",
13 NULL,
14 NULL,
15 NULL,
16 NULL,
17 NULL,
18 NULL,
19};
dfeab068 20
c4438dc0 21#ifndef ZLIB
0f113f3e 22# undef ZLIB_SHARED
c4438dc0 23#else
dfeab068 24
0f113f3e 25# include <zlib.h>
dfeab068 26
86a62cf1
RL
27static int zlib_stateful_init(COMP_CTX *ctx);
28static void zlib_stateful_finish(COMP_CTX *ctx);
29static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
0f113f3e
MC
30 unsigned int olen, unsigned char *in,
31 unsigned int ilen);
86a62cf1 32static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
0f113f3e
MC
33 unsigned int olen, unsigned char *in,
34 unsigned int ilen);
30e5e8ac
NL
35
36/* memory allocations functions for zlib intialization */
0f113f3e 37static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size)
30e5e8ac 38{
0f113f3e 39 void *p;
30e5e8ac 40
0f113f3e
MC
41 p = OPENSSL_malloc(no * size);
42 if (p)
43 memset(p, 0, no * size);
44 return p;
45}
30e5e8ac 46
0f113f3e 47static void zlib_zfree(void *opaque, void *address)
30e5e8ac 48{
0f113f3e 49 OPENSSL_free(address);
30e5e8ac
NL
50}
51
0f113f3e
MC
52
53static COMP_METHOD zlib_stateful_method = {
54 NID_zlib_compression,
55 LN_zlib_compression,
56 zlib_stateful_init,
57 zlib_stateful_finish,
58 zlib_stateful_compress_block,
59 zlib_stateful_expand_block,
60 NULL,
61 NULL,
62};
63
64/*
20f88b9b
RL
65 * When OpenSSL is built on Windows, we do not want to require that
66 * the ZLIB.DLL be available in order for the OpenSSL DLLs to
67 * work. Therefore, all ZLIB routines are loaded at run time
ad2695b1 68 * and we do not link to a .LIB file when ZLIB_SHARED is set.
20f88b9b 69 */
0f113f3e
MC
70# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
71# include <windows.h>
72# endif /* !(OPENSSL_SYS_WINDOWS ||
73 * OPENSSL_SYS_WIN32) */
c4438dc0 74
0f113f3e
MC
75# ifdef ZLIB_SHARED
76# include <openssl/dso.h>
20f88b9b 77
20f88b9b 78/* Function pointers */
0f113f3e
MC
79typedef int (*compress_ft) (Bytef *dest, uLongf * destLen,
80 const Bytef *source, uLong sourceLen);
81typedef int (*inflateEnd_ft) (z_streamp strm);
82typedef int (*inflate_ft) (z_streamp strm, int flush);
83typedef int (*inflateInit__ft) (z_streamp strm,
84 const char *version, int stream_size);
85typedef int (*deflateEnd_ft) (z_streamp strm);
86typedef int (*deflate_ft) (z_streamp strm, int flush);
87typedef int (*deflateInit__ft) (z_streamp strm, int level,
88 const char *version, int stream_size);
89typedef const char *(*zError__ft) (int err);
90static compress_ft p_compress = NULL;
91static inflateEnd_ft p_inflateEnd = NULL;
92static inflate_ft p_inflate = NULL;
93static inflateInit__ft p_inflateInit_ = NULL;
94static deflateEnd_ft p_deflateEnd = NULL;
95static deflate_ft p_deflate = NULL;
96static deflateInit__ft p_deflateInit_ = NULL;
97static zError__ft p_zError = NULL;
20f88b9b
RL
98
99static int zlib_loaded = 0; /* only attempt to init func pts once */
c4438dc0 100static DSO *zlib_dso = NULL;
20f88b9b 101
0f113f3e
MC
102# define compress p_compress
103# define inflateEnd p_inflateEnd
104# define inflate p_inflate
105# define inflateInit_ p_inflateInit_
106# define deflateEnd p_deflateEnd
107# define deflate p_deflate
108# define deflateInit_ p_deflateInit_
109# define zError p_zError
110# endif /* ZLIB_SHARED */
111
112struct zlib_state {
113 z_stream istream;
114 z_stream ostream;
115};
86a62cf1
RL
116
117static int zlib_stateful_ex_idx = -1;
118
86a62cf1 119static int zlib_stateful_init(COMP_CTX *ctx)
0f113f3e
MC
120{
121 int err;
b196e7d9 122 struct zlib_state *state = OPENSSL_malloc(sizeof(struct zlib_state));
0f113f3e
MC
123
124 if (state == NULL)
125 goto err;
126
127 state->istream.zalloc = zlib_zalloc;
128 state->istream.zfree = zlib_zfree;
129 state->istream.opaque = Z_NULL;
130 state->istream.next_in = Z_NULL;
131 state->istream.next_out = Z_NULL;
132 state->istream.avail_in = 0;
133 state->istream.avail_out = 0;
134 err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream));
135 if (err != Z_OK)
136 goto err;
137
138 state->ostream.zalloc = zlib_zalloc;
139 state->ostream.zfree = zlib_zfree;
140 state->ostream.opaque = Z_NULL;
141 state->ostream.next_in = Z_NULL;
142 state->ostream.next_out = Z_NULL;
143 state->ostream.avail_in = 0;
144 state->ostream.avail_out = 0;
145 err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION,
146 ZLIB_VERSION, sizeof(z_stream));
147 if (err != Z_OK)
148 goto err;
149
150 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
151 CRYPTO_set_ex_data(&ctx->ex_data, zlib_stateful_ex_idx, state);
152 return 1;
86a62cf1 153 err:
b548a1f1 154 OPENSSL_free(state);
0f113f3e
MC
155 return 0;
156}
86a62cf1
RL
157
158static void zlib_stateful_finish(COMP_CTX *ctx)
0f113f3e
MC
159{
160 struct zlib_state *state =
161 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
162 zlib_stateful_ex_idx);
163 inflateEnd(&state->istream);
164 deflateEnd(&state->ostream);
165 OPENSSL_free(state);
166 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
167}
86a62cf1
RL
168
169static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
0f113f3e
MC
170 unsigned int olen, unsigned char *in,
171 unsigned int ilen)
172{
173 int err = Z_OK;
174 struct zlib_state *state =
175 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
176 zlib_stateful_ex_idx);
177
178 if (state == NULL)
179 return -1;
180
181 state->ostream.next_in = in;
182 state->ostream.avail_in = ilen;
183 state->ostream.next_out = out;
184 state->ostream.avail_out = olen;
185 if (ilen > 0)
186 err = deflate(&state->ostream, Z_SYNC_FLUSH);
187 if (err != Z_OK)
188 return -1;
189# ifdef DEBUG_ZLIB
190 fprintf(stderr, "compress(%4d)->%4d %s\n",
191 ilen, olen - state->ostream.avail_out,
192 (ilen != olen - state->ostream.avail_out) ? "zlib" : "clear");
193# endif
194 return olen - state->ostream.avail_out;
195}
86a62cf1
RL
196
197static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
0f113f3e
MC
198 unsigned int olen, unsigned char *in,
199 unsigned int ilen)
200{
201 int err = Z_OK;
202
203 struct zlib_state *state =
204 (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
205 zlib_stateful_ex_idx);
206
207 if (state == NULL)
208 return 0;
209
210 state->istream.next_in = in;
211 state->istream.avail_in = ilen;
212 state->istream.next_out = out;
213 state->istream.avail_out = olen;
214 if (ilen > 0)
215 err = inflate(&state->istream, Z_SYNC_FLUSH);
216 if (err != Z_OK)
217 return -1;
218# ifdef DEBUG_ZLIB
219 fprintf(stderr, "expand(%4d)->%4d %s\n",
220 ilen, olen - state->istream.avail_out,
221 (ilen != olen - state->istream.avail_out) ? "zlib" : "clear");
222# endif
223 return olen - state->istream.avail_out;
224}
86a62cf1 225
dfeab068
RE
226#endif
227
6b691a5c 228COMP_METHOD *COMP_zlib(void)
0f113f3e
MC
229{
230 COMP_METHOD *meth = &zlib_method_nozlib;
20f88b9b 231
c4438dc0 232#ifdef ZLIB_SHARED
0f113f3e
MC
233 if (!zlib_loaded) {
234# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
235 zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0);
236# else
237 zlib_dso = DSO_load(NULL, "z", NULL, 0);
238# endif
239 if (zlib_dso != NULL) {
240 p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");
241 p_inflateEnd
242 = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");
243 p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");
244 p_inflateInit_
245 = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");
246 p_deflateEnd
247 = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd");
248 p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate");
249 p_deflateInit_
250 = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");
251 p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");
252
253 if (p_compress && p_inflateEnd && p_inflate
254 && p_inflateInit_ && p_deflateEnd
255 && p_deflate && p_deflateInit_ && p_zError)
256 zlib_loaded++;
257 }
258 }
e984b2af 259#endif
0d894c9d 260#ifdef ZLIB_SHARED
0f113f3e 261 if (zlib_loaded)
0d894c9d
DSH
262#endif
263#if defined(ZLIB) || defined(ZLIB_SHARED)
0f113f3e
MC
264 {
265 /*
266 * init zlib_stateful_ex_idx here so that in a multi-process
267 * application it's enough to intialize openssl before forking (idx
268 * will be inherited in all the children)
269 */
270 if (zlib_stateful_ex_idx == -1) {
271 CRYPTO_w_lock(CRYPTO_LOCK_COMP);
272 if (zlib_stateful_ex_idx == -1)
273 zlib_stateful_ex_idx =
274 CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
275 0, NULL, NULL, NULL, NULL);
276 CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
277 if (zlib_stateful_ex_idx == -1)
278 goto err;
279 }
280
281 meth = &zlib_stateful_method;
282 }
283 err:
20f88b9b
RL
284#endif
285
0f113f3e
MC
286 return (meth);
287}
20f88b9b 288
8931b30d 289void COMP_zlib_cleanup(void)
0f113f3e 290{
8931b30d 291#ifdef ZLIB_SHARED
0f113f3e
MC
292 if (zlib_dso)
293 DSO_free(zlib_dso);
8931b30d 294#endif
0f113f3e 295}
8931b30d
DSH
296
297#ifdef ZLIB
298
299/* Zlib based compression/decompression filter BIO */
300
0f113f3e
MC
301typedef struct {
302 unsigned char *ibuf; /* Input buffer */
303 int ibufsize; /* Buffer size */
304 z_stream zin; /* Input decompress context */
305 unsigned char *obuf; /* Output buffer */
306 int obufsize; /* Output buffer size */
307 unsigned char *optr; /* Position in output buffer */
308 int ocount; /* Amount of data in output buffer */
309 int odone; /* deflate EOF */
310 int comp_level; /* Compression level to use */
311 z_stream zout; /* Output compression context */
312} BIO_ZLIB_CTX;
313
314# define ZLIB_DEFAULT_BUFSIZE 1024
8931b30d
DSH
315
316static int bio_zlib_new(BIO *bi);
317static int bio_zlib_free(BIO *bi);
318static int bio_zlib_read(BIO *b, char *out, int outl);
319static int bio_zlib_write(BIO *b, const char *in, int inl);
320static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
321static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
322
0f113f3e
MC
323static BIO_METHOD bio_meth_zlib = {
324 BIO_TYPE_COMP,
325 "zlib",
326 bio_zlib_write,
327 bio_zlib_read,
328 NULL,
329 NULL,
330 bio_zlib_ctrl,
331 bio_zlib_new,
332 bio_zlib_free,
333 bio_zlib_callback_ctrl
334};
8931b30d
DSH
335
336BIO_METHOD *BIO_f_zlib(void)
0f113f3e
MC
337{
338 return &bio_meth_zlib;
339}
8931b30d
DSH
340
341static int bio_zlib_new(BIO *bi)
0f113f3e
MC
342{
343 BIO_ZLIB_CTX *ctx;
344# ifdef ZLIB_SHARED
345 (void)COMP_zlib();
346 if (!zlib_loaded) {
347 COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);
348 return 0;
349 }
350# endif
351 ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX));
352 if (!ctx) {
353 COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
354 return 0;
355 }
356 ctx->ibuf = NULL;
357 ctx->obuf = NULL;
358 ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
359 ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
360 ctx->zin.zalloc = Z_NULL;
361 ctx->zin.zfree = Z_NULL;
362 ctx->zin.next_in = NULL;
363 ctx->zin.avail_in = 0;
364 ctx->zin.next_out = NULL;
365 ctx->zin.avail_out = 0;
366 ctx->zout.zalloc = Z_NULL;
367 ctx->zout.zfree = Z_NULL;
368 ctx->zout.next_in = NULL;
369 ctx->zout.avail_in = 0;
370 ctx->zout.next_out = NULL;
371 ctx->zout.avail_out = 0;
372 ctx->odone = 0;
373 ctx->comp_level = Z_DEFAULT_COMPRESSION;
374 bi->init = 1;
375 bi->ptr = (char *)ctx;
376 bi->flags = 0;
377 return 1;
378}
8931b30d
DSH
379
380static int bio_zlib_free(BIO *bi)
0f113f3e
MC
381{
382 BIO_ZLIB_CTX *ctx;
383 if (!bi)
384 return 0;
385 ctx = (BIO_ZLIB_CTX *) bi->ptr;
386 if (ctx->ibuf) {
387 /* Destroy decompress context */
388 inflateEnd(&ctx->zin);
389 OPENSSL_free(ctx->ibuf);
390 }
391 if (ctx->obuf) {
392 /* Destroy compress context */
393 deflateEnd(&ctx->zout);
394 OPENSSL_free(ctx->obuf);
395 }
396 OPENSSL_free(ctx);
397 bi->ptr = NULL;
398 bi->init = 0;
399 bi->flags = 0;
400 return 1;
401}
8931b30d
DSH
402
403static int bio_zlib_read(BIO *b, char *out, int outl)
0f113f3e
MC
404{
405 BIO_ZLIB_CTX *ctx;
406 int ret;
407 z_stream *zin;
408 if (!out || !outl)
409 return 0;
410 ctx = (BIO_ZLIB_CTX *) b->ptr;
411 zin = &ctx->zin;
412 BIO_clear_retry_flags(b);
413 if (!ctx->ibuf) {
414 ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
415 if (!ctx->ibuf) {
416 COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
417 return 0;
418 }
419 inflateInit(zin);
420 zin->next_in = ctx->ibuf;
421 zin->avail_in = 0;
422 }
423
424 /* Copy output data directly to supplied buffer */
425 zin->next_out = (unsigned char *)out;
426 zin->avail_out = (unsigned int)outl;
427 for (;;) {
428 /* Decompress while data available */
429 while (zin->avail_in) {
430 ret = inflate(zin, 0);
431 if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
432 COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR);
433 ERR_add_error_data(2, "zlib error:", zError(ret));
434 return 0;
435 }
436 /* If EOF or we've read everything then return */
437 if ((ret == Z_STREAM_END) || !zin->avail_out)
438 return outl - zin->avail_out;
439 }
440
441 /*
442 * No data in input buffer try to read some in, if an error then
443 * return the total data read.
444 */
445 ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
446 if (ret <= 0) {
447 /* Total data read */
448 int tot = outl - zin->avail_out;
449 BIO_copy_next_retry(b);
450 if (ret < 0)
451 return (tot > 0) ? tot : ret;
452 return tot;
453 }
454 zin->avail_in = ret;
455 zin->next_in = ctx->ibuf;
456 }
457}
8931b30d
DSH
458
459static int bio_zlib_write(BIO *b, const char *in, int inl)
0f113f3e
MC
460{
461 BIO_ZLIB_CTX *ctx;
462 int ret;
463 z_stream *zout;
464 if (!in || !inl)
465 return 0;
466 ctx = (BIO_ZLIB_CTX *) b->ptr;
467 if (ctx->odone)
468 return 0;
469 zout = &ctx->zout;
470 BIO_clear_retry_flags(b);
471 if (!ctx->obuf) {
472 ctx->obuf = OPENSSL_malloc(ctx->obufsize);
473 /* Need error here */
474 if (!ctx->obuf) {
475 COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
476 return 0;
477 }
478 ctx->optr = ctx->obuf;
479 ctx->ocount = 0;
480 deflateInit(zout, ctx->comp_level);
481 zout->next_out = ctx->obuf;
482 zout->avail_out = ctx->obufsize;
483 }
484 /* Obtain input data directly from supplied buffer */
485 zout->next_in = (void *)in;
486 zout->avail_in = inl;
487 for (;;) {
488 /* If data in output buffer write it first */
489 while (ctx->ocount) {
490 ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
491 if (ret <= 0) {
492 /* Total data written */
493 int tot = inl - zout->avail_in;
494 BIO_copy_next_retry(b);
495 if (ret < 0)
496 return (tot > 0) ? tot : ret;
497 return tot;
498 }
499 ctx->optr += ret;
500 ctx->ocount -= ret;
501 }
502
503 /* Have we consumed all supplied data? */
504 if (!zout->avail_in)
505 return inl;
506
507 /* Compress some more */
508
509 /* Reset buffer */
510 ctx->optr = ctx->obuf;
511 zout->next_out = ctx->obuf;
512 zout->avail_out = ctx->obufsize;
513 /* Compress some more */
514 ret = deflate(zout, 0);
515 if (ret != Z_OK) {
516 COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR);
517 ERR_add_error_data(2, "zlib error:", zError(ret));
518 return 0;
519 }
520 ctx->ocount = ctx->obufsize - zout->avail_out;
521 }
522}
8931b30d
DSH
523
524static int bio_zlib_flush(BIO *b)
0f113f3e
MC
525{
526 BIO_ZLIB_CTX *ctx;
527 int ret;
528 z_stream *zout;
529 ctx = (BIO_ZLIB_CTX *) b->ptr;
530 /* If no data written or already flush show success */
531 if (!ctx->obuf || (ctx->odone && !ctx->ocount))
532 return 1;
533 zout = &ctx->zout;
534 BIO_clear_retry_flags(b);
535 /* No more input data */
536 zout->next_in = NULL;
537 zout->avail_in = 0;
538 for (;;) {
539 /* If data in output buffer write it first */
540 while (ctx->ocount) {
541 ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
542 if (ret <= 0) {
543 BIO_copy_next_retry(b);
544 return ret;
545 }
546 ctx->optr += ret;
547 ctx->ocount -= ret;
548 }
549 if (ctx->odone)
550 return 1;
551
552 /* Compress some more */
553
554 /* Reset buffer */
555 ctx->optr = ctx->obuf;
556 zout->next_out = ctx->obuf;
557 zout->avail_out = ctx->obufsize;
558 /* Compress some more */
559 ret = deflate(zout, Z_FINISH);
560 if (ret == Z_STREAM_END)
561 ctx->odone = 1;
562 else if (ret != Z_OK) {
563 COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR);
564 ERR_add_error_data(2, "zlib error:", zError(ret));
565 return 0;
566 }
567 ctx->ocount = ctx->obufsize - zout->avail_out;
568 }
569}
8931b30d
DSH
570
571static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
0f113f3e
MC
572{
573 BIO_ZLIB_CTX *ctx;
574 int ret, *ip;
575 int ibs, obs;
576 if (!b->next_bio)
577 return 0;
578 ctx = (BIO_ZLIB_CTX *) b->ptr;
579 switch (cmd) {
580
581 case BIO_CTRL_RESET:
582 ctx->ocount = 0;
583 ctx->odone = 0;
584 ret = 1;
585 break;
586
587 case BIO_CTRL_FLUSH:
588 ret = bio_zlib_flush(b);
589 if (ret > 0)
590 ret = BIO_flush(b->next_bio);
591 break;
592
593 case BIO_C_SET_BUFF_SIZE:
594 ibs = -1;
595 obs = -1;
596 if (ptr != NULL) {
597 ip = ptr;
598 if (*ip == 0)
599 ibs = (int)num;
600 else
601 obs = (int)num;
602 } else {
603 ibs = (int)num;
604 obs = ibs;
605 }
606
607 if (ibs != -1) {
b548a1f1
RS
608 OPENSSL_free(ctx->ibuf);
609 ctx->ibuf = NULL;
0f113f3e
MC
610 ctx->ibufsize = ibs;
611 }
612
613 if (obs != -1) {
b548a1f1
RS
614 OPENSSL_free(ctx->obuf);
615 ctx->obuf = NULL;
0f113f3e
MC
616 ctx->obufsize = obs;
617 }
618 ret = 1;
619 break;
620
621 case BIO_C_DO_STATE_MACHINE:
622 BIO_clear_retry_flags(b);
623 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
624 BIO_copy_next_retry(b);
625 break;
626
627 default:
628 ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
629 break;
630
631 }
8931b30d 632
0f113f3e
MC
633 return ret;
634}
8931b30d
DSH
635
636static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
0f113f3e
MC
637{
638 if (!b->next_bio)
639 return 0;
640 return BIO_callback_ctrl(b->next_bio, cmd, fp);
641}
8931b30d
DSH
642
643#endif