Module: sip-router Branch: master Commit: fdbb341c72c140516578e80e9e0823779e03d409 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fdbb341c...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Fri Apr 3 17:31:01 2009 +0200
core: loadpath can now use a list of directories
- loadpath can use a list of directories separated by ':', e.g.: loadpath "modules:modules_s:modules_k". First match wins (e.g. for loadmodule "textops" if modules/textops.so or modules/textops/textops.so exists, it will be loaded and the search will stop).
---
NEWS | 6 ++++ sr_module.c | 90 ++++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 62 insertions(+), 34 deletions(-)
diff --git a/NEWS b/NEWS index d3d6418..ba832bf 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ $Id$ sip-router changes
core: + - module search path support: loadpath takes now a list of directories + separated by ':'. The list is searched in-order. For each directory d + $d/${module_name}.so and $d/${module_name}/${module_name}.so are tried. + - dns TXT, EBL and PTR support (both cache and non-cached resolver) - support for dual module interfaces: ser and kamailio config script changes: - script mode can be switched between ser compatible, kamailio compatible @@ -21,6 +25,8 @@ config script changes: - while() - max_while_loops - maximum iterations allowed for a while, can be changed at runtime. Default 100. +build system: + - multiple modules directories are now supported (defined in Makefile.dirs)
diff --git a/sr_module.c b/sr_module.c index 24c1445..3ff127f 100644 --- a/sr_module.c +++ b/sr_module.c @@ -238,7 +238,7 @@ static inline int version_control(void *handle, char *path) * @param modname - path or module name * @return 0 on success , <0 on error */ -int load_module(char* path) +int load_module(char* mod_path) { void* handle; char* error; @@ -248,6 +248,10 @@ int load_module(char* path) struct sr_module* t; struct stat stat_buf; char* modname; + char* mdir; + char* nxt_mdir; + char* path; + int mdir_len; int len; int dlflags; int new_dlflags; @@ -257,49 +261,64 @@ int load_module(char* path) /* for openbsd */ #define RTLD_NOW DL_LAZY #endif - + path=mod_path; if (!strchr(path, '/') && !strchr(path, '.')) { /* module name was given, we try to construct the path */ modname = path; - - /* try path <MODS_DIR>/<modname>.so */ - path = (char*)pkg_malloc( - strlen(mods_dir) + 1 /* "/" */ + - strlen(modname) + 3 /* ".so" */ + 1); - strcpy(path, mods_dir); - len = strlen(path); - if (len != 0 && path[len - 1] != '/') { - strcat(path, "/"); - } - strcat(path, modname); - strcat(path, ".so"); - - if (stat(path, &stat_buf) == -1) { - DBG("load_module: module file not found <%s>\n", path); - pkg_free(path); - - /* try path <MODS_DIR>/<modname>/<modname>.so */ - path = (char*)pkg_malloc( - strlen(mods_dir) + 1 /* "/" */ + - strlen(modname) + 1 /* "/" */ + - strlen(modname) + 3 /* ".so" */ + 1); - strcpy(path, mods_dir); - len = strlen(path); - if (len != 0 && path[len - 1] != '/') { - strcat(path, "/"); + mdir=mods_dir; /* search path */ + do{ + nxt_mdir=strchr(mdir, ':'); + if (nxt_mdir) mdir_len=(int)(nxt_mdir-mdir); + else mdir_len=strlen(mdir); + + /* try path <MODS_DIR>/<modname>.so */ + path = (char*)pkg_malloc(mdir_len + 1 /* "/" */ + + strlen(modname) + 3 /* ".so" */ + 1); + if (path==0) goto error; + memcpy(path, mdir, mdir_len); + len = mdir_len; + if (len != 0 && path[len - 1] != '/'){ + path[len]='/'; + len++; } - strcat(path, modname); - strcat(path, "/"); + path[len]=0; strcat(path, modname); strcat(path, ".so");
if (stat(path, &stat_buf) == -1) { DBG("load_module: module file not found <%s>\n", path); pkg_free(path); - LOG(L_ERR, "ERROR: load_module: could not find module <%s>\n", - modname); - goto error; + + /* try path <MODS_DIR>/<modname>/<modname>.so */ + path = (char*)pkg_malloc( + mdir_len + 1 /* "/" */ + + strlen(modname) + 1 /* "/" */ + + strlen(modname) + 3 /* ".so" */ + 1); + if (path==0) goto error; + memcpy(path, mdir, mdir_len); + len = mdir_len; + if (len != 0 && path[len - 1] != '/') { + path[len]='/'; + len++; + } + path[len]=0; + strcat(path, modname); + strcat(path, "/"); + strcat(path, modname); + strcat(path, ".so"); + + if (stat(path, &stat_buf) == -1) { + DBG("load_module: module file not found <%s>\n", path); + pkg_free(path); + path=0; + } } + mdir=nxt_mdir?nxt_mdir+1:0; + }while(path==0 && mdir); + if (path==0){ + LOG(L_ERR, "ERROR: load_module: could not find module <%s> in" + " <%s>\n", modname, mods_dir); + goto error; } } retries=2; @@ -373,18 +392,21 @@ reload: } } if (register_module(*mod_if_ver, exp, path, handle)<0) goto error1; + if (path && path!=mod_path) + pkg_free(path); return 0;
error1: dlclose(handle); error: skip: + if (path && path!=mod_path) + pkg_free(path); return -1; }
- /* searches the module list for function name in module mod and returns * a pointer to the "name" function record union or 0 if not found * sets also *mod_if_ver to the module interface version (needed to know