From 866fc857f111c78c77fff0231a1db37ec1c52a87 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 11 Jun 2017 08:37:50 +0200 Subject: [PATCH] regex: exported functions to kemi interface --- src/modules/regex/regex_mod.c | 158 +++++++++++++++++++++------------- 1 file changed, 100 insertions(+), 58 deletions(-) diff --git a/src/modules/regex/regex_mod.c b/src/modules/regex/regex_mod.c index e0c8761a753..b83af7a2c94 100644 --- a/src/modules/regex/regex_mod.c +++ b/src/modules/regex/regex_mod.c @@ -42,6 +42,7 @@ #include "../../core/mod_fix.h" #include "../../core/rpc.h" #include "../../core/rpc_lookup.h" +#include "../../core/kemi.h" MODULE_VERSION @@ -507,15 +508,54 @@ static void free_shared_memory(void) */ /*! \brief Return true if the argument matches the regular expression parameter */ -static int w_pcre_match(struct sip_msg* _msg, char* _s1, char* _s2) +static int ki_pcre_match(sip_msg_t* msg, str* string, str* regex) { - str string; - str regex; pcre *pcre_re = NULL; int pcre_rc; const char *pcre_error; int pcre_erroffset; + pcre_re = pcre_compile(regex->s, pcre_options, &pcre_error, &pcre_erroffset, NULL); + if (pcre_re == NULL) { + LM_ERR("pcre_re compilation of '%s' failed at offset %d: %s\n", + regex->s, pcre_erroffset, pcre_error); + return -4; + } + + pcre_rc = pcre_exec( + pcre_re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + string->s, /* the matching string */ + (int)(string->len), /* the length of the subject */ + 0, /* start at offset 0 in the string */ + 0, /* default options */ + NULL, /* output vector for substring information */ + 0); /* number of elements in the output vector */ + + /* Matching failed: handle error cases */ + if (pcre_rc < 0) { + switch(pcre_rc) { + case PCRE_ERROR_NOMATCH: + LM_DBG("'%s' doesn't match '%s'\n", string->s, regex->s); + break; + default: + LM_DBG("matching error '%d'\n", pcre_rc); + break; + } + pcre_free(pcre_re); + return -1; + } + pcre_free(pcre_re); + LM_DBG("'%s' matches '%s'\n", string->s, regex->s); + return 1; +} + +/*! \brief Return true if the argument matches the regular expression parameter */ +static int w_pcre_match(struct sip_msg* _msg, char* _s1, char* _s2) +{ + str string; + str regex; + if (_s1 == NULL) { LM_ERR("bad parameters\n"); return -2; @@ -537,53 +577,62 @@ static int w_pcre_match(struct sip_msg* _msg, char* _s1, char* _s2) return -3; } - pcre_re = pcre_compile(regex.s, pcre_options, &pcre_error, &pcre_erroffset, NULL); - if (pcre_re == NULL) { - LM_ERR("pcre_re compilation of '%s' failed at offset %d: %s\n", regex.s, pcre_erroffset, pcre_error); + return ki_pcre_match(_msg, &string, ®ex); +} + +/*! \brief Return true if the string argument matches the pattern group parameter */ +static int ki_pcre_match_group(sip_msg_t* _msg, str* string, int num_pcre) +{ + int pcre_rc; + + /* Check if group matching feature is enabled */ + if (file == NULL) { + LM_ERR("group matching is disabled\n"); + return -2; + } + + if (num_pcre >= *num_pcres) { + LM_ERR("invalid pcre index '%i', there are %i pcres\n", num_pcre, + *num_pcres); return -4; } + lock_get(reload_lock); + pcre_rc = pcre_exec( - pcre_re, /* the compiled pattern */ + (*pcres_addr)[num_pcre], /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ - string.s, /* the matching string */ - (int)(string.len), /* the length of the subject */ + string->s, /* the matching string */ + (int)(string->len), /* the length of the subject */ 0, /* start at offset 0 in the string */ 0, /* default options */ NULL, /* output vector for substring information */ 0); /* number of elements in the output vector */ + lock_release(reload_lock); + /* Matching failed: handle error cases */ if (pcre_rc < 0) { switch(pcre_rc) { case PCRE_ERROR_NOMATCH: - LM_DBG("'%s' doesn't match '%s'\n", string.s, regex.s); + LM_DBG("'%s' doesn't match pcres[%i]\n", string->s, num_pcre); break; default: LM_DBG("matching error '%d'\n", pcre_rc); break; } - pcre_free(pcre_re); return -1; + } else { + LM_DBG("'%s' matches pcres[%i]\n", string->s, num_pcre); + return 1; } - pcre_free(pcre_re); - LM_DBG("'%s' matches '%s'\n", string.s, regex.s); - return 1; } - /*! \brief Return true if the string argument matches the pattern group parameter */ static int w_pcre_match_group(struct sip_msg* _msg, char* _s1, char* _s2) { str string, group; unsigned int num_pcre; - int pcre_rc; - - /* Check if group matching feature is enabled */ - if (file == NULL) { - LM_ERR("group matching is disabled\n"); - return -2; - } if (_s1 == NULL) { LM_ERR("bad parameters\n"); @@ -601,48 +650,13 @@ static int w_pcre_match_group(struct sip_msg* _msg, char* _s1, char* _s2) str2int(&group, &num_pcre); } - if (num_pcre >= *num_pcres) { - LM_ERR("invalid pcre index '%i', there are %i pcres\n", num_pcre, *num_pcres); - return -4; - } - if (fixup_get_svalue(_msg, (gparam_p)_s1, &string)) { LM_ERR("cannot print the format for first param\n"); return -5; } - lock_get(reload_lock); - - pcre_rc = pcre_exec( - (*pcres_addr)[num_pcre], /* the compiled pattern */ - NULL, /* no extra data - we didn't study the pattern */ - string.s, /* the matching string */ - (int)(string.len), /* the length of the subject */ - 0, /* start at offset 0 in the string */ - 0, /* default options */ - NULL, /* output vector for substring information */ - 0); /* number of elements in the output vector */ - - lock_release(reload_lock); - - /* Matching failed: handle error cases */ - if (pcre_rc < 0) { - switch(pcre_rc) { - case PCRE_ERROR_NOMATCH: - LM_DBG("'%s' doesn't match pcres[%i]\n", string.s, num_pcre); - break; - default: - LM_DBG("matching error '%d'\n", pcre_rc); - break; - } - return -1; - } - else { - LM_DBG("'%s' matches pcres[%i]\n", string.s, num_pcre); - return 1; - } - + return ki_pcre_match_group(_msg, &string, (int)num_pcre); } @@ -693,3 +707,31 @@ static int regex_init_rpc(void) return 0; } +/** + * + */ +/* clang-format off */ +static sr_kemi_t sr_kemi_regex_exports[] = { + { str_init("regex"), str_init("pcre_match"), + SR_KEMIP_INT, ki_pcre_match, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("regex"), str_init("pcre_match_group"), + SR_KEMIP_INT, ki_pcre_match_group, + { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + + { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } +}; +/* clang-format on */ + +/** + * + */ +int mod_register(char *path, int *dlflags, void *p1, void *p2) +{ + sr_kemi_modules_add(sr_kemi_regex_exports); + return 0; +} \ No newline at end of file