1bcdc6a3bSJan Kneschke #include <string.h> 2bcdc6a3bSJan Kneschke #include <stdlib.h> 3bcdc6a3bSJan Kneschke 4bcdc6a3bSJan Kneschke #include <stdio.h> 5bcdc6a3bSJan Kneschke 6bcdc6a3bSJan Kneschke #include "plugin.h" 7bcdc6a3bSJan Kneschke #include "log.h" 8bcdc6a3bSJan Kneschke #include "config.h" 9bcdc6a3bSJan Kneschke 10bcdc6a3bSJan Kneschke #ifdef HAVE_VALGRIND_VALGRIND_H 11bcdc6a3bSJan Kneschke #include <valgrind/valgrind.h> 12bcdc6a3bSJan Kneschke #endif 13bcdc6a3bSJan Kneschke 14bcdc6a3bSJan Kneschke #ifndef __WIN32 15bcdc6a3bSJan Kneschke #include <dlfcn.h> 16bcdc6a3bSJan Kneschke #endif 17bcdc6a3bSJan Kneschke /* 18bcdc6a3bSJan Kneschke * 19bcdc6a3bSJan Kneschke * if you change this enum to add a new callback, be sure 20bcdc6a3bSJan Kneschke * - that PLUGIN_FUNC_SIZEOF is the last entry 21bcdc6a3bSJan Kneschke * - that you add PLUGIN_TO_SLOT twice: 22bcdc6a3bSJan Kneschke * 1. as callback-dispatcher 23bcdc6a3bSJan Kneschke * 2. in plugins_call_init() 24bcdc6a3bSJan Kneschke * 25bcdc6a3bSJan Kneschke */ 26bcdc6a3bSJan Kneschke 27bcdc6a3bSJan Kneschke typedef struct { 28bcdc6a3bSJan Kneschke PLUGIN_DATA; 29bcdc6a3bSJan Kneschke } plugin_data; 30bcdc6a3bSJan Kneschke 31bcdc6a3bSJan Kneschke typedef enum { 32bcdc6a3bSJan Kneschke PLUGIN_FUNC_UNSET, 33bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_URI_CLEAN, 34bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_URI_RAW, 35bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_REQUEST_DONE, 36bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, 37bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_TRIGGER, 38bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_SIGHUP, 39bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_SUBREQUEST, 40bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_SUBREQUEST_START, 41bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_JOBLIST, 42bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_DOCROOT, 436adaad54SJan Kneschke PLUGIN_FUNC_HANDLE_PHYSICAL, 44bcdc6a3bSJan Kneschke PLUGIN_FUNC_CONNECTION_RESET, 45bcdc6a3bSJan Kneschke PLUGIN_FUNC_INIT, 46bcdc6a3bSJan Kneschke PLUGIN_FUNC_CLEANUP, 47bcdc6a3bSJan Kneschke PLUGIN_FUNC_SET_DEFAULTS, 48bcdc6a3bSJan Kneschke 49bcdc6a3bSJan Kneschke PLUGIN_FUNC_SIZEOF 50bcdc6a3bSJan Kneschke } plugin_t; 51bcdc6a3bSJan Kneschke 52bcdc6a3bSJan Kneschke static plugin *plugin_init(void) { 53bcdc6a3bSJan Kneschke plugin *p; 54bcdc6a3bSJan Kneschke 55bcdc6a3bSJan Kneschke p = calloc(1, sizeof(*p)); 56bcdc6a3bSJan Kneschke 57bcdc6a3bSJan Kneschke return p; 58bcdc6a3bSJan Kneschke } 59bcdc6a3bSJan Kneschke 60bcdc6a3bSJan Kneschke static void plugin_free(plugin *p) { 61bcdc6a3bSJan Kneschke int use_dlclose = 1; 62bcdc6a3bSJan Kneschke if (p->name) buffer_free(p->name); 63bcdc6a3bSJan Kneschke #ifdef HAVE_VALGRIND_VALGRIND_H 6475c3a839SJan Kneschke /*if (RUNNING_ON_VALGRIND) use_dlclose = 0;*/ 65bcdc6a3bSJan Kneschke #endif 66bcdc6a3bSJan Kneschke 67bcdc6a3bSJan Kneschke if (use_dlclose && p->lib) { 68bcdc6a3bSJan Kneschke #ifdef __WIN32 69bcdc6a3bSJan Kneschke FreeLibrary(p->lib); 70bcdc6a3bSJan Kneschke #else 71bcdc6a3bSJan Kneschke dlclose(p->lib); 72bcdc6a3bSJan Kneschke #endif 73bcdc6a3bSJan Kneschke } 74bcdc6a3bSJan Kneschke 75bcdc6a3bSJan Kneschke free(p); 76bcdc6a3bSJan Kneschke } 77bcdc6a3bSJan Kneschke 78bcdc6a3bSJan Kneschke static int plugins_register(server *srv, plugin *p) { 79bcdc6a3bSJan Kneschke plugin **ps; 80bcdc6a3bSJan Kneschke if (0 == srv->plugins.size) { 81bcdc6a3bSJan Kneschke srv->plugins.size = 4; 82bcdc6a3bSJan Kneschke srv->plugins.ptr = malloc(srv->plugins.size * sizeof(*ps)); 83bcdc6a3bSJan Kneschke srv->plugins.used = 0; 84bcdc6a3bSJan Kneschke } else if (srv->plugins.used == srv->plugins.size) { 85bcdc6a3bSJan Kneschke srv->plugins.size += 4; 86bcdc6a3bSJan Kneschke srv->plugins.ptr = realloc(srv->plugins.ptr, srv->plugins.size * sizeof(*ps)); 87bcdc6a3bSJan Kneschke } 88bcdc6a3bSJan Kneschke 89bcdc6a3bSJan Kneschke ps = srv->plugins.ptr; 90bcdc6a3bSJan Kneschke ps[srv->plugins.used++] = p; 91bcdc6a3bSJan Kneschke 92bcdc6a3bSJan Kneschke return 0; 93bcdc6a3bSJan Kneschke } 94bcdc6a3bSJan Kneschke 95bcdc6a3bSJan Kneschke /** 96bcdc6a3bSJan Kneschke * 97bcdc6a3bSJan Kneschke * 98bcdc6a3bSJan Kneschke * 99bcdc6a3bSJan Kneschke */ 100bcdc6a3bSJan Kneschke 101bcdc6a3bSJan Kneschke 102bcdc6a3bSJan Kneschke int plugins_load(server *srv) { 103bcdc6a3bSJan Kneschke plugin *p; 104bcdc6a3bSJan Kneschke int (*init)(plugin *pl); 105bcdc6a3bSJan Kneschke const char *error; 106bcdc6a3bSJan Kneschke size_t i; 107bcdc6a3bSJan Kneschke 108bcdc6a3bSJan Kneschke for (i = 0; i < srv->srvconf.modules->used; i++) { 109bcdc6a3bSJan Kneschke data_string *d = (data_string *)srv->srvconf.modules->data[i]; 110bcdc6a3bSJan Kneschke char *modules = d->value->ptr; 111bcdc6a3bSJan Kneschke 112c7ec5012SJan Kneschke buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir); 113*15dc40cdSJan Kneschke 114bcdc6a3bSJan Kneschke buffer_append_string(srv->tmp_buf, "/"); 115bcdc6a3bSJan Kneschke buffer_append_string(srv->tmp_buf, modules); 116bcdc6a3bSJan Kneschke #if defined(__WIN32) || defined(__CYGWIN__) 117bcdc6a3bSJan Kneschke buffer_append_string(srv->tmp_buf, ".dll"); 118bcdc6a3bSJan Kneschke #else 119bcdc6a3bSJan Kneschke buffer_append_string(srv->tmp_buf, ".so"); 120bcdc6a3bSJan Kneschke #endif 121bcdc6a3bSJan Kneschke 122bcdc6a3bSJan Kneschke p = plugin_init(); 123bcdc6a3bSJan Kneschke #ifdef __WIN32 124bcdc6a3bSJan Kneschke if (NULL == (p->lib = LoadLibrary(srv->tmp_buf->ptr))) { 125bcdc6a3bSJan Kneschke LPVOID lpMsgBuf; 126bcdc6a3bSJan Kneschke FormatMessage( 127bcdc6a3bSJan Kneschke FORMAT_MESSAGE_ALLOCATE_BUFFER | 128bcdc6a3bSJan Kneschke FORMAT_MESSAGE_FROM_SYSTEM, 129bcdc6a3bSJan Kneschke NULL, 130bcdc6a3bSJan Kneschke GetLastError(), 131bcdc6a3bSJan Kneschke MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 132bcdc6a3bSJan Kneschke (LPTSTR) &lpMsgBuf, 133bcdc6a3bSJan Kneschke 0, NULL ); 134bcdc6a3bSJan Kneschke 135bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed", 136bcdc6a3bSJan Kneschke lpMsgBuf, srv->tmp_buf); 137bcdc6a3bSJan Kneschke 138bcdc6a3bSJan Kneschke plugin_free(p); 139bcdc6a3bSJan Kneschke 140bcdc6a3bSJan Kneschke return -1; 141bcdc6a3bSJan Kneschke 142bcdc6a3bSJan Kneschke } 143bcdc6a3bSJan Kneschke #else 144bcdc6a3bSJan Kneschke if (NULL == (p->lib = dlopen(srv->tmp_buf->ptr, RTLD_LAZY))) { 1456b5c314cSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:", 1466b5c314cSJan Kneschke srv->tmp_buf, dlerror()); 147bcdc6a3bSJan Kneschke 148bcdc6a3bSJan Kneschke plugin_free(p); 149bcdc6a3bSJan Kneschke 150bcdc6a3bSJan Kneschke return -1; 151bcdc6a3bSJan Kneschke } 152bcdc6a3bSJan Kneschke 153bcdc6a3bSJan Kneschke #endif 154bcdc6a3bSJan Kneschke buffer_reset(srv->tmp_buf); 155bcdc6a3bSJan Kneschke buffer_copy_string(srv->tmp_buf, modules); 156bcdc6a3bSJan Kneschke buffer_append_string(srv->tmp_buf, "_plugin_init"); 157bcdc6a3bSJan Kneschke 158bcdc6a3bSJan Kneschke #ifdef __WIN32 159bcdc6a3bSJan Kneschke init = GetProcAddress(p->lib, srv->tmp_buf->ptr); 160bcdc6a3bSJan Kneschke 161bcdc6a3bSJan Kneschke if (init == NULL) { 162bcdc6a3bSJan Kneschke LPVOID lpMsgBuf; 163bcdc6a3bSJan Kneschke FormatMessage( 164bcdc6a3bSJan Kneschke FORMAT_MESSAGE_ALLOCATE_BUFFER | 165bcdc6a3bSJan Kneschke FORMAT_MESSAGE_FROM_SYSTEM, 166bcdc6a3bSJan Kneschke NULL, 167bcdc6a3bSJan Kneschke GetLastError(), 168bcdc6a3bSJan Kneschke MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 169bcdc6a3bSJan Kneschke (LPTSTR) &lpMsgBuf, 170bcdc6a3bSJan Kneschke 0, NULL ); 171bcdc6a3bSJan Kneschke 172bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "sbs", "getprocaddress failed:", srv->tmp_buf, lpMsgBuf); 173bcdc6a3bSJan Kneschke 174bcdc6a3bSJan Kneschke plugin_free(p); 175bcdc6a3bSJan Kneschke return -1; 176bcdc6a3bSJan Kneschke } 177bcdc6a3bSJan Kneschke 178bcdc6a3bSJan Kneschke #else 179bcdc6a3bSJan Kneschke *(void **)(&init) = dlsym(p->lib, srv->tmp_buf->ptr); 180bcdc6a3bSJan Kneschke if ((error = dlerror()) != NULL) { 181bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "s", error); 182bcdc6a3bSJan Kneschke 183bcdc6a3bSJan Kneschke plugin_free(p); 184bcdc6a3bSJan Kneschke return -1; 185bcdc6a3bSJan Kneschke } 186bcdc6a3bSJan Kneschke 187bcdc6a3bSJan Kneschke #endif 188bcdc6a3bSJan Kneschke if ((*init)(p)) { 189bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin init failed" ); 190bcdc6a3bSJan Kneschke 191bcdc6a3bSJan Kneschke plugin_free(p); 192bcdc6a3bSJan Kneschke return -1; 193bcdc6a3bSJan Kneschke } 194bcdc6a3bSJan Kneschke #if 0 195bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin loaded" ); 196bcdc6a3bSJan Kneschke #endif 197bcdc6a3bSJan Kneschke plugins_register(srv, p); 198bcdc6a3bSJan Kneschke } 199bcdc6a3bSJan Kneschke 200bcdc6a3bSJan Kneschke return 0; 201bcdc6a3bSJan Kneschke } 202bcdc6a3bSJan Kneschke 203bcdc6a3bSJan Kneschke #define PLUGIN_TO_SLOT(x, y) \ 204bcdc6a3bSJan Kneschke handler_t plugins_call_##y(server *srv, connection *con) {\ 205bcdc6a3bSJan Kneschke plugin **slot;\ 206bcdc6a3bSJan Kneschke size_t j;\ 207bcdc6a3bSJan Kneschke if (!srv->plugin_slots) return HANDLER_GO_ON;\ 208bcdc6a3bSJan Kneschke slot = ((plugin ***)(srv->plugin_slots))[x];\ 209bcdc6a3bSJan Kneschke if (!slot) return HANDLER_GO_ON;\ 210bcdc6a3bSJan Kneschke for (j = 0; j < srv->plugins.used && slot[j]; j++) { \ 211bcdc6a3bSJan Kneschke plugin *p = slot[j];\ 212bcdc6a3bSJan Kneschke handler_t r;\ 213bcdc6a3bSJan Kneschke switch(r = p->y(srv, con, p->data)) {\ 214bcdc6a3bSJan Kneschke case HANDLER_GO_ON:\ 215bcdc6a3bSJan Kneschke break;\ 216bcdc6a3bSJan Kneschke case HANDLER_FINISHED:\ 217bcdc6a3bSJan Kneschke case HANDLER_COMEBACK:\ 218bcdc6a3bSJan Kneschke case HANDLER_WAIT_FOR_EVENT:\ 219bcdc6a3bSJan Kneschke case HANDLER_WAIT_FOR_FD:\ 220bcdc6a3bSJan Kneschke case HANDLER_ERROR:\ 221bcdc6a3bSJan Kneschke return r;\ 222bcdc6a3bSJan Kneschke default:\ 223bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "sbs", #x, p->name, "unknown state");\ 224bcdc6a3bSJan Kneschke return HANDLER_ERROR;\ 225bcdc6a3bSJan Kneschke }\ 226bcdc6a3bSJan Kneschke }\ 227bcdc6a3bSJan Kneschke return HANDLER_GO_ON;\ 228bcdc6a3bSJan Kneschke } 229bcdc6a3bSJan Kneschke 230bcdc6a3bSJan Kneschke /** 231bcdc6a3bSJan Kneschke * plugins that use 232bcdc6a3bSJan Kneschke * 233bcdc6a3bSJan Kneschke * - server *srv 234bcdc6a3bSJan Kneschke * - connection *con 235bcdc6a3bSJan Kneschke * - void *p_d (plugin_data *) 236bcdc6a3bSJan Kneschke */ 237bcdc6a3bSJan Kneschke 238bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean) 239bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw) 240bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done) 241bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close) 242bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST, handle_subrequest) 243bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST_START, handle_subrequest_start) 244bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_JOBLIST, handle_joblist) 245bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_DOCROOT, handle_docroot) 2466adaad54SJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_PHYSICAL, handle_physical) 247bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_CONNECTION_RESET, connection_reset) 248bcdc6a3bSJan Kneschke 249bcdc6a3bSJan Kneschke #undef PLUGIN_TO_SLOT 250bcdc6a3bSJan Kneschke 251bcdc6a3bSJan Kneschke #define PLUGIN_TO_SLOT(x, y) \ 252bcdc6a3bSJan Kneschke handler_t plugins_call_##y(server *srv) {\ 253bcdc6a3bSJan Kneschke plugin **slot;\ 254bcdc6a3bSJan Kneschke size_t j;\ 255bcdc6a3bSJan Kneschke if (!srv->plugin_slots) return HANDLER_GO_ON;\ 256bcdc6a3bSJan Kneschke slot = ((plugin ***)(srv->plugin_slots))[x];\ 257bcdc6a3bSJan Kneschke if (!slot) return HANDLER_GO_ON;\ 258bcdc6a3bSJan Kneschke for (j = 0; j < srv->plugins.used && slot[j]; j++) { \ 259bcdc6a3bSJan Kneschke plugin *p = slot[j];\ 260bcdc6a3bSJan Kneschke handler_t r;\ 261bcdc6a3bSJan Kneschke switch(r = p->y(srv, p->data)) {\ 262bcdc6a3bSJan Kneschke case HANDLER_GO_ON:\ 263bcdc6a3bSJan Kneschke break;\ 264bcdc6a3bSJan Kneschke case HANDLER_FINISHED:\ 265bcdc6a3bSJan Kneschke case HANDLER_COMEBACK:\ 266bcdc6a3bSJan Kneschke case HANDLER_WAIT_FOR_EVENT:\ 267bcdc6a3bSJan Kneschke case HANDLER_WAIT_FOR_FD:\ 268bcdc6a3bSJan Kneschke case HANDLER_ERROR:\ 269bcdc6a3bSJan Kneschke return r;\ 270bcdc6a3bSJan Kneschke default:\ 271bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "sbsd", #x, p->name, "unknown state:", r);\ 272bcdc6a3bSJan Kneschke return HANDLER_ERROR;\ 273bcdc6a3bSJan Kneschke }\ 274bcdc6a3bSJan Kneschke }\ 275bcdc6a3bSJan Kneschke return HANDLER_GO_ON;\ 276bcdc6a3bSJan Kneschke } 277bcdc6a3bSJan Kneschke 278bcdc6a3bSJan Kneschke /** 279bcdc6a3bSJan Kneschke * plugins that use 280bcdc6a3bSJan Kneschke * 281bcdc6a3bSJan Kneschke * - server *srv 282bcdc6a3bSJan Kneschke * - void *p_d (plugin_data *) 283bcdc6a3bSJan Kneschke */ 284bcdc6a3bSJan Kneschke 285bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger) 286bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup) 287bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup) 288bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults) 289bcdc6a3bSJan Kneschke 290bcdc6a3bSJan Kneschke #undef PLUGIN_TO_SLOT 291bcdc6a3bSJan Kneschke 292bcdc6a3bSJan Kneschke #if 0 293bcdc6a3bSJan Kneschke /** 294bcdc6a3bSJan Kneschke * 295bcdc6a3bSJan Kneschke * special handler 296bcdc6a3bSJan Kneschke * 297bcdc6a3bSJan Kneschke */ 298bcdc6a3bSJan Kneschke handler_t plugins_call_handle_fdevent(server *srv, const fd_conn *fdc) { 299bcdc6a3bSJan Kneschke size_t i; 300bcdc6a3bSJan Kneschke plugin **ps; 301bcdc6a3bSJan Kneschke 302bcdc6a3bSJan Kneschke ps = srv->plugins.ptr; 303bcdc6a3bSJan Kneschke 304bcdc6a3bSJan Kneschke for (i = 0; i < srv->plugins.used; i++) { 305bcdc6a3bSJan Kneschke plugin *p = ps[i]; 306bcdc6a3bSJan Kneschke if (p->handle_fdevent) { 307bcdc6a3bSJan Kneschke handler_t r; 308bcdc6a3bSJan Kneschke switch(r = p->handle_fdevent(srv, fdc, p->data)) { 309bcdc6a3bSJan Kneschke case HANDLER_GO_ON: 310bcdc6a3bSJan Kneschke break; 311bcdc6a3bSJan Kneschke case HANDLER_FINISHED: 312bcdc6a3bSJan Kneschke case HANDLER_COMEBACK: 313bcdc6a3bSJan Kneschke case HANDLER_WAIT_FOR_EVENT: 314bcdc6a3bSJan Kneschke case HANDLER_ERROR: 315bcdc6a3bSJan Kneschke return r; 316bcdc6a3bSJan Kneschke default: 317bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "d", r); 318bcdc6a3bSJan Kneschke break; 319bcdc6a3bSJan Kneschke } 320bcdc6a3bSJan Kneschke } 321bcdc6a3bSJan Kneschke } 322bcdc6a3bSJan Kneschke 323bcdc6a3bSJan Kneschke return HANDLER_GO_ON; 324bcdc6a3bSJan Kneschke } 325bcdc6a3bSJan Kneschke #endif 326bcdc6a3bSJan Kneschke /** 327bcdc6a3bSJan Kneschke * 328bcdc6a3bSJan Kneschke * - call init function of all plugins to init the plugin-internals 329bcdc6a3bSJan Kneschke * - added each plugin that supports has callback to the corresponding slot 330bcdc6a3bSJan Kneschke * 331bcdc6a3bSJan Kneschke * - is only called once. 332bcdc6a3bSJan Kneschke */ 333bcdc6a3bSJan Kneschke 334bcdc6a3bSJan Kneschke handler_t plugins_call_init(server *srv) { 335bcdc6a3bSJan Kneschke size_t i; 336bcdc6a3bSJan Kneschke plugin **ps; 337bcdc6a3bSJan Kneschke 338bcdc6a3bSJan Kneschke ps = srv->plugins.ptr; 339bcdc6a3bSJan Kneschke 340bcdc6a3bSJan Kneschke /* fill slots */ 341bcdc6a3bSJan Kneschke 342bcdc6a3bSJan Kneschke srv->plugin_slots = calloc(PLUGIN_FUNC_SIZEOF, sizeof(ps)); 343bcdc6a3bSJan Kneschke 344bcdc6a3bSJan Kneschke for (i = 0; i < srv->plugins.used; i++) { 345bcdc6a3bSJan Kneschke size_t j; 346bcdc6a3bSJan Kneschke /* check which calls are supported */ 347bcdc6a3bSJan Kneschke 348bcdc6a3bSJan Kneschke plugin *p = ps[i]; 349bcdc6a3bSJan Kneschke 350bcdc6a3bSJan Kneschke #define PLUGIN_TO_SLOT(x, y) \ 351bcdc6a3bSJan Kneschke if (p->y) { \ 352bcdc6a3bSJan Kneschke plugin **slot = ((plugin ***)(srv->plugin_slots))[x]; \ 353bcdc6a3bSJan Kneschke if (!slot) { \ 354bcdc6a3bSJan Kneschke slot = calloc(srv->plugins.used, sizeof(*slot));\ 355bcdc6a3bSJan Kneschke ((plugin ***)(srv->plugin_slots))[x] = slot; \ 356bcdc6a3bSJan Kneschke } \ 357bcdc6a3bSJan Kneschke for (j = 0; j < srv->plugins.used; j++) { \ 358bcdc6a3bSJan Kneschke if (slot[j]) continue;\ 359bcdc6a3bSJan Kneschke slot[j] = p;\ 360bcdc6a3bSJan Kneschke break;\ 361bcdc6a3bSJan Kneschke }\ 362bcdc6a3bSJan Kneschke } 363bcdc6a3bSJan Kneschke 364bcdc6a3bSJan Kneschke 365bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean); 366bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw); 367bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done); 368bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close); 369bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger); 370bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup); 371bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST, handle_subrequest); 372bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST_START, handle_subrequest_start); 373bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_JOBLIST, handle_joblist); 374bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_DOCROOT, handle_docroot); 3756adaad54SJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_PHYSICAL, handle_physical); 376bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_CONNECTION_RESET, connection_reset); 377bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup); 378bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults); 379bcdc6a3bSJan Kneschke #undef PLUGIN_TO_SLOT 380bcdc6a3bSJan Kneschke 381bcdc6a3bSJan Kneschke if (p->init) { 382bcdc6a3bSJan Kneschke if (NULL == (p->data = p->init())) { 383bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "sb", 384bcdc6a3bSJan Kneschke "plugin-init failed for module", p->name); 385bcdc6a3bSJan Kneschke return HANDLER_ERROR; 386bcdc6a3bSJan Kneschke } 387bcdc6a3bSJan Kneschke 388bcdc6a3bSJan Kneschke /* used for con->mode, DIRECT == 0, plugins above that */ 389bcdc6a3bSJan Kneschke ((plugin_data *)(p->data))->id = i + 1; 390bcdc6a3bSJan Kneschke 391bcdc6a3bSJan Kneschke if (p->version != LIGHTTPD_VERSION_ID) { 392bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "sb", 393bcdc6a3bSJan Kneschke "plugin-version doesn't match lighttpd-version for", p->name); 394bcdc6a3bSJan Kneschke return HANDLER_ERROR; 395bcdc6a3bSJan Kneschke } 396bcdc6a3bSJan Kneschke } else { 397bcdc6a3bSJan Kneschke p->data = NULL; 398bcdc6a3bSJan Kneschke } 399bcdc6a3bSJan Kneschke } 400bcdc6a3bSJan Kneschke 401bcdc6a3bSJan Kneschke return HANDLER_GO_ON; 402bcdc6a3bSJan Kneschke } 403bcdc6a3bSJan Kneschke 404bcdc6a3bSJan Kneschke void plugins_free(server *srv) { 405bcdc6a3bSJan Kneschke size_t i; 406bcdc6a3bSJan Kneschke plugins_call_cleanup(srv); 407bcdc6a3bSJan Kneschke 408bcdc6a3bSJan Kneschke for (i = 0; i < srv->plugins.used; i++) { 409bcdc6a3bSJan Kneschke plugin *p = ((plugin **)srv->plugins.ptr)[i]; 410bcdc6a3bSJan Kneschke 411bcdc6a3bSJan Kneschke plugin_free(p); 412bcdc6a3bSJan Kneschke } 413bcdc6a3bSJan Kneschke 414bcdc6a3bSJan Kneschke for (i = 0; srv->plugin_slots && i < PLUGIN_FUNC_SIZEOF; i++) { 415bcdc6a3bSJan Kneschke plugin **slot = ((plugin ***)(srv->plugin_slots))[i]; 416bcdc6a3bSJan Kneschke 417bcdc6a3bSJan Kneschke if (slot) free(slot); 418bcdc6a3bSJan Kneschke } 419bcdc6a3bSJan Kneschke 420bcdc6a3bSJan Kneschke free(srv->plugin_slots); 421bcdc6a3bSJan Kneschke srv->plugin_slots = NULL; 422bcdc6a3bSJan Kneschke 423bcdc6a3bSJan Kneschke free(srv->plugins.ptr); 424bcdc6a3bSJan Kneschke srv->plugins.ptr = NULL; 425bcdc6a3bSJan Kneschke } 426