2 MiddleMan filtering proxy server
3 Copyright (C) 2002 Jason McLaughlin
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 KEYWORD_LIST *keyword_load(KEYWORD_LIST *keyword_list, XML_LIST *xml_list) {
25 KEYWORD_LIST *tmp_list = keyword_list;
26 struct KEYWORD_LIST_LIST *keywords = NULL;
28 if (tmp_list == NULL) {
29 tmp_list = xmalloc(sizeof(KEYWORD_LIST));
30 tmp_list->keyword_list = NULL;
31 tmp_list->threshold = 0;
32 tmp_list->template = NULL;
34 tmp_list->enabled = TRUE;
36 keyword_list = tmp_list;
38 pthread_rwlock_init(&tmp_list->lock, NULL);
40 keywords = tmp_list->keyword_list;
42 while ((xml_list = xml_section(xml_list, "<keywords>"))) {
43 XML_LIST_LOOP(xml_list, "<keywords>") {
44 XML_LIST_CMP(xml_list, "<item>") {
45 keywords = keyword_list_new(keywords);
46 keywords->id = tmp_list->id++;
48 if (tmp_list->keyword_list == NULL) tmp_list->keyword_list = keywords;
50 XML_LIST_LOOP(xml_list, "<item>") {
51 XML_LIST_CMP(xml_list, "<enabled>") {
52 xml_list = xml_list->next;
53 if (xml_list->type == XML_VALUE) {
54 if (!strcasecmp(xml_list->item, "false"))
55 keywords->enabled = FALSE;
57 keywords->enabled = TRUE;
60 XML_LIST_CMP(xml_list, "<comment>") {
61 xml_list = xml_list->next;
62 if (xml_list->type == XML_VALUE)
63 keyword_list_insert(keywords, xml_list->item, NULL, NULL, NULL, NULL, NULL);
65 XML_LIST_CMP(xml_list, "<host>") {
66 xml_list = xml_list->next;
67 if (xml_list->type == XML_VALUE)
68 keyword_list_insert(keywords, NULL, xml_list->item, NULL, NULL, NULL, NULL);
70 XML_LIST_CMP(xml_list, "<file>") {
71 xml_list = xml_list->next;
72 if (xml_list->type == XML_VALUE)
73 keyword_list_insert(keywords, NULL, NULL, xml_list->item, NULL, NULL, NULL);
75 XML_LIST_CMP(xml_list, "<mime>") {
76 xml_list = xml_list->next;
77 if (xml_list->type == XML_VALUE)
78 keyword_list_insert(keywords, NULL, NULL, NULL, xml_list->item, NULL, NULL);
80 XML_LIST_CMP(xml_list, "<keyword>") {
81 xml_list = xml_list->next;
82 if (xml_list->type == XML_VALUE)
83 keyword_list_insert(keywords, NULL, NULL, NULL, NULL, xml_list->item, NULL);
85 XML_LIST_CMP(xml_list, "<score>") {
86 xml_list = xml_list->next;
87 if (xml_list->type == XML_VALUE)
88 keyword_list_insert(keywords, NULL, NULL, NULL, NULL, NULL, xml_list->item);
92 XML_LIST_CMP(xml_list, "<enabled>") {
93 xml_list = xml_list->next;
94 if (xml_list->type == XML_VALUE) {
95 if (!strcasecmp(xml_list->item, "false"))
96 tmp_list->enabled = FALSE;
98 tmp_list->enabled = TRUE;
101 XML_LIST_CMP(xml_list, "<threshold>") {
102 xml_list = xml_list->next;
103 if (xml_list->type == XML_VALUE)
104 tmp_list->threshold = atoi(xml_list->item);
106 XML_LIST_CMP(xml_list, "<template>") {
107 xml_list = xml_list->next;
108 if (xml_list->type == XML_VALUE) {
109 FREE_AND_NULL(tmp_list->template);
110 tmp_list->template = xstrdup(xml_list->item);
119 XML_LIST *keyword_xml(KEYWORD_LIST *keyword_list, XML_LIST *xml_list) {
121 struct KEYWORD_LIST_LIST *kl;
123 pthread_rwlock_rdlock(&keyword_list->lock);
125 xml_list = xml_list_add(xml_list, "<keywords>", XML_TAG);
127 xml_list = xml_list_add(xml_list, "<enabled>", XML_TAG);
128 xml_list = xml_list_add(xml_list, (keyword_list->enabled == TRUE) ? "true" : "false", XML_VALUE);
129 xml_list = xml_list_add(xml_list, "</enabled>", XML_TAG);
131 xml_list = xml_list_add(xml_list, "<threshold>", XML_TAG);
132 snprintf(buf, sizeof(buf), "%d", keyword_list->threshold);
133 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
134 xml_list = xml_list_add(xml_list, "</threshold>", XML_TAG);
136 if (keyword_list->template != NULL) {
137 xml_list = xml_list_add(xml_list, "<template>", XML_TAG);
138 ptr = string_to_xml(keyword_list->template);
139 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
141 xml_list = xml_list_add(xml_list, "</template>", XML_TAG);
144 for (kl = keyword_list->keyword_list; kl; kl = kl->next) {
145 xml_list = xml_list_add(xml_list, "<item>", XML_TAG);
147 xml_list = xml_list_add(xml_list, "<enabled>", XML_TAG);
148 xml_list = xml_list_add(xml_list, (kl->enabled == TRUE) ? "true" : "false", XML_VALUE);
149 xml_list = xml_list_add(xml_list, "</enabled>", XML_TAG);
151 if (kl->comment != NULL) {
152 xml_list = xml_list_add(xml_list, "<comment>", XML_TAG);
153 ptr = string_to_xml(kl->comment);
154 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
156 xml_list = xml_list_add(xml_list, "</comment>", XML_TAG);
158 if (kl->host != NULL) {
159 xml_list = xml_list_add(xml_list, "<host>", XML_TAG);
160 ptr = string_to_xml(kl->host);
161 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
163 xml_list = xml_list_add(xml_list, "</host>", XML_TAG);
165 if (kl->file != NULL) {
166 xml_list = xml_list_add(xml_list, "<file>", XML_TAG);
167 ptr = string_to_xml(kl->file);
168 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
170 xml_list = xml_list_add(xml_list, "</file>", XML_TAG);
172 if (kl->mime != NULL) {
173 xml_list = xml_list_add(xml_list, "<mime>", XML_TAG);
174 ptr = string_to_xml(kl->mime);
175 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
177 xml_list = xml_list_add(xml_list, "</mime>", XML_TAG);
180 if (kl->keyword != NULL) {
181 xml_list = xml_list_add(xml_list, "<keyword>", XML_TAG);
182 ptr = string_to_xml(kl->keyword);
183 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
185 xml_list = xml_list_add(xml_list, "</keyword>", XML_TAG);
188 xml_list = xml_list_add(xml_list, "<score>", XML_TAG);
189 snprintf(buf, sizeof(buf), "%d", kl->score);
190 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
191 xml_list = xml_list_add(xml_list, "</score>", XML_TAG);
193 xml_list = xml_list_add(xml_list, "</item>", XML_TAG);
196 xml_list = xml_list_add(xml_list, "</keywords>", XML_TAG);
198 pthread_rwlock_unlock(&keyword_list->lock);
203 struct KEYWORD_LIST_LIST *keyword_list_new(struct KEYWORD_LIST_LIST *x) {
205 x = xmalloc(sizeof(struct KEYWORD_LIST_LIST));
208 while (x->next != NULL) x = x->next;
209 x->next = xmalloc(sizeof(struct KEYWORD_LIST_LIST));
230 void keyword_list_insert(struct KEYWORD_LIST_LIST *x, char *a, char *b, char *c, char *d, char *e, char *f) {
232 FREE_AND_NULL(x->comment);
235 x->comment = xstrdup(a);
238 if (x->he != NULL) reg_free(x->he);
239 FREE_AND_NULL(x->host);
242 x->he = reg_compile(b, REGFLAGS);
243 x->host = xstrdup(b);
247 if (x->fe != NULL) reg_free(x->fe);
248 FREE_AND_NULL(x->file);
251 x->fe = reg_compile(c, REGFLAGS);
252 x->file = xstrdup(c);
256 if (x->me != NULL) reg_free(x->me);
257 FREE_AND_NULL(x->mime);
260 x->me = reg_compile(d, REGFLAGS);
261 x->mime = xstrdup(d);
265 if (x->ke != NULL) reg_free(x->ke);
266 FREE_AND_NULL(x->keyword);
269 x->ke = reg_compile(e, REGFLAGS);
270 x->keyword = xstrdup(e);
279 struct KEYWORD_LIST_LIST *keyword_list_delete(struct KEYWORD_LIST_LIST *x) {
280 struct KEYWORD_LIST_LIST *start = x;
282 while (start->prev != NULL)
286 x->next->prev = x->prev;
288 x->prev->next = x->next;
292 if (x->he != NULL) reg_free(x->he);
293 if (x->fe != NULL) reg_free(x->fe);
294 if (x->me != NULL) reg_free(x->me);
295 if (x->ke != NULL) reg_free(x->ke);
296 FREE_AND_NULL(x->comment);
297 FREE_AND_NULL(x->host);
298 FREE_AND_NULL(x->file);
299 FREE_AND_NULL(x->mime);
300 FREE_AND_NULL(x->keyword);
307 void keyword_list_free(struct KEYWORD_LIST_LIST *kl) {
308 struct KEYWORD_LIST_LIST *tmp;
313 if (kl->he != NULL) reg_free(kl->he);
314 if (kl->fe != NULL) reg_free(kl->fe);
315 if (kl->me != NULL) reg_free(kl->me);
316 if (kl->ke != NULL) reg_free(kl->ke);
317 FREE_AND_NULL(kl->comment);
318 FREE_AND_NULL(kl->host);
319 FREE_AND_NULL(kl->file);
320 FREE_AND_NULL(kl->mime);
321 FREE_AND_NULL(kl->keyword);
329 void keyword_free(KEYWORD_LIST *keyword_list) {
330 if (keyword_list == NULL)
333 keyword_list_free(keyword_list->keyword_list);
335 FREE_AND_NULL(keyword_list->template);
337 pthread_rwlock_destroy(&keyword_list->lock);
342 int keyword_check(KEYWORD_LIST *keyword_list, CONNECTION *connection, FILEBUF *filebuf, int action) {
344 struct KEYWORD_LIST_LIST *kl;
346 if (!keyword_list || connection->bypass & FEATURE_KEYWORDS)
349 pthread_rwlock_rdlock(&keyword_list->lock);
351 if (keyword_list->enabled == FALSE) {
352 pthread_rwlock_unlock(&keyword_list->lock);
357 if (filebuf != NULL) filebuf_add(filebuf, "", 1);
359 for (kl = keyword_list->keyword_list; kl; kl = kl->next) {
360 if (kl->enabled == FALSE)
363 if (kl->he != NULL) {
364 ret = reg_exec(kl->he, connection->header->host);
368 if (kl->fe != NULL) {
369 ret = reg_exec(kl->fe, connection->header->file);
373 if (kl->me != NULL && connection->rheader->content_type != NULL) {
374 ret = reg_exec(kl->me, connection->rheader->content_type);
376 } else if (kl->me != NULL) {
377 ret = reg_exec(kl->me, "");
381 if (kl->ke != NULL && filebuf != NULL) {
382 ret = reg_exec(kl->ke, filebuf->data);
386 if (action == FALSE) {
387 /* just check if any entires apply to current page */
393 if (kl->score == 0) {
394 /* stop checking when we hit an entry with a score of 0 */
401 if (filebuf != NULL) filebuf_resize(filebuf, filebuf->size - 1);
403 pthread_rwlock_unlock(&keyword_list->lock);