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
->name
= mk_plugin_load_symbol(handler
, "_name");
143 p
->version
= mk_plugin_load_symbol(handler
, "_version");
144 p
->path
= mk_string_dup(path
);
145 p
->handler
= handler
;
146 p
->stages
= (mk_plugin_stage_t
*) mk_plugin_load_symbol(handler
, "_stages");
148 /* Plugin external function */
149 p
->call_init
= (int (*)()) mk_plugin_load_symbol(handler
,
152 p
->call_worker_init
= (int (*)()) mk_plugin_load_symbol(handler
,
153 "_mk_plugin_worker_init");
155 p
->call_stage_10
= (int (*)())
156 mk_plugin_load_symbol(handler
, "_mk_plugin_stage_00");
158 p
->call_stage_10
= (int (*)())
159 mk_plugin_load_symbol(handler
, "_mk_plugin_stage_10");
161 p
->call_stage_20
= (int (*)())
162 mk_plugin_load_symbol(handler
, "_mk_plugin_stage_20");
164 p
->call_stage_30
= (int (*)())
165 mk_plugin_load_symbol(handler
, "_mk_plugin_stage_30");
167 p
->call_stage_40
= (int (*)())
168 mk_plugin_load_symbol(handler
, "_mk_plugin_stage_40");
172 if(!p
->name
|| !p
->version
|| !p
->stages
){
177 mk_plugin_register_stages(p
);
181 void mk_plugin_init()
186 struct plugin_api
*api
;
187 struct plugin_list
*plist
;
188 struct mk_config
*cnf
;
190 api
= mk_mem_malloc_z(sizeof(struct plugin_api
));
192 /* Setup and connections list */
193 api
->config
= config
;
194 api
->sched_list
= &sched_list
;
196 /* API plugins funcions */
197 api
->mem_alloc
= (void *) mk_mem_malloc
;
198 api
->mem_alloc_z
= (void *) mk_mem_malloc_z
;
199 api
->mem_free
= (void *) mk_mem_free
;
200 api
->str_build
= (void *) m_build_buffer
;
201 api
->str_dup
= (void *) mk_string_dup
;
202 api
->str_search
= (void *) mk_string_search
;
203 api
->str_search_n
= (void *) mk_string_search_n
;
204 api
->str_copy_substr
= (void *) mk_string_copy_substr
;
205 api
->str_split_line
= (void *) mk_string_split_line
;
206 api
->file_to_buffer
= (void *) mk_file_to_buffer
;
207 api
->file_get_info
= (void *) mk_file_get_info
;
208 api
->header_send
= (void *) mk_header_send
;
209 api
->iov_create
= (void *) mk_iov_create
;
210 api
->iov_free
= (void *) mk_iov_free
;
211 api
->iov_add_entry
= (void *) mk_iov_add_entry
;
212 api
->iov_set_entry
= (void *) mk_iov_set_entry
;
213 api
->iov_send
= (void *) mk_iov_send
;
214 api
->iov_print
= (void *) mk_iov_print
;
215 api
->pointer_set
= (void *) mk_pointer_set
;
216 api
->pointer_print
= (void *) mk_pointer_print
;
217 api
->plugin_load_symbol
= (void *) mk_plugin_load_symbol
;
218 api
->socket_cork_flag
= (void *) mk_socket_set_cork_flag
;
219 api
->socket_connect
= (void *) mk_socket_connect
;
220 api
->socket_set_tcp_nodelay
= (void *) mk_socket_set_tcp_nodelay
;
221 api
->socket_create
= (void *) mk_socket_create
;
222 api
->config_create
= (void *) mk_config_create
;
223 api
->config_free
= (void *) mk_config_free
;
224 api
->config_getval
= (void *) mk_config_getval
;
225 api
->sched_get_connection
= (void *) mk_sched_get_connection
;
227 path
= mk_mem_malloc_z(1024);
228 snprintf(path
, 1024, "%s/%s", config
->serverconf
, MK_PLUGIN_LOAD
);
230 /* Read configuration file */
231 cnf
= mk_config_create(path
);
234 if(strcasecmp(cnf
->key
, "LoadPlugin") == 0){
235 handle
= mk_plugin_load(cnf
->val
);
236 p
= mk_plugin_register(handle
, cnf
->val
);
238 fprintf(stderr
, "Plugin error: %s", cnf
->val
);
249 api
->plugins
= plg_list
;
254 int mk_plugin_stage_run(mk_plugin_stage_t stage
,
256 struct sched_connection
*conx
,
257 struct client_request
*cr
,
263 if(stage
& MK_PLUGIN_STAGE_10
){
264 p
= config
->plugins
->stage_10
;
270 if(stage
& MK_PLUGIN_STAGE_20
){
271 p
= config
->plugins
->stage_20
;
273 ret
= p
->call_stage_20(socket
, conx
, cr
);
275 case MK_PLUGIN_RET_CLOSE_CONX
:
276 return MK_PLUGIN_RET_CLOSE_CONX
;
283 if(stage
& MK_PLUGIN_STAGE_30
){
284 p
= config
->plugins
->stage_30
;
286 ret
= p
->call_stage_30(cr
, sr
);
288 case MK_PLUGIN_RET_CLOSE_CONX
:
289 return MK_PLUGIN_RET_CLOSE_CONX
;
296 if(stage
& MK_PLUGIN_STAGE_40
){
297 p
= config
->plugins
->stage_40
;
299 ret
= p
->call_stage_40(cr
, sr
);
310 /* This function is called by every created worker
311 * for plugins which need to set some data under a thread
314 void mk_plugin_worker_startup()
316 struct plugin_list
*plg
;
321 if(plg
->p
->call_worker_init
){
322 plg
->p
->call_worker_init();