Removed threading
[middleman.git] / src / interface.c
1 /*
2     MiddleMan filtering proxy server
3     Copyright (C) 2002  Jason McLaughlin
4
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.
9
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.
14
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
18 */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include "proto.h"
25
26 extern char configfile[];
27
28 extern THREADLIST threads[];
29 extern pthread_mutex_t dns_cache_lock;
30 extern HASH_TABLE *dns_cache;
31 extern FILTER_LIST *filter_list;
32 extern HEADER_LIST *header_list;
33 extern MIME_LIST *mime_list;
34 extern REDIRECT_LIST *redirect_list;
35 extern KEYWORD_LIST *keyword_list;
36 extern ACCESS_LIST *access_list;
37 extern COOKIE_LIST *cookie_list;
38 extern REWRITE_LIST *rewrite_list;
39 extern FORWARD_LIST *forward_list;
40 extern TEMPLATES *templates;
41 extern EXTERNAL *external;
42 extern NETWORK *network;
43 extern LOGBUFFER *logbuffer;
44
45 struct pages_t {
46         char *file;
47         void (*handler) (FILEBUF *, struct cgi_args_t *, CONNECTION *);
48 };
49
50 struct pages_t pages[] = {
51         {"/connections", interface_page_connections},
52         {"/dnscache", interface_page_dnscache},
53         {"/headers", interface_page_headers},
54         {"/config", interface_page_config},
55         {"/save", interface_page_save},
56         {"/load", interface_page_load},
57         {"/log", interface_page_log},
58         {NULL, NULL}
59 };
60
61 struct pages_t config_pages[] = {
62         {"filter", interface_page_config_filter},
63         {"access", interface_page_config_access},
64         {"rewrite", interface_page_config_rewrite},
65         {"mime", interface_page_config_mime},
66         {"cookies", interface_page_config_cookies},
67         {"external", interface_page_config_external},
68         {"templates", interface_page_config_templates},
69         {"network", interface_page_config_network},
70         {"header", interface_page_config_header},
71         {"redirect", interface_page_config_redirect},
72         {"forward", interface_page_config_forward},
73         {"keywords", interface_page_config_keywords},
74         {NULL, NULL}
75 };
76
77 struct pages_t action_pages[] = {
78         {"filter", interface_page_config_filter_action},
79         {"external", interface_page_config_external_action},
80         {"rewrite", interface_page_config_rewrite_action},
81         {"access", interface_page_config_access_action},
82         {"mime", interface_page_config_mime_action},
83         {"templates", interface_page_config_templates_action},
84         {"header", interface_page_config_header_action},
85         {"cookies", interface_page_config_cookies_action},
86         {"redirect", interface_page_config_redirect_action},
87         {"forward", interface_page_config_forward_action},
88         {"keywords", interface_page_config_keywords_action},
89         {NULL, NULL}
90 };
91
92 struct pages_t dialog_pages[] = {
93         {"filter", interface_page_config_filter_dialog},
94         {"external", interface_page_config_external_dialog},
95         {"rewrite", interface_page_config_rewrite_dialog},
96         {"access", interface_page_config_access_dialog},
97         {"mime", interface_page_config_mime_dialog},
98         {"templates", interface_page_config_templates_dialog},
99         {"header", interface_page_config_header_dialog},
100         {"cookies", interface_page_config_cookies_dialog},
101         {"redirect", interface_page_config_redirect_dialog},
102         {"forward", interface_page_config_forward_dialog},
103         {"keywords", interface_page_config_keywords_dialog},
104         {NULL, NULL}
105 };
106
107 struct cgi_args_t *cgi_parse_request(char *file)
108 {
109         int pos = 0, astart = 0, aequal = -1;
110         struct cgi_args_t *args = NULL, *start = NULL;
111
112         for (; file[pos]; pos++) {
113                 if (file[pos] == '=')
114                         aequal = pos;
115                 else if (file[pos] == '&' && aequal != -1) {
116                         if (args == NULL) {
117                                 args = xmalloc(sizeof(struct cgi_args_t));
118                                 start = args;
119                         } else {
120                                 args->next = xmalloc(sizeof(struct cgi_args_t));
121                                 args = args->next;
122                         }
123
124                         args->name = url_decode(&file[astart], aequal - astart);
125                         args->value = url_decode(&file[aequal + 1], pos - aequal - 1);
126
127                         args->next = NULL;
128
129                         aequal = -1;
130                         astart = pos + 1;
131                 }
132         }
133
134         if (aequal != -1) {
135                 if (args == NULL) {
136                         args = xmalloc(sizeof(struct cgi_args_t));
137                         start = args;
138                 } else {
139                         args->next = xmalloc(sizeof(struct cgi_args_t));
140                         args = args->next;
141                 }
142
143                 args->next = NULL;
144
145                 args->name = url_decode(&file[astart], aequal - astart);
146                 args->value = url_decode(&file[aequal + 1], pos - aequal - 1);
147         }
148
149         return start;
150 }
151
152 void cgi_args_free(struct cgi_args_t *args)
153 {
154         struct cgi_args_t *tmp;
155
156         while (args != NULL) {
157                 tmp = args->next;
158
159                 xfree(args->name);
160                 xfree(args->value);
161
162                 xfree(args);
163                 args = tmp;
164         }
165 }
166
167 void interface_handle_request(CONNECTION * connection)
168 {
169         int i;
170         char *ptr = NULL, *file;
171         HEADER *header;
172         FILEBUF *filebuf;
173         struct cgi_args_t *args = NULL;
174
175         if (!strncasecmp(&connection->header->file[(connection->header->type == HTTP_REQUEST) ? strlen(INTERFACEURL) + 1 : 0], "/template/", 9)) {
176                 template_send(templates, &connection->header->file[(connection->header->type == HTTP_REQUEST) ? strlen(INTERFACEURL) + 11 : 10], connection, 200);
177
178                 return;
179         }
180
181         if (!(connection->access & ACCESS_CONFIG)) {
182                 template_send(templates, "noaccess", connection, 403);
183
184                 return;
185         }
186
187         header = header_new();
188
189         header->type = HTTP_RESP;
190         header->code = 200;
191         header->version = HTTP_HTTP11;
192         header->content_type = xstrdup("text/html");
193
194         if (connection->header->type == HTTP_REQUEST) {
195                 /* we wouldn't be here if connection->header->file wasn't this big */
196                 file = connection->header->file + strlen(INTERFACEURL) + 1;
197
198                 if (*file != '/') {
199                         /* send redirect to correct relative links */
200
201                         header->code = 302;
202                         header->content_length = 0;
203                         header->location = xmalloc(strlen(INTERFACEURL) + 2);
204                         sprintf(header->location, "%s/", INTERFACEURL);
205
206                         header_send(header, connection, CLIENT, HEADER_RESP);
207
208                         http_header_free(header);
209
210                         return;
211                 }
212         } else
213                 file = connection->header->file;
214
215
216         if (strcasecmp(connection->header->method, "POST")) {
217                 /* retrieve cgi arguments from GET request */
218                 ptr = strchr(file, '?');
219                 if (ptr != NULL)
220                         args = cgi_parse_request(&ptr[1]);
221         } else if (connection->header->content_length != -1) {
222                 /* retrieve form data from POST request */
223                 filebuf = http_transfer_filebuf(connection, CLIENT);
224                 filebuf_add(filebuf, "", 1);
225
226                 args = cgi_parse_request(filebuf->data);
227
228                 filebuf_free(filebuf);
229         }
230
231         filebuf = filebuf_new();
232
233         filebuf_addf(filebuf, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
234         filebuf_addf(filebuf, "<html><head><title>Middleman %s web interface</title></head>\n", MMAN_VERSION);
235         filebuf_addf(filebuf, "<body bgcolor=\"%s\" text=\"%s\" link=\"%s\" vlink=\"%s\">\n", INTERFACE_BG, INTERFACE_TEXT, INTERFACE_LINK, INTERFACE_VLINK);
236         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\">\n");
237         filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
238         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\"><tr><td align=\"center\"><font size=\"6\">Middleman Web interface</font></td></tr></table>\n", INTERFACE_TABLEBG);
239         filebuf_addf(filebuf, "</td></tr><tr><td><br></td></tr>\n");
240         filebuf_addf(filebuf, "<tr><td><table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"100%\" bgcolor=\"%s\"><tr align=\"center\">\n", INTERFACE_TABLEBG);
241         filebuf_addf(filebuf, "<td><a href=\"connections\">Active connections</a></td>\n");
242         filebuf_addf(filebuf, "<td><a href=\"config\">Config</a></td>\n");
243         filebuf_addf(filebuf, "<td><a href=\"dnscache\">DNS cache</a></td>\n");
244         filebuf_addf(filebuf, "<td><a href=\"headers\">Show headers</a></td></tr>\n");
245         filebuf_addf(filebuf, "<tr align=\"center\">\n");
246         filebuf_addf(filebuf, "<td colspan=\"2\"><a href=\"save\">Save settings</a></td>\n");
247         filebuf_addf(filebuf, "<td colspan=\"2\"><a href=\"load\">Load settings</a></td>\n");
248         filebuf_addf(filebuf, "</tr>\n");
249         filebuf_addf(filebuf, "<tr align=\"center\"><td colspan=\"4\"><a href=\"log\">View log entries</a></td></tr>\n");
250         filebuf_addf(filebuf, "</table></td></tr>\n<tr><td><br></td></tr><tr><td>\n");
251
252         for (i = 0; pages[i].file != NULL; i++) {
253                 if (!strncasecmp(file, pages[i].file, (ptr != NULL) ? ptr - file : ~0))
254                         pages[i].handler(filebuf, args, connection);
255         }
256
257         filebuf_addf(filebuf, "</td></tr></table></body></html>\n");
258
259         header->content_length = filebuf->size;
260
261         header_send(header, connection, CLIENT, HEADER_RESP);
262
263         if (strcasecmp(connection->header->method, "HEAD"))
264                 net_filebuf_send(filebuf, connection, CLIENT);
265
266         if (args != NULL)
267                 cgi_args_free(args);
268         http_header_free(header);
269         filebuf_free(filebuf);
270 }
271
272 void interface_page_connections(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
273 {
274         int i;
275
276         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"100%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
277
278         filebuf_addf(filebuf, "<tr><td>PID</td><td>IP</td><td>Requests</td><td>Method</td><td>Host</td><td>Port</td><td>File</td></tr>\n");
279
280         for (i = 0; i < MAXTHREADS; i++) {
281                 pthread_mutex_lock(&threads[i].lock);
282                 if (threads[i].flags != THREAD_UNUSED && threads[i].flags != THREAD_IDLE)
283                         filebuf_addf(filebuf, "<tr><td>%d</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td></tr>\n", threads[i].pid, threads[i].ip, threads[i].requests, (threads[i].method != NULL) ? threads[i].method : "NONE", (threads[i].host != NULL) ? threads[i].host : "NONE", threads[i].port, (threads[i].file != NULL) ? threads[i].file : "NONE");
284
285                 pthread_mutex_unlock(&threads[i].lock);
286         }
287
288         filebuf_addf(filebuf, "</table>\n");
289 }
290
291 void interface_page_dnscache(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
292 {
293         int i;
294         struct HASH_LIST *hash_list;
295
296         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"100%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
297
298         filebuf_addf(filebuf, "<tr><td>Hostname</td><td>IP address</td></tr>\n");
299
300         pthread_mutex_lock(&dns_cache_lock);
301         for (i = 0; i < dns_cache->size; i++) {
302                 hash_list = dns_cache->hash_list[i];
303
304                 for (; hash_list; hash_list = hash_list->next)
305                         filebuf_addf(filebuf, "<tr><td>%s</td><td>%s</td></tr>\n", hash_list->ref, (char *) hash_list->data);
306         }
307
308         filebuf_addf(filebuf, "</table>\n");
309
310         pthread_mutex_unlock(&dns_cache_lock);
311 }
312
313 void interface_page_headers(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
314 {
315         struct HTTP_HEADER_LIST *header_list;
316
317
318         filebuf_addf(filebuf, "<tr><td><table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"100%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
319         filebuf_addf(filebuf, "<tr><th colspan=\"2\">Unfiltered</th></tr>\n");
320         filebuf_addf(filebuf, "<tr><td>Type</td><td>Value</td></tr>\n");
321
322         for (header_list = connection->header->header; header_list; header_list = header_list->next)
323                 if (!bad_header(header_list->type, HEADER_DIRECT)) filebuf_addf(filebuf, "<tr><td>%s</td><td>%s</td></tr>\n", header_list->type, header_list->value);
324
325         filebuf_addf(filebuf, "</table></td></tr>\n");
326
327         filebuf_addf(filebuf, "<tr><td><br></td></tr>\n");
328
329         filebuf_addf(filebuf, "<tr><td><table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"100%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
330         filebuf_addf(filebuf, "<tr><th colspan=\"2\">Filtered</th></tr>\n");
331         filebuf_addf(filebuf, "<tr><td>Type</td><td>Value</td></tr>\n");
332
333         for (header_list = connection->header->header_filtered; header_list; header_list = header_list->next)
334                 if (!bad_header(header_list->type, HEADER_DIRECT)) filebuf_addf(filebuf, "<tr><td>%s</td><td>%s</td></tr>\n", header_list->type, header_list->value);
335
336         filebuf_addf(filebuf, "</table></td></tr>\n");
337 }
338
339 void interface_page_save(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
340 {
341         int ret;
342         char *filename = NULL;
343
344         for (; args; args = args->next)
345                 if (!strcasecmp(args->name, "filename"))
346                         filename = args->value;
347
348         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\"><tr><td align=\"center\">\n");
349
350         if (filename == NULL) {
351                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
352                 filebuf_addf(filebuf, "<form action=\"save\" method=\"POST\">\n");
353                 filebuf_addf(filebuf, "<tr><td>Filename</td><td><input type=\"text\" name=\"filename\" value=\"%s\" size=\"80\"></td></tr>\n", (*configfile) ? configfile : "");
354                 filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
355                 filebuf_addf(filebuf, "</form></table>\n");
356
357                 filebuf_addf(filebuf, "</td></tr></table>\n");
358
359                 return;
360         }
361
362         ret = config_save(filename);
363
364         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
365         filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
366         if (ret == TRUE)
367                 filebuf_addf(filebuf, "File saved\n");
368         else
369                 filebuf_addf(filebuf, "Saved failed\n");
370
371         filebuf_addf(filebuf, "</td></tr></table></td></tr></table>\n");
372 }
373
374 void interface_page_load(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
375 {
376         int ret, overwrite = FALSE;
377         char *filename = NULL;
378
379         for (; args; args = args->next) {
380                 if (!strcasecmp(args->name, "filename"))
381                         filename = args->value;
382                 else if (!strcasecmp(args->name, "overwrite")) {
383                         if (!strcasecmp(args->value, "yes"))
384                                 overwrite = TRUE;
385                         else
386                                 overwrite = FALSE;
387                 }
388         }
389
390         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\"><tr><td align=\"center\">\n");
391
392         if (filename == NULL) {
393                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
394                 filebuf_addf(filebuf, "<form action=\"load\" method=\"POST\">\n");
395                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Filename</td><td><input type=\"text\" name=\"filename\" value=\"%s\" size=\"80\"></td></tr>\n", (*configfile) ? configfile : "");
396                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Overwrite</td><td align=\"center\">Yes: <input type=\"radio\" name=\"overwrite\" value=\"yes\" checked>   No: <input type=\"radio\" name=\"overwrite\" value=\"no\"></td></tr>\n");
397                 filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
398                 filebuf_addf(filebuf, "</form></table>\n");
399
400                 filebuf_addf(filebuf, "</td></tr></table>\n");
401
402                 return;
403         }
404
405         ret = config_load(overwrite, filename);
406
407         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
408         filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
409
410         if (ret == TRUE)
411                 filebuf_addf(filebuf, "File loaded\n");
412         else
413                 filebuf_addf(filebuf, "Load failed\n");
414
415         filebuf_addf(filebuf, "</td></tr></table></td></tr></table>\n");
416 }
417
418 void interface_page_log(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
419 {
420         int size = -1, clear = FALSE;
421         char *ptr, *pattern = NULL;
422         struct LOGBUFFER_LIST *ll;
423         struct cgi_args_t *a;
424         regex_t *pe = NULL;
425
426         for (a = args; a; a = a->next) {
427                 if (!strcasecmp(a->name, "pattern"))
428                         pattern = a->value;
429                 if (!strcasecmp(a->name, "clear"))
430                         clear = TRUE;
431                 if (!strcasecmp(a->name, "size"))
432                         size = atoi(a->value);
433         }
434
435         if (clear == TRUE)
436                 logbuffer_clear(logbuffer);
437         if (size != -1)
438                 logbuffer_resize(logbuffer, size);
439
440         pthread_rwlock_rdlock(&logbuffer->lock);
441
442         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\"><tr><td align=\"center\">\n");
443         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
444         filebuf_addf(filebuf, "<form action=\"log\" method=\"POST\">\n");
445         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\">Regular expression match</td></tr>\n");
446         filebuf_addf(filebuf, "<tr><td align=\"center\" colspan=\"2\"><input type=\"text\" name=\"pattern\" value=\"%s\" size=\"80\"></td></tr>\n", (pattern != NULL) ? pattern : "");
447         filebuf_addf(filebuf, "<tr><td align=\"center\">Log buffer size: <input type=\"text\" name=\"size\" value=\"%d\" size=\"10\"></td>\n", logbuffer->size);
448         filebuf_addf(filebuf, "<td align=\"center\">Clear: <input type=\"checkbox\" name=\"clear\" value=\"yes\"></td></tr>");
449         filebuf_addf(filebuf, "<tr><td align=\"center\" colspan=\"2\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
450         filebuf_addf(filebuf, "</form></table></td></tr><tr><td><br></td></tr>\n");
451
452         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"100%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
453
454         pthread_rwlock_unlock(&logbuffer->lock);
455
456         if (pattern != NULL && strcmp(pattern, ""))
457                 pe = reg_compile(pattern, REGFLAGS);
458
459         pthread_rwlock_rdlock(&logbuffer->lock);
460
461         for (ll = logbuffer->head; ll; ll = ll->next) {
462                 if (pe != NULL)
463                         if (reg_exec(pe, ll->msg))
464                                 continue;
465
466                 ptr = string_to_html(ll->msg, TRUE);
467                 filebuf_addf(filebuf, "<tr><td>%s</td></tr>\n", ptr);
468                 xfree(ptr);
469         }
470
471         if (pe != NULL)
472                 reg_free(pe);
473
474         filebuf_addf(filebuf, "</table></td></tr></table>\n");
475
476         pthread_rwlock_unlock(&logbuffer->lock);
477 }
478 void interface_page_config(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
479 {
480         int i;
481         char *section = NULL, *action = NULL, *dialog = NULL;
482         struct cgi_args_t *a;
483
484         for (a = args; a != NULL; a = a->next) {
485                 if (!strcasecmp(a->name, "section"))
486                         section = a->value;
487                 else if (!strcasecmp(a->name, "action"))
488                         action = a->value;
489                 else if (!strcasecmp(a->name, "dialog"))
490                         dialog = a->value;
491                 else if (!strcasecmp(a->name, "filter")) {
492                         pthread_rwlock_wrlock(&filter_list->lock);
493                         if (!strcasecmp(a->value, "off"))
494                                 filter_list->enabled = FALSE;
495                         else
496                                 filter_list->enabled = TRUE;
497                         pthread_rwlock_unlock(&filter_list->lock);
498                 } else if (!strcasecmp(a->name, "header")) {
499                         pthread_rwlock_wrlock(&header_list->lock);
500                         if (!strcasecmp(a->value, "off"))
501                                 header_list->enabled = FALSE;
502                         else
503                                 header_list->enabled = TRUE;
504                         pthread_rwlock_unlock(&header_list->lock);
505                 } else if (!strcasecmp(a->name, "mime")) {
506                         pthread_rwlock_wrlock(&mime_list->lock);
507                         if (!strcasecmp(a->value, "off"))
508                                 mime_list->enabled = FALSE;
509                         else
510                                 mime_list->enabled = TRUE;
511                         pthread_rwlock_unlock(&mime_list->lock);
512                 } else if (!strcasecmp(a->name, "cookie")) {
513                         pthread_rwlock_wrlock(&cookie_list->lock);
514                         if (!strcasecmp(a->value, "off"))
515                                 cookie_list->enabled = FALSE;
516                         else
517                                 cookie_list->enabled = TRUE;
518                         pthread_rwlock_unlock(&cookie_list->lock);
519                 } else if (!strcasecmp(a->name, "redirect")) {
520                         pthread_rwlock_wrlock(&redirect_list->lock);
521                         if (!strcasecmp(a->value, "off"))
522                                 redirect_list->enabled = FALSE;
523                         else
524                                 redirect_list->enabled = TRUE;
525                         pthread_rwlock_unlock(&redirect_list->lock);
526                 } else if (!strcasecmp(a->name, "rewrite")) {
527                         pthread_rwlock_wrlock(&rewrite_list->lock);
528                         if (!strcasecmp(a->value, "off"))
529                                 rewrite_list->enabled = FALSE;
530                         else
531                                 rewrite_list->enabled = TRUE;
532                         pthread_rwlock_unlock(&rewrite_list->lock);
533                 } else if (!strcasecmp(a->name, "keywords")) {
534                         pthread_rwlock_wrlock(&keyword_list->lock);
535                         if (!strcasecmp(a->value, "off"))
536                                 keyword_list->enabled = FALSE;
537                         else
538                                 keyword_list->enabled = TRUE;
539                         pthread_rwlock_unlock(&keyword_list->lock);
540                 } else if (!strcasecmp(a->name, "external")) {
541                         pthread_rwlock_wrlock(&external->lock);
542                         if (!strcasecmp(a->value, "off"))
543                                 external->enabled = FALSE;
544                         else
545                                 external->enabled = TRUE;
546                         pthread_rwlock_unlock(&external->lock);
547                 } else if (!strcasecmp(a->name, "forward")) {
548                         pthread_rwlock_wrlock(&forward_list->lock);
549                         if (!strcasecmp(a->value, "off"))
550                                 forward_list->enabled = FALSE;
551                         else
552                                 forward_list->enabled = TRUE;
553                         pthread_rwlock_unlock(&forward_list->lock);
554                 }
555
556         }
557
558         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\"><tr><td align=\"center\">\n");
559         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"60%\" bgcolor=\"%s\"><tr><td align=\"center\">\n", INTERFACE_TABLEBG);
560         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
561         filebuf_addf(filebuf, "<select name=\"section\">\n");
562         filebuf_addf(filebuf, "<option value=\"\">Select a section\n");
563         filebuf_addf(filebuf, "<option value=\"access\" %s>access\n", (section != NULL && !strcasecmp(section, "access")) ? "selected" : "");
564         filebuf_addf(filebuf, "<option value=\"filter\" %s>filter\n", (section != NULL && !strcasecmp(section, "filter")) ? "selected" : "");
565         filebuf_addf(filebuf, "<option value=\"network\" %s>network\n", (section != NULL && !strcasecmp(section, "network")) ? "selected" : "");
566         filebuf_addf(filebuf, "<option value=\"mime\" %s>mime\n", (section != NULL && !strcasecmp(section, "mime")) ? "selected" : "");
567         filebuf_addf(filebuf, "<option value=\"redirect\" %s>redirect\n", (section != NULL && !strcasecmp(section, "redirect")) ? "selected" : "");
568         filebuf_addf(filebuf, "<option value=\"forward\" %s>forward\n", (section != NULL && !strcasecmp(section, "forward")) ? "selected" : "");
569         filebuf_addf(filebuf, "<option value=\"header\" %s>header\n", (section != NULL && !strcasecmp(section, "header")) ? "selected" : "");
570         filebuf_addf(filebuf, "<option value=\"rewrite\" %s>rewrite\n", (section != NULL && !strcasecmp(section, "rewrite")) ? "selected" : "");
571         filebuf_addf(filebuf, "<option value=\"keywords\" %s>keywords\n", (section != NULL && !strcasecmp(section, "keywords")) ? "selected" : "");
572         filebuf_addf(filebuf, "<option value=\"templates\" %s>templates\n", (section != NULL && !strcasecmp(section, "templates")) ? "selected" : "");
573         filebuf_addf(filebuf, "<option value=\"cookies\" %s>cookies\n", (section != NULL && !strcasecmp(section, "cookies")) ? "selected" : "");
574         filebuf_addf(filebuf, "<option value=\"external\" %s>external\n", (section != NULL && !strcasecmp(section, "external")) ? "selected" : "");
575         filebuf_addf(filebuf, "</select></td>\n");
576         filebuf_addf(filebuf, "<td align=\"center\"><input type=\"submit\" value=\"Submit\"></form></td></tr>\n");
577         filebuf_addf(filebuf, "</table></td></tr>\n");
578         filebuf_addf(filebuf, "<tr><td><br></td></tr><tr><td align=\"center\">\n");
579
580
581         if (dialog != NULL) {
582                 for (i = 0; dialog_pages[i].file; i++) {
583                         if (!strcasecmp(section, dialog_pages[i].file))
584                                 dialog_pages[i].handler(filebuf, args, connection);
585                 }
586         } else if (section != NULL && strcmp(section, "")) {
587                 if (action != NULL) {
588                         for (i = 0; action_pages[i].file; i++) {
589                                 if (!strcasecmp(section, action_pages[i].file))
590                                         action_pages[i].handler(filebuf, args, connection);
591                         }
592                 }
593                 for (i = 0; config_pages[i].file; i++) {
594                         if (!strcasecmp(section, config_pages[i].file))
595                                 config_pages[i].handler(filebuf, args, connection);
596                 }
597         } else {
598                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\"><tr><td align=\"center\">\n");
599                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
600                 filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
601                 filebuf_addf(filebuf, "<tr><td align=\"center\">Feature</td><td align=\"center\">Enabled</td><td align=\"center\">Disabled</td></tr>\n");
602
603                 pthread_rwlock_rdlock(&filter_list->lock);
604                 filebuf_addf(filebuf, "<tr><td>URL filtering</td><td><input type=\"radio\" name=\"filter\" value=\"on\" %s></td><td><input type=\"radio\" name=\"filter\" value=\"off\" %s></td></tr>\n", (filter_list->enabled == TRUE) ? "checked" : "", (filter_list->enabled == FALSE) ? "checked" : "");
605                 pthread_rwlock_unlock(&filter_list->lock);
606
607                 pthread_rwlock_rdlock(&header_list->lock);
608                 filebuf_addf(filebuf, "<tr><td>Header filtering</td><td><input type=\"radio\" name=\"header\" value=\"on\" %s></td><td><input type=\"radio\" name=\"header\" value=\"off\" %s></td></tr>\n", (header_list->enabled == TRUE) ? "checked" : "", (header_list->enabled == FALSE) ? "checked" : "");
609                 pthread_rwlock_unlock(&header_list->lock);
610
611                 pthread_rwlock_rdlock(&mime_list->lock);
612                 filebuf_addf(filebuf, "<tr><td>MIME filtering</td><td><input type=\"radio\" name=\"mime\" value=\"on\" %s></td><td><input type=\"radio\" name=\"mime\" value=\"off\" %s></td></tr>\n", (mime_list->enabled == TRUE) ? "checked" : "", (mime_list->enabled == FALSE) ? "checked" : "");
613                 pthread_rwlock_unlock(&mime_list->lock);
614
615                 pthread_rwlock_rdlock(&cookie_list->lock);
616                 filebuf_addf(filebuf, "<tr><td>Cookie filtering</td><td><input type=\"radio\" name=\"cookie\" value=\"on\" %s></td><td><input type=\"radio\" name=\"cookie\" value=\"off\" %s></td></tr>\n", (cookie_list->enabled == TRUE) ? "checked" : "", (cookie_list->enabled == FALSE) ? "checked" : "");
617                 pthread_rwlock_unlock(&cookie_list->lock);
618
619                 pthread_rwlock_rdlock(&redirect_list->lock);
620                 filebuf_addf(filebuf, "<tr><td>URL redirecting</td><td><input type=\"radio\" name=\"redirect\" value=\"on\" %s></td><td><input type=\"radio\" name=\"redirect\" value=\"off\" %s></td></tr>\n", (redirect_list->enabled == TRUE) ? "checked" : "", (redirect_list->enabled == FALSE) ? "checked" : "");
621                 pthread_rwlock_unlock(&redirect_list->lock);
622
623                 pthread_rwlock_rdlock(&forward_list->lock);
624                 filebuf_addf(filebuf, "<tr><td>Forwarding</td><td><input type=\"radio\" name=\"forward\" value=\"on\" %s></td><td><input type=\"radio\" name=\"forward\" value=\"off\" %s></td></tr>\n", (forward_list->enabled == TRUE) ? "checked" : "", (forward_list->enabled == FALSE) ? "checked" : "");
625                 pthread_rwlock_unlock(&forward_list->lock);
626
627                 pthread_rwlock_rdlock(&rewrite_list->lock);
628                 filebuf_addf(filebuf, "<tr><td>Document rewriting</td><td><input type=\"radio\" name=\"rewrite\" value=\"on\" %s></td><td><input type=\"radio\" name=\"rewrite\" value=\"off\" %s></td></tr>\n", (rewrite_list->enabled == TRUE) ? "checked" : "", (rewrite_list->enabled == FALSE) ? "checked" : "");
629                 pthread_rwlock_unlock(&rewrite_list->lock);
630
631                 pthread_rwlock_rdlock(&keyword_list->lock);
632                 filebuf_addf(filebuf, "<tr><td>Keyword filtering</td><td><input type=\"radio\" name=\"keywords\" value=\"on\" %s></td><td><input type=\"radio\" name=\"keywords\" value=\"off\" %s></td></tr>\n", (keyword_list->enabled == TRUE) ? "checked" : "", (keyword_list->enabled == FALSE) ? "checked" : "");
633                 pthread_rwlock_unlock(&keyword_list->lock);
634
635                 pthread_rwlock_rdlock(&external->lock);
636                 filebuf_addf(filebuf, "<tr><td>External parsers</td><td><input type=\"radio\" name=\"external\" value=\"on\" %s></td><td><input type=\"radio\" name=\"external\" value=\"off\" %s></td></tr>\n", (external->enabled == TRUE) ? "checked" : "", (external->enabled == FALSE) ? "checked" : "");
637                 pthread_rwlock_unlock(&external->lock);
638
639                 filebuf_addf(filebuf, "<tr><td colspan=\"3\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
640                 filebuf_addf(filebuf, "</form></table></td></tr></table>\n");
641         }
642
643
644         filebuf_addf(filebuf, "</td></tr></table>\n");
645 }
646
647 void interface_page_config_filter(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
648 {
649         int i;
650         char *ptr;
651         struct FILTER_LIST_LIST *fl = NULL;
652
653         if (filter_list == NULL)
654                 return;
655
656         pthread_rwlock_rdlock(&filter_list->lock);
657
658         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
659         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
660         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
661         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"filter\">\n");
662         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"global\">\n");
663         filebuf_addf(filebuf, "<tr><td>Policy</td><td><select name=\"policy\"><option value=\"allow\" %s>allow<option value=\"deny\" %s>deny</select></td></tr>", (filter_list->policy == POLICY_ALLOW) ? "selected" : "", (filter_list->policy == POLICY_DENY) ? "selected" : "");
664         filebuf_addf(filebuf, "<tr><td>Default template</td><td><input type=\"text\" name=\"dtemplate\" value=\"%s\" size=\"20\"></td></tr>\n", (filter_list->dtemplate != NULL) ? filter_list->dtemplate : "");
665         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
666         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=filter&amp;dialog=show\">Add</a></td></tr>\n");
667         filebuf_addf(filebuf, "</form></table></td></tr> <tr><td><br></td></tr>\n");
668
669         for (i = 0; i < 2; i++) {
670                 filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"30%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
671
672                 switch (i) {
673                 case 0:
674                         fl = filter_list->allow;
675                         if (fl != NULL)
676                                 filebuf_addf(filebuf, "<tr><th>ALLOW</th></tr>\n");
677                         break;
678                 case 1:
679                         fl = filter_list->deny;
680                         if (fl != NULL)
681                                 filebuf_addf(filebuf, "<tr><th>DENY</th></tr>\n");
682                         break;
683                 }
684
685                 filebuf_addf(filebuf, "</table></td></tr>\n");
686                 if (fl != NULL)
687                         filebuf_addf(filebuf, "<tr><td><br></td></tr>\n");
688
689                 for (; fl; fl = fl->next) {
690                         filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
691                         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
692
693                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (fl->enabled == TRUE) ? "yes" : "no");
694                         if (fl->comment != NULL) {
695                                 ptr = string_to_html(fl->comment, TRUE);
696                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
697                                 xfree(ptr);
698                         }
699                         if (fl->host != NULL) {
700                                 ptr = string_to_html(fl->host, TRUE);
701                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Host</td><td>%s</td></tr>\n", ptr);
702                                 xfree(ptr);
703                         }
704                         if (fl->file != NULL) {
705                                 ptr = string_to_html(fl->file, TRUE);
706                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">File</td><td>%s</td></tr>\n", ptr);
707                                 xfree(ptr);
708                         }
709                         if (fl->template != NULL)
710                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Template</td><td>%s</td></tr>\n", fl->template);
711
712                         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
713                         filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=filter&amp;dialog=show&amp;list=%s&amp;id=%d\">Edit</a> <a href=\"config?section=filter&amp;action=delete&amp;list=%s&amp;id=%d\">Delete</a></td>\n", (i == 0) ? "allow" : "deny", fl->id, (i == 0) ? "allow" : "deny", fl->id);
714                         filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=filter&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=filter&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=down\">Down</a></td>\n", (i == 0) ? "allow" : "deny", fl->id, (i == 0) ? "allow" : "deny", fl->id);
715                         filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=filter&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=filter&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", (i == 0) ? "allow" : "deny", fl->id, (i == 0) ? "allow" : "deny", fl->id);
716                         filebuf_addf(filebuf, "</table></td></tr>\n");
717
718                         filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
719                 }
720         }
721
722         filebuf_addf(filebuf, "</table>\n");
723
724         pthread_rwlock_unlock(&filter_list->lock);
725 }
726
727 void interface_page_config_filter_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
728 {
729         int id = -1;
730         char *list = NULL, *ptr = NULL;
731         struct FILTER_LIST_LIST *fl = NULL;
732         struct cgi_args_t *a = args;
733
734         if (filter_list == NULL)
735                 return;
736
737         pthread_rwlock_rdlock(&filter_list->lock);
738
739         for (; a; a = a->next) {
740                 if (!strcasecmp(a->name, "id"))
741                         id = atoi(a->value);
742                 if (!strcasecmp(a->name, "list"))
743                         list = a->value;
744         }
745
746         if (id != -1 && list != NULL) {
747                 if (!strcasecmp(list, "allow"))
748                         for (fl = filter_list->allow; fl && fl->id != id; fl = fl->next);
749                 else if (!strcasecmp(list, "deny"))
750                         for (fl = filter_list->deny; fl && fl->id != id; fl = fl->next);
751         }
752
753         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
754         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
755
756         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"filter\">\n");
757         if (list != NULL)
758                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"list\" value=\"%s\">\n", list);
759
760         if (id != -1) {
761                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
762                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
763         } else
764                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
765
766         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
767         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (fl == NULL || fl->enabled == TRUE) ? "checked" : "");
768         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (fl != NULL && fl->enabled == FALSE) ? "checked" : "");
769         filebuf_addf(filebuf, "</td></tr>\n");
770
771         filebuf_addf(filebuf, "<tr><td>Action</td><td><select name=\"%s\">\n", (list != NULL) ? "move" : "list");
772         filebuf_addf(filebuf, "<option value=\"allow\" %s>allow\n", (list != NULL && !strcasecmp(list, "allow")) ? "selected" : "");
773         filebuf_addf(filebuf, "<option value=\"deny\" %s>deny\n", (list != NULL && !strcasecmp(list, "deny")) ? "selected" : "");
774         filebuf_addf(filebuf, "</select></tr>\n");
775
776         if (fl != NULL && fl->comment != NULL)
777                 ptr = string_to_html(fl->comment, TRUE);
778         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
779         FREE_AND_NULL(ptr);
780
781         if (fl != NULL && fl->host != NULL)
782                 ptr = string_to_html(fl->host, TRUE);
783         filebuf_addf(filebuf, "<tr><td>Host</td><td><input type=\"text\" name=\"host\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
784         FREE_AND_NULL(ptr);
785
786         if (fl != NULL && fl->file != NULL)
787                 ptr = string_to_html(fl->file, TRUE);
788         filebuf_addf(filebuf, "<tr><td>File</td><td><input type=\"text\" name=\"file\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
789         FREE_AND_NULL(ptr);
790
791         if (fl != NULL && fl->template != NULL)
792                 ptr = string_to_html(fl->template, TRUE);
793         filebuf_addf(filebuf, "<tr><td>Template</td><td><input type=\"text\" name=\"template\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
794         FREE_AND_NULL(ptr);
795
796         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
797         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
798
799         filebuf_addf(filebuf, "</table></td></tr>\n");
800
801         pthread_rwlock_unlock(&filter_list->lock);
802 }
803
804
805 void interface_page_config_filter_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
806 {
807         int id = -1;
808         char *list = NULL, *action = NULL;
809         struct FILTER_LIST_LIST *fl = NULL;
810         struct cgi_args_t *a;
811
812         if (filter_list == NULL)
813                 return;
814
815         pthread_rwlock_wrlock(&filter_list->lock);
816
817         for (a = args; a; a = a->next) {
818                 if (!strcasecmp(a->name, "action"))
819                         action = a->value;
820                 if (!strcasecmp(a->name, "id"))
821                         id = atoi(a->value);
822                 if (!strcasecmp(a->name, "list"))
823                         list = a->value;
824         }
825
826         if (action != NULL && !strcasecmp(action, "global")) {
827                 for (a = args; a; a = a->next) {
828                         if (!strcasecmp(a->name, "policy")) {
829                                 if (!strcasecmp(a->value, "allow"))
830                                         filter_list->policy = POLICY_ALLOW;
831                                 else if (!strcasecmp(a->value, "deny"))
832                                         filter_list->policy = POLICY_DENY;
833                         } else if (!strcasecmp(a->name, "dtemplate")) {
834                                 FREE_AND_NULL(filter_list->dtemplate);
835                                 if (strcmp(a->name, ""))
836                                         filter_list->dtemplate = xstrdup(a->value);
837                         }
838                 }
839         }
840
841         if (action == NULL || list == NULL)
842                 goto finish;
843
844         if (!strcasecmp(action, "delete")) {
845                 if (!strcasecmp(list, "allow"))
846                         fl = filter_list->allow;
847                 else if (!strcasecmp(list, "deny"))
848                         fl = filter_list->deny;
849
850                 for (; fl; fl = fl->next) {
851                         if (fl->id == id) {
852                                 if (!strcasecmp(list, "allow"))
853                                         filter_list->allow = filter_ll_delete(fl);
854                                 else if (!strcasecmp(list, "deny"))
855                                         filter_list->deny = filter_ll_delete(fl);
856
857                                 break;
858                         }
859                 }
860         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
861                 if (!strcasecmp(action, "add")) {
862                         if (!strcasecmp(list, "allow")) {
863                                 fl = filter_ll_new(filter_list->allow);
864                                 if (filter_list->allow == NULL)
865                                         filter_list->allow = fl;
866                         } else if (!strcasecmp(list, "deny")) {
867                                 fl = filter_ll_new(filter_list->deny);
868                                 if (filter_list->deny == NULL)
869                                         filter_list->deny = fl;
870                         } else
871                                 goto finish;
872
873                         fl->id = filter_list->id++;
874                 } else {
875                         if (!strcasecmp(list, "allow")) {
876                                 for (fl = filter_list->allow; fl; fl = fl->next)
877                                         if (fl->id == id)
878                                                 break;
879                         } else if (!strcasecmp(list, "deny")) {
880                                 for (fl = filter_list->deny; fl; fl = fl->next)
881                                         if (fl->id == id)
882                                                 break;
883                         }
884
885                         if (fl == NULL)
886                                 goto finish;
887                 }
888
889                 if (strcasecmp(action, "shift")) {
890                         for (a = args; a; a = a->next) {
891                                 if (!strcasecmp(a->name, "enabled")) {
892                                         if (!strcasecmp(a->value, "no"))
893                                                 fl->enabled = FALSE;
894                                         else
895                                                 fl->enabled = TRUE;
896                                 } else if (!strcasecmp(a->name, "comment"))
897                                         filter_ll_insert(fl, a->value, NULL, NULL, NULL);
898                                 else if (!strcasecmp(a->name, "host"))
899                                         filter_ll_insert(fl, NULL, a->value, NULL, NULL);
900                                 else if (!strcasecmp(a->name, "file"))
901                                         filter_ll_insert(fl, NULL, NULL, a->value, NULL);
902                                 else if (!strcasecmp(a->name, "template"))
903                                         filter_ll_insert(fl, NULL, NULL, NULL, a->value);
904                                 else if (!strcasecmp(a->name, "move")) {
905                                         if (!strcasecmp(a->value, "allow") && strcasecmp(list, a->value)) {
906                                                 MOVENODE(struct FILTER_LIST_LIST *, fl, filter_list->deny, filter_list->allow);
907                                         } else if (!strcasecmp(a->value, "deny") && strcasecmp(list, a->value)) {
908                                                 MOVENODE(struct FILTER_LIST_LIST *, fl, filter_list->allow, filter_list->deny);
909                                         }
910                                 }
911                         }
912                 } else {
913                         for (a = args; a; a = a->next) {
914                                 if (!strcasecmp(a->name, "direction")) {
915                                         if (!strcasecmp(a->value, "up")) {
916                                                 SHIFTNODE(struct FILTER_LIST_LIST *, (!strcasecmp(list, "allow")) ? filter_list->allow : filter_list->deny, fl, UP);
917                                         } else if (!strcasecmp(a->value, "down")) {
918                                                 SHIFTNODE(struct FILTER_LIST_LIST *, (!strcasecmp(list, "allow")) ? filter_list->allow : filter_list->deny, fl, DOWN);
919                                         } else if (!strcasecmp(a->value, "top")) {
920                                                 SETNODE(struct FILTER_LIST_LIST *, (!strcasecmp(list, "allow")) ? filter_list->allow : filter_list->deny, fl, TOP);
921                                         } else if (!strcasecmp(a->value, "bottom")) {
922                                                 SETNODE(struct FILTER_LIST_LIST *, (!strcasecmp(list, "allow")) ? filter_list->allow : filter_list->deny, fl, BOTTOM);
923                                         }
924                                 }
925                         }
926                 }
927         }
928
929       finish:
930         pthread_rwlock_unlock(&filter_list->lock);
931 }
932
933 void interface_page_config_header(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connectin)
934 {
935         int i;
936         char *ptr;
937         struct HEADER_LIST_LIST *hl = NULL;
938
939         if (header_list == NULL)
940                 return;
941
942         pthread_rwlock_rdlock(&header_list->lock);
943
944         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
945         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
946         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
947         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"header\">\n");
948         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"global\">\n");
949         filebuf_addf(filebuf, "<tr><td>Policy</td><td><select name=\"policy\"><option value=\"allow\" %s>allow<option value=\"deny\" %s>deny</select></td></tr>", (header_list->policy == POLICY_ALLOW) ? "selected" : "", (header_list->policy == POLICY_DENY) ? "selected" : "");
950         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
951         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=header&amp;dialog=show\">Add</a></td></tr>\n");
952         filebuf_addf(filebuf, "</form></table></td></tr> <tr><td><br></td></tr>\n");
953
954         for (i = 0; i < 3; i++) {
955                 filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"30%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
956
957                 switch (i) {
958                 case 0:
959                         hl = header_list->allow;
960                         if (hl != NULL)
961                                 filebuf_addf(filebuf, "<tr><th>ALLOW</th></tr>\n");
962                         break;
963                 case 1:
964                         hl = header_list->deny;
965                         if (hl != NULL)
966                                 filebuf_addf(filebuf, "<tr><th>DENY</th></tr>\n");
967                         break;
968                 case 2:
969                         hl = header_list->insert;
970                         if (hl != NULL)
971                                 filebuf_addf(filebuf, "<tr><th>INSERT</th></tr>\n");
972                 }
973
974                 filebuf_addf(filebuf, "</table></td></tr><tr>\n");
975                 if (hl != NULL)
976                         filebuf_addf(filebuf, "<tr><td><br></td></tr>\n");
977
978                 for (; hl; hl = hl->next) {
979                         filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
980                         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
981
982                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (hl->enabled == TRUE) ? "yes" : "no");
983                         if (hl->comment != NULL) {
984                                 ptr = string_to_html(hl->comment, TRUE);
985                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
986                                 xfree(ptr);
987                         }
988                         if (hl->host != NULL) {
989                                 ptr = string_to_html(hl->host, TRUE);
990                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Host</td><td>%s</td></tr>\n", ptr);
991                                 xfree(ptr);
992                         }
993                         if (hl->type != NULL) {
994                                 ptr = string_to_html(hl->type, TRUE);
995                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Type</td><td>%s</td></tr>\n", ptr);
996                                 xfree(ptr);
997                         }
998                         if (hl->value != NULL) {
999                                 ptr = string_to_html(hl->value, TRUE);
1000                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Value</td><td>%s</td></tr>\n", ptr);
1001                                 xfree(ptr);
1002                         }
1003
1004                         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
1005                         filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=header&amp;dialog=show&amp;list=%s&amp;id=%d\">Edit</a> <a href=\"config?section=header&amp;action=delete&amp;list=%s&amp;id=%d\">Delete</a></td>\n", (i == 0) ? "allow" : (i == 1) ? "deny" : "insert", hl->id, (i == 0) ? "allow" : (i == 1) ? "deny" : "insert", hl->id);
1006                         filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=header&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=header&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=down\">Down</a></td>\n", (i == 0) ? "allow" : (i == 1) ? "deny" : "insert", hl->id, (i == 0) ? "allow" : (i == 1) ? "deny" : "insert", hl->id);
1007                         filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=header&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=header&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", (i == 0) ? "allow" : (i == 1) ? "deny" : "insert", hl->id, (i == 0) ? "allow" : (i == 1) ? "deny" : "insert", hl->id);
1008                         filebuf_addf(filebuf, "</table></td></tr>\n");
1009
1010                         filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
1011                 }
1012         }
1013
1014         filebuf_addf(filebuf, "</table>\n");
1015
1016         pthread_rwlock_unlock(&header_list->lock);
1017 }
1018
1019 void interface_page_config_header_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
1020 {
1021         int id = -1;
1022         char *list = NULL, *ptr = NULL;
1023         struct HEADER_LIST_LIST *hl = NULL;
1024         struct cgi_args_t *a = args;
1025
1026         if (header_list == NULL)
1027                 return;
1028
1029         pthread_rwlock_rdlock(&header_list->lock);
1030
1031         for (; a; a = a->next) {
1032                 if (!strcasecmp(a->name, "id"))
1033                         id = atoi(a->value);
1034                 if (!strcasecmp(a->name, "list"))
1035                         list = a->value;
1036         }
1037
1038         if (id != -1 && list != NULL) {
1039                 if (!strcasecmp(list, "allow"))
1040                         for (hl = header_list->allow; hl && hl->id != id; hl = hl->next);
1041                 else if (!strcasecmp(list, "deny"))
1042                         for (hl = header_list->deny; hl && hl->id != id; hl = hl->next);
1043                 else if (!strcasecmp(list, "insert"))
1044                         for (hl = header_list->insert; hl && hl->id != id; hl = hl->next);
1045         }
1046
1047         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1048         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
1049
1050         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"header\">\n");
1051         if (list != NULL)
1052                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"list\" value=\"%s\">\n", list);
1053
1054         if (id != -1) {
1055                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
1056                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
1057         } else
1058                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
1059
1060         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
1061         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (hl == NULL || hl->enabled == TRUE) ? "checked" : "");
1062         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (hl != NULL && hl->enabled == FALSE) ? "checked" : "");
1063         filebuf_addf(filebuf, "</td></tr>\n");
1064
1065         filebuf_addf(filebuf, "<tr><td>Action</td><td><select name=\"%s\">\n", (list != NULL) ? "move" : "list");
1066         filebuf_addf(filebuf, "<option value=\"allow\" %s>allow\n", (list != NULL && !strcasecmp(list, "allow")) ? "selected" : "");
1067         filebuf_addf(filebuf, "<option value=\"deny\" %s>deny\n", (list != NULL && !strcasecmp(list, "deny")) ? "selected" : "");
1068         filebuf_addf(filebuf, "<option value=\"insert\" %s>insert\n", (list != NULL && !strcasecmp(list, "insert")) ? "selected" : "");
1069         filebuf_addf(filebuf, "</select></tr>\n");
1070
1071         if (hl != NULL && hl->comment != NULL)
1072                 ptr = string_to_html(hl->comment, TRUE);
1073         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1074         FREE_AND_NULL(ptr);
1075
1076         if (hl != NULL && hl->host != NULL)
1077                 ptr = string_to_html(hl->host, TRUE);
1078         filebuf_addf(filebuf, "<tr><td>Host</td><td><input type=\"text\" name=\"host\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1079         FREE_AND_NULL(ptr);
1080
1081         if (hl != NULL && hl->type != NULL)
1082                 ptr = string_to_html(hl->type, TRUE);
1083         filebuf_addf(filebuf, "<tr><td>Type</td><td><input type=\"text\" name=\"type\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1084         FREE_AND_NULL(ptr);
1085
1086         if (hl != NULL && hl->value != NULL)
1087                 ptr = string_to_html(hl->value, TRUE);
1088         filebuf_addf(filebuf, "<tr><td>Value</td><td><input type=\"text\" name=\"value\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1089         FREE_AND_NULL(ptr);
1090
1091         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
1092         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
1093
1094         filebuf_addf(filebuf, "</table></td></tr>\n");
1095
1096         pthread_rwlock_unlock(&header_list->lock);
1097 }
1098
1099
1100 void interface_page_config_header_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
1101 {
1102         int id = -1;
1103         char *list = NULL, *action = NULL;
1104         struct HEADER_LIST_LIST *hl = NULL;
1105         struct cgi_args_t *a;
1106
1107         if (header_list == NULL)
1108                 return;
1109
1110         pthread_rwlock_wrlock(&header_list->lock);
1111
1112         for (a = args; a; a = a->next) {
1113                 if (!strcasecmp(a->name, "action"))
1114                         action = a->value;
1115                 if (!strcasecmp(a->name, "id"))
1116                         id = atoi(a->value);
1117                 if (!strcasecmp(a->name, "list"))
1118                         list = a->value;
1119         }
1120
1121         if (action != NULL && !strcasecmp(action, "global")) {
1122                 for (a = args; a; a = a->next) {
1123                         if (!strcasecmp(a->name, "policy")) {
1124                                 if (!strcasecmp(a->value, "allow"))
1125                                         header_list->policy = POLICY_ALLOW;
1126                                 else if (!strcasecmp(a->value, "deny"))
1127                                         header_list->policy = POLICY_DENY;
1128                         }
1129                 }
1130         }
1131
1132         if (action == NULL || list == NULL)
1133                 goto finish;
1134
1135         if (!strcasecmp(action, "delete")) {
1136                 if (!strcasecmp(list, "allow"))
1137                         hl = header_list->allow;
1138                 else if (!strcasecmp(list, "deny"))
1139                         hl = header_list->deny;
1140                 else if (!strcasecmp(list, "insert"))
1141                         hl = header_list->insert;
1142
1143                 for (; hl; hl = hl->next) {
1144                         if (hl->id == id) {
1145                                 if (!strcasecmp(list, "allow"))
1146                                         header_list->allow = header_ll_delete(hl);
1147                                 else if (!strcasecmp(list, "deny"))
1148                                         header_list->deny = header_ll_delete(hl);
1149                                 else if (!strcasecmp(list, "insert"))
1150                                         header_list->insert = header_ll_delete(hl);
1151
1152                                 break;
1153                         }
1154                 }
1155         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
1156                 if (!strcasecmp(action, "add")) {
1157                         if (!strcasecmp(list, "allow")) {
1158                                 hl = header_ll_new(header_list->allow);
1159                                 if (header_list->allow == NULL)
1160                                         header_list->allow = hl;
1161                         } else if (!strcasecmp(list, "deny")) {
1162                                 hl = header_ll_new(header_list->deny);
1163                                 if (header_list->deny == NULL)
1164                                         header_list->deny = hl;
1165                         } else if (!strcasecmp(list, "insert")) {
1166                                 hl = header_ll_new(header_list->insert);
1167                                 if (header_list->insert == NULL)
1168                                         header_list->insert = hl;
1169                         } else
1170                                 goto finish;
1171
1172                         hl->id = header_list->id++;
1173                 } else {
1174                         if (!strcasecmp(list, "allow")) {
1175                                 for (hl = header_list->allow; hl; hl = hl->next)
1176                                         if (hl->id == id)
1177                                                 break;
1178                         } else if (!strcasecmp(list, "deny")) {
1179                                 for (hl = header_list->deny; hl; hl = hl->next)
1180                                         if (hl->id == id)
1181                                                 break;
1182                         } else if (!strcasecmp(list, "insert")) {
1183                                 for (hl = header_list->insert; hl; hl = hl->next)
1184                                         if (hl->id == id)
1185                                                 break;
1186                         }
1187
1188                         if (hl == NULL)
1189                                 goto finish;
1190                 }
1191
1192                 if (strcasecmp(action, "shift")) {
1193                         for (a = args; a; a = a->next) {
1194                                 if (!strcasecmp(a->name, "enabled")) {
1195                                         if (!strcasecmp(a->value, "no"))
1196                                                 hl->enabled = FALSE;
1197                                         else
1198                                                 hl->enabled = TRUE;
1199                                 } else if (!strcasecmp(a->name, "comment"))
1200                                         header_ll_insert(hl, a->value, NULL, NULL, NULL);
1201                                 else if (!strcasecmp(a->name, "type"))
1202                                         header_ll_insert(hl, NULL, a->value, NULL, NULL);
1203                                 else if (!strcasecmp(a->name, "value"))
1204                                         header_ll_insert(hl, NULL, NULL, a->value, NULL);
1205                                 else if (!strcasecmp(a->name, "host"))
1206                                         header_ll_insert(hl, NULL, NULL, NULL, a->value);
1207                                 else if (!strcasecmp(a->name, "move")) {
1208                                         if (!strcasecmp(a->value, "allow") && strcasecmp(list, a->value)) {
1209                                                 if (!strcasecmp(list, "deny")) {
1210                                                         MOVENODE(struct HEADER_LIST_LIST *, hl, header_list->deny, header_list->allow);
1211                                                 } else if (!strcasecmp(list, "insert")) {
1212                                                         MOVENODE(struct HEADER_LIST_LIST *, hl, header_list->insert, header_list->allow);
1213                                                 }
1214                                         } else if (!strcasecmp(a->value, "deny") && strcasecmp(list, a->value)) {
1215                                                 if (!strcasecmp(list, "allow")) {
1216                                                         MOVENODE(struct HEADER_LIST_LIST *, hl, header_list->allow, header_list->deny);
1217                                                 } else if (!strcasecmp(list, "insert")) {
1218                                                         MOVENODE(struct HEADER_LIST_LIST *, hl, header_list->insert, header_list->deny);
1219                                                 }
1220                                         } else if (!strcasecmp(a->value, "insert") && strcasecmp(list, a->value)) {
1221                                                 if (!strcasecmp(list, "allow")) {
1222                                                         MOVENODE(struct HEADER_LIST_LIST *, hl, header_list->allow, header_list->insert);
1223                                                 } else if (!strcasecmp(list, "deny")) {
1224                                                         MOVENODE(struct HEADER_LIST_LIST *, hl, header_list->deny, header_list->insert);
1225                                                 }
1226                                         }
1227                                 }
1228                         }
1229                 } else {
1230                         for (a = args; a; a = a->next) {
1231                                 if (!strcasecmp(a->name, "direction")) {
1232                                         if (!strcasecmp(a->value, "up")) {
1233                                                 SHIFTNODE(struct HEADER_LIST_LIST *, (!strcasecmp(list, "allow")) ? header_list->allow : (!strcasecmp(list, "deny")) ? header_list->deny : header_list->insert, hl, UP);
1234                                         } else if (!strcasecmp(a->value, "down")) {
1235                                                 SHIFTNODE(struct HEADER_LIST_LIST *, (!strcasecmp(list, "allow")) ? header_list->allow : (!strcasecmp(list, "deny")) ? header_list->deny : header_list->insert, hl, DOWN);
1236                                         } else if (!strcasecmp(a->value, "top")) {
1237                                                 SETNODE(struct HEADER_LIST_LIST *, (!strcasecmp(list, "allow")) ? header_list->allow : (!strcasecmp(list, "deny")) ? header_list->deny : header_list->insert, hl, TOP);
1238                                         } else if (!strcasecmp(a->value, "bottom")) {
1239                                                 SETNODE(struct HEADER_LIST_LIST *, (!strcasecmp(list, "allow")) ? header_list->allow : (!strcasecmp(list, "deny")) ? header_list->deny : header_list->insert, hl, BOTTOM);
1240                                         }
1241                                 }
1242                         }
1243                 }
1244         }
1245
1246       finish:
1247         pthread_rwlock_unlock(&header_list->lock);
1248 }
1249
1250 void interface_page_config_access(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
1251 {
1252         int i;
1253         char *ptr;
1254         struct ACCESS_LIST_LIST *al = NULL;
1255
1256         if (access_list == NULL)
1257                 return;
1258
1259         pthread_rwlock_rdlock(&access_list->lock);
1260
1261         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
1262         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1263         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
1264         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"access\">\n");
1265         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"global\">\n");
1266         filebuf_addf(filebuf, "<tr><td>Policy</td><td><select name=\"policy\"><option value=\"allow\" %s>allow<option value=\"deny\" %s>deny</select></td></tr>", (access_list->policy == POLICY_ALLOW) ? "selected" : "", (access_list->policy == POLICY_DENY) ? "selected" : "");
1267         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
1268         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=access&amp;dialog=show\">Add</a></td></tr>\n");
1269         filebuf_addf(filebuf, "</form></table></td></tr> <tr><td><br></td></tr>\n");
1270
1271         for (i = 0; i < 2; i++) {
1272                 filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"30%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1273
1274                 switch (i) {
1275                 case 0:
1276                         al = access_list->allow;
1277                         if (al != NULL)
1278                                 filebuf_addf(filebuf, "<tr><th>ALLOW</th></tr>\n");
1279                         break;
1280                 case 1:
1281                         al = access_list->deny;
1282                         if (al != NULL)
1283                                 filebuf_addf(filebuf, "<tr><th>DENY</th></tr>\n");
1284                         break;
1285                 }
1286
1287                 filebuf_addf(filebuf, "</table></td></tr>\n");
1288                 if (al != NULL)
1289                         filebuf_addf(filebuf, "<tr><td><br></td></tr>\n");
1290
1291                 for (; al; al = al->next) {
1292                         filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
1293                         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1294
1295                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (al->enabled == TRUE) ? "yes" : "no");
1296                         if (al->comment != NULL) {
1297                                 ptr = string_to_html(al->comment, TRUE);
1298                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
1299                                 xfree(ptr);
1300                         }
1301                         if (al->ip != NULL) {
1302                                 ptr = string_to_html(al->ip, TRUE);
1303                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">IP address</td><td>%s</td></tr>\n", ptr);
1304                                 xfree(ptr);
1305                         }
1306                         if (al->username != NULL) {
1307                                 ptr = string_to_html(al->username, TRUE);
1308                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Username</td><td>%s</td></tr>\n", ptr);
1309                                 xfree(ptr);
1310                         }
1311                         if (al->password != NULL) {
1312                                 ptr = string_to_html(al->password, TRUE);
1313                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Password</td><td>%s</td></tr>\n", ptr);
1314                                 xfree(ptr);
1315                         }
1316
1317                         if (al->bypass != 0)
1318                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Bypass</td><td>%s,%s,%s,%s,%s,%s,%s,%s,%s</td></tr>\n", (al->bypass & FEATURE_FILTER) ? "filter" : "", (al->bypass & FEATURE_HEADER) ? "header" : "", (al->bypass & FEATURE_MIME) ? "mime" : "", (al->bypass & FEATURE_REDIRECT) ? "redirect" : "", (al->bypass & FEATURE_COOKIES) ? "cookies" : "", (al->bypass & FEATURE_REWRITE) ? "rewrite" : "", (al->bypass & FEATURE_EXTERNAL) ? "external" : "", (al->bypass & FEATURE_FORWARD) ? "forward" : "", (al->bypass & FEATURE_KEYWORDS) ? "keywords" : "");
1319
1320                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Access</td><td>%s,%s,%s,%s,%s,%s</td.</tr>\n", (al->access & ACCESS_CONFIG) ? "Web interface" : "", (al->access & ACCESS_PROXY) ? "Proxy requests" : "", (al->access & ACCESS_CONNECT) ? "CONNECT requests" : "", (al->access & ACCESS_HTTP) ? "HTTP requests" : "", (al->access & ACCESS_TRANSPARENT) ? "Transparent proxying" : "", (al->access & ACCESS_BYPASS) ? "Allow bypassing" : "");
1321
1322
1323                         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
1324                         filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=access&amp;dialog=show&amp;list=%s&amp;id=%d\">Edit</a> <a href=\"config?section=access&amp;action=delete&amp;list=%s&amp;id=%d\">Delete</a></td>\n", (i == 0) ? "allow" : "deny", al->id, (i == 0) ? "allow" : "deny", al->id);
1325                         filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=access&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=access&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=down\">Down</a></td>\n", (i == 0) ? "allow" : "deny", al->id, (i == 0) ? "allow" : "deny", al->id);
1326                         filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=access&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=access&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", (i == 0) ? "allow" : "deny", al->id, (i == 0) ? "allow" : "deny", al->id);
1327                         filebuf_addf(filebuf, "</table></td></tr>\n");
1328
1329                         filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
1330                 }
1331         }
1332
1333         filebuf_addf(filebuf, "</table>\n");
1334
1335         pthread_rwlock_unlock(&access_list->lock);
1336 }
1337
1338 void interface_page_config_access_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
1339 {
1340         int id = -1;
1341         char *list = NULL, *ptr = NULL;
1342         struct ACCESS_LIST_LIST *al = NULL;
1343         struct cgi_args_t *a = args;
1344
1345         if (access_list == NULL)
1346                 return;
1347
1348         pthread_rwlock_rdlock(&access_list->lock);
1349
1350         for (; a; a = a->next) {
1351                 if (!strcasecmp(a->name, "id"))
1352                         id = atoi(a->value);
1353                 if (!strcasecmp(a->name, "list"))
1354                         list = a->value;
1355         }
1356
1357         if (id != -1 && list != NULL) {
1358                 if (!strcasecmp(list, "allow"))
1359                         for (al = access_list->allow; al && al->id != id; al = al->next);
1360                 else if (!strcasecmp(list, "deny"))
1361                         for (al = access_list->deny; al && al->id != id; al = al->next);
1362         }
1363
1364         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1365         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
1366
1367         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"access\">\n");
1368         if (list != NULL)
1369                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"list\" value=\"%s\">\n", list);
1370
1371         if (id != -1) {
1372                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
1373                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
1374         } else
1375                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
1376
1377         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
1378         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (al == NULL || al->enabled == TRUE) ? "checked" : "");
1379         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (al != NULL && al->enabled == FALSE) ? "checked" : "");
1380         filebuf_addf(filebuf, "</td></tr>\n");
1381
1382         filebuf_addf(filebuf, "<tr><td>Action</td><td><select name=\"%s\">\n", (list != NULL) ? "move" : "list");
1383         filebuf_addf(filebuf, "<option value=\"allow\" %s>allow\n", (list != NULL && !strcasecmp(list, "allow")) ? "selected" : "");
1384         filebuf_addf(filebuf, "<option value=\"deny\" %s>deny\n", (list != NULL && !strcasecmp(list, "deny")) ? "selected" : "");
1385         filebuf_addf(filebuf, "</select></tr>\n");
1386
1387         if (al != NULL && al->comment != NULL)
1388                 ptr = string_to_html(al->comment, TRUE);
1389         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1390         FREE_AND_NULL(ptr);
1391
1392         if (al != NULL && al->ip != NULL)
1393                 ptr = string_to_html(al->ip, TRUE);
1394         filebuf_addf(filebuf, "<tr><td>IP Address</td><td><input type=\"text\" name=\"ip\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1395         FREE_AND_NULL(ptr);
1396
1397         if (al != NULL && al->username != NULL)
1398                 ptr = string_to_html(al->username, TRUE);
1399         filebuf_addf(filebuf, "<tr><td>Username</td><td><input type=\"text\" name=\"username\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1400         FREE_AND_NULL(ptr);
1401
1402         if (al != NULL && al->password!= NULL)
1403                 ptr = string_to_html(al->password, TRUE);
1404         filebuf_addf(filebuf, "<tr><td>Password</td><td><input type=\"text\" name=\"password\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1405         FREE_AND_NULL(ptr);
1406
1407         filebuf_addf(filebuf, "<tr><td>Access</td><td align=\"center\">");
1408         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n");
1409         filebuf_addf(filebuf, "<tr><td>Web interface: </td><td><input type=\"checkbox\" name=\"access_config\" %s></td></tr>", (al != NULL && (al->access & ACCESS_CONFIG)) ? "checked" : "");
1410         filebuf_addf(filebuf, "<tr><td>Proxy requests: </td><td><input type=\"checkbox\" name=\"access_proxy\" %s></td></tr>", (al != NULL && (al->access & ACCESS_PROXY)) ? "checked" : "");
1411         filebuf_addf(filebuf, "<tr><td>CONNECT requests: </td><td><input type=\"checkbox\" name=\"access_connect\" %s></td></tr>", (al != NULL && (al->access & ACCESS_CONNECT)) ? "checked" : "");
1412         filebuf_addf(filebuf, "<tr><td>HTTP requests: </td><td><input type=\"checkbox\" name=\"access_http\" %s></td></tr>", (al != NULL && (al->access & ACCESS_HTTP)) ? "checked" : "");
1413         filebuf_addf(filebuf, "<tr><td>Transparent proxying: </td><td><input type=\"checkbox\" name=\"access_transparent\" %s></td></tr>", (al != NULL && (al->access & ACCESS_TRANSPARENT)) ? "checked" : "");
1414         filebuf_addf(filebuf, "<tr><td>Allow bypassing: </td><td><input type=\"checkbox\" name=\"access_bypass\" %s></td></tr>", (al != NULL && (al->access & ACCESS_BYPASS)) ? "checked" : "");
1415         filebuf_addf(filebuf, "</table></td></tr>\n");
1416
1417         filebuf_addf(filebuf, "<tr><td>Bypass</td><td align=\"center\">");
1418         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n");
1419         filebuf_addf(filebuf, "<tr><td>URL filtering: </td><td><input type=\"checkbox\" name=\"bfilter\" %s></td></tr>", (al != NULL && (al->bypass & FEATURE_FILTER)) ? "checked" : "");
1420         filebuf_addf(filebuf, "<tr><td>Header filtering: </td><td><input type=\"checkbox\" name=\"bheader\" %s></td></tr>", (al != NULL && (al->bypass & FEATURE_HEADER)) ? "checked" : "");
1421         filebuf_addf(filebuf, "<tr><td>MIME filtering: </td><td><input type=\"checkbox\" name=\"bmime\" %s></td></tr>", (al != NULL && (al->bypass & FEATURE_MIME)) ? "checked" : "");
1422         filebuf_addf(filebuf, "<tr><td>URL redirecting: </td><td><input type=\"checkbox\" name=\"bredirect\" %s></td></tr>", (al != NULL && (al->bypass & FEATURE_REDIRECT)) ? "checked" : "");
1423         filebuf_addf(filebuf, "<tr><td>Cookie filtering: </td><td><input type=\"checkbox\" name=\"bcookies\" %s></td></tr>", (al != NULL && (al->bypass & FEATURE_COOKIES)) ? "checked" : "");
1424         filebuf_addf(filebuf, "<tr><td>Document rewriting: </td><td><input type=\"checkbox\" name=\"brewrite\" %s></td></tr>", (al != NULL && (al->bypass & FEATURE_REWRITE)) ? "checked" : "");
1425         filebuf_addf(filebuf, "<tr><td>External parsers: </td><td><input type=\"checkbox\" name=\"bexternal\" %s></td></tr>", (al != NULL && (al->bypass & FEATURE_EXTERNAL)) ? "checked" : "");
1426         filebuf_addf(filebuf, "<tr><td>Forwarding: </td><td><input type=\"checkbox\" name=\"bforward\" %s></td></tr>", (al != NULL && (al->bypass & FEATURE_FORWARD)) ? "checked" : "");
1427         filebuf_addf(filebuf, "<tr><td>Keyword filtering: </td><td><input type=\"checkbox\" name=\"bkeywords\" %s></td></tr>", (al != NULL && (al->bypass & FEATURE_KEYWORDS)) ? "checked" : "");
1428         filebuf_addf(filebuf, "</table></td></tr>\n");
1429
1430         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
1431         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
1432
1433         filebuf_addf(filebuf, "</table></td></tr>\n");
1434
1435         pthread_rwlock_unlock(&access_list->lock);
1436 }
1437
1438
1439 void interface_page_config_access_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
1440 {
1441         int id = -1;
1442         char *list = NULL, *action = NULL;
1443         struct ACCESS_LIST_LIST *al = NULL;
1444         struct cgi_args_t *a;
1445
1446         if (access_list == NULL)
1447                 return;
1448
1449         pthread_rwlock_wrlock(&access_list->lock);
1450
1451         for (a = args; a; a = a->next) {
1452                 if (!strcasecmp(a->name, "action"))
1453                         action = a->value;
1454                 if (!strcasecmp(a->name, "id"))
1455                         id = atoi(a->value);
1456                 if (!strcasecmp(a->name, "list"))
1457                         list = a->value;
1458         }
1459
1460         if (action != NULL && !strcasecmp(action, "global")) {
1461                 for (a = args; a; a = a->next) {
1462                         if (!strcasecmp(a->name, "policy")) {
1463                                 if (!strcasecmp(a->value, "allow"))
1464                                         access_list->policy = POLICY_ALLOW;
1465                                 else if (!strcasecmp(a->value, "deny"))
1466                                         access_list->policy = POLICY_DENY;
1467                         }
1468                 }
1469         }
1470
1471         if (action == NULL || list == NULL)
1472                 goto finish;
1473
1474         if (!strcasecmp(action, "delete")) {
1475                 if (!strcasecmp(list, "allow"))
1476                         al = access_list->allow;
1477                 else if (!strcasecmp(list, "deny"))
1478                         al = access_list->deny;
1479
1480                 for (; al; al = al->next) {
1481                         if (al->id == id) {
1482                                 if (!strcasecmp(list, "allow"))
1483                                         access_list->allow = access_ll_delete(al);
1484                                 else if (!strcasecmp(list, "deny"))
1485                                         access_list->deny = access_ll_delete(al);
1486
1487                                 break;
1488                         }
1489                 }
1490         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
1491                 if (!strcasecmp(action, "add")) {
1492                         if (!strcasecmp(list, "allow")) {
1493                                 al = access_ll_new(access_list->allow);
1494                                 if (access_list->allow == NULL)
1495                                         access_list->allow = al;
1496                         } else if (!strcasecmp(list, "deny")) {
1497                                 al = access_ll_new(access_list->deny);
1498                                 if (access_list->deny == NULL)
1499                                         access_list->deny = al;
1500                         } else
1501                                 goto finish;
1502
1503                         al->id = access_list->id++;
1504                 } else {
1505                         if (!strcasecmp(list, "allow")) {
1506                                 for (al = access_list->allow; al; al = al->next)
1507                                         if (al->id == id)
1508                                                 break;
1509                         } else if (!strcasecmp(list, "deny")) {
1510                                 for (al = access_list->deny; al; al = al->next)
1511                                         if (al->id == id)
1512                                                 break;
1513                         }
1514
1515                         if (al == NULL)
1516                                 goto finish;
1517                 }
1518
1519                 if (strcasecmp(action, "shift")) {
1520                         al->access = al->bypass = 0;
1521
1522                         for (a = args; a; a = a->next) {
1523                                 if (!strcasecmp(a->name, "enabled")) {
1524                                         if (!strcasecmp(a->value, "no"))
1525                                                 al->enabled = FALSE;
1526                                         else
1527                                                 al->enabled = TRUE;
1528                                 } else if (!strcasecmp(a->name, "comment"))
1529                                         access_ll_insert(al, a->value, NULL, NULL, NULL, NULL, NULL);
1530                                 else if (!strcasecmp(a->name, "ip"))
1531                                         access_ll_insert(al, NULL, a->value, NULL, NULL, NULL, NULL);
1532                                 else if (!strcasecmp(a->name, "username"))
1533                                         access_ll_insert(al, NULL, NULL, NULL, NULL, a->value, NULL);
1534                                 else if (!strcasecmp(a->name, "password"))
1535                                         access_ll_insert(al, NULL, NULL, NULL, NULL, NULL, a->value);
1536                                 else if (!strcasecmp(a->name, "access_config"))
1537                                         al->access |= ACCESS_CONFIG;
1538                                 else if (!strcasecmp(a->name, "access_proxy"))
1539                                         al->access |= ACCESS_PROXY;
1540                                 else if (!strcasecmp(a->name, "access_connect"))
1541                                         al->access |= ACCESS_CONNECT;
1542                                 else if (!strcasecmp(a->name, "access_http"))
1543                                         al->access |= ACCESS_HTTP;
1544                                 else if (!strcasecmp(a->name, "access_transparent"))
1545                                         al->access |= ACCESS_TRANSPARENT;
1546                                 else if (!strcasecmp(a->name, "access_bypass"))
1547                                         al->access |= ACCESS_BYPASS;
1548                                 else if (!strcasecmp(a->name, "bfilter"))
1549                                         al->bypass |= FEATURE_FILTER;
1550                                 else if (!strcasecmp(a->name, "bheader"))
1551                                         al->bypass |= FEATURE_HEADER;
1552                                 else if (!strcasecmp(a->name, "bmime"))
1553                                         al->bypass |= FEATURE_MIME;
1554                                 else if (!strcasecmp(a->name, "bredirect"))
1555                                         al->bypass |= FEATURE_REDIRECT;
1556                                 else if (!strcasecmp(a->name, "bcookies"))
1557                                         al->bypass |= FEATURE_COOKIES;
1558                                 else if (!strcasecmp(a->name, "brewrite"))
1559                                         al->bypass |= FEATURE_REWRITE;
1560                                 else if (!strcasecmp(a->name, "bexternal"))
1561                                         al->bypass |= FEATURE_EXTERNAL;
1562                                 else if (!strcasecmp(a->name, "bforward"))
1563                                         al->bypass |= FEATURE_FORWARD;
1564                                 else if (!strcasecmp(a->name, "bkeywords"))
1565                                         al->bypass |= FEATURE_KEYWORDS;
1566                                 else if (!strcasecmp(a->name, "move")) {
1567                                         if (!strcasecmp(a->value, "allow") && strcasecmp(list, a->value)) {
1568                                                 MOVENODE(struct ACCESS_LIST_LIST *, al, access_list->deny, access_list->allow);
1569                                         } else if (!strcasecmp(a->value, "deny") && strcasecmp(list, a->value)) {
1570                                                 MOVENODE(struct ACCESS_LIST_LIST *, al, access_list->allow, access_list->deny);
1571                                         }
1572                                 }
1573                         }
1574                 } else {
1575                         for (a = args; a; a = a->next) {
1576                                 if (!strcasecmp(a->name, "direction")) {
1577                                         if (!strcasecmp(a->value, "up")) {
1578                                                 SHIFTNODE(struct ACCESS_LIST_LIST *, (!strcasecmp(list, "allow")) ? access_list->allow : access_list->deny, al, UP);
1579                                         } else if (!strcasecmp(a->value, "down")) {
1580                                                 SHIFTNODE(struct ACCESS_LIST_LIST *, (!strcasecmp(list, "allow")) ? access_list->allow : access_list->deny, al, DOWN);
1581                                         } else if (!strcasecmp(a->value, "top")) {
1582                                                 SETNODE(struct ACCESS_LIST_LIST *, (!strcasecmp(list, "allow")) ? access_list->allow : access_list->deny, al, TOP);
1583                                         } else if (!strcasecmp(a->value, "bottom")) {
1584                                                 SETNODE(struct ACCESS_LIST_LIST *, (!strcasecmp(list, "allow")) ? access_list->allow : access_list->deny, al, BOTTOM);
1585                                         }
1586                                 }
1587                         }
1588                 }
1589         }
1590
1591       finish:
1592         pthread_rwlock_unlock(&access_list->lock);
1593 }
1594
1595 void interface_page_config_rewrite(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
1596 {
1597         char *ptr;
1598         struct REWRITE_LIST_LIST *rl = NULL;
1599
1600         if (rewrite_list == NULL)
1601                 return;
1602
1603         pthread_rwlock_rdlock(&rewrite_list->lock);
1604
1605         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
1606         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1607         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=rewrite&amp;dialog=show\">Add</a></td></tr>\n");
1608         filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
1609
1610         for (rl = rewrite_list->rewrite; rl; rl = rl->next) {
1611                 filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
1612                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1613
1614                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (rl->enabled == TRUE) ? "yes" : "no");
1615                 if (rl->comment != NULL) {
1616                         ptr = string_to_html(rl->comment, TRUE);
1617                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
1618                         xfree(ptr);
1619                 }
1620                 if (rl->host != NULL) {
1621                         ptr = string_to_html(rl->host, TRUE);
1622                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Host</td><td>%s</td></tr>\n", ptr);
1623                         xfree(ptr);
1624                 }
1625                 if (rl->file != NULL) {
1626                         ptr = string_to_html(rl->file, TRUE);
1627                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">File</td><td>%s</td></tr>\n", ptr);
1628                         xfree(ptr);
1629                 }
1630                 if (rl->mime != NULL) {
1631                         ptr = string_to_html(rl->mime, TRUE);
1632                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Mimetype</td><td>%s</td></tr>\n", ptr);
1633                         xfree(ptr);
1634                 }
1635                 if (rl->pattern != NULL) {
1636                         ptr = string_to_html(rl->pattern, TRUE);
1637                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Pattern</td><td>%s</td></tr>\n", ptr);
1638                         xfree(ptr);
1639                 }
1640                 if (rl->replace != NULL) {
1641                         ptr = string_to_html(rl->replace, TRUE);
1642                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Replacement</td><td>%s</td></tr>\n", ptr);
1643                         xfree(ptr);
1644                 }
1645
1646                 if (rl->which != 0)
1647                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Applies to</td><td>%s,%s,%s,%s</td></tr>\n", (rl->which & REWRITE_SERVER) ? "server header" : "", (rl->which & REWRITE_CLIENT) ? "client header" : "", (rl->which & REWRITE_BODY) ? "body" : "", (rl->which & REWRITE_POST) ? "post" : "");
1648
1649                 filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
1650                 filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=rewrite&amp;dialog=show&amp;id=%d\">Edit</a> <a href=\"config?section=rewrite&amp;action=delete&amp;id=%d\">Delete</a></td>\n", rl->id, rl->id);
1651                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=rewrite&amp;action=shift&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=rewrite&amp;action=shift&amp;id=%d&amp;direction=down\">Down</a></td>\n", rl->id, rl->id);
1652                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=rewrite&amp;action=shift&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=rewrite&amp;action=shift&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", rl->id, rl->id);
1653                 filebuf_addf(filebuf, "</table></td></tr>\n");
1654
1655                 filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
1656         }
1657
1658         filebuf_addf(filebuf, "</table>\n");
1659
1660         pthread_rwlock_unlock(&rewrite_list->lock);
1661 }
1662
1663 void interface_page_config_rewrite_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
1664 {
1665         int id = -1;
1666         char *ptr = NULL;
1667         struct REWRITE_LIST_LIST *rl = NULL;
1668         struct cgi_args_t *a = args;
1669
1670         if (rewrite_list == NULL)
1671                 return;
1672
1673         pthread_rwlock_rdlock(&rewrite_list->lock);
1674
1675         for (; a; a = a->next) {
1676                 if (!strcasecmp(a->name, "id"))
1677                         id = atoi(a->value);
1678         }
1679
1680         if (id != -1)
1681                 for (rl = rewrite_list->rewrite; rl && rl->id != id; rl = rl->next);
1682
1683         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1684         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
1685
1686         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"rewrite\">\n");
1687
1688         if (id != -1) {
1689                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
1690                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
1691         } else
1692                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
1693
1694         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
1695         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (rl == NULL || rl->enabled == TRUE) ? "checked" : "");
1696         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (rl != NULL && rl->enabled == FALSE) ? "checked" : "");
1697         filebuf_addf(filebuf, "</td></tr>\n");
1698
1699         if (rl != NULL && rl->comment != NULL)
1700                 ptr = string_to_html(rl->comment, TRUE);
1701         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1702         FREE_AND_NULL(ptr);
1703
1704         if (rl != NULL && rl->host != NULL)
1705                 ptr = string_to_html(rl->host, TRUE);
1706         filebuf_addf(filebuf, "<tr><td>Host</td><td><input type=\"text\" name=\"host\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1707         FREE_AND_NULL(ptr);
1708
1709         if (rl != NULL && rl->file != NULL)
1710                 ptr = string_to_html(rl->file, TRUE);
1711         filebuf_addf(filebuf, "<tr><td>File</td><td><input type=\"text\" name=\"file\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1712         FREE_AND_NULL(ptr);
1713
1714         if (rl != NULL && rl->mime != NULL)
1715                 ptr = string_to_html(rl->mime, TRUE);
1716         filebuf_addf(filebuf, "<tr><td>Mimetype</td><td><input type=\"text\" name=\"mime\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1717         FREE_AND_NULL(ptr);
1718
1719         if (rl != NULL && rl->pattern != NULL)
1720                 ptr = string_to_html(rl->pattern, TRUE);
1721         filebuf_addf(filebuf, "<tr><td>Pattern</td><td><input type=\"text\" name=\"pattern\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1722         FREE_AND_NULL(ptr);
1723
1724         if (rl != NULL && rl->replace != NULL)
1725                 ptr = string_to_html(rl->replace, FALSE);
1726         filebuf_addf(filebuf, "<tr><td>Replace</td><td><textarea name=\"replace\" cols=\"80\" rows=\"8\" wrap=\"virtual\">%s</textarea></td></tr>\n", (ptr != NULL) ? ptr : "");
1727         FREE_AND_NULL(ptr);
1728
1729         filebuf_addf(filebuf, "<tr><td>Applies to</td><td align=\"center\">");
1730         filebuf_addf(filebuf, "Server header: <input type=\"checkbox\" name=\"server\" %s>   ", (rl != NULL && rl->which & REWRITE_SERVER) ? "checked" : "");
1731         filebuf_addf(filebuf, "Client header: <input type=\"checkbox\" name=\"client\" %s>   ", (rl != NULL && rl->which & REWRITE_CLIENT) ? "checked" : "");
1732         filebuf_addf(filebuf, "Body : <input type=\"checkbox\" name=\"body\" %s>   ", (rl == NULL || rl->which & REWRITE_BODY) ? "checked" : "");
1733         filebuf_addf(filebuf, "POST data : <input type=\"checkbox\" name=\"post\" %s>   ", (rl != NULL && rl->which & REWRITE_POST) ? "checked" : "");
1734         filebuf_addf(filebuf, "</td></tr>\n");
1735
1736         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
1737         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
1738
1739         filebuf_addf(filebuf, "</table></td></tr>\n");
1740
1741         pthread_rwlock_unlock(&rewrite_list->lock);
1742 }
1743
1744
1745 void interface_page_config_rewrite_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
1746 {
1747         int id = -1;
1748         char *action = NULL;
1749         struct REWRITE_LIST_LIST *rl = NULL;
1750         struct cgi_args_t *a;
1751
1752         if (rewrite_list == NULL)
1753                 return;
1754
1755         pthread_rwlock_wrlock(&rewrite_list->lock);
1756
1757         for (a = args; a; a = a->next) {
1758                 if (!strcasecmp(a->name, "action"))
1759                         action = a->value;
1760                 if (!strcasecmp(a->name, "id"))
1761                         id = atoi(a->value);
1762         }
1763
1764         if (action == NULL)
1765                 goto finish;
1766
1767         if (!strcasecmp(action, "delete")) {
1768                 for (rl = rewrite_list->rewrite; rl; rl = rl->next) {
1769                         if (rl->id == id) {
1770                                 rewrite_list->rewrite = rewrite_list_delete(rl);
1771
1772                                 break;
1773                         }
1774                 }
1775         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
1776                 if (!strcasecmp(action, "add")) {
1777                         rl = rewrite_list_new(rewrite_list->rewrite);
1778                         if (rewrite_list->rewrite == NULL)
1779                                 rewrite_list->rewrite = rl;
1780                         rl->id = rewrite_list->id++;
1781                 } else {
1782                         for (rl = rewrite_list->rewrite; rl; rl = rl->next)
1783                                 if (rl->id == id)
1784                                         break;
1785
1786                         if (rl == NULL)
1787                                 goto finish;
1788                 }
1789
1790                 if (strcasecmp(action, "shift")) {
1791                         rl->which = 0;
1792
1793                         for (a = args; a; a = a->next) {
1794                                 if (!strcasecmp(a->name, "enabled")) {
1795                                         if (!strcasecmp(a->value, "no"))
1796                                                 rl->enabled = FALSE;
1797                                         else
1798                                                 rl->enabled = TRUE;
1799                                 } else if (!strcasecmp(a->name, "comment"))
1800                                         rewrite_list_insert(rl, a->value, NULL, NULL, NULL, NULL, NULL, NULL);
1801                                 else if (!strcasecmp(a->name, "pattern"))
1802                                         rewrite_list_insert(rl, NULL, a->value, NULL, NULL, NULL, NULL, NULL);
1803                                 else if (!strcasecmp(a->name, "replace"))
1804                                         rewrite_list_insert(rl, NULL, NULL, a->value, NULL, NULL, NULL, NULL);
1805                                 else if (!strcasecmp(a->name, "host"))
1806                                         rewrite_list_insert(rl, NULL, NULL, NULL, NULL, a->value, NULL, NULL);
1807                                 else if (!strcasecmp(a->name, "file"))
1808                                         rewrite_list_insert(rl, NULL, NULL, NULL, NULL, NULL, a->value, NULL);
1809                                 else if (!strcasecmp(a->name, "mime"))
1810                                         rewrite_list_insert(rl, NULL, NULL, NULL, NULL, NULL, NULL, a->value);
1811                                 else if (!strcasecmp(a->name, "server"))
1812                                         rl->which |= REWRITE_SERVER;
1813                                 else if (!strcasecmp(a->name, "client"))
1814                                         rl->which |= REWRITE_CLIENT;
1815                                 else if (!strcasecmp(a->name, "body"))
1816                                         rl->which |= REWRITE_BODY;
1817                                 else if (!strcasecmp(a->name, "post"))
1818                                         rl->which |= REWRITE_POST;
1819                         }
1820                 } else {
1821                         for (a = args; a; a = a->next) {
1822                                 if (!strcasecmp(a->name, "direction")) {
1823                                         if (!strcasecmp(a->value, "up")) {
1824                                                 SHIFTNODE(struct REWRITE_LIST_LIST *, rewrite_list->rewrite, rl, UP);
1825                                         } else if (!strcasecmp(a->value, "down")) {
1826                                                 SHIFTNODE(struct REWRITE_LIST_LIST *, rewrite_list->rewrite, rl, DOWN);
1827                                         } else if (!strcasecmp(a->value, "top")) {
1828                                                 SETNODE(struct REWRITE_LIST_LIST *, rewrite_list->rewrite, rl, TOP);
1829                                         } else if (!strcasecmp(a->value, "bottom")) {
1830                                                 SETNODE(struct REWRITE_LIST_LIST *, rewrite_list->rewrite, rl, BOTTOM);
1831                                         }
1832                                 }
1833                         }
1834                 }
1835         }
1836
1837       finish:
1838         pthread_rwlock_unlock(&rewrite_list->lock);
1839 }
1840
1841 void interface_page_config_mime(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
1842 {
1843         int i;
1844         char *ptr;
1845         struct MIME_LIST_LIST *ml = NULL;
1846
1847         if (mime_list == NULL)
1848                 return;
1849
1850         pthread_rwlock_rdlock(&mime_list->lock);
1851
1852         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
1853         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1854         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
1855         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"mime\">\n");
1856         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"global\">\n");
1857         filebuf_addf(filebuf, "<tr><td>Policy</td><td><select name=\"policy\"><option value=\"allow\" %s>allow<option value=\"deny\" %s>deny</select></td></tr>", (mime_list->policy == POLICY_ALLOW) ? "selected" : "", (mime_list->policy == POLICY_DENY) ? "selected" : "");
1858         filebuf_addf(filebuf, "<tr><td>Default template</td><td><input type=\"text\" name=\"dtemplate\" value=\"%s\" size=\"20\"></td></tr>\n", (mime_list->dtemplate != NULL) ? mime_list->dtemplate : "");
1859         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
1860         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=mime&amp;dialog=show\">Add</a></td></tr>\n");
1861         filebuf_addf(filebuf, "</form></table></td></tr> <tr><td><br></td></tr>\n");
1862
1863         for (i = 0; i < 2; i++) {
1864                 filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"30%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1865
1866                 switch (i) {
1867                 case 0:
1868                         ml = mime_list->allow;
1869                         if (ml != NULL)
1870                                 filebuf_addf(filebuf, "<tr><th>ALLOW</th></tr>\n");
1871                         break;
1872                 case 1:
1873                         ml = mime_list->deny;
1874                         if (ml != NULL)
1875                                 filebuf_addf(filebuf, "<tr><th>DENY</th></tr>\n");
1876                         break;
1877                 }
1878
1879                 filebuf_addf(filebuf, "</table></td></tr>\n");
1880                 if (ml != NULL)
1881                         filebuf_addf(filebuf, "<tr><td><br></td></tr>\n");
1882
1883                 for (; ml; ml = ml->next) {
1884                         filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
1885                         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1886
1887                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (ml->enabled == TRUE) ? "yes" : "no");
1888                         if (ml->comment != NULL) {
1889                                 ptr = string_to_html(ml->comment, TRUE);
1890                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
1891                                 xfree(ptr);
1892                         }
1893                         if (ml->host != NULL) {
1894                                 ptr = string_to_html(ml->host, TRUE);
1895                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Host</td><td>%s</td></tr>\n", ptr);
1896                                 xfree(ptr);
1897                         }
1898                         if (ml->file != NULL) {
1899                                 ptr = string_to_html(ml->file, TRUE);
1900                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">File</td><td>%s</td></tr>\n", ptr);
1901                                 xfree(ptr);
1902                         }
1903                         if (ml->mime != NULL) {
1904                                 ptr = string_to_html(ml->mime, TRUE);
1905                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Mimetype</td><td>%s</td></tr>\n", ptr);
1906                                 xfree(ptr);
1907                         }
1908                         if (ml->template != NULL)
1909                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Template</td><td>%s</td></tr>\n", ml->template);
1910
1911
1912                         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
1913                         filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=mime&amp;dialog=show&amp;list=%s&amp;id=%d\">Edit</a> <a href=\"config?section=mime&amp;action=delete&amp;list=%s&amp;id=%d\">Delete</a></td>\n", (i == 0) ? "allow" : "deny", ml->id, (i == 0) ? "allow" : "deny", ml->id);
1914                         filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=mime&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=mime&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=down\">Down</a></td>\n", (i == 0) ? "allow" : "deny", ml->id, (i == 0) ? "allow" : "deny", ml->id);
1915                         filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=mime&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=mime&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", (i == 0) ? "allow" : "deny", ml->id, (i == 0) ? "allow" : "deny", ml->id);
1916                         filebuf_addf(filebuf, "</table></td></tr>\n");
1917
1918                         filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
1919                 }
1920         }
1921
1922         filebuf_addf(filebuf, "</table>\n");
1923
1924         pthread_rwlock_unlock(&mime_list->lock);
1925 }
1926
1927 void interface_page_config_mime_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
1928 {
1929         int id = -1;
1930         char *list = NULL, *ptr = NULL;
1931         struct MIME_LIST_LIST *ml = NULL;
1932         struct cgi_args_t *a = args;
1933
1934         if (mime_list == NULL)
1935                 return;
1936
1937         pthread_rwlock_rdlock(&mime_list->lock);
1938
1939         for (; a; a = a->next) {
1940                 if (!strcasecmp(a->name, "id"))
1941                         id = atoi(a->value);
1942                 if (!strcasecmp(a->name, "list"))
1943                         list = a->value;
1944         }
1945
1946         if (id != -1 && list != NULL) {
1947                 if (!strcasecmp(list, "allow"))
1948                         for (ml = mime_list->allow; ml && ml->id != id; ml = ml->next);
1949                 else if (!strcasecmp(list, "deny"))
1950                         for (ml = mime_list->deny; ml && ml->id != id; ml = ml->next);
1951         }
1952
1953         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
1954         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
1955
1956         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"mime\">\n");
1957         if (list != NULL)
1958                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"list\" value=\"%s\">\n", list);
1959
1960         if (id != -1) {
1961                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
1962                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
1963         } else
1964                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
1965
1966         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
1967         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (ml == NULL || ml->enabled == TRUE) ? "checked" : "");
1968         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (ml != NULL && ml->enabled == FALSE) ? "checked" : "");
1969         filebuf_addf(filebuf, "</td></tr>\n");
1970
1971         filebuf_addf(filebuf, "<tr><td>Action</td><td><select name=\"%s\">\n", (list != NULL) ? "move" : "list");
1972         filebuf_addf(filebuf, "<option value=\"allow\" %s>allow\n", (list != NULL && !strcasecmp(list, "allow")) ? "selected" : "");
1973         filebuf_addf(filebuf, "<option value=\"deny\" %s>deny\n", (list != NULL && !strcasecmp(list, "deny")) ? "selected" : "");
1974         filebuf_addf(filebuf, "</select></tr>\n");
1975
1976         if (ml != NULL && ml->comment != NULL)
1977                 ptr = string_to_html(ml->comment, TRUE);
1978         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1979         FREE_AND_NULL(ptr);
1980
1981         if (ml != NULL && ml->host != NULL)
1982                 ptr = string_to_html(ml->host, TRUE);
1983         filebuf_addf(filebuf, "<tr><td>Host</td><td><input type=\"text\" name=\"host\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1984         FREE_AND_NULL(ptr);
1985
1986         if (ml != NULL && ml->file != NULL)
1987                 ptr = string_to_html(ml->file, TRUE);
1988         filebuf_addf(filebuf, "<tr><td>File</td><td><input type=\"text\" name=\"file\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1989         FREE_AND_NULL(ptr);
1990
1991         if (ml != NULL && ml->mime != NULL)
1992                 ptr = string_to_html(ml->mime, TRUE);
1993         filebuf_addf(filebuf, "<tr><td>Mimetype</td><td><input type=\"text\" name=\"mime\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1994         FREE_AND_NULL(ptr);
1995
1996         if (ml != NULL && ml->template != NULL)
1997                 ptr = string_to_html(ml->template, TRUE);
1998         filebuf_addf(filebuf, "<tr><td>Template</td><td><input type=\"text\" name=\"template\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
1999         FREE_AND_NULL(ptr);
2000
2001         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
2002         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
2003
2004         filebuf_addf(filebuf, "</table></td></tr>\n");
2005
2006         pthread_rwlock_unlock(&mime_list->lock);
2007 }
2008
2009 void interface_page_config_mime_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2010 {
2011         int id = -1;
2012         char *list = NULL, *action = NULL;
2013         struct MIME_LIST_LIST *ml = NULL;
2014         struct cgi_args_t *a;
2015
2016         if (mime_list == NULL)
2017                 return;
2018
2019         pthread_rwlock_wrlock(&mime_list->lock);
2020
2021         for (a = args; a; a = a->next) {
2022                 if (!strcasecmp(a->name, "action"))
2023                         action = a->value;
2024                 if (!strcasecmp(a->name, "id"))
2025                         id = atoi(a->value);
2026                 if (!strcasecmp(a->name, "list"))
2027                         list = a->value;
2028         }
2029
2030         if (action != NULL && !strcasecmp(action, "global")) {
2031                 for (a = args; a; a = a->next) {
2032                         if (!strcasecmp(a->name, "policy")) {
2033                                 if (!strcasecmp(a->value, "allow"))
2034                                         mime_list->policy = POLICY_ALLOW;
2035                                 else if (!strcasecmp(a->value, "deny"))
2036                                         mime_list->policy = POLICY_DENY;
2037                         } else if (!strcasecmp(a->name, "dtemplate")) {
2038                                 FREE_AND_NULL(mime_list->dtemplate);
2039                                 if (strcmp(a->name, ""))
2040                                         mime_list->dtemplate = xstrdup(a->value);
2041                         }
2042                 }
2043         }
2044
2045         if (action == NULL || list == NULL)
2046                 goto finish;
2047
2048         if (!strcasecmp(action, "delete")) {
2049                 if (!strcasecmp(list, "allow"))
2050                         ml = mime_list->allow;
2051                 else if (!strcasecmp(list, "deny"))
2052                         ml = mime_list->deny;
2053
2054                 for (; ml; ml = ml->next) {
2055                         if (ml->id == id) {
2056                                 if (!strcasecmp(list, "allow"))
2057                                         mime_list->allow = mime_ll_delete(ml);
2058                                 else if (!strcasecmp(list, "deny"))
2059                                         mime_list->deny = mime_ll_delete(ml);
2060
2061                                 break;
2062                         }
2063                 }
2064         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
2065                 if (!strcasecmp(action, "add")) {
2066                         if (!strcasecmp(list, "allow")) {
2067                                 ml = mime_ll_new(mime_list->allow);
2068                                 if (mime_list->allow == NULL)
2069                                         mime_list->allow = ml;
2070                         } else if (!strcasecmp(list, "deny")) {
2071                                 ml = mime_ll_new(mime_list->deny);
2072                                 if (mime_list->deny == NULL)
2073                                         mime_list->deny = ml;
2074                         } else
2075                                 goto finish;
2076
2077                         ml->id = mime_list->id++;
2078                 } else {
2079                         if (!strcasecmp(list, "allow")) {
2080                                 for (ml = mime_list->allow; ml; ml = ml->next)
2081                                         if (ml->id == id)
2082                                                 break;
2083                         } else if (!strcasecmp(list, "deny")) {
2084                                 for (ml = mime_list->deny; ml; ml = ml->next)
2085                                         if (ml->id == id)
2086                                                 break;
2087                         }
2088
2089                         if (ml == NULL)
2090                                 goto finish;
2091                 }
2092
2093                 if (strcasecmp(action, "shift")) {
2094                         for (a = args; a; a = a->next) {
2095                                 if (!strcasecmp(a->name, "enabled")) {
2096                                         if (!strcasecmp(a->value, "no"))
2097                                                 ml->enabled = FALSE;
2098                                         else
2099                                                 ml->enabled = TRUE;
2100                                 } else if (!strcasecmp(a->name, "comment"))
2101                                         mime_ll_insert(ml, a->value, NULL, NULL, NULL, NULL);
2102                                 else if (!strcasecmp(a->name, "template"))
2103                                         mime_ll_insert(ml, NULL, a->value, NULL, NULL, NULL);
2104                                 else if (!strcasecmp(a->name, "host"))
2105                                         mime_ll_insert(ml, NULL, NULL, a->value, NULL, NULL);
2106                                 else if (!strcasecmp(a->name, "mime"))
2107                                         mime_ll_insert(ml, NULL, NULL, NULL, a->value, NULL);
2108                                 else if (!strcasecmp(a->name, "file"))
2109                                         mime_ll_insert(ml, NULL, NULL, NULL, NULL, a->value);
2110                                 else if (!strcasecmp(a->name, "move")) {
2111                                         if (!strcasecmp(a->value, "allow") && strcasecmp(list, a->value)) {
2112                                                 MOVENODE(struct MIME_LIST_LIST *, ml, mime_list->deny, mime_list->allow);
2113                                         } else if (!strcasecmp(a->value, "deny") && strcasecmp(list, a->value)) {
2114                                                 MOVENODE(struct MIME_LIST_LIST *, ml, mime_list->allow, mime_list->deny);
2115                                         }
2116                                 }
2117                         }
2118                 } else {
2119                         for (a = args; a; a = a->next) {
2120                                 if (!strcasecmp(a->name, "direction")) {
2121                                         if (!strcasecmp(a->value, "up")) {
2122                                                 SHIFTNODE(struct MIME_LIST_LIST *, (!strcasecmp(list, "allow")) ? mime_list->allow : mime_list->deny, ml, UP);
2123                                         } else if (!strcasecmp(a->value, "down")) {
2124                                                 SHIFTNODE(struct MIME_LIST_LIST *, (!strcasecmp(list, "allow")) ? mime_list->allow : mime_list->deny, ml, DOWN);
2125                                         } else if (!strcasecmp(a->value, "top")) {
2126                                                 SETNODE(struct MIME_LIST_LIST *, (!strcasecmp(list, "allow")) ? mime_list->allow : mime_list->deny, ml, TOP);
2127                                         } else if (!strcasecmp(a->value, "bottom")) {
2128                                                 SETNODE(struct MIME_LIST_LIST *, (!strcasecmp(list, "allow")) ? mime_list->allow : mime_list->deny, ml, BOTTOM);
2129                                         }
2130                                 }
2131                         }
2132                 }
2133         }
2134
2135       finish:
2136         pthread_rwlock_unlock(&mime_list->lock);
2137 }
2138
2139 void interface_page_config_cookies(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2140 {
2141         int i;
2142         char *ptr;
2143         struct COOKIE_LIST_LIST *cl = NULL;
2144
2145         if (cookie_list == NULL)
2146                 return;
2147
2148         pthread_rwlock_rdlock(&cookie_list->lock);
2149
2150         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
2151         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2152         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
2153         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"cookies\">\n");
2154         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"global\">\n");
2155         filebuf_addf(filebuf, "<tr><td>Policy</td><td><select name=\"policy\"><option value=\"allow\" %s>allow<option value=\"deny\" %s>deny</select></td></tr>", (cookie_list->policy == POLICY_ALLOW) ? "selected" : "", (cookie_list->policy == POLICY_DENY) ? "selected" : "");
2156         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
2157         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=cookies&amp;dialog=show\">Add</a></td></tr>\n");
2158         filebuf_addf(filebuf, "</form></table></td></tr> <tr><td><br></td></tr>\n");
2159
2160         for (i = 0; i < 2; i++) {
2161                 filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"30%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2162
2163                 switch (i) {
2164                 case 0:
2165                         cl = cookie_list->allow;
2166                         if (cl != NULL)
2167                                 filebuf_addf(filebuf, "<tr><th>ALLOW</th></tr>\n");
2168                         break;
2169                 case 1:
2170                         cl = cookie_list->deny;
2171                         if (cl != NULL)
2172                                 filebuf_addf(filebuf, "<tr><th>DENY</th></tr>\n");
2173                         break;
2174                 }
2175
2176                 filebuf_addf(filebuf, "</table></td></tr>\n");
2177                 if (cl != NULL)
2178                         filebuf_addf(filebuf, "<tr><td><br></td></tr>\n");
2179
2180                 for (; cl; cl = cl->next) {
2181                         filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
2182                         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2183
2184                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (cl->enabled == TRUE) ? "yes" : "no");
2185                         if (cl->comment != NULL) {
2186                                 ptr = string_to_html(cl->comment, TRUE);
2187                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
2188                                 xfree(ptr);
2189                         }
2190                         if (cl->host != NULL) {
2191                                 ptr = string_to_html(cl->host, TRUE);
2192                                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Host</td><td>%s</td></tr>\n", ptr);
2193                                 xfree(ptr);
2194                         }
2195                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Direction</td><td>%s</td></tr>\n", (cl->direction == COOKIE_BOTH) ? "ANY" : (cl->direction == COOKIE_IN) ? "IN" : "OUT");
2196
2197
2198                         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
2199                         filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=cookies&amp;dialog=show&amp;list=%s&amp;id=%d\">Edit</a> <a href=\"config?section=cookies&amp;action=delete&amp;list=%s&amp;id=%d\">Delete</a></td>\n", (i == 0) ? "allow" : "deny", cl->id, (i == 0) ? "allow" : "deny", cl->id);
2200                         filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=cookies&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=cookies&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=down\">Down</a></td>\n", (i == 0) ? "allow" : "deny", cl->id, (i == 0) ? "allow" : "deny", cl->id);
2201                         filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=cookies&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=cookies&amp;action=shift&amp;list=%s&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", (i == 0) ? "allow" : "deny", cl->id, (i == 0) ? "allow" : "deny", cl->id);
2202                         filebuf_addf(filebuf, "</table></td></tr>\n");
2203
2204                         filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
2205                 }
2206         }
2207
2208         pthread_rwlock_unlock(&cookie_list->lock);
2209
2210         filebuf_addf(filebuf, "</table>\n");
2211 }
2212
2213 void interface_page_config_cookies_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2214 {
2215         int id = -1;
2216         char *list = NULL, *ptr = NULL;
2217         struct COOKIE_LIST_LIST *cl = NULL;
2218         struct cgi_args_t *a = args;
2219
2220         if (cookie_list == NULL)
2221                 return;
2222
2223         pthread_rwlock_rdlock(&cookie_list->lock);
2224
2225         for (; a; a = a->next) {
2226                 if (!strcasecmp(a->name, "id"))
2227                         id = atoi(a->value);
2228                 if (!strcasecmp(a->name, "list"))
2229                         list = a->value;
2230         }
2231
2232         if (id != -1 && list != NULL) {
2233                 if (!strcasecmp(list, "allow"))
2234                         for (cl = cookie_list->allow; cl && cl->id != id; cl = cl->next);
2235                 else if (!strcasecmp(list, "deny"))
2236                         for (cl = cookie_list->deny; cl && cl->id != id; cl = cl->next);
2237         }
2238
2239         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2240         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
2241
2242         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"cookies\">\n");
2243         if (list != NULL)
2244                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"list\" value=\"%s\">\n", list);
2245
2246         if (id != -1) {
2247                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
2248                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
2249         } else
2250                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
2251
2252         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
2253         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (cl == NULL || cl->enabled == TRUE) ? "checked" : "");
2254         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (cl != NULL && cl->enabled == FALSE) ? "checked" : "");
2255         filebuf_addf(filebuf, "</td></tr>\n");
2256
2257         filebuf_addf(filebuf, "<tr><td>Action</td><td><select name=\"%s\">\n", (list != NULL) ? "move" : "list");
2258         filebuf_addf(filebuf, "<option value=\"allow\" %s>allow\n", (list != NULL && !strcasecmp(list, "allow")) ? "selected" : "");
2259         filebuf_addf(filebuf, "<option value=\"deny\" %s>deny\n", (list != NULL && !strcasecmp(list, "deny")) ? "selected" : "");
2260         filebuf_addf(filebuf, "</select></tr>\n");
2261
2262         if (cl != NULL && cl->comment != NULL)
2263                 ptr = string_to_html(cl->comment, TRUE);
2264         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2265         FREE_AND_NULL(ptr);
2266
2267         if (cl != NULL && cl->host != NULL)
2268                 ptr = string_to_html(cl->host, TRUE);
2269         filebuf_addf(filebuf, "<tr><td>Host</td><td><input type=\"text\" name=\"host\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2270         FREE_AND_NULL(ptr);
2271
2272         filebuf_addf(filebuf, "<tr><td>Direction</td><td align=\"center\">");
2273         filebuf_addf(filebuf, "Both: <input type=\"radio\" name=\"direction\" value=\"both\" %s>   ", (cl == NULL || cl->direction == COOKIE_BOTH) ? "checked" : "");
2274         filebuf_addf(filebuf, "In: <input type=\"radio\" name=\"direction\" value=\"in\" %s>   ", (cl != NULL && cl->direction == COOKIE_IN) ? "checked" : "");
2275         filebuf_addf(filebuf, "Out: <input type=\"radio\" name=\"direction\" value=\"out\" %s>   ", (cl != NULL && cl->direction == COOKIE_OUT) ? "checked" : "");
2276         filebuf_addf(filebuf, "</td></tr>\n");
2277
2278         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
2279         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
2280
2281         filebuf_addf(filebuf, "</table></td></tr>\n");
2282
2283         pthread_rwlock_unlock(&cookie_list->lock);
2284 }
2285
2286
2287 void interface_page_config_cookies_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2288 {
2289         int id = -1;
2290         char *list = NULL, *action = NULL;
2291         struct COOKIE_LIST_LIST *cl = NULL;
2292         struct cgi_args_t *a;
2293
2294         if (cookie_list == NULL)
2295                 return;
2296
2297         pthread_rwlock_wrlock(&cookie_list->lock);
2298
2299         for (a = args; a; a = a->next) {
2300                 if (!strcasecmp(a->name, "action"))
2301                         action = a->value;
2302                 if (!strcasecmp(a->name, "id"))
2303                         id = atoi(a->value);
2304                 if (!strcasecmp(a->name, "list"))
2305                         list = a->value;
2306         }
2307
2308         if (action != NULL && !strcasecmp(action, "global")) {
2309                 for (a = args; a; a = a->next) {
2310                         if (!strcasecmp(a->name, "policy")) {
2311                                 if (!strcasecmp(a->value, "allow"))
2312                                         cookie_list->policy = POLICY_ALLOW;
2313                                 else if (!strcasecmp(a->value, "deny"))
2314                                         cookie_list->policy = POLICY_DENY;
2315                         }
2316                 }
2317         }
2318
2319         if (action == NULL || list == NULL)
2320                 goto finish;
2321
2322         if (!strcasecmp(action, "delete")) {
2323                 if (!strcasecmp(list, "allow"))
2324                         cl = cookie_list->allow;
2325                 else if (!strcasecmp(list, "deny"))
2326                         cl = cookie_list->deny;
2327
2328                 for (; cl; cl = cl->next) {
2329                         if (cl->id == id) {
2330                                 if (!strcasecmp(list, "allow"))
2331                                         cookie_list->allow = cookie_ll_delete(cl);
2332                                 else if (!strcasecmp(list, "deny"))
2333                                         cookie_list->deny = cookie_ll_delete(cl);
2334
2335                                 break;
2336                         }
2337                 }
2338         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
2339                 if (!strcasecmp(action, "add")) {
2340                         if (!strcasecmp(list, "allow")) {
2341                                 cl = cookie_ll_new(cookie_list->allow);
2342                                 if (cookie_list->allow == NULL)
2343                                         cookie_list->allow = cl;
2344                         } else if (!strcasecmp(list, "deny")) {
2345                                 cl = cookie_ll_new(cookie_list->deny);
2346                                 if (cookie_list->deny == NULL)
2347                                         cookie_list->deny = cl;
2348                         } else
2349                                 goto finish;
2350
2351                         cl->id = cookie_list->id++;
2352                 } else {
2353                         if (!strcasecmp(list, "allow")) {
2354                                 for (cl = cookie_list->allow; cl; cl = cl->next)
2355                                         if (cl->id == id)
2356                                                 break;
2357                         } else if (!strcasecmp(list, "deny")) {
2358                                 for (cl = cookie_list->deny; cl; cl = cl->next)
2359                                         if (cl->id == id)
2360                                                 break;
2361                         }
2362
2363                         if (cl == NULL)
2364                                 goto finish;
2365                 }
2366
2367                 if (strcasecmp(action, "shift")) {
2368                         for (a = args; a; a = a->next) {
2369                                 if (!strcasecmp(a->name, "enabled")) {
2370                                         if (!strcasecmp(a->value, "no"))
2371                                                 cl->enabled = FALSE;
2372                                         else
2373                                                 cl->enabled = TRUE;
2374                                 } else if (!strcasecmp(a->name, "comment"))
2375                                         cookie_ll_insert(cl, a->value, NULL, NULL);
2376                                 else if (!strcasecmp(a->name, "direction"))
2377                                         cookie_ll_insert(cl, NULL, a->value, NULL);
2378                                 else if (!strcasecmp(a->name, "host"))
2379                                         cookie_ll_insert(cl, NULL, NULL, a->value);
2380                                 else if (!strcasecmp(a->name, "move")) {
2381                                         if (!strcasecmp(a->value, "allow") && strcasecmp(list, a->value)) {
2382                                                 MOVENODE(struct COOKIE_LIST_LIST *, cl, cookie_list->deny, cookie_list->allow);
2383                                         } else if (!strcasecmp(a->value, "deny") && strcasecmp(list, a->value)) {
2384                                                 MOVENODE(struct COOKIE_LIST_LIST *, cl, cookie_list->allow, cookie_list->deny);
2385                                         }
2386                                 }
2387                         }
2388                 } else {
2389                         for (a = args; a; a = a->next) {
2390                                 if (!strcasecmp(a->name, "direction")) {
2391                                         if (!strcasecmp(a->value, "up")) {
2392                                                 SHIFTNODE(struct COOKIE_LIST_LIST *, (!strcasecmp(list, "allow")) ? cookie_list->allow : cookie_list->deny, cl, UP);
2393                                         } else if (!strcasecmp(a->value, "down")) {
2394                                                 SHIFTNODE(struct COOKIE_LIST_LIST *, (!strcasecmp(list, "allow")) ? cookie_list->allow : cookie_list->deny, cl, DOWN);
2395                                         } else if (!strcasecmp(a->value, "top")) {
2396                                                 SETNODE(struct COOKIE_LIST_LIST *, (!strcasecmp(list, "allow")) ? cookie_list->allow : cookie_list->deny, cl, TOP);
2397                                         } else if (!strcasecmp(a->value, "bottom")) {
2398                                                 SETNODE(struct COOKIE_LIST_LIST *, (!strcasecmp(list, "allow")) ? cookie_list->allow : cookie_list->deny, cl, BOTTOM);
2399                                         }
2400                                 }
2401                         }
2402                 }
2403         }
2404
2405       finish:
2406         pthread_rwlock_unlock(&cookie_list->lock);
2407 }
2408
2409 void interface_page_config_external(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2410 {
2411         char *ptr;
2412         struct EXTERNAL_LIST_LIST *el = NULL;
2413
2414         if (external == NULL)
2415                 return;
2416
2417         pthread_rwlock_rdlock(&external->lock);
2418
2419         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
2420         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2421         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=external&amp;dialog=show\">Add</a></td></tr>\n");
2422         filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
2423
2424         for (el = external->external_list; el; el = el->next) {
2425                 filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
2426                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2427
2428                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (el->enabled == TRUE) ? "yes" : "no");
2429                 if (el->comment != NULL) {
2430                         ptr = string_to_html(el->comment, TRUE);
2431                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
2432                         xfree(ptr);
2433                 }
2434                 if (el->host != NULL) {
2435                         ptr = string_to_html(el->host, TRUE);
2436                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Host</td><td>%s</td></tr>\n", ptr);
2437                         xfree(ptr);
2438                 }
2439                 if (el->file != NULL) {
2440                         ptr = string_to_html(el->file, TRUE);
2441                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">File</td><td>%s</td></tr>\n", ptr);
2442                         xfree(ptr);
2443                 }
2444                 if (el->mime != NULL) {
2445                         ptr = string_to_html(el->mime, TRUE);
2446                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Mimetype</td><td>%s</td></tr>\n", ptr);
2447                         xfree(ptr);
2448                 }
2449                 if (el->newmime != NULL) {
2450                         ptr = string_to_html(el->newmime, TRUE);
2451                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">New mime</td><td>%s</td></tr>\n", ptr);
2452                         xfree(ptr);
2453                 }
2454                 if (el->exec != NULL) {
2455                         ptr = string_to_html(el->exec, TRUE);
2456                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Executable</td><td>%s</td></tr>\n", ptr);
2457                         xfree(ptr);
2458                 }
2459
2460                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Type</td><td>%s</td></tr>\n", (el->type == EXTERNAL_PIPE) ? "pipe" : "file");
2461
2462
2463                 filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
2464                 filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=external&amp;dialog=show&amp;id=%d\">Edit</a> <a href=\"config?section=external&amp;action=delete&amp;id=%d\">Delete</a></td>\n", el->id, el->id);
2465                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=external&amp;action=shift&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=external&amp;action=shift&amp;id=%d&amp;direction=down\">Down</a></td>\n", el->id, el->id);
2466                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=external&amp;action=shift&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=external&amp;action=shift&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", el->id, el->id);
2467                 filebuf_addf(filebuf, "</table></td></tr>\n");
2468
2469                 filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
2470         }
2471
2472         filebuf_addf(filebuf, "</table>\n");
2473
2474         pthread_rwlock_unlock(&external->lock);
2475 }
2476
2477 void interface_page_config_external_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2478 {
2479         int id = -1;
2480         char *ptr = NULL;
2481         struct EXTERNAL_LIST_LIST *el = NULL;
2482         struct cgi_args_t *a = args;
2483
2484         if (external == NULL)
2485                 return;
2486
2487         pthread_rwlock_rdlock(&external->lock);
2488
2489         for (; a; a = a->next) {
2490                 if (!strcasecmp(a->name, "id"))
2491                         id = atoi(a->value);
2492         }
2493
2494         if (id != -1)
2495                 for (el = external->external_list; el && el->id != id; el = el->next);
2496
2497         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2498         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
2499
2500         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"external\">\n");
2501
2502         if (id != -1) {
2503                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
2504                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
2505         } else
2506                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
2507
2508         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
2509         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (el == NULL || el->enabled == TRUE) ? "checked" : "");
2510         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (el != NULL && el->enabled == FALSE) ? "checked" : "");
2511         filebuf_addf(filebuf, "</td></tr>\n");
2512
2513         if (el != NULL && el->comment != NULL)
2514                 ptr = string_to_html(el->comment, TRUE);
2515         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2516         FREE_AND_NULL(ptr);
2517
2518         if (el != NULL && el->exec != NULL)
2519                 ptr = string_to_html(el->exec, TRUE);
2520         filebuf_addf(filebuf, "<tr><td>Executable</td><td><input type=\"text\" name=\"exec\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2521         FREE_AND_NULL(ptr);
2522
2523         if (el != NULL && el->host != NULL)
2524                 ptr = string_to_html(el->host, TRUE);
2525         filebuf_addf(filebuf, "<tr><td>Host</td><td><input type=\"text\" name=\"host\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2526         FREE_AND_NULL(ptr);
2527
2528         if (el != NULL && el->file != NULL)
2529                 ptr = string_to_html(el->file, TRUE);
2530         filebuf_addf(filebuf, "<tr><td>File</td><td><input type=\"text\" name=\"file\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2531         FREE_AND_NULL(ptr);
2532
2533         if (el != NULL && el->mime != NULL)
2534                 ptr = string_to_html(el->mime, TRUE);
2535         filebuf_addf(filebuf, "<tr><td>Mimetype</td><td><input type=\"text\" name=\"mime\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2536         FREE_AND_NULL(ptr);
2537
2538         if (el != NULL && el->newmime != NULL)
2539                 ptr = string_to_html(el->newmime, TRUE);
2540         filebuf_addf(filebuf, "<tr><td>Newmime</td><td><input type=\"text\" name=\"newmime\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2541         FREE_AND_NULL(ptr);
2542
2543         filebuf_addf(filebuf, "<tr><td>Type</td><td align=\"center\">");
2544         filebuf_addf(filebuf, "Pipe: <input type=\"radio\" name=\"type\" value=\"pipe\" %s>   ", (el == NULL || el->type == EXTERNAL_PIPE) ? "checked" : "");
2545         filebuf_addf(filebuf, "File: <input type=\"radio\" name=\"type\" value=\"file\" %s>   ", (el != NULL && el->type == EXTERNAL_FILE) ? "checked" : "");
2546         filebuf_addf(filebuf, "</td></tr>\n");
2547
2548         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
2549         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
2550
2551         filebuf_addf(filebuf, "</table></td></tr>\n");
2552
2553         pthread_rwlock_unlock(&external->lock);
2554 }
2555
2556
2557 void interface_page_config_external_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2558 {
2559         int id = -1;
2560         char *action = NULL;
2561         struct EXTERNAL_LIST_LIST *el = NULL;
2562         struct cgi_args_t *a;
2563
2564         if (external == NULL)
2565                 return;
2566
2567         pthread_rwlock_wrlock(&external->lock);
2568
2569         for (a = args; a; a = a->next) {
2570                 if (!strcasecmp(a->name, "action"))
2571                         action = a->value;
2572                 if (!strcasecmp(a->name, "id"))
2573                         id = atoi(a->value);
2574         }
2575
2576         if (action == NULL)
2577                 goto finish;
2578
2579         if (!strcasecmp(action, "delete")) {
2580                 for (el = external->external_list; el; el = el->next) {
2581                         if (el->id == id) {
2582                                 external->external_list = external_list_delete(el);
2583
2584                                 break;
2585                         }
2586                 }
2587         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
2588                 if (!strcasecmp(action, "add")) {
2589                         el = external_list_new(external->external_list);
2590                         if (external->external_list == NULL)
2591                                 external->external_list = el;
2592                         el->id = external->id++;
2593                 } else {
2594                         for (el = external->external_list; el; el = el->next)
2595                                 if (el->id == id)
2596                                         break;
2597
2598                         if (el == NULL)
2599                                 goto finish;
2600                 }
2601
2602                 if (strcasecmp(action, "shift")) {
2603                         for (a = args; a; a = a->next) {
2604                                 if (!strcasecmp(a->name, "enabled")) {
2605                                         if (!strcasecmp(a->value, "no"))
2606                                                 el->enabled = FALSE;
2607                                         else
2608                                                 el->enabled = TRUE;
2609                                 } else if (!strcasecmp(a->name, "comment"))
2610                                         external_list_insert(el, a->value, NULL, NULL, NULL, NULL, NULL, NULL);
2611                                 else if (!strcasecmp(a->name, "mime"))
2612                                         external_list_insert(el, NULL, a->value, NULL, NULL, NULL, NULL, NULL);
2613                                 else if (!strcasecmp(a->name, "host"))
2614                                         external_list_insert(el, NULL, NULL, a->value, NULL, NULL, NULL, NULL);
2615                                 else if (!strcasecmp(a->name, "file"))
2616                                         external_list_insert(el, NULL, NULL, NULL, a->value, NULL, NULL, NULL);
2617                                 else if (!strcasecmp(a->name, "exec"))
2618                                         external_list_insert(el, NULL, NULL, NULL, NULL, a->value, NULL, NULL);
2619                                 else if (!strcasecmp(a->name, "newmime"))
2620                                         external_list_insert(el, NULL, NULL, NULL, NULL, NULL, a->value, NULL);
2621                                 else if (!strcasecmp(a->name, "type"))
2622                                         external_list_insert(el, NULL, NULL, NULL, NULL, NULL, NULL, a->value);
2623                         }
2624
2625                 } else {
2626                         for (a = args; a; a = a->next) {
2627                                 if (!strcasecmp(a->name, "direction")) {
2628                                         if (!strcasecmp(a->value, "up")) {
2629                                                 SHIFTNODE(struct EXTERNAL_LIST_LIST *, external->external_list, el, UP);
2630                                         } else if (!strcasecmp(a->value, "down")) {
2631                                                 SHIFTNODE(struct EXTERNAL_LIST_LIST *, external->external_list, el, DOWN);
2632                                         } else if (!strcasecmp(a->value, "top")) {
2633                                                 SETNODE(struct EXTERNAL_LIST_LIST *, external->external_list, el, TOP);
2634                                         } else if (!strcasecmp(a->value, "bottom")) {
2635                                                 SETNODE(struct EXTERNAL_LIST_LIST *, external->external_list, el, BOTTOM);
2636                                         }
2637                                 }
2638                         }
2639                 }
2640         }
2641
2642       finish:
2643         pthread_rwlock_unlock(&external->lock);
2644 }
2645
2646 void interface_page_config_templates(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2647 {
2648         char *ptr;
2649         struct TEMPLATE_LIST *tl = NULL;
2650
2651         if (templates == NULL)
2652                 return;
2653
2654         pthread_rwlock_rdlock(&templates->lock);
2655
2656         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
2657         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2658         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
2659         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"templates\">\n");
2660         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"global\">\n");
2661         filebuf_addf(filebuf, "<tr><td>Path</td><td><input type=\"text\" name=\"path\" value=\"%s\" size=\"20\"></td></tr>\n", (templates->path != NULL) ? templates->path : "");
2662         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
2663         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=templates&amp;dialog=show\">Add</a></td></tr>\n");
2664         filebuf_addf(filebuf, "</form></table></td></tr> <tr><td><br></td></tr>\n");
2665
2666         for (tl = templates->template_list; tl; tl = tl->next) {
2667                 filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
2668                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2669
2670                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (tl->enabled == TRUE) ? "yes" : "no");
2671                 if (tl->comment != NULL) {
2672                         ptr = string_to_html(tl->comment, TRUE);
2673                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
2674                         xfree(ptr);
2675                 }
2676                 if (tl->name != NULL) {
2677                         ptr = string_to_html(tl->name, TRUE);
2678                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Name</td><td>%s</td></tr>\n", ptr);
2679                         xfree(ptr);
2680                 }
2681                 if (tl->file != NULL) {
2682                         ptr = string_to_html(tl->file, TRUE);
2683                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">File</td><td>%s</td></tr>\n", ptr);
2684                         xfree(ptr);
2685                 }
2686                 if (tl->mime != NULL) {
2687                         ptr = string_to_html(tl->mime, TRUE);
2688                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Mimetype</td><td>%s</td></tr>\n", ptr);
2689                         xfree(ptr);
2690                 }
2691
2692                 if (tl->code != -1)
2693                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Response code</td><td>%d</td></tr>\n", tl->code);
2694
2695
2696                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Type</td><td>%s</td></tr>\n", (tl->type == TEMPLATE_FILE) ? "file" : "executable");
2697
2698                 filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
2699                 filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=templates&amp;dialog=show&amp;id=%d\">Edit</a> <a href=\"config?section=templates&amp;action=delete&amp;id=%d\">Delete</a></td>\n", tl->id, tl->id);
2700                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=templates&amp;action=shift&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=templates&amp;action=shift&amp;id=%d&amp;direction=down\">Down</a></td>\n", tl->id, tl->id);
2701                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=templates&amp;action=shift&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=templates&amp;action=shift&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", tl->id, tl->id);
2702                 filebuf_addf(filebuf, "</table></td></tr>\n");
2703
2704                 filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
2705         }
2706
2707         filebuf_addf(filebuf, "</table>\n");
2708
2709         pthread_rwlock_unlock(&templates->lock);
2710 }
2711
2712 void interface_page_config_templates_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2713 {
2714         int id = -1;
2715         char *ptr = NULL, buf[16];
2716         struct TEMPLATE_LIST *tl = NULL;
2717         struct cgi_args_t *a = args;
2718
2719         if (rewrite_list == NULL)
2720                 return;
2721
2722         pthread_rwlock_rdlock(&templates->lock);
2723
2724         for (; a; a = a->next) {
2725                 if (!strcasecmp(a->name, "id"))
2726                         id = atoi(a->value);
2727         }
2728
2729         if (id != -1)
2730                 for (tl = templates->template_list; tl && tl->id != id; tl = tl->next);
2731
2732         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2733         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
2734
2735         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"templates\">\n");
2736
2737         if (id != -1) {
2738                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
2739                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
2740         } else
2741                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
2742
2743         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
2744         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (tl == NULL || tl->enabled == TRUE) ? "checked" : "");
2745         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (tl != NULL && tl->enabled == FALSE) ? "checked" : "");
2746         filebuf_addf(filebuf, "</td></tr>\n");
2747
2748         if (tl != NULL && tl->comment != NULL)
2749                 ptr = string_to_html(tl->comment, TRUE);
2750         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2751         FREE_AND_NULL(ptr);
2752
2753         if (tl != NULL && tl->name != NULL)
2754                 ptr = string_to_html(tl->name, TRUE);
2755         filebuf_addf(filebuf, "<tr><td>Name</td><td><input type=\"text\" name=\"name\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2756         FREE_AND_NULL(ptr);
2757
2758         if (tl != NULL && tl->file != NULL)
2759                 ptr = string_to_html(tl->file, TRUE);
2760         filebuf_addf(filebuf, "<tr><td>File</td><td><input type=\"text\" name=\"file\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2761         FREE_AND_NULL(ptr);
2762
2763         if (tl != NULL && tl->mime != NULL)
2764                 ptr = string_to_html(tl->mime, TRUE);
2765         filebuf_addf(filebuf, "<tr><td>Mimetype</td><td><input type=\"text\" name=\"mime\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
2766         FREE_AND_NULL(ptr);
2767
2768         if (tl != NULL)
2769                 snprintf(buf, sizeof(buf), "%d", tl->code);
2770         filebuf_addf(filebuf, "<tr><Td>Response code</td><td><input type=\"text\" name=\"code\" value=\"%s\"></td></tr>\n", (tl != NULL && tl->code != -1) ? buf : "");
2771
2772         filebuf_addf(filebuf, "<tr><td>Type</td><td align=\"center\">");
2773         filebuf_addf(filebuf, "File: <input type=\"radio\" name=\"type\" value=\"file\" %s>   ", (tl == NULL || tl->type == TEMPLATE_FILE) ? "checked" : "");
2774         filebuf_addf(filebuf, "Executable: <input type=\"radio\" name=\"type\" value=\"executable\" %s>   ", (tl != NULL && tl->type == TEMPLATE_EXECUTABLE) ? "checked" : "");
2775         filebuf_addf(filebuf, "</td></tr>\n");
2776
2777         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
2778         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
2779
2780         filebuf_addf(filebuf, "</table></td></tr>\n");
2781
2782         pthread_rwlock_unlock(&templates->lock);
2783 }
2784
2785 void interface_page_config_templates_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2786 {
2787         int id = -1;
2788         char *action = NULL;
2789         struct TEMPLATE_LIST *tl = NULL;
2790         struct cgi_args_t *a;
2791
2792         if (templates == NULL)
2793                 return;
2794
2795         pthread_rwlock_wrlock(&templates->lock);
2796
2797         for (a = args; a; a = a->next) {
2798                 if (!strcasecmp(a->name, "action"))
2799                         action = a->value;
2800                 if (!strcasecmp(a->name, "id"))
2801                         id = atoi(a->value);
2802         }
2803
2804         if (action == NULL)
2805                 goto finish;
2806
2807         if (!strcasecmp(action, "delete")) {
2808                 for (tl = templates->template_list; tl; tl = tl->next) {
2809                         if (tl->id == id) {
2810                                 templates->template_list = template_list_delete(tl);
2811
2812                                 break;
2813                         }
2814                 }
2815         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
2816                 if (!strcasecmp(action, "add")) {
2817                         tl = template_list_new(templates->template_list);
2818                         if (templates->template_list == NULL)
2819                                 templates->template_list = tl;
2820                         tl->id = templates->id++;
2821                 } else {
2822                         for (tl = templates->template_list; tl; tl = tl->next)
2823                                 if (tl->id == id)
2824                                         break;
2825
2826                         if (tl == NULL)
2827                                 goto finish;
2828                 }
2829
2830                 if (strcasecmp(action, "shift")) {
2831                         for (a = args; a; a = a->next) {
2832                                 if (!strcasecmp(a->name, "enabled")) {
2833                                         if (!strcasecmp(a->value, "no"))
2834                                                 tl->enabled = FALSE;
2835                                         else
2836                                                 tl->enabled = TRUE;
2837                                 } else if (!strcasecmp(a->name, "comment"))
2838                                         template_list_insert(tl, a->value, NULL, NULL, NULL, NULL, NULL);
2839                                 else if (!strcasecmp(a->name, "name"))
2840                                         template_list_insert(tl, NULL, a->value, NULL, NULL, NULL, NULL);
2841                                 else if (!strcasecmp(a->name, "file"))
2842                                         template_list_insert(tl, NULL, NULL, a->value, NULL, NULL, NULL);
2843                                 else if (!strcasecmp(a->name, "type"))
2844                                         template_list_insert(tl, NULL, NULL, NULL, a->value, NULL, NULL);
2845                                 else if (!strcasecmp(a->name, "mime"))
2846                                         template_list_insert(tl, NULL, NULL, NULL, NULL, a->value, NULL);
2847                                 else if (!strcasecmp(a->name, "code"))
2848                                         template_list_insert(tl, NULL, NULL, NULL, NULL, NULL, a->value);
2849
2850                         }
2851                 } else {
2852                         for (a = args; a; a = a->next) {
2853                                 if (!strcasecmp(a->name, "direction")) {
2854                                         if (!strcasecmp(a->value, "up")) {
2855                                                 SHIFTNODE(struct TEMPLATE_LIST *, templates->template_list, tl, UP);
2856                                         } else if (!strcasecmp(a->value, "down")) {
2857                                                 SHIFTNODE(struct TEMPLATE_LIST *, templates->template_list, tl, DOWN);
2858                                         } else if (!strcasecmp(a->value, "top")) {
2859                                                 SETNODE(struct TEMPLATE_LIST *, templates->template_list, tl, TOP);
2860                                         } else if (!strcasecmp(a->value, "down")) {
2861                                                 SETNODE(struct TEMPLATE_LIST *, templates->template_list, tl, BOTTOM);
2862                                         }
2863                                 }
2864                         }
2865                 }
2866         }
2867
2868       finish:
2869         pthread_rwlock_unlock(&templates->lock);
2870 }
2871
2872 void interface_page_config_network(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2873 {
2874         char *ptr;
2875         struct LISTEN_LIST *ll = NULL;
2876
2877         if (network == NULL)
2878                 return;
2879
2880         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
2881
2882         ll = network->listen_list;
2883
2884         for (; ll; ll = ll->next) {
2885                 filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
2886                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2887                 if (ll->ip != NULL) {
2888                         ptr = string_to_html(ll->ip, TRUE);
2889                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">IP Address</td><td>%s</td></tr>\n", ptr);
2890                         xfree(ptr);
2891                 }
2892                 if (ll->port != -1) {
2893                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Port</td><td>%d</td></tr>\n", ll->port);
2894                 }
2895
2896                 if (ll->proxytype != PROXY_DIRECT) {
2897                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Proxy type</td><td>%s</td></tr>\n", (ll->proxytype == PROXY_NORMAL) ? "HTTP" : "SOCKS4");
2898                 }
2899
2900                 if (ll->proxy != NULL) {
2901                         ptr = string_to_html(ll->proxy, TRUE);
2902                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Proxy</td><td>%s</td></tr>\n", ptr);
2903                         xfree(ptr);
2904                 }
2905
2906                 filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
2907         }
2908
2909         filebuf_addf(filebuf, "</table>\n");
2910 }
2911
2912 void interface_page_config_redirect(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2913 {
2914         char *ptr;
2915         struct REDIRECT_LIST_LIST *rl = NULL;
2916
2917         if (redirect_list == NULL)
2918                 return;
2919
2920         pthread_rwlock_rdlock(&redirect_list->lock);
2921
2922         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
2923         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2924         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=redirect&amp;dialog=show\">Add</a></td></tr>\n");
2925         filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
2926
2927         for (rl = redirect_list->redirect_list; rl; rl = rl->next) {
2928                 filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
2929                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2930
2931                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (rl->enabled == TRUE) ? "yes" : "no");
2932                 if (rl->comment != NULL) {
2933                         ptr = string_to_html(rl->comment, TRUE);
2934                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
2935                         xfree(ptr);
2936                 }
2937                 if (rl->url != NULL) {
2938                         ptr = string_to_html(rl->url, TRUE);
2939                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">URL</td><td>%s</td></tr>\n", ptr);
2940                         xfree(ptr);
2941                 }
2942                 if (rl->redirect != NULL) {
2943                         ptr = string_to_html(rl->redirect, TRUE);
2944                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Redirect</td><td>%s</td></tr>\n", ptr);
2945                         xfree(ptr);
2946                 }
2947                 if (rl->port != -1)
2948                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Port</td><td>%d</td></tr>\n", rl->port);
2949
2950                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">302 redirect</td><td>%s</td></tr>\n", (rl->send302 == TRUE) ? "yes" : "no");
2951
2952                 if (rl->options != 0)
2953                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Options</td><td>%s,%s,%s</td></tr>\n", (rl->options & URL_ENCODE) ? "encode URL" : "", (rl->options & URL_DECODEBEFORE) ? "decode URL before" : "", (rl->options & URL_DECODEAFTER) ? "decode URL after" : "");
2954
2955                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Applies to</td><td>%s</td></tr>\n", (rl->which == REDIRECT_BOTH) ? "both" : (rl->which == REDIRECT_URL) ? "URL" : "location");
2956
2957                 filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
2958                 filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=redirect&amp;dialog=show&amp;id=%d\">Edit</a> <a href=\"config?section=redirect&amp;action=delete&amp;id=%d\">Delete</a></td>\n", rl->id, rl->id);
2959                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=redirect&amp;action=shift&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=redirect&amp;action=shift&amp;id=%d&amp;direction=down\">Down</a></td>\n", rl->id, rl->id);
2960                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=redirect&amp;action=shift&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=redirect&amp;action=shift&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", rl->id, rl->id);
2961                 filebuf_addf(filebuf, "</table></td></tr>\n");
2962
2963                 filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
2964         }
2965
2966         filebuf_addf(filebuf, "</table>\n");
2967
2968         pthread_rwlock_unlock(&redirect_list->lock);
2969 }
2970
2971 void interface_page_config_redirect_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
2972 {
2973         int id = -1;
2974         char *ptr = NULL;
2975         struct REDIRECT_LIST_LIST *rl = NULL;
2976         struct cgi_args_t *a = args;
2977
2978         if (redirect_list == NULL)
2979                 return;
2980
2981         pthread_rwlock_rdlock(&redirect_list->lock);
2982
2983         for (; a; a = a->next) {
2984                 if (!strcasecmp(a->name, "id"))
2985                         id = atoi(a->value);
2986         }
2987
2988         if (id != -1)
2989                 for (rl = redirect_list->redirect_list; rl && rl->id != id; rl = rl->next);
2990
2991         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
2992         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
2993
2994         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"redirect\">\n");
2995
2996         if (id != -1) {
2997                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
2998                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
2999         } else
3000                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
3001
3002         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
3003         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (rl == NULL || rl->enabled == TRUE) ? "checked" : "");
3004         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (rl != NULL && rl->enabled == FALSE) ? "checked" : "");
3005         filebuf_addf(filebuf, "</td></tr>\n");
3006
3007         if (rl != NULL && rl->comment != NULL)
3008                 ptr = string_to_html(rl->comment, TRUE);
3009         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3010         FREE_AND_NULL(ptr);
3011
3012         if (rl != NULL && rl->url != NULL)
3013                 ptr = string_to_html(rl->url, TRUE);
3014         filebuf_addf(filebuf, "<tr><td>URL</td><td><input type=\"text\" name=\"url\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3015         FREE_AND_NULL(ptr);
3016
3017         if (rl != NULL && rl->redirect != NULL)
3018                 ptr = string_to_html(rl->redirect, TRUE);
3019         filebuf_addf(filebuf, "<tr><td>Redirect</td><td><input type=\"text\" name=\"redirect\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3020         FREE_AND_NULL(ptr);
3021
3022         if (rl != NULL && rl->port != -1)
3023                 filebuf_addf(filebuf, "<tr><td>Port</td><td><input type=\"text\" name=\"port\" value=\"%d\" size=\"20\"></td></tr>\n", rl->port);
3024         else
3025                 filebuf_addf(filebuf, "<tr><td>Port</td><td><input type=\"text\" name=\"port\" value=\"\" size\"20\"></td></tr>\n");
3026
3027         filebuf_addf(filebuf, "<tr><td>302 redirect</td><td align=\"center\">");
3028         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"send302\" value=\"yes\" %s>   ", (rl == NULL || rl->send302 == TRUE) ? "checked" : "");
3029         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"send302\" value=\"no\" %s>   ", (rl != NULL && rl->send302 == FALSE) ? "checked" : "");
3030         filebuf_addf(filebuf, "</td></tr>\n");
3031
3032         filebuf_addf(filebuf, "<tr><td>Options</td><td align=\"center\">");
3033         filebuf_addf(filebuf, "Encode URL: <input type=\"checkbox\" name=\"encode\" %s>   ", (rl != NULL && (rl->options & URL_ENCODE)) ? "checked" : "");
3034         filebuf_addf(filebuf, "Decode URL before: <input type=\"checkbox\" name=\"decodebefore\" %s>   ", (rl != NULL && (rl->options & URL_DECODEBEFORE)) ? "checked" : "");
3035         filebuf_addf(filebuf, "Decode URL after: <input type=\"checkbox\" name=\"decodeafter\" %s>", (rl != NULL && (rl->options & URL_DECODEAFTER)) ? "checked" : "");
3036         filebuf_addf(filebuf, "</td></tr>\n");
3037
3038         filebuf_addf(filebuf, "<tr><td>Applies to</td><td align=\"center\">");
3039         filebuf_addf(filebuf, "Both: <input type=\"radio\" name=\"which\" value=\"both\" %s>   ", (rl != NULL && rl->which == REDIRECT_BOTH) ? "checked" : "");
3040         filebuf_addf(filebuf, "URL: <input type=\"radio\" name=\"which\" value=\"url\" %s>   ", (rl == NULL || rl->which == REDIRECT_URL) ? "checked" : "");
3041         filebuf_addf(filebuf, "Location header: <input type=\"radio\" name=\"which\" value=\"location\" %s>   ", (rl != NULL && rl->which == REDIRECT_LOCATION) ? "checked" : "");
3042         filebuf_addf(filebuf, "</td></tr>\n");
3043
3044         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
3045         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
3046
3047         filebuf_addf(filebuf, "</table></td></tr>\n");
3048
3049         pthread_rwlock_unlock(&redirect_list->lock);
3050 }
3051
3052
3053 void interface_page_config_redirect_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
3054 {
3055         int id = -1;
3056         char *action = NULL;
3057         struct REDIRECT_LIST_LIST *rl = NULL;
3058         struct cgi_args_t *a;
3059
3060         if (redirect_list == NULL)
3061                 return;
3062
3063         pthread_rwlock_wrlock(&redirect_list->lock);
3064
3065         for (a = args; a; a = a->next) {
3066                 if (!strcasecmp(a->name, "action"))
3067                         action = a->value;
3068                 if (!strcasecmp(a->name, "id"))
3069                         id = atoi(a->value);
3070         }
3071
3072         if (action == NULL)
3073                 goto finish;
3074
3075         if (!strcasecmp(action, "delete")) {
3076                 for (rl = redirect_list->redirect_list; rl; rl = rl->next) {
3077                         if (rl->id == id) {
3078                                 redirect_list->redirect_list = redirect_list_delete(rl);
3079
3080                                 break;
3081                         }
3082                 }
3083         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
3084                 if (!strcasecmp(action, "add")) {
3085                         rl = redirect_list_new(redirect_list->redirect_list);
3086                         if (redirect_list->redirect_list == NULL)
3087                                 redirect_list->redirect_list = rl;
3088                         rl->id = redirect_list->id++;
3089                 } else {
3090                         for (rl = redirect_list->redirect_list; rl; rl = rl->next)
3091                                 if (rl->id == id)
3092                                         break;
3093
3094                         if (rl == NULL)
3095                                 goto finish;
3096                 }
3097
3098                 if (strcasecmp(action, "shift")) {
3099                         rl->options = 0;
3100
3101                         for (a = args; a; a = a->next) {
3102                                 if (!strcasecmp(a->name, "enabled")) {
3103                                         if (!strcasecmp(a->value, "no"))
3104                                                 rl->enabled = FALSE;
3105                                         else
3106                                                 rl->enabled = TRUE;
3107                                 } else if (!strcasecmp(a->name, "comment"))
3108                                         redirect_list_insert(rl, a->value, NULL, NULL, NULL, NULL, NULL, NULL);
3109                                 else if (!strcasecmp(a->name, "url"))
3110                                         redirect_list_insert(rl, NULL, a->value, NULL, NULL, NULL, NULL, NULL);
3111                                 else if (!strcasecmp(a->name, "redirect"))
3112                                         redirect_list_insert(rl, NULL, NULL, a->value, NULL, NULL, NULL, NULL);
3113                                 else if (!strcasecmp(a->name, "port"))
3114                                         redirect_list_insert(rl, NULL, NULL, NULL, a->value, NULL, NULL, NULL);
3115                                 else if (!strcasecmp(a->name, "which"))
3116                                         redirect_list_insert(rl, NULL, NULL, NULL, NULL, a->value, NULL, NULL);
3117                                 else if (!strcasecmp(a->name, "send302"))
3118                                         redirect_list_insert(rl, NULL, NULL, NULL, NULL, NULL, a->value, NULL);
3119                                 else if (!strcasecmp(a->name, "encode"))
3120                                         rl->options |= URL_ENCODE;
3121                                 else if (!strcasecmp(a->name, "decodebefore"))
3122                                         rl->options |= URL_DECODEBEFORE;
3123                                 else if (!strcasecmp(a->name, "decodeafter"))
3124                                         rl->options |= URL_DECODEAFTER;
3125                         }
3126                 } else {
3127                         for (a = args; a; a = a->next) {
3128                                 if (!strcasecmp(a->name, "direction")) {
3129                                         if (!strcasecmp(a->value, "up")) {
3130                                                 SHIFTNODE(struct REDIRECT_LIST_LIST *, redirect_list->redirect_list, rl, UP);
3131                                         } else if (!strcasecmp(a->value, "down")) {
3132                                                 SHIFTNODE(struct REDIRECT_LIST_LIST *, redirect_list->redirect_list, rl, DOWN);
3133                                         } else if (!strcasecmp(a->value, "top")) {
3134                                                 SETNODE(struct REDIRECT_LIST_LIST *, redirect_list->redirect_list, rl, TOP);
3135                                         } else if (!strcasecmp(a->value, "bottom")) {
3136                                                 SETNODE(struct REDIRECT_LIST_LIST *, redirect_list->redirect_list, rl, BOTTOM);
3137                                         }
3138                                 }
3139                         }
3140                 }
3141         }
3142
3143       finish:
3144         pthread_rwlock_unlock(&redirect_list->lock);
3145 }
3146 void interface_page_config_forward(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
3147 {
3148         char *ptr;
3149         struct FORWARD_LIST_LIST *fl = NULL;
3150
3151         if (forward_list == NULL)
3152                 return;
3153
3154         pthread_rwlock_rdlock(&forward_list->lock);
3155
3156         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
3157         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
3158         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=forward&amp;dialog=show\">Add</a></td></tr>\n");
3159         filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
3160
3161         for (fl = forward_list->forward_list; fl; fl = fl->next) {
3162                 filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
3163                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
3164
3165                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (fl->enabled == TRUE) ? "yes" : "no");
3166                 if (fl->comment != NULL) {
3167                         ptr = string_to_html(fl->comment, TRUE);
3168                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
3169                         xfree(ptr);
3170                 }
3171                 if (fl->host != NULL) {
3172                         ptr = string_to_html(fl->host, TRUE);
3173                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Host</td><td>%s</td></tr>\n", ptr);
3174                         xfree(ptr);
3175                 }
3176                 if (fl->file != NULL) {
3177                         ptr = string_to_html(fl->file, TRUE);
3178                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">File</td><td>%s</td></tr>\n", ptr);
3179                         xfree(ptr);
3180                 }
3181                 if (fl->proxy != NULL) {
3182                         ptr = string_to_html(fl->proxy, TRUE);
3183                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Proxy</td><td>%s</td></tr>\n", ptr);
3184                         xfree(ptr);
3185                 }
3186                 if (fl->username != NULL) {
3187                         ptr = string_to_html(fl->username, TRUE);
3188                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Username</td><td>%s</td></tr>\n", ptr);
3189                         xfree(ptr);
3190                 }
3191                 if (fl->password != NULL) {
3192                         ptr = string_to_html(fl->password, TRUE);
3193                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Password</td><td>%s</td></tr>\n", ptr);
3194                         xfree(ptr);
3195                 }
3196                 if (fl->domain != NULL) {
3197                         ptr = string_to_html(fl->domain, TRUE);
3198                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Domain</td><td>%s</td></tr>\n", ptr);
3199                         xfree(ptr);
3200                 }
3201                 if (fl->port != -1)
3202                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Port</td><td>%d</td></tr>\n", fl->port);
3203
3204                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Type</td><td>%s</td></tr>\n", (fl->type == PROXY_NORMAL) ? "HTTP" : "SOCKS4");
3205
3206                 if (fl->which != 0)
3207                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Applies to</td><td>%s,%s</td></tr>\n", (fl->which & FORWARD_HTTP) ? "HTTP requests" : "", (fl->which & FORWARD_CONNECT) ? "CONNECT requests" : "");
3208
3209                 filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
3210                 filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=forward&amp;dialog=show&amp;id=%d\">Edit</a> <a href=\"config?section=forward&amp;action=delete&amp;id=%d\">Delete</a></td>\n", fl->id, fl->id);
3211                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=forward&amp;action=shift&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=forward&amp;action=shift&amp;id=%d&amp;direction=down\">Down</a></td>\n", fl->id, fl->id);
3212                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=forward&amp;action=shift&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=forward&amp;action=shift&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", fl->id, fl->id);
3213                 filebuf_addf(filebuf, "</table></td></tr>\n");
3214
3215                 filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
3216         }
3217
3218         filebuf_addf(filebuf, "</table>\n");
3219
3220         pthread_rwlock_unlock(&forward_list->lock);
3221 }
3222
3223 void interface_page_config_forward_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
3224 {
3225         int id = -1;
3226         char *ptr = NULL;
3227         struct FORWARD_LIST_LIST *fl = NULL;
3228         struct cgi_args_t *a = args;
3229
3230         if (forward_list == NULL)
3231                 return;
3232
3233         pthread_rwlock_rdlock(&forward_list->lock);
3234
3235         for (; a; a = a->next) {
3236                 if (!strcasecmp(a->name, "id"))
3237                         id = atoi(a->value);
3238         }
3239
3240         if (id != -1)
3241                 for (fl = forward_list->forward_list; fl && fl->id != id; fl = fl->next);
3242
3243         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
3244         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
3245
3246         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"forward\">\n");
3247
3248         if (id != -1) {
3249                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
3250                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
3251         } else
3252                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
3253
3254         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
3255         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (fl == NULL || fl->enabled == TRUE) ? "checked" : "");
3256         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (fl != NULL && fl->enabled == FALSE) ? "checked" : "");
3257         filebuf_addf(filebuf, "</td></tr>\n");
3258
3259         if (fl != NULL && fl->comment != NULL)
3260                 ptr = string_to_html(fl->comment, TRUE);
3261         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3262         FREE_AND_NULL(ptr);
3263
3264         if (fl != NULL && fl->host != NULL)
3265                 ptr = string_to_html(fl->host, TRUE);
3266         filebuf_addf(filebuf, "<tr><td>Host</td><td><input type=\"text\" name=\"host\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3267         FREE_AND_NULL(ptr);
3268
3269         if (fl != NULL && fl->file != NULL)
3270                 ptr = string_to_html(fl->file, TRUE);
3271         filebuf_addf(filebuf, "<tr><td>File</td><td><input type=\"text\" name=\"file\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3272         FREE_AND_NULL(ptr);
3273
3274         if (fl != NULL && fl->proxy != NULL)
3275                 ptr = string_to_html(fl->proxy, TRUE);
3276         filebuf_addf(filebuf, "<tr><td>Proxy</td><td><input type=\"text\" name=\"proxy\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3277         FREE_AND_NULL(ptr);
3278
3279         if (fl != NULL && fl->username != NULL)
3280                 ptr = string_to_html(fl->username, TRUE);
3281         filebuf_addf(filebuf, "<tr><td>Username</td><td><input type=\"text\" name=\"username\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3282         FREE_AND_NULL(ptr);
3283
3284         if (fl != NULL && fl->password != NULL)
3285                 ptr = string_to_html(fl->password, TRUE);
3286         filebuf_addf(filebuf, "<tr><td>Password</td><td><input type=\"text\" name=\"password\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3287         FREE_AND_NULL(ptr);
3288
3289         if (fl != NULL && fl->domain != NULL)
3290                 ptr = string_to_html(fl->domain, TRUE);
3291         filebuf_addf(filebuf, "<tr><td>Domain</td><td><input type=\"text\" name=\"domain\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3292         FREE_AND_NULL(ptr);
3293
3294         if (fl != NULL && fl->port != -1)
3295                 filebuf_addf(filebuf, "<tr><td>Port</td><td><input type=\"text\" name=\"port\" value=\"%d\" size=\"20\"></td></tr>\n", fl->port);
3296         else
3297                 filebuf_addf(filebuf, "<tr><td>Port</td><td><input type=\"text\" name=\"port\" value=\"\" size\"20\"></td></tr>\n");
3298
3299         filebuf_addf(filebuf, "<tr><td>Type</td><td align=\"center\">");
3300         filebuf_addf(filebuf, "HTTP: <input type=\"radio\" name=\"type\" value=\"HTTP\" %s>   ", (fl == NULL || fl->type == PROXY_NORMAL) ? "checked" : "");
3301         filebuf_addf(filebuf, "SOCKS4: <input type=\"radio\" name=\"type\" value=\"SOCKS4\" %s>   ", (fl != NULL && fl->type == PROXY_SOCKS4) ? "checked" : "");
3302         filebuf_addf(filebuf, "</td></tr>\n");
3303
3304         filebuf_addf(filebuf, "<tr><td>Applies to</td><td align=\"center\">");
3305         filebuf_addf(filebuf, "HTTP requests: <input type=\"checkbox\" name=\"HTTP\" %s>   ", (fl == NULL || (fl->which & FORWARD_HTTP)) ? "checked" : "");
3306         filebuf_addf(filebuf, "CONNECT requests: <input type=\"checkbox\" name=\"CONNECT\" %s>   ", (fl != NULL && (fl->which & FORWARD_CONNECT)) ? "checked" : "");
3307         filebuf_addf(filebuf, "</td></tr>\n");
3308
3309         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
3310         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
3311
3312         filebuf_addf(filebuf, "</table></td></tr>\n");
3313
3314         pthread_rwlock_unlock(&forward_list->lock);
3315 }
3316
3317
3318 void interface_page_config_forward_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
3319 {
3320         int id = -1;
3321         char *action = NULL;
3322         struct FORWARD_LIST_LIST *fl = NULL;
3323         struct cgi_args_t *a;
3324
3325         if (forward_list == NULL)
3326                 return;
3327
3328         pthread_rwlock_wrlock(&forward_list->lock);
3329
3330         for (a = args; a; a = a->next) {
3331                 if (!strcasecmp(a->name, "action"))
3332                         action = a->value;
3333                 if (!strcasecmp(a->name, "id"))
3334                         id = atoi(a->value);
3335         }
3336
3337         if (action == NULL)
3338                 goto finish;
3339
3340         if (!strcasecmp(action, "delete")) {
3341                 for (fl = forward_list->forward_list; fl; fl = fl->next) {
3342                         if (fl->id == id) {
3343                                 forward_list->forward_list = forward_list_delete(fl);
3344
3345                                 break;
3346                         }
3347                 }
3348         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
3349                 if (!strcasecmp(action, "add")) {
3350                         fl = forward_list_new(forward_list->forward_list);
3351                         if (forward_list->forward_list == NULL)
3352                                 forward_list->forward_list = fl;
3353                         fl->id = forward_list->id++;
3354                 } else {
3355                         for (fl = forward_list->forward_list; fl; fl = fl->next)
3356                                 if (fl->id == id)
3357                                         break;
3358
3359                         if (fl == NULL)
3360                                 goto finish;
3361                 }
3362
3363                 if (strcasecmp(action, "shift")) {
3364                         fl->which = 0;
3365
3366                         for (a = args; a; a = a->next) {
3367                                 if (!strcasecmp(a->name, "enabled")) {
3368                                         if (!strcasecmp(a->value, "no"))
3369                                                 fl->enabled = FALSE;
3370                                         else
3371                                                 fl->enabled = TRUE;
3372                                 } else if (!strcasecmp(a->name, "comment"))
3373                                         forward_list_insert(fl, a->value, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3374                                 else if (!strcasecmp(a->name, "host"))
3375                                         forward_list_insert(fl, NULL, a->value, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3376                                 else if (!strcasecmp(a->name, "file"))
3377                                         forward_list_insert(fl, NULL, NULL, a->value, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3378                                 else if (!strcasecmp(a->name, "proxy"))
3379                                         forward_list_insert(fl, NULL, NULL, NULL, a->value, NULL, NULL, NULL, NULL, NULL, NULL);
3380                                 else if (!strcasecmp(a->name, "port"))
3381                                         forward_list_insert(fl, NULL, NULL, NULL, NULL, a->value, NULL, NULL, NULL, NULL, NULL);
3382                                 else if (!strcasecmp(a->name, "type"))
3383                                         forward_list_insert(fl, NULL, NULL, NULL, NULL, NULL, a->value, NULL, NULL, NULL, NULL);
3384                                 else if (!strcasecmp(a->name, "username"))
3385                                         forward_list_insert(fl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, a->value, NULL, NULL);
3386                                 else if (!strcasecmp(a->name, "password"))
3387                                         forward_list_insert(fl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, a->value, NULL);
3388                                 else if (!strcasecmp(a->name, "domain"))
3389                                         forward_list_insert(fl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, a->value);
3390                                 else if (!strcasecmp(a->name, "HTTP"))
3391                                         fl->which |= FORWARD_HTTP;
3392                                 else if (!strcasecmp(a->name, "CONNECT"))
3393                                         fl->which |= FORWARD_CONNECT;
3394                         }
3395                 } else {
3396                         for (a = args; a; a = a->next) {
3397                                 if (!strcasecmp(a->name, "direction")) {
3398                                         if (!strcasecmp(a->value, "up")) {
3399                                                 SHIFTNODE(struct FORWARD_LIST_LIST *, forward_list->forward_list, fl, UP);
3400                                         } else if (!strcasecmp(a->value, "down")) {
3401                                                 SHIFTNODE(struct FORWARD_LIST_LIST *, forward_list->forward_list, fl, DOWN);
3402                                         } else if (!strcasecmp(a->value, "top")) {
3403                                                 SETNODE(struct FORWARD_LIST_LIST *, forward_list->forward_list, fl, TOP);
3404                                         } else if (!strcasecmp(a->value, "bottom")) {
3405                                                 SETNODE(struct FORWARD_LIST_LIST *, forward_list->forward_list, fl, BOTTOM);
3406                                         }
3407                                 }
3408                         }
3409                 }
3410         }
3411
3412       finish:
3413         pthread_rwlock_unlock(&forward_list->lock);
3414 }
3415
3416 void interface_page_config_keywords(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
3417 {
3418         char *ptr;
3419         struct KEYWORD_LIST_LIST *kl = NULL;
3420
3421         if (keyword_list == NULL)
3422                 return;
3423
3424         pthread_rwlock_rdlock(&keyword_list->lock);
3425
3426         filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
3427         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"60%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
3428         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
3429         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"keywords\">\n");
3430         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"global\">\n");
3431         filebuf_addf(filebuf, "<tr><td>Template</td><td><input type=\"text\" name=\"template\" value=\"%s\" size=\"20\"></td></tr>\n", (keyword_list->template != NULL) ? keyword_list->template : "");
3432         filebuf_addf(filebuf, "<tr><td>Threshold</td><td><input type=\"text\" name=\"threshold\" value=\"%d\" size=\"20\"></td></tr>\n", keyword_list->threshold);
3433         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
3434         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><a href=\"config?section=keywords&amp;dialog=show\">Add</a></td></tr>\n");
3435         filebuf_addf(filebuf, "</form></table></td></tr> <tr><td><br></td></tr>\n");
3436
3437         for (kl = keyword_list->keyword_list; kl; kl = kl->next) {
3438                 filebuf_addf(filebuf, "<tr><td align=\"center\">\n");
3439                 filebuf_addf(filebuf, "<table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
3440
3441                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Enabled</td><td>%s</td></tr>\n", (kl->enabled == TRUE) ? "yes" : "no");
3442                 if (kl->comment != NULL) {
3443                         ptr = string_to_html(kl->comment, TRUE);
3444                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
3445                         xfree(ptr);
3446                 }
3447                 if (kl->host != NULL) {
3448                         ptr = string_to_html(kl->host, TRUE);
3449                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Host</td><td>%s</td></tr>\n", ptr);
3450                         xfree(ptr);
3451                 }
3452                 if (kl->file != NULL) {
3453                         ptr = string_to_html(kl->file, TRUE);
3454                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">File</td><td>%s</td></tr>\n", ptr);
3455                         xfree(ptr);
3456                 }
3457                 if (kl->mime != NULL) {
3458                         ptr = string_to_html(kl->mime, TRUE);
3459                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Mimetype</td><td>%s</td></tr>\n", ptr);
3460                         xfree(ptr);
3461                 }
3462                 if (kl->keyword != NULL) {
3463                         ptr = string_to_html(kl->keyword, TRUE);
3464                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Keyword</td><td>%s</td></tr>\n", ptr);
3465                         xfree(ptr);
3466                 }
3467                 filebuf_addf(filebuf, "<tr><td width=\"10%%\">Score</td><td>%d</td></tr>\n", kl->score);
3468
3469                 filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
3470                 filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"config?section=keywords&amp;dialog=show&amp;id=%d\">Edit</a> <a href=\"config?section=keywords&amp;action=delete&amp;id=%d\">Delete</a></td>\n", kl->id, kl->id);
3471                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=keywords&amp;action=shift&amp;id=%d&amp;direction=up\">Up</a> <a href=\"config?section=keywords&amp;action=shift&amp;id=%d&amp;direction=down\">Down</a></td>\n", kl->id, kl->id);
3472                 filebuf_addf(filebuf, "<td align=\"center\"><a href=\"config?section=keywords&amp;action=shift&amp;id=%d&amp;direction=top\">Top</a> <a href=\"config?section=keywords&amp;action=shift&amp;id=%d&amp;direction=bottom\">Bottom</a></td></tr>\n", kl->id, kl->id);
3473                 filebuf_addf(filebuf, "</table></td></tr>\n");
3474
3475                 filebuf_addf(filebuf, "</table></td></tr> <tr><td><br></td></tr>\n");
3476         }
3477
3478         filebuf_addf(filebuf, "</table>\n");
3479
3480         pthread_rwlock_unlock(&keyword_list->lock);
3481 }
3482
3483 void interface_page_config_keywords_dialog(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
3484 {
3485         int id = -1;
3486         char *ptr = NULL;
3487         struct KEYWORD_LIST_LIST *kl = NULL;
3488         struct cgi_args_t *a = args;
3489
3490         if (keyword_list == NULL)
3491                 return;
3492
3493         pthread_rwlock_rdlock(&keyword_list->lock);
3494
3495         for (; a; a = a->next) {
3496                 if (!strcasecmp(a->name, "id"))
3497                         id = atoi(a->value);
3498         }
3499
3500         if (id != -1)
3501                 for (kl = keyword_list->keyword_list; kl && kl->id != id; kl = kl->next);
3502
3503         filebuf_addf(filebuf, "<tr><td align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
3504         filebuf_addf(filebuf, "<form action=\"config\" method=\"POST\">\n");
3505
3506         filebuf_addf(filebuf, "<input type=\"hidden\" name=\"section\" value=\"keywords\">\n");
3507
3508         if (id != -1) {
3509                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"edit\">\n");
3510                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"id\" value=\"%d\">\n", id);
3511         } else
3512                 filebuf_addf(filebuf, "<input type=\"hidden\" name=\"action\" value=\"add\">\n");
3513
3514         filebuf_addf(filebuf, "<tr><td>Enabled</td><td align=\"center\">");
3515         filebuf_addf(filebuf, "Yes: <input type=\"radio\" name=\"enabled\" value=\"yes\" %s>   ", (kl == NULL || kl->enabled == TRUE) ? "checked" : "");
3516         filebuf_addf(filebuf, "No: <input type=\"radio\" name=\"enabled\" value=\"no\" %s>   ", (kl != NULL && kl->enabled == FALSE) ? "checked" : "");
3517         filebuf_addf(filebuf, "</td></tr>\n");
3518
3519         if (kl != NULL && kl->comment != NULL)
3520                 ptr = string_to_html(kl->comment, TRUE);
3521         filebuf_addf(filebuf, "<tr><td>Comment</td><td><input type=\"text\" name=\"comment\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3522         FREE_AND_NULL(ptr);
3523
3524         if (kl != NULL && kl->host != NULL)
3525                 ptr = string_to_html(kl->host, TRUE);
3526         filebuf_addf(filebuf, "<tr><td>Host</td><td><input type=\"text\" name=\"host\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3527         FREE_AND_NULL(ptr);
3528
3529         if (kl != NULL && kl->file != NULL)
3530                 ptr = string_to_html(kl->file, TRUE);
3531         filebuf_addf(filebuf, "<tr><td>File</td><td><input type=\"text\" name=\"file\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3532         FREE_AND_NULL(ptr);
3533
3534         if (kl != NULL && kl->mime != NULL)
3535                 ptr = string_to_html(kl->mime, TRUE);
3536         filebuf_addf(filebuf, "<tr><td>Mimetype</td><td><input type=\"text\" name=\"mime\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3537         FREE_AND_NULL(ptr);
3538
3539         if (kl != NULL && kl->keyword != NULL)
3540                 ptr = string_to_html(kl->keyword, TRUE);
3541         filebuf_addf(filebuf, "<tr><td>Keyword</td><td><input type=\"text\" name=\"keyword\" value=\"%s\" size=\"80\"></td></tr>\n", (ptr != NULL) ? ptr : "");
3542         FREE_AND_NULL(ptr);
3543
3544         filebuf_addf(filebuf, "<tr><td>Score</td><td><input type=\"text\" name=\"score\" value=\"%d\" size=\"20\"></td></tr>\n", (kl != NULL) ? kl->score : 0);
3545
3546         filebuf_addf(filebuf, "<tr><td colspan=\"2\"><br></td></tr>\n");
3547         filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Submit\"></td></tr>\n");
3548
3549         filebuf_addf(filebuf, "</table></td></tr>\n");
3550
3551         pthread_rwlock_unlock(&keyword_list->lock);
3552 }
3553
3554
3555 void interface_page_config_keywords_action(FILEBUF * filebuf, struct cgi_args_t *args, CONNECTION * connection)
3556 {
3557         int id = -1;
3558         char *action = NULL;
3559         struct KEYWORD_LIST_LIST *kl = NULL;
3560         struct cgi_args_t *a;
3561
3562         if (keyword_list == NULL)
3563                 return;
3564
3565         pthread_rwlock_wrlock(&keyword_list->lock);
3566
3567         for (a = args; a; a = a->next) {
3568                 if (!strcasecmp(a->name, "action"))
3569                         action = a->value;
3570                 if (!strcasecmp(a->name, "id"))
3571                         id = atoi(a->value);
3572         }
3573
3574         if (action == NULL) goto finish;
3575
3576         if (!strcasecmp(action, "global")) {
3577                 for (a = args; a; a = a->next) {
3578                         if (!strcasecmp(a->name, "template")) {
3579                                 FREE_AND_NULL(keyword_list->template);
3580                                 if (strcmp(a->value, ""))
3581                                         keyword_list->template = xstrdup(a->value);
3582                         } else if (!strcasecmp(a->name, "threshold"))
3583                                 keyword_list->threshold = atoi(a->value);
3584                 }
3585         }
3586
3587         if (!strcasecmp(action, "delete")) {
3588                 for (kl = keyword_list->keyword_list; kl; kl = kl->next) {
3589                         if (kl->id == id) {
3590                                 keyword_list->keyword_list = keyword_list_delete(kl);
3591
3592                                 break;
3593                         }
3594                 }
3595         } else if (!strcasecmp(action, "add") || !strcasecmp(action, "edit") || !strcasecmp(action, "shift")) {
3596                 if (!strcasecmp(action, "add")) {
3597                         kl = keyword_list_new(keyword_list->keyword_list);
3598                         if (keyword_list->keyword_list == NULL)
3599                                 keyword_list->keyword_list = kl;
3600                         kl->id = keyword_list->id++;
3601                 } else {
3602                         for (kl = keyword_list->keyword_list; kl; kl = kl->next)
3603                                 if (kl->id == id)
3604                                         break;
3605
3606                         if (kl == NULL)
3607                                 goto finish;
3608                 }
3609
3610                 if (strcasecmp(action, "shift")) {
3611                         for (a = args; a; a = a->next) {
3612                                 if (!strcasecmp(a->name, "enabled")) {
3613                                         if (!strcasecmp(a->value, "no"))
3614                                                 kl->enabled = FALSE;
3615                                         else
3616                                                 kl->enabled = TRUE;
3617                                 } else if (!strcasecmp(a->name, "comment"))
3618                                         keyword_list_insert(kl, a->value, NULL, NULL, NULL, NULL, NULL);
3619                                 else if (!strcasecmp(a->name, "host"))
3620                                         keyword_list_insert(kl, NULL, a->value, NULL, NULL, NULL, NULL);
3621                                 else if (!strcasecmp(a->name, "file"))
3622                                         keyword_list_insert(kl, NULL, NULL, a->value, NULL, NULL, NULL);
3623                                 else if (!strcasecmp(a->name, "mime"))
3624                                         keyword_list_insert(kl, NULL, NULL, NULL, a->value, NULL, NULL);
3625                                 else if (!strcasecmp(a->name, "keyword"))
3626                                         keyword_list_insert(kl, NULL, NULL, NULL, NULL, a->value, NULL);
3627                                 else if (!strcasecmp(a->name, "score"))
3628                                         keyword_list_insert(kl, NULL, NULL, NULL, NULL, NULL, a->value);
3629                         }
3630                 } else {
3631                         for (a = args; a; a = a->next) {
3632                                 if (!strcasecmp(a->name, "direction")) {
3633                                         if (!strcasecmp(a->value, "up")) {
3634                                                 SHIFTNODE(struct KEYWORD_LIST_LIST *, keyword_list->keyword_list, kl, UP);
3635                                         } else if (!strcasecmp(a->value, "down")) {
3636                                                 SHIFTNODE(struct KEYWORD_LIST_LIST *, keyword_list->keyword_list, kl, DOWN);
3637                                         } else if (!strcasecmp(a->value, "top")) {
3638                                                 SETNODE(struct KEYWORD_LIST_LIST *, keyword_list->keyword_list, kl, TOP);
3639                                         } else if (!strcasecmp(a->value, "bottom")) {
3640                                                 SETNODE(struct KEYWORD_LIST_LIST *, keyword_list->keyword_list, kl, BOTTOM);
3641                                         }
3642                                 }
3643                         }
3644                 }
3645         }
3646
3647       finish:
3648         pthread_rwlock_unlock(&keyword_list->lock);
3649 }
3650
3651 void filter_check_show(CONNECTION * connection)
3652 {
3653         char *ptr;
3654         struct FILTER_LIST_LIST *fl;
3655         FILEBUF *filebuf;
3656         HEADER *header;
3657
3658         filebuf = filebuf_new();
3659
3660         fl = filter_check(filter_list, connection);
3661
3662         filebuf_addf(filebuf, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
3663         filebuf_addf(filebuf, "<html><head><title>URL filter matche for %s%s</title></head>", connection->header->host, connection->header->file);
3664         filebuf_addf(filebuf, "<body text=\"%s\" bgcolor=\"%s\" link=\"%s\" vlink=\"%s\">\n", INTERFACE_TEXT, INTERFACE_BG, INTERFACE_LINK, INTERFACE_VLINK);
3665         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%%\"><tr><td align=\"center\">\n");
3666         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
3667         filebuf_addf(filebuf, "<tr><th align=\"center\" colspan=\"2\">URL filter match for %s%s</th></tr>\n", connection->header->host, connection->header->file);
3668         if (fl == NULL)
3669                 filebuf_addf(filebuf, "<tr><td align=\"center\" colspan=\"2\">None</td></tr>\n");
3670         else {
3671                 if (fl->comment != NULL) {
3672                         ptr = string_to_html(fl->comment, TRUE);
3673                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
3674                         xfree(ptr);
3675                 }
3676                 if (fl->host != NULL) {
3677                         ptr = string_to_html(fl->host, TRUE);
3678                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Host</td><td>%s</td></tr>\n", ptr);
3679                         xfree(ptr);
3680                 }
3681                 if (fl->file != NULL) {
3682                         ptr = string_to_html(fl->file, TRUE);
3683                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">File</td><td>%s</td></tr>\n", ptr);
3684                         xfree(ptr);
3685                 }
3686
3687                 if (fl->template != NULL)
3688                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Template</td><td>%s</td></tr>\n", fl->template);
3689
3690                 filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
3691                 filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"http://%s/config?section=filter&amp;dialog=show&amp;list=deny&amp;id=%d\">Edit</a> <a href=\"http://%s/config?section=filter&amp;action=delete&amp;list=deny&amp;id=%d\">Delete</a></td>\n", INTERFACEURL, fl->id, INTERFACEURL, fl->id);
3692         }
3693
3694         filebuf_addf(filebuf, "</table></td></tr></table></body></html>\n");
3695
3696         header = header_new();;
3697         header->type = HTTP_RESP;
3698         header->code = 200;
3699         header->content_type = xstrdup("text/html");
3700         header->content_length = filebuf->size;
3701
3702         header_send(header, connection, CLIENT, HEADER_RESP);
3703         net_filebuf_send(filebuf, connection, CLIENT);
3704
3705         http_header_free(header);
3706         filebuf_free(filebuf);
3707
3708         pthread_rwlock_unlock(&filter_list->lock);
3709
3710         return;
3711 }
3712
3713 void mime_check_show(CONNECTION * connection)
3714 {
3715         char *ptr;
3716         struct MIME_LIST_LIST *ml;
3717         FILEBUF *filebuf;
3718         HEADER *header;
3719
3720         filebuf = filebuf_new();
3721
3722         ml = mime_check(mime_list, connection);
3723
3724         filebuf_addf(filebuf, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
3725         filebuf_addf(filebuf, "<html><head><title>MIME filter match for %s%s</title></head>", connection->header->host, connection->header->file);
3726         filebuf_addf(filebuf, "<body text=\"%s\" bgcolor=\"%s\" link=\"%s\" vlink=\"%s\">\n", INTERFACE_TEXT, INTERFACE_BG, INTERFACE_LINK, INTERFACE_VLINK);
3727         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%%\"><tr><td align=\"center\">\n");
3728         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
3729         filebuf_addf(filebuf, "<tr><th align=\"center\" colspan=\"2\">MIME filter match for %s%s</th></tr>\n", connection->header->host, connection->header->file);
3730         if (ml == NULL)
3731                 filebuf_addf(filebuf, "<tr><td align=\"center\" colspan=\"2\">None</td></tr>\n");
3732         else {
3733                 if (ml->comment != NULL) {
3734                         ptr = string_to_html(ml->comment, TRUE);
3735                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Comment</td><td>%s</td></tr>\n", ptr);
3736                         xfree(ptr);
3737                 }
3738                 if (ml->host != NULL) {
3739                         ptr = string_to_html(ml->host, TRUE);
3740                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Host</td><td>%s</td></tr>\n", ptr);
3741                         xfree(ptr);
3742                 }
3743                 if (ml->file != NULL) {
3744                         ptr = string_to_html(ml->file, TRUE);
3745                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">File</td><td>%s</td></tr>\n", ptr);
3746                         xfree(ptr);
3747                 }
3748                 if (ml->mime != NULL) {
3749                         ptr = string_to_html(ml->mime, TRUE);
3750                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Mimetype</td><td>%s</td></tr>\n", ptr);
3751                         xfree(ptr);
3752                 }
3753                 if (ml->template != NULL)
3754                         filebuf_addf(filebuf, "<tr><td width=\"10%%\">Template</td><td>%s</td></tr>\n", ml->template);
3755
3756
3757                 filebuf_addf(filebuf, "<tr><td colspan=\"2\" align=\"center\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%%\">\n");
3758                 filebuf_addf(filebuf, "<tr><td align=\"center\"><a href=\"http://%s/config?section=mime&amp;dialog=show&amp;list=deny&amp;id=%d\">Edit</a> <a href=\"http://%s/config?section=mime&amp;action=delete&amp;list=deny&amp;id=%d\">Delete</a></td>\n", INTERFACEURL, ml->id, INTERFACEURL, ml->id);
3759         }
3760
3761         filebuf_addf(filebuf, "</table></td></tr></table></body></html>\n");
3762
3763         header = header_new();;
3764         header->type = HTTP_RESP;
3765         header->code = 200;
3766         header->content_type = xstrdup("text/html");
3767         header->content_length = filebuf->size;
3768
3769         header_send(header, connection, CLIENT, HEADER_RESP);
3770         net_filebuf_send(filebuf, connection, CLIENT);
3771
3772         http_header_free(header);
3773         filebuf_free(filebuf);
3774
3775         pthread_rwlock_unlock(&mime_list->lock);
3776
3777         return;
3778 }
3779
3780 void score_show(CONNECTION *connection, int score) {
3781         FILEBUF *filebuf;
3782         HEADER *header;
3783
3784         filebuf = filebuf_new();
3785
3786         filebuf_addf(filebuf, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
3787         filebuf_addf(filebuf, "<html><head><title>Keyword score for %s%s</title></head>", connection->header->host, connection->header->file);
3788         filebuf_addf(filebuf, "<body text=\"%s\" bgcolor=\"%s\" link=\"%s\" vlink=\"%s\">\n", INTERFACE_TEXT, INTERFACE_BG, INTERFACE_LINK, INTERFACE_VLINK);
3789         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%%\"><tr><td align=\"center\">\n");
3790         filebuf_addf(filebuf, "<table cellpadding=\"0\" cellspacing=\"0\" border=\"1\" width=\"80%%\" bgcolor=\"%s\">\n", INTERFACE_TABLEBG);
3791         filebuf_addf(filebuf, "<tr><th align=\"center\">Keyword score for %s%s</th></tr>\n", connection->header->host, connection->header->file);
3792         filebuf_addf(filebuf, "<tr><td align=\"center\">%d</td></tr>\n", score);
3793         filebuf_addf(filebuf, "</table></td></tr></table></body></html>\n");
3794
3795         header = header_new();;
3796         header->type = HTTP_RESP;
3797         header->code = 200;
3798         header->content_type = xstrdup("text/html");
3799         header->content_length = filebuf->size;
3800
3801         header_send(header, connection, CLIENT, HEADER_RESP);
3802         net_filebuf_send(filebuf, connection, CLIENT);
3803
3804         http_header_free(header);
3805         filebuf_free(filebuf);
3806 }