[sr-dev] git:master: textopsx: added fnmatch(value, expr, flags) function

Daniel-Constantin Mierla miconda at gmail.com
Mon Dec 19 22:10:26 CET 2011


Module: sip-router
Branch: master
Commit: 0c830402b517f3e4194dd28b0383e57b8a803d21
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=0c830402b517f3e4194dd28b0383e57b8a803d21

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Mon Dec 19 22:08:57 2011 +0100

textopsx: added fnmatch(value, expr, flags) function

- shell-style pattern matching (via file selection wildcards), using C
  function fnmatch()

---

 modules/textopsx/README            |   20 +++++++++
 modules/textopsx/doc/functions.xml |   29 ++++++++++++
 modules/textopsx/textopsx.c        |   84 +++++++++++++++++++++++++++++++++++-
 3 files changed, 131 insertions(+), 2 deletions(-)

diff --git a/modules/textopsx/README b/modules/textopsx/README
index d4e51e8..104638a 100644
--- a/modules/textopsx/README
+++ b/modules/textopsx/README
@@ -19,6 +19,7 @@ Daniel-Constantin Mierla
         1.2.2. change_reply_status(code, reason)
         1.2.3. remove_body()
         1.2.4. keep_hf(regexp)
+        1.2.5. fnmatch(value, expr [, flags])
 
 1.1. Overview
 
@@ -95,3 +96,22 @@ remove_body();
 ...
 keep_hf("User-Agent");
 ...
+
+1.2.5. fnmatch(value, expr [, flags])
+
+   Match the value against the expr using the shell-style pattern for file
+   name matching (see man page for C function fnmatch()). It is known to
+   be faster and uses less-memory than regexp.
+
+   Parameters flags is optional and can be 'i' to do case insensitive
+   matching.
+
+   This function can be used from ANY_ROUTE.
+
+   Example 5. fnmatch() usage
+...
+if(fnmatch("$rU", "123*"))
+{
+    ...
+}
+...
diff --git a/modules/textopsx/doc/functions.xml b/modules/textopsx/doc/functions.xml
index eec3144..ab4eb06 100644
--- a/modules/textopsx/doc/functions.xml
+++ b/modules/textopsx/doc/functions.xml
@@ -117,4 +117,33 @@ keep_hf("User-Agent");
 		</example>
 	</section>
 
+	<section id="textopsx.fnmatch">
+		<title>
+		<function moreinfo="none">fnmatch(value, expr [, flags])</function>
+		</title>
+		<para>
+			Match the value against the expr using the shell-style pattern
+			for file name matching (see man page for C function fnmatch()).
+			It is known to be faster and uses less-memory than regexp.
+		</para>
+		<para>
+			Parameters flags is optional and can be 'i' to do case insensitive
+			matching.
+		</para>
+		<para>
+		This function can be used from ANY_ROUTE.
+		</para>
+		<example>
+		<title><function>fnmatch()</function> usage</title>
+		<programlisting format="linespecific">
+...
+if(fnmatch("$rU", "123*"))
+{
+    ...
+}
+...
+</programlisting>
+		</example>
+	</section>
+
 </section>
diff --git a/modules/textopsx/textopsx.c b/modules/textopsx/textopsx.c
index 687cce4..7dddf8b 100644
--- a/modules/textopsx/textopsx.c
+++ b/modules/textopsx/textopsx.c
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <fnmatch.h>
 
 #include "../../sr_module.h"
 #include "../../dprint.h"
@@ -40,10 +41,14 @@ MODULE_VERSION
 
 static int msg_apply_changes_f(sip_msg_t *msg, char *str1, char *str2);
 
-static int change_reply_status_f(struct sip_msg*, char*, char *);
+static int change_reply_status_f(sip_msg_t*, char*, char*);
 static int change_reply_status_fixup(void** param, int param_no);
 
-static int w_keep_hf_f(struct sip_msg*, char*, char *);
+static int w_keep_hf_f(sip_msg_t*, char*, char*);
+
+static int w_fnmatch2_f(sip_msg_t*, char*, char*);
+static int w_fnmatch3_f(sip_msg_t*, char*, char*, char*);
+static int fixup_fnmatch(void** param, int param_no);
 
 static int w_remove_body_f(struct sip_msg*, char*, char *);
 static int bind_textopsx(textopsx_api_t *tob);
@@ -58,6 +63,10 @@ static cmd_export_t cmds[] = {
 		0, ANY_ROUTE },
 	{"keep_hf",              (cmd_function)w_keep_hf_f,             1,
 		fixup_regexp_null, ANY_ROUTE },
+	{"fnmatch",              (cmd_function)w_fnmatch2_f,            2,
+		fixup_fnmatch, ANY_ROUTE },
+	{"fnmatch",              (cmd_function)w_fnmatch3_f,            3,
+		fixup_fnmatch, ANY_ROUTE },
 	{"bind_textopsx",        (cmd_function)bind_textopsx,           1,
 		0, ANY_ROUTE },
 
@@ -323,6 +332,77 @@ static int w_keep_hf_f(struct sip_msg* msg, char* key, char* foo)
 	return -1;
 }
 
+/**
+ *
+ */
+static int w_fnmatch(str *val, str *match, str *flags)
+{
+	int i;
+	i = 0;
+#ifdef FNM_CASEFOLD
+	if(flags && (flags->s[0]=='i' || flags->s[0]=='I'))
+		i = FNM_CASEFOLD;
+#endif
+	if(fnmatch(match->s, val->s, i)==0)
+		return 0;
+	return -1;
+}
+
+/**
+ *
+ */
+static int w_fnmatch2_f(sip_msg_t *msg, char *val, char *match)
+{
+	str sval;
+	str smatch;
+	if(get_str_fparam(&sval, msg, (fparam_t*)val)<0
+			|| get_str_fparam(&smatch, msg, (fparam_t*)match)<0)
+	{
+		LM_ERR("invalid parameters");
+		return -1;
+	}
+	if(w_fnmatch(&sval, &smatch, NULL)<0)
+		return -1;
+	return 1;
+}
+
+/**
+ *
+ */
+static int w_fnmatch3_f(sip_msg_t *msg, char *val, char *match, char *flags)
+{
+	str sval;
+	str smatch;
+	str sflags;
+	if(get_str_fparam(&sval, msg, (fparam_t*)val)<0
+			|| get_str_fparam(&smatch, msg, (fparam_t*)match)<0
+			|| get_str_fparam(&sflags, msg, (fparam_t*)flags)<0)
+	{
+		LM_ERR("invalid parameters");
+		return -1;
+	}
+	if(w_fnmatch(&sval, &smatch, &sflags)<0)
+		return -1;
+	return 1;
+}
+
+/**
+ *
+ */
+static int fixup_fnmatch(void** param, int param_no)
+{
+	if (param_no == 1) {
+		return fixup_var_pve_12(param, param_no);
+	} else if (param_no == 2) {
+		return fixup_var_pve_12(param, param_no);
+	} else if (param_no == 3) {
+		return fixup_var_pve_12(param, param_no);
+	} else {
+		return 0;
+	}
+
+}
+
 /*
  * Function to load the textops api.
  */




More information about the sr-dev mailing list