root/src/noit_module.c

Revision 80235b3f11f72d0a54a7ae6df1139d23ed59e2ac, 3.1 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

checkers

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7
8 #include <stdio.h>
9 #include <dlfcn.h>
10
11 #include "noit_module.h"
12 #include "noit_conf.h"
13 #include "utils/noit_hash.h"
14 #include "utils/noit_log.h"
15
16 static noit_hash_table modules = NOIT_HASH_EMPTY;
17
18 int noit_module_load(const char *file, const char *name) {
19   char module_file[PATH_MAX];
20   char *base;
21   void *dlhandle;
22   void *dlsymbol;
23   noit_module_t *module;
24
25   if(!noit_conf_get_string(NULL, "/noit/modules/directory", &base))
26     base = strdup("");
27
28   if(file[0] == '/')
29     strlcpy(module_file, file, sizeof(module_file));
30   else
31     snprintf(module_file, sizeof(module_file), "%s/%s.%s",
32              base, name, MODULEEXT);
33   free(base);
34
35   dlhandle = dlopen(module_file, RTLD_LAZY | RTLD_GLOBAL);
36   if(!dlhandle) {
37     noit_log(noit_stderr, NULL, "Cannot open image '%s': %s\n",
38              module_file, dlerror());
39     return -1;
40   }
41
42   dlsymbol = dlsym(dlhandle, name);
43   if(!dlsymbol) {
44     noit_log(noit_stderr, NULL, "Cannot find '%s' in image '%s': %s\n",
45              name, module_file, dlerror());
46     dlclose(dlhandle);
47     return -1;
48   }
49
50   if(noit_module_validate_magic((noit_module_t *)dlsymbol) == -1) {
51     noit_log(noit_stderr, NULL, "I can't understand module %s\n", name);
52     dlclose(dlhandle);
53     return -1;
54   }
55
56   module = calloc(1, sizeof(*module));
57   memcpy(module, dlsymbol, sizeof(*module));
58
59   if(module->onload(module)) {
60     free(module);
61     return -1;
62   }
63   noit_hash_store(&modules, module->name, strlen(module->name), module);
64   return 0;
65 }
66
67 noit_module_t * noit_module_lookup(const char *name) {
68   noit_module_t *module;
69
70   if(noit_hash_retrieve(&modules, name, strlen(name), (void **)&module)) {
71     return module;
72   }
73   return NULL;
74 }
75
76 void noit_module_init() {
77   noit_conf_section_t *sections;
78   int i, cnt = 0;
79
80   sections = noit_conf_get_sections(NULL, "/noit/modules/module", &cnt);
81   if(!sections) return;
82   for(i=0; i<cnt; i++) {
83     noit_hash_table *config;
84     noit_module_t *module;
85     char module_file[PATH_MAX];
86     char module_name[256];
87     if(!noit_conf_get_stringbuf(sections[i], "image",
88                                 module_file, sizeof(module_file))) {
89       noit_log(noit_stderr, NULL,
90                "No image defined in module stanza %d\n", i+1);
91       continue;
92     }
93     if(!noit_conf_get_stringbuf(sections[i], "name",
94                                 module_name, sizeof(module_name))) {
95       noit_log(noit_stderr, NULL,
96                "No name defined in module stanza %d\n", i+1);
97       continue;
98     }
99     if(noit_module_load(module_file, module_name)) {
100       noit_log(noit_stderr, NULL,
101                "Could not load %s:%s\n", module_file, module_name);
102       continue;
103     }
104     config = noit_conf_get_hash(sections[i], "config/*");
105     module = noit_module_lookup(module_name);
106     if(module->config(module, config)) {
107       noit_log(noit_stderr, NULL,
108                "Configure failed on %s:%s\n", module_file, module_name);
109       continue;
110     }
111     noit_log(noit_stderr, NULL, "Module %s:%s successfully loaded.\n",
112              module_file, module_name);
113   }
114 }
Note: See TracBrowser for help on using the browser.