Module: sip-router
Branch: master
Commit: 0c830402b517f3e4194dd28b0383e57b8a803d21
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=0c83040…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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.
*/