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
|
/* $Id: filter.c,v 1.7 2001-10-25 17:27:39 rjkaes Exp $
*
* Copyright (c) 1999 George Talusan (gstalusan@uwaterloo.ca)
*
* A substring of the domain to be filtered goes into the file
* pointed at by DEFAULT_FILTER.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include "tinyproxy.h"
#include "filter.h"
#include "regexp.h"
#include "utils.h"
static int err;
struct filter_list {
struct filter_list *next;
char *pat;
regex_t *cpat;
};
static struct filter_list *fl = NULL;
static int already_init = 0;
/* initializes a linked list of strings containing hosts to be filtered */
void filter_init(void)
{
FILE *fd;
struct filter_list *p;
char buf[255];
char *s;
if (!fl && !already_init) {
fd = fopen(config.filter, "r");
if (fd) {
p = NULL;
while (fgets(buf, 255, fd)) {
s = buf;
if (!p) /* head of list */
fl = p = safecalloc(1, sizeof(struct filter_list));
else { /* next entry */
p->next = safecalloc(1, sizeof(struct filter_list));
p = p->next;
}
/* replace first whitespace with \0 */
while (*s++)
if (isspace((unsigned char)*s))
*s = '\0';
p->pat = strdup(buf);
p->cpat = safemalloc(sizeof(regex_t));
if ((err = regcomp(p->cpat, p->pat, REG_NEWLINE | REG_NOSUB)) != 0) {
fprintf(stderr,
"Bad regex in %s: %s\n",
config.filter, p->pat);
exit(EX_DATAERR);
}
}
already_init = 1;
fclose(fd);
}
}
}
/* unlink the list */
void filter_destroy(void)
{
struct filter_list *p, *q;
if (already_init) {
for (p = q = fl; p; p = q) {
regfree(p->cpat);
safefree(p->cpat);
safefree(p->pat);
q = p->next;
safefree(p);
}
fl = NULL;
already_init = 0;
}
}
/* returns 0 if host is not an element of filter list, non-zero otherwise */
int filter_url(char *host)
{
struct filter_list *p;
char *s, *port;
int result;
if (!fl || !already_init)
return (0);
/* strip off the port number */
s = strdup(host);
port = strchr(s, ':');
if (port)
*port = '\0';
result = 0;
for (p = fl; p; p = p->next) {
result = !regexec(p->cpat, s, (size_t) 0, (regmatch_t *) 0, 0);
if (result)
break;
}
safefree(s);
return (result);
}
|