2002-11-03 17:26:12 +01:00
|
|
|
/*
|
2005-01-12 05:24:53 +01:00
|
|
|
* The contents of this file are subject to the Initial
|
|
|
|
* Developer's Public License Version 1.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the
|
|
|
|
* License. You may obtain a copy of the License at
|
|
|
|
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
2002-11-03 17:26:12 +01:00
|
|
|
*
|
2005-01-12 05:24:53 +01:00
|
|
|
* Software distributed under the License is distributed AS IS,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing rights
|
|
|
|
* and limitations under the License.
|
2002-11-03 17:26:12 +01:00
|
|
|
*
|
2005-01-12 05:24:53 +01:00
|
|
|
* The Original Code was created by Dmitry Yemanov
|
|
|
|
* for the Firebird Open Source RDBMS project.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2002 Dmitry Yemanov <dimitr@users.sf.net>
|
|
|
|
* and all contributors signed below.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
2002-11-03 17:26:12 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "firebird.h"
|
|
|
|
|
2004-03-26 00:12:50 +01:00
|
|
|
#include "../../common/classes/alloc.h"
|
2004-03-14 14:14:58 +01:00
|
|
|
#include "../../common/classes/auto.h"
|
2002-11-03 17:26:12 +01:00
|
|
|
#include "../../common/config/config_file.h"
|
2003-04-19 18:46:24 +02:00
|
|
|
#include "../jrd/os/fbsyslog.h"
|
2004-04-29 00:00:03 +02:00
|
|
|
#include <stdio.h>
|
2002-11-03 17:26:12 +01:00
|
|
|
|
|
|
|
#ifdef HAVE_STDLIB_H
|
|
|
|
#include <stdlib.h>
|
|
|
|
#endif
|
|
|
|
|
2003-04-19 18:46:24 +02:00
|
|
|
// Invalid or missing CONF_FILE may lead to severe errors
|
|
|
|
// in applications. That's why for regular SERVER builds
|
|
|
|
// it's better to exit with appropriate diags rather continue
|
|
|
|
// with missing / wrong configuration.
|
2003-05-22 08:39:54 +02:00
|
|
|
#if (! defined(BOOT_BUILD)) && (! defined(EMBEDDED)) && (! defined(SUPERCLIENT))
|
2004-08-30 20:11:08 +02:00
|
|
|
#define EXCEPTION_ON_NO_CONF
|
2003-05-22 08:39:54 +02:00
|
|
|
#else
|
2004-08-30 20:11:08 +02:00
|
|
|
#undef EXCEPTION_ON_NO_CONF
|
2003-05-22 08:39:54 +02:00
|
|
|
#endif
|
2003-04-19 18:46:24 +02:00
|
|
|
|
2004-02-08 18:08:34 +01:00
|
|
|
// config_file works with OS case-sensitivity
|
|
|
|
typedef Firebird::PathName string;
|
2002-11-03 17:26:12 +01:00
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Strip any comments
|
|
|
|
*/
|
|
|
|
|
|
|
|
void ConfigFile::stripComments(string& s)
|
|
|
|
{
|
|
|
|
// Note that this is only a hack. It won't work in case inputLine
|
|
|
|
// contains hash-marks embedded in quotes! Not that I know if we
|
|
|
|
// should care about that case.
|
|
|
|
const string::size_type commentPos = s.find('#');
|
|
|
|
if (commentPos != string::npos)
|
|
|
|
{
|
|
|
|
s = s.substr(0, commentPos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Check whether the given key exists or not
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool ConfigFile::doesKeyExist(const string& key)
|
|
|
|
{
|
|
|
|
checkLoadConfig();
|
|
|
|
|
|
|
|
string data = getString(key);
|
|
|
|
|
|
|
|
return !data.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Return string value corresponding the given key
|
|
|
|
*/
|
|
|
|
|
|
|
|
string ConfigFile::getString(const string& key)
|
|
|
|
{
|
|
|
|
checkLoadConfig();
|
|
|
|
|
2004-07-17 01:06:31 +02:00
|
|
|
size_t pos;
|
2004-03-14 14:14:58 +01:00
|
|
|
return parameters.find(key, pos) ? parameters[pos].second : string();
|
2002-11-03 17:26:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Parse key
|
|
|
|
*/
|
|
|
|
|
|
|
|
string ConfigFile::parseKeyFrom(const string& inputLine, string::size_type& endPos)
|
|
|
|
{
|
2004-03-14 14:14:58 +01:00
|
|
|
endPos = inputLine.find_first_of("=");
|
2002-11-03 17:26:12 +01:00
|
|
|
if (endPos == string::npos)
|
|
|
|
{
|
|
|
|
return inputLine;
|
|
|
|
}
|
|
|
|
|
|
|
|
return inputLine.substr(0, endPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Parse value
|
|
|
|
*/
|
|
|
|
|
|
|
|
string ConfigFile::parseValueFrom(string inputLine, string::size_type initialPos)
|
|
|
|
{
|
|
|
|
if (initialPos == string::npos)
|
|
|
|
{
|
|
|
|
return string();
|
|
|
|
}
|
|
|
|
|
|
|
|
// skip leading white spaces
|
2005-01-12 09:30:24 +01:00
|
|
|
const string::size_type startPos = inputLine.find_first_not_of("= \t", initialPos);
|
2002-11-03 17:26:12 +01:00
|
|
|
if (startPos == string::npos)
|
|
|
|
{
|
|
|
|
return string();
|
|
|
|
}
|
|
|
|
|
2004-03-14 14:14:58 +01:00
|
|
|
inputLine.rtrim(" \t\r");
|
2002-11-03 17:26:12 +01:00
|
|
|
return inputLine.substr(startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Load file, if necessary
|
|
|
|
*/
|
|
|
|
|
|
|
|
void ConfigFile::checkLoadConfig()
|
|
|
|
{
|
|
|
|
if (!isLoadedFlg)
|
|
|
|
{
|
|
|
|
loadConfig();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Load file immediately
|
|
|
|
*/
|
|
|
|
|
2004-03-14 14:14:58 +01:00
|
|
|
namespace {
|
|
|
|
class FileClose
|
|
|
|
{
|
2004-06-14 01:45:02 +02:00
|
|
|
public:
|
2004-04-29 00:00:03 +02:00
|
|
|
static void clear(FILE *f)
|
2004-03-14 14:14:58 +01:00
|
|
|
{
|
|
|
|
if (f) {
|
2004-04-29 00:00:03 +02:00
|
|
|
fclose(f);
|
2004-03-14 14:14:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2004-06-14 01:45:02 +02:00
|
|
|
} // namespace
|
2004-03-14 14:14:58 +01:00
|
|
|
|
2002-11-03 17:26:12 +01:00
|
|
|
void ConfigFile::loadConfig()
|
|
|
|
{
|
|
|
|
isLoadedFlg = true;
|
|
|
|
|
|
|
|
parameters.clear();
|
|
|
|
|
2004-04-29 00:00:03 +02:00
|
|
|
Firebird::AutoPtr<FILE, FileClose> ifile(fopen(configFile.c_str(), "rt"));
|
2003-04-19 18:46:24 +02:00
|
|
|
|
2004-08-30 20:11:08 +02:00
|
|
|
#ifdef EXCEPTION_ON_NO_CONF
|
2003-04-19 18:46:24 +02:00
|
|
|
int BadLinesCount = 0;
|
|
|
|
#endif
|
2004-02-08 18:08:34 +01:00
|
|
|
if (!ifile)
|
2002-11-03 17:26:12 +01:00
|
|
|
{
|
2003-04-19 18:46:24 +02:00
|
|
|
// config file does not exist
|
2004-08-30 20:11:08 +02:00
|
|
|
#ifdef EXCEPTION_ON_NO_CONF
|
|
|
|
if (fExceptionOnError)
|
2004-04-11 16:47:04 +02:00
|
|
|
{
|
|
|
|
Firebird::string Msg = "Missing configuration file: " +
|
|
|
|
configFile.ToString() + ", exiting";
|
2008-01-31 13:05:08 +01:00
|
|
|
Firebird::Syslog::Record(Firebird::Syslog::Error, Msg.c_str());
|
2004-08-16 14:24:30 +02:00
|
|
|
Firebird::fatal_exception::raise(Msg.c_str());
|
2004-04-11 16:47:04 +02:00
|
|
|
}
|
2004-08-30 20:11:08 +02:00
|
|
|
#endif //EXCEPTION_ON_NO_CONF
|
2003-04-19 18:46:24 +02:00
|
|
|
return;
|
2002-11-03 17:26:12 +01:00
|
|
|
}
|
|
|
|
string inputLine;
|
|
|
|
|
2004-02-08 18:08:34 +01:00
|
|
|
while (!feof(ifile))
|
2002-11-03 17:26:12 +01:00
|
|
|
{
|
2004-02-08 18:08:34 +01:00
|
|
|
inputLine.LoadFromFile(ifile);
|
2002-11-03 17:26:12 +01:00
|
|
|
|
|
|
|
stripComments(inputLine);
|
2004-03-14 14:14:58 +01:00
|
|
|
inputLine.ltrim(" \t\r");
|
2002-11-03 17:26:12 +01:00
|
|
|
|
|
|
|
if (!inputLine.size())
|
|
|
|
{
|
|
|
|
continue; // comment-line or empty line
|
|
|
|
}
|
|
|
|
|
|
|
|
if (inputLine.find('=') == string::npos)
|
|
|
|
{
|
2004-02-08 18:08:34 +01:00
|
|
|
Firebird::string Msg = (configFile + ": illegal line \"" +
|
|
|
|
inputLine + "\"").ToString();
|
2004-08-30 20:11:08 +02:00
|
|
|
Firebird::Syslog::Record(fExceptionOnError ?
|
2003-04-19 18:46:24 +02:00
|
|
|
Firebird::Syslog::Error :
|
2008-01-31 13:05:08 +01:00
|
|
|
Firebird::Syslog::Warning, Msg.c_str());
|
2004-08-30 20:11:08 +02:00
|
|
|
#ifdef EXCEPTION_ON_NO_CONF
|
2003-04-19 18:46:24 +02:00
|
|
|
BadLinesCount++;
|
|
|
|
#endif
|
2002-11-03 17:26:12 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
string::size_type endPos;
|
|
|
|
|
|
|
|
string key = parseKeyFrom(inputLine, endPos);
|
2004-03-14 14:14:58 +01:00
|
|
|
key.rtrim(" \t\r");
|
2003-04-19 18:46:24 +02:00
|
|
|
// TODO: here we must check for correct parameter spelling !
|
2002-11-03 17:26:12 +01:00
|
|
|
string value = parseValueFrom(inputLine, endPos);
|
|
|
|
|
2004-03-14 14:14:58 +01:00
|
|
|
parameters.add(Parameter(getPool(), key, value));
|
2002-11-03 17:26:12 +01:00
|
|
|
}
|
2004-08-30 20:11:08 +02:00
|
|
|
#ifdef EXCEPTION_ON_NO_CONF
|
|
|
|
if (BadLinesCount && fExceptionOnError)
|
2004-08-16 14:24:30 +02:00
|
|
|
{
|
|
|
|
Firebird::fatal_exception::raise("Bad lines in firebird.conf");
|
2003-04-19 18:46:24 +02:00
|
|
|
}
|
|
|
|
#endif
|
2002-11-03 17:26:12 +01:00
|
|
|
}
|
2005-01-12 09:30:24 +01:00
|
|
|
|