File: filterutil.c

package info (click to toggle)
leafnode 1.12.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,488 kB
  • sloc: ansic: 10,961; sh: 1,738; xml: 627; makefile: 258; perl: 84; sed: 4
file content (124 lines) | stat: -rw-r--r-- 3,030 bytes parent folder | download | duplicates (2)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
filterutil.c -- read filter file and do filtering of messages

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

Modified and Copyright of modifications 2001-2021 by Matthias Andree

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 "ln_log.h"

struct filterlist {
    struct filterlist *next;
    char *cleartext;
    pcre2_code_8 *re;
};

static struct filterlist *filter;

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

    if (fifi == NULL || !strlen(fifi))
	return;
    filter = NULL;
    ff = fopen(fifi, "r");
    if (!ff) {
	int e = errno;
	syslog(LOG_ERR, "Unable to open filterfile %s: %m", fifi);
	printf("Unable to open filterfile %s: %s\n", fifi, strerror(e));
	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 (NULL == (f->re = pcre2_compile_8((u_char *)l, PCRE2_ZERO_TERMINATED, PCRE2_MULTILINE,
					   &regex_errcode, &regex_errpos, NULL)))
	{
	    unsigned char buf[SIZE_lineout];
	    int len = pcre2_get_error_message_8(regex_errcode, buf, sizeof(buf));
	    syslog(LOG_ERR, "Invalid filter pattern %s: %s%s", l, buf,
		   len == PCRE2_ERROR_NOMEMORY ? "[...]" : "");
	    printf("Invalid filter pattern %s %s%s", l, buf,
	    	   len == PCRE2_ERROR_NOMEMORY ? "[...]" : "");
	    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(unsigned char *h)
{
    struct filterlist *f = filter;
    int match;
    pcre2_match_data_8 *match_data = pcre2_match_data_create_8(1, NULL);
    if (NULL == match_data) {
	    ln_log(LNLOG_SERR, LNLOG_CTOP, "filterutil.c::dofilter: out of memory allocating match_data");
	    return -1;
    }

    match = PCRE2_ERROR_NOMATCH;
    while (f && 0 > match) {
	match = pcre2_match_8(f->re, h, PCRE2_ZERO_TERMINATED, /*offset*/ 0, /*options*/ 0, match_data, /*ctx*/ NULL);
	if (debugmode > 1) {
	    syslog(LOG_DEBUG, "(\"%s\" =~ /%s/) = %d", h, f->cleartext, match);
	}
	if (match >= 0) {
	    pcre2_match_data_free_8(match_data);
	    return TRUE;
	}
	f = f->next;
    }
    pcre2_match_data_free_8(match_data);
    return FALSE;		/* no match, or internal error */
}

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

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