static int fixup_insert_avp(void** param, int param_no) { pv_elem_t* pv_elem; str s; if(param_no== 0) return 0; if(!param) { LM_ERR( "null format\n"); return E_UNSPEC; } s.s = (char*)(*param); s.len = strlen(s.s); if(param_no == 3) /* the third argumet in an integer */ { unsigned int* index; index = (unsigned int*)pkg_malloc(sizeof(unsigned int*)); if(index == NULL) { LM_ERR("No more memory\n"); return E_OUT_OF_MEM; } if(str2int(&s, index) < 0) { LM_ERR("Bad format for the third argument - must be a positive integer\n"); return E_UNSPEC; } *param = (void*)index; return 0; } if(pv_parse_format(&s, &pv_elem)<0) { LM_ERR( "wrong format[%s]\n",(char*)(*param)); return E_UNSPEC; } *param = (void*)pv_elem; /* attr name is mandatory */ if (param_no == 1 && pv_elem->spec.type!=PVT_AVP) { LM_ERR("The first parameter must be an AVP name\n"); return E_UNSPEC; } *param = (void*)pv_elem; return 0; }
void log_prefix_init(void) { str s; if(log_prefix_fmt==NULL) return; s.s = log_prefix_fmt; s.len = strlen(s.s); if(pv_parse_format(&s, &log_prefix_pvs)<0) { LM_ERR("wrong format[%s]\n", s.s); return; } }
static int acc_fixup(void** param, int param_no) { struct acc_param *accp; char *p; p = (char*)*param; if (p==0 || p[0]==0) { LM_ERR("first parameter is empty\n"); return E_SCRIPT; } if (param_no == 1) { accp = (struct acc_param*)pkg_malloc(sizeof(struct acc_param)); if (!accp) { LM_ERR("no more pkg mem\n"); return E_OUT_OF_MEM; } memset( accp, 0, sizeof(struct acc_param)); accp->reason.s = p; accp->reason.len = strlen(p); if (strchr(p,PV_MARKER)!=NULL) { /* is a variable $xxxxx */ if (pv_parse_format(&accp->reason, &accp->elem)<0) { LM_ERR("bad param 1 - parse format error [%.*s]\n", accp->reason.len, accp->reason.s); pkg_free(accp); return E_UNSPEC; } } else { if(acc_parse_code(p,accp)<0) { LM_ERR("bad param 1 - parse code error\n"); pkg_free(accp); return E_UNSPEC; } } *param = (void*)accp; #ifdef SQL_ACC } else if (param_no == 2) { /* only for db acc - the table name */ if (db_url.s==0) { pkg_free(p); *param = 0; } else { return fixup_var_pve_str_12(param, 2); } #endif } return 0; }
int pv_parse_name(pv_spec_p sp, str *in) { stat_var *stat; pv_elem_t *format; if(in==NULL || in->s==NULL || sp==NULL) return -1; LM_NOTICE("xXx name %p with name <%.*s>\n", &sp->pvp.pvn, in->len, in->s); if (pv_parse_format( in, &format)!=0) { LM_ERR("failed to parse statistic name format <%.*s> \n", in->len,in->s); return -1; } /* text only ? */ if (format->next==NULL && format->spec.type==PVT_NONE) { /* search for the statistic */ stat = get_stat( &format->text ); if (stat==NULL) { /* statistic does not exist (yet) -> fill in the string name */ sp->pvp.pvn.type = PV_NAME_INTSTR; sp->pvp.pvn.u.isname.type = AVP_NAME_STR; if (clone_pv_stat_name( in, &sp->pvp.pvn.u.isname.name.s )!=0) { LM_ERR("failed to clone name of statistic \n"); return -1; } LM_NOTICE("xXx name %p, name cloned (in=%p, out=%p)\n", &sp->pvp.pvn, in->s, sp->pvp.pvn.u.isname.name.s.s); } else { /* link the stat pointer directly as dynamic name */ sp->pvp.pvn.type = PV_NAME_PVAR; sp->pvp.pvn.u.dname = (void*)stat; LM_NOTICE("xXx name %p, stat found\n", &sp->pvp.pvn); } } else { sp->pvp.pvn.type = PV_NAME_INTSTR; sp->pvp.pvn.u.isname.type = 0; /* not string */ sp->pvp.pvn.u.isname.name.s.s = (char*)(void*)format; sp->pvp.pvn.u.isname.name.s.len = 0; LM_NOTICE("xXx name %p, stat name is FMT\n", &sp->pvp.pvn); } return 0; }
static int fixup_db_query_avp(void** param, int param_no) { pv_elem_t *model = NULL; pvname_list_t *anlist = NULL; str s; if (db_url.s==0) { LM_ERR("you have to configure db_url for using avp_db_query function\n"); return E_UNSPEC; } s.s = (char*)(*param); if (param_no==1) { if(s.s==NULL) { LM_ERR("null format in P%d\n", param_no); return E_UNSPEC; } s.len = strlen(s.s); if(pv_parse_format(&s, &model)<0) { LM_ERR("wrong format[%s]\n", s.s); return E_UNSPEC; } *param = (void*)model; return 0; } else if(param_no==2) { if(s.s==NULL) { LM_ERR("null format in P%d\n", param_no); return E_UNSPEC; } s.len = strlen(s.s); anlist = parse_pvname_list(&s, PVT_AVP); if(anlist==NULL) { LM_ERR("bad format in P%d [%s]\n", param_no, s.s); return E_UNSPEC; } *param = (void*)anlist; return 0; } return 0; }
static int fixup_db_query_avp(void** param, int param_no) { pv_elem_t *model = NULL; pvname_list_t *anlist = NULL; str s; if (default_db_url==NULL) { LM_ERR("no db url defined to be used by this function\n"); return E_CFG; } s.s = (char*)(*param); if (param_no==1) { if(s.s==NULL) { LM_ERR("null format in P%d\n", param_no); return E_UNSPEC; } s.len = strlen(s.s); if(pv_parse_format(&s, &model)<0) { LM_ERR("wrong format[%s]\n", s.s); return E_UNSPEC; } *param = (void*)model; return 0; } else if(param_no==2) { if(s.s==NULL || s.s[0]==0) { *param = NULL; return 0; } s.len = strlen(s.s); anlist = parse_pvname_list(&s, PVT_AVP); if(anlist==NULL) { LM_ERR("bad format in P%d [%s]\n", param_no, s.s); return E_UNSPEC; } *param = (void*)anlist; return 0; } else if (param_no==3) { return fixup_db_url(param); } return 0; }
/** * fixes the module functions' parameters if it is a phone number. * supports string, pseudo-variables and AVPs. * * @param param the parameter * * @return 0 on success, -1 on failure */ static int mp_fixup(void ** param) { pv_spec_t avp_spec; struct multiparam_t *mp; str s; mp = (struct multiparam_t *)pkg_malloc(sizeof(struct multiparam_t)); if (mp == NULL) { LM_ERR("out of pkg memory\n"); return -1; } memset(mp, 0, sizeof(struct multiparam_t)); s.s = (char *)(*param); s.len = strlen(s.s); if (s.s[0]!='$') { /* This is string */ mp->type=MP_STR; mp->u.s=s; } else { /* This is a pseudo-variable */ if (pv_parse_spec(&s, &avp_spec)==0) { LM_ERR("pv_parse_spec failed for '%s'\n", (char *)(*param)); pkg_free(mp); return -1; } if (avp_spec.type==PVT_AVP) { /* This is an AVP - could be an id or name */ mp->type=MP_AVP; if(pv_get_avp_name(0, &(avp_spec.pvp), &(mp->u.a.name), &(mp->u.a.flags))!=0) { LM_ERR("Invalid AVP definition <%s>\n", (char *)(*param)); pkg_free(mp); return -1; } } else { mp->type=MP_PVE; if(pv_parse_format(&s, &(mp->u.p))<0) { LM_ERR("pv_parse_format failed for '%s'\n", (char *)(*param)); pkg_free(mp); return -1; } } } *param = (void*)mp; return 0; }
/** * fixes the module functions' parameters with generic pseudo variable support. * * @param param the parameter * * @return 0 on success, -1 on failure */ static int pv_fixup(void ** param) { pv_elem_t *model; str s; s.s = (char *)(*param); s.len = strlen(s.s); if (s.len <= 0) return -1; /* Check the format */ if(pv_parse_format(&s, &model)<0) { LM_ERR("pv_parse_format failed for '%s'\n", (char *)(*param)); return -1; } *param = (void*)model; return 0; }
static int it_list_fixup(void** param, int param_no) { pv_elem_t *model; str s; if(*param) { s.s = (char*)(*param); s.len = strlen(s.s); if(pv_parse_format(&s, &model)<0) { LM_ERR("wrong format[%s]\n",(char*)(*param)); return E_UNSPEC; } *param = (void*)model; } return 0; }
static int fixup_b2b_logic(void** param, int param_no) { pv_elem_t *model; str s; if(param_no== 0) return 0; if(*param) { s.s = (char*)(*param); s.len = strlen(s.s); if(pv_parse_format(&s, &model)<0) { LM_ERR( "wrong format[%s]\n",(char*)(*param)); return E_UNSPEC; } /* the first parameter must be the scenario id and must be a string */ if(param_no == 1) { if(model->spec.type != PVT_NONE ) { LM_ERR("The first parameter is not a string\n"); return -1; } if(s.len == B2B_TOP_HIDING_SCENARY_LEN && strncmp(s.s,B2B_TOP_HIDING_SCENARY,B2B_TOP_HIDING_SCENARY_LEN)==0) { *param = NULL; return 0; } *param = get_scenario_id_list(&s, script_scenarios); if(*param) return 0; LM_ERR("Wrong Scenary ID. No scenario with this ID [%.*s]\n", s.len, s.s); return E_UNSPEC; } *param = (void*)model; return 0; } LM_ERR( "null format\n"); return E_UNSPEC; }
static int ldap_filter_url_encode_fixup(void** param, int param_no) { pv_elem_t *elem_p; pv_spec_t *spec_p; str s; if (param_no == 1) { s.s = (char*)*param; if (s.s==0 || s.s[0]==0) { elem_p = 0; } else { s.len = strlen(s.s); if (pv_parse_format(&s, &elem_p) < 0) { LM_ERR("pv_parse_format failed\n"); return E_OUT_OF_MEM; } } *param = (void*)elem_p; } else if (param_no == 2) { spec_p = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t)); if (spec_p == NULL) { LM_ERR("no memory\n"); return E_OUT_OF_MEM; } s.s = (char*)*param; s.len = strlen(s.s); if (pv_parse_spec(&s, spec_p) == 0) { pkg_free(spec_p); LM_ERR("parse error for [%s]\n", (char*)*param); return E_UNSPEC; } if (spec_p->type != PVT_AVP) { pkg_free(spec_p); LM_ERR("bad attribute name" " [%s]\n", (char*)*param); return E_UNSPEC; } *param = (void*)spec_p; } return 0; }
/* * * fixup_sig_send_reply */ static int fixup_sig_send_reply(void** param, int param_no) { pv_elem_t *model=NULL; str s; /* convert to str */ s.s = (char*)*param; s.len = strlen(s.s); model=NULL; if (param_no==1 || param_no==2) { if(s.len==0) { LM_ERR("no param %d!\n", param_no); return E_UNSPEC; } if(pv_parse_format(&s ,&model) || model==NULL) { LM_ERR("wrong format [%s] for param no %d!\n", s.s, param_no); return E_UNSPEC; } if(model->spec.getf==NULL) { if(param_no==1) { if(str2int(&s, (unsigned int*)&model->spec.pvp.pvn.u.isname.name.n)!=0 || model->spec.pvp.pvn.u.isname.name.n<100 || model->spec.pvp.pvn.u.isname.name.n>699) { LM_ERR("wrong value [%s] for param no %d!\n", s.s, param_no); LM_ERR("allowed values: 1xx - 6xx only!\n"); return E_UNSPEC; } } } *param = (void*)model; } return 0; }
/* * Convert char* parameter to pv_elem_t* parameter */ static int auth_fixup(void** param, int param_no) { pv_elem_t *model; str s; pv_spec_t *sp; if (param_no == 1) { /* realm (string that may contain pvars) */ s.s = (char*)*param; if (s.s==0 || s.s[0]==0) { model = 0; } else { s.len = strlen(s.s); if (pv_parse_format(&s,&model)<0) { LM_ERR("pv_parse_format failed\n"); return E_OUT_OF_MEM; } } *param = (void*)model; } if (param_no == 2) { /* URI user (a pvar) */ sp = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t)); if (sp == 0) { LM_ERR("no pkg memory left\n"); return -1; } s.s = (char*)*param; s.len = strlen(s.s); if (pv_parse_spec(&s, sp) == 0) { LM_ERR("parsing of pseudo variable %s failed!\n", (char*)*param); pkg_free(sp); return -1; } if (sp->type == PVT_NULL) { LM_ERR("bad pseudo variable\n"); pkg_free(sp); return -1; } *param = (void*)sp; } return 0; }
static int fixup_evaluate_exp(void **param, int param_no) { pv_elem_p ep; pv_spec_p sp; str s; if (param_no != 1 && param_no != 2) { LM_ERR("Invalid parameter number: %d\n", param_no); return E_UNSPEC; } if (param_no == 1) { s.s = (char*)(*param); s.len = strlen(s.s); if (pv_parse_format(&s, &ep) < 0) { LM_ERR("wrong format[%.*s]\n", s.len, s.s); return E_UNSPEC; } *param = (void *)ep; return 0; } else { if (!(sp = pkg_malloc(sizeof(*sp)))) { LM_ERR("No more pkg memory!\n"); return -1; } memset(sp, 0, sizeof(*sp)); s.s = (char *)*param; s.len = strlen(s.s); if (!pv_parse_spec(&s, sp)) { LM_ERR("Parameter 2 only accepts pvars! Given: <%.*s>\n", s.len, s.s); return -1; } *param = (void *)sp; return 0; } }
static int check_user_blacklist_fixup(void** param, int param_no) { pv_elem_t *model=NULL; str s; /* convert to str */ s.s = (char*)*param; s.len = strlen(s.s); if (param_no > 0 && param_no <= 4) { if(s.len == 0 && param_no != 4) { LM_ERR("no parameter %d\n", param_no); return E_UNSPEC; } if(pv_parse_format(&s, &model) < 0 || !model) { LM_ERR("wrong format [%.*s] for parameter %d\n", s.len, s.s, param_no); return E_UNSPEC; } if(!model->spec.getf) { if(param_no == 1) { if(str2int(&s, (unsigned int*)&model->spec.pvp.pvn.u.isname.name.n) != 0) { LM_ERR("wrong value [%.*s] for parameter %d\n", s.len, s.s, param_no); return E_UNSPEC; } } else { if(param_no == 2 || param_no == 3) { LM_ERR("wrong value [%.*s] for parameter %d\n", s.len, s.s, param_no); return E_UNSPEC; } else { // only a string return 0; } } } *param = (void*)model; } else { LM_ERR("wrong number of parameters\n"); } return 0; }
int pv_printf_fixup(void** param, int param_no) { pv_spec_t *spec=NULL; pv_elem_t *pvmodel=NULL; str tstr; if(param_no==1) { spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t)); if(spec==NULL) { LM_ERR("out of pkg\n"); return -1; } memset(spec, 0, sizeof(pv_spec_t)); tstr.s = (char*)(*param); tstr.len = strlen(tstr.s); if(pv_parse_spec(&tstr, spec)==NULL) { LM_ERR("unknown script variable in first parameter"); pkg_free(spec); return -1; } if(!pv_is_w(spec)) { LM_ERR("read-only script variable in first parameter"); pkg_free(spec); return -1; } *param = spec; } else if(param_no==2) { pvmodel = 0; tstr.s = (char*)(*param); tstr.len = strlen(tstr.s); if(pv_parse_format(&tstr, &pvmodel)<0) { LM_ERR("error in second parameter"); return -1; } *param = pvmodel; } return 0; }
static int fixup_xcaps_put(void** param, int param_no) { str s; pv_elem_t *xm; if (param_no == 1) { return fixup_spve_null(param, 1); } else if (param_no == 2) { return fixup_spve_null(param, 1); } else if (param_no == 3) { s.s = (char*)(*param); s.len = strlen(s.s); if(pv_parse_format(&s, &xm)<0) { LM_ERR("wrong format[%s]\n", (char*)(*param)); return E_UNSPEC; } *param = (void*)xm; return 0; } return 0; }
int fixup_subscribe(void** param, int param_no) { pv_elem_t *model; str s; if (param_no == 1) { if(*param) { s.s = (char*)(*param); s.len = strlen(s.s); if(pv_parse_format(&s, &model)<0) { LM_ERR("wrong format[%s]\n",(char*)(*param)); return E_UNSPEC; } *param = (void*)model; return 1; } LM_ERR("null format\n"); return E_UNSPEC; } else if (param_no == 2) { return fixup_igp_igp(param, param_no); } else return 1; }
static int fixup_replace_disp_uri(void** param, int param_no) { pv_elem_t *model; char *p; str s; /* convert to str */ s.s = (char*)*param; s.len = strlen(s.s); model=NULL; if (param_no==1 && s.len) { /* check to see if it is already quoted */ if ((s.s[0] == '\"' && s.s[s.len - 1] == '\"') || str_check_token(&s)) goto unquoted; /* put " around display name */ p = (char*)pkg_malloc(s.len+3); if (p==0) { LM_CRIT("no more pkg mem\n"); return E_OUT_OF_MEM; } p[0] = '\"'; memcpy(p+1, s.s, s.len); p[s.len+1] = '\"'; p[s.len+2] = '\0'; pkg_free(s.s); s.s = p; s.len += 2; } unquoted: if(pv_parse_format(&s ,&model)<0) { LM_ERR("wrong format [%s] for param no %d!\n", s.s, param_no); pkg_free(s.s); return E_UNSPEC; } *param = (void*)model; return 0; }
static int one_str_pv_elem_fixup(void** param, int param_no) { pv_elem_t *model; str s; if (param_no == 1) { s.s = (char*)*param; if (s.s==0 || s.s[0]==0) { model = 0; } else { s.len = strlen(s.s); if (pv_parse_format(&s,&model)<0) { LM_ERR("pv_parse_format failed\n"); return E_OUT_OF_MEM; } } *param = (void*)model; } return 0; }
static int ldap_search_fixup(void** param, int param_no) { pv_elem_t *model; str s; if (param_no == 1) { s.s = (char*)*param; s.len = strlen(s.s); if (s.len==0) { LM_ERR("ldap url is empty string!\n"); return E_CFG; } if ( pv_parse_format(&s,&model) || model==NULL) { LM_ERR("wrong format [%s] for ldap url!\n", s.s); return E_CFG; } *param = (void*)model; } return 0; }
static int fixup_dlg_sval(void** param, int param_no) { pv_elem_t *model=NULL; str s; s.s = (char*)*param; s.len = strlen(s.s); if (param_no==1) { /* name of the value */ return fixup_str(param); } else if (param_no==2) { /* value */ if(pv_parse_format(&s ,&model) || model==NULL) { LM_ERR("wrong format [%s] for value param!\n", s.s); return E_CFG; } *param = (void*)model; } return 0; }
static int fixup_replace_uri(void** param, int param_no) { pv_elem_t *model; str s; model=NULL; s.s = (char*)(*param); s.len = strlen(s.s); if(pv_parse_format(&s, &model)<0) { LM_ERR("wrong format[%s]!\n",(char*)(*param)); return E_UNSPEC; } if (model==NULL) { LM_ERR("empty parameter!\n"); return E_UNSPEC; } *param = (void*)model; return 0; }
int fixup_cmd_erlang_info(void** param, int param_no){ if (param_no <= 2) return fixup_spve_null(param, 1); if (param_no == 3) { pv_elem_t *model=NULL; str s; s.s = (char*)(*param); s.len = strlen(s.s); if(s.len==0) { LM_ERR("cmd_erlang_info: param %d is empty string!\n", param_no); return -1; } if(pv_parse_format(&s ,&model) || model==NULL) { LM_ERR("cmd_erlang_info: wrong format [%s] for value param!\n", s.s); return -1; } *param = (void*)model; return 0; } LM_ERR("erlang_info takes exactly 3 parameters.\n"); return -1; }
static int fixup_dlginfo(void** param, int param_no) { pv_elem_t *model; str s; if(param_no== 0) return 0; if(*param) { s.s = (char*)(*param); s.len = strlen(s.s); if(pv_parse_format(&s, &model)<0) { LM_ERR( "wrong format[%s]\n",(char*)(*param)); return E_UNSPEC; } *param = (void*)model; return 0; } LM_ERR( "null format\n"); return E_UNSPEC; }
/* * Fix curl_connect params when posting (5 parameters): * connection (string/pvar), url (string with pvars), content-type, * data (string/pvar, pvar) */ static int fixup_curl_connect_post(void** param, int param_no) { str s; pv_elem_t *pv = NULL; if (param_no == 1 || param_no == 3) { /* We want char * strings */ return 0; } /* URL and data may contain pvar */ if (param_no == 4 || param_no == 2) { s.s = (char*)(*param); s.len = strlen(s.s); if(pv_parse_format(&s, &pv) < 0) { LM_ERR("failed to parse postdata \n"); return -1; } *param = (void*)pv; return 0; } if (param_no == 5) { if (fixup_pvar_null(param, 1) != 0) { LM_ERR("failed to fixup result pvar\n"); return -1; } if (((pv_spec_t *)(*param))->setf == NULL) { LM_ERR("result pvar is not writeble\n"); return -1; } return 0; } LM_ERR("invalid parameter number <%d>\n", param_no); return -1; }
static int acc_fixup(void** param, int param_no) { str s; pv_elem_t *model = NULL; s.s = (char*)(*param); if (s.s==0 || s.s[0]==0) { LM_ERR("first parameter is empty\n"); return E_SCRIPT; } if (param_no == 1) { if (s.s==NULL) { LM_ERR("null format in P%d\n", param_no); } s.len = strlen(s.s); if(pv_parse_format(&s, &model)<0) { LM_ERR("wrong format[%s]\n", s.s); return E_UNSPEC; } *param = (void*)model; return 0; } else if (param_no == 2) { /* only for db acc - the table name */ if (db_url.s==0) { pkg_free(s.s); *param = 0; } } return 0; }
static int fixup_lookup3(void **param, int param_no) { str s; s.s=(char *)(*param); s.len=strlen(s.s); if(!s.len) { LM_ERR("fixup_lookup3:Parameter %d is empty.\n", param_no); return E_CFG; } if(1==param_no || 2==param_no) { /* Expecting input pseudo vars --> pv_elem_t */ pv_elem_t *model=0; if(pv_parse_format(&s,&model) || !model) { LM_ERR("Bad format for input PV: '%s'.", s.s); return E_CFG; } *param=(void*)model; return 0; } else if(3==param_no) { /* Expecting AVP spec --> pv_spec_t */ pv_spec_t *spec; int ret=fixup_pvar(param); if(ret<0) return ret; spec=(pv_spec_t*)(*param); if(spec->type!=PVT_AVP) { LM_ERR("AVP required for return value!\n"); return E_CFG; } return 0; } else { LM_ERR("Invalid parameter number: %d.\n", param_no); return E_CFG; } return 0; }
int fixup_var_str_int(void **param, int param_no) { int ret; pv_elem_t *model; str s; if (param_no == 1) { model = NULL; s.s = (char *)(*param); s.len = strlen(s.s); if (pv_parse_format(&s, &model) < 0) { LM_ERR("wrong format[%s]!\n", (char *)(*param)); return E_UNSPEC; } if (model == NULL) { LM_ERR("empty parameter!\n"); return E_UNSPEC; } *param = (void *)model; } else if (param_no == 2) { /* According to * http://www.kamailio.org/docs/modules/1.5.x/nathelper.html#rtpproxy_stream2xxx * this could be -1 */ s.s = (char *)(*param); s.len = strlen(s.s); if (str2sint(&s, &ret)==0) { pkg_free(*param); *param = (void *)(long)ret; } else { LM_ERR("bad number <%s>\n", (char *)(*param)); return E_CFG; } } return 0; }
static int fixup_sql_query(void** param, int param_no) { sql_con_t *con = NULL; pv_elem_t *query = NULL; sql_result_t *res = NULL; str s; s.s = (char*)(*param); s.len = strlen(s.s); if (param_no==1) { con = sql_get_connection(&s); if(con==NULL) { LM_ERR("invalid connection [%s]\n", s.s); return E_UNSPEC; } *param = (void*)con; } else if (param_no==2) { if(pv_parse_format(&s, &query)<0) { LM_ERR("invalid query string [%s]\n", s.s); return E_UNSPEC; } *param = (void*)query; } else if (param_no==3) { res = sql_get_result(&s); if(res==NULL) { LM_ERR("invalid result [%s]\n", s.s); return E_UNSPEC; } *param = (void*)res; } return 0; }