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