123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- /* $Id$
- *
- * Copyright (C) 2001-2003 Fhg Fokus
- *
- * This file is part of ser, a free SIP server.
- *
- * ser is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * For a license to use the ser software under conditions
- * other than those described here, or to purchase support for this
- * software, please contact iptel.org by e-mail at the following addresses:
- * [email protected]
- *
- * ser is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- #include "sr_module.h"
- #include "dprint.h"
- #include "error.h"
- #include <dlfcn.h>
- #include <strings.h>
- #include <stdlib.h>
- #include <string.h>
- struct sr_module* modules=0;
- #ifdef STATIC_EXEC
- extern struct module_exports* exec_exports();
- #endif
- #ifdef STATIC_TM
- extern struct module_exports* tm_exports();
- #endif
- #ifdef STATIC_MAXFWD
- extern struct module_exports* maxfwd_exports();
- #endif
- #ifdef STATIC_AUTH
- extern struct module_exports* auth_exports();
- #endif
- #ifdef STATIC_RR
- extern struct module_exports* rr_exports();
- #endif
- #ifdef STATIC_USRLOC
- extern struct module_exports* usrloc_exports();
- #endif
- #ifdef STATIC_SL
- extern struct module_exports* sl_exports();
- #endif
- /* initializes statically built (compiled in) modules*/
- int register_builtin_modules()
- {
- int ret;
- ret=0;
- #ifdef STATIC_TM
- ret=register_module(tm_exports,"built-in", 0);
- if (ret<0) return ret;
- #endif
- #ifdef STATIC_EXEC
- ret=register_module(exec_exports,"built-in", 0);
- if (ret<0) return ret;
- #endif
- #ifdef STATIC_MAXFWD
- ret=register_module(maxfwd_exports, "built-in", 0);
- if (ret<0) return ret;
- #endif
- #ifdef STATIC_AUTH
- ret=register_module(auth_exports, "built-in", 0);
- if (ret<0) return ret;
- #endif
-
- #ifdef STATIC_RR
- ret=register_module(rr_exports, "built-in", 0);
- if (ret<0) return ret;
- #endif
-
- #ifdef STATIC_USRLOC
- ret=register_module(usrloc_exports, "built-in", 0);
- if (ret<0) return ret;
- #endif
- #ifdef STATIC_SL
- ret=register_module(sl_exports, "built-in", 0);
- if (ret<0) return ret;
- #endif
-
- return ret;
- }
- /* registers a module, register_f= module register functions
- * returns <0 on error, 0 on success */
- int register_module(struct module_exports* e, char* path, void* handle)
- {
- int ret;
- struct sr_module* mod;
-
- ret=-1;
- /* add module to the list */
- if ((mod=malloc(sizeof(struct sr_module)))==0){
- LOG(L_ERR, "load_module: memory allocation failure\n");
- ret=E_OUT_OF_MEM;
- goto error;
- }
- memset(mod,0, sizeof(struct sr_module));
- mod->path=path;
- mod->handle=handle;
- mod->exports=e;
- mod->next=modules;
- modules=mod;
- return 0;
- error:
- return ret;
- }
- /* returns 0 on success , <0 on error */
- int load_module(char* path)
- {
- void* handle;
- char* error;
- struct module_exports* exp;
- struct sr_module* t;
-
- #ifndef RTLD_NOW
- /* for openbsd */
- #define RTLD_NOW DL_LAZY
- #endif
- #ifndef DLSYM_PREFIX
- /* define it to null */
- #define DLSYM_PREFIX
- #endif
- handle=dlopen(path, RTLD_NOW); /* resolve all symbols now */
- if (handle==0){
- LOG(L_ERR, "ERROR: load_module: could not open module <%s>: %s\n",
- path, dlerror() );
- goto error;
- }
-
- for(t=modules;t; t=t->next){
- if (t->handle==handle){
- LOG(L_WARN, "WARNING: load_module: attempting to load the same"
- " module twice (%s)\n", path);
- goto skip;
- }
- }
- /* launch register */
- exp = (struct module_exports*)dlsym(handle, DLSYM_PREFIX "exports");
- if ( (error =(char*)dlerror())!=0 ){
- LOG(L_ERR, "ERROR: load_module: %s\n", error);
- goto error1;
- }
- if (register_module(exp, path, handle)<0) goto error1;
- return 0;
- error1:
- dlclose(handle);
- error:
- skip:
- return -1;
- }
- /* searches the module list and returns a pointer to the "name" function or
- * 0 if not found */
- cmd_function find_export(char* name, int param_no)
- {
- struct sr_module* t;
- int r;
- for(t=modules;t;t=t->next){
- for(r=0;r<t->exports->cmd_no;r++){
- if((strcmp(name, t->exports->cmd_names[r])==0)&&
- (t->exports->param_no[r]==param_no) ){
- DBG("find_export: found <%s> in module %s [%s]\n",
- name, t->exports->name, t->path);
- return t->exports->cmd_pointers[r];
- }
- }
- }
- DBG("find_export: <%s> not found \n", name);
- return 0;
- }
- void* find_param_export(char* mod, char* name, modparam_t type)
- {
- struct sr_module* t;
- int r;
- for(t = modules; t; t = t->next) {
- if (strcmp(mod, t->exports->name) == 0) {
- for(r = 0; r < t->exports->par_no; r++) {
- if ((strcmp(name, t->exports->param_names[r]) == 0) &&
- (t->exports->param_types[r] == type)) {
- DBG("find_param_export: found <%s> in module %s [%s]\n",
- name, t->exports->name, t->path);
- return t->exports->param_pointers[r];
- }
- }
- }
- }
- DBG("find_param_export: parameter <%s> or module <%s> not found\n",
- name, mod);
- return 0;
- }
- /* finds a module, given a pointer to a module function *
- * returns pointer to module, & if i i!=0, *i=the function index */
- struct sr_module* find_module(void* f, int *i)
- {
- struct sr_module* t;
- int r;
- for (t=modules;t;t=t->next){
- for(r=0;r<t->exports->cmd_no;r++)
- if (f==(void*)t->exports->cmd_pointers[r]) {
- if (i) *i=r;
- return t;
- }
- }
- return 0;
- }
- void destroy_modules()
- {
- struct sr_module* t;
- for(t=modules;t;t=t->next)
- if ((t->exports)&&(t->exports->destroy_f)) t->exports->destroy_f();
- }
- #ifdef NO_REVERSE_INIT
- /*
- * Initialize all loaded modules, the initialization
- * is done *AFTER* the configuration file is parsed
- */
- int init_modules(void)
- {
- struct sr_module* t;
-
- for(t = modules; t; t = t->next) {
- if ((t->exports) && (t->exports->init_f))
- if (t->exports->init_f() != 0) {
- LOG(L_ERR, "init_modules(): Error while initializing"
- " module %s\n", t->exports->name);
- return -1;
- }
- }
- return 0;
- }
- /*
- * per-child initialization
- */
- int init_child(int rank)
- {
- struct sr_module* t;
- for(t = modules; t; t = t->next) {
- if (t->exports->init_child_f) {
- if ((t->exports->init_child_f(rank)) < 0) {
- LOG(L_ERR, "init_child(): Initialization of child %d failed\n",
- rank);
- return -1;
- }
- }
- }
- return 0;
- }
- #else
- /* recursive module child initialization; (recursion is used to
- process the module linear list in the same order in
- which modules are loaded in config file
- */
- static int init_mod_child( struct sr_module* m, int rank )
- {
- if (m) {
- /* iterate through the list; if error occurs,
- propagate it up the stack
- */
- if (init_mod_child(m->next, rank)!=0) return -1;
- if (m->exports && m->exports->init_child_f) {
- DBG("DEBUG: init_mod_child (%d): %s\n",
- rank, m->exports->name);
- if (m->exports->init_child_f(rank)<0) {
- LOG(L_ERR, "init_mod_child(): Error while initializing"
- " module %s\n", m->exports->name);
- return -1;
- } else {
- /* module correctly initialized */
- return 0;
- }
- }
- /* no init function -- proceed with success */
- return 0;
- } else {
- /* end of list */
- return 0;
- }
- }
- /*
- * per-child initialization
- */
- int init_child(int rank)
- {
- return init_mod_child(modules, rank);
- }
- /* recursive module initialization; (recursion is used to
- process the module linear list in the same order in
- which modules are loaded in config file
- */
- static int init_mod( struct sr_module* m )
- {
- if (m) {
- /* iterate through the list; if error occurs,
- propagate it up the stack
- */
- if (init_mod(m->next)!=0) return -1;
- if (m->exports && m->exports->init_f) {
- DBG("DEBUG: init_mod: %s\n", m->exports->name);
- if (m->exports->init_f()!=0) {
- LOG(L_ERR, "init_mod(): Error while initializing"
- " module %s\n", m->exports->name);
- return -1;
- } else {
- /* module correctly initialized */
- return 0;
- }
- }
- /* no init function -- proceed with success */
- return 0;
- } else {
- /* end of list */
- return 0;
- }
- }
- /*
- * Initialize all loaded modules, the initialization
- * is done *AFTER* the configuration file is parsed
- */
- int init_modules(void)
- {
- return init_mod(modules);
- }
- #endif
|