summaryrefslogtreecommitdiffstats
path: root/src/msntab.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/msntab.c')
-rw-r--r--src/msntab.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/src/msntab.c b/src/msntab.c
index 6bdd17c..12002d5 100644
--- a/src/msntab.c
+++ b/src/msntab.c
@@ -29,6 +29,7 @@
#include <fnmatch.h>
#include <stdio.h>
#include <unistd.h>
+#include <regex.h>
#include <libdaemon/dlog.h>
@@ -43,13 +44,63 @@ static int n_entries = 0;
static int n_includes = 0;
+int regex_match(const char *re, const char *s) {
+ regex_t r;
+ int ret;
+ char e[256];
+
+ if ((ret = regcomp(&r, re, REG_EXTENDED|REG_NOSUB)) != 0) {
+ regerror(ret, &r, e, sizeof(e));
+ daemon_log(LOG_WARNING, "Failed to compile regular expression '%s', will never match: %s", re, e);
+ return -1;
+ }
+
+ ret = regexec(&r, s, 0, NULL, 0) == 0 ? 0 : -1;
+ regfree(&r);
+
+ return ret;
+}
+
+int glob_match(const char *e, const char *s) {
+ char p[256];
+ const char *n = e;
+
+ for (;;) {
+ size_t m, i = strcspn(n, ";,");
+
+ m = sizeof(p)-1 < i ? sizeof(p)-1 : i;
+ strncpy(p, n, m);
+ p[m] = 0;
+
+ if (!fnmatch(p, s, 0))
+ return 0;
+
+ if (*(n+i) == 0)
+ return -1;
+
+ n += i+1;
+ }
+}
+
struct tabentry* msntab_check_call(const char *callee, const char *caller) {
struct tabentry *l = first;
while (l) {
+ int a, b;
assert(l->local && l->remote);
+
+ if (l->local[0] == '~')
+ a = !regex_match(l->local+1, callee);
+ else
+ a = !glob_match(l->local, callee);
+
+
+ if (l->remote[0] == '~')
+ b = !regex_match(l->remote+1, caller);
+ else
+ b = !glob_match(l->remote, caller);
- if (!fnmatch(l->local, callee, 0) && !fnmatch(l->remote, caller, 0)) {
+ if (a && b) {
daemon_log(LOG_INFO, "MSN table entry from '%s:%u' matched.", l->filename, l->line);
return msntab_ref(l);
}