You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
7.4 KiB

//
// HtConfiguration.cc
//
// HtConfiguration: extends Configuration class
// to implement Apache-style config. Uses parser
// generated by Bison from conf_parser.yxx
//
// Part of the ht://Dig package <http://www.htdig.org/>
// Copyright (c) 1995-2004 The ht://Dig Group
// For copyright details, see the file COPYING in your distribution
// or the GNU Library General Public License (LGPL) version 2 or later
// <http://www.gnu.org/copyleft/lgpl.html>
//
// $Id: HtConfiguration.cc,v 1.10 2004/05/28 13:15:12 lha Exp $
//
#ifdef HAVE_CONFIG_H
#include "htconfig.h"
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include "HtConfiguration.h"
#include <stdlib.h>
#ifdef HAVE_STD
#include <fstream>
#ifdef HAVE_NAMESPACES
using namespace std;
#endif
#else
#include <fstream.h>
#endif /* HAVE_STD */
#include <stdlib.h>
#include <ctype.h>
#include <locale.h>
//********************************************************************
// Add complex entry to the configuration
//
void
HtConfiguration::Add(const char *name, const char *value, Configuration *aList) {
if (strcmp("url",name)==0) { //add URL entry
URL tmpUrl(strdup(value));
Dictionary *paths= NULL;
if ( (paths=(Dictionary *)dcUrls[tmpUrl.host()]) ) {
paths->Add(tmpUrl.path(),aList);
} else {
paths=new Dictionary();
paths->Add(tmpUrl.path(),aList);
dcUrls.Add(tmpUrl.host(),paths);
}
} else {
Object *treeEntry=dcBlocks[name];
if (treeEntry!=NULL) {
((Dictionary *)treeEntry)->Add(value,aList);
} else {
treeEntry=new Dictionary(16);
((Dictionary *)treeEntry)->Add(value,aList);
dcBlocks.Add(name, treeEntry);
}
}
}
//*********************************************************************
const String HtConfiguration::Find(const char *blockName,const char *name,const char *value) const
{
if (!(blockName && name && value) )
return String();
union {
void *ptr;
Object *obj;
Dictionary *dict;
HtConfiguration *conf;
} tmpPtr;
String chr;
if (strcmp("url",blockName)==0) { // URL needs special compare
URL paramUrl(name); // split URL to compare separatly host and path
chr=Find(&paramUrl,value);
if (chr[0]!=0) {
return chr;
}
}
else { // end "server"
tmpPtr.obj=dcBlocks.Find(blockName);
if (tmpPtr.ptr) {
tmpPtr.obj = tmpPtr.dict->Find(name);
if (tmpPtr.ptr) {
chr = tmpPtr.conf->Find(value);
if (chr[0] != 0)
return chr;
}
}
}
// If this parameter is defined in global then return it
chr=Find(value);
if (chr[0]!=0) {
return chr;
}
#ifdef DEBUG
cerr << "Could not find configuration option " << blockName<<":"
<<name<<":"<<value<< "\n";
#endif
return String();
}
//*********************************************************************
//
const String HtConfiguration::Find(URL *aUrl, const char *value) const
{
if (!aUrl)
return String();
Dictionary *tmpPtr=(Dictionary *)dcUrls.Find( aUrl->host() );
if (tmpPtr) { // We've got such host in config
tmpPtr->Start_Get();
// Try to find best matched URL
//
struct candidate {
Object *obj;
unsigned int len;
String value;
} candidate;
candidate.len=0;
String returnValue;
// Begin competition: which URL is better?
//
// TODO: move this loop into Dictionary
// (or create Dictionary::FindBest ?)
// or make url list sorted ?
// or implement abstract Dictionary::Compare?
const char *strParamUrl=(const char *)aUrl->path();
char* confUrl= NULL;
bool found(false);
while ((confUrl=tmpPtr->Get_Next()) ) {
if (strncmp(confUrl,strParamUrl,strlen(confUrl))==0
&& (strlen(confUrl)>=candidate.len)) {
// it seems this URL match better
candidate.obj=tmpPtr->Find(confUrl);
// Let's see if it exists
if (((HtConfiguration *)candidate.obj)->Exists(value))
{
// yes, it has! We've got new candidate.
candidate.value=((HtConfiguration *)candidate.obj)->Find(value);
returnValue=candidate.value;
candidate.len=candidate.value.length();
found = true;
}
}
}
if (found)
return ParsedString(returnValue).get(dcGlobalVars);
}
return Find(value);
}
//*********************************************************************
int HtConfiguration::Value(const char *blockName, const char *name,
const char *value, int default_value ) {
int retValue=default_value;
String tmpStr=Find(blockName,name,value);
if (tmpStr[0]!=0) {
retValue=atoi(tmpStr.get());
}
return retValue;
}
//*********************************************************************
double HtConfiguration::Double(const char *blockName, const char *name,
const char *value, double default_value ) {
double retValue=default_value;
String tmpStr=Find(blockName,name,value);
if (tmpStr[0]!=0) {
retValue=atof(tmpStr.get());
}
return retValue;
}
//*********************************************************************
int HtConfiguration::Boolean(const char *blockName, const char *name,
const char *value, int default_value ) {
int retValue=default_value;
String tmpStr=Find(blockName,name,value);
if (tmpStr[0]!=0) {
if (mystrcasecmp((char*)tmpStr, "true") == 0 ||
mystrcasecmp((char*)tmpStr, "yes") == 0 ||
mystrcasecmp((char*)tmpStr, "1") == 0)
retValue = 1;
else if (mystrcasecmp((char*)tmpStr, "false") == 0 ||
mystrcasecmp((char*)tmpStr, "no") == 0 ||
mystrcasecmp((char*)tmpStr, "0") == 0)
retValue = 0;
}
return retValue;
}
//*********************************************************************
//*********************************************************************
int HtConfiguration::Value(URL *aUrl, const char *value,
int default_value ) {
int retValue=default_value;
String tmpStr=Find(aUrl,value);
if (tmpStr[0]!=0) {
retValue=atoi(tmpStr.get());
}
return retValue;
}
//*********************************************************************
double HtConfiguration::Double(URL *aUrl,const char *value,
double default_value ) {
double retValue=default_value;
String tmpStr=Find(aUrl,value);
if (tmpStr[0]!=0) {
retValue=atof(tmpStr.get());
}
return retValue;
}
//*********************************************************************
int HtConfiguration::Boolean(URL *aUrl,const char *value,
int default_value ) {
int retValue=default_value;
String tmpStr=Find(aUrl,value);
if (tmpStr[0]!=0) {
if (mystrcasecmp((char*)tmpStr, "true") == 0 ||
mystrcasecmp((char*)tmpStr, "yes") == 0 ||
mystrcasecmp((char*)tmpStr, "1") == 0)
retValue = 1;
else if (mystrcasecmp((char*)tmpStr, "false") == 0 ||
mystrcasecmp((char*)tmpStr, "no") == 0 ||
mystrcasecmp((char*)tmpStr, "0") == 0)
retValue = 0;
}
return retValue;
}
//*********************************************************************
//
int
HtConfiguration::Read(const String& filename)
{
extern FILE* yyin;
extern int yyparse(void*);
if ((yyin=fopen(filename,"r"))==NULL)
return NOTOK;
FileName=filename; // need to be before yyparse() because is used in it
yyparse(this);
fclose(yyin);
return OK;
}
HtConfiguration* HtConfiguration::_config= NULL;
HtConfiguration* const HtConfiguration::config() {
if(_config == NULL) {
_config= new HtConfiguration();
}
return _config;
}