/[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.21 - (show annotations)
Fri May 17 20:53:18 2002 UTC (21 years, 10 months ago) by nmav
Branch: MAIN
Changes since 1.20: +9 -1 lines
File MIME type: text/plain
Corrected stuff for comma separated algorithms. Do not open directories when not in LTDL mode.

1 /*
2 * Copyright (C) 1998,1999,2001 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.20 2002/01/31 01:13:58 nmav Exp $ */
21
22 #include <libdefs.h>
23 #include <bzero.h>
24 #include <xmemory.h>
25 #include <mcrypt_internal.h>
26
27 int mcrypt_algorithm_module_ok(const char *file, const char *directory);
28 int mcrypt_mode_module_ok(const char *file, const char *directory);
29
30 void *mcrypt_dlopen(mcrypt_dlhandle *handle, const char *a_directory, const char *m_directory,
31 const char *filename);
32
33 #ifdef HAVE_READDIR_R
34 # define MAXPATHLEN 256
35 #endif
36
37 WIN32DLL_DEFINE char *mcrypt_readdir(DIR * dirstream)
38 {
39
40 char *result;
41 struct dirent *ret = NULL;
42 #ifdef HAVE_READDIR_R
43 struct dirent ret2[sizeof(struct dirent)+MAXPATHLEN];
44 #endif
45
46 #ifdef DT_REG
47 do {
48 #endif
49
50 #ifdef HAVE_READDIR_R
51 readdir_r(dirstream, ret2, &ret);
52 #else
53 ret = readdir(dirstream);
54 #endif
55 if (ret==NULL) return NULL;
56
57 result = calloc(1, strlen(ret->d_name) + 1);
58 if (result == NULL) {
59 return NULL;
60 }
61 strcpy(result, ret->d_name);
62 #ifdef DT_REG
63 }
64 while ((ret->d_type != DT_REG) && (ret->d_type != DT_UNKNOWN)
65 && (ret != NULL));
66 #endif
67
68 return result;
69
70 }
71
72 extern const mcrypt_preloaded mps[];
73
74 WIN32DLL_DEFINE char **mcrypt_list_algorithms(char *libdir, int *size)
75 {
76 DIR *pdir;
77 char directory[512];
78 char *dirname;
79 char **filename = NULL, *ptr;
80 int tmpsize, i=0;
81
82
83 *size = 0;
84
85 while( mps[i].name!=0 || mps[i].address!=0) {
86 if (mps[i].name!=NULL && mps[i].address==NULL) {
87 if (mcrypt_algorithm_module_ok( mps[i].name, NULL) > 0) {
88 filename =
89 realloc(filename,
90 ((*size) + 1) * sizeof(char *));
91 if (filename==NULL) {
92 goto freeall;
93 }
94 filename[*size] = strdup( mps[i].name);
95 if (filename[*size]==NULL) goto freeall;
96 (*size)++;
97 }
98 }
99 i++;
100 }
101
102 #ifdef USE_LTDL
103
104 if (libdir == NULL) {
105 strcpy(directory, LIBDIR);
106 } else {
107 strcpy(directory, libdir);
108 }
109
110 pdir = opendir(directory);
111 if (pdir == NULL) {
112 #ifdef DEBUG
113 fprintf(stderr, "Unable to open directory %s.\n",
114 directory);
115 #endif
116 return filename;
117 }
118
119 for (;;) {
120 dirname = mcrypt_readdir(pdir);
121 if (dirname != NULL) {
122 tmpsize = strlen(dirname);
123 if (tmpsize > 3) {
124 if (mcrypt_algorithm_module_ok
125 (dirname, directory) > 0) {
126
127 ptr =
128 strrchr( dirname, '.');
129 if (ptr != NULL) {
130 *ptr = '\0';
131 tmpsize = strlen(dirname);
132 }
133 if (_mcrypt_search_symlist_lib( dirname)!=NULL) {
134 free(dirname);
135 continue; /* it's already in the list,
136 * since it's included in the lib.
137 */
138 }
139 filename =
140 realloc(filename,
141 (*size +
142 1) * sizeof(char *));
143 if (filename==NULL) {
144 free(dirname);
145 goto freeall;
146 }
147
148
149 filename[*size] = (char*)
150 calloc(1, tmpsize + 1);
151 if (filename[*size]==NULL) {
152 free(dirname);
153 goto freeall;
154 }
155 strcpy(filename[*size], dirname);
156
157 (*size)++;
158 }
159 }
160 free(dirname);
161 } else {
162 break;
163 }
164
165 }
166
167
168 closedir(pdir);
169
170 #endif
171
172 return filename;
173
174 freeall:
175 for (i=0;i<(*size);i++) {
176 free(filename[i]);
177 }
178 free(filename);
179 return NULL;
180 }
181
182 WIN32DLL_DEFINE char **mcrypt_list_modes(char *libdir, int *size)
183 {
184 DIR *pdir;
185 char directory[512];
186 char *dirname;
187 char **filename = NULL, *ptr;
188 int tmpsize;
189 int i=0;
190
191 *size = 0;
192
193 while( mps[i].name!=0 || mps[i].address!=0) {
194 if (mps[i].name!=NULL && mps[i].address==NULL) {
195 if (mcrypt_mode_module_ok( mps[i].name, NULL) > 0) {
196 filename =
197 realloc(filename,
198 (*size +
199 1) * sizeof(char *));
200 if (filename==NULL) {
201 goto freeall;
202 }
203 filename[*size] = strdup( mps[i].name);
204 if (filename[*size]==NULL) goto freeall;
205 (*size)++;
206 }
207 }
208 i++;
209 }
210
211 #ifdef USE_LTDL
212
213 if (libdir == NULL) {
214 strcpy(directory, LIBDIR);
215 } else {
216 strcpy(directory, libdir);
217 }
218
219 pdir = opendir(directory);
220 if (pdir == NULL) {
221 #ifdef DEBUG
222 fprintf(stderr, "Unable to open directory %s.\n",
223 directory);
224 #endif
225 return filename;
226 }
227
228 for (;;) {
229
230 dirname = mcrypt_readdir(pdir);
231 if (dirname != NULL) {
232 tmpsize = strlen(dirname);
233 if (tmpsize > 3) {
234 if (mcrypt_mode_module_ok
235 (dirname, directory) > 0) {
236
237 ptr =
238 strrchr( dirname, '.');
239 if (ptr != NULL) {
240 *ptr = '\0';
241 tmpsize = strlen(dirname);
242 }
243 if (_mcrypt_search_symlist_lib( dirname)!=NULL) {
244 free(dirname);
245 continue; /* it's already in the list,
246 * since it's included in the lib.
247 */
248 }
249 filename =
250 realloc(filename,
251 (*size +
252 1) * sizeof(char *));
253 if (filename==NULL) {
254 free(dirname);
255 goto freeall;
256 }
257 filename[*size] =
258 calloc(1, tmpsize + 1);
259 if (filename[*size]==NULL) {
260 free(dirname);
261 goto freeall;
262 }
263
264 strcpy(filename[*size], dirname);
265 (*size)++;
266 }
267 }
268 free(dirname);
269 } else {
270 break;
271 }
272
273 }
274
275 closedir(pdir);
276 #endif
277
278 return filename;
279
280 freeall:
281 for (i=0;i<(*size);i++) {
282 free(filename[i]);
283 }
284 free(filename);
285 return NULL;
286 }
287
288 WIN32DLL_DEFINE void mcrypt_free_p(char **p, int size)
289 {
290 int i;
291
292 for (i = 0; i < size; i++) {
293 free(p[i]);
294 }
295 free(p);
296 }
297
298 WIN32DLL_DEFINE
299 int mcrypt_algorithm_module_ok(const char *file, const char *directory)
300 {
301 word32 ret;
302 mcrypt_dlhandle _handle;
303 void* rr;
304 int (*_version) (void);
305
306 if (file == NULL && directory == NULL) {
307 return MCRYPT_UNKNOWN_ERROR;
308 }
309
310 if (lt_dlinit() != 0) {
311 return MCRYPT_UNKNOWN_ERROR;
312 }
313
314
315 rr = mcrypt_dlopen(&_handle, directory, NULL, file);
316
317 if (!rr) {
318 lt_dlexit();
319 return MCRYPT_UNKNOWN_ERROR;
320 }
321
322
323 _version = mcrypt_dlsym(_handle, "_mcrypt_algorithm_version");
324
325 if (_version == NULL) {
326 mcrypt_dlclose(_handle);
327 lt_dlexit();
328 return MCRYPT_UNKNOWN_ERROR;
329 }
330
331 ret = _version();
332
333 mcrypt_dlclose(_handle);
334 lt_dlexit();
335
336 return ret;
337
338 }
339
340 WIN32DLL_DEFINE
341 int mcrypt_mode_module_ok(const char *file, const char *directory)
342 {
343 word32 ret;
344 mcrypt_dlhandle _handle;
345 void* rr;
346 int (*_version) (void);
347
348 if (file == NULL && directory == NULL) {
349 return MCRYPT_UNKNOWN_ERROR;
350 }
351
352 if (lt_dlinit() != 0) {
353 return MCRYPT_UNKNOWN_ERROR;
354 }
355
356 rr = mcrypt_dlopen(&_handle, directory, NULL, file);
357 if (!rr) {
358 lt_dlexit();
359 return MCRYPT_UNKNOWN_ERROR;
360 }
361
362
363 _version = mcrypt_dlsym(_handle, "_mcrypt_mode_version");
364
365 if (_version == NULL) {
366 mcrypt_dlclose(_handle);
367 lt_dlexit();
368 return MCRYPT_UNKNOWN_ERROR;
369 }
370
371 ret = _version();
372
373 mcrypt_dlclose(_handle);
374 lt_dlexit();
375
376 return ret;
377
378 }
379
380 /* Taken from libgcrypt */
381
382 static const char*
383 parse_version_number( const char *s, int *number )
384 {
385 int val = 0;
386
387 if( *s == '0' && isdigit(s[1]) )
388 return NULL; /* leading zeros are not allowed */
389 for ( ; isdigit(*s); s++ ) {
390 val *= 10;
391 val += *s - '0';
392 }
393 *number = val;
394 return val < 0? NULL : s;
395 }
396
397
398 static const char *
399 parse_version_string( const char *s, int *major, int *minor, int *micro )
400 {
401 s = parse_version_number( s, major );
402 if( !s || *s != '.' )
403 return NULL;
404 s++;
405 s = parse_version_number( s, minor );
406 if( !s || *s != '.' )
407 return NULL;
408 s++;
409 s = parse_version_number( s, micro );
410 if( !s )
411 return NULL;
412 return s; /* patchlevel */
413 }
414
415 /****************
416 * Check that the the version of the library is at minimum the requested one
417 * and return the version string; return NULL if the condition is not
418 * satisfied. If a NULL is passed to this function, no check is done,
419 * but the version string is simply returned.
420 */
421 const char *
422 mcrypt_check_version( const char *req_version )
423 {
424 const char *ver = VERSION;
425 int my_major, my_minor, my_micro;
426 int rq_major, rq_minor, rq_micro;
427 const char *my_plvl, *rq_plvl;
428
429 if ( !req_version )
430 return ver;
431
432 my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
433 if ( !my_plvl )
434 return NULL; /* very strange our own version is bogus */
435 rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
436 &rq_micro );
437 if ( !rq_plvl )
438 return NULL; /* req version string is invalid */
439
440 if ( my_major > rq_major
441 || (my_major == rq_major && my_minor > rq_minor)
442 || (my_major == rq_major && my_minor == rq_minor
443 && my_micro > rq_micro)
444 || (my_major == rq_major && my_minor == rq_minor
445 && my_micro == rq_micro
446 && strcmp( my_plvl, rq_plvl ) >= 0) ) {
447 return ver;
448 }
449 return NULL;
450 }
451

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26