1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
5 * Copyright (C) 2001-2008, Eduardo Silva P.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include <sys/types.h>
35 #include "scheduler.h"
43 void *mk_plugin_load(char *path
)
47 handle
= dlopen(path
, RTLD_LAZY
);
49 fprintf(stderr
, "Error during dlopen(): %s\n", dlerror());
55 void *mk_plugin_load_symbol(void *handler
, const char *symbol
)
61 s
= dlsym(handler
, symbol
);
62 if((err
= dlerror()) != NULL
){
69 void mk_plugin_register_add_to_stage(struct plugin
**st
, struct plugin
*p
)
87 void mk_plugin_register_stages(struct plugin
*p
)
89 struct plugin_list
*new, *list
;
91 /* Main plugin list */
92 new = mk_mem_malloc(sizeof(struct plugin_list
));
107 /* Assign plugin to stages */
108 if(*p
->stages
& MK_PLUGIN_STAGE_00
){
109 mk_plugin_register_add_to_stage(&config
->plugins
->stage_00
, p
);
112 if(*p
->stages
& MK_PLUGIN_STAGE_10
){
113 mk_plugin_register_add_to_stage(&config
->plugins
->stage_10
, p
);
116 if(*p
->stages
& MK_PLUGIN_STAGE_20
){
117 mk_plugin_register_add_to_stage(&config
->plugins
->stage_20
, p
);
120 if(*p
->stages
& MK_PLUGIN_STAGE_30
){
121 mk_plugin_register_add_to_stage(&config
->plugins
->stage_30
, p
);
124 if(*p
->stages
& MK_PLUGIN_STAGE_40
){
125 mk_plugin_register_add_to_stage(&config
->plugins
->stage_40
, p
);
128 if(*p
->stages
& MK_PLUGIN_STAGE_50
){
129 mk_plugin_register_add_to_stage(&config
->plugins
->stage_50
, p
);
132 if(*p
->stages
& MK_PLUGIN_STAGE_60
){
133 mk_plugin_register_add_to_stage(&config
->plugins
->stage_60
, p
);
137 void *mk_plugin_register(void *handler
, char *path
)
141 p
= mk_mem_malloc_z(sizeof(struct plugin
));
142 p
->shortname
= mk_plugin_load_symbol(handler
, "_shortname");
143 p
->name
= mk_plugin_load_symbol(handler
, "_name");
144 p
->version
= mk_plugin_load_symbol(handler
, "_version");
145 p
->path
= mk_string_dup(path
);
146 p
->handler
= handler
;
147 p
->stages
= (mk_plugin_stage_t
*) mk_plugin_load_symbol(handler
, "_stages");
149 /* Plugin external function */
150 p
->call_init
= (int (*)()) mk_plugin_load_symbol(handler
,
153 p
->call_worker_init
= (int (*)()) mk_plugin_load_symbol(handler
,
154 "_mk_plugin_worker_init");
156 p
->call_stage_10
= (int (*)())
157 mk_plugin_load_symbol(handler
, "_mk_plugin_stage_00");
159 p
->call_stage_10
= (int (*)())
160 mk_plugin_load_symbol(handler
, "_mk_plugin_stage_10");
162 p
->call_stage_20
= (int (*)())
163 mk_plugin_load_symbol(handler
, "_mk_plugin_stage_20");
165 p
->call_stage_30
= (int (*)())
166 mk_plugin_load_symbol(handler
, "_mk_plugin_stage_30");
168 p
->call_stage_40
= (int (*)())
169 mk_plugin_load_symbol(handler
, "_mk_plugin_stage_40");
173 if(!p
->name
|| !p
->version
|| !p
->stages
){
178 mk_plugin_register_stages(p
);
182 void mk_plugin_init()
187 struct plugin_api
*api
;
188 struct plugin_list
*plist
;
189 struct mk_config
*cnf
;
191 api
= mk_mem_malloc_z(sizeof(struct plugin_api
));
193 /* Setup and connections list */
194 api
->config
= config
;
195 api
->sched_list
= &sched_list
;
197 /* API plugins funcions */
198 api
->mem_alloc
= (void *) mk_mem_malloc
;
199 api
->mem_alloc_z
= (void *) mk_mem_malloc_z
;
200 api
->mem_free
= (void *) mk_mem_free
;
201 api
->str_build
= (void *) m_build_buffer
;
202 api
->str_dup
= (void *) mk_string_dup
;
203 api
->str_search
= (void *) mk_string_search
;
204 api
->str_search_n
= (void *) mk_string_search_n
;
205 api
->str_copy_substr
= (void *) mk_string_copy_substr
;
206 api
->str_split_line
= (void *) mk_string_split_line
;
207 api
->file_to_buffer
= (void *) mk_file_to_buffer
;
208 api
->file_get_info
= (void *) mk_file_get_info
;
209 api
->header_send
= (void *) mk_header_send
;
210 api
->iov_create
= (void *) mk_iov_create
;
211 api
->iov_free
= (void *) mk_iov_free
;
212 api
->iov_add_entry
= (void *) mk_iov_add_entry
;
213 api
->iov_set_entry
= (void *) mk_iov_set_entry
;
214 api
->iov_send
= (void *) mk_iov_send
;
215 api
->iov_print
= (void *) mk_iov_print
;
216 api
->pointer_set
= (void *) mk_pointer_set
;
217 api
->pointer_print
= (void *) mk_pointer_print
;
218 api
->plugin_load_symbol
= (void *) mk_plugin_load_symbol
;
219 api
->socket_cork_flag
= (void *) mk_socket_set_cork_flag
;
220 api
->socket_connect
= (void *) mk_socket_connect
;
221 api
->socket_set_tcp_nodelay
= (void *) mk_socket_set_tcp_nodelay
;
222 api
->socket_create
= (void *) mk_socket_create
;
223 api
->config_create
= (void *) mk_config_create
;
224 api
->config_free
= (void *) mk_config_free
;
225 api
->config_getval
= (void *) mk_config_getval
;
226 api
->sched_get_connection
= (void *) mk_sched_get_connection
;
228 path
= mk_mem_malloc_z(1024);
229 snprintf(path
, 1024, "%s/%s", config
->serverconf
, MK_PLUGIN_LOAD
);
231 /* Read configuration file */
232 cnf
= mk_config_create(path
);
235 if(strcasecmp(cnf
->key
, "LoadPlugin") == 0){
236 handle
= mk_plugin_load(cnf
->val
);
237 p
= mk_plugin_register(handle
, cnf
->val
);
239 fprintf(stderr
, "Plugin error: %s", cnf
->val
);
243 char *plugin_confdir
= 0;
246 m_build_buffer(&plugin_confdir
,
252 p
->call_init(&api
, plugin_confdir
);
258 api
->plugins
= plg_list
;
263 int mk_plugin_stage_run(mk_plugin_stage_t stage
,
265 struct sched_connection
*conx
,
266 struct client_request
*cr
,
272 if(stage
& MK_PLUGIN_STAGE_10
){
273 p
= config
->plugins
->stage_10
;
279 if(stage
& MK_PLUGIN_STAGE_20
){
280 p
= config
->plugins
->stage_20
;
282 ret
= p
->call_stage_20(socket
, conx
, cr
);
284 case MK_PLUGIN_RET_CLOSE_CONX
:
285 return MK_PLUGIN_RET_CLOSE_CONX
;
292 if(stage
& MK_PLUGIN_STAGE_30
){
293 p
= config
->plugins
->stage_30
;
295 ret
= p
->call_stage_30(cr
, sr
);
297 case MK_PLUGIN_RET_CLOSE_CONX
:
298 return MK_PLUGIN_RET_CLOSE_CONX
;
305 if(stage
& MK_PLUGIN_STAGE_40
){
306 p
= config
->plugins
->stage_40
;
308 ret
= p
->call_stage_40(cr
, sr
);
319 /* This function is called by every created worker
320 * for plugins which need to set some data under a thread
323 void mk_plugin_worker_startup()
325 struct plugin_list
*plg
;
330 if(plg
->p
->call_worker_init
){
331 plg
->p
->call_worker_init();