/[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.24 - (show annotations)
Mon Dec 16 09:46:50 2002 UTC (21 years, 4 months ago) by nmav
Branch: MAIN
Changes since 1.23: +126 -129 lines
File MIME type: text/plain
*** empty log message ***

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26