/[mcrypt]/libmcrypt/lib/mcrypt_extra.c
ViewVC logotype

Contents of /libmcrypt/lib/mcrypt_extra.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (show annotations)
Sun Sep 2 14:49:00 2001 UTC (22 years, 7 months ago) by nmav
Branch: MAIN
Changes since 1.12: +29 -17 lines
File MIME type: text/plain
changed to support dlpreopening

1 /*
2 * Copyright (C) 1998,1999 Nikos Mavroyanopoulos
3 *
4 * This library is free software; you can redistribute it and/or modify it under the terms of the
5 * GNU Library General Public License as published by the Free Software
6 * Foundation; either version 2 of the License, or (at your option) any
7 * later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20 /* $Id: mcrypt_extra.c,v 1.12 2001/07/11 07:34:20 nmav Exp $ */
21
22 #ifndef LIBDEFS_H
23 #define LIBDEFS_H
24 #include <libdefs.h>
25 #endif
26 #include <bzero.h>
27 #include <xmemory.h>
28 #include <mcrypt_internal.h>
29
30
31 int mcrypt_algorithm_module_ok(const char *file, const char *directory);
32 int mcrypt_mode_module_ok(const char *file, const char *directory);
33
34 void *mcrypt_dlopen(mcrypt_dlhandle *handle, const char *a_directory, const char *m_directory,
35 const char *filename);
36
37 #ifdef HAVE_READDIR_R
38 # define MAXPATHLEN 256
39 #endif
40
41 WIN32DLL_DEFINE char *mcrypt_readdir(DIR * dirstream)
42 {
43
44 char *result;
45 struct dirent *ret = NULL;
46 #ifdef HAVE_READDIR_R
47 struct dirent ret2[sizeof(struct dirent)+MAXPATHLEN];
48 #endif
49
50 #ifdef DT_REG
51 do {
52 #endif
53
54 #ifdef HAVE_READDIR_R
55 readdir_r(dirstream, ret2, &ret);
56 #else
57 ret = readdir(dirstream);
58 #endif
59 if (ret==NULL) return NULL;
60
61 result = calloc(1, strlen(ret->d_name) + 1);
62 if (result == NULL) {
63 return NULL;
64 }
65 strcpy(result, ret->d_name);
66 #ifdef DT_REG
67 }
68 while ((ret->d_type != DT_REG) && (ret->d_type != DT_UNKNOWN)
69 && (ret != NULL));
70 #endif
71
72 return result;
73
74 }
75
76 static char* inc_algos[] = {
77 "arcfour",
78 NULL
79 };
80
81 static char* inc_modes[] = {
82 "stream",
83 NULL
84 };
85
86
87 WIN32DLL_DEFINE char **mcrypt_list_algorithms(char *libdir, int *size)
88 {
89 DIR *pdir;
90 char directory[512];
91 char *dirname;
92 char **filename = NULL, *ptr;
93 int tmpsize;
94
95
96 *size = 0;
97
98 if (libdir == NULL) {
99 strcpy(directory, LIBDIR);
100 } else {
101 strcpy(directory, libdir);
102 }
103
104 pdir = opendir(directory);
105 if (pdir == NULL) {
106 #ifdef DEBUG
107 fprintf(stderr, "Unable to open directory %s.\n",
108 directory);
109 #endif
110 return NULL;
111 }
112
113 for (;;) {
114 dirname = mcrypt_readdir(pdir);
115 if (dirname != NULL) {
116 tmpsize = strlen(dirname);
117 if (tmpsize > 3) {
118 if (mcrypt_algorithm_module_ok
119 (dirname, directory) > 0) {
120 filename =
121 realloc(filename,
122 (*size +
123 1) * sizeof(char *));
124 if (filename==NULL) {
125 free(dirname);
126 return NULL;
127 }
128 filename[*size] =
129 calloc(1, tmpsize + 1);
130 if (filename[*size]==NULL) return NULL;
131 strcpy(filename[*size], dirname);
132
133 ptr =
134 strrchr(filename[*size], '.');
135 if (ptr != NULL)
136 *ptr = '\0';
137 (*size)++;
138 }
139 }
140 free(dirname);
141 } else {
142 break;
143 }
144
145 }
146
147
148 closedir(pdir);
149
150 return filename;
151
152 }
153
154 WIN32DLL_DEFINE char **mcrypt_list_modes(char *libdir, int *size)
155 {
156 DIR *pdir;
157 char directory[512];
158 char *dirname;
159 char **filename = NULL, *ptr;
160 int tmpsize;
161
162 if (libdir == NULL) {
163 strcpy(directory, LIBDIR);
164 } else {
165 strcpy(directory, libdir);
166 }
167
168 pdir = opendir(directory);
169 if (pdir == NULL) {
170 #ifdef DEBUG
171 fprintf(stderr, "Unable to open directory %s.\n",
172 directory);
173 #endif
174 return NULL;
175 }
176
177 *size = 0;
178 for (;;) {
179
180 dirname = mcrypt_readdir(pdir);
181 if (dirname != NULL) {
182 tmpsize = strlen(dirname);
183 if (tmpsize > 3) {
184 if (mcrypt_mode_module_ok
185 (dirname, directory) > 0) {
186 filename =
187 realloc(filename,
188 (*size +
189 1) * sizeof(char *));
190 if (filename==NULL) {
191 free(dirname);
192 return NULL;
193 }
194 filename[*size] =
195 calloc(1, tmpsize + 1);
196 if (filename[*size]==NULL) return NULL;
197
198 strcpy(filename[*size], dirname);
199 ptr =
200 strrchr(filename[*size], '.');
201 if (ptr != NULL)
202 *ptr = '\0';
203 (*size)++;
204 }
205 }
206 free(dirname);
207 } else {
208 break;
209 }
210
211 }
212
213 closedir(pdir);
214 return filename;
215 }
216
217 WIN32DLL_DEFINE void mcrypt_free_p(char **p, int size)
218 {
219 int i;
220
221 for (i = 0; i < size; i++) {
222 free(p[i]);
223 }
224 free(p);
225 }
226
227 WIN32DLL_DEFINE
228 int mcrypt_algorithm_module_ok(const char *file, const char *directory)
229 {
230 word32 ret;
231 mcrypt_dlhandle _handle;
232 void* rr;
233 int (*_version) (void);
234
235 if (file == NULL && directory == NULL) {
236 return MCRYPT_UNKNOWN_ERROR;
237 }
238
239 if (lt_dlinit() != 0) {
240 return MCRYPT_UNKNOWN_ERROR;
241 }
242
243
244 /* LTDL_SET_PRELOADED_SYMBOLS(); */
245
246 rr = mcrypt_dlopen(&_handle, directory, NULL, file);
247
248 if (!rr) {
249 lt_dlexit();
250 return MCRYPT_UNKNOWN_ERROR;
251 }
252
253
254 _version = mcrypt_dlsym(_handle, "_mcrypt_algorithm_version");
255
256 if (_version == NULL) {
257 mcrypt_dlclose(_handle);
258 lt_dlexit();
259 return MCRYPT_UNKNOWN_ERROR;
260 }
261
262 ret = _version();
263
264 mcrypt_dlclose(_handle);
265 lt_dlexit();
266
267 return ret;
268
269 }
270
271 WIN32DLL_DEFINE
272 int mcrypt_mode_module_ok(const char *file, const char *directory)
273 {
274 word32 ret;
275 mcrypt_dlhandle _handle;
276 void* rr;
277 int (*_version) (void);
278
279 if (file == NULL && directory == NULL) {
280 return MCRYPT_UNKNOWN_ERROR;
281 }
282
283 if (lt_dlinit() != 0) {
284 return MCRYPT_UNKNOWN_ERROR;
285 }
286 /* LTDL_SET_PRELOADED_SYMBOLS(); */
287
288 rr = mcrypt_dlopen(&_handle, directory, NULL, file);
289
290 if (!rr) {
291 lt_dlexit();
292 return MCRYPT_UNKNOWN_ERROR;
293 }
294
295
296 _version = mcrypt_dlsym(_handle, "_mcrypt_mode_version");
297
298 if (_version == NULL) {
299 mcrypt_dlclose(_handle);
300 lt_dlexit();
301 return MCRYPT_UNKNOWN_ERROR;
302 }
303
304 ret = _version();
305
306 mcrypt_dlclose(_handle);
307 lt_dlexit();
308
309 return ret;
310
311 }
312
313 /* Taken from libgcrypt */
314
315 static const char*
316 parse_version_number( const char *s, int *number )
317 {
318 int val = 0;
319
320 if( *s == '0' && isdigit(s[1]) )
321 return NULL; /* leading zeros are not allowed */
322 for ( ; isdigit(*s); s++ ) {
323 val *= 10;
324 val += *s - '0';
325 }
326 *number = val;
327 return val < 0? NULL : s;
328 }
329
330
331 static const char *
332 parse_version_string( const char *s, int *major, int *minor, int *micro )
333 {
334 s = parse_version_number( s, major );
335 if( !s || *s != '.' )
336 return NULL;
337 s++;
338 s = parse_version_number( s, minor );
339 if( !s || *s != '.' )
340 return NULL;
341 s++;
342 s = parse_version_number( s, micro );
343 if( !s )
344 return NULL;
345 return s; /* patchlevel */
346 }
347
348 /****************
349 * Check that the the version of the library is at minimum the requested one
350 * and return the version string; return NULL if the condition is not
351 * satisfied. If a NULL is passed to this function, no check is done,
352 * but the version string is simply returned.
353 */
354 const char *
355 mcrypt_check_version( const char *req_version )
356 {
357 const char *ver = VERSION;
358 int my_major, my_minor, my_micro;
359 int rq_major, rq_minor, rq_micro;
360 const char *my_plvl, *rq_plvl;
361
362 if ( !req_version )
363 return ver;
364
365 my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
366 if ( !my_plvl )
367 return NULL; /* very strange our own version is bogus */
368 rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
369 &rq_micro );
370 if ( !rq_plvl )
371 return NULL; /* req version string is invalid */
372
373 if ( my_major > rq_major
374 || (my_major == rq_major && my_minor > rq_minor)
375 || (my_major == rq_major && my_minor == rq_minor
376 && my_micro > rq_micro)
377 || (my_major == rq_major && my_minor == rq_minor
378 && my_micro == rq_micro
379 && strcmp( my_plvl, rq_plvl ) >= 0) ) {
380 return ver;
381 }
382 return NULL;
383 }
384

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26