-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);
- }
-
-static int
-stub_deflateEnd(z_streamp strm)
- {
- if ( p_deflateEnd )
- return(p_deflateEnd(strm));
- else
- return(Z_MEM_ERROR);
- }
-
-static int
-stub_deflate(z_streamp strm, int flush)
- {
- if ( p_deflate )
- return(p_deflate(strm,flush));
- else
- return(Z_MEM_ERROR);
- }
-
-static int
-stub_deflateInit_(z_streamp strm, int level,
- const char * version, int stream_size)
- {
- if ( p_deflateInit_ )
- return(p_deflateInit_(strm,level,version,stream_size));
- else
- return(Z_MEM_ERROR);
- }
-
-#endif /* ZLIB_SHARED */
+ /* Copy output data directly to supplied buffer */
+ zin->next_out = (unsigned char *)out;
+ zin->avail_out = (unsigned int)outl;
+ for (;;) {
+ /* Decompress while data available */
+ while (zin->avail_in) {
+ ret = inflate(zin, 0);
+ if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
+ COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR);
+ ERR_add_error_data(2, "zlib error:", zError(ret));
+ return 0;
+ }
+ /* If EOF or we've read everything then return */
+ if ((ret == Z_STREAM_END) || !zin->avail_out)
+ return outl - zin->avail_out;
+ }
+
+ /*
+ * No data in input buffer try to read some in, if an error then
+ * return the total data read.
+ */
+ ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
+ if (ret <= 0) {
+ /* Total data read */
+ int tot = outl - zin->avail_out;
+ BIO_copy_next_retry(b);
+ if (ret < 0)
+ return (tot > 0) ? tot : ret;
+ return tot;
+ }
+ zin->avail_in = ret;
+ zin->next_in = ctx->ibuf;
+ }
+}
+
+static int bio_zlib_write(BIO *b, const char *in, int inl)
+{
+ BIO_ZLIB_CTX *ctx;
+ int ret;
+ z_stream *zout;
+ if (!in || !inl)
+ return 0;
+ ctx = (BIO_ZLIB_CTX *) b->ptr;
+ if (ctx->odone)
+ return 0;
+ zout = &ctx->zout;
+ BIO_clear_retry_flags(b);
+ if (!ctx->obuf) {
+ ctx->obuf = OPENSSL_malloc(ctx->obufsize);
+ /* Need error here */
+ if (!ctx->obuf) {
+ COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ctx->optr = ctx->obuf;
+ ctx->ocount = 0;
+ deflateInit(zout, ctx->comp_level);
+ zout->next_out = ctx->obuf;
+ zout->avail_out = ctx->obufsize;
+ }
+ /* Obtain input data directly from supplied buffer */
+ zout->next_in = (void *)in;
+ zout->avail_in = inl;
+ for (;;) {
+ /* If data in output buffer write it first */
+ while (ctx->ocount) {
+ ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
+ if (ret <= 0) {
+ /* Total data written */
+ int tot = inl - zout->avail_in;
+ BIO_copy_next_retry(b);
+ if (ret < 0)
+ return (tot > 0) ? tot : ret;
+ return tot;
+ }
+ ctx->optr += ret;
+ ctx->ocount -= ret;
+ }
+
+ /* Have we consumed all supplied data? */
+ if (!zout->avail_in)
+ return inl;
+
+ /* Compress some more */
+
+ /* Reset buffer */
+ ctx->optr = ctx->obuf;
+ zout->next_out = ctx->obuf;
+ zout->avail_out = ctx->obufsize;
+ /* Compress some more */
+ ret = deflate(zout, 0);
+ if (ret != Z_OK) {
+ COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR);
+ ERR_add_error_data(2, "zlib error:", zError(ret));
+ return 0;
+ }
+ ctx->ocount = ctx->obufsize - zout->avail_out;
+ }
+}
+
+static int bio_zlib_flush(BIO *b)
+{
+ BIO_ZLIB_CTX *ctx;
+ int ret;
+ z_stream *zout;
+ ctx = (BIO_ZLIB_CTX *) b->ptr;
+ /* If no data written or already flush show success */
+ if (!ctx->obuf || (ctx->odone && !ctx->ocount))
+ return 1;
+ zout = &ctx->zout;
+ BIO_clear_retry_flags(b);
+ /* No more input data */
+ zout->next_in = NULL;
+ zout->avail_in = 0;
+ for (;;) {
+ /* If data in output buffer write it first */
+ while (ctx->ocount) {
+ ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
+ if (ret <= 0) {
+ BIO_copy_next_retry(b);
+ return ret;
+ }
+ ctx->optr += ret;
+ ctx->ocount -= ret;
+ }
+ if (ctx->odone)
+ return 1;
+
+ /* Compress some more */
+
+ /* Reset buffer */
+ ctx->optr = ctx->obuf;
+ zout->next_out = ctx->obuf;
+ zout->avail_out = ctx->obufsize;
+ /* Compress some more */
+ ret = deflate(zout, Z_FINISH);
+ if (ret == Z_STREAM_END)
+ ctx->odone = 1;
+ else if (ret != Z_OK) {
+ COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR);
+ ERR_add_error_data(2, "zlib error:", zError(ret));
+ return 0;
+ }
+ ctx->ocount = ctx->obufsize - zout->avail_out;
+ }
+}
+
+static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ BIO_ZLIB_CTX *ctx;
+ int ret, *ip;
+ int ibs, obs;
+ if (!b->next_bio)
+ return 0;
+ ctx = (BIO_ZLIB_CTX *) b->ptr;
+ switch (cmd) {
+
+ case BIO_CTRL_RESET:
+ ctx->ocount = 0;
+ ctx->odone = 0;
+ ret = 1;
+ break;
+
+ case BIO_CTRL_FLUSH:
+ ret = bio_zlib_flush(b);
+ if (ret > 0)
+ ret = BIO_flush(b->next_bio);
+ break;
+
+ case BIO_C_SET_BUFF_SIZE:
+ ibs = -1;
+ obs = -1;
+ if (ptr != NULL) {
+ ip = ptr;
+ if (*ip == 0)
+ ibs = (int)num;
+ else
+ obs = (int)num;
+ } else {
+ ibs = (int)num;
+ obs = ibs;
+ }
+
+ if (ibs != -1) {
+ if (ctx->ibuf) {
+ OPENSSL_free(ctx->ibuf);
+ ctx->ibuf = NULL;
+ }
+ ctx->ibufsize = ibs;
+ }
+
+ if (obs != -1) {
+ if (ctx->obuf) {
+ OPENSSL_free(ctx->obuf);
+ ctx->obuf = NULL;
+ }
+ ctx->obufsize = obs;
+ }
+ ret = 1;
+ break;
+
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+
+ }
+
+ return ret;
+}
+
+static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+ if (!b->next_bio)
+ return 0;
+ return BIO_callback_ctrl(b->next_bio, cmd, fp);
+}
+
+#endif