1 #include <net-snmp/net-snmp-config.h>
17 #include <netinet/in.h>
23 #include <net-snmp/net-snmp-includes.h>
24 #include <net-snmp/agent/net-snmp-agent-includes.h>
30 static struct dlmod *dlmods = NULL;
32 int dlmod_next_index = 1;
34 static void dlmod_parse_config(char *, char *);
35 static void dlmod_free_config(void);
36 static char dlmod_path[1024];
44 snmpd_register_config_handler("dlmod", dlmod_parse_config,
45 dlmod_free_config, "dlmod-file-to-load");
47 p = getenv("SNMP_DLMOD_PATH");
48 strncpy(dlmod_path, DLMOD_DEFAULT_PATH, sizeof(dlmod_path));
51 l = strlen(dlmod_path);
52 if (dlmod_path[l - 1] != ':')
53 strncat(dlmod_path, ":", sizeof(dlmod_path) - l);
54 strncat(dlmod_path, p + 1,
55 sizeof(dlmod_path) - strlen(dlmod_path));
57 strncpy(dlmod_path, p, sizeof(dlmod_path));
60 DEBUGMSGTL(("dlmod", "dlmod_path: %s\n", dlmod_path));
67 snmpd_unregister_config_handler("dlmod");
71 dlmod_parse_config(char *token, char *cptr)
73 char *dlm_name, *dlm_path;
77 config_perror("Bad dlmod line");
83 *(cptr + strcspn(cptr, "#;\r\n")) = '\0';
85 dlm = dlmod_create_module();
92 dlm_name = strtok(cptr, "\t ");
93 if (dlm_name == NULL) {
94 config_perror("Bad dlmod line");
95 dlmod_delete_module(dlm);
98 strncpy(dlm->name, dlm_name, sizeof(dlm->name));
101 * dynamic module path
103 dlm_path = strtok(NULL, "\t ");
105 strncpy(dlm->path, dlm_path, sizeof(dlm->path));
107 strncpy(dlm->path, dlm_name, sizeof(dlm->path));
109 dlmod_load_module(dlm);
111 if (dlm->status == DLMOD_ERROR)
112 snmp_log(LOG_ERR, "%s\n", dlm->error);
117 dlmod_free_config(void)
119 struct dlmod *dtmp, *dtmp2;
121 for (dtmp = dlmods; dtmp != NULL;) {
124 dlmod_unload_module(dtmp2);
128 dlmod_next_index = 1;
132 dlmod_create_module(void)
134 struct dlmod **pdlmod, *dlm;
136 DEBUGMSGTL(("dlmod", "dlmod_create_module\n"));
138 dlm = calloc(1, sizeof(struct dlmod));
142 dlm->index = dlmod_next_index++;
143 dlm->status = DLMOD_UNLOADED;
145 for (pdlmod = &dlmods; *pdlmod != NULL; pdlmod = &((*pdlmod)->next));
152 dlmod_delete_module(struct dlmod *dlm)
154 struct dlmod **pdlmod;
157 DEBUGMSGTL(("dlmod", "dlmod_delete_module\n"));
159 if (!dlm || dlm->status != DLMOD_UNLOADED)
162 for (pdlmod = &dlmods; *pdlmod; pdlmod = &((*pdlmod)->next))
163 if (*pdlmod == dlm) {
171 dlmod_load_module(struct dlmod *dlm)
174 char *p, tmp_path[255];
175 int (*dl_init) (void);
177 DEBUGMSGTL(("dlmod", "dlmod_load_module\n"));
180 if (!dlm || !dlm->path || !dlm->name || dlm->status != DLMOD_UNLOADED)
184 if (dlm->path[0] == '/') {
185 dlm->handle = dlopen(dlm->path, RTLD_NOW);
186 if (dlm->handle == NULL) {
187 snprintf(dlm->error, sizeof(dlm->error),
188 "dlopen failed: %s", dlerror());
189 dlm->status = DLMOD_ERROR;
193 for (p = strtok(dlmod_path, ":"); p; p = strtok(NULL, ":")) {
194 snprintf(tmp_path, sizeof(tmp_path), "%s/%s.so", p, dlm->path);
196 DEBUGMSGTL(("dlmod", "p: %s tmp_path: %s\n", p, tmp_path));
198 dlm->handle = dlopen(tmp_path, RTLD_NOW);
199 if (dlm->handle == NULL) {
200 snprintf(dlm->error, sizeof(dlm->error),
201 "dlopen failed: %s", dlerror());
202 dlm->status = DLMOD_ERROR;
205 strncpy(dlm->path, tmp_path, sizeof(dlm->path));
206 if (dlm->status == DLMOD_ERROR)
209 snprintf(sym_init, sizeof(sym_init), "_dynamic_init_%s", dlm->name);
210 dl_init = dlsym(dlm->handle, sym_init);
211 if (dl_init == NULL) {
212 snprintf(dlm->error, sizeof(dlm->error),
213 "dlsym failed: can't find \'%s\'", sym_init);
214 dlm->status = DLMOD_ERROR;
219 snprintf(dlm->error, sizeof(dlm->error), "\'%s\' failed",
221 dlm->status = DLMOD_ERROR;
225 dlm->error[0] = '\0';
226 dlm->status = DLMOD_LOADED;
230 dlmod_unload_module(struct dlmod *dlm)
234 int (*dl_deinit) (void);
236 if (!dlm || dlm->status != DLMOD_LOADED)
239 snprintf(sym_deinit, sizeof(sym_deinit), "_dynamic_deinit_%s",
241 dl_deinit = dlsym(dlm->handle, sym_deinit);
242 if (dl_deinit == NULL) {
243 /** it's right way ? */
244 dlm->status = DLMOD_ERROR;
248 dlclose(dlm->handle);
249 dlm->status = DLMOD_UNLOADED;
251 DEBUGMSGTL(("dlmod", "Module %s unloaded\n", dlm->name));
256 dlmod_get_next_index(void)
258 return dlmod_next_index;
262 dlmod_get_by_index(int iindex)
266 for (dlmod = dlmods; dlmod; dlmod = dlmod->next)
267 if (dlmod->index == iindex)
275 dlmod_get_next(struct dlmod *dlm)