/*compile the expressions, and if ok, build the rule */ dpl_node_t * build_rule(db_val_t * values) { tmrec_t *parsed_timerec; pcre * match_comp, *subst_comp; struct subst_expr * repl_comp; dpl_node_t * new_rule; str match_exp, subst_exp, repl_exp, attrs, timerec; int matchop; int namecount; matchop = VAL_INT(values+2); if((matchop != REGEX_OP) && (matchop!=EQUAL_OP)){ LM_ERR("invalid value for match operator\n"); return NULL; } parsed_timerec = 0; match_comp = subst_comp = 0; repl_comp = 0; new_rule = 0; GET_STR_VALUE(match_exp, values, 3, 0); if(matchop == REGEX_OP){ LM_DBG("Compiling %.*s expression with flag: %d\n", match_exp.len, match_exp.s, VAL_INT(values+4)); match_comp = wrap_pcre_compile(match_exp.s, VAL_INT(values+4)); if(!match_comp){ LM_ERR("failed to compile match expression \"%.*s\"\n", match_exp.len, match_exp.s); goto err; } } LM_DBG("building subst rule\n"); GET_STR_VALUE(subst_exp, values, 5, 1); if(!VAL_NULL(values+5) && subst_exp.s && subst_exp.len){ /* subst regexp */ subst_comp = wrap_pcre_compile(subst_exp.s, VAL_INT(values+4)); if(subst_comp == NULL){ LM_ERR("failed to compile subst expression \"%.*s\"\n", subst_exp.len, subst_exp.s); goto err; } } /* replace exp */ GET_STR_VALUE(repl_exp, values, 6, 1); if(!VAL_NULL(values+6) && repl_exp.len && repl_exp.s){ repl_comp = repl_exp_parse(repl_exp); if(!repl_comp){ LM_ERR("failed to compile replacing expression \"%.*s\"\n", repl_exp.len, repl_exp.s); goto err; } } pcre_fullinfo( subst_comp, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_CAPTURECOUNT, /* number of named substrings */ &namecount); /* where to put the answer */ LM_DBG("references:%d , max:%d\n",namecount, repl_comp?repl_comp->max_pmatch:0); if ( (repl_comp!=NULL) && (namecount<repl_comp->max_pmatch) && (repl_comp->max_pmatch!=0) ){ LM_ERR("repl_exp uses a non existing subexpression\n"); goto err; } new_rule = (dpl_node_t *)shm_malloc(sizeof(dpl_node_t)); if(!new_rule){ LM_ERR("out of shm memory(new_rule)\n"); goto err; } memset(new_rule, 0, sizeof(dpl_node_t)); if(str_to_shm(match_exp, &new_rule->match_exp)!=0) goto err; if (subst_comp) if(str_to_shm(subst_exp, &new_rule->subst_exp)!=0) goto err; if (repl_comp) if(str_to_shm(repl_exp, &new_rule->repl_exp)!=0) goto err; /*set the rest of the rule fields*/ new_rule->dpid = VAL_INT(values); new_rule->pr = VAL_INT(values+1); new_rule->match_flags = VAL_INT(values+4); new_rule->matchop = matchop; /* attributes */ GET_STR_VALUE(attrs, values, 7, 1); if( !VAL_NULL(values+7) && attrs.len && attrs.s) { if(str_to_shm(attrs, &new_rule->attrs)!=0) goto err; LM_DBG("attrs are %.*s\n", new_rule->attrs.len, new_rule->attrs.s); } /* Retrieve and Parse Timerec Matching Pattern */ GET_STR_VALUE(timerec, values, 8, 1); if( !VAL_NULL(values+8) && timerec.len && timerec.s) { parsed_timerec = parse_time_def(timerec.s); if(!parsed_timerec) { LM_ERR("failed to parse timerec pattern %.*s\n", timerec.len, timerec.s); goto err; } if(str_to_shm(timerec, &new_rule->timerec) != 0) goto err; new_rule->parsed_timerec = parsed_timerec; LM_DBG("timerecs are %.*s\n", new_rule->timerec.len, new_rule->timerec.s); } if (match_comp) new_rule->match_comp = match_comp; if (subst_comp) new_rule->subst_comp = subst_comp; if (repl_comp) new_rule->repl_comp = repl_comp; return new_rule; err: if(parsed_timerec) shm_free(parsed_timerec); if(match_comp) wrap_pcre_free(match_comp); if(subst_comp) wrap_pcre_free(subst_comp); if(repl_comp) repl_expr_free(repl_comp); if(new_rule) destroy_rule(new_rule); return NULL; }
/*compile the expressions, and if ok, build the rule */ dpl_node_t * build_rule(db_val_t * values) { pcre * match_comp, *subst_comp; struct subst_expr * repl_comp; dpl_node_t * new_rule; str match_exp, subst_exp, repl_exp, attrs; int matchop; int namecount; matchop = VAL_INT(values+2); if((matchop != REGEX_OP) && (matchop!=EQUAL_OP)){ LM_ERR("invalid value for match operator\n"); return NULL; } match_comp = subst_comp =0; repl_comp = 0; new_rule = 0; GET_STR_VALUE(match_exp, values, 3); if(matchop == REGEX_OP){ match_comp = wrap_pcre_compile(match_exp.s); if(!match_comp){ LM_ERR("failed to compile match expression %.*s\n", match_exp.len, match_exp.s); goto err; } } LM_DBG("building subst rule\n"); GET_STR_VALUE(subst_exp, values, 5); if(subst_exp.s && subst_exp.len){ /* subst regexp */ subst_comp = wrap_pcre_compile(subst_exp.s); if(subst_comp == NULL){ LM_ERR("failed to compile subst expression\n"); goto err; } } /* replace exp */ GET_STR_VALUE(repl_exp, values, 6); if(repl_exp.len && repl_exp.s){ repl_comp = repl_exp_parse(repl_exp); if(!repl_comp){ LM_ERR("failed to compile replacing expression %.*s\n", repl_exp.len, repl_exp.s); goto err; } } pcre_fullinfo( subst_comp, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_CAPTURECOUNT, /* number of named substrings */ &namecount); /* where to put the answer */ LM_DBG("references:%d , max:%d\n",namecount, repl_comp?repl_comp->max_pmatch:0); if ( (repl_comp!=NULL) && (namecount<repl_comp->max_pmatch) && (repl_comp->max_pmatch!=0) ){ LM_ERR("repl_exp uses a non existing subexpression\n"); goto err; } new_rule = (dpl_node_t *)shm_malloc(sizeof(dpl_node_t)); if(!new_rule){ LM_ERR("out of shm memory(new_rule)\n"); goto err; } memset(new_rule, 0, sizeof(dpl_node_t)); if(str_to_shm(match_exp, &new_rule->match_exp)!=0) goto err; if (subst_comp) if(str_to_shm(subst_exp, &new_rule->subst_exp)!=0) goto err; if (repl_comp) if(str_to_shm(repl_exp, &new_rule->repl_exp)!=0) goto err; /*set the rest of the rule fields*/ new_rule->dpid = VAL_INT(values); new_rule->pr = VAL_INT(values+1); new_rule->matchlen = VAL_INT(values+4); new_rule->matchop = matchop; GET_STR_VALUE(attrs, values, 7); if(str_to_shm(attrs, &new_rule->attrs)!=0) goto err; LM_DBG("attrs are %.*s\n", new_rule->attrs.len, new_rule->attrs.s); if (match_comp) new_rule->match_comp = match_comp; if (subst_comp) new_rule->subst_comp = subst_comp; if (repl_comp) new_rule->repl_comp = repl_comp; return new_rule; err: if(subst_comp) wrap_pcre_free(subst_comp); if(repl_comp) repl_expr_free(repl_comp); if(new_rule) destroy_rule(new_rule); return NULL; }