static struct subst_expr *fill_subst_expr(char *pattern) { str subst = {0, 0}; subst.s = pattern; subst.len = (int) strlen(pattern); return subst_parser(&subst); }
static int fixup_substre(void** param) { struct subst_expr* se; se=subst_parser((str*)*param); if (se==0){ LM_ERR("%s: bad subst. re %.*s\n", exports.name, ((str*)*param)->len, ((str*)*param)->s); return E_BAD_RE; } *param=se; return 0; }
static int fixup_substre(void** param, int param_no) { struct subst_expr* se; str subst; DBG("%s module -- fixing %s\n", exports.name, (char*)(*param)); if (param_no!=1) return 0; subst.s=*param; subst.len=strlen(*param); se=subst_parser(&subst); if (se==0){ LOG(L_ERR, "ERROR: %s: bad subst. re %s\n", exports.name, (char*)*param); return E_BAD_RE; } /* don't free string -- needed for specifiers */ /* pkg_free(*param); */ /* replace it with the compiled subst. re */ *param=se; return 0; }
int tr_txt_eval_re(struct sip_msg *msg, tr_param_t *tp, int subtype, pv_value_t *val) { struct subst_expr *se = NULL; int nmatches; str* result; #define TR_TXT_BUF_SIZE 2048 static char tr_txt_buf[TR_TXT_BUF_SIZE]; pv_value_t v; if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0) return -1; switch(subtype) { case TR_TXT_RE_SUBST: if (tp->type == TR_PARAM_SUBST) { se = (struct subst_expr*)tp->v.data; if (se==NULL) return 0; } else if (tp->type == TR_PARAM_SPEC) { if (pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0 || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0) { LM_ERR("Can't evaluate regexp\n"); return -1; } se=subst_parser(&v.rs); if (se==0) { LM_ERR("Can't compile regexp\n"); return -1; } } else { LM_ERR("Unknown parameter type\n"); return -1; } if(val->rs.len>=TR_TXT_BUF_SIZE-1) { LM_ERR("PV value too big %d, increase buffer size\n", val->rs.len); goto error; } memcpy(tr_txt_buf, val->rs.s, val->rs.len); tr_txt_buf[val->rs.len] = '\0'; /* pkg malloc'ed result */ result=subst_str(tr_txt_buf, msg, se, &nmatches); if (result == NULL) { if (nmatches==0) { LM_DBG("no match for subst expression\n"); break; } if (nmatches<0) LM_ERR("subst failed\n"); goto error; } if(result->len>=TR_TXT_BUF_SIZE-1) { LM_ERR("subst result too big %d, increase buffer size\n", result->len); goto error; } memcpy(tr_txt_buf, result->s, result->len); tr_txt_buf[result->len] = '\0'; memset(val, 0, sizeof(pv_value_t)); val->flags = PV_VAL_STR; val->rs.s = tr_txt_buf; val->rs.len = result->len; pkg_free(result->s); pkg_free(result); break; default: LM_ERR("unknown subtype %d\n", subtype); goto error; } if (tp->type == TR_PARAM_SPEC) { subst_expr_free(se); } return 0; error: if (tp->type == TR_PARAM_SPEC) { subst_expr_free(se); } return -1; }
char* tr_txt_parse_re(str *in, trans_t *t) { char *p; str name; str tok; struct subst_expr *se = NULL; tr_param_t *tp = NULL; int n; pv_spec_t *spec = NULL; if(in==NULL || t==NULL) return NULL; p = in->s; name.s = in->s; t->type = TR_TXT_RE; t->trf = tr_txt_eval_re; /* find next token */ while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++; if(*p=='\0') goto error; name.len = p - name.s; trim(&name); if(name.len==5 && strncasecmp(name.s, "subst", 5)==0) { t->subtype = TR_TXT_RE_SUBST; if(*p!=TR_PARAM_MARKER) goto error; p++; if(*p==PV_MARKER) { spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t)); if(spec==NULL) { LM_ERR("no more private memory!\n"); return 0; } tok.s = p; tok.len = in->s + in->len - p; p = pv_parse_spec(&tok, spec); if(p==NULL) { LM_ERR("invalid pv spec in transformation: %.*s!\n", in->len, in->s); pkg_free(spec); return 0; } tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t)); if(tp==NULL) { LM_ERR("no more private memory!\n"); pkg_free(spec); goto error; } tp->type = TR_PARAM_SPEC; tp->v.data = (void*)spec; } else { /* get trans here */ n = 0; tok.s = p; while(is_in_str(p, in)) { if(*p==TR_RBRACKET) { if(n==0) break; n--; } if(*p == TR_LBRACKET) n++; p++; } if(!is_in_str(p, in)) goto error; if(p==tok.s) goto error; tok.len = p - tok.s; tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t)); if(tp==NULL) { LM_ERR("no more private memory!\n"); goto error; } se=subst_parser(&tok); if (se==0) goto error; tp->type = TR_PARAM_SUBST; tp->v.data = (void*)se; } t->params = tp; while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++; if(*p!=TR_RBRACKET) goto error; goto done; } LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s, name.len, name.s, name.len); error: LM_ERR("invalid transformation [%.*s] <%d>\n", in->len, in->s, (int)(p-in->s)); if(tp!=NULL) pkg_free(tp); if(se!=NULL) subst_expr_free(se); return NULL; done: t->name = name; return p; }
static int ldap_result_check_fixup(void** param, int param_no) { struct ldap_result_check_params *lp; struct subst_expr *se; str subst; str s; char *arg_str, *check_str; int arg_str_len; if (param_no == 1) { arg_str = (char*)*param; arg_str_len = strlen(arg_str); if ((check_str = strchr(arg_str, '/')) == 0) { /* no / found in arg_str */ LM_ERR( "invalid first argument [%s] (no '/' found)\n", arg_str); return E_UNSPEC; } *(check_str++) = 0; lp = (struct ldap_result_check_params*)pkg_malloc(sizeof(struct ldap_result_check_params)); if (lp == NULL) { LM_ERR("no memory\n"); return E_OUT_OF_MEM; } memset(lp, 0, sizeof(struct ldap_result_check_params)); lp->ldap_attr_name.s = arg_str; lp->ldap_attr_name.len = strlen(arg_str); if (lp->ldap_attr_name.len + 1 == arg_str_len) { /* empty check_str */ lp->check_str_elem_p = 0; } else { s.s = check_str; s.len = strlen(s.s); if (pv_parse_format(&s, &(lp->check_str_elem_p)) < 0) { LM_ERR("pv_parse_format failed\n"); return E_OUT_OF_MEM; } } *param = (void*)lp; } else if (param_no == 2) { subst.s = *param; subst.len = strlen(*param); se = subst_parser(&subst); if (se == 0) { LM_ERR( "bad subst re [%s]\n", (char*)*param); return E_BAD_RE; } *param = (void*)se; } return 0; }
static int ldap_result_fixup(void** param, int param_no) { struct ldap_result_params* lp; struct subst_expr* se; str subst; char *arg_str, *dst_avp_str, *dst_avp_val_type_str; char *p; str s; int dst_avp_val_type = 0; if (param_no == 1) { arg_str = (char*)*param; if ((dst_avp_str = strchr(arg_str, '/')) == 0) { /* no / found in arg_str */ LM_ERR("invalid first argument [%s]\n", arg_str); return E_UNSPEC; } *(dst_avp_str++) = 0; if ((dst_avp_val_type_str = strchr(dst_avp_str, '/'))) { *(dst_avp_val_type_str++) = 0; if (!strcmp(dst_avp_val_type_str, "int")) { dst_avp_val_type = 1; } else if (strcmp(dst_avp_val_type_str, "str")) { LM_ERR( "invalid avp_type [%s]\n", dst_avp_val_type_str); return E_UNSPEC; } } lp = (struct ldap_result_params*)pkg_malloc(sizeof(struct ldap_result_params)); if (lp == NULL) { LM_ERR("no memory\n"); return E_OUT_OF_MEM; } memset(lp, 0, sizeof(struct ldap_result_params)); lp->ldap_attr_name.s = arg_str; lp->ldap_attr_name.len = strlen(arg_str); lp->dst_avp_val_type = dst_avp_val_type; s.s = dst_avp_str; s.len = strlen(s.s); p = pv_parse_spec(&s, &lp->dst_avp_spec); if (p == 0) { pkg_free(lp); LM_ERR("parse error for [%s]\n", dst_avp_str); return E_UNSPEC; } if (lp->dst_avp_spec.type != PVT_AVP) { pkg_free(lp); LM_ERR( "bad attribute name [%s]\n", dst_avp_str); return E_UNSPEC; } *param = (void*)lp; } else if (param_no == 2) { subst.s = *param; subst.len = strlen(*param); se = subst_parser(&subst); if (se == 0) { LM_ERR("bad subst re [%s]\n", (char*)*param); return E_BAD_RE; } *param = (void*)se; } return 0; }
static int fixup_subst(void** param, int param_no) { struct subst_expr* se; str subst; struct fis_param *ap; struct fis_param **av; char *s; char *p; if (param_no==1) { s = (char*)*param; ap = 0; p = 0; av = (struct fis_param**)pkg_malloc(2*sizeof(struct fis_param*)); if(av==NULL) { LM_ERR("no more pkg memory\n"); return E_UNSPEC; } memset(av, 0, 2*sizeof(struct fis_param*)); /* avp src / avp dst /flags */ if ( (p=strchr(s,'/'))!=0 ) *(p++)=0; ap = avpops_parse_pvar(s); if (ap==0) { LM_ERR("unable to get pseudo-variable in param 2 [%s]\n", s); return E_OUT_OF_MEM; } if (ap->u.sval.type!=PVT_AVP) { LM_ERR("bad attribute name <%s>\n", (char*)*param); pkg_free(av); return E_UNSPEC; } /* attr name is mandatory */ if (ap->opd&AVPOPS_VAL_NONE) { LM_ERR("you must specify a name for the AVP\n"); return E_UNSPEC; } av[0] = ap; if(p==0 || *p=='\0') { *param=(void*)av; return 0; } /* dst || flags */ s = p; if(*s==PV_MARKER) { if ( (p=strchr(s,'/'))!=0 ) *(p++)=0; if(p==0 || (p!=0 && p-s>1)) { ap = avpops_parse_pvar(s); if (ap==0) { LM_ERR("unable to get pseudo-variable in param 2 [%s]\n",s); return E_OUT_OF_MEM; } if (ap->u.sval.type!=PVT_AVP) { LM_ERR("bad attribute name <%s>!\n", s); pkg_free(av); return E_UNSPEC; } /* attr name is mandatory */ if (ap->opd&AVPOPS_VAL_NONE) { LM_ERR("you must specify a name for the AVP!\n"); return E_UNSPEC; } av[1] = ap; } if(p==0 || *p=='\0') { *param=(void*)av; return 0; } } /* flags */ for( ; p&&*p ; p++ ) { switch (*p) { case 'g': case 'G': av[0]->ops|=AVPOPS_FLAG_ALL; break; case 'd': case 'D': av[0]->ops|=AVPOPS_FLAG_DELETE; break; default: LM_ERR("bad flag <%c>\n",*p); return E_UNSPEC; } } *param=(void*)av; } else if (param_no==2) { LM_DBG("%s fixing %s\n", exports.name, (char*)(*param)); subst.s=*param; subst.len=strlen(*param); se=subst_parser(&subst); if (se==0){ LM_ERR("%s: bad subst re %s\n",exports.name, (char*)*param); return E_BAD_RE; } /* don't free string -- needed for specifiers */ /* pkg_free(*param); */ /* replace it with the compiled subst. re */ *param=se; } return 0; }
/** Generic parameter fixup function. * Creates a fparam_t structure. * @param type contains allowed parameter types * @param param is the parameter that will be fixed-up * * @return * 0 on success, * 1 if the param doesn't match the specified type * <0 on failure */ int fix_param(int type, void** param) { fparam_t* p; str name, s; int num; int err; p = (fparam_t*)pkg_malloc(sizeof(fparam_t)); if (!p) { LM_ERR("No memory left\n"); return E_OUT_OF_MEM; } memset(p, 0, sizeof(fparam_t)); p->orig = *param; switch(type) { case FPARAM_UNSPEC: LM_ERR("Invalid type value\n"); goto error; case FPARAM_STRING: p->v.asciiz = *param; /* no break */ case FPARAM_STR: p->v.str.s = (char*)*param; p->v.str.len = strlen(p->v.str.s); p->fixed = &p->v; break; case FPARAM_INT: s.s = (char*)*param; s.len = strlen(s.s); err = str2sint(&s, &num); if (err == 0) { p->v.i = (int)num; } else { /* Not a number */ pkg_free(p); return 1; } p->fixed = (void*)(long)num; break; case FPARAM_REGEX: if ((p->v.regex = pkg_malloc(sizeof(regex_t))) == 0) { LM_ERR("No memory left\n"); goto error; } if (regcomp(p->v.regex, *param, REG_EXTENDED|REG_ICASE|REG_NEWLINE)) { pkg_free(p->v.regex); p->v.regex=0; /* not a valid regex */ goto no_match; } p->fixed = p->v.regex; break; case FPARAM_AVP: name.s = (char*)*param; name.len = strlen(name.s); trim(&name); if (!name.len || name.s[0] != '$') { /* Not an AVP identifier */ goto no_match; } name.s++; name.len--; if (parse_avp_ident(&name, &p->v.avp) < 0) { /* invalid avp identifier (=> no match) */ goto no_match; } p->fixed = &p->v; break; case FPARAM_SELECT: name.s = (char*)*param; name.len = strlen(name.s); trim(&name); if (!name.len || name.s[0] != '@') { /* Not a select identifier */ goto no_match; } if (parse_select(&name.s, &p->v.select) < 0) { LM_ERR("Error while parsing select identifier\n"); goto error; } p->fixed = &p->v; break; case FPARAM_SUBST: s.s = *param; s.len = strlen(s.s); p->v.subst = subst_parser(&s); if (!p->v.subst) { LM_ERR("Error while parsing regex substitution\n"); goto error; } p->fixed = &p->v; break; case FPARAM_PVS: name.s = (char*)*param; name.len = strlen(name.s); trim(&name); if (!name.len || name.s[0] != '$'){ /* not a pvs identifier */ goto no_match; } p->v.pvs=pkg_malloc(sizeof(pv_spec_t)); if (p->v.pvs==0){ LM_ERR("out of memory while parsing pv_spec_t\n"); goto error; } if (pv_parse_spec2(&name, p->v.pvs, 1)==0){ /* not a valid pvs identifier (but it might be an avp) */ pkg_free(p->v.pvs); p->v.pvs=0; goto no_match; } p->fixed = p->v.pvs; break; case FPARAM_PVE: name.s = (char*)*param; name.len = strlen(name.s); if (pv_parse_format(&name, &p->v.pve)<0){ LM_ERR("bad PVE format: \"%.*s\"\n", name.len, name.s); goto error; } p->fixed = &p->v; break; } p->type = type; *param = (void*)p; return 0; no_match: pkg_free(p); return 1; error: pkg_free(p); return E_UNSPEC; }