/*************************************************************************** * 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 #include #include #include "hlswmaster.h" #include "plugin.h" #include "configfile.h" #include "netpkt.h" #include "list.h" /* liste der geladenen plugins */ LIST_HEAD(plugin_list); /* sichert die plugin list UND die plugins ab */ static pthread_mutex_t plugin_lock = PTHREAD_MUTEX_INITIALIZER; /** * plugin_load() * laedt ein shared object, * fuehrt wenn vorhanden init() aus * und haengt den plugin an das ende der liste * * @param char *name * @return false on error */ int plugin_load(char *name) { struct hlswmaster_plugin *plugin; void *tmp; struct conf_section *section; dlerror(); if ((tmp = dlopen(name, RTLD_NOW))) { if ((plugin = dlsym(tmp, "plugin"))) { plugin->dlref = tmp; section = config_get_section(plugin->name); log_print("loading plugin '%s'", plugin->name); 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; } log_print("%s", dlerror()); dlclose(tmp); } 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, §ion->tupel, list) if (!strcmp(tupel->option, "plugin")) plugin_load(tupel->parameter); } return 1; } /** * plugin_unload_all() * entfernt alle plugins aus der liste, * ruft wenn vorhanden fini() auf * und entlaed das shared object * * @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 (wenn vorhanden) * * @return true */ int plugins_scan(void) { struct hlswmaster_plugin *plugin; pthread_mutex_lock(&plugin_lock); list_for_each_entry(plugin, &plugin_list, list) 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 (wenn vorhanden) * bis ein Plugin das Paket annimmt * * @param struct net_pkt *pkt * @return false wenn kein Plugin das Paket angenommen hat */ int plugins_parse(struct net_pkt *pkt) { struct hlswmaster_plugin *plugin; pthread_mutex_lock(&plugin_lock); list_for_each_entry(plugin, &plugin_list, list) { if (plugin->parse && plugin->parse(pkt)) { pthread_mutex_unlock(&plugin_lock); return 1; } } pthread_mutex_unlock(&plugin_lock); return 0; } /** * plugins_gc() * ruft die gc() Funktionen der Plugins auf (wenn vorhanden) * * @param unsigned long timeout * @return true * * TODO: wird noch nicht benutzt, welcher thread soll das machen? */ 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; }