1 const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.19 2001/07/15 17:45:16 jongfoster Exp $";
2 /*********************************************************************
4 * File : $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
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.
11 * Copyright : Written by and Copyright (C) 2001 the SourceForge
12 * IJBSWA team. http://ijbswa.sourceforge.net
14 * Based on the Internet Junkbuster originally written
15 * by and Copyright (C) 1997 Anonymous Coders and
16 * Junkbusters Corporation. http://www.junkbusters.com
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.
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.
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.
38 * Revision 1.19 2001/07/15 17:45:16 jongfoster
39 * Removing some unused #includes
41 * Revision 1.18 2001/07/13 14:01:14 oes
42 * - Removed all #ifdef PCRS
43 * - Removed vim-settings
45 * Revision 1.17 2001/06/29 13:31:03 oes
47 * - Fixed (actionsfile) and sorted hashes
48 * - Introduced admin_address and proxy-info-url
49 * as config parameters
50 * - Renamed config->proxy_args_invocation (which didn't have
51 * the invocation but the options!) to config->proxy_args
53 * - Removed logentry from cancelled commit
55 * Revision 1.16 2001/06/09 10:55:28 jongfoster
56 * Changing BUFSIZ ==> BUFFER_SIZE
58 * Revision 1.15 2001/06/07 23:13:40 jongfoster
59 * Merging ACL and forward files into config file.
60 * Cosmetic: Sorting config file options alphabetically.
61 * Cosmetic: Adding brief syntax comments to config file options.
63 * Revision 1.14 2001/06/07 14:46:25 joergs
64 * Missing make_path() added for re_filterfile.
66 * Revision 1.13 2001/06/05 22:33:54 jongfoster
68 * Fixed minor memory leak.
69 * Also now uses make_path to prepend the pathnames.
71 * Revision 1.12 2001/06/05 20:04:09 jongfoster
72 * Now uses _snprintf() in place of snprintf() under Win32.
74 * Revision 1.11 2001/06/04 18:31:58 swa
75 * files are now prefixed with either `confdir' or `logdir'.
76 * `make redhat-dist' replaces both entries confdir and logdir
79 * Revision 1.10 2001/06/03 19:11:54 oes
80 * introduced confdir option
82 * Revision 1.9 2001/06/01 20:06:24 jongfoster
83 * Removed support for "tinygif" option - moved to actions file.
85 * Revision 1.8 2001/05/31 21:27:13 jongfoster
86 * Removed many options from the config file and into the
87 * "actions" file: add_forwarded, suppress_vanilla_wafer,
88 * wafer, add_header, user_agent, referer, from
89 * Also globally replaced "permission" with "action".
91 * Revision 1.7 2001/05/29 09:50:24 jongfoster
92 * Unified blocklist/imagelist/permissionslist.
93 * File format is still under discussion, but the internal changes
96 * Also modified interceptor behaviour:
97 * - We now intercept all URLs beginning with one of the following
98 * prefixes (and *only* these prefixes):
100 * * http://ijbswa.sf.net/config/
101 * * http://ijbswa.sourceforge.net/config/
102 * - New interceptors "home page" - go to http://i.j.b/ to see it.
103 * - Internal changes so that intercepted and fast redirect pages
104 * are not replaced with an image.
105 * - Interceptors now have the option to send a binary page direct
106 * to the client. (i.e. ijb-send-banner uses this)
107 * - Implemented show-url-info interceptor. (Which is why I needed
108 * the above interceptors changes - a typical URL is
109 * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
110 * The previous mechanism would not have intercepted that, and
111 * if it had been intercepted then it then it would have replaced
114 * Revision 1.6 2001/05/26 00:28:36 jongfoster
115 * Automatic reloading of config file.
116 * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
117 * Most of the global variables have been moved to a new
118 * struct configuration_spec, accessed through csp->config->globalname
119 * Most of the globals remaining are used by the Win32 GUI.
121 * Revision 1.5 2001/05/25 22:34:30 jongfoster
124 * Revision 1.4 2001/05/22 18:46:04 oes
126 * - Enabled filtering banners by size rather than URL
127 * by adding patterns that replace all standard banner
128 * sizes with the "Junkbuster" gif to the re_filterfile
130 * - Enabled filtering WebBugs by providing a pattern
131 * which kills all 1x1 images
133 * - Added support for PCRE_UNGREEDY behaviour to pcrs,
134 * which is selected by the (nonstandard and therefore
135 * capital) letter 'U' in the option string.
136 * It causes the quantifiers to be ungreedy by default.
137 * Appending a ? turns back to greedy (!).
139 * - Added a new interceptor ijb-send-banner, which
140 * sends back the "Junkbuster" gif. Without imagelist or
141 * MSIE detection support, or if tinygif = 1, or the
142 * URL isn't recognized as an imageurl, a lame HTML
143 * explanation is sent instead.
145 * - Added new feature, which permits blocking remote
146 * script redirects and firing back a local redirect
148 * The feature is conditionally compiled, i.e. it
149 * can be disabled with --disable-fast-redirects,
150 * plus it must be activated by a "fast-redirects"
151 * line in the config file, has its own log level
152 * and of course wants to be displayed by show-proxy-args
153 * Note: Boy, all the #ifdefs in 1001 locations and
154 * all the fumbling with configure.in and acconfig.h
155 * were *way* more work than the feature itself :-(
157 * - Because a generic redirect template was needed for
158 * this, tinygif = 3 now uses the same.
160 * - Moved GIFs, and other static HTTP response templates
165 * - Removed some >400 CRs again (Jon, you really worked
168 * Revision 1.3 2001/05/20 01:21:20 jongfoster
169 * Version 2.9.4 checkin.
170 * - Merged popupfile and cookiefile, and added control over PCRS
171 * filtering, in new "permissionsfile".
172 * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
173 * file error you now get a message box (in the Win32 GUI) rather
174 * than the program exiting with no explanation.
175 * - Made killpopup use the PCRS MIME-type checking and HTTP-header
177 * - Removed tabs from "config"
178 * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
179 * - Bumped up version number.
181 * Revision 1.2 2001/05/17 23:01:01 oes
182 * - Cleaned CRLF's from the sources and related files
184 * Revision 1.1.1.1 2001/05/15 13:58:58 oes
185 * Initial import of version 2.9.3 source tree
188 *********************************************************************/
194 #include <sys/types.h>
204 # include <windows.h>
207 # ifndef _WIN_CONSOLE
209 # endif /* ndef _WIN_CONSOLE */
211 /* VC++ has "_snprintf", not "snprintf" */
212 #define snprintf _snprintf
214 #else /* ifndef _WIN32 */
217 # include <sys/time.h>
218 # include <sys/wait.h>
219 # include <sys/stat.h>
229 #include "showargs.h"
231 #include "killpopup.h"
232 #include "miscutil.h"
234 #include "jbsockets.h"
238 const char loadcfg_h_rcs[] = LOADCFG_H_VERSION;
241 * Fix a problem with Solaris. There should be no effect on other
243 * Solaris's isspace() is a macro which uses it's argument directly
244 * as an array index. Therefore we need to make sure that high-bit
245 * characters generate +ve values, and ideally we also want to make
246 * the argument match the declared parameter type of "int".
248 #define ijb_isupper(__X) isupper((int)(unsigned char)(__X))
249 #define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
251 #ifdef FEATURE_TOGGLE
252 /* by haroon - indicates if ijb is enabled */
253 int g_bToggleIJB = 1; /* JunkBusters is enabled by default. */
254 #endif /* def FEATURE_TOGGLE */
256 /* The filename of the configfile */
257 const char *configfile = NULL;
260 * CGI functions will later need access to the invocation args,
261 * so we will make argc and argv global.
264 const char **Argv = NULL;
266 static struct file_list *current_configfile = NULL;
270 * This takes the "cryptic" hash of each keyword and aliases them to
271 * something a little more readable. This also makes changing the
272 * hash values easier if they should change or the hash algorthm changes.
273 * Use the included "hash" program to find out what the hash will be
274 * for any string supplied on the command line. (Or just put it in the
275 * config file and read the number from the error message in the log).
277 * Please keep this list sorted alphabetically (but with the Windows
278 * console and GUI specific options last).
281 #define hash_actions_file 1196306641ul /* "actionsfile" */
282 #define hash_admin_address 4112573064ul /* "admin-address" */
283 #define hash_confdir 1978389ul /* "confdir" */
284 #define hash_debug 78263ul /* "debug" */
285 #define hash_deny_access 1227333715ul /* "deny-access" */
286 #define hash_forward 2029845ul /* "forward" */
287 #define hash_forward_socks4 3963965521ul /* "forward-socks4" */
288 #define hash_forward_socks4a 2639958518ul /* "forward-socks4a" */
289 #define hash_jarfile 2046641ul /* "jarfile" */
290 #define hash_listen_address 1255650842ul /* "listen-address" */
291 #define hash_logdir 422889ul /* "logdir" */
292 #define hash_logfile 2114766ul /* "logfile" */
293 #define hash_permit_access 3587953268ul /* "permit-access" */
294 #define hash_proxy_info_url 3903079059ul /* "proxy-info-url" */
295 #define hash_re_filterfile 3877522444ul /* "re_filterfile" */
296 #define hash_single_threaded 4250084780ul /* "single-threaded" */
297 #define hash_suppress_blocklists 1948693308ul /* "suppress-blocklists" */
298 #define hash_toggle 447966ul /* "toggle" */
299 #define hash_trust_info_url 430331967ul /* "trust-info-url" */
300 #define hash_trustfile 56494766ul /* "trustfile" */
302 #define hash_activity_animation 1817904738ul /* "activity-animation" */
303 #define hash_close_button_minimizes 3651284693ul /* "close-button-minimizes" */
304 #define hash_hide_console 2048809870ul /* "hide-console" */
305 #define hash_log_buffer_size 2918070425ul /* "log-buffer-size" */
306 #define hash_log_font_name 2866730124ul /* "log-font-name" */
307 #define hash_log_font_size 2866731014ul /* "log-font-size" */
308 #define hash_log_highlight_messages 4032101240ul /* "log-highlight-messages" */
309 #define hash_log_max_lines 2868344173ul /* "log-max-lines" */
310 #define hash_log_messages 2291744899ul /* "log-messages" */
311 #define hash_show_on_task_bar 215410365ul /* "show-on-task-bar" */
315 /*********************************************************************
317 * Function : unload_configfile
319 * Description : Free the config structure and all components.
322 * 1 : data: struct configuration_spec to unload
326 *********************************************************************/
327 void unload_configfile (void * data)
329 struct configuration_spec * config = (struct configuration_spec *)data;
330 struct forward_spec *cur_fwd = config->forward;
332 struct access_control_list *cur_acl = config->acl;
334 while (cur_acl != NULL)
336 struct access_control_list * next_acl = cur_acl->next;
341 #endif /* def FEATURE_ACL */
343 while (cur_fwd != NULL)
345 struct forward_spec * next_fwd = cur_fwd->next;
346 free_url(cur_fwd->url);
348 freez(cur_fwd->gateway_host);
349 freez(cur_fwd->forward_host);
353 config->forward = NULL;
355 #ifdef FEATURE_COOKIE_JAR
356 if ( NULL != config->jar )
358 fclose( config->jar );
361 #endif /* def FEATURE_COOKIE_JAR */
363 freez((char *)config->confdir);
364 freez((char *)config->logdir);
366 freez((char *)config->haddr);
367 freez((char *)config->logfile);
369 freez((char *)config->actions_file);
370 freez((char *)config->admin_address);
371 freez((char *)config->proxy_info_url);
372 freez((char *)config->proxy_args);
374 #ifdef FEATURE_COOKIE_JAR
375 freez((char *)config->jarfile);
376 #endif /* def FEATURE_COOKIE_JAR */
378 freez((char *)config->re_filterfile);
383 /*********************************************************************
385 * Function : load_config
387 * Description : Load the config file and all parameters.
390 * 1 : csp = Client state (the config member will be
391 * filled in by this function).
393 * Returns : 0 => Ok, everything else is an error.
395 *********************************************************************/
396 struct configuration_spec * load_config(void)
398 char buf[BUFFER_SIZE];
400 FILE *configfp = NULL;
401 struct configuration_spec * config = NULL;
402 struct client_state * fake_csp;
403 struct file_list *fs;
405 if (!check_file_changed(current_configfile, configfile, &fs))
407 /* No need to load */
408 return ((struct configuration_spec *)current_configfile->f);
412 log_error(LOG_LEVEL_FATAL, "can't check configuration file '%s': %E",
416 log_error(LOG_LEVEL_INFO, "loading configuration file '%s':", configfile);
418 #ifdef FEATURE_TOGGLE
420 #endif /* def FEATURE_TOGGLE */
422 fs->f = config = (struct configuration_spec *)zalloc(sizeof(*config));
428 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
429 /* Never get here - LOG_LEVEL_FATAL causes program exit */
433 * This is backwards from how it's usually done.
434 * Following the usual pattern, "fs" would be stored in a member
435 * variable in "csp", and then we'd access "config" from "fs->f",
436 * using a cast. However, "config" is used so often that a
437 * cast each time would be very ugly, and the extra indirection
438 * would waste CPU cycles. Therefore we store "config" in
439 * "csp->config", and "fs" in "csp->config->config_file_list".
441 config->config_file_list = fs;
447 config->multi_threaded = 1;
448 config->hport = HADDR_PORT;
450 if ((configfp = fopen(configfile, "r")) == NULL)
452 log_error(LOG_LEVEL_FATAL, "can't open configuration file '%s': %E",
454 /* Never get here - LOG_LEVEL_FATAL causes program exit */
457 while (read_config_line(buf, sizeof(buf), configfp, fs) != NULL)
459 char cmd[BUFFER_SIZE];
460 char arg[BUFFER_SIZE];
461 char tmp[BUFFER_SIZE];
463 struct access_control_list *cur_acl;
464 #endif /* def FEATURE_ACL */
465 struct forward_spec *cur_fwd;
471 /* Copy command (i.e. up to space or tab) into cmd */
474 while (*p && (*p != ' ') && (*p != '\t'))
480 /* Skip over the whitespace in buf */
481 while (*p && ((*p == ' ') || (*p == '\t')))
486 /* Copy the argument into arg */
489 /* Should never happen, but check this anyway */
495 /* Make sure the command field is lower case */
500 *p = ijb_tolower(*p);
504 /* Save the argument for show-proxy-args */
505 savearg(cmd, arg, config);
508 switch( hash_string( cmd ) )
510 /****************************************************************************
511 * actionsfile actions-file-name
512 * In confdir by default
513 ****************************************************************************/
514 case hash_actions_file :
515 freez((char *)config->actions_file);
516 config->actions_file = make_path(config->confdir, arg);
519 /****************************************************************************
520 * admin-address email-address
521 ****************************************************************************/
522 case hash_admin_address :
523 freez((char *)config->admin_address);
524 config->admin_address = strdup(arg);
527 /****************************************************************************
528 * confdir directory-name
529 ****************************************************************************/
531 freez((char *)config->confdir);
532 config->confdir = strdup(arg);
535 /****************************************************************************
537 * Specifies debug level, multiple values are ORed together.
538 ****************************************************************************/
540 config->debug |= atoi(arg);
543 /****************************************************************************
544 * deny-access source-ip[/significant-bits] [dest-ip[/significant-bits]]
545 ****************************************************************************/
547 case hash_deny_access:
548 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
550 if ((vec_count != 1) && (vec_count != 2))
552 log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
553 "deny-access directive in configuration file.");
554 config->proxy_args = strsav( config->proxy_args,
555 "<br>\nWARNING: Wrong number of parameters for "
556 "deny-access directive in configuration file.<br><br>\n");
560 /* allocate a new node */
561 cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
565 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
566 /* Never get here - LOG_LEVEL_FATAL causes program exit */
569 cur_acl->action = ACL_DENY;
571 if (acl_addr(vec[0], cur_acl->src) < 0)
573 log_error(LOG_LEVEL_ERROR, "Invalid source IP for deny-access "
574 "directive in configuration file: \"%s\"", vec[0]);
575 config->proxy_args = strsav( config->proxy_args,
576 "<br>\nWARNING: Invalid source IP for deny-access directive"
577 " in configuration file: \"");
578 config->proxy_args = strsav( config->proxy_args,
580 config->proxy_args = strsav( config->proxy_args,
587 if (acl_addr(vec[1], cur_acl->dst) < 0)
589 log_error(LOG_LEVEL_ERROR, "Invalid destination IP for deny-access "
590 "directive in configuration file: \"%s\"", vec[0]);
591 config->proxy_args = strsav( config->proxy_args,
592 "<br>\nWARNING: Invalid destination IP for deny-access directive"
593 " in configuration file: \"");
594 config->proxy_args = strsav( config->proxy_args,
596 config->proxy_args = strsav( config->proxy_args,
604 * Add it to the list. Note we reverse the list to get the
605 * behaviour the user expects. With both the ACL and
606 * actions file, the last match wins. However, the internal
607 * implementations are different: The actions file is stored
608 * in the same order as the file, and scanned completely.
609 * With the ACL, we reverse the order as we load it, then
610 * when we scan it we stop as soon as we get a match.
612 cur_acl->next = config->acl;
613 config->acl = cur_acl;
616 #endif /* def FEATURE_ACL */
618 /****************************************************************************
619 * forward url-pattern (.|http-proxy-host[:port])
620 ****************************************************************************/
622 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
626 log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for forward "
627 "directive in configuration file.");
628 config->proxy_args = strsav( config->proxy_args,
629 "<br>\nWARNING: Wrong number of parameters for "
630 "forward directive in configuration file.");
634 /* allocate a new node */
635 cur_fwd = zalloc(sizeof(*cur_fwd));
638 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
639 /* Never get here - LOG_LEVEL_FATAL causes program exit */
643 cur_fwd->type = SOCKS_NONE;
645 /* Save the URL pattern */
646 if (create_url_spec(cur_fwd->url, vec[0]))
648 log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward "
649 "directive in configuration file.");
650 config->proxy_args = strsav( config->proxy_args,
651 "<br>\nWARNING: Bad URL specifier for "
652 "forward directive in configuration file.");
656 /* Parse the parent HTTP proxy host:port */
659 if (strcmp(p, ".") != 0)
661 cur_fwd->forward_host = strdup(p);
663 if ((p = strchr(cur_fwd->forward_host, ':')))
666 cur_fwd->forward_port = atoi(p);
669 if (cur_fwd->forward_port <= 0)
671 cur_fwd->forward_port = 8000;
676 cur_fwd->next = config->forward;
677 config->forward = cur_fwd;
681 /****************************************************************************
682 * forward-socks4 url-pattern socks-proxy[:port] (.|http-proxy[:port])
683 ****************************************************************************/
684 case hash_forward_socks4:
685 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
689 log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
690 "forward-socks4 directive in configuration file.");
691 config->proxy_args = strsav( config->proxy_args,
692 "<br>\nWARNING: Wrong number of parameters for "
693 "forward-socks4 directive in configuration file.");
697 /* allocate a new node */
698 cur_fwd = zalloc(sizeof(*cur_fwd));
701 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
702 /* Never get here - LOG_LEVEL_FATAL causes program exit */
706 cur_fwd->type = SOCKS_4;
708 /* Save the URL pattern */
709 if (create_url_spec(cur_fwd->url, vec[0]))
711 log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward-socks4 "
712 "directive in configuration file.");
713 config->proxy_args = strsav( config->proxy_args,
714 "<br>\nWARNING: Bad URL specifier for "
715 "forward-socks4 directive in configuration file.");
719 /* Parse the SOCKS proxy host[:port] */
722 if (strcmp(p, ".") != 0)
724 cur_fwd->gateway_host = strdup(p);
726 if ((p = strchr(cur_fwd->gateway_host, ':')))
729 cur_fwd->gateway_port = atoi(p);
731 if (cur_fwd->gateway_port <= 0)
733 cur_fwd->gateway_port = 1080;
737 /* Parse the parent HTTP proxy host[:port] */
740 if (strcmp(p, ".") != 0)
742 cur_fwd->forward_host = strdup(p);
744 if ((p = strchr(cur_fwd->forward_host, ':')))
747 cur_fwd->forward_port = atoi(p);
750 if (cur_fwd->forward_port <= 0)
752 cur_fwd->forward_port = 8000;
757 cur_fwd->next = config->forward;
758 config->forward = cur_fwd;
762 /****************************************************************************
763 * forward-socks4a url-pattern socks-proxy[:port] (.|http-proxy[:port])
764 ****************************************************************************/
765 case hash_forward_socks4a:
766 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
770 log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
771 "forward-socks4a directive in configuration file.");
772 config->proxy_args = strsav( config->proxy_args,
773 "<br>\nWARNING: Wrong number of parameters for "
774 "forward-socks4a directive in configuration file.");
778 /* allocate a new node */
779 cur_fwd = zalloc(sizeof(*cur_fwd));
782 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
783 /* Never get here - LOG_LEVEL_FATAL causes program exit */
787 cur_fwd->type = SOCKS_4A;
789 /* Save the URL pattern */
790 if (create_url_spec(cur_fwd->url, vec[0]))
792 log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward-socks4a "
793 "directive in configuration file.");
794 config->proxy_args = strsav( config->proxy_args,
795 "<br>\nWARNING: Bad URL specifier for "
796 "forward-socks4a directive in configuration file.");
800 /* Parse the SOCKS proxy host[:port] */
803 cur_fwd->gateway_host = strdup(p);
805 if ((p = strchr(cur_fwd->gateway_host, ':')))
808 cur_fwd->gateway_port = atoi(p);
810 if (cur_fwd->gateway_port <= 0)
812 cur_fwd->gateway_port = 1080;
815 /* Parse the parent HTTP proxy host[:port] */
818 if (strcmp(p, ".") != 0)
820 cur_fwd->forward_host = strdup(p);
822 if ((p = strchr(cur_fwd->forward_host, ':')))
825 cur_fwd->forward_port = atoi(p);
828 if (cur_fwd->forward_port <= 0)
830 cur_fwd->forward_port = 8000;
835 cur_fwd->next = config->forward;
836 config->forward = cur_fwd;
840 /****************************************************************************
841 * jarfile jar-file-name
842 * In logdir by default
843 ****************************************************************************/
844 #ifdef FEATURE_COOKIE_JAR
846 freez((char *)config->jarfile);
847 config->jarfile = make_path(config->logdir, arg);
849 #endif /* def FEATURE_COOKIE_JAR */
851 /****************************************************************************
852 * listen-address [ip][:port]
853 ****************************************************************************/
854 case hash_listen_address :
855 freez((char *)config->haddr);
856 config->haddr = strdup(arg);
859 /****************************************************************************
860 * logdir directory-name
861 ****************************************************************************/
863 freez((char *)config->logdir);
864 config->logdir = strdup(arg);
867 /****************************************************************************
868 * logfile log-file-name
869 * In logdir by default
870 ****************************************************************************/
872 freez((char *)config->logfile);
873 config->logfile = make_path(config->logdir, arg);
876 /****************************************************************************
877 * permit-access source-ip[/significant-bits] [dest-ip[/significant-bits]]
878 ****************************************************************************/
880 case hash_permit_access:
881 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
883 if ((vec_count != 1) && (vec_count != 2))
885 log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
886 "permit-access directive in configuration file.");
887 config->proxy_args = strsav( config->proxy_args,
888 "<br>\nWARNING: Wrong number of parameters for "
889 "permit-access directive in configuration file.<br><br>\n");
894 /* allocate a new node */
895 cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
899 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
900 /* Never get here - LOG_LEVEL_FATAL causes program exit */
903 cur_acl->action = ACL_PERMIT;
905 if (acl_addr(vec[0], cur_acl->src) < 0)
907 log_error(LOG_LEVEL_ERROR, "Invalid source IP for permit-access "
908 "directive in configuration file: \"%s\"", vec[0]);
909 config->proxy_args = strsav( config->proxy_args,
910 "<br>\nWARNING: Invalid source IP for permit-access directive"
911 " in configuration file: \"");
912 config->proxy_args = strsav( config->proxy_args,
914 config->proxy_args = strsav( config->proxy_args,
921 if (acl_addr(vec[1], cur_acl->dst) < 0)
923 log_error(LOG_LEVEL_ERROR, "Invalid destination IP for "
924 "permit-access directive in configuration file: \"%s\"",
926 config->proxy_args = strsav( config->proxy_args,
927 "<br>\nWARNING: Invalid destination IP for permit-access directive"
928 " in configuration file: \"");
929 config->proxy_args = strsav( config->proxy_args,
931 config->proxy_args = strsav( config->proxy_args,
939 * Add it to the list. Note we reverse the list to get the
940 * behaviour the user expects. With both the ACL and
941 * actions file, the last match wins. However, the internal
942 * implementations are different: The actions file is stored
943 * in the same order as the file, and scanned completely.
944 * With the ACL, we reverse the order as we load it, then
945 * when we scan it we stop as soon as we get a match.
947 cur_acl->next = config->acl;
948 config->acl = cur_acl;
951 #endif /* def FEATURE_ACL */
953 /****************************************************************************
955 ****************************************************************************/
956 case hash_proxy_info_url :
957 freez((char *)config->proxy_info_url);
958 config->proxy_info_url = strdup(arg);
961 /****************************************************************************
962 * re_filterfile file-name
963 * In confdir by default.
964 ****************************************************************************/
965 case hash_re_filterfile :
966 freez((char *)config->re_filterfile);
967 config->re_filterfile = make_path(config->confdir, arg);
970 /****************************************************************************
972 ****************************************************************************/
973 case hash_single_threaded :
974 config->multi_threaded = 0;
977 /****************************************************************************
979 ****************************************************************************/
980 #ifdef FEATURE_TOGGLE
982 g_bToggleIJB = atoi(arg);
984 #endif /* def FEATURE_TOGGLE */
986 /****************************************************************************
988 ****************************************************************************/
990 case hash_trust_info_url :
991 enlist(config->trust_info, arg);
993 #endif /* def FEATURE_TRUST */
995 /****************************************************************************
997 * (In confdir by default.)
998 ****************************************************************************/
1000 case hash_trustfile :
1001 freez((char *)config->trustfile);
1002 config->trustfile = make_path(config->confdir, arg);
1004 #endif /* def FEATURE_TRUST */
1007 /****************************************************************************
1008 * Win32 Console options:
1009 ****************************************************************************/
1011 /****************************************************************************
1013 ****************************************************************************/
1015 case hash_hide_console :
1018 #endif /*def _WIN_CONSOLE*/
1021 /****************************************************************************
1022 * Win32 GUI options:
1023 ****************************************************************************/
1025 #if defined(_WIN32) && ! defined(_WIN_CONSOLE)
1026 /****************************************************************************
1027 * activity-animation (0|1)
1028 ****************************************************************************/
1029 case hash_activity_animation :
1030 g_bShowActivityAnimation = atoi(arg);
1033 /****************************************************************************
1034 * close-button-minimizes (0|1)
1035 ****************************************************************************/
1036 case hash_close_button_minimizes :
1037 g_bCloseHidesWindow = atoi(arg);
1040 /****************************************************************************
1041 * log-buffer-size (0|1)
1042 ****************************************************************************/
1043 case hash_log_buffer_size :
1044 g_bLimitBufferSize = atoi(arg);
1047 /****************************************************************************
1048 * log-font-name fontnane
1049 ****************************************************************************/
1050 case hash_log_font_name :
1051 strcpy( g_szFontFaceName, arg );
1054 /****************************************************************************
1056 ****************************************************************************/
1057 case hash_log_font_size :
1058 g_nFontSize = atoi(arg);
1061 /****************************************************************************
1062 * log-highlight-messages (0|1)
1063 ****************************************************************************/
1064 case hash_log_highlight_messages :
1065 g_bHighlightMessages = atoi(arg);
1068 /****************************************************************************
1070 ****************************************************************************/
1071 case hash_log_max_lines :
1072 g_nMaxBufferLines = atoi(arg);
1075 /****************************************************************************
1076 * log-messages (0|1)
1077 ****************************************************************************/
1078 case hash_log_messages :
1079 g_bLogMessages = atoi(arg);
1082 /****************************************************************************
1083 * show-on-task-bar (0|1)
1084 ****************************************************************************/
1085 case hash_show_on_task_bar :
1086 g_bShowOnTaskBar = atoi(arg);
1089 #endif /* defined(_WIN32) && ! defined(_WIN_CONSOLE) */
1092 /****************************************************************************/
1093 /* Warnings about unsupported features */
1094 /****************************************************************************/
1096 case hash_deny_access:
1097 #endif /* ndef FEATURE_ACL */
1098 #ifndef FEATURE_COOKIE_JAR
1100 #endif /* ndef FEATURE_COOKIE_JAR */
1102 case hash_permit_access:
1103 #endif /* ndef FEATURE_ACL */
1104 #ifndef FEATURE_TOGGLE
1106 #endif /* ndef FEATURE_TOGGLE */
1107 #ifndef FEATURE_TRUST
1108 case hash_trustfile :
1109 case hash_trust_info_url :
1110 #endif /* ndef FEATURE_TRUST */
1112 #ifndef _WIN_CONSOLE
1113 case hash_hide_console :
1114 #endif /* ndef _WIN_CONSOLE */
1116 #if defined(_WIN_CONSOLE) || ! defined(_WIN32)
1117 case hash_activity_animation :
1118 case hash_close_button_minimizes :
1119 case hash_log_buffer_size :
1120 case hash_log_font_name :
1121 case hash_log_font_size :
1122 case hash_log_highlight_messages :
1123 case hash_log_max_lines :
1124 case hash_log_messages :
1125 case hash_show_on_task_bar :
1126 #endif /* defined(_WIN_CONSOLE) || ! defined(_WIN32) */
1127 /* These warnings are annoying - so hide them. -- Jon */
1128 /* log_error(LOG_LEVEL_INFO, "Unsupported directive \"%s\" ignored.", cmd); */
1131 /****************************************************************************/
1133 /****************************************************************************/
1135 * I decided that I liked this better as a warning than an
1136 * error. To change back to an error, just change log level
1137 * to LOG_LEVEL_FATAL.
1139 log_error(LOG_LEVEL_ERROR, "Unrecognized directive (%luul) in "
1140 "configuration file: \"%s\"", hash_string( cmd ), buf);
1141 config->proxy_args = strsav( config->proxy_args, "<br>\nWARNING: unrecognized directive : ");
1142 config->proxy_args = strsav( config->proxy_args, buf);
1143 config->proxy_args = strsav( config->proxy_args, "<br><br>\n");
1146 /****************************************************************************/
1147 } /* end switch( hash_string(cmd) ) */
1148 } /* end while ( read_config_line(...) ) */
1152 init_error_log(Argv[0], config->logfile, config->debug);
1154 if (config->actions_file)
1156 add_loader(load_actions_file, config);
1159 if (config->re_filterfile)
1161 add_loader(load_re_filterfile, config);
1164 #ifdef FEATURE_TRUST
1165 if (config->trustfile)
1167 add_loader(load_trustfile, config);
1169 #endif /* def FEATURE_TRUST */
1171 #ifdef FEATURE_COOKIE_JAR
1172 if ( NULL != config->jarfile )
1174 if ( NULL == (config->jar = fopen(config->jarfile, "a")) )
1176 log_error(LOG_LEVEL_FATAL, "can't open jarfile '%s': %E", config->jarfile);
1177 /* Never get here - LOG_LEVEL_FATAL causes program exit */
1179 setbuf(config->jar, NULL);
1181 #endif /* def FEATURE_COOKIE_JAR */
1183 if ( NULL == config->haddr )
1185 config->haddr = strdup( HADDR_DEFAULT );
1188 if ( NULL != config->haddr )
1190 if ((p = strchr(config->haddr, ':')))
1195 config->hport = atoi(p);
1199 if (config->hport <= 0)
1202 log_error(LOG_LEVEL_FATAL, "invalid bind port spec %s", config->haddr);
1203 /* Never get here - LOG_LEVEL_FATAL causes program exit */
1205 if (*config->haddr == '\0')
1207 config->haddr = NULL;
1212 * Want to run all the loaders once now.
1214 * Need to set up a fake csp, so they can get to the config.
1216 fake_csp = (struct client_state *) zalloc (sizeof(*fake_csp));
1217 fake_csp->config = config;
1219 if (run_loader(fake_csp))
1222 log_error(LOG_LEVEL_FATAL, "A loader failed while loading config file. Exiting.");
1223 /* Never get here - LOG_LEVEL_FATAL causes program exit */
1227 /* FIXME: this is a kludge for win32 */
1228 #if defined(_WIN32) && !defined (_WIN_CONSOLE)
1230 g_actions_file = config->actions_file;
1231 g_re_filterfile = config->re_filterfile;
1233 #ifdef FEATURE_TRUST
1234 g_trustfile = config->trustfile;
1235 #endif /* def FEATURE_TRUST */
1238 #endif /* defined(_WIN32) && !defined (_WIN_CONSOLE) */
1239 /* FIXME: end kludge */
1242 config->need_bind = 1;
1244 if (current_configfile)
1246 struct configuration_spec * oldcfg = (struct configuration_spec *)
1247 current_configfile->f;
1249 * Check if config->haddr,hport == oldcfg->haddr,hport
1251 * The following could be written more compactly as a single,
1252 * (unreadably long) if statement.
1254 config->need_bind = 0;
1255 if (config->hport != oldcfg->hport)
1257 config->need_bind = 1;
1259 else if (config->haddr == NULL)
1261 if (oldcfg->haddr != NULL)
1263 config->need_bind = 1;
1266 else if (oldcfg->haddr == NULL)
1268 config->need_bind = 1;
1270 else if (0 != strcmp(config->haddr, oldcfg->haddr))
1272 config->need_bind = 1;
1275 current_configfile->unloader = unload_configfile;
1278 fs->next = files->next;
1281 current_configfile = fs;