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