Browse Source

dialplan: added fnmatch (2) matching operator

- if match_op=2, the matching of the rule is done using fnmatch function
  which does shell-like pattern matching
Daniel-Constantin Mierla 13 năm trước cách đây
mục cha
commit
a6da2035c2

+ 28 - 23
modules/dialplan/README

@@ -12,9 +12,9 @@ Edited by
 
 Juha Heinanen
 
-   Copyright © 2007-2008 Voice Sistem SRL
+   Copyright © 2007-2008 Voice Sistem SRL
 
-   Copyright © 2008-2010 Juha Heinanen
+   Copyright © 2008-2010 Juha Heinanen
      __________________________________________________________________
 
    Table of Contents
@@ -138,12 +138,13 @@ Chapter 1. Admin Guide
    the matching transformation.
 
    The module expects an input value which will be matched against a rule
-   by using regular expressions (see 'man pcresyntax' for syntax) or
-   string matching. Overlapping matching expressions can be controlled via
-   priorities. Once a rule is matched, the defined transformation (if any)
-   is applied and the result is returned as output value. Also, if any
-   string attribute is associated to the rule, this will be returned to
-   the script along with the output value.
+   by using regular expressions (see 'man pcresyntax' for syntax), string
+   or fnmatch (see 'man fnmatch') matching. Overlapping matching
+   expressions can be controlled via priorities. Once a rule is matched,
+   the defined transformation (if any) is applied and the result is
+   returned as output value. Also, if any string attribute is associated
+   to the rule, this will be returned to the script along with the output
+   value.
 
    The first matching rule will be processed.
 
@@ -199,7 +200,7 @@ Chapter 1. Admin Guide
 
    The translation rules will be loaded using this database URL.
 
-   Default value is “mysql://openser:openserrw@localhost/openser�.
+   Default value is "mysql://openser:openserrw@localhost/openser".
 
    Example 1.1. Set db_url parameter
 ...
@@ -210,7 +211,7 @@ modparam("dialplan", "db_url", "mysql://user:passwb@localhost/db")
 
    The table's name from which to load the translation rules.
 
-   Default value is “dialplan�.
+   Default value is "dialplan".
 
    Example 1.2. Set table_name parameter
 ...
@@ -221,7 +222,7 @@ modparam("dialplan", "table_name", "my_table")
 
    The column name used to store the dialplan ID group.
 
-   Default value is “dpid�.
+   Default value is "dpid".
 
    Example 1.3. Set dpid_col parameter
 ...
@@ -233,7 +234,7 @@ modparam("dialplan", "dpid_col", "column_name")
    The column name used to store the priority of the corresponding rule
    from the database row.
 
-   Default value is “pr�.
+   Default value is "pr".
 
    Example 1.4. Set pr_col parameter
 ...
@@ -244,7 +245,7 @@ modparam("dialplan", "pr_col", "column_name")
 
    The column name used to store the type of matching of the rule.
 
-   Default value is “match_op�.
+   Default value is "match_op".
 
    Example 1.5. Set match_op_col parameter
 ...
@@ -255,7 +256,7 @@ modparam("dialplan", "match_op_col", "column_name")
 
    The column name to store the rule match expression.
 
-   Default value is “match_exp�.
+   Default value is "match_exp".
 
    Example 1.6. Set match_exp_col parameter
 ...
@@ -267,7 +268,7 @@ modparam("dialplan", "match_exp_col", "column_name")
    The column name to store the length of a string matching the match
    expression.
 
-   Default value is “match_len�.
+   Default value is "match_len".
 
    Example 1.7. Set pr_col parameter
 ...
@@ -278,7 +279,7 @@ modparam("dialplan", "match_len_col", "column_name")
 
    The column name to store the rule's substitution expression.
 
-   Default value is “subst_exp�.
+   Default value is "subst_exp".
 
    Example 1.8. Set pr_col parameter
 ...
@@ -289,7 +290,7 @@ modparam("dialplan", "subst_exp_col", "column_name")
 
    The column name to store the rule's replacement expression.
 
-   Default value is “repl_exp�.
+   Default value is "repl_exp".
 
    Example 1.9. Set repl_exp_col parameter
 ...
@@ -301,7 +302,7 @@ modparam("dialplan", "repl_exp_col", "column_name")
    The column name to store the rule's attributes to be set to the
    message.
 
-   Default value is “attrs�.
+   Default value is "attrs".
 
    Example 1.10. Set attrs_col parameter
 ...
@@ -314,7 +315,7 @@ modparam("dialplan", "attrs_col", "column_name")
    (dp_translate() succeeds). This parameter can be an AVP or a SCRIPT
    VAR.
 
-   Default value is “NULL�.
+   Default value is "NULL".
 
    Example 1.11. Set attrs_pvar parameter
 ...
@@ -325,7 +326,7 @@ modparam("dialplan", "attrs_pvar", "$avp(s:dest)")
 
    The number of rows to be fetched at once from database
 
-   Default value is “1000�.
+   Default value is "1000".
 
    Example 1.12. Set fetch_rows parameter
 ...
@@ -336,7 +337,7 @@ modparam("dialplan", "fetch_rows", 4000)
 
    6.1. dp_translate(id, src[/dest])
 
-6.1.  dp_translate(id, src[/dest])
+6.1. dp_translate(id, src[/dest])
 
    Will try to translate src into dest according to the translation rules
    with dialplan ID equal to id. If dest is missing, only matching and
@@ -354,7 +355,7 @@ modparam("dialplan", "fetch_rows", 4000)
           + script var - the dialplan id is the value of an existing
             script variable.
      * src/dest - input and output of the function. If this parameter is
-       missing the default parameter “ruri.user/ruri.user� will be used,
+       missing the default parameter "ruri.user/ruri.user" will be used,
        thus translating the request uri user part.
        Input parameter src can be any pseudo variable. Output parameter
        dest can be:
@@ -369,7 +370,7 @@ modparam("dialplan", "fetch_rows", 4000)
             existing script variable. At output the function will set an
             script variable with the value of the output string.
 
-   This function can be used from REQUEST_ROUTE, BRANCH_ROUTE.
+   This function can be used from ANY_ROUTE.
 
    Example 1.13. dp_translate usage
 ...
@@ -488,6 +489,10 @@ attrs: xyz
    private variables ($var(...)) and AVPs with static name are among those
    that are safe to use in replacement expressions.
 
+   The match_op field specify matching operator, valid value being: 0 -
+   string comparison; 1 - regular expression matching (pcre); 2 - fnmatch
+   (shell-like pattern) matching.
+
 Chapter 2. Developer's Guide
 
    The module does not provide any API to use in other Kamailio modules.

+ 3 - 2
modules/dialplan/dialplan.h

@@ -40,8 +40,9 @@
 #include "../../pvar.h"
 #include "../../parser/msg_parser.h"
 
-#define REGEX_OP	1
-#define EQUAL_OP	0
+#define DP_EQUAL_OP		0
+#define DP_REGEX_OP		1
+#define DP_FNMATCH_OP	2
 
 #define MAX_REPLACE_WITH	10
 

+ 9 - 3
modules/dialplan/doc/dialplan_admin.xml

@@ -33,8 +33,9 @@
 	</para>
 	<para>
 	The module expects an input value which will be matched against a rule
-	by using regular expressions (see 'man pcresyntax' for syntax) or string
-	matching. Overlapping matching expressions can be controlled via priorities. 
+	by using regular expressions (see 'man pcresyntax' for syntax), string
+	or fnmatch (see 'man fnmatch') matching. Overlapping matching expressions
+	can be controlled via priorities. 
 	Once a rule is matched, the defined transformation (if any) is applied and 
 	the result is returned as output value. Also, if any string attribute is 
 	associated to the rule, this will be returned to the script along with
@@ -434,7 +435,7 @@ modparam("dialplan", "fetch_rows", 4000)
         </listitem>
 	</itemizedlist>
 	<para>
-	This function can be used from REQUEST_ROUTE, BRANCH_ROUTE.
+	This function can be used from ANY_ROUTE.
 	</para>
 	<example>
 	<title><function>dp_translate</function> usage</title>
@@ -605,6 +606,11 @@ attrs: xyz
 		private variables ($var(...)) and AVPs with static name are among
 		those that are safe to use in replacement expressions.
 		</para>
+		<para>
+		The match_op field specify matching operator, valid value being:
+		0 - string comparison; 1 - regular expression matching (pcre);
+		2 - fnmatch (shell-like pattern) matching.
+		</para>
     </section>
 
 </chapter>

+ 5 - 3
modules/dialplan/dp_db.c

@@ -364,7 +364,8 @@ dpl_node_t * build_rule(db_val_t * values)
 
 	matchop = VAL_INT(values+2);
 
-	if((matchop != REGEX_OP) && (matchop!=EQUAL_OP)){
+	if((matchop != DP_REGEX_OP) && (matchop!=DP_EQUAL_OP)
+			&& (matchop!=DP_FNMATCH_OP)){
 		LM_ERR("invalid value for match operator\n");
 		return NULL;
 	}
@@ -374,7 +375,7 @@ dpl_node_t * build_rule(db_val_t * values)
 	new_rule = 0;
 
 	GET_STR_VALUE(match_exp, values, 3);
-	if(matchop == REGEX_OP){
+	if(matchop == DP_REGEX_OP){
 		match_comp = reg_ex_comp(match_exp.s, &cap_cnt);
 		if(!match_comp){
 			LM_ERR("failed to compile match expression %.*s\n",
@@ -660,9 +661,10 @@ void list_hash(int h_index)
 
 void list_rule(dpl_node_t * rule)
 {
-	LM_DBG("RULE %p: pr %i next %p match_exp %.*s, "
+	LM_DBG("RULE %p: pr %i next %p op %d match_exp %.*s, "
 			"subst_exp %.*s, repl_exp %.*s and attrs %.*s\n", rule,
 			rule->pr, rule->next,
+			rule->matchop,
 			rule->match_exp.len, rule->match_exp.s, 
 			rule->subst_exp.len, rule->subst_exp.s,
 			rule->repl_exp.len, rule->repl_exp.s,

+ 15 - 3
modules/dialplan/dp_repl.c

@@ -34,6 +34,8 @@
  */
 
 
+#include <fnmatch.h>
+
 #include "../../re.h"
 #include "../../mem/shm_mem.h"
 #include "dialplan.h"
@@ -306,7 +308,7 @@ error:
 	return -1;
 }
 
-#define DP_MAX_ATTRS_LEN	32
+#define DP_MAX_ATTRS_LEN	128
 static char dp_attrs_buf[DP_MAX_ATTRS_LEN+1];
 int translate(struct sip_msg *msg, str input, str *output, dpl_id_p idp,
 		str *attrs)
@@ -314,6 +316,7 @@ int translate(struct sip_msg *msg, str input, str *output, dpl_id_p idp,
 	dpl_node_p rulep;
 	dpl_index_p indexp;
 	int user_len, rez;
+	char b;
 
 	if(!input.s || !input.len) {
 		LM_ERR("invalid input string\n");
@@ -334,13 +337,13 @@ search_rule:
 	for(rulep=indexp->first_rule; rulep!=NULL; rulep= rulep->next) {
 		switch(rulep->matchop) {
 
-			case REGEX_OP:
+			case DP_REGEX_OP:
 				LM_DBG("regex operator testing\n");
 				rez = pcre_exec(rulep->match_comp, NULL, input.s, input.len,
 						0, 0, NULL, 0);
 				break;
 
-			case EQUAL_OP:
+			case DP_EQUAL_OP:
 				LM_DBG("equal operator testing\n");
 				if(rulep->match_exp.len != input.len) {
 					rez = -1;
@@ -350,6 +353,15 @@ search_rule:
 				}
 				break;
 
+			case DP_FNMATCH_OP:
+				LM_DBG("fnmatch operator testing\n");
+				b = input.s[input.len];
+				input.s[input.len] = '\0';
+				rez = fnmatch(rulep->match_exp.s, input.s, 0);
+				input.s[input.len] = b;
+				rez = (rez==0)?0:-1;
+				break;
+
 			default:
 				LM_ERR("bogus match operator code %i\n", rulep->matchop);
 				return -1;