18abd06a7SGlenn Strauss #include "first.h" 28abd06a7SGlenn Strauss 322e8b456SStefan Bühler #include "plugin.h" 404d76e7aSGlenn Strauss #include "base.h" 522e8b456SStefan Bühler #include "log.h" 622e8b456SStefan Bühler 7bcdc6a3bSJan Kneschke #include <string.h> 8bcdc6a3bSJan Kneschke #include <stdlib.h> 9bcdc6a3bSJan Kneschke 10bcdc6a3bSJan Kneschke #ifdef HAVE_VALGRIND_VALGRIND_H 11bcdc6a3bSJan Kneschke # include <valgrind/valgrind.h> 12bcdc6a3bSJan Kneschke #endif 13bcdc6a3bSJan Kneschke 1402594f10SStefan Bühler #if !defined(__WIN32) && !defined(LIGHTTPD_STATIC) 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, 33b66fa2cbSStefan Bühler 34bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_URI_CLEAN, 35bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_URI_RAW, 36cb7ed136SGlenn Strauss PLUGIN_FUNC_HANDLE_REQUEST_ENV, 37bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_REQUEST_DONE, 38cb7ed136SGlenn Strauss PLUGIN_FUNC_HANDLE_CONNECTION_ACCEPT, 39cb7ed136SGlenn Strauss PLUGIN_FUNC_HANDLE_CONNECTION_SHUT_WR, 40bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, 41bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_TRIGGER, 42bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_SIGHUP, 439030cfaeSGlenn Strauss PLUGIN_FUNC_HANDLE_WAITPID, 44bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_SUBREQUEST, 45bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_SUBREQUEST_START, 46cb1a3c62SGlenn Strauss PLUGIN_FUNC_HANDLE_RESPONSE_START, 47bcdc6a3bSJan Kneschke PLUGIN_FUNC_HANDLE_DOCROOT, 486adaad54SJan Kneschke PLUGIN_FUNC_HANDLE_PHYSICAL, 49bcdc6a3bSJan Kneschke PLUGIN_FUNC_CONNECTION_RESET, 50bcdc6a3bSJan Kneschke PLUGIN_FUNC_INIT, 51bcdc6a3bSJan Kneschke PLUGIN_FUNC_CLEANUP, 52bcdc6a3bSJan Kneschke PLUGIN_FUNC_SET_DEFAULTS, 53f1e9bcb0SGlenn Strauss PLUGIN_FUNC_WORKER_INIT, 54bcdc6a3bSJan Kneschke 55bcdc6a3bSJan Kneschke PLUGIN_FUNC_SIZEOF 56bcdc6a3bSJan Kneschke } plugin_t; 57bcdc6a3bSJan Kneschke 58bcdc6a3bSJan Kneschke static plugin *plugin_init(void) { 59bcdc6a3bSJan Kneschke plugin *p; 60bcdc6a3bSJan Kneschke 61bcdc6a3bSJan Kneschke p = calloc(1, sizeof(*p)); 62566cf8deSStefan Bühler force_assert(NULL != p); 63bcdc6a3bSJan Kneschke 64bcdc6a3bSJan Kneschke return p; 65bcdc6a3bSJan Kneschke } 66bcdc6a3bSJan Kneschke 67bcdc6a3bSJan Kneschke static void plugin_free(plugin *p) { 68b66fa2cbSStefan Bühler #if !defined(LIGHTTPD_STATIC) 69*e2de4e58SGlenn Strauss if (p->lib) { 70*e2de4e58SGlenn Strauss #if defined(HAVE_VALGRIND_VALGRIND_H) 71*e2de4e58SGlenn Strauss /*if (!RUNNING_ON_VALGRIND) */ 72b66fa2cbSStefan Bühler #endif 73b66fa2cbSStefan Bühler #if defined(__WIN32) 74*e2de4e58SGlenn Strauss FreeLibrary(p->lib); 75bcdc6a3bSJan Kneschke #else 76bcdc6a3bSJan Kneschke dlclose(p->lib); 77bcdc6a3bSJan Kneschke #endif 78bcdc6a3bSJan Kneschke } 794c91a14cSJan Kneschke #endif 80bcdc6a3bSJan Kneschke 81bcdc6a3bSJan Kneschke free(p); 82bcdc6a3bSJan Kneschke } 83bcdc6a3bSJan Kneschke 84bcdc6a3bSJan Kneschke static int plugins_register(server *srv, plugin *p) { 85bcdc6a3bSJan Kneschke plugin **ps; 86d28bac32SGlenn Strauss if (srv->plugins.used == srv->plugins.size) { 87bcdc6a3bSJan Kneschke srv->plugins.size += 4; 88bcdc6a3bSJan Kneschke srv->plugins.ptr = realloc(srv->plugins.ptr, srv->plugins.size * sizeof(*ps)); 89566cf8deSStefan Bühler force_assert(NULL != srv->plugins.ptr); 90bcdc6a3bSJan Kneschke } 91bcdc6a3bSJan Kneschke 92bcdc6a3bSJan Kneschke ps = srv->plugins.ptr; 93bcdc6a3bSJan Kneschke ps[srv->plugins.used++] = p; 94bcdc6a3bSJan Kneschke 95bcdc6a3bSJan Kneschke return 0; 96bcdc6a3bSJan Kneschke } 97bcdc6a3bSJan Kneschke 98bcdc6a3bSJan Kneschke /** 99bcdc6a3bSJan Kneschke * 100bcdc6a3bSJan Kneschke * 101bcdc6a3bSJan Kneschke * 102bcdc6a3bSJan Kneschke */ 103bcdc6a3bSJan Kneschke 104b66fa2cbSStefan Bühler #if defined(LIGHTTPD_STATIC) 105b66fa2cbSStefan Bühler 106b66fa2cbSStefan Bühler /* pre-declare functions, as there is no header for them */ 1074c91a14cSJan Kneschke #define PLUGIN_INIT(x)\ 108b66fa2cbSStefan Bühler int x ## _plugin_init(plugin *p); 109bcdc6a3bSJan Kneschke 110a5e280fdSJan Kneschke #include "plugin-static.h" 1114c91a14cSJan Kneschke 112b66fa2cbSStefan Bühler #undef PLUGIN_INIT 113b66fa2cbSStefan Bühler 114b66fa2cbSStefan Bühler /* build NULL-terminated table of name + init-function */ 115b66fa2cbSStefan Bühler 116b66fa2cbSStefan Bühler typedef struct { 117b66fa2cbSStefan Bühler const char* name; 118b66fa2cbSStefan Bühler int (*plugin_init)(plugin *p); 119b66fa2cbSStefan Bühler } plugin_load_functions; 120b66fa2cbSStefan Bühler 121b66fa2cbSStefan Bühler static const plugin_load_functions load_functions[] = { 122b66fa2cbSStefan Bühler #define PLUGIN_INIT(x) \ 123b66fa2cbSStefan Bühler { #x, &x ## _plugin_init }, 124b66fa2cbSStefan Bühler 125b66fa2cbSStefan Bühler #include "plugin-static.h" 126b66fa2cbSStefan Bühler 127b66fa2cbSStefan Bühler { NULL, NULL } 128b66fa2cbSStefan Bühler #undef PLUGIN_INIT 129b66fa2cbSStefan Bühler }; 130b66fa2cbSStefan Bühler 131b66fa2cbSStefan Bühler int plugins_load(server *srv) { 132b66fa2cbSStefan Bühler plugin *p; 133b66fa2cbSStefan Bühler size_t i, j; 134b66fa2cbSStefan Bühler 135b66fa2cbSStefan Bühler for (i = 0; i < srv->srvconf.modules->used; i++) { 136601c572cSGlenn Strauss data_string *ds = (data_string *)srv->srvconf.modules->data[i]; 137601c572cSGlenn Strauss char *module = ds->value.ptr; 138b66fa2cbSStefan Bühler 139b66fa2cbSStefan Bühler for (j = 0; j < i; j++) { 140601c572cSGlenn Strauss if (buffer_is_equal(&ds->value, &((data_string *) srv->srvconf.modules->data[j])->value)) { 141b66fa2cbSStefan Bühler log_error_write(srv, __FILE__, __LINE__, "sbs", 142601c572cSGlenn Strauss "Cannot load plugin", &ds->value, 143b66fa2cbSStefan Bühler "more than once, please fix your config (lighttpd may not accept such configs in future releases)"); 144b66fa2cbSStefan Bühler continue; 145b66fa2cbSStefan Bühler } 146b66fa2cbSStefan Bühler } 147b66fa2cbSStefan Bühler 148b66fa2cbSStefan Bühler for (j = 0; load_functions[j].name; ++j) { 149b66fa2cbSStefan Bühler if (0 == strcmp(load_functions[j].name, module)) { 150b66fa2cbSStefan Bühler p = plugin_init(); 151b66fa2cbSStefan Bühler if ((*load_functions[j].plugin_init)(p)) { 152b66fa2cbSStefan Bühler log_error_write(srv, __FILE__, __LINE__, "ss", module, "plugin init failed" ); 153b66fa2cbSStefan Bühler plugin_free(p); 154b66fa2cbSStefan Bühler return -1; 155b66fa2cbSStefan Bühler } 156b66fa2cbSStefan Bühler plugins_register(srv, p); 157b66fa2cbSStefan Bühler break; 158b66fa2cbSStefan Bühler } 159b66fa2cbSStefan Bühler } 160b66fa2cbSStefan Bühler if (!load_functions[j].name) { 161b66fa2cbSStefan Bühler log_error_write(srv, __FILE__, __LINE__, "ss", module, " plugin not found" ); 162b66fa2cbSStefan Bühler return -1; 163b66fa2cbSStefan Bühler } 164b66fa2cbSStefan Bühler } 165b66fa2cbSStefan Bühler 1664c91a14cSJan Kneschke return 0; 1674c91a14cSJan Kneschke } 168b66fa2cbSStefan Bühler #else /* defined(LIGHTTPD_STATIC) */ 169bcdc6a3bSJan Kneschke int plugins_load(server *srv) { 170bcdc6a3bSJan Kneschke plugin *p; 171bcdc6a3bSJan Kneschke int (*init)(plugin *pl); 172614bb753SStefan Bühler size_t i, j; 173bcdc6a3bSJan Kneschke 174bcdc6a3bSJan Kneschke for (i = 0; i < srv->srvconf.modules->used; i++) { 175601c572cSGlenn Strauss data_string *ds = (data_string *)srv->srvconf.modules->data[i]; 176601c572cSGlenn Strauss char *module = ds->value.ptr; 177bcdc6a3bSJan Kneschke 178614bb753SStefan Bühler for (j = 0; j < i; j++) { 179601c572cSGlenn Strauss if (buffer_is_equal(&ds->value, &((data_string *) srv->srvconf.modules->data[j])->value)) { 180b66fa2cbSStefan Bühler log_error_write(srv, __FILE__, __LINE__, "sbs", 181601c572cSGlenn Strauss "Cannot load plugin", &ds->value, 182b66fa2cbSStefan Bühler "more than once, please fix your config (lighttpd may not accept such configs in future releases)"); 1836e724c05SStefan Bühler continue; 184614bb753SStefan Bühler } 185614bb753SStefan Bühler } 186614bb753SStefan Bühler 1876afad87dSStefan Bühler buffer_copy_buffer(srv->tmp_buf, srv->srvconf.modules_dir); 18815dc40cdSJan Kneschke 18952861d77SStefan Bühler buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("/")); 190b66fa2cbSStefan Bühler buffer_append_string(srv->tmp_buf, module); 191bcdc6a3bSJan Kneschke #if defined(__WIN32) || defined(__CYGWIN__) 19252861d77SStefan Bühler buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN(".dll")); 193bcdc6a3bSJan Kneschke #else 19452861d77SStefan Bühler buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN(".so")); 195bcdc6a3bSJan Kneschke #endif 196bcdc6a3bSJan Kneschke 197bcdc6a3bSJan Kneschke p = plugin_init(); 198bcdc6a3bSJan Kneschke #ifdef __WIN32 199bcdc6a3bSJan Kneschke if (NULL == (p->lib = LoadLibrary(srv->tmp_buf->ptr))) { 200bcdc6a3bSJan Kneschke LPVOID lpMsgBuf; 201bcdc6a3bSJan Kneschke FormatMessage( 202bcdc6a3bSJan Kneschke FORMAT_MESSAGE_ALLOCATE_BUFFER | 203bcdc6a3bSJan Kneschke FORMAT_MESSAGE_FROM_SYSTEM, 204bcdc6a3bSJan Kneschke NULL, 205bcdc6a3bSJan Kneschke GetLastError(), 206bcdc6a3bSJan Kneschke MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 207bcdc6a3bSJan Kneschke (LPTSTR) &lpMsgBuf, 208bcdc6a3bSJan Kneschke 0, NULL); 209bcdc6a3bSJan Kneschke 210bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed", 211bcdc6a3bSJan Kneschke lpMsgBuf, srv->tmp_buf); 212bcdc6a3bSJan Kneschke 213bcdc6a3bSJan Kneschke plugin_free(p); 214bcdc6a3bSJan Kneschke 215bcdc6a3bSJan Kneschke return -1; 216bcdc6a3bSJan Kneschke 217bcdc6a3bSJan Kneschke } 218bcdc6a3bSJan Kneschke #else 21953ab644eSMarcus Rückert if (NULL == (p->lib = dlopen(srv->tmp_buf->ptr, RTLD_NOW|RTLD_GLOBAL))) { 2206b5c314cSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:", 2216b5c314cSJan Kneschke srv->tmp_buf, dlerror()); 222bcdc6a3bSJan Kneschke 223bcdc6a3bSJan Kneschke plugin_free(p); 224bcdc6a3bSJan Kneschke 225bcdc6a3bSJan Kneschke return -1; 226bcdc6a3bSJan Kneschke } 227bcdc6a3bSJan Kneschke 228bcdc6a3bSJan Kneschke #endif 229b66fa2cbSStefan Bühler buffer_copy_string(srv->tmp_buf, module); 23052861d77SStefan Bühler buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("_plugin_init")); 231bcdc6a3bSJan Kneschke 232bcdc6a3bSJan Kneschke #ifdef __WIN32 233bcdc6a3bSJan Kneschke init = GetProcAddress(p->lib, srv->tmp_buf->ptr); 234bcdc6a3bSJan Kneschke 235bcdc6a3bSJan Kneschke if (init == NULL) { 236bcdc6a3bSJan Kneschke LPVOID lpMsgBuf; 237bcdc6a3bSJan Kneschke FormatMessage( 238bcdc6a3bSJan Kneschke FORMAT_MESSAGE_ALLOCATE_BUFFER | 239bcdc6a3bSJan Kneschke FORMAT_MESSAGE_FROM_SYSTEM, 240bcdc6a3bSJan Kneschke NULL, 241bcdc6a3bSJan Kneschke GetLastError(), 242bcdc6a3bSJan Kneschke MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 243bcdc6a3bSJan Kneschke (LPTSTR) &lpMsgBuf, 244bcdc6a3bSJan Kneschke 0, NULL); 245bcdc6a3bSJan Kneschke 246bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "sbs", "getprocaddress failed:", srv->tmp_buf, lpMsgBuf); 247bcdc6a3bSJan Kneschke 248bcdc6a3bSJan Kneschke plugin_free(p); 249bcdc6a3bSJan Kneschke return -1; 250bcdc6a3bSJan Kneschke } 251bcdc6a3bSJan Kneschke 252bcdc6a3bSJan Kneschke #else 2530ed6b729SJan Kneschke #if 1 2545a9992b1SStefan Bühler init = (int (*)(plugin *))(intptr_t)dlsym(p->lib, srv->tmp_buf->ptr); 2550ed6b729SJan Kneschke #else 256bcdc6a3bSJan Kneschke *(void **)(&init) = dlsym(p->lib, srv->tmp_buf->ptr); 2570ed6b729SJan Kneschke #endif 258eefb94bbSGlenn Strauss if (NULL == init) { 259eefb94bbSGlenn Strauss const char *error = dlerror(); 260eefb94bbSGlenn Strauss if (error != NULL) { 261eefb94bbSGlenn Strauss log_error_write(srv, __FILE__, __LINE__, "ss", "dlsym:", error); 262eefb94bbSGlenn Strauss } else { 263eefb94bbSGlenn Strauss log_error_write(srv, __FILE__, __LINE__, "ss", "dlsym symbol not found:", srv->tmp_buf->ptr); 264eefb94bbSGlenn Strauss } 265bcdc6a3bSJan Kneschke 266bcdc6a3bSJan Kneschke plugin_free(p); 267bcdc6a3bSJan Kneschke return -1; 268bcdc6a3bSJan Kneschke } 269bcdc6a3bSJan Kneschke 270bcdc6a3bSJan Kneschke #endif 271bcdc6a3bSJan Kneschke if ((*init)(p)) { 272b66fa2cbSStefan Bühler log_error_write(srv, __FILE__, __LINE__, "ss", module, "plugin init failed" ); 273bcdc6a3bSJan Kneschke 274bcdc6a3bSJan Kneschke plugin_free(p); 275bcdc6a3bSJan Kneschke return -1; 276bcdc6a3bSJan Kneschke } 277bcdc6a3bSJan Kneschke #if 0 278b66fa2cbSStefan Bühler log_error_write(srv, __FILE__, __LINE__, "ss", module, "plugin loaded" ); 279bcdc6a3bSJan Kneschke #endif 280bcdc6a3bSJan Kneschke plugins_register(srv, p); 281bcdc6a3bSJan Kneschke } 282bcdc6a3bSJan Kneschke 283bcdc6a3bSJan Kneschke return 0; 284bcdc6a3bSJan Kneschke } 285b66fa2cbSStefan Bühler #endif /* defined(LIGHTTPD_STATIC) */ 286bcdc6a3bSJan Kneschke 287bcdc6a3bSJan Kneschke #define PLUGIN_TO_SLOT(x, y) \ 288bcdc6a3bSJan Kneschke handler_t plugins_call_##y(server *srv, connection *con) {\ 28913f957d2SGlenn Strauss plugin ** const slot = ((plugin ***)(srv->plugin_slots))[x];\ 29062e97967SGlenn Strauss const uint32_t used = srv->plugins.used;\ 29113f957d2SGlenn Strauss handler_t rc = HANDLER_GO_ON;\ 29213f957d2SGlenn Strauss if (slot) {\ 29313f957d2SGlenn Strauss const plugin *p;\ 29462e97967SGlenn Strauss for (uint32_t i = 0; i < used && (p = slot[i]) && (rc = p->y(srv, con, p->data)) == HANDLER_GO_ON; ++i) ;\ 295bcdc6a3bSJan Kneschke }\ 29613f957d2SGlenn Strauss return rc;\ 297bcdc6a3bSJan Kneschke } 298bcdc6a3bSJan Kneschke 299bcdc6a3bSJan Kneschke /** 300bcdc6a3bSJan Kneschke * plugins that use 301bcdc6a3bSJan Kneschke * 302bcdc6a3bSJan Kneschke * - server *srv 303bcdc6a3bSJan Kneschke * - connection *con 304bcdc6a3bSJan Kneschke * - void *p_d (plugin_data *) 305bcdc6a3bSJan Kneschke */ 306bcdc6a3bSJan Kneschke 307bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean) 308bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw) 309cb7ed136SGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_ENV, handle_request_env) 310bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done) 311cb7ed136SGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_ACCEPT, handle_connection_accept) 312cb7ed136SGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_SHUT_WR, handle_connection_shut_wr) 313bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close) 314bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST, handle_subrequest) 315bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST_START, handle_subrequest_start) 316cb1a3c62SGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_RESPONSE_START, handle_response_start) 317bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_DOCROOT, handle_docroot) 3186adaad54SJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_PHYSICAL, handle_physical) 319bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_CONNECTION_RESET, connection_reset) 320bcdc6a3bSJan Kneschke 321bcdc6a3bSJan Kneschke #undef PLUGIN_TO_SLOT 322bcdc6a3bSJan Kneschke 323bcdc6a3bSJan Kneschke #define PLUGIN_TO_SLOT(x, y) \ 324bcdc6a3bSJan Kneschke handler_t plugins_call_##y(server *srv) {\ 32513f957d2SGlenn Strauss plugin ** const slot = ((plugin ***)(srv->plugin_slots))[x];\ 32662e97967SGlenn Strauss const uint32_t used = srv->plugins.used; \ 32713f957d2SGlenn Strauss handler_t rc = HANDLER_GO_ON;\ 32813f957d2SGlenn Strauss if (slot) {\ 32913f957d2SGlenn Strauss const plugin *p;\ 33062e97967SGlenn Strauss for (uint32_t i = 0; i < used && (p = slot[i]) && (rc = p->y(srv, p->data)) == HANDLER_GO_ON; ++i) ;\ 331bcdc6a3bSJan Kneschke }\ 33213f957d2SGlenn Strauss return rc;\ 333bcdc6a3bSJan Kneschke } 334bcdc6a3bSJan Kneschke 335bcdc6a3bSJan Kneschke /** 336bcdc6a3bSJan Kneschke * plugins that use 337bcdc6a3bSJan Kneschke * 338bcdc6a3bSJan Kneschke * - server *srv 339bcdc6a3bSJan Kneschke * - void *p_d (plugin_data *) 340bcdc6a3bSJan Kneschke */ 341bcdc6a3bSJan Kneschke 342bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger) 343bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup) 344bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup) 345bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults) 346f1e9bcb0SGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_WORKER_INIT, worker_init) 347bcdc6a3bSJan Kneschke 348bcdc6a3bSJan Kneschke #undef PLUGIN_TO_SLOT 349bcdc6a3bSJan Kneschke 3509030cfaeSGlenn Strauss handler_t plugins_call_handle_waitpid(server *srv, pid_t pid, int status) { 3519030cfaeSGlenn Strauss plugin ** const slot = 3529030cfaeSGlenn Strauss ((plugin ***)(srv->plugin_slots))[PLUGIN_FUNC_HANDLE_WAITPID]; 3539030cfaeSGlenn Strauss if (!slot) return HANDLER_GO_ON; 35462e97967SGlenn Strauss for (uint32_t i = 0; i < srv->plugins.used && slot[i]; ++i) { 3559030cfaeSGlenn Strauss plugin *p = slot[i]; 3569030cfaeSGlenn Strauss handler_t r = p->handle_waitpid(srv, p->data, pid, status); 3579030cfaeSGlenn Strauss if (r != HANDLER_GO_ON) return r; 3589030cfaeSGlenn Strauss } 3599030cfaeSGlenn Strauss return HANDLER_GO_ON; 3609030cfaeSGlenn Strauss } 3619030cfaeSGlenn Strauss 362bcdc6a3bSJan Kneschke #if 0 363bcdc6a3bSJan Kneschke /** 364bcdc6a3bSJan Kneschke * 365bcdc6a3bSJan Kneschke * special handler 366bcdc6a3bSJan Kneschke * 367bcdc6a3bSJan Kneschke */ 368bcdc6a3bSJan Kneschke handler_t plugins_call_handle_fdevent(server *srv, const fd_conn *fdc) { 36962e97967SGlenn Strauss plugin ** const ps = srv->plugins.ptr; 37062e97967SGlenn Strauss for (uint32_t i = 0; i < srv->plugins.used; ++i) { 371bcdc6a3bSJan Kneschke plugin *p = ps[i]; 372bcdc6a3bSJan Kneschke if (p->handle_fdevent) { 373bcdc6a3bSJan Kneschke handler_t r; 374bcdc6a3bSJan Kneschke switch(r = p->handle_fdevent(srv, fdc, p->data)) { 375bcdc6a3bSJan Kneschke case HANDLER_GO_ON: 376bcdc6a3bSJan Kneschke break; 377bcdc6a3bSJan Kneschke case HANDLER_FINISHED: 378bcdc6a3bSJan Kneschke case HANDLER_COMEBACK: 379bcdc6a3bSJan Kneschke case HANDLER_WAIT_FOR_EVENT: 380bcdc6a3bSJan Kneschke case HANDLER_ERROR: 381bcdc6a3bSJan Kneschke return r; 382bcdc6a3bSJan Kneschke default: 383bcdc6a3bSJan Kneschke log_error_write(srv, __FILE__, __LINE__, "d", r); 384bcdc6a3bSJan Kneschke break; 385bcdc6a3bSJan Kneschke } 386bcdc6a3bSJan Kneschke } 387bcdc6a3bSJan Kneschke } 388bcdc6a3bSJan Kneschke 389bcdc6a3bSJan Kneschke return HANDLER_GO_ON; 390bcdc6a3bSJan Kneschke } 391bcdc6a3bSJan Kneschke #endif 392bcdc6a3bSJan Kneschke /** 393bcdc6a3bSJan Kneschke * 394bcdc6a3bSJan Kneschke * - call init function of all plugins to init the plugin-internals 395bcdc6a3bSJan Kneschke * - added each plugin that supports has callback to the corresponding slot 396bcdc6a3bSJan Kneschke * 397bcdc6a3bSJan Kneschke * - is only called once. 398bcdc6a3bSJan Kneschke */ 399bcdc6a3bSJan Kneschke 400bcdc6a3bSJan Kneschke handler_t plugins_call_init(server *srv) { 40162e97967SGlenn Strauss plugin ** const ps = srv->plugins.ptr; 402bcdc6a3bSJan Kneschke 403bcdc6a3bSJan Kneschke /* fill slots */ 404bcdc6a3bSJan Kneschke 405bcdc6a3bSJan Kneschke srv->plugin_slots = calloc(PLUGIN_FUNC_SIZEOF, sizeof(ps)); 406566cf8deSStefan Bühler force_assert(NULL != srv->plugin_slots); 407bcdc6a3bSJan Kneschke 40862e97967SGlenn Strauss for (uint32_t i = 0; i < srv->plugins.used; ++i) { 409bcdc6a3bSJan Kneschke /* check which calls are supported */ 410bcdc6a3bSJan Kneschke 411bcdc6a3bSJan Kneschke plugin *p = ps[i]; 412bcdc6a3bSJan Kneschke 413bcdc6a3bSJan Kneschke #define PLUGIN_TO_SLOT(x, y) \ 414bcdc6a3bSJan Kneschke if (p->y) { \ 415bcdc6a3bSJan Kneschke plugin **slot = ((plugin ***)(srv->plugin_slots))[x]; \ 416bcdc6a3bSJan Kneschke if (!slot) { \ 417bcdc6a3bSJan Kneschke slot = calloc(srv->plugins.used, sizeof(*slot));\ 418566cf8deSStefan Bühler force_assert(NULL != slot); \ 419bcdc6a3bSJan Kneschke ((plugin ***)(srv->plugin_slots))[x] = slot; \ 420bcdc6a3bSJan Kneschke } \ 42162e97967SGlenn Strauss for (uint32_t j = 0; j < srv->plugins.used; ++j) { \ 422bcdc6a3bSJan Kneschke if (slot[j]) continue;\ 423bcdc6a3bSJan Kneschke slot[j] = p;\ 424bcdc6a3bSJan Kneschke break;\ 425bcdc6a3bSJan Kneschke }\ 426bcdc6a3bSJan Kneschke } 427bcdc6a3bSJan Kneschke 428bcdc6a3bSJan Kneschke 429bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean); 430bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw); 431cb7ed136SGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_ENV, handle_request_env); 432bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done); 433cb7ed136SGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_ACCEPT, handle_connection_accept); 434cb7ed136SGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_SHUT_WR, handle_connection_shut_wr); 435bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close); 436bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger); 437bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup); 4389030cfaeSGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_WAITPID, handle_waitpid); 439bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST, handle_subrequest); 440bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SUBREQUEST_START, handle_subrequest_start); 441cb1a3c62SGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_RESPONSE_START, handle_response_start); 442bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_DOCROOT, handle_docroot); 4436adaad54SJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_PHYSICAL, handle_physical); 444bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_CONNECTION_RESET, connection_reset); 445bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup); 446bcdc6a3bSJan Kneschke PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults); 447f1e9bcb0SGlenn Strauss PLUGIN_TO_SLOT(PLUGIN_FUNC_WORKER_INIT, worker_init); 448bcdc6a3bSJan Kneschke #undef PLUGIN_TO_SLOT 449bcdc6a3bSJan Kneschke 450bcdc6a3bSJan Kneschke if (p->init) { 451bcdc6a3bSJan Kneschke if (NULL == (p->data = p->init())) { 452*e2de4e58SGlenn Strauss log_error_write(srv, __FILE__, __LINE__, "ss", 453bcdc6a3bSJan Kneschke "plugin-init failed for module", p->name); 454bcdc6a3bSJan Kneschke return HANDLER_ERROR; 455bcdc6a3bSJan Kneschke } 456bcdc6a3bSJan Kneschke 457bcdc6a3bSJan Kneschke /* used for con->mode, DIRECT == 0, plugins above that */ 458bcdc6a3bSJan Kneschke ((plugin_data *)(p->data))->id = i + 1; 459bcdc6a3bSJan Kneschke 460bcdc6a3bSJan Kneschke if (p->version != LIGHTTPD_VERSION_ID) { 461*e2de4e58SGlenn Strauss log_error_write(srv, __FILE__, __LINE__, "ss", 462bcdc6a3bSJan Kneschke "plugin-version doesn't match lighttpd-version for", p->name); 463bcdc6a3bSJan Kneschke return HANDLER_ERROR; 464bcdc6a3bSJan Kneschke } 465bcdc6a3bSJan Kneschke } 4668af9e71cSGlenn Strauss 4678af9e71cSGlenn Strauss if (p->priv_defaults && HANDLER_ERROR==p->priv_defaults(srv, p->data)) { 4688af9e71cSGlenn Strauss return HANDLER_ERROR; 4698af9e71cSGlenn Strauss } 470bcdc6a3bSJan Kneschke } 471bcdc6a3bSJan Kneschke 472bcdc6a3bSJan Kneschke return HANDLER_GO_ON; 473bcdc6a3bSJan Kneschke } 474bcdc6a3bSJan Kneschke 475bcdc6a3bSJan Kneschke void plugins_free(server *srv) { 47662e97967SGlenn Strauss if (srv->plugin_slots) { 47762e97967SGlenn Strauss plugins_call_cleanup(srv); 47862e97967SGlenn Strauss for (int i = 0; i < PLUGIN_FUNC_SIZEOF; ++i) { 47962e97967SGlenn Strauss plugin **slot = ((plugin ***)(srv->plugin_slots))[i]; 48062e97967SGlenn Strauss if (slot) free(slot); 48162e97967SGlenn Strauss } 48262e97967SGlenn Strauss free(srv->plugin_slots); 48362e97967SGlenn Strauss srv->plugin_slots = NULL; 48462e97967SGlenn Strauss } 485bcdc6a3bSJan Kneschke 48662e97967SGlenn Strauss for (uint32_t i = 0; i < srv->plugins.used; ++i) { 487bcdc6a3bSJan Kneschke plugin *p = ((plugin **)srv->plugins.ptr)[i]; 488bcdc6a3bSJan Kneschke 489bcdc6a3bSJan Kneschke plugin_free(p); 490bcdc6a3bSJan Kneschke } 491bcdc6a3bSJan Kneschke free(srv->plugins.ptr); 492bcdc6a3bSJan Kneschke srv->plugins.ptr = NULL; 493b37a9585SmOo srv->plugins.used = 0; 49462e97967SGlenn Strauss srv->plugins.size = 0; 495bcdc6a3bSJan Kneschke } 496