Files
smmapdfw/smmapdfw/smmapd/containers.c
whottgen c41ee865e1 changes
2004-09-27 14:35:43 +00:00

268 lines
6.7 KiB
C

#if HAVE_CONFIG_H
# include "config.h"
#endif
#if HAVE_SYSLOG_H
#include <syslog.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#endif
#if STDC_HEADERS
#include <stdlib.h>
#endif
#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#include "containers.h"
#include "cfg.h"
#include "smmapd.h"
#define CFG_SECTION_GLOBAL "global"
#define CFG_NAME_PLUGIN_DIR "plugin_dir"
#define CFG_NAME_PLUGINS "plugins"
#define CFG_PLUGINS_DELIMITER " "
#define CFG_NAME_OBJ "obj"
extern cfg_t *cfg;
classes_t classes_root = {NULL, 0, NULL, NULL};
classes_t *classes_head = &classes_root;
int containers_setup(container_handle_t **ch) {
*ch = (container_handle_t*)malloc(sizeof(container_handle_t));
(*ch)->worker_handle_root.next = NULL;
return 0;
}
int containers_destroy(container_handle_t *ch) {
worker_handle_t *wh, *wh2;
classes_t *classes;
int err;
syslog(LOG_DEBUG, "containers_destroy: going to free container_handle, first the worker handles");
wh = ch->worker_handle_root.next;
while (NULL != wh) {
for (classes = classes_root.next; classes != NULL; classes = classes->next) {
if (classes->id == wh->id) {
if (NULL != classes->descr->work_destroy_function) {
syslog(LOG_DEBUG, "containers_destroy: calling work_destroy_function for class %s (%d)",
classes->descr->name, classes->id);
err = (*classes->descr->work_destroy_function)(classes->handle, wh->handle);
}
}
}
wh2 = wh;
wh = wh->next;
free(wh2);
}
free(ch);
syslog(LOG_DEBUG, "containers_destroy: all freed");
}
int containers_dispatcher(container_handle_t *ch, char *input, char *output) {
char *class;
char *data;
classes_t *classes;
int result, err;
worker_handle_t *wh, *wh_last, *wh2;
syslog(LOG_DEBUG, "dispatcher: input: %s", input);
data = strchr(input, ' ');
if (NULL == data) {
syslog(LOG_ERR, "dispatcher: illegal input (%s)", input);
return SMM_ILLEGAL_INPUT;
}
data++; /* skip the blank */
class = input;
class[strlen(class)-strlen(data)-1] = '\0';
syslog(LOG_DEBUG, "dispatcher: class: %s, data: %s", class, data);
for (classes = classes_root.next; classes != NULL; classes = classes->next) {
if (0 == strcmp(class, classes->descr->name)) {
syslog(LOG_DEBUG, "dispatcher: yes, we support it, it's id=%d", classes->id);
for (wh = ch->worker_handle_root.next, wh_last = &ch->worker_handle_root, wh2 = NULL;
wh != NULL;
wh = wh->next) {
wh_last = wh;
if (wh->id == classes->id) {
syslog(LOG_DEBUG, "dispatcher: we already have a worker handle");
wh2 = wh;
break;
}
}
if ((NULL == wh_last->next) && (NULL == wh2)) {
syslog(LOG_DEBUG, "dispatcher: we haven't one, we create one");
wh2 = (worker_handle_t*)malloc(sizeof(worker_handle_t));
wh2->id = classes->id;
if (NULL != classes->descr->work_setup_function) {
err = (*classes->descr->work_setup_function)(classes->handle, &(wh2->handle));
} else {
wh2->handle = NULL;
}
wh2->next = NULL;
wh_last->next = wh2;
}
result = (*classes->descr->work_function)(classes->handle, wh2->handle, data, output);
syslog(LOG_DEBUG, "dispatcher: worker output: (%d, %s)", result, output);
break;
}
}
if (NULL == classes) {
syslog(LOG_ERR, "dispatcher: unknown class: %s", class);
return SMM_UNKNOWN_CLASS;
}
return result;
}
static int register_class(int id, class_descriptor_t *class_descriptor) {
int result = 0;
cfgl_t *c;
classes_t *w;
syslog(LOG_DEBUG, "register_class: registering class %s", class_descriptor->name);
c = findcfgsection(cfg, class_descriptor->name);
if (NULL == c) {
syslog(LOG_ERR, "register_class: no configuration section for this plugin available");
return -1;
}
w = (classes_t *) malloc(sizeof(classes_t));
if (NULL == w) {
syslog(LOG_ERR, "register_class: unable to alloc memory");
return -2;
}
if (NULL != class_descriptor->init_function) {
syslog(LOG_DEBUG, "register_class: initializing class %s", class_descriptor->name);
result = (*class_descriptor->init_function)(c, &w->handle);
if (0 != result) {
syslog(LOG_ERR, "register_class: unable to init class %s, exit", class_descriptor->name);
return -3;
}
} else {
w->handle = NULL;
}
w->descr = class_descriptor;
w->id = id;
w->next = NULL;
classes_head->next = w;
classes_head = w;
return 0;
}
static int unregister_class(classes_t *class) {
int result = 0;
syslog(LOG_DEBUG, "unregister_class: unregistering class %s", class->descr->name);
if (NULL != class->descr->destroy_function) {
syslog(LOG_DEBUG, "unregister_class: destroying class");
result = (*class->descr->destroy_function)(&class->handle);
syslog(LOG_ERR, "unregister_class: destroy function returns %d", result);
}
return 0;
}
int unregister_all() {
classes_t *classes, *cf;
classes = classes_root.next;
while (NULL != classes) {
cf = classes;
classes = classes->next;
unregister_class(cf);
free(cf);
}
}
int register_all() {
void *dl_handle;
class_descriptor_t * class_descriptor;
char *cfg_plugin_dir, *cfg_plugins, *cfg_plugin, *cfg_obj;
char *obj_name;
const char *err_msg;
int err;
int id = 0;
cfg_plugin_dir = findcfg(cfg, CFG_SECTION_GLOBAL, CFG_NAME_PLUGIN_DIR);
if (NULL == cfg_plugin_dir) {
syslog(LOG_ERR, "register_all: no plugin dir configured");
return -1;
}
cfg_plugins = findcfg(cfg, CFG_SECTION_GLOBAL, CFG_NAME_PLUGINS);
if (NULL == cfg_plugins) {
syslog(LOG_ERR, "register_all: no plugins configured");
return -2;
}
while (NULL != (cfg_plugin = strtok(cfg_plugins, CFG_PLUGINS_DELIMITER))) {
cfg_plugins = NULL; /* this is for subsequence calls of strtok */
dlerror(); /* this is to clear old errors */
cfg_obj = findcfg(cfg, cfg_plugin, CFG_NAME_OBJ);
if (NULL == cfg_obj) {
syslog(LOG_ERR, "register_all: obj for plugin %s not configured", cfg_plugin);
return -3;
}
obj_name = (char*) malloc(strlen(cfg_plugin_dir) + strlen(cfg_obj) + 5);
obj_name[0] = '\0';
strcat(obj_name, cfg_plugin_dir);
strcat(obj_name, "/");
strcat(obj_name, cfg_obj);
dl_handle = dlopen(obj_name, RTLD_NOW);
if (NULL == dl_handle) {
syslog(LOG_ERR, "register_all: error when dlopen: %s", dlerror());
free(obj_name);
return -4;
}
free(obj_name);
class_descriptor = (class_descriptor_t*) dlsym(dl_handle, cfg_plugin);
if (NULL != (err_msg = dlerror())) {
syslog(LOG_ERR, "register_all: plugin %s not found, error %s", cfg_plugin, err_msg);
return -5;
}
err = register_class(id++, class_descriptor);
if (0 != err) {
syslog(LOG_ERR, "register_all: unable to initialize plugin %s, error %d", cfg_plugin, err);
return -6;
}
}
return 0;
}