sr_module.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /* $Id$
  2. *
  3. * Copyright (C) 2001-2003 Fhg Fokus
  4. *
  5. * This file is part of ser, a free SIP server.
  6. *
  7. * ser 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
  11. *
  12. * For a license to use the ser software under conditions
  13. * other than those described here, or to purchase support for this
  14. * software, please contact iptel.org by e-mail at the following addresses:
  15. * [email protected]
  16. *
  17. * ser is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  25. */
  26. #include "sr_module.h"
  27. #include "dprint.h"
  28. #include "error.h"
  29. #include <dlfcn.h>
  30. #include <strings.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. struct sr_module* modules=0;
  34. #ifdef STATIC_EXEC
  35. extern struct module_exports* exec_exports();
  36. #endif
  37. #ifdef STATIC_TM
  38. extern struct module_exports* tm_exports();
  39. #endif
  40. #ifdef STATIC_MAXFWD
  41. extern struct module_exports* maxfwd_exports();
  42. #endif
  43. #ifdef STATIC_AUTH
  44. extern struct module_exports* auth_exports();
  45. #endif
  46. #ifdef STATIC_RR
  47. extern struct module_exports* rr_exports();
  48. #endif
  49. #ifdef STATIC_USRLOC
  50. extern struct module_exports* usrloc_exports();
  51. #endif
  52. #ifdef STATIC_SL
  53. extern struct module_exports* sl_exports();
  54. #endif
  55. /* initializes statically built (compiled in) modules*/
  56. int register_builtin_modules()
  57. {
  58. int ret;
  59. ret=0;
  60. #ifdef STATIC_TM
  61. ret=register_module(tm_exports,"built-in", 0);
  62. if (ret<0) return ret;
  63. #endif
  64. #ifdef STATIC_EXEC
  65. ret=register_module(exec_exports,"built-in", 0);
  66. if (ret<0) return ret;
  67. #endif
  68. #ifdef STATIC_MAXFWD
  69. ret=register_module(maxfwd_exports, "built-in", 0);
  70. if (ret<0) return ret;
  71. #endif
  72. #ifdef STATIC_AUTH
  73. ret=register_module(auth_exports, "built-in", 0);
  74. if (ret<0) return ret;
  75. #endif
  76. #ifdef STATIC_RR
  77. ret=register_module(rr_exports, "built-in", 0);
  78. if (ret<0) return ret;
  79. #endif
  80. #ifdef STATIC_USRLOC
  81. ret=register_module(usrloc_exports, "built-in", 0);
  82. if (ret<0) return ret;
  83. #endif
  84. #ifdef STATIC_SL
  85. ret=register_module(sl_exports, "built-in", 0);
  86. if (ret<0) return ret;
  87. #endif
  88. return ret;
  89. }
  90. /* registers a module, register_f= module register functions
  91. * returns <0 on error, 0 on success */
  92. int register_module(struct module_exports* e, char* path, void* handle)
  93. {
  94. int ret;
  95. struct sr_module* mod;
  96. ret=-1;
  97. /* add module to the list */
  98. if ((mod=malloc(sizeof(struct sr_module)))==0){
  99. LOG(L_ERR, "load_module: memory allocation failure\n");
  100. ret=E_OUT_OF_MEM;
  101. goto error;
  102. }
  103. memset(mod,0, sizeof(struct sr_module));
  104. mod->path=path;
  105. mod->handle=handle;
  106. mod->exports=e;
  107. mod->next=modules;
  108. modules=mod;
  109. return 0;
  110. error:
  111. return ret;
  112. }
  113. /* returns 0 on success , <0 on error */
  114. int load_module(char* path)
  115. {
  116. void* handle;
  117. char* error;
  118. struct module_exports* exp;
  119. struct sr_module* t;
  120. #ifndef RTLD_NOW
  121. /* for openbsd */
  122. #define RTLD_NOW DL_LAZY
  123. #endif
  124. #ifndef DLSYM_PREFIX
  125. /* define it to null */
  126. #define DLSYM_PREFIX
  127. #endif
  128. handle=dlopen(path, RTLD_NOW); /* resolve all symbols now */
  129. if (handle==0){
  130. LOG(L_ERR, "ERROR: load_module: could not open module <%s>: %s\n",
  131. path, dlerror() );
  132. goto error;
  133. }
  134. for(t=modules;t; t=t->next){
  135. if (t->handle==handle){
  136. LOG(L_WARN, "WARNING: load_module: attempting to load the same"
  137. " module twice (%s)\n", path);
  138. goto skip;
  139. }
  140. }
  141. /* launch register */
  142. exp = (struct module_exports*)dlsym(handle, DLSYM_PREFIX "exports");
  143. if ( (error =(char*)dlerror())!=0 ){
  144. LOG(L_ERR, "ERROR: load_module: %s\n", error);
  145. goto error1;
  146. }
  147. if (register_module(exp, path, handle)<0) goto error1;
  148. return 0;
  149. error1:
  150. dlclose(handle);
  151. error:
  152. skip:
  153. return -1;
  154. }
  155. /* searches the module list and returns a pointer to the "name" function or
  156. * 0 if not found */
  157. cmd_function find_export(char* name, int param_no)
  158. {
  159. struct sr_module* t;
  160. int r;
  161. for(t=modules;t;t=t->next){
  162. for(r=0;r<t->exports->cmd_no;r++){
  163. if((strcmp(name, t->exports->cmd_names[r])==0)&&
  164. (t->exports->param_no[r]==param_no) ){
  165. DBG("find_export: found <%s> in module %s [%s]\n",
  166. name, t->exports->name, t->path);
  167. return t->exports->cmd_pointers[r];
  168. }
  169. }
  170. }
  171. DBG("find_export: <%s> not found \n", name);
  172. return 0;
  173. }
  174. void* find_param_export(char* mod, char* name, modparam_t type)
  175. {
  176. struct sr_module* t;
  177. int r;
  178. for(t = modules; t; t = t->next) {
  179. if (strcmp(mod, t->exports->name) == 0) {
  180. for(r = 0; r < t->exports->par_no; r++) {
  181. if ((strcmp(name, t->exports->param_names[r]) == 0) &&
  182. (t->exports->param_types[r] == type)) {
  183. DBG("find_param_export: found <%s> in module %s [%s]\n",
  184. name, t->exports->name, t->path);
  185. return t->exports->param_pointers[r];
  186. }
  187. }
  188. }
  189. }
  190. DBG("find_param_export: parameter <%s> or module <%s> not found\n",
  191. name, mod);
  192. return 0;
  193. }
  194. /* finds a module, given a pointer to a module function *
  195. * returns pointer to module, & if i i!=0, *i=the function index */
  196. struct sr_module* find_module(void* f, int *i)
  197. {
  198. struct sr_module* t;
  199. int r;
  200. for (t=modules;t;t=t->next){
  201. for(r=0;r<t->exports->cmd_no;r++)
  202. if (f==(void*)t->exports->cmd_pointers[r]) {
  203. if (i) *i=r;
  204. return t;
  205. }
  206. }
  207. return 0;
  208. }
  209. void destroy_modules()
  210. {
  211. struct sr_module* t;
  212. for(t=modules;t;t=t->next)
  213. if ((t->exports)&&(t->exports->destroy_f)) t->exports->destroy_f();
  214. }
  215. #ifdef NO_REVERSE_INIT
  216. /*
  217. * Initialize all loaded modules, the initialization
  218. * is done *AFTER* the configuration file is parsed
  219. */
  220. int init_modules(void)
  221. {
  222. struct sr_module* t;
  223. for(t = modules; t; t = t->next) {
  224. if ((t->exports) && (t->exports->init_f))
  225. if (t->exports->init_f() != 0) {
  226. LOG(L_ERR, "init_modules(): Error while initializing"
  227. " module %s\n", t->exports->name);
  228. return -1;
  229. }
  230. }
  231. return 0;
  232. }
  233. /*
  234. * per-child initialization
  235. */
  236. int init_child(int rank)
  237. {
  238. struct sr_module* t;
  239. for(t = modules; t; t = t->next) {
  240. if (t->exports->init_child_f) {
  241. if ((t->exports->init_child_f(rank)) < 0) {
  242. LOG(L_ERR, "init_child(): Initialization of child %d failed\n",
  243. rank);
  244. return -1;
  245. }
  246. }
  247. }
  248. return 0;
  249. }
  250. #else
  251. /* recursive module child initialization; (recursion is used to
  252. process the module linear list in the same order in
  253. which modules are loaded in config file
  254. */
  255. static int init_mod_child( struct sr_module* m, int rank )
  256. {
  257. if (m) {
  258. /* iterate through the list; if error occurs,
  259. propagate it up the stack
  260. */
  261. if (init_mod_child(m->next, rank)!=0) return -1;
  262. if (m->exports && m->exports->init_child_f) {
  263. DBG("DEBUG: init_mod_child (%d): %s\n",
  264. rank, m->exports->name);
  265. if (m->exports->init_child_f(rank)<0) {
  266. LOG(L_ERR, "init_mod_child(): Error while initializing"
  267. " module %s\n", m->exports->name);
  268. return -1;
  269. } else {
  270. /* module correctly initialized */
  271. return 0;
  272. }
  273. }
  274. /* no init function -- proceed with success */
  275. return 0;
  276. } else {
  277. /* end of list */
  278. return 0;
  279. }
  280. }
  281. /*
  282. * per-child initialization
  283. */
  284. int init_child(int rank)
  285. {
  286. return init_mod_child(modules, rank);
  287. }
  288. /* recursive module initialization; (recursion is used to
  289. process the module linear list in the same order in
  290. which modules are loaded in config file
  291. */
  292. static int init_mod( struct sr_module* m )
  293. {
  294. if (m) {
  295. /* iterate through the list; if error occurs,
  296. propagate it up the stack
  297. */
  298. if (init_mod(m->next)!=0) return -1;
  299. if (m->exports && m->exports->init_f) {
  300. DBG("DEBUG: init_mod: %s\n", m->exports->name);
  301. if (m->exports->init_f()!=0) {
  302. LOG(L_ERR, "init_mod(): Error while initializing"
  303. " module %s\n", m->exports->name);
  304. return -1;
  305. } else {
  306. /* module correctly initialized */
  307. return 0;
  308. }
  309. }
  310. /* no init function -- proceed with success */
  311. return 0;
  312. } else {
  313. /* end of list */
  314. return 0;
  315. }
  316. }
  317. /*
  318. * Initialize all loaded modules, the initialization
  319. * is done *AFTER* the configuration file is parsed
  320. */
  321. int init_modules(void)
  322. {
  323. return init_mod(modules);
  324. }
  325. #endif