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