Add OpenSSL 0.9.7e.
[dragonfly.git] / crypto / openssl-0.9.7e / crypto / comp / c_zlib.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <openssl/objects.h>
5 #include <openssl/comp.h>
6
7 COMP_METHOD *COMP_zlib(void );
8
9 static COMP_METHOD zlib_method_nozlib={
10         NID_undef,
11         "(undef)",
12         NULL,
13         NULL,
14         NULL,
15         NULL,
16         NULL,
17         NULL,
18         };
19
20 #ifndef ZLIB
21 #undef ZLIB_SHARED
22 #else
23
24 #include <zlib.h>
25
26 static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
27         unsigned int olen, unsigned char *in, unsigned int ilen);
28 static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
29         unsigned int olen, unsigned char *in, unsigned int ilen);
30
31 static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
32         uLong sourceLen);
33
34 static COMP_METHOD zlib_method={
35         NID_zlib_compression,
36         LN_zlib_compression,
37         NULL,
38         NULL,
39         zlib_compress_block,
40         zlib_expand_block,
41         NULL,
42         NULL,
43         };
44
45 /* 
46  * When OpenSSL is built on Windows, we do not want to require that
47  * the ZLIB.DLL be available in order for the OpenSSL DLLs to
48  * work.  Therefore, all ZLIB routines are loaded at run time
49  * and we do not link to a .LIB file.
50  */
51 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
52 # include <windows.h>
53
54 # define Z_CALLCONV _stdcall
55 # define ZLIB_SHARED
56 #else
57 # define Z_CALLCONV
58 #endif /* !(OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32) */
59
60 #ifdef ZLIB_SHARED
61 #include <openssl/dso.h>
62
63 /* Prototypes for built in stubs */
64 static int stub_compress(Bytef *dest,uLongf *destLen,
65         const Bytef *source, uLong sourceLen);
66 static int stub_inflateEnd(z_streamp strm);
67 static int stub_inflate(z_streamp strm, int flush);
68 static int stub_inflateInit_(z_streamp strm, const char * version,
69         int stream_size);
70
71 /* Function pointers */
72 typedef int (Z_CALLCONV *compress_ft)(Bytef *dest,uLongf *destLen,
73         const Bytef *source, uLong sourceLen);
74 typedef int (Z_CALLCONV *inflateEnd_ft)(z_streamp strm);
75 typedef int (Z_CALLCONV *inflate_ft)(z_streamp strm, int flush);
76 typedef int (Z_CALLCONV *inflateInit__ft)(z_streamp strm,
77         const char * version, int stream_size);
78 static compress_ft      p_compress=NULL;
79 static inflateEnd_ft    p_inflateEnd=NULL;
80 static inflate_ft       p_inflate=NULL;
81 static inflateInit__ft  p_inflateInit_=NULL;
82
83 static int zlib_loaded = 0;     /* only attempt to init func pts once */
84 static DSO *zlib_dso = NULL;
85
86 #define compress                stub_compress
87 #define inflateEnd              stub_inflateEnd
88 #define inflate                 stub_inflate
89 #define inflateInit_            stub_inflateInit_
90 #endif /* ZLIB_SHARED */
91
92 static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
93              unsigned int olen, unsigned char *in, unsigned int ilen)
94         {
95         unsigned long l;
96         int i;
97         int clear=1;
98
99         if (ilen > 128)
100                 {
101                 out[0]=1;
102                 l=olen-1;
103                 i=compress(&(out[1]),&l,in,(unsigned long)ilen);
104                 if (i != Z_OK)
105                         return(-1);
106                 if (ilen > l)
107                         {
108                         clear=0;
109                         l++;
110                         }
111                 }
112         if (clear)
113                 {
114                 out[0]=0;
115                 memcpy(&(out[1]),in,ilen);
116                 l=ilen+1;
117                 }
118 #ifdef DEBUG_ZLIB
119         fprintf(stderr,"compress(%4d)->%4d %s\n",
120                 ilen,(int)l,(clear)?"clear":"zlib");
121 #endif
122         return((int)l);
123         }
124
125 static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
126              unsigned int olen, unsigned char *in, unsigned int ilen)
127         {
128         unsigned long l;
129         int i;
130
131         if (in[0])
132                 {
133                 l=olen;
134                 i=zz_uncompress(out,&l,&(in[1]),(unsigned long)ilen-1);
135                 if (i != Z_OK)
136                         return(-1);
137                 }
138         else
139                 {
140                 memcpy(out,&(in[1]),ilen-1);
141                 l=ilen-1;
142                 }
143 #ifdef DEBUG_ZLIB
144         fprintf(stderr,"expand  (%4d)->%4d %s\n",
145                 ilen,(int)l,in[0]?"zlib":"clear");
146 #endif
147         return((int)l);
148         }
149
150 static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source,
151              uLong sourceLen)
152 {
153     z_stream stream;
154     int err;
155
156     stream.next_in = (Bytef*)source;
157     stream.avail_in = (uInt)sourceLen;
158     /* Check for source > 64K on 16-bit machine: */
159     if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
160
161     stream.next_out = dest;
162     stream.avail_out = (uInt)*destLen;
163     if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
164
165     stream.zalloc = (alloc_func)0;
166     stream.zfree = (free_func)0;
167
168     err = inflateInit(&stream);
169     if (err != Z_OK) return err;
170
171     err = inflate(&stream, Z_FINISH);
172     if (err != Z_STREAM_END) {
173         inflateEnd(&stream);
174         return err;
175     }
176     *destLen = stream.total_out;
177
178     err = inflateEnd(&stream);
179     return err;
180 }
181
182 #endif
183
184 COMP_METHOD *COMP_zlib(void)
185         {
186         COMP_METHOD *meth = &zlib_method_nozlib;
187
188 #ifdef ZLIB_SHARED
189         if (!zlib_loaded)
190                 {
191 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
192                 zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0);
193                 if (!zlib_dso)
194                         {
195                         zlib_dso = DSO_load(NULL, "ZLIB", NULL, 0);
196                         if (zlib_dso)
197                                 {
198                                 /* Clear the errors from the first failed
199                                    DSO_load() */
200                                 ERR_clear_error();
201                                 }
202                         }
203 #else
204                 zlib_dso = DSO_load(NULL, "z", NULL, 0);
205 #endif
206                 if (zlib_dso != NULL)
207                         {
208                         p_compress
209                                 = (compress_ft) DSO_bind_func(zlib_dso,
210                                         "compress");
211                         p_inflateEnd
212                                 = (inflateEnd_ft) DSO_bind_func(zlib_dso,
213                                         "inflateEnd");
214                         p_inflate
215                                 = (inflate_ft) DSO_bind_func(zlib_dso,
216                                         "inflate");
217                         p_inflateInit_
218                                 = (inflateInit__ft) DSO_bind_func(zlib_dso,
219                                         "inflateInit_");
220                         zlib_loaded++;
221                         }
222                 }
223
224 #endif
225 #if defined(ZLIB) || defined(ZLIB_SHARED)
226         meth = &zlib_method;
227 #endif
228
229         return(meth);
230         }
231
232 #ifdef ZLIB_SHARED
233 /* Stubs for each function to be dynamicly loaded */
234 static int 
235 stub_compress(Bytef *dest,uLongf *destLen,const Bytef *source, uLong sourceLen)
236         {
237         if (p_compress)
238                 return(p_compress(dest,destLen,source,sourceLen));
239         else
240                 return(Z_MEM_ERROR);
241         }
242
243 static int
244 stub_inflateEnd(z_streamp strm)
245         {
246         if ( p_inflateEnd )
247                 return(p_inflateEnd(strm));
248         else
249                 return(Z_MEM_ERROR);
250         }
251
252 static int
253 stub_inflate(z_streamp strm, int flush)
254         {
255         if ( p_inflate )
256                 return(p_inflate(strm,flush));
257         else
258                 return(Z_MEM_ERROR);
259         }
260
261 static int
262 stub_inflateInit_(z_streamp strm, const char * version, int stream_size)
263         {
264         if ( p_inflateInit_ )
265                 return(p_inflateInit_(strm,version,stream_size));
266         else
267                 return(Z_MEM_ERROR);
268         }
269
270 #endif /* ZLIB_SHARED */