Sfoglia il codice sorgente

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

- shell-style pattern matching (via file selection wildcards), using C
  function fnmatch()
Daniel-Constantin Mierla 13 anni fa
parent
commit
0c830402b5
3 ha cambiato i file con 131 aggiunte e 2 eliminazioni
  1. 20 0
      modules/textopsx/README
  2. 29 0
      modules/textopsx/doc/functions.xml
  3. 82 2
      modules/textopsx/textopsx.c

+ 20 - 0
modules/textopsx/README

@@ -19,6 +19,7 @@ Daniel-Constantin Mierla
         1.2.2. change_reply_status(code, reason)
         1.2.2. change_reply_status(code, reason)
         1.2.3. remove_body()
         1.2.3. remove_body()
         1.2.4. keep_hf(regexp)
         1.2.4. keep_hf(regexp)
+        1.2.5. fnmatch(value, expr [, flags])
 
 
 1.1. Overview
 1.1. Overview
 
 
@@ -95,3 +96,22 @@ remove_body();
 ...
 ...
 keep_hf("User-Agent");
 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*"))
+{
+    ...
+}
+...

+ 29 - 0
modules/textopsx/doc/functions.xml

@@ -113,6 +113,35 @@ remove_body();
 ...
 ...
 keep_hf("User-Agent");
 keep_hf("User-Agent");
 ...
 ...
+</programlisting>
+		</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>
 </programlisting>
 		</example>
 		</example>
 	</section>
 	</section>

+ 82 - 2
modules/textopsx/textopsx.c

@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
+#include <fnmatch.h>
 
 
 #include "../../sr_module.h"
 #include "../../sr_module.h"
 #include "../../dprint.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 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 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 w_remove_body_f(struct sip_msg*, char*, char *);
 static int bind_textopsx(textopsx_api_t *tob);
 static int bind_textopsx(textopsx_api_t *tob);
@@ -58,6 +63,10 @@ static cmd_export_t cmds[] = {
 		0, ANY_ROUTE },
 		0, ANY_ROUTE },
 	{"keep_hf",              (cmd_function)w_keep_hf_f,             1,
 	{"keep_hf",              (cmd_function)w_keep_hf_f,             1,
 		fixup_regexp_null, ANY_ROUTE },
 		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,
 	{"bind_textopsx",        (cmd_function)bind_textopsx,           1,
 		0, ANY_ROUTE },
 		0, ANY_ROUTE },
 
 
@@ -323,6 +332,77 @@ static int w_keep_hf_f(struct sip_msg* msg, char* key, char* foo)
 	return -1;
 	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.
  * Function to load the textops api.
  */
  */