diff options
Diffstat (limited to 'src/msntab.c')
-rw-r--r-- | src/msntab.c | 53 |
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); } |