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