File: filterutil.c

package info (click to toggle)
leafnode 1.11.11-1
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 2,468 kB
  • sloc: ansic: 10,914; sh: 1,748; xml: 628; makefile: 291; perl: 84; sed: 4
file content (110 lines) | stat: -rw-r--r-- 2,302 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
libutil -- read filter file and do filtering of messages

Written by Cornelius Krasel <krasel@wpxx02.toxi.uni-wuerzburg.de>.
Copyright 1998.

See file COPYING for restrictions on the use of this software.
*/

#include "leafnode.h"
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <pcre.h>

struct filterlist {
    struct filterlist *next;
    char *cleartext;
    pcre *expr;
};

static struct filterlist *filter;

/*
 * read filters into memory. Filters are just plain regexps
 */
void
readfilter(char *fifi)
{
    FILE *ff;
    char *l;
    const char *regex_errmsg;
    int regex_errpos;
    struct filterlist *f, *oldf;

    if (fifi == NULL || !strlen(fifi))
	return;
    filter = NULL;
    ff = fopen(fifi, "r");
    if (!ff) {
	syslog(LOG_ERR, "Unable to open filterfile %s: %m", fifi);
	printf("Unable to open filterfile %s\n", fifi);
	return;
    }
    oldf = NULL;
    debug = 0;
    while ((l = getaline(ff)) != NULL) {
	if (*l == '#' || *l == '\0')
	    continue;
	f = (struct filterlist *)critmalloc(sizeof(struct filterlist),
					    "Allocating filterlist space");
	if ((f->expr = pcre_compile(l, PCRE_MULTILINE,
				    &regex_errmsg, &regex_errpos,
				    NULL)) == NULL) {
	    syslog(LOG_ERR, "Invalid filter pattern %s: %s", l, regex_errmsg);
	    printf("Invalid filter pattern %s %s", l, regex_errmsg);
	    free(f);
	} else {
	    f->next = NULL;
	    f->cleartext = critstrdup(l, "readfilter");
	    if (!filter)
		filter = f;
	    else
		oldf->next = f;
	    oldf = f;
	}
    }
    debug = debugmode;
    fclose(ff);
}

/*
 * read and filter headers.
 * Return true if headers matched pattern, false if not
 */
int
dofilter(char *h)
{
    struct filterlist *f = filter;
    int match;

    match = -1;
    while (f && match == -1) {
	match = pcre_exec(f->expr, NULL, h, strlen(h), 0, 0, NULL, 0);
	if (debugmode > 1) {
	    syslog(LOG_DEBUG, "(\"%s\" =~ /%s/) = %d", h, f->cleartext, match);
	}
	if (match >= 0) {
	    return TRUE;
	}
	f = f->next;
    }
    return FALSE;		/* no match, or internal error */
}

void freefilter(void) {
    struct filterlist *f = filter, *g;

    while(f) {
	free(f->cleartext);
	pcre_free(f->expr);
	g = f->next;
	free(f);
	f = g;
    }
    filter = NULL;
}