/*************************************************************************** * 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 #include "plugin.h" #include "configfile.h" #include "logging.h" #include "netpkt.h" #include "list.h" #include "event.h" #define BUFSIZE 512 static LIST_HEAD(plugin_list); static int plugin_load(const char *filename, void *privdata) { char *plugin_dir = (char *)privdata; char *fullname = malloc(BUFSIZE); if (fullname == NULL) { log_print(LOG_ERROR, "plugin_load: out of memory"); return -1; } int len = snprintf(fullname, BUFSIZE, "%s/%s", plugin_dir, filename); if (len < 0 || len >= BUFSIZE) { log_print(LOG_ERROR, "plugin_load: file name too long: %s/%s", plugin_dir, filename); free(fullname); return -1; } dlerror(); void *dlref = dlopen(fullname, RTLD_NOW); if (dlref == NULL) { log_print(LOG_WARN, "plugin_load: %s", dlerror()); free(fullname); return -1; } struct hlswmaster_plugin *plugin = dlsym(dlref, "plugin"); if (plugin == NULL) { log_print(LOG_WARN, "plugin_load: invalid plugin '%s'", fullname); dlclose(dlref); free(fullname); return -1; } log_print(LOG_INFO, "loading plugin '%s'", plugin->name); if (plugin->init == NULL || (plugin->init() == 0)) { list_add_tail(&plugin->list, &plugin_list); free(fullname); return 0; } log_print(LOG_WARN, "plugin_load: failed to load '%s'", plugin->name); dlclose(dlref); free(fullname); return -1; } int plugins_scan(void) { struct hlswmaster_plugin *plugin; list_for_each_entry(plugin, &plugin_list, list) if (plugin->scan && !plugin->scan()) log_print(LOG_WARN, "plugin %s: scan error", plugin->name); return 0; } int plugins_parse(struct net_pkt *pkt) { int retval; struct hlswmaster_plugin *plugin; list_for_each_entry(plugin, &plugin_list, list) if (plugin->parse && (retval = plugin->parse(pkt))) return retval; return PARSE_REJECT; } int plugin_init(void) { char *dir = config_get_string("global", "plugin_dir", "."); int cnt = config_get_strings("global", "plugin", plugin_load, (void *)dir); log_print(LOG_INFO, "%d plugins loaded", cnt); return 0; }