⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache_cf.c

📁 -
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * $Id: cache_cf.c,v 1.324.2.4 1999/04/19 00:14:34 wessels Exp $ * * DEBUG: section 3     Configuration File Parsing * AUTHOR: Harvest Derived * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please see *  the CREDITS file for full details. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"#if SQUID_SNMP#include "snmp.h"#endifstatic const char *const T_SECOND_STR = "second";static const char *const T_MINUTE_STR = "minute";static const char *const T_HOUR_STR = "hour";static const char *const T_DAY_STR = "day";static const char *const T_WEEK_STR = "week";static const char *const T_FORTNIGHT_STR = "fortnight";static const char *const T_MONTH_STR = "month";static const char *const T_YEAR_STR = "year";static const char *const T_DECADE_STR = "decade";static const char *const B_BYTES_STR = "bytes";static const char *const B_KBYTES_STR = "KB";static const char *const B_MBYTES_STR = "MB";static const char *const B_GBYTES_STR = "GB";static const char *const list_sep = ", \t\n\r";static int http_header_first = 0;static void self_destruct(void);static void configDoConfigure(void);static void parse_refreshpattern(refresh_t **);static int parseTimeUnits(const char *unit);static void parseTimeLine(time_t * tptr, const char *units);static void parse_ushort(u_short * var);static void parse_string(char **);static void parse_wordlist(wordlist **);static void default_all(void);static void defaults_if_none(void);static int parse_line(char *);static void parseBytesLine(size_t * bptr, const char *units);static size_t parseBytesUnits(const char *unit);static void free_all(void);static void requirePathnameExists(const char *name, const char *path);static OBJH dump_config;static void dump_http_header(StoreEntry * entry, const char *name, HttpHeaderMask header);static void parse_http_header(HttpHeaderMask * header);static void free_http_header(HttpHeaderMask * header);static voidself_destruct(void){    fatalf("Bungled %s line %d: %s",	cfg_filename, config_lineno, config_input_line);}voidwordlistDestroy(wordlist ** list){    wordlist *w = NULL;    while ((w = *list) != NULL) {	*list = w->next;	safe_free(w->key);	memFree(w, MEM_WORDLIST);    }    *list = NULL;}wordlist *wordlistAdd(wordlist ** list, const char *key){    while (*list)	list = &(*list)->next;    *list = memAllocate(MEM_WORDLIST);    (*list)->key = xstrdup(key);    (*list)->next = NULL;    return *list;}voidwordlistCat(const wordlist * w, MemBuf * mb){    while (NULL != w) {	memBufPrintf(mb, "%s\n", w->key);	w = w->next;    }}wordlist *wordlistDup(const wordlist * w){    wordlist *D = NULL;    while (NULL != w) {	wordlistAdd(&D, w->key);	w = w->next;    }    return D;}voidintlistDestroy(intlist ** list){    intlist *w = NULL;    intlist *n = NULL;    for (w = *list; w; w = n) {	n = w->next;	memFree(w, MEM_INTLIST);    }    *list = NULL;}intintlistFind(intlist * list, int i){    intlist *w = NULL;    for (w = list; w; w = w->next)	if (w->i == i)	    return 1;    return 0;}/* * Use this #define in all the parse*() functions.  Assumes char *token is * defined */#define GetInteger(var) \	token = strtok(NULL, w_space); \	if( token == NULL) \		self_destruct(); \	if (sscanf(token, "%d", &var) != 1) \		self_destruct();intparseConfigFile(const char *file_name){    FILE *fp = NULL;    char *token = NULL;    char *tmp_line;    int err_count = 0;    free_all();    default_all();    if ((fp = fopen(file_name, "r")) == NULL)	fatalf("Unable to open configuration file: %s: %s",	    file_name, xstrerror());    cfg_filename = file_name;    if ((token = strrchr(cfg_filename, '/')))	cfg_filename = token + 1;    memset(config_input_line, '\0', BUFSIZ);    config_lineno = 0;    while (fgets(config_input_line, BUFSIZ, fp)) {	config_lineno++;	if ((token = strchr(config_input_line, '\n')))	    *token = '\0';	if (config_input_line[0] == '#')	    continue;	if (config_input_line[0] == '\0')	    continue;	debug(3, 5) ("Processing: '%s'\n", config_input_line);	tmp_line = xstrdup(config_input_line);	if (!parse_line(tmp_line)) {	    debug(3, 0) ("parseConfigFile: line %d unrecognized: '%s'\n",		config_lineno,		config_input_line);	    err_count++;	}	safe_free(tmp_line);    }    fclose(fp);    defaults_if_none();    configDoConfigure();    cachemgrRegister("config",	"Current Squid Configuration",	dump_config,	1, 1);    return err_count;}static voidconfigDoConfigure(void){    LOCAL_ARRAY(char, buf, BUFSIZ);    memset(&Config2, '\0', sizeof(SquidConfig2));    /* init memory as early as possible */    memConfigure();    /* Sanity checks */    if (Config.cacheSwap.swapDirs == NULL)	fatal("No cache_dir's specified in config file");    /* calculate Config.Swap.maxSize */    storeDirConfigure();    if (Config.Swap.maxSize < (Config.memMaxSize >> 10))	fatal("cache_swap is lower than cache_mem");    if (Config.Announce.period > 0) {	Config.onoff.announce = 1;    } else if (Config.Announce.period < 1) {	Config.Announce.period = 86400 * 365;	/* one year */	Config.onoff.announce = 0;    }    if (Config.dnsChildren < 1)	fatal("No dnsservers allocated");    if (Config.dnsChildren > DefaultDnsChildrenMax) {	debug(3, 0) ("WARNING: dns_children was set to a bad value: %d\n",	    Config.dnsChildren);	debug(3, 0) ("Setting it to the maximum (%d).\n",	    DefaultDnsChildrenMax);	Config.dnsChildren = DefaultDnsChildrenMax;    }    if (Config.Program.redirect) {	if (Config.redirectChildren < 1) {	    Config.redirectChildren = 0;	    safe_free(Config.Program.redirect);	} else if (Config.redirectChildren > DefaultRedirectChildrenMax) {	    debug(3, 0) ("WARNING: redirect_children was set to a bad value: %d\n",		Config.redirectChildren);	    debug(3, 0) ("Setting it to the maximum (%d).\n", DefaultRedirectChildrenMax);	    Config.redirectChildren = DefaultRedirectChildrenMax;	}    }    if (Config.Program.authenticate) {	if (Config.authenticateChildren < 1) {	    Config.authenticateChildren = 0;	    wordlistDestroy(&Config.Program.authenticate);	} else if (Config.authenticateChildren > DefaultAuthenticateChildrenMax) {	    debug(3, 0) ("WARNING: authenticate_children was set to a bad value: %d\n",		Config.authenticateChildren);	    debug(3, 0) ("Setting it to the maximum (%d).\n", DefaultAuthenticateChildrenMax);	    Config.authenticateChildren = DefaultAuthenticateChildrenMax;	}    }    if (Config.Accel.host) {	snprintf(buf, BUFSIZ, "http://%s:%d", Config.Accel.host, Config.Accel.port);	Config2.Accel.prefix = xstrdup(buf);	Config2.Accel.on = 1;    }    if (Config.appendDomain)	if (*Config.appendDomain != '.')	    fatal("append_domain must begin with a '.'");    if (Config.errHtmlText == NULL)	Config.errHtmlText = xstrdup(null_string);    storeConfigure();    if (Config2.Accel.on && !strcmp(Config.Accel.host, "virtual"))	vhost_mode = 1;    if (Config.Port.http == NULL)	fatal("No http_port specified!");    snprintf(ThisCache, sizeof(ThisCache), "%s:%d (%s)",	uniqueHostname(),	(int) Config.Port.http->i,	full_appname_string);    /*     * the extra space is for loop detection in client_side.c -- we search     * for substrings in the Via header.     */    snprintf(ThisCache2, sizeof(ThisCache), " %s:%d (%s)",	uniqueHostname(),	(int) Config.Port.http->i,	full_appname_string);    if (!Config.udpMaxHitObjsz || Config.udpMaxHitObjsz > SQUID_UDP_SO_SNDBUF)	Config.udpMaxHitObjsz = SQUID_UDP_SO_SNDBUF;    if (Config.appendDomain)	Config.appendDomainLen = strlen(Config.appendDomain);    else	Config.appendDomainLen = 0;    safe_free(debug_options)	debug_options = xstrdup(Config.debugOptions);    if (Config.retry.timeout < 5)	fatal("minimum_retry_timeout must be at least 5 seconds");    if (Config.retry.maxtries > 10)	fatal("maximum_single_addr_tries cannot be larger than 10");    if (Config.retry.maxtries < 1) {	debug(3, 0) ("WARNING: resetting 'maximum_single_addr_tries to 1\n");	Config.retry.maxtries = 1;    }    if (Config.referenceAge < 300) {	debug(3, 0) ("WARNING: resetting 'reference_age' to 1 week\n");	Config.referenceAge = 86400 * 7;    }    requirePathnameExists("MIME Config Table", Config.mimeTablePathname);    requirePathnameExists("cache_dns_program", Config.Program.dnsserver);    requirePathnameExists("unlinkd_program", Config.Program.unlinkd);    if (Config.Program.redirect)	requirePathnameExists("redirect_program", Config.Program.redirect);    if (Config.Program.authenticate)	requirePathnameExists("authenticate_program", Config.Program.authenticate->key);    requirePathnameExists("Icon Directory", Config.icons.directory);    requirePathnameExists("Error Directory", Config.errorDirectory);#if HTTP_VIOLATIONS    {	const refresh_t *R;	for (R = Config.Refresh; R; R = R->next) {	    if (!R->flags.override_expire)		continue;	    debug(22, 1) ("WARNING: use of 'override-expire' in 'refresh_pattern' violates HTTP\n");	    break;	}	for (R = Config.Refresh; R; R = R->next) {	    if (!R->flags.override_lastmod)		continue;	    debug(22, 1) ("WARNING: use of 'override-lastmod' in 'refresh_pattern' violates HTTP\n");	    break;	}    }#endif    if (Config.Wais.relayHost) {	if (Config.Wais.peer)	    cbdataFree(Config.Wais.peer);	Config.Wais.peer = memAllocate(MEM_PEER);	cbdataAdd(Config.Wais.peer, peerDestroy, MEM_PEER);	Config.Wais.peer->host = xstrdup(Config.Wais.relayHost);	Config.Wais.peer->http_port = Config.Wais.relayPort;    }}/* Parse a time specification from the config file.  Store the * result in 'tptr', after converting it to 'units' */static voidparseTimeLine(time_t * tptr, const char *units){    char *token;    double d;    time_t m;    time_t u;    if ((u = parseTimeUnits(units)) == 0)	self_destruct();    if ((token = strtok(NULL, w_space)) == NULL)	self_destruct();    d = atof(token);    m = u;			/* default to 'units' if none specified */    if (0 == d)	(void) 0;    else if ((token = strtok(NULL, w_space)) == NULL)	debug(3, 0) ("WARNING: No units on '%s', assuming %f %s\n",	    config_input_line, d, units);    else if ((m = parseTimeUnits(token)) == 0)	self_destruct();    *tptr = m * d / u;}static intparseTimeUnits(const char *unit){    if (!strncasecmp(unit, T_SECOND_STR, strlen(T_SECOND_STR)))	return 1;    if (!strncasecmp(unit, T_MINUTE_STR, strlen(T_MINUTE_STR)))	return 60;    if (!strncasecmp(unit, T_HOUR_STR, strlen(T_HOUR_STR)))	return 3600;    if (!strncasecmp(unit, T_DAY_STR, strlen(T_DAY_STR)))	return 86400;    if (!strncasecmp(unit, T_WEEK_STR, strlen(T_WEEK_STR)))	return 86400 * 7;    if (!strncasecmp(unit, T_FORTNIGHT_STR, strlen(T_FORTNIGHT_STR)))	return 86400 * 14;    if (!strncasecmp(unit, T_MONTH_STR, strlen(T_MONTH_STR)))	return 86400 * 30;    if (!strncasecmp(unit, T_YEAR_STR, strlen(T_YEAR_STR)))	return 86400 * 365.2522;    if (!strncasecmp(unit, T_DECADE_STR, strlen(T_DECADE_STR)))	return 86400 * 365.2522 * 10;    debug(3, 1) ("parseTimeUnits: unknown time unit '%s'\n", unit);    return 0;}static voidparseBytesLine(size_t * bptr, const char *units){    char *token;    double d;    size_t m;    size_t u;    if ((u = parseBytesUnits(units)) == 0)	self_destruct();    if ((token = strtok(NULL, w_space)) == NULL)	self_destruct();    d = atof(token);    m = u;			/* default to 'units' if none specified */    if (0 == d)	(void) 0;    else if ((token = strtok(NULL, w_space)) == NULL)	debug(3, 0) ("WARNING: No units on '%s', assuming %f %s\n",	    config_input_line, d, units);    else if ((m = parseBytesUnits(token)) == 0)	self_destruct();    *bptr = m * d / u;}static size_tparseBytesUnits(const char *unit){    if (!strncasecmp(unit, B_BYTES_STR, strlen(B_BYTES_STR)))	return 1;    if (!strncasecmp(unit, B_KBYTES_STR, strlen(B_KBYTES_STR)))	return 1 << 10;    if (!strncasecmp(unit, B_MBYTES_STR, strlen(B_MBYTES_STR)))	return 1 << 20;    if (!strncasecmp(unit, B_GBYTES_STR, strlen(B_GBYTES_STR)))	return 1 << 30;    debug(3, 1) ("parseBytesUnits: unknown bytes unit '%s'\n", unit);    return 0;}/***************************************************************************** * Max *****************************************************************************/static voiddump_acl(StoreEntry * entry, const char *name, acl * ae){    wordlist *w;    wordlist *v;    while (ae != NULL) {	debug(3, 3) ("dump_acl: %s %s\n", name, ae->name);	v = w = aclDumpGeneric(ae);	while (v != NULL) {	    debug(3, 3) ("dump_acl: %s %s %s\n", name, ae->name, v->key);	    storeAppendPrintf(entry, "%s %s %s %s\n",		name,		ae->name,		aclTypeToStr(ae->type),		v->key);	    v = v->next;	}	wordlistDestroy(&w);	ae = ae->next;    }}static voidparse_acl(acl ** ae){    aclParseAclLine(ae);}static voidfree_acl(acl ** ae){    aclDestroyAcls(ae);}static voiddump_acl_access(StoreEntry * entry, const char *name, acl_access * head){    acl_list *l;    while (head != NULL) {	storeAppendPrintf(entry, "%s %s",	    name,	    head->allow ? "Allow" : "Deny");	for (l = head->acl_list; l != NULL; l = l->next) {	    storeAppendPrintf(entry, " %s%s",		l->op ? null_string : "!",		l->acl->name);	}	storeAppendPrintf(entry, "\n");	head = head->next;    }}static voidparse_acl_access(acl_access ** head){    aclParseAccessLine(head);}static voidfree_acl_access(acl_access ** head){    aclDestroyAccessList(head);}static voiddump_address(StoreEntry * entry, const char *name, struct in_addr addr){    storeAppendPrintf(entry, "%s %s\n", name, inet_ntoa(addr));}static voidparse_address(struct in_addr *addr){    const struct hostent *hp;    char *token = strtok(NULL, w_space);    if (token == NULL)	self_destruct();    if (safe_inet_addr(token, addr) == 1)	(void) 0;    else if ((hp = gethostbyname(token)))	/* dont use ipcache */	*addr = inaddrFromHostent(hp);    else	self_destruct();}static voidfree_address(struct in_addr *addr){    memset(addr, '\0', sizeof(struct in_addr));}#if DELAY_POOLS/* do nothing - free_delay_pool_count is the magic free function. * this is why delay_pool_count isn't just marked TYPE: ushort */#define free_delay_pool_class(X)#define free_delay_pool_access(X)#define free_delay_pool_rates(X)#define dump_delay_pool_class(X, Y, Z)#define dump_delay_pool_access(X, Y, Z)#define dump_delay_pool_rates(X, Y, Z)static voidfree_delay_pool_count(delayConfig * cfg){    int i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -