sr_module.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561
  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. /*
  27. * History:
  28. * --------
  29. * 2003-03-10 switched to new module_exports format: updated find_export,
  30. * find_export_param, find_module (andrei)
  31. * 2003-03-19 replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
  32. * 2003-03-19 Support for flags in find_export (janakj)
  33. * 2003-03-29 cleaning pkg_mallocs introduced (jiri)
  34. * 2003-04-24 module version checking introduced (jiri)
  35. * 2004-09-19 compile flags are checked too (andrei)
  36. * 2005-01-07 removed find_module-overloading problems, added
  37. * find_export_record
  38. * 2006-02-07 added fix_flag (andrei)
  39. * 2008-02-29 store all the reponse callbacks in their own array (andrei)
  40. * 2008-11-17 support dual module interface: ser & kamailio (andrei)
  41. * 2008-11-26 added fparam_free_contents() and fix_param_types (andrei)
  42. */
  43. #include "sr_module.h"
  44. #include "dprint.h"
  45. #include "error.h"
  46. #include "mem/mem.h"
  47. #include "core_cmd.h"
  48. #include "ut.h"
  49. #include "re.h"
  50. #include "route_struct.h"
  51. #include "flags.h"
  52. #include "trim.h"
  53. #include "globals.h"
  54. #include "rpc_lookup.h"
  55. #include "sr_compat.h"
  56. #include <sys/stat.h>
  57. #include <regex.h>
  58. #include <dlfcn.h>
  59. #include <strings.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. struct sr_module* modules=0;
  63. #ifdef STATIC_EXEC
  64. extern struct module_exports exec_exports;
  65. #endif
  66. #ifdef STATIC_TM
  67. extern struct module_exports tm_exports;
  68. #endif
  69. #ifdef STATIC_MAXFWD
  70. extern struct module_exports maxfwd_exports;
  71. #endif
  72. #ifdef STATIC_AUTH
  73. extern struct module_exports auth_exports;
  74. #endif
  75. #ifdef STATIC_RR
  76. extern struct module_exports rr_exports;
  77. #endif
  78. #ifdef STATIC_USRLOC
  79. extern struct module_exports usrloc_exports;
  80. #endif
  81. #ifdef STATIC_SL
  82. extern struct module_exports sl_exports;
  83. #endif
  84. int mod_response_cbk_no=0;
  85. response_function* mod_response_cbks=0;
  86. /* initializes statically built (compiled in) modules*/
  87. int register_builtin_modules()
  88. {
  89. int ret;
  90. ret=0;
  91. #ifdef STATIC_TM
  92. ret=register_module(MODULE_INTERFACE_VER, &tm_exports,"built-in", 0);
  93. if (ret<0) return ret;
  94. #endif
  95. #ifdef STATIC_EXEC
  96. ret=register_module(MODULE_INTERFACE_VER, &exec_exports,"built-in", 0);
  97. if (ret<0) return ret;
  98. #endif
  99. #ifdef STATIC_MAXFWD
  100. ret=register_module(MODULE_INTERFACE_VER, &maxfwd_exports, "built-in", 0);
  101. if (ret<0) return ret;
  102. #endif
  103. #ifdef STATIC_AUTH
  104. ret=register_module(MODULE_INTERFACE_VER, &auth_exports, "built-in", 0);
  105. if (ret<0) return ret;
  106. #endif
  107. #ifdef STATIC_RR
  108. ret=register_module(MODULE_INTERFACE_VER, &rr_exports, "built-in", 0);
  109. if (ret<0) return ret;
  110. #endif
  111. #ifdef STATIC_USRLOC
  112. ret=register_module(MODULE_INTERFACE_VER, &usrloc_exports, "built-in", 0);
  113. if (ret<0) return ret;
  114. #endif
  115. #ifdef STATIC_SL
  116. ret=register_module(MODULE_INTERFACE_VER, &sl_exports, "built-in", 0);
  117. if (ret<0) return ret;
  118. #endif
  119. return ret;
  120. }
  121. /* registers a module, register_f= module register functions
  122. * returns <0 on error, 0 on success */
  123. static int register_module(unsigned ver, union module_exports_u* e,
  124. char* path, void* handle)
  125. {
  126. int ret, i;
  127. struct sr_module* mod;
  128. ret=-1;
  129. /* add module to the list */
  130. if ((mod=pkg_malloc(sizeof(struct sr_module)))==0){
  131. LOG(L_ERR, "load_module: memory allocation failure\n");
  132. ret=E_OUT_OF_MEM;
  133. goto error;
  134. }
  135. memset(mod,0, sizeof(struct sr_module));
  136. mod->path=path;
  137. mod->handle=handle;
  138. mod->mod_interface_ver=ver;
  139. mod->exports=e;
  140. mod->next=modules;
  141. modules=mod;
  142. if (ver==1 && e->v1.items) {
  143. /* register module pseudo-variables for kamailio modules */
  144. LM_DBG("register PV from: %s\n", e->c.name);
  145. if (register_pvars_mod(e->c.name, e->v1.items)!=0) {
  146. LM_ERR("failed to register pseudo-variables for module %s\n",
  147. e->c.name);
  148. pkg_free(mod);
  149. return -1;
  150. }
  151. }else if (ver==0 && e->v0.rpc_methods){
  152. /* register rpcs for ser modules */
  153. i=rpc_register_array(e->v0.rpc_methods);
  154. if (i<0){
  155. ERR("failed to register RPCs for module %s\n", e->c.name);
  156. goto error;
  157. }else if (i>0){
  158. ERR("%d duplicate RPCs name detected while registering RPCs"
  159. " declared in modules %s\n", i, e->c.name);
  160. goto error;
  161. }
  162. /* i==0 => success */
  163. }
  164. return 0;
  165. error:
  166. return ret;
  167. }
  168. #ifndef DLSYM_PREFIX
  169. /* define it to null */
  170. #define DLSYM_PREFIX
  171. #endif
  172. static inline int version_control(void *handle, char *path)
  173. {
  174. char **m_ver;
  175. char **m_flags;
  176. char* error;
  177. m_ver=(char **)dlsym(handle, DLSYM_PREFIX "module_version");
  178. if ((error=(char *)dlerror())!=0) {
  179. LOG(L_ERR, "ERROR: no version info in module <%s>: %s\n",
  180. path, error );
  181. return 0;
  182. }
  183. m_flags=(char **)dlsym(handle, DLSYM_PREFIX "module_flags");
  184. if ((error=(char *)dlerror())!=0) {
  185. LOG(L_ERR, "ERROR: no compile flags info in module <%s>: %s\n",
  186. path, error );
  187. return 0;
  188. }
  189. if (!m_ver || !(*m_ver)) {
  190. LOG(L_ERR, "ERROR: no version in module <%s>\n", path );
  191. return 0;
  192. }
  193. if (!m_flags || !(*m_flags)) {
  194. LOG(L_ERR, "ERROR: no compile flags in module <%s>\n", path );
  195. return 0;
  196. }
  197. if (strcmp(SER_FULL_VERSION, *m_ver)==0){
  198. if (strcmp(SER_COMPILE_FLAGS, *m_flags)==0)
  199. return 1;
  200. else {
  201. LOG(L_ERR, "ERROR: module compile flags mismatch for %s "
  202. " \ncore: %s \nmodule: %s\n",
  203. path, SER_COMPILE_FLAGS, *m_flags);
  204. return 0;
  205. }
  206. }
  207. LOG(L_ERR, "ERROR: module version mismatch for %s; "
  208. "core: %s; module: %s\n", path, SER_FULL_VERSION, *m_ver );
  209. return 0;
  210. }
  211. /** load a sr module.
  212. * tries to load the module specified by mod_path.
  213. * If mod_path is 'modname' or 'modname.so' then
  214. * <MODS_DIR>/<modname>.so will be tried and if this fails
  215. * <MODS_DIR>/<modname>/<modname>.so
  216. * If mod_path contain a '/' it is assumed to be the
  217. * path to the module and tried first. If fails and mod_path is not
  218. * absolute path (not starting with '/') then will try:
  219. * <MODS_DIR>/mod_path
  220. * @param modname - path or module name
  221. * @return 0 on success , <0 on error
  222. */
  223. int load_module(char* mod_path)
  224. {
  225. void* handle;
  226. char* error;
  227. mod_register_function mr;
  228. union module_exports_u* exp;
  229. unsigned* mod_if_ver;
  230. struct sr_module* t;
  231. struct stat stat_buf;
  232. str modname;
  233. char* mdir;
  234. char* nxt_mdir;
  235. char* path;
  236. int mdir_len;
  237. int len;
  238. int dlflags;
  239. int new_dlflags;
  240. int retries;
  241. int path_type;
  242. #ifndef RTLD_NOW
  243. /* for openbsd */
  244. #define RTLD_NOW DL_LAZY
  245. #endif
  246. path=mod_path;
  247. path_type = 0;
  248. modname.s = path;
  249. modname.len = strlen(mod_path);
  250. if(modname.len>3 && strcmp(modname.s+modname.len-3, ".so")==0) {
  251. path_type = 1;
  252. modname.len -= 3;
  253. }
  254. if (!strchr(path, '/'))
  255. path_type |= 2;
  256. if((path_type&2) || path[0] != '/') {
  257. /* module name was given, we try to construct the path */
  258. mdir=mods_dir; /* search path */
  259. do{
  260. nxt_mdir=strchr(mdir, ':');
  261. if (nxt_mdir) mdir_len=(int)(nxt_mdir-mdir);
  262. else mdir_len=strlen(mdir);
  263. if(path_type&2) {
  264. /* try path <MODS_DIR>/<modname>.so */
  265. path = (char*)pkg_malloc(mdir_len + 1 /* "/" */ +
  266. modname.len + 3 /* ".so" */ + 1);
  267. if (path==0) goto error;
  268. memcpy(path, mdir, mdir_len);
  269. len = mdir_len;
  270. if (len != 0 && path[len - 1] != '/'){
  271. path[len]='/';
  272. len++;
  273. }
  274. path[len]=0;
  275. strcat(path, modname.s);
  276. if(!(path_type&1))
  277. strcat(path, ".so");
  278. if (stat(path, &stat_buf) == -1) {
  279. DBG("load_module: module file not found <%s>\n", path);
  280. pkg_free(path);
  281. /* try path <MODS_DIR>/<modname>/<modname>.so */
  282. path = (char*)pkg_malloc(
  283. mdir_len + 1 /* "/" */ +
  284. modname.len + 1 /* "/" */ +
  285. modname.len + 3 /* ".so" */ + 1);
  286. if (path==0) goto error;
  287. memcpy(path, mdir, mdir_len);
  288. len = mdir_len;
  289. if (len != 0 && path[len - 1] != '/') {
  290. path[len]='/';
  291. len++;
  292. }
  293. path[len]=0;
  294. strncat(path, modname.s, modname.len);
  295. strcat(path, "/");
  296. strcat(path, modname.s);
  297. if(!(path_type&1))
  298. strcat(path, ".so");
  299. if (stat(path, &stat_buf) == -1) {
  300. DBG("load_module: module file not found <%s>\n", path);
  301. pkg_free(path);
  302. path=0;
  303. }
  304. }
  305. } else {
  306. /* try mod_path - S compat */
  307. if(path==mod_path) {
  308. if (stat(path, &stat_buf) == -1) {
  309. DBG("load_module: module file not found <%s>\n", path);
  310. path=0;
  311. }
  312. }
  313. if(path==0) {
  314. /* try path <MODS_DIR>/mod_path - K compat */
  315. path = (char*)pkg_malloc(mdir_len + 1 /* "/" */ +
  316. strlen(mod_path) + 1);
  317. if (path==0) goto error;
  318. memcpy(path, mdir, mdir_len);
  319. len = mdir_len;
  320. if (len != 0 && path[len - 1] != '/'){
  321. path[len]='/';
  322. len++;
  323. }
  324. path[len]=0;
  325. strcat(path, mod_path);
  326. if (stat(path, &stat_buf) == -1) {
  327. DBG("load_module: module file not found <%s>\n", path);
  328. pkg_free(path);
  329. path=0;
  330. }
  331. }
  332. }
  333. mdir=nxt_mdir?nxt_mdir+1:0;
  334. }while(path==0 && mdir);
  335. if (path==0){
  336. LOG(L_ERR, "ERROR: load_module: could not find module <%.*s> in"
  337. " <%s>\n", modname.len, modname.s, mods_dir);
  338. goto error;
  339. }
  340. }
  341. DBG("load_module: trying to load <%s>\n", path);
  342. retries=2;
  343. dlflags=RTLD_NOW;
  344. reload:
  345. handle=dlopen(path, RTLD_NOW); /* resolve all symbols now */
  346. if (handle==0){
  347. LOG(L_ERR, "ERROR: load_module: could not open module <%s>: %s\n",
  348. path, dlerror());
  349. goto error;
  350. }
  351. for(t=modules;t; t=t->next){
  352. if (t->handle==handle){
  353. LOG(L_WARN, "WARNING: load_module: attempting to load the same"
  354. " module twice (%s)\n", path);
  355. goto skip;
  356. }
  357. }
  358. /* version control */
  359. if (!version_control(handle, path)) {
  360. exit(0);
  361. }
  362. mod_if_ver = (unsigned *)dlsym(handle,
  363. DLSYM_PREFIX "module_interface_ver");
  364. if ( (error =(char*)dlerror())!=0 ){
  365. LOG(L_ERR, "ERROR: no module interface version in module <%s>\n",
  366. path );
  367. goto error1;
  368. }
  369. /* launch register */
  370. mr = (mod_register_function)dlsym(handle, DLSYM_PREFIX "mod_register");
  371. if (((error =(char*)dlerror())==0) && mr) {
  372. /* no error call it */
  373. new_dlflags=dlflags;
  374. if (mr(path, &dlflags, 0, 0)!=0) {
  375. LOG(L_ERR, "ERROR: load_module: %s: mod_register failed\n", path);
  376. goto error1;
  377. }
  378. if (new_dlflags!=dlflags && new_dlflags!=0) {
  379. /* we have to reload the module */
  380. dlclose(handle);
  381. dlflags=new_dlflags;
  382. retries--;
  383. if (retries>0) goto reload;
  384. LOG(L_ERR, "ERROR: load_module: %s: cannot agree"
  385. " on the dlflags\n", path);
  386. goto error;
  387. }
  388. }
  389. exp = (union module_exports_u*)dlsym(handle, DLSYM_PREFIX "exports");
  390. if ( (error =(char*)dlerror())!=0 ){
  391. LOG(L_ERR, "ERROR: load_module: %s\n", error);
  392. goto error1;
  393. }
  394. /* hack to allow for kamailio style dlflags inside exports */
  395. if (*mod_if_ver == 1) {
  396. new_dlflags = exp->v1.dlflags;
  397. if (new_dlflags!=dlflags && new_dlflags!=DEFAULT_DLFLAGS) {
  398. /* we have to reload the module */
  399. dlclose(handle);
  400. WARN("%s: exports dlflags interface is deprecated and it will not"
  401. "be supported in newer versions; consider using"
  402. " mod_register() instead", path);
  403. dlflags=new_dlflags;
  404. retries--;
  405. if (retries>0) goto reload;
  406. LOG(L_ERR, "ERROR: load_module: %s: cannot agree"
  407. " on the dlflags\n", path);
  408. goto error;
  409. }
  410. }
  411. if (register_module(*mod_if_ver, exp, path, handle)<0) goto error1;
  412. return 0;
  413. error1:
  414. dlclose(handle);
  415. error:
  416. skip:
  417. if (path && path!=mod_path)
  418. pkg_free(path);
  419. return -1;
  420. }
  421. /* searches the module list for function name in module mod and returns
  422. * a pointer to the "name" function record union or 0 if not found
  423. * sets also *mod_if_ver to the module interface version (needed to know
  424. * which member of the union should be accessed v0 or v1)
  425. * mod==0 is a wildcard matching all modules
  426. * flags parameter is OR value of all flags that must match
  427. */
  428. union cmd_export_u* find_mod_export_record(char* mod, char* name,
  429. int param_no, int flags,
  430. unsigned* mod_if_ver)
  431. {
  432. struct sr_module* t;
  433. union cmd_export_u* cmd;
  434. int i;
  435. unsigned mver;
  436. #define FIND_EXPORT_IN_MOD(VER) \
  437. if (t->exports->VER.cmds) \
  438. for(i=0, cmd=(void*)&t->exports->VER.cmds[0]; cmd->VER.name; \
  439. i++, cmd=(void*)&t->exports->VER.cmds[i]){\
  440. if((strcmp(name, cmd->VER.name)==0)&& \
  441. ((cmd->VER.param_no==param_no) || \
  442. (cmd->VER.param_no==VAR_PARAM_NO)) && \
  443. ((cmd->VER.flags & flags) == flags) \
  444. ){ \
  445. DBG("find_export_record: found <%s> in module %s [%s]\n", \
  446. name, t->exports->VER.name, t->path); \
  447. *mod_if_ver=mver; \
  448. return cmd; \
  449. } \
  450. }
  451. for(t=modules;t;t=t->next){
  452. if (mod!=0 && (strcmp(t->exports->c.name, mod) !=0))
  453. continue;
  454. mver=t->mod_interface_ver;
  455. switch (mver){
  456. case 0:
  457. FIND_EXPORT_IN_MOD(v0);
  458. break;
  459. case 1:
  460. FIND_EXPORT_IN_MOD(v1);
  461. break;
  462. default:
  463. BUG("invalid module interface version %d for modules %s\n",
  464. t->mod_interface_ver, t->path);
  465. }
  466. }
  467. DBG("find_export_record: <%s> not found \n", name);
  468. return 0;
  469. }
  470. /* searches the module list for function name and returns
  471. * a pointer to the "name" function record union or 0 if not found
  472. * sets also *mod_if_ver to the module interface version (needed to know
  473. * which member of the union should be accessed v0 or v1)
  474. * mod==0 is a wildcard matching all modules
  475. * flags parameter is OR value of all flags that must match
  476. */
  477. union cmd_export_u* find_export_record(char* name,
  478. int param_no, int flags,
  479. unsigned* mod_if_ver)
  480. {
  481. return find_mod_export_record(0, name, param_no, flags, mod_if_ver);
  482. }
  483. cmd_function find_export(char* name, int param_no, int flags)
  484. {
  485. union cmd_export_u* cmd;
  486. unsigned mver;
  487. cmd = find_export_record(name, param_no, flags, &mver);
  488. return cmd?cmd->c.function:0;
  489. }
  490. rpc_export_t* find_rpc_export(char* name, int flags)
  491. {
  492. return rpc_lookup((char*)name, strlen(name));
  493. }
  494. /*
  495. * searches the module list and returns pointer to "name" function in module
  496. * "mod"
  497. * 0 if not found
  498. * flags parameter is OR value of all flags that must match
  499. */
  500. cmd_function find_mod_export(char* mod, char* name, int param_no, int flags)
  501. {
  502. union cmd_export_u* cmd;
  503. unsigned mver;
  504. cmd=find_mod_export_record(mod, name, param_no, flags, &mver);
  505. if (cmd)
  506. return cmd->c.function;
  507. DBG("find_mod_export: <%s> in module <%s> not found\n", name, mod);
  508. return 0;
  509. }
  510. struct sr_module* find_module_by_name(char* mod) {
  511. struct sr_module* t;
  512. for(t = modules; t; t = t->next) {
  513. if (strcmp(mod, t->exports->c.name) == 0) {
  514. return t;
  515. }
  516. }
  517. DBG("find_module_by_name: module <%s> not found\n", mod);
  518. return 0;
  519. }
  520. void* find_param_export(struct sr_module* mod, char* name,
  521. modparam_t type_mask, modparam_t *param_type)
  522. {
  523. param_export_t* param;
  524. if (!mod)
  525. return 0;
  526. param=0;
  527. switch(mod->mod_interface_ver){
  528. case 0:
  529. param=mod->exports->v0.params;
  530. break;
  531. case 1:
  532. param=mod->exports->v1.params;
  533. break;
  534. default:
  535. BUG("bad module interface version %d in module %s [%s]\n",
  536. mod->mod_interface_ver, mod->exports->c.name, mod->path);
  537. return 0;
  538. }
  539. for(;param && param->name ; param++) {
  540. if ((strcmp(name, param->name) == 0) &&
  541. ((param->type & PARAM_TYPE_MASK(type_mask)) != 0)) {
  542. DBG("find_param_export: found <%s> in module %s [%s]\n",
  543. name, mod->exports->c.name, mod->path);
  544. *param_type = param->type;
  545. return param->param_pointer;
  546. }
  547. }
  548. DBG("find_param_export: parameter <%s> not found in module <%s>\n",
  549. name, mod->exports->c.name);
  550. return 0;
  551. }
  552. void destroy_modules()
  553. {
  554. struct sr_module* t, *foo;
  555. t=modules;
  556. while(t) {
  557. foo=t->next;
  558. if (t->exports){
  559. switch(t->mod_interface_ver){
  560. case 0:
  561. if ((t->exports->v0.destroy_f)) t->exports->v0.destroy_f();
  562. break;
  563. case 1:
  564. if ((t->exports->v1.destroy_f)) t->exports->v1.destroy_f();
  565. break;
  566. default:
  567. BUG("bad module interface version %d in module %s [%s]\n",
  568. t->mod_interface_ver, t->exports->c.name,
  569. t->path);
  570. }
  571. }
  572. pkg_free(t);
  573. t=foo;
  574. }
  575. modules=0;
  576. if (mod_response_cbks){
  577. pkg_free(mod_response_cbks);
  578. mod_response_cbks=0;
  579. }
  580. }
  581. #ifdef NO_REVERSE_INIT
  582. /*
  583. * Initialize all loaded modules, the initialization
  584. * is done *AFTER* the configuration file is parsed
  585. */
  586. int init_modules(void)
  587. {
  588. struct sr_module* t;
  589. for(t = modules; t; t = t->next) {
  590. if (t->exports){
  591. switch(t->mod_interface_ver){
  592. case 0:
  593. if (t->exports->v0.init_f)
  594. if (t->exports->v0.init_f() != 0) {
  595. LOG(L_ERR, "init_modules(): Error while"
  596. " initializing module %s\n",
  597. t->exports->v0.name);
  598. return -1;
  599. }
  600. if (t->exports->v0.response_f)
  601. mod_response_cbk_no++;
  602. break;
  603. case 1:
  604. if (t->exports->v1.init_f)
  605. if (t->exports->v1.init_f() != 0) {
  606. LOG(L_ERR, "init_modules(): Error while"
  607. " initializing module %s\n",
  608. t->exports->v1.name);
  609. return -1;
  610. }
  611. if (t->exports->v1.response_f)
  612. mod_response_cbk_no++;
  613. break;
  614. default:
  615. BUG("bad module interface version %d in module %s [%s]\n",
  616. t->exports->c.name, t->path);
  617. return -1;
  618. }
  619. }
  620. }
  621. mod_response_cbks=pkg_malloc(mod_response_cbk_no *
  622. sizeof(response_function));
  623. if (mod_response_cbks==0){
  624. LOG(L_ERR, "init_modules(): memory allocation failure"
  625. " for %d response_f callbacks\n", mod_response_cbk_no);
  626. return -1;
  627. }
  628. for (t=modules, i=0; t && (i<mod_response_cbk_no); t=t->next){
  629. if (t->exports){
  630. switch(t->mod_interface_ver){
  631. case 0:
  632. if (t->exports->v0.response_f){
  633. mod_response_cbks[i]=t->exports->v0.response_f;
  634. i++;
  635. }
  636. break;
  637. case 1:
  638. if (t->exports->v1.response_f){
  639. mod_response_cbks[i]=t->exports->v1.response_f;
  640. i++;
  641. }
  642. break;
  643. }
  644. }
  645. }
  646. return 0;
  647. }
  648. /*
  649. * per-child initialization
  650. */
  651. int init_child(int rank)
  652. {
  653. struct sr_module* t;
  654. char* type;
  655. switch(rank) {
  656. case PROC_MAIN: type = "PROC_MAIN"; break;
  657. case PROC_TIMER: type = "PROC_TIMER"; break;
  658. case PROC_FIFO: type = "PROC_FIFO"; break;
  659. case PROC_TCP_MAIN: type = "PROC_TCP_MAIN"; break;
  660. default: type = "CHILD"; break;
  661. }
  662. DBG("init_child: initializing %s with rank %d\n", type, rank);
  663. for(t = modules; t; t = t->next) {
  664. switch(t->mod_interface_ver){
  665. case 0:
  666. if (t->exports->v0.init_child_f) {
  667. if ((t->exports->v0.init_child_f(rank)) < 0) {
  668. LOG(L_ERR, "init_child(): Initialization of child"
  669. " %d failed\n", rank);
  670. return -1;
  671. }
  672. }
  673. break;
  674. case 1:
  675. if (t->exports->v1.init_child_f) {
  676. if ((t->exports->v1.init_child_f(rank)) < 0) {
  677. LOG(L_ERR, "init_child(): Initialization of child"
  678. " %d failed\n", rank);
  679. return -1;
  680. }
  681. }
  682. break;
  683. default:
  684. BUG("bad module interface version %d in module %s [%s]\n",
  685. t->mod_interface_ver, t->exports->c.name,
  686. t->path);
  687. return -1;
  688. }
  689. }
  690. return 0;
  691. }
  692. #else
  693. /* recursive module child initialization; (recursion is used to
  694. process the module linear list in the same order in
  695. which modules are loaded in config file
  696. */
  697. static int init_mod_child( struct sr_module* m, int rank )
  698. {
  699. if (m) {
  700. /* iterate through the list; if error occurs,
  701. propagate it up the stack
  702. */
  703. if (init_mod_child(m->next, rank)!=0) return -1;
  704. if (m->exports){
  705. switch(m->mod_interface_ver){
  706. case 0:
  707. if (m->exports->v0.init_child_f) {
  708. DBG("DEBUG: init_mod_child (%d): %s\n",
  709. rank, m->exports->v0.name);
  710. if (m->exports->v0.init_child_f(rank)<0) {
  711. LOG(L_ERR, "init_mod_child(): Error while"
  712. " initializing module %s\n",
  713. m->exports->v0.name);
  714. return -1;
  715. } else {
  716. /* module correctly initialized */
  717. return 0;
  718. }
  719. }
  720. /* no init function -- proceed with success */
  721. return 0;
  722. case 1:
  723. if (m->exports->v1.init_child_f) {
  724. DBG("DEBUG: init_mod_child (%d): %s\n",
  725. rank, m->exports->v1.name);
  726. if (m->exports->v1.init_child_f(rank)<0) {
  727. LOG(L_ERR, "init_mod_child(): Error while"
  728. " initializing module %s\n",
  729. m->exports->v1.name);
  730. return -1;
  731. } else {
  732. /* module correctly initialized */
  733. return 0;
  734. }
  735. }
  736. /* no init function -- proceed with success */
  737. return 0;
  738. }
  739. }
  740. /* no exports -- proceed with success */
  741. return 0;
  742. } else {
  743. /* end of list */
  744. return 0;
  745. }
  746. }
  747. /*
  748. * per-child initialization
  749. */
  750. int init_child(int rank)
  751. {
  752. return init_mod_child(modules, rank);
  753. }
  754. /* recursive module initialization; (recursion is used to
  755. process the module linear list in the same order in
  756. which modules are loaded in config file
  757. */
  758. static int init_mod( struct sr_module* m )
  759. {
  760. if (m) {
  761. /* iterate through the list; if error occurs,
  762. propagate it up the stack
  763. */
  764. if (init_mod(m->next)!=0) return -1;
  765. if (m->exports){
  766. switch(m->mod_interface_ver){
  767. case 0:
  768. if ( m->exports->v0.init_f) {
  769. DBG("DEBUG: init_mod: %s\n", m->exports->v0.name);
  770. if (m->exports->v0.init_f()!=0) {
  771. LOG(L_ERR, "init_mod(): Error while initializing"
  772. " module %s\n", m->exports->v0.name);
  773. return -1;
  774. } else {
  775. /* module correctly initialized */
  776. return 0;
  777. }
  778. }
  779. /* no init function -- proceed with success */
  780. return 0;
  781. case 1:
  782. if ( m->exports->v1.init_f) {
  783. DBG("DEBUG: init_mod: %s\n", m->exports->v1.name);
  784. if (m->exports->v1.init_f()!=0) {
  785. LOG(L_ERR, "init_mod(): Error while initializing"
  786. " module %s\n", m->exports->v1.name);
  787. return -1;
  788. } else {
  789. /* module correctly initialized */
  790. return 0;
  791. }
  792. }
  793. /* no init function -- proceed with success */
  794. return 0;
  795. }
  796. }
  797. /* no exports -- proceed with success */
  798. return 0;
  799. } else {
  800. /* end of list */
  801. return 0;
  802. }
  803. }
  804. /*
  805. * Initialize all loaded modules, the initialization
  806. * is done *AFTER* the configuration file is parsed
  807. */
  808. int init_modules(void)
  809. {
  810. struct sr_module* t;
  811. int i;
  812. for(t = modules; t; t = t->next)
  813. if (t->exports){
  814. switch(t->mod_interface_ver){
  815. case 0:
  816. if (t->exports->v0.response_f)
  817. mod_response_cbk_no++;
  818. break;
  819. case 1:
  820. if (t->exports->v1.response_f)
  821. mod_response_cbk_no++;
  822. break;
  823. }
  824. }
  825. mod_response_cbks=pkg_malloc(mod_response_cbk_no *
  826. sizeof(response_function));
  827. if (mod_response_cbks==0){
  828. LOG(L_ERR, "init_modules(): memory allocation failure"
  829. " for %d response_f callbacks\n", mod_response_cbk_no);
  830. return -1;
  831. }
  832. for (t=modules, i=0; t && (i<mod_response_cbk_no); t=t->next){
  833. if (t->exports){
  834. switch(t->mod_interface_ver){
  835. case 0:
  836. if (t->exports->v0.response_f){
  837. mod_response_cbks[i]=t->exports->v0.response_f;
  838. i++;
  839. }
  840. break;
  841. case 1:
  842. if (t->exports->v1.response_f){
  843. mod_response_cbks[i]=t->exports->v1.response_f;
  844. i++;
  845. }
  846. break;
  847. }
  848. }
  849. }
  850. return init_mod(modules);
  851. }
  852. #endif
  853. action_u_t *fixup_get_param(void **cur_param, int cur_param_no,
  854. int required_param_no)
  855. {
  856. action_u_t *a, a2;
  857. /* cur_param points to a->u.string, get pointer to a */
  858. a = (void*) ((char *)cur_param - ((char *)&a2.u.string-(char *)&a2));
  859. return a + required_param_no - cur_param_no;
  860. }
  861. int fixup_get_param_count(void **cur_param, int cur_param_no)
  862. {
  863. action_u_t *a;
  864. a = fixup_get_param(cur_param, cur_param_no, 0);
  865. if (a)
  866. return a->u.number;
  867. else
  868. return -1;
  869. }
  870. /* fixes flag params (resolves possible named flags)
  871. * use PARAM_USE_FUNC|PARAM_STRING as a param. type and create
  872. * a wrapper function that does just:
  873. * return fix_flag(type, val, "my_module", "my_param", &flag_var)
  874. * see also param_func_t.
  875. */
  876. int fix_flag( modparam_t type, void* val,
  877. char* mod_name, char* param_name, int* flag)
  878. {
  879. int num;
  880. int err;
  881. int f, len;
  882. char* s;
  883. char *p;
  884. if ((type & PARAM_STRING)==0){
  885. LOG(L_CRIT, "BUG: %s: fix_flag(%s): bad parameter type\n",
  886. mod_name, param_name);
  887. return -1;
  888. }
  889. s=(char*)val;
  890. len=strlen(s);
  891. f=-1;
  892. /* try to see if it's a number */
  893. num = str2s(s, len, &err);
  894. if (err != 0) {
  895. /* see if it's in the name:<no> format */
  896. p=strchr(s, ':');
  897. if (p){
  898. f= str2s(p+1, strlen(p+1), &err);
  899. if (err!=0){
  900. LOG(L_ERR, "ERROR: %s: invalid %s format:"
  901. " \"%s\"", mod_name, param_name, s);
  902. return -1;
  903. }
  904. *p=0;
  905. }
  906. if ((num=get_flag_no(s, len))<0){
  907. /* not declared yet, declare it */
  908. num=register_flag(s, f);
  909. }
  910. if (num<0){
  911. LOG(L_ERR, "ERROR: %s: bad %s %s\n", mod_name, param_name, s);
  912. return -1;
  913. } else if ((f>0) && (num!=f)){
  914. LOG(L_ERR, "WARNING: %s: flag %s already defined"
  915. " as %d (and not %d), using %s:%d\n",
  916. mod_name, s, num, f, s, num);
  917. }
  918. }
  919. *flag=num;
  920. return 0;
  921. }
  922. /*
  923. * Common function parameter fixups
  924. */
  925. /** Generic parameter fixup function.
  926. * Creates a fparam_t structure.
  927. * @param type contains allowed parameter types
  928. * @param param is the parameter that will be fixed-up
  929. *
  930. * @return
  931. * 0 on success,
  932. * 1 if the param doesn't match the specified type
  933. * <0 on failure
  934. */
  935. int fix_param(int type, void** param)
  936. {
  937. fparam_t* p;
  938. str name, s;
  939. unsigned int num;
  940. int err;
  941. p = (fparam_t*)pkg_malloc(sizeof(fparam_t));
  942. if (!p) {
  943. ERR("No memory left\n");
  944. return E_OUT_OF_MEM;
  945. }
  946. memset(p, 0, sizeof(fparam_t));
  947. p->orig = *param;
  948. switch(type) {
  949. case FPARAM_UNSPEC:
  950. ERR("Invalid type value\n");
  951. goto error;
  952. case FPARAM_STRING:
  953. p->v.asciiz = *param;
  954. /* no break */
  955. case FPARAM_STR:
  956. p->v.str.s = (char*)*param;
  957. p->v.str.len = strlen(p->v.str.s);
  958. p->fixed = &p->v;
  959. break;
  960. case FPARAM_INT:
  961. s.s = (char*)*param;
  962. s.len = strlen(s.s);
  963. err = str2int(&s, &num);
  964. if (err == 0) {
  965. p->v.i = (int)num;
  966. } else {
  967. /* Not a number */
  968. pkg_free(p);
  969. return 1;
  970. }
  971. p->fixed = (void*)(long)num;
  972. break;
  973. case FPARAM_REGEX:
  974. if ((p->v.regex = pkg_malloc(sizeof(regex_t))) == 0) {
  975. ERR("No memory left\n");
  976. goto error;
  977. }
  978. if (regcomp(p->v.regex, *param,
  979. REG_EXTENDED|REG_ICASE|REG_NEWLINE)) {
  980. pkg_free(p->v.regex);
  981. p->v.regex=0;
  982. /* not a valid regex */
  983. goto no_match;
  984. }
  985. p->fixed = p->v.regex;
  986. break;
  987. case FPARAM_AVP:
  988. name.s = (char*)*param;
  989. name.len = strlen(name.s);
  990. trim(&name);
  991. if (!name.len || name.s[0] != '$') {
  992. /* Not an AVP identifier */
  993. goto no_match;
  994. }
  995. name.s++;
  996. name.len--;
  997. if (parse_avp_ident(&name, &p->v.avp) < 0) {
  998. /* invalid avp identifier (=> no match) */
  999. goto no_match;
  1000. }
  1001. p->fixed = &p->v;
  1002. break;
  1003. case FPARAM_SELECT:
  1004. name.s = (char*)*param;
  1005. name.len = strlen(name.s);
  1006. trim(&name);
  1007. if (!name.len || name.s[0] != '@') {
  1008. /* Not a select identifier */
  1009. goto no_match;
  1010. }
  1011. if (parse_select(&name.s, &p->v.select) < 0) {
  1012. ERR("Error while parsing select identifier\n");
  1013. goto error;
  1014. }
  1015. p->fixed = &p->v;
  1016. break;
  1017. case FPARAM_SUBST:
  1018. s.s = *param;
  1019. s.len = strlen(s.s);
  1020. p->v.subst = subst_parser(&s);
  1021. if (!p->v.subst) {
  1022. ERR("Error while parsing regex substitution\n");
  1023. goto error;
  1024. }
  1025. p->fixed = &p->v;
  1026. break;
  1027. case FPARAM_PVS:
  1028. name.s = (char*)*param;
  1029. name.len = strlen(name.s);
  1030. trim(&name);
  1031. if (!name.len || name.s[0] != '$'){
  1032. /* not a pvs identifier */
  1033. goto no_match;
  1034. }
  1035. p->v.pvs=pkg_malloc(sizeof(pv_spec_t));
  1036. if (p->v.pvs==0){
  1037. ERR("out of memory while parsing pv_spec_t\n");
  1038. goto error;
  1039. }
  1040. if (pv_parse_spec2(&name, p->v.pvs, 1)==0){
  1041. /* not a valid pvs identifier (but it might be an avp) */
  1042. pkg_free(p->v.pvs);
  1043. p->v.pvs=0;
  1044. goto no_match;
  1045. }
  1046. p->fixed = p->v.pvs;
  1047. break;
  1048. case FPARAM_PVE:
  1049. name.s = (char*)*param;
  1050. name.len = strlen(name.s);
  1051. if (pv_parse_format(&name, &p->v.pve)<0){
  1052. ERR("bad PVE format: \"%.*s\"\n", name.len, name.s);
  1053. goto error;
  1054. }
  1055. p->fixed = &p->v;
  1056. break;
  1057. }
  1058. p->type = type;
  1059. *param = (void*)p;
  1060. return 0;
  1061. no_match:
  1062. pkg_free(p);
  1063. return 1;
  1064. error:
  1065. pkg_free(p);
  1066. return E_UNSPEC;
  1067. }
  1068. /** fparam_t free function.
  1069. * Frees the "content" of a fparam, but not the fparam itself.
  1070. * Assumes pkg_malloc'ed content.
  1071. * @param fp - fparam to be freed
  1072. *
  1073. */
  1074. void fparam_free_contents(fparam_t* fp)
  1075. {
  1076. if (fp==0)
  1077. return;
  1078. switch(fp->type) {
  1079. case FPARAM_UNSPEC:
  1080. case FPARAM_STRING: /* asciiz string, not str */
  1081. case FPARAM_INT:
  1082. case FPARAM_STR:
  1083. /* nothing to do */
  1084. break;
  1085. case FPARAM_REGEX:
  1086. if (fp->v.regex){
  1087. regfree(fp->v.regex);
  1088. pkg_free(fp->v.regex);
  1089. fp->v.regex=0;
  1090. }
  1091. break;
  1092. case FPARAM_AVP:
  1093. free_avp_name(&fp->v.avp.flags, &fp->v.avp.name);
  1094. break;
  1095. case FPARAM_SELECT:
  1096. if (fp->v.select){
  1097. free_select(fp->v.select);
  1098. fp->v.select=0;
  1099. }
  1100. break;
  1101. case FPARAM_SUBST:
  1102. if (fp->v.subst){
  1103. subst_expr_free(fp->v.subst);
  1104. fp->v.subst=0;
  1105. }
  1106. break;
  1107. case FPARAM_PVS:
  1108. if (fp->v.pvs){
  1109. pv_spec_free(fp->v.pvs);
  1110. fp->v.pvs=0;
  1111. }
  1112. break;
  1113. case FPARAM_PVE:
  1114. if (fp->v.pve){
  1115. pv_elem_free_all(fp->v.pve);
  1116. fp->v.pve=0;
  1117. }
  1118. break;
  1119. }
  1120. if (fp->orig){
  1121. pkg_free(fp->orig);
  1122. fp->orig=0;
  1123. }
  1124. }
  1125. /** fix a param to one of the given types (mask).
  1126. *
  1127. * @param types - bitmap of the allowed types (e.g. FPARAM_INT|FPARAM_STR)
  1128. * @param param - value/result
  1129. * @return - 0 on success, -1 on error, 1 if param doesn't
  1130. * match any of the types
  1131. */
  1132. int fix_param_types(int types, void** param)
  1133. {
  1134. int ret;
  1135. int t;
  1136. for (t=types & ~(types-1); types; types&=(types-1), t=types & ~(types-1)){
  1137. if ((ret=fix_param(t, param))<=0) return ret;
  1138. }
  1139. return E_UNSPEC;
  1140. }
  1141. /*
  1142. * Fixup variable string, the parameter can be
  1143. * AVP, SELECT, or ordinary string. AVP and select
  1144. * identifiers will be resolved to their values during
  1145. * runtime
  1146. *
  1147. * The parameter value will be converted to fparam structure
  1148. * This function returns -1 on an error
  1149. */
  1150. int fixup_var_str_12(void** param, int param_no)
  1151. {
  1152. int ret;
  1153. if ((sr_cfg_compat!=SR_COMPAT_SER) &&
  1154. ((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret;
  1155. if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret;
  1156. if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret;
  1157. if ((ret = fix_param(FPARAM_STR, param)) <= 0) return ret;
  1158. ERR("Error while fixing parameter, AVP, SELECT, and str conversions"
  1159. " failed\n");
  1160. return -1;
  1161. }
  1162. /* Same as fixup_var_str_12 but applies to the 1st parameter only */
  1163. int fixup_var_str_1(void** param, int param_no)
  1164. {
  1165. if (param_no == 1) return fixup_var_str_12(param, param_no);
  1166. else return 0;
  1167. }
  1168. /* Same as fixup_var_str_12 but applies to the 2nd parameter only */
  1169. int fixup_var_str_2(void** param, int param_no)
  1170. {
  1171. if (param_no == 2) return fixup_var_str_12(param, param_no);
  1172. else return 0;
  1173. }
  1174. /*
  1175. * Fixup variable integer, the parameter can be
  1176. * AVP, SELECT, or ordinary integer. AVP and select
  1177. * identifiers will be resolved to their values and
  1178. * converted to int if necessary during runtime
  1179. *
  1180. * The parameter value will be converted to fparam structure
  1181. * This function returns -1 on an error
  1182. */
  1183. int fixup_var_int_12(void** param, int param_no)
  1184. {
  1185. int ret;
  1186. if ((sr_cfg_compat!=SR_COMPAT_SER) &&
  1187. ((ret = fix_param(FPARAM_PVS, param)) <= 0)) return ret;
  1188. if ((ret = fix_param(FPARAM_AVP, param)) <= 0) return ret;
  1189. if ((ret = fix_param(FPARAM_SELECT, param)) <= 0) return ret;
  1190. if ((ret = fix_param(FPARAM_INT, param)) <= 0) return ret;
  1191. ERR("Error while fixing parameter, AVP, SELECT, and int conversions"
  1192. " failed\n");
  1193. return -1;
  1194. }
  1195. /* Same as fixup_var_int_12 but applies to the 1st parameter only */
  1196. int fixup_var_int_1(void** param, int param_no)
  1197. {
  1198. if (param_no == 1) return fixup_var_int_12(param, param_no);
  1199. else return 0;
  1200. }
  1201. /* Same as fixup_var_int_12 but applies to the 2nd parameter only */
  1202. int fixup_var_int_2(void** param, int param_no)
  1203. {
  1204. if (param_no == 2) return fixup_var_int_12(param, param_no);
  1205. else return 0;
  1206. }
  1207. /*
  1208. * The parameter must be a regular expression which must compile, the
  1209. * parameter will be converted to compiled regex
  1210. */
  1211. int fixup_regex_12(void** param, int param_no)
  1212. {
  1213. int ret;
  1214. if ((ret = fix_param(FPARAM_REGEX, param)) <= 0) return ret;
  1215. ERR("Error while compiling regex in function parameter\n");
  1216. return -1;
  1217. }
  1218. /* Same as fixup_regex_12 but applies to the 1st parameter only */
  1219. int fixup_regex_1(void** param, int param_no)
  1220. {
  1221. if (param_no == 1) return fixup_regex_12(param, param_no);
  1222. else return 0;
  1223. }
  1224. /* Same as fixup_regex_12 but applies to the 2nd parameter only */
  1225. int fixup_regex_2(void** param, int param_no)
  1226. {
  1227. if (param_no == 2) return fixup_regex_12(param, param_no);
  1228. else return 0;
  1229. }
  1230. /*
  1231. * The string parameter will be converted to integer
  1232. */
  1233. int fixup_int_12(void** param, int param_no)
  1234. {
  1235. int ret;
  1236. if ((ret = fix_param(FPARAM_INT, param)) <= 0) return ret;
  1237. ERR("Cannot function parameter to integer\n");
  1238. return -1;
  1239. }
  1240. /* Same as fixup_int_12 but applies to the 1st parameter only */
  1241. int fixup_int_1(void** param, int param_no)
  1242. {
  1243. if (param_no == 1) return fixup_int_12(param, param_no);
  1244. else return 0;
  1245. }
  1246. /* Same as fixup_int_12 but applies to the 2nd parameter only */
  1247. int fixup_int_2(void** param, int param_no)
  1248. {
  1249. if (param_no == 2) return fixup_int_12(param, param_no);
  1250. else return 0;
  1251. }
  1252. /*
  1253. * Parse the parameter as static string, do not resolve
  1254. * AVPs or selects, convert the parameter to str structure
  1255. */
  1256. int fixup_str_12(void** param, int param_no)
  1257. {
  1258. int ret;
  1259. if ((ret = fix_param(FPARAM_STR, param)) <= 0) return ret;
  1260. ERR("Cannot function parameter to string\n");
  1261. return -1;
  1262. }
  1263. /* Same as fixup_str_12 but applies to the 1st parameter only */
  1264. int fixup_str_1(void** param, int param_no)
  1265. {
  1266. if (param_no == 1) return fixup_str_12(param, param_no);
  1267. else return 0;
  1268. }
  1269. /* Same as fixup_str_12 but applies to the 2nd parameter only */
  1270. int fixup_str_2(void** param, int param_no)
  1271. {
  1272. if (param_no == 2) return fixup_str_12(param, param_no);
  1273. else return 0;
  1274. }
  1275. #define PV_PRINT_BUF_SIZE 1024
  1276. #define PV_PRINT_BUF_NO 3
  1277. /** Get the function parameter value as string.
  1278. * @return 0 - Success
  1279. * -1 - Cannot get value
  1280. */
  1281. int get_str_fparam(str* dst, struct sip_msg* msg, fparam_t* param)
  1282. {
  1283. int_str val;
  1284. int ret;
  1285. avp_t* avp;
  1286. pv_value_t pv_val;
  1287. static int buf_itr = 0; /* ugly hack needed for PVE */
  1288. static char pve_buf[PV_PRINT_BUF_NO][PV_PRINT_BUF_SIZE];
  1289. switch(param->type) {
  1290. case FPARAM_REGEX:
  1291. case FPARAM_UNSPEC:
  1292. case FPARAM_INT:
  1293. return -1;
  1294. case FPARAM_STRING:
  1295. dst->s = param->v.asciiz;
  1296. dst->len = strlen(param->v.asciiz);
  1297. break;
  1298. case FPARAM_STR:
  1299. *dst = param->v.str;
  1300. break;
  1301. case FPARAM_AVP:
  1302. avp = search_first_avp(param->v.avp.flags, param->v.avp.name,
  1303. &val, 0);
  1304. if (unlikely(!avp)) {
  1305. DBG("Could not find AVP from function parameter '%s'\n",
  1306. param->orig);
  1307. return -1;
  1308. }
  1309. if (likely(avp->flags & AVP_VAL_STR)) {
  1310. *dst = val.s;
  1311. } else {
  1312. /* The caller does not know of what type the AVP will be so
  1313. * convert int AVPs into string here
  1314. */
  1315. dst->s = int2str(val.n, &dst->len);
  1316. }
  1317. break;
  1318. case FPARAM_SELECT:
  1319. ret = run_select(dst, param->v.select, msg);
  1320. if (unlikely(ret < 0 || ret > 0)) return -1;
  1321. break;
  1322. case FPARAM_PVS:
  1323. if (likely((pv_get_spec_value(msg, param->v.pvs, &pv_val)==0) &&
  1324. ((pv_val.flags&(PV_VAL_NULL|PV_VAL_STR))==PV_VAL_STR))){
  1325. *dst=pv_val.rs;
  1326. }else{
  1327. ERR("Could not convert PV to str\n");
  1328. return -1;
  1329. }
  1330. break;
  1331. case FPARAM_PVE:
  1332. dst->s=pve_buf[buf_itr];
  1333. dst->len=PV_PRINT_BUF_SIZE;
  1334. buf_itr = (buf_itr+1)%PV_PRINT_BUF_NO;
  1335. if (unlikely(pv_printf(msg, param->v.pve, dst->s, &dst->len)!=0)){
  1336. ERR("Could not convert the PV-formated string to str\n");
  1337. dst->len=0;
  1338. return -1;
  1339. };
  1340. break;
  1341. }
  1342. return 0;
  1343. }
  1344. /** Get the function parameter value as integer.
  1345. * @return 0 - Success
  1346. * -1 - Cannot get value
  1347. */
  1348. int get_int_fparam(int* dst, struct sip_msg* msg, fparam_t* param)
  1349. {
  1350. int_str val;
  1351. int ret;
  1352. avp_t* avp;
  1353. str tmp;
  1354. pv_value_t pv_val;
  1355. switch(param->type) {
  1356. case FPARAM_INT:
  1357. *dst = param->v.i;
  1358. return 0;
  1359. case FPARAM_REGEX:
  1360. case FPARAM_UNSPEC:
  1361. case FPARAM_STRING:
  1362. case FPARAM_STR:
  1363. return -1;
  1364. case FPARAM_AVP:
  1365. avp = search_first_avp(param->v.avp.flags, param->v.avp.name,
  1366. &val, 0);
  1367. if (unlikely(!avp)) {
  1368. DBG("Could not find AVP from function parameter '%s'\n",
  1369. param->orig);
  1370. return -1;
  1371. }
  1372. if (avp->flags & AVP_VAL_STR) {
  1373. if (str2int(&val.s, (unsigned int*)dst) < 0) {
  1374. ERR("Could not convert AVP string value to int\n");
  1375. return -1;
  1376. }
  1377. } else {
  1378. *dst = val.n;
  1379. }
  1380. break;
  1381. case FPARAM_SELECT:
  1382. ret = run_select(&tmp, param->v.select, msg);
  1383. if (unlikely(ret < 0 || ret > 0)) return -1;
  1384. if (unlikely(str2int(&tmp, (unsigned int*)dst) < 0)) {
  1385. ERR("Could not convert select result to int\n");
  1386. return -1;
  1387. }
  1388. break;
  1389. case FPARAM_PVS:
  1390. if (likely((pv_get_spec_value(msg, param->v.pvs, &pv_val)==0) &&
  1391. ((pv_val.flags&(PV_VAL_NULL|PV_VAL_INT))==PV_VAL_INT))){
  1392. *dst=pv_val.ri;
  1393. }else{
  1394. ERR("Could not convert PV to int\n");
  1395. return -1;
  1396. }
  1397. break;
  1398. case FPARAM_PVE:
  1399. return -1;
  1400. }
  1401. return 0;
  1402. }
  1403. /**
  1404. * Retrieve the compiled RegExp.
  1405. * @return: 0 for success, negative on error.
  1406. */
  1407. int get_regex_fparam(regex_t *dst, struct sip_msg* msg, fparam_t* param)
  1408. {
  1409. switch (param->type) {
  1410. case FPARAM_REGEX:
  1411. *dst = *param->v.regex;
  1412. return 0;
  1413. default:
  1414. ERR("unexpected parameter type (%d), instead of regexp.\n",
  1415. param->type);
  1416. }
  1417. return -1;
  1418. }