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