hlswmaster/plugin.c
2006-11-24 21:52:14 +01:00

191 lines
4.9 KiB
C

/***************************************************************************
* Copyright (C) 03/2005 by Olaf Rempel *
* razzor@kopf-tisch.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <stdlib.h>
#include <dlfcn.h>
#include <pthread.h>
#include "hlswmaster.h"
#include "plugin.h"
#include "configfile.h"
#include "netpkt.h"
#include "list.h"
/** liste der geladenen plugins */
static LIST_HEAD(plugin_list);
/** sichert die plugin liste UND die plugins selbst ab */
static pthread_mutex_t plugin_lock = PTHREAD_MUTEX_INITIALIZER;
/**
* plugin_load()
* laedt ein plugin und fuegt es in die plugin liste ein
*
* @param *name filename des plugins
* @return false on error
*/
int plugin_load(char *name)
{
struct hlswmaster_plugin *plugin;
void *tmp;
struct conf_section *section;
dlerror();
/* shared objekt oeffnen */
if ((tmp = dlopen(name, RTLD_NOW))) {
/* plugin struct suchen */
if ((plugin = dlsym(tmp, "plugin"))) {
plugin->dlref = tmp;
section = config_get_section(plugin->name);
log_print("loading plugin '%s'", plugin->name);
/* wenn vorhanden, init aufrufen */
if (!plugin->init || (plugin->init(section))) {
pthread_mutex_lock(&plugin_lock);
list_add_tail(&plugin->list, &plugin_list);
pthread_mutex_unlock(&plugin_lock);
return 1;
}
log_print("failed to load '%s'", name);
dlclose(tmp);
return 0;
}
dlclose(tmp);
}
log_print("%s", dlerror());
return 0;
}
/**
* plugin_load_all()
* laedt alle in der config angegebenen plugins
*
* @return false on error
*/
int plugin_load_all()
{
struct conf_section *section;
struct conf_tupel *tupel;
section = config_get_section("global");
if (section) {
list_for_each_entry(tupel, &section->tupel, list)
if (!strcmp(tupel->option, "plugin"))
plugin_load(tupel->parameter);
}
return 1;
}
/**
* plugin_unload_all()
* entfernt alle plugins aus der liste,
*
* @return false on error
*/
int plugin_unload_all()
{
struct hlswmaster_plugin *plugin, *tmp;
pthread_mutex_lock(&plugin_lock);
list_for_each_entry_safe(plugin, tmp, &plugin_list, list) {
list_del(&plugin->list);
if (plugin->fini)
plugin->fini();
log_print("plugin '%s' unloaded", plugin->name);
dlclose(plugin->dlref);
}
pthread_mutex_unlock(&plugin_lock);
return 1;
}
/**
* plugins_scan()
* ruft die scan() Funktionen der Plugins auf
*
* @return true
*/
int plugins_scan(void)
{
struct hlswmaster_plugin *plugin;
pthread_mutex_lock(&plugin_lock);
list_for_each_entry(plugin, &plugin_list, list)
/* wenn vorhanden die scan funktion aufrufen */
if (plugin->scan && !plugin->scan())
log_print("plugin %s: scan error", plugin->name);
pthread_mutex_unlock(&plugin_lock);
return 1;
}
/**
* plugins_parse()
* ruft die parse() Funktionen der Plugins auf
* bis ein Plugin das Paket annimmt
*
* @param *pkt das zu parsene paket
* @return false wenn kein Plugin das Paket angenommen,
* sonst rueckgabewert des Plugins
*/
int plugins_parse(struct net_pkt *pkt)
{
struct hlswmaster_plugin *plugin;
int retval;
pthread_mutex_lock(&plugin_lock);
list_for_each_entry(plugin, &plugin_list, list) {
/* wenn vorhanden die parse funktion aufrufen */
if (plugin->parse && (retval = plugin->parse(pkt))) {
pthread_mutex_unlock(&plugin_lock);
return retval;
}
}
pthread_mutex_unlock(&plugin_lock);
return PARSE_REJECT;
}
/**
* plugins_gc()
* ruft die gc() Funktionen der Plugins auf
*
* @param timeout timeout interval in sekunden
* @return true
*/
int plugins_gc(unsigned long timeout)
{
struct hlswmaster_plugin *plugin;
pthread_mutex_lock(&plugin_lock);
list_for_each_entry(plugin, &plugin_list, list)
if (plugin->gc)
plugin->gc(timeout);
pthread_mutex_unlock(&plugin_lock);
return 1;
}