d58e96165415d42fdb5e3a1ce93a9fc64a08e1ff
[privoxy.git] / loadcfg.c
1 const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.1.1.1 2001/05/15 13:58:58 oes Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
5  *
6  * Purpose     :  Loads settings from the configuration file into
7  *                global variables.  This file contains both the 
8  *                routine to load the configuration and the global
9  *                variables it writes to.
10  *
11  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
12  *                IJBSWA team.  http://ijbswa.sourceforge.net
13  *
14  *                Based on the Internet Junkbuster originally written
15  *                by and Copyright (C) 1997 Anonymous Coders and 
16  *                Junkbusters Corporation.  http://www.junkbusters.com
17  *
18  *                This program is free software; you can redistribute it 
19  *                and/or modify it under the terms of the GNU General
20  *                Public License as published by the Free Software
21  *                Foundation; either version 2 of the License, or (at
22  *                your option) any later version.
23  *
24  *                This program is distributed in the hope that it will
25  *                be useful, but WITHOUT ANY WARRANTY; without even the
26  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
27  *                PARTICULAR PURPOSE.  See the GNU General Public
28  *                License for more details.
29  *
30  *                The GNU General Public License should be included with
31  *                this file.  If not, you can view it at
32  *                http://www.gnu.org/copyleft/gpl.html
33  *                or write to the Free Software Foundation, Inc., 59
34  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
35  *
36  * Revisions   :
37  *    $Log: loadcfg.c,v $
38  *    Revision 1.1.1.1  2001/05/15 13:58:58  oes
39  *    Initial import of version 2.9.3 source tree
40  *
41  *
42  *********************************************************************/
43 \f
44
45 #include "config.h"
46
47 #include <stdio.h>
48 #include <sys/types.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <signal.h>
52 #include <fcntl.h>
53 #include <errno.h>
54 #include <ctype.h>
55
56 #ifdef _WIN32
57
58 # include <sys/timeb.h>
59 # include <windows.h>
60 # include <io.h>
61 # include <process.h>
62 # ifdef TOGGLE
63 #  include <time.h>
64 # endif /* def TOGGLE */
65
66 # include "win32.h"
67 # ifndef _WIN_CONSOLE
68 #  include "w32log.h"
69 # endif /* ndef _WIN_CONSOLE */
70
71 #else /* ifndef _WIN32 */
72
73 # include <unistd.h>
74 # include <sys/time.h>
75 # include <sys/wait.h>
76 # include <sys/stat.h>
77 # include <signal.h>
78
79 #endif
80
81 #include "loadcfg.h"
82 #include "jcc.h"
83 #include "filters.h"
84 #include "loaders.h"
85 #include "showargs.h"
86 #include "parsers.h"
87 #include "killpopup.h"
88 #include "miscutil.h"
89 #include "errlog.h"
90 #include "jbsockets.h"
91 #include "gateway.h"
92
93 const char loadcfg_h_rcs[] = LOADCFG_H_VERSION;
94
95 /*
96  * Fix a problem with Solaris.  There should be no effect on other
97  * platforms.
98  * Solaris's isspace() is a macro which uses it's argument directly
99  * as an array index.  Therefore we need to make sure that high-bit
100  * characters generate +ve values, and ideally we also want to make
101  * the argument match the declared parameter type of "int".
102  */
103 #define ijb_isupper(__X) isupper((int)(unsigned char)(__X))
104 #define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
105
106 static const char VANILLA_WAFER[] =
107    "NOTICE=TO_WHOM_IT_MAY_CONCERN_"
108    "Do_not_send_me_any_copyrighted_information_other_than_the_"
109    "document_that_I_am_requesting_or_any_of_its_necessary_components._"
110    "In_particular_do_not_send_me_any_cookies_that_"
111    "are_subject_to_a_claim_of_copyright_by_anybody._"
112    "Take_notice_that_I_refuse_to_be_bound_by_any_license_condition_"
113    "(copyright_or_otherwise)_applying_to_any_cookie._";
114
115 #ifdef TOGGLE
116 /* by haroon - indicates if ijb is enabled */
117 int g_bToggleIJB        = 1;   /* JunkBusters is enabled by default. */
118 #endif
119
120 int debug               = 0;
121 int multi_threaded      = 1;
122
123 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
124 int tinygif             = 0;
125 const char *tinygifurl  = NULL;
126 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
127
128 const char *logfile     = NULL;
129
130 const char *configfile  = NULL;
131
132 const char *blockfile   = NULL;
133 const char *cookiefile  = NULL;
134 const char *forwardfile = NULL;
135
136 #ifdef ACL_FILES
137 const char *aclfile     = NULL;
138 #endif /* def ACL_FILES */
139
140 #ifdef USE_IMAGE_LIST
141 const char *imagefile   = NULL;
142 #endif /* def USE_IMAGE_LIST */
143
144 #ifdef KILLPOPUPS
145 const char *popupfile   = NULL;
146 int kill_all_popups     = 0;     /* Not recommended really ... */
147 #endif /* def KILLPOPUPS */
148
149 #ifdef PCRS
150 const char *re_filterfile = NULL;
151 int re_filter_all       = 0;
152 #endif /* def PCRS */
153
154 #ifdef TRUST_FILES
155 const char *trustfile   = NULL;
156 #endif /* def TRUST_FILES */
157
158 #ifdef JAR_FILES
159 const char *jarfile     = NULL;
160 FILE *jar = NULL;
161 #endif /* def JAR_FILES */
162
163 const char *referrer    = NULL;
164 const char *uagent      = NULL;
165 const char *from        = NULL;
166
167 #ifndef SPLIT_PROXY_ARGS
168 const char *suppress_message = NULL;
169 #endif /* ndef SPLIT_PROXY_ARGS */
170
171 int suppress_vanilla_wafer = 0;
172 int add_forwarded       = 0;
173
174 struct list wafer_list[1];
175 struct list xtra_list[1];
176
177 #ifdef TRUST_FILES
178 struct list trust_info[1];
179 struct url_spec *trust_list[64];
180 #endif /* def TRUST_FILES */
181
182 /*
183  * Port and IP to bind to.
184  * Defaults to HADDR_DEFAULT:HADDR_PORT == 127.0.0.1:8000
185  */
186 const char *haddr = NULL;
187 int         hport = 0;
188
189 #ifndef SPLIT_PROXY_ARGS
190 int suppress_blocklists = 0;  /* suppress listing sblock and simage */
191 #endif /* ndef SPLIT_PROXY_ARGS */
192
193 struct proxy_args proxy_args[1];
194
195 int configret = 0;
196 int config_changed = 0;
197
198
199 /*
200  * The load_config function is now going to call `init_proxy_args',
201  * so it will need argc and argv.  Since load_config will also be
202  * a signal handler, we need to have these globally available.
203  */
204 int Argc = 0;
205 const char **Argv = NULL;
206
207
208 /*
209  * This takes the "cryptic" hash of each keyword and aliases them to
210  * something a little more readable.  This also makes changing the
211  * hash values easier if they should change or the hash algorthm changes.
212  * Use the included "hash" program to find out what the hash will be
213  * for any string supplied on the command line.
214  */
215
216 #define hash_trustfile                 56494766ul
217 #define hash_trust_info_url            449869467ul
218 #define hash_debug                     78263ul
219 #define hash_tinygif                   2227702ul
220 #define hash_add_forwarded_header      3191044770ul
221 #define hash_single_threaded           4250084780ul
222 #define hash_suppress_vanilla_wafer    3121233547ul
223 #define hash_wafer                     89669ul
224 #define hash_add_header                237434619ul
225 #define hash_cookiefile                247469766ul
226 #define hash_logfile                   2114766ul
227 #define hash_blockfile                 48845391ul
228 #define hash_imagefile                 51447891ul
229 #define hash_jarfile                   2046641ul
230 #define hash_listen_address            1255650842ul
231 #define hash_forwardfile               1268669141ul
232 #define hash_aclfile                   1908516ul
233 #define hash_popupfile                 54623516ul
234 #define hash_kill_all_popups           2311539906ul
235 #define hash_re_filterfile             3877522444ul
236 #define hash_re_filter_all             3877521376ul
237 #define hash_user_agent                283326691ul
238 #define hash_referrer                  10883969ul
239 #define hash_referer                   2176719ul
240 #define hash_from                      16264ul
241 #define hash_hide_console              2048809870ul
242 #define hash_include_stats             2174146548ul
243 #define hash_suppress_blocklists       1948693308ul
244 #define hash_toggle                    447966ul
245
246 #define hash_activity_animation        1817904738ul
247 #define hash_log_messages              2291744899ul
248 #define hash_log_highlight_messages    4032101240ul
249 #define hash_log_buffer_size           2918070425ul
250 #define hash_log_max_lines             2868344173ul
251 #define hash_log_font_name             2866730124ul
252 #define hash_log_font_size             2866731014ul
253 #define hash_show_on_task_bar          215410365ul
254 #define hash_close_button_minimizes    3651284693ul
255
256
257 /*********************************************************************
258  *
259  * Function    :  load_config
260  *
261  * Description :  Load the config file and all parameters.
262  *
263  * Parameters  :
264  *          1  :  signum : this can be the signal SIGHUP or 0 (if from main).
265  *                In any case, we just ignore this and reload the config file.
266  *
267  * Returns     :  configret : 0 => Ok, everything else is an error.
268  *                Note: we use configret since a signal handler cannot
269  *                return a value, and this function does double duty.
270  *                Ie. Is is called from main and from signal( SIGHUP );
271  *
272  *********************************************************************/
273 void load_config( int signum )
274 {
275    char buf[BUFSIZ];
276    char *p, *q;
277    FILE *configfp = NULL;
278
279    configret = 0;
280    config_changed = 1;
281
282    log_error(LOG_LEVEL_INFO, "loading configuration file '%s':", configfile);
283
284    init_proxy_args(Argc, Argv);
285
286
287    /* (Waste of memory [not quite a "leak"] here.  The 
288     * last blockfile/popupfile/... etc will not be 
289     * unloaded until we load a new one.  If the 
290     * block/popup/... feature has been disabled in 
291     * the new config file, then we're wasting some 
292     * memory we could otherwise reclaim.
293     */
294
295    /* Disable all loaders. */
296    remove_all_loaders();
297
298    /*
299     * Reset to as close to startup state as we can.
300     * But leave changing the logfile until after we're done loading.
301     */
302
303    #ifdef JAR_FILES
304    if ( NULL != jar )
305    {
306       fclose( jar );
307       jar = NULL;
308    }
309    #endif /* def JAR_FILES */
310
311    debug             = 0;
312    multi_threaded    = 1;
313
314 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
315    tinygif           = 0;
316    freez((char *)tinygifurl);
317 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
318
319    suppress_vanilla_wafer = 0;
320    add_forwarded     = 0;
321    hport             = HADDR_PORT;
322
323 #ifdef _WIN_CONSOLE
324    hideConsole       = 0;
325 #endif /*def _WIN_CONSOLE*/
326
327 #ifdef PCRS
328    re_filter_all     = 0;
329 #endif /* def PCRS */
330
331 #ifdef KILLPOPUPS
332    kill_all_popups   = 0;
333 #endif /* def KILLPOPUPS */
334
335 #ifdef TOGGLE
336    g_bToggleIJB      = 1;
337 #endif
338
339 #ifdef STATISTICS
340    urls_read         = 0;
341    urls_rejected     = 0;
342 #endif /* def STATISTICS */
343
344 #ifndef SPLIT_PROXY_ARGS
345    suppress_blocklists = 0;
346 #endif /* ndef SPLIT_PROXY_ARGS */
347
348    freez((char *)from);
349    freez((char *)haddr);
350    freez((char *)uagent);
351    freez((char *)referrer);
352    freez((char *)logfile);
353
354
355    freez((char *)blockfile);
356    freez((char *)cookiefile);
357    freez((char *)forwardfile);
358
359 #ifdef ACL_FILES
360    freez((char *)aclfile);
361 #endif /* def ACL_FILES */
362
363 #ifdef USE_IMAGE_LIST
364    freez((char *)imagefile);
365 #endif /* def USE_IMAGE_LIST */
366
367 #ifdef JAR_FILES
368    freez((char *)jarfile);
369 #endif /* def JAR_FILES */
370
371 #ifdef KILLPOPUPS
372    freez((char *)popupfile);
373 #endif /* def KILLPOPUPS */
374
375 #ifndef SPLIT_PROXY_ARGS
376    freez((char *)suppress_message);
377 #endif /* ndef SPLIT_PROXY_ARGS */
378
379 #ifdef TRUST_FILES
380    freez((char *)trustfile);
381 #endif /* def TRUST_FILES */
382
383 #ifdef PCRS
384    freez((char *)re_filterfile);
385 #endif /* def PCRS */
386
387    if (NULL != configfile)
388    {
389       if ((configfp = fopen(configfile, "r")) == NULL)
390       {
391          log_error(LOG_LEVEL_ERROR, "can't open configuration file '%s':  %E",
392                  configfile);
393          configret = 1;
394          return;
395       }
396    }
397
398    if (NULL != configfp)
399    {
400       memset (buf, 'j', sizeof(buf));
401       while (read_config_line(buf, sizeof(buf), configfp, NULL) != NULL)
402       {
403          char cmd[BUFSIZ];
404          char arg[BUFSIZ];
405          char tmp[BUFSIZ];
406
407          strcpy(tmp, buf);
408
409          /* Copy command (i.e. up to space or tab) into cmd */
410          p = buf;
411          q = cmd;
412          while (*p && (*p != ' ') && (*p != '\t'))
413          {
414             *q++ = *p++;
415          }
416          *q = '\0';
417
418          /* Skip over the whitespace in buf */
419          while (*p && ((*p == ' ') || (*p == '\t')))
420          {
421             p++;
422          }
423
424          /* Copy the argument into arg */
425          strcpy(arg, p);
426
427          /* Should never happen, but check this anyway */
428          if (*cmd == '\0')
429          {
430             continue;
431          }
432
433          /* Make sure the command field is lower case */
434          for (p=cmd; *p; p++)
435          {
436             if (ijb_isupper(*p))
437             {
438                *p = ijb_tolower(*p);
439             }
440          }
441
442          /* Save the argument for show-proxy-args */
443          savearg(cmd, arg);
444
445
446          switch( hash_string( cmd ) )
447          {
448 #ifdef TRUST_FILES
449             case hash_trustfile :
450                freez((char *)trustfile);
451                trustfile = strdup(arg);
452                continue;
453
454             case hash_trust_info_url :
455                enlist(trust_info, arg);
456                continue;
457 #endif /* def TRUST_FILES */
458
459             case hash_debug :
460                debug |= atoi(arg);
461                continue;
462
463 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
464             case hash_tinygif :
465                freez((char *)tinygifurl);
466                tinygif = atoi(arg);
467                if(3 == tinygif)
468                {
469                   p = arg;
470                   while((*p >= '0') && (*p <= '9'))
471                   {
472                      p++;
473                   }
474                   while((*p == ' ') || (*p == '\t'))
475                   {
476                      p++;
477                   }
478                   if (*p)
479                   {
480                      q = malloc(strlen(p) + 5);
481                      if (q)
482                      {
483                         strcpy(q, p);
484                         strcat(q, "\r\n\r\n");
485                         tinygifurl = q;
486                      }
487                   }
488                }
489                if ((tinygif != 1) && 
490                    (tinygif != 2) && 
491                    ((tinygif != 3) || (tinygifurl==NULL)) )
492                {
493                   log_error(LOG_LEVEL_ERROR, "tinygif setting invalid.");
494                }
495                continue;
496 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
497
498             case hash_add_forwarded_header :
499                add_forwarded = 1;
500                continue;
501
502             case hash_single_threaded :
503                multi_threaded = 0;
504                continue;
505
506             case hash_suppress_vanilla_wafer :
507                suppress_vanilla_wafer = 1;
508                continue;
509
510             case hash_wafer :
511                enlist(wafer_list, arg);
512                continue;
513
514             case hash_add_header :
515                enlist(xtra_list, arg);
516                continue;
517
518             case hash_cookiefile :
519                freez((char *)cookiefile);
520                cookiefile = strdup(arg);
521                continue;
522
523             case hash_logfile :
524                freez((char *)logfile);
525                logfile = strdup(arg);
526                continue;
527
528             case hash_blockfile :
529                freez((char *)blockfile);
530                blockfile = strdup(arg);
531                continue;
532
533 #ifdef USE_IMAGE_LIST
534             case hash_imagefile :
535                freez((char *)imagefile);
536                imagefile = strdup(arg);
537                continue;
538 #endif /* def USE_IMAGE_LIST */
539
540 #ifdef JAR_FILES
541             case hash_jarfile :
542                freez((char *)jarfile);
543                jarfile = strdup(arg);
544                continue;
545 #endif /* def JAR_FILES */
546
547             case hash_listen_address :
548                freez((char *)haddr);
549                haddr = strdup(arg);
550                continue;
551
552             case hash_forwardfile :
553                freez((char *)forwardfile);
554                forwardfile = strdup(arg);
555                continue;
556
557 #ifdef ACL_FILES
558             case hash_aclfile :
559                freez((char *)aclfile);
560                aclfile = strdup(arg);
561                continue;
562 #endif /* def ACL_FILES */
563
564 #ifdef KILLPOPUPS
565             case hash_popupfile :
566                freez((char *)popupfile);
567                popupfile = strdup(arg);
568                continue;
569
570             case hash_kill_all_popups :
571                kill_all_popups = 1;
572                continue;
573 #endif /* def KILLPOPUPS */
574
575 #ifdef PCRS
576             case hash_re_filterfile :
577                freez((char *)re_filterfile);
578                re_filterfile = strdup(arg);
579                continue;
580
581             case hash_re_filter_all :
582                re_filter_all = 1;
583                log_error(LOG_LEVEL_REF, "re_filter policy is %s.",
584                           re_filter_all ? "RADICAL" : "SEMI-SMART");
585                continue;
586 #endif /* def PCRS */
587
588             case hash_user_agent :
589                freez((char *)uagent);
590                uagent = strdup(arg);
591                continue;
592
593                /*
594                 * Offer choice of correct spelling according to dictionary,
595                 * or the misspelling used in the HTTP spec.
596                 */
597             case hash_referrer :
598             case hash_referer :
599                freez((char *)referrer);
600                referrer = strdup(arg);
601                continue;
602
603             case hash_from :
604                freez((char *)from);
605                from = strdup(arg);
606                continue;
607
608 #ifdef _WIN_CONSOLE
609             case hash_hide_console :
610                hideConsole = 1;
611                continue;
612 #endif /*def _WIN_CONSOLE*/
613
614 #ifndef SPLIT_PROXY_ARGS
615             case hash_suppress_blocklists :
616                if (arg[0] != '\0')
617                {
618                   suppress_message = strdup(arg);
619                }
620                else
621                {
622                   /* There will be NO reference in proxy-args. */
623                   suppress_message = NULL;
624                }
625
626                suppress_blocklists = 1;
627                continue;
628 #endif /* ndef SPLIT_PROXY_ARGS */
629
630 #ifdef TOGGLE
631             case hash_toggle :
632                g_bToggleIJB = atoi(arg);
633                continue;
634 #endif /* def TOGGLE */
635
636 #if defined(_WIN32) && ! defined(_WIN_CONSOLE)
637             case hash_activity_animation :
638                g_bShowActivityAnimation = atoi(arg);
639                continue;
640
641             case hash_log_messages :
642                g_bLogMessages = atoi(arg);
643                continue;
644
645             case hash_log_highlight_messages :
646                g_bHighlightMessages = atoi(arg);
647                continue;
648
649             case hash_log_buffer_size :
650                g_bLimitBufferSize = atoi(arg);
651                continue;
652
653             case hash_log_max_lines :
654                g_nMaxBufferLines = atoi(arg);
655                continue;
656
657             case hash_log_font_name :
658                strcpy( g_szFontFaceName, arg );
659                continue;
660
661             case hash_log_font_size :
662                g_nFontSize = atoi(arg);
663                continue;
664
665             case hash_show_on_task_bar :
666                g_bShowOnTaskBar = atoi(arg);
667                continue;
668
669             case hash_close_button_minimizes :
670                g_bCloseHidesWindow = atoi(arg);
671                continue;
672 #endif /* defined(_WIN32) && ! defined(_WIN_CONSOLE) */
673
674             /* Warnings about unsupported features */
675
676 #ifndef TRUST_FILES
677             case hash_trustfile :
678             case hash_trust_info_url :
679 #endif /* ndef TRUST_FILES */
680 #ifndef USE_IMAGE_LIST
681             case hash_imagefile :
682 #endif /* ndef USE_IMAGE_LIST */
683 #ifndef PCRS
684             case hash_re_filterfile :
685             case hash_re_filter_all :
686 #endif /* ndef PCRS */
687 #ifndef TOGGLE
688             case hash_toggle :
689 #endif /* ndef TOGGLE */
690 #if defined(_WIN_CONSOLE) || ! defined(_WIN32)
691             case hash_activity_animation :
692             case hash_log_messages :
693             case hash_log_highlight_messages :
694             case hash_log_buffer_size :
695             case hash_log_max_lines :
696             case hash_log_font_name :
697             case hash_log_font_size :
698             case hash_show_on_task_bar :
699             case hash_close_button_minimizes :
700 #endif /* defined(_WIN_CONSOLE) || ! defined(_WIN32) */
701 #ifndef _WIN_CONSOLE
702             case hash_hide_console :
703 #endif /* ndef _WIN_CONSOLE */
704 #if !defined(DETECT_MSIE_IMAGES) && !defined(USE_IMAGE_LIST)
705             case hash_tinygif :
706 #endif /* !defined(DETECT_MSIE_IMAGES) && !defined(USE_IMAGE_LIST) */
707 #ifndef KILLPOPUPS
708             case hash_popupfile :
709             case hash_kill_all_popups :
710 #endif /* ndef KILLPOPUPS */
711 #ifndef JAR_FILES
712             case hash_jarfile :
713 #endif /* ndef JAR_FILES */
714 #ifndef ACL_FILES
715             case hash_aclfile :
716 #endif /* ndef ACL_FILES */
717
718 #ifdef SPLIT_PROXY_ARGS
719             case hash_suppress_blocklists :
720 #endif /* def SPLIT_PROXY_ARGS */
721                log_error(LOG_LEVEL_INFO, "Unsupported directive \"%s\" ignored.", cmd);
722                continue;
723
724             default :
725                log_error(LOG_LEVEL_ERROR, "Unrecognized directive (%lulu) in "
726                      "configuration file: \"%s\"", hash_string( cmd ), buf);
727                p = malloc( BUFSIZ );
728                if (p != NULL)
729                {
730                   sprintf( p, "<br>\nWARNING: unrecognized directive : %s<br><br>\n", buf );
731                   proxy_args->invocation = strsav( proxy_args->invocation, p );
732                   freez( p );
733                }
734                /*
735                 * I decided that I liked this better as a warning than an
736                 * error.
737                 */
738
739                /*
740                 * configret = 1;
741                 * return;
742                 */
743                continue;
744          }
745       }
746       fclose(configfp);
747    }
748
749    init_error_log(Argv[0], logfile, debug);
750
751    if (cookiefile)
752    {
753       add_loader(load_cookiefile);
754    }
755
756    if (blockfile)
757    {
758       add_loader(load_blockfile);
759    }
760
761 #ifdef USE_IMAGE_LIST
762    if (imagefile)
763    {
764       add_loader(load_imagefile);
765    }
766 #endif /* def USE_IMAGE_LIST */
767
768 #ifdef TRUST_FILES
769    if (trustfile)
770    {
771       add_loader(load_trustfile);
772    }
773 #endif /* def TRUST_FILES */
774
775    if (forwardfile)
776    {
777       add_loader(load_forwardfile);
778    }
779
780 #ifdef ACL_FILES
781    if (aclfile)
782    {
783       add_loader(load_aclfile);
784    }
785 #endif /* def ACL_FILES */
786
787 #ifdef KILLPOPUPS
788    if (popupfile)
789    {
790       add_loader(load_popupfile);
791    }
792 #endif /* def KILLPOPUPS */
793
794 #ifdef PCRS
795    if (re_filterfile)
796    {
797       add_loader(load_re_filterfile);
798    }
799 #endif /* def PCRS */
800
801 #ifdef JAR_FILES
802    if ( NULL != jarfile )
803    {
804       if ( NULL == (jar = fopen(jarfile, "a")) )
805       {
806          log_error(LOG_LEVEL_ERROR, "can't open jarfile '%s': %E", jarfile);
807          configret = 1;
808          return;
809       }
810       setbuf(jar, NULL);
811    }
812 #endif /* def JAR_FILES */
813
814    if ( NULL == haddr )
815    {
816       haddr = strdup( HADDR_DEFAULT );
817    }
818
819    if ( NULL != haddr )
820    {
821       if ((p = strchr(haddr, ':')))
822       {
823          *p++ = '\0';
824          if (*p)
825          {
826             hport = atoi(p);
827          }
828       }
829
830       if (hport <= 0)
831       {
832          *--p = ':';
833          log_error(LOG_LEVEL_ERROR, "invalid bind port spec %s", haddr);
834          configret = 1;
835          return;
836       }
837       if (*haddr == '\0')
838       {
839          haddr = NULL;
840       }
841    }
842
843    if (run_loader(NULL))
844    {
845       configret = 1;
846       return;
847    }
848
849 #ifdef JAR_FILES
850    /*
851     * If we're logging cookies in a cookie jar, and the user has not
852     * supplied any wafers, and the user has not told us to suppress the
853     * vanilla wafer, then send the vanilla wafer.
854     */
855    if ((jarfile != NULL)
856        && (wafer_list->next == NULL)
857        && (suppress_vanilla_wafer == 0))
858    {
859       enlist(wafer_list, VANILLA_WAFER);
860    }
861 #endif /* def JAR_FILES */
862
863    end_proxy_args();
864
865 }
866
867
868 /*
869   Local Variables:
870   tab-width: 3
871   end:
872 */