1 /*
2 * Module handling
3 *
4 * Copyright (C) 2003 Olaf Kirch <okir@suse.de>
5 */
6
7 #include "internal.h"
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <limits.h>
12 #include <sys/param.h>
13 #include <ltdl.h>
14
ifd_module_path(const char * subdir)15 static const char *ifd_module_path(const char *subdir)
16 {
17 static char path[PATH_MAX];
18
19 if (!ct_config.modules_dir
20 && !(ct_config.modules_dir = getenv("IFD_MODULES")))
21 ct_config.modules_dir = OPENCT_MODULES_PATH;
22
23 snprintf(path, sizeof(path), "%s/%ss", ct_config.modules_dir, subdir);
24 return path;
25 }
26
ifd_load_module(const char * type,const char * name)27 int ifd_load_module(const char *type, const char *name)
28 {
29 const char *dirname;
30 char path[PATH_MAX];
31 lt_dlhandle handle;
32 void (*init_func) (void);
33
34 if (strstr(name, "..")) {
35 ct_error("Illegal module path \"%s\"", name);
36 return -1;
37 }
38
39 if (!strcmp(type, "driver")) {
40 dirname = ct_config.driver_modules_dir;
41 } else if (!strcmp(type, "protocol")) {
42 dirname = ct_config.protocol_modules_dir;
43 } else {
44 ct_error("Unknown module type \"%s\"", type);
45 return -1;
46 }
47
48 if (!dirname)
49 dirname = ifd_module_path(type);
50
51 #if defined(HAVE_DLFCN_H) && defined(__APPLE__)
52 snprintf(path, sizeof(path), "%s/%s.so", dirname, name);
53 #elif defined(__APPLE__)
54 snprintf(path, sizeof(path), "%s/%s.bundle", dirname, name);
55 #else
56 snprintf(path, sizeof(path), "%s/%s.so", dirname, name);
57 #endif
58
59 handle = lt_dlopen(path);
60 if (!handle) {
61 ct_error("Failed to load %s: %s", path, lt_dlerror());
62 return -1;
63 }
64
65 init_func = (void (*)(void))lt_dlsym(handle, "ifd_init_module");
66 if (!init_func) {
67 ct_error("%s: no function called ifd_init_module", path);
68 lt_dlclose(handle);
69 return -1;
70 }
71
72 init_func();
73 return 0;
74 }
75