diff options
Diffstat (limited to 'src/plugin.c')
-rw-r--r-- | src/plugin.c | 176 |
1 files changed, 90 insertions, 86 deletions
diff --git a/src/plugin.c b/src/plugin.c index e74d8b0..55f8b03 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -1,39 +1,36 @@ +#include "plugin.h" +#include "log.h" + #include <string.h> #include <stdlib.h> #include <stdio.h> -#include "plugin.h" -#include "log.h" -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #ifdef HAVE_VALGRIND_VALGRIND_H -#include <valgrind/valgrind.h> +# include <valgrind/valgrind.h> #endif #ifndef __WIN32 -#include <dlfcn.h> +# include <dlfcn.h> #endif /* - * + * * if you change this enum to add a new callback, be sure * - that PLUGIN_FUNC_SIZEOF is the last entry * - that you add PLUGIN_TO_SLOT twice: - * 1. as callback-dispatcher + * 1. as callback-dispatcher * 2. in plugins_call_init() - * + * */ typedef struct { PLUGIN_DATA; } plugin_data; -typedef enum { +typedef enum { PLUGIN_FUNC_UNSET, - PLUGIN_FUNC_HANDLE_URI_CLEAN, - PLUGIN_FUNC_HANDLE_URI_RAW, + PLUGIN_FUNC_HANDLE_URI_CLEAN, + PLUGIN_FUNC_HANDLE_URI_RAW, PLUGIN_FUNC_HANDLE_REQUEST_DONE, PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, PLUGIN_FUNC_HANDLE_TRIGGER, @@ -44,18 +41,18 @@ typedef enum { PLUGIN_FUNC_HANDLE_DOCROOT, PLUGIN_FUNC_HANDLE_PHYSICAL, PLUGIN_FUNC_CONNECTION_RESET, - PLUGIN_FUNC_INIT, + PLUGIN_FUNC_INIT, PLUGIN_FUNC_CLEANUP, PLUGIN_FUNC_SET_DEFAULTS, - + PLUGIN_FUNC_SIZEOF } plugin_t; static plugin *plugin_init(void) { plugin *p; - + p = calloc(1, sizeof(*p)); - + return p; } @@ -67,7 +64,7 @@ static void plugin_free(plugin *p) { #endif #ifndef LIGHTTPD_STATIC - if (use_dlclose && p->lib) { + if (use_dlclose && p->lib) { #ifdef __WIN32 FreeLibrary(p->lib); #else @@ -75,7 +72,7 @@ static void plugin_free(plugin *p) { #endif } #endif - + free(p); } @@ -89,17 +86,17 @@ static int plugins_register(server *srv, plugin *p) { srv->plugins.size += 4; srv->plugins.ptr = realloc(srv->plugins.ptr, srv->plugins.size * sizeof(*ps)); } - + ps = srv->plugins.ptr; ps[srv->plugins.used++] = p; - + return 0; } /** - * - * - * + * + * + * */ #ifdef LIGHTTPD_STATIC @@ -123,28 +120,35 @@ int plugins_load(server *srv) { plugin *p; int (*init)(plugin *pl); const char *error; - size_t i; - + size_t i, j; + for (i = 0; i < srv->srvconf.modules->used; i++) { data_string *d = (data_string *)srv->srvconf.modules->data[i]; char *modules = d->value->ptr; - + + for (j = 0; j < i; j++) { + if (buffer_is_equal(d->value, ((data_string *) srv->srvconf.modules->data[j])->value)) { + log_error_write(srv, __FILE__, __LINE__, "sbs", "Cannot load plugin", d->value, "more than once, please fix your config (we may not accept such configs in future releases"); + continue; + } + } + buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir); - buffer_append_string(srv->tmp_buf, "/"); + buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("/")); buffer_append_string(srv->tmp_buf, modules); #if defined(__WIN32) || defined(__CYGWIN__) - buffer_append_string(srv->tmp_buf, ".dll"); + buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN(".dll")); #else - buffer_append_string(srv->tmp_buf, ".so"); + buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN(".so")); #endif - + p = plugin_init(); #ifdef __WIN32 if (NULL == (p->lib = LoadLibrary(srv->tmp_buf->ptr))) { LPVOID lpMsgBuf; FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), @@ -152,28 +156,28 @@ int plugins_load(server *srv) { (LPTSTR) &lpMsgBuf, 0, NULL ); - log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed", + log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed", lpMsgBuf, srv->tmp_buf); - + plugin_free(p); - + return -1; } -#else - if (NULL == (p->lib = dlopen(srv->tmp_buf->ptr, RTLD_LAZY))) { - log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:", +#else + if (NULL == (p->lib = dlopen(srv->tmp_buf->ptr, RTLD_NOW|RTLD_GLOBAL))) { + log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:", srv->tmp_buf, dlerror()); - + plugin_free(p); - + return -1; } - + #endif buffer_reset(srv->tmp_buf); buffer_copy_string(srv->tmp_buf, modules); - buffer_append_string(srv->tmp_buf, "_plugin_init"); + buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("_plugin_init")); #ifdef __WIN32 init = GetProcAddress(p->lib, srv->tmp_buf->ptr); @@ -181,7 +185,7 @@ int plugins_load(server *srv) { if (init == NULL) { LPVOID lpMsgBuf; FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), @@ -190,28 +194,28 @@ int plugins_load(server *srv) { 0, NULL ); log_error_write(srv, __FILE__, __LINE__, "sbs", "getprocaddress failed:", srv->tmp_buf, lpMsgBuf); - + plugin_free(p); return -1; } #else #if 1 - init = (int (*)(plugin *))dlsym(p->lib, srv->tmp_buf->ptr); + init = (int (*)(plugin *))(intptr_t)dlsym(p->lib, srv->tmp_buf->ptr); #else *(void **)(&init) = dlsym(p->lib, srv->tmp_buf->ptr); #endif if ((error = dlerror()) != NULL) { log_error_write(srv, __FILE__, __LINE__, "s", error); - + plugin_free(p); return -1; } - + #endif if ((*init)(p)) { log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin init failed" ); - + plugin_free(p); return -1; } @@ -220,7 +224,7 @@ int plugins_load(server *srv) { #endif plugins_register(srv, p); } - + return 0; } #endif @@ -253,8 +257,8 @@ int plugins_load(server *srv) { } /** - * plugins that use - * + * plugins that use + * * - server *srv * - connection *con * - void *p_d (plugin_data *) @@ -301,12 +305,12 @@ PLUGIN_TO_SLOT(PLUGIN_FUNC_CONNECTION_RESET, connection_reset) } /** - * plugins that use - * + * plugins that use + * * - server *srv * - void *p_d (plugin_data *) */ - + PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger) PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup) PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup) @@ -314,18 +318,18 @@ PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults) #undef PLUGIN_TO_SLOT -#if 0 +#if 0 /** - * + * * special handler - * + * */ handler_t plugins_call_handle_fdevent(server *srv, const fd_conn *fdc) { size_t i; plugin **ps; - + ps = srv->plugins.ptr; - + for (i = 0; i < srv->plugins.used; i++) { plugin *p = ps[i]; if (p->handle_fdevent) { @@ -344,34 +348,34 @@ handler_t plugins_call_handle_fdevent(server *srv, const fd_conn *fdc) { } } } - + return HANDLER_GO_ON; } #endif /** - * + * * - call init function of all plugins to init the plugin-internals * - added each plugin that supports has callback to the corresponding slot - * + * * - is only called once. */ handler_t plugins_call_init(server *srv) { size_t i; plugin **ps; - + ps = srv->plugins.ptr; - + /* fill slots */ - + srv->plugin_slots = calloc(PLUGIN_FUNC_SIZEOF, sizeof(ps)); - + for (i = 0; i < srv->plugins.used; i++) { size_t j; /* check which calls are supported */ - + plugin *p = ps[i]; - + #define PLUGIN_TO_SLOT(x, y) \ if (p->y) { \ plugin **slot = ((plugin ***)(srv->plugin_slots))[x]; \ @@ -384,11 +388,11 @@ handler_t plugins_call_init(server *srv) { slot[j] = p;\ break;\ }\ - } - - - PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean); - PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw); + } + + + PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean); + PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw); PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done); PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close); PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger); @@ -402,19 +406,19 @@ handler_t plugins_call_init(server *srv) { PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup); PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults); #undef PLUGIN_TO_SLOT - + if (p->init) { if (NULL == (p->data = p->init())) { - log_error_write(srv, __FILE__, __LINE__, "sb", + log_error_write(srv, __FILE__, __LINE__, "sb", "plugin-init failed for module", p->name); return HANDLER_ERROR; } - + /* used for con->mode, DIRECT == 0, plugins above that */ ((plugin_data *)(p->data))->id = i + 1; - + if (p->version != LIGHTTPD_VERSION_ID) { - log_error_write(srv, __FILE__, __LINE__, "sb", + log_error_write(srv, __FILE__, __LINE__, "sb", "plugin-version doesn't match lighttpd-version for", p->name); return HANDLER_ERROR; } @@ -422,29 +426,29 @@ handler_t plugins_call_init(server *srv) { p->data = NULL; } } - + return HANDLER_GO_ON; } void plugins_free(server *srv) { size_t i; plugins_call_cleanup(srv); - + for (i = 0; i < srv->plugins.used; i++) { plugin *p = ((plugin **)srv->plugins.ptr)[i]; - + plugin_free(p); } - + for (i = 0; srv->plugin_slots && i < PLUGIN_FUNC_SIZEOF; i++) { plugin **slot = ((plugin ***)(srv->plugin_slots))[i]; - + if (slot) free(slot); } - + free(srv->plugin_slots); srv->plugin_slots = NULL; - + free(srv->plugins.ptr); srv->plugins.ptr = NULL; srv->plugins.used = 0; |