Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,2000 +0,0 @@
1
-/*
2
- * Copyright (C) 2001-2003 FhG Fokus
3
- *
4
- * This file is part of Kamailio, a free SIP server.
5
- *
6
- * Kamailio is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * Kamailio is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
- */
20
-
21
-/**
22
- * @file
23
- * @brief Kamailio core :: modules loading, structures declarations and utilities
24
- * @ingroup core
25
- * Module: \ref core
26
- */
27
-
28
-
29
-#include "sr_module.h"
30
-#include "mod_fix.h"
31
-#include "dprint.h"
32
-#include "error.h"
33
-#include "mem/mem.h"
34
-#include "core_cmd.h"
35
-#include "ut.h"
36
-#include "re.h"
37
-#include "route_struct.h"
38
-#include "flags.h"
39
-#include "trim.h"
40
-#include "pvapi.h"
41
-#include "globals.h"
42
-#include "rpc_lookup.h"
43
-#include "sr_compat.h"
44
-#include "ppcfg.h"
45
-#include "async_task.h"
46
-
47
-#include <sys/stat.h>
48
-#include <regex.h>
49
-#include <dlfcn.h>
50
-#include <strings.h>
51
-#include <stdlib.h>
52
-#include <string.h>
53
-#include <stddef.h> /* for offsetof */
54
-
55
-
56
-struct sr_module* modules=0;
57
-
58
-/*We need to define this symbol on Solaris becuase libcurl relies on libnspr which looks for this symbol.
59
-  If it is not defined, dynamic module loading (dlsym) fails */
60
-#ifdef __OS_solaris
61
-	int nspr_use_zone_allocator = 0;
62
-#endif
63
-
64
-
65
-#ifdef STATIC_EXEC
66
-	extern struct module_exports exec_exports;
67
-#endif
68
-#ifdef STATIC_TM
69
-	extern struct module_exports tm_exports;
70
-#endif
71
-
72
-#ifdef STATIC_MAXFWD
73
-	extern struct module_exports maxfwd_exports;
74
-#endif
75
-
76
-#ifdef STATIC_AUTH
77
-	extern struct module_exports auth_exports;
78
-#endif
79
-
80
-#ifdef STATIC_RR
81
-	extern struct module_exports rr_exports;
82
-#endif
83
-
84
-#ifdef STATIC_USRLOC
85
-	extern struct module_exports usrloc_exports;
86
-#endif
87
-
88
-#ifdef STATIC_SL
89
-	extern struct module_exports sl_exports;
90
-#endif
91
-
92
-#ifndef offsetof
93
-#warning "use null pointer dereference for offsetof"
94
-#define offsetof(st, m) \
95
-		((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
96
-#endif
97
-
98
-int mod_response_cbk_no=0;
99
-response_function* mod_response_cbks=0;
100
-
101
-/* number of usec to wait before initializing a module */
102
-static unsigned int modinit_delay = 0;
103
-
104
-unsigned int set_modinit_delay(unsigned int v)
105
-{
106
-	unsigned int r;
107
-	r =  modinit_delay;
108
-	modinit_delay = v;
109
-	return r;
110
-}
111
-
112
-/* keep state if server is in destroy modules phase */
113
-static int _sr_destroy_modules_phase = 0;
114
-
115
-/**
116
- * return destroy modules phase state
117
- */
118
-int destroy_modules_phase(void)
119
-{
120
-	return _sr_destroy_modules_phase;
121
-}
122
-
123
-/**
124
- * if bit 1 set, SIP worker processes handle RPC commands as well
125
- * if bit 2 set, RPC worker processes handle SIP commands as well
126
- */
127
-static int child_sip_rpc_mode = 0;
128
-
129
-#define CHILD_SIP_RPC	1<<0
130
-#define CHILD_RPC_SIP	1<<1
131
-
132
-void set_child_sip_rpc_mode(void)
133
-{
134
-	child_sip_rpc_mode |= CHILD_SIP_RPC;
135
-}
136
-
137
-void set_child_rpc_sip_mode(void)
138
-{
139
-	child_sip_rpc_mode |= CHILD_RPC_SIP;
140
-}
141
-
142
-int is_rpc_worker(int rank)
143
-{
144
-	if(rank==PROC_RPC
145
-			|| (rank>PROC_MAIN && (child_sip_rpc_mode&CHILD_SIP_RPC)!=0))
146
-		return 1;
147
-	return 0;
148
-}
149
-
150
-int is_sip_worker(int rank)
151
-{
152
-	if(rank>PROC_MAIN
153
-			|| ((rank==PROC_RPC || rank==PROC_NOCHLDINIT)
154
-					&& (child_sip_rpc_mode&CHILD_RPC_SIP)!=0))
155
-		return 1;
156
-	return 0;
157
-}
158
-
159
-/* initializes statically built (compiled in) modules*/
160
-int register_builtin_modules()
161
-{
162
-	int ret;
163
-
164
-	ret=0;
165
-#ifdef STATIC_TM
166
-	ret=register_module(MODULE_INTERFACE_VER, &tm_exports,"built-in", 0);
167
-	if (ret<0) return ret;
168
-#endif
169
-
170
-#ifdef STATIC_EXEC
171
-	ret=register_module(MODULE_INTERFACE_VER, &exec_exports,"built-in", 0);
172
-	if (ret<0) return ret;
173
-#endif
174
-
175
-#ifdef STATIC_MAXFWD
176
-	ret=register_module(MODULE_INTERFACE_VER, &maxfwd_exports, "built-in", 0);
177
-	if (ret<0) return ret;
178
-#endif
179
-
180
-#ifdef STATIC_AUTH
181
-	ret=register_module(MODULE_INTERFACE_VER, &auth_exports, "built-in", 0);
182
-	if (ret<0) return ret;
183
-#endif
184
-
185
-#ifdef STATIC_RR
186
-	ret=register_module(MODULE_INTERFACE_VER, &rr_exports, "built-in", 0);
187
-	if (ret<0) return ret;
188
-#endif
189
-
190
-#ifdef STATIC_USRLOC
191
-	ret=register_module(MODULE_INTERFACE_VER, &usrloc_exports, "built-in", 0);
192
-	if (ret<0) return ret;
193
-#endif
194
-
195
-#ifdef STATIC_SL
196
-	ret=register_module(MODULE_INTERFACE_VER, &sl_exports, "built-in", 0);
197
-	if (ret<0) return ret;
198
-#endif
199
-
200
-	return ret;
201
-}
202
-
203
-
204
-
205
-/** convert cmd exports to current format.
206
- * @param ver - module interface versions (0 == ser, 1 == kam).
207
- * @param src - null terminated array of cmd exports
208
- *              (either ser_cmd_export_t or kam_cmd_export_t, depending
209
- *               on ver).
210
- * @param mod - pointer to module exports structure.
211
- * @return - pkg_malloc'ed null terminated sr_cmd_export_v31_t array with
212
- *           the converted cmd exports  or 0 on error.
213
- */
214
-static sr31_cmd_export_t* sr_cmd_exports_convert(unsigned ver,
215
-													void* src, void* mod)
216
-{
217
-	int i, n;
218
-	ser_cmd_export_t* ser_cmd;
219
-	kam_cmd_export_t* kam_cmd;
220
-	sr31_cmd_export_t* ret;
221
-
222
-	ser_cmd = 0;
223
-	kam_cmd = 0;
224
-	ret = 0;
225
-	n = 0;
226
-	/* count the number of elements */
227
-	if (ver == 0) {
228
-		ser_cmd = src;
229
-		for (; ser_cmd[n].name; n++);
230
-	} else if (ver == 1) {
231
-		kam_cmd = src;
232
-		for (; kam_cmd[n].name; n++);
233
-	} else goto error; /* unknown interface version */
234
-	/* alloc & init new array */
235
-	ret = pkg_malloc(sizeof(*ret)*(n+1));
236
-	memset(ret, 0, sizeof(*ret)*(n+1));
237
-	/* convert/copy */
238
-	for (i=0; i < n; i++) {
239
-		if (ver == 0) {
240
-			ret[i].name = ser_cmd[i].name;
241
-			ret[i].function = ser_cmd[i].function;
242
-			ret[i].param_no = ser_cmd[i].param_no;
243
-			ret[i].fixup = ser_cmd[i].fixup;
244
-			ret[i].free_fixup = 0; /* no present in ser  <= 2.1 */
245
-			ret[i].flags = ser_cmd[i].flags;
246
-		} else {
247
-			ret[i].name = kam_cmd[i].name;
248
-			ret[i].function = kam_cmd[i].function;
249
-			ret[i].param_no = kam_cmd[i].param_no;
250
-			ret[i].fixup = kam_cmd[i].fixup;
251
-			ret[i].free_fixup = kam_cmd[i].free_fixup;
252
-			ret[i].flags = kam_cmd[i].flags;
253
-		}
254
-		/* 3.1+ specific stuff */
255
-		ret[i].fixup_flags = 0;
256
-		ret[i].module_exports = mod;
257
-		/* fill known free fixups */
258
-		if (ret[i].fixup && ret[i].free_fixup == 0)
259
-			ret[i].free_fixup = get_fixup_free(ret[i].fixup);
260
-	}
261
-	return ret;
262
-error:
263
-	return 0;
264
-}
265
-
266
-
267
-
268
-/* registers a module,  register_f= module register  functions
269
- * returns <0 on error, 0 on success */
270
-static int register_module(unsigned ver, union module_exports_u* e,
271
-					char* path, void* handle)
272
-{
273
-	int ret, i;
274
-	struct sr_module* mod;
275
-	char defmod[64];
276
-
277
-	ret=-1;
278
-
279
-	/* add module to the list */
280
-	if ((mod=pkg_malloc(sizeof(struct sr_module)))==0){
281
-		LM_ERR("memory allocation failure\n");
282
-		ret=E_OUT_OF_MEM;
283
-		goto error;
284
-	}
285
-	memset(mod,0, sizeof(struct sr_module));
286
-	mod->path=path;
287
-	mod->handle=handle;
288
-	mod->orig_mod_interface_ver=ver;
289
-	/* convert exports to sr31 format */
290
-	if (ver == 0) {
291
-		/* ser <= 3.0 */
292
-		mod->exports.name = e->v0.name;
293
-		if (e->v0.cmds) {
294
-			mod->exports.cmds = sr_cmd_exports_convert(ver, e->v0.cmds, mod);
295
-			if (mod->exports.cmds == 0) {
296
-				LM_ERR("failed to convert module command exports to 3.1 format"
297
-						" for module \"%s\" (%s), interface version %d\n",
298
-						mod->exports.name, mod->path, ver);
299
-				ret = E_UNSPEC;
300
-				goto error;
301
-			}
302
-		}
303
-		mod->exports.params = e->v0.params;
304
-		mod->exports.init_f = e->v0.init_f;
305
-		mod->exports.response_f = e->v0.response_f;
306
-		mod->exports.destroy_f = e->v0.destroy_f;
307
-		mod->exports.onbreak_f = e->v0.onbreak_f;
308
-		mod->exports.init_child_f = e->v0.init_child_f;
309
-		mod->exports.dlflags = 0; /* not used in ser <= 3.0 */
310
-		mod->exports.rpc_methods = e->v0.rpc_methods;
311
-		/* the rest are 0, not used in ser */
312
-	} else if (ver == 1) {
313
-		/* kamailio <= 3.0 */
314
-		mod->exports.name = e->v1.name;
315
-		if (e->v1.cmds) {
316
-			mod->exports.cmds = sr_cmd_exports_convert(ver, e->v1.cmds, mod);
317
-			if (mod->exports.cmds == 0) {
318
-				LM_ERR("failed to convert module command exports to 3.1 format"
319
-						" for module \"%s\" (%s), interface version %d\n",
320
-						mod->exports.name, mod->path, ver);
321
-				ret = E_UNSPEC;
322
-				goto error;
323
-			}
324
-		}
325
-		mod->exports.params = e->v1.params;
326
-		mod->exports.init_f = e->v1.init_f;
327
-		mod->exports.response_f = e->v1.response_f;
328
-		mod->exports.destroy_f = e->v1.destroy_f;
329
-		mod->exports.onbreak_f = 0; /* not used in k <= 3.0 */
330
-		mod->exports.init_child_f = e->v1.init_child_f;
331
-		mod->exports.dlflags = e->v1.dlflags;
332
-		mod->exports.rpc_methods = 0; /* not used in k <= 3.0 */
333
-		mod->exports.stats = e->v1.stats;
334
-		mod->exports.mi_cmds = e->v1.mi_cmds;
335
-		mod->exports.items = e->v1.items;
336
-		mod->exports.procs = e->v1.procs;
337
-	} else {
338
-		LM_ERR("unsupported module interface version %d\n", ver);
339
-		ret = E_UNSPEC;
340
-		goto error;
341
-	}
342
-
343
-	if (mod->exports.items) {
344
-		/* register module pseudo-variables for kamailio modules */
345
-		LM_DBG("register PV from: %s\n", mod->exports.name);
346
-		if (register_pvars_mod(mod->exports.name, mod->exports.items)!=0) {
347
-			LM_ERR("failed to register pseudo-variables for module %s (%s)\n",
348
-				mod->exports.name, path);
349
-			ret = E_UNSPEC;
350
-			goto error;
351
-		}
352
-	}
353
-	if (mod->exports.rpc_methods){
354
-		/* register rpcs for ser modules */
355
-		i=rpc_register_array(mod->exports.rpc_methods);
356
-		if (i<0){
357
-			LM_ERR("failed to register RPCs for module %s (%s)\n",
358
-					mod->exports.name, path);
359
-			ret = E_UNSPEC;
360
-			goto error;
361
-		}else if (i>0){
362
-			LM_ERR("%d duplicate RPCs name detected while registering RPCs"
363
-					" declared in module %s (%s)\n",
364
-					i, mod->exports.name, path);
365
-			ret = E_UNSPEC;
366
-			goto error;
367
-		}
368
-		/* i==0 => success */
369
-	}
370
-
371
-	/* add cfg define for each module: MOD_modulename */
372
-	if(strlen(mod->exports.name)>=60) {
373
-		LM_ERR("too long module name: %s\n", mod->exports.name);
374
-		goto error;
375
-	}
376
-	strcpy(defmod, "MOD_");
377
-	strcat(defmod, mod->exports.name);
378
-	pp_define_set_type(0);
379
-	if(pp_define(strlen(defmod), defmod)<0) {
380
-		LM_ERR("unable to set cfg define for module: %s\n",
381
-				mod->exports.name);
382
-		goto error;
383
-	}
384
-
385
-	/* link module in the list */
386
-	mod->next=modules;
387
-	modules=mod;
388
-	return 0;
389
-error:
390
-	if (mod)
391
-		pkg_free(mod);
392
-	return ret;
393
-}
394
-
395
-static inline int version_control(void *handle, char *path)
396
-{
397
-	char **m_ver;
398
-	char **m_flags;
399
-	char* error;
400
-
401
-	m_ver=(char **)dlsym(handle, "module_version");
402
-	if ((error=(char *)dlerror())!=0) {
403
-		LM_ERR("no version info in module <%s>: %s\n", path, error);
404
-		return 0;
405
-	}
406
-	m_flags=(char **)dlsym(handle, "module_flags");
407
-	if ((error=(char *)dlerror())!=0) {
408
-		LM_ERR("no compile flags info in module <%s>: %s\n", path, error);
409
-		return 0;
410
-	}
411
-	if (!m_ver || !(*m_ver)) {
412
-		LM_ERR("no version in module <%s>\n", path );
413
-		return 0;
414
-	}
415
-	if (!m_flags || !(*m_flags)) {
416
-		LM_ERR("no compile flags in module <%s>\n", path );
417
-		return 0;
418
-	}
419
-
420
-	if (strcmp(SER_FULL_VERSION, *m_ver)==0){
421
-		if (strcmp(SER_COMPILE_FLAGS, *m_flags)==0)
422
-			return 1;
423
-		else {
424
-			LM_ERR("module compile flags mismatch for %s "
425
-						" \ncore: %s \nmodule: %s\n",
426
-						path, SER_COMPILE_FLAGS, *m_flags);
427
-			return 0;
428
-		}
429
-	}
430
-	LM_ERR("module version mismatch for %s; "
431
-		"core: %s; module: %s\n", path, SER_FULL_VERSION, *m_ver );
432
-	return 0;
433
-}
434
-
435
-/**
436
- * \brief load a sr module
437
- *
438
- * tries to load the module specified by mod_path.
439
- * If mod_path is 'modname' or 'modname.so' then
440
- *  \<MODS_DIR\>/\<modname\>.so will be tried and if this fails
441
- *  \<MODS_DIR\>/\<modname\>/\<modname\>.so
442
- * If mod_path contain a '/' it is assumed to be the
443
- * path to the module and tried first. If fails and mod_path is not
444
- * absolute path (not starting with '/') then will try:
445
- * \<MODS_DIR\>/mod_path
446
- * @param mod_path path or module name
447
- * @return 0 on success , <0 on error
448
- */
449
-int load_module(char* mod_path)
450
-{
451
-	void* handle;
452
-	char* error;
453
-	mod_register_function mr;
454
-	union module_exports_u* exp;
455
-	unsigned* mod_if_ver;
456
-	struct sr_module* t;
457
-	struct stat stat_buf;
458
-	str modname;
459
-	char* mdir;
460
-	char* nxt_mdir;
461
-	char* path;
462
-	int mdir_len;
463
-	int len;
464
-	int dlflags;
465
-	int new_dlflags;
466
-	int retries;
467
-	int path_type;
468
-	str expref;
469
-	char exbuf[64];
470
-
471
-#ifndef RTLD_NOW
472
-/* for openbsd */
473
-#define RTLD_NOW DL_LAZY
474
-#endif
475
-	path=mod_path;
476
-	path_type = 0;
477
-	modname.s = path;
478
-	modname.len = strlen(mod_path);
479
-	if(modname.len>3 && strcmp(modname.s+modname.len-3, ".so")==0) {
480
-		path_type = 1;
481
-		modname.len -= 3;
482
-	}
483
-	if (!strchr(path, '/'))
484
-		path_type |= 2;
485
-	if((path_type&2) || path[0] != '/') {
486
-		/* module name was given, we try to construct the path */
487
-		mdir=mods_dir; /* search path */
488
-		do{
489
-			nxt_mdir=strchr(mdir, ':');
490
-			if (nxt_mdir) mdir_len=(int)(nxt_mdir-mdir);
491
-			else mdir_len=strlen(mdir);
492
-
493
-			if(path_type&2) {
494
-				/* try path <MODS_DIR>/<modname>.so */
495
-				path = (char*)pkg_malloc(mdir_len + 1 /* "/" */ +
496
-									modname.len + 3 /* ".so" */ + 1);
497
-				if (path==0) goto error;
498
-				memcpy(path, mdir, mdir_len);
499
-				len = mdir_len;
500
-				if (len != 0 && path[len - 1] != '/'){
501
-					path[len]='/';
502
-					len++;
503
-				}
504
-				path[len]=0;
505
-				strcat(path, modname.s);
506
-				if(!(path_type&1))
507
-					strcat(path, ".so");
508
-
509
-				if (stat(path, &stat_buf) == -1) {
510
-					LM_DBG("module file not found <%s>\n", path);
511
-					pkg_free(path);
512
-
513
-					/* try path <MODS_DIR>/<modname>/<modname>.so */
514
-					path = (char*)pkg_malloc(
515
-						mdir_len + 1 /* "/" */ +
516
-						modname.len + 1 /* "/" */ +
517
-						modname.len + 3 /* ".so" */ + 1);
518
-					if (path==0) goto error;
519
-					memcpy(path, mdir, mdir_len);
520
-					len = mdir_len;
521
-					if (len != 0 && path[len - 1] != '/') {
522
-						path[len]='/';
523
-						len++;
524
-					}
525
-					path[len]=0;
526
-					strncat(path, modname.s, modname.len);
527
-					strcat(path, "/");
528
-					strcat(path, modname.s);
529
-					if(!(path_type&1))
530
-						strcat(path, ".so");
531
-
532
-					if (stat(path, &stat_buf) == -1) {
533
-						LM_DBG("module file not found <%s>\n", path);
534
-						pkg_free(path);
535
-						path=0;
536
-					}
537
-				}
538
-			} else {
539
-				/* try mod_path - S compat */
540
-				if(path==mod_path) {
541
-					if (stat(path, &stat_buf) == -1) {
542
-						LM_DBG("module file not found <%s>\n", path);
543
-						path=0;
544
-					}
545
-				}
546
-				if(path==0) {
547
-					/* try path <MODS_DIR>/mod_path - K compat */
548
-					path = (char*)pkg_malloc(mdir_len + 1 /* "/" */ +
549
-									strlen(mod_path) + 1);
550
-					if (path==0) goto error;
551
-					memcpy(path, mdir, mdir_len);
552
-					len = mdir_len;
553
-					if (len != 0 && path[len - 1] != '/'){
554
-						path[len]='/';
555
-						len++;
556
-					}
557
-					path[len]=0;
558
-					strcat(path, mod_path);
559
-
560
-					if (stat(path, &stat_buf) == -1) {
561
-						LM_DBG("module file not found <%s>\n", path);
562
-						pkg_free(path);
563
-						path=0;
564
-					}
565
-				}
566
-			}
567
-			mdir=nxt_mdir?nxt_mdir+1:0;
568
-		}while(path==0 && mdir);
569
-		if (path==0){
570
-			LM_ERR("could not find module <%.*s> in <%s>\n",
571
-						modname.len, modname.s, mods_dir);
572
-			goto error;
573
-		}
574
-	}
575
-	LM_DBG("trying to load <%s>\n", path);
576
-
577
-	retries=2;
578
-	dlflags=RTLD_NOW;
579
-reload:
580
-	handle=dlopen(path, dlflags); /* resolve all symbols now */
581
-	if (handle==0){
582
-		LM_ERR("could not open module <%s>: %s\n", path, dlerror());
583
-		goto error;
584
-	}
585
-
586
-	for(t=modules;t; t=t->next){
587
-		if (t->handle==handle){
588
-			LM_WARN("attempting to load the same module twice (%s)\n", path);
589
-			goto skip;
590
-		}
591
-	}
592
-	/* version control */
593
-	if (!version_control(handle, path)) {
594
-		exit(-1);
595
-	}
596
-	mod_if_ver = (unsigned *)dlsym(handle, "module_interface_ver");
597
-	if ( (error =(char*)dlerror())!=0 ){
598
-		LM_ERR("no module interface version in module <%s>\n", path );
599
-		goto error1;
600
-	}
601
-	/* launch register */
602
-	mr = (mod_register_function)dlsym(handle, "mod_register");
603
-	if (((error =(char*)dlerror())==0) && mr) {
604
-		/* no error call it */
605
-		new_dlflags=dlflags;
606
-		if (mr(path, &new_dlflags, 0, 0)!=0) {
607
-			LM_ERR("%s: mod_register failed\n", path);
608
-			goto error1;
609
-		}
610
-		if (new_dlflags!=dlflags && new_dlflags!=0) {
611
-			/* we have to reload the module */
612
-			dlclose(handle);
613
-			dlflags=new_dlflags;
614
-			retries--;
615
-			if (retries>0) goto reload;
616
-			LM_ERR("%s: cannot agree on the dlflags\n", path);
617
-			goto error;
618
-		}
619
-	}
620
-	exp = (union module_exports_u*)dlsym(handle, "exports");
621
-	if(exp==NULL) {
622
-		/* 'exports' structure not found, look up for '_modulename_exports' */
623
-		mdir = strrchr(mod_path, '/');
624
-		if (!mdir) {
625
-			expref.s = mod_path;
626
-		} else {
627
-			expref.s = mdir+1;
628
-		}
629
-		expref.len = strlen(expref.s);
630
-		if(expref.len>3 && strcmp(expref.s+expref.len-3, ".so")==0)
631
-			expref.len -= 3;
632
-		snprintf(exbuf, 62, "_%.*s_exports", expref.len, expref.s);
633
-		exp = (union module_exports_u*)dlsym(handle, exbuf);
634
-		LM_DBG("looking up exports with name: %s\n", exbuf);
635
-		if ( (error =(char*)dlerror())!=0 ){
636
-			LM_ERR("%s\n", error);
637
-			goto error1;
638
-		}
639
-	}
640
-	/* hack to allow for kamailio style dlflags inside exports */
641
-	if (*mod_if_ver == 1) {
642
-		new_dlflags = exp->v1.dlflags;
643
-		if (new_dlflags!=dlflags && new_dlflags!=DEFAULT_DLFLAGS) {
644
-			/* we have to reload the module */
645
-			dlclose(handle);
646
-			DEBUG("%s: exports dlflags interface is deprecated and it will not"
647
-					" be supported in newer versions; consider using"
648
-					" mod_register() instead\n", path);
649
-			dlflags=new_dlflags;
650
-			retries--;
651
-			if (retries>0) goto reload;
652
-			LM_ERR("%s: cannot agree on the dlflags\n", path);
653
-			goto error;
654
-		}
655
-	}
656
-	if (register_module(*mod_if_ver, exp, path, handle)<0) goto error1;
657
-	return 0;
658
-
659
-error1:
660
-	dlclose(handle);
661
-error:
662
-skip:
663
-	if (path && path!=mod_path)
664
-		pkg_free(path);
665
-	return -1;
666
-}
667
-
668
-
669
-
670
-/* searches the module list for function name in module mod and returns
671
- *  a pointer to the "name" function record union or 0 if not found
672
- * sets also *mod_if_ver to the original module interface version.
673
- * mod==0 is a wildcard matching all modules
674
- * flags parameter is OR value of all flags that must match
675
- */
676
-sr31_cmd_export_t* find_mod_export_record(char* mod, char* name,
677
-											int param_no, int flags,
678
-											unsigned* mod_if_ver)
679
-{
680
-	struct sr_module* t;
681
-	sr31_cmd_export_t* cmd;
682
-
683
-	for(t=modules;t;t=t->next){
684
-		if (mod!=0 && (strcmp(t->exports.name, mod) !=0))
685
-			continue;
686
-		if (t->exports.cmds)
687
-			for(cmd=&t->exports.cmds[0]; cmd->name; cmd++) {
688
-				if((strcmp(name, cmd->name) == 0) &&
689
-					((cmd->param_no == param_no) ||
690
-					(cmd->param_no==VAR_PARAM_NO)) &&
691
-					((cmd->flags & flags) == flags)
692
-				){
693
-					LM_DBG("find_export_record: found <%s> in module %s [%s]\n",
694
-						name, t->exports.name, t->path);
695
-					*mod_if_ver=t->orig_mod_interface_ver;
696
-					return cmd;
697
-				}
698
-			}
699
-	}
700
-	LM_DBG("find_export_record: <%s> not found \n", name);
701
-	return 0;
702
-}
703
-
704
-
705
-
706
-/* searches the module list for function name and returns
707
- *  a pointer to the "name" function record union or 0 if not found
708
- * sets also *mod_if_ver to the module interface version (needed to know
709
- * which member of the union should be accessed v0 or v1)
710
- * mod==0 is a wildcard matching all modules
711
- * flags parameter is OR value of all flags that must match
712
- */
713
-sr31_cmd_export_t* find_export_record(char* name,
714
-											int param_no, int flags,
715
-											unsigned* mod_if_ver)
716
-{
717
-	return find_mod_export_record(0, name, param_no, flags, mod_if_ver);
718
-}
719
-
720
-
721
-
722
-cmd_function find_export(char* name, int param_no, int flags)
723
-{
724
-	sr31_cmd_export_t* cmd;
725
-	unsigned mver;
726
-
727
-	cmd = find_export_record(name, param_no, flags, &mver);
728
-	return cmd?cmd->function:0;
729
-}
730
-
731
-
732
-rpc_export_t* find_rpc_export(char* name, int flags)
733
-{
734
-	return rpc_lookup((char*)name, strlen(name));
735
-}
736
-
737
-
738
-/*
739
- * searches the module list and returns pointer to "name" function in module
740
- * "mod"
741
- * 0 if not found
742
- * flags parameter is OR value of all flags that must match
743
- */
744
-cmd_function find_mod_export(char* mod, char* name, int param_no, int flags)
745
-{
746
-	sr31_cmd_export_t* cmd;
747
-	unsigned mver;
748
-
749
-	cmd=find_mod_export_record(mod, name, param_no, flags, &mver);
750
-	if (cmd)
751
-		return cmd->function;
752
-
753
-	LM_DBG("<%s> in module <%s> not found\n", name, mod);
754
-	return 0;
755
-}
756
-
757
-
758
-struct sr_module* find_module_by_name(char* mod) {
759
-	struct sr_module* t;
760
-
761
-	for(t = modules; t; t = t->next) {
762
-		if (strcmp(mod, t->exports.name) == 0) {
763
-			return t;
764
-		}
765
-	}
766
-	LM_DBG("module <%s> not found\n", mod);
767
-	return 0;
768
-}
769
-
770
-
771
-/*!
772
- * \brief Find a parameter with given type
773
- * \param mod module
774
- * \param name parameter name
775
- * \param type_mask parameter mask
776
- * \param param_type parameter type
777
- * \return parameter address in memory, if there is no such parameter, NULL is returned
778
- */
779
-void* find_param_export(struct sr_module* mod, char* name,
780
-						modparam_t type_mask, modparam_t *param_type)
781
-{
782
-	param_export_t* param;
783
-
784
-	if (!mod)
785
-		return 0;
786
-	for(param = mod->exports.params ;param && param->name ; param++) {
787
-		if ((strcmp(name, param->name) == 0) &&
788
-			((param->type & PARAM_TYPE_MASK(type_mask)) != 0)) {
789
-			LM_DBG("found <%s> in module %s [%s]\n",
790
-				name, mod->exports.name, mod->path);
791
-			*param_type = param->type;
792
-			return param->param_pointer;
793
-		}
794
-	}
795
-	LM_DBG("parameter <%s> not found in module <%s>\n",
796
-			name, mod->exports.name);
797
-	return 0;
798
-}
799
-
800
-
801
-void destroy_modules()
802
-{
803
-	struct sr_module* t, *foo;
804
-
805
-	_sr_destroy_modules_phase = 1;
806
-	/* call first destroy function from each module */
807
-	t=modules;
808
-	while(t) {
809
-		foo=t->next;
810
-		if (t->exports.destroy_f){
811
-			t->exports.destroy_f();
812
-		}
813
-		t=foo;
814
-	}
815
-	/* free module exports structures */
816
-	t=modules;
817
-	while(t) {
818
-		foo=t->next;
819
-		pkg_free(t);
820
-		t=foo;
821
-	}
822
-	modules=0;
823
-	if (mod_response_cbks){
824
-		pkg_free(mod_response_cbks);
825
-		mod_response_cbks=0;
826
-	}
827
-}
828
-
829
-#ifdef NO_REVERSE_INIT
830
-
831
-/*
832
- * Initialize all loaded modules, the initialization
833
- * is done *AFTER* the configuration file is parsed
834
- */
835
-int init_modules(void)
836
-{
837
-	struct sr_module* t;
838
-
839
-	if(async_task_init()<0)
840
-		return -1;
841
-
842
-	for(t = modules; t; t = t->next) {
843
-		if (t->exports.init_f) {
844
-			if (t->exports.init_f() != 0) {
845
-				LM_ERR("Error while initializing module %s\n", t->exports.name);
846
-				return -1;
847
-			}
848
-			/* delay next module init, if configured */
849
-			if(unlikely(modinit_delay>0))
850
-				sleep_us(modinit_delay);
851
-		}
852
-		if (t->exports.response_f)
853
-			mod_response_cbk_no++;
854
-	}
855
-	mod_response_cbks=pkg_malloc(mod_response_cbk_no *
856
-									sizeof(response_function));
857
-	if (mod_response_cbks==0){
858
-		LM_ERR("memory allocation failure for %d response_f callbacks\n",
859
-					mod_response_cbk_no);
860
-		return -1;
861
-	}
862
-	for (t=modules, i=0; t && (i<mod_response_cbk_no); t=t->next) {
863
-		if (t->exports.response_f) {
864
-			mod_response_cbks[i]=t->exports.response_f;
865
-			i++;
866
-		}
867
-	}
868
-	return 0;
869
-}
870
-
871
-
872
-
873
-/*
874
- * per-child initialization
875
- */
876
-int init_child(int rank)
877
-{
878
-	struct sr_module* t;
879
-	char* type;
880
-
881
-	switch(rank) {
882
-	case PROC_MAIN:     type = "PROC_MAIN";     break;
883
-	case PROC_TIMER:    type = "PROC_TIMER";    break;
884
-	case PROC_FIFO:     type = "PROC_FIFO";     break;
885
-	case PROC_TCP_MAIN: type = "PROC_TCP_MAIN"; break;
886
-	default:            type = "CHILD";         break;
887
-	}
888
-	LM_DBG("initializing %s with rank %d\n", type, rank);
889
-
890
-	if(async_task_child_init(rank)<0)
891
-		return -1;
892
-
893
-	for(t = modules; t; t = t->next) {
894
-		if (t->exports.init_child_f) {
895
-			if ((t->exports.init_child_f(rank)) < 0) {
896
-				LM_ERR("Initialization of child %d failed\n", rank);
897
-				return -1;
898
-			}
899
-		}
900
-	}
901
-	return 0;
902
-}
903
-
904
-#else
905