~ubuntu-branches/ubuntu/lucid/openssl/lucid-proposed

« back to all changes in this revision

Viewing changes to crypto/comp/c_zlib.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2009-06-13 18:15:46 UTC
  • mto: (11.1.5 squeeze)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: james.westby@ubuntu.com-20090613181546-vbfntai3b009dl1u
Tags: upstream-0.9.8k
ImportĀ upstreamĀ versionĀ 0.9.8k

Show diffs side-by-side

added added

removed removed

Lines of Context:
105
105
typedef int (*deflate_ft)(z_streamp strm, int flush);
106
106
typedef int (*deflateInit__ft)(z_streamp strm, int level,
107
107
        const char * version, int stream_size);
 
108
typedef const char * (*zError__ft)(int err);
108
109
static compress_ft      p_compress=NULL;
109
110
static inflateEnd_ft    p_inflateEnd=NULL;
110
111
static inflate_ft       p_inflate=NULL;
112
113
static deflateEnd_ft    p_deflateEnd=NULL;
113
114
static deflate_ft       p_deflate=NULL;
114
115
static deflateInit__ft  p_deflateInit_=NULL;
 
116
static zError__ft       p_zError=NULL;
115
117
 
116
118
static int zlib_loaded = 0;     /* only attempt to init func pts once */
117
119
static DSO *zlib_dso = NULL;
123
125
#define deflateEnd              p_deflateEnd
124
126
#define deflate                 p_deflate
125
127
#define deflateInit_            p_deflateInit_
 
128
#define zError                  p_zError
126
129
#endif /* ZLIB_SHARED */
127
130
 
128
131
struct zlib_state
373
376
                        p_deflateInit_
374
377
                                = (deflateInit__ft) DSO_bind_func(zlib_dso,
375
378
                                        "deflateInit_");
 
379
                        p_zError
 
380
                                = (zError__ft) DSO_bind_func(zlib_dso,
 
381
                                        "zError");
376
382
 
377
383
                        if (p_compress && p_inflateEnd && p_inflate
378
384
                                && p_inflateInit_ && p_deflateEnd
379
 
                                && p_deflate && p_deflateInit_)
 
385
                                && p_deflate && p_deflateInit_ && p_zError)
380
386
                                zlib_loaded++;
381
387
                        }
382
388
                }
410
416
        return(meth);
411
417
        }
412
418
 
 
419
void COMP_zlib_cleanup(void)
 
420
        {
 
421
#ifdef ZLIB_SHARED
 
422
        if (zlib_dso)
 
423
                DSO_free(zlib_dso);
 
424
#endif
 
425
        }
 
426
 
 
427
#ifdef ZLIB
 
428
 
 
429
/* Zlib based compression/decompression filter BIO */
 
430
 
 
431
typedef struct
 
432
        {
 
433
        unsigned char *ibuf;    /* Input buffer */
 
434
        int ibufsize;           /* Buffer size */
 
435
        z_stream zin;           /* Input decompress context */
 
436
        unsigned char *obuf;    /* Output buffer */
 
437
        int obufsize;           /* Output buffer size */
 
438
        unsigned char *optr;    /* Position in output buffer */
 
439
        int ocount;             /* Amount of data in output buffer */
 
440
        int odone;              /* deflate EOF */
 
441
        int comp_level;         /* Compression level to use */
 
442
        z_stream zout;          /* Output compression context */
 
443
        } BIO_ZLIB_CTX;
 
444
 
 
445
#define ZLIB_DEFAULT_BUFSIZE 1024
 
446
 
 
447
static int bio_zlib_new(BIO *bi);
 
448
static int bio_zlib_free(BIO *bi);
 
449
static int bio_zlib_read(BIO *b, char *out, int outl);
 
450
static int bio_zlib_write(BIO *b, const char *in, int inl);
 
451
static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
 
452
static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
 
453
 
 
454
static BIO_METHOD bio_meth_zlib = 
 
455
        {
 
456
        BIO_TYPE_COMP,
 
457
        "zlib",
 
458
        bio_zlib_write,
 
459
        bio_zlib_read,
 
460
        NULL,
 
461
        NULL,
 
462
        bio_zlib_ctrl,
 
463
        bio_zlib_new,
 
464
        bio_zlib_free,
 
465
        bio_zlib_callback_ctrl
 
466
        };
 
467
 
 
468
BIO_METHOD *BIO_f_zlib(void)
 
469
        {
 
470
        return &bio_meth_zlib;
 
471
        }
 
472
 
 
473
 
 
474
static int bio_zlib_new(BIO *bi)
 
475
        {
 
476
        BIO_ZLIB_CTX *ctx;
 
477
#ifdef ZLIB_SHARED
 
478
        (void)COMP_zlib();
 
479
        if (!zlib_loaded)
 
480
                {
 
481
                COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);
 
482
                return 0;
 
483
                }
 
484
#endif
 
485
        ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX));
 
486
        if(!ctx)
 
487
                {
 
488
                COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
 
489
                return 0;
 
490
                }
 
491
        ctx->ibuf = NULL;
 
492
        ctx->obuf = NULL;
 
493
        ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
 
494
        ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
 
495
        ctx->zin.zalloc = Z_NULL;
 
496
        ctx->zin.zfree = Z_NULL;
 
497
        ctx->zin.next_in = NULL;
 
498
        ctx->zin.avail_in = 0;
 
499
        ctx->zin.next_out = NULL;
 
500
        ctx->zin.avail_out = 0;
 
501
        ctx->zout.zalloc = Z_NULL;
 
502
        ctx->zout.zfree = Z_NULL;
 
503
        ctx->zout.next_in = NULL;
 
504
        ctx->zout.avail_in = 0;
 
505
        ctx->zout.next_out = NULL;
 
506
        ctx->zout.avail_out = 0;
 
507
        ctx->odone = 0;
 
508
        ctx->comp_level = Z_DEFAULT_COMPRESSION;
 
509
        bi->init = 1;
 
510
        bi->ptr = (char *)ctx;
 
511
        bi->flags = 0;
 
512
        return 1;
 
513
        }
 
514
 
 
515
static int bio_zlib_free(BIO *bi)
 
516
        {
 
517
        BIO_ZLIB_CTX *ctx;
 
518
        if(!bi) return 0;
 
519
        ctx = (BIO_ZLIB_CTX *)bi->ptr;
 
520
        if(ctx->ibuf)
 
521
                {
 
522
                /* Destroy decompress context */
 
523
                inflateEnd(&ctx->zin);
 
524
                OPENSSL_free(ctx->ibuf);
 
525
                }
 
526
        if(ctx->obuf)
 
527
                {
 
528
                /* Destroy compress context */
 
529
                deflateEnd(&ctx->zout);
 
530
                OPENSSL_free(ctx->obuf);
 
531
                }
 
532
        OPENSSL_free(ctx);
 
533
        bi->ptr = NULL;
 
534
        bi->init = 0;
 
535
        bi->flags = 0;
 
536
        return 1;
 
537
        }
 
538
 
 
539
static int bio_zlib_read(BIO *b, char *out, int outl)
 
540
        {
 
541
        BIO_ZLIB_CTX *ctx;
 
542
        int ret;
 
543
        z_stream *zin;
 
544
        if(!out || !outl) return 0;
 
545
        ctx = (BIO_ZLIB_CTX *)b->ptr;
 
546
        zin = &ctx->zin;
 
547
        BIO_clear_retry_flags(b);
 
548
        if(!ctx->ibuf)
 
549
                {
 
550
                ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
 
551
                if(!ctx->ibuf)
 
552
                        {
 
553
                        COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
 
554
                        return 0;
 
555
                        }
 
556
                inflateInit(zin);
 
557
                zin->next_in = ctx->ibuf;
 
558
                zin->avail_in = 0;
 
559
                }
 
560
 
 
561
        /* Copy output data directly to supplied buffer */
 
562
        zin->next_out = (unsigned char *)out;
 
563
        zin->avail_out = (unsigned int)outl;
 
564
        for(;;)
 
565
                {
 
566
                /* Decompress while data available */
 
567
                while(zin->avail_in)
 
568
                        {
 
569
                        ret = inflate(zin, 0);
 
570
                        if((ret != Z_OK) && (ret != Z_STREAM_END))
 
571
                                {
 
572
                                COMPerr(COMP_F_BIO_ZLIB_READ,
 
573
                                                COMP_R_ZLIB_INFLATE_ERROR);
 
574
                                ERR_add_error_data(2, "zlib error:",
 
575
                                                        zError(ret));
 
576
                                return 0;
 
577
                                }
 
578
                        /* If EOF or we've read everything then return */
 
579
                        if((ret == Z_STREAM_END) || !zin->avail_out)
 
580
                                return outl - zin->avail_out;
 
581
                        }
 
582
 
 
583
                /* No data in input buffer try to read some in,
 
584
                 * if an error then return the total data read.
 
585
                 */
 
586
                ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
 
587
                if(ret <= 0)
 
588
                        {
 
589
                        /* Total data read */
 
590
                        int tot = outl - zin->avail_out;
 
591
                        BIO_copy_next_retry(b);
 
592
                        if(ret < 0) return (tot > 0) ? tot : ret;
 
593
                        return tot;
 
594
                        }
 
595
                zin->avail_in = ret;
 
596
                zin->next_in = ctx->ibuf;
 
597
                }
 
598
        }
 
599
 
 
600
static int bio_zlib_write(BIO *b, const char *in, int inl)
 
601
        {
 
602
        BIO_ZLIB_CTX *ctx;
 
603
        int ret;
 
604
        z_stream *zout;
 
605
        if(!in || !inl) return 0;
 
606
        ctx = (BIO_ZLIB_CTX *)b->ptr;
 
607
        if(ctx->odone) return 0;
 
608
        zout = &ctx->zout;
 
609
        BIO_clear_retry_flags(b);
 
610
        if(!ctx->obuf)
 
611
                {
 
612
                ctx->obuf = OPENSSL_malloc(ctx->obufsize);
 
613
                /* Need error here */
 
614
                if(!ctx->obuf)
 
615
                        {
 
616
                        COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
 
617
                        return 0;
 
618
                        }
 
619
                ctx->optr = ctx->obuf;
 
620
                ctx->ocount = 0;
 
621
                deflateInit(zout, ctx->comp_level);
 
622
                zout->next_out = ctx->obuf;
 
623
                zout->avail_out = ctx->obufsize;
 
624
                }
 
625
        /* Obtain input data directly from supplied buffer */
 
626
        zout->next_in = (void *)in;
 
627
        zout->avail_in = inl;
 
628
        for(;;)
 
629
                {
 
630
                /* If data in output buffer write it first */
 
631
                while(ctx->ocount) {
 
632
                        ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
 
633
                        if(ret <= 0)
 
634
                                {
 
635
                                /* Total data written */
 
636
                                int tot = inl - zout->avail_in;
 
637
                                BIO_copy_next_retry(b);
 
638
                                if(ret < 0) return (tot > 0) ? tot : ret;
 
639
                                return tot;
 
640
                                }
 
641
                        ctx->optr += ret;
 
642
                        ctx->ocount -= ret;
 
643
                }
 
644
 
 
645
                /* Have we consumed all supplied data? */
 
646
                if(!zout->avail_in)
 
647
                        return inl;
 
648
 
 
649
                /* Compress some more */
 
650
 
 
651
                /* Reset buffer */
 
652
                ctx->optr = ctx->obuf;
 
653
                zout->next_out = ctx->obuf;
 
654
                zout->avail_out = ctx->obufsize;
 
655
                /* Compress some more */
 
656
                ret = deflate(zout, 0);
 
657
                if(ret != Z_OK)
 
658
                        {
 
659
                        COMPerr(COMP_F_BIO_ZLIB_WRITE,
 
660
                                                COMP_R_ZLIB_DEFLATE_ERROR);
 
661
                        ERR_add_error_data(2, "zlib error:", zError(ret));
 
662
                        return 0;
 
663
                        }
 
664
                ctx->ocount = ctx->obufsize - zout->avail_out;
 
665
                }
 
666
        }
 
667
 
 
668
static int bio_zlib_flush(BIO *b)
 
669
        {
 
670
        BIO_ZLIB_CTX *ctx;
 
671
        int ret;
 
672
        z_stream *zout;
 
673
        ctx = (BIO_ZLIB_CTX *)b->ptr;
 
674
        /* If no data written or already flush show success */
 
675
        if(!ctx->obuf || (ctx->odone && !ctx->ocount)) return 1;
 
676
        zout = &ctx->zout;
 
677
        BIO_clear_retry_flags(b);
 
678
        /* No more input data */
 
679
        zout->next_in = NULL;
 
680
        zout->avail_in = 0;
 
681
        for(;;)
 
682
                {
 
683
                /* If data in output buffer write it first */
 
684
                while(ctx->ocount)
 
685
                        {
 
686
                        ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
 
687
                        if(ret <= 0)
 
688
                                {
 
689
                                BIO_copy_next_retry(b);
 
690
                                return ret;
 
691
                                }
 
692
                        ctx->optr += ret;
 
693
                        ctx->ocount -= ret;
 
694
                        }
 
695
                if(ctx->odone) return 1;
 
696
 
 
697
                /* Compress some more */
 
698
 
 
699
                /* Reset buffer */
 
700
                ctx->optr = ctx->obuf;
 
701
                zout->next_out = ctx->obuf;
 
702
                zout->avail_out = ctx->obufsize;
 
703
                /* Compress some more */
 
704
                ret = deflate(zout, Z_FINISH);
 
705
                if(ret == Z_STREAM_END) ctx->odone = 1;
 
706
                else if(ret != Z_OK)
 
707
                        {
 
708
                        COMPerr(COMP_F_BIO_ZLIB_FLUSH,
 
709
                                                COMP_R_ZLIB_DEFLATE_ERROR);
 
710
                        ERR_add_error_data(2, "zlib error:", zError(ret));
 
711
                        return 0;
 
712
                        }
 
713
                ctx->ocount = ctx->obufsize - zout->avail_out;
 
714
                }
 
715
        }
 
716
 
 
717
static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
 
718
        {
 
719
        BIO_ZLIB_CTX *ctx;
 
720
        int ret, *ip;
 
721
        int ibs, obs;
 
722
        if(!b->next_bio) return 0;
 
723
        ctx = (BIO_ZLIB_CTX *)b->ptr;
 
724
        switch (cmd)
 
725
                {
 
726
 
 
727
        case BIO_CTRL_RESET:
 
728
                ctx->ocount = 0;
 
729
                ctx->odone = 0;
 
730
                ret = 1;
 
731
                break;
 
732
 
 
733
        case BIO_CTRL_FLUSH:
 
734
                ret = bio_zlib_flush(b);
 
735
                if (ret > 0)
 
736
                        ret = BIO_flush(b->next_bio);
 
737
                break;
 
738
 
 
739
        case BIO_C_SET_BUFF_SIZE:
 
740
                ibs = -1;
 
741
                obs = -1;
 
742
                if (ptr != NULL)
 
743
                        {
 
744
                        ip = ptr;
 
745
                        if (*ip == 0)
 
746
                                ibs = (int) num;
 
747
                        else 
 
748
                                obs = (int) num;
 
749
                        }
 
750
                else
 
751
                        {
 
752
                        ibs = (int)num;
 
753
                        obs = ibs;
 
754
                        }
 
755
 
 
756
                if (ibs != -1)
 
757
                        {
 
758
                        if (ctx->ibuf)
 
759
                                {
 
760
                                OPENSSL_free(ctx->ibuf);
 
761
                                ctx->ibuf = NULL;
 
762
                                }
 
763
                        ctx->ibufsize = ibs;
 
764
                        }
 
765
 
 
766
                if (obs != -1)
 
767
                        {
 
768
                        if (ctx->obuf)
 
769
                                {
 
770
                                OPENSSL_free(ctx->obuf);
 
771
                                ctx->obuf = NULL;
 
772
                                }
 
773
                        ctx->obufsize = obs;
 
774
                        }
 
775
                ret = 1;
 
776
                break;
 
777
 
 
778
        case BIO_C_DO_STATE_MACHINE:
 
779
                BIO_clear_retry_flags(b);
 
780
                ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
 
781
                BIO_copy_next_retry(b);
 
782
                break;
 
783
 
 
784
        default:
 
785
                ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
 
786
                break;
 
787
                }
 
788
 
 
789
        return ret;
 
790
        }
 
791
 
 
792
 
 
793
static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
 
794
        {
 
795
        if(!b->next_bio)
 
796
                return 0;
 
797
        return
 
798
                BIO_callback_ctrl(b->next_bio, cmd, fp);
 
799
        }
 
800
 
 
801
#endif