diff options
Diffstat (limited to 'src/filter.c')
-rw-r--r-- | src/filter.c | 117 |
1 files changed, 45 insertions, 72 deletions
diff --git a/src/filter.c b/src/filter.c index 3164191..d70cb59 100644 --- a/src/filter.c +++ b/src/filter.c @@ -24,23 +24,23 @@ #include "main.h" +#include <regex.h> #include "filter.h" #include "heap.h" #include "log.h" #include "reqs.h" #include "conf.h" +#include "sblist.h" #define FILTER_BUFFER_LEN (512) static int err; struct filter_list { - struct filter_list *next; - char *pat; - regex_t *cpat; + regex_t cpatb; }; -static struct filter_list *fl = NULL; +static sblist *fl = NULL; static int already_init = 0; static filter_policy_t default_policy = FILTER_DEFAULT_ALLOW; @@ -50,34 +50,38 @@ static filter_policy_t default_policy = FILTER_DEFAULT_ALLOW; void filter_init (void) { FILE *fd; - struct filter_list *p; + struct filter_list fe; char buf[FILTER_BUFFER_LEN]; - char *s; - int cflags; + char *s, *start; + int cflags, lineno = 0; if (fl || already_init) { return; } - fd = fopen (config.filter, "r"); + fd = fopen (config->filter, "r"); if (!fd) { return; } - p = NULL; - cflags = REG_NEWLINE | REG_NOSUB; - if (config.filter_extended) + if (config->filter_extended) cflags |= REG_EXTENDED; - if (!config.filter_casesensitive) + if (!config->filter_casesensitive) cflags |= REG_ICASE; while (fgets (buf, FILTER_BUFFER_LEN, fd)) { + ++lineno; + /* skip leading whitespace */ + s = buf; + while (*s && isspace ((unsigned char) *s)) + s++; + start = s; + /* * Remove any trailing white space and * comments. */ - s = buf; while (*s) { if (isspace ((unsigned char) *s)) break; @@ -93,34 +97,28 @@ void filter_init (void) ++s; } *s = '\0'; - - /* skip leading whitespace */ - s = buf; - while (*s && isspace ((unsigned char) *s)) - s++; + s = start; /* skip blank lines and comments */ if (*s == '\0') continue; - if (!p) /* head of list */ - fl = p = - (struct filter_list *) - safecalloc (1, sizeof (struct filter_list)); - else { /* next entry */ - p->next = - (struct filter_list *) - safecalloc (1, sizeof (struct filter_list)); - p = p->next; - } + if (!fl) fl = sblist_new(sizeof(struct filter_list), + 4096/sizeof(struct filter_list)); - p->pat = safestrdup (s); - p->cpat = (regex_t *) safemalloc (sizeof (regex_t)); - err = regcomp (p->cpat, p->pat, cflags); + err = regcomp (&fe.cpatb, s, cflags); if (err != 0) { + if (err == REG_ESPACE) goto oom; + fprintf (stderr, + "Bad regex in %s: line %d - %s\n", + config->filter, lineno, s); + exit (EX_DATAERR); + } + if (!sblist_add(fl, &fe)) { + oom:; fprintf (stderr, - "Bad regex in %s: %s\n", - config.filter, p->pat); + "out of memory parsing filter file %s: line %d\n", + config->filter, lineno); exit (EX_DATAERR); } } @@ -136,15 +134,16 @@ void filter_init (void) /* unlink the list */ void filter_destroy (void) { - struct filter_list *p, *q; + struct filter_list *p; + size_t i; if (already_init) { - for (p = q = fl; p; p = q) { - regfree (p->cpat); - safefree (p->cpat); - safefree (p->pat); - q = p->next; - safefree (p); + if (fl) { + for (i = 0; i < sblist_getsize(fl); ++i) { + p = sblist_get(fl, i); + regfree (&p->cpatb); + } + sblist_free(fl); } fl = NULL; already_init = 0; @@ -156,7 +155,7 @@ void filter_destroy (void) */ void filter_reload (void) { - if (config.filter) { + if (config->filter) { log_message (LOG_NOTICE, "Re-reading filter file."); filter_destroy (); filter_init (); @@ -164,45 +163,19 @@ void filter_reload (void) } /* Return 0 to allow, non-zero to block */ -int filter_domain (const char *host) -{ - struct filter_list *p; - int result; - - if (!fl || !already_init) - goto COMMON_EXIT; - - for (p = fl; p; p = p->next) { - result = - regexec (p->cpat, host, (size_t) 0, (regmatch_t *) 0, 0); - - if (result == 0) { - if (default_policy == FILTER_DEFAULT_ALLOW) - return 1; - else - return 0; - } - } - -COMMON_EXIT: - if (default_policy == FILTER_DEFAULT_ALLOW) - return 0; - else - return 1; -} - -/* returns 0 to allow, non-zero to block */ -int filter_url (const char *url) +int filter_run (const char *str) { struct filter_list *p; + size_t i; int result; if (!fl || !already_init) goto COMMON_EXIT; - for (p = fl; p; p = p->next) { + for (i = 0; i < sblist_getsize(fl); ++i) { + p = sblist_get(fl, i); result = - regexec (p->cpat, url, (size_t) 0, (regmatch_t *) 0, 0); + regexec (&p->cpatb, str, (size_t) 0, (regmatch_t *) 0, 0); if (result == 0) { if (default_policy == FILTER_DEFAULT_ALLOW) |