From c5307363beab9eecaff610c9cba7df7b783414a3 Mon Sep 17 00:00:00 2001 From: Robert James Kaes Date: Sat, 14 Aug 2004 03:18:41 +0000 Subject: Reorganized the source code. Added the missing reverse proxy directives. Added a bunch of comments to clarify how the code works. --- src/conffile.c | 252 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 143 insertions(+), 109 deletions(-) diff --git a/src/conffile.c b/src/conffile.c index 62ba363..7b1430f 100644 --- a/src/conffile.c +++ b/src/conffile.c @@ -1,8 +1,8 @@ -/* $Id: conffile.c,v 1.2 2004-08-13 21:03:58 rjkaes Exp $ +/* $Id: conffile.c,v 1.3 2004-08-14 03:18:41 rjkaes Exp $ * * Parses the configuration file and sets up the config_s structure for * use by the application. This file replaces the old grammar.y and - * scannar.l files. It takes up less space and _I_ think is easier to + * scanner.l files. It takes up less space and _I_ think is easier to * add new directives to. Who knows if I'm right though. * * Copyright (C) 2004 Robert James Kaes (rjkaes@users.sourceforge.net) @@ -78,22 +78,11 @@ typedef int (*CONFFILE_HANDLER)(struct config_s*, const char*, regmatch_t[]); #define HANDLE_FUNC(func) int func(struct config_s* conf, const char* line, regmatch_t match[]) -/* - * This is a do nothing function used for the comment and blank lines - * in the configuration file. We don't do anything for those, but - * the function pointer needs to be defined to something so we simply - * return true for those lines. - */ -static HANDLE_FUNC(handle_nop) -{ - return 0; -} - /* * List all the handling functions. These are defined later, but they need * to be in-scope before the big structure below. */ - +static HANDLE_FUNC(handle_nop) { return 0; } /* do nothing function */ static HANDLE_FUNC(handle_allow); static HANDLE_FUNC(handle_anonymous); static HANDLE_FUNC(handle_bind); @@ -102,7 +91,6 @@ static HANDLE_FUNC(handle_connectport); static HANDLE_FUNC(handle_defaulterrorfile); static HANDLE_FUNC(handle_deny); static HANDLE_FUNC(handle_errorfile); -static HANDLE_FUNC(handle_errorfile); static HANDLE_FUNC(handle_filter); static HANDLE_FUNC(handle_filtercasesensitive); static HANDLE_FUNC(handle_filterdefaultdeny); @@ -111,7 +99,6 @@ static HANDLE_FUNC(handle_filterurls); static HANDLE_FUNC(handle_group); static HANDLE_FUNC(handle_listen); static HANDLE_FUNC(handle_logfile); -static HANDLE_FUNC(handle_logfile); static HANDLE_FUNC(handle_loglevel); static HANDLE_FUNC(handle_maxclients); static HANDLE_FUNC(handle_maxrequestsperchild); @@ -150,7 +137,7 @@ static HANDLE_FUNC(handle_xtinyproxy); /* * Holds the regular expression used to match the configuration directive, - * the function pointer to the rountine to handle the directive, and + * the function pointer to the routine to handle the directive, and * for internal use, a pointer to the compiled regex so it only needs * to be compiled one. */ @@ -213,10 +200,11 @@ struct { STDCONF("reversebaseurl", STR, handle_reversebaseurl), STDCONF("reverseonly", BOOL, handle_reverseonly), STDCONF("reversemagic", BOOL, handle_reversemagic), - STDCONF("reversepath", STR WS STR, handle_reversepath), + STDCONF("reversepath", STR WS "(" STR ")?", handle_reversepath), /* upstream is rather complicated */ -// { BEGIN "(no[[:space:]]+)?upstream" WS, handle_upstream }, +// { BEGIN "no" WS "upstream" WS STR END, handle_no_upstream }, +// { BEGIN "upstream" WS IP ":" INT "(" WS STR ")" END, handle_upstream }, /* loglevel */ STDCONF("loglevel", "(critical|error|warning|notice|connect|info)", handle_loglevel) @@ -235,6 +223,7 @@ config_compile(void) int i, r; for (i = 0; i != ndirectives; ++i) { + assert(directives[i].handler); assert(!directives[i].cre); directives[i].cre = safemalloc(sizeof(regex_t)); @@ -244,7 +233,6 @@ config_compile(void) r = regcomp(directives[i].cre, directives[i].re, REG_EXTENDED | REG_ICASE | REG_NEWLINE); - if (r) return r; } return 0; @@ -269,10 +257,8 @@ check_match(struct config_s* conf, const char* line) for (i = 0; i != ndirectives; ++i) { assert(directives[i].cre); - if (!regexec(directives[i].cre, line, RE_MAX_MATCHES, match, 0)) { - assert(directives[i].handler); + if (!regexec(directives[i].cre, line, RE_MAX_MATCHES, match, 0)) return (*directives[i].handler)(conf, line, match); - } } return -1; @@ -289,7 +275,7 @@ config_parse(struct config_s* conf, FILE* f) while (fgets(buffer, sizeof(buffer), f)) { if (check_match(conf, buffer)) { - printf("Syntax error near line %ld\n", lineno); + printf("Syntax error on line %ld\n", lineno); return 1; } ++lineno; @@ -298,13 +284,12 @@ config_parse(struct config_s* conf, FILE* f) } -/* - * Functions to handle the various configuration file directives. - */ - -/* - * String arguments. - */ +/*********************************************************************** + * + * The following are basic data extraction building blocks that can + * be used to simplify the parsing of a directive. + * + ***********************************************************************/ static char* get_string_arg(const char* line, regmatch_t* match) @@ -335,6 +320,70 @@ set_string_arg(char** var, const char* line, regmatch_t* match) return *var ? 0 : -1; } +static int +get_bool_arg(const char* line, regmatch_t* match) +{ + assert(line); + assert(match && match->rm_so != -1); + + const char* p = line + match->rm_so; + + /* "y"es or o"n" map as true, otherwise it's false. */ + if (tolower(p[0]) == 'y' || tolower(p[1]) == 'n') + return 1; + else + return 0; +} + +static int +set_bool_arg(unsigned int* var, const char* line, regmatch_t* match) +{ + assert(var); + assert(line); + assert(match && match->rm_so != -1); + + *var = get_bool_arg(line, match); + return 0; +} + +static inline long int +get_int_arg(const char* line, regmatch_t* match) +{ + assert(line); + assert(match && match->rm_so != -1); + + return strtol(line + match->rm_so, NULL, 0); +} +static int +set_int_arg(int long* var, const char* line, regmatch_t* match) +{ + assert(var); + assert(line); + assert(match); + + *var = get_int_arg(line, match); + return 0; +} + + +/*********************************************************************** + * + * Below are all the directive handling functions. You will notice + * that most of the directives delegate to one of the basic data + * extraction routines. This is deliberate. To add a new directive + * to tinyproxy only requires you to define the regular expression + * above and then figure out what data extract routine to use. + * + * However, you will also notice that more complicated directives are + * possible. You can make your directive as complicated as you require + * to express a solution to the problem you're tackling. + * + * See the definition/comment about the HANDLE_FUNC() macro to learn + * what arguments are supplied to the handler, and to determine what + * values to return. + * + ***********************************************************************/ + static HANDLE_FUNC(handle_logfile) { return set_string_arg(&conf->logf_name, line, &match[2]); @@ -355,7 +404,12 @@ static HANDLE_FUNC(handle_anonymous) } static HANDLE_FUNC(handle_viaproxyname) { - return set_string_arg(&conf->via_proxy_name, line, &match[2]); + int r = set_string_arg(&conf->via_proxy_name, line, &match[2]); + if (r) return r; + log_message(LOG_INFO, + "Setting \"Via\" header proxy to %s", + conf->via_proxy_name); + return 0; } static HANDLE_FUNC(handle_defaulterrorfile) { @@ -367,7 +421,12 @@ static HANDLE_FUNC(handle_statfile) } static HANDLE_FUNC(handle_stathost) { - return set_string_arg(&conf->stathost, line, &match[2]); + int r = set_string_arg(&conf->stathost, line, &match[2]); + if (r) return r; + log_message(LOG_INFO, + "Stathost set to \"%s\"", + conf->stathost); + return 0; } static HANDLE_FUNC(handle_xtinyproxy) { @@ -379,38 +438,6 @@ static HANDLE_FUNC(handle_xtinyproxy) return 1; #endif } - - -/* - * Boolean arguments. - */ - -static int -get_bool_arg(const char* line, regmatch_t* match) -{ - assert(line); - assert(match && match->rm_so != -1); - - const char* p = line + match->rm_so; - - /* "y"es or o"n" map as true, otherwise it's false. */ - if (tolower(p[0]) == 'y' || tolower(p[1]) == 'n') - return 1; - else - return 0; -} - -static int -set_bool_arg(unsigned int* var, const char* line, regmatch_t* match) -{ - assert(var); - assert(line); - assert(match && match->rm_so != -1); - - *var = get_bool_arg(line, match); - return 0; -} - static HANDLE_FUNC(handle_syslog) { #ifdef HAVE_SYSLOG_H @@ -423,30 +450,9 @@ static HANDLE_FUNC(handle_syslog) } static HANDLE_FUNC(handle_bindsame) { - return set_bool_arg(&conf->bindsame, line, &match[2]); -} - - -/* - * Integer arguments. - */ - -static inline long int -get_int_arg(const char* line, regmatch_t* match) -{ - assert(line); - assert(match && match->rm_so != -1); - - return strtol(line + match->rm_so, NULL, 0); -} -static int -set_int_arg(int long* var, const char* line, regmatch_t* match) -{ - assert(var); - assert(line); - assert(match); - - *var = get_int_arg(line, match); + int r = set_bool_arg(&conf->bindsame, line, &match[2]); + if (r) return r; + log_message(LOG_INFO, "Binding outgoing connection to incoming IP"); return 0; } static HANDLE_FUNC(handle_port) @@ -487,11 +493,6 @@ static HANDLE_FUNC(handle_connectport) add_connect_port_allowed(get_int_arg(line, &match[2])); return 0; } - - -/* - * Alpha numeric argument - */ static HANDLE_FUNC(handle_user) { return set_string_arg(&conf->username, line, &match[2]); @@ -500,11 +501,6 @@ static HANDLE_FUNC(handle_group) { return set_string_arg(&conf->group, line, &match[2]); } - - -/* - * IP addresses - */ static HANDLE_FUNC(handle_allow) { char* arg = get_string_arg(line, &match[2]); @@ -522,7 +518,12 @@ static HANDLE_FUNC(handle_deny) static HANDLE_FUNC(handle_bind) { #ifndef TRANSPARENT_PROXY - return set_string_arg(&conf->bind_address, line, &match[2]); + int r = set_string_arg(&conf->bind_address, line, &match[2]); + if (r) return r; + log_message(LOG_INFO, + "Outgoing connections bound to IP %s", + conf->bind_address); + return 0; #else fprintf(stderr, "\"Bind\" cannot be used with transparent support enabled.\n"); @@ -531,25 +532,29 @@ static HANDLE_FUNC(handle_bind) } static HANDLE_FUNC(handle_listen) { - return set_string_arg(&conf->ipAddr, line, &match[2]); + int r = set_string_arg(&conf->ipAddr, line, &match[2]); + if (r) return r; + log_message(LOG_INFO, "Listing on IP %s", conf->ipAddr); + return 0; } - - -/* - * Error file has a integer and string argument - */ static HANDLE_FUNC(handle_errorfile) { + /* + * Because an integer is defined as ((0x)?[[:digit:]]+) _two_ + * match places are used. match[2] matches the full digit + * string, while match[3] matches only the "0x" part if + * present. This is why the "string" is located at + * match[4] (rather than the more intuitive match[3]. + */ long int err = get_int_arg(line, &match[2]); - char *page = get_string_arg(line, &match[3]); + char *page = get_string_arg(line, &match[4]); add_new_errorpage(page, err); safefree(page); return 0; } - /* - * Log level's are strings. + * Log level's strings. */ struct log_levels_s { const char* string; @@ -631,6 +636,35 @@ static HANDLE_FUNC(handle_reversemagic) { return set_bool_arg(&conf->reversemagic, line, &match[2]); } +static HANDLE_FUNC(handle_reversebaseurl) +{ + return set_string_arg(&conf->reversebaseurl, line, &match[2]); +} +static HANDLE_FUNC(handle_reversepath) +{ + /* + * The second string argument is optional. + */ + char *arg1, *arg2; + + arg1 = get_string_arg(line, &match[2]); + if (!arg1) return -1; + + if (match[3].rm_so != -1) { + arg2 = get_string_arg(line, &match[3]); + if (!arg2) { + safefree(arg1); + return -1; + } + reversepath_add(arg1, arg2); + safefree(arg1); + safefree(arg2); + } else { + reversepath_add(NULL, arg1); + safefree(arg1); + } + return 0; +} #else static int no_reverse_support(void) -- cgit v1.2.3